diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c01cbfe0954f..11a16c3ec785 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,19 +16,19 @@ /.github @TimWolla /build/gen_stub.php @kocsismate -/ext/bcmath @ndossche @SakiTakamachi +/ext/bcmath @SakiTakamachi /ext/curl @adoy /ext/date @derickr /ext/dba @Girgias -/ext/dom @ndossche +/ext/dom @devnexen /ext/ffi @dstogov /ext/gd @devnexen /ext/gettext @devnexen /ext/gmp @Girgias -/ext/intl @devnexen +/ext/intl @devnexen @LamentXU123 +/ext/libxml @devnexen /ext/json @bukka -/ext/lexbor @kocsismate @ndossche -/ext/libxml @ndossche +/ext/lexbor @kocsismate /ext/mbstring @alexdowad @youkidearitai /ext/mysqli @bukka @kamil-tekiela /ext/mysqlnd @bukka @kamil-tekiela @SakiTakamachi @@ -44,20 +44,21 @@ /ext/pdo_pgsql @devnexen @SakiTakamachi /ext/pdo_sqlite @SakiTakamachi /ext/pgsql @devnexen +/ext/phar @LamentXU123 /ext/random @TimWolla @zeriyoshi /ext/reflection @DanielEScherzer /ext/session @Girgias -/ext/simplexml @ndossche -/ext/soap @ndossche +/ext/simplexml @devnexen +/ext/soap @devnexen /ext/sockets @devnexen /ext/spl @Girgias /ext/standard @bukka -/ext/tidy @ndossche /ext/uri @kocsismate @TimWolla -/ext/xml @ndossche -/ext/xmlreader @ndossche -/ext/xmlwriter @ndossche -/ext/xsl @ndossche +/ext/xml @devnexen +/ext/xmlreader @devnexen +/ext/xmlwriter @devnexen +/ext/xsl @devnexen +/ext/zip @LamentXU123 /main @bukka /sapi/fpm @bukka /Zend/Optimizer @dstogov diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 53bd4df5a1ca..296835e02e0d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -26,14 +26,15 @@ body: attributes: label: PHP Version description: | - Please run PHP with the `-v` flag (e.g. `php -v`, `php8.3 -v`, `php-fpm -v` or similar) and provide the full output of that command. If executing that command is not possible, please provide the full version number as given in PHPInfo. + Please run PHP with the `-v` flag (e.g. `php -v`, `php8.5 -v`, `php-fpm -v` or similar) and provide the full output of that command. If executing that command is not possible, please provide the full version number as given in PHPInfo. Please make sure that the used PHP version [is a supported version](https://www.php.net/supported-versions.php). placeholder: | - PHP 8.3.19 (cli) (built: Mar 13 2025 17:44:40) (NTS) - Copyright (c) The PHP Group - Zend Engine v4.3.19, Copyright (c) Zend Technologies - with Zend OPcache v8.3.19, Copyright (c), by Zend Technologies + PHP 8.5.2 (cli) (built: Jan 21 2026 17:35:28) (NTS) + Copyright © The PHP Group and Contributors + Built by Ubuntu + Zend Engine v4.5.2, Copyright © Zend by Perforce + with Zend OPcache v8.5.2, Copyright ©, Zend by Perforce render: plain validations: required: true diff --git a/.github/actions/apk/action.yml b/.github/actions/apk/action.yml index 0cda4963a6a9..8d0fee161187 100644 --- a/.github/actions/apk/action.yml +++ b/.github/actions/apk/action.yml @@ -28,7 +28,6 @@ runs: curl-dev \ freetype-dev \ gettext-dev \ - gnu-libiconv-dev \ gmp-dev \ icu-dev \ icu-data-full \ diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml index 7ae0a88ff755..3e654ef9fdc4 100644 --- a/.github/actions/apt-x64/action.yml +++ b/.github/actions/apt-x64/action.yml @@ -63,6 +63,7 @@ runs: snmp-mibs-downloader \ freetds-dev \ unixodbc-dev \ + libsqliteodbc \ llvm \ clang \ dovecot-core \ diff --git a/.github/actions/brew/action.yml b/.github/actions/brew/action.yml index f90a66f239de..db43010f396f 100644 --- a/.github/actions/brew/action.yml +++ b/.github/actions/brew/action.yml @@ -33,4 +33,6 @@ runs: t1lib \ libxml2 \ libjpeg \ - libxslt + libxslt \ + openssl@4 + brew link --force --overwrite openssl@4 diff --git a/.github/actions/configure-alpine/action.yml b/.github/actions/configure-alpine/action.yml index fe02dacfcdaf..d1b4cfea0412 100644 --- a/.github/actions/configure-alpine/action.yml +++ b/.github/actions/configure-alpine/action.yml @@ -43,7 +43,7 @@ runs: --enable-pcntl \ --with-readline \ --enable-mbstring \ - --with-iconv=/usr \ + --with-iconv \ --with-curl \ --with-gettext \ --enable-sockets \ diff --git a/.github/actions/configure-macos/action.yml b/.github/actions/configure-macos/action.yml index f0af959d2102..b9739a790530 100644 --- a/.github/actions/configure-macos/action.yml +++ b/.github/actions/configure-macos/action.yml @@ -11,7 +11,7 @@ runs: set -x BREW_OPT="$(brew --prefix)"/opt export PATH="$BREW_OPT/bison/bin:$PATH" - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/openssl/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/openssl@4/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/curl/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libffi/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libxml2/lib/pkgconfig" diff --git a/.github/actions/freebsd/action.yml b/.github/actions/freebsd/action.yml index 3b6d0c4e8617..197362d9f52b 100644 --- a/.github/actions/freebsd/action.yml +++ b/.github/actions/freebsd/action.yml @@ -46,7 +46,7 @@ runs: pkgconf \ webp \ libavif \ - `#sqlite3` \ + sqlite3 \ curl \ $OPCACHE_TLS_TESTS_DEPS @@ -57,9 +57,7 @@ runs: --enable-debug \ --enable-option-checking=fatal \ --enable-fpm \ - `#--with-pdo-sqlite` \ - --without-sqlite3 \ - --without-pdo-sqlite \ + --with-pdo-sqlite \ --without-pear \ --with-bz2 \ --with-avif \ diff --git a/.github/actions/setup-windows/action.yml b/.github/actions/setup-windows/action.yml index e0a3fd4e7d31..a5fa4cdddcb1 100644 --- a/.github/actions/setup-windows/action.yml +++ b/.github/actions/setup-windows/action.yml @@ -16,5 +16,6 @@ runs: - name: Setup PostgreSQL shell: pwsh run: | - Set-Service -Name "postgresql-x64-14" -StartupType manual -Status Running + $postgresService = if ($env:PHP_BUILD_CRT -eq "vs18") { "postgresql-x64-17" } else { "postgresql-x64-14" } + Set-Service -Name $postgresService -StartupType manual -Status Running pwsh -Command { $env:PGPASSWORD="root"; & "$env:PGBIN\psql" -U postgres -c "ALTER USER postgres WITH PASSWORD 'Password12!';" } diff --git a/.github/labeler.yml b/.github/labeler.yml index b9f0f36e147d..e9731352c8cc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -20,6 +20,18 @@ - scripts/**/* - win32/build/**/* +"Category: CI": + - changed-files: + - any-glob-to-any-file: + - .circleci/* + - .github/actions/**/* + - .github/scripts/**/* + - .github/workflows/* + - .github/CODEOWNERS + - .github/labeler.yml + - .github/setup_hmailserver.php + - .github/matrix.php + "Extension: bcmath": - changed-files: - any-glob-to-any-file: diff --git a/.github/matrix.php b/.github/matrix.php index 2ce59cb657b5..7970442d7050 100644 --- a/.github/matrix.php +++ b/.github/matrix.php @@ -61,7 +61,6 @@ function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $re $test_macos = in_array('CI: macOS', $labels, true); $test_msan = in_array('CI: MSAN', $labels, true); $test_opcache_variation = in_array('CI: Opcache Variation', $labels, true); - $test_pecl = in_array('CI: PECL', $labels, true); $test_solaris = in_array('CI: Solaris', $labels, true); $test_windows = in_array('CI: Windows', $labels, true); @@ -80,7 +79,14 @@ function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $re $jobs['COMMUNITY']['matrix'] = version_compare($php_version, '8.4', '>=') ? ['type' => ['asan', 'verify_type_inference']] : ['type' => ['asan']]; - $jobs['COMMUNITY']['config']['symfony_version'] = version_compare($php_version, '8.4', '>=') ? '8.1' : '7.4'; + $jobs['COMMUNITY']['config']['symfony_version'] = match (true) { + version_compare($php_version, '8.3', '<=') => '7.4', + default => '', + }; + $jobs['COMMUNITY']['config']['laravel_version'] = match (true) { + version_compare($php_version, '8.2', '<=') => '12.x', + default => '', + }; } if (($all_jobs && $ref === 'master') || $test_coverage) { $jobs['COVERAGE'] = true; @@ -130,22 +136,24 @@ function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $re if ($all_jobs || $test_opcache_variation) { $jobs['OPCACHE_VARIATION'] = true; } - if (($all_jobs && $ref === 'master') || $test_pecl) { - $jobs['PECL'] = true; - } if (version_compare($php_version, '8.6', '>=') && ($all_jobs || $test_solaris)) { $jobs['SOLARIS'] = true; } if ($all_jobs || !$no_jobs || $test_windows) { - $jobs['WINDOWS']['matrix'] = $all_variations - ? ['include' => [ - ['asan' => true, 'opcache' => true, 'x64' => true, 'zts' => true], - ['asan' => false, 'opcache' => false, 'x64' => false, 'zts' => false], - ]] - : ['include' => [['asan' => false, 'opcache' => true, 'x64' => true, 'zts' => true]]]; - $jobs['WINDOWS']['config'] = version_compare($php_version, '8.4', '>=') - ? ['vs_crt_version' => 'vs17'] - : ['vs_crt_version' => 'vs16']; + $matrix = [['asan' => false, 'opcache' => true, 'x64' => true, 'zts' => true]]; + if ($all_variations) { + $matrix[] = ['asan' => true, 'opcache' => true, 'x64' => true, 'zts' => true]; + $matrix[] = ['asan' => false, 'opcache' => false, 'x64' => false, 'zts' => false]; + if (version_compare($php_version, '8.6', '>=')) { + $matrix[] = ['asan' => false, 'opcache' => true, 'x64' => true, 'zts' => true, 'clang' => true]; + } + } + $jobs['WINDOWS']['matrix'] = ['include' => $matrix]; + $jobs['WINDOWS']['config'] = match (true) { + version_compare($php_version, '8.6', '>=') => ['vs_crt_version' => 'vs18', 'runs_on' => 'windows-2025-vs2026'], + version_compare($php_version, '8.4', '>=') => ['vs_crt_version' => 'vs17', 'runs_on' => 'windows-2022'], + default => ['vs_crt_version' => 'vs16', 'runs_on' => 'windows-2022'], + }; } if ($all_jobs || !$no_jobs || $test_freebsd) { $jobs['FREEBSD']['matrix'] = $all_variations && version_compare($php_version, '8.3', '>=') diff --git a/.github/scripts/download-bundled/boost-context.sh b/.github/scripts/download-bundled/boost-context.sh index b1fd8708b85b..02febff73c3f 100755 --- a/.github/scripts/download-bundled/boost-context.sh +++ b/.github/scripts/download-bundled/boost-context.sh @@ -5,7 +5,7 @@ cd "$(dirname "$0")/../../.." tmp_dir=/tmp/php-src-download-bundled/boost-context rm -rf "$tmp_dir" -revision=refs/tags/boost-1.86.0 +revision=refs/tags/boost-1.91.0 git clone --depth 1 --revision="$revision" https://github.com/boostorg/context.git "$tmp_dir" @@ -16,12 +16,14 @@ cd Zend/asm # remove unneeded files rm jump_arm_aapcs_pe_armasm.asm +rm jump_arm64_aapcs_pe_armclang.S rm jump_i386_ms_pe_clang_gas.S rm jump_i386_ms_pe_gas.asm rm jump_i386_x86_64_sysv_macho_gas.S rm jump_ppc32_ppc64_sysv_macho_gas.S rm jump_x86_64_ms_pe_clang_gas.S rm make_arm_aapcs_pe_armasm.asm +rm make_arm64_aapcs_pe_armclang.S rm make_i386_ms_pe_clang_gas.S rm make_i386_ms_pe_gas.asm rm make_i386_x86_64_sysv_macho_gas.S diff --git a/.github/scripts/download-bundled/uriparser.sh b/.github/scripts/download-bundled/uriparser.sh index 8820a67333f0..2b8d61a2d56f 100755 --- a/.github/scripts/download-bundled/uriparser.sh +++ b/.github/scripts/download-bundled/uriparser.sh @@ -5,7 +5,7 @@ cd "$(dirname "$0")/../../.." tmp_dir=/tmp/php-src-download-bundled/uriparser rm -rf "$tmp_dir" -revision=refs/tags/uriparser-1.0.0 +revision=refs/tags/uriparser-1.0.2 git clone --depth 1 --revision="$revision" https://github.com/uriparser/uriparser.git "$tmp_dir" diff --git a/.github/scripts/windows/build_task.bat b/.github/scripts/windows/build_task.bat index b65479451849..1177cef3be4d 100644 --- a/.github/scripts/windows/build_task.bat +++ b/.github/scripts/windows/build_task.bat @@ -26,12 +26,18 @@ if %errorlevel% neq 0 exit /b 3 if "%THREAD_SAFE%" equ "0" set ADD_CONF=%ADD_CONF% --disable-zts if "%INTRINSICS%" neq "" set ADD_CONF=%ADD_CONF% --enable-native-intrinsics=%INTRINSICS% if "%ASAN%" equ "1" set ADD_CONF=%ADD_CONF% --enable-sanitizer --enable-debug-pack +if "%CLANG_TOOLSET%" equ "1" set ADD_CONF=%ADD_CONF% --with-toolset=clang rem C4018: comparison: signed/unsigned mismatch rem C4146: unary minus operator applied to unsigned type rem C4244: type conversion, possible loss of data rem C4267: 'size_t' type conversion, possible loss of data -set CFLAGS=/W3 /WX /wd4018 /wd4146 /wd4244 /wd4267 +if "%CLANG_TOOLSET%" equ "1" ( + rem Clang is much stricter than MSVC, produces too many warnings that would fail the build with /WX + set CFLAGS=/W3 /wd4018 /wd4146 /wd4244 /wd4267 +) else ( + set CFLAGS=/W3 /WX /wd4018 /wd4146 /wd4244 /wd4267 +) cmd /c configure.bat ^ --enable-snapshot-build ^ diff --git a/.github/scripts/windows/find-vs-toolset.bat b/.github/scripts/windows/find-vs-toolset.bat index 2d9e68e73031..ecaca6775b07 100644 --- a/.github/scripts/windows/find-vs-toolset.bat +++ b/.github/scripts/windows/find-vs-toolset.bat @@ -3,7 +3,7 @@ setlocal enabledelayedexpansion if "%~1"=="" ( - echo ERROR: Usage: %~nx0 [vc14^|vc15^|vs16^|vs17] + echo ERROR: Usage: %~nx0 [vc14^|vc15^|vs16^|vs17^|vs18] exit /b 1 ) @@ -11,6 +11,7 @@ set "toolsets_vc14=14.0" set "toolsets_vc15=" set "toolsets_vs16=" set "toolsets_vs17=" +set "toolsets_vs18=" for /f "usebackq tokens=*" %%I in (`vswhere.exe -latest -find "VC\Tools\MSVC"`) do set "MSVCDIR=%%I" @@ -30,8 +31,10 @@ for /f "delims=" %%D in ('dir /b /ad "%MSVCDIR%"') do ( set "toolsets_vc15=%%D" ) else if !min! LEQ 29 ( set "toolsets_vs16=%%D" - ) else ( + ) else if !min! LEQ 49 ( set "toolsets_vs17=%%D" + ) else ( + set "toolsets_vs18=%%D" ) ) ) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 83aae655a3c3..e269ed336408 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -16,6 +16,7 @@ jobs: name: LINUX_PPC64_ASAN_DEBUG_ZTS # This runs on a self-hosted runner; see https://wiki.php.net/systems/ci runs-on: [self-hosted, gentoo, ppc64] + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -55,6 +56,7 @@ jobs: if: ${{ fromJson(inputs.branch).jobs.ALPINE }} name: ALPINE_X64_ASAN_DEBUG_ZTS runs-on: ubuntu-24.04 + timeout-minutes: 180 container: image: 'alpine:3.22' steps: @@ -130,6 +132,7 @@ jobs: matrix: ${{ fromJson(inputs.branch).jobs.LINUX_X64.matrix }} name: "LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -166,7 +169,7 @@ jobs: ${{ matrix.variation && 'CFLAGS="-DZEND_RC_DEBUG=1 -DPROFITABILITY_CHECKS=0 -DZEND_VERIFY_FUNC_INFO=1 -DZEND_VERIFY_TYPE_INFERENCE"' || '' }} ${{ (matrix.variation && fromJson(inputs.branch).jobs.LINUX_X64.config.variation_enable_zend_max_execution_timers) && '--enable-zend-max-execution-timers' || '' }} --${{ matrix.debug && 'enable' || 'disable' }}-debug - ${{ matrix.debug && 'CXXFLAGS="-D_GLIBCXX_ASSERTIONS"' || '' }} + ${{ (matrix.variation || matrix.debug) && format('CXXFLAGS="{0} {1}"', matrix.variation && '-DZEND_VERIFY_TYPE_INFERENCE' || '', matrix.debug && '-D_GLIBCXX_ASSERTIONS' || '') || '' }} --${{ matrix.zts && 'enable' || 'disable' }}-zts asan: ${{ matrix.asan && 'true' || 'false' }} skipSlow: ${{ (matrix.asan && !inputs.all_variations) && 'true' || 'false' }} @@ -228,6 +231,7 @@ jobs: matrix: ${{ fromJson(inputs.branch).jobs.LINUX_X32.matrix }} name: "LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-latest + timeout-minutes: 180 container: image: ubuntu:${{ fromJson(inputs.branch).config.ubuntu_version }} env: @@ -309,6 +313,7 @@ jobs: matrix: ${{ fromJson(inputs.branch).jobs.MACOS.matrix }} name: "MACOS_${{ matrix.arch }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: macos-${{ matrix.arch == 'X64' && '15-intel' || fromJson(inputs.branch).jobs.MACOS.config.arm64_version }} + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -386,6 +391,7 @@ jobs: FIREBIRD_USER: test FIREBIRD_PASSWORD: test runs-on: ubuntu-24.04 + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -413,10 +419,15 @@ jobs: with: enableOpcache: true jitType: tracing - - uses: codecov/codecov-action@v5 + - name: Generate coverage report + if: ${{ !cancelled() }} + run: make gcovr-xml + - uses: codecov/codecov-action@v6 if: ${{ !cancelled() }} with: + disable_search: true fail_ci_if_error: true + files: gcovr.xml token: ${{ secrets.CODECOV_TOKEN }} verbose: true COMMUNITY: @@ -506,7 +517,8 @@ jobs: - name: Test Laravel if: ${{ !cancelled() }} run: | - git clone https://github.com/laravel/framework.git --depth=1 + branch=${{ fromJson(inputs.branch).jobs.COMMUNITY.config.laravel_version }} + git clone https://github.com/laravel/framework.git --depth=1 ${branch:+--branch="$branch"} cd framework git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-req=php+ @@ -551,7 +563,8 @@ jobs: - name: Test Symfony if: ${{ !cancelled() }} run: | - git clone https://github.com/symfony/symfony.git --depth=1 --branch="${{ fromJson(inputs.branch).jobs.COMMUNITY.config.symfony_version }}" + branch=${{ fromJson(inputs.branch).jobs.COMMUNITY.config.symfony_version }} + git clone https://github.com/symfony/symfony.git --depth=1 ${branch:+--branch="$branch"} cd symfony git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-req=php+ @@ -560,6 +573,10 @@ jobs: php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);' # Buggy FFI test in Symfony, see https://github.com/symfony/symfony/issues/47668 php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("public function testCastNonTrailingCharPointer()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);' + # Causes massive amounts of system calls with USE_ZEND_ALLOC=0, exceeding the timeout + if [ -e 'src/Symfony/Component/Console/Tests/Helper/FileInputHelperTest.php' ]; then + php -r '$c = file_get_contents("src/Symfony/Component/Console/Tests/Helper/FileInputHelperTest.php"); $c = str_replace("public function testReadWithPasteDetectionAbortsBeyondMaxBytes()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testReadWithPasteDetectionAbortsBeyondMaxBytes()", $c); file_put_contents("src/Symfony/Component/Console/Tests/Helper/FileInputHelperTest.php", $c);' + fi export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 X=0 for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do @@ -635,6 +652,7 @@ jobs: FIREBIRD_PASSWORD: test name: OPCACHE_VARIATION runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -698,6 +716,7 @@ jobs: if: ${{ fromJson(inputs.branch).jobs.MSAN }} name: MSAN runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -789,6 +808,7 @@ jobs: if: ${{ fromJson(inputs.branch).jobs.LIBMYSQLCLIENT }} name: LIBMYSQLCLIENT runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + timeout-minutes: 180 steps: - name: git checkout uses: actions/checkout@v6 @@ -820,126 +840,19 @@ jobs: uses: ./.github/actions/test-libmysqlclient - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files - PECL: - if: ${{ fromJson(inputs.branch).jobs.PECL }} - runs-on: ubuntu-24.04 - steps: - - name: git checkout PHP - uses: actions/checkout@v6 - with: - path: php - ref: ${{ fromJson(inputs.branch).ref }} - # Used for ccache action - - name: Move .github - run: mv php/.github . - - name: git checkout apcu - uses: actions/checkout@v6 - with: - repository: krakjoe/apcu - path: apcu - - name: git checkout imagick - uses: actions/checkout@v6 - with: - repository: Imagick/imagick - path: imagick - - name: git checkout memcached - uses: actions/checkout@v6 - with: - repository: php-memcached-dev/php-memcached - path: memcached - - name: git checkout redis - if: ${{ false }} - uses: actions/checkout@v6 - with: - repository: phpredis/phpredis - path: redis - - name: git checkout xdebug - uses: actions/checkout@v6 - with: - repository: xdebug/xdebug - path: xdebug - - name: git checkout yaml - uses: actions/checkout@v6 - with: - repository: php/pecl-file_formats-yaml - path: yaml - - name: apt - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - ccache \ - libmemcached-dev \ - imagemagick \ - libmagickwand-dev \ - bison \ - re2c - - name: ccache - uses: ./.github/actions/ccache - with: - name: "${{ github.job }}" - php_directory: php - - name: build PHP - run: | - cd php - ./buildconf --force - ./configure \ - --enable-option-checking=fatal \ - --prefix=/opt/php \ - --enable-cli \ - --disable-all \ - --enable-session \ - --enable-werror - make -j$(/usr/bin/nproc) - sudo make install - - name: build apcu - run: | - cd apcu - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build imagick - run: | - cd imagick - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build memcached - run: | - cd memcached - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build redis - if: ${{ false }} - run: | - cd redis - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build xdebug - run: | - cd xdebug - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build yaml - run: | - cd yaml - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) WINDOWS: if: ${{ fromJson(inputs.branch).jobs.WINDOWS }} strategy: fail-fast: false matrix: ${{ fromJson(inputs.branch).jobs.WINDOWS.matrix }} - name: "WINDOWS_${{ matrix.x64 && 'X64' || 'X86' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || ''}}" - runs-on: windows-2022 + name: "WINDOWS_${{ matrix.x64 && 'X64' || 'X86' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || ''}}${{ matrix.clang && '_CLANG' || ''}}" + runs-on: ${{ fromJson(inputs.branch).jobs.WINDOWS.config.runs_on }} + timeout-minutes: 180 env: PHP_BUILD_CACHE_BASE_DIR: C:\build-cache PHP_BUILD_OBJ_DIR: C:\obj PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.5.0 + PHP_BUILD_SDK_BRANCH: php-sdk-2.7.1 PHP_BUILD_CRT: ${{ fromJson(inputs.branch).jobs.WINDOWS.config.vs_crt_version }} PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }} THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}" @@ -947,6 +860,7 @@ jobs: PARALLEL: -j2 OPCACHE: "${{ matrix.opcache && '1' || '0' }}" ASAN: "${{ matrix.asan && '1' || '0' }}" + CLANG_TOOLSET: "${{ matrix.clang && '1' || '0' }}" steps: - name: git config run: git config --global core.autocrlf false && git config --global core.eol lf diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69ba4c0e4865..eafedec5eafa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,15 +2,17 @@ name: Test on: push: paths-ignore: &ignore_paths + - .circleci/** + - .github/CODEOWNERS + - .github/ISSUE_TEMPLATE/** + - '**/*.md' + - '**/*.rst' - docs/** + - EXTENSIONS + - LICENSE - NEWS - UPGRADING - UPGRADING.INTERNALS - - '**/README.*' - - CONTRIBUTING.md - - CODING_STANDARDS.md - - .cirrus.yml - - .circleci/** branches: - PHP-8.2 - PHP-8.3 diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 6338a1cb945d..fa79580f42ec 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -3,6 +3,8 @@ on: push: paths: - 'main/network.c' + - 'main/io/**' + - 'main/php_io.h' - 'tests/unit/**' - '.github/workflows/unit-tests.yml' branches: @@ -10,6 +12,8 @@ on: pull_request: paths: - 'main/network.c' + - 'main/io/**' + - 'main/php_io.h' - 'tests/unit/**' - '.github/workflows/unit-tests.yml' branches: diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 47b76717c839..3a53d0e258ca 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -79,6 +79,16 @@ rewritten to comply with these rules. return value for functions that perform some operation that may succeed or fail. +1. When throwing a `ValueError` or emitting a warning, use consistent + phrasing for error messages. Common patterns are: + + * Type errors: `must be of type int` (use the type name, not e.g. `must be an integer`) + * Range/boundary: `must be between X and Y` / `must be greater than [or equal to] X` / `must be less than X` / `must be finite` + * String constraints: `must not contain any null bytes` / `must not be empty` / `must be a single character` + * Valid value: `must be a valid X` (e.g. `must be a valid encoding`, `must be a valid calendar ID`) + * Enum-like: `must be one of X, Y, or Z` + * Structural: `must have X` / `must have key X` / `must have N elements` + ## User functions/methods naming conventions 1. Function names for user-level functions should be enclosed with in the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f797df1e97a..aabd945ad385 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,7 @@ had several contributions accepted, commit privileges are often quickly granted. * [Git commit rules](#git-commit-rules) * [Copyright and license headers](#copyright-and-license-headers) * [NEWS file](#news) +* [LLM usage in GitHub comments](#llm-usage-in-github-comments) ## Pull requests @@ -36,8 +37,8 @@ implement RFCs. Please be sure to include tests as appropriate! By submitting a pull request, you certify that you have the necessary rights to submit the work, that the work does not violate any third-party rights (including those of your employer, if applicable), and that you license your -contribution under the PHP License or under another license if explicitly -accepted by the PHP project maintainers. +contribution under the [Modified BSD License](LICENSE) or under another license +if explicitly accepted by the PHP project maintainers. If you are fixing a bug, then please submit your PR against the lowest actively supported branch of PHP that the bug affects (only green branches on @@ -90,7 +91,7 @@ repository. Mailing list subscription is explained on the [mailing lists page](https://www.php.net/mailing-lists.php). You may also want to read -[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/post/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) +[The Mysterious PHP RFC Process](https://web.archive.org/web/20210621140006/https://blogs.oracle.com/opal/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) for additional notes on the best way to approach submitting an RFC. ## Technical resources @@ -151,9 +152,8 @@ about what you're working on, you can contact us via the issues. Although not a formal channel, you can also find a number of core developers on -the #php.pecl channel on [EFnet](http://www.efnet.org/). Similarly, many -documentation writers can be found on #php.doc. Windows development IRC channel -is available at #winphp-dev on FreeNode. +the [php community discord server](https://phpc.chat/) (`#php-internals` channel) +where many people are eager to help. ## PHP source code directory structure @@ -355,30 +355,21 @@ Having said that, here are the organizational rules: `--enable-zts` switch to ensure your code handles TSRM correctly and doesn't break for those who need that. -Currently, we have the following branches in use: - -| Branch | | -| --------- | --------- | -| master | Active development branch for PHP 8.6, which is open for backwards incompatible changes and major internal API changes. | -| PHP-8.5 | Is used to release the PHP 8.5.x series. This is a current stable version and is open for bugfixes only. | -| PHP-8.4 | Is used to release the PHP 8.4.x series. This is a current stable version and is open for bugfixes only. | -| PHP-8.3 | Is used to release the PHP 8.3.x series. This is a current stable version and is open for bugfixes only. | -| PHP-8.2 | Is used to release the PHP 8.2.x series. This is an old stable version and is open for security fixes only. | -| PHP-8.1 | Is used to release the PHP 8.1.x series. This is an old stable version and is open for security fixes only. | -| PHP-8.0 | This branch is closed. | -| PHP-7.4 | This branch is closed. | -| PHP-7.3 | This branch is closed. | -| PHP-7.2 | This branch is closed. | -| PHP-7.1 | This branch is closed. | -| PHP-7.0 | This branch is closed. | -| PHP-5.6 | This branch is closed. | -| PHP-5.5 | This branch is closed. | -| PHP-5.4 | This branch is closed. | -| PHP-5.3 | This branch is closed. | -| PHP-5.2 | This branch is closed. | -| PHP-5.1 | This branch is closed. | -| PHP-4.4 | This branch is closed. | -| PHP-X.Y.Z | These branches are used for the release managers for tagging the releases, hence they are closed to the general public. | +The master branch is an active development branch for the newest version of PHP, +which is open for backwards incompatible changes and major internal API changes. + +For PHP-X.Y branches, they are used to release the PHP X.Y.z series. Please see +the [supported versions page](https://www.php.net/supported-versions.php) to get +the status of each version. + +If a version is described as "Active support", the corresponding branch is a +current stable version and is open for bugfixes only. If a version is described +as "Security fixes only", the corresponding branch is an old stable version +and is open for security fixes only. If a version is described as "End of life", +the corresponding branch is closed. + +Note that PHP-X.Y.Z branches are used for the release managers for tagging the +releases, hence they are closed to the general public. The next few rules are more of a technical nature: @@ -438,15 +429,13 @@ New source code files should include the following header block: ```c /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: | +----------------------------------------------------------------------+ @@ -537,6 +526,12 @@ If for some reason a feature is introduced in a branch lower than master, although this is strictly prohibited by other policies, then the entry must also be in master. +## LLM usage in GitHub comments + +When using LLMs to generate comments to maintainers for any purpose other than +direct translation, we would highly appreciate it if you disclosed the relevant +paragraphs as such via markdown quote. + ## Thanks Thank you for contributing to PHP! diff --git a/EXTENSIONS b/EXTENSIONS index 8da09aed5392..01807655e3a5 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -171,28 +171,28 @@ PRIMARY MAINTAINER: Christian Stocker (2003 - 2011) Rob Richards (2003 - 2012) Marcus Börger (2003 - 2006) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- EXTENSION: simplexml PRIMARY MAINTAINER: Marcus Börger (2003 - 2008) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- EXTENSION: soap PRIMARY MAINTAINER: Dmitry Stogov (2004 - 2018) Nora Dossche (2024 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xml PRIMARY MAINTAINER: Thies C. Arntzen (1999 - 2002) Rob Richards (2003 - 2013) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: lexbor @@ -206,28 +206,28 @@ EXTENSION: libxml PRIMARY MAINTAINER: Rob Richards (2003 - 2009) Christian Stocker (2004 - 2011) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xmlreader PRIMARY MAINTAINER: Rob Richards (2004 - 2010) Christian Stocker (2004 - 2004) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xmlwriter PRIMARY MAINTAINER: Rob Richards (2004 - 2010) Pierre-Alain Joye (2005-2009) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xsl PRIMARY MAINTAINER: Christian Stocker (2003 - 2011) Rob Richards (2003 - 2010) Nora Dossche (2023 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- @@ -351,6 +351,7 @@ STATUS: Working EXTENSION: intl PRIMARY MAINTAINER: Stanislav Malyshev (2008 - 2019) Anatol Belski (2017 - 2018) + Weilin Du (2026 - 2026) MAINTENANCE: Maintained STATUS: Working SINCE: 5.3 @@ -409,6 +410,7 @@ PRIMARY MAINTAINER: Greg Beaver (2008 - 2009) Marcus Börger (2008 - 2008) Steph Fox (2008 - 2008) Bishop Bettini (2018 - 2019) + Weilin Du (2026 - 2026) MAINTENANCE: Maintained STATUS: Working SINCE: 5.3 @@ -496,7 +498,7 @@ PRIMARY MAINTAINER: John Coggeshall (2003 - 2006) Ilia Alshanetsky (2003 - 2009) Nuno Lopes (2006 - 2012) Nora Dossche (2025 - 2026) -MAINTENANCE: Odd fixes +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: tokenizer @@ -514,7 +516,8 @@ SINCE: 8.5.0 ------------------------------------------------------------------------------- EXTENSION: zip PRIMARY MAINTAINER: Pierre-Alain Joye (2006 - 2011) - Remi Collet (2013-2020) + Remi Collet (2013 - 2020) + Weilin Du (2026 - 2026) MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index b155a18c2fb7..ee42a57fffbb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,68 +1,27 @@ --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2025 The PHP Group. All rights reserved. --------------------------------------------------------------------- +Copyright © 1999–2026, The PHP Group and Contributors. +Copyright © 1999–2026, Zend Technologies Ltd., a subsidiary company of Perforce Software, Inc. Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". - -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NEWS b/NEWS index 4dcac8bb21e4..63e4fdf0c244 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,211 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.6.0alpha1 +?? ??? ????, PHP 8.6.0alpha3 + +- Core: + . Implemented partial function application RFC. (Arnaud) + . Fixed bug GH-22263 (reset typed property default on every unserialize + failure path). (David Carlier) + +- DOM: + . Fixed bug GH-22825 (DOMElement::setAttribute() fails silently when the DTD + declares a default value for the attribute). (iliaal) + +- GMP: + . Fixed GMP power and shift operators to reject GMP right operands outside + the unsigned long range instead of silently truncating them. (Weilin Du) + . Fixed GMP integer string parsing to reject strings containing NUL bytes + instead of silently truncating them. (Weilin Du) + . Fixed GMP error messages that referenced outdated parameter names. + (Weilin Du) + +- Intl: + . Fixed grammatical issues in Normalizer invalid form and IntlCalendar time + zone offset error messages. (Weilin Du) + +- ODBC: + . Fixed bug GH-22668 (Heap buffer over-read when a column value exceeds the + driver-reported display size). (iliaal) + +- Opcache: + . Re-enable JIT for ZTS builds on Apple Silicon. (realFlowControl) + +- PDO_ODBC: + . Fixed bug GH-22667 (Heap buffer over-read when a column value exceeds the + driver-reported display size). (iliaal) + . Fixed bug GH-22666 (Heap buffer overflow when an output parameter value is + longer than the declared maxlen). (iliaal) + . Fixed bug GH-22665 (Out-of-bounds write when the ODBC driver reports a + diagnostic message length beyond the error buffer). (iliaal) + +- Phar: + . Fixed grammatical issues and outdated terminology in Phar error messages. + (Weilin Du) + +- Reflection: + . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes). + (DanielEScherzer) + +- SOAP: + . Fixed header injection through the Content-Type context option, the + soapaction and the cookie names and values. (David Carlier) + +- MBString: + . Fixed bug GH-22779 (mb_strrpos() returns the wrong position for a negative + offset in a non-UTF-8 encoding). (Eyüp Can Akman) + +- Sockets: + . Fixed socket_set_option() validation error messages for UDP_SEGMENT and + TCP_USER_TIMEOUT, and SO_LINGER options. (Weilin Du) + . Fixed various memory related issues in ext/sockets. (David Carlier) + +- Streams: + . Added a new IO copy API used by php_stream_copy_to_stream_ex() that + leverages platform primitives (sendfile, splice, copy_file_range, + TransmitFile) for faster stream copying. (Jakub Zelenka, David Carlier) + +16 Jul 2026, PHP 8.6.0alpha2 + +- Core: + . Sync Boost.Context assembly with 1.91.0. (kn1g78) + . Fixed bug GH-22387 (AST pretty-printing drops meaningful parentheses around + RHS of instanceof). (timwolla) + . Fixed bug GH-15672 and GH-15911 (Stack overflow when an internal function + recurses through zend_call_function, such as a self-attached SPL + iterator). (iliaal) + . Lock unmodified readonly properties for modification after clone-with. + (NickSdot) + . abort() instead of exit() on hard OOM. (realFlowControl) + . perf: ZTS: move AG and SCNG into native __thread storage. (henderkes) + +- Calendar: + . Fixed bug GH-22602 (gregoriantojd() and juliantojd() integer overflow with + INT_MAX year). (arshidkv12) + +- Curl: + . Added CURLOPT_SEEKFUNCTION and the CURL_SEEKFUNC_OK, CURL_SEEKFUNC_FAIL + and CURL_SEEKFUNC_CANTSEEK constants, letting libcurl rewind a streamed + request body to resend it on a redirect, multi-pass authentication or a + retried reused connection. (GrahamCampbell) + +- Date: + . Update timelib to 2022.17. (Derick) + . Fixed bug GH-19803 (Parsing a string with a single white space does create + an error). (Derick) + . Fixed Unix timestamps in February of the year 0 are misparsed with + @-notation. (LukasGelbmann) + . Fixed bug GH-11368 (idate() doesn't work for the year -1). (Derick) + . Fixed bug GH-11310 (__debugInfo does nothing on userland classes extending + Date classes). (Derick) + +- DBA: + . Fixed OOB read on malformed length field in dba flatfile handler. (alhudz) + +- DOM: + . Fixed bug GH-22570 (Stack overflow when serializing a deeply nested + Dom\XMLDocument). (iliaal) + . Fixed Dom\DtdNamedNodeMap integer dimension access so negative indexes + return NULL and indexes outside the int range throw ValueError instead of + returning the first entity or notation. (Weilin Du) + . Fixed bug GH-22623 (use after free with namespace nodes from + XSLTProcessor::registerFunctions())/ (David Carlier) + . Fixed bug GH-22554 (use-after-free with XPath callback returning a node + from a foreign document). (David Carlier) + +- Exif: + . Fixed bug GH-11020 (exif_read_data() emits a spurious "Illegal IFD size" + warning when an IFD is not followed by a next-IFD offset). (Eyüp Can Akman) + +- GMP: + . Fixed bug GH-22549 (Assertion failure / UB on a compound GMP power or shift + assignment with a negative exponent). (iliaal) + +- Intl: + . Fixed NumberFormatter::parse() and NumberFormatter::parseCurrency() to + reject offset values outside the 32-bit range instead of silently + truncating them. (Weilin Du) + . IntlDateFormatter::parse()/datefmt_parse() and + IntlDateFormatter::localtime()/datefmt_localtime() now raise TypeError + when the offset argument is not of type int. (Weilin Du) + +- JSON: + . Report unterminated JSON strings as syntax errors. (timwolla) + . Improve performance error position tracking during JSON decoding. + (henderkes) + . Fixed bug GH-22514 (Incorrect error column in PHP 8.6 JSON parser). + (henderkes, timwolla) + +- Opcache: + . Fixed bug GH-21770 (Infinite recursion in property hook getter in opcache + preloaded trait). (iliaal) + +- OpenSSL: + . Added $salt_length parameter to openssl_sign() and openssl_verify() with + new OPENSSL_RSA_PSS_SALTLEN_* constants. (Jakub Zelenka) + . Fixed timeout for supplemental read at end of a blocking stream in SSL + stream wrapper. (ilutov) + . Fixed stream_socket_get_crypto_status() after supplemental read. (ilutov) + +- PDO_ODBC: + . Fixed bug GH-20726 (Crash with ODBC connection pooling when the DSN + carries no credentials). (iliaal) + +- PHPDBG: + . Fixed fleaked lowercased lookup keys in phpdbg_resolve_opline_break. + (jorgsowa) + . Fixed off-by-one in phpdbg_safe_class_lookup() causing class lookups to + always fail during phpdbg's signal-safe interruption path. (jorgsowa) + +- Reflection: + . Fixed bug GH-22683 (Reflection(Class)Constant::__toString() should not warn + on NAN conversions). (Khaled Alam) + . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes). + (DanielEScherzer) + +- Session: + . Fixed bug GH-21314 (Different session garbage collector behavior between + PHP 8.3 and PHP 8.5). (jorgsowa) + +- SOAP: + . Fixed bug GH-22585 (OOM on bailout with uninitialized + do_request() parameters). (David Carlier) + . Fixed xsd:hexBinary decoding to reject odd-length values instead of + silently truncating the last nibble. (Weilin Du) + . Made SOAP encoding errors report the affected type or failing operation + instead of the generic "Violation of encoding rules" message. (Weilin Du) + +- Standard: + . Fixed sleep() and usleep() to reject values that overflow the underlying + unsigned int timeout. (Weilin Du) + . Fixed bug GH-22671 (assert.bail aborts the process when the assert callback + throws an exception whose reporting re-throws). (iliaal) + . Fixed bug GH-22678 (Use-after-free in array_multisort() when the comparator + mutates the array being sorted). (azchin, iliaal) + +- Streams: + . Fixed bug GH-21468 (Segfault in file_get_contents w/ a https URL + and a proxy set). (CVE-2026-12184) (ndossche) + +- URI: + . Fixed bug GH-22628 (Percent-encoding of caret in WHATWG URL paths is not + performed). (kocsismate) + . Fixed bug GH-22629 (WHATWG Validation error incorrect with empty host and + non-empty userinfo). (kocsismate) + +- Zip: + . Fixed bug GH-22649 (ZipArchive::setCommentName() and setCommentIndex() + could crash after overwriting an entry and resetting its inherited + unchanged comment). (Weilin Du) + . Fixed bug GH-21705 (ZipArchive::getFromIndex() ignores + ZipArchive::FL_UNCHANGED for deleted entries). (Weilin Du) + . Fixed bug GH-22176 (memory leak with ZipArchive::registerCancelBack() + is used with reference returning function during shutdown). + (David Carlier) + . ZipArchive::addGlob() and ZipArchive::addPattern() now raise a TypeError + for invalid "remove_all_path", "comp_method", "comp_flags", and + "enc_method" options instead of emitting a warning. (David Carlier) + +02 Jul 2026, PHP 8.6.0alpha1 - Core: . Added first-class callable cache to share instances for the duration of the @@ -16,39 +221,118 @@ PHP NEWS . Fixed bug GH-20174 (Assertion failure in ReflectionProperty::skipLazyInitialization after failed LazyProxy initialization). (Arnaud) + . Enabled the TAILCALL VM on Windows when compiling with Clang >= 19 x86_64. + (henderkes) + . Deprecate specifying a nullable return type for __debugInfo(). (timwolla) + . Fixed bug GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF). + (David Carlier) + . Fixed bug GH-22046 (The unserialize function can lead to segfault when + non-Serializable internal classes are serialized back with the C format). + (kocsismate) + . Fixed bug GH-22292 (AST pretty printing does not correctly handle invalid + variable names). (timwolla) + . Fixed bug GH-22291 (AST pretty printing does not correctly handle braces in + string interpolation). (timwolla) + . Fixed bug GH-22373 (AST pretty-printing drops meaningful parentheses + surrounding property access). (timwolla) + . Fixed GH-22422 (zend_arena layout mismatch leaked memory in separately + built extensions under AddressSanitizer). (iliaal) + . TSRM: use local-exec TLS in PIE executables. (henderkes) + . perf: make all static extensions use TSRMG_STATIC. (henderkes) + . Fixed bug GH-22257 (type confusion in Exception::getTraceAsString()). + (David Carlier) + . TSRM: make CG, EG, SCNG and AG compile-time offsets. (henderkes) + . Deprecate returning values from __construct() and __destruct(). (timwolla) + +- BCMath: + . Added NUL-byte validation to BCMath functions. (jorgsowa) + +- BZ2: + . Reject oversized input in bzdecompress(). (arshidkv12) + +- Curl: + . Add support for CURLINFO_SIZE_DELIVERED (libcurl >= 8.20.0). (Ayesh) - Date: . Update timelib to 2022.16. (Derick) - DOM: - . Removed LIBXML_XINCLUDE from valid options for XMLDocument, - as it was a no-op. (ndossche) + . Removed LIBXML_XINCLUDE from valid options for XMLDocument, as it was a + no-op. (ndossche) + . Readonly DOM properties are now declared with asymmetric visibility + (public private(set)). ReflectionProperty::isWritable() reports them + correctly, and external writes raise "Cannot modify private(set) + property" instead of the previous readonly modification error. + (David Carlier) + . Fixed Dom\Notation nodes missing tree connection, so that ownerDocument, + parentNode, isConnected and baseURI now return correct values, and + textContent returns NULL per the DOM specification. (jordikroon) + +- EXIF: + . Added support for reading EXIF metadata from WebP images (GH-19904). + (iliaal) - Fileinfo: . Fixed bug GH-20679 (finfo_file() doesn't work on remote resources). (ndossche) + . Fixed bug #66095 (Hide libmagic dynamic symbols). (orlitzky) + +- GD: + . imagesetstyle()/imagefilter()/imagecrop() check array argument entries + types. (David Carlier) + +- GMP: + . gmp_fact() reject values larger than unsigned long. (David Carlier) + . gmp_pow/binomial/root/rootrem and shift/pow operators reject values larger + than unsigned long. (David Carlier) + . GMP exponentiation and shift operators now emit a deprecation warning + when converting a float right operand to int loses precision. (Weilin Du) - Hash: . Upgrade xxHash to 0.8.2. (timwolla) - Intl: + . Fixed malformed ResourceBundle::get() error message when fallback is + disabled. (Weilin Du) + . Added Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue(), + with the alias of locale_get_display_keyword() and + locale_get_display_keyword_value() respectively. (Weilin Du) + . Fix incorrect argument positions for invalid start/end arguments in + transliterator_transliterate(). (Weilin Du) + . Fixed IntlTimeZone::getDisplayName() to synchronize object error state + for invalid display types. (Weilin Du) + . Fixed Locale::lookup() and locale_lookup() to return NULL instead of the + fallback locale when a language tag cannot be canonicalized. (Weilin Du) . Added IntlNumberRangeFormatter class to format an interval of two numbers with a given skeleton, locale, collapse type and identity fallback. (BogdanUngureanu) . Fixed bug GH-20426 (Spoofchecker::setRestrictionLevel() error message suggests missing constants). (DanielEScherzer) . Added grapheme_strrev (Yuya Hamada) + . Passing a non-stringable object as a time zone to Intl time zone + argument handling now raises TypeError instead of Error. (Weilin Du) + . IntlBreakIterator::getLocale() now raises ValueError for invalid locale + types. (Weilin Du) + . Fixed MessageFormatter::parse() and parseMessage() returning PHP_INT_MIN + as float rather than int on 64-bit platforms. (Weilin Du) + . Fixed UConverter::transcode() silently truncating from_subst and to_subst + option lengths greater than 127 bytes. (Weilin Du) + . Fixed IntlIterator::current() to return NULL instead of an undefined value + when the iterator is not positioned on a valid element. (Weilin Du) + +- IO: + . Added new polling API. (Jakub Zelenka) - JSON: . Enriched JSON last error / exception message with error location. (Juan Morales) - Fibers: - . Fixed bug GH-20483 (ASAN stack overflow with fiber.stack_size INI - small value). (David Carlier) + . Fixed bug GH-20483 (ASAN stack overflow with fiber.stack_size INI small + value). (David Carlier) - Mail: - . Fixed bug GH-20862 (null pointer dereference in + . Fixed bug GH-20862 (null pointer dereference in php_mail_detect_multiple_crlf via error_log (jordikroon) - Mbstring: @@ -59,32 +343,63 @@ PHP NEWS recursive array references). (alexandre-daubois) . Fixed bug GH-21223; mb_guess_encoding no longer crashes when passed huge list of candidate encodings (with 200,000+ entries). (Jordi Kroon) + . mbregex has been deprecated. (youkidearitai) + +- Mysqli: + . Added mysqli_quote_string() and mysqli::quote_string(). (Kamil Tekiela) - Opcache: . Fixed bug GH-20051 (apache2 shutdowns when restart is requested during preloading). (Arnaud, welcomycozyhom) - OpenSSL: + . Added AES-SIV support. (jordikroon) . Implemented GH-20310 (No critical extension indication in openssl_x509_parse() output). (StephenWall) + . Added TLS session resumption support for streams with new context options + and Openssl\Session class. (Jakub Zelenka) + . Added TLS external PSK support for streams with new context options and + Openssl\Psk class. (Jakub Zelenka) + . Added stream crypto status for exposing OpenSSL WANT_READ / WANT_WRITE. + (Jakub Zelenka) + +- PCNTL: + . pcntl_exec() now throws a ValueError if the $args array is not a list + array. (Weilin Du) + +- PDO_DBLIB: + . Added dblib_handle_check_liveness handler. (freddy77) - PDO_PGSQL: . Clear session-local state disconnect-equivalent processing. (KentarouTakeda) - PGSQL: - . Enabled 64 bits support for pg_lo_truncate()/pg_lo_tell() - if the server supports it. (KentarouTakeda) + . Enabled 64 bits support for pg_lo_truncate()/pg_lo_tell() if the server + supports it. (KentarouTakeda) + . pg_fetch_object() now surfaces non-instantiable class errors before + fetching, resolves the constructor via the get_constructor handler, and + reports the empty-constructor ValueError on the $constructor_args argument. + (David Carlier) - Phar: . Support reference values in Phar::mungServer(). (ndossche) . Invalid values now throw in Phar::mungServer() instead of being silently ignored. (ndossche) + . Fixed a bypass of the magic ".phar" directory protection in + Phar::addEmptyDir() for paths starting with "/.phar". (Weilin Du) + . Fixed an integer underflow when parsing ZIP extra fields. (Weilin Du) + . Phar::addEmptyDir() now allows non-magic directory names that merely + share the ".phar" prefix. (Weilin Du) . Support overridden methods in SplFileInfo for getMTime() and getPathname() when building a phar. (ndossche) . Mark Phar::buildFromIterator() base directory argument as a path. (ndossche) +- phpdbg: + . Fixed GH-22480 (Use-after-free when re-watching an already-watched + variable). (iliaal) + - Posix: . Added validity check to the flags argument for posix_access(). (arshidkv12) @@ -92,18 +407,37 @@ PHP NEWS . Fixed bug GH-20217 (ReflectionClass::isIterable() incorrectly returns true for classes with property hooks). (alexandre-daubois) . Added ReflectionConstant::inNamespace(). (Khaled Alam) - . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). - (ilutov) + . Added ReflectionProperty::isReadable() and ::isWritable(). (ilutov) . Fixed bug GH-21362 (ReflectionMethod::invoke/invokeArgs() did not verify Closure instance identity for Closure::__invoke()). (Ilia Alshanetsky) + . Added ReflectionParameter::getDocComment(). (chschneider) - Session: . Fixed bug 71162 (updateTimestamp never called when session data is empty). (Girgias) + . Null bytes in session.cookie_path, session.cookie_domain, and + session.cache_limiter are now rejected with a warning. (jorgsowa) + . session.cookie_samesite now rejects invalid values with a warning; only + "Strict", "Lax", "None", or "" are accepted. (jorgsowa) + . session.cookie_lifetime now rejects non-integer and out-of-range values + with a warning. (jorgsowa) + . Session file GC now recursively cleans nested subdirectories when + session.save_path uses the dirdepth prefix. (jorgsowa) + . Changed defaults of session.use_strict_mode (now 1), session.cookie_httponly + (now 1) and session.cookie_samesite (now "Lax"). (jorgsowa) + +- Shmop: + . Fixed bug GH-9945 (shmop_open() silently truncates keys outside the key_t + range). (Weilin Du) - Soap: . Soap::__setCookie() when cookie name is a digit is now not stored and represented as a string anymore but a int. (David Carlier) + . Fixed bug GH-21421 (SoapClient typemap property breaks engine assumptions). + (ndossche) + . WSDL/XML Schema parsing now rejects out-of-range integer values for + occurrence constraints and integer restriction facets. Negative minOccurs + and maxOccurs values are rejected as well. (Weilin Du) - Sockets: . Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in @@ -112,13 +446,27 @@ PHP NEWS AF_INET* family only. (David Carlier) . Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new optional parameter). (David Carlier) + . Added AF_PACKET support completion for socket_sendto()/socket_recvfrom(). + (David Carlier) - Sodium: . Added support for libsodium 1.0.21 IPcrypt and XOF APIs. (jedisct1) + . pwhash argument-validation errors now throw ValueError instead of + SodiumException. (iliaal) - SPL: . DirectoryIterator key can now work better with filesystem supporting larger directory indexing. (David Carlier) + . Fixed bug GH-21831 (SplObjectStorage::removeAllExcept() use-after-free with + re-entrant getHash()). (Pratik Bhujel) + . Fix bugs GH-8561, GH-8562, GH-8563, and GH-8564 (Fixing various + SplFileObject iterator desync bugs). (iliaal) + . Fix bug GH-22062 (SplDoublyLinkedList iterator UAF via destructor releasing + next node). (David Carlier) + +- Sysvshm: + . Fixed shm_attach() to throw ValueError for keys outside the key_t range. + (Weilin Du) - Sqlite3: . Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche) @@ -134,19 +482,63 @@ PHP NEWS null destination). (David Carlier) . Fixed bug GH-13204 (glob() fails if square bracket is in current directory). (ndossche) + . Add array size maximum to array_diff(). (ndossche) + . Add enum SortDirection. (timwolla) + . pathinfo() raises a ValueError with an invalid $flags argument. + (David Carlier) + . Passing an invalid flag value to the second argument of scandir() will now + throw a ValueError. (alexandre-daubois) + . array_change_key_case() now raises a ValueError when an invalid $case + argument value is passed. (Girgias) + . linkinfo() now raises a ValueError when the argument is an empty string. + (Weilin Du) + . getenv() and putenv() now raises a ValueError when the first argument + contains NUL bytes. (Weilin Du) + . dl() now raises a ValueError when the $extension_filename argument contains + NUL bytes. (Weilin Du) + . openlog() now raises a ValueError when the $prefix argument contains NUL + bytes. (Weilin Du) + . parse_str() now raises a ValueError when the $string argument contains NUL + bytes. (Weilin Du) + . proc_open() now raises a ValueError when the $cwd argument contains NUL + bytes. (Weilin Du) + . ini_get_all() now includes the built-in default value in the details. + (sebastian) + . Fixed bug GH-22171 (Invalid auth header generation in http(s) stream + wrapper). (David Carlier) + . Fixed bug GH-17384 (number_format() may exhaust memory with decimals + outside the range from -2147483648 to 2147483647). (Weilin Du) - Streams: + . Added new stream errors API including new StreamException, StreamError + classes, StreamErrorStore, StreamErrorMode, StreamErrorCode enums, + stream_last_errors() and stream_clear_errors() functions, error_mode, + error_store and error_handler stream context options and extending some + stream functions with context param. (Jakub Zelenka) . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream - socket context options. + socket context options. (Jakub Zelenka) . Added so_reuseaddr streams context socket option that allows disabling - address resuse. + address reuse. (Jakub Zelenka) . Fixed bug GH-20370 (User stream filters could violate typed property constraints). (alexandre-daubois) . Allowed filtered streams to be casted as fd for select. (Jakub Zelenka) . Fixed bug GH-21221 (Prevent closing of innerstream of php://temp stream). (ilutov) + . Improved stream_socket_server() bind failure error reporting. (ilutov) + . Fixed bug #49874 (ftell() and fseek() inconsistency when using stream + filters). (Jakub Zelenka) + +- URI: + . Added Uri\Rfc3986\Uri::getUriType() and Uri\WhatWg\Url::isSpecialScheme(). + (kocsismate) + . Added Uri\Rfc3986\Uri::getHostType() and Uri\WhatWg\Url::getHostType(). + (kocsismate) + . Added Uri\Rfc3986\UriBuilder. (kocsismate) - Zip: + . Fixed bug GH-21682 (ZipArchive instances should not be serializable). + serialize()/unserialize() now throw unless a subclass overrides + __serialize()/__unserialize(). (iliaal) . Fixed ZipArchive callback being called after executor has shut down. (ilutov) . Support minimum version for libzip dependency updated to 1.0.0. @@ -154,4 +546,11 @@ PHP NEWS . Added ZipArchive::openString() method. (Tim Starling, Soner Sayakci, Ghaith Olabi) +- Zlib: + . deflate_init() now raises a TypeError when the value for option + "level", "memory", "window", or "strategy" is not of type int. + (Weilin Du) + . inflate_init() now raises a TypeError when the value for option + "window" is not of type int. (Weilin Du) + <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/README.md b/README.md index 9a058bb942e2..d83203d74c0b 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ PHP is a popular general-purpose scripting language that is especially suited to web development. Fast, flexible and pragmatic, PHP powers everything from your -blog to the most popular websites in the world. PHP is distributed under the -[PHP License v3.01](LICENSE). +blog to the most popular websites in the world. -[![Push](https://github.com/php/php-src/actions/workflows/push.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/push.yml) +PHP is distributed under the [Modified BSD License](LICENSE) +(SPDX-License-Identifier: `BSD-3-Clause`). + +[![Test](https://github.com/php/php-src/actions/workflows/test.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/test.yml) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://issues.oss-fuzz.com/issues?q=project:php) ## Documentation @@ -128,8 +130,10 @@ permissions. ## PHP extensions Extensions provide additional functionality on top of PHP. PHP consists of many -essential bundled extensions. Additional extensions can be found in the PHP -Extension Community Library - [PECL](https://pecl.php.net). +essential bundled extensions. Additional extensions can be found on the +[PIE Extensions](https://packagist.org/extensions) list, and installed with +[🥧 PIE, the PHP Installer for Extensions](https://github.com/php/pie) or the +deprecated PHP Extension Community Library - [PECL](https://pecl.php.net). ## Contributing diff --git a/SECURITY.md b/SECURITY.md index deb5a7a950a4..24801b3b4e43 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,6 +11,31 @@ Vulnerability reports remain private until published. When published, you will be credited as a contributor, and your contribution will reflect the MITRE Credit System. +# Classification + +Issues commonly reported that are _not_ considered security issues include (but +are not limited to): + +- Invocation of specially crafted, malicious code intended to cause memory + violations. This commonly includes malicious error handlers, destructors or + `__toString()` functions. PHP does not offer sandboxing, and the execution of + untrusted code is always considered unsafe. Such issues are bugs, but not + security issues. They may still be reported, though please avoid reporting + the known issues. + +- Passing malicious arguments to functions clearly not intended to receive + unsanitized values, e.g. `mysqli_query()`. `escapeshellarg()` on the other + hand should clearly be hardened against unsafe inputs. + +- The use of legacy APIs or settings known to be insecure, particularly those + documented as such, or those with a secure alternative. + +- The use of FFI. + +- `open_basedir` or `disable_functions` bypasses. + +- Malicious `unserialize()` inputs. + # Vulnerability Policy Our full policy is described at diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index e99993204b6f..a5032e456aae 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -36,12 +36,13 @@ struct _tsrm_tls_entry { tsrm_tls_entry *next; }; - typedef struct { size_t size; ts_allocate_ctor ctor; ts_allocate_dtor dtor; - size_t fast_offset; + ptrdiff_t fast_offset; + /* When set, storage comes from __thread memory instead of being allocated by TSRM. */ + void *(*tls_addr)(void); int done; } tsrm_resource_type; @@ -58,6 +59,7 @@ static int resource_types_table_size; /* Reserved space for fast globals access */ static size_t tsrm_reserved_pos = 0; static size_t tsrm_reserved_size = 0; +static size_t tsrm_reserved_front = 0; static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */ static MUTEX_T tsrm_env_mutex; /* tsrm environ mutex */ @@ -155,6 +157,7 @@ TSRM_API bool tsrm_startup(int expected_threads, int expected_resources, int deb tsrm_reserved_pos = 0; tsrm_reserved_size = 0; + tsrm_reserved_front = 0; tsrm_env_mutex = tsrm_mutex_alloc(); @@ -163,14 +166,20 @@ TSRM_API bool tsrm_startup(int expected_threads, int expected_resources, int deb static void ts_free_resources(tsrm_tls_entry *thread_resources) { + bool own_thread = thread_resources->thread_id == tsrm_thread_id(); + /* Need to destroy in reverse order to respect dependencies. */ for (int i = thread_resources->count - 1; i >= 0; i--) { if (!resource_types_table[i].done) { + /* A __thread block of a foreign thread is inaccessible. */ + if (resource_types_table[i].tls_addr && !own_thread) { + continue; + } if (resource_types_table[i].dtor) { resource_types_table[i].dtor(thread_resources->storage[i]); } - if (!resource_types_table[i].fast_offset) { + if (!resource_types_table[i].fast_offset && !resource_types_table[i].tls_addr) { free(thread_resources->storage[i]); } } @@ -179,7 +188,9 @@ static void ts_free_resources(tsrm_tls_entry *thread_resources) free(thread_resources->storage); } -/* Shutdown TSRM (call once for the entire process) */ +/* Shutdown TSRM (call once for the entire process). Tears down every thread left + * in the table. For resources allocated with ts_allocate_tls_id(), only the dtor + * of the calling thread is invoked. */ TSRM_API void tsrm_shutdown(void) {/*{{{*/ if (is_thread_shutdown) { @@ -205,7 +216,7 @@ TSRM_API void tsrm_shutdown(void) } else { free(p->storage); } - free(p); + free((char *) p - tsrm_reserved_front); p = next_p; } } @@ -232,6 +243,7 @@ TSRM_API void tsrm_shutdown(void) tsrm_reserved_pos = 0; tsrm_reserved_size = 0; + tsrm_reserved_front = 0; }/*}}}*/ /* {{{ */ @@ -256,7 +268,10 @@ static void tsrm_update_active_threads(void) p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count); for (j=p->count; jthread_id == tsrm_thread_id()); + p->storage[j] = resource_types_table[j].tls_addr(); + } else if (resource_types_table[j].fast_offset) { p->storage[j] = (void *) (((char*)p) + resource_types_table[j].fast_offset); } else { p->storage[j] = (void *) malloc(resource_types_table[j].size); @@ -301,6 +316,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = 0; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].tls_addr = NULL; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0; tsrm_update_active_threads(); @@ -319,17 +335,20 @@ TSRM_API void tsrm_reserve(size_t size) }/*}}}*/ +/* Carve a fixed-offset front region out of the reserved space. It is placed + * before the TLS entry, so the hot globals get compile-time-constant negative + * offsets from the cache pointer. */ +TSRM_API void tsrm_reserve_fast_front(size_t size) +{ + tsrm_reserved_front = TSRM_ALIGNED_SIZE(size); + tsrm_reserved_size -= tsrm_reserved_front; +} + + /* allocates a new fast thread-safe-resource id */ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) {/*{{{*/ - TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new fast resource id, %d bytes", size)); - tsrm_mutex_lock(tsmm_mutex); - - /* obtain a resource id */ - *rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++); - TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id)); - size = TSRM_ALIGNED_SIZE(size); if (tsrm_reserved_size - tsrm_reserved_pos < size) { TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate space for fast resource")); @@ -338,9 +357,26 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz tsrm_mutex_unlock(tsmm_mutex); return 0; } - - *offset = TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_pos; + ptrdiff_t fixed_offset = TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_pos; tsrm_reserved_pos += size; + tsrm_mutex_unlock(tsmm_mutex); + + return ts_allocate_fast_id_at(rsrc_id, offset, fixed_offset, size, ctor, dtor); +}/*}}}*/ + + +TSRM_API ts_rsrc_id ts_allocate_fast_id_at(ts_rsrc_id *rsrc_id, size_t *offset, ptrdiff_t fixed_offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) +{ + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new fast resource id, %d bytes", size)); + + tsrm_mutex_lock(tsmm_mutex); + + /* obtain a resource id */ + *rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++); + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id)); + + size = TSRM_ALIGNED_SIZE(size); + *offset = (size_t) fixed_offset; /* store the new resource type in the resource sizes table */ if (resource_types_table_size < id_count) { @@ -359,6 +395,7 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = *offset; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].tls_addr = NULL; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0; tsrm_update_active_threads(); @@ -366,7 +403,42 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id)); return *rsrc_id; -}/*}}}*/ +} + +/* allocates a resource id whose per-thread storage is a native __thread block */ +TSRM_API ts_rsrc_id ts_allocate_tls_id(ts_rsrc_id *rsrc_id, void *(*tls_addr)(void), size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) +{ + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new TLS resource id, %d bytes", size)); + + tsrm_mutex_lock(tsmm_mutex); + + *rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++); + + if (resource_types_table_size < id_count) { + tsrm_resource_type *_tmp; + _tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count); + if (!_tmp) { + TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource")); + *rsrc_id = 0; + tsrm_mutex_unlock(tsmm_mutex); + return 0; + } + resource_types_table = _tmp; + resource_types_table_size = id_count; + } + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = 0; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].tls_addr = tls_addr; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0; + + tsrm_update_active_threads(); + tsrm_mutex_unlock(tsmm_mutex); + + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new TLS resource id %d", *rsrc_id)); + return *rsrc_id; +} static void set_thread_local_storage_resource_to(tsrm_tls_entry *thread_resource) { @@ -378,7 +450,10 @@ static void set_thread_local_storage_resource_to(tsrm_tls_entry *thread_resource static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id) {/*{{{*/ TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id)); - (*thread_resources_ptr) = (tsrm_tls_entry *) malloc(TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_size); + /* The entry follows the fixed-offset front region. + * hot globals live at negative offsets from the TLS cache pointer. */ + char *block = (char *) malloc(tsrm_reserved_front + TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_size); + (*thread_resources_ptr) = (tsrm_tls_entry *) (block + tsrm_reserved_front); (*thread_resources_ptr)->storage = NULL; if (id_count > 0) { (*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count); @@ -397,7 +472,9 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_ if (resource_types_table[i].done) { (*thread_resources_ptr)->storage[i] = NULL; } else { - if (resource_types_table[i].fast_offset) { + if (resource_types_table[i].tls_addr) { + (*thread_resources_ptr)->storage[i] = resource_types_table[i].tls_addr(); + } else if (resource_types_table[i].fast_offset) { (*thread_resources_ptr)->storage[i] = (void *) (((char*)(*thread_resources_ptr)) + resource_types_table[i].fast_offset); } else { (*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size); @@ -485,9 +562,11 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) /* In case that extensions don't use the pointer passed from the dtor, but incorrectly * use the global pointer, we need to setup the global pointer temporarily here. */ set_thread_local_storage_resource_to(thread_resources); - /* Free up the old resource from the old thread instance */ + /* Dead thread with a recycled id: its __thread blocks are gone, and this + * thread's blocks were never constructed, so keep tls dtors from running. */ + thread_resources->thread_id = 0; ts_free_resources(thread_resources); - free(thread_resources); + free((char *) thread_resources - tsrm_reserved_front); /* Allocate a new resource at the same point in the linked list, and relink the next pointer */ allocate_new_resource(last_thread_resources, thread_id); thread_resources = *last_thread_resources; @@ -529,7 +608,7 @@ void ts_free_thread(void) tsrm_tls_table[hash_value] = thread_resources->next; } tsrm_tls_set(0); - free(thread_resources); + free((char *) thread_resources - tsrm_reserved_front); break; } if (thread_resources->next) { @@ -559,7 +638,7 @@ void ts_free_id(ts_rsrc_id id) if (resource_types_table[rsrc_id].dtor) { resource_types_table[rsrc_id].dtor(p->storage[rsrc_id]); } - if (!resource_types_table[rsrc_id].fast_offset) { + if (!resource_types_table[rsrc_id].fast_offset && !resource_types_table[rsrc_id].tls_addr) { free(p->storage[rsrc_id]); } } diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 80d6cbad0443..752ea1803f9c 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -20,6 +20,7 @@ # include
#endif +#include #include #include @@ -94,6 +95,15 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate TSRM_API void tsrm_reserve(size_t size); TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); +/* Fast resources at caller-chosen, compile-time-constant offsets. The fixed + * front region must be reserved after tsrm_reserve() and before any fast id. */ +TSRM_API void tsrm_reserve_fast_front(size_t size); +TSRM_API ts_rsrc_id ts_allocate_fast_id_at(ts_rsrc_id *rsrc_id, size_t *offset, ptrdiff_t fixed_offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); + +/* Resource whose per-thread storage is a native __thread block. + * Must be called at startup before any other thread exists. */ +TSRM_API ts_rsrc_id ts_allocate_tls_id(ts_rsrc_id *rsrc_id, void *(*tls_addr)(void), size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); + /* fetches the requested resource for the current thread */ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); #define ts_resource(id) ts_resource_ex(id, NULL) @@ -155,7 +165,7 @@ TSRM_API bool tsrm_is_managed_thread(void); #if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MUSL__) || defined(__HAIKU__) # define TSRM_TLS_MODEL_ATTR # define TSRM_TLS_MODEL_DEFAULT -#elif __PIC__ +#elif defined(__PIC__) && !defined(__PIE__) # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec"))) # define TSRM_TLS_MODEL_INITIAL_EXEC #else @@ -175,9 +185,14 @@ TSRM_API bool tsrm_is_managed_thread(void); #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) #define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element) #define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset))) +#ifdef __cplusplus +#define TSRMLS_MAIN_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; } +#define TSRMLS_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE; } +#else #define TSRMLS_MAIN_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; -#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE; +#endif +#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() #define TSRMLS_CACHE _tsrm_ls_cache diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index 4c8fc9d19aa9..90317ab64b19 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Daniel Beulshausen | +----------------------------------------------------------------------+ diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h index c5bdc492be1b..9c16bd7c654b 100644 --- a/TSRM/tsrm_win32.h +++ b/TSRM/tsrm_win32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Daniel Beulshausen | +----------------------------------------------------------------------+ diff --git a/UPGRADING b/UPGRADING index 113258ebbd3e..97670e09246d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -19,17 +19,104 @@ PHP 8.6 UPGRADE NOTES 1. Backward Incompatible Changes ======================================== +- Core: + . ??/empty() on a magic property no longer call __get() when __isset() + has materialised the property by writing into the property table. + The freshly-written value is returned directly. isset() is unaffected. + +- COM + . It is no longer possible to clone variant objects, this is because + the cloning behaviour was ill defined. + +- DOM: + . Properties previously documented as @readonly (e.g. DOMNode::$nodeType, + DOMDocument::$xmlEncoding, DOMEntity::$actualEncoding, ::$encoding, + ::$version) are now declared with asymmetric visibility + (public private(set)). Attempts to write to them from outside the + class now raise "Cannot modify private(set) property ::$ + from global scope" instead of the prior readonly modification error. + ReflectionProperty::isWritable() also reports these properties + accurately. + . Array access on Dom\DtdNamedNodeMap objects now returns null for negative + integer indexes instead of returning the first node. + . Array access on Dom\DtdNamedNodeMap objects now raises a ValueError when + the integer index is greater than INT_MAX instead of overflowing to a + smaller index. + +- GD: + . imagesetstyle(), imagefilter() and imagecrop() filter their array arguments + types / values and raise a TypeError / ValueError accordingly. + +- GMP: + . GMP power and shift operators now throw ValueError when GMP right operands + are outside the unsigned long range, instead of silently truncating them. + . GMP integer string parsing now throw ValueError strings containing NUL + bytes, instead of silently truncating them. + +- Intl: + . Passing a non-stringable object as a time zone to Intl APIs that accept + time zone objects or strings now raises a TypeError instead of an Error. + . IntlIterator::current() now returns null when called before the iterator is + positioned, or after the iterator becomes invalid, instead of exposing an + undefined value. + . IntlBreakIterator::getLocale() now raises a ValueError when the type is + neither Locale::ACTUAL_LOCALE nor Locale::VALID_LOCALE instead of + returning false. + . MessageFormatter::parse() and parseMessage() now return PHP_INT_MIN as + int, rather than float, on 64-bit platforms when parsing integer values. + . The $type parameter of IntlBreakIterator::getPartsIterator() has been + changed from string to int to match the underlying implementation. + . UConverter::transcode() now rejects from_subst and to_subst option values + longer than 127 bytes instead of silently truncating the length before + passing it to ICU. + . ResourceBundle::get() and resourcebundle_get() now report fallback-disabled + resource lookups with "without fallback to " instead of the + malformed "without fallback from to ". + . IntlDateFormatter::parse()/datefmt_parse() and + IntlDateFormatter::localtime()/datefmt_localtime() now raise a TypeError + when the offset argument is not of type int instead of silently converting + the value. + +- PCNTL: + . pcntl_alarm() now raises a ValueError if the seconds argument is + lower than zero or greater than platform's UINT_MAX. + . pcntl_exec() now raises a ValueError if the $args argument is not a list + array. + - PCRE: . preg_grep() now returns false instead of a partial array when a PCRE execution error occurs (e.g. malformed UTF-8 input with the /u modifier). This is consistent with other preg_* functions. - Phar: - . Invalid values now throw in Phar::mungServer() instead of being silently - ignored. + . Phar::mungServer() now raises a ValueError when an invalid argument value + is passed instead of being silently ignored. + . Phar::addEmptyDir() now rejects "/.phar" paths in addition to ".phar" + paths, and raises the same BadMethodCallException for attempts to create + the reserved magic ".phar" directory through that form. + . Phar::addEmptyDir() now treats non-magic names that merely share the + ".phar" prefix as ordinary directories. + +- PGSQL: + . pg_fetch_object() now reports the ValueError for a non-empty + $constructor_args on a class without a constructor on the + $constructor_args argument instead of $class. Errors raised when + the requested class is not instantiable (abstract, interface, enum) + now surface before the row is fetched. + +- Posix: + . posix_access() now raises a ValueError when an invalid $flags + argument value is passed. + . posix_mkfifo() now raises a ValueError when an invalid $permissions + argument value is passed. - Session: - . A ValueError is not thrown if $name is a string containing null bytes in + . Setting session.cookie_path, session.cookie_domain, or session.cache_limiter + to a value containing NUL bytes now emits a warning and leaves the setting + unchanged. Previously, NUL bytes were silently accepted: for cookie_path + and cookie_domain this caused the SAPI to drop the Set-Cookie header; for + cache_limiter the value was silently truncated at the NUL byte. + . A ValueError is not thrown if $name is a string containing NUL bytes in session_module_name(). . session_encode() now returns an empty string instead of false for empty sessions. It only returns false now when the session data could not be @@ -43,12 +130,110 @@ PHP 8.6 UPGRADE NOTES comparison. Custom session handlers that rely on write() being called with empty data (e.g. to destroy the session) should implement the same logic in their updateTimestamp() method. + . The defaults of three session INI settings have changed to provide secure + behavior out of the box: + - session.use_strict_mode is now 1 (was 0). Strict mode rejects + uninitialized session IDs, mitigating session fixation. Custom session + handlers that previously relied on accepting externally supplied IDs + without a corresponding storage entry must either implement + validateId() / create_sid() or explicitly set this to 0. + - session.cookie_httponly is now 1 (was 0). Session cookies are no + longer accessible to JavaScript via document.cookie. Applications + that read the session cookie from JavaScript must explicitly set + this to 0. + - session.cookie_samesite is now "Lax" (was unset). Session cookies + are no longer sent on cross-site requests other than top-level + navigations using safe HTTP methods. Applications that depend on + session cookies being sent on cross-site POST submissions must + explicitly set this to "None" (and also set session.cookie_secure + to 1). + RFC: https://wiki.php.net/rfc/session_security_defaults + +- Shmop: + . shmop_open() now raises a ValueError when the $key argument is outside the + platform's key_t range instead of passing a truncated key to the operating + system. + +- SOAP: + . WSDL/XML Schema parsing now rejects out-of-range integer values for + occurrence constraints and integer restriction facets. Negative minOccurs + and maxOccurs values are rejected as well. + . SOAP encoding errors now report the affected type or failing operation in + the error message instead of the generic "Encoding: Violation of encoding + rules" message. Code that compares the exact message may need to be + updated. + +- Sodium: + . The password-hashing functions sodium_crypto_pwhash(), + sodium_crypto_pwhash_str(), + sodium_crypto_pwhash_scryptsalsa208sha256() and + sodium_crypto_pwhash_scryptsalsa208sha256_str() now throw ValueError + instead of SodiumException when an argument is out of range, such as an + opslimit or memlimit below the documented minimum. SodiumException is + still thrown for internal libsodium failures. + +- SPL: + . SplObjectStorage::getHash() implementations may no longer mutate any + SplObjectStorage instance. Attempting to do so now throws an Error. + . SplFileObject::next() now advances the stream when no prior current() + call has cached a line. A subsequent current() call returns the new line + rather than the previous one. + . SplFileObject::fgets() no longer caches the returned line for subsequent + current() calls. current() now re-reads from the current stream position + instead of returning the line fgets() just returned. + . SplFileObject::next() past EOF no longer increments key() without bound. + SplFileObject::seek() past EOF now produces the same key() value as + SplTempFileObject; the two previously returned different values. - Standard: - . Invalid mode values now throw in array_filter() instead of being silently - defaulted to 0. . Form feed (\f) is now added in the default trimmed characters of trim(), - rtrim() and ltrim(). RFC: https://wiki.php.net/rfc/trim_form_feed + rtrim() and ltrim(). + RFC: https://wiki.php.net/rfc/trim_form_feed + . array_filter() now raises a ValueError when an invalid $mode argument value + is passed. + . array_change_key_case() now raises a ValueError when an invalid $case + argument value is passed. + . getenv() and putenv() now raises a ValueError when the first argument + contains NUL bytes. + . dl() now raises a ValueError when the $extension_filename argument contains + NUL bytes. + . openlog() now raises a ValueError when the $prefix argument contains NUL + bytes. + . parse_str() now raises a ValueError when the $string argument contains NUL + bytes. + . linkinfo() now raises a ValueError when the $path argument is empty. + . pathinfo() now raises a ValueError when an invalid $flag argument value is + passed. + . scandir() now raises a ValueError when an invalid $sorting_order argument + value is passed. + . number_format() now raises a ValueError when $decimals is outside the + integer range instead of silently clamping very large positive values. + . sleep() now raises a ValueError when $seconds is greater than the platform + limit (UINT_MAX seconds, or UINT_MAX / 1000 seconds on Windows) instead of + allowing the value to overflow. + . usleep() now raises a ValueError when $microseconds is greater than + UINT_MAX instead of allowing the value to overflow. + . proc_open() now raises a ValueError when the $cwd argument contains NUL + bytes. + +- Sysvshm: + . shm_attach() now raises a ValueError when the $key argument is outside the + platform's key_t range instead of passing a truncated key to the operating + system. + +- Zip: + . ZipArchive::extractTo now raises a TypeError for the files argument if one + or more of the entries is not a string. + . ZipArchive::addGlob() and ZipArchive::addPattern() now raise a TypeError + when the "remove_all_path" option is not of type bool, or when the + "comp_method", "comp_flags", or "enc_method" options are not of type int + (numeric strings are coerced), instead of emitting a warning. + +- Zlib: + . deflate_init() now raises a TypeError when the value for option "level", + "memory", "window", or "strategy" is not of type int. + . inflate_init() now raises a TypeError when the value for option "window" is + not of type int. ======================================== 2. New Features @@ -57,11 +242,34 @@ PHP 8.6 UPGRADE NOTES - Core: . It is now possible to use reference assign on WeakMap without the key needing to be present beforehand. + . It is now possible to define the __debugInfo() magic method on enums. + RFC: https://wiki.php.net/rfc/debugable-enums + . #[\Override] can now be applied to class constants, including enum cases. + RFC: https://wiki.php.net/rfc/override_constants + . Implemented partial function application + RFC: https://wiki.php.net/rfc/partial_function_application_v2 + +- Curl: + . curl_getinfo() return array now includes a new size_delivered key, which + indicates the total number of bytes passed to the download write callback. + This value can also be obtained by passing CURLINFO_SIZE_DELIVERED as the + $option parameter. + Requires libcurl 8.20.0 or later. + . Added CURLOPT_SEEKFUNCTION to register a callback that repositions a + streamed request body so libcurl can rewind and resend it on a redirect, + multi-pass authentication, or a retried reused connection instead of + failing with CURLE_SEND_FAIL_REWIND. The callback receives the CurlHandle, + offset and origin, and must return one of CURL_SEEKFUNC_OK, + CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK. - Fileinfo: . finfo_file() now works with remote streams. - Intl: + . Added Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue(), + with the alias of locale_get_display_keyword() and + locale_get_display_keyword_value() respectively. + RFC: https://wiki.php.net/rfc/getdisplaykeyword_and_getdisplaykeywordvalue . Added IntlNumberRangeFormatter class to format an interval of two numbers with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, @@ -73,16 +281,35 @@ PHP 8.6 UPGRADE NOTES IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE identity fallbacks. It is supported from icu 63. +- IO: + . Added new polling API. + RFC: https://wiki.php.net/rfc/poll_api + - JSON: . Added extra info about error location to the JSON error messages returned from json_last_error_msg() and JsonException message. +- OpenSSL: + . Added TLS session resumption support for streams with new stream context + options: session_data, session_new_cb, session_cache, session_cache_size, + session_timeout, session_id_context, session_get_cb, session_remove_cb, + and num_tickets. This allows saving and restoring client sessions across + requests, implementing custom server-side session storage, and controlling + session cache behavior. + RFC: https://wiki.php.net/rfc/tls_session_resumption + . Added TLS external PSK support for streams with new strem context options: + psk_client_cb and psk_server_cb. This allows setting and receiving PSK. + - Phar: . Overriding the getMTime() and getPathname() methods of SplFileInfo now influences the result of the phar buildFrom family of functions. This makes it possible to override the timestamp and names of files. - Streams: + . Added new stream errors API including new classes, enums, functions and + internal API. It is controlled using error_mode, error_store and + error_handler stream context options. + RFC: https://wiki.php.net/rfc/stream_errors . Added stream socket context option so_reuseaddr that allows disabling address reuse (SO_REUSEADDR) and explicitly uses SO_EXCLUSIVEADDRUSE on Windows. @@ -90,77 +317,178 @@ PHP 8.6 UPGRADE NOTES tcp_keepintvl and tcp_keepcnt that allow setting socket keepalive options. . Allowed casting casting filtered streams as file descriptor for select. + . Added the "write_seek_mode stream" filter parameter for the bz2, iconv, + zlib, and string stream filters. This parameter must be set via an + associative array where the key is "write_seek_mode stream" and the + value is one of the following strings "preserve", "reset", or "strict". + +- URI: + . Added Uri\Rfc3986\Uri::getUriType() and Uri\WhatWg\Url::isSpecialScheme(). + RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection + . Added Uri\Rfc3986\Uri::getHostType() and Uri\WhatWg\Url::getHostType(). + RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection + . Added Uri\Rfc3986\UriBuilder. + RFC: https://wiki.php.net/rfc/uri_followup#uri_building ======================================== 3. Changes in SAPI modules ======================================== +- CLI: + . The built-in development server now accepts requests using the QUERY HTTP + method instead of returning 501 Not Implemented. + ======================================== 4. Deprecated Functionality ======================================== +- Core: + . Specifying a return type of array|null / ?array for __debugInfo() is now + deprecated. Specify array instead. + . Returning values from __construct() and __destruct() is now deprecated. + RFC: https://wiki.php.net/rfc/deprecate-return-value-from-construct + . Making __construct() and __destruct() a Generator is now deprecated. + RFC: https://wiki.php.net/rfc/deprecate-return-value-from-construct + +- GMP + . The shift (<<, >>) and exponentiation (**) operators on GMP objects now + emit a deprecation warning when converting a float right operand to int + loses precision. + +- Mbstring: + . Mbregex has been deprecated, because the underlying Oniguruma library + is no longer maintained. + RFC: https://wiki.php.net/rfc/eol-oniguruma + ======================================== 5. Changed Functions ======================================== +- GMP: + . gmp_fact() now throws a ValueError() if $num does not fit into a unsigned + long. + . gmp_pow(), gmp_binomial(), gmp_root() and gmp_rootrem() now throw a + ValueError if their second argument does not fit into an unsigned long. + . The shift (<<, >>) and exponentiation (**) operators on GMP objects now + throw a ValueError if the right operand does not fit into an unsigned long. + . gmp_powm() modulo-by-zero now raises a DivisionByZeroError whose message + includes the function name and argument index ($modulus). + - mysqli: - . The return structure of mysqli_get_charset() no longer contains - the undocumented "comment" element. The value of "charsetnr" is - now set to a constant 0 as this number was an implementation detail - that should not have been exposed to the public. + . The return structure of mysqli_get_charset() no longer contains the + undocumented "comment" element. The value of "charsetnr" is now set to a + constant 0 as this number was an implementation detail that should not have + been exposed to the public. - OpenSSL: . Output of openssl_x509_parse() contains criticalExtensions listing all critical certificate extensions. + . openssl_sign() and openssl_verify() now have an additional optional + argument $salt_length that allows controlling the RSA-PSS salt length + when OPENSSL_PKCS1_PSS_PADDING is used. It accepts an explicit length or + one of the new OPENSSL_RSA_PSS_SALTLEN_* constants. -- PCNTL: - . pcntl_alarm() now throws a ValueError if the seconds argument is - lower than zero or greater than platform's UINT_MAX. +- PDO_DBLIB: + . When using persistent connections, there is now a liveness check in the + constructor. - Phar: . Phar::mungServer() now supports reference values. -- Posix: - . posix_access() now throws a ValueError exception if the flags - argument is invalid. - . posix_mkfifo() now throws a ValueError exception if the permissions - argument is invalid. - - Sockets: . socket_addrinfo_lookup() now has an additional optional argument $error when not null, and on failure, gives the error code (one of the EAI_* constants). -- Zip: - . ZipArchive::extractTo now raises a TypeError for the - files argument if one or more of the entries is not - a string. +- Standard: + . ini_get_all() now includes a "builtin_default_value" element for each + directive when $details is true. It holds the built-in default value of the + directive (or null if it has none), independent of values set in php.ini, + on the command line, or at runtime. ======================================== 6. New Functions ======================================== +- Intl: + . grapheme_strrev() + RFC: https://wiki.php.net/rfc/grapheme_strrev + . Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue() + RFC: https://wiki.php.net/rfc/getdisplaykeyword_and_getdisplaykeywordvalue + +- mysqli: + . Added mysqli::quote_string() and mysqli_quote_string(). + RFC: https://wiki.php.net/rfc/mysqli_quote_string + - Reflection: . ReflectionConstant::inNamespace() - . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). + . ReflectionProperty::isReadable() and ReflectionProperty::isWritable() RFC: https://wiki.php.net/rfc/isreadable-iswriteable - -- Intl: - . `grapheme_strrev()` returns strrev for grapheme cluster unit. - RFC: https://wiki.php.net/rfc/grapheme_strrev + . ReflectionParameter::getDocComment() + RFC: https://wiki.php.net/rfc/parameter-doccomments - Standard: - . `clamp()` returns the given value if in range, else return the nearest + . clamp() returns the given value if in range, else return the nearest bound. RFC: https://wiki.php.net/rfc/clamp_v2 + . stream_last_errors() and stream_clear_errors() + RFC: https://wiki.php.net/rfc/stream_errors + . stream_socket_get_crypto_status() + +- URI: + . Uri\Rfc3986\Uri::getUriType() and Uri\WhatWg\Url::isSpecialScheme() + RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection + . Uri\Rfc3986\Uri::getHostType() and Uri\WhatWg\Url::getHostType() + RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection - Zip: - . Added ZipArchive::openString() method. + . ZipArchive::openString() + . ZipArchive::closeString() ======================================== 7. New Classes and Interfaces ======================================== +- Intl: + . IntlNumberRangeFormatter + +- OpenSSL: + . Openssl\OpensslException + . Openssl\Session + RFC: https://wiki.php.net/rfc/tls_session_resumption + . Openssl\Psk + +- Standard: + . enum SortDirection + RFC: https://wiki.php.net/rfc/sort_direction_enum + . StreamError + . StreamException + . enum StreamErrorStore + . enum StreamErrorMode + . enum StreamErrorCode + RFC: https://wiki.php.net/rfc/stream_errors + . Io\Poll\Context + . Io\Poll\Watcher + . enum Io\Poll\Backend + . enum Io\Poll\Event + . interface Io\Poll\Handle + . Io\IoException + . Io\Poll\PollException + . Io\Poll\FailedPollOperationException + . Io\Poll\FailedContextInitializationException + . Io\Poll\FailedHandleAddException + . Io\Poll\FailedWatcherModificationException + . Io\Poll\FailedPollWaitException + . Io\Poll\BackendUnavailableException + . Io\Poll\InactiveWatcherException + . Io\Poll\HandleAlreadyWatchedException + . Io\Poll\InvalidHandleException + . StreamPollHandle + +- URI: + . Uri\Rfc3986\UriBuilder + RFC: https://wiki.php.net/rfc/uri_followup#uri_building + ======================================== 8. Removed Extensions and SAPIs ======================================== @@ -175,10 +503,25 @@ PHP 8.6 UPGRADE NOTES - mysqli . Added new constant MYSQLI_OPT_COMPRESS. +- Opcache + . JIT is now supported for ZTS builds on Apple Silicon. + ======================================== 10. New Global Constants ======================================== +- Curl: + . CURLINFO_SIZE_DELIVERED (libcurl >= 8.20.0). + . CURLOPT_SEEKFUNCTION. + . CURL_SEEKFUNC_OK. + . CURL_SEEKFUNC_FAIL. + . CURL_SEEKFUNC_CANTSEEK. + +- OpenSSL: + . OPENSSL_RSA_PSS_SALTLEN_DIGEST. + . OPENSSL_RSA_PSS_SALTLEN_AUTO. + . OPENSSL_RSA_PSS_SALTLEN_MAX. + - Sockets: . TCP_USER_TIMEOUT (Linux only). . AF_UNSPEC. @@ -201,12 +544,22 @@ PHP 8.6 UPGRADE NOTES . EAI_IDN_ENCODE. - Standard - . ARRAY_FILTER_USE_KEY. + . ARRAY_FILTER_USE_VALUE. + . STREAM_CRYPTO_STATUS_NONE + . STREAM_CRYPTO_STATUS_WANT_READ + . STREAM_CRYPTO_STATUS_WANT_WRITE ======================================== 11. Changes to INI File Handling ======================================== +- Mbstring: + . The mbstring.detect_order INI directive now updates the internal detection + order when changed at runtime via ini_set(). Previously, runtime changes + using ini_set() did not take effect for mb_detect_order(). Setting the + directive to NULL or an empty string at runtime now leaves the previously + configured detection order unchanged. + - Mysqli: . mysqli.default_port now checks the validity of the value which should be between 0 and 65535 included. @@ -216,13 +569,6 @@ PHP 8.6 UPGRADE NOTES When used along with ZEND_JIT_DEBUG_TRACE_EXIT_INFO, the source of exit points is printed in exit info output, in debug builds. -- Mbstring: - . The mbstring.detect_order INI directive now updates the internal detection - order when changed at runtime via ini_set(). Previously, runtime changes - using ini_set() did not take effect for mb_detect_order(). Setting the - directive to NULL or an empty string at runtime now leaves the previously - configured detection order unchanged. - ======================================== 12. Windows Support ======================================== @@ -231,12 +577,18 @@ PHP 8.6 UPGRADE NOTES 13. Other Changes ======================================== +- Core: + . In case of a hard OOM PHP now calls abort() instead of exit(1), changing + the exit code to 134 and possibly creating a core dump. + . The PHP_OS_FAMILY constant has an AIX value for when running on AIX or + IBM i via PASE. + ======================================== 14. Performance Improvements ======================================== - Core: - . `printf()` using only `%s` and `%d` will be compiled into the equivalent + . printf() using only "%s" and "%d" will be compiled into the equivalent string interpolation, avoiding the overhead of a function call and repeatedly parsing the format string. . Arguments are now passed more efficiently to known constructors (e.g. when @@ -246,20 +598,48 @@ PHP 8.6 UPGRADE NOTES creation of intermediate Closures, the overhead of calling userland callbacks from internal functions and providing for better insight for the JIT. + . The performance of the TAILCALL VM has been improved. + . The TAILCALL VM is now enabled on Windows when compiling with Clang >= 19 + x86_64. + . The performance of ZTS builds has been improved. - DOM: . Made splitText() faster and consume less memory. - JSON: . Improve performance of encoding arrays and objects. + . Improved performance of indentation generation in json_encode() + when using PHP_JSON_PRETTY_PRINT. + +- Intl: + . Improved performance of IntlCalendar::getAvailableLocales() and + IntlDateFormatter::localtime() / datefmt_localtime() by pre-allocating + their returned arrays. + . Improved performance of transliterator_list_ids() and + resourcebundle_locales() by pre-allocating their returned arrays. + +- Phar: + . Reduced temporary allocations when iterating Phar directories. - Standard: . Improved performance of array_fill_keys(). . Improved performance of array_map() with multiple arrays passed. + . Improved performance of array_sum() and array_product() for + integer-only arrays. . Improved performance of array_unshift(). . Improved performance of array_walk(). . Improved performance of intval('+0b...', 2) and intval('0b...', 2). . Improved performance of str_split(). +- URI: + . Improved performance of Uri\WhatWg\Url::parse() when collecting + validation errors by pre-allocating the error array. + . Reduced allocations when reading IPv6/IPFuture hosts and paths with + Uri\Rfc3986\Uri. + . Improved performance and memory consumption when using normalizing + (non-raw) getters on already-normalized URIs with Uri\Rfc3986\Uri. + - Zip: + . Improved performance of ZipArchive::addGlob() and + ZipArchive::addPattern() by pre-allocating their returned arrays. . Avoid string copies in ZipArchive::addFromString(). diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 57bef65c25ee..49f9e1317143 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -14,12 +14,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES 1. Internal API changes ======================== - . ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and - zend_string_starts_with_literal_ci() now support strings containing NUL - bytes. Passing non-literal char* is no longer supported. +- Removed: . The misnamed ZVAL_IS_NULL() has been removed. Use Z_ISNULL() instead. - . New zend_class_entry.ce_flags2 and zend_function.fn_flags2 fields were - added, given the primary flags were running out of bits. . The zval_is_true() alias of zend_is_true() has been removed. Call zend_is_true() directly instead. . The _zval_get_*() compatibility macros for PHP 7.2 have been removed @@ -35,35 +31,79 @@ PHP 8.6 INTERNALS UPGRADE NOTES . The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed. Call zval_ptr_dtor_nogc() directly instead. . The internal zend_copy_parameters_array() function is no longer exposed. + . The internal zend_hash_minmax() function is no longer exposed. Scan the + HashTable directly and use zend_compare() for value comparisons instead. . The zend_make_callable() function has been removed, if a callable zval needs to be obtained use the zend_get_callable_zval_from_fcc() function instead. If this was used to store a callable, then an FCC should be stored instead. - . The zend_active_function{_ex}() functions now return a const zend_function - pointer. - . The zend_get_call_trampoline_func() API now takes the __call or - __callStatic zend_function* instead of a CE and a boolean argument. + . The zend_exception_save() and zend_exception_restore() functions were + removed. . The zend_set_hash_symbol() API has been removed. - . Added zend_hash_str_lookup(). . The WRONG_PARAM_COUNT and ZEND_WRONG_PARAM_COUNT() macros have been removed. Call zend_wrong_param_count(); followed by RETURN_THROWS(); instead. . PHP_HAVE_STREAMS macro removed from . - . zend_function.arg_info is now always a zend_arg_info*. Before, it was a - zend_internal_arg_info on internal functions, unless the - ZEND_ACC_USER_ARG_INFO flag was set. - . Added zend_ast_call_get_args() to fetch the argument node from any call - node. - . The zend_exception_save() and zend_exception_restore() functions were - removed. + . The INI_STR(), INI_INT(), INI_FLT(), and INI_BOOL() macros have been + removed. Instead new zend_ini_{bool|long|double|str|string}_literal() + macros have been added. This fixes an internal naming inconsistency as + "str" usually means zend_string*, and "string" means char*. + However INI_STR() returned a char* + . The INI_ORIG_{INT|STR|FLT|BOOL}() macros have been removed as they are + unused. If this behaviour is required fall back to the zend_ini_* + functions. + . The unused ZEND_AST_PARENT_PROPERTY_HOOK_CALL has been removed. + . The EMPTY_SWITCH_DEFAULT_CASE() macro has been removed. Use + default: ZEND_UNREACHABLE(); instead. + . The ZEND_RESULT_CODE type has been removed. Use zend_result directly. + . The zend_parse_parameters_none_throw(), zend_parse_parameters_throw(), + and ZEND_PARSE_PARAMS_THROW have been removed due to being misleading, + since ZPP always throws, unless ZEND_PARSE_PARAMS_QUIET is given. Use + the non-throw versions. + . The XtOffsetOf() alias of C’s offsetof() macro has been removed. Use + offsetof() directly. + . The deprecated Z_COPYABLE(), Z_COPYABLE_P(), Z_OPT_COPYABLE(), and + Z_OPT_COPYABLE_P() macros have been removed. Check for IS_ARRAY directly. + . The deprecated Z_IMMUTABLE(), Z_IMMUTABLE_P(), Z_OPT_IMMUTABLE(), and + Z_OPT_IMMUTABLE_P() macros have been removed. Check for + IS_ARRAY && !REFCOUNTED directly. + . The unused Z_GC_*() macros have been removed. Use the corresponding + GC_*() macro on the result of Z_COUNTED(). + . The zend_binary_zval_strcmp() and zend_binary_zval_strncmp() functions + have been removed, because they are unsafe by relying on the zvals + having a specific type. Use zend_binary_strcmp() / zend_binary_strncmp(), + string_compare_function() or similar instead. + . The OPENBASEDIR_CHECKPATH() compatibility macro has been removed, instead + use php_check_open_basedir() directly. + . The Z_CONSTANT(), Z_CONSTANT_P(), Z_OPT_CONSTANT(), and + Z_OPT_CONSTANT_P() macros have been removed. Check for IS_CONSTANT_AST + directly. + . The {_}php_stream_fopen_with_path() functions have been removed as they are + unused. + . The php_error_docref1() and php_error_docref2() functions have been + removed, instead rely on the error_include_args INI option to show the + arguments to functions in a consistent manner. + +- Changed: . Internal functions that return by reference are now expected to automatically unwrap references when the result of the call is stored in an IS_TMP_VAR variable. This may be achieved by calling the zend_return_unwrap_ref() function. - . The php_math_round_mode_from_enum() function now takes a - zend_enum_RoundingMode parameter. - . Added Z_PARAM_ENUM(). - . Added zend_enum_fetch_case_id(). + . ZEND_AST_METHOD_REFERENCE has been renamed to + ZEND_AST_TRAIT_METHOD_REFERENCE. + . Functions using zend_forbid_dynamic_call() *must* be flagged with + ZEND_ACC2_FORBID_DYN_CALLS (@forbid-dynamic-calls in stubs). In debug + builds, failing to include that flag will lead to assertion failures. + . The zend_get_call_trampoline_func() API now takes the __call or + __callStatic zend_function* instead of a CE and a boolean argument. + . ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and + zend_string_starts_with_literal_ci() now support strings containing NUL + bytes. Passing non-literal char* is no longer supported. + . The zend_active_function{_ex}() functions now return a const zend_function + pointer. + . zend_function.arg_info is now always a zend_arg_info*. Before, it was a + zend_internal_arg_info on internal functions, unless the + ZEND_ACC_USER_ARG_INFO flag was set. . ZEND_INI_GET_ADDR() is now a void* pointer instead of a char* pointer. This more correctly represents the generic nature of the returned pointer and allows to remove explicit casts, but possibly breaks pointer arithmetic @@ -72,8 +112,48 @@ PHP 8.6 INTERNALS UPGRADE NOTES zend_string* parameter. . EG(in_autoload) was renamed to EG(autoload_current_classnames) and no longer is a pointer, but a directly embedded HashTable struct. + . Extended php_stream_filter_ops with seek method. + . zend_argument_error_variadic() now takes a new 'function' parameter. + . The param argument in the php_verror() function has been removed. + +- Added: + . New zend_class_entry.ce_flags2 and zend_function.fn_flags2 fields were + added, given the primary flags were running out of bits. + . Added zend_hash_str_lookup(). + . Added zend_ast_call_get_args() to fetch the argument node from any call + node. + . Added Z_PARAM_ENUM(). + . Added zend_enum_fetch_case_id(). + . Added zend_enum_get_case_by_id(). + . Added zend_bin2hex() and zend_bin2hex_str() as helper functions to remove + dependencies on /ext/hash in various extensions. . Added a C23_ENUM() helper macro to define forward-compatible fixed-size enums. + . Added zend_fcall_info.consumed_args together with + zend_fci_consumed_arg(), which allows moving a selected callback argument + instead of copying it in zend_call_function(). Currently only a single + consumed argument is supported. + . Added ZEND_CONTAINER_OF(). + . Added zend_reflection_property_set_raw_value_without_lazy_initialization(), + zend_reflection_property_set_raw_value() to expose the functionality of + ReflectionProperty::setRawValueWithoutLazyInitialization() and + ReflectionProperty::setRawValue() to C extensions. + . Added zend_argument_error_ex(), zend_argument_type_error_ex(), + zend_argument_value_error_ex(). + . Added zend_ast_dup(). + . Added zend_compile_ast(). + . Added zend_check_type_ex(). + . Added zend_create_partial_closure(). + . Added a new IO copy API in . php_io_copy() copies bytes between + file descriptors using the most efficient platform primitive available + (sendfile, splice, copy_file_range, TransmitFile), and is now used by + php_stream_copy_to_stream_ex(). The mmap-based copy fallback was removed. + . Added zend_string_equals_cstr_ci(). + . Added zend_cstr_append_char(), zend_cstr_concat(), and + zend_cstr_concat3() as helper functions to allocate NUL-terminated raw C + strings from one or more buffers. + . Added zend_string_ends_with() and related variants. + . Added trait support for internal classes. ======================== 2. Build system changes @@ -99,6 +179,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES . --with-pic is now --enable-pic. The old flag will result in an error. . Symbol HAVE_ST_BLOCKS has been removed from php_config.h (use HAVE_STRUCT_STAT_ST_BLOCKS). + . Added a new configure option --disable-apache2-conf to prevent apxs from + editing httpd.conf during installation. - Windows build system changes: . Function SETUP_OPENSSL() doesn't accept 6th argument anymore and doesn't @@ -112,6 +194,18 @@ PHP 8.6 INTERNALS UPGRADE NOTES 3. Module changes ======================== +- ext/date: + . php_idate() now returns the result state, and moves the return value into an + out parameter. + +- ext/intl: + . Added intl_icu_compat.h with helpers and feature macros for ICU + version-specific API differences. Code in ext/intl should use the + intl_icu_compat_* helpers and INTL_ICU_HAS_* macros instead of adding + direct U_ICU_VERSION_* guards for supported ICU API variants. + . The internal grapheme_get_break_iterator() helper no longer accepts a + stack buffer argument; pass only the UErrorCode* status argument. + - ext/mbstring: . Added GB18030-2022 to default encoding list for zh-CN. @@ -119,6 +213,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES . Dropped session_options parameter from all methods in mysqlnd_auth. The same information is present in conn->options and should be used instead. + . Removed charsets plugin. - ext/session: . php_session_flush() now returns a bool rather than a zend_result. @@ -142,6 +237,13 @@ PHP 8.6 INTERNALS UPGRADE NOTES . _php_error_log() now accepts zend_string* values instead of char*. . _php_error_log_ex() has been removed. . php_mail()'s extra_cmd parameter is now a zend_string*. + . The php_math_round_mode_from_enum() function now takes a + zend_enum_RoundingMode parameter. + +- ext/uri: + . The value parameter of the php_uri_property_handler_write callback is now + const zval * instead of zval *, reflecting that write handlers must + not modify the input zval. - ext/xml: . Removed the XML_ExpatVersion() libxml compatibility wrapper, @@ -160,3 +262,11 @@ PHP 8.6 INTERNALS UPGRADE NOTES ======================== 5. SAPI changes ======================== + +- SAPIs should explicitly release a thread's resources by calling + ts_free_thread() before terminating it. tsrm_shutdown() can only release the + resources of the calling thread, for resources allocated with + ts_allocate_tls_id(). + +- AG and SCNG are now allocated with ts_allocate_tls_id() and live in native + __thread storage on ZTS builds. diff --git a/Zend/LICENSE b/Zend/LICENSE deleted file mode 100644 index 51f5cccde950..000000000000 --- a/Zend/LICENSE +++ /dev/null @@ -1,56 +0,0 @@ --------------------------------------------------------------------- - The Zend Engine License, Version 2.00 -Copyright (c) 1999-2006 Zend Technologies Ltd. All rights reserved. --------------------------------------------------------------------- - -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - 3. The names "Zend" and "Zend Engine" must not be used to endorse - or promote products derived from this software without prior - permission from Zend Technologies Ltd. For written permission, - please contact license@zend.com. - - 4. Zend Technologies Ltd. may publish revised and/or new versions - of the license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the - terms of that version. You may also choose to use such covered - code under the terms of any subsequent version of the license - published by Zend Technologies Ltd. No one other than Zend - Technologies Ltd. has the right to modify the terms applicable - to covered code created under this License. - - 5. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes the Zend Engine, freely available at - http://www.zend.com" - - 6. All advertising materials mentioning features or use of this - software must display the following acknowledgment: - "The Zend Engine is freely available at http://www.zend.com" - -THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZEND -TECHNOLOGIES LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - --------------------------------------------------------------------- diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 5a0af2630391..3775f8165c3e 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -346,59 +344,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; -#if 0 - /* pre-evaluate functions: - constant(x) - function_exists(x) - extension_loaded(x) - BAD: interacts badly with Accelerator - */ - if((opline->op1_type & IS_VAR) && - VAR_SOURCE(opline->op1) && VAR_SOURCE(opline->op1)->opcode == ZEND_DO_CF_FCALL && - VAR_SOURCE(opline->op1)->extended_value == 1) { - zend_op *fcall = VAR_SOURCE(opline->op1); - zend_op *sv = fcall-1; - if(sv >= block->start_opline && sv->opcode == ZEND_SEND_VAL && - sv->op1_type == IS_CONST && Z_TYPE(OPLINE_OP1_LITERAL(sv)) == IS_STRING && - Z_LVAL(OPLINE_OP2_LITERAL(sv)) == 1 - ) { - zval *arg = &OPLINE_OP1_LITERAL(sv); - char *fname = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].function_name; - size_t flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len; - if((flen == sizeof("function_exists")-1 && zend_binary_strcasecmp(fname, flen, "function_exists", sizeof("function_exists")-1) == 0) || - (flen == sizeof("is_callable")-1 && zend_binary_strcasecmp(fname, flen, "is_callable", sizeof("is_callable")-1) == 0) - ) { - zend_function *function; - if((function = zend_hash_find_ptr(EG(function_table), Z_STR_P(arg))) != NULL) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - LITERAL_BOOL(opline->op1, 1); - opline->op1_type = IS_CONST; - } - } else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) { - zval c; - if (zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, true ELS_CC)) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - ZEND_OP1_LITERAL(opline) = zend_optimizer_add_literal(op_array, &c); - /* no copy ctor - get already copied it */ - opline->op1_type = IS_CONST; - } - } else if(flen == sizeof("extension_loaded")-1 && zend_binary_strcasecmp(fname, flen, "extension_loaded", sizeof("extension_loaded")-1) == 0) { - if(zend_hash_exists(&module_registry, Z_STR_P(arg))) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - LITERAL_BOOL(opline->op1, 1); - opline->op1_type = IS_CONST; - } - } - } - } -#endif - case ZEND_FETCH_LIST_R: case ZEND_FETCH_LIST_W: if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { @@ -703,7 +648,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } else if (opline->op1_type == IS_TMP_VAR && !zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) { src = VAR_SOURCE(opline->op1); - if (src) { + if (src && (src->op1_type != IS_VAR)) { if (src->opcode == ZEND_BOOL_NOT) { VAR_SOURCE(opline->op1) = NULL; COPY_NODE(opline->op1, src->op1); @@ -747,7 +692,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array (!zend_bitset_in(used_ext, VAR_NUM(opline->op1.var)) || opline->result.var == opline->op1.var)) { src = VAR_SOURCE(opline->op1); - if (src) { + if (src && (src->op1_type != IS_VAR)) { if (src->opcode == ZEND_BOOL || src->opcode == ZEND_QM_ASSIGN) { VAR_SOURCE(opline->op1) = NULL; @@ -1185,7 +1130,7 @@ static void assemble_code_blocks(const zend_cfg *cfg, zend_op_array *op_array, z /* rebuild map (just for printing) */ memset(cfg->map, -1, sizeof(int) * op_array->last); - for (int n = 0; n < cfg->blocks_count; n++) { + for (uint32_t n = 0; n < cfg->blocks_count; n++) { if (cfg->blocks[n].flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { cfg->map[cfg->blocks[n].start] = n; } @@ -1493,7 +1438,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr * defined. We won't apply some optimization patterns for such variables. */ static void zend_t_usage(const zend_cfg *cfg, const zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx) { - int n; + uint32_t n; zend_basic_block *block, *next_block; uint32_t var_num; uint32_t bitset_len; @@ -1697,11 +1642,10 @@ static void zend_t_usage(const zend_cfg *cfg, const zend_op_array *op_array, zen static void zend_merge_blocks(const zend_op_array *op_array, const zend_cfg *cfg, uint32_t *opt_count) { - int i; zend_basic_block *b, *bb; zend_basic_block *prev = NULL; - for (i = 0; i < cfg->blocks_count; i++) { + for (uint32_t i = 0; i < cfg->blocks_count; i++) { b = cfg->blocks + i; if (b->flags & ZEND_BB_REACHABLE) { if ((b->flags & ZEND_BB_FOLLOW) && diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c index 447a034530e1..a4ecb19c85ef 100644 --- a/Zend/Optimizer/compact_literals.c +++ b/Zend/Optimizer/compact_literals.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -735,6 +733,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_SEND_VAR_NO_REF_EX: case ZEND_SEND_REF: case ZEND_SEND_FUNC_ARG: + case ZEND_SEND_PLACEHOLDER: case ZEND_CHECK_FUNC_ARG: if (opline->op2_type == IS_CONST) { opline->result.num = cache_size; @@ -747,6 +746,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx cache_size += sizeof(void *); } break; + case ZEND_CALLABLE_CONVERT_PARTIAL: + opline->op1.num = cache_size; + cache_size += 2 * sizeof(void *); + break; } opline++; } diff --git a/Zend/Optimizer/compact_vars.c b/Zend/Optimizer/compact_vars.c index 9898714a17c5..b4a861d3595c 100644 --- a/Zend/Optimizer/compact_vars.c +++ b/Zend/Optimizer/compact_vars.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Removing unused variables | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 6c5a885fba40..0780ac190cdd 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DCE - Dead Code Elimination | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Dmitry Stogov | @@ -571,7 +569,7 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer } FOREACH_PHI_END(); /* Mark reachable instruction without side effects as dead */ - int b = ssa->cfg.blocks_count; + uint32_t b = ssa->cfg.blocks_count; while (b > 0) { int op_data = -1; diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 796e998493d7..77dc322fbdec 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -398,13 +396,13 @@ static bool variable_defined_or_used_in_range(zend_ssa *ssa, int var, int start, return false; } -int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) +static uint32_t zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) { - zend_func_info *func_info = ZEND_FUNC_INFO(op_array); - int removed_ops = 0; + const zend_func_info *func_info = ZEND_FUNC_INFO(op_array); + uint32_t removed_ops = 0; if (func_info->callee_info) { - zend_call_info *call_info = func_info->callee_info; + const zend_call_info *call_info = func_info->callee_info; do { zend_op *op = call_info->caller_init_opline; @@ -413,7 +411,6 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) || (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST)) && call_info->callee_func && zend_string_equals_literal_ci(call_info->callee_func->common.function_name, "in_array")) { - bool strict = false; bool has_opdata = op->opcode == ZEND_FRAMELESS_ICALL_3; ZEND_ASSERT(!call_info->is_prototype); @@ -428,7 +425,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) && Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) { bool ok = true; - HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant)); + const HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant)); HashTable *dst; zval *val, tmp; zend_ulong idx; @@ -479,7 +476,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) return removed_ops; } -static zend_always_inline void take_successor_0(zend_ssa *ssa, int block_num, zend_basic_block *block) +static zend_always_inline void take_successor_0(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block) { if (block->successors_count == 2) { if (block->successors[1] != block->successors[0]) { @@ -489,7 +486,7 @@ static zend_always_inline void take_successor_0(zend_ssa *ssa, int block_num, ze } } -static zend_always_inline void take_successor_1(zend_ssa *ssa, int block_num, zend_basic_block *block) +static zend_always_inline void take_successor_1(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block) { if (block->successors_count == 2) { if (block->successors[1] != block->successors[0]) { @@ -500,11 +497,9 @@ static zend_always_inline void take_successor_1(zend_ssa *ssa, int block_num, ze } } -static zend_always_inline void take_successor_ex(zend_ssa *ssa, int block_num, zend_basic_block *block, int target_block) +static zend_always_inline void take_successor_ex(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block, int target_block) { - int i; - - for (i = 0; i < block->successors_count; i++) { + for (uint32_t i = 0; i < block->successors_count; i++) { if (block->successors[i] != target_block) { zend_ssa_remove_predecessor(ssa, block_num, block->successors[i]); } @@ -531,10 +526,9 @@ static void replace_predecessor(zend_ssa *ssa, int block_id, int old_pred, int n int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset]; zend_ssa_phi *phi; - int i; int old_pred_idx = -1; int new_pred_idx = -1; - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { if (predecessors[i] == old_pred) { old_pred_idx = i; } @@ -582,10 +576,9 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa zend_basic_block *src = &ssa->cfg.blocks[from]; zend_basic_block *old = &ssa->cfg.blocks[to]; zend_basic_block *dst = &ssa->cfg.blocks[new_to]; - int i; zend_op *opline; - for (i = 0; i < src->successors_count; i++) { + for (uint32_t i = 0; i < src->successors_count; i++) { if (src->successors[i] == to) { src->successors[i] = new_to; } @@ -650,10 +643,10 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa replace_predecessor(ssa, new_to, to, from); } -static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_basic_block *block, int block_num) +static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_basic_block *block, uint32_t block_num) { if (block->predecessors_count == 1 && ssa->blocks[block_num].phis == NULL) { - int *predecessors, i; + int *predecessors; zend_basic_block *fe_fetch_block = NULL; ZEND_ASSERT(block->successors_count == 1); @@ -669,7 +662,7 @@ static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_b } } } - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { zend_ssa_replace_control_link(op_array, ssa, predecessors[i], block_num, block->successors[0]); } zend_ssa_remove_block(op_array, ssa, block_num); @@ -686,7 +679,7 @@ static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_b static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) { int removed_ops = 0; - int block_num = 0; + uint32_t block_num = 0; for (block_num = 1; block_num < ssa->cfg.blocks_count; block_num++) { zend_basic_block *block = &ssa->cfg.blocks[block_num]; @@ -706,7 +699,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) block_num++; } while (block_num < ssa->cfg.blocks_count) { - int next_block_num = block_num + 1; + uint32_t next_block_num = block_num + 1; zend_basic_block *block = &ssa->cfg.blocks[block_num]; uint32_t op_num; zend_op *opline; @@ -941,11 +934,13 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) if (block_num > 0) { zend_ssa_unlink_block(op_array, ssa, block, block_num); /* backtrack to previous basic block */ + int backtracking_block_num = block_num; do { - block_num--; - } while (block_num >= 0 - && !(ssa->cfg.blocks[block_num].flags & ZEND_BB_REACHABLE)); - if (block_num >= 0) { + backtracking_block_num--; + } while (backtracking_block_num >= 0 + && !(ssa->cfg.blocks[backtracking_block_num].flags & ZEND_BB_REACHABLE)); + if (backtracking_block_num >= 0) { + block_num = backtracking_block_num; continue; } } diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c index 00ee32984502..8dbd6855d68d 100644 --- a/Zend/Optimizer/escape_analysis.c +++ b/Zend/Optimizer/escape_analysis.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache, Escape Analysis | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -78,7 +76,7 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar zend_ssa_var *ssa_vars = ssa->vars; int ssa_vars_count = ssa->vars_count; zend_ssa_phi *p; - int i, j; + int i; int *size; ALLOCA_FLAG(use_heap) @@ -94,7 +92,7 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar if (p->pi >= 0) { union_find_unite(parent, size, i, p->sources[0]); } else { - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { union_find_unite(parent, size, i, p->sources[j]); } } diff --git a/Zend/Optimizer/nop_removal.c b/Zend/Optimizer/nop_removal.c index 7de3919ee8cb..0a6a04fc4a9b 100644 --- a/Zend/Optimizer/nop_removal.c +++ b/Zend/Optimizer/nop_removal.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/optimize_func_calls.c b/Zend/Optimizer/optimize_func_calls.c index 62b50464e87b..05cdce4fc4cf 100644 --- a/Zend/Optimizer/optimize_func_calls.c +++ b/Zend/Optimizer/optimize_func_calls.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -193,6 +191,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: call--; if (call_stack[call].func && call_stack[call].opline) { zend_op *fcall = call_stack[call].opline; @@ -225,13 +224,14 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) * At this point we also know whether or not the result of * the DO opcode is used, allowing to optimize calls to * ZEND_ACC_NODISCARD functions. */ - if (opline->opcode != ZEND_CALLABLE_CONVERT) { + if (opline->opcode != ZEND_CALLABLE_CONVERT && opline->opcode != ZEND_CALLABLE_CONVERT_PARTIAL) { opline->opcode = zend_get_call_op(fcall, call_stack[call].func, !RESULT_UNUSED(opline)); } if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level) && call_stack[call].try_inline - && opline->opcode != ZEND_CALLABLE_CONVERT) { + && opline->opcode != ZEND_CALLABLE_CONVERT + && opline->opcode != ZEND_CALLABLE_CONVERT_PARTIAL) { zend_try_inline_call(op_array, fcall, opline, call_stack[call].func); } } diff --git a/Zend/Optimizer/optimize_temp_vars_5.c b/Zend/Optimizer/optimize_temp_vars_5.c index de0b189d5dca..6a5c99f4755b 100644 --- a/Zend/Optimizer/optimize_temp_vars_5.c +++ b/Zend/Optimizer/optimize_temp_vars_5.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 4be966c25d89..962bdb6e4be3 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 5c31de7bc49c..2d2a44685226 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index 60afe3165f77..ba94e9b7b91f 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SCCP - Sparse Conditional Constant Propagation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Dmitry Stogov | @@ -1596,7 +1594,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o case ZEND_SHORT_CIRCUITING_CHAIN_EMPTY: ZVAL_TRUE(&zv); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } SET_RESULT(result, &zv); break; @@ -1832,7 +1830,7 @@ static void sccp_mark_feasible_successors( zend_op *opline, zend_ssa_op *ssa_op) { sccp_ctx *ctx = (sccp_ctx *) scdf; zval *op1, zv; - int s; + uint32_t s; /* We can't determine the branch target at compile-time for these */ switch (opline->opcode) { @@ -2049,7 +2047,6 @@ static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) { zend_basic_block *block = &ssa->cfg.blocks[phi->block]; int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset]; - int i; zval result; MAKE_TOP(&result); #if SCP_DEBUG @@ -2061,7 +2058,7 @@ static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) { join_phi_values(&result, &ctx->values[phi->sources[0]], ssa->vars[phi->ssa_var].escape_state != ESCAPE_STATE_NO_ESCAPE); } } else { - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { ZEND_ASSERT(phi->sources[i] >= 0); if (scdf_is_edge_feasible(scdf, predecessors[i], phi->block)) { #if SCP_DEBUG diff --git a/Zend/Optimizer/scdf.c b/Zend/Optimizer/scdf.c index e5c40b8c90cf..31f40a7ed9f9 100644 --- a/Zend/Optimizer/scdf.c +++ b/Zend/Optimizer/scdf.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Sparse Conditional Data Flow Propagation Framework | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -254,9 +252,8 @@ static uint32_t cleanup_loop_var_free_block(const scdf_ctx *scdf, const zend_bas * unreachable. Blocks already marked unreachable are not removed. */ uint32_t scdf_remove_unreachable_blocks(const scdf_ctx *scdf) { zend_ssa *ssa = scdf->ssa; - int i; uint32_t removed_ops = 0; - for (i = 0; i < ssa->cfg.blocks_count; i++) { + for (uint32_t i = 0; i < ssa->cfg.blocks_count; i++) { const zend_basic_block *block = &ssa->cfg.blocks[i]; if (!zend_bitset_in(scdf->executable_blocks, i) && (block->flags & ZEND_BB_REACHABLE)) { if (!kept_alive_by_loop_var_free(scdf, block)) { diff --git a/Zend/Optimizer/scdf.h b/Zend/Optimizer/scdf.h index 49222880f22b..d7bee4b73816 100644 --- a/Zend/Optimizer/scdf.h +++ b/Zend/Optimizer/scdf.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -75,11 +73,10 @@ static inline void scdf_add_def_to_worklist(const scdf_ctx *scdf, int var_num) { } } -static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, int to) { +static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, uint32_t to) { const zend_basic_block *to_block = cfg->blocks + to; - int i; - for (i = 0; i < to_block->predecessors_count; i++) { + for (uint32_t i = 0; i < to_block->predecessors_count; i++) { uint32_t edge = to_block->predecessor_offset + i; if (cfg->predecessors[edge] == from) { @@ -89,7 +86,7 @@ static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, int to) { ZEND_UNREACHABLE(); } -static inline bool scdf_is_edge_feasible(const scdf_ctx *scdf, int from, int to) { +static inline bool scdf_is_edge_feasible(const scdf_ctx *scdf, int from, uint32_t to) { uint32_t edge = scdf_edge(&scdf->ssa->cfg, from, to); return zend_bitset_in(scdf->feasible_edges, edge); } diff --git a/Zend/Optimizer/ssa_integrity.c b/Zend/Optimizer/ssa_integrity.c index 793fb1c06c8b..34a2b3a9ef64 100644 --- a/Zend/Optimizer/ssa_integrity.c +++ b/Zend/Optimizer/ssa_integrity.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA validation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -66,8 +64,8 @@ static inline bool is_in_phi_sources(zend_ssa *ssa, zend_ssa_phi *phi, int check } static inline bool is_in_predecessors(zend_cfg *cfg, zend_basic_block *block, int check) { - int i, *predecessors = &cfg->predecessors[block->predecessor_offset]; - for (i = 0; i < block->predecessors_count; i++) { + int *predecessors = &cfg->predecessors[block->predecessor_offset]; + for (uint32_t i = 0; i < block->predecessors_count; i++) { if (predecessors[i] == check) { return true; } @@ -76,8 +74,7 @@ static inline bool is_in_predecessors(zend_cfg *cfg, zend_basic_block *block, in } static inline bool is_in_successors(zend_basic_block *block, int check) { - int s; - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { if (block->successors[s] == check) { return true; } @@ -329,7 +326,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex /* Phis */ FOREACH_PHI(phi) { - unsigned num_sources = NUM_PHI_SOURCES(phi); + uint32_t num_sources = NUM_PHI_SOURCES(phi); for (i = 0; i < num_sources; i++) { int source = phi->sources[i]; if (source < 0) { @@ -360,7 +357,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex for (i = 0; i < cfg->blocks_count; i++) { zend_basic_block *block = &cfg->blocks[i]; int *predecessors = &cfg->predecessors[block->predecessor_offset]; - int s, j; + uint32_t j; if (i != 0 && block->start < (block-1)->start + (block-1)->len) { FAIL("Block %d start %d smaller previous end %d\n", @@ -384,7 +381,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex continue; } - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { zend_basic_block *next_block; if (block->successors[s] < 0) { FAIL("Successor number %d of %d negative", s, i); @@ -400,7 +397,6 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex for (j = 0; j < block->predecessors_count; j++) { if (predecessors[j] >= 0) { - int k; zend_basic_block *prev_block = &cfg->blocks[predecessors[j]]; if (!(prev_block->flags & ZEND_BB_REACHABLE)) { FAIL("Predecessor %d of %d not reachable\n", predecessors[j], i); @@ -408,7 +404,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex if (!is_in_successors(prev_block, i)) { FAIL("Block %d successors missing %d\n", predecessors[j], i); } - for (k = 0; k < block->predecessors_count; k++) { + for (uint32_t k = 0; k < block->predecessors_count; k++) { if (k != j && predecessors[k] == predecessors[j]) { FAIL("Block %d has duplicate predecessor %d\n", i, predecessors[j]); } diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index 884b481aceb8..b67f57cf041d 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -126,6 +124,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: func_info->flags |= ZEND_FUNC_HAS_CALLS; if (call_info) { call_info->caller_call_opline = opline; @@ -142,6 +141,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 case ZEND_SEND_VAR_NO_REF: case ZEND_SEND_VAR_NO_REF_EX: case ZEND_SEND_USER: + case ZEND_SEND_PLACEHOLDER: if (call_info) { if (opline->op2_type == IS_CONST) { call_info->named_args = true; diff --git a/Zend/Optimizer/zend_call_graph.h b/Zend/Optimizer/zend_call_graph.h index 8810dc1a560e..57c6bdffe998 100644 --- a/Zend/Optimizer/zend_call_graph.h +++ b/Zend/Optimizer/zend_call_graph.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 32d5f49ef7df..837515169d70 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, CFG - Control Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -35,7 +33,6 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc zend_worklist_push(&work, b - cfg->blocks); while (zend_worklist_len(&work)) { - int i; b = cfg->blocks + zend_worklist_pop(&work); b->flags |= ZEND_BB_REACHABLE; @@ -44,7 +41,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc continue; } - for (i = 0; i < b->successors_count; i++) { + for (uint32_t i = 0; i < b->successors_count; i++) { zend_basic_block *succ = blocks + b->successors[i]; if (b->len != 0) { @@ -104,7 +101,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc } /* }}} */ -static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg, int start) /* {{{ */ +static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg, uint32_t start) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; @@ -113,14 +110,14 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * if (op_array->last_try_catch) { zend_basic_block *b; - int j, changed; + int changed; uint32_t *block_map = cfg->map; do { changed = 0; /* Add exception paths */ - for (j = 0; j < op_array->last_try_catch; j++) { + for (uint32_t j = 0; j < op_array->last_try_catch; j++) { /* check for jumps into the middle of try block */ b = blocks + block_map[op_array->try_catch_array[j].try_op]; @@ -202,7 +199,6 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * if (cfg->flags & ZEND_FUNC_FREE_LOOP_VAR) { zend_basic_block *b; - int j; uint32_t *block_map = cfg->map; /* Mark blocks that are unreachable, but free a loop var created in a reachable block. */ @@ -211,7 +207,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * continue; } - for (j = b->start; j < b->start + b->len; j++) { + for (uint32_t j = b->start; j < b->start + b->len; j++) { zend_op *opline = &op_array->opcodes[j]; if (zend_optimizer_is_loop_var_free(opline)) { zend_op *def_opline = zend_optimizer_get_loop_var_def(op_array, opline); @@ -232,8 +228,8 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; - int i; - int start = 0; + uint32_t i; + uint32_t start = 0; for (i = 0; i < cfg->blocks_count; i++) { if (blocks[i].flags & ZEND_BB_REACHABLE) { @@ -593,13 +589,12 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* {{{ */ { - int j, s, edges; zend_basic_block *b; zend_basic_block *blocks = cfg->blocks; zend_basic_block *end = blocks + cfg->blocks_count; + uint32_t edges = 0; int *predecessors; - edges = 0; for (b = blocks; b < end; b++) { b->predecessors_count = 0; } @@ -608,7 +603,7 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* b->successors_count = 0; b->predecessors_count = 0; } else { - for (s = 0; s < b->successors_count; s++) { + for (uint32_t s = 0; s < b->successors_count; s++) { edges++; blocks[b->successors[s]].predecessors_count++; } @@ -627,14 +622,13 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* } } - for (j = 0; j < cfg->blocks_count; j++) { + for (uint32_t j = 0; j < cfg->blocks_count; j++) { if (blocks[j].flags & ZEND_BB_REACHABLE) { /* SWITCH_STRING/LONG may have few identical successors */ - for (s = 0; s < blocks[j].successors_count; s++) { + for (uint32_t s = 0; s < blocks[j].successors_count; s++) { int duplicate = 0; - int p; - for (p = 0; p < s; p++) { + for (uint32_t p = 0; p < s; p++) { if (blocks[j].successors[p] == blocks[j].successors[s]) { duplicate = 1; break; @@ -654,16 +648,15 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* /* Computes a postorder numbering of the CFG */ static void compute_postnum_recursive( - int *postnum, int *cur, const zend_cfg *cfg, int block_num) /* {{{ */ + int *postnum, uint32_t *cur, const zend_cfg *cfg, int block_num) /* {{{ */ { - int s; zend_basic_block *block = &cfg->blocks[block_num]; if (postnum[block_num] != -1) { return; } postnum[block_num] = -2; /* Marker for "currently visiting" */ - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { compute_postnum_recursive(postnum, cur, cfg, block->successors[s]); } postnum[block_num] = (*cur)++; @@ -675,8 +668,9 @@ static void compute_postnum_recursive( ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; - int blocks_count = cfg->blocks_count; - int j, k, changed; + uint32_t blocks_count = cfg->blocks_count; + uint32_t j; + int changed; if (cfg->blocks_count == 1) { blocks[0].level = 0; @@ -700,7 +694,7 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) { continue; } - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { int pred = cfg->predecessors[blocks[j].predecessor_offset + k]; if (blocks[pred].idom >= 0) { @@ -776,7 +770,7 @@ static bool dominates(zend_basic_block *blocks, int a, int b) /* {{{ */ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { - int i, j, k, n; + int i, j, n; int time; zend_basic_block *blocks = cfg->blocks; int *entry_times, *exit_times; @@ -890,7 +884,7 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c continue; } blocks[j].loop_header = i; - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { zend_worklist_push(&work, cfg->predecessors[blocks[j].predecessor_offset + k]); } } diff --git a/Zend/Optimizer/zend_cfg.h b/Zend/Optimizer/zend_cfg.h index 1f3885f511f5..3ed635ecdedc 100644 --- a/Zend/Optimizer/zend_cfg.h +++ b/Zend/Optimizer/zend_cfg.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, CFG - Control Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -44,8 +42,8 @@ typedef struct _zend_basic_block { uint32_t flags; uint32_t start; /* first opcode number */ uint32_t len; /* number of opcodes */ - int successors_count; /* number of successors */ - int predecessors_count; /* number of predecessors */ + uint32_t successors_count; /* number of successors */ + uint32_t predecessors_count; /* number of predecessors */ int predecessor_offset; /* offset of 1-st predecessor, or -1 */ int idom; /* immediate dominator block, or -1 */ int loop_header; /* closest loop header, or -1 */ @@ -82,8 +80,8 @@ typedef struct _zend_basic_block { */ typedef struct _zend_cfg { - int blocks_count; /* number of basic blocks */ - int edges_count; /* number of edges */ + uint32_t blocks_count; /* number of basic blocks */ + uint32_t edges_count; /* number of edges */ zend_basic_block *blocks; /* array of basic blocks */ int *predecessors; uint32_t *map; diff --git a/Zend/Optimizer/zend_dfg.c b/Zend/Optimizer/zend_dfg.c index c14d67e873a2..72e15693a844 100644 --- a/Zend/Optimizer/zend_dfg.c +++ b/Zend/Optimizer/zend_dfg.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DFG - Data Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -253,10 +251,9 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const ze { uint32_t set_size = dfg->size; zend_basic_block *blocks = cfg->blocks; - int blocks_count = cfg->blocks_count; + uint32_t blocks_count = cfg->blocks_count; zend_bitset tmp, def, use, in, out; - int k; - int j; + uint32_t j; tmp = dfg->tmp; def = dfg->def; @@ -305,7 +302,7 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const ze } if (blocks[j].successors_count != 0) { zend_bitset_copy(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[0]), set_size); - for (k = 1; k < blocks[j].successors_count; k++) { + for (uint32_t k = 1; k < blocks[j].successors_count; k++) { zend_bitset_union(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[k]), set_size); } } else { @@ -318,7 +315,7 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const ze /* Add predecessors of changed block to worklist */ { const int *predecessors = &cfg->predecessors[blocks[j].predecessor_offset]; - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { zend_bitset_incl(worklist, predecessors[k]); } } diff --git a/Zend/Optimizer/zend_dfg.h b/Zend/Optimizer/zend_dfg.h index af3d761ba29f..464ea6bb2ebe 100644 --- a/Zend/Optimizer/zend_dfg.h +++ b/Zend/Optimizer/zend_dfg.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DFG - Data Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/zend_dump.c b/Zend/Optimizer/zend_dump.c index 16cb75188242..c6cc5193b2dc 100644 --- a/Zend/Optimizer/zend_dump.c +++ b/Zend/Optimizer/zend_dump.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Bytecode Visualisation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -25,7 +23,7 @@ #include "zend_dump.h" #include "zend_smart_str.h" -void zend_dump_ht(HashTable *ht) +void zend_dump_ht(const HashTable *ht) { zend_ulong index; zend_string *key; @@ -190,7 +188,7 @@ static void zend_dump_range(const zend_ssa_range *r) } } -static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_instanceof, uint32_t dump_flags) +static void zend_dump_type_info(uint32_t info, const zend_class_entry *ce, bool is_instanceof, uint32_t dump_flags) { bool first = true; @@ -482,7 +480,7 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block } if (ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) { - zend_function *func = ZEND_FLF_FUNC(opline); + const zend_function *func = ZEND_FLF_FUNC(opline); fprintf(stderr, "(%s)", ZSTR_VAL(func->common.function_name)); } @@ -674,13 +672,13 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block } if (opline->op2_type == IS_CONST) { - zval *op = CRT_CONSTANT(opline->op2); + const zval *op = CRT_CONSTANT(opline->op2); if ( opline->opcode == ZEND_SWITCH_LONG || opline->opcode == ZEND_SWITCH_STRING || opline->opcode == ZEND_MATCH ) { - HashTable *jumptable = Z_ARRVAL_P(op); + const HashTable *jumptable = Z_ARRVAL_P(op); zend_string *key; zend_ulong num_key; zval *zv; @@ -778,7 +776,7 @@ ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_ { int len = 0; const zend_ssa *ssa = NULL; - zend_ssa_op *ssa_op = NULL; + const zend_ssa_op *ssa_op = NULL; if (dump_flags & ZEND_DUMP_LINE_NUMBERS) { fprintf(stderr, "L%04u ", opline->lineno); @@ -800,7 +798,7 @@ ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags) { - zend_basic_block *b = cfg->blocks + n; + const zend_basic_block *b = cfg->blocks + n; if (n > 0) { fprintf(stderr, "\n"); @@ -856,8 +854,8 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags fprintf(stderr, "\n"); if (b->predecessors_count) { - int *p = cfg->predecessors + b->predecessor_offset; - int *end = p + b->predecessors_count; + const int *p = cfg->predecessors + b->predecessor_offset; + const int *end = p + b->predecessors_count; fprintf(stderr, " ; from=(BB%d", *p); for (p++; p < end; p++) { @@ -867,9 +865,8 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags } if (b->successors_count > 0) { - int s; fprintf(stderr, " ; to=(BB%d", b->successors[0]); - for (s = 1; s < b->successors_count; s++) { + for (uint32_t s = 1; s < b->successors_count; s++) { fprintf(stderr, ", BB%d", b->successors[s]); } fprintf(stderr, ")\n"); @@ -900,16 +897,14 @@ static void zend_dump_block_header(const zend_cfg *cfg, const zend_op_array *op_ { zend_dump_block_info(cfg, n, dump_flags); if (ssa && ssa->blocks && ssa->blocks[n].phis) { - zend_ssa_phi *p = ssa->blocks[n].phis; + const zend_ssa_phi *p = ssa->blocks[n].phis; do { - int j; - fprintf(stderr, " "); zend_dump_ssa_var(op_array, ssa, p->ssa_var, 0, p->var, dump_flags); if (p->pi < 0) { fprintf(stderr, " = Phi("); - for (j = 0; j < cfg->blocks[n].predecessors_count; j++) { + for (uint32_t j = 0; j < cfg->blocks[n].predecessors_count; j++) { if (j > 0) { fprintf(stderr, ", "); } @@ -949,7 +944,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl { const zend_cfg *cfg = NULL; const zend_ssa *ssa = NULL; - zend_func_info *func_info = NULL; + const zend_func_info *func_info = NULL; uint32_t func_flags = 0; if (dump_flags & (ZEND_DUMP_CFG|ZEND_DUMP_SSA)) { @@ -1040,11 +1035,8 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl } if (cfg) { - int n; - zend_basic_block *b; - - for (n = 0; n < cfg->blocks_count; n++) { - b = cfg->blocks + n; + for (uint32_t n = 0; n < cfg->blocks_count; n++) { + const zend_basic_block *b = cfg->blocks + n; if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) || (b->flags & ZEND_BB_REACHABLE)) { const zend_op *opline; const zend_op *end; @@ -1180,13 +1172,11 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg) { - int j; - fprintf(stderr, "\nDOMINATORS-TREE for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < cfg->blocks_count; j++) { - zend_basic_block *b = cfg->blocks + j; + for (uint32_t j = 0; j < cfg->blocks_count; j++) { + const zend_basic_block *b = cfg->blocks + j; if (b->flags & ZEND_BB_REACHABLE) { zend_dump_block_info(cfg, j, 0); } @@ -1195,14 +1185,12 @@ void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg) void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags) { - int j; - if (ssa->vars) { fprintf(stderr, "\nSSA Variable for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < ssa->vars_count; j++) { + for (int j = 0; j < ssa->vars_count; j++) { fprintf(stderr, " "); zend_dump_ssa_var(op_array, ssa, j, IS_CV, ssa->vars[j].var, dump_flags); if (ssa->vars[j].scc >= 0) { @@ -1221,10 +1209,9 @@ void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, static void zend_dump_var_set(const zend_op_array *op_array, const char *name, zend_bitset set) { bool first = true; - uint32_t i; fprintf(stderr, " ; %s = {", name); - for (i = 0; i < op_array->last_var + op_array->T; i++) { + for (uint32_t i = 0; i < op_array->last_var + op_array->T; i++) { if (zend_bitset_in(set, i)) { if (first) { first = false; @@ -1239,12 +1226,11 @@ static void zend_dump_var_set(const zend_op_array *op_array, const char *name, z void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg) { - int j; fprintf(stderr, "\nVariable Liveness for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < cfg->blocks_count; j++) { + for (uint32_t j = 0; j < cfg->blocks_count; j++) { fprintf(stderr, " BB%d:\n", j); zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j)); zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j)); @@ -1255,17 +1241,16 @@ void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zen void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa) { - int j; - zend_ssa_block *ssa_blocks = ssa->blocks; - int blocks_count = ssa->cfg.blocks_count; + const zend_ssa_block *ssa_blocks = ssa->blocks; + uint32_t blocks_count = ssa->cfg.blocks_count; fprintf(stderr, "\nSSA Phi() Placement for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < blocks_count; j++) { + for (uint32_t j = 0; j < blocks_count; j++) { if (ssa_blocks && ssa_blocks[j].phis) { - zend_ssa_phi *p = ssa_blocks[j].phis; - int first = 1; + const zend_ssa_phi *p = ssa_blocks[j].phis; + bool first = true; fprintf(stderr, " BB%d:\n", j); if (p->pi >= 0) { @@ -1275,7 +1260,7 @@ void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa) } do { if (first) { - first = 0; + first = false; } else { fprintf(stderr, ", "); } diff --git a/Zend/Optimizer/zend_dump.h b/Zend/Optimizer/zend_dump.h index db8f762bfc49..45740d9609cb 100644 --- a/Zend/Optimizer/zend_dump.h +++ b/Zend/Optimizer/zend_dump.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Bytecode Visualisation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -44,7 +42,7 @@ ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *s ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num); void zend_dump_op_array_name(const zend_op_array *op_array); void zend_dump_const(const zval *zv); -void zend_dump_ht(HashTable *ht); +void zend_dump_ht(const HashTable *ht); END_EXTERN_C() diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index cec52f7e9860..185fcc40be67 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Func Info | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | diff --git a/Zend/Optimizer/zend_func_info.h b/Zend/Optimizer/zend_func_info.h index db00d843ee10..6b5b51cac58b 100644 --- a/Zend/Optimizer/zend_func_info.h +++ b/Zend/Optimizer/zend_func_info.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Func Info | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index b7b118c710c5..2a9353c9b86e 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -596,6 +596,7 @@ static const func_info_t func_infos[] = { F1("stream_get_line", MAY_BE_STRING|MAY_BE_FALSE), F1("stream_resolve_include_path", MAY_BE_STRING|MAY_BE_FALSE), F1("stream_get_wrappers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING), + FN("stream_last_errors", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_OBJECT), F1("stream_get_transports", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING), #if defined(HAVE_GETTIMEOFDAY) F1("uniqid", MAY_BE_STRING), diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 6963fc63dd15..2e6cc70ec254 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, e-SSA based Type & Range Inference | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -493,7 +491,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, co const zend_ssa_op *ssa_ops = ssa->ops; int ssa_vars_count = ssa->vars_count; zend_bitset worklist; - int i, j, use; + int i, use; const zend_ssa_phi *p; ALLOCA_FLAG(use_heap); @@ -527,7 +525,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, co zend_bitset_incl(worklist, p->sources[0]); } } else { - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { ZEND_ASSERT(p->sources[j] >= 0); if (ssa->vars[p->sources[j]].no_val) { ssa_vars[p->sources[j]].no_val = 0; /* used indirectly */ @@ -1063,7 +1061,7 @@ static bool zend_inference_calc_binary_op_range( case ZEND_BW_XOR: // TODO break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 0; } @@ -1076,7 +1074,6 @@ static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ if (ssa->vars[var].definition_phi) { const zend_ssa_phi *p = ssa->vars[var].definition_phi; - int i; tmp->underflow = 0; tmp->min = ZEND_LONG_MAX; @@ -1222,7 +1219,7 @@ static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ } } } else { - for (i = 0; i < ssa->cfg.blocks[p->block].predecessors_count; i++) { + for (uint32_t i = 0; i < ssa->cfg.blocks[p->block].predecessors_count; i++) { ZEND_ASSERT(p->sources[i] >= 0); if (ssa->var_info[p->sources[i]].has_range) { /* union */ @@ -2351,7 +2348,7 @@ static uint32_t binary_op_result_type( /* TODO: +MAY_BE_OBJECT ??? */ tmp = MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return tmp; } @@ -3709,7 +3706,7 @@ static zend_always_inline zend_result _zend_update_type_info( case ZEND_FREE: /* This may happen if the using opcode is DCEd. */ break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } j = zend_ssa_next_use(ssa->ops, ssa_op->result_def, j); if (j >= 0) { @@ -3906,6 +3903,7 @@ static zend_always_inline zend_result _zend_update_type_info( } break; case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: UPDATE_SSA_TYPE(MAY_BE_OBJECT | MAY_BE_RC1 | MAY_BE_RCN, ssa_op->result_def); UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def); break; @@ -4192,7 +4190,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend zend_ssa_var *ssa_vars = ssa->vars; zend_ssa_var_info *ssa_var_info = ssa->var_info; int ssa_vars_count = ssa->vars_count; - int i, j; + int j; uint32_t tmp, worklist_len = zend_bitset_len(ssa_vars_count); bool update_worklist = 1; const zend_op **ssa_opcodes = NULL; @@ -4236,6 +4234,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend bool first = true; bool is_instanceof = false; zend_class_entry *ce = NULL; + uint32_t i; tmp = 0; for (i = 0; i < blocks[p->block].predecessors_count; i++) { @@ -4261,7 +4260,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend UPDATE_SSA_OBJ_TYPE(ce, ce ? is_instanceof : 0, j); } } else if (ssa_vars[j].definition >= 0) { - i = ssa_vars[j].definition; + int i = ssa_vars[j].definition; if (_zend_update_type_info(op_array, ssa, script, worklist, op_array->opcodes + i, ssa->ops + i, NULL, optimization_level, true) == FAILURE) { return FAILURE; } @@ -4562,9 +4561,8 @@ static void zend_func_return_info(const zend_op_array *op_array, { const zend_func_info *info = ZEND_FUNC_INFO(op_array); const zend_ssa *ssa = &info->ssa; - int blocks_count = info->ssa.cfg.blocks_count; + uint32_t blocks_count = info->ssa.cfg.blocks_count; const zend_basic_block *blocks = info->ssa.cfg.blocks; - int j; uint32_t t1; uint32_t tmp = 0; zend_class_entry *tmp_ce = NULL; @@ -4589,7 +4587,7 @@ static void zend_func_return_info(const zend_op_array *op_array, | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF; } - for (j = 0; j < blocks_count; j++) { + for (uint32_t j = 0; j < blocks_count; j++) { if ((blocks[j].flags & ZEND_BB_REACHABLE) && blocks[j].len != 0) { zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1; @@ -5295,10 +5293,10 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op return (t1 & MAY_BE_OBJECT); case IS_OBJECT: return 0; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } /* GCC is getting confused here for the Wimplicit-fallthrough warning with - * EMPTY_SWITCH_DEFAULT_CASE() macro */ + * default: ZEND_UNREACHABLE(); macro */ return 0; case ZEND_ARRAY_KEY_EXISTS: if ((t2 & MAY_BE_ANY) != MAY_BE_ARRAY) { diff --git a/Zend/Optimizer/zend_inference.h b/Zend/Optimizer/zend_inference.h index 1b626fa2ee22..e6b4207c7494 100644 --- a/Zend/Optimizer/zend_inference.h +++ b/Zend/Optimizer/zend_inference.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, e-SSA based Type & Range Inference | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index f8cbefdaaf2b..0173d2ef47a2 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -106,9 +104,7 @@ zend_result zend_optimizer_eval_special_func_call( zval *result, const zend_string *name, zend_string *arg) { if (zend_string_equals_literal(name, "function_exists") || zend_string_equals_literal(name, "is_callable")) { - zend_string *lc_name = zend_string_tolower(arg); - const zend_internal_function *func = zend_hash_find_ptr(EG(function_table), lc_name); - zend_string_release_ex(lc_name, 0); + const zend_internal_function *func = zend_hash_find_ptr_lc(EG(function_table), arg); if (func && func->type == ZEND_INTERNAL_FUNCTION && func->module->type == MODULE_PERSISTENT @@ -122,9 +118,7 @@ zend_result zend_optimizer_eval_special_func_call( return FAILURE; } if (zend_string_equals_literal(name, "extension_loaded")) { - zend_string *lc_name = zend_string_tolower(arg); - zend_module_entry *m = zend_hash_find_ptr(&module_registry, lc_name); - zend_string_release_ex(lc_name, 0); + zend_module_entry *m = zend_hash_find_ptr_lc(&module_registry, arg); if (!m) { if (PG(enable_dl)) { @@ -782,7 +776,7 @@ static bool zend_optimizer_ignore_class(zval *ce_zv, const zend_string *filename if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { return true; } - const Bucket *ce_bucket = (const Bucket*)((uintptr_t)ce_zv - XtOffsetOf(Bucket, val)); + const Bucket *ce_bucket = ZEND_CONTAINER_OF(ce_zv, Bucket, val); size_t offset = ce_bucket - EG(class_table)->arData; if (offset < EG(persistent_classes_count)) { return false; @@ -803,7 +797,7 @@ static bool zend_optimizer_ignore_function(zval *fbc_zv, const zend_string *file if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { return true; } - const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val)); + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); size_t offset = fbc_bucket - EG(function_table)->arData; if (offset < EG(persistent_functions_count)) { return false; @@ -945,7 +939,7 @@ zend_function *zend_optimizer_get_called_func( if (ce) { zend_string *func_name = Z_STR_P(CRT_CONSTANT(opline->op2) + 1); zend_function *fbc = zend_hash_find_ptr(&ce->function_table, func_name); - if (fbc) { + if (fbc && !(fbc->common.fn_flags & ZEND_ACC_ABSTRACT)) { bool is_public = (fbc->common.fn_flags & ZEND_ACC_PUBLIC) != 0; bool same_scope = fbc->common.scope == op_array->scope; if (is_public || same_scope) { diff --git a/Zend/Optimizer/zend_optimizer.h b/Zend/Optimizer/zend_optimizer.h index 43a0f60a2321..d2847c92869c 100644 --- a/Zend/Optimizer/zend_optimizer.h +++ b/Zend/Optimizer/zend_optimizer.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index 869275811e3d..d01df56260bc 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 99978da9d7e8..fa2901b89421 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA - Static Single Assignment Form | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Nikita Popov | @@ -35,8 +33,7 @@ static bool dominates(const zend_basic_block *blocks, int a, int b) { static bool will_rejoin( const zend_cfg *cfg, const zend_dfg *dfg, const zend_basic_block *block, int other_successor, int exclude, int var) { - int i; - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { int predecessor = cfg->predecessors[block->predecessor_offset + i]; if (predecessor == exclude) { continue; @@ -243,8 +240,8 @@ static void place_essa_pis( zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, const zend_ssa *ssa, const zend_dfg *dfg) /* {{{ */ { const zend_basic_block *blocks = ssa->cfg.blocks; - int j, blocks_count = ssa->cfg.blocks_count; - for (j = 0; j < blocks_count; j++) { + uint32_t blocks_count = ssa->cfg.blocks_count; + for (uint32_t j = 0; j < blocks_count; j++) { zend_ssa_phi *pi; zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1; int bt; /* successor block number if a condition is true */ @@ -823,7 +820,6 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui const zend_ssa_block *ssa_blocks = ssa->blocks; zend_ssa_op *ssa_ops = ssa->ops; int ssa_vars_count = ssa->vars_count; - int i, j; const zend_op *opline, *end; if (ssa_blocks[n].phis) { @@ -853,7 +849,7 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui && ((end-1)->opcode == ZEND_FE_FETCH_R || (end-1)->opcode == ZEND_FE_FETCH_RW) && (end-1)->op2_type == IS_CV ? &ssa_ops[blocks[n].start + blocks[n].len - 1] : NULL; - for (i = 0; i < blocks[n].successors_count; i++) { + for (uint32_t i = 0; i < blocks[n].successors_count; i++) { int succ = blocks[n].successors[i]; zend_ssa_phi *p; for (p = ssa_blocks[succ].phis; p; p = p->next) { @@ -867,7 +863,7 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui p->constraint.range.max_ssa_var = var[p->constraint.range.max_var]; } } - for (j = 0; j < blocks[succ].predecessors_count; j++) { + for (uint32_t j = 0; j < blocks[succ].predecessors_count; j++) { p->sources[j] = var[p->var]; } if (p->ssa_var < 0) { @@ -876,6 +872,7 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui } } else if (p->pi < 0) { /* Normal Phi */ + uint32_t j; for (j = 0; j < blocks[succ].predecessors_count; j++) if (ssa->cfg.predecessors[blocks[succ].predecessor_offset + j] == n) { break; @@ -893,6 +890,7 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui zend_ssa_phi *q = p->next; while (q) { if (q->pi < 0 && q->var == p->var) { + uint32_t j; for (j = 0; j < blocks[succ].predecessors_count; j++) { if (ssa->cfg.predecessors[blocks[succ].predecessor_offset + j] == n) { break; @@ -997,11 +995,11 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip { const zend_basic_block *blocks = ssa->cfg.blocks; zend_ssa_block *ssa_blocks; - int blocks_count = ssa->cfg.blocks_count; + uint32_t blocks_count = ssa->cfg.blocks_count; uint32_t set_size; zend_bitset def, in, phi; int *var = NULL; - int i, j, k, changed; + int i, j, changed; zend_dfg dfg; ALLOCA_FLAG(dfg_use_heap) ALLOCA_FLAG(var_use_heap) @@ -1056,7 +1054,7 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip register allocator depends on this property. */ zend_bitset_union(phi_j, in + (j * set_size), set_size); } else { - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k]; while (i != -1 && i != blocks[j].idom) { zend_bitset_union_with_intersection( @@ -1223,9 +1221,7 @@ ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_ } } } else { - int j; - - for (j = 0; j < ssa->cfg.blocks[i].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[i].predecessors_count; j++) { zend_ssa_phi *p; ZEND_ASSERT(phi->sources[j] >= 0); @@ -1374,8 +1370,7 @@ static inline zend_ssa_phi **zend_ssa_next_use_phi_ptr(const zend_ssa *ssa, int if (p->pi >= 0) { return &p->use_chains[0]; } else { - int j; - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { if (p->sources[j] == var) { return &p->use_chains[j]; } @@ -1438,9 +1433,9 @@ void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) /* {{{ */ } /* }}} */ -static inline void zend_ssa_remove_phi_source(const zend_ssa *ssa, const zend_ssa_phi *phi, int pred_offset, int predecessors_count) /* {{{ */ +static inline void zend_ssa_remove_phi_source(const zend_ssa *ssa, const zend_ssa_phi *phi, int pred_offset, uint32_t predecessors_count) /* {{{ */ { - int j, var_num = phi->sources[pred_offset]; + int var_num = phi->sources[pred_offset]; zend_ssa_phi *next_phi = phi->use_chains[pred_offset]; predecessors_count--; @@ -1451,7 +1446,7 @@ static inline void zend_ssa_remove_phi_source(const zend_ssa *ssa, const zend_ss /* Check if they same var is used in a different phi operand as well, in this case we don't * need to adjust the use chain (but may have to move the next pointer). */ - for (j = 0; j < predecessors_count; j++) { + for (uint32_t j = 0; j < predecessors_count; j++) { if (phi->sources[j] == var_num) { if (j < pred_offset) { ZEND_ASSERT(next_phi == NULL); @@ -1485,8 +1480,8 @@ void zend_ssa_remove_uses_of_var(const zend_ssa *ssa, int var_num) /* {{{ */ zend_ssa_phi *phi; int use; FOREACH_PHI_USE(var, phi) { - int i, end = NUM_PHI_SOURCES(phi); - for (i = 0; i < end; i++) { + uint32_t end = NUM_PHI_SOURCES(phi); + for (uint32_t i = 0; i < end; i++) { if (phi->sources[i] == var_num) { phi->use_chains[i] = NULL; } @@ -1517,13 +1512,12 @@ void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to) /* {{{ */ zend_basic_block *next_block = &ssa->cfg.blocks[to]; const zend_ssa_block *next_ssa_block = &ssa->blocks[to]; zend_ssa_phi *phi; - int j; /* Find at which predecessor offset this block is referenced */ int pred_offset = -1; int *predecessors = &ssa->cfg.predecessors[next_block->predecessor_offset]; - for (j = 0; j < next_block->predecessors_count; j++) { + for (uint32_t j = 0; j < next_block->predecessors_count; j++) { if (predecessors[j] == from) { pred_offset = j; break; @@ -1558,7 +1552,7 @@ void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to) /* {{{ */ } /* }}} */ -void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, int i) /* {{{ */ +void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, uint32_t i) /* {{{ */ { zend_basic_block *block = &ssa->cfg.blocks[i]; const zend_ssa_block *ssa_block = &ssa->blocks[i]; @@ -1591,7 +1585,8 @@ void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int i) /* {{{ */ { zend_basic_block *block = &ssa->cfg.blocks[i]; int *predecessors; - int j, s; + int j; + uint32_t s; for (s = 0; s < block->successors_count; s++) { zend_ssa_remove_predecessor(ssa, i, block->successors[s]); @@ -1722,7 +1717,7 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types /* Update phi use chains */ FOREACH_PHI_USE(old_var, phi) { - int j; + uint32_t j; bool after_first_new_source = false; /* If the phi already uses the new var, find its use chain, as we may diff --git a/Zend/Optimizer/zend_ssa.h b/Zend/Optimizer/zend_ssa.h index 0696d2bba867..ee9faf9bfd23 100644 --- a/Zend/Optimizer/zend_ssa.h +++ b/Zend/Optimizer/zend_ssa.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA - Static Single Assignment Form | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -66,7 +64,7 @@ struct _zend_ssa_phi { zend_ssa_pi_constraint constraint; /* e-SSA Pi constraint */ int var; /* Original CV, VAR or TMP variable index */ int ssa_var; /* SSA variable index */ - int block; /* current BB index */ + uint32_t block; /* current BB index */ bool has_range_constraint; zend_ssa_phi **use_chains; zend_ssa_phi *sym_use_chain; @@ -155,7 +153,7 @@ void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op); void zend_ssa_remove_instr(const zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op); void zend_ssa_remove_phi(const zend_ssa *ssa, zend_ssa_phi *phi); void zend_ssa_remove_uses_of_var(const zend_ssa *ssa, int var_num); -void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, int b); +void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, uint32_t b); void zend_ssa_rename_var_uses(zend_ssa *ssa, int old_var, int new_var, bool update_types); void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int b); @@ -207,8 +205,7 @@ static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(const zend_ssa *ss if (p->pi >= 0) { return p->use_chains[0]; } else { - int j; - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { if (p->sources[j] == var) { return p->use_chains[j]; } @@ -285,7 +282,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend #define FOREACH_PHI_SOURCE(phi, source) do { \ zend_ssa_phi *_phi = (phi); \ - int _i, _end = NUM_PHI_SOURCES(phi); \ + uint32_t _i, _end = NUM_PHI_SOURCES(phi); \ for (_i = 0; _i < _end; _i++) { \ ZEND_ASSERT(_phi->sources[_i] >= 0); \ source = _phi->sources[_i]; @@ -294,8 +291,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend } while (0) #define FOREACH_PHI(phi) do { \ - int _i; \ - for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \ + for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \ phi = ssa->blocks[_i].phis; \ for (; phi; phi = phi->next) { #define FOREACH_PHI_END() \ @@ -304,8 +300,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend } while (0) #define FOREACH_BLOCK(block) do { \ - int _i; \ - for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \ + for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \ (block) = &ssa->cfg.blocks[_i]; \ if (!((block)->flags & ZEND_BB_REACHABLE)) { \ continue; \ diff --git a/Zend/Optimizer/zend_worklist.h b/Zend/Optimizer/zend_worklist.h index 85e7b111d5c9..ea03048e9756 100644 --- a/Zend/Optimizer/zend_worklist.h +++ b/Zend/Optimizer/zend_worklist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andy Wingo | +----------------------------------------------------------------------+ diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index d0c682e8e659..5e69a97db197 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -317,6 +317,7 @@ int emu(const opcode_handler_t *ip, void *fp) { while ((*ip)()); FP = orig_fp; IP = orig_ip; + return 0; }], [])], [php_cv_have_global_register_vars=yes], [php_cv_have_global_register_vars=no]) diff --git a/Zend/asm/jump_arm64_aapcs_elf_gas.S b/Zend/asm/jump_arm64_aapcs_elf_gas.S index cefd1830d718..b8abb2ef6bc4 100644 --- a/Zend/asm/jump_arm64_aapcs_elf_gas.S +++ b/Zend/asm/jump_arm64_aapcs_elf_gas.S @@ -53,10 +53,29 @@ .file "jump_arm64_aapcs_elf_gas.S" .text +#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) +/* Mark this object as requiring BTI, enabling the linker to set BTI on the output */ + .pushsection .note.gnu.property, "a", %note + .p2align 3 + .long 4 /* namesz */ + .long 16 /* descsz (16 bytes) */ + .long 5 /* type = NT_GNU_PROPERTY_TYPE_0 */ + .asciz "GNU" + .p2align 3 + .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ + .long 4 /* datasz = 4 */ + .long 1 /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI */ + .long 0 /* pad to 8-byte alignment */ + .popsection +#endif .align 2 .global jump_fcontext +.hidden jump_fcontext .type jump_fcontext, %function jump_fcontext: +#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) + hint #34 /* bti c: valid indirect-entry target */ +#endif # prepare stack for GP + FPU sub sp, sp, #0xb0 diff --git a/Zend/asm/jump_arm64_aapcs_macho_gas.S b/Zend/asm/jump_arm64_aapcs_macho_gas.S index 31738f745314..12cc02158685 100644 --- a/Zend/asm/jump_arm64_aapcs_macho_gas.S +++ b/Zend/asm/jump_arm64_aapcs_macho_gas.S @@ -52,6 +52,7 @@ *******************************************************/ .text +.private_extern _jump_fcontext .globl _jump_fcontext .balign 16 _jump_fcontext: diff --git a/Zend/asm/jump_arm64_aapcs_pe_armasm.asm b/Zend/asm/jump_arm64_aapcs_pe_armasm.asm index 3100243d68de..afb6d2b2e703 100644 --- a/Zend/asm/jump_arm64_aapcs_pe_armasm.asm +++ b/Zend/asm/jump_arm64_aapcs_pe_armasm.asm @@ -45,7 +45,7 @@ ;* ------------------------------------------------- * ;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * ;* ------------------------------------------------- * -;* | fiber data| base | limit | dealloc | * +;* | base | limit | dealloc | fiber data| * ;* ------------------------------------------------- * ;* ------------------------------------------------- * ;* | 48 | 49 | 50 | 51 | | | * @@ -130,4 +130,4 @@ jump_fcontext proc ret x4 ENDP - END \ No newline at end of file + END diff --git a/Zend/asm/jump_arm_aapcs_elf_gas.S b/Zend/asm/jump_arm_aapcs_elf_gas.S index 86efe9d82146..4415a541fd3e 100644 --- a/Zend/asm/jump_arm_aapcs_elf_gas.S +++ b/Zend/asm/jump_arm_aapcs_elf_gas.S @@ -41,6 +41,7 @@ .file "jump_arm_aapcs_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 2 .type jump_fcontext,%function .syntax unified @@ -48,8 +49,38 @@ jump_fcontext: @ save LR as PC push {lr} @ save hidden,V1-V8,LR + + #if __ARM_ARCH >= 7 + push {a1,v1-v8,lr} + #else + + sub sp, #40 + + str a1, [sp, #0] + str v1, [sp, #4] + str v2, [sp, #8] + str v3, [sp, #12] + str v4, [sp, #16] + + mov v4, v5 + str v4, [sp, #20] + + mov v4, v6 + str v4, [sp, #24] + + mov v4, v7 + str v4, [sp, #28] + + mov v4, v8 + str v4, [sp, #32] + + mov v4, lr + str v4, [sp, #36] + + #endif + @ prepare stack for FPU sub sp, sp, #64 #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) @@ -71,7 +102,34 @@ jump_fcontext: add sp, sp, #64 @ restore hidden,V1-V8,LR + #if __ARM_ARCH >= 7 pop {a4,v1-v8,lr} + #else + + ldr v4, [sp, #20] + mov v5, v4 + + ldr v4, [sp, #24] + mov v6, v4 + + ldr v4, [sp, #28] + mov v7, v4 + + ldr v4, [sp, #32] + mov v8, v4 + + ldr v4, [sp, #36] + mov lr, v4 + + ldr a4, [sp, #0] + ldr v1, [sp, #4] + ldr v2, [sp, #8] + ldr v3, [sp, #12] + ldr v4, [sp, #16] + + add sp, #40 + + #endif @ return transfer_t from jump str a1, [a4, #0] diff --git a/Zend/asm/jump_arm_aapcs_macho_gas.S b/Zend/asm/jump_arm_aapcs_macho_gas.S index 077c36409e83..44e7f2a42274 100644 --- a/Zend/asm/jump_arm_aapcs_macho_gas.S +++ b/Zend/asm/jump_arm_aapcs_macho_gas.S @@ -39,6 +39,7 @@ *******************************************************/ .text +.private_extern _jump_fcontext .globl _jump_fcontext .align 2 _jump_fcontext: diff --git a/Zend/asm/jump_i386_ms_pe_masm.asm b/Zend/asm/jump_i386_ms_pe_masm.asm index 7a9e848f1c3f..a0450d0532f8 100644 --- a/Zend/asm/jump_i386_ms_pe_masm.asm +++ b/Zend/asm/jump_i386_ms_pe_masm.asm @@ -55,17 +55,17 @@ ENDIF mov eax, [edx] mov [esp+018h], eax - mov [esp+01ch], edi ; save EDI - mov [esp+020h], esi ; save ESI - mov [esp+024h], ebx ; save EBX - mov [esp+028h], ebp ; save EBP + mov [esp+01ch], edi ; save EDI + mov [esp+020h], esi ; save ESI + mov [esp+024h], ebx ; save EBX + mov [esp+028h], ebp ; save EBP ; store ESP (pointing to context-data) in EAX mov eax, esp ; firstarg of jump_fcontext() == fcontext to jump to mov ecx, [esp+030h] - + ; restore ESP (pointing to context-data) from ECX mov esp, ecx @@ -98,10 +98,10 @@ ENDIF mov ecx, [esp+02ch] ; restore EIP - mov edi, [esp+01ch] ; restore EDI - mov esi, [esp+020h] ; restore ESI - mov ebx, [esp+024h] ; restore EBX - mov ebp, [esp+028h] ; restore EBP + mov edi, [esp+01ch] ; restore EDI + mov esi, [esp+020h] ; restore ESI + mov ebx, [esp+024h] ; restore EBX + mov ebp, [esp+028h] ; restore EBP ; prepare stack lea esp, [esp+030h] diff --git a/Zend/asm/jump_i386_sysv_elf_gas.S b/Zend/asm/jump_i386_sysv_elf_gas.S index ed83717ce2b8..d00ac4fffd42 100644 --- a/Zend/asm/jump_i386_sysv_elf_gas.S +++ b/Zend/asm/jump_i386_sysv_elf_gas.S @@ -31,6 +31,7 @@ .file "jump_i386_sysv_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 2 .type jump_fcontext,@function jump_fcontext: diff --git a/Zend/asm/jump_i386_sysv_macho_gas.S b/Zend/asm/jump_i386_sysv_macho_gas.S index 8ab7c6f29c66..4cae3252d171 100644 --- a/Zend/asm/jump_i386_sysv_macho_gas.S +++ b/Zend/asm/jump_i386_sysv_macho_gas.S @@ -25,6 +25,7 @@ ****************************************************************************************/ .text +.private_extern _jump_fcontext .globl _jump_fcontext .align 2 _jump_fcontext: @@ -54,8 +55,8 @@ _jump_fcontext: /* return parent fcontext_t */ movl %ecx, %eax - /* returned data is stored in EDX */ - + /* returned data is stored in EDX */ + movl 0x18(%esp), %ecx /* restore EIP */ #if !defined(BOOST_USE_TSX) diff --git a/Zend/asm/jump_loongarch64_sysv_elf_gas.S b/Zend/asm/jump_loongarch64_sysv_elf_gas.S index 74c081e07faa..6f99e719ec00 100644 --- a/Zend/asm/jump_loongarch64_sysv_elf_gas.S +++ b/Zend/asm/jump_loongarch64_sysv_elf_gas.S @@ -41,6 +41,7 @@ .file "jump_loongarch64_sysv_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 2 .type jump_fcontext,@function jump_fcontext: diff --git a/Zend/asm/jump_mips32_o32_elf_gas.S b/Zend/asm/jump_mips32_o32_elf_gas.S index f2b8034d8c5b..38d22d26f6d7 100644 --- a/Zend/asm/jump_mips32_o32_elf_gas.S +++ b/Zend/asm/jump_mips32_o32_elf_gas.S @@ -41,6 +41,7 @@ .file "jump_mips32_o32_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 2 .type jump_fcontext,@function .ent jump_fcontext @@ -102,13 +103,13 @@ jump_fcontext: # adjust stack addiu $sp, $sp, 96 - + # return transfer_t from jump sw $a0, ($v0) # fctx of transfer_t sw $a2, 4($v0) # data of transfer_t # pass transfer_t as first arg in context function # A0 == fctx, A1 == data - move $a1, $a2 + move $a1, $a2 # jump to context jr $t9 diff --git a/Zend/asm/jump_mips64_n64_elf_gas.S b/Zend/asm/jump_mips64_n64_elf_gas.S index e338912bb6e8..60027fe61734 100644 --- a/Zend/asm/jump_mips64_n64_elf_gas.S +++ b/Zend/asm/jump_mips64_n64_elf_gas.S @@ -48,6 +48,7 @@ .file "jump_mips64_n64_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 3 .type jump_fcontext,@function .ent jump_fcontext diff --git a/Zend/asm/jump_ppc32_sysv_elf_gas.S b/Zend/asm/jump_ppc32_sysv_elf_gas.S index 48e09c935e09..e31336640065 100644 --- a/Zend/asm/jump_ppc32_sysv_elf_gas.S +++ b/Zend/asm/jump_ppc32_sysv_elf_gas.S @@ -53,6 +53,7 @@ .file "jump_ppc32_sysv_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .align 2 .type jump_fcontext,@function jump_fcontext: diff --git a/Zend/asm/jump_ppc32_sysv_macho_gas.S b/Zend/asm/jump_ppc32_sysv_macho_gas.S index fef90c295f8c..c2a2061e8774 100644 --- a/Zend/asm/jump_ppc32_sysv_macho_gas.S +++ b/Zend/asm/jump_ppc32_sysv_macho_gas.S @@ -68,12 +68,13 @@ * ------------------------------------------------- * * | 256 | | * * ------------------------------------------------- * - * | DATA| | * + * | DATA| | * * ------------------------------------------------- * * * *******************************************************/ .text +.private_extern _jump_fcontext .globl _jump_fcontext .align 2 _jump_fcontext: @@ -193,7 +194,7 @@ _jump_fcontext: ; adjust stack addi r1, r1, 244 - ; return transfer_t + ; return transfer_t stw r6, 0(r3) stw r5, 4(r3) diff --git a/Zend/asm/jump_ppc64_sysv_elf_gas.S b/Zend/asm/jump_ppc64_sysv_elf_gas.S index 28907db32b8c..debeb3466404 100644 --- a/Zend/asm/jump_ppc64_sysv_elf_gas.S +++ b/Zend/asm/jump_ppc64_sysv_elf_gas.S @@ -68,6 +68,7 @@ .file "jump_ppc64_sysv_elf_gas.S" .globl jump_fcontext +.hidden jump_fcontext #if _CALL_ELF == 2 .text .align 2 @@ -97,7 +98,7 @@ jump_fcontext: # endif #endif # reserve space on stack - subi %r1, %r1, 184 + subi %r1, %r1, 200 #if _CALL_ELF != 2 std %r2, 0(%r1) # save TOC @@ -133,6 +134,10 @@ jump_fcontext: # save LR as PC std %r0, 176(%r1) + # Save VS63 + li %r31, 184 + stvx %v31, %r1, %r31 + # store RSP (pointing to context-data) in R6 mr %r6, %r1 @@ -145,6 +150,11 @@ jump_fcontext: ld %r2, 0(%r1) # restore TOC #endif + + # Restore VS63 + li %r31, 184 + lvx %v31, %r1, %r31 + ld %r14, 8(%r1) # restore R14 ld %r15, 16(%r1) # restore R15 ld %r16, 24(%r1) # restore R16 @@ -180,7 +190,7 @@ jump_fcontext: mtctr %r12 # adjust stack - addi %r1, %r1, 184 + addi %r1, %r1, 200 #if _CALL_ELF == 2 # copy transfer_t into transfer_fn arg registers diff --git a/Zend/asm/jump_ppc64_sysv_macho_gas.S b/Zend/asm/jump_ppc64_sysv_macho_gas.S index dcc6c645db61..e4d8944b563d 100644 --- a/Zend/asm/jump_ppc64_sysv_macho_gas.S +++ b/Zend/asm/jump_ppc64_sysv_macho_gas.S @@ -68,6 +68,7 @@ .text .align 2 +.private_extern _jump_fcontext .globl _jump_fcontext _jump_fcontext: diff --git a/Zend/asm/jump_riscv64_sysv_elf_gas.S b/Zend/asm/jump_riscv64_sysv_elf_gas.S index 5417e5d5e349..879eb7efee62 100644 --- a/Zend/asm/jump_riscv64_sysv_elf_gas.S +++ b/Zend/asm/jump_riscv64_sysv_elf_gas.S @@ -61,6 +61,7 @@ .text .align 1 .global jump_fcontext +.hidden jump_fcontext .type jump_fcontext, %function jump_fcontext: # prepare stack for GP + FPU diff --git a/Zend/asm/jump_s390x_sysv_elf_gas.S b/Zend/asm/jump_s390x_sysv_elf_gas.S index fa71467756d2..59bc58bf370b 100644 --- a/Zend/asm/jump_s390x_sysv_elf_gas.S +++ b/Zend/asm/jump_s390x_sysv_elf_gas.S @@ -46,6 +46,7 @@ .text .align 8 .global jump_fcontext +.hidden jump_fcontext .type jump_fcontext, @function #define ARG_OFFSET 0 diff --git a/Zend/asm/jump_x86_64_sysv_elf_gas.S b/Zend/asm/jump_x86_64_sysv_elf_gas.S index be264bdc2e2b..2eff59a380cb 100644 --- a/Zend/asm/jump_x86_64_sysv_elf_gas.S +++ b/Zend/asm/jump_x86_64_sysv_elf_gas.S @@ -44,6 +44,7 @@ .file "jump_x86_64_sysv_elf_gas.S" .text .globl jump_fcontext +.hidden jump_fcontext .type jump_fcontext,@function .align 16 jump_fcontext: @@ -67,14 +68,6 @@ jump_fcontext: movq %rbx, 0x30(%rsp) /* save RBX */ movq %rbp, 0x38(%rsp) /* save RBP */ -#if BOOST_CONTEXT_SHADOW_STACK - /* grow the stack to reserve space for shadow stack pointer(SSP) */ - leaq -0x8(%rsp), %rsp - /* read the current SSP and store it */ - rdsspq %rcx - movq %rcx, (%rsp) -#endif - #if BOOST_CONTEXT_SHADOW_STACK /* grow the stack to reserve space for shadow stack pointer(SSP) */ leaq -0x8(%rsp), %rsp diff --git a/Zend/asm/jump_x86_64_sysv_macho_gas.S b/Zend/asm/jump_x86_64_sysv_macho_gas.S index afc3e5c126f9..673daa61dfaa 100644 --- a/Zend/asm/jump_x86_64_sysv_macho_gas.S +++ b/Zend/asm/jump_x86_64_sysv_macho_gas.S @@ -25,6 +25,7 @@ ****************************************************************************************/ .text +.private_extern _jump_fcontext .globl _jump_fcontext .align 8 _jump_fcontext: diff --git a/Zend/asm/make_arm64_aapcs_elf_gas.S b/Zend/asm/make_arm64_aapcs_elf_gas.S index 66cfb2da17ea..246525402f5c 100644 --- a/Zend/asm/make_arm64_aapcs_elf_gas.S +++ b/Zend/asm/make_arm64_aapcs_elf_gas.S @@ -53,10 +53,29 @@ .file "make_arm64_aapcs_elf_gas.S" .text +#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) +/* Mark this object as requiring BTI, enabling the linker to set BTI on the output */ + .pushsection .note.gnu.property, "a", %note + .p2align 3 + .long 4 /* namesz */ + .long 16 /* descsz (16 bytes) */ + .long 5 /* type = NT_GNU_PROPERTY_TYPE_0 */ + .asciz "GNU" + .p2align 3 + .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ + .long 4 /* datasz = 4 */ + .long 1 /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI */ + .long 0 /* pad to 8-byte alignment */ + .popsection +#endif .align 2 .global make_fcontext +.hidden make_fcontext .type make_fcontext, %function make_fcontext: +#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) + hint #34 /* bti c */ +#endif # shift address in x0 (allocated stack) to lower 16 byte boundary and x0, x0, ~0xF diff --git a/Zend/asm/make_arm64_aapcs_macho_gas.S b/Zend/asm/make_arm64_aapcs_macho_gas.S index b30b1e3e5bbb..a6a1314c0dcd 100644 --- a/Zend/asm/make_arm64_aapcs_macho_gas.S +++ b/Zend/asm/make_arm64_aapcs_macho_gas.S @@ -52,6 +52,7 @@ *******************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext .balign 16 diff --git a/Zend/asm/make_arm64_aapcs_pe_armasm.asm b/Zend/asm/make_arm64_aapcs_pe_armasm.asm index 50f9b69876be..c384af039fc4 100644 --- a/Zend/asm/make_arm64_aapcs_pe_armasm.asm +++ b/Zend/asm/make_arm64_aapcs_pe_armasm.asm @@ -73,7 +73,7 @@ make_fcontext proc ; save top address of context_stack as 'base' str x3, [x0, #0xa0] - ; save bottom address of context-stack as 'limit' and 'dealloction stack' + ; save bottom address of context-stack as 'limit' and 'deallocation stack' sub x3, x3, x1 stp x3, x3, [x0, #0xa8] ; save 0 as 'fiber data' diff --git a/Zend/asm/make_arm_aapcs_elf_gas.S b/Zend/asm/make_arm_aapcs_elf_gas.S index 98ae64b43f9d..2367c75a6a77 100644 --- a/Zend/asm/make_arm_aapcs_elf_gas.S +++ b/Zend/asm/make_arm_aapcs_elf_gas.S @@ -41,26 +41,47 @@ .file "make_arm_aapcs_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 2 .type make_fcontext,%function .syntax unified make_fcontext: @ shift address in A1 to lower 16 byte boundary + + #if __ARM_ARCH >= 7 bic a1, a1, #15 + #else + lsrs a1, a1, #4 + lsls a1, a1, #4 + #endif @ reserve space for context-data on context-stack + #if __ARM_ARCH >= 7 sub a1, a1, #124 + #else + subs a1, #124 + #endif @ third arg of make_fcontext() == address of context-function str a3, [a1, #104] @ compute address of returned transfer_t + #if __ARM_ARCH >= 7 add a2, a1, #108 + #else + mov a2, a1 + adds a2, #108 + #endif mov a3, a2 str a3, [a1, #64] + @ compute abs address of label finish + #if __ARM_ARCH >= 7 adr a2, finish + #else + ldr a2, =finish + #endif @ save address of finish as return-address for context-function @ will be entered after context-function returns str a2, [a1, #100] @@ -72,7 +93,13 @@ make_fcontext: finish: @ exit code is zero + #if __ARM_ARCH >=7 mov a1, #0 + #else + movs r3, #0 + movs r0, r3 + #endif + @ exit application bl _exit@PLT .size make_fcontext,.-make_fcontext diff --git a/Zend/asm/make_arm_aapcs_macho_gas.S b/Zend/asm/make_arm_aapcs_macho_gas.S index c909ae9d43a2..de934075d247 100644 --- a/Zend/asm/make_arm_aapcs_macho_gas.S +++ b/Zend/asm/make_arm_aapcs_macho_gas.S @@ -39,6 +39,7 @@ *******************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext .align 2 _make_fcontext: diff --git a/Zend/asm/make_i386_ms_pe_masm.asm b/Zend/asm/make_i386_ms_pe_masm.asm index 5246465cb975..3879396390f2 100644 --- a/Zend/asm/make_i386_ms_pe_masm.asm +++ b/Zend/asm/make_i386_ms_pe_masm.asm @@ -53,7 +53,7 @@ make_fcontext PROC BOOST_CONTEXT_EXPORT mov [eax+014h], ecx ; second arg of make_fcontext() == size of context-stack mov edx, [esp+08h] - ; negate stack size for LEA instruction (== substraction) + ; negate stack size for LEA instruction (== subtraction) neg edx ; compute bottom address of context stack (limit) lea ecx, [ecx+edx] diff --git a/Zend/asm/make_i386_sysv_elf_gas.S b/Zend/asm/make_i386_sysv_elf_gas.S index c6e0b36558a6..992bae019af2 100644 --- a/Zend/asm/make_i386_sysv_elf_gas.S +++ b/Zend/asm/make_i386_sysv_elf_gas.S @@ -31,6 +31,7 @@ .file "make_i386_sysv_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 2 .type make_fcontext,@function make_fcontext: diff --git a/Zend/asm/make_i386_sysv_macho_gas.S b/Zend/asm/make_i386_sysv_macho_gas.S index 519e406248bb..01076129bcf5 100644 --- a/Zend/asm/make_i386_sysv_macho_gas.S +++ b/Zend/asm/make_i386_sysv_macho_gas.S @@ -25,6 +25,7 @@ ****************************************************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext .align 2 _make_fcontext: @@ -69,7 +70,7 @@ _make_fcontext: addl $finish-2b, %ecx /* save address of finish as return-address for context-function */ /* will be entered after context-function returns */ - movl %ecx, 0x14(%eax) + movl %ecx, 0x14(%eax) ret /* return pointer to context-data */ diff --git a/Zend/asm/make_loongarch64_sysv_elf_gas.S b/Zend/asm/make_loongarch64_sysv_elf_gas.S index 55062702f18d..a067baded56f 100644 --- a/Zend/asm/make_loongarch64_sysv_elf_gas.S +++ b/Zend/asm/make_loongarch64_sysv_elf_gas.S @@ -41,6 +41,7 @@ .file "make_loongarch64_sysv_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 2 .type make_fcontext,@function make_fcontext: diff --git a/Zend/asm/make_mips32_o32_elf_gas.S b/Zend/asm/make_mips32_o32_elf_gas.S index 4e11e3d05825..54742f3a8be2 100644 --- a/Zend/asm/make_mips32_o32_elf_gas.S +++ b/Zend/asm/make_mips32_o32_elf_gas.S @@ -41,6 +41,7 @@ .file "make_mips32_o32_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 2 .type make_fcontext,@function .ent make_fcontext diff --git a/Zend/asm/make_mips64_n64_elf_gas.S b/Zend/asm/make_mips64_n64_elf_gas.S index 7bb30b14dee7..c43f2ff368f9 100644 --- a/Zend/asm/make_mips64_n64_elf_gas.S +++ b/Zend/asm/make_mips64_n64_elf_gas.S @@ -48,6 +48,7 @@ .file "make_mips64_n64_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 3 .type make_fcontext,@function .ent make_fcontext @@ -69,7 +70,7 @@ make_fcontext: # save global pointer in context-data sd $gp, 136($v0) - # psudo instruction compute abs address of label finish based on GP + # pseudo instruction compute abs address of label finish based on GP dla $t9, finish # save address of finish as return-address for context-function diff --git a/Zend/asm/make_ppc32_sysv_elf_gas.S b/Zend/asm/make_ppc32_sysv_elf_gas.S index 9616c4ca9b46..0dd77719354b 100644 --- a/Zend/asm/make_ppc32_sysv_elf_gas.S +++ b/Zend/asm/make_ppc32_sysv_elf_gas.S @@ -53,6 +53,7 @@ .file "make_ppc32_sysv_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .align 2 .type make_fcontext,@function make_fcontext: diff --git a/Zend/asm/make_ppc32_sysv_macho_gas.S b/Zend/asm/make_ppc32_sysv_macho_gas.S index 1102ee90ef07..75d1c80e5263 100644 --- a/Zend/asm/make_ppc32_sysv_macho_gas.S +++ b/Zend/asm/make_ppc32_sysv_macho_gas.S @@ -68,12 +68,13 @@ * ------------------------------------------------- * * | 256 | | * * ------------------------------------------------- * - * | DATA| | * + * | DATA| | * * ------------------------------------------------- * * * *******************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext .align 2 _make_fcontext: @@ -101,8 +102,8 @@ _make_fcontext: ; compute address of returned transfer_t addi r0, r3, 252 - mr r4, r0 - stw r4, 228(r3) + mr r4, r0 + stw r4, 228(r3) ; load LR mflr r0 diff --git a/Zend/asm/make_ppc64_sysv_elf_gas.S b/Zend/asm/make_ppc64_sysv_elf_gas.S index c4d7ee59826a..f513d3639ea9 100644 --- a/Zend/asm/make_ppc64_sysv_elf_gas.S +++ b/Zend/asm/make_ppc64_sysv_elf_gas.S @@ -68,6 +68,7 @@ .file "make_ppc64_sysv_elf_gas.S" .globl make_fcontext +.hidden make_fcontext #if _CALL_ELF == 2 .text .align 2 diff --git a/Zend/asm/make_ppc64_sysv_macho_gas.S b/Zend/asm/make_ppc64_sysv_macho_gas.S index dd7bf2c5c0c0..d8cdd2d080db 100644 --- a/Zend/asm/make_ppc64_sysv_macho_gas.S +++ b/Zend/asm/make_ppc64_sysv_macho_gas.S @@ -67,6 +67,7 @@ *******************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext _make_fcontext: ; save return address into R6 diff --git a/Zend/asm/make_riscv64_sysv_elf_gas.S b/Zend/asm/make_riscv64_sysv_elf_gas.S index 5322e0fdbdec..6d97c59e877e 100644 --- a/Zend/asm/make_riscv64_sysv_elf_gas.S +++ b/Zend/asm/make_riscv64_sysv_elf_gas.S @@ -61,6 +61,7 @@ .text .align 1 .global make_fcontext +.hidden make_fcontext .type make_fcontext, %function make_fcontext: # shift address in a0 (allocated stack) to lower 16 byte boundary diff --git a/Zend/asm/make_s390x_sysv_elf_gas.S b/Zend/asm/make_s390x_sysv_elf_gas.S index 4dd423e2a44c..4d6aa62c0ae1 100644 --- a/Zend/asm/make_s390x_sysv_elf_gas.S +++ b/Zend/asm/make_s390x_sysv_elf_gas.S @@ -46,6 +46,7 @@ .text .align 8 .global make_fcontext +.hidden make_fcontext .type make_fcontext, @function #define ARG_OFFSET 0 diff --git a/Zend/asm/make_sparc64_sysv_elf_gas.S b/Zend/asm/make_sparc64_sysv_elf_gas.S index 3e7ee809c918..3d504471afd5 100644 --- a/Zend/asm/make_sparc64_sysv_elf_gas.S +++ b/Zend/asm/make_sparc64_sysv_elf_gas.S @@ -45,7 +45,7 @@ make_fcontext: add %l0, (trampoline - 1b - 8), %l0 stx %l0, [%i0 + I7] - # Save framepointer to first stack frame but first substract the BIAS + # Save framepointer to first stack frame but first subtract the BIAS add %i0, CC64FSZ - BIAS, %l0 stx %l0, [%i0 + SP] diff --git a/Zend/asm/make_x86_64_ms_pe_gas.S b/Zend/asm/make_x86_64_ms_pe_gas.S index 958a2a7b6d0e..7146637c0319 100644 --- a/Zend/asm/make_x86_64_ms_pe_gas.S +++ b/Zend/asm/make_x86_64_ms_pe_gas.S @@ -113,7 +113,7 @@ make_fcontext: /* save top address of context stack as 'base' */ movq %rcx, 0xc8(%rax) /* second arg of make_fcontext() == size of context-stack */ - /* negate stack size for LEA instruction (== substraction) */ + /* negate stack size for LEA instruction (== subtraction) */ negq %rdx /* compute bottom address of context stack (limit) */ leaq (%rcx,%rdx), %rcx @@ -151,7 +151,7 @@ make_fcontext: trampoline: /* store return address on stack */ - /* fix stack alignment */ + /* fix stack alignment */ pushq %rbp /* jump to context-function */ jmp *%rbx diff --git a/Zend/asm/make_x86_64_ms_pe_masm.asm b/Zend/asm/make_x86_64_ms_pe_masm.asm index 8f6c959a8376..a6c2b147e446 100644 --- a/Zend/asm/make_x86_64_ms_pe_masm.asm +++ b/Zend/asm/make_x86_64_ms_pe_masm.asm @@ -110,7 +110,7 @@ make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME ; save top address of context stack as 'base' mov [rax+0c8h], rcx ; second arg of make_fcontext() == size of context-stack - ; negate stack size for LEA instruction (== substraction) + ; negate stack size for LEA instruction (== subtraction) neg rdx ; compute bottom address of context stack (limit) lea rcx, [rcx+rdx] @@ -141,7 +141,7 @@ make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME ; compute abs address of label finish lea rcx, finish ; save address of finish as return-address for context-function in RBP - ; will be entered after context-function returns + ; will be entered after context-function returns mov [rax+0108h], rcx ret ; return pointer to context-data diff --git a/Zend/asm/make_x86_64_sysv_elf_gas.S b/Zend/asm/make_x86_64_sysv_elf_gas.S index b0d0c0341ef3..cabebff6e626 100644 --- a/Zend/asm/make_x86_64_sysv_elf_gas.S +++ b/Zend/asm/make_x86_64_sysv_elf_gas.S @@ -44,6 +44,7 @@ .file "make_x86_64_sysv_elf_gas.S" .text .globl make_fcontext +.hidden make_fcontext .type make_fcontext,@function .align 16 make_fcontext: @@ -76,7 +77,7 @@ make_fcontext: #if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR) /* save stack guard */ movq %fs:0x28, %rcx /* read stack guard from TLS record */ - movq %rcx, 0x8(%rsp) /* save stack guard */ + movq %rcx, 0x8(%rax) /* save stack guard */ #endif /* compute abs address of label trampoline */ @@ -91,35 +92,6 @@ make_fcontext: /* will be entered after context-function returns */ movq %rcx, 0x38(%rax) -#if BOOST_CONTEXT_SHADOW_STACK - /* Populate the shadow stack and normal stack */ - /* get original SSP */ - rdsspq %r8 - /* restore new shadow stack */ - rstorssp -0x8(%r9) - /* save the restore token on the original shadow stack */ - saveprevssp - /* push the address of "jmp trampoline" to the new shadow stack */ - /* as well as the stack */ - call 1f - jmp trampoline -1: - /* save address of "jmp trampoline" as return-address */ - /* for context-function */ - pop 0x38(%rax) - /* Get the new SSP. */ - rdsspq %r9 - /* restore original shadow stack */ - rstorssp -0x8(%r8) - /* save the restore token on the new shadow stack. */ - saveprevssp - - /* reserve space for the new SSP */ - leaq -0x8(%rax), %rax - /* save the new SSP to this fcontext */ - movq %r9, (%rax) -#endif - #if BOOST_CONTEXT_SHADOW_STACK /* Populate the shadow stack */ @@ -161,6 +133,8 @@ make_fcontext: ret /* return pointer to context-data */ trampoline: + .cfi_startproc + .cfi_undefined rip /* store return address on stack */ /* fix stack alignment */ _CET_ENDBR @@ -175,6 +149,7 @@ trampoline: #endif /* jump to context-function */ jmp *%rbx + .cfi_endproc finish: _CET_ENDBR diff --git a/Zend/asm/make_x86_64_sysv_macho_gas.S b/Zend/asm/make_x86_64_sysv_macho_gas.S index 5d6c5431c598..06357f678ac9 100644 --- a/Zend/asm/make_x86_64_sysv_macho_gas.S +++ b/Zend/asm/make_x86_64_sysv_macho_gas.S @@ -25,6 +25,7 @@ ****************************************************************************************/ .text +.private_extern _make_fcontext .globl _make_fcontext .align 8 _make_fcontext: diff --git a/Zend/asm/save_xmm_x86_64_ms_masm.asm b/Zend/asm/save_xmm_x86_64_ms_masm.asm index 1569d6bdb0e8..0af7c346095d 100644 --- a/Zend/asm/save_xmm_x86_64_ms_masm.asm +++ b/Zend/asm/save_xmm_x86_64_ms_masm.asm @@ -9,34 +9,34 @@ EXTERN execute_ex_real:PROC ; save the preserved registers when re-entering the VM from JIT code. ; See GH-18136. execute_ex PROC EXPORT FRAME - ; 10 floating points numbers + ; 10 XMM registers ; 32 bytes shadow space ; 8 bytes to align after the return address - sub rsp, 8*10 + 32 + 8 - .allocstack 8*10 + 32 + 8 + sub rsp, 16*10 + 32 + 8 + .allocstack 16*10 + 32 + 8 .endprolog - movsd qword ptr [rsp + 32 + 8*0], xmm6 - movsd qword ptr [rsp + 32 + 8*1], xmm7 - movsd qword ptr [rsp + 32 + 8*2], xmm8 - movsd qword ptr [rsp + 32 + 8*3], xmm9 - movsd qword ptr [rsp + 32 + 8*4], xmm10 - movsd qword ptr [rsp + 32 + 8*5], xmm11 - movsd qword ptr [rsp + 32 + 8*6], xmm12 - movsd qword ptr [rsp + 32 + 8*7], xmm13 - movsd qword ptr [rsp + 32 + 8*8], xmm14 - movsd qword ptr [rsp + 32 + 8*9], xmm15 + movaps xmmword ptr [rsp + 32 + 16*0], xmm6 + movaps xmmword ptr [rsp + 32 + 16*1], xmm7 + movaps xmmword ptr [rsp + 32 + 16*2], xmm8 + movaps xmmword ptr [rsp + 32 + 16*3], xmm9 + movaps xmmword ptr [rsp + 32 + 16*4], xmm10 + movaps xmmword ptr [rsp + 32 + 16*5], xmm11 + movaps xmmword ptr [rsp + 32 + 16*6], xmm12 + movaps xmmword ptr [rsp + 32 + 16*7], xmm13 + movaps xmmword ptr [rsp + 32 + 16*8], xmm14 + movaps xmmword ptr [rsp + 32 + 16*9], xmm15 call execute_ex_real - movsd xmm6, qword ptr [rsp + 32 + 8*0] - movsd xmm7, qword ptr [rsp + 32 + 8*1] - movsd xmm8, qword ptr [rsp + 32 + 8*2] - movsd xmm9, qword ptr [rsp + 32 + 8*3] - movsd xmm10, qword ptr [rsp + 32 + 8*4] - movsd xmm11, qword ptr [rsp + 32 + 8*5] - movsd xmm12, qword ptr [rsp + 32 + 8*6] - movsd xmm13, qword ptr [rsp + 32 + 8*7] - movsd xmm14, qword ptr [rsp + 32 + 8*8] - movsd xmm15, qword ptr [rsp + 32 + 8*9] - add rsp, 8*10 + 32 + 8 + movaps xmm6, xmmword ptr [rsp + 32 + 16*0] + movaps xmm7, xmmword ptr [rsp + 32 + 16*1] + movaps xmm8, xmmword ptr [rsp + 32 + 16*2] + movaps xmm9, xmmword ptr [rsp + 32 + 16*3] + movaps xmm10, xmmword ptr [rsp + 32 + 16*4] + movaps xmm11, xmmword ptr [rsp + 32 + 16*5] + movaps xmm12, xmmword ptr [rsp + 32 + 16*6] + movaps xmm13, xmmword ptr [rsp + 32 + 16*7] + movaps xmm14, xmmword ptr [rsp + 32 + 16*8] + movaps xmm15, xmmword ptr [rsp + 32 + 16*9] + add rsp, 16*10 + 32 + 8 ret execute_ex ENDP diff --git a/Zend/tests/GHSA-wm6j-2649-pv75.phpt b/Zend/tests/GHSA-wm6j-2649-pv75.phpt new file mode 100644 index 000000000000..c1035938bd7b --- /dev/null +++ b/Zend/tests/GHSA-wm6j-2649-pv75.phpt @@ -0,0 +1,24 @@ +--TEST-- +GHSA-wm6j-2649-pv75: Null pointer dereference in php_mb_check_encoding() via mb_ereg_search_init() +--CREDITS-- +vi3tL0u1s +--EXTENSIONS-- +mbstring +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Fatal error: Uncaught ValueError: mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "iso-8859-11" given in %s:%d +Stack trace: +#0 %s(%d): mb_regex_encoding('iso-8859-11') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 9f8e9b77003b..3bb08504f581 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -201,7 +201,7 @@ assert(0 && ($a = function &(array &$a, ?X $b = null) use($c, &$d): ?X { $s[$i] = $a[$j]; } foreach ($a as $key => &$val) { - print "$key => $val\n"; + print "{$key} => {$val}\n"; } while ($s[$i]) { $i++; @@ -299,12 +299,12 @@ assert(0 && ($a = function (): ?static { echo 1; } $x = '\'"`$a'; - $x = "'\"`$a"; - $x = `'"\`$a`; + $x = "'\"`{$a}"; + $x = `'"\`{$a}`; $x = "{$a}b"; $x = "{$a}b"; $x = " {$foo->bar} {${$foo->bar}} "; - $x = " ${---} "; + $x = " {${'---'}} "; foo(); \foo(); namespace\foo(); diff --git a/Zend/tests/assert/expect_020.phpt b/Zend/tests/assert/expect_020.phpt index d305667a28d7..2146abc96045 100644 --- a/Zend/tests/assert/expect_020.phpt +++ b/Zend/tests/assert/expect_020.phpt @@ -16,5 +16,5 @@ assert(0 && ($a = function () { --EXPECT-- assert(): assert(0 && ($a = function () { $var = 'test'; - $str = "$var, {$var[1]}, {$var}[], {$var[1]}[], {$var}[], {$var[1]}[]"; + $str = "{$var}, {$var[1]}, {$var}[], {$var[1]}[], {$var}[], {$var[1]}[]"; })) failed diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_constant.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_constant.phpt new file mode 100644 index 000000000000..9ebb8e4c0202 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_constant.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (class constant) +--FILE-- + +--EXPECTF-- +Fatal error: DemoClass::CLASS_CONSTANT has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_enum_case.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_enum_case.phpt new file mode 100644 index 000000000000..53d75412a849 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_enum_case.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (enum case) +--FILE-- + +--EXPECTF-- +Fatal error: DemoEnum::MyCase has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt index dd077f4b9cbd..494d85eaea9c 100644 --- a/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt @@ -12,6 +12,8 @@ class Base { set => $value; } + public const CLASS_CONST = ''; + public function printVal() { echo __METHOD__ . "\n"; } @@ -34,7 +36,7 @@ class DemoClass extends Base { } #[DelayedTargetValidation] - #[Override] // Does nothing here + #[Override] // Does something here public const CLASS_CONST = 'FOO'; public function __construct( diff --git a/Zend/tests/attributes/override/constants/anon_failure.phpt b/Zend/tests/attributes/override/constants/anon_failure.phpt new file mode 100644 index 000000000000..c43cedda81d7 --- /dev/null +++ b/Zend/tests/attributes/override/constants/anon_failure.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - anonymous class, no interface or parent class +--FILE-- + +--EXPECTF-- +Fatal error: class@anonymous::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/anon_interface.phpt b/Zend/tests/attributes/override/constants/anon_interface.phpt new file mode 100644 index 000000000000..b19abfbf4d3a --- /dev/null +++ b/Zend/tests/attributes/override/constants/anon_interface.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - anonymous class overrides interface +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/anon_parent.phpt b/Zend/tests/attributes/override/constants/anon_parent.phpt new file mode 100644 index 000000000000..b430705c3c9d --- /dev/null +++ b/Zend/tests/attributes/override/constants/anon_parent.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - anonymous class overrides parent class +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/basic.phpt b/Zend/tests/attributes/override/constants/basic.phpt new file mode 100644 index 000000000000..c89007022051 --- /dev/null +++ b/Zend/tests/attributes/override/constants/basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +#[\Override]: Constants - basic +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/enum_failure.phpt b/Zend/tests/attributes/override/constants/enum_failure.phpt new file mode 100644 index 000000000000..77ba225e9b9e --- /dev/null +++ b/Zend/tests/attributes/override/constants/enum_failure.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - no interface for enum constant +--FILE-- + +--EXPECTF-- +Fatal error: Demo::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/enum_failure_case.phpt b/Zend/tests/attributes/override/constants/enum_failure_case.phpt new file mode 100644 index 000000000000..2f2c6fc84a08 --- /dev/null +++ b/Zend/tests/attributes/override/constants/enum_failure_case.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - no interface for enum case +--FILE-- + +--EXPECTF-- +Fatal error: Demo::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/failure.phpt b/Zend/tests/attributes/override/constants/failure.phpt new file mode 100644 index 000000000000..be621915d927 --- /dev/null +++ b/Zend/tests/attributes/override/constants/failure.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - no interface or parent class +--FILE-- + +--EXPECTF-- +Fatal error: Demo::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/interface_failure.phpt b/Zend/tests/attributes/override/constants/interface_failure.phpt new file mode 100644 index 000000000000..0aa4d33d1301 --- /dev/null +++ b/Zend/tests/attributes/override/constants/interface_failure.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - no parent interface +--FILE-- + +--EXPECTF-- +Fatal error: IFace::I has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/trait_failure.phpt b/Zend/tests/attributes/override/constants/trait_failure.phpt new file mode 100644 index 000000000000..8d4af0e57977 --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_failure.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - on a trait, no interface or parent class +--FILE-- + +--EXPECTF-- +Fatal error: UsesTrait::T has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/trait_interface.phpt b/Zend/tests/attributes/override/constants/trait_interface.phpt new file mode 100644 index 000000000000..3a2ba799ae4e --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_interface.phpt @@ -0,0 +1,23 @@ +--TEST-- +#[\Override]: Constants - on a trait, overrides interface +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/trait_parent.phpt b/Zend/tests/attributes/override/constants/trait_parent.phpt new file mode 100644 index 000000000000..2753aaf546a2 --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_parent.phpt @@ -0,0 +1,23 @@ +--TEST-- +#[\Override]: Constants - on a trait, overrides parent class +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/trait_redeclared.phpt b/Zend/tests/attributes/override/constants/trait_redeclared.phpt new file mode 100644 index 000000000000..984f9eedb668 --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_redeclared.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Constants - trait constant redeclared, not overridden +--FILE-- + +--EXPECTF-- +Fatal error: UsesTrait::T has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/trait_redeclared_interface.phpt b/Zend/tests/attributes/override/constants/trait_redeclared_interface.phpt new file mode 100644 index 000000000000..21a1aa532249 --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_redeclared_interface.phpt @@ -0,0 +1,25 @@ +--TEST-- +#[\Override]: Constants - trait constant redeclared, overrides interface +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/trait_redeclared_parent.phpt b/Zend/tests/attributes/override/constants/trait_redeclared_parent.phpt new file mode 100644 index 000000000000..c3d1e43d2534 --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_redeclared_parent.phpt @@ -0,0 +1,25 @@ +--TEST-- +#[\Override]: Constants - trait constant redeclared, overrides parent class +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/trait_unused.phpt b/Zend/tests/attributes/override/constants/trait_unused.phpt new file mode 100644 index 000000000000..785f2888e90b --- /dev/null +++ b/Zend/tests/attributes/override/constants/trait_unused.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Constants - on a trait, unused +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/visibility_01.phpt b/Zend/tests/attributes/override/constants/visibility_01.phpt new file mode 100644 index 000000000000..49671471f758 --- /dev/null +++ b/Zend/tests/attributes/override/constants/visibility_01.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - private constant not overridden (by public constant) +--FILE-- + +--EXPECTF-- +Fatal error: Child::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/visibility_02.phpt b/Zend/tests/attributes/override/constants/visibility_02.phpt new file mode 100644 index 000000000000..c160a29a6180 --- /dev/null +++ b/Zend/tests/attributes/override/constants/visibility_02.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - private constant not overridden (by private constant) +--FILE-- + +--EXPECTF-- +Fatal error: Child::C has #[\Override] attribute, but no matching parent constant exists in %s on line %d diff --git a/Zend/tests/attributes/override/constants/visibility_03.phpt b/Zend/tests/attributes/override/constants/visibility_03.phpt new file mode 100644 index 000000000000..db460f24375e --- /dev/null +++ b/Zend/tests/attributes/override/constants/visibility_03.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - protected constant is overridden (by public constant) +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/constants/visibility_04.phpt b/Zend/tests/attributes/override/constants/visibility_04.phpt new file mode 100644 index 000000000000..0ad46b022f43 --- /dev/null +++ b/Zend/tests/attributes/override/constants/visibility_04.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Constants - protected constant is overridden (by protected constant) +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/backtrace/debug_backtrace_with_include_and_this.phpt b/Zend/tests/backtrace/debug_backtrace_with_include_and_this.phpt index 49796a9b9103..18f155611f42 100644 --- a/Zend/tests/backtrace/debug_backtrace_with_include_and_this.phpt +++ b/Zend/tests/backtrace/debug_backtrace_with_include_and_this.phpt @@ -30,7 +30,7 @@ try { } ?> --EXPECTF-- -ERR#2: include(class://non.existent.Class): Failed to open stream: "CLWrapper::stream_open" call failed @ include +ERR#2: include(): Failed to open stream: "CLWrapper::stream_open" call failed @ include ERR#2: include(): Failed opening 'class://non.existent.Class' for inclusion (include_path='%s') @ include Fatal error: Uncaught Exception: Failed loading class://non.existent.Class in %s diff --git a/Zend/tests/bug30998.phpt b/Zend/tests/bug30998.phpt index 9d8435121671..a4cd6de8f50e 100644 --- a/Zend/tests/bug30998.phpt +++ b/Zend/tests/bug30998.phpt @@ -14,6 +14,6 @@ set_error_handler('my_error'); $f = fopen("/tmp/blah", "r"); ?> --EXPECTF-- -fopen(/tmp/blah): Failed to open stream: %s (2) in %s:%d +fopen(): Failed to open stream: %s (2) in %s:%d -Warning: fopen(/tmp/blah): Failed to open stream: %s in %s on line %d +Warning: fopen(): Failed to open stream: %s in %s on line %d diff --git a/Zend/tests/bug60909_1.phpt b/Zend/tests/bug60909_1.phpt index 4404adfd54a3..bde5a381ba47 100644 --- a/Zend/tests/bug60909_1.phpt +++ b/Zend/tests/bug60909_1.phpt @@ -11,10 +11,10 @@ set_error_handler(function($errno, $errstr, $errfile, $errline){ require 'notfound.php'; ?> --EXPECTF-- -error(require(notfound.php): Failed to open stream: %s) +error(require(): Failed to open stream: %s) Fatal error: Uncaught Exception: Foo in %sbug60909_1.php:5 Stack trace: -#0 %s(%d): {closure:%s:%d}(2, 'require(notfoun...', '%s', 8) +#0 %s(%d): {closure:%s:%d}(2, 'require(): Fail...', '%s', 8) #1 %sbug60909_1.php(8): require() #2 {main} thrown in %sbug60909_1.php on line 5 diff --git a/Zend/tests/bug74093.phpt b/Zend/tests/bug74093.phpt index d9adfeefa50e..d38d6e5109c4 100644 --- a/Zend/tests/bug74093.phpt +++ b/Zend/tests/bug74093.phpt @@ -1,5 +1,6 @@ --TEST-- Bug #74093 (Maximum execution time of n+2 seconds exceed not written in error_log) +--FLAKY-- --SKIPIF-- --EXPECTF-- diff --git a/Zend/tests/clone/clone_with_014.phpt b/Zend/tests/clone/clone_with_014.phpt new file mode 100644 index 000000000000..bfbee40e163c --- /dev/null +++ b/Zend/tests/clone/clone_with_014.phpt @@ -0,0 +1,41 @@ +--TEST-- +Properties are still readonly after clone-with +--FILE-- +a = 1; + $this->b = 2; + } +} + +$test = clone(new Test(), ['a' => 3]); +var_dump($test); + +try { + $test->b = 4; +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +var_dump($test); + +?> +--EXPECT-- +object(Test)#2 (2) { + ["a"]=> + int(3) + ["b"]=> + int(2) +} +Error: Cannot modify readonly property Test::$b +object(Test)#2 (2) { + ["a"]=> + int(3) + ["b"]=> + int(2) +} diff --git a/Zend/tests/comparison/spaceship_type_compare.phpt b/Zend/tests/comparison/spaceship_type_compare.phpt new file mode 100644 index 000000000000..7382a593cc84 --- /dev/null +++ b/Zend/tests/comparison/spaceship_type_compare.phpt @@ -0,0 +1,536 @@ +--TEST-- +Compare types via <=> operator +--FILE-- + $r) { + 0 => "EQUAL", + 1 => match ($r <=> $l) { + -1 => "GREATER THAN", + 1 => "UNCOMPARABLE", + }, + -1 => "LESS THAN", + }; +} + +class test { +} + +$values = [ + 'null' => null, + 'false' => false, + 'true' => true, + 'i-5' => -5, + 'i0' => 0, + 'i10' => 10, + 'f-5' => -5.0, + 'f0' => 0.0, + 'f2.5' => 2.5, + 'f10' => 10.0, + 's""' => "", + 's"str"' => "str", + 's"-5"' => "-5", + 's"0"' => "0", + 's"2.5"' => "2.5", + 's"10"' => "10", + 'a[]' => [], + 'a[1, 2, 3]' => [1, 2, 3], + 'c"stdClass"' => new stdClass(), + 'c"test"' => new test(), + 'r"STDOUT"' => STDOUT, + 'r"STDERR"' => STDERR, +]; + +foreach($values as $l_name => $l) { + foreach($values as $r_name => $r) { + echo $l_name, ' ', cmp($l, $r), ' ', $r_name, "\n"; + } +} + +?> +--EXPECT-- +null EQUAL null +null EQUAL false +null LESS THAN true +null LESS THAN i-5 +null EQUAL i0 +null LESS THAN i10 +null LESS THAN f-5 +null EQUAL f0 +null LESS THAN f2.5 +null LESS THAN f10 +null EQUAL s"" +null LESS THAN s"str" +null LESS THAN s"-5" +null LESS THAN s"0" +null LESS THAN s"2.5" +null LESS THAN s"10" +null EQUAL a[] +null LESS THAN a[1, 2, 3] +null LESS THAN c"stdClass" +null LESS THAN c"test" +null LESS THAN r"STDOUT" +null LESS THAN r"STDERR" +false EQUAL null +false EQUAL false +false LESS THAN true +false LESS THAN i-5 +false EQUAL i0 +false LESS THAN i10 +false LESS THAN f-5 +false EQUAL f0 +false LESS THAN f2.5 +false LESS THAN f10 +false EQUAL s"" +false LESS THAN s"str" +false LESS THAN s"-5" +false EQUAL s"0" +false LESS THAN s"2.5" +false LESS THAN s"10" +false EQUAL a[] +false LESS THAN a[1, 2, 3] +false LESS THAN c"stdClass" +false LESS THAN c"test" +false LESS THAN r"STDOUT" +false LESS THAN r"STDERR" +true GREATER THAN null +true GREATER THAN false +true EQUAL true +true EQUAL i-5 +true GREATER THAN i0 +true EQUAL i10 +true EQUAL f-5 +true GREATER THAN f0 +true EQUAL f2.5 +true EQUAL f10 +true GREATER THAN s"" +true EQUAL s"str" +true EQUAL s"-5" +true GREATER THAN s"0" +true EQUAL s"2.5" +true EQUAL s"10" +true GREATER THAN a[] +true EQUAL a[1, 2, 3] +true EQUAL c"stdClass" +true EQUAL c"test" +true EQUAL r"STDOUT" +true EQUAL r"STDERR" +i-5 GREATER THAN null +i-5 GREATER THAN false +i-5 EQUAL true +i-5 EQUAL i-5 +i-5 LESS THAN i0 +i-5 LESS THAN i10 +i-5 EQUAL f-5 +i-5 LESS THAN f0 +i-5 LESS THAN f2.5 +i-5 LESS THAN f10 +i-5 GREATER THAN s"" +i-5 LESS THAN s"str" +i-5 EQUAL s"-5" +i-5 LESS THAN s"0" +i-5 LESS THAN s"2.5" +i-5 LESS THAN s"10" +i-5 LESS THAN a[] +i-5 LESS THAN a[1, 2, 3] +i-5 LESS THAN c"stdClass" +i-5 LESS THAN c"test" +i-5 LESS THAN r"STDOUT" +i-5 LESS THAN r"STDERR" +i0 EQUAL null +i0 EQUAL false +i0 LESS THAN true +i0 GREATER THAN i-5 +i0 EQUAL i0 +i0 LESS THAN i10 +i0 GREATER THAN f-5 +i0 EQUAL f0 +i0 LESS THAN f2.5 +i0 LESS THAN f10 +i0 GREATER THAN s"" +i0 LESS THAN s"str" +i0 GREATER THAN s"-5" +i0 EQUAL s"0" +i0 LESS THAN s"2.5" +i0 LESS THAN s"10" +i0 LESS THAN a[] +i0 LESS THAN a[1, 2, 3] +i0 LESS THAN c"stdClass" +i0 LESS THAN c"test" +i0 LESS THAN r"STDOUT" +i0 LESS THAN r"STDERR" +i10 GREATER THAN null +i10 GREATER THAN false +i10 EQUAL true +i10 GREATER THAN i-5 +i10 GREATER THAN i0 +i10 EQUAL i10 +i10 GREATER THAN f-5 +i10 GREATER THAN f0 +i10 GREATER THAN f2.5 +i10 EQUAL f10 +i10 GREATER THAN s"" +i10 LESS THAN s"str" +i10 GREATER THAN s"-5" +i10 GREATER THAN s"0" +i10 GREATER THAN s"2.5" +i10 EQUAL s"10" +i10 LESS THAN a[] +i10 LESS THAN a[1, 2, 3] +i10 GREATER THAN c"stdClass" +i10 GREATER THAN c"test" +i10 GREATER THAN r"STDOUT" +i10 GREATER THAN r"STDERR" +f-5 GREATER THAN null +f-5 GREATER THAN false +f-5 EQUAL true +f-5 EQUAL i-5 +f-5 LESS THAN i0 +f-5 LESS THAN i10 +f-5 EQUAL f-5 +f-5 LESS THAN f0 +f-5 LESS THAN f2.5 +f-5 LESS THAN f10 +f-5 GREATER THAN s"" +f-5 LESS THAN s"str" +f-5 EQUAL s"-5" +f-5 LESS THAN s"0" +f-5 LESS THAN s"2.5" +f-5 LESS THAN s"10" +f-5 LESS THAN a[] +f-5 LESS THAN a[1, 2, 3] +f-5 LESS THAN c"stdClass" +f-5 LESS THAN c"test" +f-5 LESS THAN r"STDOUT" +f-5 LESS THAN r"STDERR" +f0 EQUAL null +f0 EQUAL false +f0 LESS THAN true +f0 GREATER THAN i-5 +f0 EQUAL i0 +f0 LESS THAN i10 +f0 GREATER THAN f-5 +f0 EQUAL f0 +f0 LESS THAN f2.5 +f0 LESS THAN f10 +f0 GREATER THAN s"" +f0 LESS THAN s"str" +f0 GREATER THAN s"-5" +f0 EQUAL s"0" +f0 LESS THAN s"2.5" +f0 LESS THAN s"10" +f0 LESS THAN a[] +f0 LESS THAN a[1, 2, 3] +f0 LESS THAN c"stdClass" +f0 LESS THAN c"test" +f0 LESS THAN r"STDOUT" +f0 LESS THAN r"STDERR" +f2.5 GREATER THAN null +f2.5 GREATER THAN false +f2.5 EQUAL true +f2.5 GREATER THAN i-5 +f2.5 GREATER THAN i0 +f2.5 LESS THAN i10 +f2.5 GREATER THAN f-5 +f2.5 GREATER THAN f0 +f2.5 EQUAL f2.5 +f2.5 LESS THAN f10 +f2.5 GREATER THAN s"" +f2.5 LESS THAN s"str" +f2.5 GREATER THAN s"-5" +f2.5 GREATER THAN s"0" +f2.5 EQUAL s"2.5" +f2.5 LESS THAN s"10" +f2.5 LESS THAN a[] +f2.5 LESS THAN a[1, 2, 3] +f2.5 GREATER THAN c"stdClass" +f2.5 GREATER THAN c"test" +f2.5 GREATER THAN r"STDOUT" +f2.5 LESS THAN r"STDERR" +f10 GREATER THAN null +f10 GREATER THAN false +f10 EQUAL true +f10 GREATER THAN i-5 +f10 GREATER THAN i0 +f10 EQUAL i10 +f10 GREATER THAN f-5 +f10 GREATER THAN f0 +f10 GREATER THAN f2.5 +f10 EQUAL f10 +f10 GREATER THAN s"" +f10 LESS THAN s"str" +f10 GREATER THAN s"-5" +f10 GREATER THAN s"0" +f10 GREATER THAN s"2.5" +f10 EQUAL s"10" +f10 LESS THAN a[] +f10 LESS THAN a[1, 2, 3] +f10 GREATER THAN c"stdClass" +f10 GREATER THAN c"test" +f10 GREATER THAN r"STDOUT" +f10 GREATER THAN r"STDERR" +s"" EQUAL null +s"" EQUAL false +s"" LESS THAN true +s"" LESS THAN i-5 +s"" LESS THAN i0 +s"" LESS THAN i10 +s"" LESS THAN f-5 +s"" LESS THAN f0 +s"" LESS THAN f2.5 +s"" LESS THAN f10 +s"" EQUAL s"" +s"" LESS THAN s"str" +s"" LESS THAN s"-5" +s"" LESS THAN s"0" +s"" LESS THAN s"2.5" +s"" LESS THAN s"10" +s"" LESS THAN a[] +s"" LESS THAN a[1, 2, 3] +s"" LESS THAN c"stdClass" +s"" LESS THAN c"test" +s"" LESS THAN r"STDOUT" +s"" LESS THAN r"STDERR" +s"str" GREATER THAN null +s"str" GREATER THAN false +s"str" EQUAL true +s"str" GREATER THAN i-5 +s"str" GREATER THAN i0 +s"str" GREATER THAN i10 +s"str" GREATER THAN f-5 +s"str" GREATER THAN f0 +s"str" GREATER THAN f2.5 +s"str" GREATER THAN f10 +s"str" GREATER THAN s"" +s"str" EQUAL s"str" +s"str" GREATER THAN s"-5" +s"str" GREATER THAN s"0" +s"str" GREATER THAN s"2.5" +s"str" GREATER THAN s"10" +s"str" LESS THAN a[] +s"str" LESS THAN a[1, 2, 3] +s"str" LESS THAN c"stdClass" +s"str" LESS THAN c"test" +s"str" LESS THAN r"STDOUT" +s"str" LESS THAN r"STDERR" +s"-5" GREATER THAN null +s"-5" GREATER THAN false +s"-5" EQUAL true +s"-5" EQUAL i-5 +s"-5" LESS THAN i0 +s"-5" LESS THAN i10 +s"-5" EQUAL f-5 +s"-5" LESS THAN f0 +s"-5" LESS THAN f2.5 +s"-5" LESS THAN f10 +s"-5" GREATER THAN s"" +s"-5" LESS THAN s"str" +s"-5" EQUAL s"-5" +s"-5" LESS THAN s"0" +s"-5" LESS THAN s"2.5" +s"-5" LESS THAN s"10" +s"-5" LESS THAN a[] +s"-5" LESS THAN a[1, 2, 3] +s"-5" LESS THAN c"stdClass" +s"-5" LESS THAN c"test" +s"-5" LESS THAN r"STDOUT" +s"-5" LESS THAN r"STDERR" +s"0" GREATER THAN null +s"0" EQUAL false +s"0" LESS THAN true +s"0" GREATER THAN i-5 +s"0" EQUAL i0 +s"0" LESS THAN i10 +s"0" GREATER THAN f-5 +s"0" EQUAL f0 +s"0" LESS THAN f2.5 +s"0" LESS THAN f10 +s"0" GREATER THAN s"" +s"0" LESS THAN s"str" +s"0" GREATER THAN s"-5" +s"0" EQUAL s"0" +s"0" LESS THAN s"2.5" +s"0" LESS THAN s"10" +s"0" LESS THAN a[] +s"0" LESS THAN a[1, 2, 3] +s"0" LESS THAN c"stdClass" +s"0" LESS THAN c"test" +s"0" LESS THAN r"STDOUT" +s"0" LESS THAN r"STDERR" +s"2.5" GREATER THAN null +s"2.5" GREATER THAN false +s"2.5" EQUAL true +s"2.5" GREATER THAN i-5 +s"2.5" GREATER THAN i0 +s"2.5" LESS THAN i10 +s"2.5" GREATER THAN f-5 +s"2.5" GREATER THAN f0 +s"2.5" EQUAL f2.5 +s"2.5" LESS THAN f10 +s"2.5" GREATER THAN s"" +s"2.5" LESS THAN s"str" +s"2.5" GREATER THAN s"-5" +s"2.5" GREATER THAN s"0" +s"2.5" EQUAL s"2.5" +s"2.5" LESS THAN s"10" +s"2.5" LESS THAN a[] +s"2.5" LESS THAN a[1, 2, 3] +s"2.5" LESS THAN c"stdClass" +s"2.5" LESS THAN c"test" +s"2.5" GREATER THAN r"STDOUT" +s"2.5" LESS THAN r"STDERR" +s"10" GREATER THAN null +s"10" GREATER THAN false +s"10" EQUAL true +s"10" GREATER THAN i-5 +s"10" GREATER THAN i0 +s"10" EQUAL i10 +s"10" GREATER THAN f-5 +s"10" GREATER THAN f0 +s"10" GREATER THAN f2.5 +s"10" EQUAL f10 +s"10" GREATER THAN s"" +s"10" LESS THAN s"str" +s"10" GREATER THAN s"-5" +s"10" GREATER THAN s"0" +s"10" GREATER THAN s"2.5" +s"10" EQUAL s"10" +s"10" LESS THAN a[] +s"10" LESS THAN a[1, 2, 3] +s"10" LESS THAN c"stdClass" +s"10" LESS THAN c"test" +s"10" GREATER THAN r"STDOUT" +s"10" GREATER THAN r"STDERR" +a[] EQUAL null +a[] EQUAL false +a[] LESS THAN true +a[] GREATER THAN i-5 +a[] GREATER THAN i0 +a[] GREATER THAN i10 +a[] GREATER THAN f-5 +a[] GREATER THAN f0 +a[] GREATER THAN f2.5 +a[] GREATER THAN f10 +a[] GREATER THAN s"" +a[] GREATER THAN s"str" +a[] GREATER THAN s"-5" +a[] GREATER THAN s"0" +a[] GREATER THAN s"2.5" +a[] GREATER THAN s"10" +a[] EQUAL a[] +a[] LESS THAN a[1, 2, 3] +a[] LESS THAN c"stdClass" +a[] LESS THAN c"test" +a[] GREATER THAN r"STDOUT" +a[] GREATER THAN r"STDERR" +a[1, 2, 3] GREATER THAN null +a[1, 2, 3] GREATER THAN false +a[1, 2, 3] EQUAL true +a[1, 2, 3] GREATER THAN i-5 +a[1, 2, 3] GREATER THAN i0 +a[1, 2, 3] GREATER THAN i10 +a[1, 2, 3] GREATER THAN f-5 +a[1, 2, 3] GREATER THAN f0 +a[1, 2, 3] GREATER THAN f2.5 +a[1, 2, 3] GREATER THAN f10 +a[1, 2, 3] GREATER THAN s"" +a[1, 2, 3] GREATER THAN s"str" +a[1, 2, 3] GREATER THAN s"-5" +a[1, 2, 3] GREATER THAN s"0" +a[1, 2, 3] GREATER THAN s"2.5" +a[1, 2, 3] GREATER THAN s"10" +a[1, 2, 3] GREATER THAN a[] +a[1, 2, 3] EQUAL a[1, 2, 3] +a[1, 2, 3] LESS THAN c"stdClass" +a[1, 2, 3] LESS THAN c"test" +a[1, 2, 3] GREATER THAN r"STDOUT" +a[1, 2, 3] GREATER THAN r"STDERR" +c"stdClass" GREATER THAN null +c"stdClass" GREATER THAN false +c"stdClass" EQUAL true +c"stdClass" GREATER THAN i-5 +c"stdClass" GREATER THAN i0 +c"stdClass" LESS THAN i10 +c"stdClass" GREATER THAN f-5 +c"stdClass" GREATER THAN f0 +c"stdClass" LESS THAN f2.5 +c"stdClass" LESS THAN f10 +c"stdClass" GREATER THAN s"" +c"stdClass" GREATER THAN s"str" +c"stdClass" GREATER THAN s"-5" +c"stdClass" GREATER THAN s"0" +c"stdClass" GREATER THAN s"2.5" +c"stdClass" GREATER THAN s"10" +c"stdClass" GREATER THAN a[] +c"stdClass" GREATER THAN a[1, 2, 3] +c"stdClass" EQUAL c"stdClass" +c"stdClass" UNCOMPARABLE c"test" +c"stdClass" GREATER THAN r"STDOUT" +c"stdClass" GREATER THAN r"STDERR" +c"test" GREATER THAN null +c"test" GREATER THAN false +c"test" EQUAL true +c"test" GREATER THAN i-5 +c"test" GREATER THAN i0 +c"test" LESS THAN i10 +c"test" GREATER THAN f-5 +c"test" GREATER THAN f0 +c"test" LESS THAN f2.5 +c"test" LESS THAN f10 +c"test" GREATER THAN s"" +c"test" GREATER THAN s"str" +c"test" GREATER THAN s"-5" +c"test" GREATER THAN s"0" +c"test" GREATER THAN s"2.5" +c"test" GREATER THAN s"10" +c"test" GREATER THAN a[] +c"test" GREATER THAN a[1, 2, 3] +c"test" UNCOMPARABLE c"stdClass" +c"test" EQUAL c"test" +c"test" GREATER THAN r"STDOUT" +c"test" GREATER THAN r"STDERR" +r"STDOUT" GREATER THAN null +r"STDOUT" GREATER THAN false +r"STDOUT" EQUAL true +r"STDOUT" GREATER THAN i-5 +r"STDOUT" GREATER THAN i0 +r"STDOUT" LESS THAN i10 +r"STDOUT" GREATER THAN f-5 +r"STDOUT" GREATER THAN f0 +r"STDOUT" LESS THAN f2.5 +r"STDOUT" LESS THAN f10 +r"STDOUT" GREATER THAN s"" +r"STDOUT" GREATER THAN s"str" +r"STDOUT" GREATER THAN s"-5" +r"STDOUT" GREATER THAN s"0" +r"STDOUT" LESS THAN s"2.5" +r"STDOUT" LESS THAN s"10" +r"STDOUT" LESS THAN a[] +r"STDOUT" LESS THAN a[1, 2, 3] +r"STDOUT" LESS THAN c"stdClass" +r"STDOUT" LESS THAN c"test" +r"STDOUT" EQUAL r"STDOUT" +r"STDOUT" LESS THAN r"STDERR" +r"STDERR" GREATER THAN null +r"STDERR" GREATER THAN false +r"STDERR" EQUAL true +r"STDERR" GREATER THAN i-5 +r"STDERR" GREATER THAN i0 +r"STDERR" LESS THAN i10 +r"STDERR" GREATER THAN f-5 +r"STDERR" GREATER THAN f0 +r"STDERR" GREATER THAN f2.5 +r"STDERR" LESS THAN f10 +r"STDERR" GREATER THAN s"" +r"STDERR" GREATER THAN s"str" +r"STDERR" GREATER THAN s"-5" +r"STDERR" GREATER THAN s"0" +r"STDERR" GREATER THAN s"2.5" +r"STDERR" LESS THAN s"10" +r"STDERR" LESS THAN a[] +r"STDERR" LESS THAN a[1, 2, 3] +r"STDERR" LESS THAN c"stdClass" +r"STDERR" LESS THAN c"test" +r"STDERR" GREATER THAN r"STDOUT" +r"STDERR" EQUAL r"STDERR" diff --git a/Zend/tests/debug_info/debug_info-error-0.0.phpt b/Zend/tests/debug_info/debug_info-error-0.0.phpt index ab41b440fc88..4df25c4c95af 100644 --- a/Zend/tests/debug_info/debug_info-error-0.0.phpt +++ b/Zend/tests/debug_info/debug_info-error-0.0.phpt @@ -17,4 +17,4 @@ $c = new C(0.0); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-0.phpt b/Zend/tests/debug_info/debug_info-error-0.phpt index 37289c6468ff..c0cedf3b88e5 100644 --- a/Zend/tests/debug_info/debug_info-error-0.phpt +++ b/Zend/tests/debug_info/debug_info-error-0.phpt @@ -17,4 +17,4 @@ $c = new C(0); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-1.0.phpt b/Zend/tests/debug_info/debug_info-error-1.0.phpt index 9b168621b5ef..6af945cb0e37 100644 --- a/Zend/tests/debug_info/debug_info-error-1.0.phpt +++ b/Zend/tests/debug_info/debug_info-error-1.0.phpt @@ -17,4 +17,4 @@ $c = new C(1.0); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-1.phpt b/Zend/tests/debug_info/debug_info-error-1.phpt index ae01a6055c00..7cadd485118d 100644 --- a/Zend/tests/debug_info/debug_info-error-1.phpt +++ b/Zend/tests/debug_info/debug_info-error-1.phpt @@ -17,4 +17,4 @@ $c = new C(1); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-case-insensitive.phpt b/Zend/tests/debug_info/debug_info-error-case-insensitive.phpt new file mode 100644 index 000000000000..c2a6f4357a5c --- /dev/null +++ b/Zend/tests/debug_info/debug_info-error-case-insensitive.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing __debugInfo() magic method declared with non-canonical case +--FILE-- +val; + } + public function __construct($val) { + $this->val = $val; + } +} + +$c = new C(1); +var_dump($c); +?> +--EXPECTF-- +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-empty_str.phpt b/Zend/tests/debug_info/debug_info-error-empty_str.phpt index bbab78cd8202..21611cc9bde5 100644 --- a/Zend/tests/debug_info/debug_info-error-empty_str.phpt +++ b/Zend/tests/debug_info/debug_info-error-empty_str.phpt @@ -17,4 +17,4 @@ $c = new C(""); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-false.phpt b/Zend/tests/debug_info/debug_info-error-false.phpt index 3e48372c420c..fb5a35c2d1e3 100644 --- a/Zend/tests/debug_info/debug_info-error-false.phpt +++ b/Zend/tests/debug_info/debug_info-error-false.phpt @@ -17,4 +17,4 @@ $c = new C(false); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-object.phpt b/Zend/tests/debug_info/debug_info-error-object.phpt index 42e073999908..5cdc6b289e62 100644 --- a/Zend/tests/debug_info/debug_info-error-object.phpt +++ b/Zend/tests/debug_info/debug_info-error-object.phpt @@ -17,4 +17,4 @@ $c = new C(new stdClass); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-resource.phpt b/Zend/tests/debug_info/debug_info-error-resource.phpt index ccacce7a74b4..1fc84fe83d87 100644 --- a/Zend/tests/debug_info/debug_info-error-resource.phpt +++ b/Zend/tests/debug_info/debug_info-error-resource.phpt @@ -19,4 +19,4 @@ $c = new C(fopen("data:text/plain,Foo", 'r')); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-str.phpt b/Zend/tests/debug_info/debug_info-error-str.phpt index 85d3f63b97e0..fe4201de1c9f 100644 --- a/Zend/tests/debug_info/debug_info-error-str.phpt +++ b/Zend/tests/debug_info/debug_info-error-str.phpt @@ -17,4 +17,4 @@ $c = new C("foo"); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info-error-true.phpt b/Zend/tests/debug_info/debug_info-error-true.phpt index 3843c6a7a14a..12bb7329a856 100644 --- a/Zend/tests/debug_info/debug_info-error-true.phpt +++ b/Zend/tests/debug_info/debug_info-error-true.phpt @@ -17,4 +17,4 @@ $c = new C(true); var_dump($c); ?> --EXPECTF-- -Fatal error: __debuginfo() must return an array in %s on line %d +Fatal error: __debugInfo() must return an array in %s on line %d diff --git a/Zend/tests/debug_info/debug_info.phpt b/Zend/tests/debug_info/debug_info.phpt index bff5876777ba..e7bb4d48aec6 100644 --- a/Zend/tests/debug_info/debug_info.phpt +++ b/Zend/tests/debug_info/debug_info.phpt @@ -21,6 +21,12 @@ class Bar { } } +class Baz { + public function __debugInfo(): ?array { + return null; + } +} + $f = new Foo; var_dump($f); @@ -28,6 +34,7 @@ $b = new Bar; var_dump($b); ?> --EXPECTF-- +Deprecated: Returning null from Baz::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d object(Foo)#%d (3) { ["a"]=> int(1) diff --git a/Zend/tests/display_error_function_args.phpt b/Zend/tests/display_error_function_args.phpt new file mode 100644 index 000000000000..03530eb98189 --- /dev/null +++ b/Zend/tests/display_error_function_args.phpt @@ -0,0 +1,30 @@ +--TEST-- +Displaying function arguments in errors +--INI-- +error_include_args=On +--FILE-- + "123456789012345678901" . chr(0), "cost" => 4]; +password_hash("test", PASSWORD_BCRYPT, $flags); + +ini_set("error_include_args", "Off"); + +unlink('/'); +password_hash("test", PASSWORD_BCRYPT, $flags); + +?> +--EXPECTF-- +Warning: unlink('/'): %s in %s on line %d + +Warning: password_hash(Object(SensitiveParameterValue), '2y', Array): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d + +Warning: unlink(): %s in %s on line %d + +Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d diff --git a/Zend/tests/enum/__debugInfo.phpt b/Zend/tests/enum/__debugInfo.phpt deleted file mode 100644 index 33e0f49851f9..000000000000 --- a/Zend/tests/enum/__debugInfo.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Enum __debugInfo ---FILE-- -cases(); - } -} - -?> ---EXPECTF-- -Fatal error: Enum Foo cannot include magic method __debugInfo in %s on line %d diff --git a/Zend/tests/enum/debugInfo/backed_enum_value.phpt b/Zend/tests/enum/debugInfo/backed_enum_value.phpt new file mode 100644 index 000000000000..2bf56eb3a59e --- /dev/null +++ b/Zend/tests/enum/debugInfo/backed_enum_value.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum with __debugInfo() magic method - backed enum value accessible +--FILE-- +name . ' = ' . $this->value]; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECT-- +enum(Foo::Bar) (1) { + [0]=> + string(14) "Foo::Bar = Baz" +} diff --git a/Zend/tests/enum/debugInfo/magic_method.phpt b/Zend/tests/enum/debugInfo/magic_method.phpt new file mode 100644 index 000000000000..4c5963f73b26 --- /dev/null +++ b/Zend/tests/enum/debugInfo/magic_method.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum supports __debugInfo() magic method +--FILE-- +name . ' is a case of the ' . __CLASS__ . ' enum']; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECT-- +enum(Foo::Bar) (1) { + [0]=> + string(29) "Bar is a case of the Foo enum" +} diff --git a/Zend/tests/enum/debugInfo/missing_magic.phpt b/Zend/tests/enum/debugInfo/missing_magic.phpt new file mode 100644 index 000000000000..9cb5b0c69e52 --- /dev/null +++ b/Zend/tests/enum/debugInfo/missing_magic.phpt @@ -0,0 +1,14 @@ +--TEST-- +When an enum does not have __debugInfo() it is printed nicely +--FILE-- + +--EXPECT-- +enum(Foo::Bar) diff --git a/Zend/tests/enum/debugInfo/param_validation.phpt b/Zend/tests/enum/debugInfo/param_validation.phpt new file mode 100644 index 000000000000..84c60730822e --- /dev/null +++ b/Zend/tests/enum/debugInfo/param_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - param validation +--FILE-- + +--EXPECTF-- +Fatal error: Method Foo::__debugInfo() cannot take arguments in %s on line %d diff --git a/Zend/tests/enum/debugInfo/return_validation.phpt b/Zend/tests/enum/debugInfo/return_validation.phpt new file mode 100644 index 000000000000..5583dcadf409 --- /dev/null +++ b/Zend/tests/enum/debugInfo/return_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - return validation +--FILE-- + +--EXPECTF-- +Fatal error: Foo::__debugInfo(): Return type must be ?array when declared in %s on line %d diff --git a/Zend/tests/enum/debugInfo/visibility_validation.phpt b/Zend/tests/enum/debugInfo/visibility_validation.phpt new file mode 100644 index 000000000000..97e2f2c7456b --- /dev/null +++ b/Zend/tests/enum/debugInfo/visibility_validation.phpt @@ -0,0 +1,20 @@ +--TEST-- +Enum with __debugInfo() magic method - visibility validation +--FILE-- + +--EXPECTF-- +Warning: The magic method Foo::__debugInfo() must have public visibility in %s on line %d +enum(Foo::Bar) (0) { +} diff --git a/Zend/tests/enum/gh21760.phpt b/Zend/tests/enum/gh21760.phpt new file mode 100644 index 000000000000..0835e3ca937d --- /dev/null +++ b/Zend/tests/enum/gh21760.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-21760 (Trait with class constant name conflict against enum case causes SEGV) +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use trait X, because X::Up conflicts with enum case Direction::Up in %s on line %d diff --git a/Zend/tests/fibers/gh19983.phpt b/Zend/tests/fibers/gh19983.phpt new file mode 100644 index 000000000000..554a7c8bf8ef --- /dev/null +++ b/Zend/tests/fibers/gh19983.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-19983 (GC Assertion Failure with fibers, generators and destructors) +--SKIPIF-- + +--INI-- +memory_limit=16M +--FILE-- +current(); + }); + $fiber->start(); + } +} +new a; +?> +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted%s diff --git a/Zend/tests/first_class_callable/constexpr/gh22782.inc b/Zend/tests/first_class_callable/constexpr/gh22782.inc new file mode 100644 index 000000000000..d67ba4eab14e --- /dev/null +++ b/Zend/tests/first_class_callable/constexpr/gh22782.inc @@ -0,0 +1,18 @@ + +--FILE-- +getAttributes(A::class)[0]->newInstance()->fn)('hello')); +echo "# Method attr\n"; +var_dump((new ReflectionMethod(C::class, 'f')->getAttributes(A::class)[0]->newInstance()->fn)('hello')); +echo "# Method default value\n"; +var_dump((new C()->f())('hello')); + +?> +--EXPECT-- +# Class const +int(5) +# Class attr +int(5) +# Method attr +int(5) +# Method default value +int(5) diff --git a/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt b/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt deleted file mode 100644 index 74e36a9ad0df..000000000000 --- a/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -First class callable error: more than one argument ---FILE-- - ---EXPECTF-- -Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d diff --git a/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt b/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt deleted file mode 100644 index efbd13b7593b..000000000000 --- a/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -First class callable error: non-variadic placeholder ---FILE-- - ---EXPECTF-- -Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d diff --git a/Zend/tests/gh11735_2.phpt b/Zend/tests/gh11735_2.phpt index b568b6f6df37..521862b48237 100644 --- a/Zend/tests/gh11735_2.phpt +++ b/Zend/tests/gh11735_2.phpt @@ -13,5 +13,5 @@ stream_wrapper_register('foo', 'FooWrapper'); var_dump(fopen('foo://bar', 'r')); ?> --EXPECTF-- -Warning: fopen(foo://bar): Failed to open stream: "FooWrapper::stream_open" call failed in %s on line %d +Warning: fopen(): Failed to open stream: "FooWrapper::stream_open" call failed in %s on line %d bool(false) diff --git a/Zend/tests/gh16799.phpt b/Zend/tests/gh16799.phpt index ce1dbd5b1655..d31d1a5705c6 100644 --- a/Zend/tests/gh16799.phpt +++ b/Zend/tests/gh16799.phpt @@ -15,7 +15,12 @@ Test::test(); --EXPECTF-- Fatal error: Uncaught Exception: Use of "static" in callables is deprecated in %s:%d Stack trace: -#0 %s(%d): {closure:%s:%d}(8192, 'Use of "static"...', %s, %d) +#0 %s(%d): {closure:%s}(8192, 'Use of "static"%s', '%s', %d) #1 %s(%d): Test::test() #2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Test::test() +#1 {main} thrown in %s on line %d diff --git a/Zend/tests/gh21504.inc b/Zend/tests/gh21504.inc new file mode 100644 index 000000000000..71dc5c2e61f6 --- /dev/null +++ b/Zend/tests/gh21504.inc @@ -0,0 +1,3 @@ + var_dump(...); diff --git a/Zend/tests/gh21504.phpt b/Zend/tests/gh21504.phpt new file mode 100644 index 000000000000..5fd9eaff91ab --- /dev/null +++ b/Zend/tests/gh21504.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-21504: Incorrect RC-handling for ZEND_EXT_STMT op1 +--FILE-- + +--EXPECT-- +string(4) "1234" diff --git a/Zend/tests/gh21603.phpt b/Zend/tests/gh21603.phpt new file mode 100644 index 000000000000..ab2fbc44e797 --- /dev/null +++ b/Zend/tests/gh21603.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-21603: Missing addref for __unset +--CREDITS-- +cnwangjihe +--FILE-- +prop); + +?> +--EXPECTF-- +object(C)#%d (0) { +} diff --git a/Zend/tests/gh21605.phpt b/Zend/tests/gh21605.phpt new file mode 100644 index 000000000000..973339ad3bb9 --- /dev/null +++ b/Zend/tests/gh21605.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-21605: Missing addref for Countable::count() +--CREDITS-- +cnwangjihe +--FILE-- + +--EXPECTF-- +object(C)#%d (0) { +} +int(42) diff --git a/Zend/tests/gh22257.phpt b/Zend/tests/gh22257.phpt new file mode 100644 index 000000000000..9bbf3b1f8d35 --- /dev/null +++ b/Zend/tests/gh22257.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-22257 (Type confusion / OOB read unserializing an Exception with a non-array trace) +--CREDITS-- +Igor Sak-Sakovskiy (Positive Technologies) +--FILE-- +getPrevious()) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +/* By-ref type violation: the slot is reset to the property default. */ +class Test { public int $i; public array $a; } +try { + var_dump(unserialize('O:4:"Test":2:{s:1:"i";N;s:1:"a";R:2;}')); +} catch (\Throwable $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +echo "OK\n"; +?> +--EXPECTF-- +Warning: unserialize(): Error at offset %d of %d bytes in %s on line %d +TypeError: Cannot assign null to property Test::$i of type int +OK diff --git a/Zend/tests/gh22849.phpt b/Zend/tests/gh22849.phpt new file mode 100644 index 000000000000..a38c64baf542 --- /dev/null +++ b/Zend/tests/gh22849.phpt @@ -0,0 +1,31 @@ +--TEST-- +PHP 8.6 error_include_args=1 mishandled for include() +--INI-- +error_include_args=On +--FILE-- + +--EXPECTF-- +Warning: include('does not exist'): Failed to open stream: No such file or directory in %s on line %d + +Warning: include('does not exist'): Failed opening 'does not exist' for inclusion (include_path='%s') in %s on line %d + +Warning: include_once('does not exist'): Failed to open stream: No such file or directory in %s on line %d + +Warning: include_once('does not exist'): Failed opening 'does not exist' for inclusion (include_path='%s') in %s on line %d + +Warning: require('does not exist'): Failed to open stream: No such file or directory in %s on line %d + +Fatal error: Uncaught Error: Failed opening required 'does not exist' (include_path='%s') in %s:%d +Stack trace: +#0 %s(%d): foo(1, 2) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699.phpt b/Zend/tests/gh_21699.phpt new file mode 100644 index 000000000000..49b58365dabf --- /dev/null +++ b/Zend/tests/gh_21699.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699: Assertion failure in shutdown_executor when error handler throws during self:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "self" i%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_parent.phpt b/Zend/tests/gh_21699_parent.phpt new file mode 100644 index 000000000000..73cae41f3f5b --- /dev/null +++ b/Zend/tests/gh_21699_parent.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21699 (parent::): no shutdown_executor trampoline assertion when error handler throws during parent:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "parent"%s', '%s', %d) +#1 %s(%d): Child->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Child->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_static.phpt b/Zend/tests/gh_21699_static.phpt new file mode 100644 index 000000000000..4d9604ebe77b --- /dev/null +++ b/Zend/tests/gh_21699_static.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699 (static::): no shutdown_executor trampoline assertion when error handler throws during static:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "static"%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/include_stat_is_quiet.phpt b/Zend/tests/include_stat_is_quiet.phpt index 75ba8f3d6273..39eb3053fbe4 100644 --- a/Zend/tests/include_stat_is_quiet.phpt +++ b/Zend/tests/include_stat_is_quiet.phpt @@ -26,7 +26,7 @@ try { ?> --EXPECTF-- -Warning: require_once(doesnt_exist.php): Failed to open stream: No such file or directory in %s on line %d +Warning: require_once(): Failed to open stream: No such file or directory in %s on line %d Fatal error: Uncaught Error: Failed opening required 'doesnt_exist.php' (include_path='test://foo:test://bar') in %s:%d Stack trace: diff --git a/Zend/tests/lazy_objects/gh18038-002.phpt b/Zend/tests/lazy_objects/gh18038-002.phpt index 4c12f21de811..d363731c62a0 100644 --- a/Zend/tests/lazy_objects/gh18038-002.phpt +++ b/Zend/tests/lazy_objects/gh18038-002.phpt @@ -34,5 +34,4 @@ var_dump($obj->prop); --EXPECT-- init string(19) "RealInstance::__set" -string(12) "Proxy::__set" int(2) diff --git a/Zend/tests/lazy_objects/gh18038-004.phpt b/Zend/tests/lazy_objects/gh18038-004.phpt index 8810efb6bec2..c1495c5a6d8d 100644 --- a/Zend/tests/lazy_objects/gh18038-004.phpt +++ b/Zend/tests/lazy_objects/gh18038-004.phpt @@ -36,7 +36,6 @@ var_dump($real->prop); --EXPECTF-- init string(19) "RealInstance::__get" -string(12) "Proxy::__get" Warning: Undefined property: RealInstance::$prop in %s on line %d NULL diff --git a/Zend/tests/lazy_objects/gh18038-007.phpt b/Zend/tests/lazy_objects/gh18038-007.phpt index 9925190a1980..4c7c0d0b4b0a 100644 --- a/Zend/tests/lazy_objects/gh18038-007.phpt +++ b/Zend/tests/lazy_objects/gh18038-007.phpt @@ -36,6 +36,5 @@ var_dump(isset($real->prop[''])); --EXPECT-- init string(21) "RealInstance::__isset" -string(14) "Proxy::__isset" bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/gh18038-009.phpt b/Zend/tests/lazy_objects/gh18038-009.phpt index 3c165a71ccff..11067cdb970b 100644 --- a/Zend/tests/lazy_objects/gh18038-009.phpt +++ b/Zend/tests/lazy_objects/gh18038-009.phpt @@ -36,6 +36,5 @@ var_dump(isset($real->prop)); --EXPECT-- init string(21) "RealInstance::__isset" -string(14) "Proxy::__isset" bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/gh20854.phpt b/Zend/tests/lazy_objects/gh20854.phpt new file mode 100644 index 000000000000..26a69cfcbbf5 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20854.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20854 (Assertion in ZEND_RETURN_BY_REF with lazy proxy and return-by-ref __get) +--FILE-- +x; + } +} + +$rc = new ReflectionClass(C::class); +$obj = $rc->newLazyProxy(function () { + return new C; +}); +$obj->x; +echo "Done\n"; +?> +--EXPECTF-- +Deprecated: Creation of dynamic property C::$x is deprecated in %s on line %d +Done diff --git a/Zend/tests/lazy_objects/gh20873.phpt b/Zend/tests/lazy_objects/gh20873.phpt new file mode 100644 index 000000000000..e5b8c31e9130 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20873.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-20873 (Assertion failure in _zendi_try_convert_scalar_to_number with lazy proxy) +--FILE-- +x =& $this->_; + static $a = $a; + $e =& $this->_ - $a; + } +} +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A); +$rc->initializeLazyObject($obj); +var_dump($obj->p); +?> +--EXPECTF-- +Deprecated: Creation of dynamic property A::$x is deprecated in %s on line %d + +Warning: Undefined variable $a in %s on line %d + +Notice: Indirect modification of overloaded property A::$x has no effect in %s on line %d + +Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d +Stack trace: +#0 %s(%d): A->__get('p') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/gh20875.phpt b/Zend/tests/lazy_objects/gh20875.phpt new file mode 100644 index 000000000000..ff036edabd59 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20875.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-20875 (Assertion failure in _get_zval_ptr_tmp with lazy proxy) +--FILE-- +f =& $this->b - $x > $y = new StdClass; + static $a = $a; + $t = 'x'; + foreach (get_defined_vars() as $key => $e) {} + if ($v ==!1) $x = $a ?: $t = "ok"; + } +} +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(function () { return new A; }); +$real = $rc->initializeLazyObject($obj); +var_dump($real->prop); +?> +--EXPECTF-- +Deprecated: Creation of dynamic property A::$b is deprecated in %s on line %d + +Deprecated: Creation of dynamic property A::$f is deprecated in %s on line %d + +Warning: Undefined variable $x in %s on line %d + +Notice: Object of class stdClass could not be converted to int in %s on line %d + +Warning: Undefined variable $a in %s on line %d + +Warning: Undefined variable $v in %s on line %d + +Notice: Indirect modification of overloaded property A::$f has no effect in %s on line %d + +Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d +Stack trace: +#0 %s(%d): A->__get('b') +#1 %s(%d): A->__get('prop') +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt b/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt new file mode 100644 index 000000000000..d5d9754864b4 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20875 (Lazy proxy should not initialize when __get handles dynamic property access) +--FILE-- +newLazyProxy(function () { + echo "init\n"; + return new Foo(); +}); +$x = &$proxy->x; + +?> +--EXPECT-- +__get diff --git a/Zend/tests/lazy_objects/gh21478-isset.phpt b/Zend/tests/lazy_objects/gh21478-isset.phpt new file mode 100644 index 000000000000..9138984af01b --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-isset.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: __isset on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name}); + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +isset($real->x); + +?> +--EXPECT-- +Init +__isset($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt b/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt new file mode 100644 index 000000000000..520c8f662353 --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: Proxy's own __get runs when accessed directly (not from real instance) +--FILE-- +newLazyProxy(function () { + return new Foo(); +}); +$rc->initializeLazyObject($proxy); + +$proxy->x; + +?> +--EXPECT-- +Bar x diff --git a/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt b/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt new file mode 100644 index 000000000000..fa737cf18f2e --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478: No assertion failure when &__get forwards through initialized lazy proxy +--FILE-- +{$name}; + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$a = &$real->x; +var_dump($a); +?> +--EXPECTF-- +Init +Foo::__get($x) on Foo + +Warning: Undefined property: Foo::$x in %s on line %d +NULL diff --git a/Zend/tests/lazy_objects/gh21478-set.phpt b/Zend/tests/lazy_objects/gh21478-set.phpt new file mode 100644 index 000000000000..0b2f872de11a --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-set.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478: __set on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name} = $value; + } +} + +#[AllowDynamicProperties] +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$real->x = 1; + +?> +--EXPECT-- +Init +__set($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478-unset.phpt b/Zend/tests/lazy_objects/gh21478-unset.phpt new file mode 100644 index 000000000000..5febbd235d82 --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-unset.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: __unset on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name}); + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +unset($real->x); + +?> +--EXPECT-- +Init +__unset($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478.phpt b/Zend/tests/lazy_objects/gh21478.phpt new file mode 100644 index 000000000000..aaa226a9a09a --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478 (Property access on lazy proxy may invoke magic method despite real instance guards) +--FILE-- +{$name}; + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$real->x; + +?> +--EXPECTF-- +Init +__get($x) on Foo + +Warning: Undefined property: Foo::$x in %s on line %d diff --git a/Zend/tests/magic_methods/constructor_destructor_return.phpt b/Zend/tests/magic_methods/constructor_destructor_return.phpt new file mode 100644 index 000000000000..635548bb6f47 --- /dev/null +++ b/Zend/tests/magic_methods/constructor_destructor_return.phpt @@ -0,0 +1,35 @@ +--TEST-- +Returning values from constructors and destructors is deprecated +--FILE-- +voidMethod(); } + public function __destruct() { return $this->voidMethod(); } + + public function voidMethod(): void { } +} + +class Gen { + public function __construct() { yield ''; } + public function __destruct() { yield ''; } +} + +?> +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a destructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a destructor is deprecated in %s on line %d + +Deprecated: Making a constructor a Generator is deprecated in %s on line %d + +Deprecated: Making a destructor a Generator is deprecated in %s on line %d diff --git a/Zend/tests/magic_methods/gh12695.phpt b/Zend/tests/magic_methods/gh12695.phpt new file mode 100644 index 000000000000..957f474fb6a1 --- /dev/null +++ b/Zend/tests/magic_methods/gh12695.phpt @@ -0,0 +1,65 @@ +--TEST-- +GH-12695: ?? on unset property does not call __get() when __isset() materialized the property +--FILE-- +$n = 123; + return true; + } +} + +echo "Dynamic property materialised in __isset, then `??`:\n"; +$a = new A; +var_dump($a->foo ?? 'fallback'); + +echo "\nSame on a declared (unset) property:\n"; +class B { + public int $x = 99; + public function __get($n) { + throw new Exception("__get must not be called when __isset materialised the property"); + } + public function __isset($n) { + echo " __isset($n)\n"; + $this->$n = 7; + return true; + } +} +$b = new B; +unset($b->x); +var_dump($b->x ?? 'fallback'); + +echo "\nWhen __isset() materialises the property to null, `??` falls back:\n"; +#[AllowDynamicProperties] +class D { + public function __get($n) { + throw new Exception("__get must not be called when __isset materialised the property"); + } + public function __isset($n) { + echo " __isset($n)\n"; + $this->$n = null; + return true; + } +} +$d = new D; +var_dump($d->foo ?? 'fallback'); + +?> +--EXPECT-- +Dynamic property materialised in __isset, then `??`: + __isset(foo) +int(123) + +Same on a declared (unset) property: + __isset(x) +int(7) + +When __isset() materialises the property to null, `??` falls back: + __isset(foo) +string(8) "fallback" diff --git a/Zend/tests/magic_methods/gh12695_empty.phpt b/Zend/tests/magic_methods/gh12695_empty.phpt new file mode 100644 index 000000000000..99806820cc6f --- /dev/null +++ b/Zend/tests/magic_methods/gh12695_empty.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-12695: empty() on unset property does not call __get() when __isset() materialized the property +--FILE-- +$n = $GLOBALS['next_value']; + return true; + } +} + +echo "empty() when __isset materialised a truthy value: __get is not called, empty=false:\n"; +$GLOBALS['next_value'] = 7; +$a = new A; +var_dump(empty($a->foo)); + +echo "\nempty() when __isset materialised a falsy value: __get is not called, empty=true:\n"; +$GLOBALS['next_value'] = 0; +$a = new A; +var_dump(empty($a->bar)); + +echo "\nempty() with no materialization: __get is still called (legacy path preserved):\n"; +class B { + public function __get($n) { + echo " __get($n)\n"; + return 'value'; + } + public function __isset($n) { + echo " __isset($n)\n"; + return true; + } +} +$b = new B; +var_dump(empty($b->any)); + +?> +--EXPECT-- +empty() when __isset materialised a truthy value: __get is not called, empty=false: + __isset(foo) +bool(false) + +empty() when __isset materialised a falsy value: __get is not called, empty=true: + __isset(bar) +bool(true) + +empty() with no materialization: __get is still called (legacy path preserved): + __isset(any) + __get(any) +bool(false) diff --git a/Zend/tests/magic_methods/gh12695_no_materialization.phpt b/Zend/tests/magic_methods/gh12695_no_materialization.phpt new file mode 100644 index 000000000000..700b605e2984 --- /dev/null +++ b/Zend/tests/magic_methods/gh12695_no_materialization.phpt @@ -0,0 +1,65 @@ +--TEST-- +GH-12695: __get() invocation is based on __isset()'s return value +--FILE-- +any ?? 'fallback'); + +echo "\n`??` when __isset=true and __get returns null: __get is called and fallback is used:\n"; +class D { + public function __get($n) { + echo " __get($n)\n"; + return null; + } + public function __isset($n) { + echo " __isset($n)\n"; + return true; + } +} +$d = new D; +var_dump($d->any ?? 'fallback'); + +echo "\n`??` when __isset returns false: __get is not called:\n"; +class E { + public function __get($n) { + throw new Exception("__get must not be called when __isset returned false"); + } + public function __isset($n) { + echo " __isset($n)\n"; + return false; + } +} +$e = new E; +var_dump($e->any ?? 'fallback'); + +?> +--EXPECT-- +`??` when __isset=true and __get returns a value: __get is called: + __isset(any) + __get(any) +string(8) "from-get" + +`??` when __isset=true and __get returns null: __get is called and fallback is used: + __isset(any) + __get(any) +string(8) "fallback" + +`??` when __isset returns false: __get is not called: + __isset(any) +string(8) "fallback" diff --git a/Zend/tests/magic_methods/gh12695_object_released_in_isset.phpt b/Zend/tests/magic_methods/gh12695_object_released_in_isset.phpt new file mode 100644 index 000000000000..911ffde637a9 --- /dev/null +++ b/Zend/tests/magic_methods/gh12695_object_released_in_isset.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-12695: Object freed by __isset() during materialization +--FILE-- +prop = 'materialised'; + return true; + } +} + +$obj = new C(); +unset($obj->prop); +var_dump($obj->prop ?? 'fb'); + +?> +--EXPECT-- +string(12) "materialised" diff --git a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt index 6bdcafb1bfb5..a4076ee00ce2 100644 --- a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt +++ b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt @@ -66,5 +66,6 @@ class WidenedArgumentType extends NarrowedReturnType { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from ValidMagicMethods::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/tests/magic_methods/stringable_automatic_implementation_case_insensitive.phpt b/Zend/tests/magic_methods/stringable_automatic_implementation_case_insensitive.phpt new file mode 100644 index 000000000000..7f4564794452 --- /dev/null +++ b/Zend/tests/magic_methods/stringable_automatic_implementation_case_insensitive.phpt @@ -0,0 +1,23 @@ +--TEST-- +Stringable is automatically implemented for __toString() declared with non-canonical case +--FILE-- +getInterfaceNames()); +var_dump((string) new Test); + +?> +--EXPECT-- +bool(true) +array(1) { + [0]=> + string(10) "Stringable" +} +string(3) "foo" diff --git a/Zend/tests/oss_fuzz_64209.phpt b/Zend/tests/oss_fuzz_64209.phpt index 599ae258e5b2..56b9dcfc7a24 100644 --- a/Zend/tests/oss_fuzz_64209.phpt +++ b/Zend/tests/oss_fuzz_64209.phpt @@ -5,7 +5,7 @@ oss-fuzz #64209: Fix in-place modification of filename in php_message_handler_fo require '://@'; ?> --EXPECTF-- -Warning: require(://@): Failed to open stream: No such file or directory in %s on line %d +Warning: require(): Failed to open stream: No such file or directory in %s on line %d Fatal error: Uncaught Error: Failed opening required '://@' (include_path='%s') in %s:%d Stack trace: diff --git a/Zend/tests/partial_application/assert.phpt b/Zend/tests/partial_application/assert.phpt new file mode 100644 index 000000000000..166cc5022eb2 --- /dev/null +++ b/Zend/tests/partial_application/assert.phpt @@ -0,0 +1,45 @@ +--TEST-- +PFA of assert() behaves like a dynamic call to assert() +--FILE-- +getMessage(), "\n"; +} + +try { + echo "# Dynamic call:\n"; + (function ($f) { $f(false); })('assert'); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage() ?: '(no message)', "\n"; +} + +try { + echo "# PFA call:\n"; + $f = assert(?); + $f(false); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage() ?: '(no message)', "\n"; +} + +try { + echo "# Upper-case assert():\n"; + $f = ASSERT(?); + $f(false); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage() ?: '(no message)', "\n"; +} + +?> +--EXPECT-- +# Static call: +AssertionError: assert(false) +# Dynamic call: +AssertionError: (no message) +# PFA call: +AssertionError: (no message) +# Upper-case assert(): +AssertionError: (no message) diff --git a/Zend/tests/partial_application/attributes_001.phpt b/Zend/tests/partial_application/attributes_001.phpt new file mode 100644 index 000000000000..827ad41321ec --- /dev/null +++ b/Zend/tests/partial_application/attributes_001.phpt @@ -0,0 +1,88 @@ +--TEST-- +PFA inherits NoDiscard and SensitiveParameter attributes +--FILE-- +getAttributes()); + + foreach ($r->getParameters() as $i => $p) { + echo "Parameter $i:\n"; + var_dump($p->getAttributes()); + } +} + +echo "# Orig attributes:\n"; + +dump_attributes('f'); + +$f = f(1, ?, ?, ...); + +echo "# PFA attributes:\n"; + +dump_attributes($f); + +?> +--EXPECTF-- +# Orig attributes: +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "NoDiscard" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(4) "Test" + } +} +Parameter 0: +array(0) { +} +Parameter 1: +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(18) "SensitiveParameter" + } +} +Parameter 2: +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(4) "Test" + } +} +# PFA attributes: +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "NoDiscard" + } +} +Parameter 0: +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(18) "SensitiveParameter" + } +} +Parameter 1: +array(0) { +} +Parameter 2: +array(0) { +} diff --git a/Zend/tests/partial_application/attributes_002.phpt b/Zend/tests/partial_application/attributes_002.phpt new file mode 100644 index 000000000000..be1f1612f938 --- /dev/null +++ b/Zend/tests/partial_application/attributes_002.phpt @@ -0,0 +1,19 @@ +--TEST-- +PFA preserves #[SensitiveParameter] +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): f(1, Object(SensitiveParameterValue), 3, Object(SensitiveParameterValue), Object(SensitiveParameterValue)) +#1 %s(%d): {closure:pfa:%s:7}(Object(SensitiveParameterValue), 3, Object(SensitiveParameterValue), Object(SensitiveParameterValue)) +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/partial_application/attributes_003.phpt b/Zend/tests/partial_application/attributes_003.phpt new file mode 100644 index 000000000000..d113d02eb8f7 --- /dev/null +++ b/Zend/tests/partial_application/attributes_003.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA preserves #[NoDiscard] +--FILE-- + +--EXPECTF-- +Warning: The return value of function {closure:%s}() should either be used or intentionally ignored by casting it as (void) in %s on line 7 diff --git a/Zend/tests/partial_application/bound_arg_strict_types.phpt b/Zend/tests/partial_application/bound_arg_strict_types.phpt new file mode 100644 index 000000000000..d7e2ddcae5c4 --- /dev/null +++ b/Zend/tests/partial_application/bound_arg_strict_types.phpt @@ -0,0 +1,26 @@ +--TEST-- +Partial application checks bound arguments with the creating scope's strict_types +--FILE-- +getMessage(), "\n"; +} + +function make() { + try { + f("3", ?); + } catch (\TypeError $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; + } +} +make(); +?> +--EXPECT-- +TypeError: f(): Argument #1 ($a) must be of type int, string given +TypeError: f(): Argument #1 ($a) must be of type int, string given diff --git a/Zend/tests/partial_application/clone.phpt b/Zend/tests/partial_application/clone.phpt new file mode 100644 index 000000000000..f778d776b717 --- /dev/null +++ b/Zend/tests/partial_application/clone.phpt @@ -0,0 +1,50 @@ +--TEST-- +clone() can be partially applied +--FILE-- + 7])); + +$clone = clone(?, ['a' => 8]); +var_dump($clone(new C(9, 10))); + +?> +--EXPECTF-- +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +object(C)#%d (2) { + ["a"]=> + int(3) + ["b"]=> + int(4) +} +object(C)#%d (2) { + ["a"]=> + int(7) + ["b"]=> + int(6) +} +object(C)#%d (2) { + ["a"]=> + int(8) + ["b"]=> + int(10) +} diff --git a/Zend/tests/partial_application/closure_rt_cache_lifetime.phpt b/Zend/tests/partial_application/closure_rt_cache_lifetime.phpt new file mode 100644 index 000000000000..7eb4810cf00a --- /dev/null +++ b/Zend/tests/partial_application/closure_rt_cache_lifetime.phpt @@ -0,0 +1,19 @@ +--TEST-- +Partial application over a Closure::fromCallable() must not double-free the run_time_cache +--FILE-- + +--EXPECT-- +int(15) +OK diff --git a/Zend/tests/partial_application/compile_errors_001.phpt b/Zend/tests/partial_application/compile_errors_001.phpt new file mode 100644 index 000000000000..f08495a1f1e5 --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_001.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: multiple variadic placeholders +--FILE-- + +--EXPECTF-- +Fatal error: Variadic placeholder may only appear once in %s on line %d diff --git a/Zend/tests/partial_application/compile_errors_002.phpt b/Zend/tests/partial_application/compile_errors_002.phpt new file mode 100644 index 000000000000..b6a2073a8363 --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_002.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: variadic placeholder must be last +--FILE-- + +--EXPECTF-- +Fatal error: Variadic placeholder must be last in %s on line %d diff --git a/Zend/tests/partial_application/compile_errors_003.phpt b/Zend/tests/partial_application/compile_errors_003.phpt new file mode 100644 index 000000000000..26ff8435111b --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_003.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: placeholders can not appear after named args +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use positional argument after named argument in %s on line %d diff --git a/Zend/tests/partial_application/compile_errors_004.phpt b/Zend/tests/partial_application/compile_errors_004.phpt new file mode 100644 index 000000000000..ac7ec163c5da --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_004.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: variadic placeholder must be last, including after named args +--FILE-- + +--EXPECTF-- +Fatal error: Variadic placeholder must be last in %s on line %d diff --git a/Zend/tests/partial_application/compile_errors_005.phpt b/Zend/tests/partial_application/compile_errors_005.phpt new file mode 100644 index 000000000000..30e4aa12b488 --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_005.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: variadic placeholder must be last, including after positional args +--FILE-- + +--EXPECTF-- +Fatal error: Variadic placeholder must be last in %s on line %d diff --git a/Zend/tests/partial_application/compile_errors_006.phpt b/Zend/tests/partial_application/compile_errors_006.phpt new file mode 100644 index 000000000000..8549c671e906 --- /dev/null +++ b/Zend/tests/partial_application/compile_errors_006.phpt @@ -0,0 +1,8 @@ +--TEST-- +PFA compile errors: can not use unpacking in PFA, including with variadic placeholders +--FILE-- + "bar"], ...); +?> +--EXPECTF-- +Fatal error: Cannot combine partial application and unpacking in %s on line %d diff --git a/Zend/tests/partial_application/construct_throw_arg_leak.phpt b/Zend/tests/partial_application/construct_throw_arg_leak.phpt new file mode 100644 index 000000000000..1291901f0cc8 --- /dev/null +++ b/Zend/tests/partial_application/construct_throw_arg_leak.phpt @@ -0,0 +1,34 @@ +--TEST-- +Partial application must not leak bound arguments when construction throws +--FILE-- + +--EXPECT-- +TypeError +TypeError +ArgumentCountError +OK diff --git a/Zend/tests/partial_application/default_const_expr.phpt b/Zend/tests/partial_application/default_const_expr.phpt new file mode 100644 index 000000000000..12d25adedeff --- /dev/null +++ b/Zend/tests/partial_application/default_const_expr.phpt @@ -0,0 +1,116 @@ +--TEST-- +PFA: constant-expression default for a skipped optional parameter +--FILE-- +name, $c]; +} + +$p = f(a: 10, c: ?); +var_dump($p(99)); + +$v = variadic(a: 10, c: ?, foo: 1); +var_dump($v(99)); + +$q = C::m(a: 1, c: ?); +var_dump($q(9)); + +$r = g(a: 1, c: ?); +var_dump($r(9)); + +$l = late(a: 1, c: ?); +define('App\LATE', 'defined after the partial was created'); +var_dump($l(9)); + +define('GLOBAL_ONLY', 'global fallback'); +$s = fallback(a: 1, c: ?); +var_dump($s(9)); + +?> +--EXPECT-- +array(3) { + [0]=> + int(10) + [1]=> + int(7) + [2]=> + int(99) +} +array(4) { + [0]=> + int(10) + [1]=> + int(7) + [2]=> + int(99) + [3]=> + array(1) { + ["foo"]=> + int(1) + } +} +array(3) { + [0]=> + int(1) + [1]=> + int(42) + [2]=> + int(9) +} +array(3) { + [0]=> + int(1) + [1]=> + string(1) "A" + [2]=> + int(9) +} +array(3) { + [0]=> + int(1) + [1]=> + string(37) "defined after the partial was created" + [2]=> + int(9) +} +array(3) { + [0]=> + int(1) + [1]=> + string(15) "global fallback" + [2]=> + int(9) +} diff --git a/Zend/tests/partial_application/deprecated.phpt b/Zend/tests/partial_application/deprecated.phpt new file mode 100644 index 000000000000..5a6280347cfc --- /dev/null +++ b/Zend/tests/partial_application/deprecated.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFAs may emit deprecation warnings +--FILE-- + +--EXPECTF-- +Deprecated: Function f() is deprecated in %s on line %d diff --git a/Zend/tests/partial_application/errors_001.phpt b/Zend/tests/partial_application/errors_001.phpt new file mode 100644 index 000000000000..2d5348cb28af --- /dev/null +++ b/Zend/tests/partial_application/errors_001.phpt @@ -0,0 +1,62 @@ +--TEST-- +PFA errors: PFA instantiation follows the usual argument count validation +--FILE-- +getMessage()); +} + +try { + foo(?, ?, ?, ?); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +try { + $c = new C(); + $c->f(?); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +try { + property_exists(?); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +try { + usleep(?, ?); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +try { + foo(?, ?, ?, ?, ...); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +/* It is allowed to specify less than the number of required params, when there + * is a variadic placeholder */ +foo(?, ...); + +?> +--EXPECT-- +ArgumentCountError: Partial application of foo() expects exactly 3 arguments, 1 given +ArgumentCountError: Partial application of foo() expects at most 3 arguments, 4 given +ArgumentCountError: Partial application of C::f() expects exactly 3 arguments, 1 given +ArgumentCountError: Partial application of property_exists() expects exactly 2 arguments, 1 given +ArgumentCountError: Partial application of usleep() expects at most 1 arguments, 2 given +ArgumentCountError: Partial application of foo() expects at most 3 arguments, 4 given diff --git a/Zend/tests/partial_application/errors_002.phpt b/Zend/tests/partial_application/errors_002.phpt new file mode 100644 index 000000000000..0132d8873e2a --- /dev/null +++ b/Zend/tests/partial_application/errors_002.phpt @@ -0,0 +1,15 @@ +--TEST-- +PFA errors: named parameter that resolve to the position of a placeholder is an error +--FILE-- +getMessage()); +} +?> +--EXPECT-- +Error: Named parameter $a overwrites previous placeholder diff --git a/Zend/tests/partial_application/errors_003.phpt b/Zend/tests/partial_application/errors_003.phpt new file mode 100644 index 000000000000..85ecf398fa1b --- /dev/null +++ b/Zend/tests/partial_application/errors_003.phpt @@ -0,0 +1,74 @@ +--TEST-- +PFA errors: PFA call follows the usual argument count validation +--FILE-- +getMessage()); +} + +$foo = foo(?, ?); + +try { + $foo(1); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +$bar = bar(?, ?, ...); + +try { + $bar(1); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +class Foo { + public function bar($a, ...$b) {} +} + +$foo = new Foo; + +$bar = $foo->bar(?); + +try { + $bar(); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +$repeat = str_repeat('a', ...); + +try { + $repeat(); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +$usleep = usleep(?); + +try { + $usleep(); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +$usleep(1, 2); + +?> +--EXPECTF-- +ArgumentCountError: Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected +ArgumentCountError: Too few arguments to function {closure:%s:%d}(), 1 passed in %s on line %d and exactly 2 expected +ArgumentCountError: Too few arguments to function {closure:%s:%d}(), 1 passed in %s on line %d and exactly 3 expected +ArgumentCountError: Too few arguments to function Foo::{closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected +ArgumentCountError: Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected +ArgumentCountError: Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected diff --git a/Zend/tests/partial_application/errors_004.phpt b/Zend/tests/partial_application/errors_004.phpt new file mode 100644 index 000000000000..e5e1432753b2 --- /dev/null +++ b/Zend/tests/partial_application/errors_004.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA errors: not specifying a required param is an error +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ArgumentCountError: f(): Argument #2 ($b) not passed in %s:6 +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/partial_application/errors_005.phpt b/Zend/tests/partial_application/errors_005.phpt new file mode 100644 index 000000000000..23fc2a75dff3 --- /dev/null +++ b/Zend/tests/partial_application/errors_005.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA errors: Can not fetch default parameter value for Closure::__invoke() +--FILE-- +__invoke(0, 0, ?); +echo "No error\n"; + +try { + $g = $f->__invoke(0, 0, ...); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +No error +ArgumentCountError: Closure::__invoke(): Argument #3 ($c) must be passed explicitly, because the default value is not known diff --git a/Zend/tests/partial_application/errors_006.phpt b/Zend/tests/partial_application/errors_006.phpt new file mode 100644 index 000000000000..9534bb40ee54 --- /dev/null +++ b/Zend/tests/partial_application/errors_006.phpt @@ -0,0 +1,45 @@ +--TEST-- +PFA errors: Some internal function parameters have UNKNOWN default value +--FILE-- + array_keys($array, ???, true) + $f = array_keys(?, strict: true); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +try { + // fn (array $array, mixed $filter_value = ???) => array_keys($array, $filter_value, true) + $f = array_keys(?, strict: true, ...); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +array(1) { + [0]=> + int(1) +} +array(0) { +} +array(1) { + [0]=> + int(1) +} +array(0) { +} +ArgumentCountError: array_keys(): Argument #2 ($filter_value) must be passed explicitly, because the default value is not known +ArgumentCountError: array_keys(): Argument #2 ($filter_value) must be passed explicitly, because the default value is not known diff --git a/Zend/tests/partial_application/export_001.phpt b/Zend/tests/partial_application/export_001.phpt new file mode 100644 index 000000000000..b48146bcc65a --- /dev/null +++ b/Zend/tests/partial_application/export_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA AST export +--INI-- +assert.exception=1 +--FILE-- +getMessage()); +} +?> +--EXPECT-- +AssertionError: assert(0 && foo(?) && foo(new stdClass(), bar: 1, ...)) diff --git a/Zend/tests/partial_application/extra_named.phpt b/Zend/tests/partial_application/extra_named.phpt new file mode 100644 index 000000000000..4dd80cfa0127 --- /dev/null +++ b/Zend/tests/partial_application/extra_named.phpt @@ -0,0 +1,49 @@ +--TEST-- +PFA extra named parameters are forwarded to the actual function +--FILE-- + +--EXPECT-- +array(3) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" + ["baz"]=> + string(3) "baz" +} +array(2) { + ["bar"]=> + string(3) "bar" + ["baz"]=> + string(3) "baz" +} +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} diff --git a/Zend/tests/partial_application/function_name.phpt b/Zend/tests/partial_application/function_name.phpt new file mode 100644 index 000000000000..68d2ccf84871 --- /dev/null +++ b/Zend/tests/partial_application/function_name.phpt @@ -0,0 +1,40 @@ +--TEST-- +Partial application function name +--FILE-- +getName()); + } +} + +function f() { + echo "# From a function:\n"; + var_dump((new ReflectionFunction(g(?)))->getName()); + + echo "# Declared on same line:\n"; + [$a, $b] = [g(?), g(?)]; + var_dump((new ReflectionFunction($a))->getName(), (new ReflectionFunction($b))->getName()); +} + +f(); +C::m(); + +echo "# From global scope:\n"; +var_dump((new ReflectionFunction(g(?)))->getName()); + +?> +--EXPECTF-- +# From a function: +string(20) "{closure:pfa:f():14}" +# Declared on same line: +string(20) "{closure:pfa:f():17}" +string(20) "{closure:pfa:f():17}" +# From a method: +string(22) "{closure:pfa:C::m():8}" +# From global scope: +string(%d) "{closure:pfa:%sfunction_name.php:25}" diff --git a/Zend/tests/partial_application/fuzz_001.phpt b/Zend/tests/partial_application/fuzz_001.phpt new file mode 100644 index 000000000000..790162ba6a36 --- /dev/null +++ b/Zend/tests/partial_application/fuzz_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure application fuzz 001 +--FILE-- + +--EXPECTF-- +Closure [ function {closure:%s:%d} ] { + @@ %s 4 - 4 + + - Bound Variables [2] { + Variable #0 [ $fn ] + Variable #1 [ $a ] + } + + - Parameters [1] { + Parameter #0 [ $b ] + } +} diff --git a/Zend/tests/partial_application/fuzz_003.phpt b/Zend/tests/partial_application/fuzz_003.phpt new file mode 100644 index 000000000000..6e9d583fda99 --- /dev/null +++ b/Zend/tests/partial_application/fuzz_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Closure application fuzz 003 +--FILE-- +method(1, ...); +$bar(2); +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/Zend/tests/partial_application/fuzz_004.phpt b/Zend/tests/partial_application/fuzz_004.phpt new file mode 100644 index 000000000000..ea005304a3af --- /dev/null +++ b/Zend/tests/partial_application/fuzz_004.phpt @@ -0,0 +1,19 @@ +--TEST-- +Closure application fuzz 004 +--FILE-- +__invoke(UNDEFINED); +} catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Error: Undefined constant "UNDEFINED" diff --git a/Zend/tests/partial_application/fuzz_005.phpt b/Zend/tests/partial_application/fuzz_005.phpt new file mode 100644 index 000000000000..ea04862d8399 --- /dev/null +++ b/Zend/tests/partial_application/fuzz_005.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA fuzz 005 +--FILE-- + +==DONE== +--EXPECT-- +==DONE== diff --git a/Zend/tests/partial_application/fuzz_006.phpt b/Zend/tests/partial_application/fuzz_006.phpt new file mode 100644 index 000000000000..26ec6e3e4dd1 --- /dev/null +++ b/Zend/tests/partial_application/fuzz_006.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA fuzz 006 +--FILE-- + +--EXPECT-- +int(1) diff --git a/Zend/tests/partial_application/fuzz_007.phpt b/Zend/tests/partial_application/fuzz_007.phpt new file mode 100644 index 000000000000..123ce29d8b18 --- /dev/null +++ b/Zend/tests/partial_application/fuzz_007.phpt @@ -0,0 +1,19 @@ +--TEST-- +PFA fuzz 007 +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Undefined constant "UNDEFINED" diff --git a/Zend/tests/partial_application/hook.phpt b/Zend/tests/partial_application/hook.phpt new file mode 100644 index 000000000000..6402c5d01e74 --- /dev/null +++ b/Zend/tests/partial_application/hook.phpt @@ -0,0 +1,25 @@ +--TEST-- +Parent property hook call can not be partially applied +--FILE-- +a = 1; + +?> +--EXPECTF-- +Fatal error: Cannot create Closure for parent property hook call in %s on line %d diff --git a/Zend/tests/partial_application/instance_polymorphism.phpt b/Zend/tests/partial_application/instance_polymorphism.phpt new file mode 100644 index 000000000000..59fb5795d60f --- /dev/null +++ b/Zend/tests/partial_application/instance_polymorphism.phpt @@ -0,0 +1,43 @@ +--TEST-- +PFA: instance polymorphism +--FILE-- +m(?); + } +} + +class C extends P { + public function m(string|array $b): void { + echo __METHOD__, PHP_EOL; + var_dump($b); + } +} + +for ($i = 0; $i < 2; $i++) { + (new P())->get()(a: 'a'); + (new C())->get()(b: []); +} + +?> +--EXPECT-- +P::m +string(1) "a" +C::m +array(0) { +} +P::m +string(1) "a" +C::m +array(0) { +} diff --git a/Zend/tests/partial_application/invokable.phpt b/Zend/tests/partial_application/invokable.phpt new file mode 100644 index 000000000000..c21030e7733a --- /dev/null +++ b/Zend/tests/partial_application/invokable.phpt @@ -0,0 +1,51 @@ +--TEST-- +__invoke() can be partially applied +--FILE-- + +--EXPECTF-- +Closure [ public method {closure:%s:%d} ] { + @@ %s.php 11 - 11 + + - Parameters [2] { + Parameter #0 [ int $a ] + Parameter #1 [ object $b ] + } + - Return [ C ] +} + +Closure [ public method {closure:%s:%d} ] { + @@ %s.php 15 - 15 + + - Bound Variables [1] { + Variable #0 [ $b ] + } + + - Parameters [1] { + Parameter #0 [ int $a ] + } + - Return [ C ] +} + +int(1) +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/partial_application/jit_001.phpt b/Zend/tests/partial_application/jit_001.phpt new file mode 100644 index 000000000000..84aefa05ab28 --- /dev/null +++ b/Zend/tests/partial_application/jit_001.phpt @@ -0,0 +1,9 @@ +--TEST-- +PFA JIT 001 +--FILE-- + +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/partial_application/magic_001.phpt b/Zend/tests/partial_application/magic_001.phpt new file mode 100644 index 000000000000..bdcc10675785 --- /dev/null +++ b/Zend/tests/partial_application/magic_001.phpt @@ -0,0 +1,81 @@ +--TEST-- +__call() can be partially applied +--FILE-- +method(?); + +echo (string) new ReflectionFunction($bar); + +try { + $bar(); +} catch (Error $ex) { + printf("%s: %s\n", $ex::class, $ex->getMessage()); +} + +$bar(1, 2); +$bar(1); + +$bar = $foo->method(?, ...); + +echo (string) new ReflectionFunction($bar); + +$bar(10); +$bar(10, 20); + +$bar = $foo->method(new Foo, ...); + +echo (string) new ReflectionFunction($bar); + +$bar(100); +?> +--EXPECTF-- +Closure [ public method {closure:%s:%d} ] { + @@ %s 12 - 12 + + - Parameters [1] { + Parameter #0 [ mixed $arguments0 ] + } +} +ArgumentCountError: Too few arguments to function Foo::{closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected +Foo::method +int(1) +Foo::method +int(1) +Closure [ public method {closure:%s:%d} ] { + @@ %s 25 - 25 + + - Parameters [2] { + Parameter #0 [ mixed $arguments0 ] + Parameter #1 [ mixed ...$arguments ] + } +} +Foo::method +int(10) +Foo::method +int(10) +int(20) +Closure [ public method {closure:%s:%d} ] { + @@ %s 32 - 32 + + - Bound Variables [1] { + Variable #0 [ $arguments2 ] + } + + - Parameters [1] { + Parameter #0 [ mixed ...$arguments ] + } +} +Foo::method +object(Foo)#%d (0) { +} +int(100) diff --git a/Zend/tests/partial_application/magic_002.phpt b/Zend/tests/partial_application/magic_002.phpt new file mode 100644 index 000000000000..1d5efaea7c63 --- /dev/null +++ b/Zend/tests/partial_application/magic_002.phpt @@ -0,0 +1,72 @@ +--TEST-- +__callStatic() can be partially applied +--FILE-- + +--EXPECTF-- +Closure [ static public method {closure:%s:%d} ] { + @@ %s 10 - 10 + + - Parameters [1] { + Parameter #0 [ mixed $arguments0 ] + } +} +Foo::method +int(1) +Foo::method +int(1) +Closure [ static public method {closure:%s:%d} ] { + @@ %s 17 - 17 + + - Parameters [2] { + Parameter #0 [ mixed $arguments0 ] + Parameter #1 [ mixed ...$arguments ] + } +} +Foo::method +int(10) +Foo::method +int(10) +int(20) +Closure [ static public method {closure:%s:%d} ] { + @@ %s 24 - 24 + + - Bound Variables [1] { + Variable #0 [ $arguments2 ] + } + + - Parameters [1] { + Parameter #0 [ mixed ...$arguments ] + } +} +Foo::method +object(Foo)#%d (0) { +} +int(100) diff --git a/Zend/tests/partial_application/magic_003.phpt b/Zend/tests/partial_application/magic_003.phpt new file mode 100644 index 000000000000..242403ea38fc --- /dev/null +++ b/Zend/tests/partial_application/magic_003.phpt @@ -0,0 +1,13 @@ +--TEST-- +PFA magic trampoline release (result unused) +--FILE-- + +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/magic_004.phpt b/Zend/tests/partial_application/magic_004.phpt new file mode 100644 index 000000000000..8ef93a91ce83 --- /dev/null +++ b/Zend/tests/partial_application/magic_004.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA magic trampoline release (result used) +--FILE-- + +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/magic_005.phpt b/Zend/tests/partial_application/magic_005.phpt new file mode 100644 index 000000000000..e70ed90b1767 --- /dev/null +++ b/Zend/tests/partial_application/magic_005.phpt @@ -0,0 +1,29 @@ +--TEST-- +PFA magic null ptr deref in arginfo +--FILE-- +method(?); +var_dump($bar); +?> +--EXPECTF-- +object(Closure)#%d (%d) { + ["name"]=> + string(%d) "{closure:%s}" + ["file"]=> + string(%d) "%smagic_005.php" + ["line"]=> + int(7) + ["this"]=> + object(Foo)#%d (0) { + } + ["parameter"]=> + array(1) { + ["$arguments0"]=> + string(10) "" + } +} diff --git a/Zend/tests/partial_application/magic_006.phpt b/Zend/tests/partial_application/magic_006.phpt new file mode 100644 index 000000000000..29564d8b615a --- /dev/null +++ b/Zend/tests/partial_application/magic_006.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA magic varargs +--FILE-- +method(1,...); +$bar(2); +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/Zend/tests/partial_application/named_placeholders.phpt b/Zend/tests/partial_application/named_placeholders.phpt new file mode 100644 index 000000000000..19ce8cc03860 --- /dev/null +++ b/Zend/tests/partial_application/named_placeholders.phpt @@ -0,0 +1,121 @@ +--TEST-- +PFA supports named placeholders +--FILE-- +getMessage(), "\n"; +} + +echo "# Case 4\n"; + +function bar($a = 1, $b = 2, ...$c) { + var_dump($a, $b, $c); +} + +$d = bar(b: ?, ...); + +echo (string) new ReflectionFunction($d); + +$d(new B, new A, new C); + +echo "# Case 5\n"; + +try { + $d = bar(?, a: ?); +} catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Case 6\n"; + +try { + $d = bar(c: ?, ...); +} catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +# Case 1 +Closure [ static function {closure:%s:%d} ] { + @@ %snamed_placeholders.php 13 - 13 + + - Parameters [1] { + Parameter #0 [ $b ] + } +} +int(1) +object(B)#%d (0) { +} +int(3) +# Case 2 +Closure [ static function {closure:%s:%d} ] { + @@ %snamed_placeholders.php 21 - 21 + + - Bound Variables [1] { + Variable #0 [ $fn ] + } + + - Parameters [1] { + Parameter #0 [ $b ] + } +} +int(1) +object(B)#%d (0) { +} +int(3) +# Case 3 +ArgumentCountError: {closure:pfa:%s:29}(): Argument #1 ($a) not passed +# Case 4 +Closure [ static function {closure:%s:%d} ] { + @@ %snamed_placeholders.php 42 - 42 + + - Parameters [3] { + Parameter #0 [ $b ] + Parameter #1 [ $a = 1 ] + Parameter #2 [ ...$c ] + } +} +object(A)#%d (0) { +} +object(B)#%d (0) { +} +array(1) { + [0]=> + object(C)#%d (0) { + } +} +# Case 5 +Error: Named parameter $a overwrites previous placeholder +# Case 6 +Error: Cannot use named placeholder for unknown or variadic parameter $c diff --git a/Zend/tests/partial_application/never_cache_001.phpt b/Zend/tests/partial_application/never_cache_001.phpt new file mode 100644 index 000000000000..3c9e8a173e51 --- /dev/null +++ b/Zend/tests/partial_application/never_cache_001.phpt @@ -0,0 +1,30 @@ +--TEST-- +Inline cache can not be used for ZEND_ACC_NEVER_CACHE functions +--FILE-- +__invoke(?)); +} + +?> +--EXPECT-- +string(1) "A" +string(1) "B" +string(1) "A" +string(1) "B" diff --git a/Zend/tests/partial_application/non_dynamic_call_funcs.phpt b/Zend/tests/partial_application/non_dynamic_call_funcs.phpt new file mode 100644 index 000000000000..db25ef3dcc93 --- /dev/null +++ b/Zend/tests/partial_application/non_dynamic_call_funcs.phpt @@ -0,0 +1,46 @@ +--TEST-- +Functions that can not be called dynamically, can not be partially applied +--FILE-- +getMessage(), "\n"; + } +} + +?> +--EXPECT-- +Error: Cannot call func_get_arg() dynamically +Error: Cannot call compact() dynamically +Error: Cannot call extract() dynamically +Error: Cannot call func_get_args() dynamically +Error: Cannot call func_num_args() dynamically +Error: Cannot call get_defined_vars() dynamically diff --git a/Zend/tests/partial_application/observers.phpt b/Zend/tests/partial_application/observers.phpt new file mode 100644 index 000000000000..8717b38ca326 --- /dev/null +++ b/Zend/tests/partial_application/observers.phpt @@ -0,0 +1,34 @@ +--TEST-- +PFA support observers +--EXTENSIONS-- +zend_test +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.show_output=1 +zend_test.observer.observe_all=1 +--FILE-- + +--EXPECTF-- + + + + <{closure:%s}> + + + + +int(1) +int(2) + + + + diff --git a/Zend/tests/partial_application/optional_placeholder.phpt b/Zend/tests/partial_application/optional_placeholder.phpt new file mode 100644 index 000000000000..d6230241d906 --- /dev/null +++ b/Zend/tests/partial_application/optional_placeholder.phpt @@ -0,0 +1,77 @@ +--TEST-- +PFA optional placeholder: ? always generates required params; ... inherits optionality +--FILE-- +getParameters()[0]->isOptional()); + +$f = foo(?, ?); +$params = (new ReflectionFunction($f))->getParameters(); +var_dump($params[0]->isOptional(), $params[1]->isOptional()); + +$f = foo(?, ?, ?); +$params = (new ReflectionFunction($f))->getParameters(); +var_dump($params[0]->isOptional(), $params[1]->isOptional(), $params[2]->isOptional()); + +echo "# ... inherits optionality from the original function\n"; +$f = foo(?, ...); +$params = (new ReflectionFunction($f))->getParameters(); +var_dump($params[0]->isOptional(), $params[1]->isOptional(), $params[2]->isOptional()); + +$f = foo(?, ?, ...); +$params = (new ReflectionFunction($f))->getParameters(); +var_dump($params[0]->isOptional(), $params[1]->isOptional(), $params[2]->isOptional()); + +echo "# Calling works: ? params are required, unspecified optional params use their defaults\n"; +$f = foo(?, ?); +var_dump($f(10, 'hello')); + +echo "# Named ? placeholders are also required\n"; + +function bar(int $x = 0, int $y = 0) { + return [$x, $y]; +} + +$f = bar(y: ?); +var_dump((new ReflectionFunction($f))->getParameters()[0]->isOptional()); +var_dump($f(42)); + +?> +--EXPECT-- +# ? makes targeted params required regardless of original optionality +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +# ... inherits optionality from the original function +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +# Calling works: ? params are required, unspecified optional params use their defaults +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + float(3.14) +} +# Named ? placeholders are also required +bool(false) +array(2) { + [0]=> + int(0) + [1]=> + int(42) +} diff --git a/Zend/tests/partial_application/param_reorder.phpt b/Zend/tests/partial_application/param_reorder.phpt new file mode 100644 index 000000000000..3ade1beb0af7 --- /dev/null +++ b/Zend/tests/partial_application/param_reorder.phpt @@ -0,0 +1,202 @@ +--TEST-- +Named parameters define the order of parameters in a PFA +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +# All named +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 13 - 13 + + - Parameters [4] { + Parameter #0 [ $d ] + Parameter #1 [ $c ] + Parameter #2 [ $b ] + Parameter #3 [ $a ] + } +} + +array(4) { + [0]=> + int(4) + [1]=> + int(3) + [2]=> + int(2) + [3]=> + int(1) +} +# Some named: Positional first, then named in specified order +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 19 - 19 + + - Parameters [4] { + Parameter #0 [ $a ] + Parameter #1 [ $b ] + Parameter #2 [ $d ] + Parameter #3 [ $c ] + } +} + +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(4) + [3]=> + int(3) +} +# Some named, one unspecified +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 25 - 25 + + - Parameters [3] { + Parameter #0 [ $a ] + Parameter #1 [ $c ] + Parameter #2 [ $b ] + } +} + +array(4) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(2) + [3]=> + NULL +} +# Some named, some implicit added by '...' +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 31 - 31 + + - Parameters [4] { + Parameter #0 [ $c ] + Parameter #1 [ $b ] + Parameter #2 [ $a ] + Parameter #3 [ $d = NULL ] + } +} + +array(4) { + [0]=> + int(3) + [1]=> + int(2) + [2]=> + int(1) + [3]=> + int(4) +} +# Some named, some implicit added by '...' on variadic function +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 37 - 37 + + - Parameters [4] { + Parameter #0 [ $c ] + Parameter #1 [ $b ] + Parameter #2 [ $a ] + Parameter #3 [ ...$d ] + } +} + +array(4) { + [0]=> + int(3) + [1]=> + int(2) + [2]=> + int(1) + [3]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +# Some prebound, some named +Closure [ static function {closure:%s:%d} ] { + @@ %sparam_reorder.php 43 - 43 + + - Bound Variables [2] { + Variable #0 [ $a ] + Variable #1 [ $d ] + } + + - Parameters [2] { + Parameter #0 [ $c ] + Parameter #1 [ $b ] + } +} + +array(4) { + [0]=> + int(-1) + [1]=> + int(2) + [2]=> + int(1) + [3]=> + int(-2) +} +# Some named, some required missing +ArgumentCountError: f(): Argument #1 ($a) not passed diff --git a/Zend/tests/partial_application/pipe_optimization_001.phpt b/Zend/tests/partial_application/pipe_optimization_001.phpt new file mode 100644 index 000000000000..9610f37b76ac --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_001.phpt @@ -0,0 +1,47 @@ +--TEST-- +PFA optimization: PFA with single placeholder arg can be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a) { + var_dump($a); + } +} + +1 |> foo(?); + +?> +--EXPECTF-- +$_main: + ; (lines=9, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_001.php:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 1 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 DO_FCALL_BY_NAME +0008 RETURN int(1) + +foo: + ; (lines=5, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_001.php:4-6 +0000 CV0($a) = RECV 1 +0001 INIT_FCALL 1 %d string("var_dump") +0002 SEND_VAR CV0($a) 1 +0003 DO_ICALL +0004 RETURN null +int(1) diff --git a/Zend/tests/partial_application/pipe_optimization_002.phpt b/Zend/tests/partial_application/pipe_optimization_002.phpt new file mode 100644 index 000000000000..729e70d30e6b --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_002.phpt @@ -0,0 +1,51 @@ +--TEST-- +PFA pipe optimization: PFA with only one placeholder can be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +2 |> foo(1, ?); + +?> +--EXPECTF-- +$_main: + ; (lines=10, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_002.php:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 2 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(2) 2 +0008 DO_FCALL_BY_NAME +0009 RETURN int(1) + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_002.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_003.phpt b/Zend/tests/partial_application/pipe_optimization_003.phpt new file mode 100644 index 000000000000..da112f8f3cea --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_003.phpt @@ -0,0 +1,51 @@ +--TEST-- +PFA pipe optimization: PFA with only one placeholder can be optimized (placeholder first) +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +2 |> foo(?, 1); + +?> +--EXPECTF-- +$_main: + ; (lines=10, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_003.php:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 2 string("foo") +0006 SEND_VAL_EX int(2) 1 +0007 SEND_VAL_EX int(1) 2 +0008 DO_FCALL_BY_NAME +0009 RETURN int(1) + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_003.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null +int(2) +int(1) diff --git a/Zend/tests/partial_application/pipe_optimization_004.phpt b/Zend/tests/partial_application/pipe_optimization_004.phpt new file mode 100644 index 000000000000..addee498d810 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_004.phpt @@ -0,0 +1,88 @@ +--TEST-- +PFA pipe optimization: PFA with multiple placeholders can not be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +try { + 2 |> foo(?, ?); +} catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +$_main: + ; (lines=22, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_004.php:1-16 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 2 string("foo") +0006 SEND_PLACEHOLDER 1 +0007 SEND_PLACEHOLDER 2 +0008 T1 = CALLABLE_CONVERT_PARTIAL %d +0009 INIT_DYNAMIC_CALL 1 T1 +0010 SEND_VAL_EX int(2) 1 +0011 DO_FCALL +0012 RETURN int(1) +0013 CV0($e) = CATCH string("Throwable") +0014 T1 = FETCH_CLASS_NAME CV0($e) +0015 ECHO T1 +0016 ECHO string(": ") +0017 INIT_METHOD_CALL 0 CV0($e) string("getMessage") +0018 T1 = DO_FCALL +0019 ECHO T1 +0020 ECHO string("\n") +0021 RETURN int(1) +EXCEPTION TABLE: + 0005, 0013, -, - + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_004.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null + +$_main: + ; (lines=3, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s:1-10 +0000 T0 = DECLARE_LAMBDA_FUNCTION 0 +0001 FREE T0 +0002 RETURN int(1) + +{closure:%s:%d}: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s:10-10 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("foo") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 T2 = DO_UCALL +0006 RETURN T2 +ArgumentCountError: Too few arguments to function {closure:pfa:%s:%d}(), 1 passed in %s on line %d and exactly 2 expected diff --git a/Zend/tests/partial_application/pipe_optimization_005.phpt b/Zend/tests/partial_application/pipe_optimization_005.phpt new file mode 100644 index 000000000000..3ccfec836609 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_005.phpt @@ -0,0 +1,51 @@ +--TEST-- +PFA pipe optimization: PFA with only one placeholder can be optimized (variadic) +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +2 |> foo(1, ...); + +?> +--EXPECTF-- +$_main: + ; (lines=10, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_005.php:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 2 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(2) 2 +0008 DO_FCALL_BY_NAME +0009 RETURN int(1) + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_005.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_006.phpt b/Zend/tests/partial_application/pipe_optimization_006.phpt new file mode 100644 index 000000000000..6e06477427a3 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_006.phpt @@ -0,0 +1,55 @@ +--TEST-- +PFA pipe optimization: PFA with only one placeholder can be optimized (named) +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b = null, $c = null) { + var_dump($a, $b, $c); + } +} + +2 |> foo(1, c: ?); + +?> +--EXPECTF-- +$_main: + ; (lines=11, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_006.php:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 1 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(2) string("c") +0008 CHECK_UNDEF_ARGS +0009 DO_FCALL_BY_NAME +0010 RETURN int(1) + +foo: + ; (lines=9, args=3, vars=3, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_006.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV_INIT 2 null +0002 CV2($c) = RECV_INIT 3 null +0003 INIT_FCALL 3 %d string("var_dump") +0004 SEND_VAR CV0($a) 1 +0005 SEND_VAR CV1($b) 2 +0006 SEND_VAR CV2($c) 3 +0007 DO_ICALL +0008 RETURN null +int(1) +NULL +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_007.phpt b/Zend/tests/partial_application/pipe_optimization_007.phpt new file mode 100644 index 000000000000..09c3c765d237 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_007.phpt @@ -0,0 +1,88 @@ +--TEST-- +PFA pipe optimization: PFA with multiple placeholders can not be optimized (named) +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +try { + 2 |> foo(a: ?, b: ?); +} catch (\Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +$_main: + ; (lines=22, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_007.php:1-16 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 0 string("foo") +0006 SEND_PLACEHOLDER string("a") +0007 SEND_PLACEHOLDER string("b") +0008 T1 = CALLABLE_CONVERT_PARTIAL %d array(...) +0009 INIT_DYNAMIC_CALL 1 T1 +0010 SEND_VAL_EX int(2) 1 +0011 DO_FCALL +0012 RETURN int(1) +0013 CV0($e) = CATCH string("Throwable") +0014 T1 = FETCH_CLASS_NAME CV0($e) +0015 ECHO T1 +0016 ECHO string(": ") +0017 INIT_METHOD_CALL 0 CV0($e) string("getMessage") +0018 T1 = DO_FCALL +0019 ECHO T1 +0020 ECHO string("\n") +0021 RETURN int(1) +EXCEPTION TABLE: + 0005, 0013, -, - + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_007.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null + +$_main: + ; (lines=3, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s:1-10 +0000 T0 = DECLARE_LAMBDA_FUNCTION 0 +0001 FREE T0 +0002 RETURN int(1) + +{closure:%s:%d}: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s:10-10 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("foo") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 T2 = DO_UCALL +0006 RETURN T2 +ArgumentCountError: Too few arguments to function {closure:pfa:%s:%d}(), 1 passed in %s on line %d and exactly 2 expected diff --git a/Zend/tests/partial_application/pipe_optimization_008.phpt b/Zend/tests/partial_application/pipe_optimization_008.phpt new file mode 100644 index 000000000000..070074632c77 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_008.phpt @@ -0,0 +1,99 @@ +--TEST-- +PFA pipe optimization: PFA with both a variadic placeholder and named arg can not be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +try { + 2 |> foo(a: 1, ...); +} catch (\Throwable $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +$_main: + ; (lines=18, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_008.php:1-16 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 0 string("foo") +0006 SEND_VAL_EX int(1) string("a") +0007 T1 = CALLABLE_CONVERT_PARTIAL %d +0008 INIT_DYNAMIC_CALL 1 T1 +0009 SEND_VAL_EX int(2) 1 +0010 DO_FCALL +0011 RETURN int(1) +0012 CV0($e) = CATCH string("Throwable") +0013 INIT_METHOD_CALL 0 CV0($e) string("getMessage") +0014 T1 = DO_FCALL +0015 ECHO T1 +0016 ECHO string("\n") +0017 RETURN int(1) +EXCEPTION TABLE: + 0005, 0012, -, - + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_008.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null + +$_main: + ; (lines=4, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %s:1-10 +0000 T1 = DECLARE_LAMBDA_FUNCTION 0 +0001 BIND_LEXICAL T1 CV0($a) +0002 FREE T1 +0003 RETURN int(1) +LIVE RANGES: + 1: 0001 - 0002 (tmp/var) + +{closure:%s:%d}: + ; (lines=18, args=1, vars=2, tmps=%d) + ; (after optimizer) + ; %s:10-10 +0000 CV0($b) = RECV 1 +0001 BIND_STATIC CV1($a) +0002 T3 = FUNC_NUM_ARGS +0003 T2 = IS_SMALLER_OR_EQUAL T3 int(1) +0004 JMPZ T2 0010 +0005 INIT_FCALL 2 %d string("foo") +0006 SEND_VAR CV1($a) 1 +0007 SEND_VAR CV0($b) 2 +0008 T2 = DO_UCALL +0009 RETURN T2 +0010 INIT_FCALL 2 %d string("foo") +0011 SEND_VAR CV1($a) 1 +0012 SEND_VAR CV0($b) 2 +0013 T2 = FUNC_GET_ARGS int(1) +0014 SEND_UNPACK T2 +0015 CHECK_UNDEF_ARGS +0016 T2 = DO_UCALL +0017 RETURN T2 +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_009.phpt b/Zend/tests/partial_application/pipe_optimization_009.phpt new file mode 100644 index 000000000000..118482a3860b --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_009.phpt @@ -0,0 +1,102 @@ +--TEST-- +PFA pipe optimization: Evaluation order +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b, $c) { + var_dump($a, $b, $c); + } + function lhs() { + echo __FUNCTION__, "\n"; + return 0; + } + function arg1() { + echo __FUNCTION__, "\n"; + return 1; + } + function arg2() { + echo __FUNCTION__, "\n"; + return 2; + } +} + +lhs() |> foo(arg1(), ?, arg2()); + +?> +--EXPECTF-- +$_main: + ; (lines=20, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_009.php:1-24 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0008 +0004 DECLARE_FUNCTION string("foo") 0 +0005 DECLARE_FUNCTION string("lhs") 1 +0006 DECLARE_FUNCTION string("arg1") 2 +0007 DECLARE_FUNCTION string("arg2") 3 +0008 INIT_FCALL_BY_NAME 0 string("lhs") +0009 T0 = DO_FCALL_BY_NAME +0010 INIT_FCALL_BY_NAME 3 string("foo") +0011 INIT_FCALL_BY_NAME 0 string("arg1") +0012 V1 = DO_FCALL_BY_NAME +0013 SEND_VAR_NO_REF_EX V1 1 +0014 SEND_VAL_EX T0 2 +0015 INIT_FCALL_BY_NAME 0 string("arg2") +0016 V0 = DO_FCALL_BY_NAME +0017 SEND_VAR_NO_REF_EX V0 3 +0018 DO_FCALL_BY_NAME +0019 RETURN int(1) +LIVE RANGES: + 0: 0010 - 0014 (tmp/var) + +foo: + ; (lines=9, args=3, vars=3, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_009.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 CV2($c) = RECV 3 +0003 INIT_FCALL 3 %d string("var_dump") +0004 SEND_VAR CV0($a) 1 +0005 SEND_VAR CV1($b) 2 +0006 SEND_VAR CV2($c) 3 +0007 DO_ICALL +0008 RETURN null + +lhs: + ; (lines=2, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_009.php:7-10 +0000 ECHO string("lhs\n") +0001 RETURN int(0) + +arg1: + ; (lines=2, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_009.php:11-14 +0000 ECHO string("arg1\n") +0001 RETURN int(1) + +arg2: + ; (lines=2, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_009.php:15-18 +0000 ECHO string("arg2\n") +0001 RETURN int(2) +lhs +arg1 +arg2 +int(1) +int(0) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_010.phpt b/Zend/tests/partial_application/pipe_optimization_010.phpt new file mode 100644 index 000000000000..f77c2a97732e --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_010.phpt @@ -0,0 +1,58 @@ +--TEST-- +PFA pipe optimization: References +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo(&$a, $b) { + var_dump($a, $b); + $a = 2; + } +} + +1 |> foo($a, ?); +var_dump($a); + +?> +--EXPECTF-- +$_main: + ; (lines=13, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_010.php:1-14 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 2 string("foo") +0006 SEND_VAR_EX CV0($a) 1 +0007 SEND_VAL_EX int(1) 2 +0008 DO_FCALL_BY_NAME +0009 INIT_FCALL 1 %d string("var_dump") +0010 SEND_VAR CV0($a) 1 +0011 DO_ICALL +0012 RETURN int(1) + +foo: + ; (lines=8, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_010.php:4-7 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 ASSIGN CV0($a) int(2) +0007 RETURN null +NULL +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_011.phpt b/Zend/tests/partial_application/pipe_optimization_011.phpt new file mode 100644 index 000000000000..cd1c986d99e7 --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_011.phpt @@ -0,0 +1,98 @@ +--TEST-- +PFA pipe optimization: Evaluation order +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b, $c) { + var_dump($a, $b, $c); + } + function arg1() { + global $a; + $a = 2; + echo __FUNCTION__, "\n"; + return 1; + } + function arg2() { + global $a; + $a = 3; + echo __FUNCTION__, "\n"; + return 2; + } +} + +$a = 0; +$a |> foo(arg1(), ?, arg2()); + +?> +--EXPECTF-- +$_main: + ; (lines=19, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_011.php:1-25 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0007 +0004 DECLARE_FUNCTION string("foo") 0 +0005 DECLARE_FUNCTION string("arg1") %d +0006 DECLARE_FUNCTION string("arg2") %d +0007 ASSIGN CV0($a) int(0) +0008 T1 = QM_ASSIGN CV0($a) +0009 INIT_FCALL_BY_NAME 3 string("foo") +0010 INIT_FCALL_BY_NAME 0 string("arg1") +0011 V2 = DO_FCALL_BY_NAME +0012 SEND_VAR_NO_REF_EX V2 1 +0013 SEND_VAL_EX T1 2 +0014 INIT_FCALL_BY_NAME 0 string("arg2") +0015 V1 = DO_FCALL_BY_NAME +0016 SEND_VAR_NO_REF_EX V1 3 +0017 DO_FCALL_BY_NAME +0018 RETURN int(1) +LIVE RANGES: + 1: 0009 - 0013 (tmp/var) + +foo: + ; (lines=9, args=3, vars=3, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_011.php:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 CV2($c) = RECV 3 +0003 INIT_FCALL 3 %d string("var_dump") +0004 SEND_VAR CV0($a) 1 +0005 SEND_VAR CV1($b) 2 +0006 SEND_VAR CV2($c) 3 +0007 DO_ICALL +0008 RETURN null + +arg1: + ; (lines=4, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_011.php:7-12 +0000 BIND_GLOBAL CV0($a) string("a") +0001 ASSIGN CV0($a) int(2) +0002 ECHO string("arg1\n") +0003 RETURN int(1) + +arg2: + ; (lines=4, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %spipe_optimization_011.php:13-18 +0000 BIND_GLOBAL CV0($a) string("a") +0001 ASSIGN CV0($a) int(3) +0002 ECHO string("arg2\n") +0003 RETURN int(2) +arg1 +arg2 +int(1) +int(0) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_012.phpt b/Zend/tests/partial_application/pipe_optimization_012.phpt new file mode 100644 index 000000000000..da172874adce --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_012.phpt @@ -0,0 +1,52 @@ +--TEST-- +PFA optimization: PFA with named args and placeholders can be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +1 |> foo(?, b: 2); + +?> +--EXPECTF-- +$_main: + ; (lines=11, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 1 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(2) string("b") +0008 CHECK_UNDEF_ARGS +0009 DO_FCALL_BY_NAME +0010 RETURN int(1) + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_013.phpt b/Zend/tests/partial_application/pipe_optimization_013.phpt new file mode 100644 index 000000000000..7d1a48b2f2ed --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_013.phpt @@ -0,0 +1,87 @@ +--TEST-- +PFA optimization: PFA with named args and a variadic placeholder can not be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b) { + var_dump($a, $b); + } +} + +1 |> foo(b: 2, ...); + +?> +--EXPECTF-- +$_main: + ; (lines=12, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 0 string("foo") +0006 SEND_VAL_EX int(2) string("b") +0007 T0 = CALLABLE_CONVERT_PARTIAL 3 +0008 INIT_DYNAMIC_CALL 1 T0 +0009 SEND_VAL_EX int(1) 1 +0010 DO_FCALL +0011 RETURN int(1) + +foo: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 INIT_FCALL 2 %d string("var_dump") +0003 SEND_VAR CV0($a) 1 +0004 SEND_VAR CV1($b) 2 +0005 DO_ICALL +0006 RETURN null + +$_main: + ; (lines=4, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %s:1-9 +0000 T1 = DECLARE_LAMBDA_FUNCTION 0 +0001 BIND_LEXICAL T1 CV0($b) +0002 FREE T1 +0003 RETURN int(1) +LIVE RANGES: + 1: 0001 - 0002 (tmp/var) + +{closure:pfa:%s:9}: + ; (lines=18, args=1, vars=2, tmps=%d) + ; (after optimizer) + ; %s:9-9 +0000 CV0($a) = RECV 1 +0001 BIND_STATIC CV1($b) +0002 T3 = FUNC_NUM_ARGS +0003 T2 = IS_SMALLER_OR_EQUAL T3 int(1) +0004 JMPZ T2 0010 +0005 INIT_FCALL 2 %d string("foo") +0006 SEND_VAR CV0($a) 1 +0007 SEND_VAR CV1($b) 2 +0008 T2 = DO_UCALL +0009 RETURN T2 +0010 INIT_FCALL 2 %d string("foo") +0011 SEND_VAR CV0($a) 1 +0012 SEND_VAR CV1($b) 2 +0013 T2 = FUNC_GET_ARGS int(1) +0014 SEND_UNPACK T2 +0015 CHECK_UNDEF_ARGS +0016 T2 = DO_UCALL +0017 RETURN T2 +int(1) +int(2) diff --git a/Zend/tests/partial_application/pipe_optimization_014.phpt b/Zend/tests/partial_application/pipe_optimization_014.phpt new file mode 100644 index 000000000000..6e66d7e0e99d --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_014.phpt @@ -0,0 +1,68 @@ +--TEST-- +PFA pipe optimization: PFA with unknown named parameter can be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b = null, $c = null) { + var_dump($a, $b, $c); + } +} + +try { + 2 |> foo(1, unknown: ?); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +$_main: + ; (lines=20, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %s:1-16 +0000 INIT_FCALL 0 %d string("time") +0001 T2 = DO_ICALL +0002 T1 = IS_SMALLER int(0) T2 +0003 JMPZ T1 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 1 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(2) string("unknown") +0008 CHECK_UNDEF_ARGS +0009 DO_FCALL_BY_NAME +0010 RETURN int(1) +0011 CV0($e) = CATCH string("Error") +0012 T1 = FETCH_CLASS_NAME CV0($e) +0013 ECHO T1 +0014 ECHO string(": ") +0015 INIT_METHOD_CALL 0 CV0($e) string("getMessage") +0016 T1 = DO_FCALL +0017 ECHO T1 +0018 ECHO string("\n") +0019 RETURN int(1) +EXCEPTION TABLE: + 0005, 0011, -, - + +foo: + ; (lines=9, args=3, vars=3, tmps=%d) + ; (after optimizer) + ; %s:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV_INIT 2 null +0002 CV2($c) = RECV_INIT 3 null +0003 INIT_FCALL 3 %d string("var_dump") +0004 SEND_VAR CV0($a) 1 +0005 SEND_VAR CV1($b) 2 +0006 SEND_VAR CV2($c) 3 +0007 DO_ICALL +0008 RETURN null +Error: Unknown named parameter $unknown diff --git a/Zend/tests/partial_application/pipe_optimization_015.phpt b/Zend/tests/partial_application/pipe_optimization_015.phpt new file mode 100644 index 000000000000..ce293c7a300c --- /dev/null +++ b/Zend/tests/partial_application/pipe_optimization_015.phpt @@ -0,0 +1,55 @@ +--TEST-- +PFA pipe optimization: PFA with skipped optional parameter can be optimized +--EXTENSIONS-- +opcache +--INI-- +opcache.opt_debug_level=0x20000 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache= +opcache.file_cache_only=0 +--FILE-- + 0) { + function foo($a, $b = null, $c = null) { + var_dump($a, $b, $c); + } +} + +3 |> foo(1, c: ?); + +?> +--EXPECTF-- +$_main: + ; (lines=11, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s:1-12 +0000 INIT_FCALL 0 %d string("time") +0001 T1 = DO_ICALL +0002 T0 = IS_SMALLER int(0) T1 +0003 JMPZ T0 0005 +0004 DECLARE_FUNCTION string("foo") 0 +0005 INIT_FCALL_BY_NAME 1 string("foo") +0006 SEND_VAL_EX int(1) 1 +0007 SEND_VAL_EX int(3) string("c") +0008 CHECK_UNDEF_ARGS +0009 DO_FCALL_BY_NAME +0010 RETURN int(1) + +foo: + ; (lines=9, args=3, vars=3, tmps=%d) + ; (after optimizer) + ; %s:4-6 +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV_INIT 2 null +0002 CV2($c) = RECV_INIT 3 null +0003 INIT_FCALL 3 %d string("var_dump") +0004 SEND_VAR CV0($a) 1 +0005 SEND_VAR CV1($b) 2 +0006 SEND_VAR CV2($c) 3 +0007 DO_ICALL +0008 RETURN null +int(1) +NULL +int(3) diff --git a/Zend/tests/partial_application/preloading.inc b/Zend/tests/partial_application/preloading.inc new file mode 100644 index 000000000000..885ed0c5b0f1 --- /dev/null +++ b/Zend/tests/partial_application/preloading.inc @@ -0,0 +1,13 @@ + diff --git a/Zend/tests/partial_application/preloading.phpt b/Zend/tests/partial_application/preloading.phpt new file mode 100644 index 000000000000..23ad6edf2c4c --- /dev/null +++ b/Zend/tests/partial_application/preloading.phpt @@ -0,0 +1,19 @@ +--TEST-- +PFA preloading +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.preload={PWD}/preloading.inc +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(2) +int(2) diff --git a/Zend/tests/partial_application/rebinding_001.phpt b/Zend/tests/partial_application/rebinding_001.phpt new file mode 100644 index 000000000000..d1913957a8c9 --- /dev/null +++ b/Zend/tests/partial_application/rebinding_001.phpt @@ -0,0 +1,59 @@ +--TEST-- +PFA can only be rebound to an instanceof $this +--FILE-- +f(?); +$g = $c->g(?); + +echo "# Can be rebound to \$this of the same class:\n"; +$f->bindTo(new C)(1); + +echo "# Can be rebound to \$this of a sub-class:\n"; +$f->bindTo(new SubClass)(1); + +echo "# Cannot be rebound to an unrelated class:\n"; +try { + $f->bindTo(new Unrelated)(1); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Cannot unbind \$this on instance method:\n"; +try { + $f->bindTo(null)(1); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Can unbind \$this on static method:\n"; +$g->bindTo(null)(1); + +?> +--EXPECTF-- +# Can be rebound to $this of the same class: +object(C)#%d (0) { +} +# Can be rebound to $this of a sub-class: +object(SubClass)#%d (0) { +} +# Cannot be rebound to an unrelated class: + +Warning: Cannot bind method C::{closure:%s:%d}() to object of class Unrelated, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable +# Cannot unbind $this on instance method: + +Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable +# Can unbind $this on static method: +string(1) "C" diff --git a/Zend/tests/partial_application/rebinding_002.phpt b/Zend/tests/partial_application/rebinding_002.phpt new file mode 100644 index 000000000000..cfead54bbd81 --- /dev/null +++ b/Zend/tests/partial_application/rebinding_002.phpt @@ -0,0 +1,45 @@ +--TEST-- +PFA scope cannot be rebound +--FILE-- +f(?); +$g = g(?); + +echo "# Can be rebound to the same scope:\n"; +$f->bindTo($c, C::class)(1); + +echo "# Method cannot be rebound to a different scope:\n"; +try { + $f->bindTo($c, SubClass::class)(1); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Function cannot be rebound to a different scope:\n"; +try { + $g->bindTo($c, SubClass::class)(1); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +# Can be rebound to the same scope: +string(1) "C" +# Method cannot be rebound to a different scope: + +Warning: Cannot rebind scope of closure created from method, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable +# Function cannot be rebound to a different scope: + +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable diff --git a/Zend/tests/partial_application/rebinding_003.phpt b/Zend/tests/partial_application/rebinding_003.phpt new file mode 100644 index 000000000000..9417bbc2d320 --- /dev/null +++ b/Zend/tests/partial_application/rebinding_003.phpt @@ -0,0 +1,69 @@ +--TEST-- +Rebinding PFA of Closure rebinds inner Closure +--FILE-- +getF()(?); +$g = $c->getG()(?); + +echo "# Can be rebound to \$this of the same class:\n"; +$d = new C(); +$f->bindTo($d)($d); + +echo "# Can be rebound to \$this of a sub-class:\n"; +$d = new SubClass(); +$f->bindTo($d)($d); + +echo "# Cannot be rebound to an unrelated class:\n"; +try { + $f->bindTo(new Unrelated)($c); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Cannot unbind \$this on non-static closure:\n"; +try { + $f->bindTo(null)($c); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# Can unbind \$this on static closure:\n"; +$g->bindTo(null)($c); + +?> +--EXPECTF-- +# Can be rebound to $this of the same class: +object(C)#%d (0) { +} +bool(true) +# Can be rebound to $this of a sub-class: +object(SubClass)#%d (0) { +} +bool(true) +# Cannot be rebound to an unrelated class: + +Warning: Cannot bind method C::{closure:%s:%d}() to object of class Unrelated, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable +# Cannot unbind $this on non-static closure: + +Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d +Error: Value of type null is not callable +# Can unbind $this on static closure: +string(1) "C" +object(C)#%d (0) { +} diff --git a/Zend/tests/partial_application/recorded_warnings.phpt b/Zend/tests/partial_application/recorded_warnings.phpt new file mode 100644 index 000000000000..f25be826f525 --- /dev/null +++ b/Zend/tests/partial_application/recorded_warnings.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA compilation warnings are recorded and replayed +--FILE-- + +--EXPECTF-- +Deprecated: Using "_" as a type name is deprecated since 8.4 in %s on line 3 + +Deprecated: Using "_" as a type name is deprecated since 8.4 in %s on line 5 diff --git a/Zend/tests/partial_application/references_001.phpt b/Zend/tests/partial_application/references_001.phpt new file mode 100644 index 000000000000..080b3085acc0 --- /dev/null +++ b/Zend/tests/partial_application/references_001.phpt @@ -0,0 +1,24 @@ +--TEST-- +PFA receives by val if the actual function does +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + &string(49) "unchanged because foo() doesn't take by reference" +} +string(49) "unchanged because foo() doesn't take by reference" diff --git a/Zend/tests/partial_application/references_002.phpt b/Zend/tests/partial_application/references_002.phpt new file mode 100644 index 000000000000..42a90648c1ae --- /dev/null +++ b/Zend/tests/partial_application/references_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +PFA receives by ref if the actual function does +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + &int(2) +} +int(2) diff --git a/Zend/tests/partial_application/references_003.phpt b/Zend/tests/partial_application/references_003.phpt new file mode 100644 index 000000000000..be116b06c79f --- /dev/null +++ b/Zend/tests/partial_application/references_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA receives by ref if the actual function does +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +{closure:%s}(): Argument #1 ($b) could not be passed by reference diff --git a/Zend/tests/partial_application/references_004.phpt b/Zend/tests/partial_application/references_004.phpt new file mode 100644 index 000000000000..e5163c710da2 --- /dev/null +++ b/Zend/tests/partial_application/references_004.phpt @@ -0,0 +1,42 @@ +--TEST-- +PFA receives variadic param by ref if the actual function does +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %sreferences_004.php 13 - 13 + + - Bound Variables [2] { + Variable #0 [ $a ] + Variable #1 [ $args2 ] + } + + - Parameters [2] { + Parameter #0 [ &$args0 ] + Parameter #1 [ &...$args ] + } +} + +int(-2) +int(-3) +int(-4) diff --git a/Zend/tests/partial_application/references_005.phpt b/Zend/tests/partial_application/references_005.phpt new file mode 100644 index 000000000000..e8c7c27a07be --- /dev/null +++ b/Zend/tests/partial_application/references_005.phpt @@ -0,0 +1,26 @@ +--TEST-- +PFA inherits return by ref +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} diff --git a/Zend/tests/partial_application/reflection_001.phpt b/Zend/tests/partial_application/reflection_001.phpt new file mode 100644 index 000000000000..ac079515d0a0 --- /dev/null +++ b/Zend/tests/partial_application/reflection_001.phpt @@ -0,0 +1,48 @@ +--TEST-- +PFA reflection: optional parameters +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_001.php 6 - 6 + + - Parameters [3] { + Parameter #0 [ $a ] + Parameter #1 [ $b = 5 ] + Parameter #2 [ $c = 10 ] + } +} +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_001.php 10 - 10 + + - Parameters [3] { + Parameter #0 [ $a ] + Parameter #1 [ $b ] + Parameter #2 [ $c = 10 ] + } +} +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_001.php 14 - 14 + + - Parameters [3] { + Parameter #0 [ $a ] + Parameter #1 [ $b ] + Parameter #2 [ $c ] + } +} diff --git a/Zend/tests/partial_application/reflection_002.phpt b/Zend/tests/partial_application/reflection_002.phpt new file mode 100644 index 000000000000..da91a7af50cf --- /dev/null +++ b/Zend/tests/partial_application/reflection_002.phpt @@ -0,0 +1,57 @@ +--TEST-- +PFA reflection: variadics +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %s 6 - 6 + + - Parameters [1] { + Parameter #0 [ $a ] + } +} +Closure [ static function {closure:%s:%d} ] { + @@ %s 10 - 10 + + - Parameters [2] { + Parameter #0 [ $a ] + Parameter #1 [ ...$b ] + } +} +Closure [ static function {closure:%s:%d} ] { + @@ %s 14 - 14 + + - Parameters [2] { + Parameter #0 [ $a ] + Parameter #1 [ $b0 ] + } +} +Closure [ static function {closure:%s:%d} ] { + @@ %s 18 - 18 + + - Parameters [3] { + Parameter #0 [ $a ] + Parameter #1 [ $b0 ] + Parameter #2 [ $b1 ] + } +} diff --git a/Zend/tests/partial_application/reflection_003.phpt b/Zend/tests/partial_application/reflection_003.phpt new file mode 100644 index 000000000000..90506d38a778 --- /dev/null +++ b/Zend/tests/partial_application/reflection_003.phpt @@ -0,0 +1,43 @@ +--TEST-- +PFA reflection: internal with variadics +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_003.php 2 - 2 + + - Parameters [1] { + Parameter #0 [ string $format ] + } + - Return [ string ] +} +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_003.php 6 - 6 + + - Parameters [2] { + Parameter #0 [ string $format ] + Parameter #1 [ mixed ...$values ] + } + - Return [ string ] +} +Closure [ static function {closure:%s:%d} ] { + @@ %sreflection_003.php 10 - 10 + + - Parameters [2] { + Parameter #0 [ string $format ] + Parameter #1 [ mixed $values0 ] + } + - Return [ string ] +} diff --git a/Zend/tests/partial_application/reflection_004.phpt b/Zend/tests/partial_application/reflection_004.phpt new file mode 100644 index 000000000000..7226383f5afa --- /dev/null +++ b/Zend/tests/partial_application/reflection_004.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA reflection: ReflectionFunction::isAnonymous() is true for partials +--FILE-- +isAnonymous()); + +var_dump((new ReflectionFunction(function () {}))->isAnonymous()); + +var_dump((new ReflectionFunction(sprintf(?)))->isAnonymous()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) diff --git a/Zend/tests/partial_application/reflection_005.phpt b/Zend/tests/partial_application/reflection_005.phpt new file mode 100644 index 000000000000..be86270c004c --- /dev/null +++ b/Zend/tests/partial_application/reflection_005.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA reflection: ReflectionFunction::isClosure() is true for partials +--FILE-- +isClosure()); + +var_dump((new ReflectionFunction(function () {}))->isClosure()); + +var_dump((new ReflectionFunction(sprintf(?)))->isClosure()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) diff --git a/Zend/tests/partial_application/relative_return_types.phpt b/Zend/tests/partial_application/relative_return_types.phpt new file mode 100644 index 000000000000..5729f7edfd02 --- /dev/null +++ b/Zend/tests/partial_application/relative_return_types.phpt @@ -0,0 +1,148 @@ +--TEST-- +PFA supports relative return types +--FILE-- + 0) { + trait T { + public function getSelf(object $o): self { + return $o; + } + public function getStatic(object $o): static { + return $o; + } + } +} + +class C { + use T; +} + +class D extends C { +} + +$c = new C; + +echo "# C::getSelf():\n"; + +$self = $c->getSelf(?); + +echo (string) new ReflectionFunction($self), "\n"; + +var_dump($self($c)); +var_dump($self(new D)); +try { + $self(new stdClass); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +echo "# C::getStatic():\n"; + +$static = $c->getStatic(?); + +echo (string) new ReflectionFunction($static), "\n"; + +var_dump($static($c)); +var_dump($static(new D)); +try { + $static(new stdClass); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$d = new D; + +echo "# D::getSelf():\n"; + +$self = $d->getSelf(?); + +echo (string) new ReflectionFunction($self), "\n"; + +var_dump($self($d)); +var_dump($self(new C)); +try { + $self(new stdClass); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +echo "# D::getStatic():\n"; + +$static = $d->getStatic(?); + +echo (string) new ReflectionFunction($static), "\n"; + +var_dump($static($d)); +try { + var_dump($static(new C)); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +try { + $static(new stdClass); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +# C::getSelf(): +Closure [ public method {closure:%s:%d} ] { + @@ %s 25 - 25 + + - Parameters [1] { + Parameter #0 [ object $o ] + } + - Return [ self ] +} + +object(C)#%d (0) { +} +object(D)#%d (0) { +} +C::getSelf(): Return value must be of type C, stdClass returned +# C::getStatic(): +Closure [ public method {closure:%s:%d} ] { + @@ %s 39 - 39 + + - Parameters [1] { + Parameter #0 [ object $o ] + } + - Return [ static ] +} + +object(C)#%d (0) { +} +object(D)#%d (0) { +} +C::getStatic(): Return value must be of type C, stdClass returned +# D::getSelf(): +Closure [ public method {closure:%s:%d} ] { + @@ %s 55 - 55 + + - Parameters [1] { + Parameter #0 [ object $o ] + } + - Return [ self ] +} + +object(D)#%d (0) { +} +object(C)#%d (0) { +} +TypeError: C::getSelf(): Return value must be of type C, stdClass returned +# D::getStatic(): +Closure [ public method {closure:%s:%d} ] { + @@ %s 69 - 69 + + - Parameters [1] { + Parameter #0 [ object $o ] + } + - Return [ static ] +} + +object(D)#%d (0) { +} +TypeError: C::getStatic(): Return value must be of type D, C returned +C::getStatic(): Return value must be of type D, stdClass returned diff --git a/Zend/tests/partial_application/return_type.phpt b/Zend/tests/partial_application/return_type.phpt new file mode 100644 index 000000000000..ae3738e2c660 --- /dev/null +++ b/Zend/tests/partial_application/return_type.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA inherits return type +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %s 4 - 4 + + - Bound Variables [1] { + Variable #0 [ $a ] + } + + - Parameters [0] { + } + - Return [ array ] +} diff --git a/Zend/tests/partial_application/rfc_examples.inc b/Zend/tests/partial_application/rfc_examples.inc new file mode 100644 index 000000000000..53babc07888b --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples.inc @@ -0,0 +1,76 @@ + [$pfa, $closure]) { + echo "# ", $test, ": "; + $pfaReflector = new ReflectionFunction($pfa); + $closureReflector = new ReflectionFunction($closure); + + try { + if (count($pfaReflector->getParameters()) !== count($closureReflector->getParameters())) { + throw new Exception(sprintf( + "Arity does not match: expected %d, got %d", + count($closureReflector->getParameters()), + count($pfaReflector->getParameters()), + )); + } + + $it = new MultipleIterator(); + $it->attachIterator(new ArrayIterator($pfaReflector->getParameters())); + $it->attachIterator(new ArrayIterator($closureReflector->getParameters())); + foreach ($it as $i => [$pfaParam, $closureParam]) { + [$i] = $i; + if ($pfaParam->getName() !== $closureParam->getName()) { + throw new Exception(sprintf("Name of param %d does not match: %s vs %s", + $i, + $pfaParam->getName(), + $closureParam->getName(), + )); + } + if ((string)$pfaParam->getType() !== (string)$closureParam->getType()) { + throw new Exception(sprintf("Type of param %d does not match: %s vs %s", + $i, + $pfaParam->getType(), + $closureParam->getType(), + )); + } + if ($pfaParam->isOptional() !== $closureParam->isOptional()) { + throw new Exception(sprintf("Optionalness of param %d does not match: %d vs %d", + $i, + $pfaParam->isOptional(), + $closureParam->isOptional(), + )); + } + } + + $args = []; + foreach ($pfaReflector->getParameters() as $i => $p) { + $args[] = match ((string) $p->getType()) { + 'int' => 100 + $i, + 'float' => 100.5 + $i, + '?float' => 100.5 + $i, + 'string' => (string) (100 + $i), + 'Point' => new Point, + 'mixed' => "mixed($i)", + '' => "mixed($i)", + }; + } + + if ($pfaReflector->getClosureThis() !== $closureReflector->getClosureThis()) { + throw new Exception("\$this differs"); + } + + if ($pfa(...$args) !== $closure(...$args)) { + throw new Exception("PFA is not equivalent to closure"); + } + } catch (Exception $e) { + echo $e->getMessage(), "\n"; + echo $pfaReflector; + echo $closureReflector; + return; + } + + echo "Ok\n"; + } +} diff --git a/Zend/tests/partial_application/rfc_examples_const_expr.phpt b/Zend/tests/partial_application/rfc_examples_const_expr.phpt new file mode 100644 index 000000000000..e2fc57440256 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_const_expr.phpt @@ -0,0 +1,25 @@ +--TEST-- +PFA RFC examples: "Constant expressions" section +--XFAIL-- +PFA in constant expressions not implemented yet +--FILE-- + +==DONE== +--EXPECTF-- +==DONE== diff --git a/Zend/tests/partial_application/rfc_examples_debug.phpt b/Zend/tests/partial_application/rfc_examples_debug.phpt new file mode 100644 index 000000000000..9c5501090d4e --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_debug.phpt @@ -0,0 +1,25 @@ +--TEST-- +PFA RFC examples: "Debug output" section +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): g() +#1 %s(%d): f(1, Object(SensitiveParameterValue), 3) +#2 %s(%d): {closure:pfa:%s}(1, Object(SensitiveParameterValue)) +#3 {main} + thrown in %s on line %d diff --git a/Zend/tests/partial_application/rfc_examples_errors.phpt b/Zend/tests/partial_application/rfc_examples_errors.phpt new file mode 100644 index 000000000000..21818d7446e3 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_errors.phpt @@ -0,0 +1,34 @@ +--TEST-- +PFA RFC examples: "Error examples" section +--FILE-- +getMessage(), "\n"; +} + +try { + stuff(?, ?, ?, ?, ?, ?); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +try { + stuff(?, ?, 3.5, $point, i: 5); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +ArgumentCountError: Partial application of stuff() expects at least 4 arguments, 1 given +ArgumentCountError: Partial application of stuff() expects at most 5 arguments, 6 given +Error: Named parameter $i overwrites previous placeholder diff --git a/Zend/tests/partial_application/rfc_examples_eval_order.phpt b/Zend/tests/partial_application/rfc_examples_eval_order.phpt new file mode 100644 index 000000000000..2fd6c9422e92 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_eval_order.phpt @@ -0,0 +1,30 @@ +--TEST-- +PFA RFC examples: "Evaluation order" section +--FILE-- + speak($who, getArg()); +print "Arnaud\n"; +$arrow('Larry'); + +$partial = speak(?, getArg()); +print "Arnaud\n"; +$partial('Larry'); + +?> +--EXPECT-- +Arnaud +getArg +Larry: hi +getArg +Arnaud +Larry: hi diff --git a/Zend/tests/partial_application/rfc_examples_extra_args.phpt b/Zend/tests/partial_application/rfc_examples_extra_args.phpt new file mode 100644 index 000000000000..f6a24df8cc71 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_extra_args.phpt @@ -0,0 +1,54 @@ +--TEST-- +PFA RFC examples: "Variadics, func_get_args(), and extraneous arguments" section +--FILE-- + [ + foo(1, ?), + static function (int $j) { return foo(1, $j); }, + ], + 'If a PFA call has a ... placeholder, then any extraneous arguments will be passed through to the underlying function' => [ + foo(1, ?, ...), + static function (int $j) { return foo(1, $j, ...array_slice(func_get_args(), 1)); }, + ], + 'If a PFA call has a ... placeholder and the underlying function is variadic, then the trailing arguments will be forwarded directly but will get “collected” by the variadic parameter as normal' => [ + foo2(1, ?, ...), + static function (int $j, ...$extra) { return foo2(1, $j, ...$extra); }, + ], +]; + +check_equivalence($tests); + +echo "# The extra parameter here will be passed to the closure object, which will simply ignore it:\n"; +var_dump(foo(1, ?)(4, 'ignore me')); + +echo "# The extra parameter here will be passed to the closure object, which will forward it directly to the underlying function. It will be accessible only via ''func_get_args()'' et al:\n"; +var_dump(foo(1, ?, ...)(4, 'ignore me')); + +echo "# The extra parameter here will be passed to the closure object, which will forward it directly to the underlying function. It will show up as part of the \$extra array:\n"; +var_dump(foo2(1, ?, ...)(4, 'ignore me')); + +?> +==DONE== +--EXPECT-- +# If a PFA call has no ... placeholder, then any extraneous arguments to the resulting closure will be ignored. That is consistent with how manually writing the equivalent closure would behave, and is the same regardless of whether the underlying function is variadic: Ok +# If a PFA call has a ... placeholder, then any extraneous arguments will be passed through to the underlying function: Ok +# If a PFA call has a ... placeholder and the underlying function is variadic, then the trailing arguments will be forwarded directly but will get “collected” by the variadic parameter as normal: Ok +# The extra parameter here will be passed to the closure object, which will simply ignore it: +int(2) +# The extra parameter here will be passed to the closure object, which will forward it directly to the underlying function. It will be accessible only via ''func_get_args()'' et al: +int(3) +# The extra parameter here will be passed to the closure object, which will forward it directly to the underlying function. It will show up as part of the $extra array: +int(3) +==DONE== diff --git a/Zend/tests/partial_application/rfc_examples_incompatible_functions.phpt b/Zend/tests/partial_application/rfc_examples_incompatible_functions.phpt new file mode 100644 index 000000000000..dd99cb229ae8 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_incompatible_functions.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA RFC examples: "Incompatible functions" section +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Error: Cannot call func_get_arg() dynamically diff --git a/Zend/tests/partial_application/rfc_examples_magic_methods.phpt b/Zend/tests/partial_application/rfc_examples_magic_methods.phpt new file mode 100644 index 000000000000..7162a790c57c --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_magic_methods.phpt @@ -0,0 +1,47 @@ +--TEST-- +PFA RFC examples: "Magic methods" section +--FILE-- + [ + $f->method(?, ?), + (function ($f) { + return fn(mixed $arguments0, mixed $arguments1) => $f->method($arguments0, $arguments1); + })($f)->bindTo($f), + ], +]); + +try { + $f->method(?, ?)(a: 1, b: 2); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +# Test 1: Foo::method +Array +( + [0] => mixed(0) + [1] => mixed(1) +) +Foo::method +Array +( + [0] => mixed(0) + [1] => mixed(1) +) +Ok +Error: Unknown named parameter $a diff --git a/Zend/tests/partial_application/rfc_examples_overview.phpt b/Zend/tests/partial_application/rfc_examples_overview.phpt new file mode 100644 index 000000000000..b6fc8c0586c2 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_overview.phpt @@ -0,0 +1,44 @@ +--TEST-- +PFA RFC examples: "Overview" section +--FILE-- + [ + foo(1, ?, 3, 4), + static fn(int $b): int => foo(1, $b, 3, 4), + ], + 'Test 2' => [ + foo(1, ?, 3, ?), + static fn(int $b, int $d): int => foo(1, $b, 3, $d), + ], + 'Test 3' => [ + foo(1, ...), + static fn(int $b, int $c, int $d): int => foo(1, $b, $c, $d), + ], + 'Test 4' => [ + foo(1, 2, ...), + static fn(int $c, int $d): int => foo(1, 2, $c, $d), + ], + 'Test 5' => [ + foo(1, ?, 3, ...), + static fn(int $b, int $d): int => foo(1, $b, 3, $d), + ], +]; + +check_equivalence($tests); + +?> +--EXPECT-- +# Test 1: Ok +# Test 2: Ok +# Test 3: Ok +# Test 4: Ok +# Test 5: Ok diff --git a/Zend/tests/partial_application/rfc_examples_scoping.phpt b/Zend/tests/partial_application/rfc_examples_scoping.phpt new file mode 100644 index 000000000000..232d225dca6a --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_scoping.phpt @@ -0,0 +1,113 @@ +--TEST-- +PFA RFC examples: "Scoping" section +--FILE-- + [ + foo(?, ?), + static fn(int $i, int $j): string => foo($i, $j), + ], + 'Static closure 2' => [ + Foo::bar(?, ?), + static fn(int $i, int $j): string => Foo::bar($i, $j), + ], + 'Static closure 3' => [ + foo(?, ?)(1, ?), + static fn(int $j): string => foo(1, $j), + ], + 'Static closure 4' => [ + foo(...)(?), + static fn(int $i): string => foo($i, 0), + ], +]; + +check_equivalence($tests); + +$c = new C(); +$f = $c->f(?); + +echo "# Cannot unbind \$this:\n"; +var_dump($f->bindTo(null, C::class)); // Warning: Cannot unbind $this of method, this will be an error in PHP 9 (returns null) + +echo "# Cannot rebind scope:\n"; +var_dump($f->bindTo($c, CSubClass::class)); // Warning: Cannot rebind scope of closure created from method, this will be an error in PHP 9 (returns null) + +echo "# Can rebind \$this with subclass:\n"; +var_dump($f->bindTo(new CSubClass, C::class)); // Allowed + +echo "# Cannot rebind \$this with unrelated class:\n"; +$f = $f->bindTo(new Unrelated, C::class); // Warning: Cannot bind method C::{closure:/path/to/test.php:11}() to object of class Unrelated, this will be an error in PHP 9 (returns null) + +echo "# self resolution:\n"; +$c = new CSubClass(); +var_dump($c->f(?)(1)); // string(1) "C" +var_dump($c->g(?)(1)); // string(9) "CSubClass" +var_dump($c->h(1)(1)); // string(1) "C" + +?> +--EXPECTF-- +# Static closure 1: Ok +# Static closure 2: Ok +# Static closure 3: Ok +# Static closure 4: Ok +# Cannot unbind $this: + +Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d +NULL +# Cannot rebind scope: + +Warning: Cannot rebind scope of closure created from method, this will be an error in PHP 9 in %s on line %d +NULL +# Can rebind $this with subclass: +object(Closure)#%d (5) { + ["name"]=> + string(%d) "{closure:pfa:%s}" + ["file"]=> + string(%d) "%s" + ["line"]=> + int(53) + ["this"]=> + object(CSubClass)#%d (0) { + } + ["parameter"]=> + array(1) { + ["$a"]=> + string(10) "" + } +} +# Cannot rebind $this with unrelated class: + +Warning: Cannot bind method C::{closure:pfa:%s}() to object of class Unrelated, this will be an error in PHP 9 in %s on line %d +# self resolution: +string(1) "C" +string(9) "CSubClass" +string(1) "C" diff --git a/Zend/tests/partial_application/rfc_examples_semantics.phpt b/Zend/tests/partial_application/rfc_examples_semantics.phpt new file mode 100644 index 000000000000..a3ea25c30d6d --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_semantics.phpt @@ -0,0 +1,30 @@ +--TEST-- +PFA RFC examples: "Placeholder Semantics" section +--FILE-- + [ + foo(?, ?, ?, ?), + static fn(int $a, int $b, string $c0, string $c1) => foo($a, $b, $c0, $c1), + ], + 'Test 2' => [ + stuff(1, ?, p: ?, f: 3.14, ...), + static fn(string $s, Point $p, int $m = 0) => stuff(1, $s, 3.14, $p, $m), + ], +]; + +check_equivalence($tests); + +?> +--EXPECT-- +# Test 1: Ok +# Test 2: Ok diff --git a/Zend/tests/partial_application/rfc_examples_semantics_examples.phpt b/Zend/tests/partial_application/rfc_examples_semantics_examples.phpt new file mode 100644 index 000000000000..d8c4a83ca074 --- /dev/null +++ b/Zend/tests/partial_application/rfc_examples_semantics_examples.phpt @@ -0,0 +1,217 @@ +--TEST-- +PFA RFC examples: "Placeholder Semantics: Examples" section +--FILE-- + [ + stuff(?, ?, ...), + static fn(int $i1, string $s2, float $f3, Point $p4, int $m5 = 0): array + => stuff($i1, $s2, $f3, $p4, $m5), + ], + 'The degenerate "first class callables" case. (Supported since 8.1)' => [ + stuff(...), + static fn(int $i1, string $s2, float $f3, Point $p4, int $m5 = 0): array + => stuff($i1, $s2, $f3, $p4, $m5), + ], + 'Provide some values, require the rest to be provided later (1)' => [ + stuff(1, 'hi', ?, ?, ?), + static fn(float $f3, Point $p4, int $m5): array => stuff(1, 'hi', $f3, $p4, $m5), + ], + 'Provide some values, require the rest to be provided later (2)' => [ + stuff(1, 'hi', ...), + static fn(float $f3, Point $p4, int $m5 = 0): array => stuff(1, 'hi', $f3, $p4, $m5), + ], + 'Provide some values, but not just from the left (1)' => [ + stuff(1, ?, 3.5, ?, ?), + static fn(string $s2, Point $p4, int $m5): array => stuff(1, $s2, 3.5, $p4, $m5), + ], + 'Provide some values, but not just from the left (2)' => [ + stuff(1, ?, 3.5, ...), + static fn(string $s2, Point $p4, int $m5 = 0): array => stuff(1, $s2, 3.5, $p4, $m5), + ], + 'Provide just the last value' => [ + stuff(?, ?, ?, ?, 5), + static fn(int $i1, string $s2, float $f3, Point $p4): array + => stuff($i1, $s2, $f3, $p4, 5), + ], + 'Not accounting for an optional argument means it will always get its default value' => [ + stuff(?, ?, ?, ?), + static fn(int $i1, string $s2, float $f3, Point $p4): array + => stuff($i1, $s2, $f3, $p4), + ], + 'Named arguments can be pulled "out of order", and still work (1)' => [ + stuff(?, ?, f3: 3.5, p4: $point), + static fn(int $i1, string $s2): array => stuff($i1, $s2, 3.5, $point), + ], + 'Named arguments can be pulled "out of order", and still work (2)' => [ + stuff(?, ?, p4: $point, f3: 3.5), + static fn(int $i1, string $s2): array => stuff($i1, $s2, 3.5, $point), + ], + + 'But named placeholders adopt the order listed' => [ + stuff(s2: ?, i1: ?, p4: ?, f3: 3.5), + static fn(string $s2, int $i1, Point $p4): array => stuff($i1, $s2, 3.5, $p4), + ], + 'The ... "everything else" placeholder respects named arguments' => [ + stuff(?, ?, f3: 3.5, p4: $point, ...), + static fn(int $i1, string $s2, int $m5 = 0): array => stuff($i1, $s2, 3.5, $point, $m5), + ], + 'Prefill all parameters, making a "delayed call" or "thunk"' => [ + stuff(1, 'hi', 3.4, $point, 5, ...), + static fn(): array => stuff(1, 'hi', 3.4, $point, 5), + ], + + // Variadics + + 'FCC equivalent. The signature is unchanged' => [ + things(...), + static fn(int $i1, ?float $f3 = null, Point ...$points): array => things(...[$i1, $f3, ...$points]), + ], + 'Provide some values, but allow the variadic to remain variadic' => [ + things(1, 3.14, ...), + static fn(Point ...$points): array => things(1, 3.14, ...$points), + ], + 'In this version, the partial requires precisely four arguments, the last two of which will get received by things() in the variadic parameter. Note too that $f becomes required in this case' => [ + things(?, ?, ?, ?), + static fn(int $i1, ?float $f3, Point $points0, Point $points1): array => things($i1, $f3, $points0, $points1), + ], + + // Esoteric examples + + 'Esoteric 1' => [ + four(...), + static fn(int $a, int $b, int $c, int $d): string => four($a, $b, $c, $d), + ], + 'Esoteric 2' => [ + four(1, 2, ...), + static fn(int $c, int $d): string => four(1, 2, $c, $d), + ], + 'Esoteric 3' => [ + four(1, 2, 3, ?), + static fn(int $d): string => four(1, 2, 3, $d), + ], + 'Esoteric 4' => [ + four(1, ?, ?, 4), + static fn(int $b, int $c): string => four(1, $b, $c, 4), + ], + 'Esoteric 5' => [ + four(1, 2, 3, 4, ...), + static fn(): string => four(1, 2, 3, 4, ...array_slice(func_get_args(), 4)), + ], + 'Esoteric 6' => [ + four(d: 4, a: 1, ...), + static fn(int $b, int $c): string => four(1, $b, $c, 4, ...array_slice(func_get_args(), 4)), + ], + 'Esoteric 7' => [ + four(c: ?, d: 4, b: ?, a: 1), + static fn(int $c, int $b): string => four(1, $b, $c, 4, ...array_slice(func_get_args(), 4)), + ], + + // Other callable styles + + 'This is allowed. Note the method is static, thus the partial closure is static' => [ + E::make(1, ?), + static fn(int $y): E => E::make(1, $y), + ], + 'Note the method is non-static, so the partial closure is non-static' => (function () { + $eMaker = E::make(1, ?); + $e = $eMaker(2); + return [ + $e->foo(?, ?, 3), + (function ($e) { + return fn(int $a, int $b): array => $e->foo($a, $b, 3); + })($e)->bindTo($e), + ]; + })(), + '$c can then be further refined' => (function () { + $eMaker = E::make(1, ?); + $e = $eMaker(2); + $c = $e->foo(?, ?, 3); + return [ + $c(1, ?), + (function ($e) { + return fn(int $b): array => $e->foo(1, $b, 3); + })($e)->bindTo($e), + ]; + })(), + 'RunMe' => (function () { + $r = new RunMe(); + return [ + $r(?, 3), + (function ($r) { + return fn(int $a): string => $r($a, 3); + })($r)->bindTo($r), + ]; + })(), +]; + +check_equivalence($tests); + +?> +--EXPECT-- +# Manually specify the first two values, and pull the rest "as is": Ok +# The degenerate "first class callables" case. (Supported since 8.1): Ok +# Provide some values, require the rest to be provided later (1): Ok +# Provide some values, require the rest to be provided later (2): Ok +# Provide some values, but not just from the left (1): Ok +# Provide some values, but not just from the left (2): Ok +# Provide just the last value: Ok +# Not accounting for an optional argument means it will always get its default value: Ok +# Named arguments can be pulled "out of order", and still work (1): Ok +# Named arguments can be pulled "out of order", and still work (2): Ok +# But named placeholders adopt the order listed: Ok +# The ... "everything else" placeholder respects named arguments: Ok +# Prefill all parameters, making a "delayed call" or "thunk": Ok +# FCC equivalent. The signature is unchanged: Ok +# Provide some values, but allow the variadic to remain variadic: Ok +# In this version, the partial requires precisely four arguments, the last two of which will get received by things() in the variadic parameter. Note too that $f becomes required in this case: Ok +# Esoteric 1: Ok +# Esoteric 2: Ok +# Esoteric 3: Ok +# Esoteric 4: Ok +# Esoteric 5: Ok +# Esoteric 6: Ok +# Esoteric 7: Ok +# This is allowed. Note the method is static, thus the partial closure is static: Ok +# Note the method is non-static, so the partial closure is non-static: Ok +# $c can then be further refined: Ok +# RunMe: Ok diff --git a/Zend/tests/partial_application/static_method_001.phpt b/Zend/tests/partial_application/static_method_001.phpt new file mode 100644 index 000000000000..ce4151441c33 --- /dev/null +++ b/Zend/tests/partial_application/static_method_001.phpt @@ -0,0 +1,18 @@ +--TEST-- +PFA supports static methods +--FILE-- + +--EXPECTF-- +Foo::method diff --git a/Zend/tests/partial_application/static_pfa_001.phpt b/Zend/tests/partial_application/static_pfa_001.phpt new file mode 100644 index 000000000000..bc0f65b1ffd8 --- /dev/null +++ b/Zend/tests/partial_application/static_pfa_001.phpt @@ -0,0 +1,45 @@ +--TEST-- +PFA of static method is static +--FILE-- +f(?); +echo new ReflectionFunction($f), "\n"; +$f(1); + +// Warns +var_dump($f->bindTo(new C)); + +?> +--EXPECTF-- +Closure [ static public method {closure:pfa:%s:9} ] { + @@ %s 9 - 9 + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +int(1) +Closure [ static public method {closure:pfa:%s:13} ] { + @@ %s 13 - 13 + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +int(1) + +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d +NULL diff --git a/Zend/tests/partial_application/static_pfa_002.phpt b/Zend/tests/partial_application/static_pfa_002.phpt new file mode 100644 index 000000000000..5222109958b8 --- /dev/null +++ b/Zend/tests/partial_application/static_pfa_002.phpt @@ -0,0 +1,35 @@ +--TEST-- +PFA of instance method is not static +--FILE-- +f(?); +echo new ReflectionFunction($f), "\n"; +$f($c); + +$c2 = new C(); +$f->bindTo($c2)($c2); + +?> +--EXPECTF-- +Closure [ public method {closure:pfa:%s:10} ] { + @@ %s 10 - 10 + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +object(C)#%d (0) { +} +bool(true) +object(C)#%d (0) { +} +bool(true) diff --git a/Zend/tests/partial_application/static_pfa_003.phpt b/Zend/tests/partial_application/static_pfa_003.phpt new file mode 100644 index 000000000000..e7b3c187e187 --- /dev/null +++ b/Zend/tests/partial_application/static_pfa_003.phpt @@ -0,0 +1,30 @@ +--TEST-- +PFA of standalone function is static +--FILE-- +bindTo(new class {})); + +?> +--EXPECTF-- +Closure [ static function {closure:pfa:%s:7} ] { + @@ %s 7 - 7 + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +int(1) + +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d +NULL diff --git a/Zend/tests/partial_application/static_pfa_004.phpt b/Zend/tests/partial_application/static_pfa_004.phpt new file mode 100644 index 000000000000..093430232d43 --- /dev/null +++ b/Zend/tests/partial_application/static_pfa_004.phpt @@ -0,0 +1,44 @@ +--TEST-- +PFA of non-static closure is not static +--FILE-- +getMessage(), "\n"; + } +}; + +echo "# Original PFA\n"; + +$f = $c(?); +echo new ReflectionFunction($f), "\n"; +$f($c); + +echo "# Re-bound PFA\n"; + +$c2 = new class {}; +$f->bindTo($c2)($c2); + +?> +--EXPECTF-- +# Original PFA +Closure [ function {closure:pfa:%s:13} ] { + @@ %s 13 - 13 + + - Bound Variables [1] { + Variable #0 [ $fn ] + } + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +Error: Using $this when not in object context +# Re-bound PFA +object(class@anonymous)#3 (0) { +} +bool(true) diff --git a/Zend/tests/partial_application/static_pfa_005.phpt b/Zend/tests/partial_application/static_pfa_005.phpt new file mode 100644 index 000000000000..2783485b2f49 --- /dev/null +++ b/Zend/tests/partial_application/static_pfa_005.phpt @@ -0,0 +1,34 @@ +--TEST-- +PFA of static closure is static +--FILE-- +bindTo(new class {})); + +?> +--EXPECTF-- +Closure [ static function {closure:pfa:%s:7} ] { + @@ %s 7 - 7 + + - Bound Variables [1] { + Variable #0 [ $fn ] + } + + - Parameters [1] { + Parameter #0 [ $a ] + } +} + +int(1) + +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d +NULL diff --git a/Zend/tests/partial_application/static_polymorphism.phpt b/Zend/tests/partial_application/static_polymorphism.phpt new file mode 100644 index 000000000000..5f121c65c0e8 --- /dev/null +++ b/Zend/tests/partial_application/static_polymorphism.phpt @@ -0,0 +1,43 @@ +--TEST-- +PFA: static polymorphism +--FILE-- + +--EXPECT-- +P::m +string(1) "a" +C::m +array(0) { +} +P::m +string(1) "a" +C::m +array(0) { +} diff --git a/Zend/tests/partial_application/static_vars_001.phpt b/Zend/tests/partial_application/static_vars_001.phpt new file mode 100644 index 000000000000..610cddf37b54 --- /dev/null +++ b/Zend/tests/partial_application/static_vars_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +PFA static variables are shared (001) +--FILE-- + +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/partial_application/static_vars_002.phpt b/Zend/tests/partial_application/static_vars_002.phpt new file mode 100644 index 000000000000..4e6cc82b720d --- /dev/null +++ b/Zend/tests/partial_application/static_vars_002.phpt @@ -0,0 +1,22 @@ +--TEST-- +PFA static variables are shared (002) +--FILE-- + +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/partial_application/static_vars_003.phpt b/Zend/tests/partial_application/static_vars_003.phpt new file mode 100644 index 000000000000..04328bf717b8 --- /dev/null +++ b/Zend/tests/partial_application/static_vars_003.phpt @@ -0,0 +1,25 @@ +--TEST-- +PFA static variables are shared (003) +--FILE-- + +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/partial_application/superfluous_args_are_forwarded.phpt b/Zend/tests/partial_application/superfluous_args_are_forwarded.phpt new file mode 100644 index 000000000000..506092655217 --- /dev/null +++ b/Zend/tests/partial_application/superfluous_args_are_forwarded.phpt @@ -0,0 +1,44 @@ +--TEST-- +PFAs forwards superfluous args iff a variadic placeholder is specified +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(1) { + [0]=> + int(1) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/Zend/tests/partial_application/this.phpt b/Zend/tests/partial_application/this.phpt new file mode 100644 index 000000000000..bda6900bae39 --- /dev/null +++ b/Zend/tests/partial_application/this.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA $this +--FILE-- +method(new stdClass, ...); + +$baz = $bar(new stdClass, ...); + +var_dump($foo === $baz()); +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/partial_application/variation_call_001.phpt b/Zend/tests/partial_application/variation_call_001.phpt new file mode 100644 index 000000000000..b9c1c19ec9c6 --- /dev/null +++ b/Zend/tests/partial_application/variation_call_001.phpt @@ -0,0 +1,31 @@ +--TEST-- +PFA variation: call +--FILE-- +method(?, new Param); + +$closure(1); + +$closure->call(/* newThis: */ new Foo(), 10); +?> +--EXPECT-- +Bar: 1, Param +Foo: 10, Param diff --git a/Zend/tests/partial_application/variation_closure_001.phpt b/Zend/tests/partial_application/variation_closure_001.phpt new file mode 100644 index 000000000000..1d31f22c7f8a --- /dev/null +++ b/Zend/tests/partial_application/variation_closure_001.phpt @@ -0,0 +1,40 @@ +--TEST-- +PFA variation: Closure +--FILE-- + +--EXPECTF-- +Closure [ function {closure:%s:%d} ] { + @@ %s 5 - 5 + + - Bound Variables [2] { + Variable #0 [ $fn ] + Variable #1 [ $a ] + } + + - Parameters [1] { + Parameter #0 [ $b ] + } +} +Closure [ function {closure:pfa:%s:%d} ] { + @@ %s 10 - 10 + + - Bound Variables [2] { + Variable #0 [ $fn2 ] + Variable #1 [ $a ] + } + + - Parameters [1] { + Parameter #0 [ $fn ] + } +} diff --git a/Zend/tests/partial_application/variation_closure_002.phpt b/Zend/tests/partial_application/variation_closure_002.phpt new file mode 100644 index 000000000000..41abe0aaab0e --- /dev/null +++ b/Zend/tests/partial_application/variation_closure_002.phpt @@ -0,0 +1,28 @@ +--TEST-- +PFA variation: Closure::__invoke() +--FILE-- +__invoke(1, ?); + +echo (string) new ReflectionFunction($function); + +$function(10); +?> +--EXPECTF-- +Closure [ public method {closure:%s:%d} ] { + @@ %svariation_closure_002.php 6 - 6 + + - Bound Variables [1] { + Variable #0 [ $a ] + } + + - Parameters [1] { + Parameter #0 [ $b ] + } +} +int(1) +int(10) diff --git a/Zend/tests/partial_application/variation_closure_003.phpt b/Zend/tests/partial_application/variation_closure_003.phpt new file mode 100644 index 000000000000..da567e179853 --- /dev/null +++ b/Zend/tests/partial_application/variation_closure_003.phpt @@ -0,0 +1,46 @@ +--TEST-- +PFA variation: Closure::__invoke() with $this +--FILE-- +bar(); + +$function = $closure->__invoke(1, ?); + +echo (string) new ReflectionFunction($function); + +var_dump($function(10)); +?> +--EXPECTF-- +Closure [ public method {closure:%s:%d} ] { + @@ %svariation_closure_003.php 14 - 14 + + - Bound Variables [1] { + Variable #0 [ $a ] + } + + - Parameters [1] { + Parameter #0 [ $b ] + } +} +array(2) { + [0]=> + object(Foo)#1 (0) { + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(10) + } +} diff --git a/Zend/tests/partial_application/variation_debug_001.phpt b/Zend/tests/partial_application/variation_debug_001.phpt new file mode 100644 index 000000000000..04b63f3c4010 --- /dev/null +++ b/Zend/tests/partial_application/variation_debug_001.phpt @@ -0,0 +1,40 @@ +--TEST-- +PFA variation: var_dump(), user function +--FILE-- + +--EXPECTF-- +object(Closure)#%d (5) { + ["name"]=> + string(%d) "{closure:%s}" + ["file"]=> + string(%d) "%svariation_debug_001.php" + ["line"]=> + int(6) + ["static"]=> + array(4) { + ["b"]=> + object(stdClass)#%d (0) { + } + ["c"]=> + int(20) + ["c2"]=> + object(stdClass)#%d (0) { + } + ["extra_named_params"]=> + array(1) { + ["four"]=> + int(4) + } + } + ["parameter"]=> + array(1) { + ["$a"]=> + string(10) "" + } +} diff --git a/Zend/tests/partial_application/variation_debug_002.phpt b/Zend/tests/partial_application/variation_debug_002.phpt new file mode 100644 index 000000000000..a7c4c2d76e49 --- /dev/null +++ b/Zend/tests/partial_application/variation_debug_002.phpt @@ -0,0 +1,49 @@ +--TEST-- +PFA variation: var_dump(), internal function +--FILE-- + +--EXPECTF-- +object(Closure)#%d (5) { + ["name"]=> + string(%d) "{closure:%s}" + ["file"]=> + string(%d) "%svariation_debug_002.php" + ["line"]=> + int(2) + ["static"]=> + array(3) { + ["array"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["arrays2"]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + ["extra_named_params"]=> + array(1) { + ["four"]=> + object(stdClass)#%d (0) { + } + } + } + ["parameter"]=> + array(2) { + ["$callback"]=> + string(10) "" + ["$arrays"]=> + string(10) "" + } +} diff --git a/Zend/tests/partial_application/variation_ex_001.phpt b/Zend/tests/partial_application/variation_ex_001.phpt new file mode 100644 index 000000000000..0f36e90f616d --- /dev/null +++ b/Zend/tests/partial_application/variation_ex_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA variation: UAF in cleanup unfinished calls +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECTF-- +ArgumentCountError: Partial application of {closure:%s:%d}() expects at most 0 arguments, 1 given diff --git a/Zend/tests/partial_application/variation_gc_001.phpt b/Zend/tests/partial_application/variation_gc_001.phpt new file mode 100644 index 000000000000..2db49cc74363 --- /dev/null +++ b/Zend/tests/partial_application/variation_gc_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +PFA variation: GC (001) +--FILE-- +method = self::__construct(new stdClass, ...); + } +} + +$foo = new Foo(new stdClass); +$foo->bar = $foo; + +echo "OK"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/variation_gc_002.phpt b/Zend/tests/partial_application/variation_gc_002.phpt new file mode 100644 index 000000000000..31c721e8e681 --- /dev/null +++ b/Zend/tests/partial_application/variation_gc_002.phpt @@ -0,0 +1,11 @@ +--TEST-- +PFA variation: GC (002) +--FILE-- +prop = var_dump($obj, ?); + +echo "OK"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/variation_gc_003.phpt b/Zend/tests/partial_application/variation_gc_003.phpt new file mode 100644 index 000000000000..23cdaa1c666f --- /dev/null +++ b/Zend/tests/partial_application/variation_gc_003.phpt @@ -0,0 +1,15 @@ +--TEST-- +PFA variation: GC (003) +--FILE-- +prop = test(?, x: $obj); + +echo "OK"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/variation_invoke_001.phpt b/Zend/tests/partial_application/variation_invoke_001.phpt new file mode 100644 index 000000000000..9285c08da19b --- /dev/null +++ b/Zend/tests/partial_application/variation_invoke_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +PFA variation: __invoke() +--FILE-- +__invoke(32)); + +try { + $foo->nothing(); +} catch (Error $ex) { + echo $ex::class, ": ", $ex->getMessage(), "\n"; +} +?> +--EXPECT-- +int(42) +Error: Call to undefined method Closure::nothing() diff --git a/Zend/tests/partial_application/variation_nocall_001.phpt b/Zend/tests/partial_application/variation_nocall_001.phpt new file mode 100644 index 000000000000..3fbb3ec8d8c3 --- /dev/null +++ b/Zend/tests/partial_application/variation_nocall_001.phpt @@ -0,0 +1,12 @@ +--TEST-- +PFA variation: no call args leak +--FILE-- + +--EXPECT-- +OK diff --git a/Zend/tests/partial_application/variation_nocall_002.phpt b/Zend/tests/partial_application/variation_nocall_002.phpt new file mode 100644 index 000000000000..cd4823f1bd05 --- /dev/null +++ b/Zend/tests/partial_application/variation_nocall_002.phpt @@ -0,0 +1,30 @@ +--TEST-- +PFA variation: no call, order of destruction +--FILE-- +id, "\n"; + } +} +$foo = new Foo; +$f = $foo->method(?); +$g = $f(?); + +$map = new WeakMap(); +$map[$f] = new Dtor(1); +$map[$g] = new Dtor(2); + +unset($f); +unset($g); + +echo "OK"; +?> +--EXPECT-- +Dtor::__destruct 2 +Dtor::__destruct 1 +OK diff --git a/Zend/tests/partial_application/variation_parent_001.phpt b/Zend/tests/partial_application/variation_parent_001.phpt new file mode 100644 index 000000000000..98095f45009a --- /dev/null +++ b/Zend/tests/partial_application/variation_parent_001.phpt @@ -0,0 +1,76 @@ +--TEST-- +PFA variation: parent +--FILE-- +method(10, ...); +$baz = $bar(20, ...); + +var_dump($baz, $c = $baz(), $c() === $foo); +?> +--EXPECTF-- +object(Closure)#%d (6) { + ["name"]=> + string(%d) "{closure:%s}" + ["file"]=> + string(%d) "%svariation_parent_001.php" + ["line"]=> + int(12) + ["static"]=> + array(2) { + ["fn"]=> + object(Closure)#%d (6) { + ["name"]=> + string(%d) "{closure:%s:%d}" + ["file"]=> + string(%d) "%s" + ["line"]=> + int(11) + ["static"]=> + array(1) { + ["a"]=> + int(10) + } + ["this"]=> + object(Foo)#%d (0) { + } + ["parameter"]=> + array(2) { + ["$b"]=> + string(10) "" + ["$c"]=> + string(10) "" + } + } + ["b"]=> + int(20) + } + ["this"]=> + object(Foo)#%d (0) { + } + ["parameter"]=> + array(1) { + ["$c"]=> + string(10) "" + } +} +object(Closure)#%d (4) { + ["name"]=> + string(25) "{closure:Foo::method():4}" + ["file"]=> + string(%d) "%s" + ["line"]=> + int(4) + ["this"]=> + object(Foo)#%d (0) { + } +} +bool(true) diff --git a/Zend/tests/partial_application/variation_scope_001.phpt b/Zend/tests/partial_application/variation_scope_001.phpt new file mode 100644 index 000000000000..0dcea0921c43 --- /dev/null +++ b/Zend/tests/partial_application/variation_scope_001.phpt @@ -0,0 +1,18 @@ +--TEST-- +PFA variation: called scope +--FILE-- +method(new stdClass, ...); + +$bar(); +?> +--EXPECT-- +Foo::method diff --git a/Zend/tests/partial_application/variation_strict_001.phpt b/Zend/tests/partial_application/variation_strict_001.phpt new file mode 100644 index 000000000000..835f6e138055 --- /dev/null +++ b/Zend/tests/partial_application/variation_strict_001.phpt @@ -0,0 +1,20 @@ +--TEST-- +PFA variation: strict_types declared +--FILE-- +getMessage()); +} +?> +--EXPECTF-- +TypeError: {closure:%s:%d}(): Argument #1 ($int) must be of type int, string given, called in %s on line %d diff --git a/Zend/tests/partial_application/variation_variadics_001.phpt b/Zend/tests/partial_application/variation_variadics_001.phpt new file mode 100644 index 000000000000..850f0eda149d --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_001.phpt @@ -0,0 +1,31 @@ +--TEST-- +PFA variation: variadics, user function +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %s 6 - 6 + + - Bound Variables [2] { + Variable #0 [ $a ] + Variable #1 [ $b2 ] + } + + - Parameters [1] { + Parameter #0 [ ...$b ] + } +} +int(10) +int(100) +int(1000) +int(10000) diff --git a/Zend/tests/partial_application/variation_variadics_002.phpt b/Zend/tests/partial_application/variation_variadics_002.phpt new file mode 100644 index 000000000000..21d8169fc42c --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_002.phpt @@ -0,0 +1,25 @@ +--TEST-- +PFA variation: variadics, internal function +--FILE-- + +--EXPECTF-- +Closure [ static function {closure:%s:%d} ] { + @@ %svariation_variadics_002.php 2 - 2 + + - Bound Variables [2] { + Variable #0 [ $format ] + Variable #1 [ $values2 ] + } + + - Parameters [1] { + Parameter #0 [ mixed ...$values ] + } + - Return [ string ] +} +100 1000 10000 diff --git a/Zend/tests/partial_application/variation_variadics_004.phpt b/Zend/tests/partial_application/variation_variadics_004.phpt new file mode 100644 index 000000000000..228404dc8272 --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_004.phpt @@ -0,0 +1,45 @@ +--TEST-- +PFA variation: variadics and optional args +--FILE-- + +--EXPECT-- +# Bound year, pass day: +2006-01-02 +# Bound month, pass day: +2005-12-02 +# Bound month, bound year, pass day: +2016-12-02 +# Bound month, no args: +2005-12-01 +# Bound month, bound year, no args: +2016-12-01 diff --git a/Zend/tests/partial_application/variation_variadics_006.phpt b/Zend/tests/partial_application/variation_variadics_006.phpt new file mode 100644 index 000000000000..cda62a2f3bfb --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_006.phpt @@ -0,0 +1,17 @@ +--TEST-- +PFA variation: named may overwrite variadic placeholder +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + string(1) "a" +} diff --git a/Zend/tests/partial_application/variation_variadics_007.phpt b/Zend/tests/partial_application/variation_variadics_007.phpt new file mode 100644 index 000000000000..9624e05b449b --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_007.phpt @@ -0,0 +1,14 @@ +--TEST-- +PFA variation: extra through variadic +--FILE-- + $a + $b)); +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/partial_application/variation_variadics_008.phpt b/Zend/tests/partial_application/variation_variadics_008.phpt new file mode 100644 index 000000000000..4190bb759e68 --- /dev/null +++ b/Zend/tests/partial_application/variation_variadics_008.phpt @@ -0,0 +1,16 @@ +--TEST-- +PFA variation: variadics wrong signature checked +--FILE-- +getMessage() . PHP_EOL; +} +?> +--EXPECTF-- +Partial application of {closure:%s:%d}() expects at most 1 arguments, 2 given diff --git a/Zend/tests/pipe_operator/gh22490.phpt b/Zend/tests/pipe_operator/gh22490.phpt new file mode 100644 index 000000000000..c801d938c275 --- /dev/null +++ b/Zend/tests/pipe_operator/gh22490.phpt @@ -0,0 +1,60 @@ +--TEST-- +GH-22490: Null pointer dereference compiling a pipe on the lhs of ??= +--FILE-- +p = 7; + return $o; +} + +echo "property unset, assigns and returns default: "; +var_dump((1 |> unset_prop(...))->p ??= 99); +echo "pipe evaluated once: "; +var_dump($calls); + +$calls = 0; +echo "property set, returns existing value: "; +var_dump((1 |> set_prop(...))->p ??= 99); +echo "pipe evaluated once: "; +var_dump($calls); + +function new_array($x) { + global $calls; + $calls++; + return []; +} + +$calls = 0; +echo "dim target on a pipe result: "; +var_dump((1 |> new_array(...))[0] ??= 42); +echo "pipe evaluated once: "; +var_dump($calls); + +function identity($x) { + return $x; +} + +$calls = 0; +echo "nested pipe on the lhs: "; +var_dump((1 |> identity(...) |> unset_prop(...))->p ??= 5); +echo "pipe evaluated once: "; +var_dump($calls); +?> +--EXPECT-- +property unset, assigns and returns default: int(99) +pipe evaluated once: int(1) +property set, returns existing value: int(7) +pipe evaluated once: int(1) +dim target on a pipe result: int(42) +pipe evaluated once: int(1) +nested pipe on the lhs: int(5) +pipe evaluated once: int(1) diff --git a/Zend/tests/prop_const_expr/non_enums_catchable.phpt b/Zend/tests/prop_const_expr/non_enums_catchable.phpt index 6f410ac7acbe..702bc024122d 100644 --- a/Zend/tests/prop_const_expr/non_enums_catchable.phpt +++ b/Zend/tests/prop_const_expr/non_enums_catchable.phpt @@ -18,6 +18,7 @@ const A_prop = (new A)->{new Printer ? 'printer' : null}; ?> --EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d Printer Fatal error: Uncaught Error: Fetching properties on non-enums in constant expressions is not allowed in %s:%d diff --git a/Zend/tests/require_once_warning_to_exception.phpt b/Zend/tests/require_once_warning_to_exception.phpt index d115ac68ccde..bc706622438f 100644 --- a/Zend/tests/require_once_warning_to_exception.phpt +++ b/Zend/tests/require_once_warning_to_exception.phpt @@ -16,4 +16,4 @@ try { ?> --EXPECT-- -require_once(does-not-exist.php): Failed to open stream: No such file or directory +require_once(): Failed to open stream: No such file or directory diff --git a/Zend/tests/return_types/042.phpt b/Zend/tests/return_types/042.phpt index 069e0228ff99..21483047d4f2 100644 --- a/Zend/tests/return_types/042.phpt +++ b/Zend/tests/return_types/042.phpt @@ -20,5 +20,10 @@ class JustAnArray { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from UnionType::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionType2::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionTypeOldStyle::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/tests/traits/bug60536_001.phpt b/Zend/tests/traits/bug60536_001.phpt index a58098ca3112..712600a4b1d1 100644 --- a/Zend/tests/traits/bug60536_001.phpt +++ b/Zend/tests/traits/bug60536_001.phpt @@ -23,5 +23,9 @@ $a->__construct(); echo "DONE"; ?> --EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + Warning: Undefined property: Z::$x in %s on line %d DONE diff --git a/Zend/tests/try/gh22280.phpt b/Zend/tests/try/gh22280.phpt new file mode 100644 index 000000000000..30944aff59a6 --- /dev/null +++ b/Zend/tests/try/gh22280.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-22280: goto to label before try/finally after try/catch +--FILE-- + +--EXPECT-- +try +finally +done diff --git a/Zend/tests/type_coercion/gh22112.phpt b/Zend/tests/type_coercion/gh22112.phpt new file mode 100644 index 000000000000..84fdc393a828 --- /dev/null +++ b/Zend/tests/type_coercion/gh22112.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-22112 (Assertion failure when error handler throws during NaN to bool/string coercion at function entry) +--FILE-- +getMessage(), "\n"; +} + +try { + take_string($nan); +} catch (Exception $e) { + echo "string: ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +bool: unexpected NAN value was coerced to bool +string: unexpected NAN value was coerced to string diff --git a/Zend/tests/unserialize_typed_prop_reset_on_failure.phpt b/Zend/tests/unserialize_typed_prop_reset_on_failure.phpt new file mode 100644 index 000000000000..2380c8e5550e --- /dev/null +++ b/Zend/tests/unserialize_typed_prop_reset_on_failure.phpt @@ -0,0 +1,37 @@ +--TEST-- +unserialize() resets a typed property to its default on every failure path +--FILE-- +getPrevious()) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +/* By-ref type violation: the slot is reset to its default. */ +class C { public array $a; } +try { + var_dump(unserialize('O:1:"C":1:{s:1:"a";R:1;}')); +} catch (\Throwable $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +echo "OK\n"; +?> +--EXPECTF-- +Warning: unserialize(): Error at offset %d of %d bytes in %s on line %d +TypeError: %s +OK diff --git a/Zend/tests/vm_kind_tailcall_clang_windows.phpt b/Zend/tests/vm_kind_tailcall_clang_windows.phpt new file mode 100644 index 000000000000..f66a17ae0daf --- /dev/null +++ b/Zend/tests/vm_kind_tailcall_clang_windows.phpt @@ -0,0 +1,25 @@ +--TEST-- +Tailcall VM is selected when compiled with Clang >= 19 on Windows x64 +--SKIPIF-- + clang version (\d+)/', $info, $m)) { + die('skip not compiled with clang'); +} + +if ((int)$m[1] < 19) { + die('skip requires clang >= 19'); +} +?> +--FILE-- + +--EXPECT-- +string(21) "ZEND_VM_KIND_TAILCALL" diff --git a/Zend/tests/weakrefs/gh17442_1.phpt b/Zend/tests/weakrefs/gh17442_1.phpt index fc7f60174ed9..d535c307e3be 100644 --- a/Zend/tests/weakrefs/gh17442_1.phpt +++ b/Zend/tests/weakrefs/gh17442_1.phpt @@ -17,6 +17,6 @@ headers_sent($obj,$generator); Fatal error: Uncaught Exception: Test in %s:%d Stack trace: #0 [internal function]: class@anonymous->__destruct() -#1 %s(%d): headers_sent(NULL, 0) +#1 %s(%d): headers_sent(NULL, NULL) #2 {main} thrown in %s on line %d diff --git a/Zend/zend.c b/Zend/zend.c index bce1faede8fb..07692db85196 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -55,6 +54,9 @@ ZEND_API int compiler_globals_id; ZEND_API int executor_globals_id; ZEND_API size_t compiler_globals_offset; ZEND_API size_t executor_globals_offset; +/* ts_allocate_tls_id takes a callback so each thread resolves its own block. + * A plain &language_scanner_globals would capture only the registering thread's address. */ +static void *language_scanner_globals_tls_addr(void) { return &language_scanner_globals; } static HashTable *global_function_table = NULL; static HashTable *global_class_table = NULL; static HashTable *global_constants_table = NULL; @@ -78,7 +80,7 @@ ZEND_API bool zend_dtrace_enabled; /* version information */ static char *zend_version_info; static uint32_t zend_version_info_length; -#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n" +#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright © Zend by Perforce\n" #define PRINT_ZVAL_INDENT 4 /* true multithread-shared globals */ @@ -565,6 +567,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* zend_object *zobj = Z_OBJ_P(expr); uint32_t *guard = zend_get_recursion_guard(zobj); zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(zobj); + /* cut off on NULL byte ... class@anonymous */ smart_str_appends(buf, ZSTR_VAL(class_name)); zend_string_release_ex(class_name, 0); @@ -811,6 +814,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ executor_globals->user_error_handler_error_reporting = 0; ZVAL_UNDEF(&executor_globals->user_error_handler); ZVAL_UNDEF(&executor_globals->user_exception_handler); + ZVAL_UNDEF(&executor_globals->last_fatal_error_backtrace); executor_globals->current_execute_data = NULL; executor_globals->current_module = NULL; executor_globals->exit_status = 0; @@ -832,8 +836,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ #endif executor_globals->flags = EG_FLAGS_INITIAL; executor_globals->record_errors = false; - executor_globals->num_errors = 0; - executor_globals->errors = NULL; + memset(&executor_globals->errors, 0, sizeof(executor_globals->errors)); executor_globals->filename_override = NULL; executor_globals->lineno_override = -1; #ifdef ZEND_CHECK_STACK_LIMIT @@ -1019,9 +1022,11 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_init_rsrc_list_dtors(); #ifdef ZTS - ts_allocate_fast_id(&compiler_globals_id, &compiler_globals_offset, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor); - ts_allocate_fast_id(&executor_globals_id, &executor_globals_offset, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor); - ts_allocate_fast_id(&language_scanner_globals_id, &language_scanner_globals_offset, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL); + ts_allocate_fast_id_at(&compiler_globals_id, &compiler_globals_offset, ZEND_CG_OFFSET, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor); + ts_allocate_fast_id_at(&executor_globals_id, &executor_globals_offset, ZEND_EG_OFFSET, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor); + ts_allocate_tls_id(&language_scanner_globals_id, language_scanner_globals_tls_addr, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL); + ZEND_ASSERT(compiler_globals_offset == ZEND_CG_OFFSET); + ZEND_ASSERT(executor_globals_offset == ZEND_EG_OFFSET); ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL); compiler_globals = ts_resource(compiler_globals_id); executor_globals = ts_resource(executor_globals_id); @@ -1304,7 +1309,7 @@ ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ * snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author); - zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1); + zend_version_info = (char *) perealloc(zend_version_info, zend_version_info_length+new_info_length + 1, true); strncat(zend_version_info, new_info, new_info_length); zend_version_info_length += new_info_length; free(new_info); @@ -1445,8 +1450,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; bool orig_record_errors; - uint32_t orig_num_errors; - zend_error_info **orig_errors; + zend_err_buf orig_errors_buf; zend_result res; /* If we're executing a function during SCCP, count any warnings that may be emitted, @@ -1458,11 +1462,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( } /* Emit any delayed error before handling fatal error */ - if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(num_errors)) { - uint32_t num_errors = EG(num_errors); - zend_error_info **errors = EG(errors); - EG(num_errors) = 0; - EG(errors) = NULL; + if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(errors).size) { + zend_err_buf errors_buf = EG(errors); + EG(errors).size = 0; bool orig_record_errors = EG(record_errors); EG(record_errors) = false; @@ -1472,12 +1474,11 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( int orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting); EG(user_error_handler_error_reporting) = 0; - zend_emit_recorded_errors_ex(num_errors, errors); + zend_emit_recorded_errors_ex(errors_buf.size, errors_buf.errors); EG(user_error_handler_error_reporting) = orig_user_error_handler_error_reporting; EG(record_errors) = orig_record_errors; - EG(num_errors) = num_errors; - EG(errors) = errors; + EG(errors) = errors_buf; } if (EG(record_errors)) { @@ -1486,12 +1487,13 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( info->lineno = error_lineno; info->filename = zend_string_copy(error_filename); info->message = zend_string_copy(message); - - /* This is very inefficient for a large number of errors. - * Use pow2 realloc if it becomes a problem. */ - EG(num_errors)++; - EG(errors) = erealloc(EG(errors), sizeof(zend_error_info*) * EG(num_errors)); - EG(errors)[EG(num_errors)-1] = info; + EG(errors).size++; + if (EG(errors).size > EG(errors).capacity) { + uint32_t capacity = EG(errors).capacity ? EG(errors).capacity + (EG(errors).capacity >> 1) : 2; + EG(errors).errors = erealloc(EG(errors).errors, sizeof(zend_error_info *) * capacity); + EG(errors).capacity = capacity; + } + EG(errors).errors[EG(errors).size - 1] = info; /* Do not process non-fatal recorded error */ if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) { @@ -1574,17 +1576,15 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( } orig_record_errors = EG(record_errors); - orig_num_errors = EG(num_errors); - orig_errors = EG(errors); EG(record_errors) = false; - EG(num_errors) = 0; - EG(errors) = NULL; + + orig_errors_buf = EG(errors); + memset(&EG(errors), 0, sizeof(EG(errors))); res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params); EG(record_errors) = orig_record_errors; - EG(num_errors) = orig_num_errors; - EG(errors) = orig_errors; + EG(errors) = orig_errors_buf; if (res == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { @@ -1779,8 +1779,7 @@ ZEND_API void zend_begin_record_errors(void) { ZEND_ASSERT(!EG(record_errors) && "Error recording already enabled"); EG(record_errors) = true; - EG(num_errors) = 0; - EG(errors) = NULL; + EG(errors).size = 0; } ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors) @@ -1794,24 +1793,23 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info ZEND_API void zend_emit_recorded_errors(void) { EG(record_errors) = false; - zend_emit_recorded_errors_ex(EG(num_errors), EG(errors)); + zend_emit_recorded_errors_ex(EG(errors).size, EG(errors).errors); } ZEND_API void zend_free_recorded_errors(void) { - if (!EG(num_errors)) { + if (!EG(errors).size) { return; } - for (uint32_t i = 0; i < EG(num_errors); i++) { - zend_error_info *info = EG(errors)[i]; + for (uint32_t i = 0; i < EG(errors).size; i++) { + zend_error_info *info = EG(errors).errors[i]; zend_string_release(info->filename); zend_string_release(info->message); - efree(info); + efree_size(info, sizeof(zend_error_info)); } - efree(EG(errors)); - EG(errors) = NULL; - EG(num_errors) = 0; + efree(EG(errors).errors); + memset(&EG(errors), 0, sizeof(EG(errors))); } ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ diff --git a/Zend/zend.h b/Zend/zend.h index ebb7d2391955..0d5303192b57 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -281,7 +280,9 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); EG(bailout) = &__bailout; \ if (SETJMP(__bailout)==0) { #define zend_catch \ + ZEND_ASSERT(EG(bailout) == &__bailout); \ } else { \ + ZEND_ASSERT(EG(bailout) == &__bailout); \ EG(bailout) = __orig_bailout; #define zend_end_try() \ } \ diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 211a5d14e6c3..72f4727eeddf 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -126,7 +125,7 @@ ZEND_API const char *zend_get_type_by_const(int type) /* {{{ */ return "mixed"; case _IS_NUMBER: return "int|float"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -262,7 +261,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, case ZPP_ERROR_FAILURE: ZEND_ASSERT(EG(exception) && "Should have produced an error already"); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -375,7 +374,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void) ); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic( + zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, va_list va) { zend_string *func_name; const char *arg_name; @@ -384,8 +384,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en return; } - func_name = get_active_function_or_method_name(); - arg_name = get_active_function_arg_name(arg_num); + func_name = get_function_or_method_name(function); + arg_name = get_function_arg_name(function, arg_num); zend_vspprintf(&message, 0, format, va); zend_throw_error(error_ce, "%s(): Argument #%d%s%s%s %s", @@ -395,34 +395,65 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en efree(message); zend_string_release(func_name); } -/* }}} */ + +ZEND_API ZEND_COLD void zend_argument_error_ex(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, ...) +{ + va_list va; + + va_start(va, format); + zend_argument_error_variadic(error_ce, function, arg_num, format, va); + va_end(va); +} ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...) /* {{{ */ { va_list va; + const zend_function *function = zend_active_function(); va_start(va, format); - zend_argument_error_variadic(error_ce, arg_num, format, va); + zend_argument_error_variadic(error_ce, function, arg_num, format, va); va_end(va); } /* }}} */ +ZEND_API ZEND_COLD void zend_argument_type_error_ex( + const zend_function *function, uint32_t arg_num, const char *format, ...) +{ + va_list va; + + va_start(va, format); + zend_argument_error_variadic(zend_ce_type_error, function, arg_num, format, va); + va_end(va); +} + ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...) /* {{{ */ { va_list va; + const zend_function *function = zend_active_function(); va_start(va, format); - zend_argument_error_variadic(zend_ce_type_error, arg_num, format, va); + zend_argument_error_variadic(zend_ce_type_error, function, arg_num, format, va); va_end(va); } /* }}} */ +ZEND_API ZEND_COLD void zend_argument_value_error_ex( + const zend_function *function, uint32_t arg_num, const char *format, ...) +{ + va_list va; + + va_start(va, format); + zend_argument_error_variadic(zend_ce_value_error, function, arg_num, format, va); + va_end(va); +} + ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...) /* {{{ */ { va_list va; + const zend_function *function = zend_active_function(); va_start(va, format); - zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va); + zend_argument_error_variadic(zend_ce_value_error, function, arg_num, format, va); va_end(va); } /* }}} */ @@ -510,35 +541,37 @@ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32 return !EG(exception); } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */ +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("bool", arg_num)) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - *dest = zend_is_true(arg); - } else { - return 0; + bool result = zend_is_true(arg); + if (UNEXPECTED(EG(exception))) { + return ZPP_PARSE_BOOL_STATUS_ERROR; + } + return result; } - return 1; + return ZPP_PARSE_BOOL_STATUS_ERROR; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */ +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) /* {{{ */ { if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - return zend_parse_arg_bool_weak(arg, dest, arg_num); + return zend_parse_arg_bool_weak(arg, arg_num); } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) { if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - return zend_parse_arg_bool_weak(arg, dest, arg_num); + return zend_parse_arg_bool_weak(arg, arg_num); } ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */ @@ -625,44 +658,46 @@ ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_l return zend_parse_arg_long_weak(arg, dest, arg_num); } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */ +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { - *dest = (double)Z_LVAL_P(arg); + return (double)Z_LVAL_P(arg); } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { zend_long l; + double dval; uint8_t type; - if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) { + if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, &dval)) != IS_DOUBLE)) { if (EXPECTED(type != 0)) { - *dest = (double)(l); + return (double)(l); } else { - return 0; + return NAN; } + } else { + return dval; } } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("float", arg_num)) { - return 0; + return NAN; } - *dest = 0.0; + return 0.0; } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { - *dest = 1.0; + return 1.0; } else { - return 0; + return NAN; } - return 1; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */ +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { /* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */ - *dest = (double)Z_LVAL_P(arg); + return (double)Z_LVAL_P(arg); } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return NAN; } - return zend_parse_arg_double_weak(arg, dest, arg_num); + return zend_parse_arg_double_weak(arg, arg_num); } /* }}} */ @@ -729,58 +764,61 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval ** return true; } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) { - return 0; + return NULL; } convert_to_string(arg); - *dest = Z_STR_P(arg); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + return Z_STR_P(arg); } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) { zend_object *zobj = Z_OBJ_P(arg); zval obj; if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) { OBJ_RELEASE(zobj); ZVAL_COPY_VALUE(arg, &obj); - *dest = Z_STR_P(arg); - return 1; + return Z_STR_P(arg); } - return 0; + return NULL; } else { - return 0; + return NULL; } - return 1; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num) /* {{{ */ { if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return NULL; } - return zend_parse_arg_str_weak(arg, dest, arg_num); + return zend_parse_arg_str_weak(arg, arg_num); } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) +ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num) { if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) { - return 0; + return NULL; } - return zend_parse_arg_str_weak(arg, dest, arg_num); + return zend_parse_arg_str_weak(arg, arg_num); } ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num) /* {{{ */ { + zend_string *str; if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { return 0; } if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) { *dest_str = NULL; return 1; - } else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) { + } else if ((str = zend_parse_arg_str_weak(arg, arg_num)) != NULL) { *dest_long = 0; + *dest_str = str; return 1; } else { return 0; @@ -2505,19 +2543,19 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ dl_loaded_count++; } } ZEND_HASH_FOREACH_END(); - module_request_startup_handlers = (zend_module_entry**)realloc( + module_request_startup_handlers = (zend_module_entry**)perealloc( module_request_startup_handlers, sizeof(zend_module_entry*) * (startup_count + 1 + shutdown_count + 1 + - post_deactivate_count + 1)); + post_deactivate_count + 1), true); module_request_startup_handlers[startup_count] = NULL; module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1; module_request_shutdown_handlers[shutdown_count] = NULL; module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1; module_post_deactivate_handlers[post_deactivate_count] = NULL; /* Cannot reuse module_request_startup_handlers because it is freed in zend_destroy_modules, which happens before zend_unload_modules. */ - modules_dl_loaded = realloc(modules_dl_loaded, sizeof(zend_module_entry*) * (dl_loaded_count + 1)); + modules_dl_loaded = perealloc(modules_dl_loaded, sizeof(zend_module_entry*) * (dl_loaded_count + 1), true); modules_dl_loaded[dl_loaded_count] = NULL; startup_count = 0; @@ -2544,10 +2582,10 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ } } ZEND_HASH_FOREACH_END(); - class_cleanup_handlers = (zend_class_entry**)realloc( + class_cleanup_handlers = (zend_class_entry**)perealloc( class_cleanup_handlers, sizeof(zend_class_entry*) * - (class_count + 1)); + (class_count + 1), true); class_cleanup_handlers[class_count] = NULL; if (class_count) { @@ -2810,34 +2848,38 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_ARRAY); - } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_LCNAME)) { zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_magic_method_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_ARRAY); - } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_LCNAME)) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_STRING); - } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_LCNAME)) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, (MAY_BE_ARRAY | MAY_BE_NULL)); - } else if (zend_string_equals_literal(lcname, "__serialize")) { + if ((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & MAY_BE_NULL) { + zend_error(E_DEPRECATED, "Returning null from %s::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead", + ZSTR_VAL(ce->name)); + } + } else if (zend_string_equals_literal(lcname, ZEND_SERIALIZE_FUNC_NAME)) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_ARRAY); - } else if (zend_string_equals_literal(lcname, "__unserialize")) { + } else if (zend_string_equals_literal(lcname, ZEND_UNSERIALIZE_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ARRAY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); - } else if (zend_string_equals_literal(lcname, "__set_state")) { + } else if (zend_string_equals_literal(lcname, ZEND_SET_STATE_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); @@ -2885,16 +2927,16 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, c } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) { ce->__isset = fptr; ce->ce_flags |= ZEND_ACC_USE_GUARDS; - } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_LCNAME)) { ce->__callstatic = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_LCNAME)) { ce->__tostring = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_LCNAME)) { ce->__debugInfo = fptr; ce->ce_flags |= ZEND_ACC_USE_GUARDS; - } else if (zend_string_equals_literal(lcname, "__serialize")) { + } else if (zend_string_equals_literal(lcname, ZEND_SERIALIZE_FUNC_NAME)) { ce->__serialize = fptr; - } else if (zend_string_equals_literal(lcname, "__unserialize")) { + } else if (zend_string_equals_literal(lcname, ZEND_UNSERIALIZE_FUNC_NAME)) { ce->__unserialize = fptr; } } @@ -2997,6 +3039,7 @@ ZEND_API void zend_convert_internal_arg_info(zend_arg_info *new_arg_info, const new_arg_info->name = NULL; new_arg_info->default_value = NULL; } + new_arg_info->doc_comment = NULL; new_arg_info->type = arg_info->type; zend_convert_internal_arg_info_type(&new_arg_info->type, persistent); } @@ -3045,7 +3088,6 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend internal_function->prop_info = NULL; internal_function->attributes = NULL; internal_function->frameless_function_infos = ptr->frameless_function_infos; - internal_function->fn_flags2 = 0; if (EG(active)) { // at run-time: this ought to only happen if registered with dl() or somehow temporarily at runtime ZEND_MAP_PTR_INIT(internal_function->run_time_cache, zend_arena_calloc(&CG(arena), 1, zend_internal_run_time_cache_reserved_size())); } else { @@ -3055,7 +3097,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend ZEND_MAP_PTR_INIT(internal_function->run_time_cache, NULL); #endif } - if (ptr->flags) { + if (ptr->flags & UINT32_MAX) { if (!(ptr->flags & ZEND_ACC_PPP_MASK)) { if (ptr->flags != ZEND_ACC_DEPRECATED && scope) { zend_error(error_type, "Invalid access level for %s::%s() - access must be exactly one of public, protected or private", ZSTR_VAL(scope->name), ptr->fname); @@ -3067,6 +3109,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } else { internal_function->fn_flags = ZEND_ACC_PUBLIC; } + internal_function->fn_flags2 = ptr->flags >> 32; if (ptr->arg_info) { zend_internal_function_info *info = (zend_internal_function_info*)ptr->arg_info; @@ -3107,7 +3150,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend /* If not specified, add __toString() return type for compatibility with Stringable * interface. */ - if (scope && zend_string_equals_literal_ci(internal_function->function_name, "__tostring") && + if (scope && zend_string_equals_literal_ci(internal_function->function_name, ZEND_TOSTRING_FUNC_LCNAME) && !(internal_function->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { zend_error(E_CORE_WARNING, "%s::__toString() implemented without string return type", ZSTR_VAL(scope->name)); @@ -3143,7 +3186,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } lowercase_name = zend_string_tolower_ex(internal_function->function_name, type == MODULE_PERSISTENT); lowercase_name = zend_new_interned_string(lowercase_name); - reg_function = malloc(sizeof(zend_internal_function)); + reg_function = pemalloc(sizeof(zend_internal_function), true); memcpy(reg_function, &function, sizeof(zend_internal_function)); if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) { unload=1; @@ -3161,8 +3204,8 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend zend_flf_capacity *= 2; } /* +1 for NULL terminator */ - zend_flf_handlers = realloc(zend_flf_handlers, (zend_flf_capacity + 1) * sizeof(void *)); - zend_flf_functions = realloc(zend_flf_functions, (zend_flf_capacity + 1) * sizeof(zend_function *)); + zend_flf_handlers = perealloc(zend_flf_handlers, (zend_flf_capacity + 1) * sizeof(void *), true); + zend_flf_functions = perealloc(zend_flf_functions, (zend_flf_capacity + 1) * sizeof(zend_function *), true); } zend_flf_handlers[zend_flf_count] = flf_info->handler; zend_flf_functions[zend_flf_count] = (zend_function *)reg_function; @@ -3208,7 +3251,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend /* Treat return type as an extra argument */ num_args++; - new_arg_info = malloc(sizeof(zend_arg_info) * num_args); + new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, true); reg_function->arg_info = new_arg_info + 1; for (i = 0; i < num_args; i++) { zend_convert_internal_arg_info(&new_arg_info[i], &arg_info[i], @@ -3493,7 +3536,7 @@ ZEND_API int zend_next_free_module(void) /* {{{ */ static zend_class_entry *do_register_internal_class(const zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */ { - zend_class_entry *class_entry = malloc(sizeof(zend_class_entry)); + zend_class_entry *class_entry = pemalloc(sizeof(zend_class_entry), true); zend_string *lowercase_name; *class_entry = *orig_class_entry; @@ -3769,6 +3812,10 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (error) zend_spprintf(error, 0, "class \"%.*s\" not found", (int)name_len, ZSTR_VAL(name)); } ZSTR_ALLOCA_FREE(lcname, use_heap); + /* User error handlers may throw from deprecations above; do not report callable as valid. */ + if (UNEXPECTED(EG(exception))) { + return false; + } return ret; } /* }}} */ @@ -4030,7 +4077,7 @@ static zend_always_inline bool zend_is_callable_check_func(const zval *callable, } /* }}} */ -ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, const zend_object *object) /* {{{ */ +ZEND_API zend_string *zend_get_callable_name_ex(const zval *callable, const zend_object *object) /* {{{ */ { try_again: switch (Z_TYPE_P(callable)) { @@ -4088,7 +4135,53 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, const zend_objec } /* }}} */ -ZEND_API zend_string *zend_get_callable_name(zval *callable) /* {{{ */ +static bool zend_fcc_function_handler_equals(const zend_function *func1, const zend_function *func2) /* {{{ */ +{ + if (func1 == func2) { + return true; + } + + const bool fake_closure1 = (func1->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0; + const bool fake_closure2 = (func2->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0; + + if (!fake_closure1 && !fake_closure2) { + return false; + } + if (((func1->common.fn_flags & ZEND_ACC_CLOSURE) && !fake_closure1) || + ((func2->common.fn_flags & ZEND_ACC_CLOSURE) && !fake_closure2)) { + return false; + } + if (func1->type != func2->type || + func1->common.scope != func2->common.scope || + !zend_string_equals(func1->common.function_name, func2->common.function_name)) { + return false; + } + + if (func1->type == ZEND_USER_FUNCTION) { + return func1->op_array.opcodes == func2->op_array.opcodes; + } + + return func1->internal_function.handler == func2->internal_function.handler; +} +/* }}} */ + +ZEND_API bool zend_fcc_closure_equals_ex(const zend_fcall_info_cache* a, const zend_fcall_info_cache* b) /* {{{ */ +{ + const zend_function *func1 = a->function_handler; + const zend_function *func2 = b->function_handler; + + if (a->closure && a->closure->ce == zend_ce_closure) { + func1 = zend_get_closure_method_def(a->closure); + } + if (b->closure && b->closure->ce == zend_ce_closure) { + func2 = zend_get_closure_method_def(b->closure); + } + + return zend_fcc_function_handler_equals(func1, func2); +} +/* }}} */ + +ZEND_API zend_string *zend_get_callable_name(const zval *callable) /* {{{ */ { return zend_get_callable_name_ex(callable, NULL); } @@ -4205,7 +4298,7 @@ ZEND_API bool zend_is_callable_at_frame( } /* }}} */ -ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error) /* {{{ */ +ZEND_API bool zend_is_callable_ex(const zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error) /* {{{ */ { /* Determine callability at the first parent user frame. */ const zend_execute_data *frame = EG(current_execute_data); @@ -4220,13 +4313,13 @@ ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t return ret; } -ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name) /* {{{ */ +ZEND_API bool zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name) /* {{{ */ { return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL); } /* }}} */ -ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error) /* {{{ */ +ZEND_API zend_result zend_fcall_info_init(const zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error) /* {{{ */ { if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error)) { return FAILURE; @@ -4239,6 +4332,7 @@ ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, fci->param_count = 0; fci->params = NULL; fci->named_params = NULL; + fci->consumed_args = 0; return SUCCESS; } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index d78ee6604e34..2c0b892d1941 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -37,7 +36,7 @@ typedef struct _zend_function_entry { zif_handler handler; const struct _zend_internal_arg_info *arg_info; uint32_t num_args; - uint32_t flags; + uint64_t flags; const zend_frameless_function_info *frameless_function_infos; const char *doc_comment; } zend_function_entry; @@ -49,6 +48,7 @@ typedef struct _zend_fcall_info { zval *params; zend_object *object; uint32_t param_count; + uint32_t consumed_args; /* This hashtable can also contain positional arguments (with integer keys), * which will be appended to the normal params[]. This makes it easier to * integrate APIs like call_user_func_array(). The usual restriction that @@ -75,6 +75,8 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(zif_##name) #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(zim_##classname##_##name) +#define ZEND_FENTRY_FLAGS(flags, flags2) (((uint64_t)flags) | ((uint64_t)flags2 << 32)) + #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags, NULL, NULL }, #define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags, frameless_function_infos, doc_comment) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags, frameless_function_infos, doc_comment }, @@ -340,6 +342,13 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0) #define ZEND_FCC_INITIALIZED(fcc) ((fcc).function_handler != NULL) +static zend_always_inline uint32_t zend_fci_consumed_arg(uint32_t arg_index) { + return arg_index < 32 ? (UINT32_C(1) << arg_index) : UINT32_C(0); +} +static zend_always_inline bool zend_fci_is_consumed_arg(uint32_t consumed_args, uint32_t arg_index) { + return arg_index < 32 && (consumed_args & (UINT32_C(1) << arg_index)); +} + ZEND_API int zend_next_free_module(void); BEGIN_EXTERN_C() @@ -351,18 +360,12 @@ ZEND_API zend_result zend_get_parameters_array_ex(uint32_t param_count, zval *ar zend_get_parameters_array_ex(param_count, argument_array) #define zend_parse_parameters_none() \ (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : (zend_wrong_parameters_none_error(), FAILURE)) -#define zend_parse_parameters_none_throw() \ - zend_parse_parameters_none() /* Parameter parsing API -- andrei */ -#define ZEND_PARSE_PARAMS_THROW 0 /* No longer used, zpp always uses exceptions */ #define ZEND_PARSE_PARAMS_QUIET (1<<1) ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec, ...); ZEND_API zend_result zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec, ...); -/* NOTE: This must have at least one value in __VA_ARGS__ for the expression to be valid */ -#define zend_parse_parameters_throw(num_args, ...) \ - zend_parse_parameters(num_args, __VA_ARGS__) ZEND_API const char *zend_zval_type_name(const zval *arg); ZEND_API const char *zend_zval_value_name(const zval *arg); ZEND_API zend_string *zend_zval_get_legacy_type(const zval *arg); @@ -392,6 +395,7 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(const zend_class_entr ZEND_API zend_class_entry *zend_register_internal_class_with_flags(const zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t flags); ZEND_API zend_class_entry *zend_register_internal_interface(const zend_class_entry *orig_class_entry); ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...); +ZEND_API void zend_class_use_internal_traits(zend_class_entry *class_entry, int num_traits, ...); ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, bool persistent); @@ -410,13 +414,13 @@ ZEND_API ZEND_COLD void zend_wrong_property_read(const zval *object, zval *prope #define IS_CALLABLE_SUPPRESS_DEPRECATIONS (1<<1) ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc); -ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, const zend_object *object); -ZEND_API zend_string *zend_get_callable_name(zval *callable); +ZEND_API zend_string *zend_get_callable_name_ex(const zval *callable, const zend_object *object); +ZEND_API zend_string *zend_get_callable_name(const zval *callable); ZEND_API bool zend_is_callable_at_frame( const zval *callable, zend_object *object, const zend_execute_data *frame, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error); -ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); -ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name); +ZEND_API bool zend_is_callable_ex(const zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); +ZEND_API bool zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name); ZEND_API const char *zend_get_module_version(const char *module_name); ZEND_API zend_result zend_get_module_started(const char *module_name); @@ -445,10 +449,10 @@ ZEND_API zend_result zend_update_class_constant(zend_class_constant *c, const ze ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type); ZEND_API HashTable *zend_separate_class_constants_table(const zend_class_entry *class_type); -static zend_always_inline HashTable *zend_class_constants_table(zend_class_entry *ce) { +static zend_always_inline const HashTable *zend_class_constants_table(const zend_class_entry *ce) { if ((ce->ce_flags & ZEND_ACC_HAS_AST_CONSTANTS) && ZEND_MAP_PTR(ce->mutable_data)) { - zend_class_mutable_data *mutable_data = - (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = + (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); if (mutable_data && mutable_data->constants_table) { return mutable_data->constants_table; } else { @@ -459,10 +463,10 @@ static zend_always_inline HashTable *zend_class_constants_table(zend_class_entry } } -static zend_always_inline zval *zend_class_default_properties_table(zend_class_entry *ce) { +static zend_always_inline zval *zend_class_default_properties_table(const zend_class_entry *ce) { if ((ce->ce_flags & ZEND_ACC_HAS_AST_PROPERTIES) && ZEND_MAP_PTR(ce->mutable_data)) { - zend_class_mutable_data *mutable_data = - (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = + (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); return mutable_data->default_properties_table; } else { return ce->default_properties_table; @@ -479,10 +483,10 @@ static zend_always_inline void zend_class_set_backed_enum_table(zend_class_entry } } -static zend_always_inline HashTable *zend_class_backed_enum_table(zend_class_entry *ce) +static zend_always_inline HashTable *zend_class_backed_enum_table(const zend_class_entry *ce) { if (ZEND_MAP_PTR(ce->mutable_data) && ce->type == ZEND_USER_CLASS) { - zend_class_mutable_data *mutable_data = (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); return mutable_data->backed_enum_table; } else { return ce->backed_enum_table; @@ -529,8 +533,16 @@ ZEND_API const char *zend_get_type_by_const(int type); #define DLEXPORT #endif -#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0)) -#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size)) +static zend_always_inline void array_init_size(zval *arg, uint32_t size) +{ + ZVAL_ARR(arg, zend_new_array(size)); +} + +static zend_always_inline void array_init(zval *arg) +{ + array_init_size(arg, 0); +} + ZEND_API void object_init(zval *arg); ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *ce); ZEND_API zend_result object_init_with_constructor(zval *arg, zend_class_entry *class_type, uint32_t param_count, zval *params, HashTable *named_params); @@ -701,7 +713,7 @@ ZEND_API zend_result _call_user_function_impl(zval *object, zval *function_name, * fci->params = NULL; * The callable_name argument may be NULL. */ -ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error); +ZEND_API zend_result zend_fcall_info_init(const zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error); /** Clear arguments connected with zend_fcall_info *fci * If free_mem is not zero then the params array gets free'd as well @@ -747,20 +759,27 @@ ZEND_API void zend_fcall_info_argn(zend_fcall_info *fci, uint32_t argc, ...); ZEND_API zend_result zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval, zval *args); /* Zend FCC API to store and handle PHP userland functions */ +ZEND_API bool zend_fcc_closure_equals_ex(const zend_fcall_info_cache* a, const zend_fcall_info_cache* b); + static zend_always_inline bool zend_fcc_equals(const zend_fcall_info_cache* a, const zend_fcall_info_cache* b) { + if (a->closure || b->closure) { + return a->object == b->object + && a->calling_scope == b->calling_scope + && a->called_scope == b->called_scope + && (a->closure == b->closure || zend_fcc_closure_equals_ex(a, b)) + ; + } if (UNEXPECTED((a->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) && (b->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) { return a->object == b->object && a->calling_scope == b->calling_scope - && a->closure == b->closure && zend_string_equals(a->function_handler->common.function_name, b->function_handler->common.function_name) ; } return a->function_handler == b->function_handler && a->object == b->object && a->calling_scope == b->calling_scope - && a->closure == b->closure ; } @@ -895,6 +914,8 @@ static zend_always_inline zend_result zend_forbid_dynamic_call(void) const zend_execute_data *ex = EG(current_execute_data); ZEND_ASSERT(ex != NULL && ex->func != NULL); + ZEND_ASSERT(ex->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS); + if (ZEND_CALL_INFO(ex) & ZEND_CALL_DYNAMIC) { zend_string *function_or_method_name = get_active_function_or_method_name(); zend_throw_error(NULL, "Cannot call %.*s() dynamically", @@ -1559,10 +1580,13 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_nu ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_or_null_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, va_list va); ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...); +ZEND_API ZEND_COLD void zend_argument_error_ex(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); +ZEND_API ZEND_COLD void zend_argument_type_error_ex(const zend_function *function, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); +ZEND_API ZEND_COLD void zend_argument_value_error_ex(const zend_function *function, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num); ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, const zend_class_entry *old_ce); ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, const zend_class_entry *old_ce); @@ -2174,21 +2198,27 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string /* Inlined implementations shared by new and old parameter parsing APIs */ +typedef enum zpp_parse_bool_status { + ZPP_PARSE_BOOL_STATUS_FALSE = 0, + ZPP_PARSE_BOOL_STATUS_TRUE = 1, + ZPP_PARSE_BOOL_STATUS_ERROR = 2, +} zpp_parse_bool_status; + ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num); +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num); +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num); static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless) @@ -2204,11 +2234,16 @@ static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *des *is_null = 1; *dest = 0; } else { + zpp_parse_bool_status result; if (frameless) { - return zend_flf_parse_arg_bool_slow(arg, dest, arg_num); + result = zend_flf_parse_arg_bool_slow(arg, arg_num); } else { - return zend_parse_arg_bool_slow(arg, dest, arg_num); + result = zend_parse_arg_bool_slow(arg, arg_num); + } + if (UNEXPECTED(result == ZPP_PARSE_BOOL_STATUS_ERROR)) { + return false; } + *dest = result; } return 1; } @@ -2254,7 +2289,8 @@ static zend_always_inline bool zend_parse_arg_double(const zval *arg, double *de *is_null = 1; *dest = 0.0; } else { - return zend_parse_arg_double_slow(arg, dest, arg_num); + *dest = zend_parse_arg_double_slow(arg, arg_num); + return !zend_isnan(*dest); } return 1; } @@ -2291,12 +2327,13 @@ static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **de *dest = NULL; } else { if (frameless) { - return zend_flf_parse_arg_str_slow(arg, dest, arg_num); + *dest = zend_flf_parse_arg_str_slow(arg, arg_num); } else { - return zend_parse_arg_str_slow(arg, dest, arg_num); + *dest = zend_parse_arg_str_slow(arg, arg_num); } + return *dest != NULL; } - return 1; + return true; } static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num) @@ -2482,7 +2519,7 @@ static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, b return 1; } -static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error, bool free_trampoline) +static zend_always_inline bool zend_parse_arg_func(const zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error, bool free_trampoline) { if (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) { dest_fci->size = 0; @@ -2527,7 +2564,8 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str( *dest_str = NULL; } else { *dest_ht = NULL; - return zend_parse_arg_str_slow(arg, dest_str, arg_num); + *dest_str = zend_parse_arg_str_slow(arg, arg_num); + return *dest_str != NULL; } return 1; } diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index bca2190976c7..fc7bc1f4d9d4 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -198,7 +197,7 @@ typedef zend_mm_bitset zend_mm_page_map[ZEND_MM_PAGE_MAP_LEN]; /* 64B */ #define ZEND_MM_SRUN_BIN_NUM_MASK 0x0000001f #define ZEND_MM_SRUN_BIN_NUM_OFFSET 0 -#define ZEND_MM_SRUN_FREE_COUNTER_MASK 0x01ff0000 +#define ZEND_MM_SRUN_FREE_COUNTER_MASK 0x03ff0000 #define ZEND_MM_SRUN_FREE_COUNTER_OFFSET 16 #define ZEND_MM_NRUN_OFFSET_MASK 0x01ff0000 @@ -2614,12 +2613,12 @@ typedef struct _zend_alloc_globals { #ifdef ZTS static int alloc_globals_id; -static size_t alloc_globals_offset; -# define AG(v) ZEND_TSRMG_FAST(alloc_globals_offset, zend_alloc_globals *, v) +static TSRM_TLS TSRM_TLS_MODEL_ATTR zend_alloc_globals alloc_globals; +static void *alloc_globals_tls_addr(void) { return &alloc_globals; } #else -# define AG(v) (alloc_globals.v) static zend_alloc_globals alloc_globals; #endif +#define AG(v) (alloc_globals.v) ZEND_API bool is_zend_mm(void) { @@ -2974,7 +2973,7 @@ ZEND_API void refresh_memory_manager(void) static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) { fprintf(stderr, "Out of memory\n"); - exit(1); + abort(); } #if ZEND_MM_CUSTOM @@ -3336,7 +3335,7 @@ ZEND_API void start_memory_manager(void) # endif #endif #ifdef ZTS - ts_allocate_fast_id(&alloc_globals_id, &alloc_globals_offset, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + ts_allocate_tls_id(&alloc_globals_id, alloc_globals_tls_addr, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); #else alloc_globals_ctor(&alloc_globals); #endif @@ -3582,9 +3581,3 @@ ZEND_API char * __zend_strdup(const char *s) zend_out_of_memory(); } -#ifdef ZTS -size_t zend_mm_globals_size(void) -{ - return sizeof(zend_alloc_globals); -} -#endif diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 264e13848d1b..7e3ea031dc72 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -404,10 +403,6 @@ static void apc_init_heap(void) */ -#ifdef ZTS -size_t zend_mm_globals_size(void); -#endif - END_EXTERN_C() #endif diff --git a/Zend/zend_alloc_sizes.h b/Zend/zend_alloc_sizes.h index 502b982a5052..f806056ad9d3 100644 --- a/Zend/zend_alloc_sizes.h +++ b/Zend/zend_alloc_sizes.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_arena.h b/Zend/zend_arena.h index 37cda28f29db..9b917a47e927 100644 --- a/Zend/zend_arena.h +++ b/Zend/zend_arena.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 9d93c4d22251..1b293c832c91 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bob Weinand | | Dmitry Stogov | @@ -814,7 +813,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner( case IS_OBJECT: zend_cast_zval_to_object(result, &op1, IS_VAR); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } zval_ptr_dtor_nogc(&op1); if (UNEXPECTED(EG(exception))) { @@ -1140,6 +1139,12 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner( case ZEND_AST_CALL: case ZEND_AST_STATIC_CALL: { + // Preloading will attempt to resolve constants but objects can't be stored in shm + // Aborting here to store the const AST instead + if (CG(in_compilation)) { + return FAILURE; + } + zend_function *fptr; zend_class_entry *called_scope = NULL; @@ -1240,7 +1245,7 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner( break; } - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } zend_create_fake_closure(result, fptr, fptr->common.scope, called_scope, NULL); @@ -1460,6 +1465,16 @@ ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast) return ref; } +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_dup(zend_ast *ast) +{ + ZEND_ASSERT(ast != NULL); + + zend_ast *buf = zend_ast_alloc(zend_ast_tree_size(ast)); + zend_ast_tree_copy(ast, buf); + + return buf; +} + ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast) { tail_call: @@ -1579,9 +1594,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio static ZEND_COLD void zend_ast_export_str(smart_str *str, const zend_string *s) { - size_t i; - - for (i = 0; i < ZSTR_LEN(s); i++) { + for (size_t i = 0; i < ZSTR_LEN(s); i++) { unsigned char c = ZSTR_VAL(s)[i]; if (c == '\'' || c == '\\') { smart_str_appendc(str, '\\'); @@ -1594,9 +1607,7 @@ static ZEND_COLD void zend_ast_export_str(smart_str *str, const zend_string *s) static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, const zend_string *s) { - size_t i; - - for (i = 0; i < ZSTR_LEN(s); i++) { + for (size_t i = 0; i < ZSTR_LEN(s); i++) { unsigned char c = ZSTR_VAL(s)[i]; if (c < ' ') { switch (c) { @@ -1637,6 +1648,22 @@ static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, const zen } } +static ZEND_COLD void zend_ast_export_quoted_str(smart_str *str, const zend_string *s) +{ + for (size_t i = 0; i < ZSTR_LEN(s); i++) { + unsigned char c = ZSTR_VAL(s)[i]; + if (c < ' ') { + smart_str_appendc(str, '"'); + zend_ast_export_qstr(str, '"', s); + smart_str_appendc(str, '"'); + return; + } + } + smart_str_appendc(str, '\''); + zend_ast_export_str(str, s); + smart_str_appendc(str, '\''); +} + static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent) { while (indent > 0) { @@ -1675,18 +1702,18 @@ static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int } zend_ast_export_ex(str, ast, priority, indent); } - -static ZEND_COLD bool zend_ast_valid_var_char(char ch) +static ZEND_COLD void zend_ast_export_ns_name_or_expression(smart_str *str, zend_ast *ast, int priority, int indent) { - unsigned char c = (unsigned char)ch; - - if (c != '_' && c < 127 && - (c < '0' || c > '9') && - (c < 'A' || c > 'Z') && - (c < 'a' || c > 'z')) { - return false; + switch (ast->kind) { + case ZEND_AST_ZVAL: + case ZEND_AST_VAR: + zend_ast_export_ns_name(str, ast, priority, indent); + break; + default: + smart_str_appendc(str, '('); + zend_ast_export_ex(str, ast, priority, indent); + smart_str_appendc(str, ')'); } - return true; } static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len) @@ -1715,18 +1742,18 @@ static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len) return true; } -static ZEND_COLD bool zend_ast_var_needs_braces(char ch) -{ - return ch == '[' || zend_ast_valid_var_char(ch); -} - static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int indent) { if (ast->kind == ZEND_AST_ZVAL) { zval *zv = zend_ast_get_zval(ast); - if (Z_TYPE_P(zv) == IS_STRING && - zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) { - smart_str_append(str, Z_STR_P(zv)); + if (Z_TYPE_P(zv) == IS_STRING) { + if (zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) { + smart_str_append(str, Z_STR_P(zv)); + } else { + smart_str_appends(str, "{'"); + zend_ast_export_str(str, Z_STR_P(zv)); + smart_str_appends(str, "'}"); + } return; } } else if (ast->kind == ZEND_AST_VAR) { @@ -1771,14 +1798,6 @@ static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, co ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); zend_ast_export_qstr(str, quote, Z_STR_P(zv)); - } else if (ast->kind == ZEND_AST_VAR && - ast->child[0]->kind == ZEND_AST_ZVAL && - (i + 1 == list->children || - list->child[i + 1]->kind != ZEND_AST_ZVAL || - !zend_ast_var_needs_braces( - *Z_STRVAL_P( - zend_ast_get_zval(list->child[i + 1]))))) { - zend_ast_export_ex(str, ast, 0, indent); } else { smart_str_appendc(str, '{'); zend_ast_export_ex(str, ast, 0, indent); @@ -1929,9 +1948,7 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, const zval *zv, int p str, Z_DVAL_P(zv), (int) EG(precision), /* zero_fraction */ true); break; case IS_STRING: - smart_str_appendc(str, '\''); - zend_ast_export_str(str, Z_STR_P(zv)); - smart_str_appendc(str, '\''); + zend_ast_export_quoted_str(str, Z_STR_P(zv)); break; case IS_ARRAY: { zend_long idx; @@ -1946,13 +1963,11 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, const zval *zv, int p smart_str_appends(str, ", "); } if (key) { - smart_str_appendc(str, '\''); - zend_ast_export_str(str, key); - smart_str_appends(str, "' => "); + zend_ast_export_quoted_str(str, key); } else { smart_str_append_long(str, idx); - smart_str_appends(str, " => "); } + smart_str_appends(str, " => "); zend_ast_export_zval(str, val, 0, indent); } ZEND_HASH_FOREACH_END(); smart_str_appendc(str, ']'); @@ -1961,7 +1976,7 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, const zval *zv, int p case IS_CONSTANT_AST: zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -2160,7 +2175,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio break; case ZEND_AST_CONSTANT: { zend_string *name = zend_ast_get_constant_name(ast); - smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name)); + smart_str_append(str, name); break; } case ZEND_AST_OP_ARRAY: @@ -2210,7 +2225,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appendc(str, '&'); } if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) { - smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name)); + smart_str_append(str, decl->name); } smart_str_appendc(str, '('); zend_ast_export_ex(str, decl->child[0], 0, indent); @@ -2268,7 +2283,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appends(str, "class "); } - smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name)); + smart_str_append(str, decl->name); if (decl->flags & ZEND_ACC_ENUM && decl->child[4]) { smart_str_appends(str, ": "); zend_ast_export_type(str, decl->child[4], indent); @@ -2396,7 +2411,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case T_PROPERTY_C: APPEND_STR("__PROPERTY__"); case T_NS_C: APPEND_STR("__NAMESPACE__"); case T_CLASS_C: APPEND_STR("__CLASS__"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_TYPE: @@ -2405,7 +2420,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case IS_CALLABLE: APPEND_STR("callable"); case IS_STATIC: APPEND_STR("static"); case IS_MIXED: APPEND_STR("mixed"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_PLACEHOLDER_ARG: @@ -2439,7 +2454,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case IS_STRING: PREFIX_OP("(string)", 240, 241); case IS_ARRAY: PREFIX_OP("(array)", 240, 241); case IS_OBJECT: PREFIX_OP("(object)", 240, 241); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_CAST_VOID: @@ -2473,14 +2488,14 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_REQUIRE_ONCE: FUNC_OP("require_once"); case ZEND_REQUIRE: FUNC_OP("require"); case ZEND_EVAL: FUNC_OP("eval"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_UNARY_OP: switch (ast->attr) { case ZEND_BW_NOT: PREFIX_OP("~", 240, 241); case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_PRE_INC: @@ -2537,37 +2552,24 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_var(str, ast->child[1], indent); break; case ZEND_AST_STATIC_PROP: - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); smart_str_appends(str, "::$"); zend_ast_export_var(str, ast->child[1], indent); break; case ZEND_AST_CALL: { - zend_ast *left = ast->child[0]; - if (left->kind == ZEND_AST_ARROW_FUNC || left->kind == ZEND_AST_CLOSURE) { - smart_str_appendc(str, '('); - zend_ast_export_ns_name(str, left, 0, indent); - smart_str_appendc(str, ')'); - } else { - zend_ast_export_ns_name(str, left, 0, indent); - } + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[1], 0, indent); smart_str_appendc(str, ')'); break; } - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: - smart_str_append(str, Z_STR_P(zend_ast_get_zval(ast->child[0]))); - smart_str_appendc(str, '('); - zend_ast_export_ex(str, ast->child[1], 0, indent); - smart_str_appendc(str, ')'); - break; case ZEND_AST_CALLABLE_CONVERT: { zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast; ast = fcc_ast->args; goto simple_list; } case ZEND_AST_CLASS_CONST: - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); smart_str_appends(str, "::"); zend_ast_export_name(str, ast->child[1], 0, indent); break; @@ -2581,10 +2583,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_FETCH_CLASS_PARENT: smart_str_append(str, ZSTR_KNOWN(ZEND_STR_PARENT)); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } else { - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); } smart_str_appends(str, "::class"); break; @@ -2604,7 +2606,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_BW_AND: BINARY_OP(" &= ", 90, 91, 90); case ZEND_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90); case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90); @@ -2630,7 +2632,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250); case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41); case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_GREATER: BINARY_OP(" > ", 180, 181, 181); @@ -2663,7 +2665,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } zend_ast_export_class_no_header(str, decl, indent); } else { - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[1], 0, indent); smart_str_appendc(str, ')'); @@ -2672,7 +2674,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_INSTANCEOF: zend_ast_export_ex(str, ast->child[0], 0, indent); smart_str_appends(str, " instanceof "); - zend_ast_export_ns_name(str, ast->child[1], 0, indent); + zend_ast_export_ns_name_or_expression(str, ast->child[1], 0, indent); break; case ZEND_AST_YIELD: if (priority > 70) smart_str_appendc(str, '('); @@ -2809,7 +2811,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appends(str, " insteadof "); zend_ast_export_ex(str, ast->child[1], 0, indent); break; - case ZEND_AST_METHOD_REFERENCE: + case ZEND_AST_TRAIT_METHOD_REFERENCE: if (ast->child[0]) { zend_ast_export_name(str, ast->child[0], 0, indent); smart_str_appends(str, "::"); @@ -2865,7 +2867,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appendc(str, ')'); break; case ZEND_AST_STATIC_CALL: - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + if (zend_ast_is_parent_hook_call(ast)) { + zend_ast_export_ns_name(str, ast->child[0], 0, indent); + } else { + zend_ast_export_ns_name_or_expression(str, ast->child[0], 0, indent); + } + smart_str_appends(str, "::"); zend_ast_export_var(str, ast->child[1], indent); smart_str_appendc(str, '('); @@ -2982,7 +2989,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_indent(str, indent); smart_str_appendc(str, '}'); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return; @@ -3079,7 +3086,7 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr) * zend_compile_const_decl() checks the kind of the list elements. */ ast = zend_ast_list_add(ast, attr); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return ast; @@ -3096,3 +3103,22 @@ zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast) ZEND_UNREACHABLE(); return NULL; } + +bool zend_ast_is_parent_hook_call(const zend_ast *ast) +{ + ZEND_ASSERT(ast->kind == ZEND_AST_STATIC_CALL); + + const zend_ast *class_ast = ast->child[0]; + zend_ast *method_ast = ast->child[1]; + + return class_ast->kind == ZEND_AST_STATIC_PROP + && !(class_ast->attr & ZEND_PARENTHESIZED_STATIC_PROP) + && class_ast->child[0]->kind == ZEND_AST_ZVAL + && Z_TYPE_P(zend_ast_get_zval(class_ast->child[0])) == IS_STRING + && zend_get_class_fetch_type(zend_ast_get_str(class_ast->child[0])) == ZEND_FETCH_CLASS_PARENT + && class_ast->child[1]->kind == ZEND_AST_ZVAL + && method_ast->kind == ZEND_AST_ZVAL + && Z_TYPE_P(zend_ast_get_zval(method_ast)) == IS_STRING + && (zend_string_equals_literal_ci(zend_ast_get_str(method_ast), "get") + || zend_string_equals_literal_ci(zend_ast_get_str(method_ast), "set")); +} diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index a88efefd85b2..26f54102a143 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bob Weinand | | Dmitry Stogov | @@ -144,7 +143,7 @@ enum _zend_ast_kind { ZEND_AST_DECLARE, ZEND_AST_USE_TRAIT, ZEND_AST_TRAIT_PRECEDENCE, - ZEND_AST_METHOD_REFERENCE, + ZEND_AST_TRAIT_METHOD_REFERENCE, ZEND_AST_NAMESPACE, ZEND_AST_USE_ELEM, ZEND_AST_TRAIT_ALIAS, @@ -153,7 +152,6 @@ enum _zend_ast_kind { ZEND_AST_MATCH, ZEND_AST_MATCH_ARM, ZEND_AST_NAMED_ARG, - ZEND_AST_PARENT_PROPERTY_HOOK_CALL, ZEND_AST_PIPE, /* 3 child nodes */ @@ -352,7 +350,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *ast, zend_class_entry *scope, bool *short_circuited_ptr, zend_ast_evaluate_ctx *ctx); ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix); +/* Copies 'ast' to the heap, returns a refcounted AST reference */ ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast); +/* Duplicates 'ast' on the arena */ +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_dup(zend_ast *ast); ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast); ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast); @@ -360,7 +361,7 @@ typedef void (*zend_ast_apply_func)(zend_ast **ast_ptr, void *context); ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *context); static zend_always_inline size_t zend_ast_size(uint32_t children) { - return XtOffsetOf(zend_ast, child) + (sizeof(zend_ast *) * children); + return offsetof(zend_ast, child) + (sizeof(zend_ast *) * children); } static zend_always_inline bool zend_ast_is_special(const zend_ast *ast) { @@ -442,4 +443,7 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr) zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast); +/* Recognize parent::$prop::get() pattern. */ +bool zend_ast_is_parent_hook_call(const zend_ast *ast); + #endif diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 5f6a7793beea..98a39c583437 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Levi Morrison | +----------------------------------------------------------------------+ @@ -57,7 +57,7 @@ ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired) { zend_atomic_int_store_ex(obj, desired); } -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) /* On these platforms it is non-const due to underlying APIs. */ ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj) { return zend_atomic_bool_load_ex(obj); diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 56422a721fdb..31558996c3c3 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Levi Morrison | +----------------------------------------------------------------------+ @@ -39,7 +39,7 @@ * and alignment purposes. */ -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) typedef struct zend_atomic_bool_s { volatile char value; } zend_atomic_bool; @@ -68,7 +68,7 @@ typedef struct zend_atomic_int_s { BEGIN_EXTERN_C() -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS) #ifndef InterlockedExchange8 #define InterlockedExchange8 _InterlockedExchange8 @@ -123,7 +123,7 @@ static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_i } } -/* On this platform it is non-const due to Iterlocked API*/ +/* On this platform it is non-const due to Interlocked API */ static zend_always_inline bool zend_atomic_bool_load_ex(zend_atomic_bool *obj) { /* Or'ing with false won't change the value. */ return InterlockedOr8(&obj->value, false); @@ -376,7 +376,7 @@ ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expect ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired); -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS)) || defined(HAVE_SYNC_ATOMICS) /* On these platforms it is non-const due to underlying APIs. */ ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj); ZEND_API int zend_atomic_int_load(zend_atomic_int *obj); diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index cba95810ba49..71f0d788e921 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Benjamin Eberlei | | Martin Schröder | diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index f8b61ac9d166..c044ef073cc8 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Benjamin Eberlei | | Martin Schröder | diff --git a/Zend/zend_attributes.stub.php b/Zend/zend_attributes.stub.php index ded9c89593a3..05fd285d5b9f 100644 --- a/Zend/zend_attributes.stub.php +++ b/Zend/zend_attributes.stub.php @@ -68,7 +68,7 @@ public function __debugInfo(): array {} /** * @strict-properties */ -#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_PROPERTY)] +#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_PROPERTY|Attribute::TARGET_CLASS_CONSTANT)] final class Override { public function __construct() {} diff --git a/Zend/zend_attributes_arginfo.h b/Zend/zend_attributes_arginfo.h index 54a66af29966..8acac398426f 100644 --- a/Zend/zend_attributes_arginfo.h +++ b/Zend/zend_attributes_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit zend_attributes.stub.php instead. - * Stub hash: b868cb33f41d9442f42d0cec84e33fcc09f5d88c */ + * Stub hash: bae42fcb945360f90a1e2762c6c22177f25efb9e */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Attribute___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "Attribute::TARGET_ALL") @@ -230,7 +230,7 @@ static zend_class_entry *register_class_Override(void) zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_Override_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Override_0, 1); zend_string_release_ex(attribute_name_Attribute_class_Override_0, true); - ZVAL_LONG(&attribute_Attribute_class_Override_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_PROPERTY); + ZVAL_LONG(&attribute_Attribute_class_Override_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_PROPERTY | ZEND_ATTRIBUTE_TARGET_CLASS_CONST); return class_entry; } diff --git a/Zend/zend_autoload.c b/Zend/zend_autoload.c index bc74efa1afda..2ca3d7eea022 100644 --- a/Zend/zend_autoload.c +++ b/Zend/zend_autoload.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gina Peter Banyard | +----------------------------------------------------------------------+ diff --git a/Zend/zend_autoload.h b/Zend/zend_autoload.h index fde4a4a82e9a..84e6ab80b5af 100644 --- a/Zend/zend_autoload.h +++ b/Zend/zend_autoload.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gina Peter Banyard | +----------------------------------------------------------------------+ diff --git a/Zend/zend_bitset.h b/Zend/zend_bitset.h index d990b6a2a871..877f2aaabc05 100644 --- a/Zend/zend_bitset.h +++ b/Zend/zend_bitset.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_build.h b/Zend/zend_build.h index c604fb311a74..8ba7064042e3 100644 --- a/Zend/zend_build.h +++ b/Zend/zend_build.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c16d8e74f2bd..87acf073a2da 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2,21 +2,21 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | +----------------------------------------------------------------------+ */ +#include "php_version.h" #include "zend.h" #include "zend_API.h" #include "zend_attributes.h" @@ -84,10 +84,10 @@ ZEND_FUNCTION(clone) /* clone() also exists as the ZEND_CLONE OPcode and both implementations must be kept in sync. */ - zend_class_entry *scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); - zend_class_entry *ce = zobj->ce; - zend_function *clone = ce->clone; + const zend_class_entry *ce = zobj->ce; + const 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)); @@ -239,7 +239,7 @@ ZEND_FUNCTION(gc_status) /* {{{ Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args) { - zend_execute_data *ex = EX(prev_execute_data); + const zend_execute_data *ex = EX(prev_execute_data); ZEND_PARSE_PARAMETERS_NONE(); @@ -249,7 +249,7 @@ ZEND_FUNCTION(func_num_args) } if (zend_forbid_dynamic_call() == FAILURE) { - RETURN_LONG(-1); + RETURN_THROWS(); } RETURN_LONG(ZEND_CALL_NUM_ARGS(ex)); @@ -503,7 +503,7 @@ ZEND_FUNCTION(error_reporting) } /* }}} */ -static bool validate_constant_array_argument(HashTable *ht, int argument_number) /* {{{ */ +static bool validate_constant_array_argument(HashTable *ht, uint32_t argument_number) /* {{{ */ { bool ret = true; zval *val; @@ -527,7 +527,7 @@ static bool validate_constant_array_argument(HashTable *ht, int argument_number) } /* }}} */ -static void copy_constant_array(zval *dst, zval *src) /* {{{ */ +static void copy_constant_array(zval *dst, const zval *src) /* {{{ */ { zend_string *key; zend_ulong idx; @@ -590,11 +590,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) != NULL) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_register_constant(&c) != NULL); } /* }}} */ @@ -608,11 +604,7 @@ ZEND_FUNCTION(defined) Z_PARAM_STR(name) ZEND_PARSE_PARAMETERS_END(); - if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)); } /* }}} */ @@ -626,7 +618,7 @@ ZEND_FUNCTION(get_class) } if (!obj) { - zend_class_entry *scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); if (scope) { zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); @@ -647,11 +639,9 @@ ZEND_FUNCTION(get_class) /* {{{ Retrieves the "Late Static Binding" class name */ ZEND_FUNCTION(get_called_class) { - zend_class_entry *called_scope; - ZEND_PARSE_PARAMETERS_NONE(); - called_scope = zend_get_called_scope(execute_data); + const zend_class_entry *called_scope = zend_get_called_scope(execute_data); if (!called_scope) { zend_throw_error(NULL, "get_called_class() must be called from within a class"); RETURN_THROWS(); @@ -691,10 +681,8 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ * { zval *obj; zend_string *class_name; - zend_class_entry *instance_ce; - zend_class_entry *ce; + const zend_class_entry *instance_ce; bool allow_string = only_subclass; - bool retval; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_ZVAL(obj) @@ -721,21 +709,19 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ * } if (!only_subclass && EXPECTED(zend_string_equals(instance_ce->name, class_name))) { - retval = 1; - } else { - ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (!ce) { - retval = 0; - } else { - if (only_subclass && instance_ce == ce) { - retval = 0; - } else { - retval = instanceof_function(instance_ce, ce); - } - } + RETURN_TRUE; + } + + const zend_class_entry *ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (!ce) { + RETURN_FALSE; } - RETURN_BOOL(retval); + if (only_subclass && instance_ce == ce) { + RETURN_FALSE; + } + + RETURN_BOOL(instanceof_function(instance_ce, ce)); } /* }}} */ @@ -754,7 +740,7 @@ ZEND_FUNCTION(is_a) /* }}} */ /* {{{ add_class_vars */ -static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool statics, zval *return_value) +static void add_class_vars(const zend_class_entry *scope, zend_class_entry *ce, bool statics, const zval *return_value) { zend_property_info *prop_info; zval *prop, prop_copy; @@ -805,7 +791,7 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool s /* {{{ Returns an array of default properties of the class. */ ZEND_FUNCTION(get_class_vars) { - zend_class_entry *ce = NULL, *scope; + zend_class_entry *ce = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &ce) == FAILURE) { RETURN_THROWS(); @@ -818,7 +804,7 @@ ZEND_FUNCTION(get_class_vars) } } - scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); add_class_vars(scope, ce, false, return_value); add_class_vars(scope, ce, true, return_value); } @@ -944,7 +930,6 @@ ZEND_FUNCTION(get_class_methods) { zval method_name; zend_class_entry *ce = NULL; - zend_class_entry *scope; zend_function *mptr; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -952,7 +937,7 @@ ZEND_FUNCTION(get_class_methods) ZEND_PARSE_PARAMETERS_END(); array_init(return_value); - scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { if (zend_check_method_accessible(mptr, scope)) { @@ -968,7 +953,6 @@ ZEND_FUNCTION(method_exists) { zval *klass; zend_string *method_name; - zend_string *lcname; zend_class_entry *ce; zend_function *func; @@ -985,13 +969,11 @@ ZEND_FUNCTION(method_exists) RETURN_FALSE; } } else { - zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(klass)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_OBJECT_OR_STRING, klass); RETURN_THROWS(); } - lcname = zend_string_tolower(method_name); - func = zend_hash_find_ptr(&ce->function_table, lcname); - zend_string_release_ex(lcname, 0); + func = zend_hash_find_ptr_lc(&ce->function_table, method_name); if (func) { /* Exclude shadow properties when checking a method on a specific class. Include @@ -1027,10 +1009,9 @@ ZEND_FUNCTION(method_exists) } /* }}} */ -static void _property_exists(zval *return_value, zval *object, zend_string *property) +static void _property_exists(zval *return_value, const zval *object, zend_string *property) { zend_class_entry *ce; - zend_property_info *property_info; if (Z_TYPE_P(object) == IS_STRING) { ce = zend_lookup_class(Z_STR_P(object)); @@ -1040,22 +1021,21 @@ static void _property_exists(zval *return_value, zval *object, zend_string *prop } else if (Z_TYPE_P(object) == IS_OBJECT) { ce = Z_OBJCE_P(object); } else { - zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(object)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_OBJECT_OR_STRING, object); RETURN_THROWS(); } - property_info = zend_hash_find_ptr(&ce->properties_info, property); + const zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, property); if (property_info != NULL && (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce)) { RETURN_TRUE; } - if (Z_TYPE_P(object) == IS_OBJECT && - Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, ZEND_PROPERTY_EXISTS, NULL)) { - RETURN_TRUE; - } - RETURN_FALSE; + RETURN_BOOL( + Z_TYPE_P(object) == IS_OBJECT && + Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, ZEND_PROPERTY_EXISTS, NULL) + ); } /* {{{ Checks if the object or class has a property */ @@ -1091,7 +1071,7 @@ flf_clean:; static zend_always_inline void _class_exists_impl(zval *return_value, zend_string *name, bool autoload, int flags, int skip_flags) /* {{{ */ { zend_string *lcname; - zend_class_entry *ce; + const zend_class_entry *ce; if (ZSTR_HAS_CE_CACHE(name)) { ce = ZSTR_GET_CE_CACHE(name); @@ -1115,11 +1095,7 @@ static zend_always_inline void _class_exists_impl(zval *return_value, zend_strin ce = zend_lookup_class(name); } - if (ce) { - RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags)); - } else { - RETURN_FALSE; - } + RETURN_BOOL(ce && ((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags)); } /* {{{ */ @@ -1425,7 +1401,6 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla { zend_string *key; zval *zv; - zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -1433,7 +1408,7 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) { - ce = Z_PTR_P(zv); + const zend_class_entry *ce = Z_PTR_P(zv); if ((ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT)) == flags && key && ZSTR_VAL(key)[0] != 0) { @@ -1551,7 +1526,7 @@ ZEND_FUNCTION(get_resource_type) if (resource_type) { RETURN_STRING(resource_type); } else { - RETURN_STRING("Unknown"); + RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_UNKNOWN_CAPITALIZED)); } } /* }}} */ @@ -1616,7 +1591,7 @@ ZEND_FUNCTION(get_resources) } /* }}} */ -static void add_zendext_info(zend_extension *ext, void *arg) /* {{{ */ +static void add_zendext_info(const zend_extension *ext, void *arg) /* {{{ */ { zval *name_array = (zval *)arg; add_next_index_string(name_array, ext->name); @@ -1719,7 +1694,7 @@ ZEND_FUNCTION(get_defined_constants) static bool backtrace_is_arg_sensitive(const zend_execute_data *call, uint32_t offset) { - zend_attribute *attribute = zend_get_parameter_attribute_str( + const zend_attribute *attribute = zend_get_parameter_attribute_str( call->func->common.attributes, "sensitiveparameter", sizeof("sensitiveparameter") - 1, @@ -1891,7 +1866,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int zend_execute_data *call, *last_call = NULL; zend_object *object; bool fake_frame = false; - int lineno, frameno = 0; + int frameno = 0; zend_function *func; zend_string *filename; zend_string *include_filename = NULL; @@ -1912,12 +1887,12 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int EG(filename_override) = NULL; EG(lineno_override) = -1; - zend_string *filename = zend_get_executed_filename_ex(); - zend_long lineno = zend_get_executed_lineno(); - if (filename && (!zend_string_equals(filename, filename_override) || lineno != lineno_override)) { + zend_string *executed_filename = zend_get_executed_filename_ex(); + uint32_t lineno = zend_get_executed_lineno(); + if (executed_filename && (!zend_string_equals(executed_filename, filename_override) || lineno != lineno_override)) { stack_frame = zend_new_array(8); zend_hash_real_init_mixed(stack_frame); - ZVAL_STR_COPY(&tmp, filename); + ZVAL_STR_COPY(&tmp, executed_filename); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1); ZVAL_LONG(&tmp, lineno); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1); @@ -1980,19 +1955,21 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int zval *arg = zend_get_zval_ptr(op_data, op_data->op1_type, &op_data->op1, call); if (Z_TYPE_P(arg) == IS_UNDEF) goto not_frameless_call; } - zend_function *func = ZEND_FLF_FUNC(opline); + zend_function *frameless_func = ZEND_FLF_FUNC(opline); /* Assume frameless functions are not recursive with themselves. * This condition may be true when observers are enabled: * Observers will put a call frame on top of the frameless opcode. */ - if (last_call && last_call->func == func) { + if (last_call && last_call->func == frameless_func) { goto not_frameless_call; } stack_frame = zend_new_array(8); zend_hash_real_init_mixed(stack_frame); - ZVAL_STR_COPY(&tmp, func->common.function_name); + ZVAL_STR_COPY(&tmp, frameless_func->common.function_name); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1); /* Steal file and line from the previous frame. */ if (call->func && ZEND_USER_CODE(call->func->common.type)) { + uint32_t lineno; + filename = call->func->op_array.filename; if (call->opline->opcode == ZEND_HANDLE_EXCEPTION) { if (EG(opline_before_exception)) { @@ -2044,6 +2021,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int zend_hash_real_init_mixed(stack_frame); if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type)) { + uint32_t lineno; + filename = prev->func->op_array.filename; if (prev->opline->opcode == ZEND_HANDLE_EXCEPTION) { if (EG(opline_before_exception)) { @@ -2237,7 +2216,6 @@ ZEND_FUNCTION(extension_loaded) ZEND_FUNCTION(get_extension_funcs) { zend_string *extension_name; - zend_string *lcname; bool array; zend_module_entry *module; zend_function *zif; @@ -2246,9 +2224,7 @@ ZEND_FUNCTION(get_extension_funcs) RETURN_THROWS(); } if (strncasecmp(ZSTR_VAL(extension_name), "zend", sizeof("zend"))) { - lcname = zend_string_tolower(extension_name); - module = zend_hash_find_ptr(&module_registry, lcname); - zend_string_release_ex(lcname, 0); + module = zend_hash_find_ptr_lc(&module_registry, extension_name); } else { module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core") - 1); } diff --git a/Zend/zend_builtin_functions.h b/Zend/zend_builtin_functions.h index 237b34b2927b..018d0cdb1c1d 100644 --- a/Zend/zend_builtin_functions.h +++ b/Zend/zend_builtin_functions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index 9b2267b531eb..1d405587145d 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -18,11 +18,16 @@ function die(string|int $status = 0): never {} /** @refcount 1 */ function zend_version(): string {} +/** @forbid-dynamic-calls */ function func_num_args(): int {} +/** @forbid-dynamic-calls */ function func_get_arg(int $position): mixed {} -/** @return array */ +/** + * @return array + * @forbid-dynamic-calls + */ function func_get_args(): array {} function strlen(string $string): int {} @@ -156,6 +161,7 @@ function get_defined_functions(bool $exclude_disabled = true): array {} /** * @return array * @refcount 1 + * @forbid-dynamic-calls */ function get_defined_vars(): array {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index cb626ff430e6..b3af43fef340 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit zend_builtin_functions.stub.php instead. - * Stub hash: 9b49f527064695c812cd204d9efc63c13681d942 */ + * Stub hash: 64c61862de86d9968930893bf21b516119724064 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_clone, 0, 1, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) @@ -316,9 +316,21 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(exit, arginfo_exit) ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL) ZEND_FE(zend_version, arginfo_zend_version) - ZEND_FE(func_num_args, arginfo_func_num_args) - ZEND_FE(func_get_arg, arginfo_func_get_arg) - ZEND_FE(func_get_args, arginfo_func_get_args) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_num_args", zif_func_num_args, arginfo_func_num_args, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_num_args", zif_func_num_args, arginfo_func_num_args, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_get_arg", zif_func_get_arg, arginfo_func_get_arg, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_get_arg", zif_func_get_arg, arginfo_func_get_arg, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_get_args", zif_func_get_args, arginfo_func_get_args, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_get_args", zif_func_get_args, arginfo_func_get_args, 0, NULL, NULL) +#endif ZEND_FE(strlen, arginfo_strlen) ZEND_RAW_FENTRY("strcmp", zif_strcmp, arginfo_strcmp, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("strncmp", zif_strncmp, arginfo_strncmp, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) @@ -358,7 +370,11 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(get_declared_traits, arginfo_get_declared_traits) ZEND_FE(get_declared_interfaces, arginfo_get_declared_interfaces) ZEND_FE(get_defined_functions, arginfo_get_defined_functions) - ZEND_FE(get_defined_vars, arginfo_get_defined_vars) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("get_defined_vars", zif_get_defined_vars, arginfo_get_defined_vars, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("get_defined_vars", zif_get_defined_vars, arginfo_get_defined_vars, 0, NULL, NULL) +#endif ZEND_FE(get_resource_type, arginfo_get_resource_type) ZEND_FE(get_resource_id, arginfo_get_resource_id) ZEND_FE(get_resources, arginfo_get_resources) diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index ed86ecc74a23..aa23c2e3e2fa 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | +----------------------------------------------------------------------+ diff --git a/Zend/zend_call_stack.h b/Zend/zend_call_stack.h index 58e91694f93f..c0b84334239d 100644 --- a/Zend/zend_call_stack.h +++ b/Zend/zend_call_stack.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | +----------------------------------------------------------------------+ diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index cca69985a0df..91f690c73ed0 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | | Dmitry Stogov | @@ -28,6 +27,11 @@ #include "zend_globals.h" #include "zend_closures_arginfo.h" +/* Closure is a PFA */ +#define ZEND_PARTIAL OBJ_EXTRA_FLAG_PRIV_1 +/* Closure is a PFA of a Closure. Rebinding the PFA requires rebinding the inner Closure. */ +#define ZEND_PARTIAL_OF_CLOSURE OBJ_EXTRA_FLAG_PRIV_2 + typedef struct _zend_closure { zend_object std; zend_function func; @@ -41,6 +45,17 @@ ZEND_API zend_class_entry *zend_ce_closure; static zend_object_handlers closure_handlers; static zend_result zend_closure_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only); +static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr, bool is_fake, uint32_t flags); + +static inline uint32_t zend_closure_flags(const zend_closure *closure) +{ + return closure->std.extra_flags & (ZEND_PARTIAL|ZEND_PARTIAL_OF_CLOSURE); +} + +static inline bool zend_closure_is_fake(const zend_closure *closure) +{ + return closure->func.common.fn_flags & ZEND_ACC_FAKE_CLOSURE; +} ZEND_METHOD(Closure, __invoke) /* {{{ */ { @@ -78,7 +93,9 @@ static bool zend_valid_closure_binding( zend_closure *closure, zval *newthis, zend_class_entry *scope) /* {{{ */ { zend_function *func = &closure->func; - bool is_fake_closure = (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0; + // TODO: rename variable + bool is_fake_closure = (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0 + || (closure->std.extra_flags & ZEND_PARTIAL); if (newthis) { if (func->common.fn_flags & ZEND_ACC_STATIC) { zend_error(E_WARNING, "Cannot bind an instance to a static closure, this will be an error in PHP 9"); @@ -155,13 +172,16 @@ ZEND_METHOD(Closure, call) fci_cache.object = fci.object = newobj; fci.size = sizeof(fci); + fci.consumed_args = 0; ZVAL_OBJ(&fci.function_name, &closure->std); ZVAL_UNDEF(&closure_result); fci.retval = &closure_result; if (closure->func.common.fn_flags & ZEND_ACC_GENERATOR) { zval new_closure; - zend_create_closure(&new_closure, &closure->func, newclass, closure->called_scope, newthis); + zend_create_closure_ex(&new_closure, &closure->func, newclass, + closure->called_scope, newthis, + zend_closure_is_fake(closure), zend_closure_flags(closure)); closure = (zend_closure *) Z_OBJ(new_closure); fci_cache.function_handler = &closure->func; @@ -177,6 +197,7 @@ ZEND_METHOD(Closure, call) memset(&fake_closure->std, 0, sizeof(fake_closure->std)); fake_closure->std.gc.refcount = 1; fake_closure->std.gc.u.type_info = GC_NULL; + fake_closure->std.extra_flags = zend_closure_flags(closure); ZVAL_UNDEF(&fake_closure->this_ptr); fake_closure->called_scope = NULL; my_function = &fake_closure->func; @@ -223,7 +244,7 @@ ZEND_METHOD(Closure, call) } /* }}} */ -static void do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, zend_object *scope_obj, zend_string *scope_str) +static zend_result do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, zend_object *scope_obj, zend_string *scope_str) { zend_class_entry *ce, *called_scope; zend_closure *closure = (zend_closure *) Z_OBJ_P(zclosure); @@ -235,14 +256,15 @@ static void do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, z ce = closure->func.common.scope; } else if ((ce = zend_lookup_class(scope_str)) == NULL) { zend_error(E_WARNING, "Class \"%s\" not found", ZSTR_VAL(scope_str)); - RETURN_NULL(); + RETVAL_NULL(); + return FAILURE; } } else { ce = NULL; } if (!zend_valid_closure_binding(closure, newthis, ce)) { - return; + return FAILURE; } if (newthis) { @@ -251,7 +273,34 @@ static void do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, z called_scope = ce; } - zend_create_closure(return_value, &closure->func, ce, called_scope, newthis); + zend_create_closure_ex(return_value, &closure->func, ce, called_scope, newthis, + zend_closure_is_fake(closure), zend_closure_flags(closure)); + + if (zend_closure_flags(closure) & ZEND_PARTIAL_OF_CLOSURE) { + /* Re-bind the inner closure */ + + zend_closure *new_closure = (zend_closure*)Z_OBJ_P(return_value); + HashTable *static_variables = ZEND_MAP_PTR_GET(new_closure->func.op_array.static_variables_ptr); + ZEND_ASSERT(static_variables->nNumOfElements > 0); + zval *inner = &static_variables->arData[0].val; + ZEND_ASSERT(Z_TYPE_P(inner) == IS_OBJECT && Z_OBJCE_P(inner) == zend_ce_closure); + + zval new_inner; + if (do_closure_bind(&new_inner, inner, newthis, scope_obj, scope_str) != SUCCESS) { + /* Should not happen, as we have already validated arguments and the + * inner closure should have the same constraints. */ + ZEND_UNREACHABLE(); + zval_ptr_dtor(return_value); + ZVAL_NULL(return_value); + return FAILURE; + } + + zend_object *garbage = Z_OBJ_P(inner); + ZVAL_COPY_VALUE(inner, &new_inner); + zend_object_release(garbage); + } + + return SUCCESS; } /* {{{ Create a closure from another one and bind to another object and scope */ @@ -588,8 +637,9 @@ static zend_object *zend_closure_clone(zend_object *zobject) /* {{{ */ zend_closure *closure = (zend_closure *)zobject; zval result; - zend_create_closure(&result, &closure->func, - closure->func.common.scope, closure->called_scope, &closure->this_ptr); + zend_create_closure_ex(&result, &closure->func, + closure->func.common.scope, closure->called_scope, &closure->this_ptr, + zend_closure_is_fake(closure), zend_closure_flags(closure)); return Z_OBJ(result); } /* }}} */ @@ -750,13 +800,14 @@ static ZEND_NAMED_FUNCTION(zend_closure_internal_handler) /* {{{ */ { zend_closure *closure = (zend_closure*)ZEND_CLOSURE_OBJECT(EX(func)); closure->orig_internal_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + ZEND_ASSERT(!(closure->func.common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS) || EG(exception)); // Assign to EX(this) so that it is released after observer checks etc. ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_RELEASE_THIS); Z_OBJ(EX(This)) = &closure->std; } /* }}} */ -static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr, bool is_fake) /* {{{ */ +static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr, bool is_fake, uint32_t flags) /* {{{ */ { zend_closure *closure; void *ptr; @@ -764,6 +815,7 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en object_init_ex(res, zend_ce_closure); closure = (zend_closure *)Z_OBJ_P(res); + closure->std.extra_flags = flags; if ((scope == NULL) && this_ptr && (Z_TYPE_P(this_ptr) != IS_UNDEF)) { /* use dummy scope if we're binding an object without specifying a scope */ @@ -829,7 +881,7 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en /* wrap internal function handler to avoid memory leak */ if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) { /* avoid infinity recursion, by taking handler from nested closure */ - zend_closure *nested = (zend_closure*)((char*)func - XtOffsetOf(zend_closure, func)); + zend_closure *nested = ZEND_CONTAINER_OF(func, zend_closure, func); ZEND_ASSERT(nested->std.ce == zend_ce_closure); closure->orig_internal_handler = nested->orig_internal_handler; } else { @@ -861,14 +913,16 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) { zend_create_closure_ex(res, func, scope, called_scope, this_ptr, - /* is_fake */ (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0); + /* is_fake */ (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0, + /* flags */ 0); } ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */ { zend_closure *closure; - zend_create_closure_ex(res, func, scope, called_scope, this_ptr, /* is_fake */ true); + zend_create_closure_ex(res, func, scope, called_scope, this_ptr, + /* is_fake */ true, /* flags */ 0); closure = (zend_closure *)Z_OBJ_P(res); closure->func.common.fn_flags |= ZEND_ACC_FAKE_CLOSURE; @@ -878,6 +932,16 @@ ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_clas } /* }}} */ +ZEND_API void zend_create_partial_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr, bool partial_of_closure) +{ + uint32_t flags = ZEND_PARTIAL; + if (partial_of_closure) { + flags |= ZEND_PARTIAL_OF_CLOSURE; + } + zend_create_closure_ex(res, func, scope, called_scope, this_ptr, + /* is_fake */ false, flags); +} + void zend_closure_from_frame(zval *return_value, const zend_execute_data *call) { /* {{{ */ zval instance; zend_internal_function trampoline; diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index 8bea4ffb051e..305d82e5015a 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | | Dmitry Stogov | @@ -37,6 +36,7 @@ extern ZEND_API zend_class_entry *zend_ce_closure; ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr); ZEND_API void zend_create_fake_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr); +ZEND_API void zend_create_partial_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr, bool partial_of_closure); ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj); ZEND_API const zend_function *zend_get_closure_method_def(zend_object *obj); ZEND_API zval* zend_get_closure_this_ptr(zval *obj); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ee83ee75ff6e..6a677e71a6b6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -29,6 +28,8 @@ #include "zend_exceptions.h" #include "zend_interfaces.h" #include "zend_types.h" +#include "zend_portability.h" +#include "zend_string.h" #include "zend_virtual_cwd.h" #include "zend_multibyte.h" #include "zend_language_scanner.h" @@ -103,6 +104,8 @@ static void zend_compile_expr(znode *result, zend_ast *ast); static void zend_compile_stmt(zend_ast *ast); static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_t type); +static zend_ast *zend_partial_apply(zend_ast *callable_ast, zend_ast *pipe_arg); + #ifdef ZEND_CHECK_STACK_LIMIT zend_never_inline static void zend_stack_limit_error(void) { @@ -188,10 +191,10 @@ static bool zend_get_unqualified_name(const zend_string *name, const char **resu if (ns_separator != NULL) { *result = ns_separator + 1; *result_len = ZSTR_VAL(name) + ZSTR_LEN(name) - *result; - return 1; + return true; } - return 0; + return false; } /* }}} */ @@ -234,11 +237,11 @@ static bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */ if (uqname_len == reserved->len && zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0 ) { - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -531,6 +534,12 @@ ZEND_API bool zend_is_compiling(void) /* {{{ */ } /* }}} */ +static bool zend_is_constructor(const zend_string *name) /* {{{ */ +{ + return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME); +} +/* }}} */ + static zend_always_inline uint32_t get_temporary_variable(void) /* {{{ */ { return (uint32_t)CG(active_op_array)->T++; @@ -668,12 +677,10 @@ static int zend_add_const_name_literal(zend_string *name, bool unqualified) /* { int ret = zend_add_literal_string(&name); - size_t ns_len = 0, after_ns_len = ZSTR_LEN(name); - const char *after_ns = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); - if (after_ns) { - after_ns += 1; - ns_len = after_ns - ZSTR_VAL(name) - 1; - after_ns_len = ZSTR_LEN(name) - ns_len - 1; + const char *after_ns; + size_t after_ns_len; + if (zend_get_unqualified_name(name, &after_ns, &after_ns_len)) { + size_t ns_len = after_ns - ZSTR_VAL(name) - 1; /* lowercased namespace name & original constant name */ tmp_name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), 0); @@ -685,6 +692,7 @@ static int zend_add_const_name_literal(zend_string *name, bool unqualified) /* { } } else { after_ns = ZSTR_VAL(name); + after_ns_len = ZSTR_LEN(name); } /* original unqualified constant name */ @@ -891,7 +899,7 @@ static const char *zend_modifier_token_to_string(uint32_t token) return "protected(set)"; case T_PRIVATE_SET: return "private(set)"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1665,13 +1673,13 @@ static bool array_is_const(const zend_array *array) static bool can_ct_eval_const(const zend_constant *c) { if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - return 0; + return false; } if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) && !((ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE) && (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) { - return 1; + return true; } if (Z_TYPE(c->value) < IS_ARRAY && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) { @@ -1681,7 +1689,7 @@ static bool can_ct_eval_const(const zend_constant *c) { && array_is_const(Z_ARR(c->value))) { return 1; } - return 0; + return false; } static bool zend_try_ct_eval_const(zval *zv, zend_string *name, bool is_fully_qualified) /* {{{ */ @@ -1698,14 +1706,14 @@ static bool zend_try_ct_eval_const(zval *zv, zend_string *name, bool is_fully_qu zend_constant *c; if ((c = zend_get_special_const(lookup_name, lookup_len))) { ZVAL_COPY_VALUE(zv, &c->value); - return 1; + return true; } c = zend_hash_find_ptr(EG(zend_constants), name); if (c && can_ct_eval_const(c)) { ZVAL_COPY_OR_DUP(zv, &c->value); - return 1; + return true; } - return 0; + return false; } /* }}} */ @@ -1713,12 +1721,12 @@ static inline bool zend_is_scope_known(void) /* {{{ */ { if (!CG(active_op_array)) { /* This can only happen when evaluating a default value string. */ - return 0; + return false; } if (CG(active_op_array)->fn_flags & ZEND_ACC_CLOSURE) { /* Closures can be rebound to a different scope */ - return 0; + return false; } if (!CG(active_class_entry)) { @@ -1735,10 +1743,10 @@ static inline bool zend_is_scope_known(void) /* {{{ */ static inline bool class_name_refers_to_active_ce(const zend_string *class_name, uint32_t fetch_type) /* {{{ */ { if (!CG(active_class_entry)) { - return 0; + return false; } if (fetch_type == ZEND_FETCH_CLASS_SELF && zend_is_scope_known()) { - return 1; + return true; } return fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name); @@ -1803,7 +1811,7 @@ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *c const zval *class_name; if (class_ast->kind != ZEND_AST_ZVAL) { - return 0; + return false; } class_name = zend_ast_get_zval(class_ast); @@ -1819,22 +1827,22 @@ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *c case ZEND_FETCH_CLASS_SELF: if (CG(active_class_entry) && zend_is_scope_known()) { ZVAL_STR_COPY(zv, CG(active_class_entry)->name); - return 1; + return true; } - return 0; + return false; case ZEND_FETCH_CLASS_PARENT: if (CG(active_class_entry) && CG(active_class_entry)->parent_name && zend_is_scope_known()) { ZVAL_STR_COPY(zv, CG(active_class_entry)->parent_name); - return 1; + return true; } - return 0; + return false; case ZEND_FETCH_CLASS_STATIC: - return 0; + return false; case ZEND_FETCH_CLASS_DEFAULT: ZVAL_STR(zv, zend_resolve_class_name_ast(class_ast)); - return 1; - EMPTY_SWITCH_DEFAULT_CASE() + return true; + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -1896,11 +1904,11 @@ static bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend } if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) { - return 0; + return false; } if (!cc || !zend_verify_ct_const_access(cc, CG(active_class_entry))) { - return 0; + return false; } c = &cc->value; @@ -1914,7 +1922,7 @@ static bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend return 1; } - return 0; + return false; } /* }}} */ @@ -1950,6 +1958,9 @@ static void zend_do_extended_stmt(znode* result) /* {{{ */ opline->opcode = ZEND_EXT_STMT; if (result) { + if (result->op_type == IS_CONST) { + Z_TRY_ADDREF(result->u.constant); + } SET_NODE(opline->op1, result); } } @@ -2196,7 +2207,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len) /* Note that on Win32 CWD is per drive (heritage from CP/M). * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive. */ - if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) { + if ((2 <= len) && isalpha((unsigned char)path[0]) && (':' == path[1])) { /* Skip over the drive spec (if any) so as not to change */ path += 2; len_adjust += 2; @@ -2278,7 +2289,7 @@ static void zend_adjust_for_fetch_type(zend_op *opline, znode *result, uint32_t case BP_VAR_UNSET: opline->opcode += 5 * factor; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2441,7 +2452,7 @@ static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_t case ZEND_JMP_FRAMELESS: opline->op2.opline_num = opnum_target; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2510,9 +2521,9 @@ static bool zend_ast_kind_is_short_circuited(zend_ast_kind ast_kind) case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: - return 1; + return true; default: - return 0; + return false; } } @@ -2527,9 +2538,9 @@ static bool zend_ast_is_short_circuited(const zend_ast *ast) return zend_ast_is_short_circuited(ast->child[0]); case ZEND_AST_NULLSAFE_PROP: case ZEND_AST_NULLSAFE_METHOD_CALL: - return 1; + return true; default: - return 0; + return false; } } @@ -2799,7 +2810,7 @@ static inline bool zend_can_write_to_variable(const zend_ast *ast) /* {{{ */ static inline bool zend_is_const_default_class_ref(zend_ast *name_ast) /* {{{ */ { if (name_ast->kind != ZEND_AST_ZVAL) { - return 0; + return false; } return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type_ast(name_ast); @@ -2968,7 +2979,6 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, const zend_ast *ast opline->extended_value = ZEND_FETCH_GLOBAL; } else { - // TODO: Have a test case for this? if (name_node.op_type == IS_CONST && type == BP_VAR_R && zend_string_equals_literal(Z_STR(name_node.u.constant), "http_response_header")) { @@ -2991,7 +3001,7 @@ static bool is_this_fetch(const zend_ast *ast) /* {{{ */ return Z_TYPE_P(name) == IS_STRING && zend_string_equals(Z_STR_P(name), ZSTR_KNOWN(ZEND_STR_THIS)); } - return 0; + return false; } /* }}} */ @@ -3002,7 +3012,7 @@ static bool is_globals_fetch(const zend_ast *ast) return Z_TYPE_P(name) == IS_STRING && zend_string_equals_literal(Z_STR_P(name), "GLOBALS"); } - return 0; + return false; } static bool is_global_var_fetch(const zend_ast *ast) @@ -3458,7 +3468,7 @@ static void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */ static bool zend_is_assign_to_self(const zend_ast *var_ast, const zend_ast *expr_ast) /* {{{ */ { if (expr_ast->kind != ZEND_AST_VAR || expr_ast->child[0]->kind != ZEND_AST_ZVAL) { - return 0; + return false; } while (zend_is_variable(var_ast) && var_ast->kind != ZEND_AST_VAR) { @@ -3466,7 +3476,7 @@ static bool zend_is_assign_to_self(const zend_ast *var_ast, const zend_ast *expr } if (var_ast->kind != ZEND_AST_VAR || var_ast->child[0]->kind != ZEND_AST_ZVAL) { - return 0; + return false; } { @@ -3591,7 +3601,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_ result->op_type = IS_UNUSED; } return; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -3747,7 +3757,7 @@ static void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ opline = zend_emit_op_data(&expr_node); opline->extended_value = cache_slot; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -3765,12 +3775,16 @@ static uint32_t zend_get_arg_num(const zend_function *fn, const zend_string *arg return (uint32_t) -1; } -static uint32_t zend_compile_args( - zend_ast *ast, const zend_function *fbc, bool *may_have_extra_named_args) /* {{{ */ +static uint32_t zend_compile_args_ex( + zend_ast *ast, const zend_function *fbc, + bool *may_have_extra_named_args, + bool is_call_partial, bool *uses_variadic_placeholder_p, + zval *named_positions) /* {{{ */ { const zend_ast_list *args = zend_ast_get_list(ast); uint32_t i; bool uses_arg_unpack = false; + bool uses_variadic_placeholder = false; uint32_t arg_count = 0; /* number of arguments not including unpacks */ /* Whether named arguments are used syntactically, to enforce language level limitations. @@ -3796,6 +3810,11 @@ static uint32_t zend_compile_args( "Cannot use argument unpacking after named arguments"); } + if (is_call_partial) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot combine partial application and unpacking"); + } + /* Unpack may contain named arguments. */ may_have_undef = true; if (!fbc || (fbc->common.fn_flags & ZEND_ACC_VARIADIC)) { @@ -3836,18 +3855,75 @@ static uint32_t zend_compile_args( may_have_undef = true; *may_have_extra_named_args = true; } + + if (uses_variadic_placeholder) { + zend_error_noreturn(E_COMPILE_ERROR, + "Variadic placeholder must be last"); + } } else { if (uses_arg_unpack) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use positional argument after argument unpacking"); } - if (uses_named_args) { + bool is_variadic_placeholder = arg->kind == ZEND_AST_PLACEHOLDER_ARG + && arg->attr == ZEND_PLACEHOLDER_VARIADIC; + + if (uses_named_args && !is_variadic_placeholder) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use positional argument after named argument"); } - arg_count++; + if (uses_variadic_placeholder) { + if (is_variadic_placeholder) { + zend_error_noreturn(E_COMPILE_ERROR, + "Variadic placeholder may only appear once"); + } else { + zend_error_noreturn(E_COMPILE_ERROR, + "Variadic placeholder must be last"); + } + } + + if (!is_variadic_placeholder) { + arg_count++; + } + } + + if (arg->kind == ZEND_AST_PLACEHOLDER_ARG) { + if (uses_arg_unpack) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot combine partial application and unpacking"); + } + + if (arg->attr == ZEND_PLACEHOLDER_VARIADIC) { + uses_variadic_placeholder = true; + /* Do not emit ZEND_SEND_PLACEHOLDER: We represent the variadic + * placeholder with a flag on the ZEND_CONVERT_CALLABLE_PARTIAL + * op instead. */ + continue; + } + + if (arg_name) { + if (Z_ISUNDEF_P(named_positions)) { + array_init(named_positions); + } + zval tmp; + ZVAL_LONG(&tmp, zend_hash_num_elements(Z_ARRVAL_P(named_positions))); + zend_hash_add(Z_ARRVAL_P(named_positions), arg_name, &tmp); + } + + opline = zend_emit_op(NULL, ZEND_SEND_PLACEHOLDER, NULL, NULL); + if (arg_name) { + opline->op2_type = IS_CONST; + zend_string_addref(arg_name); + opline->op2.constant = zend_add_literal_string(&arg_name); + opline->result.num = zend_alloc_cache_slots(2); + } else if (arg->attr != ZEND_PLACEHOLDER_VARIADIC) { + opline->op2.opline_num = arg_num; + opline->result.var = EX_NUM_TO_VAR(arg_num - 1); + } + + continue; } /* Treat passing of $GLOBALS the same as passing a call. @@ -3962,14 +4038,23 @@ static uint32_t zend_compile_args( } } - if (may_have_undef) { - zend_emit_op(NULL, ZEND_CHECK_UNDEF_ARGS, NULL, NULL); + if (!is_call_partial) { + if (may_have_undef) { + zend_emit_op(NULL, ZEND_CHECK_UNDEF_ARGS, NULL, NULL); + } + } else { + *uses_variadic_placeholder_p = uses_variadic_placeholder; } return arg_count; } /* }}} */ +static uint32_t zend_compile_args(zend_ast *ast, const zend_function *fbc, bool *may_have_extra_named_args) +{ + return zend_compile_args_ex(ast, fbc, may_have_extra_named_args, false, NULL, NULL); +} + ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, const zend_function *fbc, bool result_used) /* {{{ */ { uint32_t no_discard = result_used ? 0 : ZEND_ACC_NODISCARD; @@ -4003,6 +4088,38 @@ ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, const zend_function *f } /* }}} */ +static void zend_compile_call_partial(znode *result, uint32_t arg_count, + bool may_have_extra_named_args, bool uses_variadic_placeholder, + zval *named_positions, uint32_t opnum_init, const zend_function *fbc) { + + zend_op *init_opline = &CG(active_op_array)->opcodes[opnum_init]; + + init_opline->extended_value = arg_count; + + ZEND_ASSERT(init_opline->opcode != ZEND_NEW); + + if (init_opline->opcode == ZEND_INIT_FCALL) { + init_opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc); + } + + zend_op *opline = zend_emit_op_tmp(result, ZEND_CALLABLE_CONVERT_PARTIAL, + NULL, NULL); + + opline->op1.num = zend_alloc_cache_slots(2); + + if (may_have_extra_named_args) { + opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; + } + if (uses_variadic_placeholder) { + opline->extended_value |= ZEND_FCALL_USES_VARIADIC_PLACEHOLDER; + } + + if (!Z_ISUNDEF_P(named_positions)) { + opline->op2.constant = zend_add_literal(named_positions); + opline->op2_type = IS_CONST; + } +} + static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const zend_function *fbc, uint32_t lineno, uint32_t type) /* {{{ */ { zend_op *opline; @@ -4018,23 +4135,43 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const ze zend_error_noreturn(E_COMPILE_ERROR, "Cannot create Closure for new expression"); } - zend_ast_list *args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); - if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders"); - } + zend_ast_list *fcc_args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); - if (opcode == ZEND_INIT_FCALL) { - opline->op1.num = zend_vm_calc_used_stack(0, fbc); - } + /* FCCs are a special case of PFAs with a single variadic placeholder */ + if (fcc_args->children == 1 && fcc_args->child[0]->attr == ZEND_PLACEHOLDER_VARIADIC) { - zend_op *callable_convert_op = zend_emit_op_tmp(result, ZEND_CALLABLE_CONVERT, NULL, NULL); - if (opcode == ZEND_INIT_FCALL - || opcode == ZEND_INIT_FCALL_BY_NAME - || opcode == ZEND_INIT_NS_FCALL_BY_NAME) { - callable_convert_op->extended_value = zend_alloc_cache_slot(); - } else { - callable_convert_op->extended_value = (uint32_t)-1; + if (opline->opcode == ZEND_INIT_FCALL) { + opline->op1.num = zend_vm_calc_used_stack(0, fbc); + } + + zend_op *callable_convert_op = zend_emit_op_tmp(result, ZEND_CALLABLE_CONVERT, NULL, NULL); + if (opcode == ZEND_INIT_FCALL + || opcode == ZEND_INIT_FCALL_BY_NAME + || opcode == ZEND_INIT_NS_FCALL_BY_NAME) { + callable_convert_op->extended_value = zend_alloc_cache_slot(); + } else { + callable_convert_op->extended_value = (uint32_t)-1; + } + + return true; } + + args_ast = ((zend_ast_fcc*)args_ast)->args; + + bool may_have_extra_named_args; + bool uses_variadic_placeholder; + + zval named_positions; + ZVAL_UNDEF(&named_positions); + + uint32_t arg_count = zend_compile_args_ex(args_ast, fbc, + &may_have_extra_named_args, true, &uses_variadic_placeholder, + &named_positions); + + zend_compile_call_partial(result, arg_count, + may_have_extra_named_args, uses_variadic_placeholder, + &named_positions, opnum_init, fbc); + return true; } @@ -4129,10 +4266,10 @@ static inline bool zend_args_contain_unpack_or_named(const zend_ast_list *args) for (i = 0; i < args->children; ++i) { const zend_ast *arg = args->child[i]; if (arg->kind == ZEND_AST_UNPACK || arg->kind == ZEND_AST_NAMED_ARG) { - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -5009,7 +5146,7 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args) case 'd': zend_emit_op_tmp(&elements[placeholder_count], ZEND_CAST, &elements[placeholder_count], NULL)->extended_value = IS_LONG; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if (rope_elements == 0) { @@ -5120,42 +5257,21 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg } zend_ast *callback = args->child[0]; - - /* Bail out if the callback is not a FCC/PFA. */ - zend_ast *args_ast; - switch (callback->kind) { - case ZEND_AST_CALL: - case ZEND_AST_STATIC_CALL: - args_ast = zend_ast_call_get_args(callback); - if (args_ast->kind != ZEND_AST_CALLABLE_CONVERT) { - return FAILURE; - } - - break; - default: - return FAILURE; - } - - /* Bail out if the callback is assert() due to the AST stringification logic - * breaking for the generated call. - */ - if (callback->kind == ZEND_AST_CALL - && callback->child[0]->kind == ZEND_AST_ZVAL - && Z_TYPE_P(zend_ast_get_zval(callback->child[0])) == IS_STRING - && zend_string_equals_literal_ci(zend_ast_get_str(callback->child[0]), "assert")) { - return FAILURE; - } - - zend_ast_list *callback_args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); - if (callback_args->children != 1 || callback_args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { - /* Full PFA is not yet implemented, will fail in zend_compile_call_common(). */ + if (callback->kind != ZEND_AST_CALL && callback->kind != ZEND_AST_STATIC_CALL) { return FAILURE; } znode value; value.op_type = IS_TMP_VAR; value.u.op.var = get_temporary_variable(); - zend_ast *call_args = zend_ast_create_list(1, ZEND_AST_ARG_LIST, zend_ast_create_znode(&value)); + + zend_ast *call_args = zend_partial_apply(callback, + zend_ast_create_znode(&value)); + if (!call_args) { + CG(active_op_array)->T--; + /* The callback is not a FCC/PFA, or is not optimizable */ + return FAILURE; + } zend_op *opline; @@ -5174,7 +5290,7 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg opline->lineno = lineno; opline->extended_value = (2 << 16) | IS_ARRAY; const zval *fbc_zv = zend_hash_find(CG(function_table), lcname); - const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val)); + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); Z_EXTRA_P(CT_CONSTANT(opline->op1)) = fbc_bucket - CG(function_table)->arData; /* Initialize the result array. */ @@ -5326,7 +5442,7 @@ static const char *zend_get_cstring_from_property_hook_kind(zend_property_hook_k return "get"; case ZEND_PROPERTY_HOOK_SET: return "set"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -5347,17 +5463,7 @@ static bool zend_compile_parent_property_hook_call(znode *result, const zend_ast const zend_ast *class_ast = ast->child[0]; zend_ast *method_ast = ast->child[1]; - /* Recognize parent::$prop::get() pattern. */ - if (class_ast->kind != ZEND_AST_STATIC_PROP - || (class_ast->attr & ZEND_PARENTHESIZED_STATIC_PROP) - || class_ast->child[0]->kind != ZEND_AST_ZVAL - || Z_TYPE_P(zend_ast_get_zval(class_ast->child[0])) != IS_STRING - || zend_get_class_fetch_type(zend_ast_get_str(class_ast->child[0])) != ZEND_FETCH_CLASS_PARENT - || class_ast->child[1]->kind != ZEND_AST_ZVAL - || method_ast->kind != ZEND_AST_ZVAL - || Z_TYPE_P(zend_ast_get_zval(method_ast)) != IS_STRING - || (!zend_string_equals_literal_ci(zend_ast_get_str(method_ast), "get") - && !zend_string_equals_literal_ci(zend_ast_get_str(method_ast), "set"))) { + if (!zend_ast_is_parent_hook_call(ast)) { return false; } @@ -5464,14 +5570,14 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type) } zval_ptr_dtor(&name_node.u.constant); - ZVAL_NEW_STR(&name_node.u.constant, lcname); + ZVAL_STR(&name_node.u.constant, lcname); opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node); opline->result.num = zend_alloc_cache_slot(); /* Store offset to function from symbol table in op2.extra. */ if (fbc->type == ZEND_INTERNAL_FUNCTION) { - const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val)); + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); Z_EXTRA_P(CT_CONSTANT(opline->op2)) = fbc_bucket - CG(function_table)->arData; } @@ -5548,12 +5654,6 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type } /* }}} */ -static bool zend_is_constructor(const zend_string *name) /* {{{ */ -{ - return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME); -} -/* }}} */ - static bool is_func_accessible(const zend_function *fbc) { if ((fbc->common.fn_flags & ZEND_ACC_PUBLIC) || fbc->common.scope == CG(active_class_entry)) { @@ -5876,7 +5976,7 @@ static void zend_compile_unset(const zend_ast *ast) /* {{{ */ opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_UNSET, false, false); opline->opcode = ZEND_UNSET_STATIC_PROP; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -5887,7 +5987,7 @@ static bool zend_handle_loops_and_finally_ex(zend_long depth, znode *return_valu zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); if (!loop_var) { - return 1; + return true; } base = zend_stack_base(&CG(loop_var_stack)); for (; loop_var >= base; loop_var--) { @@ -5942,7 +6042,7 @@ static bool zend_has_finally_ex(zend_long depth) /* {{{ */ zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); if (!loop_var) { - return 0; + return false; } base = zend_stack_base(&CG(loop_var_stack)); for (; loop_var >= base; loop_var--) { @@ -5958,7 +6058,7 @@ static bool zend_has_finally_ex(zend_long depth) /* {{{ */ depth--; } } - return 0; + return false; } /* }}} */ @@ -5992,6 +6092,16 @@ static void zend_compile_return(const zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); } + if (expr_ast) { + if (CG(active_class_entry) != NULL) { + if (zend_is_constructor(CG(active_op_array)->function_name)) { + zend_error(E_DEPRECATED, "Returning a value from a constructor is deprecated"); + } else if (zend_string_equals_literal_ci(CG(active_op_array)->function_name, ZEND_DESTRUCTOR_FUNC_NAME)) { + zend_error(E_DEPRECATED, "Returning a value from a destructor is deprecated"); + } + } + } + if ((CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) && (expr_node.op_type == IS_CV || (by_ref && expr_node.op_type == IS_VAR)) && zend_has_finally()) { @@ -6560,7 +6670,7 @@ static uint8_t determine_switch_jumptable_type(const zend_ast_list *cases) { static bool should_use_jumptable(const zend_ast_list *cases, uint8_t jumptable_type) { if (CG(compiler_options) & ZEND_COMPILE_NO_JUMPTABLES) { - return 0; + return false; } /* Thresholds are chosen based on when the average switch time for equidistributed @@ -6743,17 +6853,17 @@ static bool can_match_use_jumptable(const zend_ast_list *arms) { zend_eval_const_expr(cond_ast); if ((*cond_ast)->kind != ZEND_AST_ZVAL) { - return 0; + return false; } const zval *cond_zv = zend_ast_get_zval(*cond_ast); if (Z_TYPE_P(cond_zv) != IS_LONG && Z_TYPE_P(cond_zv) != IS_STRING) { - return 0; + return false; } } } - return 1; + return true; } static bool zend_is_pipe_optimizable_callable_name(zend_ast *ast) @@ -6769,6 +6879,76 @@ static bool zend_is_pipe_optimizable_callable_name(zend_ast *ast) return true; } +static zend_ast *zend_partial_apply(zend_ast *callable_ast, zend_ast *pipe_arg) +{ + if (callable_ast->kind != ZEND_AST_CALL + && callable_ast->kind != ZEND_AST_STATIC_CALL + && callable_ast->kind != ZEND_AST_METHOD_CALL) { + return NULL; + } + + zend_ast *args_ast = zend_ast_call_get_args(callable_ast); + if (!args_ast || args_ast->kind != ZEND_AST_CALLABLE_CONVERT) { + return NULL; + } + + if (callable_ast->kind == ZEND_AST_CALL && + !zend_is_pipe_optimizable_callable_name(callable_ast->child[0])) { + return NULL; + } + + zend_ast_list *arg_list = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); + + zend_ast *first_placeholder = NULL; + bool uses_named_args = false; + + for (uint32_t i = 0; i < arg_list->children; i++) { + zend_ast *arg = arg_list->child[i]; + if (arg->kind == ZEND_AST_NAMED_ARG) { + uses_named_args = true; + arg = arg->child[1]; + } + + if (arg->kind == ZEND_AST_PLACEHOLDER_ARG) { + if (first_placeholder == NULL) { + first_placeholder = arg; + } else { + /* A PFA with multiple placeholders is unexpected in this + * context, and will usually error due to a missing argument, + * so we don't optimize those. */ + return NULL; + } + if (arg->attr == ZEND_PLACEHOLDER_VARIADIC && uses_named_args) { + /* A PFA with both a variadic placeholder and named args can not + * be optimized because this would result in a positional arg + * after a named arg: f(name: $v, ...) -> f(name: $v, pipe_arg). + * Arg placeholders ('?') are safe since they are not allowed + * after named args. */ + return NULL; + } + } + } + + ZEND_ASSERT(first_placeholder); + + zend_ast *new_arg_list = zend_ast_create_list(0, arg_list->kind); + for (uint32_t i = 0; i < arg_list->children; i++) { + zend_ast *arg = arg_list->child[i]; + if (arg == first_placeholder) { + new_arg_list = zend_ast_list_add(new_arg_list, pipe_arg); + } else if (arg->kind == ZEND_AST_NAMED_ARG + && arg->child[1] == first_placeholder) { + zend_ast *name = arg->child[0]; + new_arg_list = zend_ast_list_add(new_arg_list, + zend_ast_create(ZEND_AST_NAMED_ARG, name, pipe_arg)); + } else { + new_arg_list = zend_ast_list_add(new_arg_list, arg); + } + } + + return new_arg_list; +} + static void zend_compile_pipe(znode *result, zend_ast *ast, uint32_t type) { zend_ast *operand_ast = ast->child[0]; @@ -6793,29 +6973,35 @@ static void zend_compile_pipe(znode *result, zend_ast *ast, uint32_t type) } /* Turn the operand into a function parameter list. */ - zend_ast *arg_list_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, zend_ast_create_znode(&wrapped_operand_result)); + zend_ast *arg = zend_ast_create_znode(&wrapped_operand_result); zend_ast *fcall_ast; znode callable_result; + zend_ast *pfa_arg_list_ast = NULL; - /* Turn $foo |> bar(...) into bar($foo). */ - if (callable_ast->kind == ZEND_AST_CALL - && callable_ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT - && zend_is_pipe_optimizable_callable_name(callable_ast->child[0])) { - fcall_ast = zend_ast_create(ZEND_AST_CALL, - callable_ast->child[0], arg_list_ast); - /* Turn $foo |> bar::baz(...) into bar::baz($foo). */ - } else if (callable_ast->kind == ZEND_AST_STATIC_CALL - && callable_ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT) { - fcall_ast = zend_ast_create(ZEND_AST_STATIC_CALL, - callable_ast->child[0], callable_ast->child[1], arg_list_ast); - /* Turn $foo |> $bar->baz(...) into $bar->baz($foo). */ - } else if (callable_ast->kind == ZEND_AST_METHOD_CALL - && callable_ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT) { - fcall_ast = zend_ast_create(ZEND_AST_METHOD_CALL, - callable_ast->child[0], callable_ast->child[1], arg_list_ast); + /* Turn $foo |> PFA into plain function call if possible */ + if ((pfa_arg_list_ast = zend_partial_apply(callable_ast, arg))) { + switch (callable_ast->kind) { + case ZEND_AST_CALL: + fcall_ast = zend_ast_create(ZEND_AST_CALL, + callable_ast->child[0], pfa_arg_list_ast); + break; + case ZEND_AST_STATIC_CALL: + fcall_ast = zend_ast_create(ZEND_AST_STATIC_CALL, + callable_ast->child[0], callable_ast->child[1], + pfa_arg_list_ast); + break; + case ZEND_AST_METHOD_CALL: + fcall_ast = zend_ast_create(ZEND_AST_METHOD_CALL, + callable_ast->child[0], callable_ast->child[1], + pfa_arg_list_ast); + break; + default: + ZEND_UNREACHABLE(); + } /* Turn $foo |> $expr into ($expr)($foo) */ } else { + zend_ast *arg_list_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, arg); zend_compile_expr(&callable_result, callable_ast); callable_ast = zend_ast_create_znode(&callable_result); fcall_ast = zend_ast_create(ZEND_AST_CALL, @@ -7201,7 +7387,7 @@ bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */ if (zend_string_equals_literal_ci(name, "encoding")) { if (value_ast->kind != ZEND_AST_ZVAL) { zend_throw_exception(zend_ce_compile_error, "Encoding must be a literal", 0); - return 0; + return false; } if (CG(multibyte)) { @@ -7235,7 +7421,7 @@ bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */ } } - return 1; + return true; } /* }}} */ @@ -7469,15 +7655,15 @@ static void zend_are_intersection_types_redundant(const zend_type left_type, con unsigned int sum = 0; const zend_type *outer_type; - ZEND_TYPE_LIST_FOREACH(smaller_type_list, outer_type) + ZEND_TYPE_LIST_FOREACH(smaller_type_list, outer_type) { const zend_type *inner_type; - ZEND_TYPE_LIST_FOREACH(larger_type_list, inner_type) + ZEND_TYPE_LIST_FOREACH(larger_type_list, inner_type) { if (zend_string_equals_ci(ZEND_TYPE_NAME(*inner_type), ZEND_TYPE_NAME(*outer_type))) { sum++; break; } - ZEND_TYPE_LIST_FOREACH_END(); - ZEND_TYPE_LIST_FOREACH_END(); + } ZEND_TYPE_LIST_FOREACH_END(); + } ZEND_TYPE_LIST_FOREACH_END(); if (sum == smaller_type_list->num_types) { zend_string *smaller_type_str; @@ -7505,14 +7691,14 @@ static void zend_is_intersection_type_redundant_by_single_type(const zend_type i ZEND_ASSERT(!ZEND_TYPE_IS_INTERSECTION(single_type)); const zend_type *single_intersection_type = NULL; - ZEND_TYPE_FOREACH(intersection_type, single_intersection_type) + ZEND_TYPE_FOREACH(intersection_type, single_intersection_type) { if (zend_string_equals_ci(ZEND_TYPE_NAME(*single_intersection_type), ZEND_TYPE_NAME(single_type))) { zend_string *single_type_str = zend_type_to_string(single_type); zend_string *complete_type = zend_type_to_string(intersection_type); zend_error_noreturn(E_COMPILE_ERROR, "Type %s is redundant as it is more restrictive than type %s", ZSTR_VAL(complete_type), ZSTR_VAL(single_type_str)); } - ZEND_TYPE_FOREACH_END(); + } ZEND_TYPE_FOREACH_END(); } /* Used by both intersection and union types prior to transforming the type list to a full zend_type */ @@ -7773,14 +7959,14 @@ static bool zend_is_valid_default_value(zend_type type, zval *value) { ZEND_ASSERT(ZEND_TYPE_IS_SET(type)); if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE_P(value))) { - return 1; + return true; } if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) { /* Integers are allowed as initializers for floating-point values. */ convert_to_double(value); - return 1; + return true; } - return 0; + return false; } static void zend_compile_attributes( @@ -8024,6 +8210,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 } else { arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0); } + arg_infos->doc_comment = NULL; arg_infos++; op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE; @@ -8122,6 +8309,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 arg_info->name = zend_string_copy(name); arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0); arg_info->default_value = NULL; + arg_info->doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL; if (attributes_ast) { zend_compile_attributes( @@ -8460,7 +8648,7 @@ static void compile_implicit_lexical_binds( op_array->static_variables = zend_new_array(8); } - ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) + ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) { zval *value = zend_hash_add( op_array->static_variables, var_name, &EG(uninitialized_zval)); uint32_t offset = (uint32_t)((char*)value - (char*)op_array->static_variables->arData); @@ -8469,7 +8657,7 @@ static void compile_implicit_lexical_binds( opline->op2_type = IS_CV; opline->op2.var = lookup_cv(var_name); opline->extended_value = offset | ZEND_BIND_IMPLICIT; - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } static void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ @@ -8509,11 +8697,11 @@ static void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ static void zend_compile_implicit_closure_uses(const closure_info *info) { zend_string *var_name; - ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) + ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) { zval zv; ZVAL_NULL(&zv); zend_compile_static_var_common(var_name, &zv, ZEND_BIND_IMPLICIT); - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } static void add_stringable_interface(zend_class_entry *ce) { @@ -8607,7 +8795,7 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string } zend_add_magic_method(ce, (zend_function *) op_array, lcname); - if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME) + if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_LCNAME) && !(ce->ce_flags & ZEND_ACC_TRAIT)) { add_stringable_interface(ce); } @@ -8838,8 +9026,16 @@ static zend_op_array *zend_compile_func_decl_ex( } zend_compile_params(params_ast, return_type_ast, - is_method && zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME) ? IS_STRING : 0); + is_method && zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_LCNAME) ? IS_STRING : 0); if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { + if (CG(active_class_entry) != NULL) { + if (zend_is_constructor(CG(active_op_array)->function_name)) { + zend_error(E_DEPRECATED, "Making a constructor a Generator is deprecated"); + } else if (zend_string_equals_literal_ci(CG(active_op_array)->function_name, ZEND_DESTRUCTOR_FUNC_NAME)) { + zend_error(E_DEPRECATED, "Making a destructor a Generator is deprecated"); + } + } + zend_mark_function_as_generator(); zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL); } @@ -9204,7 +9400,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (*value_ast_ptr) { zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false); - if (ZEND_TYPE_IS_SET(type) && !Z_CONSTANT(value_zv) + if (ZEND_TYPE_IS_SET(type) && Z_TYPE(value_zv) != IS_CONSTANT_AST && !zend_is_valid_default_value(type, &value_zv)) { zend_string *str = zend_type_to_string(type); if (Z_TYPE(value_zv) == IS_NULL && !ZEND_TYPE_IS_INTERSECTION(type)) { @@ -9328,7 +9524,7 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false); - if (!Z_CONSTANT(value_zv) && ZEND_TYPE_IS_SET(type) && !zend_is_valid_default_value(type, &value_zv)) { + if (Z_TYPE(value_zv) != IS_CONSTANT_AST && ZEND_TYPE_IS_SET(type) && !zend_is_valid_default_value(type, &value_zv)) { zend_string *type_str = zend_type_to_string(type); zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as value for class constant %s::%s of type %s", @@ -9349,6 +9545,15 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as ce->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS; ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } + + const zend_attribute *override = zend_get_attribute_str(c->attributes, "override", sizeof("override") - 1); + if (override) { + ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_OVERRIDE; + /* We need to be able to remove the flag once the override is + * resolved. See ZEND_ACC_DEPRECATED above. */ + ce->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS; + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } } } } @@ -9460,7 +9665,7 @@ static void zend_compile_use_trait(const zend_ast *ast) /* {{{ */ case ZEND_AST_TRAIT_ALIAS: zend_compile_trait_alias(adaptation_ast); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } } @@ -9808,6 +10013,16 @@ static void zend_compile_enum_case(zend_ast *ast) if (deprecated) { ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED; } + + const zend_attribute *override = zend_get_attribute_str(c->attributes, "override", sizeof("override") - 1); + if (override) { + ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_OVERRIDE; + /* We need to be able to remove the flag once the override is + * resolved. See ZEND_ACC_DEPRECATED handling in + * zend_compile_class_const_decl(). */ + enum_class->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS; + enum_class->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } } } @@ -9832,7 +10047,7 @@ static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */ zend_hash_init(FC(imports_const), 8, NULL, str_dtor, 0); } return FC(imports_const); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return NULL; @@ -9848,7 +10063,7 @@ static char *zend_get_use_type_str(uint32_t type) /* {{{ */ return " function"; case ZEND_SYMBOL_CONST: return " const"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return " unknown"; @@ -10214,10 +10429,10 @@ static bool zend_try_ct_eval_magic_const(zval *zv, const zend_ast *ast) /* {{{ * ZVAL_EMPTY_STRING(zv); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } - return 1; + return true; } /* }}} */ @@ -10321,12 +10536,12 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, co static inline bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */ { if (zend_binary_op_produces_error(opcode, op1, op2)) { - return 0; + return false; } const binary_op_type fn = get_binary_op(opcode); fn(result, op1, op2); - return 1; + return true; } /* }}} */ @@ -10351,12 +10566,12 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op) static inline bool zend_try_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */ { if (zend_unary_op_produces_error(opcode, op)) { - return 0; + return false; } const unary_op_type fn = get_unary_op(opcode); fn(result, op); - return 1; + return true; } /* }}} */ @@ -10420,12 +10635,12 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ } if (!is_constant) { - return 0; + return false; } if (!list->children) { ZVAL_EMPTY_ARRAY(result); - return 1; + return true; } array_init_size(result, list->children); @@ -10498,7 +10713,7 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ } } - return 1; + return true; } /* }}} */ @@ -10956,7 +11171,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ zend_emit_op_data(&default_node); assign_node = var_node_w; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } opline = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &assign_node, NULL); @@ -11176,7 +11391,7 @@ static void zend_compile_isset_or_empty(znode *result, const zend_ast *ast) /* { opline = zend_compile_static_prop(result, var_ast, BP_VAR_IS, false, false); opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } result->op_type = opline->result_type = IS_TMP_VAR; @@ -11304,12 +11519,25 @@ static void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ +static void zend_emit_fetch_constant(znode *result, zend_string *resolved_name, bool unqualified_in_namespace) +{ + zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL); + opline->op2_type = IS_CONST; + + if (unqualified_in_namespace) { + opline->op1.num = IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE; + opline->op2.constant = zend_add_const_name_literal(resolved_name, true); + } else { + opline->op1.num = 0; + opline->op2.constant = zend_add_const_name_literal(resolved_name, false); + } + opline->extended_value = zend_alloc_cache_slot(); +} + static void zend_compile_const(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; - zend_op *opline; - bool is_fully_qualified; zend_string *orig_name = zend_ast_get_str(name_ast); zend_string *resolved_name = zend_resolve_const_name(orig_name, name_ast->attr, &is_fully_qualified); @@ -11338,22 +11566,19 @@ static void zend_compile_const(znode *result, const zend_ast *ast) /* {{{ */ return; } - opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL); - opline->op2_type = IS_CONST; - - if (is_fully_qualified || !FC(current_namespace)) { - opline->op1.num = 0; - opline->op2.constant = zend_add_const_name_literal( - resolved_name, false); - } else { - opline->op1.num = IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE; - opline->op2.constant = zend_add_const_name_literal( - resolved_name, true); - } - opline->extended_value = zend_alloc_cache_slot(); + zend_emit_fetch_constant(result, resolved_name, + !is_fully_qualified && FC(current_namespace)); } /* }}} */ +static void zend_compile_constant(znode *result, zend_ast *ast) +{ + zend_string *name = zend_ast_get_constant_name(ast); + + zend_emit_fetch_constant(result, zend_string_copy(name), + (ast->attr & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) != 0); +} + static void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *class_ast; @@ -11692,7 +11917,7 @@ static void zend_compile_const_expr_class_name(zend_ast **ast_ptr) /* {{{ */ case ZEND_FETCH_CLASS_STATIC: zend_error_noreturn(E_COMPILE_ERROR, "static::class cannot be used for compile-time class name resolution"); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -11800,12 +12025,17 @@ static void zend_compile_const_expr_fcc(zend_ast **ast_ptr) case ZEND_AST_STATIC_CALL: args_ast = &(*ast_ptr)->child[2]; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if ((*args_ast)->kind != ZEND_AST_CALLABLE_CONVERT) { zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); } - ZEND_MAP_PTR_NEW(((zend_ast_fcc *)*args_ast)->fptr); + + zend_ast_list *args = zend_ast_get_list(((zend_ast_fcc*)*args_ast)->args); + if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { + // TODO: PFAs + zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); + } switch ((*ast_ptr)->kind) { case ZEND_AST_CALL: { @@ -11838,7 +12068,7 @@ static void zend_compile_const_expr_fcc(zend_ast **ast_ptr) } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -12130,7 +12360,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: case ZEND_AST_PIPE: zend_compile_var(result, ast, BP_VAR_R, false); return; @@ -12215,6 +12444,9 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_CONST: zend_compile_const(result, ast); return; + case ZEND_AST_CONSTANT: + zend_compile_constant(result, ast); + return; case ZEND_AST_CLASS_CONST: zend_compile_class_const(result, ast); return; @@ -12268,6 +12500,7 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: + case ZEND_AST_PIPE: zend_compile_memoized_expr(result, ast, BP_VAR_W); /* This might not actually produce an opcode, e.g. for expressions evaluated at comptime. */ return NULL; @@ -12287,9 +12520,6 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty case ZEND_AST_CALL: zend_compile_call(result, ast, type); return NULL; - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: - zend_compile_parent_property_hook_call(result, ast, type); - return NULL; case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: zend_compile_method_call(result, ast, type); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5414467f3f87..69d7aeb2f373 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -369,7 +368,7 @@ typedef struct _zend_oparray_context { #define ZEND_ACC_USES_THIS (1 << 17) /* | X | | */ /* | | | */ /* call through user function trampoline. e.g. | | | */ -/* __call, __callstatic | | | */ +/* __call, __callStatic | | | */ #define ZEND_ACC_CALL_VIA_TRAMPOLINE (1 << 18) /* | X | | */ /* | | | */ /* disable inline caching | | | */ @@ -413,10 +412,11 @@ typedef struct _zend_oparray_context { /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ /* | | | */ -/* Function Flags 2 (fn_flags2) (unused: 0-31) | | | */ +/* Function Flags 2 (fn_flags2) (unused: 1-31) | | | */ /* ============================ | | | */ /* | | | */ -/* #define ZEND_ACC2_EXAMPLE (1 << 0) | X | | */ +/* Function forbids dynamic calls | | | */ +#define ZEND_ACC2_FORBID_DYN_CALLS (1 << 0) /* | X | | */ #define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE) #define ZEND_ACC_PPP_SET_MASK (ZEND_ACC_PUBLIC_SET | ZEND_ACC_PROTECTED_SET | ZEND_ACC_PRIVATE_SET) @@ -430,7 +430,7 @@ static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t vi return ZEND_ACC_PROTECTED_SET; case ZEND_ACC_PRIVATE: return ZEND_ACC_PRIVATE_SET; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -481,7 +481,7 @@ typedef struct _zend_property_info { #define OBJ_PROP_NUM(obj, num) \ (&(obj)->properties_table[(num)]) #define OBJ_PROP_TO_OFFSET(num) \ - ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) + ((uint32_t)(offsetof(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ (((offset) - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) #define OBJ_PROP_SLOT_TO_OFFSET(obj, slot) \ @@ -515,6 +515,7 @@ typedef struct _zend_arg_info { zend_string *name; zend_type type; zend_string *default_value; + zend_string *doc_comment; } zend_arg_info; /* the following structure repeats the layout of zend_internal_arg_info, @@ -957,6 +958,7 @@ struct _zend_arena; ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type); ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename, zend_compile_position position); ZEND_API zend_op_array *compile_filename(int type, zend_string *filename); +ZEND_API zend_op_array *zend_compile_ast(zend_ast *ast, int type, zend_string *filename); ZEND_API zend_ast *zend_compile_string_to_ast( zend_string *code, struct _zend_arena **ast_arena, zend_string *filename); ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...); @@ -1118,7 +1120,8 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_THROW_IS_EXPR 1u -#define ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS 1 +#define ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS (1<<0) +#define ZEND_FCALL_USES_VARIADIC_PLACEHOLDER (1<<1) /* The send mode, the is_variadic, the is_promoted, and the is_tentative flags are stored as part of zend_type */ #define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT @@ -1248,10 +1251,18 @@ END_EXTERN_C() #define ZEND_UNSET_FUNC_NAME "__unset" #define ZEND_ISSET_FUNC_NAME "__isset" #define ZEND_CALL_FUNC_NAME "__call" -#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic" -#define ZEND_TOSTRING_FUNC_NAME "__tostring" +#define ZEND_CALLSTATIC_FUNC_NAME "__callStatic" +#define ZEND_CALLSTATIC_FUNC_LCNAME "__callstatic" +#define ZEND_TOSTRING_FUNC_NAME "__toString" +#define ZEND_TOSTRING_FUNC_LCNAME "__tostring" #define ZEND_INVOKE_FUNC_NAME "__invoke" -#define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo" +#define ZEND_DEBUGINFO_FUNC_NAME "__debugInfo" +#define ZEND_DEBUGINFO_FUNC_LCNAME "__debuginfo" +#define ZEND_SLEEP_FUNC_NAME "__sleep" +#define ZEND_WAKEUP_FUNC_NAME "__wakeup" +#define ZEND_SERIALIZE_FUNC_NAME "__serialize" +#define ZEND_UNSERIALIZE_FUNC_NAME "__unserialize" +#define ZEND_SET_STATE_FUNC_NAME "__set_state" /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index a44a8b9f70d2..629d7b4437f2 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index a18c393be7f9..18292203bee9 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -251,7 +250,7 @@ ZEND_API zend_constant *_zend_get_special_const(const char *name, size_t len) /* } /* }}} */ -ZEND_API bool zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ +ZEND_API bool zend_verify_const_access(const zend_class_constant *c, const zend_class_entry *scope) /* {{{ */ { if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_PUBLIC) { return 1; @@ -312,9 +311,9 @@ ZEND_API zval *zend_get_constant(zend_string *name) return NULL; } -ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, zend_class_entry *scope, uint32_t flags) +ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, const zend_class_entry *scope, uint32_t flags) { - zend_class_entry *ce = NULL; + const zend_class_entry *ce = NULL; zend_class_constant *c = NULL; zval *ret_constant = NULL; @@ -413,7 +412,7 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string * return ret_constant; } -ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) +ZEND_API zval *zend_get_constant_ex(zend_string *cname, const zend_class_entry *scope, uint32_t flags) { zend_constant *c; const char *colon; @@ -495,7 +494,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, return &c->value; } -static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c) +static void* zend_hash_add_constant(HashTable *ht, zend_string *key, const zend_constant *c) { void *ret; zend_constant *copy = pemalloc(sizeof(zend_constant), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 6bdb19c4d5af..9461ac764c90 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -85,12 +84,12 @@ void clean_module_constants(int module_number); void free_zend_constant(zval *zv); void zend_startup_constants(void); void zend_register_standard_constants(void); -ZEND_API bool zend_verify_const_access(zend_class_constant *c, zend_class_entry *ce); +ZEND_API bool zend_verify_const_access(const zend_class_constant *c, const zend_class_entry *ce); ZEND_API zval *zend_get_constant(zend_string *name); ZEND_API zend_constant *zend_get_constant_ptr(zend_string *name); ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len); -ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, uint32_t flags); -ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, zend_class_entry *scope, uint32_t flags); +ZEND_API zval *zend_get_constant_ex(zend_string *name, const zend_class_entry *scope, uint32_t flags); +ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, const zend_class_entry *scope, uint32_t flags); ZEND_API zend_constant *zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number); ZEND_API zend_constant *zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number); ZEND_API zend_constant *zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number); diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 9f8f1354be06..6fc42ca39e6c 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Xinchen Hui | +----------------------------------------------------------------------+ diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index 7e53ba654dd4..855e245beafe 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Xinchen Hui | +----------------------------------------------------------------------+ @@ -272,8 +271,11 @@ static zend_always_inline int zend_cpu_supports_avx512_vbmi(void) { } #endif -/* __builtin_cpu_supports has pclmul from gcc9 */ -#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) +/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */ +#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (defined(__x86_64__) || defined(__i386__)) && \ + ( \ + (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000)) \ + ) ZEND_NO_SANITIZE_ADDRESS static inline int zend_cpu_supports_pclmul(void) { #ifdef PHP_HAVE_BUILTIN_CPU_INIT @@ -287,8 +289,13 @@ static inline int zend_cpu_supports_pclmul(void) { } #endif -/* __builtin_cpu_supports has cldemote from gcc11 */ -#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000) +/* __builtin_cpu_supports has cldemote from gcc11 and clang 19 */ +#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (defined(__x86_64__) || defined(__i386__)) && \ + ( \ + (defined(__clang__) && (__clang_major__ >= 19)) || \ + (!defined(__clang__) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000)) \ + ) +#define HAVE_ZEND_CPU_SUPPORTS_CLDEMOTE 1 ZEND_NO_SANITIZE_ADDRESS static inline int zend_cpu_supports_cldemote(void) { #ifdef PHP_HAVE_BUILTIN_CPU_INIT diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 7ab9b8325a39..cc534e04549d 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | | Marcus Boerger | diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c index dfc43a85139b..1052022f3bed 100644 --- a/Zend/zend_dtrace.c +++ b/Zend/zend_dtrace.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_dtrace.d b/Zend/zend_dtrace.d index 6920d0e3602a..9ff085031178 100644 --- a/Zend/zend_dtrace.d +++ b/Zend/zend_dtrace.d @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h index 53ccaca4e407..ada77ce664e3 100644 --- a/Zend/zend_dtrace.h +++ b/Zend/zend_dtrace.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 6e9c68810d4b..ecebe7a5d51b 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ilija Tovilo | +----------------------------------------------------------------------+ @@ -91,24 +90,23 @@ static void zend_verify_enum_properties(const zend_class_entry *ce) static void zend_verify_enum_magic_methods(const zend_class_entry *ce) { - // Only __get, __call and __invoke are allowed - - ZEND_ENUM_DISALLOW_MAGIC_METHOD(constructor, "__construct"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(destructor, "__destruct"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(clone, "__clone"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__get, "__get"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__set, "__set"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unset, "__unset"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__isset, "__isset"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__tostring, "__toString"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__debugInfo, "__debugInfo"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__serialize, "__serialize"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unserialize, "__unserialize"); + // Only __get, __call, __debugInfo and __invoke are allowed + + ZEND_ENUM_DISALLOW_MAGIC_METHOD(constructor, ZEND_CONSTRUCTOR_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(destructor, ZEND_DESTRUCTOR_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(clone, ZEND_CLONE_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__get, ZEND_GET_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__set, ZEND_SET_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unset, ZEND_UNSET_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__isset, ZEND_ISSET_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__tostring, ZEND_TOSTRING_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__serialize, ZEND_SERIALIZE_FUNC_NAME); + ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unserialize, ZEND_UNSERIALIZE_FUNC_NAME); static const char *const forbidden_methods[] = { - "__sleep", - "__wakeup", - "__set_state", + ZEND_SLEEP_FUNC_NAME, + ZEND_WAKEUP_FUNC_NAME, + ZEND_SET_STATE_FUNC_NAME, }; uint32_t forbidden_methods_length = sizeof(forbidden_methods) / sizeof(forbidden_methods[0]); @@ -177,7 +175,7 @@ void zend_register_enum_ce(void) zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum; memcpy(&zend_enum_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - zend_enum_object_handlers.offset = XtOffsetOf(zend_enum_obj, std); + zend_enum_object_handlers.offset = offsetof(zend_enum_obj, std); zend_enum_object_handlers.clone_obj = NULL; zend_enum_object_handlers.compare = zend_objects_not_comparable; } @@ -675,6 +673,11 @@ ZEND_API zend_object *zend_enum_get_case_cstr(zend_class_entry *ce, const char * return zend_enum_case_from_class_constant(c); } +ZEND_API zend_object *zend_enum_get_case_by_id(zend_class_entry *ce, int id) { + zend_class_constant *c = Z_PTR(CE_CONSTANTS_TABLE(ce)->arData[id - 1].val); + return zend_enum_case_from_class_constant(c); +} + void zend_enum_startup(void) { for (size_t i = 0; i < sizeof(zarginfo_class_UnitEnum_cases)/sizeof(zend_arg_info); i++) { diff --git a/Zend/zend_enum.h b/Zend/zend_enum.h index 4d0799e4f0ac..f252c938eb83 100644 --- a/Zend/zend_enum.h +++ b/Zend/zend_enum.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ilija Tovilo | +----------------------------------------------------------------------+ @@ -37,7 +36,7 @@ typedef struct zend_enum_obj { static inline zend_enum_obj *zend_enum_obj_from_obj(zend_object *zobj) { ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM); - return (zend_enum_obj*)((char*)(zobj) - XtOffsetOf(zend_enum_obj, std)); + return ZEND_CONTAINER_OF(zobj, zend_enum_obj, std); } void zend_enum_startup(void); @@ -56,6 +55,7 @@ ZEND_API void zend_enum_add_case(zend_class_entry *ce, zend_string *case_name, z ZEND_API void zend_enum_add_case_cstr(zend_class_entry *ce, const char *name, zval *value); ZEND_API zend_object *zend_enum_get_case(zend_class_entry *ce, zend_string *name); ZEND_API zend_object *zend_enum_get_case_cstr(zend_class_entry *ce, const char *name); +ZEND_API zend_object *zend_enum_get_case_by_id(zend_class_entry *ce, int id); ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_class_entry *ce, zend_long long_key, zend_string *string_key, bool try_from); static zend_always_inline int zend_enum_fetch_case_id(zend_object *zobj) diff --git a/Zend/zend_errors.h b/Zend/zend_errors.h index 954be61a0aec..831e4a9b912a 100644 --- a/Zend/zend_errors.h +++ b/Zend/zend_errors.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 52e3ab009254..ca91ec0ce12b 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Marcus Boerger | @@ -497,17 +496,17 @@ ZEND_METHOD(ErrorException, getSeverity) #define TRACE_APPEND_KEY(key) do { \ tmp = zend_hash_find(ht, key); \ if (tmp) { \ - if (Z_TYPE_P(tmp) != IS_STRING) { \ + if (UNEXPECTED(Z_TYPE_P(tmp) != IS_STRING)) { \ zend_error(E_WARNING, "Value for %s is not a string", \ ZSTR_VAL(key)); \ smart_str_appends(str, "[unknown]"); \ } else { \ - smart_str_appends(str, Z_STRVAL_P(tmp)); \ + smart_str_append(str, Z_STR_P(tmp)); \ } \ } \ } while (0) -static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ +static void build_trace_args(zval *arg, smart_str *str) /* {{{ */ { /* the trivial way would be to do * convert_to_string(arg); @@ -517,23 +516,21 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ ZVAL_DEREF(arg); - if (smart_str_append_zval(str, arg, EG(exception_string_param_max_len)) == SUCCESS) { - smart_str_appends(str, ", "); - } else { + if (smart_str_append_zval(str, arg, EG(exception_string_param_max_len)) != SUCCESS) { switch (Z_TYPE_P(arg)) { case IS_RESOURCE: smart_str_appends(str, "Resource id #"); smart_str_append_long(str, Z_RES_HANDLE_P(arg)); - smart_str_appends(str, ", "); break; case IS_ARRAY: - smart_str_appends(str, "Array, "); + smart_str_appends(str, "Array"); break; case IS_OBJECT: { zend_string *class_name = Z_OBJ_HANDLER_P(arg, get_class_name)(Z_OBJ_P(arg)); smart_str_appends(str, "Object("); + /* cut off on NULL byte ... class@anonymous */ smart_str_appends(str, ZSTR_VAL(class_name)); - smart_str_appends(str, "), "); + smart_str_appends(str, ")"); zend_string_release_ex(class_name, 0); break; } @@ -542,7 +539,30 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ } /* }}} */ -static void _build_trace_string(smart_str *str, const HashTable *ht, uint32_t num) /* {{{ */ +static void build_trace_args_list(zval *tmp, smart_str *str) /* {{{ */ +{ + if (UNEXPECTED(Z_TYPE_P(tmp) != IS_ARRAY)) { + /* only happens w/ reflection abuse (Zend/tests/bug63762.phpt) */ + zend_error(E_WARNING, "args element is not an array"); + return; + } + + bool first = true; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), zend_string *name, zval *arg) { + if (!first) { + smart_str_appends(str, ", "); + } + first = false; + if (name) { + smart_str_append(str, name); + smart_str_appends(str, ": "); + } + build_trace_args(arg, str); + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + +static void build_trace_string(smart_str *str, const HashTable *ht, uint32_t num) /* {{{ */ { zval *file, *tmp; @@ -573,33 +593,68 @@ static void _build_trace_string(smart_str *str, const HashTable *ht, uint32_t nu } else { smart_str_appends(str, "[internal function]: "); } - TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_CLASS)); + const zval *class_name = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_CLASS)); + if (class_name) { + if (UNEXPECTED(Z_TYPE_P(class_name) != IS_STRING)) { + zend_error(E_WARNING, "Value for class is not a string"); + smart_str_appends(str, "[unknown]"); + } else { + /* cut off on NULL byte ... class@anonymous */ + smart_str_appends(str, Z_STRVAL_P(class_name)); + } + } TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_TYPE)); TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_FUNCTION)); smart_str_appendc(str, '('); tmp = zend_hash_find_known_hash(ht, ZSTR_KNOWN(ZEND_STR_ARGS)); if (tmp) { - if (EXPECTED(Z_TYPE_P(tmp) == IS_ARRAY)) { - size_t last_len = ZSTR_LEN(str->s); - zend_string *name; - zval *arg; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), name, arg) { - if (name) { - smart_str_append(str, name); - smart_str_appends(str, ": "); - } - _build_trace_args(arg, str); - } ZEND_HASH_FOREACH_END(); + build_trace_args_list(tmp, str); + } + smart_str_appends(str, ")\n"); +} +/* }}} */ - if (last_len != ZSTR_LEN(str->s)) { - ZSTR_LEN(str->s) -= 2; /* remove last ', ' */ - } - } else { - zend_error(E_WARNING, "args element is not an array"); +/* {{{ Gets the function arguments printed as a string from a backtrace frame. */ +ZEND_API zend_string *zend_trace_function_args_to_string(const HashTable *frame) { + smart_str str = {0}; + + zval *tmp = zend_hash_find_known_hash(frame, ZSTR_KNOWN(ZEND_STR_ARGS)); + if (tmp) { + build_trace_args_list(tmp, &str); + } + + return smart_str_extract(&str); +} +/* }}} */ + +/* {{{ Gets the currently executing function's arguments as a string. Used by php_verror. */ +ZEND_API zend_string *zend_trace_current_function_args_string(void) { + zend_string *dynamic_params = NULL; + /* Special case: require_once/include_once aren't functions, but we + * want to capture their arguments anyways, for i.e. file not found. + */ + zend_execute_data *execute_data = EG(current_execute_data); + if (execute_data && execute_data->func + && ZEND_USER_CODE(execute_data->func->common.type) + && (execute_data->opline->opcode == ZEND_INCLUDE_OR_EVAL)) { + zval *inc_filename = RT_CONSTANT(execute_data->opline, execute_data->opline->op1); + smart_str str = {0}; + build_trace_args(inc_filename, &str); + return smart_str_extract(&str); + } + + /* get a backtrace to snarf function args */ + zval backtrace; + zend_fetch_debug_backtrace(&backtrace, /* skip_last */ 0, /* options */ 0, /* limit */ 1); + /* can fail esp if low memory condition */ + if (Z_TYPE(backtrace) == IS_ARRAY) { + zval *first_frame = zend_hash_index_find(Z_ARRVAL(backtrace), 0); + if (first_frame) { + dynamic_params = zend_trace_function_args_to_string(Z_ARRVAL_P(first_frame)); } } - smart_str_appends(str, ")\n"); + zval_ptr_dtor(&backtrace); + return dynamic_params; } /* }}} */ @@ -615,7 +670,7 @@ ZEND_API zend_string *zend_trace_to_string(const HashTable *trace, bool include_ continue; } - _build_trace_string(&str, Z_ARRVAL_P(frame), num++); + build_trace_string(&str, Z_ARRVAL_P(frame), num++); } ZEND_HASH_FOREACH_END(); if (include_main) { diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index e5a6be2f32fe..7ef9ef016393 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Marcus Boerger | @@ -66,6 +65,8 @@ ZEND_API zend_result zend_update_exception_properties(zend_execute_data *execute /* show an exception using zend_error(severity,...), severity should be E_ERROR */ ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *exception, int severity); ZEND_NORETURN void zend_exception_uncaught_error(const char *prefix, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2); +ZEND_API zend_string *zend_trace_function_args_to_string(const HashTable *frame); +ZEND_API zend_string *zend_trace_current_function_args_string(void); ZEND_API zend_string *zend_trace_to_string(const HashTable *trace, bool include_main); ZEND_API ZEND_COLD zend_object *zend_create_unwind_exit(void); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 37278c5cb9a2..f5b70d74aa61 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -605,7 +604,7 @@ static zend_never_inline ZEND_COLD zval *zend_wrong_assign_to_variable_reference return zend_assign_to_variable_ex(variable_ptr, value_ptr, IS_TMP_VAR, EX_USES_STRICT_TYPES(), garbage_ptr); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) { const zend_execute_data *execute_data = EG(current_execute_data); zend_string *func_name = get_function_or_method_name(EX(call)->func); @@ -647,7 +646,7 @@ static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_err } /* this should modify object only if it's empty */ -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, const zval *property OPLINE_DC EXECUTE_DATA_DC) { zend_string *tmp_property_name; zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); @@ -681,7 +680,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_erro } } -static ZEND_COLD void zend_verify_type_error_common( +static zend_never_inline ZEND_COLD void zend_verify_type_error_common( const zend_function *zf, const zend_arg_info *arg_info, const zval *value, const char **fname, const char **fsep, const char **fclass, zend_string **need_msg, const char **given_kind) @@ -704,7 +703,7 @@ static ZEND_COLD void zend_verify_type_error_common( } } -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value) { const zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; @@ -734,8 +733,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg) { zend_long lval; double dval; - zend_string *str; - bool bval; /* Type preference order: int -> float -> string -> bool */ if (type_mask & MAY_BE_LONG) { @@ -761,16 +758,23 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg) return false; } } - if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) { - zval_ptr_dtor(arg); - ZVAL_DOUBLE(arg, dval); - return true; + if (type_mask & MAY_BE_DOUBLE) { + dval = zend_parse_arg_double_weak(arg, 0); + if (EXPECTED(!zend_isnan(dval))) { + zval_ptr_dtor(arg); + ZVAL_DOUBLE(arg, dval); + return true; + } } - if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) { + if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) { /* on success "arg" is converted to IS_STRING */ return true; } - if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) { + if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) { + zpp_parse_bool_status bval = zend_parse_arg_bool_weak(arg, 0); + if (UNEXPECTED(bval == ZPP_PARSE_BOOL_STATUS_ERROR)) { + return false; + } zval_ptr_dtor(arg); ZVAL_BOOL(arg, bval); return true; @@ -794,21 +798,19 @@ static bool can_convert_to_string(const zval *zv) { static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg) { zend_long lval; - double dval; - bool bval; /* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice, * this is needed because the version with side effects also uses 0 (e.g. for typed properties) */ if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval, (uint32_t)-1)) { return true; } - if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, (uint32_t)-1)) { + if ((type_mask & MAY_BE_DOUBLE) && !zend_isnan(zend_parse_arg_double_weak(arg, (uint32_t)-1))) { return true; } if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) { return true; } - if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, (uint32_t)-1)) { + if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, (uint32_t)-1) != ZPP_PARSE_BOOL_STATUS_ERROR) { return true; } return false; @@ -836,7 +838,7 @@ ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool s return zend_verify_weak_scalar_type_hint(type_mask, arg); } -ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) +static zend_never_inline ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) { zend_string *type_str = zend_type_to_string(c->type); @@ -846,7 +848,7 @@ ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zen zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property) { zend_string *type_str; @@ -864,7 +866,7 @@ ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_prop zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) { /* we _may_ land here in case reading already errored and runtime cache thus has not been updated (i.e. it contains a valid but unrelated info) */ if (EG(exception)) { @@ -881,7 +883,7 @@ ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_erro zend_string_release(type_str); } -ZEND_COLD void zend_match_unhandled_error(const zval *value) +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value) { zend_long max_len = EG(exception_string_param_max_len); smart_str msg = {0}; @@ -901,35 +903,35 @@ ZEND_COLD void zend_match_unhandled_error(const zval *value) smart_str_free(&msg); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( const zend_property_info *info) { zend_readonly_property_modification_error_ex( ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( const char *class_name, const char *prop_name) { zend_throw_error(NULL, "Cannot modify readonly property %s::$%s", class_name, prop_name); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) { zend_throw_error(NULL, "Cannot indirectly modify readonly property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) { zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(type)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) { zend_throw_error(NULL, "Object was released while assigning to property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( const zend_property_info *prop_info, const char *operation ) { const zend_class_entry *scope; @@ -1151,7 +1153,7 @@ static bool zend_check_intersection_type_from_list( static zend_always_inline bool zend_check_type_slow( const zend_type *type, zval *arg, const zend_reference *ref, - bool is_return_type, bool is_internal) + bool current_frame, bool is_internal) { if (ZEND_TYPE_IS_COMPLEX(*type) && EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) { zend_class_entry *ce; @@ -1197,7 +1199,7 @@ static zend_always_inline bool zend_check_type_slow( /* We cannot have conversions for typed refs. */ return 0; } - if (is_internal && is_return_type) { + if (is_internal && current_frame) { /* For internal returns, the type has to match exactly, because we're not * going to check it for non-debug builds, and there will be no chance to * apply coercions. */ @@ -1205,7 +1207,7 @@ static zend_always_inline bool zend_check_type_slow( } return zend_verify_scalar_type_hint(type_mask, arg, - is_return_type ? ZEND_RET_USES_STRICT_TYPES() : ZEND_ARG_USES_STRICT_TYPES(), + current_frame ? ZEND_RET_USES_STRICT_TYPES() : ZEND_ARG_USES_STRICT_TYPES(), is_internal); /* Special handling for IS_VOID is not necessary (for return types), @@ -1213,7 +1215,7 @@ static zend_always_inline bool zend_check_type_slow( } static zend_always_inline bool zend_check_type( - const zend_type *type, zval *arg, bool is_return_type, bool is_internal) + const zend_type *type, zval *arg, bool current_frame, bool is_internal) { const zend_reference *ref = NULL; ZEND_ASSERT(ZEND_TYPE_IS_SET(*type)); @@ -1227,14 +1229,21 @@ static zend_always_inline bool zend_check_type( return 1; } - return zend_check_type_slow(type, arg, ref, is_return_type, is_internal); + return zend_check_type_slow(type, arg, ref, current_frame, is_internal); +} + +/* We can not expose zend_check_type() directly because it's inline and uses static functions */ +ZEND_API bool zend_check_type_ex( + const zend_type *type, zval *arg, bool current_frame, bool is_internal) +{ + return zend_check_type(type, arg, current_frame, is_internal); } ZEND_API bool zend_check_user_type_slow( - const zend_type *type, zval *arg, const zend_reference *ref, bool is_return_type) + const zend_type *type, zval *arg, const zend_reference *ref, bool current_frame) { return zend_check_type_slow( - type, arg, ref, is_return_type, /* is_internal */ false); + type, arg, ref, current_frame, /* is_internal */ false); } static zend_always_inline bool zend_verify_recv_arg_type(const zend_function *zf, uint32_t arg_num, zval *arg) @@ -1322,7 +1331,7 @@ ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_exe return 0; } -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) { zend_error_noreturn(E_ERROR, "Arginfo / zpp mismatch during call of %s%s%s()", fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", @@ -1393,7 +1402,7 @@ static void zend_verify_internal_func_info(const zend_function *fn, const zval * } #endif -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) { const zend_execute_data *ptr = EX(prev_execute_data); @@ -1418,7 +1427,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_ } } -ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1434,7 +1443,7 @@ ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zend_string_release(need_msg); } -ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error(const zend_function *zf) { zend_string *func_name = get_function_or_method_name(zf); @@ -1445,7 +1454,7 @@ ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) } #if ZEND_DEBUG -static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) +static zend_never_inline ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1459,7 +1468,7 @@ static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, fclass, fsep, fname, ZSTR_VAL(need_msg), given_msg); } -static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) +static zend_never_inline ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) { const char *fname = ZSTR_VAL(zf->common.function_name); const char *fsep; @@ -1498,7 +1507,7 @@ ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *re } #endif -static ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) +static zend_never_inline ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) { /* VERIFY_RETURN_TYPE is not emitted for "void" functions, so this is always an error. */ zend_verify_return_error(zf, NULL); @@ -1710,7 +1719,7 @@ static zend_never_inline void zend_binary_assign_op_typed_prop(const zend_proper } } -static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type EXECUTE_DATA_DC) +static zend_never_inline zend_long zend_check_string_offset(const zval *dim, int type EXECUTE_DATA_DC) { zend_long offset; @@ -1755,7 +1764,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type return zval_get_long_func(dim, /* is_strict */ false); } -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void) +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void) { const char *msg = NULL; const zend_execute_data *execute_data = EG(current_execute_data); @@ -1789,10 +1798,10 @@ ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void) case ZEND_FETCH_DIM_INCDEC: msg = "Cannot increment/decrement string offsets"; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } ZEND_ASSERT(msg != NULL); zend_throw_error(NULL, "%s", msg); @@ -2185,7 +2194,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re return NULL; } -static ZEND_COLD zend_long zend_throw_incdec_ref_error(zend_property_info *error_prop OPLINE_DC) +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_ref_error(const zend_property_info *error_prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(error_prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2207,7 +2216,7 @@ static ZEND_COLD zend_long zend_throw_incdec_ref_error(zend_property_info *error } } -static ZEND_COLD zend_long zend_throw_incdec_prop_error(zend_property_info *prop OPLINE_DC) { +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_prop_error(const zend_property_info *prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { zend_type_error("Cannot increment property %s::$%s of type %s past its maximal value", @@ -2258,7 +2267,7 @@ static void zend_incdec_typed_ref(zend_reference *ref, zval *copy OPLINE_DC EXEC } } -static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) +static void zend_incdec_typed_prop(const zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) { zval tmp; @@ -2288,7 +2297,7 @@ static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, } } -static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_pre_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2326,7 +2335,7 @@ static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_i } } -static void zend_post_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_post_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(prop)); @@ -2554,13 +2563,13 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(co zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method)); } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(zval *object, zval *function_name) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(const zval *object, const zval *function_name) { zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_zval_value_name(object)); } -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) { zend_throw_error( zend_ce_error, @@ -2618,7 +2627,7 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_err } #endif /* ZEND_CHECK_STACK_LIMIT */ -static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static ZEND_COLD void zend_binary_assign_op_dim_slow(const zval *container, const zval *dim OPLINE_DC EXECUTE_DATA_DC) { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (opline->op2_type == IS_UNUSED) { @@ -3052,7 +3061,7 @@ static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_UNSET(z zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET EXECUTE_DATA_CC); } -static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, bool is_list, bool slow EXECUTE_DATA_DC) +static zend_always_inline void zend_fetch_dimension_address_read(zval *result, const zval *container, zval *dim, int dim_type, int type, bool is_list, bool slow EXECUTE_DATA_DC) { zval *retval; @@ -3206,36 +3215,36 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_fetch_dimension_address_read_R_slow(const zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 0, 1 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0 EXECUTE_DATA_CC); } -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type) +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type) { zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0 NO_EXECUTE_DATA_CC); } -static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, zval *offset EXECUTE_DATA_DC) +static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, const zval *offset EXECUTE_DATA_DC) { zend_ulong hval; @@ -3290,7 +3299,7 @@ static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable } } -static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3329,7 +3338,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, } } -static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3368,7 +3377,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *containe } } -static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, const zval *key OPLINE_DC EXECUTE_DATA_DC) { zend_string *str; zend_ulong hval; @@ -3426,8 +3435,8 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable } } -static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( - zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( + const zval *subject, const zval *key OPLINE_DC EXECUTE_DATA_DC) { if (Z_TYPE_P(key) == IS_UNDEF) { ZVAL_UNDEFINED_OP1(); @@ -3441,7 +3450,7 @@ static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( } } -static zend_always_inline bool promotes_to_array(zval *val) { +static zend_always_inline bool promotes_to_array(const zval *val) { return Z_TYPE_P(val) <= IS_FALSE || (Z_ISREF_P(val) && Z_TYPE_P(Z_REFVAL_P(val)) <= IS_FALSE); } @@ -3500,13 +3509,23 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(ptr), prop_info); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 1; } -static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, zend_property_info **prop_info_p OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_fetch_property_address( + zval *result, + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + void **cache_slot, + int type, + uint32_t flags, + zend_property_info **prop_info_p + OPLINE_DC EXECUTE_DATA_DC +) { zval *ptr; zend_object *zobj; zend_string *name, *tmp_name; @@ -3651,8 +3670,14 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } -static zend_always_inline void zend_assign_to_property_reference(zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_assign_to_property_reference( + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + zval *value_ptr + OPLINE_DC EXECUTE_DATA_DC +) { zval variable, *variable_ptr = &variable; void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL; zend_refcounted *garbage = NULL; @@ -3690,25 +3715,25 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container } } -static zend_never_inline void zend_assign_to_property_reference_this_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_this_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); @@ -3879,7 +3904,7 @@ ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, i return result; } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Reference with value of type %s held by property %s::$%s of type %s is not compatible with property %s::$%s of type %s", @@ -3895,7 +3920,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info zend_string_release(type2_str); } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s", zend_zval_value_name(zv), @@ -3906,7 +3931,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info zend_string_release(type_str); } -ZEND_API ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +static zend_never_inline ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s and property %s::$%s of type %s, as this would result in an inconsistent type conversion", @@ -4220,7 +4245,7 @@ static zend_never_inline void zend_fetch_this_var(int type OPLINE_DC EXECUTE_DAT ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -4309,8 +4334,15 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *ca } \ } while (0) +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +# define ZEND_VM_KIND_TAILCALL_SAVE_OPLINE() SAVE_OPLINE() +#else +# define ZEND_VM_KIND_TAILCALL_SAVE_OPLINE() +#endif + #define ZEND_VM_LOOP_INTERRUPT_CHECK() do { \ if (UNEXPECTED(zend_atomic_bool_load_ex(&EG(vm_interrupt)))) { \ + ZEND_VM_KIND_TAILCALL_SAVE_OPLINE(); \ ZEND_VM_LOOP_INTERRUPT(); \ } \ } while (0) @@ -4481,7 +4513,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len) /* {{{ */ { - zval *zv = zend_hash_str_find(EG(function_table), name, len); + const zval *zv = zend_hash_str_find(EG(function_table), name, len); if (EXPECTED(zv != NULL)) { zend_function *fbc = Z_FUNC_P(zv); @@ -4651,6 +4683,7 @@ ZEND_API void zend_unfinished_calls_gc(zend_execute_data *execute_data, zend_exe case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: level++; break; case ZEND_INIT_FCALL: @@ -4707,6 +4740,7 @@ ZEND_API void zend_unfinished_calls_gc(zend_execute_data *execute_data, zend_exe case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: level++; break; case ZEND_INIT_FCALL: @@ -4787,6 +4821,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: level++; break; case ZEND_INIT_FCALL: @@ -4844,6 +4879,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: level++; break; case ZEND_INIT_FCALL: @@ -4890,9 +4926,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) /* {{{ */ { - int i; - - for (i = 0; i < EX(func)->op_array.last_live_range; i++) { + for (uint32_t i = 0; i < EX(func)->op_array.last_live_range; i++) { const zend_live_range *range = &EX(func)->op_array.live_range[i]; if (range->start > op_num) { /* further blocks will not be relevant... */ @@ -4905,7 +4939,7 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, /* Handle the split range for loop vars */ if (catch_op_num) { - zend_op *final_op = EX(func)->op_array.opcodes + range->end; + const zend_op *final_op = EX(func)->op_array.opcodes + range->end; if (final_op->extended_value & ZEND_FREE_ON_RETURN && (final_op->opcode == ZEND_FE_FREE || final_op->opcode == ZEND_FREE)) { if (catch_op_num < range->end + final_op->op2.num) { continue; @@ -5193,7 +5227,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o } /* }}} */ -static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_array *function, uint32_t num_args) /* {{{ */ +static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(const zend_array *function, uint32_t num_args) /* {{{ */ { zend_function *fbc; void *object_or_called_scope; @@ -5284,7 +5318,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar #define ZEND_FAKE_OP_ARRAY ((zend_op_array*)(intptr_t)-1) -static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval *inc_filename_zv, int type) /* {{{ */ +static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(const zval *inc_filename_zv, int type) /* {{{ */ { zend_op_array *new_op_array = NULL; zend_string *tmp_inc_filename; @@ -5357,7 +5391,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval efree(eval_desc); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } zend_tmp_string_release(tmp_inc_filename); @@ -5555,9 +5589,10 @@ zval * ZEND_FASTCALL zend_handle_named_arg( } } else { arg = ZEND_CALL_VAR_NUM(call, arg_offset); + if (UNEXPECTED(!Z_ISUNDEF_P(arg))) { - zend_throw_error(NULL, "Named parameter $%s overwrites previous argument", - ZSTR_VAL(arg_name)); + zend_throw_error(NULL, "Named parameter $%s overwrites previous %s", + ZSTR_VAL(arg_name), Z_TYPE_P(arg) == _IS_PLACEHOLDER ? "placeholder" : "argument"); return NULL; } } diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 89a9e79143a8..eb73b3f3de9e 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -61,7 +60,7 @@ ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval /* export zend_pass_function to allow comparisons against it */ extern ZEND_API const zend_internal_function zend_pass_function; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_nodiscard_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name); @@ -81,39 +80,41 @@ typedef enum { ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref_ex(const zend_property_info *prop_info, zval *orig_val, bool strict, zend_verify_prop_assignable_by_ref_context context); ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(const zend_property_info *prop_info, zval *orig_val, bool strict); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset); -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void); +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value); -ZEND_API ZEND_COLD void zend_verify_return_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error( const zend_function *zf, const zval *value); -ZEND_API ZEND_COLD void zend_verify_never_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error( const zend_function *zf); ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref); ZEND_API bool zend_check_user_type_slow( - const zend_type *type, zval *arg, const zend_reference *ref, bool is_return_type); + const zend_type *type, zval *arg, const zend_reference *ref, bool current_frame); +ZEND_API bool zend_check_type_ex( + const zend_type *type, zval *arg, bool current_frame, bool is_internal); #if ZEND_DEBUG ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_execute_data *call); -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret); #endif @@ -135,7 +136,7 @@ ZEND_API void ZEND_FASTCALL zend_ref_del_type_source(zend_property_info_source_l ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, uint8_t value_type, bool strict); ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *value, uint8_t value_type, bool strict, zend_refcounted **garbage_ptr); -static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *value, uint8_t value_type) +static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, const zval *value, uint8_t value_type) { zend_refcounted *ref = NULL; @@ -211,7 +212,7 @@ static zend_always_inline zval* zend_assign_to_variable_ex(zval *variable_ptr, z return variable_ptr; } -static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, zval *value) { +static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, const zval *value) { if (Z_REFCOUNTED_P(variable_ptr)) { ZEND_ASSERT(Z_TYPE_P(variable_ptr) != IS_REFERENCE); zend_refcounted *ref = Z_COUNTED_P(variable_ptr); @@ -248,7 +249,7 @@ static zend_always_inline void zend_cast_zval_to_object(zval *result, zval *expr } static zend_always_inline void zend_cast_zval_to_array(zval *result, zval *expr, uint8_t op1_type) { - extern zend_class_entry *zend_ce_closure; + extern ZEND_API zend_class_entry *zend_ce_closure; if (op1_type == IS_CONST || Z_TYPE_P(expr) != IS_OBJECT || Z_OBJCE_P(expr) == zend_ce_closure) { if (Z_TYPE_P(expr) != IS_NULL) { if (UNEXPECTED(Z_TYPE_P(expr) == IS_DOUBLE && zend_isnan(Z_DVAL_P(expr)))) { @@ -472,7 +473,7 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void); ZEND_API uint32_t zend_get_executed_lineno(void); ZEND_API zend_class_entry *zend_get_executed_scope(void); ZEND_API bool zend_is_executing(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); ZEND_API void zend_set_timeout(zend_long seconds, bool reset_signals); ZEND_API void zend_unset_timeout(void); @@ -485,7 +486,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len); ZEND_API void ZEND_FASTCALL zend_init_func_run_time_cache(zend_op_array *op_array); -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type); +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type); ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var); @@ -512,7 +513,7 @@ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield); ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, int fetch_type); ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method); -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); ZEND_API void zend_frameless_observed_call(zend_execute_data *execute_data); @@ -586,11 +587,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal ZEND_API bool zend_verify_class_constant_type(const zend_class_constant *c, const zend_string *name, zval *constant); -ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant); ZEND_API bool zend_verify_property_type(const zend_property_info *info, zval *property, bool strict); -ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property); -ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property); #define ZEND_REF_ADD_TYPE_SOURCE(ref, source) \ zend_ref_add_type_source(&ZEND_REF_TYPE_SOURCES(ref), source) @@ -619,7 +617,7 @@ ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_prope } \ } while (0) -ZEND_COLD void zend_match_unhandled_error(const zval *value); +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value); /* Call this to handle the timeout or the interrupt function. It will set * EG(vm_interrupt) to false. diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dbd2a9039cfc..88b0a485750a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -39,6 +38,7 @@ #include "zend_observer.h" #include "zend_call_stack.h" #include "zend_frameless_function.h" +#include "zend_partial.h" #ifdef HAVE_SYS_TIME_H #include #endif @@ -192,8 +192,7 @@ void init_executor(void) /* {{{ */ EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL; EG(record_errors) = false; - EG(num_errors) = 0; - EG(errors) = NULL; + memset(&EG(errors), 0, sizeof(EG(errors))); EG(filename_override) = NULL; EG(lineno_override) = -1; @@ -203,6 +202,7 @@ void init_executor(void) /* {{{ */ zend_weakrefs_init(); zend_hash_init(&EG(callable_convert_cache), 8, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(&EG(partial_function_application_cache), 8, NULL, zend_partial_op_array_dtor, 0); EG(active) = 1; } @@ -420,6 +420,7 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1); zend_hash_clean(&EG(callable_convert_cache)); + zend_hash_clean(&EG(partial_function_application_cache)); #if ZEND_DEBUG if (!CG(unclean_shutdown)) { @@ -516,6 +517,7 @@ void shutdown_executor(void) /* {{{ */ } zend_hash_destroy(&EG(callable_convert_cache)); + zend_hash_destroy(&EG(partial_function_application_cache)); } #if ZEND_DEBUG @@ -797,6 +799,7 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re fci.param_count = param_count; fci.params = params; fci.named_params = named_params; + fci.consumed_args = 0; return zend_call_function(&fci, NULL); } @@ -862,8 +865,19 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ } } +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + zend_call_stack_size_error(); + zend_release_fcall_info_cache(fci_cache); + return SUCCESS; + } +#endif + call = zend_vm_stack_push_call_frame(call_info, func, fci->param_count, object_or_called_scope); + uint32_t consumed_args = fci->param_count ? fci->consumed_args : 0; + + ZEND_ASSERT((consumed_args & (consumed_args - 1)) == 0); for (uint32_t i = 0; i < fci->param_count; i++) { zval *param = ZEND_CALL_ARG(call, i+1); @@ -905,7 +919,15 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ } if (EXPECTED(!must_wrap)) { - ZVAL_COPY(param, arg); + if (EXPECTED(consumed_args == 0) + || !zend_fci_is_consumed_arg(consumed_args, i) + || Z_ISREF_P(arg) + || arg != &fci->params[i]) { + ZVAL_COPY(param, arg); + } else { + ZVAL_COPY_VALUE(param, arg); + ZVAL_UNDEF(arg); + } } else { Z_TRY_ADDREF_P(arg); ZVAL_NEW_REF(param, arg); @@ -1026,10 +1048,13 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ if (should_throw) { zend_internal_call_arginfo_violation(call->func); } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, fci->retval)); + if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + bool result = zend_verify_internal_return_type(call->func, fci->retval); + ZEND_ASSERT(result); + } ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval)); + ZEND_ASSERT(!(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS)); } #endif ZEND_OBSERVER_FCALL_END(call, fci->retval); @@ -1091,6 +1116,7 @@ ZEND_API void zend_call_known_function( fci.param_count = param_count; fci.params = params; fci.named_params = named_params; + fci.consumed_args = 0; ZVAL_UNDEF(&fci.function_name); /* Unused */ fcic.function_handler = fn; @@ -1207,7 +1233,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * ALLOC_HASHTABLE(CG(unlinked_uses)); zend_hash_init(CG(unlinked_uses), 0, NULL, NULL, 0); } - zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_long)(uintptr_t)ce); + zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_ulong)(uintptr_t)ce); return ce; } return NULL; @@ -1765,7 +1791,7 @@ zend_class_entry *zend_fetch_class_with_scope( case 0: break; /* Other fetch types are not supported by this function. */ - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } ce = zend_lookup_class_ex(class_name, NULL, fetch_type); diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index a4e5a38f90d8..4459c3015d15 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 4de8ad5414c2..1e6887e444a6 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index d571a622e476..c91436050856 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | | Martin Schröder | @@ -572,9 +571,9 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer) zend_fiber *fiber = EG(active_fiber); /* Determine the current error_reporting ini setting. */ - zend_long error_reporting = INI_INT("error_reporting"); - /* If error_reporting is 0 and not explicitly set to 0, INI_STR returns a null pointer. */ - if (!error_reporting && !INI_STR("error_reporting")) { + zend_long error_reporting = zend_ini_long_literal("error_reporting"); + /* If error_reporting is 0 and not explicitly set to 0, zend_ini_str returns a null pointer. */ + if (!error_reporting && !zend_ini_str_literal("error_reporting")) { error_reporting = E_ALL; } diff --git a/Zend/zend_fibers.h b/Zend/zend_fibers.h index 9442019bfa25..c72ffdc8f18e 100644 --- a/Zend/zend_fibers.h +++ b/Zend/zend_fibers.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | | Martin Schröder | @@ -155,7 +154,7 @@ static zend_always_inline zend_fiber *zend_fiber_from_context(zend_fiber_context { ZEND_ASSERT(context->kind == zend_ce_fiber && "Fiber context does not belong to a Zend fiber"); - return (zend_fiber *)(((char *) context) - XtOffsetOf(zend_fiber, context)); + return ZEND_CONTAINER_OF(context, zend_fiber, context); } static zend_always_inline zend_fiber_context *zend_fiber_get_context(zend_fiber *fiber) diff --git a/Zend/zend_float.c b/Zend/zend_float.c index 90af0c4a5f90..12fd0fd74f7f 100644 --- a/Zend/zend_float.c +++ b/Zend/zend_float.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | +----------------------------------------------------------------------+ diff --git a/Zend/zend_float.h b/Zend/zend_float.h index 63e0f6f7f69b..12aa02005c2a 100644 --- a/Zend/zend_float.h +++ b/Zend/zend_float.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | +----------------------------------------------------------------------+ diff --git a/Zend/zend_frameless_function.c b/Zend/zend_frameless_function.c index 7ccda0cfb570..be390744fd92 100644 --- a/Zend/zend_frameless_function.c +++ b/Zend/zend_frameless_function.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/Zend/zend_frameless_function.h b/Zend/zend_frameless_function.h index d64ca7ee15e2..b6f361f104b0 100644 --- a/Zend/zend_frameless_function.h +++ b/Zend/zend_frameless_function.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -65,7 +64,7 @@ dest_ht = NULL; \ ZVAL_COPY(&str_tmp, arg ## arg_num); \ arg ## arg_num = &str_tmp; \ - if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \ + if (!(dest_str = zend_flf_parse_arg_str_slow(arg ## arg_num, arg_num))) { \ zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \ goto flf_clean; \ } \ diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index fc0c9fc0634a..5de2b69bf568 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Wang | | Dmitry Stogov | @@ -1953,13 +1952,15 @@ static zend_never_inline void gc_call_destructors_in_fiber(void) GC_G(dtor_idx) = GC_FIRST_ROOT; GC_G(dtor_end) = GC_G(first_unused); + zend_object *exception = NULL; + remember_prev_exception(&exception); + if (UNEXPECTED(!fiber)) { fiber = gc_create_destructor_fiber(); } else { zend_fiber_resume(fiber, NULL, NULL); } - zend_object *exception = NULL; remember_prev_exception(&exception); for (;;) { diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 06f550647bd7..b72b90ccd5ef 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Wang | | Dmitry Stogov | diff --git a/Zend/zend_gdb.c b/Zend/zend_gdb.c index 5975d8c29c09..0c2a82a144c0 100644 --- a/Zend/zend_gdb.c +++ b/Zend/zend_gdb.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | diff --git a/Zend/zend_gdb.h b/Zend/zend_gdb.h index aad0fefb097b..554791f5255a 100644 --- a/Zend/zend_gdb.h +++ b/Zend/zend_gdb.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 3bec062e9ce1..52d409f2e69b 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Bob Weinand | @@ -179,7 +178,7 @@ static void zend_generator_remove_child(zend_generator_node *node, zend_generato node->child.single = NULL; } else { HashTable *ht = node->child.ht; - zend_hash_index_del(ht, (zend_ulong) child); + zend_hash_index_del(ht, (zend_ulong)(uintptr_t) child); if (node->children == 2) { zend_generator *other_child; ZEND_HASH_FOREACH_PTR(ht, other_child) { @@ -558,7 +557,7 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator * node->child.ht = ht; } - zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong) child, child); + zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong)(uintptr_t) child, child); } ++node->children; diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index e7b01fb20ad7..73dd9ddc1f91 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Bob Weinand | diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 31f54cd8284b..83360a2c96d2 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -74,6 +73,7 @@ typedef struct _zend_vm_stack *zend_vm_stack; typedef struct _zend_ini_entry zend_ini_entry; typedef struct _zend_fiber_context zend_fiber_context; typedef struct _zend_fiber zend_fiber; +typedef struct _zend_error_info zend_error_info; typedef enum { ZEND_MEMOIZE_NONE, @@ -81,6 +81,12 @@ typedef enum { ZEND_MEMOIZE_FETCH, } zend_memoize_mode; +typedef struct zend_err_buf { + uint32_t size; + uint32_t capacity; + zend_error_info **errors; +} zend_err_buf; + struct _zend_compiler_globals { zend_stack loop_var_stack; @@ -298,8 +304,7 @@ struct _zend_executor_globals { * and their processing is delayed until zend_emit_recorded_errors() * is called or a fatal diagnostic is emitted. */ bool record_errors; - uint32_t num_errors; - zend_error_info **errors; + zend_err_buf errors; /* Override filename or line number of thrown errors and exceptions */ zend_string *filename_override; @@ -320,10 +325,17 @@ struct _zend_executor_globals { zend_strtod_state strtod_state; HashTable callable_convert_cache; + HashTable partial_function_application_cache; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; +#ifdef ZTS +/* Compile-time offsets of the hot globals, in a reserved region just before *_tsrm_ls_cache. */ +# define ZEND_CG_OFFSET (-(ptrdiff_t) TSRM_ALIGNED_SIZE(sizeof(zend_compiler_globals))) +# define ZEND_EG_OFFSET (ZEND_CG_OFFSET - (ptrdiff_t) TSRM_ALIGNED_SIZE(sizeof(zend_executor_globals))) +#endif + #define EG_FLAGS_INITIAL (0) #define EG_FLAGS_IN_SHUTDOWN (1<<0) #define EG_FLAGS_OBJECT_STORE_NO_REUSE (1<<1) diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index d3cd9f923eee..adb3913ece71 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -31,7 +30,7 @@ BEGIN_EXTERN_C() /* Compiler */ #ifdef ZTS -# define CG(v) ZEND_TSRMG_FAST(compiler_globals_offset, zend_compiler_globals *, v) +# define CG(v) ZEND_TSRMG_FAST(ZEND_CG_OFFSET, zend_compiler_globals *, v) #else # define CG(v) (compiler_globals.v) extern ZEND_API struct _zend_compiler_globals compiler_globals; @@ -41,7 +40,7 @@ ZEND_API int zendparse(void); /* Executor */ #ifdef ZTS -# define EG(v) ZEND_TSRMG_FAST(executor_globals_offset, zend_executor_globals *, v) +# define EG(v) ZEND_TSRMG_FAST(ZEND_EG_OFFSET, zend_executor_globals *, v) #else # define EG(v) (executor_globals.v) extern ZEND_API zend_executor_globals executor_globals; @@ -49,12 +48,20 @@ extern ZEND_API zend_executor_globals executor_globals; /* Language Scanner */ #ifdef ZTS -# define LANG_SCNG(v) ZEND_TSRMG_FAST(language_scanner_globals_offset, zend_php_scanner_globals *, v) extern ZEND_API ts_rsrc_id language_scanner_globals_id; -extern ZEND_API size_t language_scanner_globals_offset; +# if defined(ZEND_WIN32) && !defined(LIBZEND_EXPORTS) +# define LANG_SCNG(v) TSRMG(language_scanner_globals_id, zend_php_scanner_globals *, v) +# else +# ifdef ZEND_WIN32 +extern TSRM_TLS zend_php_scanner_globals language_scanner_globals; +# else +extern ZEND_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_php_scanner_globals language_scanner_globals; +# endif +# define LANG_SCNG(v) (language_scanner_globals.v) +# endif #else -# define LANG_SCNG(v) (language_scanner_globals.v) extern ZEND_API zend_php_scanner_globals language_scanner_globals; +# define LANG_SCNG(v) (language_scanner_globals.v) #endif diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index e0e789cb7cb4..acc342bc267d 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -1111,7 +1110,10 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, if ((flag & (HASH_ADD_NEW|HASH_ADD_NEXT)) != (HASH_ADD_NEW|HASH_ADD_NEXT) && h < ht->nNumUsed) { zv = ht->arPacked + h; - if (Z_TYPE_P(zv) != IS_UNDEF) { + if (flag & HASH_ADD_NEW) { + ZEND_ASSERT(Z_TYPE_P(zv) == IS_UNDEF); + goto convert_to_hash; + } else if (Z_TYPE_P(zv) != IS_UNDEF) { if (flag & HASH_LOOKUP) { return zv; } @@ -3209,7 +3211,7 @@ static zend_always_inline int zend_hash_compare_impl(const HashTable *ht1, const return 0; } -ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, bool ordered) +ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered) { int result; IS_CONSISTENT(ht1); @@ -3236,73 +3238,6 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co } -ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag) -{ - uint32_t idx; - zval *res; - - IS_CONSISTENT(ht); - - if (ht->nNumOfElements == 0 ) { - return NULL; - } - - if (HT_IS_PACKED(ht)) { - zval *zv; - - idx = 0; - while (1) { - if (idx == ht->nNumUsed) { - return NULL; - } - if (Z_TYPE(ht->arPacked[idx]) != IS_UNDEF) break; - idx++; - } - res = ht->arPacked + idx; - for (; idx < ht->nNumUsed; idx++) { - zv = ht->arPacked + idx; - if (UNEXPECTED(Z_TYPE_P(zv) == IS_UNDEF)) continue; - - if (flag) { - if (compar(res, zv) < 0) { /* max */ - res = zv; - } - } else { - if (compar(res, zv) > 0) { /* min */ - res = zv; - } - } - } - } else { - Bucket *p; - - idx = 0; - while (1) { - if (idx == ht->nNumUsed) { - return NULL; - } - if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) break; - idx++; - } - res = &ht->arData[idx].val; - for (; idx < ht->nNumUsed; idx++) { - p = ht->arData + idx; - if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; - - if (flag) { - if (compar(res, &p->val) < 0) { /* max */ - res = &p->val; - } - } else { - if (compar(res, &p->val) > 0) { /* min */ - res = &p->val; - } - } - } - } - return res; -} - ZEND_API bool ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx) { const char *tmp = key; diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 70d9721cb7a1..1181bee29fae 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -301,10 +300,9 @@ ZEND_API void zend_hash_bucket_renum_swap(Bucket *p, Bucket *q); ZEND_API void zend_hash_bucket_packed_swap(Bucket *p, Bucket *q); typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b); -ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, bool ordered); +ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered); ZEND_API void ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber); ZEND_API void ZEND_FASTCALL zend_array_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber); -ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag); static zend_always_inline void ZEND_FASTCALL zend_hash_sort(HashTable *ht, bucket_compare_func_t compare_func, bool renumber) { zend_hash_sort_ex(ht, zend_sort, compare_func, renumber); @@ -405,14 +403,14 @@ static zend_always_inline bool _zend_handle_numeric_str(const char *key, size_t const char *tmp = key; if (EXPECTED(*tmp > '9')) { - return 0; + return false; } else if (*tmp < '0') { if (*tmp != '-') { - return 0; + return false; } tmp++; if (*tmp > '9' || *tmp < '0') { - return 0; + return false; } } return _zend_handle_numeric_str_ex(key, length, idx); @@ -1606,30 +1604,30 @@ static zend_always_inline bool zend_array_is_list(const zend_array *array) zend_string* str_idx; /* Empty arrays are lists */ if (zend_hash_num_elements(array) == 0) { - return 1; + return true; } /* Packed arrays are lists */ if (HT_IS_PACKED(array)) { if (HT_IS_WITHOUT_HOLES(array)) { - return 1; + return true; } /* Check if the list could theoretically be repacked */ ZEND_HASH_PACKED_FOREACH_KEY(array, num_idx) { if (num_idx != expected_idx++) { - return 0; + return false; } } ZEND_HASH_FOREACH_END(); } else { /* Check if the list could theoretically be repacked */ ZEND_HASH_MAP_FOREACH_KEY(array, num_idx, str_idx) { if (str_idx != NULL || num_idx != expected_idx++) { - return 0; + return false; } } ZEND_HASH_FOREACH_END(); } - return 1; + return true; } diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c index 5c3cd136d580..a3c65932ca4d 100644 --- a/Zend/zend_highlight.c +++ b/Zend/zend_highlight.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -79,8 +78,8 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini { zval token; int token_type; - char *last_color = syntax_highlighter_ini->highlight_html; - char *next_color; + const char *last_color = syntax_highlighter_ini->highlight_html; + const char *next_color; zend_printf("
", last_color);
 	/* highlight stuff coming back from zendlex() */
diff --git a/Zend/zend_highlight.h b/Zend/zend_highlight.h
index 04688d65132b..2e399f408063 100644
--- a/Zend/zend_highlight.h
+++ b/Zend/zend_highlight.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -30,11 +29,11 @@
 
 
 typedef struct _zend_syntax_highlighter_ini {
-	char *highlight_html;
-	char *highlight_comment;
-	char *highlight_default;
-	char *highlight_string;
-	char *highlight_keyword;
+	const char *highlight_html;
+	const char *highlight_comment;
+	const char *highlight_default;
+	const char *highlight_string;
+	const char *highlight_keyword;
 } zend_syntax_highlighter_ini;
 
 
diff --git a/Zend/zend_hrtime.c b/Zend/zend_hrtime.c
index 773e0525cadd..819f95c47662 100644
--- a/Zend/zend_hrtime.c
+++ b/Zend/zend_hrtime.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Niklas Keller                               |
    | Author: Anatol Belski                                    |
diff --git a/Zend/zend_hrtime.h b/Zend/zend_hrtime.h
index f3bc4deeaf50..6d802caacfe0 100644
--- a/Zend/zend_hrtime.h
+++ b/Zend/zend_hrtime.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Niklas Keller                               |
    | Author: Anatol Belski                                    |
@@ -44,7 +42,7 @@
 #elif defined(_WIN32) || defined(_WIN64)
 # undef  ZEND_HRTIME_PLATFORM_WINDOWS
 # define ZEND_HRTIME_PLATFORM_WINDOWS 1
-#elif HAVE_CLOCK_GETTIME_NSEC_NP
+#elif defined(HAVE_CLOCK_GETTIME_NSEC_NP)
 # undef  ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC
 # define ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC 1
 #elif defined(__APPLE__)
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index ba13a3233ed2..4424c9a1a3ab 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -189,9 +188,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
 
 	if (ce->constructor) {
 		if (parent->constructor && UNEXPECTED(parent->constructor->common.fn_flags & ZEND_ACC_FINAL)) {
-			zend_error_noreturn(E_ERROR, "Cannot override final %s::%s() with %s::%s()",
-				ZSTR_VAL(parent->name), ZSTR_VAL(parent->constructor->common.function_name),
-				ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
+			zend_error_noreturn(E_ERROR, "Cannot override final %s::__construct() with %s::__construct()",
+				ZSTR_VAL(parent->name),
+				ZSTR_VAL(ce->name));
 		}
 		return;
 	}
@@ -265,11 +264,7 @@ static zend_class_entry *lookup_class_ex(
 	bool in_preload = CG(compiler_options) & ZEND_COMPILE_PRELOAD;
 
 	if (UNEXPECTED(!EG(active) && !in_preload)) {
-		zend_string *lc_name = zend_string_tolower(name);
-
-		ce = zend_hash_find_ptr(CG(class_table), lc_name);
-
-		zend_string_release(lc_name);
+		ce = zend_hash_find_ptr_lc(CG(class_table), name);
 
 		if (register_unresolved && !ce) {
 			zend_error_noreturn(
@@ -537,7 +532,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 						return INHERITANCE_SUCCESS;
 					}
 					continue;
-				EMPTY_SWITCH_DEFAULT_CASE();
+				default: ZEND_UNREACHABLE();
 			}
 		}
 
@@ -924,7 +919,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 			/* cut off on NULL byte ... class@anonymous */
 			smart_str_appends(&str, ZSTR_VAL(fptr->common.scope->name));
 		} else {
-			smart_str_appendl(&str, ZSTR_VAL(fptr->common.scope->name), ZSTR_LEN(fptr->common.scope->name));
+			smart_str_append(&str, fptr->common.scope->name);
 		}
 		smart_str_appends(&str, "::");
 	}
@@ -1596,11 +1591,7 @@ static void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_en
 
 	ce_num = ce->num_interfaces;
 
-	if (ce->type == ZEND_INTERNAL_CLASS) {
-		ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
-	} else {
-		ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
-	}
+	ce->interfaces = (zend_class_entry **) perealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num), ce->type == ZEND_INTERNAL_CLASS);
 
 	/* Inherit the interfaces, only if they're not already inherited by the class */
 	while (if_num--) {
@@ -2124,6 +2115,12 @@ static bool do_inherit_constant_check(
 		);
 	}
 
+	if (!(ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_PRIVATE)) {
+		if (child_constant->ce == ce) {
+			ZEND_CLASS_CONST_FLAGS(child_constant) &= ~ZEND_ACC_OVERRIDE;
+		}
+	}
+
 	if (!(ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_PRIVATE) && ZEND_TYPE_IS_SET(parent_constant->type)) {
 		inheritance_status status = class_constant_types_compatible(parent_constant, child_constant);
 		if (status == INHERITANCE_ERROR) {
@@ -2235,11 +2232,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
 		} ZEND_HASH_FOREACH_END();
 	} else {
 		if (ce->num_interfaces >= current_iface_num) {
-			if (ce->type == ZEND_INTERNAL_CLASS) {
-				ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
-			} else {
-				ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
-			}
+			ce->interfaces = (zend_class_entry **) perealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num), ce->type == ZEND_INTERNAL_CLASS);
 		}
 		ce->interfaces[ce->num_interfaces++] = iface;
 
@@ -2330,6 +2323,15 @@ void zend_inheritance_check_override(const zend_class_entry *ce)
 		}
 	} ZEND_HASH_FOREACH_END();
 
+	ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->constants_table, zend_string *name, zend_class_constant *c) {
+		if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_OVERRIDE) {
+			zend_error_noreturn(
+				E_COMPILE_ERROR,
+				"%s::%s has #[\\Override] attribute, but no matching parent constant exists",
+				ZSTR_VAL(ce->name), ZSTR_VAL(name));
+		}
+	} ZEND_HASH_FOREACH_END();
+
 	ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) {
 		if (prop->flags & ZEND_ACC_OVERRIDE) {
 			zend_error_noreturn(
@@ -2401,7 +2403,11 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
 		}
 	}
 
-	if (UNEXPECTED(fn->type == ZEND_INTERNAL_FUNCTION)) {
+	if (ce->type == ZEND_INTERNAL_CLASS) {
+		ZEND_ASSERT(fn->type == ZEND_INTERNAL_FUNCTION);
+		new_fn = (zend_function*)(uintptr_t)malloc(sizeof(zend_internal_function));
+		memcpy(new_fn, fn, sizeof(zend_internal_function));
+	} else if (UNEXPECTED(fn->type == ZEND_INTERNAL_FUNCTION)) {
 		new_fn = zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
 		memcpy(new_fn, fn, sizeof(zend_internal_function));
 		new_fn->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
@@ -2539,7 +2545,6 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
 	size_t i, j = 0;
 	zend_trait_precedence *cur_precedence;
 	zend_trait_method_reference *cur_method_ref;
-	zend_string *lc_trait_name;
 	zend_string *lcname;
 	HashTable **exclude_tables = NULL;
 	zend_class_entry **aliases = NULL;
@@ -2554,9 +2559,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
 		while ((cur_precedence = precedences[i])) {
 			/** Resolve classes for all precedence operations. */
 			cur_method_ref = &cur_precedence->trait_method;
-			lc_trait_name = zend_string_tolower(cur_method_ref->class_name);
-			trait = zend_hash_find_ptr(EG(class_table), lc_trait_name);
-			zend_string_release_ex(lc_trait_name, 0);
+			trait = zend_hash_find_ptr_lc(EG(class_table), cur_method_ref->class_name);
 			if (!trait || !(trait->ce_flags & ZEND_ACC_LINKED)) {
 				zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", ZSTR_VAL(cur_method_ref->class_name));
 			}
@@ -2583,9 +2586,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
 				zend_class_entry *exclude_ce;
 				uint32_t trait_num;
 
-				lc_trait_name = zend_string_tolower(class_name);
-				exclude_ce = zend_hash_find_ptr(EG(class_table), lc_trait_name);
-				zend_string_release_ex(lc_trait_name, 0);
+				exclude_ce = zend_hash_find_ptr_lc(EG(class_table), class_name);
 				if (!exclude_ce || !(exclude_ce->ce_flags & ZEND_ACC_LINKED)) {
 					zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", ZSTR_VAL(class_name));
 				}
@@ -2628,9 +2629,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
 			lcname = zend_string_tolower(cur_method_ref->method_name);
 			if (cur_method_ref->class_name) {
 				/* For all aliases with an explicit class name, resolve the class now. */
-				lc_trait_name = zend_string_tolower(cur_method_ref->class_name);
-				trait = zend_hash_find_ptr(EG(class_table), lc_trait_name);
-				zend_string_release_ex(lc_trait_name, 0);
+				trait = zend_hash_find_ptr_lc(EG(class_table), cur_method_ref->class_name);
 				if (!trait || !(trait->ce_flags & ZEND_ACC_LINKED)) {
 					zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", ZSTR_VAL(cur_method_ref->class_name));
 				}
@@ -2766,6 +2765,19 @@ static void emit_incompatible_trait_constant_error(
 	);
 }
 
+static void emit_trait_constant_enum_case_conflict_error(
+	const zend_class_entry *ce, const zend_class_constant *trait_constant, zend_string *name
+) {
+	zend_error_noreturn(E_COMPILE_ERROR,
+		"Cannot use trait %s, because %s::%s conflicts with enum case %s::%s",
+		ZSTR_VAL(trait_constant->ce->name),
+		ZSTR_VAL(trait_constant->ce->name),
+		ZSTR_VAL(name),
+		ZSTR_VAL(ce->name),
+		ZSTR_VAL(name)
+	);
+}
+
 static bool do_trait_constant_check(
 	zend_class_entry *ce, zend_class_constant *trait_constant, zend_string *name, zend_class_entry **traits, size_t current_trait
 ) {
@@ -2779,6 +2791,11 @@ static bool do_trait_constant_check(
 
 	zend_class_constant *existing_constant = Z_PTR_P(zv);
 
+	if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(existing_constant) & ZEND_CLASS_CONST_IS_CASE)) {
+		emit_trait_constant_enum_case_conflict_error(ce, trait_constant, name);
+		return false;
+	}
+
 	if ((ZEND_CLASS_CONST_FLAGS(trait_constant) & flags_mask) != (ZEND_CLASS_CONST_FLAGS(existing_constant) & flags_mask)) {
 		emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant, name, traits, current_trait);
 		return false;
@@ -2820,7 +2837,11 @@ static void zend_do_traits_constant_binding(zend_class_entry *ce, zend_class_ent
 			if (do_trait_constant_check(ce, constant, constant_name, traits, i)) {
 				zend_class_constant *ct = NULL;
 
-				ct = zend_arena_alloc(&CG(arena),sizeof(zend_class_constant));
+				if (ce->type == ZEND_INTERNAL_CLASS) {
+					ct = malloc(sizeof(zend_class_constant));
+				} else {
+					ct = zend_arena_alloc(&CG(arena),sizeof(zend_class_constant));
+				}
 				memcpy(ct, constant, sizeof(zend_class_constant));
 				constant = ct;
 
@@ -2999,6 +3020,49 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
 }
 /* }}} */
 
+ZEND_API void zend_class_use_internal_traits(zend_class_entry *class_entry, int num_traits, ...)
+{
+	ZEND_ASSERT(class_entry->ce_flags & ZEND_ACC_LINKED);
+	ZEND_ASSERT(num_traits >= 0);
+
+	if (UNEXPECTED(num_traits == 0)) {
+		return;
+	}
+
+	zend_class_entry **traits = safe_pemalloc(num_traits, sizeof(zend_class_entry *), 0, /* persistent */ true);
+	class_entry->trait_names = safe_pemalloc(num_traits, sizeof(zend_class_name), 0, /* persistent */ true);
+	class_entry->num_traits = num_traits;
+
+	va_list trait_list;
+	va_start(trait_list, num_traits);
+	for (int i = 0; i < num_traits; i++) {
+		zend_class_entry *trait_entry = va_arg(trait_list, zend_class_entry *);
+		class_entry->trait_names[i].name = zend_string_copy(trait_entry->name);
+		class_entry->trait_names[i].lc_name = zend_string_tolower_ex(zend_string_copy(trait_entry->name), /* persistent */ true);
+
+		if (UNEXPECTED(!(trait_entry->ce_flags & ZEND_ACC_TRAIT))) {
+			free(traits);
+			zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot use %s - it is not a trait",
+				ZSTR_VAL(class_entry->name), ZSTR_VAL(trait_entry->name));
+		}
+		traits[i] = trait_entry;
+	}
+	va_end(trait_list);
+
+	bool contains_abstract_methods = false;
+	zend_do_traits_method_binding(class_entry, traits, NULL, NULL, false, &contains_abstract_methods);
+	zend_do_traits_constant_binding(class_entry, traits);
+	zend_do_traits_property_binding(class_entry, traits);
+
+	ZEND_HASH_MAP_FOREACH_PTR(&class_entry->function_table, zend_function *fn) {
+		zend_fixup_trait_method(fn, class_entry);
+	} ZEND_HASH_FOREACH_END();
+
+	free(traits);
+
+	/* TODO: Verify abstract trait method implementation requirements are enforced. */
+}
+
 #define MAX_ABSTRACT_INFO_CNT 3
 #define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
 #define DISPLAY_ABSTRACT_FN(idx) \
@@ -3308,7 +3372,7 @@ static void check_unrecoverable_load_failure(const zend_class_entry *ce) {
 	 * a dependence on the inheritance hierarchy of this specific class. Instead we fall back to
 	 * a fatal error, as would happen if we did not allow exceptions in the first place. */
 	if (CG(unlinked_uses)
-			&& zend_hash_index_del(CG(unlinked_uses), (zend_long)(uintptr_t)ce) == SUCCESS) {
+			&& zend_hash_index_del(CG(unlinked_uses), (zend_ulong)(uintptr_t)ce) == SUCCESS) {
 		zend_exception_uncaught_error(
 			"During inheritance of %s with variance dependencies", ZSTR_VAL(ce->name));
 	}
@@ -3603,7 +3667,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
 		}
 
 		if (CG(unlinked_uses)) {
-			zend_hash_index_del(CG(unlinked_uses), (zend_long)(uintptr_t) ce);
+			zend_hash_index_del(CG(unlinked_uses), (zend_ulong)(uintptr_t) ce);
 		}
 
 		orig_linking_class = CG(current_linking_class);
@@ -3748,6 +3812,11 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
 		if (ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) {
 			resolve_delayed_variance_obligations(ce);
 		}
+		/* Delayed variance resolution can re-enter linking before the full
+		 * hierarchy is linked. See ext/opcache/tests/gh20469*.phpt. */
+		if (CG(unlinked_uses) && zend_hash_index_exists(CG(unlinked_uses), (zend_long)(uintptr_t) ce)) {
+			ce->ce_flags &= ~ZEND_ACC_CACHEABLE;
+		}
 		if (ce->ce_flags & ZEND_ACC_CACHEABLE) {
 			ce->ce_flags &= ~ZEND_ACC_CACHEABLE;
 		} else {
@@ -3755,6 +3824,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
 		}
 	}
 
+	bool was_cacheable = is_cacheable;
 	if (!CG(current_linking_class)) {
 		is_cacheable = 0;
 	}
@@ -3775,6 +3845,13 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
 			zend_hash_destroy(ht);
 			FREE_HASHTABLE(ht);
 		}
+	} else if (was_cacheable && ce->inheritance_cache) {
+		/* Cacheability can be disabled after dependency tracking prepared
+		 * an inheritance-cache dependency table. Discard it here. */
+		HashTable *ht = (HashTable*)ce->inheritance_cache;
+		ce->inheritance_cache = NULL;
+		zend_hash_destroy(ht);
+		FREE_HASHTABLE(ht);
 	}
 
 	if (!orig_record_errors) {
diff --git a/Zend/zend_inheritance.h b/Zend/zend_inheritance.h
index 7171a9385f3b..fdcbd95764b3 100644
--- a/Zend/zend_inheritance.h
+++ b/Zend/zend_inheritance.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_ini.c b/Zend/zend_ini.c
index d8f1d4f50f95..093683526d31 100644
--- a/Zend/zend_ini.c
+++ b/Zend/zend_ini.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Zeev Suraski                                   |
    +----------------------------------------------------------------------+
@@ -491,7 +490,7 @@ ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig)
 }
 /* }}} */
 
-ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists) /* {{{ */
+ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists) /* {{{ */
 {
 	zend_string *str = zend_ini_str_ex(name, name_length, orig, exists);
 
@@ -499,7 +498,7 @@ ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, bool ori
 }
 /* }}} */
 
-ZEND_API char *zend_ini_string(const char *name, size_t name_length, bool orig) /* {{{ */
+ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig) /* {{{ */
 {
 	zend_string *str = zend_ini_str(name, name_length, orig);
 
@@ -562,6 +561,11 @@ ZEND_API zend_string *zend_ini_get_value(zend_string *name) /* {{{ */
 
 ZEND_API bool zend_ini_parse_bool(const zend_string *str)
 {
+	/* May happen if an unknown INI setting is queried via zend_ini_bool_literal(),
+	 * as zend_ini_str() would return NULL */
+	if (UNEXPECTED(str == NULL)) {
+		return false;
+	}
 	if (zend_string_equals_literal_ci(str, "true")
 			|| zend_string_equals_literal_ci(str, "yes")
 			|| zend_string_equals_literal_ci(str, "on")
@@ -585,7 +589,7 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
 		++digits_consumed;
 	}
 
-	if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
+	if (digits_consumed[0] == '0' && !isdigit((unsigned char)digits_consumed[1])) {
 		/* Value is just 0 */
 		if ((digits_consumed+1) == str_end) {
 			return digits_consumed;
@@ -643,7 +647,7 @@ static zend_ulong zend_ini_parse_quantity_internal(const zend_string *value, zen
 	}
 
 	/* if there is no digit after +/- */
-	if (!isdigit(digits[0])) {
+	if (!isdigit((unsigned char)digits[0])) {
 		/* Escape the string to avoid null bytes and to make non-printable chars
 		 * visible */
 		smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
@@ -657,7 +661,7 @@ static zend_ulong zend_ini_parse_quantity_internal(const zend_string *value, zen
 	}
 
 	int base = 0;
-	if (digits[0] == '0' && !isdigit(digits[1])) {
+	if (digits[0] == '0' && !isdigit((unsigned char)digits[1])) {
 		/* Value is just 0 */
 		if ((digits+1) == str_end) {
 			*errstr = NULL;
diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h
index d8d7f599f461..dbe650675b66 100644
--- a/Zend/zend_ini.h
+++ b/Zend/zend_ini.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Zeev Suraski                                   |
    +----------------------------------------------------------------------+
@@ -88,13 +87,19 @@ ZEND_API void display_ini_entries(zend_module_entry *module);
 
 ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, bool orig);
 ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig);
-ZEND_API char *zend_ini_string(const char *name, size_t name_length, bool orig);
-ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists);
+ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig);
+ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists);
 ZEND_API zend_string *zend_ini_str(const char *name, size_t name_length, bool orig);
 ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool orig, bool *exists);
 ZEND_API zend_string *zend_ini_get_value(zend_string *name);
 ZEND_API bool zend_ini_parse_bool(const zend_string *str);
 
+#define zend_ini_bool_literal(name) zend_ini_parse_bool(zend_ini_str((name), sizeof("" name) - 1, false))
+#define zend_ini_long_literal(name) zend_ini_long((name), sizeof("" name) - 1, false)
+#define zend_ini_double_literal(name) zend_ini_double((name), sizeof("" name) - 1, false)
+#define zend_ini_str_literal(name) zend_ini_str((name), sizeof("" name) - 1, false)
+#define zend_ini_string_literal(name) zend_ini_string((name), sizeof("" name) - 1, false)
+
 /**
  * Parses an ini quantity
  *
@@ -177,30 +182,20 @@ END_EXTERN_C()
 
 #ifdef ZTS
 #define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id)
+	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id)
 #define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
-	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, displayer)
+	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id, displayer)
 #define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, NULL, zend_ini_boolean_displayer_cb)
+	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id, NULL, zend_ini_boolean_displayer_cb)
 #else
 #define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr)
+	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr)
 #define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
-	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, displayer)
+	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr, displayer)
 #define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
+	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
 #endif
 
-#define INI_INT(name) zend_ini_long((name), strlen(name), 0)
-#define INI_FLT(name) zend_ini_double((name), strlen(name), 0)
-#define INI_STR(name) zend_ini_string_ex((name), strlen(name), 0, NULL)
-#define INI_BOOL(name) ((bool) INI_INT(name))
-
-#define INI_ORIG_INT(name)	zend_ini_long((name), strlen(name), 1)
-#define INI_ORIG_FLT(name)	zend_ini_double((name), strlen(name), 1)
-#define INI_ORIG_STR(name)	zend_ini_string((name), strlen(name), 1)
-#define INI_ORIG_BOOL(name) ((bool) INI_ORIG_INT(name))
-
 #define REGISTER_INI_ENTRIES() zend_register_ini_entries_ex(ini_entries, module_number, type)
 #define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries_ex(module_number, type)
 #define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module)
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
index 748ccd2235a6..47b05de4e692 100644
--- a/Zend/zend_ini_parser.y
+++ b/Zend/zend_ini_parser.y
@@ -4,15 +4,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Zeev Suraski                                  |
    |          Jani Taskinen                                 |
@@ -57,7 +56,7 @@ static int get_int_val(zval *op) {
 			zend_string_free(Z_STR_P(op));
 			return val;
 		}
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 
@@ -152,7 +151,7 @@ static void zend_ini_get_constant(zval *result, zval *name)
 		   	&& (c = zend_get_constant(Z_STR_P(name))) != 0) {
 		if (Z_TYPE_P(c) != IS_STRING) {
 			ZVAL_COPY_OR_DUP(&tmp, c);
-			if (Z_OPT_CONSTANT(tmp)) {
+			if (Z_OPT_TYPE(tmp) == IS_CONSTANT_AST) {
 				zval_update_constant_ex(&tmp, NULL);
 			}
 			convert_to_string(&tmp);
diff --git a/Zend/zend_ini_scanner.h b/Zend/zend_ini_scanner.h
index 9a6c84fce429..c013564a10f4 100644
--- a/Zend/zend_ini_scanner.h
+++ b/Zend/zend_ini_scanner.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index 5f9b77e6a3d8..7fd51654ac82 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Zeev Suraski                                  |
    |          Jani Taskinen                                 |
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 404dd9db893e..49169dfca234 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h
index 883e482f510c..3aeac4fc8146 100644
--- a/Zend/zend_interfaces.h
+++ b/Zend/zend_interfaces.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c
index 64dbb0541a80..c05434486f89 100644
--- a/Zend/zend_iterators.c
+++ b/Zend/zend_iterators.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Marcus Boerger                                |
diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h
index 75549188ed6b..973903768405 100644
--- a/Zend/zend_iterators.h
+++ b/Zend/zend_iterators.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Marcus Boerger                                |
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index e2686c7e1c5a..b4dda00404ea 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -3,15 +3,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -821,9 +820,9 @@ parameter:
 			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, NULL,
 					NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $7); }
 	|	optional_cpp_modifiers optional_type_without_static
-		is_reference is_variadic T_VARIABLE backup_doc_comment '=' expr optional_property_hook_list
-			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $8,
-					NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $9); }
+		is_reference is_variadic T_VARIABLE '=' expr backup_doc_comment optional_property_hook_list
+			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $7,
+					NULL, $8 ? zend_ast_create_zval_from_str($8) : NULL, $9); }
 ;
 
 optional_type_without_static:
@@ -1059,13 +1058,13 @@ trait_alias:
 
 trait_method_reference:
 		identifier
-			{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); }
+			{ $$ = zend_ast_create(ZEND_AST_TRAIT_METHOD_REFERENCE, NULL, $1); }
 	|	absolute_trait_method_reference { $$ = $1; }
 ;
 
 absolute_trait_method_reference:
 	class_name T_PAAMAYIM_NEKUDOTAYIM identifier
-		{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
+		{ $$ = zend_ast_create(ZEND_AST_TRAIT_METHOD_REFERENCE, $1, $3); }
 ;
 
 method_body:
diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h
index c494564ba234..e502d91411b5 100644
--- a/Zend/zend_language_scanner.h
+++ b/Zend/zend_language_scanner.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 1c985189fd3c..bf6bbe7f9d90 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    |          Nuno Lopes                                 |
@@ -85,7 +84,11 @@
 #define SCNG	LANG_SCNG
 #ifdef ZTS
 ZEND_API ts_rsrc_id language_scanner_globals_id;
-ZEND_API size_t language_scanner_globals_offset;
+# ifdef ZEND_WIN32
+TSRM_TLS zend_php_scanner_globals language_scanner_globals;
+# else
+ZEND_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_php_scanner_globals language_scanner_globals;
+# endif
 #else
 ZEND_API zend_php_scanner_globals language_scanner_globals;
 #endif
@@ -591,6 +594,43 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
 	return SUCCESS;
 }
 
+static zend_op_array *zend_compile_ast_internal(int type)
+{
+	ZEND_ASSERT(CG(in_compilation));
+	ZEND_ASSERT(CG(ast));
+
+	uint32_t last_lineno = CG(zend_lineno);
+	zend_file_context original_file_context;
+	zend_oparray_context original_oparray_context;
+	zend_op_array *original_active_op_array = CG(active_op_array);
+
+	zend_op_array *op_array = emalloc(sizeof(*op_array));
+	init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE);
+	CG(active_op_array) = op_array;
+
+	/* Use heap to not waste arena memory */
+	op_array->fn_flags |= ZEND_ACC_HEAP_RT_CACHE;
+
+	if (zend_ast_process) {
+		zend_ast_process(CG(ast));
+	}
+
+	zend_file_context_begin(&original_file_context);
+	zend_oparray_context_begin(&original_oparray_context, op_array);
+	zend_compile_top_stmt(CG(ast));
+	CG(zend_lineno) = last_lineno;
+	zend_emit_final_return(type == ZEND_USER_FUNCTION);
+	op_array->line_start = 1;
+	op_array->line_end = last_lineno;
+	pass_two(op_array);
+	zend_oparray_context_end(&original_oparray_context);
+	zend_file_context_end(&original_file_context);
+
+	CG(active_op_array) = original_active_op_array;
+
+	return op_array;
+}
+
 static zend_op_array *zend_compile(zend_function_type type)
 {
 	zend_op_array *op_array = NULL;
@@ -601,34 +641,7 @@ static zend_op_array *zend_compile(zend_function_type type)
 	CG(ast_arena) = zend_arena_create(1024 * 32);
 
 	if (!zendparse()) {
-		uint32_t last_lineno = CG(zend_lineno);
-		zend_file_context original_file_context;
-		zend_oparray_context original_oparray_context;
-		zend_op_array *original_active_op_array = CG(active_op_array);
-
-		op_array = emalloc(sizeof(zend_op_array));
-		init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE);
-		CG(active_op_array) = op_array;
-
-		/* Use heap to not waste arena memory */
-		op_array->fn_flags |= ZEND_ACC_HEAP_RT_CACHE;
-
-		if (zend_ast_process) {
-			zend_ast_process(CG(ast));
-		}
-
-		zend_file_context_begin(&original_file_context);
-		zend_oparray_context_begin(&original_oparray_context, op_array);
-		zend_compile_top_stmt(CG(ast));
-		CG(zend_lineno) = last_lineno;
-		zend_emit_final_return(type == ZEND_USER_FUNCTION);
-		op_array->line_start = 1;
-		op_array->line_end = last_lineno;
-		pass_two(op_array);
-		zend_oparray_context_end(&original_oparray_context);
-		zend_file_context_end(&original_file_context);
-
-		CG(active_op_array) = original_active_op_array;
+		op_array = zend_compile_ast_internal(type);
 	}
 
 	zend_ast_destroy(CG(ast));
@@ -671,6 +684,23 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
 	return op_array;
 }
 
+ZEND_API zend_op_array *zend_compile_ast(
+	zend_ast *ast, int type, zend_string *filename)
+{
+	zend_string *original_compiled_filename = CG(compiled_filename);
+	bool original_in_compilation = CG(in_compilation);
+	CG(in_compilation) = true;
+	CG(ast) = ast;
+
+	zend_set_compiled_filename(filename);
+	zend_op_array *op_array = zend_compile_ast_internal(type);
+
+	CG(in_compilation) = original_in_compilation;
+	zend_restore_compiled_filename(original_compiled_filename);
+
+	return op_array;
+}
+
 ZEND_API zend_ast *zend_compile_string_to_ast(
 		zend_string *code, zend_arena **ast_arena, zend_string *filename) {
 	zval code_zv;
diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c
index e88ecf9fbe65..a8316768ef5f 100644
--- a/Zend/zend_lazy_objects.c
+++ b/Zend/zend_lazy_objects.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Arnaud Le Blanc                        |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h
index fc0a908e7ad2..8e66ee3facd6 100644
--- a/Zend/zend_lazy_objects.h
+++ b/Zend/zend_lazy_objects.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Arnaud Le Blanc                        |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_list.c b/Zend/zend_list.c
index 10aa9174cfcc..4e96ce0ec7da 100644
--- a/Zend/zend_list.c
+++ b/Zend/zend_list.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_list.h b/Zend/zend_list.h
index 55ccf78dca10..108bd3fc3e7f 100644
--- a/Zend/zend_list.h
+++ b/Zend/zend_list.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
index 28a275e6fce7..95ce31764bfc 100644
--- a/Zend/zend_llist.c
+++ b/Zend/zend_llist.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_llist.h b/Zend/zend_llist.h
index 848543eba0a6..a92b8a59648c 100644
--- a/Zend/zend_llist.h
+++ b/Zend/zend_llist.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_long.h b/Zend/zend_long.h
index fef237701f3b..303bacd03d4c 100644
--- a/Zend/zend_long.h
+++ b/Zend/zend_long.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h
index 4dfa0e5043ef..af3b5178aa4a 100644
--- a/Zend/zend_map_ptr.h
+++ b/Zend/zend_map_ptr.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c
index 005ce14868a0..5d0eb1219c0b 100644
--- a/Zend/zend_max_execution_timer.c
+++ b/Zend/zend_max_execution_timer.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Kévin Dunglas                             |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_max_execution_timer.h b/Zend/zend_max_execution_timer.h
index 6557d6c91845..3839ea4cf676 100644
--- a/Zend/zend_max_execution_timer.h
+++ b/Zend/zend_max_execution_timer.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Kévin Dunglas                             |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_mmap.h b/Zend/zend_mmap.h
index 201fd84d074d..d56196c24687 100644
--- a/Zend/zend_mmap.h
+++ b/Zend/zend_mmap.h
@@ -1,12 +1,15 @@
 /*
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Max Kellermann                    |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h
index a8076c0fb905..3a98b1c06e29 100644
--- a/Zend/zend_modules.h
+++ b/Zend/zend_modules.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_multibyte.c b/Zend/zend_multibyte.c
index f61ed79fd1f7..28be8126b117 100644
--- a/Zend/zend_multibyte.c
+++ b/Zend/zend_multibyte.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at                              |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Masaki Fujimoto                           |
    |          Rui Hirokawa                              |
@@ -114,8 +113,8 @@ ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions
 	 * populated, we need to reinitialize script_encoding here.
 	 */
 	{
-		const char *value = zend_ini_string("zend.script_encoding", sizeof("zend.script_encoding") - 1, 0);
-		zend_multibyte_set_script_encoding_by_string(value, strlen(value));
+		const zend_string *value = zend_ini_str_literal("zend.script_encoding");
+		zend_multibyte_set_script_encoding_by_string(ZSTR_VAL(value), ZSTR_LEN(value));
 	}
 	return SUCCESS;
 }
diff --git a/Zend/zend_multibyte.h b/Zend/zend_multibyte.h
index 16ba56ec69fd..41480ed6f86b 100644
--- a/Zend/zend_multibyte.h
+++ b/Zend/zend_multibyte.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at                              |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Masaki Fujimoto                           |
    |          Rui Hirokawa                              |
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index 716e3ba4b571..6457f85f64fb 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sascha Schumann                         |
    |          Ard Biesheuvel                   |
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 45eac02949d1..313113d7dc28 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -893,6 +892,28 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 
 	retval = &EG(uninitialized_zval);
 
+	/* For initialized lazy proxies: if the real instance's magic method
+	 * guard is already set for this property, we are inside a recursive
+	 * call from the real instance's __get/__isset. Forward directly to
+	 * the real instance to avoid double invocation. (GH-21478) */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			uint32_t guard_type = ((type == BP_VAR_IS) && zobj->ce->__isset)
+				? IN_ISSET : IN_GET;
+			if ((*instance_guard) & guard_type) {
+				retval = zend_std_read_property(instance, name, type, cache_slot, rv);
+				if (retval == &EG(uninitialized_zval)) {
+					ZVAL_NULL(rv);
+					retval = rv;
+				}
+				return retval;
+			}
+		}
+	}
+
 	/* magic isset */
 	if ((type == BP_VAR_IS) && zobj->ce->__isset) {
 		zval tmp_result;
@@ -913,6 +934,35 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 			}
 
 			zval_ptr_dtor(&tmp_result);
+
+			/* __isset() may have materialised the property by writing into
+			 * the property table. Re-check it before deferring to __get(),
+			 * so the freshly-written value is returned directly without a
+			 * redundant __get() call (GH-12695). The value is copied into
+			 * `rv` because the property table can be freed by the OBJ_RELEASE
+			 * below (e.g. when __isset() drops the last external reference
+			 * to the object). */
+			if (IS_VALID_PROPERTY_OFFSET(property_offset)) {
+				retval = OBJ_PROP(zobj, property_offset);
+				if (Z_TYPE_P(retval) != IS_UNDEF) {
+					ZVAL_COPY(rv, retval);
+					retval = rv;
+					OBJ_RELEASE(zobj);
+					goto exit;
+				}
+			} else if (IS_DYNAMIC_PROPERTY_OFFSET(property_offset)) {
+				if (zobj->properties != NULL) {
+					retval = zend_hash_find(zobj->properties, name);
+					if (retval) {
+						ZVAL_COPY(rv, retval);
+						retval = rv;
+						OBJ_RELEASE(zobj);
+						goto exit;
+					}
+				}
+			}
+			retval = &EG(uninitialized_zval);
+
 			if (zobj->ce->__get && !((*guard) & IN_GET)) {
 				goto call_getter;
 			}
@@ -1209,6 +1259,20 @@ found:;
 		goto exit;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __set guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __set. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_SET) {
+				return zend_std_write_property(instance, name, value, cache_slot);
+			}
+		}
+	}
+
 	/* magic set */
 	if (zobj->ce->__set) {
 		if (!guard) {
@@ -1409,12 +1473,24 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 			    UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET) ||
 			    UNEXPECTED(prop_info && (Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT))) {
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
+					bool guarded = zobj->ce->__get
+						&& (*zend_get_property_guard(zobj, name) & IN_GET);
+					zend_object *instance = zend_lazy_object_init(zobj);
+					if (!instance) {
 						return &EG(error_zval);
 					}
 
-					return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot);
+					if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
+						uint32_t *guard = zend_get_property_guard(instance, name);
+						if (!(*guard & IN_GET)) {
+							(*guard) |= IN_GET;
+							retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+							(*guard) &= ~IN_GET;
+							return retval;
+						}
+					}
+
+					return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
 				}
 				if (UNEXPECTED(type == BP_VAR_RW)) {
 					if (prop_info) {
@@ -1457,6 +1533,25 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 		}
 		if (EXPECTED(!zobj->ce->__get) ||
 		    UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
+			if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+				bool guarded = (zobj->ce->__get != NULL);
+				zend_object *instance = zend_lazy_object_init(zobj);
+				if (!instance) {
+					return &EG(error_zval);
+				}
+
+				if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
+					uint32_t *guard = zend_get_property_guard(instance, name);
+					if (!(*guard & IN_GET)) {
+						(*guard) |= IN_GET;
+						retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+						(*guard) &= ~IN_GET;
+						return retval;
+					}
+				}
+
+				return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+			}
 			if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
 				zend_forbidden_dynamic_property(zobj->ce, name);
 				return &EG(error_zval);
@@ -1466,14 +1561,6 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 					return &EG(error_zval);
 				}
 			}
-			if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-				zobj = zend_lazy_object_init(zobj);
-				if (!zobj) {
-					return &EG(error_zval);
-				}
-
-				return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot);
-			}
 			if (UNEXPECTED(!zobj->properties)) {
 				rebuild_object_properties_internal(zobj);
 			}
@@ -1580,6 +1667,21 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 		return;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __unset guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __unset. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_UNSET) {
+				zend_std_unset_property(instance, name, cache_slot);
+				return;
+			}
+		}
+	}
+
 	/* magic unset */
 	if (zobj->ce->__unset) {
 		if (!guard) {
@@ -1587,9 +1689,11 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 		}
 		if (!((*guard) & IN_UNSET)) {
 			/* have unsetter - try with it! */
+			GC_ADDREF(zobj);
 			(*guard) |= IN_UNSET; /* prevent circular unsetting */
 			zend_std_call_unsetter(zobj, name);
 			(*guard) &= ~IN_UNSET;
+			OBJ_RELEASE(zobj);
 			return;
 		} else if (UNEXPECTED(IS_WRONG_PROPERTY_OFFSET(property_offset))) {
 			/* Trigger the correct error */
@@ -1750,6 +1854,18 @@ ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(
 }
 /* }}} */
 
+ZEND_API void zend_free_trampoline(zend_function *func)
+{
+	ZEND_ASSERT(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE);
+
+	if (func == &EG(trampoline)) {
+		EG(trampoline).common.attributes = NULL;
+		EG(trampoline).common.function_name = NULL;
+	} else {
+		efree(func);
+	}
+}
+
 static ZEND_FUNCTION(zend_parent_hook_get_trampoline)
 {
 	zend_object *obj = Z_PTR_P(ZEND_THIS);
@@ -2091,22 +2207,25 @@ 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(const zend_class_entry *ce, const zend_string *property_name) /* {{{ */
+ZEND_API ZEND_COLD void 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(const zend_function *constructor, const zend_class_entry *scope) /* {{{ */
 {
 	if (scope) {
-		zend_throw_error(NULL, "Call to %s %s::%s() from scope %s",
-			zend_visibility_string(constructor->common.fn_flags), ZSTR_VAL(constructor->common.scope->name),
-			ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name)
+		zend_throw_error(NULL, "Call to %s %s::__construct() from scope %s",
+			zend_visibility_string(constructor->common.fn_flags),
+			ZSTR_VAL(constructor->common.scope->name),
+			ZSTR_VAL(scope->name)
 		);
 	} else {
-		zend_throw_error(NULL, "Call to %s %s::%s() from global scope", zend_visibility_string(constructor->common.fn_flags), ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
+		zend_throw_error(NULL, "Call to %s %s::__construct() from global scope",
+			zend_visibility_string(constructor->common.fn_flags),
+			ZSTR_VAL(constructor->common.scope->name)
+		);
 	}
 }
 /* }}} */
@@ -2376,6 +2495,20 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 		goto exit;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __isset guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __isset. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_ISSET) {
+				return zend_std_has_property(instance, name, has_set_exists, cache_slot);
+			}
+		}
+	}
+
 	if (!zobj->ce->__isset) {
 		goto lazy_init;
 	}
@@ -2394,7 +2527,20 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 			result = zend_is_true(&rv);
 			zval_ptr_dtor(&rv);
 			if (has_set_exists == ZEND_PROPERTY_NOT_EMPTY && result) {
-				if (EXPECTED(!EG(exception)) && zobj->ce->__get && !((*guard) & IN_GET)) {
+				/* GH-12695, see above. */
+				zval *prop = NULL;
+				if (IS_VALID_PROPERTY_OFFSET(property_offset)) {
+					prop = OBJ_PROP(zobj, property_offset);
+					if (Z_TYPE_P(prop) == IS_UNDEF) {
+						prop = NULL;
+					}
+				} else if (IS_DYNAMIC_PROPERTY_OFFSET(property_offset)
+						&& zobj->properties != NULL) {
+					prop = zend_hash_find(zobj->properties, name);
+				}
+				if (prop) {
+					result = i_zend_is_true(prop);
+				} else if (EXPECTED(!EG(exception)) && zobj->ce->__get && !((*guard) & IN_GET)) {
 					(*guard) |= IN_GET;
 					zend_std_call_getter(zobj, name, &rv);
 					(*guard) &= ~IN_GET;
diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h
index 3e922343eb15..d41ae01bf700 100644
--- a/Zend/zend_object_handlers.h
+++ b/Zend/zend_object_handlers.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -205,7 +204,7 @@ typedef zend_result (*zend_object_do_operation_t)(uint8_t opcode, zval *result,
 
 struct _zend_object_handlers {
 	/* offset of real object header (usually zero) */
-	int										offset;
+	size_t										offset;
 	/* object handlers */
 	zend_object_free_obj_t					free_obj;             /* required */
 	zend_object_dtor_obj_t					dtor_obj;             /* required */
@@ -237,11 +236,10 @@ struct _zend_object_handlers {
 BEGIN_EXTERN_C()
 extern const ZEND_API zend_object_handlers std_object_handlers;
 
-#define zend_get_std_object_handlers() \
-	(&std_object_handlers)
-
-#define zend_get_function_root_class(fbc) \
-	((fbc)->common.prototype ? (fbc)->common.prototype->common.scope : (fbc)->common.scope)
+static zend_always_inline const zend_object_handlers *zend_get_std_object_handlers(void)
+{
+	return &std_object_handlers;
+}
 
 #define ZEND_PROPERTY_ISSET     0x0          /* Property exists and is not NULL */
 #define ZEND_PROPERTY_NOT_EMPTY ZEND_ISEMPTY /* Property is not empty */
@@ -251,7 +249,7 @@ ZEND_API void zend_class_init_statics(zend_class_entry *ce);
 ZEND_API zend_function *zend_std_get_static_method(const 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(const zend_class_entry *ce, const zend_string *property_name);
+ZEND_API ZEND_COLD void 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);
@@ -291,18 +289,20 @@ static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *obj
 /* Implements the fast path for array cast */
 ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj);
 
-#define ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(object) (            \
-		/* We can use zend_std_build_object_properties_array() for objects     \
-		 * without properties ht and with standard handlers */                 \
-		Z_OBJ_P(object)->properties == NULL                                    \
-		&& Z_OBJ_HT_P(object)->get_properties_for == NULL                      \
-		&& Z_OBJ_HT_P(object)->get_properties == zend_std_get_properties       \
-		/* For initialized proxies we need to forward to the real instance */  \
-		&& (                                                                   \
-			!zend_object_is_lazy_proxy(Z_OBJ_P(object))                        \
-			|| !zend_lazy_object_initialized(Z_OBJ_P(object))                  \
-		)                                                                      \
-)
+static zend_always_inline bool ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(const zval *zv) {
+	/* We can use zend_std_build_object_properties_array() for objects
+	 * without properties ht and with standard handlers */
+	const zend_object *obj = Z_OBJ_P(zv);
+
+	return obj->properties == NULL
+		&& obj->handlers->get_properties_for == NULL
+		&& obj->handlers->get_properties == zend_std_get_properties
+		/* For initialized proxies we need to forward to the real instance */
+		&& (
+			!zend_object_is_lazy_proxy(obj)
+			|| !zend_lazy_object_initialized(obj)
+		);
+}
 
 /* Handler for objects that cannot be meaningfully compared.
  * Only objects with the same identity will be considered equal. */
@@ -313,6 +313,7 @@ ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_
 ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_string *prop_info_name, bool is_dynamic);
 
 ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(const zend_function *fbc, zend_string *method_name);
+ZEND_API void zend_free_trampoline(zend_function *func);
 
 ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *member);
 
@@ -336,20 +337,12 @@ ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_p
 
 void zend_object_handlers_startup(void);
 
-#define zend_release_properties(ht) do { \
-	if (ht) { \
-		zend_array_release(ht); \
-	} \
-} while (0)
-
-#define zend_free_trampoline(func) do { \
-		if ((func) == &EG(trampoline)) { \
-			EG(trampoline).common.attributes = NULL; \
-			EG(trampoline).common.function_name = NULL; \
-		} else { \
-			efree(func); \
-		} \
-	} while (0)
+static zend_always_inline void zend_release_properties(HashTable *ht)
+{
+	if (ht) {
+		zend_array_release(ht);
+	}
+}
 
 /* Fallback to default comparison implementation if the arguments aren't both objects
  * and have the same compare() handler. You'll likely want to use this unless you
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 6f6a82638944..474157e73d39 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -194,14 +193,14 @@ ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce)
 	return object;
 }
 
-ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object)
+ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object)
 {
 	bool has_clone_method = old_object->ce->clone != NULL;
 
 	if (old_object->ce->default_properties_count) {
-		zval *src = old_object->properties_table;
+		const zval *src = old_object->properties_table;
 		zval *dst = new_object->properties_table;
-		zval *end = src + old_object->ce->default_properties_count;
+		const zval *end = src + old_object->ce->default_properties_count;
 
 		do {
 			i_zval_ptr_dtor(dst);
@@ -322,6 +321,14 @@ ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const
 		} ZEND_HASH_FOREACH_END();
 
 		EG(fake_scope) = old_scope;
+
+		/* Lock readonly properties once more. */
+		if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) {
+			for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) {
+				zval* prop = OBJ_PROP_NUM(new_object, i);
+				Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE;
+			}
+		}
 	}
 
 	return new_object;
diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h
index 712fd442da5a..0930fa043101 100644
--- a/Zend/zend_objects.h
+++ b/Zend/zend_objects.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -25,7 +24,7 @@
 BEGIN_EXTERN_C()
 ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce);
 ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce);
-ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object);
+ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object);
 
 ZEND_API void zend_object_std_dtor(zend_object *object);
 ZEND_API void zend_objects_destroy_object(zend_object *object);
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index c19873cf3be3..537cad8a3644 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -44,8 +43,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_sto
 {
 	EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE;
 	if (objects->top > 1) {
-		uint32_t i;
-		for (i = 1; i < objects->top; i++) {
+		for (uint32_t i = 1; i < objects->top; i++) {
 			zend_object *obj = objects->object_buckets[i];
 			if (IS_OBJ_VALID(obj)) {
 				if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
@@ -128,20 +126,19 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
 /* Store objects API */
 static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_objects_store_put_cold(zend_object *object)
 {
-	int handle;
 	uint32_t new_size = 2 * EG(objects_store).size;
 
 	EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*));
 	/* Assign size after realloc, in case it fails */
 	EG(objects_store).size = new_size;
-	handle = EG(objects_store).top++;
+	uint32_t handle = EG(objects_store).top++;
 	object->handle = handle;
 	EG(objects_store).object_buckets[handle] = object;
 }
 
 ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
 {
-	int handle;
+	uint32_t handle;
 
 	/* When in shutdown sequence - do not reuse previously freed handles, to make sure
 	 * the dtors for newly created objects are called in zend_objects_store_call_destructors() loop
diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h
index 86c3a49f8c8c..434ac4499e7f 100644
--- a/Zend/zend_objects_API.h
+++ b/Zend/zend_objects_API.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -80,7 +79,7 @@ static zend_always_inline void zend_object_release(zend_object *obj)
 	}
 }
 
-static zend_always_inline size_t zend_object_properties_size(zend_class_entry *ce)
+static zend_always_inline size_t zend_object_properties_size(const zend_class_entry *ce)
 {
 	return sizeof(zval) *
 		(ce->default_properties_count -
@@ -90,7 +89,7 @@ static zend_always_inline size_t zend_object_properties_size(zend_class_entry *c
 /* Allocates object type and zeros it, but not the standard zend_object and properties.
  * Standard object MUST be initialized using zend_object_std_init().
  * Properties MUST be initialized using object_properties_init(). */
-static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_entry *ce) {
+static zend_always_inline void *zend_object_alloc(size_t obj_size, const zend_class_entry *ce) {
 	void *obj = emalloc(obj_size + zend_object_properties_size(ce));
 	memset(obj, 0, obj_size - sizeof(zend_object));
 	return obj;
@@ -137,6 +136,11 @@ static inline zend_property_info *zend_get_typed_property_info_for_slot(zend_obj
 	return NULL;
 }
 
+static zend_always_inline zend_class_entry *zend_get_function_root_class(const zend_function *fbc)
+{
+	return fbc->common.prototype ? fbc->common.prototype->common.scope : fbc->common.scope;
+}
+
 static zend_always_inline bool zend_check_method_accessible(const zend_function *fn, const zend_class_entry *scope)
 {
 	if (!(fn->common.fn_flags & ZEND_ACC_PUBLIC)
diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c
index bee20bdbc20d..1cb4373f4c07 100644
--- a/Zend/zend_observer.c
+++ b/Zend/zend_observer.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Levi Morrison                                |
    |          Sammy Kaye Powers                           |
@@ -168,7 +167,7 @@ static bool zend_observer_remove_handler(void **first_handler, const void *old_h
 				*next_handler = NULL;
 			} else {
 				if (cur_handler != last_handler) {
-					memmove(cur_handler, cur_handler + 1, sizeof(cur_handler) * (last_handler - cur_handler));
+					memmove(cur_handler, cur_handler + 1, sizeof(*cur_handler) * (last_handler - cur_handler));
 				}
 				*last_handler = NULL;
 				*next_handler = *cur_handler;
@@ -219,7 +218,7 @@ ZEND_API void zend_observer_add_end_handler(const zend_function *function, zend_
 	if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) {
 		// there's no space for new handlers, then it's forbidden to call this function
 		ZEND_ASSERT(end_handler[registered_observers - 1] == NULL);
-		memmove(end_handler + 1, end_handler, sizeof(end_handler) * (registered_observers - 1));
+		memmove(end_handler + 1, end_handler, sizeof(*end_handler) * (registered_observers - 1));
 	} else if (*begin_handler == ZEND_OBSERVER_NONE_OBSERVED) {
 		*begin_handler = ZEND_OBSERVER_NOT_OBSERVED;
 	}
diff --git a/Zend/zend_observer.h b/Zend/zend_observer.h
index cfec5200055a..bcfba35c0658 100644
--- a/Zend/zend_observer.h
+++ b/Zend/zend_observer.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Levi Morrison                                |
    |          Sammy Kaye Powers                           |
@@ -33,8 +32,9 @@ extern ZEND_API bool zend_observer_errors_observed;
 extern ZEND_API bool zend_observer_function_declared_observed;
 extern ZEND_API bool zend_observer_class_linked_observed;
 
-#define ZEND_OBSERVER_HANDLE(function) (ZEND_USER_CODE((function)->type) \
-	? zend_observer_fcall_op_array_extension : zend_observer_fcall_internal_function_extension)
+static zend_always_inline int ZEND_OBSERVER_HANDLE(const zend_function *function) {
+	return ZEND_USER_CODE(function->common.type) ? zend_observer_fcall_op_array_extension : zend_observer_fcall_internal_function_extension;
+}
 
 #define ZEND_OBSERVER_DATA(function) \
 	((zend_observer_fcall_begin_handler *)&ZEND_OP_ARRAY_EXTENSION((&(function)->common), ZEND_OBSERVER_HANDLE(function)))
@@ -46,18 +46,6 @@ extern ZEND_API bool zend_observer_class_linked_observed;
 /* Omit zend_observer_fcall_internal_function_extension check, they are set at the same time. */
 #define ZEND_OBSERVER_ENABLED (zend_observer_fcall_op_array_extension != -1)
 
-#define ZEND_OBSERVER_FCALL_BEGIN(execute_data) do { \
-		if (ZEND_OBSERVER_ENABLED) { \
-			zend_observer_fcall_begin(execute_data); \
-		} \
-	} while (0)
-
-#define ZEND_OBSERVER_FCALL_END(execute_data, return_value) do { \
-		if (ZEND_OBSERVER_ENABLED) { \
-			zend_observer_fcall_end(execute_data, return_value); \
-		} \
-	} while (0)
-
 typedef void (*zend_observer_fcall_begin_handler)(zend_execute_data *execute_data);
 typedef void (*zend_observer_fcall_end_handler)(zend_execute_data *execute_data, zval *retval);
 
@@ -88,6 +76,12 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute
 /* prechecked: the call is actually observed. */
 ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin_prechecked(zend_execute_data *execute_data, zend_observer_fcall_begin_handler *observer_data);
 
+static zend_always_inline void ZEND_OBSERVER_FCALL_BEGIN(zend_execute_data *execute_data) {
+	if (ZEND_OBSERVER_ENABLED) {
+		zend_observer_fcall_begin(execute_data);
+	}
+}
+
 static zend_always_inline bool zend_observer_handler_is_unobserved(const zend_observer_fcall_begin_handler *handler) {
 	return *handler == ZEND_OBSERVER_NONE_OBSERVED;
 }
@@ -127,6 +121,12 @@ static zend_always_inline void zend_observer_fcall_end(zend_execute_data *execut
 	}
 }
 
+static zend_always_inline void ZEND_OBSERVER_FCALL_END(zend_execute_data *execute_data, zval *return_value) {
+	if (ZEND_OBSERVER_ENABLED) {
+		zend_observer_fcall_end(execute_data, return_value);
+	}
+}
+
 ZEND_API void zend_observer_fcall_end_all(void);
 
 typedef void (*zend_observer_function_declared_cb)(zend_op_array *op_array, zend_string *name);
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 24b480ad71e6..a25f236c3c20 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -486,7 +485,7 @@ ZEND_API void destroy_zend_class(zval *zv)
 			zend_string_release_ex(ce->name, 1);
 
 			ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
-				if (fn->common.scope == ce) {
+				if (fn->common.scope == ce && !(fn->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
 					zend_free_internal_arg_info(&fn->internal_function, true);
 
 					if (fn->common.attributes) {
@@ -536,6 +535,13 @@ ZEND_API void destroy_zend_class(zval *zv)
 			if (ce->attributes) {
 				zend_hash_release(ce->attributes);
 			}
+			if (ce->num_traits > 0) {
+				for (uint32_t i = 0; i < ce->num_traits; i++) {
+					zend_string_release(ce->trait_names[i].name);
+					zend_string_release(ce->trait_names[i].lc_name);
+				}
+				free(ce->trait_names);
+			}
 			free(ce);
 			break;
 	}
@@ -648,6 +654,9 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
 			if (arg_info[i].name) {
 				zend_string_release_ex(arg_info[i].name, 0);
 			}
+			if (arg_info[i].doc_comment) {
+				zend_string_release_ex(arg_info[i].doc_comment, 0);
+			}
 			zend_type_release(arg_info[i].type, /* persistent */ false);
 		}
 		efree(arg_info);
@@ -696,6 +705,10 @@ static void zend_extension_op_array_handler(zend_extension *extension, zend_op_a
 static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num, uint32_t dst_num)
 {
 	for (uint32_t i = 0; i < op_array->last_try_catch; i++) {
+		if (!op_array->try_catch_array[i].finally_op) {
+			continue;
+		}
+
 		if ((op_num < op_array->try_catch_array[i].finally_op ||
 					op_num >= op_array->try_catch_array[i].finally_end)
 				&& (dst_num >= op_array->try_catch_array[i].finally_op &&
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 571494088e33..ab8f2c2b54f8 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -359,7 +358,7 @@ static zend_never_inline zend_result ZEND_FASTCALL _zendi_try_convert_scalar_to_
 		case IS_RESOURCE:
 		case IS_ARRAY:
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -449,6 +448,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 				ZEND_ASSERT(Z_TYPE(dst) == IS_LONG);
 				return Z_LVAL(dst);
 			}
+		case IS_UNDEF:
 		case IS_RESOURCE:
 		case IS_ARRAY:
 			*failed = true;
@@ -461,7 +461,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 				goto try_again;
 			}
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -606,7 +606,7 @@ ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -665,7 +665,7 @@ ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -747,7 +747,7 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -805,7 +805,7 @@ ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -1014,7 +1014,7 @@ ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_stri
 		case IS_REFERENCE:
 			op = Z_REFVAL_P(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return 0;
 }
@@ -1053,13 +1053,13 @@ ZEND_API double ZEND_FASTCALL zval_get_double_func(const zval *op) /* {{{ */
 		case IS_REFERENCE:
 			op = Z_REFVAL_P(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return 0.0;
 }
 /* }}} */
 
-static zend_always_inline zend_string* __zval_get_string_func(zval *op, bool try) /* {{{ */
+static zend_always_inline zend_string* __zval_get_string_func(const zval *op, bool try) /* {{{ */
 {
 try_again:
 	switch (Z_TYPE_P(op)) {
@@ -1094,25 +1094,25 @@ static zend_always_inline zend_string* __zval_get_string_func(zval *op, bool try
 			goto try_again;
 		case IS_STRING:
 			return zend_string_copy(Z_STR_P(op));
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return NULL;
 }
 /* }}} */
 
-ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op) /* {{{ */
+ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(const zval *op) /* {{{ */
 {
 	return __zval_get_string_func(op, false);
 }
 /* }}} */
 
-ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(zval *op) /* {{{ */
+ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(const zval *op) /* {{{ */
 {
 	return __zval_get_string_func(op, true);
 }
 /* }}} */
 
-static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const char *operator, zval *op1, zval *op2) /* {{{ */ {
+static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const char *operator, const zval *op1, const zval *op2) /* {{{ */ {
 	if (EG(exception)) {
 		return;
 	}
@@ -1122,7 +1122,7 @@ static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const cha
 }
 /* }}} */
 
-static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */
+static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	if (result == op1 && Z_ARR_P(op1) == Z_ARR_P(op2)) {
 		/* $a += $a */
@@ -2159,7 +2159,7 @@ has_op2_string:;
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool case_insensitive) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(const zval *op1, const zval *op2, bool case_insensitive) /* {{{ */
 {
 	zend_string *tmp_str1, *tmp_str2;
 	zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1);
@@ -2178,7 +2178,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
 	    EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
@@ -2200,7 +2200,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_case_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
 	    EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
@@ -2222,7 +2222,7 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /*
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	zend_string *tmp_str1, *tmp_str2;
 	zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1);
@@ -2235,7 +2235,7 @@ ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2)
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL numeric_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	double d1, d2;
 
@@ -2253,7 +2253,7 @@ ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zva
 }
 /* }}} */
 
-static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
+static int compare_long_to_string(zend_long lval, const zend_string *str) /* {{{ */
 {
 	zend_long str_lval;
 	double str_dval;
@@ -2275,7 +2275,7 @@ static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
 }
 /* }}} */
 
-static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
+static int compare_double_to_string(double dval, const zend_string *str) /* {{{ */
 {
 	zend_long str_lval;
 	double str_dval;
@@ -2459,7 +2459,7 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
 /* }}} */
 
 /* return int to be compatible with compare_func_t */
-static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
+static int hash_zval_identical_function(const zval *z1, const zval *z2) /* {{{ */
 {
 	/* is_identical_function() returns 1 in case of identity and 0 in case
 	 * of a difference;
@@ -2501,14 +2501,14 @@ ZEND_API bool ZEND_FASTCALL zend_is_identical(const zval *op1, const zval *op2)
 }
 /* }}} */
 
-ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	ZVAL_BOOL(result, zend_is_identical(op1, op2));
 	return SUCCESS;
 }
 /* }}} */
 
-ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	ZVAL_BOOL(result, !zend_is_identical(op1, op2));
 	return SUCCESS;
@@ -2784,7 +2784,7 @@ ZEND_API zend_result ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
 		case IS_ARRAY:
 			zend_type_error("Cannot increment %s", zend_zval_value_name(op1));
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return SUCCESS;
 }
@@ -2891,7 +2891,7 @@ ZEND_API zend_result ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
 		case IS_ARRAY:
 			zend_type_error("Cannot decrement %s", zend_zval_value_name(op1));
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 
 	return SUCCESS;
@@ -3322,8 +3322,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1,
 
 	len = MIN(len1, len2);
 	while (len--) {
-		c1 = zend_tolower((int)*(unsigned char *)s1++);
-		c2 = zend_tolower((int)*(unsigned char *)s2++);
+		c1 = zend_tolower((unsigned char)*(s1++));
+		c2 = zend_tolower((unsigned char)*(s2++));
 		if (c1 != c2) {
 			return c1 - c2;
 		}
@@ -3343,8 +3343,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
 	}
 	len = MIN(length, MIN(len1, len2));
 	while (len--) {
-		c1 = zend_tolower((int)*(unsigned char *)s1++);
-		c2 = zend_tolower((int)*(unsigned char *)s2++);
+		c1 = zend_tolower((unsigned char)*(s1++));
+		c2 = zend_tolower((unsigned char)*(s2++));
 		if (c1 != c2) {
 			return c1 - c2;
 		}
@@ -3354,19 +3354,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
-{
-	return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
-}
-/* }}} */
-
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
-{
-	return zend_binary_strncmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
-}
-/* }}} */
-
-ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zendi_smart_streq(const zend_string *s1, const zend_string *s2) /* {{{ */
 {
 	uint8_t ret1, ret2;
 	int oflow1, oflow2;
@@ -3414,7 +3402,7 @@ ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2)
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(const zend_string *s1, const zend_string *s2) /* {{{ */
 {
 	uint8_t ret1, ret2;
 	int oflow1, oflow2;
@@ -3489,7 +3477,7 @@ ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_compare_arrays(const zval *a1, const zval *a2) /* {{{ */
 {
 	return zend_compare_symbol_tables(Z_ARRVAL_P(a1), Z_ARRVAL_P(a2));
 }
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index e6d648d1208a..27aa4fdb0486 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -47,7 +46,6 @@
 #include "zend_portability.h"
 #include "zend_strtod.h"
 #include "zend_multiply.h"
-#include "zend_object_handlers.h"
 
 #define LONG_SIGN_MASK ZEND_LONG_MIN
 
@@ -71,8 +69,8 @@ ZEND_API zend_result ZEND_FASTCALL concat_function(zval *result, zval *op1, zval
 ZEND_API bool ZEND_FASTCALL zend_is_identical(const zval *op1, const zval *op2);
 
 ZEND_API zend_result ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2);
-ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2);
-ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2);
+ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, const zval *op1, const zval *op2);
+ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, const zval *op1, const zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
@@ -325,8 +323,8 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op);
 ZEND_API zend_long    ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_strict);
 ZEND_API zend_long    ZEND_FASTCALL zval_try_get_long(const zval *op, bool *failed);
 ZEND_API double       ZEND_FASTCALL zval_get_double_func(const zval *op);
-ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op);
-ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(zval *op);
+ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(const zval *op);
+ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(const zval *op);
 
 static zend_always_inline zend_long zval_get_long(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_LONG) ? Z_LVAL_P(op) : zval_get_long_func(op, false);
@@ -337,11 +335,11 @@ static zend_always_inline zend_long zval_get_long_ex(const zval *op, bool is_str
 static zend_always_inline double zval_get_double(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_DOUBLE) ? Z_DVAL_P(op) : zval_get_double_func(op);
 }
-static zend_always_inline zend_string *zval_get_string(zval *op) {
+static zend_always_inline zend_string *zval_get_string(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_STRING) ? zend_string_copy(Z_STR_P(op)) : zval_get_string_func(op);
 }
 
-static zend_always_inline zend_string *zval_get_tmp_string(zval *op, zend_string **tmp) {
+static zend_always_inline zend_string *zval_get_tmp_string(const zval *op, zend_string **tmp) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		*tmp = NULL;
 		return Z_STR_P(op);
@@ -356,7 +354,7 @@ static zend_always_inline void zend_tmp_string_release(zend_string *tmp) {
 }
 
 /* Like zval_get_string, but returns NULL if the conversion fails with an exception. */
-static zend_always_inline zend_string *zval_try_get_string(zval *op) {
+static zend_always_inline zend_string *zval_try_get_string(const zval *op) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		zend_string *ret = zend_string_copy(Z_STR_P(op));
 		ZEND_ASSUME(ret != NULL);
@@ -367,7 +365,7 @@ static zend_always_inline zend_string *zval_try_get_string(zval *op) {
 }
 
 /* Like zval_get_tmp_string, but returns NULL if the conversion fails with an exception. */
-static zend_always_inline zend_string *zval_try_get_tmp_string(zval *op, zend_string **tmp) {
+static zend_always_inline zend_string *zval_try_get_tmp_string(const zval *op, zend_string **tmp) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		zend_string *ret = Z_STR_P(op);
 		*tmp = NULL;
@@ -458,11 +456,11 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2);
 
 ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2);
 
-ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool case_insensitive);
-ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2);
+ZEND_API int ZEND_FASTCALL numeric_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(const zval *op1, const zval *op2, bool case_insensitive);
+ZEND_API int ZEND_FASTCALL string_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_case_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(const zval *op1, const zval *op2);
 
 ZEND_API extern const unsigned char zend_tolower_map[256];
 ZEND_API extern const unsigned char zend_toupper_map[256];
@@ -488,8 +486,6 @@ static zend_always_inline zend_string* zend_string_toupper(zend_string *str) {
 	return zend_string_toupper_ex(str, false);
 }
 
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2);
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
 ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2);
 ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
 ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
@@ -497,10 +493,10 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1,
 ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
 ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
 
-ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2);
-ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2);
+ZEND_API bool ZEND_FASTCALL zendi_smart_streq(const zend_string *s1, const zend_string *s2);
+ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(const zend_string *s1, const zend_string *s2);
 ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2);
-ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2);
+ZEND_API int ZEND_FASTCALL zend_compare_arrays(const zval *a1, const zval *a2);
 ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2);
 
 /** Deprecated in favor of ZEND_STRTOL() */
@@ -947,7 +943,7 @@ static zend_always_inline bool fast_equal_check_string(zval *op1, zval *op2)
 	return zend_compare(op1, op2) == 0;
 }
 
-static zend_always_inline bool fast_is_identical_function(zval *op1, zval *op2)
+static zend_always_inline bool fast_is_identical_function(const zval *op1, const zval *op2)
 {
 	if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
 		return 0;
@@ -957,7 +953,7 @@ static zend_always_inline bool fast_is_identical_function(zval *op1, zval *op2)
 	return zend_is_identical(op1, op2);
 }
 
-static zend_always_inline bool fast_is_not_identical_function(zval *op1, zval *op2)
+static zend_always_inline bool fast_is_not_identical_function(const zval *op1, const zval *op2)
 {
 	if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
 		return 1;
diff --git a/Zend/zend_partial.c b/Zend/zend_partial.c
new file mode 100644
index 000000000000..e7a3e1c92b58
--- /dev/null
+++ b/Zend/zend_partial.c
@@ -0,0 +1,1179 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
+   +----------------------------------------------------------------------+
+   | Authors: Arnaud Le Blanc                        |
+   +----------------------------------------------------------------------+
+*/
+
+/**
+ * Partial Function Application:
+ *
+ * A partial application is compiled to the usual sequence of function call
+ * opcodes (INIT_FCALL, SEND_VAR, etc), but the sequence ends with a
+ * CALLABLE_CONVERT_PARTIAL opcode instead of DO_FCALL, similarly to
+ * first class callables. Placeholders are compiled to SEND_PLACEHOLDER opcodes:
+ *
+ * $f = f($a, ?)
+ *
+ * 0001 INIT_FCALL f
+ * 0002 SEND_VAR CV($a)
+ * 0003 SEND_PLACEHOLDER
+ * 0004 CV($f) = CALLABLE_CONVERT_PARTIAL
+ *
+ * SEND_PLACEHOLDER sets the argument slot type to _IS_PLACEHOLDER.
+ *
+ * CALLABLE_CONVERT_PARTIAL uses the information available on the stack to
+ * create a Closure and return it, consuming the stack frame in the process
+ * like an internal function call.
+ *
+ * We create the Closure by generating the relevant AST and compiling it to an
+ * op_array. The op_array is cached in the Opcache SHM and inline caches.
+ *
+ * This file implements the Closure generation logic
+ * (see zend_partial_create(), zp_compile()).
+ */
+
+#include "zend.h"
+#include "zend_API.h"
+#include "zend_arena.h"
+#include "zend_ast.h"
+#include "zend_compile.h"
+#include "zend_closures.h"
+#include "zend_attributes.h"
+#include "zend_exceptions.h"
+#include "ext/opcache/ZendAccelerator.h"
+
+static zend_always_inline bool Z_IS_PLACEHOLDER_P(const zval *p) {
+	return Z_TYPE_P(p) == _IS_PLACEHOLDER;
+}
+
+static zend_always_inline bool zp_is_static_closure(const zend_function *function) {
+	return ((function->common.fn_flags & (ZEND_ACC_STATIC|ZEND_ACC_CLOSURE)) == (ZEND_ACC_STATIC|ZEND_ACC_CLOSURE));
+}
+
+static zend_always_inline bool zp_is_non_static_closure(const zend_function *function) {
+	return ((function->common.fn_flags & (ZEND_ACC_STATIC|ZEND_ACC_CLOSURE)) == ZEND_ACC_CLOSURE);
+}
+
+static zend_never_inline ZEND_COLD void zp_args_underflow(
+		const zend_function *function, uint32_t args, uint32_t expected)
+{
+	zend_string *symbol = get_function_or_method_name(function);
+	const char *limit = function->common.num_args <= function->common.required_num_args ?
+			"exactly" : "at least";
+
+	zend_argument_count_error(
+		"Partial application of %s() expects %s %d arguments, %d given",
+		ZSTR_VAL(symbol), limit, expected, args);
+
+	zend_string_release(symbol);
+}
+
+static zend_never_inline ZEND_COLD void zp_args_overflow(
+		const zend_function *function, uint32_t args, uint32_t expected)
+{
+	zend_string *symbol = get_function_or_method_name(function);
+
+	zend_argument_count_error(
+		"Partial application of %s() expects at most %d arguments, %d given",
+		ZSTR_VAL(symbol), expected, args);
+
+	zend_string_release(symbol);
+}
+
+static zend_result zp_args_check(const zend_function *function,
+		uint32_t argc, const zval *argv,
+		const zend_array *extra_named_args,
+		bool uses_variadic_placeholder) {
+
+	if (extra_named_args) {
+		ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(extra_named_args, zend_string *key, zval *arg) {
+			if (UNEXPECTED(Z_IS_PLACEHOLDER_P(arg))) {
+				zend_throw_error(NULL,
+						"Cannot use named placeholder for unknown or variadic parameter $%s",
+						ZSTR_VAL(key));
+				return FAILURE;
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	if (argc < function->common.required_num_args) {
+		if (uses_variadic_placeholder) {
+			/* Missing args will be turned into placeholders */
+			return SUCCESS;
+		}
+
+		zp_args_underflow(function, argc, function->common.required_num_args);
+		return FAILURE;
+	} else if (argc > function->common.num_args
+			&& !(function->common.fn_flags & ZEND_ACC_VARIADIC)) {
+		zp_args_overflow(function, argc, function->common.num_args);
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+
+typedef struct zp_names {
+	zend_string *variadic_param;
+	zend_string *extra_named_params;
+	zend_string *inner_closure;
+	zend_string *params[1]; /* argc elements */
+} zp_names;
+
+static bool zp_name_exists(const zp_names *names, uint32_t argc, const zend_string *name)
+{
+	for (uint32_t i = 0; i < argc; i++) {
+		if (names->params[i] && zend_string_equals(names->params[i], name)) {
+			return true;
+		}
+	}
+	if (names->variadic_param && zend_string_equals(names->variadic_param, name)) {
+		return true;
+	}
+	if (names->extra_named_params && zend_string_equals(names->extra_named_params, name)) {
+		return true;
+	}
+	if (names->inner_closure && zend_string_equals(names->inner_closure, name)) {
+		return true;
+	}
+
+	return false;
+}
+
+static void zp_names_dtor(zp_names *names, uint32_t argc)
+{
+	for (uint32_t i = 0; i < argc; i++) {
+		if (names->params[i]) {
+			zend_string_release(names->params[i]);
+		}
+	}
+	if (names->variadic_param) {
+		zend_string_release(names->variadic_param);
+	}
+	if (names->extra_named_params) {
+		zend_string_release(names->extra_named_params);
+	}
+	if (names->inner_closure) {
+		zend_string_release(names->inner_closure);
+	}
+}
+
+static zend_string *zp_get_func_param_name(const zend_function *function, uint32_t arg_offset)
+{
+	return zend_string_copy(function->common.arg_info[arg_offset].name);
+}
+
+/* Assign a name for every variable that will be used in the generated closure,
+ * including params and used vars. */
+static zp_names *zp_assign_names(uint32_t argc, zval *argv,
+		zend_function *function, bool variadic_partial,
+		zend_array *extra_named_params)
+{
+	zp_names *names = zend_arena_calloc(&CG(ast_arena),
+			1, zend_safe_address_guarded(argc, sizeof(*names->params), offsetof(zp_names, params)));
+
+	/* Assign names for params. We never rename those. */
+	for (uint32_t offset = 0, num_args = MIN(argc, function->common.num_args);
+			offset < num_args; offset++) {
+		if (Z_IS_PLACEHOLDER_P(&argv[offset])) {
+			names->params[offset] = zp_get_func_param_name(function, offset);
+		}
+	}
+
+	/* Assign name for the variadic param. Never renamed. */
+	if (variadic_partial && (function->common.fn_flags & ZEND_ACC_VARIADIC)) {
+		names->variadic_param = zp_get_func_param_name(function, function->common.num_args);
+	}
+
+	/* Assign names for placeholders that bind to the variadic param:
+	 *
+	 * function f($a, ...$args) {}
+	 * f(?, ?, ...); // The second placeholder binds into the variadic param.
+	 *
+	 * By default these are named $origNameN with N the offset from the
+	 * variadic param. In case of clash we increment N until a free name is
+	 * found. */
+	for (uint32_t offset = function->common.num_args; offset < argc; offset++) {
+		ZEND_ASSERT(function->common.fn_flags & ZEND_ACC_VARIADIC);
+		if (!Z_IS_PLACEHOLDER_P(&argv[offset])) {
+			continue;
+		}
+		zend_string *orig_name = zp_get_func_param_name(function, function->common.num_args);
+		zend_string *new_name;
+		for (uint32_t n = 0;; n++) {
+			new_name = zend_strpprintf_unchecked(0, "%S%" PRIu32, orig_name, n);
+			if (!zp_name_exists(names, argc, new_name)) {
+				break;
+			}
+			zend_string_release(new_name);
+		}
+		names->params[offset] = new_name;
+		zend_string_release(orig_name);
+	}
+
+	/* Assign names for pre-bound params (lexical vars).
+	 * There may be clashes, we ensure to generate unique names. */
+	for (uint32_t offset = 0; offset < argc; offset++) {
+		if (Z_IS_PLACEHOLDER_P(&argv[offset]) || Z_ISUNDEF(argv[offset])) {
+			continue;
+		}
+		uint32_t n = 2;
+		zend_string *orig_name = zp_get_func_param_name(function, MIN(offset, function->common.num_args));
+		zend_string *new_name = zend_string_copy(orig_name);
+		while (zp_name_exists(names, argc, new_name)) {
+			zend_string_release(new_name);
+			new_name = zend_strpprintf_unchecked(0, "%S%" PRIu32, orig_name, n);
+			n++;
+		}
+		names->params[offset] = new_name;
+		zend_string_release(orig_name);
+	}
+
+	/* Assign name for $extra_named_params */
+	if (extra_named_params) {
+		uint32_t n = 2;
+		zend_string *new_name = ZSTR_INIT_LITERAL("extra_named_params", 0);
+		while (zp_name_exists(names, argc, new_name)) {
+			zend_string_release(new_name);
+			new_name = zend_strpprintf(0, "%s%" PRIu32, "extra_named_params", n);
+			n++;
+		}
+		names->extra_named_params = new_name;
+	}
+
+	/* Assign name for $fn */
+	if (function->common.fn_flags & ZEND_ACC_CLOSURE) {
+		uint32_t n = 2;
+		zend_string *new_name = ZSTR_INIT_LITERAL("fn", 0);
+		while (zp_name_exists(names, argc, new_name)) {
+			zend_string_release(new_name);
+			new_name = zend_strpprintf(0, "%s%" PRIu32, "fn", n);
+			n++;
+		}
+		names->inner_closure = new_name;
+	}
+
+	return names;
+}
+
+ZEND_ATTRIBUTE_CONST static inline bool zp_is_power_of_two(uint32_t x)
+{
+	return (x > 0) && !(x & (x - 1));
+}
+
+ZEND_ATTRIBUTE_CONST static bool zp_is_simple_type(uint32_t type_mask)
+{
+	ZEND_ASSERT(!(type_mask & ~_ZEND_TYPE_MAY_BE_MASK));
+
+	return zp_is_power_of_two(type_mask)
+		|| type_mask == MAY_BE_BOOL
+		|| type_mask == MAY_BE_ANY;
+}
+
+static zend_ast *zp_simple_type_to_ast(uint32_t type)
+{
+	zend_string *name;
+
+	switch (type) {
+		case MAY_BE_NULL:
+			name = ZSTR_KNOWN(ZEND_STR_NULL_LOWERCASE);
+			break;
+		case MAY_BE_TRUE:
+			name = ZSTR_KNOWN(ZEND_STR_TRUE);
+			break;
+		case MAY_BE_FALSE:
+			name = ZSTR_KNOWN(ZEND_STR_FALSE);
+			break;
+		case MAY_BE_LONG:
+			name = ZSTR_KNOWN(ZEND_STR_INT);
+			break;
+		case MAY_BE_DOUBLE:
+			name = ZSTR_KNOWN(ZEND_STR_FLOAT);
+			break;
+		case MAY_BE_STRING:
+			name = ZSTR_KNOWN(ZEND_STR_STRING);
+			break;
+		case MAY_BE_BOOL:
+			name = ZSTR_KNOWN(ZEND_STR_BOOL);
+			break;
+		case MAY_BE_VOID:
+			name = ZSTR_KNOWN(ZEND_STR_VOID);
+			break;
+		case MAY_BE_NEVER:
+			name = ZSTR_KNOWN(ZEND_STR_NEVER);
+			break;
+		case MAY_BE_OBJECT:
+			name = ZSTR_KNOWN(ZEND_STR_OBJECT);
+			break;
+		case MAY_BE_ANY:
+			name = ZSTR_KNOWN(ZEND_STR_MIXED);
+			break;
+		case MAY_BE_CALLABLE:
+			return zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE);
+		case MAY_BE_ARRAY:
+			return zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY);
+		case MAY_BE_STATIC:
+			return zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC);
+		default:
+			ZEND_UNREACHABLE();
+	}
+
+	zend_ast *ast = zend_ast_create_zval_from_str(name);
+	ast->attr = ZEND_NAME_NOT_FQ;
+
+	return ast;
+}
+
+static zend_ast *zp_type_name_to_ast(zend_string *name)
+{
+	zend_ast *ast = zend_ast_create_zval_from_str(name);
+
+	if (zend_get_class_fetch_type(name) != ZEND_FETCH_CLASS_DEFAULT) {
+		ast->attr = ZEND_NAME_NOT_FQ;
+	} else {
+		ast->attr = ZEND_NAME_FQ;
+	}
+
+	return ast;
+}
+
+static zend_ast *zp_type_to_ast(const zend_type type)
+{
+	if (!ZEND_TYPE_IS_SET(type)) {
+		return NULL;
+	}
+
+	if (ZEND_TYPE_IS_UNION(type)
+			|| (ZEND_TYPE_IS_COMPLEX(type) && ZEND_TYPE_PURE_MASK(type))
+			|| (ZEND_TYPE_PURE_MASK(type) && !zp_is_simple_type(ZEND_TYPE_PURE_MASK(type)))) {
+		/* This is a union type */
+
+		zend_ast *type_ast = zend_ast_create_list(0, ZEND_AST_TYPE_UNION);
+
+		/* Add complex types if any */
+		if (ZEND_TYPE_HAS_LIST(type)) {
+			ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), const zend_type *type_ptr) {
+				type_ast = zend_ast_list_add(type_ast, zp_type_to_ast(*type_ptr));
+			} ZEND_TYPE_LIST_FOREACH_END();
+		} else if (ZEND_TYPE_HAS_NAME(type)) {
+			zend_ast *name_ast = zp_type_name_to_ast(
+					zend_string_copy(ZEND_TYPE_NAME(type)));
+			type_ast = zend_ast_list_add(type_ast, name_ast);
+		} else {
+			ZEND_ASSERT(!ZEND_TYPE_IS_COMPLEX(type));
+		}
+
+		/* Add simple types if any */
+		uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
+
+		/* IS_TRUE|IS_FALSE is represented as a single bool node */
+		if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) {
+			type_ast = zend_ast_list_add(type_ast, zp_simple_type_to_ast(MAY_BE_BOOL));
+			type_mask &= ~MAY_BE_BOOL;
+		}
+		for (uint32_t may_be_type = 1; may_be_type < _ZEND_TYPE_MAY_BE_MASK; may_be_type <<= 1) {
+			if (type_mask & may_be_type) {
+				type_ast = zend_ast_list_add(type_ast, zp_simple_type_to_ast(may_be_type));
+			}
+		}
+
+		return type_ast;
+	}
+
+	if (ZEND_TYPE_IS_INTERSECTION(type)) {
+		ZEND_ASSERT(!ZEND_TYPE_PURE_MASK(type));
+		zend_ast *type_ast = zend_ast_create_list(0, ZEND_AST_TYPE_INTERSECTION);
+		ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), const zend_type *type_ptr) {
+			type_ast = zend_ast_list_add(type_ast, zp_type_to_ast(*type_ptr));
+		} ZEND_TYPE_LIST_FOREACH_END();
+		return type_ast;
+	}
+
+	if (ZEND_TYPE_HAS_NAME(type)) {
+		ZEND_ASSERT(!ZEND_TYPE_PURE_MASK(type));
+		zend_ast *type_ast = zp_type_name_to_ast(
+				zend_string_copy(ZEND_TYPE_NAME(type)));
+		return type_ast;
+	}
+
+	ZEND_ASSERT(!ZEND_TYPE_IS_COMPLEX(type));
+
+	uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
+	ZEND_ASSERT(zp_is_simple_type(type_mask));
+
+	return zp_simple_type_to_ast(type_mask);
+}
+
+static zend_result zp_get_param_default_value(zval *result, zend_function *function, uint32_t arg_offset)
+{
+	ZEND_ASSERT(arg_offset < function->common.num_args);
+
+	if (function->type == ZEND_USER_FUNCTION) {
+		zend_op *opline = &function->op_array.opcodes[arg_offset];
+		if (EXPECTED(opline->opcode == ZEND_RECV_INIT)) {
+			ZVAL_COPY(result, RT_CONSTANT(opline, opline->op2));
+			return SUCCESS;
+		}
+		ZEND_ASSERT(opline->opcode == ZEND_RECV);
+	} else {
+		if (function->common.fn_flags & ZEND_ACC_USER_ARG_INFO) {
+			goto error;
+		}
+
+		const zend_arg_info *arg_info = &function->internal_function.arg_info[arg_offset];
+
+		if (zend_get_default_from_internal_arg_info(result, arg_info) == SUCCESS) {
+			return SUCCESS;
+		}
+	}
+
+error:
+	zend_argument_error_ex(zend_ce_argument_count_error, function, arg_offset + 1,
+			"must be passed explicitly, because the default value is not known");
+
+	return FAILURE;
+}
+
+static bool zp_arg_must_be_sent_by_ref(const zend_function *function, uint32_t arg_num)
+{
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(function, arg_num)) {
+			return true;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(function, arg_num)) {
+		return true;
+	}
+	return false;
+}
+
+static zend_ast *zp_attribute_to_ast(zend_attribute *attribute)
+{
+	zend_ast *args_ast;
+	if (attribute->argc) {
+		args_ast = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST);
+		for (uint32_t i = 0; i < attribute->argc; i++) {
+			zend_ast *arg_ast = zend_ast_create_zval(&attribute->args[i].value);
+			if (attribute->args[i].name) {
+				arg_ast = zend_ast_create(ZEND_AST_NAMED_ARG,
+						zend_ast_create_zval_from_str(
+							zend_string_copy(attribute->args[i].name)),
+						arg_ast);
+			}
+			args_ast = zend_ast_list_add(args_ast, arg_ast);
+		}
+	} else {
+		args_ast = NULL;
+	}
+	return zend_ast_create(ZEND_AST_ATTRIBUTE,
+			zend_ast_create_zval_from_str(zend_string_copy(attribute->name)),
+			args_ast);
+}
+
+static zend_ast *zp_param_attributes_to_ast(zend_function *function,
+		uint32_t offset)
+{
+	zend_ast *attributes_ast = NULL;
+	if (!function->common.attributes) {
+		return NULL;
+	}
+
+	/* Inherit the SensitiveParameter attribute */
+	zend_attribute *attr = zend_get_parameter_attribute_str(
+			function->common.attributes,
+			"sensitiveparameter", strlen("sensitiveparameter"), offset);
+	if (attr) {
+		attributes_ast = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_GROUP,
+				zp_attribute_to_ast(attr));
+		attributes_ast = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_LIST,
+				attributes_ast);
+	}
+
+	return attributes_ast;
+}
+
+static zend_string *zp_pfa_name(const zend_op_array *declaring_op_array,
+		const zend_op *declaring_opline)
+{
+	/* We attempt to generate a name that hints at where the PFA was created,
+	 * similarly to Closures (GH-13550).
+	 * We do not attempt to make the name unique. */
+
+	zend_string *filename = declaring_op_array->filename;
+	uint32_t start_lineno = declaring_opline->lineno;
+
+	zend_string *class = zend_empty_string;
+	zend_string *separator = zend_empty_string;
+	zend_string *function = filename;
+	const char *parens = "";
+
+	if (declaring_op_array->function_name) {
+		function = declaring_op_array->function_name;
+		if (declaring_op_array->fn_flags & ZEND_ACC_CLOSURE) {
+			/* If the parent function is a closure, don't redundantly
+			 * add the classname and parentheses. */
+		} else {
+			parens = "()";
+
+			if (declaring_op_array->scope && declaring_op_array->scope->name) {
+				class = declaring_op_array->scope->name;
+				separator = ZSTR_KNOWN(ZEND_STR_PAAMAYIM_NEKUDOTAYIM);
+			}
+		}
+	}
+
+	zend_string *name = zend_strpprintf_unchecked(
+		0,
+		"{closure:pfa:%S%S%S%s:%" PRIu32 "}",
+		class,
+		separator,
+		function,
+		parens,
+		start_lineno
+	);
+
+	return name;
+}
+
+/* Generate the AST for calling the actual function */
+static zend_ast *zp_compile_forwarding_call(
+	zval *this_ptr, zend_function *function,
+	uint32_t argc, zval *argv, zend_array *extra_named_params,
+	zp_names *var_names, bool uses_variadic_placeholder, uint32_t num_args,
+	zend_class_entry *called_scope, zend_type return_type,
+	bool forward_superfluous_args,
+	zend_ast *stmts_ast)
+{
+	bool is_assert = zend_string_equals(function->common.function_name,
+			ZSTR_KNOWN(ZEND_STR_ASSERT));
+
+	zend_ast *args_ast = zend_ast_create_list(0, ZEND_AST_ARG_LIST);
+	zend_ast *call_ast = NULL;
+
+	if (is_assert) {
+		/* We are going to call assert() dynamically (via call_user_func),
+		 * otherwise assert() would print the generated AST on failure, which is
+		 * irrelevant. */
+		args_ast = zend_ast_list_add(args_ast,
+				zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_ASSERT)));
+	}
+
+	/* Generate positional arguments */
+	for (uint32_t offset = 0; offset < argc; offset++) {
+		if (Z_ISUNDEF(argv[offset])) {
+			/* Argument was not passed. Pass its default value. */
+			if (offset < function->common.required_num_args) {
+				/* Required param was not passed. This can happen due to named
+				 * args. Using the same exception CE and message as
+				 * zend_handle_undef_args(). */
+				zend_argument_error_ex(zend_ce_argument_count_error, function, offset + 1, "not passed");
+				goto error;
+			}
+			zval default_value;
+			if (zp_get_param_default_value(&default_value, function, offset) == FAILURE) {
+				ZEND_ASSERT(EG(exception));
+				goto error;
+			}
+			zend_ast *default_value_ast;
+			if (Z_TYPE(default_value) == IS_CONSTANT_AST) {
+				/* Must dup AST because we are going to destroy it */
+				default_value_ast = zend_ast_dup(Z_ASTVAL(default_value));
+				zval_ptr_dtor_nogc(&default_value);
+			} else {
+				default_value_ast = zend_ast_create_zval(&default_value);
+			}
+			args_ast = zend_ast_list_add(args_ast, default_value_ast);
+		} else {
+			args_ast = zend_ast_list_add(args_ast, zend_ast_create(ZEND_AST_VAR,
+						zend_ast_create_zval_from_str(zend_string_copy(var_names->params[offset]))));
+		}
+	}
+	/* Use unpacking to pass extra named params */
+	if (extra_named_params) {
+		args_ast = zend_ast_list_add(args_ast, zend_ast_create(ZEND_AST_UNPACK,
+					zend_ast_create(ZEND_AST_VAR,
+						zend_ast_create_zval_from_str(zend_string_copy(var_names->extra_named_params)))));
+	}
+	if (uses_variadic_placeholder) {
+		if (function->common.fn_flags & ZEND_ACC_VARIADIC) {
+			/* Pass variadic params */
+			args_ast = zend_ast_list_add(args_ast, zend_ast_create(ZEND_AST_UNPACK,
+						zend_ast_create(ZEND_AST_VAR,
+							zend_ast_create_zval_from_str(zend_string_copy(var_names->variadic_param)))));
+		} else if (forward_superfluous_args) {
+			/* When a '...' placeholder is used, and the underlying function is
+			 * not variadic, superfluous arguments are forwarded.
+			 * Add a ...array_slice(func_get_args(), n) argument, which should
+			 * be compiled as ZEND_AST_UNPACK + ZEND_FUNC_GET_ARGS. */
+
+			zend_ast *func_get_args_name_ast = zend_ast_create_zval_from_str(
+					zend_string_copy(ZSTR_KNOWN(ZEND_STR_FUNC_GET_ARGS)));
+			func_get_args_name_ast->attr = ZEND_NAME_FQ;
+
+			zend_ast *array_slice_name_ast = zend_ast_create_zval_from_str(
+					zend_string_copy(ZSTR_KNOWN(ZEND_STR_ARRAY_SLICE)));
+			array_slice_name_ast->attr = ZEND_NAME_FQ;
+
+			args_ast = zend_ast_list_add(args_ast,
+				zend_ast_create(ZEND_AST_UNPACK,
+					zend_ast_create(ZEND_AST_CALL,
+							array_slice_name_ast,
+							zend_ast_create_list(2, ZEND_AST_ARG_LIST,
+								zend_ast_create(ZEND_AST_CALL,
+									func_get_args_name_ast,
+									zend_ast_create_list(0, ZEND_AST_ARG_LIST)),
+								zend_ast_create_zval_from_long(num_args)))));
+		}
+	}
+
+	if (is_assert) {
+		zend_ast *func_name_ast = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CALL_USER_FUNC));
+		func_name_ast->attr = ZEND_NAME_FQ;
+		call_ast = zend_ast_create(ZEND_AST_CALL, func_name_ast, args_ast);
+	} else if (function->common.fn_flags & ZEND_ACC_CLOSURE) {
+		zend_ast *fn_ast = zend_ast_create(ZEND_AST_VAR,
+					zend_ast_create_zval_from_str(zend_string_copy(var_names->inner_closure)));
+		call_ast = zend_ast_create(ZEND_AST_CALL, fn_ast, args_ast);
+	} else if (Z_TYPE_P(this_ptr) == IS_OBJECT) {
+		zend_ast *this_ast = zend_ast_create(ZEND_AST_VAR,
+					zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_THIS)));
+		zend_ast *method_name_ast = zend_ast_create_zval_from_str(
+				zend_string_copy(function->common.function_name));
+		call_ast = zend_ast_create(ZEND_AST_METHOD_CALL, this_ast,
+				method_name_ast, args_ast);
+	} else if (called_scope) {
+		zend_ast *class_name_ast = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_STATIC));
+		class_name_ast->attr = ZEND_NAME_NOT_FQ;
+		zend_ast *method_name_ast = zend_ast_create_zval_from_str(
+				zend_string_copy(function->common.function_name));
+		call_ast = zend_ast_create(ZEND_AST_STATIC_CALL, class_name_ast,
+				method_name_ast, args_ast);
+	} else {
+		zend_ast *func_name_ast = zend_ast_create_zval_from_str(zend_string_copy(function->common.function_name));
+		func_name_ast->attr = ZEND_NAME_FQ;
+		call_ast = zend_ast_create(ZEND_AST_CALL, func_name_ast, args_ast);
+	}
+
+	/* Void functions can not 'return $expr' */
+	if (ZEND_TYPE_FULL_MASK(return_type) & MAY_BE_VOID) {
+		stmts_ast = zend_ast_list_add(stmts_ast, call_ast);
+	} else {
+		zend_ast *return_ast = zend_ast_create(ZEND_AST_RETURN, call_ast);
+		stmts_ast = zend_ast_list_add(stmts_ast, return_ast);
+	}
+
+	return stmts_ast;
+
+error:
+	zend_ast_destroy(args_ast);
+	zend_ast_destroy(call_ast);
+	return NULL;
+}
+
+static uint32_t zp_compute_num_required(const zend_function *function,
+		uint32_t orig_offset, uint32_t new_offset, uint32_t num_required) {
+	if (orig_offset < function->common.num_args) {
+		if (orig_offset < function->common.required_num_args) {
+			num_required = MAX(num_required, new_offset + 1);
+		}
+	} else {
+		ZEND_ASSERT(function->common.fn_flags & ZEND_ACC_VARIADIC);
+		/* Placeholders that run into the variadic portion become
+		 * required and make all params before them required */
+		ZEND_ASSERT(orig_offset >= num_required);
+		num_required = new_offset + 1;
+	}
+
+	return num_required;
+}
+
+/* Compile PFA to an op_array */
+static zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
+		uint32_t argc, zval *argv, zend_array *extra_named_params,
+		const zend_array *named_positions,
+		const zend_op_array *declaring_op_array,
+		const zend_op *declaring_opline, void **cache_slot,
+		bool uses_variadic_placeholder) {
+
+	zend_op_array *op_array = NULL;
+
+	if (UNEXPECTED(function->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS)) {
+		const char *format = "Cannot call %S() dynamically";
+		zend_throw_error(NULL, format, function->common.function_name);
+		return NULL;
+	}
+
+	if (UNEXPECTED(zp_args_check(function, argc, argv, extra_named_params, uses_variadic_placeholder) != SUCCESS)) {
+		ZEND_ASSERT(EG(exception));
+		return NULL;
+	}
+
+	zend_class_entry *called_scope;
+	if (Z_TYPE_P(this_ptr) == IS_OBJECT) {
+		called_scope = Z_OBJCE_P(this_ptr);
+	} else {
+		called_scope = Z_CE_P(this_ptr);
+	}
+
+	/* CG(ast_arena) is usually NULL, so we can't just make a snapshot */
+	zend_arena *orig_ast_arena = CG(ast_arena);
+	CG(ast_arena) = zend_arena_create(1024 * 4);
+
+	uint32_t orig_lineno = CG(zend_lineno);
+	CG(zend_lineno) = zend_get_executed_lineno();
+
+	uint32_t new_argc = argc;
+
+	if (uses_variadic_placeholder) {
+		/* A variadic placeholder generates an implicit positional placeholder
+		 * for any unspecified arg, so make room for those. */
+		new_argc = MAX(new_argc, function->common.num_args);
+	}
+
+	zval *tmp = zend_arena_alloc(&CG(ast_arena), zend_safe_address_guarded(new_argc, sizeof(*tmp), 0));
+	memcpy(tmp, argv, zend_safe_address_guarded(argc, sizeof(*tmp), 0));
+	argv = tmp;
+
+	/* Compute param positions and number of required args, add implicit
+	 * placeholders.
+	 *
+	 * Parameters are placed in the following order:
+	 * - Positional placeholders
+	 * - Then named placeholders in their syntax order
+	 * - Then implicit placeholders added by '...'
+	 */
+	uint32_t num_params = 0;
+	uint32_t num_required = 0;
+	uint32_t *arg_to_param_offset_map = zend_arena_alloc(&CG(ast_arena),
+			zend_safe_address_guarded(new_argc, sizeof(*arg_to_param_offset_map), 0));
+	{
+		uint32_t num_positional = 0;
+
+		/* First, we handle explicit placeholders */
+		for (uint32_t arg_offset = 0; arg_offset < argc; arg_offset++) {
+			if (!Z_IS_PLACEHOLDER_P(&argv[arg_offset])) {
+				continue;
+			}
+
+			num_params++;
+
+			zend_arg_info *arg_info = &function->common.arg_info[MIN(arg_offset, function->common.num_args)];
+			zval *named_pos = named_positions ? zend_hash_find(named_positions, arg_info->name) : NULL;
+			uint32_t param_offset;
+			if (named_pos) {
+				/* Placeholder is sent as named arg. 'num_positional' is fixed
+				 * at this point. */
+				param_offset = num_positional + Z_LVAL_P(named_pos);
+			} else {
+				/* Placeholder is sent as positional */
+				param_offset = num_positional++;
+			}
+
+			arg_to_param_offset_map[arg_offset] = param_offset;
+		}
+
+		num_required = num_params;
+
+		/* Handle implicit placeholders added by '...' */
+		if (uses_variadic_placeholder) {
+			for (uint32_t arg_offset = 0; arg_offset < new_argc; arg_offset++) {
+				if (arg_offset < argc && !Z_ISUNDEF(argv[arg_offset])) {
+					continue;
+				}
+
+				/* Unspecified parameters become placeholders */
+				Z_TYPE_INFO(argv[arg_offset]) = _IS_PLACEHOLDER;
+
+				num_params++;
+
+				uint32_t param_offset = num_params - 1;
+
+				arg_to_param_offset_map[arg_offset] = param_offset;
+
+				num_required = zp_compute_num_required(function,
+						arg_offset, param_offset, num_required);
+			}
+		}
+	}
+
+	argc = new_argc;
+
+	/* Assign variable names */
+
+	zp_names *var_names = zp_assign_names(argc, argv, function,
+			uses_variadic_placeholder, extra_named_params);
+
+	/* Generate AST */
+
+	zend_ast *lexical_vars_ast = zend_ast_create_list(0, ZEND_AST_CLOSURE_USES);
+	zend_ast *params_ast = zend_ast_create_list(0, ZEND_AST_ARG_LIST);
+	zend_ast *return_type_ast = NULL;
+	zend_ast *stmts_ast = zend_ast_create_list(0, ZEND_AST_STMT_LIST);
+	zend_ast *attributes_ast = NULL;
+
+	/* Generate AST for params and lexical vars */
+	{
+		/* The inner Closure, if any, is assumed to be the first lexical var by
+		 * do_closure_bind(). */
+		if (function->common.fn_flags & ZEND_ACC_CLOSURE) {
+			zend_ast *lexical_var_ast = zend_ast_create_zval_from_str(
+					zend_string_copy(var_names->inner_closure));
+			lexical_vars_ast = zend_ast_list_add(lexical_vars_ast, lexical_var_ast);
+		}
+
+		zend_ast **params = zend_arena_calloc(&CG(ast_arena), num_params, sizeof(*params));
+		for (uint32_t offset = 0; offset < argc; offset++) {
+			if (Z_IS_PLACEHOLDER_P(&argv[offset])) {
+				zend_arg_info *arg_info = &function->common.arg_info[MIN(offset, function->common.num_args)];
+
+				int param_flags = 0;
+				if (zp_arg_must_be_sent_by_ref(function, offset+1)) {
+					param_flags |= ZEND_PARAM_REF;
+				}
+
+				uint32_t param_offset = arg_to_param_offset_map[offset];
+				zend_ast *param_type_ast = zp_type_to_ast(arg_info->type);
+				zend_ast *default_value_ast = NULL;
+				if (param_offset >= num_required) {
+					zval default_value;
+					if (zp_get_param_default_value(&default_value, function, offset) == FAILURE) {
+						for (uint32_t i = 0; i < num_params; i++) {
+							zend_ast_destroy(params[i]);
+						}
+						goto error;
+					}
+					default_value_ast = zend_ast_create_zval(&default_value);
+				}
+
+				ZEND_ASSERT(offset < function->common.num_args || (function->common.fn_flags & ZEND_ACC_VARIADIC));
+
+				zend_ast *attributes_ast = zp_param_attributes_to_ast(function, MIN(offset, function->common.num_args));
+				params[param_offset] = zend_ast_create_ex(ZEND_AST_PARAM,
+						param_flags, param_type_ast,
+						zend_ast_create_zval_from_str(
+							zend_string_copy(var_names->params[offset])),
+						default_value_ast, attributes_ast, NULL, NULL);
+
+			} else if (!Z_ISUNDEF(argv[offset])) {
+				// TODO: If the pre-bound parameter is a literal, it can be a
+				// literal in the function body instead of a lexical var.
+				zend_ast *lexical_var_ast = zend_ast_create_zval_from_str(
+						zend_string_copy(var_names->params[offset]));
+				if (zp_arg_must_be_sent_by_ref(function, offset+1)) {
+					lexical_var_ast->attr = ZEND_BIND_REF;
+				}
+				lexical_vars_ast = zend_ast_list_add(
+						lexical_vars_ast, lexical_var_ast);
+			}
+		}
+
+		for (uint32_t i = 0; i < num_params; i++) {
+			params_ast = zend_ast_list_add(params_ast, params[i]);
+		}
+	}
+
+	if (extra_named_params) {
+		zend_ast *lexical_var_ast = zend_ast_create_zval_from_str(
+				zend_string_copy(var_names->extra_named_params));
+		lexical_vars_ast = zend_ast_list_add(lexical_vars_ast, lexical_var_ast);
+	}
+
+	/* If we have a variadic placeholder and the underlying function is
+	 * variadic, add a variadic param. */
+	if (uses_variadic_placeholder
+			&& (function->common.fn_flags & ZEND_ACC_VARIADIC)) {
+		zend_arg_info *arg_info = &function->common.arg_info[function->common.num_args];
+		int param_flags = ZEND_PARAM_VARIADIC;
+		if (zp_arg_must_be_sent_by_ref(function, function->common.num_args+1)) {
+			param_flags |= ZEND_PARAM_REF;
+		}
+		zend_ast *param_type_ast = zp_type_to_ast(arg_info->type);
+		zend_ast *attributes_ast = zp_param_attributes_to_ast(function, function->common.num_args);
+		params_ast = zend_ast_list_add(params_ast, zend_ast_create_ex(ZEND_AST_PARAM,
+				param_flags, param_type_ast,
+				zend_ast_create_zval_from_str(
+					zend_string_copy(var_names->variadic_param)),
+				NULL, attributes_ast, NULL, NULL));
+	}
+
+	zend_type return_type = {0};
+	if (function->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+		return_type = (function->common.arg_info-1)->type;
+		return_type_ast = zp_type_to_ast(return_type);
+	}
+
+	/**
+	 * Generate function body.
+	 *
+	 * If we may need to forward superflous arguments, do that conditionally, as
+	 * it's faster:
+	 *
+	 * if (func_num_args() <= n) {
+	 *    // normal call
+	 * } else {
+	 *    // call with superflous arg forwarding
+	 * }
+	 *
+	 * The func_num_args() call should be compiled to a single FUNC_NUM_ARGS op.
+	 */
+
+	if (uses_variadic_placeholder && !(function->common.fn_flags & ZEND_ACC_VARIADIC)) {
+		zend_ast *no_forwarding_ast = zend_ast_create_list(0, ZEND_AST_STMT_LIST);
+		zend_ast *forwarding_ast = zend_ast_create_list(0, ZEND_AST_STMT_LIST);
+
+		no_forwarding_ast = zp_compile_forwarding_call(this_ptr, function,
+				argc, argv, extra_named_params,
+				var_names, uses_variadic_placeholder, num_params,
+				called_scope, return_type, false, no_forwarding_ast);
+
+		if (!no_forwarding_ast) {
+			ZEND_ASSERT(EG(exception));
+			goto error;
+		}
+
+		forwarding_ast = zp_compile_forwarding_call(this_ptr, function,
+				argc, argv, extra_named_params,
+				var_names, uses_variadic_placeholder, num_params,
+				called_scope, return_type, true, forwarding_ast);
+
+		if (!forwarding_ast) {
+			ZEND_ASSERT(EG(exception));
+			zend_ast_destroy(no_forwarding_ast);
+			goto error;
+		}
+
+		zend_ast *func_num_args_name_ast = zend_ast_create_zval_from_str(
+				zend_string_copy(ZSTR_KNOWN(ZEND_STR_FUNC_NUM_ARGS)));
+		func_num_args_name_ast->attr = ZEND_NAME_FQ;
+
+		stmts_ast = zend_ast_list_add(stmts_ast,
+			zend_ast_create_list(2, ZEND_AST_IF,
+				zend_ast_create(ZEND_AST_IF_ELEM,
+					zend_ast_create_binary_op(ZEND_IS_SMALLER_OR_EQUAL,
+						zend_ast_create(ZEND_AST_CALL, func_num_args_name_ast,
+							zend_ast_create_list(0, ZEND_AST_ARG_LIST)),
+						zend_ast_create_zval_from_long(num_params)),
+					no_forwarding_ast),
+				zend_ast_create(ZEND_AST_IF_ELEM,
+					NULL,
+					forwarding_ast)));
+	} else {
+		stmts_ast = zp_compile_forwarding_call(this_ptr, function,
+				argc, argv, extra_named_params,
+				var_names, uses_variadic_placeholder, num_params,
+				called_scope, return_type, false, stmts_ast);
+
+		if (!stmts_ast) {
+			ZEND_ASSERT(EG(exception));
+			goto error;
+		}
+	}
+
+	/* Inherit the NoDiscard attribute */
+	if (function->common.attributes) {
+		zend_attribute *attr = zend_get_attribute_str(
+				function->common.attributes, "nodiscard", strlen("nodiscard"));
+		if (attr) {
+			attributes_ast = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_GROUP,
+					zp_attribute_to_ast(attr));
+			attributes_ast = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_LIST,
+					attributes_ast);
+		}
+	}
+
+	int closure_flags = function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE;
+	zend_ast *closure_ast = zend_ast_create_decl(ZEND_AST_CLOSURE,
+			closure_flags, CG(zend_lineno), NULL,
+			NULL, params_ast, lexical_vars_ast, stmts_ast,
+			return_type_ast, attributes_ast);
+
+	if (Z_TYPE_P(this_ptr) != IS_OBJECT && !zp_is_non_static_closure(function)) {
+		((zend_ast_decl*)closure_ast)->flags |= ZEND_ACC_STATIC;
+	}
+
+#if ZEND_DEBUG
+	{
+		const char *tmp = getenv("DUMP_PFA_AST");
+		if (tmp && ZEND_ATOL(tmp)) {
+			zend_string *str = zend_ast_export("", closure_ast, "");
+			fprintf(stderr, "PFA AST: %s\n", ZSTR_VAL(str));
+			zend_string_release(str);
+		}
+	}
+#endif
+
+	zend_string *pfa_name = zp_pfa_name(declaring_op_array, declaring_opline);
+
+	op_array = zend_accel_compile_pfa(closure_ast, declaring_op_array,
+			declaring_opline, function, pfa_name);
+
+	zend_ast_destroy(closure_ast);
+
+clean:
+	zp_names_dtor(var_names, argc);
+	zend_arena_destroy(CG(ast_arena));
+	CG(ast_arena) = orig_ast_arena;
+	CG(zend_lineno) = orig_lineno;
+
+	return op_array;
+
+error:
+	zend_ast_destroy(lexical_vars_ast);
+	zend_ast_destroy(params_ast);
+	zend_ast_destroy(return_type_ast);
+	zend_ast_destroy(stmts_ast);
+	zend_ast_destroy(attributes_ast);
+	goto clean;
+}
+
+/* Get the op_array of a PFA from caches or compile it */
+static const zend_op_array *zp_get_op_array(zval *this_ptr, zend_function *function,
+		uint32_t argc, zval *argv, zend_array *extra_named_params,
+		const zend_array *named_positions,
+		const zend_op_array *declaring_op_array,
+		const zend_op *declaring_opline, void **cache_slot,
+		bool uses_variadic_placeholder) {
+
+	if (EXPECTED(function->type == ZEND_INTERNAL_FUNCTION
+					? cache_slot[0] == function
+					: cache_slot[0] == function->op_array.opcodes)) {
+		ZEND_ASSERT(!(function->common.fn_flags & ZEND_ACC_NEVER_CACHE));
+		return cache_slot[1];
+	}
+
+	const zend_op_array *op_array = zend_accel_pfa_cache_get(declaring_op_array,
+			declaring_opline, function);
+
+	if (UNEXPECTED(!op_array)) {
+		op_array = zp_compile(this_ptr, function, argc, argv,
+			extra_named_params, named_positions, declaring_op_array, declaring_opline,
+			cache_slot, uses_variadic_placeholder);
+	}
+
+	if (EXPECTED(op_array) && !(function->common.fn_flags & ZEND_ACC_NEVER_CACHE)) {
+		cache_slot[0] = function->type == ZEND_INTERNAL_FUNCTION
+			? (void*)function
+			: (void*)function->op_array.opcodes;
+		cache_slot[1] = (zend_op_array*)op_array;
+	}
+
+	return op_array;
+}
+
+static void zp_free_unbound_args(uint32_t start, uint32_t argc, zval *argv)
+{
+	for (uint32_t offset = start; offset < argc; offset++) {
+		zval_ptr_dtor_nogc(&argv[offset]);
+	}
+}
+
+/* Bind pre-bound arguments as lexical vars */
+static void zp_bind(zval *result, zend_function *function, uint32_t argc, zval *argv,
+		zend_array *extra_named_params) {
+
+	zend_arg_info *arg_infos = function->common.arg_info;
+	uint32_t bind_offset = 0;
+
+	if (function->common.fn_flags & ZEND_ACC_CLOSURE) {
+		zval var;
+		ZVAL_OBJ(&var, ZEND_CLOSURE_OBJECT(function));
+		Z_ADDREF(var);
+		zend_closure_bind_var_ex(result, bind_offset, &var);
+		bind_offset += sizeof(Bucket);
+	}
+
+	for (uint32_t offset = 0; offset < argc; offset++) {
+		zval *var = &argv[offset];
+		if (Z_IS_PLACEHOLDER_P(var) || Z_ISUNDEF_P(var)) {
+			continue;
+		}
+		zend_arg_info *arg_info;
+		if (offset < function->common.num_args) {
+			arg_info = &arg_infos[offset];
+		} else if (function->common.fn_flags & ZEND_ACC_VARIADIC) {
+			arg_info = &arg_infos[function->common.num_args];
+		} else {
+			arg_info = NULL;
+		}
+		if (arg_info && ZEND_TYPE_IS_SET(arg_info->type)
+				&& UNEXPECTED(!zend_check_type_ex(&arg_info->type, var,
+					/* current_frame */ true, /* is_internal */ false))) {
+			zend_string *need_msg = zend_type_to_string_resolved(arg_info->type,
+					function->common.scope);
+			zend_argument_type_error_ex(function, offset + 1,
+					"must be of type %s, %s given",
+					ZSTR_VAL(need_msg), zend_zval_value_name(var));
+			zend_string_release(need_msg);
+			zval_ptr_dtor(result);
+			ZVAL_NULL(result);
+			zp_free_unbound_args(offset, argc, argv);
+			return;
+		}
+		ZEND_ASSERT(zp_arg_must_be_sent_by_ref(function, offset+1) ? Z_ISREF_P(var) : !Z_ISREF_P(var));
+		zend_closure_bind_var_ex(result, bind_offset, var);
+		bind_offset += sizeof(Bucket);
+	}
+
+	if (extra_named_params) {
+		zval var;
+		ZVAL_ARR(&var, extra_named_params);
+		Z_ADDREF(var);
+		zend_closure_bind_var_ex(result, bind_offset, &var);
+	}
+}
+
+void zend_partial_create(zval *result, zval *this_ptr, zend_function *function,
+		uint32_t argc, zval *argv, zend_array *extra_named_params,
+		const zend_array *named_positions,
+		const zend_op_array *declaring_op_array,
+		const zend_op *declaring_opline, void **cache_slot,
+		bool uses_variadic_placeholder) {
+
+	const zend_op_array *op_array = zp_get_op_array(this_ptr, function, argc, argv,
+			extra_named_params, named_positions,
+			declaring_op_array, declaring_opline,
+			cache_slot, uses_variadic_placeholder);
+
+	if (UNEXPECTED(!op_array)) {
+		ZEND_ASSERT(EG(exception));
+		zp_free_unbound_args(0, argc, argv);
+		ZVAL_NULL(result);
+		return;
+	}
+
+	zend_class_entry *called_scope;
+	zval object;
+
+	if (Z_TYPE_P(this_ptr) == IS_OBJECT) {
+		called_scope = Z_OBJCE_P(this_ptr);
+	} else {
+		called_scope = Z_CE_P(this_ptr);
+	}
+
+	if (Z_TYPE_P(this_ptr) == IS_OBJECT && !zp_is_static_closure(function)) {
+		ZVAL_COPY_VALUE(&object, this_ptr);
+	} else {
+		ZVAL_UNDEF(&object);
+	}
+
+	zend_create_partial_closure(result, (zend_function*)op_array,
+			function->common.scope, called_scope, &object,
+			(function->common.fn_flags & ZEND_ACC_CLOSURE) != 0);
+
+	zp_bind(result, function, argc, argv, extra_named_params);
+}
+
+void zend_partial_op_array_dtor(zval *pDest)
+{
+	destroy_op_array(Z_PTR_P(pDest));
+}
diff --git a/Zend/zend_partial.h b/Zend/zend_partial.h
new file mode 100644
index 000000000000..3c47305ff543
--- /dev/null
+++ b/Zend/zend_partial.h
@@ -0,0 +1,35 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
+   +----------------------------------------------------------------------+
+   | Authors: Arnaud Le Blanc                        |
+   +----------------------------------------------------------------------+
+*/
+#ifndef ZEND_PARTIAL_H
+#define ZEND_PARTIAL_H
+
+#include "zend_compile.h"
+
+BEGIN_EXTERN_C()
+
+void zend_partial_create(zval *result, zval *this_ptr, zend_function *function,
+		uint32_t argc, zval *argv, zend_array *extra_named_params,
+		const zend_array *named_positions,
+		const zend_op_array *declaring_op_array,
+		const zend_op *declaring_opline, void **cache_slot,
+		bool uses_variadic_placeholder);
+
+void zend_partial_op_array_dtor(zval *pDest);
+
+END_EXTERN_C()
+
+#endif
diff --git a/Zend/zend_perf_stat.h b/Zend/zend_perf_stat.h
new file mode 100644
index 000000000000..447315de0133
--- /dev/null
+++ b/Zend/zend_perf_stat.h
@@ -0,0 +1,135 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
+   +----------------------------------------------------------------------+
+   | Authors: Ilija Tovilo                                |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_PERF_STAT_H
+#define ZEND_PERF_STAT_H
+
+#include "zend_portability.h"
+
+# if !(HAVE_FCNTL_H && HAVE_SYS_SELECT_H && HAVE_SYS_STAT_H && HAVE_SYS_TIME_H && HAVE_UNISTD_H)
+static void zend_perf_stat_enable(void) {}
+static void zend_perf_stat_disable(void) {}
+# else
+
+# include 
+# include 
+# include 
+# include 
+
+# include "Zend/zend.h"
+
+# define ZPS_CTL_FIFO_ENV "PERF_STAT_CTL_FIFO"
+# define ZPS_ACK_FIFO_ENV "PERF_STAT_ACK_FIFO"
+
+static int ctl_fd = -2;
+static int ack_fd = -2;
+
+static int zps_open_fifo(const char *env_name, int flags)
+{
+	const char *path = getenv(env_name);
+
+	if (path == NULL || path[0] == '\0') {
+		return -1;
+	}
+
+# ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+# endif
+	int fd = open(path, flags | O_NONBLOCK);
+	if (fd < 0) {
+		fprintf(stderr, "Failed to open fifo %s\n", path);
+		fflush(stderr);
+		zend_bailout();
+	}
+
+	struct stat st;
+	if (fstat(fd, &st) != 0 || !S_ISFIFO(st.st_mode)) {
+		close(fd);
+		fprintf(stderr, "File %s is not a fifo\n", path);
+		fflush(stderr);
+		zend_bailout();
+	}
+	return fd;
+}
+
+static void zps_init(void)
+{
+	if (ctl_fd == -2) {
+		ctl_fd = zps_open_fifo(ZPS_CTL_FIFO_ENV, O_WRONLY);
+	}
+	if (ack_fd == -2) {
+		ack_fd = zps_open_fifo(ZPS_ACK_FIFO_ENV, O_RDONLY);
+	}
+}
+
+static void zps_wait_ack(void)
+{
+	if (ack_fd < 0) {
+		return;
+	}
+
+	struct timeval timeout;
+	timeout.tv_sec = 1;
+	timeout.tv_usec = 0;
+
+	fd_set readfds;
+	FD_ZERO(&readfds);
+	FD_SET(ack_fd, &readfds);
+	if (select(ack_fd + 1, &readfds, NULL, NULL, &timeout) <= 0) {
+		return;
+	}
+
+	char ack[sizeof("ack\n") - 1];
+	ssize_t bytes_read;
+	do {
+		bytes_read = read(ack_fd, ack, sizeof(ack));
+	} while (bytes_read > 0);
+}
+
+static void zps_control(const char *command, size_t command_len)
+{
+	zps_init();
+
+	if (ctl_fd < 0) {
+		return;
+	}
+
+	if (write(ctl_fd, command, command_len) != (ssize_t) command_len) {
+		close(ctl_fd);
+		ctl_fd = -1;
+		return;
+	}
+
+	zps_wait_ack();
+}
+
+static void zend_perf_stat_enable(void)
+{
+	static const char command[] = "enable\n";
+
+	zps_control(command, sizeof(command) - 1);
+}
+
+static void zend_perf_stat_disable(void)
+{
+	static const char command[] = "disable\n";
+
+	zps_control(command, sizeof(command) - 1);
+}
+
+# endif
+#endif
diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h
index c8a6dfa871b5..ccad24682fdb 100644
--- a/Zend/zend_portability.h
+++ b/Zend/zend_portability.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -106,7 +105,10 @@
 # define ZEND_ASSUME(c)
 #endif
 
-#if ZEND_DEBUG
+#ifdef HAVE_GCOV
+/* Disable assert() when compiling with gcov to avoid untested branch warning. */
+# define ZEND_ASSERT(c) ((void)sizeof(c))
+#elif ZEND_DEBUG
 # define ZEND_ASSERT(c)	assert(c)
 #else
 # define ZEND_ASSERT(c) ZEND_ASSUME(c)
@@ -128,16 +130,14 @@
 #endif
 
 /* pseudo fallthrough keyword; */
-#if defined(__GNUC__) && __GNUC__ >= 7
+#if __STDC_VERSION__ >= 202311L || defined(__cplusplus)
+# define ZEND_FALLTHROUGH [[fallthrough]]
+#elif defined(__GNUC__) && __GNUC__ >= 7
 # define ZEND_FALLTHROUGH __attribute__((__fallthrough__))
 #else
 # define ZEND_FALLTHROUGH ((void)0)
 #endif
 
-/* Only use this macro if you know for sure that all of the switches values
-   are covered by its case statements */
-#define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_UNREACHABLE(); break;
-
 #if defined(__GNUC__) && __GNUC__ >= 4
 # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
 #else
@@ -272,7 +272,7 @@ char *alloca();
 # define ZEND_ATTRIBUTE_NODISCARD
 #endif
 
-#if ZEND_GCC_VERSION >= 3000
+#if ZEND_GCC_VERSION >= 3000 || __has_attribute(const)
 # define ZEND_ATTRIBUTE_CONST __attribute__((const))
 #else
 # define ZEND_ATTRIBUTE_CONST
@@ -314,22 +314,21 @@ char *alloca();
 # define ZEND_ATTRIBUTE_NONNULL_ARGS(...)
 #endif
 
-#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
+#if (defined(__GNUC__) && ZEND_GCC_VERSION >= 4003) || __has_attribute(cold)
 # define ZEND_COLD __attribute__((cold))
-# ifdef __OPTIMIZE__
-#  define ZEND_OPT_SIZE  __attribute__((optimize("Os")))
-#  define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
-# else
-#  define ZEND_OPT_SIZE
-#  define ZEND_OPT_SPEED
-# endif
 #else
 # define ZEND_COLD
+#endif
+
+#if ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4003) || __has_attribute(optimize)) && defined(__OPTIMIZE__)
+# define ZEND_OPT_SIZE  __attribute__((optimize("Os")))
+# define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
+#else
 # define ZEND_OPT_SIZE
 # define ZEND_OPT_SPEED
 #endif
 
-#if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000
+#if (defined(__GNUC__) && ZEND_GCC_VERSION >= 5000)
 # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((unused));
 # define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold));
 #else
@@ -388,6 +387,34 @@ char *alloca();
 #define ZEND_ELEMENT_COUNT(m)
 #endif
 
+#if __cplusplus
+extern "C++" {
+# include 
+	template
+	const T* zend_container_of(const M *ptr, size_t offset) {
+		return reinterpret_cast(reinterpret_cast(ptr) - offset);
+	}
+	template
+	T* zend_container_of(M *ptr, size_t offset) {
+		return reinterpret_cast(reinterpret_cast(ptr) - offset);
+	}
+
+# define ZEND_CONTAINER_OF(ptr, Type, member) zend_container_of(ptr, offsetof(Type, member))
+}
+#elif __STDC_VERSION__ >= 202311L || ZEND_GCC_VERSION
+/* typeof is C23 or a GCC extension */
+# define ZEND_CONTAINER_OF(ptr, Type, member) \
+	_Generic( \
+		(ptr), \
+		const typeof(((Type*)0)->member) *: ((const Type*)((char*)(ptr) - offsetof(Type, member))), \
+		typeof(((Type*)0)->member) *: ((Type*)((char*)(ptr) - offsetof(Type, member))) \
+	)
+#else
+/* Define a variant that does not keep const-ness for older compilers. Mismatches
+ * are expected to be caught by CI running modern compilers. */
+# define ZEND_CONTAINER_OF(ptr, Type, member) ((Type*)((char*)(ptr) - offsetof(Type, member)))
+#endif
+
 #ifdef HAVE_BUILTIN_CONSTANT_P
 # define ZEND_CONST_COND(_condition, _default) \
 	(__builtin_constant_p(_condition) ? (_condition) : (_default))
@@ -433,10 +460,6 @@ char *alloca();
 # define UNEXPECTED(condition) (condition)
 #endif
 
-#ifndef XtOffsetOf
-# define XtOffsetOf(s_type, field) offsetof(s_type, field)
-#endif
-
 #ifndef ZEND_WIN32
 # define SETJMP(a) sigsetjmp(a, 0)
 # define LONGJMP(a,b) siglongjmp(a, b)
@@ -653,8 +676,8 @@ extern "C++" {
 #endif
 
 /* Do not use for conditional declaration of API functions! */
-#if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
-/* __builtin_cpu_supports has pclmul from gcc9 */
+#if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000))
+/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */
 # define ZEND_INTRIN_PCLMUL_FUNC_PROTO 1
 #elif defined(ZEND_INTRIN_PCLMUL_RESOLVER)
 # define ZEND_INTRIN_PCLMUL_FUNC_PTR 1
@@ -679,8 +702,8 @@ extern "C++" {
 #endif
 
 /* Do not use for conditional declaration of API functions! */
-#if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
-/* __builtin_cpu_supports has pclmul from gcc9 */
+#if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000))
+/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */
 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO 1
 #elif defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER)
 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR 1
diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c
index 57e22f23ad7b..dd6fe95ef57a 100644
--- a/Zend/zend_property_hooks.c
+++ b/Zend/zend_property_hooks.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Ilija Tovilo                                |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_property_hooks.h b/Zend/zend_property_hooks.h
index 3793fa1a683c..9c88cccb0c07 100644
--- a/Zend/zend_property_hooks.h
+++ b/Zend/zend_property_hooks.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Ilija Tovilo                                |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c
index fdabdeb61cef..67cc836a240c 100644
--- a/Zend/zend_ptr_stack.c
+++ b/Zend/zend_ptr_stack.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h
index 3ef1478fe4c3..6a6376f79dae 100644
--- a/Zend/zend_ptr_stack.h
+++ b/Zend/zend_ptr_stack.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_range_check.h b/Zend/zend_range_check.h
index 9c822493fa3e..8db867434399 100644
--- a/Zend/zend_range_check.h
+++ b/Zend/zend_range_check.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c
index 83f8aa0852db..2e4b398aa965 100644
--- a/Zend/zend_signal.c
+++ b/Zend/zend_signal.c
@@ -2,15 +2,13 @@
   +----------------------------------------------------------------------+
   | Zend Signal Handling                                                 |
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Authors: Lucas Nealan                                 |
   |          Arnaud Le Blanc                           |
@@ -22,8 +20,9 @@
    Facebook Inc. as the original contributor of this module by leaving
    this note intact in the source code.
 
-   All other licensing and usage conditions are those of the PHP Group.
-*/
+   All other licensing and usage conditions are those of the PHP Group and
+   Contributors.
+ */
 
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE
diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h
index e88892da35aa..973f0c302b21 100644
--- a/Zend/zend_signal.h
+++ b/Zend/zend_signal.h
@@ -2,20 +2,17 @@
   +----------------------------------------------------------------------+
   | Zend Signal Handling                                                 |
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Authors: Lucas Nealan                                 |
   |          Arnaud Le Blanc                           |
   +----------------------------------------------------------------------+
-
  */
 
 #ifndef ZEND_SIGNAL_H
diff --git a/Zend/zend_smart_str.c b/Zend/zend_smart_str.c
index c779ee5c97ca..e6475c1dd626 100644
--- a/Zend/zend_smart_str.c
+++ b/Zend/zend_smart_str.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Dmitry Stogov                                |
    +----------------------------------------------------------------------+
@@ -229,7 +227,7 @@ ZEND_API void ZEND_FASTCALL smart_str_append_scalar(smart_str *dest, const zval
 			smart_str_appendc(dest, '\'');
 		break;
 
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 }
 
diff --git a/Zend/zend_smart_str.h b/Zend/zend_smart_str.h
index affbb5c50ac2..cb81cd2361c8 100644
--- a/Zend/zend_smart_str.h
+++ b/Zend/zend_smart_str.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_smart_str_public.h b/Zend/zend_smart_str_public.h
index 6a3b526254e4..d08ee49e47e0 100644
--- a/Zend/zend_smart_str_public.h
+++ b/Zend/zend_smart_str_public.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_smart_string.h b/Zend/zend_smart_string.h
index 9f04e1a340ad..e8655681186b 100644
--- a/Zend/zend_smart_string.h
+++ b/Zend/zend_smart_string.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    |         Xinchen Hui                                |
diff --git a/Zend/zend_smart_string_public.h b/Zend/zend_smart_string_public.h
index 543e1d37a4ef..8b2bfbedb271 100644
--- a/Zend/zend_smart_string_public.h
+++ b/Zend/zend_smart_string_public.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    |         Xinchen Hui                                |
diff --git a/Zend/zend_sort.c b/Zend/zend_sort.c
index 355d2d1bad58..ac559141dd97 100644
--- a/Zend/zend_sort.c
+++ b/Zend/zend_sort.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Xinchen Hui                               |
    |          Sterling Hughes                           |
diff --git a/Zend/zend_sort.h b/Zend/zend_sort.h
index 5954575dbc25..03c63bb12e17 100644
--- a/Zend/zend_sort.h
+++ b/Zend/zend_sort.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Xinchen Hui                               |
    |          Sterling Hughes                           |
diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c
index 5d9cc166367e..d999d684d05d 100644
--- a/Zend/zend_stack.c
+++ b/Zend/zend_stack.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_stack.h b/Zend/zend_stack.h
index a2edc12b1fb4..66c90f0b5217 100644
--- a/Zend/zend_stack.h
+++ b/Zend/zend_stack.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c
index 8e11841ad265..0627ae145939 100644
--- a/Zend/zend_stream.c
+++ b/Zend/zend_stream.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Wez Furlong                           |
    |          Scott MacVicar                            |
diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h
index 33d8656dad5e..ed2bef941e2a 100644
--- a/Zend/zend_stream.h
+++ b/Zend/zend_stream.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Wez Furlong                           |
    |          Scott MacVicar                            |
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index ad4b9d2d6cde..b1b4a0e17a69 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -18,6 +17,7 @@
 
 #include "zend.h"
 #include "zend_globals.h"
+#include "zend_multiply.h"
 
 #ifdef HAVE_VALGRIND
 # include "valgrind/callgrind.h"
@@ -52,6 +52,17 @@ ZEND_API zend_string  *zend_empty_string = NULL;
 ZEND_API zend_string  *zend_one_char_string[256];
 ZEND_API zend_string **zend_known_strings = NULL;
 
+/* this is read-only, so it's ok */
+ZEND_SET_ALIGNED(16, static const char zend_hexconvtab[]) = "0123456789abcdef";
+
+static zend_always_inline void zend_bin2hex_impl(char *out, const unsigned char *in, size_t in_len, const char *hexconvtab)
+{
+	for (size_t i = 0; i < in_len; i++) {
+		out[i * 2] = hexconvtab[in[i] >> 4];
+		out[i * 2 + 1] = hexconvtab[in[i] & 0x0f];
+	}
+}
+
 ZEND_API zend_ulong ZEND_FASTCALL zend_string_hash_func(zend_string *str)
 {
 	return ZSTR_H(str) = zend_hash_func(ZSTR_VAL(str), ZSTR_LEN(str));
@@ -62,6 +73,21 @@ ZEND_API zend_ulong ZEND_FASTCALL zend_hash_func(const char *str, size_t len)
 	return zend_inline_hash_func(str, len);
 }
 
+ZEND_API void ZEND_FASTCALL zend_bin2hex(char *out, const unsigned char *in, size_t in_len)
+{
+	zend_bin2hex_impl(out, in, in_len, zend_hexconvtab);
+}
+
+ZEND_API zend_string *zend_bin2hex_str(const unsigned char *in, size_t in_len)
+{
+	zend_string *result = zend_string_safe_alloc(in_len, 2 * sizeof(char), 0, 0);
+
+	zend_bin2hex(ZSTR_VAL(result), in, in_len);
+	ZSTR_VAL(result)[in_len * 2] = '\0';
+
+	return result;
+}
+
 static void _str_dtor(zval *zv)
 {
 	zend_string *str = Z_STR_P(zv);
@@ -474,12 +500,12 @@ ZEND_API zend_string *zend_string_concat2(
 		const char *str1, size_t str1_len,
 		const char *str2, size_t str2_len)
 {
-	size_t len = str1_len + str2_len;
-	zend_string *res = zend_string_alloc(len, 0);
+	zend_string *res = zend_string_safe_alloc(1, str1_len, str2_len, 0);
 
-	memcpy(ZSTR_VAL(res), str1, str1_len);
-	memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
-	ZSTR_VAL(res)[len] = '\0';
+	char *p = ZSTR_VAL(res);
+	p = zend_mempcpy(p, str1, str1_len);
+	p = zend_mempcpy(p, str2, str2_len);
+	*p++ = '\0';
 
 	return res;
 }
@@ -489,13 +515,15 @@ ZEND_API zend_string *zend_string_concat3(
 		const char *str2, size_t str2_len,
 		const char *str3, size_t str3_len)
 {
-	size_t len = str1_len + str2_len + str3_len;
+	size_t tmp_len = zend_safe_address_guarded(1, str1_len, str2_len);
+	size_t len = zend_safe_address_guarded(1, tmp_len, str3_len);
 	zend_string *res = zend_string_alloc(len, 0);
 
-	memcpy(ZSTR_VAL(res), str1, str1_len);
-	memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
-	memcpy(ZSTR_VAL(res) + str1_len + str2_len, str3, str3_len);
-	ZSTR_VAL(res)[len] = '\0';
+	char *p = ZSTR_VAL(res);
+	p = zend_mempcpy(p, str1, str1_len);
+	p = zend_mempcpy(p, str2, str2_len);
+	p = zend_mempcpy(p, str3, str3_len);
+	*p++ = '\0';
 
 	return res;
 }
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 97386ea6bad6..d9efea00e7bd 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -23,8 +22,14 @@
 #include "zend_gc.h"
 #include "zend_alloc.h"
 
+#include "zend_errors.h"
+
 BEGIN_EXTERN_C()
 
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+
+#include "zend_multiply.h"
+
 typedef void (*zend_string_copy_storage_func_t)(void);
 typedef zend_string *(ZEND_FASTCALL *zend_new_interned_string_func_t)(zend_string *str);
 typedef zend_string *(ZEND_FASTCALL *zend_string_init_interned_func_t)(const char *str, size_t size, bool permanent);
@@ -38,6 +43,8 @@ ZEND_API extern zend_string_init_existing_interned_func_t zend_string_init_exist
 ZEND_API zend_ulong ZEND_FASTCALL zend_string_hash_func(zend_string *str);
 ZEND_API zend_ulong ZEND_FASTCALL zend_hash_func(const char *str, size_t len);
 ZEND_API zend_string* ZEND_FASTCALL zend_interned_string_find_permanent(zend_string *str);
+ZEND_API void ZEND_FASTCALL zend_bin2hex(char *out, const unsigned char *in, size_t in_len);
+ZEND_API zend_string *zend_bin2hex_str(const unsigned char *in, size_t in_len);
 
 ZEND_API zend_string *zend_string_concat2(
 	const char *str1, size_t str1_len,
@@ -72,35 +79,51 @@ END_EXTERN_C()
 
 /*---*/
 
-#define ZSTR_IS_INTERNED(s)					(GC_FLAGS(s) & IS_STR_INTERNED)
-#define ZSTR_IS_VALID_UTF8(s)				(GC_FLAGS(s) & IS_STR_VALID_UTF8)
+static zend_always_inline bool ZSTR_IS_INTERNED(const zend_string *s) {
+	return GC_FLAGS(s) & IS_STR_INTERNED;
+}
+
+static inline bool ZSTR_IS_VALID_UTF8(const zend_string *s) {
+	return GC_FLAGS(s) & IS_STR_VALID_UTF8;
+}
 
 /* These are properties, encoded as flags, that will hold on the resulting string
  * after concatenating two strings that have these property.
  * Example: concatenating two UTF-8 strings yields another UTF-8 string. */
 #define ZSTR_COPYABLE_CONCAT_PROPERTIES		(IS_STR_VALID_UTF8)
 
-#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s) 				(GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES)
-/* This macro returns the copyable concat properties which hold on both strings. */
-#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(s1, s2)	(GC_FLAGS(s1) & GC_FLAGS(s2) & ZSTR_COPYABLE_CONCAT_PROPERTIES)
+static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(const zend_string *s) {
+	return GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES;
+}
 
-#define ZSTR_COPY_CONCAT_PROPERTIES(out, in) do { \
-	zend_string *_out = (out); \
-	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES((in)); \
-	GC_ADD_FLAGS(_out, properties); \
-} while (0)
+/* This function returns the copyable concat properties which hold on both strings. */
+static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(const zend_string *s1, const zend_string *s2) {
+	return ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s1) & ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s2);
+}
 
-#define ZSTR_COPY_CONCAT_PROPERTIES_BOTH(out, in1, in2) do { \
-	zend_string *_out = (out); \
-	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH((in1), (in2)); \
-	GC_ADD_FLAGS(_out, properties); \
-} while (0)
+static inline void ZSTR_COPY_CONCAT_PROPERTIES(zend_string *out, const zend_string *in) {
+	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(in);
+	GC_ADD_FLAGS(out, properties);
+}
+
+static inline void ZSTR_COPY_CONCAT_PROPERTIES_BOTH(zend_string *out, const zend_string *in1, const zend_string *in2) {
+	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(in1, in2);
+	GC_ADD_FLAGS(out, properties);
+}
 
-#define ZSTR_EMPTY_ALLOC() zend_empty_string
-#define ZSTR_CHAR(c) zend_one_char_string[c]
-#define ZSTR_KNOWN(idx) zend_known_strings[idx]
+static zend_always_inline zend_string *ZSTR_EMPTY_ALLOC(void) {
+	return zend_empty_string;
+}
+
+static zend_always_inline zend_string *ZSTR_CHAR(unsigned char c) {
+	return zend_one_char_string[c];
+}
 
-#define _ZSTR_HEADER_SIZE XtOffsetOf(zend_string, val)
+static zend_always_inline zend_string *ZSTR_KNOWN(size_t idx) {
+	return zend_known_strings[idx];
+}
+
+#define _ZSTR_HEADER_SIZE offsetof(zend_string, val)
 
 #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
 
@@ -316,6 +339,48 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s,
 	return ret;
 }
 
+static zend_always_inline char *zend_cstr_append_char(const char *str, size_t len, char c) {
+	char *res = (char *)safe_emalloc(len, 1, 2);
+	if (len > 0) {
+		memcpy(res, str, len);
+	}
+	res[len] = c;
+	res[len + 1] = '\0';
+	return res;
+}
+
+static zend_always_inline char *zend_cstr_concat(const char *s1, size_t len1, const char *s2, size_t len2) {
+	size_t size = zend_safe_address_guarded(1, len1, len2);
+	size = zend_safe_address_guarded(1, size, 1);
+	char *res = (char *)emalloc(size);
+	if (len1 > 0) {
+		memcpy(res, s1, len1);
+	}
+	if (len2 > 0) {
+		memcpy(res + len1, s2, len2);
+	}
+	res[len1 + len2] = '\0';
+	return res;
+}
+
+static zend_always_inline char *zend_cstr_concat3(const char *s1, size_t len1, const char *s2, size_t len2, const char *s3, size_t len3) {
+	size_t size = zend_safe_address_guarded(1, len1, len2);
+	size = zend_safe_address_guarded(1, size, len3);
+	size = zend_safe_address_guarded(1, size, 1);
+	char *res = (char *)emalloc(size);
+	if (len1 > 0) {
+		memcpy(res, s1, len1);
+	}
+	if (len2 > 0) {
+		memcpy(res + len1, s2, len2);
+	}
+	if (len3 > 0) {
+		memcpy(res + len1 + len2, s3, len3);
+	}
+	res[len1 + len2 + len3] = '\0';
+	return res;
+}
+
 static zend_always_inline void zend_string_free(zend_string *s)
 {
 	if (!ZSTR_IS_INTERNED(s)) {
@@ -382,11 +447,22 @@ static zend_always_inline bool zend_string_equals(const zend_string *s1, const z
 	return s1 == s2 || zend_string_equal_content(s1, s2);
 }
 
-#define zend_string_equals_ci(s1, s2) \
-	(ZSTR_LEN(s1) == ZSTR_LEN(s2) && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)))
+BEGIN_EXTERN_C()
+ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
+END_EXTERN_C()
 
-#define zend_string_equals_literal_ci(str, c) \
-	(ZSTR_LEN(str) == sizeof("" c) - 1 && !zend_binary_strcasecmp(ZSTR_VAL(str), ZSTR_LEN(str), (c), sizeof(c) - 1))
+static zend_always_inline bool zend_string_equals_cstr_ci(const zend_string *s1, const char *s2, size_t s2_length)
+{
+	return ZSTR_LEN(s1) == s2_length && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), s2, s2_length);
+}
+
+#define zend_string_equals_literal_ci(str, literal) \
+	zend_string_equals_cstr_ci(str, "" literal, sizeof(literal) - 1)
+
+static zend_always_inline bool zend_string_equals_ci(const zend_string *s1, const zend_string *s2)
+{
+	return zend_string_equals_cstr_ci(s1, ZSTR_VAL(s2), ZSTR_LEN(s2));
+}
 
 #define zend_string_equals_literal(str, literal) \
 	zend_string_equals_cstr(str, "" literal, sizeof(literal) - 1)
@@ -417,6 +493,32 @@ static zend_always_inline bool zend_string_starts_with_ci(const zend_string *str
 #define zend_string_starts_with_literal_ci(str, prefix) \
 	zend_string_starts_with_cstr_ci(str, "" prefix, sizeof(prefix) - 1)
 
+static zend_always_inline bool zend_string_ends_with_cstr(const zend_string *str, const char *suffix, size_t suffix_length)
+{
+	return ZSTR_LEN(str) >= suffix_length && !memcmp(ZSTR_VAL(str) + ZSTR_LEN(str) - suffix_length, suffix, suffix_length);
+}
+
+static zend_always_inline bool zend_string_ends_with(const zend_string *str, const zend_string *suffix)
+{
+	return zend_string_ends_with_cstr(str, ZSTR_VAL(suffix), ZSTR_LEN(suffix));
+}
+
+#define zend_string_ends_with_literal(str, suffix) \
+	zend_string_ends_with_cstr(str, "" suffix, sizeof(suffix) - 1)
+
+static zend_always_inline bool zend_string_ends_with_cstr_ci(const zend_string *str, const char *suffix, size_t suffix_length)
+{
+	return ZSTR_LEN(str) >= suffix_length && !strncasecmp(ZSTR_VAL(str) + ZSTR_LEN(str) - suffix_length, suffix, suffix_length);
+}
+
+static zend_always_inline bool zend_string_ends_with_ci(const zend_string *str, const zend_string *suffix)
+{
+	return zend_string_ends_with_cstr_ci(str, ZSTR_VAL(suffix), ZSTR_LEN(suffix));
+}
+
+#define zend_string_ends_with_literal_ci(str, suffix) \
+	zend_string_ends_with_cstr_ci(str, "" suffix, sizeof(suffix) - 1)
+
 /*
  * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
  *
@@ -537,7 +639,7 @@ static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size
 		case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
 		case 1: hash = ((hash << 5) + hash) + *str++; break;
 		case 0: break;
-EMPTY_SWITCH_DEFAULT_CASE()
+default: ZEND_UNREACHABLE();
 	}
 #endif
 
@@ -631,10 +733,16 @@ EMPTY_SWITCH_DEFAULT_CASE()
 	_(ZEND_STR_AUTOGLOBAL_ENV,         "_ENV") \
 	_(ZEND_STR_AUTOGLOBAL_REQUEST,     "_REQUEST") \
 	_(ZEND_STR_COUNT,                  "count") \
+	_(ZEND_STR_FUNC_NUM_ARGS,          "func_num_args") \
+	_(ZEND_STR_FUNC_GET_ARGS,          "func_get_args") \
+	_(ZEND_STR_ASSERT,                 "assert") \
+	_(ZEND_STR_CALL_USER_FUNC,         "call_user_func") \
+	_(ZEND_STR_ARRAY_SLICE,            "array_slice") \
 	_(ZEND_STR_SENSITIVEPARAMETER,     "SensitiveParameter") \
 	_(ZEND_STR_CONST_EXPR_PLACEHOLDER, "[constant expression]") \
 	_(ZEND_STR_DEPRECATED_CAPITALIZED, "Deprecated") \
 	_(ZEND_STR_SINCE,                  "since") \
+	_(ZEND_STR_NODISCARD,              "NoDiscard") \
 	_(ZEND_STR_GET,                    "get") \
 	_(ZEND_STR_SET,                    "set") \
 	_(ZEND_STR_8_DOT_0,                "8.0") \
diff --git a/Zend/zend_strtod.h b/Zend/zend_strtod.h
index 4e0d85a7d216..fa557ed2a0c3 100644
--- a/Zend/zend_strtod.h
+++ b/Zend/zend_strtod.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Derick Rethans                              |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_strtod_int.h b/Zend/zend_strtod_int.h
index 06a02618e9e6..4de5c225ccd8 100644
--- a/Zend/zend_strtod_int.h
+++ b/Zend/zend_strtod_int.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_system_id.c b/Zend/zend_system_id.c
index 2c3ebab0f480..aaeb254386b7 100644
--- a/Zend/zend_system_id.c
+++ b/Zend/zend_system_id.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sammy Kaye Powers                           |
    |          Dmitry Stogov                               |
@@ -19,7 +17,6 @@
 #include "zend_system_id.h"
 #include "zend_extensions.h"
 #include "ext/standard/md5.h"
-#include "ext/hash/php_hash.h"
 
 ZEND_API char zend_system_id[32];
 
@@ -90,6 +87,6 @@ void zend_finalize_system_id(void)
 	}
 
 	PHP_MD5Final(digest, &context);
-	php_hash_bin2hex(zend_system_id, digest, sizeof digest);
+	zend_bin2hex(zend_system_id, digest, sizeof digest);
 	finalized = 1;
 }
diff --git a/Zend/zend_system_id.h b/Zend/zend_system_id.h
index b6785f8d7b67..ae39381a52a3 100644
--- a/Zend/zend_system_id.h
+++ b/Zend/zend_system_id.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sammy Kaye Powers                            |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_type_info.h b/Zend/zend_type_info.h
index eeab7bf0431d..1e0045558383 100644
--- a/Zend/zend_type_info.h
+++ b/Zend/zend_type_info.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 22dbfa9be879..b30f53d7f917 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -55,12 +54,10 @@
 
 typedef unsigned char zend_uchar;
 
-typedef enum {
+typedef enum zend_result {
   SUCCESS =  0,
   FAILURE = -1,		/* this MUST stay a negative number, or it may affect functions! */
-} ZEND_RESULT_CODE;
-
-typedef ZEND_RESULT_CODE zend_result;
+} zend_result;
 
 /* This constant is deprecated, use SIZE_MAX instead */
 #define ZEND_SIZE_MAX SIZE_MAX
@@ -449,20 +446,31 @@ struct _zend_array {
  */
 #if SIZEOF_SIZE_T == 4
 # define HT_MAX_SIZE 0x02000000
-# define HT_HASH_TO_BUCKET_EX(data, idx) \
-	((Bucket*)((char*)(data) + (idx)))
-# define HT_IDX_TO_HASH(idx) \
-	((idx) * sizeof(Bucket))
-# define HT_HASH_TO_IDX(idx) \
-	((idx) / sizeof(Bucket))
+
+static zend_always_inline Bucket *HT_HASH_TO_BUCKET_EX(Bucket *data, uint32_t idx) {
+	return ((Bucket*)((char*)(data) + (idx)));
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline uint32_t HT_IDX_TO_HASH(uint32_t idx) {
+	return idx * sizeof(Bucket);
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline uint32_t HT_HASH_TO_IDX(uint32_t idx) {
+	return idx / sizeof(Bucket);
+}
 #elif SIZEOF_SIZE_T == 8
 # define HT_MAX_SIZE 0x40000000
-# define HT_HASH_TO_BUCKET_EX(data, idx) \
-	((data) + (idx))
-# define HT_IDX_TO_HASH(idx) \
-	(idx)
-# define HT_HASH_TO_IDX(idx) \
-	(idx)
+static zend_always_inline Bucket *HT_HASH_TO_BUCKET_EX(Bucket *data, uint32_t idx) {
+	return data + idx;
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline uint32_t HT_IDX_TO_HASH(uint32_t idx) {
+	return idx;
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline uint32_t HT_HASH_TO_IDX(uint32_t idx) {
+	return idx;
+}
 #else
 # error "Unknown SIZEOF_SIZE_T"
 #endif
@@ -472,81 +480,96 @@ struct _zend_array {
 #define HT_HASH(ht, idx) \
 	HT_HASH_EX((ht)->arHash, idx)
 
-#define HT_SIZE_TO_MASK(nTableSize) \
-	((uint32_t)(-((nTableSize) + (nTableSize))))
-#define HT_HASH_SIZE(nTableMask) \
-	(((size_t)-(uint32_t)(nTableMask)) * sizeof(uint32_t))
-#define HT_DATA_SIZE(nTableSize) \
-	((size_t)(nTableSize) * sizeof(Bucket))
-#define HT_SIZE_EX(nTableSize, nTableMask) \
-	(HT_DATA_SIZE((nTableSize)) + HT_HASH_SIZE((nTableMask)))
-#define HT_SIZE(ht) \
-	HT_SIZE_EX((ht)->nTableSize, (ht)->nTableMask)
-#define HT_USED_SIZE(ht) \
-	(HT_HASH_SIZE((ht)->nTableMask) + ((size_t)(ht)->nNumUsed * sizeof(Bucket)))
-#define HT_PACKED_DATA_SIZE(nTableSize) \
-	((size_t)(nTableSize) * sizeof(zval))
-#define HT_PACKED_SIZE_EX(nTableSize, nTableMask) \
-	(HT_PACKED_DATA_SIZE((nTableSize)) + HT_HASH_SIZE((nTableMask)))
-#define HT_PACKED_SIZE(ht) \
-	HT_PACKED_SIZE_EX((ht)->nTableSize, (ht)->nTableMask)
-#define HT_PACKED_USED_SIZE(ht) \
-	(HT_HASH_SIZE((ht)->nTableMask) + ((size_t)(ht)->nNumUsed * sizeof(zval)))
+ZEND_ATTRIBUTE_CONST static zend_always_inline uint32_t HT_SIZE_TO_MASK(uint32_t nTableSize) {
+	return (uint32_t)(-(nTableSize + nTableSize));
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline size_t HT_HASH_SIZE(uint32_t nTableMask) {
+	return ((size_t)(-nTableMask)) * sizeof(uint32_t);
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline size_t HT_DATA_SIZE(uint32_t nTableSize) {
+	return ((size_t)nTableSize) * sizeof(Bucket);
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline size_t HT_SIZE_EX(uint32_t nTableSize, uint32_t nTableMask) {
+	return HT_DATA_SIZE(nTableSize) + HT_HASH_SIZE(nTableMask);
+}
+
+static zend_always_inline size_t HT_SIZE(const HashTable *ht) {
+	return HT_SIZE_EX(ht->nTableSize, ht->nTableMask);
+}
+
+static zend_always_inline size_t HT_USED_SIZE(const HashTable *ht) {
+	return HT_HASH_SIZE(ht->nTableMask) + ((size_t)ht->nNumUsed * sizeof(Bucket));
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline size_t HT_PACKED_DATA_SIZE(uint32_t nTableSize) {
+	return ((size_t)nTableSize) * sizeof(zval);
+}
+
+ZEND_ATTRIBUTE_CONST static zend_always_inline size_t HT_PACKED_SIZE_EX(uint32_t nTableSize, uint32_t nTableMask) {
+	return HT_PACKED_DATA_SIZE(nTableSize) + HT_HASH_SIZE(nTableMask);
+}
+
+static zend_always_inline size_t HT_PACKED_SIZE(const HashTable *ht) {
+	return HT_PACKED_SIZE_EX(ht->nTableSize, ht->nTableMask);
+}
+
+static zend_always_inline size_t HT_PACKED_USED_SIZE(const HashTable *ht) {
+	return HT_HASH_SIZE(ht->nTableMask) + ((size_t)ht->nNumUsed * sizeof(zval));
+}
+
+static zend_always_inline void HT_HASH_RESET(HashTable *ht) {
+	char *p = (char*)&HT_HASH(ht, ht->nTableMask);
+	size_t size = HT_HASH_SIZE(ht->nTableMask);
+
 #if defined(__AVX2__)
-# define HT_HASH_RESET(ht) do { \
-		char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
-		size_t size = HT_HASH_SIZE((ht)->nTableMask); \
-		__m256i ymm0 = _mm256_setzero_si256(); \
-		ymm0 = _mm256_cmpeq_epi64(ymm0, ymm0); \
-		ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
-		do { \
-			_mm256_storeu_si256((__m256i*)p, ymm0); \
-			_mm256_storeu_si256((__m256i*)(p+32), ymm0); \
-			p += 64; \
-			size -= 64; \
-		} while (size != 0); \
-	} while (0)
+	__m256i ymm0 = _mm256_setzero_si256();
+	ymm0 = _mm256_cmpeq_epi64(ymm0, ymm0);
+	ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0));
+	do {
+		_mm256_storeu_si256((__m256i*)p, ymm0);
+		_mm256_storeu_si256((__m256i*)(p+32), ymm0);
+		p += 64;
+		size -= 64;
+	} while (size != 0);
 #elif defined(__SSE2__)
-# define HT_HASH_RESET(ht) do { \
-		char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
-		size_t size = HT_HASH_SIZE((ht)->nTableMask); \
-		__m128i xmm0 = _mm_setzero_si128(); \
-		xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
-		ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
-		do { \
-			_mm_storeu_si128((__m128i*)p, xmm0); \
-			_mm_storeu_si128((__m128i*)(p+16), xmm0); \
-			_mm_storeu_si128((__m128i*)(p+32), xmm0); \
-			_mm_storeu_si128((__m128i*)(p+48), xmm0); \
-			p += 64; \
-			size -= 64; \
-		} while (size != 0); \
-	} while (0)
+	__m128i xmm0 = _mm_setzero_si128();
+	xmm0 = _mm_cmpeq_epi8(xmm0, xmm0);
+	ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0));
+	do {
+		_mm_storeu_si128((__m128i*)p, xmm0);
+		_mm_storeu_si128((__m128i*)(p+16), xmm0);
+		_mm_storeu_si128((__m128i*)(p+32), xmm0);
+		_mm_storeu_si128((__m128i*)(p+48), xmm0);
+		p += 64;
+		size -= 64;
+	} while (size != 0);
 #elif defined(__aarch64__) || defined(_M_ARM64)
-# define HT_HASH_RESET(ht) do { \
-		char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
-		size_t size = HT_HASH_SIZE((ht)->nTableMask); \
-		int32x4_t t = vdupq_n_s32(-1); \
-		ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
-		do { \
-			vst1q_s32((int32_t*)p, t); \
-			vst1q_s32((int32_t*)(p+16), t); \
-			vst1q_s32((int32_t*)(p+32), t); \
-			vst1q_s32((int32_t*)(p+48), t); \
-			p += 64; \
-			size -= 64; \
-		} while (size != 0); \
-	} while (0)
+	int32x4_t t = vdupq_n_s32(-1);
+	ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0));
+	do {
+		vst1q_s32((int32_t*)p, t);
+		vst1q_s32((int32_t*)(p+16), t);
+		vst1q_s32((int32_t*)(p+32), t);
+		vst1q_s32((int32_t*)(p+48), t);
+		p += 64;
+		size -= 64;
+	} while (size != 0);
 #else
-# define HT_HASH_RESET(ht) \
-	memset(&HT_HASH(ht, (ht)->nTableMask), HT_INVALID_IDX, HT_HASH_SIZE((ht)->nTableMask))
+	memset(p, HT_INVALID_IDX, size);
 #endif
-#define HT_HASH_RESET_PACKED(ht) do { \
-		HT_HASH(ht, -2) = HT_INVALID_IDX; \
-		HT_HASH(ht, -1) = HT_INVALID_IDX; \
-	} while (0)
-#define HT_HASH_TO_BUCKET(ht, idx) \
-	HT_HASH_TO_BUCKET_EX((ht)->arData, idx)
+}
+
+static zend_always_inline void HT_HASH_RESET_PACKED(HashTable *ht) {
+	HT_HASH(ht, -2) = HT_INVALID_IDX;
+	HT_HASH(ht, -1) = HT_INVALID_IDX;
+}
+
+static zend_always_inline Bucket *HT_HASH_TO_BUCKET(HashTable *ht, uint32_t idx) {
+	return HT_HASH_TO_BUCKET_EX(ht->arData, idx);
+}
 
 #define HT_SET_DATA_ADDR(ht, ptr) do { \
 		(ht)->arData = (Bucket*)(((char*)(ptr)) + HT_HASH_SIZE((ht)->nTableMask)); \
@@ -716,6 +739,116 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
 #define Z_TYPE_FLAGS_SHIFT			8
 #define Z_TYPE_INFO_EXTRA_SHIFT		16
 
+/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */
+#define GC_NOT_COLLECTABLE			(1<<4)
+#define GC_PROTECTED                (1<<5) /* used for recursion detection */
+#define GC_IMMUTABLE                (1<<6) /* can't be changed in place */
+#define GC_PERSISTENT               (1<<7) /* allocated using malloc */
+#define GC_PERSISTENT_LOCAL         (1<<8) /* persistent, but thread-local */
+
+#define GC_TYPE_MASK				0x0000000f
+#define GC_FLAGS_MASK				0x000003f0
+#define GC_INFO_MASK				0xfffffc00
+#define GC_FLAGS_SHIFT				0
+#define GC_INFO_SHIFT				10
+
+static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
+	return (gc_type_info & GC_TYPE_MASK);
+}
+
+static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) {
+	return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
+}
+
+static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
+	return (gc_type_info >> GC_INFO_SHIFT);
+}
+
+#define GC_TYPE_INFO(p)				(p)->gc.u.type_info
+#define GC_TYPE(p)					zval_gc_type(GC_TYPE_INFO(p))
+#define GC_FLAGS(p)					zval_gc_flags(GC_TYPE_INFO(p))
+#define GC_INFO(p)					zval_gc_info(GC_TYPE_INFO(p))
+
+#define GC_ADD_FLAGS(p, flags) do { \
+		GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \
+	} while (0)
+#define GC_DEL_FLAGS(p, flags) do { \
+		GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \
+	} while (0)
+
+#ifndef ZEND_RC_DEBUG
+# define ZEND_RC_DEBUG 0
+#endif
+
+#if ZEND_RC_DEBUG
+extern ZEND_API bool zend_rc_debug;
+/* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects.
+ * Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */
+# define ZEND_RC_MOD_CHECK(p) do { \
+		if (zend_rc_debug) { \
+			uint8_t type = zval_gc_type((p)->u.type_info); \
+			if (type != IS_OBJECT && type != IS_NULL) { \
+				ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \
+				ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
+			} \
+		} \
+	} while (0)
+# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
+		GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \
+	} while (0)
+#else
+# define ZEND_RC_MOD_CHECK(p) \
+	do { } while (0)
+# define GC_MAKE_PERSISTENT_LOCAL(p) \
+	do { } while (0)
+#endif
+
+static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) {
+	return p->refcount;
+}
+
+static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) {
+	p->refcount = rc;
+	return p->refcount;
+}
+
+static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
+	ZEND_RC_MOD_CHECK(p);
+	return ++(p->refcount);
+}
+
+static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) {
+	if (!(p->u.type_info & GC_IMMUTABLE)) {
+		ZEND_RC_MOD_CHECK(p);
+		++p->refcount;
+	}
+}
+
+static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) {
+	if (!(p->u.type_info & GC_IMMUTABLE)) {
+		ZEND_RC_MOD_CHECK(p);
+		--p->refcount;
+	}
+}
+
+static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
+	ZEND_ASSERT(p->refcount > 0);
+	ZEND_RC_MOD_CHECK(p);
+	return --(p->refcount);
+}
+
+static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) {
+	ZEND_RC_MOD_CHECK(p);
+	p->refcount += rc;
+	return p->refcount;
+}
+
+static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) {
+	ZEND_RC_MOD_CHECK(p);
+	p->refcount -= rc;
+	return p->refcount;
+}
+
 #define GC_REFCOUNT(p)				zend_gc_refcount(&(p)->gc)
 #define GC_SET_REFCOUNT(p, rc)		zend_gc_set_refcount(&(p)->gc, rc)
 #define GC_ADDREF(p)				zend_gc_addref(&(p)->gc)
@@ -757,54 +890,6 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
 		} \
 	} while (0)
 
-#define GC_TYPE_MASK				0x0000000f
-#define GC_FLAGS_MASK				0x000003f0
-#define GC_INFO_MASK				0xfffffc00
-#define GC_FLAGS_SHIFT				0
-#define GC_INFO_SHIFT				10
-
-static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
-	return (gc_type_info & GC_TYPE_MASK);
-}
-
-static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) {
-	return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
-}
-
-static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
-	return (gc_type_info >> GC_INFO_SHIFT);
-}
-
-#define GC_TYPE_INFO(p)				(p)->gc.u.type_info
-#define GC_TYPE(p)					zval_gc_type(GC_TYPE_INFO(p))
-#define GC_FLAGS(p)					zval_gc_flags(GC_TYPE_INFO(p))
-#define GC_INFO(p)					zval_gc_info(GC_TYPE_INFO(p))
-
-#define GC_ADD_FLAGS(p, flags) do { \
-		GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \
-	} while (0)
-#define GC_DEL_FLAGS(p, flags) do { \
-		GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \
-	} while (0)
-
-#define Z_GC_TYPE(zval)				GC_TYPE(Z_COUNTED(zval))
-#define Z_GC_TYPE_P(zval_p)			Z_GC_TYPE(*(zval_p))
-
-#define Z_GC_FLAGS(zval)			GC_FLAGS(Z_COUNTED(zval))
-#define Z_GC_FLAGS_P(zval_p)		Z_GC_FLAGS(*(zval_p))
-
-#define Z_GC_INFO(zval)				GC_INFO(Z_COUNTED(zval))
-#define Z_GC_INFO_P(zval_p)			Z_GC_INFO(*(zval_p))
-#define Z_GC_TYPE_INFO(zval)		GC_TYPE_INFO(Z_COUNTED(zval))
-#define Z_GC_TYPE_INFO_P(zval_p)	Z_GC_TYPE_INFO(*(zval_p))
-
-/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */
-#define GC_NOT_COLLECTABLE			(1<<4)
-#define GC_PROTECTED                (1<<5) /* used for recursion detection */
-#define GC_IMMUTABLE                (1<<6) /* can't be changed in place */
-#define GC_PERSISTENT               (1<<7) /* allocated using malloc */
-#define GC_PERSISTENT_LOCAL         (1<<8) /* persistent, but thread-local */
-
 #define GC_NULL						(IS_NULL         | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT))
 #define GC_STRING					(IS_STRING       | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT))
 #define GC_ARRAY					IS_ARRAY
@@ -858,6 +943,8 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 
 #define IS_OBJ_LAZY_UNINITIALIZED   (1U<<31) /* Virtual proxy or uninitialized Ghost */
 #define IS_OBJ_LAZY_PROXY           (1U<<30) /* Virtual proxy (may be initialized) */
+#define OBJ_EXTRA_FLAG_PRIV_1       (1U<<29) /* Reserved for private use by the object itself */
+#define OBJ_EXTRA_FLAG_PRIV_2       (1U<<28) /* Reserved for private use by the object itself */
 
 #define OBJ_EXTRA_FLAGS(obj)		((obj)->extra_flags)
 
@@ -932,8 +1019,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 	} while(0)
 
 /* All data types < IS_STRING have their constructor/destructors skipped */
-#define Z_CONSTANT(zval)			(Z_TYPE(zval) == IS_CONSTANT_AST)
-#define Z_CONSTANT_P(zval_p)		Z_CONSTANT(*(zval_p))
 
 #if 1
 /* This optimized version assumes that we have a single "type_flag" */
@@ -947,33 +1032,16 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 #define Z_COLLECTABLE(zval)			((Z_TYPE_FLAGS(zval) & IS_TYPE_COLLECTABLE) != 0)
 #define Z_COLLECTABLE_P(zval_p)		Z_COLLECTABLE(*(zval_p))
 
-/* deprecated: (COPYABLE is the same as IS_ARRAY) */
-#define Z_COPYABLE(zval)			(Z_TYPE(zval) == IS_ARRAY)
-#define Z_COPYABLE_P(zval_p)		Z_COPYABLE(*(zval_p))
-
-/* deprecated: (IMMUTABLE is the same as IS_ARRAY && !REFCOUNTED) */
-#define Z_IMMUTABLE(zval)			(Z_TYPE_INFO(zval) == IS_ARRAY)
-#define Z_IMMUTABLE_P(zval_p)		Z_IMMUTABLE(*(zval_p))
-#define Z_OPT_IMMUTABLE(zval)		Z_IMMUTABLE(zval_p)
-#define Z_OPT_IMMUTABLE_P(zval_p)	Z_IMMUTABLE(*(zval_p))
-
 /* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
 #define Z_OPT_TYPE(zval)			(Z_TYPE_INFO(zval) & Z_TYPE_MASK)
 #define Z_OPT_TYPE_P(zval_p)		Z_OPT_TYPE(*(zval_p))
 
-#define Z_OPT_CONSTANT(zval)		(Z_OPT_TYPE(zval) == IS_CONSTANT_AST)
-#define Z_OPT_CONSTANT_P(zval_p)	Z_OPT_CONSTANT(*(zval_p))
-
 #define Z_OPT_REFCOUNTED(zval)		Z_TYPE_INFO_REFCOUNTED(Z_TYPE_INFO(zval))
 #define Z_OPT_REFCOUNTED_P(zval_p)	Z_OPT_REFCOUNTED(*(zval_p))
 
 #define Z_OPT_COLLECTABLE(zval)		((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
 #define Z_OPT_COLLECTABLE_P(zval_p)	Z_OPT_COLLECTABLE(*(zval_p))
 
-/* deprecated: (COPYABLE is the same as IS_ARRAY) */
-#define Z_OPT_COPYABLE(zval)		(Z_OPT_TYPE(zval) == IS_ARRAY)
-#define Z_OPT_COPYABLE_P(zval_p)	Z_OPT_COPYABLE(*(zval_p))
-
 #define Z_OPT_ISREF(zval)			(Z_OPT_TYPE(zval) == IS_REFERENCE)
 #define Z_OPT_ISREF_P(zval_p)		Z_OPT_ISREF(*(zval_p))
 
@@ -1316,79 +1384,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 #define Z_TRY_ADDREF(z)				Z_TRY_ADDREF_P(&(z))
 #define Z_TRY_DELREF(z)				Z_TRY_DELREF_P(&(z))
 
-#ifndef ZEND_RC_DEBUG
-# define ZEND_RC_DEBUG 0
-#endif
-
-#if ZEND_RC_DEBUG
-extern ZEND_API bool zend_rc_debug;
-/* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects.
- * Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */
-# define ZEND_RC_MOD_CHECK(p) do { \
-		if (zend_rc_debug) { \
-			uint8_t type = zval_gc_type((p)->u.type_info); \
-			if (type != IS_OBJECT && type != IS_NULL) { \
-				ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \
-				ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
-			} \
-		} \
-	} while (0)
-# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
-		GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \
-	} while (0)
-#else
-# define ZEND_RC_MOD_CHECK(p) \
-	do { } while (0)
-# define GC_MAKE_PERSISTENT_LOCAL(p) \
-	do { } while (0)
-#endif
-
-static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) {
-	return p->refcount;
-}
-
-static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) {
-	p->refcount = rc;
-	return p->refcount;
-}
-
-static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
-	ZEND_RC_MOD_CHECK(p);
-	return ++(p->refcount);
-}
-
-static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) {
-	if (!(p->u.type_info & GC_IMMUTABLE)) {
-		ZEND_RC_MOD_CHECK(p);
-		++p->refcount;
-	}
-}
-
-static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) {
-	if (!(p->u.type_info & GC_IMMUTABLE)) {
-		ZEND_RC_MOD_CHECK(p);
-		--p->refcount;
-	}
-}
-
-static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
-	ZEND_ASSERT(p->refcount > 0);
-	ZEND_RC_MOD_CHECK(p);
-	return --(p->refcount);
-}
-
-static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) {
-	ZEND_RC_MOD_CHECK(p);
-	p->refcount += rc;
-	return p->refcount;
-}
-
-static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) {
-	ZEND_RC_MOD_CHECK(p);
-	p->refcount -= rc;
-	return p->refcount;
-}
-
 static zend_always_inline uint32_t zval_refcount_p(const zval* pz) {
 #if ZEND_DEBUG
 	ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_TYPE_P(pz) == IS_ARRAY);
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 00f10b08f80a..02c286ac486a 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h
index d90ad9951782..9c6040a75bcb 100644
--- a/Zend/zend_variables.h
+++ b/Zend/zend_variables.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_verify_type_inference.h b/Zend/zend_verify_type_inference.h
index 8e9cbcbc181f..807bf21e3910 100644
--- a/Zend/zend_verify_type_inference.h
+++ b/Zend/zend_verify_type_inference.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
 */
 
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index 94183e3724c4..da27e9fd5426 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Sascha Schumann                         |
@@ -195,7 +193,7 @@ void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */
 	main_cwd_state.cwd_length = strlen(cwd);
 #ifdef ZEND_WIN32
 	if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') {
-		cwd[0] = toupper(cwd[0]);
+		cwd[0] = toupper((unsigned char)cwd[0]);
 	}
 #endif
 	main_cwd_state.cwd = strdup(cwd);
@@ -271,7 +269,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length) /* {{{ */
 		*length = state->cwd_length+1;
 		retval = (char *) emalloc(*length+1);
 		memcpy(retval, state->cwd, *length);
-		retval[0] = toupper(retval[0]);
+		retval[0] = toupper((unsigned char)retval[0]);
 		retval[*length-1] = DEFAULT_SLASH;
 		retval[*length] = '\0';
 		return retval;
@@ -1114,7 +1112,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
 			if (resolved_path[start] == 0) {
 				goto verify;
 			}
-			resolved_path[start] = toupper(resolved_path[start]);
+			resolved_path[start] = toupper((unsigned char)resolved_path[start]);
 			start++;
 		}
 		resolved_path[start++] = DEFAULT_SLASH;
@@ -1122,13 +1120,13 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
 			if (resolved_path[start] == 0) {
 				goto verify;
 			}
-			resolved_path[start] = toupper(resolved_path[start]);
+			resolved_path[start] = toupper((unsigned char)resolved_path[start]);
 			start++;
 		}
 		resolved_path[start++] = DEFAULT_SLASH;
 	} else if (IS_ABSOLUTE_PATH(resolved_path, path_length)) {
 		/* skip DRIVE name */
-		resolved_path[0] = toupper(resolved_path[0]);
+		resolved_path[0] = toupper((unsigned char)resolved_path[0]);
 		resolved_path[2] = DEFAULT_SLASH;
 		if (path_length == 2) {
 			resolved_path[3] = '\0';
diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h
index 21735f6dfae5..ad30c0323892 100644
--- a/Zend/zend_virtual_cwd.h
+++ b/Zend/zend_virtual_cwd.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Sascha Schumann                         |
@@ -87,7 +85,7 @@ typedef unsigned short mode_t;
 #define IS_UNC_PATH(path, len) \
 	(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
 #define IS_ABSOLUTE_PATH(path, len) \
-	(len >= 2 && (/* is local */isalpha(path[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
+	(len >= 2 && (/* is local */isalpha((unsigned char)(path)[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
 
 #else
 #ifdef HAVE_DIRENT_H
diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h
index c9c41c75c72a..4f4a48c92205 100644
--- a/Zend/zend_vm.h
+++ b/Zend/zend_vm.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -32,6 +31,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op);
 ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op);
 ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op);
 ZEND_API const zend_op *zend_get_halt_op(void);
+ZEND_API const zend_op *zend_get_interrupt_op(void);
 ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data *ex);
 ZEND_API int zend_vm_kind(void);
 ZEND_API bool zend_gcc_global_regs(void);
@@ -39,6 +39,10 @@ ZEND_API bool zend_gcc_global_regs(void);
 void zend_vm_init(void);
 void zend_vm_dtor(void);
 
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+const struct _zend_op *ZEND_FASTCALL zend_vm_handle_interrupt(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
+#endif
+
 END_EXTERN_C()
 
 #define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 86708f8c97a2..0e5efa6f826c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -4154,11 +4153,15 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 	ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
@@ -4283,11 +4286,15 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -4412,11 +4419,15 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -4480,7 +4491,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -4509,6 +4520,9 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -5712,6 +5726,30 @@ ZEND_VM_HELPER(zend_verify_recv_arg_type_helper, ANY, ANY, zval *op_1)
 	ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(213, ZEND_SEND_PLACEHOLDER, UNUSED, CONST|UNUSED|NUM)
+{
+	zval *arg;
+
+	if (OP2_TYPE == IS_CONST) {
+		/* Named placeholder */
+		USE_OPLINE
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* Positional placeholder */
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	Z_TYPE_INFO_P(arg) = _IS_PLACEHOLDER;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_HOT_HANDLER(63, ZEND_RECV, NUM, UNUSED)
 {
 	USE_OPLINE
@@ -8309,7 +8347,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
 	val   = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 			FREE_OP1();
@@ -8341,7 +8379,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
 	val   = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 			FREE_OP1();
@@ -8832,7 +8870,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMP|CV, ANY)
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -8907,9 +8945,10 @@ ZEND_VM_HOT_HANDLER(211, ZEND_TYPE_ASSERT, CONST, ANY, NUM)
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
@@ -9012,7 +9051,7 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMP|UNUSED|CLASS_FETCH, ANY)
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -9119,11 +9158,15 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 		ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
@@ -9572,7 +9615,9 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMP|CV, UNUSED)
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -9821,6 +9866,45 @@ ZEND_VM_HANDLER(202, ZEND_CALLABLE_CONVERT, UNUSED, UNUSED, NUM|CACHE_SLOT)
 	ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(212, ZEND_CALLABLE_CONVERT_PARTIAL, CACHE_SLOT, CONST|UNUSED, NUM)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_execute_data *call = EX(call);
+	void **cache_slot = CACHE_ADDR(opline->op1.num);
+	zval *named_positions = GET_OP2_ZVAL_PTR();
+
+	zend_partial_create(EX_VAR(opline->result.var),
+		&call->This, call->func,
+		ZEND_CALL_NUM_ARGS(call), ZEND_CALL_ARG(call, 1),
+		(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) ?
+			call->extra_named_params : NULL,
+		OP2_TYPE == IS_CONST ? Z_ARRVAL_P(named_positions) : NULL,
+		&EX(func)->op_array, opline, cache_slot,
+		opline->extended_value & ZEND_FCALL_USES_VARIADIC_PLACEHOLDER);
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_array_release(call->extra_named_params);
+	}
+
+	if ((call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+		zend_free_trampoline(call->func);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	} else if (ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE) {
+		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 ZEND_VM_HANDLER(208, ZEND_JMP_FRAMELESS, CONST, JMP_ADDR, NUM|CACHE_SLOT)
 {
 	USE_OPLINE
@@ -10607,7 +10691,12 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
 ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
 {
 	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
 	SAVE_OPLINE();
+#endif
 	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
 		zend_timeout();
 	} else if (zend_interrupt_function) {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index cbfae90802cf..6b675837d3a7 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -307,6 +306,7 @@ static uint8_t zend_user_opcodes[256] = {0,
 };
 
 #include "Zend/zend_vm_opcodes.h"
+#include "Zend/zend_partial.h"
 
 #define SPEC_START_MASK        0x0000ffff
 #define SPEC_EXTRA_MASK        0xfffc0000
@@ -331,6 +331,11 @@ static zend_op hybrid_halt_op;
 
 static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;
 #endif
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static const zend_op call_interrupt_op;
+#endif
+
 #if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC
 static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);
 #endif
@@ -1322,11 +1327,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
@@ -1388,11 +1397,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
@@ -1454,11 +1467,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 	zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -1636,11 +1653,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -1750,11 +1771,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -1863,11 +1888,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -1995,11 +2024,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -2126,11 +2159,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -2254,11 +2291,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -3639,11 +3680,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALL_TRAMPOLI
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 
@@ -3783,11 +3828,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALL_TRAMPOLI
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -3984,7 +4033,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_J
 static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
 	SAVE_OPLINE();
+#endif
 	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
 		zend_timeout();
 	} else if (zend_interrupt_function) {
@@ -4219,6 +4273,45 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_R
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_execute_data *call = EX(call);
+	void **cache_slot = CACHE_ADDR(opline->op1.num);
+	zval *named_positions = RT_CONSTANT(opline, opline->op2);
+
+	zend_partial_create(EX_VAR(opline->result.var),
+		&call->This, call->func,
+		ZEND_CALL_NUM_ARGS(call), ZEND_CALL_ARG(call, 1),
+		(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) ?
+			call->extra_named_params : NULL,
+		IS_CONST == IS_CONST ? Z_ARRVAL_P(named_positions) : NULL,
+		&EX(func)->op_array, opline, cache_slot,
+		opline->extended_value & ZEND_FCALL_USES_VARIADIC_PLACEHOLDER);
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_array_release(call->extra_named_params);
+	}
+
+	if ((call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+		zend_free_trampoline(call->func);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	} else if (ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE) {
+		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -4363,6 +4456,45 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RECV_VARIADIC
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_execute_data *call = EX(call);
+	void **cache_slot = CACHE_ADDR(opline->op1.num);
+	zval *named_positions = NULL;
+
+	zend_partial_create(EX_VAR(opline->result.var),
+		&call->This, call->func,
+		ZEND_CALL_NUM_ARGS(call), ZEND_CALL_ARG(call, 1),
+		(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) ?
+			call->extra_named_params : NULL,
+		IS_UNUSED == IS_CONST ? Z_ARRVAL_P(named_positions) : NULL,
+		&EX(func)->op_array, opline, cache_slot,
+		opline->extended_value & ZEND_FCALL_USES_VARIADIC_PLACEHOLDER);
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_array_release(call->extra_named_params);
+	}
+
+	if ((call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+		zend_free_trampoline(call->func);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	} else if (ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE) {
+		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -6040,7 +6172,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -6117,9 +6249,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_T
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
@@ -8237,7 +8370,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_CONST
 	val   = RT_CONSTANT(opline, opline->op2);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 
@@ -8272,7 +8405,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_ATTRI
 	val   = RT_CONSTANT(opline, opline->op2);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 
@@ -11166,7 +11299,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -11195,6 +11328,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -11765,7 +11901,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -18122,7 +18260,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_T
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -18232,7 +18370,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_N
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -21473,7 +21611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -21502,6 +21640,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -21965,7 +22106,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_TM
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -29516,7 +29659,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -29545,6 +29688,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -32825,7 +32971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_N
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -34405,6 +34551,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_AR
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *arg;
+
+	if (IS_CONST == IS_CONST) {
+		/* Named placeholder */
+		USE_OPLINE
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* Positional placeholder */
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	Z_TYPE_INFO_P(arg) = _IS_PLACEHOLDER;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -36903,7 +37073,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -36932,6 +37102,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -37029,6 +37202,30 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_C
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		/* Named placeholder */
+		USE_OPLINE
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* Positional placeholder */
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	Z_TYPE_INFO_P(arg) = _IS_PLACEHOLDER;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -40711,7 +40908,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_C
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -40825,7 +41022,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_N
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -49112,7 +49309,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -49141,6 +49338,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -49894,7 +50094,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_CV
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -53439,6 +53641,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(
 	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
 }
 
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS) {
+	SAVE_OPLINE();
+	return &call_interrupt_op;
+}
+#endif
 
 #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
 # undef ZEND_VM_TAIL_CALL
@@ -53457,6 +53665,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(
 # undef ZEND_VM_RETURN
 # undef ZEND_VM_DISPATCH_TO_HELPER
 # undef ZEND_VM_INTERRUPT
+# undef ZEND_VM_ENTER_EX
+# undef ZEND_VM_LEAVE
 
 # define ZEND_VM_TAIL_CALL(call)               ZEND_MUSTTAIL return call
 # define ZEND_VM_CONTINUE()                    ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))
@@ -53467,9 +53677,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(
         ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \
     } while (0)
 # define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE()
-# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))
+# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))
+# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()
+# define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()
 
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
 static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline);
@@ -53480,6 +53694,9 @@ static const zend_op call_halt_op = {
 static const zend_op call_leave_op = {
     .handler = zend_leave_helper_SPEC_TAILCALL,
 };
+static const zend_op call_interrupt_op = {
+    .handler = zend_interrupt_helper_SPEC_TAILCALL,
+};
 
 static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
 static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
@@ -54042,11 +54259,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICA
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
@@ -54108,11 +54329,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICA
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
@@ -54174,11 +54399,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_IC
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 	zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -54356,11 +54585,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCA
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -54470,11 +54703,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCA
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -54583,11 +54820,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FC
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -54715,11 +54956,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCA
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -54846,11 +55091,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCA
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -54974,11 +55223,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FC
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
@@ -56243,11 +56496,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SP
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 
@@ -56387,11 +56644,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SP
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -56588,7 +56849,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FO
 static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
 	SAVE_OPLINE();
+#endif
 	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
 		zend_timeout();
 	} else if (zend_interrupt_function) {
@@ -56823,6 +57089,45 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_I
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_execute_data *call = EX(call);
+	void **cache_slot = CACHE_ADDR(opline->op1.num);
+	zval *named_positions = RT_CONSTANT(opline, opline->op2);
+
+	zend_partial_create(EX_VAR(opline->result.var),
+		&call->This, call->func,
+		ZEND_CALL_NUM_ARGS(call), ZEND_CALL_ARG(call, 1),
+		(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) ?
+			call->extra_named_params : NULL,
+		IS_CONST == IS_CONST ? Z_ARRVAL_P(named_positions) : NULL,
+		&EX(func)->op_array, opline, cache_slot,
+		opline->extended_value & ZEND_FCALL_USES_VARIADIC_PLACEHOLDER);
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_array_release(call->extra_named_params);
+	}
+
+	if ((call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+		zend_free_trampoline(call->func);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	} else if (ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE) {
+		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -56967,6 +57272,45 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_VARIADIC_SPEC
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_execute_data *call = EX(call);
+	void **cache_slot = CACHE_ADDR(opline->op1.num);
+	zval *named_positions = NULL;
+
+	zend_partial_create(EX_VAR(opline->result.var),
+		&call->This, call->func,
+		ZEND_CALL_NUM_ARGS(call), ZEND_CALL_ARG(call, 1),
+		(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) ?
+			call->extra_named_params : NULL,
+		IS_UNUSED == IS_CONST ? Z_ARRVAL_P(named_positions) : NULL,
+		&EX(func)->op_array, opline, cache_slot,
+		opline->extended_value & ZEND_FCALL_USES_VARIADIC_PLACEHOLDER);
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_array_release(call->extra_named_params);
+	}
+
+	if ((call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+		zend_free_trampoline(call->func);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	} else if (ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE) {
+		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -58644,7 +58988,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLE
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -58721,9 +59065,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_A
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
@@ -60841,7 +61186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CONST_SPEC
 	val   = RT_CONSTANT(opline, opline->op2);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 
@@ -60876,7 +61221,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ATTRIBUTED
 	val   = RT_CONSTANT(opline, opline->op2);
 
 	ZVAL_COPY(&c.value, val);
-	if (Z_OPT_CONSTANT(c.value)) {
+	if (Z_OPT_TYPE(c.value) == IS_CONSTANT_AST) {
 		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 			zval_ptr_dtor_nogc(&c.value);
 
@@ -63668,7 +64013,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIF
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -63697,6 +64042,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIF
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -64267,7 +64615,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -70624,7 +70974,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_TMP_TA
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -70734,7 +71084,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_S
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -73875,7 +74225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -73904,6 +74254,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -74367,7 +74720,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_TMP_UNU
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -81918,7 +82273,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -81947,6 +82302,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -85227,7 +85585,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_S
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -86807,6 +87165,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_FUNC_ARG_SPE
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *arg;
+
+	if (IS_CONST == IS_CONST) {
+		/* Named placeholder */
+		USE_OPLINE
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* Positional placeholder */
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	Z_TYPE_INFO_P(arg) = _IS_PLACEHOLDER;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -89305,7 +89687,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -89334,6 +89716,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -89431,6 +89816,30 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		/* Named placeholder */
+		USE_OPLINE
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* Positional placeholder */
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	Z_TYPE_INFO_P(arg) = _IS_PLACEHOLDER;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -93113,7 +93522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_CV_TAI
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -93227,7 +93636,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_S
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -101412,7 +101821,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 			ZVAL_DEREF(retval_ptr);
 		}
 
-		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
 
@@ -101441,6 +101850,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE
 				}
 				retval_ptr = retval_ref;
 			}
+			if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+				ZEND_VM_NEXT_OPCODE();
+			}
 		}
 
 		SAVE_OPLINE();
@@ -102194,7 +102606,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_CV_UNUS
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -105744,13 +106158,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HAND
 	return (zend_op*) ZEND_VM_ENTER_BIT;
 }
 
+static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) {
+	SAVE_OPLINE();
+	ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
 /* The following helpers can not tailcall due to signature mismatch. Redefine some macros so they do not enforce tailcall. */
 #pragma push_macro("ZEND_VM_CONTINUE")
 #undef  ZEND_VM_CONTINUE
 #pragma push_macro("ZEND_VM_INTERRUPT")
 #undef  ZEND_VM_INTERRUPT
 #define ZEND_VM_CONTINUE(handler) return opline
-#define ZEND_VM_INTERRUPT()       return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+#define ZEND_VM_INTERRUPT()       return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
 static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
@@ -109110,6 +109528,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_LABEL,
 			(void*)&&ZEND_TYPE_ASSERT_SPEC_CONST_LABEL,
+			(void*)&&ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL,
 			(void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -110514,6 +110942,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_RECV_INIT_SPEC_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST):
+				VM_TRACE(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST)
+				ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP):
 				VM_TRACE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP)
 				ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -110529,6 +110962,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_RECV_VARIADIC_SPEC_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED):
+				VM_TRACE(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED)
+				ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED):
 				VM_TRACE(ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED)
 				ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -113752,6 +114190,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST):
+				VM_TRACE(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST)
+				ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST):
 				VM_TRACE(ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST)
 				ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -113932,6 +114375,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED):
+				VM_TRACE(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED)
+				ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_NEW_SPEC_UNUSED_UNUSED):
 				VM_TRACE(ZEND_NEW_SPEC_UNUSED_UNUSED)
 				ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -118048,6 +118496,16 @@ void zend_vm_init(void)
 		ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER,
 		ZEND_TYPE_ASSERT_SPEC_CONST_HANDLER,
+		ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER,
 		ZEND_RECV_NOTYPE_SPEC_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -121526,6 +121984,16 @@ void zend_vm_init(void)
 		ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
 		ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER,
 		ZEND_TYPE_ASSERT_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
 		ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER,
 		ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER,
 		ZEND_NULL_TAILCALL_HANDLER,
@@ -122494,7 +122962,7 @@ void zend_vm_init(void)
 		1255,
 		1256 | SPEC_RULE_OP1,
 		1261 | SPEC_RULE_OP1,
-		3474,
+		3484,
 		1266 | SPEC_RULE_OP1,
 		1271 | SPEC_RULE_OP1,
 		1276 | SPEC_RULE_OP2,
@@ -122528,7 +122996,7 @@ void zend_vm_init(void)
 		1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 		1584 | SPEC_RULE_OP1,
 		1589,
-		3474,
+		3484,
 		1590 | SPEC_RULE_OP1,
 		1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 		1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
@@ -122661,50 +123129,50 @@ void zend_vm_init(void)
 		2556,
 		2557,
 		2558,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
-		3474,
+		2559 | SPEC_RULE_OP2,
+		2564 | SPEC_RULE_OP2,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
+		3484,
 	};
 #if 0
 #elif (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
@@ -122745,7 +123213,7 @@ static void init_opcode_serialiser(void)
 	Z_TYPE_INFO(tmp) = IS_LONG;
 	for (i = 0; i < zend_handlers_count; i++) {
 		Z_LVAL(tmp) = i;
-		zend_hash_index_add(zend_handlers_table, (zend_long)(uintptr_t)zend_opcode_handlers[i], &tmp);
+		zend_hash_index_add(zend_handlers_table, (zend_ulong)(uintptr_t)zend_opcode_handlers[i], &tmp);
 	}
 }
 
@@ -122756,7 +123224,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
 }
@@ -122774,7 +123242,7 @@ ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *o
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	return zend_opcode_handler_funcs[Z_LVAL_P(zv)];
 #elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
@@ -122793,6 +123261,22 @@ ZEND_API const zend_op *zend_get_halt_op(void)
 #endif
 }
 
+ZEND_API const zend_op *zend_get_interrupt_op(void)
+{
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	return &call_interrupt_op;
+#else
+	return NULL;
+#endif
+}
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS)
+{
+	return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+#endif
+
 ZEND_API int zend_vm_kind(void)
 {
 	return ZEND_VM_KIND;
@@ -122881,7 +123365,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2567 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2577 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -122889,7 +123373,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2592 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2602 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -122897,7 +123381,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2617 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2627 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -122908,17 +123392,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2642 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2652 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2667 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2677 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2692 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2702 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			}
 			break;
 		case ZEND_MUL:
@@ -122929,17 +123413,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2717 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2727 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2742 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2752 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2767 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_IDENTICAL:
@@ -122950,16 +123434,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2802 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2877 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) {
-				spec = 3092 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3102 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
-				spec = 3098 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 3108 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_NOT_IDENTICAL:
@@ -122970,16 +123454,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2952 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3027 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) {
-				spec = 3095 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3105 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
-				spec = 3103 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 3113 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_EQUAL:
@@ -122990,12 +123474,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2802 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2877 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_NOT_EQUAL:
@@ -123006,12 +123490,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2952 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3027 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_SMALLER:
@@ -123019,12 +123503,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3108 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3118 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3183 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3193 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			}
 			break;
 		case ZEND_IS_SMALLER_OR_EQUAL:
@@ -123032,79 +123516,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3258 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3268 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3333 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3343 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			}
 			break;
 		case ZEND_QM_ASSIGN:
 			if (op1_info == MAY_BE_LONG) {
-				spec = 3420 | SPEC_RULE_OP1;
+				spec = 3430 | SPEC_RULE_OP1;
 			} else if (op1_info == MAY_BE_DOUBLE) {
-				spec = 3425 | SPEC_RULE_OP1;
+				spec = 3435 | SPEC_RULE_OP1;
 			} else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) {
-				spec = 3430 | SPEC_RULE_OP1;
+				spec = 3440 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_PRE_INC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3408 | SPEC_RULE_RETVAL;
+				spec = 3418 | SPEC_RULE_RETVAL;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3410 | SPEC_RULE_RETVAL;
+				spec = 3420 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_PRE_DEC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3412 | SPEC_RULE_RETVAL;
+				spec = 3422 | SPEC_RULE_RETVAL;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3414 | SPEC_RULE_RETVAL;
+				spec = 3424 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_POST_INC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3416;
+				spec = 3426;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3417;
+				spec = 3427;
 			}
 			break;
 		case ZEND_POST_DEC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3418;
+				spec = 3428;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3419;
+				spec = 3429;
 			}
 			break;
 		case ZEND_JMP:
 			if (OP_JMP_ADDR(op, op->op1) > op) {
-				spec = 2566;
+				spec = 2576;
 			}
 			break;
 		case ZEND_INIT_FCALL:
 			if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) {
-				spec = 2559;
+				spec = 2569;
 			}
 			break;
 		case ZEND_RECV:
 			if (op->op2.num == MAY_BE_ANY) {
-				spec = 2560;
+				spec = 2570;
 			}
 			break;
 		case ZEND_SEND_VAL:
 			if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
-				spec = 3470;
+				spec = 3480;
 			}
 			break;
 		case ZEND_SEND_VAR_EX:
 			if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
-				spec = 3465 | SPEC_RULE_OP1;
+				spec = 3475 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_FE_FETCH_R:
 			if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
-				spec = 3472 | SPEC_RULE_RETVAL;
+				spec = 3482 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_FETCH_DIM_R:
@@ -123112,22 +123596,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3435 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 3445 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			}
 			break;
 		case ZEND_SEND_VAL_EX:
 			if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
-				spec = 3471;
+				spec = 3481;
 			}
 			break;
 		case ZEND_SEND_VAR:
 			if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
-				spec = 3460 | SPEC_RULE_OP1;
+				spec = 3470 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_COUNT:
 			if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) {
-				spec = 2561 | SPEC_RULE_OP1;
+				spec = 2571 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_BW_OR:
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 53b1ac6baf0a..4e8f28270bae 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -1,4 +1,5 @@
 #include "Zend/zend_vm_opcodes.h"
+#include "Zend/zend_partial.h"
 
 {%DEFINES%}
 
@@ -113,7 +114,7 @@ static void init_opcode_serialiser(void)
 	Z_TYPE_INFO(tmp) = IS_LONG;
 	for (i = 0; i < zend_handlers_count; i++) {
 		Z_LVAL(tmp) = i;
-		zend_hash_index_add(zend_handlers_table, (zend_long)(uintptr_t)zend_opcode_handlers[i], &tmp);
+		zend_hash_index_add(zend_handlers_table, (zend_ulong)(uintptr_t)zend_opcode_handlers[i], &tmp);
 	}
 }
 
@@ -124,7 +125,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
 }
@@ -142,7 +143,7 @@ ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *o
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	return zend_opcode_handler_funcs[Z_LVAL_P(zv)];
 #elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
@@ -161,6 +162,22 @@ ZEND_API const zend_op *zend_get_halt_op(void)
 #endif
 }
 
+ZEND_API const zend_op *zend_get_interrupt_op(void)
+{
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	return &call_interrupt_op;
+#else
+	return NULL;
+#endif
+}
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS)
+{
+	return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+#endif
+
 ZEND_API int zend_vm_kind(void)
 {
 	return ZEND_VM_KIND;
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index f8989b2336f4..8e65bc0a28ea 100755
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -4,15 +4,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -23,15 +22,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -1593,6 +1591,19 @@ function gen_halt_handler($f, $kind) {
     out($f,"}\n\n");
 }
 
+function gen_interrupt_func($f, $kind, $spec) {
+    $cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    out($f, "static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET {$cconv} zend_interrupt{$variant}(ZEND_OPCODE_HANDLER_ARGS) {\n");
+    out($f,"\tSAVE_OPLINE();\n");
+    if ($kind === ZEND_VM_KIND_TAILCALL) {
+        out($f,"\tZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+    } else {
+        out($f, "\treturn &call_interrupt_op;\n");
+    }
+    out($f, "}\n");
+}
+
 function extra_spec_name($extra_spec) {
     global $prefix;
 
@@ -1803,10 +1814,14 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
     switch ($kind) {
         case ZEND_VM_KIND_CALL:
             gen_null_handler($f, $kind);
+            out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+            gen_interrupt_func($f, $kind, $spec);
+            out($f, "#endif\n");
             break;
         case ZEND_VM_KIND_TAILCALL:
             gen_null_handler($f, $kind);
             gen_halt_handler($f, $kind);
+            gen_interrupt_func($f, $kind, $spec);
             break;
         case ZEND_VM_KIND_SWITCH:
             out($f,"default: ZEND_NULL_LABEL:\n");
@@ -1842,7 +1857,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
         out($f, "#pragma push_macro(\"ZEND_VM_INTERRUPT\")\n");
         out($f, "#undef  ZEND_VM_INTERRUPT\n");
         out($f, "#define ZEND_VM_CONTINUE(handler) return opline\n");
-        out($f, "#define ZEND_VM_INTERRUPT()       return zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)\n");
+        out($f, "#define ZEND_VM_INTERRUPT()       return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)\n");
         out($f, $delayed_helpers);
         out($f, "#pragma pop_macro(\"ZEND_VM_INTERRUPT\")\n");
         out($f, "#pragma pop_macro(\"ZEND_VM_CONTINUE\")\n");
@@ -1897,7 +1912,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                     if ($kind == ZEND_VM_KIND_HYBRID || $kind == ZEND_VM_KIND_CALL) {
                         out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n\n");
                         out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
-                        out($f,"#endif\n");
+                        out($f,"#endif\n\n");
+                        out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+                        out($f,"static const zend_op call_interrupt_op;\n");
+                        out($f,"#endif\n\n");
                     }
                     out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC\n");
                     out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
@@ -2126,6 +2144,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                         out($f,"# undef ZEND_VM_RETURN\n");
                         out($f,"# undef ZEND_VM_DISPATCH_TO_HELPER\n");
                         out($f,"# undef ZEND_VM_INTERRUPT\n");
+                        out($f,"# undef ZEND_VM_ENTER_EX\n");
+                        out($f,"# undef ZEND_VM_LEAVE\n");
                         out($f,"\n");
                         out($f,"# define ZEND_VM_TAIL_CALL(call)               ZEND_MUSTTAIL return call\n");
                         out($f,"# define ZEND_VM_CONTINUE()                    ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
@@ -2136,9 +2156,13 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                         out($f,"        ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \\\n");
                         out($f,"    } while (0)\n");
                         out($f,"# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE()\n");
-                        out($f,"# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
+                        out($f,"# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
+                        out($f,"# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                        out($f,"# define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
                         out($f,"\n");
                         out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
                         out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
                         out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
                         out($f,"static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline);\n");
@@ -2149,6 +2173,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                         out($f,"static const zend_op call_leave_op = {\n");
                         out($f,"    .handler = zend_leave_helper_SPEC_TAILCALL,\n");
                         out($f,"};\n");
+                        out($f,"static const zend_op call_interrupt_op = {\n");
+                        out($f,"    .handler = zend_interrupt_helper_SPEC_TAILCALL,\n");
+                        out($f,"};\n");
                         out($f,"\n");
 
                         gen_executor_code($f, $spec, ZEND_VM_KIND_TAILCALL, $m[1]);
@@ -2495,7 +2522,7 @@ function gen_vm_opcodes_header(
         $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_HYBRID\n";
     }
     if ($GLOBALS["vm_kind_name"][ZEND_VM_GEN_KIND] === "ZEND_VM_KIND_HYBRID" || $GLOBALS["vm_kind_name"][ZEND_VM_GEN_KIND] === "ZEND_VM_KIND_CALL") {
-        $str .= "#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__))\n";
+        $str .= "#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__))\n";
         $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_TAILCALL\n";
         $str .= "#else\n";
         $str .= "# define ZEND_VM_KIND\t\tZEND_VM_KIND_CALL\n";
diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h
index 6f1595195450..7ffe2c220a02 100644
--- a/Zend/zend_vm_handlers.h
+++ b/Zend/zend_vm_handlers.h
@@ -1087,507 +1087,511 @@
 	_(2556, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \
 	_(2557, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \
 	_(2558, ZEND_TYPE_ASSERT_SPEC_CONST) \
-	_(2559, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \
-	_(2560, ZEND_RECV_NOTYPE_SPEC) \
-	_(2562, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \
-	_(2565, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \
-	_(2566, ZEND_JMP_FORWARD_SPEC) \
-	_(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2577, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2578, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2579, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2581, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2559, ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_CONST) \
+	_(2562, ZEND_CALLABLE_CONVERT_PARTIAL_SPEC_UNUSED) \
+	_(2564, ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_CONST) \
+	_(2567, ZEND_SEND_PLACEHOLDER_SPEC_UNUSED_UNUSED) \
+	_(2569, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \
+	_(2570, ZEND_RECV_NOTYPE_SPEC) \
+	_(2572, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \
+	_(2575, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \
+	_(2576, ZEND_JMP_FORWARD_SPEC) \
+	_(2582, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2583, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2584, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2586, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2587, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2588, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2589, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
-	_(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2602, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
-	_(2603, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2604, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2606, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2598, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2599, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2601, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2607, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
+	_(2608, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2609, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2611, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2612, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
 	_(2613, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2614, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2627, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2628, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2629, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2631, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
+	_(2623, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2624, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2626, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2632, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2633, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2634, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2636, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2637, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2638, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2639, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
-	_(2644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
-	_(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
-	_(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2652, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2654, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2656, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2648, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2649, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2651, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2654, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2656, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2657, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2658, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2659, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2668, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
-	_(2669, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
-	_(2671, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
-	_(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
-	_(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2677, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
-	_(2678, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2679, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2681, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2673, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2674, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2676, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2678, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2679, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2681, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2682, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
+	_(2683, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2684, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2686, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2687, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
 	_(2688, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2689, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2693, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(2694, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(2696, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2702, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2703, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2704, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2706, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
+	_(2698, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2699, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2701, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2703, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2704, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2706, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2707, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2708, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2709, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2711, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2712, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2713, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2714, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2727, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2728, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2729, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2731, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2723, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2724, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2726, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2732, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2733, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2734, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2736, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2737, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2738, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2739, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2752, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2753, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2754, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2756, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2748, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2749, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2751, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2757, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2758, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2759, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2761, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2762, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
 	_(2763, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2764, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2777, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2778, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2779, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2781, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2773, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2774, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2776, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2782, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2783, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2784, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2786, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2787, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2788, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2789, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2860, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2864, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2865, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2866, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2935, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2939, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2940, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2941, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3010, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3014, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3015, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3016, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3085, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3089, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3090, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3091, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3092, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
-	_(3093, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3094, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3095, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
-	_(3096, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3097, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3098, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
-	_(3102, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \
-	_(3103, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
-	_(3107, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \
-	_(3111, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3112, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3113, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3114, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3115, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3116, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3120, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3121, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3122, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3127, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3128, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3172, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3173, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3174, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3175, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3176, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3247, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3248, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3249, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3250, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3251, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3322, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3323, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3324, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3325, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3326, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3397, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3398, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3399, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3400, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3401, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3408, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
-	_(3409, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
-	_(3410, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \
-	_(3411, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \
-	_(3412, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
-	_(3413, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
-	_(3414, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \
-	_(3415, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \
-	_(3416, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \
-	_(3417, ZEND_POST_INC_LONG_SPEC_CV) \
-	_(3418, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \
-	_(3419, ZEND_POST_DEC_LONG_SPEC_CV) \
-	_(3420, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \
-	_(3421, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3422, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3424, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3425, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \
-	_(3426, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3427, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3429, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3430, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \
-	_(3431, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3432, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3434, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
-	_(3437, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
-	_(3439, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
-	_(3440, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
-	_(3441, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3442, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3444, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3445, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
-	_(3446, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3447, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \
-	_(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3462, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \
-	_(3464, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \
-	_(3467, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \
-	_(3469, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \
-	_(3470, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \
-	_(3471, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \
-	_(3472, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \
-	_(3473, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \
-	_(3473+1, ZEND_NULL)
+	_(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2798, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2799, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2801, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2817, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2818, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2862, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2863, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2864, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2865, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2866, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2867, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2868, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2869, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2892, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2893, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2937, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2938, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2939, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2940, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2941, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2942, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2943, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2944, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2967, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2968, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3012, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3013, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3014, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3015, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3016, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3017, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3018, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3019, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3042, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3043, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3087, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3088, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3089, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3090, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3091, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3092, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3093, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3094, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3102, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
+	_(3103, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3104, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3105, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
+	_(3106, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3107, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3108, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
+	_(3112, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \
+	_(3113, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
+	_(3117, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \
+	_(3121, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3122, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3123, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3131, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3133, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3134, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3178, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3179, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3191, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3253, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3254, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3266, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3328, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3329, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3341, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3403, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3404, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3416, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3418, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
+	_(3419, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
+	_(3420, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \
+	_(3421, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \
+	_(3422, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
+	_(3423, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
+	_(3424, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \
+	_(3425, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \
+	_(3426, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \
+	_(3427, ZEND_POST_INC_LONG_SPEC_CV) \
+	_(3428, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \
+	_(3429, ZEND_POST_DEC_LONG_SPEC_CV) \
+	_(3430, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \
+	_(3431, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3432, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3434, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3435, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \
+	_(3436, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3437, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3440, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \
+	_(3441, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3442, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3446, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3447, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3450, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
+	_(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
+	_(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3465, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \
+	_(3466, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3472, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \
+	_(3474, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \
+	_(3477, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \
+	_(3479, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \
+	_(3480, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \
+	_(3481, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \
+	_(3482, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \
+	_(3483, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \
+	_(3483+1, ZEND_NULL)
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 87cd00a6f8b5..9846e36037b9 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -22,7 +21,7 @@
 #include 
 #include 
 
-static const char *zend_vm_opcodes_names[212] = {
+static const char *zend_vm_opcodes_names[214] = {
 	"ZEND_NOP",
 	"ZEND_ADD",
 	"ZEND_SUB",
@@ -235,9 +234,11 @@ static const char *zend_vm_opcodes_names[212] = {
 	"ZEND_INIT_PARENT_PROPERTY_HOOK_CALL",
 	"ZEND_DECLARE_ATTRIBUTED_CONST",
 	"ZEND_TYPE_ASSERT",
+	"ZEND_CALLABLE_CONVERT_PARTIAL",
+	"ZEND_SEND_PLACEHOLDER",
 };
 
-static uint32_t zend_vm_opcodes_flags[212] = {
+static uint32_t zend_vm_opcodes_flags[214] = {
 	0x00000000,
 	0x00000b0b,
 	0x00000b0b,
@@ -450,6 +451,8 @@ static uint32_t zend_vm_opcodes_flags[212] = {
 	0x01001103,
 	0x00000303,
 	0x01000003,
+	0x010003a0,
+	0x00001301,
 };
 
 ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 7aae4d0e55f1..61147518d36c 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -42,7 +41,7 @@ static const char *const zend_vm_kind_name[] = {
 /* HYBRID requires support for computed GOTO and global register variables*/
 #elif (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))
 # define ZEND_VM_KIND		ZEND_VM_KIND_HYBRID
-#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(__aarch64__))
+#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__))
 # define ZEND_VM_KIND		ZEND_VM_KIND_TAILCALL
 #else
 # define ZEND_VM_KIND		ZEND_VM_KIND_CALL
@@ -332,7 +331,9 @@ END_EXTERN_C()
 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209
 #define ZEND_DECLARE_ATTRIBUTED_CONST       210
 #define ZEND_TYPE_ASSERT                    211
+#define ZEND_CALLABLE_CONVERT_PARTIAL       212
+#define ZEND_SEND_PLACEHOLDER               213
 
-#define ZEND_VM_LAST_OPCODE                 211
+#define ZEND_VM_LAST_OPCODE                 213
 
 #endif
diff --git a/Zend/zend_vm_trace_handlers.h b/Zend/zend_vm_trace_handlers.h
index eaf97e012cac..e7510f406711 100644
--- a/Zend/zend_vm_trace_handlers.h
+++ b/Zend/zend_vm_trace_handlers.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_vm_trace_lines.h b/Zend/zend_vm_trace_lines.h
index 740e18776395..8c194edbcde1 100644
--- a/Zend/zend_vm_trace_lines.h
+++ b/Zend/zend_vm_trace_lines.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_vm_trace_map.h b/Zend/zend_vm_trace_map.h
index d84aa0442d26..18c705b454d5 100644
--- a/Zend/zend_vm_trace_map.h
+++ b/Zend/zend_vm_trace_map.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c
index 8c1263885bf6..ad0308f44e20 100644
--- a/Zend/zend_weakrefs.c
+++ b/Zend/zend_weakrefs.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: krakjoe@php.net                                             |
    +----------------------------------------------------------------------+
@@ -60,10 +58,10 @@ static zend_class_entry *zend_ce_weakmap;
 static zend_object_handlers zend_weakref_handlers;
 static zend_object_handlers zend_weakmap_handlers;
 
-#define zend_weakref_from(o) ((zend_weakref*)(((char*) o) - XtOffsetOf(zend_weakref, std)))
+#define zend_weakref_from(o) (ZEND_CONTAINER_OF(o, zend_weakref, std))
 #define zend_weakref_fetch(z) zend_weakref_from(Z_OBJ_P(z))
 
-#define zend_weakmap_from(o) ((zend_weakmap*)(((char*) o) - XtOffsetOf(zend_weakmap, std)))
+#define zend_weakmap_from(o) (ZEND_CONTAINER_OF(o, zend_weakmap, std))
 #define zend_weakmap_fetch(z) zend_weakmap_from(Z_OBJ_P(z))
 
 static inline void zend_weakref_unref_single(
@@ -109,15 +107,15 @@ static void zend_weakref_register(zend_object *object, void *payload) {
 	void *tagged_ptr = Z_PTR_P(zv);
 	if (ZEND_WEAKREF_GET_TAG(tagged_ptr) == ZEND_WEAKREF_TAG_HT) {
 		HashTable *ht = ZEND_WEAKREF_GET_PTR(tagged_ptr);
-		zend_hash_index_add_new_ptr(ht, (zend_ulong) payload, payload);
+		zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) payload, payload);
 		return;
 	}
 
 	/* Convert simple pointer to hashtable. */
 	HashTable *ht = emalloc(sizeof(HashTable));
 	zend_hash_init(ht, 0, NULL, NULL, 0);
-	zend_hash_index_add_new_ptr(ht, (zend_ulong) tagged_ptr, tagged_ptr);
-	zend_hash_index_add_new_ptr(ht, (zend_ulong) payload, payload);
+	zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) tagged_ptr, tagged_ptr);
+	zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) payload, payload);
 	/* Replace the single WeakMap or WeakReference entry in EG(weakrefs) with a HashTable with 2 entries in place. */
 	ZVAL_PTR(zv, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_HT));
 }
@@ -146,11 +144,11 @@ static void zend_weakref_unregister(zend_object *object, void *payload, bool wea
 
 	HashTable *ht = ptr;
 #if ZEND_DEBUG
-	void *old_payload = zend_hash_index_find_ptr(ht, (zend_ulong) payload);
+	void *old_payload = zend_hash_index_find_ptr(ht, (zend_ulong)(uintptr_t) payload);
 	ZEND_ASSERT(old_payload && "Weakref not registered?");
 	ZEND_ASSERT(old_payload == payload);
 #endif
-	zend_hash_index_del(ht, (zend_ulong) payload);
+	zend_hash_index_del(ht, (zend_ulong)(uintptr_t) payload);
 	if (zend_hash_num_elements(ht) == 0) {
 		GC_DEL_FLAGS(object, IS_OBJ_WEAKLY_REFERENCED);
 		zend_hash_destroy(ht);
@@ -798,7 +796,7 @@ void zend_register_weakref_ce(void) /* {{{ */
 	zend_ce_weakref->default_object_handlers = &zend_weakref_handlers;
 
 	memcpy(&zend_weakref_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-	zend_weakref_handlers.offset = XtOffsetOf(zend_weakref, std);
+	zend_weakref_handlers.offset = offsetof(zend_weakref, std);
 
 	zend_weakref_handlers.free_obj = zend_weakref_free;
 	zend_weakref_handlers.get_debug_info = zend_weakref_get_debug_info;
@@ -811,7 +809,7 @@ void zend_register_weakref_ce(void) /* {{{ */
 	zend_ce_weakmap->default_object_handlers = &zend_weakmap_handlers;
 
 	memcpy(&zend_weakmap_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-	zend_weakmap_handlers.offset = XtOffsetOf(zend_weakmap, std);
+	zend_weakmap_handlers.offset = offsetof(zend_weakmap, std);
 	zend_weakmap_handlers.free_obj = zend_weakmap_free_obj;
 	zend_weakmap_handlers.read_dimension = zend_weakmap_read_dimension;
 	zend_weakmap_handlers.write_dimension = zend_weakmap_write_dimension;
diff --git a/Zend/zend_weakrefs.h b/Zend/zend_weakrefs.h
index 00d4fbcc6bc4..41662c33a300 100644
--- a/Zend/zend_weakrefs.h
+++ b/Zend/zend_weakrefs.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: krakjoe@php.net                                             |
    +----------------------------------------------------------------------+
diff --git a/build/Makefile.gcov b/build/Makefile.gcov
index de85893398cd..5097bfaaa277 100644
--- a/build/Makefile.gcov
+++ b/build/Makefile.gcov
@@ -16,15 +16,6 @@ LCOV_EXCLUDES = \
 	'$(top_srcdir)/parse_date.re' \
 	'$(top_srcdir)/parse_iso_intervals.re'
 
-GCOVR_EXCLUDES = \
-	'ext/bcmath/libbcmath/.*' \
-	'ext/date/lib/.*' \
-	'ext/fileinfo/libmagic/.*' \
-	'ext/gd/libgd/.*' \
-	'ext/hash/sha3/.*' \
-	'ext/mbstring/libmbfl/.*' \
-	'ext/pcre/pcre2lib/.*'
-
 lcov: lcov-html
 
 php_lcov.info:
@@ -48,15 +39,11 @@ gcovr-html:
 	@echo "Generating gcovr HTML"
 	@rm -rf gcovr_html/
 	@mkdir gcovr_html
-	gcovr -sr . -o gcovr_html/index.html --html --html-details \
-		--exclude-directories 'ext/date/lib$$' \
-		$(foreach lib, $(GCOVR_EXCLUDES), -e $(lib))
+	gcovr -r . -o gcovr_html/index.html --html --html-details
 
 gcovr-xml:
 	@echo "Generating gcovr XML"
 	@rm -f gcovr.xml
-	gcovr -sr . -o gcovr.xml --xml \
-		--exclude-directories 'ext/date/lib$$' \
-		$(foreach lib, $(GCOVR_EXCLUDES), -e $(lib))
+	gcovr -r . -o gcovr.xml --xml
 
 .PHONY: gcovr-html lcov-html php_lcov.info
diff --git a/build/gen_stub.php b/build/gen_stub.php
index ca14022cc524..b2f38c978cf3 100755
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@ -13,6 +13,7 @@
 use PhpParser\Node\Stmt\Enum_;
 use PhpParser\Node\Stmt\Interface_;
 use PhpParser\Node\Stmt\Trait_;
+use PhpParser\Node\Stmt\TraitUse;
 use PhpParser\PrettyPrinter\Standard;
 use PhpParser\PrettyPrinterAbstract;
 
@@ -26,6 +27,7 @@
 const PHP_83_VERSION_ID = 80300;
 const PHP_84_VERSION_ID = 80400;
 const PHP_85_VERSION_ID = 80500;
+const PHP_86_VERSION_ID = 80600;
 const ALL_PHP_VERSION_IDS = [
     PHP_70_VERSION_ID,
     PHP_80_VERSION_ID,
@@ -34,6 +36,7 @@
     PHP_83_VERSION_ID,
     PHP_84_VERSION_ID,
     PHP_85_VERSION_ID,
+    PHP_86_VERSION_ID,
 ];
 
 // file_put_contents() but with a success message printed after saving
@@ -43,6 +46,35 @@ function reportFilePutContents(string $filename, string $content): void {
     }
 }
 
+if (!function_exists('array_any')) {
+    function array_any(array $array, callable $callback): bool {
+        foreach ($array as $key => $value) {
+            if ($callback($value, $key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+if (function_exists('clone')) {
+    // Replace (\clone)(...) with \clone(...) once the minimally
+    // supported PHP version is 8.5.
+    define('clone', \clone(...));
+} else {
+    define(
+        'clone',
+        /**
+         * @template T
+         * @param T $o
+         * @return T
+         */
+        function (object $o): object {
+            return clone $o;
+        }
+    );
+}
+
 /**
  * @return FileInfo[]
  */
@@ -53,8 +85,8 @@ function processDirectory(string $dir, Context $context): array {
         RecursiveIteratorIterator::LEAVES_ONLY
     );
     foreach ($it as $file) {
-        $pathName = $file->getPathName();
-        if (substr($pathName, -9) === '.stub.php') {
+        $pathName = $file->getPathname();
+        if (str_ends_with($pathName, '.stub.php')) {
             $pathNames[] = $pathName;
         }
     }
@@ -133,9 +165,8 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
             return $fileInfo;
         }
 
-        [$arginfoCode, $declCode] = generateArgInfoCode(
+        [$arginfoCode, $declCode] = $fileInfo->generateArgInfoCode(
             basename($stubFilenameWithoutExtension),
-            $fileInfo,
             $context->allConstInfos,
             $stubHash
         );
@@ -151,9 +182,8 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
         if ($fileInfo->shouldGenerateLegacyArginfo()) {
             $legacyFileInfo = $fileInfo->getLegacyVersion();
 
-            [$arginfoCode] = generateArgInfoCode(
+            [$arginfoCode] = $legacyFileInfo->generateArgInfoCode(
                 basename($stubFilenameWithoutExtension),
-                $legacyFileInfo,
                 $context->allConstInfos,
                 $stubHash
             );
@@ -201,20 +231,17 @@ class Context {
 }
 
 class ArrayType extends SimpleType {
-    private /* readonly */ Type $keyType;
-    private /* readonly */ Type $valueType;
 
-    public static function createGenericArray(): self
-    {
-        return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref"));
+    public function __construct(
+        private readonly Type $keyType,
+        private readonly Type $valueType,
+    ) {
+        parent::__construct("array", true);
     }
 
-    public function __construct(Type $keyType, Type $valueType)
+    public static function createGenericArray(): self
     {
-        parent::__construct("array", true);
-
-        $this->keyType = $keyType;
-        $this->valueType = $valueType;
+        return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref"));
     }
 
     public function toOptimizerTypeMask(): string {
@@ -240,8 +267,11 @@ public function equals(SimpleType $other): bool {
 }
 
 class SimpleType {
-    public /* readonly */ string $name;
-    public /* readonly */ bool $isBuiltin;
+
+    protected function __construct(
+        public readonly string $name,
+        public readonly bool $isBuiltin,
+    ) {}
 
     public static function fromNode(Node $node): SimpleType {
         if ($node instanceof Node\Name) {
@@ -320,24 +350,16 @@ public static function fromString(string $typeString): SimpleType
      */
     public static function fromValue($value): SimpleType
     {
-        switch (gettype($value)) {
-            case "NULL":
-                return SimpleType::null();
-            case "boolean":
-                return new SimpleType("bool", true);
-            case "integer":
-                return new SimpleType("int", true);
-            case "double":
-                return new SimpleType("float", true);
-            case "string":
-                return new SimpleType("string", true);
-            case "array":
-                return new SimpleType("array", true);
-            case "object":
-                return new SimpleType("object", true);
-            default:
-                throw new Exception("Type \"" . gettype($value) . "\" cannot be inferred based on value");
-        }
+        return match (gettype($value)) {
+            "NULL" => SimpleType::null(),
+            "boolean" => new SimpleType("bool", true),
+            "integer" => new SimpleType("int", true),
+            "double" => new SimpleType("float", true),
+            "string" => new SimpleType("string", true),
+            "array" => new SimpleType("array", true),
+            "object" => new SimpleType("object", true),
+            default => throw new Exception("Type \"" . gettype($value) . "\" cannot be inferred based on value"),
+        };
     }
 
     public static function null(): SimpleType
@@ -345,11 +367,6 @@ public static function null(): SimpleType
         return new SimpleType("null", true);
     }
 
-    protected function __construct(string $name, bool $isBuiltin) {
-        $this->name = $name;
-        $this->isBuiltin = $isBuiltin;
-    }
-
     public function isScalar(): bool {
         return $this->isBuiltin && in_array($this->name, ["null", "false", "true", "bool", "int", "float"], true);
     }
@@ -385,38 +402,23 @@ public function isMixed(): bool {
     private function toTypeInfo(): array {
         assert($this->isBuiltin);
 
-        switch ($this->name) {
-            case "null":
-                return ["IS_NULL", "MAY_BE_NULL"];
-            case "false":
-                return ["IS_FALSE", "MAY_BE_FALSE"];
-            case "true":
-                return ["IS_TRUE", "MAY_BE_TRUE"];
-            case "bool":
-                return ["_IS_BOOL", "MAY_BE_BOOL"];
-            case "int":
-                return ["IS_LONG", "MAY_BE_LONG"];
-            case "float":
-                return ["IS_DOUBLE", "MAY_BE_DOUBLE"];
-            case "string":
-                return ["IS_STRING", "MAY_BE_STRING"];
-            case "array":
-                return ["IS_ARRAY", "MAY_BE_ARRAY"];
-            case "object":
-                return ["IS_OBJECT", "MAY_BE_OBJECT"];
-            case "callable":
-                return ["IS_CALLABLE", "MAY_BE_CALLABLE"];
-            case "mixed":
-                return ["IS_MIXED", "MAY_BE_ANY"];
-            case "void":
-                return ["IS_VOID", "MAY_BE_VOID"];
-            case "static":
-                return ["IS_STATIC", "MAY_BE_STATIC"];
-            case "never":
-                return ["IS_NEVER", "MAY_BE_NEVER"];
-            default:
-                throw new Exception("Not implemented: $this->name");
-        }
+        return match ($this->name) {
+            "null" => ["IS_NULL", "MAY_BE_NULL"],
+            "false" => ["IS_FALSE", "MAY_BE_FALSE"],
+            "true" => ["IS_TRUE", "MAY_BE_TRUE"],
+            "bool" => ["_IS_BOOL", "MAY_BE_BOOL"],
+            "int" => ["IS_LONG", "MAY_BE_LONG"],
+            "float" => ["IS_DOUBLE", "MAY_BE_DOUBLE"],
+            "string" => ["IS_STRING", "MAY_BE_STRING"],
+            "array" => ["IS_ARRAY", "MAY_BE_ARRAY"],
+            "object" => ["IS_OBJECT", "MAY_BE_OBJECT"],
+            "callable" => ["IS_CALLABLE", "MAY_BE_CALLABLE"],
+            "mixed" => ["IS_MIXED", "MAY_BE_ANY"],
+            "void" => ["IS_VOID", "MAY_BE_VOID"],
+            "static" => ["IS_STATIC", "MAY_BE_STATIC"],
+            "never" => ["IS_NEVER", "MAY_BE_NEVER"],
+            default => throw new Exception("Not implemented: $this->name"),
+        };
     }
 
     public function toTypeCode(): string {
@@ -430,14 +432,11 @@ public function toTypeMask(): string {
     public function toOptimizerTypeMaskForArrayKey(): string {
         assert($this->isBuiltin);
 
-        switch ($this->name) {
-            case "int":
-                return "MAY_BE_ARRAY_KEY_LONG";
-            case "string":
-                return "MAY_BE_ARRAY_KEY_STRING";
-            default:
-                throw new Exception("Type $this->name cannot be an array key");
-        }
+        return match ($this->name) {
+            "int" => "MAY_BE_ARRAY_KEY_LONG",
+            "string" => "MAY_BE_ARRAY_KEY_STRING",
+            default => throw new Exception("Type $this->name cannot be an array key"),
+        };
     }
 
     public function toOptimizerTypeMaskForArrayValue(): string {
@@ -445,34 +444,21 @@ public function toOptimizerTypeMaskForArrayValue(): string {
             return "MAY_BE_ARRAY_OF_OBJECT";
         }
 
-        switch ($this->name) {
-            case "null":
-                return "MAY_BE_ARRAY_OF_NULL";
-            case "false":
-                return "MAY_BE_ARRAY_OF_FALSE";
-            case "true":
-                return "MAY_BE_ARRAY_OF_TRUE";
-            case "bool":
-                return "MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE";
-            case "int":
-                return "MAY_BE_ARRAY_OF_LONG";
-            case "float":
-                return "MAY_BE_ARRAY_OF_DOUBLE";
-            case "string":
-                return "MAY_BE_ARRAY_OF_STRING";
-            case "array":
-                return "MAY_BE_ARRAY_OF_ARRAY";
-            case "object":
-                return "MAY_BE_ARRAY_OF_OBJECT";
-            case "resource":
-                return "MAY_BE_ARRAY_OF_RESOURCE";
-            case "mixed":
-                return "MAY_BE_ARRAY_OF_ANY";
-            case "ref":
-                return "MAY_BE_ARRAY_OF_REF";
-            default:
-                throw new Exception("Type $this->name cannot be an array value");
-        }
+        return match ($this->name) {
+            "null" => "MAY_BE_ARRAY_OF_NULL",
+            "false" => "MAY_BE_ARRAY_OF_FALSE",
+            "true" => "MAY_BE_ARRAY_OF_TRUE",
+            "bool" => "MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE",
+            "int" => "MAY_BE_ARRAY_OF_LONG",
+            "float" => "MAY_BE_ARRAY_OF_DOUBLE",
+            "string" => "MAY_BE_ARRAY_OF_STRING",
+            "array" => "MAY_BE_ARRAY_OF_ARRAY",
+            "object" => "MAY_BE_ARRAY_OF_OBJECT",
+            "resource" => "MAY_BE_ARRAY_OF_RESOURCE",
+            "mixed" => "MAY_BE_ARRAY_OF_ANY",
+            "ref" => "MAY_BE_ARRAY_OF_REF",
+            default => throw new Exception("Type $this->name cannot be an array value"),
+        };
     }
 
     public function toOptimizerTypeMask(): string {
@@ -480,18 +466,13 @@ public function toOptimizerTypeMask(): string {
             return "MAY_BE_OBJECT";
         }
 
-        switch ($this->name) {
-            case "resource":
-                return "MAY_BE_RESOURCE";
-            case "callable":
-                return "MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT";
-            case "iterable":
-                return "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT";
-            case "mixed":
-                return "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY";
-        }
-
-        return $this->toTypeMask();
+        return match ($this->name) {
+            "resource" => "MAY_BE_RESOURCE",
+            "callable" => "MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT",
+            "iterable" => "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT",
+            "mixed" => "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY",
+            default => $this->toTypeMask(),
+        };
     }
 
     public function toEscapedName(): string {
@@ -515,13 +496,18 @@ public function equals(SimpleType $other): bool {
 // Instances of Type are immutable and do not need to be cloned
 // when held by an object that is cloned
 class Type {
-    /** @var SimpleType[] */
-    public /* readonly */ array $types;
-    public /* readonly */ bool $isIntersection;
+
+    /**
+     * @param SimpleType[] $types
+     */
+    private function __construct(
+        public readonly array $types,
+        public readonly bool $isIntersection
+    ) {}
 
     public static function fromNode(Node $node): Type {
         if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
-            $nestedTypeObjects = array_map(['Type', 'fromNode'], $node->types);
+            $nestedTypeObjects = array_map(Type::fromNode(...), $node->types);
             $types = [];
             foreach ($nestedTypeObjects as $typeObject) {
                 array_push($types, ...$typeObject->types);
@@ -590,32 +576,12 @@ public static function fromString(string $typeString): self {
         return new Type($simpleTypes, $isIntersection);
     }
 
-    /**
-     * @param SimpleType[] $types
-     */
-    private function __construct(array $types, bool $isIntersection) {
-        $this->types = $types;
-        $this->isIntersection = $isIntersection;
-    }
-
     public function isScalar(): bool {
-        foreach ($this->types as $type) {
-            if (!$type->isScalar()) {
-                return false;
-            }
-        }
-
-        return true;
+        return !array_any($this->types, static fn (SimpleType $type): bool => !$type->isScalar());
     }
 
     public function isNullable(): bool {
-        foreach ($this->types as $type) {
-            if ($type->isNull()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any($this->types, static fn (SimpleType $type): bool => $type->isNull());
     }
 
     public function tryToSimpleType(): ?SimpleType {
@@ -725,19 +691,15 @@ function ($type) { return $type->name; },
 }
 
 class ArginfoType {
-    /** @var SimpleType[] $classTypes */
-    public /* readonly */ array $classTypes;
-    /** @var SimpleType[] $builtinTypes */
-    private /* readonly */ array $builtinTypes;
 
     /**
      * @param SimpleType[] $classTypes
      * @param SimpleType[] $builtinTypes
      */
-    public function __construct(array $classTypes, array $builtinTypes) {
-        $this->classTypes = $classTypes;
-        $this->builtinTypes = $builtinTypes;
-    }
+    public function __construct(
+        public readonly array $classTypes,
+        private readonly array $builtinTypes,
+    ) {}
 
     public function hasClassType(): bool {
         return !empty($this->classTypes);
@@ -764,35 +726,18 @@ class ArgInfo {
     public const SEND_BY_REF = "1";
     public const SEND_PREFER_REF = "ZEND_SEND_PREFER_REF";
 
-    public /* readonly */ string $name;
-    public /* readonly */ string $sendBy;
-    public /* readonly */ bool $isVariadic;
-    public ?Type $type;
-    private /* readonly */ ?Type $phpDocType;
-    public ?string $defaultValue;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        string $name,
-        string $sendBy,
-        bool $isVariadic,
-        ?Type $type,
-        ?Type $phpDocType,
-        ?string $defaultValue,
-        array $attributes
-    ) {
-        $this->name = $name;
-        $this->sendBy = $sendBy;
-        $this->isVariadic = $isVariadic;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->defaultValue = $defaultValue;
-        $this->attributes = $attributes;
-    }
+        public readonly string $name,
+        public readonly string $sendBy,
+        public readonly bool $isVariadic,
+        public ?Type $type,
+        private readonly ?Type $phpDocType,
+        public ?string $defaultValue,
+        public array $attributes,
+    ) {}
 
     public function equals(ArgInfo $other): bool {
         return $this->name === $other->name
@@ -827,16 +772,11 @@ private function getDefaultValueAsArginfoString(): string {
     }
 
     public function getDefaultValueAsMethodSynopsisString(): ?string {
-        switch ($this->defaultValue) {
-            case 'UNKNOWN':
-                return null;
-            case 'false':
-            case 'true':
-            case 'null':
-                return "&{$this->defaultValue};";
-        }
-
-        return $this->defaultValue;
+        return match ($this->defaultValue) {
+            'UNKNOWN' => null,
+            'false' | 'true' | 'null' => "&{$this->defaultValue};",
+            default => $this->defaultValue,
+        };
     }
 
     public function toZendInfo(): string {
@@ -898,7 +838,7 @@ public function isUnknown(): bool
 }
 
 class ConstName extends AbstractConstName {
-    private /* readonly */ string $const;
+    private readonly string $const;
 
     public function __construct(?Name $namespace, string $const)
     {
@@ -929,14 +869,11 @@ public function getDeclarationName(): string
 }
 
 class ClassConstName extends AbstractConstName {
-    public /* readonly */ Name $class;
-    private /* readonly */ string $const;
 
-    public function __construct(Name $class, string $const)
-    {
-        $this->class = $class;
-        $this->const = $const;
-    }
+    public function __construct(
+        public readonly Name $class,
+        private readonly string $const,
+    ) {}
 
     public function __toString(): string
     {
@@ -950,14 +887,11 @@ public function getDeclarationName(): string
 }
 
 class PropertyName implements VariableLikeName {
-    public /* readonly */ Name $class;
-    private /* readonly */ string $property;
 
-    public function __construct(Name $class, string $property)
-    {
-        $this->class = $class;
-        $this->property = $property;
-    }
+    public function __construct(
+        public readonly Name $class,
+        private readonly string $property
+    ) {}
 
     public function __toString(): string
     {
@@ -970,6 +904,19 @@ public function getDeclarationName(): string
     }
 }
 
+class EnumCaseName {
+    public function __construct(
+        public readonly Name $enum,
+        public readonly string $case
+    ) {
+    }
+
+    public function __toString(): string
+    {
+        return "$this->enum::$this->case";
+    }
+}
+
 interface FunctionOrMethodName {
     public function getDeclaration(): string;
     public function getArgInfoName(): string;
@@ -981,11 +928,10 @@ public function isDestructor(): bool;
 }
 
 class FunctionName implements FunctionOrMethodName {
-    private /* readonly */ Name $name;
 
-    public function __construct(Name $name) {
-        $this->name = $name;
-    }
+    public function __construct(
+        private readonly Name $name,
+    ) {}
 
     public function getNamespace(): ?string {
         if ($this->name->isQualified()) {
@@ -1045,13 +991,11 @@ public function isDestructor(): bool {
 }
 
 class MethodName implements FunctionOrMethodName {
-    public /* readonly */ Name $className;
-    public /* readonly */ string $methodName;
 
-    public function __construct(Name $className, string $methodName) {
-        $this->className = $className;
-        $this->methodName = $methodName;
-    }
+    public function __construct(
+        public readonly Name $className,
+        public readonly string $methodName,
+    ) {}
 
     public function getDeclarationClassName(): string {
         return implode('_', $this->className->getParts());
@@ -1099,18 +1043,16 @@ class ReturnInfo {
         self::REFCOUNT_N,
     ];
 
-    private /* readonly */ bool $byRef;
-    // NOT readonly - gets removed when discarding info for older PHP versions
-    public ?Type $type;
-    public /* readonly */ ?Type $phpDocType;
-    public /* readonly */ bool $tentativeReturnType;
-    public /* readonly */ string $refcount;
-
-    public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType, ?string $refcount) {
-        $this->byRef = $byRef;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->tentativeReturnType = $tentativeReturnType;
+    public readonly string $refcount;
+
+    public function __construct(
+        private readonly bool $byRef,
+        // NOT readonly - gets removed when discarding info for older PHP versions
+        public ?Type $type,
+        public readonly ?Type $phpDocType,
+        public readonly bool $tentativeReturnType,
+        ?string $refcount
+    ) {
         $this->setRefcount($refcount);
     }
 
@@ -1237,12 +1179,36 @@ public function addForVersionsAbove(string $flag, int $minimumVersionId): void {
     }
 
     public function isEmpty(): bool {
-        foreach (ALL_PHP_VERSION_IDS as $version) {
-            if ($this->flagsByVersion[$version] !== []) {
-                return false;
+        return !array_any(
+            ALL_PHP_VERSION_IDS,
+            fn (int $version): bool => $this->flagsByVersion[$version] !== []
+        );
+    }
+
+    /**
+     * If we have ZEND_ACC2_ flags, represent as 'ZEND_FENTRY_FLAGS(flags1, flags2)'.
+     * Otherwise, represent as just 'flags1' (backwards compatible).
+     */
+    private function formatFlags(array $flags): string {
+        $flags1 = [];
+        $flags2 = [];
+        foreach ($flags as $flag) {
+            if (str_starts_with($flag, 'ZEND_ACC2_')) {
+                $flags2[] = $flag;
+            } else {
+                $flags1[] = $flag;
             }
         }
-        return true;
+
+        if ($flags2 !== []) {
+            return sprintf(
+                'ZEND_FENTRY_FLAGS(%s, %s)',
+                $flags1 === [] ? 0 : implode("|", $flags1),
+                implode("|", $flags2),
+            );
+        }
+
+        return implode("|", $flags1);
     }
 
     public function generateVersionDependentFlagCode(
@@ -1260,7 +1226,7 @@ public function generateVersionDependentFlagCode(
             if (empty($flagsByPhpVersions[$currentPhpVersion])) {
                 return '';
             }
-            return sprintf($codeTemplate, implode("|", $flagsByPhpVersions[$currentPhpVersion]));
+            return sprintf($codeTemplate, $this->formatFlags($flagsByPhpVersions[$currentPhpVersion]));
         }
 
         ksort($flagsByPhpVersions);
@@ -1301,7 +1267,7 @@ public function generateVersionDependentFlagCode(
             reset($flagsByPhpVersions);
             $firstVersion = key($flagsByPhpVersions);
             if ($firstVersion === $phpVersionIdMinimumCompatibility) {
-                return sprintf($codeTemplate, implode("|", reset($flagsByPhpVersions)));
+                return sprintf($codeTemplate, $this->formatFlags(reset($flagsByPhpVersions)));
             }
         }
 
@@ -1314,7 +1280,7 @@ public function generateVersionDependentFlagCode(
 
             $code .= "$if (PHP_VERSION_ID >= $version)\n";
 
-            $code .= sprintf($codeTemplate, implode("|", $versionFlags));
+            $code .= sprintf($codeTemplate, $this->formatFlags($versionFlags));
             $code .= $endif;
 
             $i++;
@@ -1325,26 +1291,6 @@ public function generateVersionDependentFlagCode(
 }
 
 class FuncInfo {
-    public /* readonly */ FunctionOrMethodName $name;
-    private /* readonly */ int $classFlags;
-    public int $flags;
-    public /* readonly */ ?string $aliasType;
-    public ?FunctionOrMethodName $alias;
-    private /* readonly */ bool $isDeprecated;
-    private bool $supportsCompileTimeEval;
-    public /* readonly */ bool $verify;
-    /** @var ArgInfo[] */
-    public /* readonly */ array $args;
-    public /* readonly */ ReturnInfo $return;
-    private /* readonly */ int $numRequiredArgs;
-    public /* readonly */ ?string $cond;
-    public bool $isUndocumentable;
-    private ?int $minimumPhpVersionIdCompatibility;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-    /** @var FramelessFunctionInfo[] */
-    private array $framelessFunctionInfos;
-    private ?ExposedDocComment $exposedDocComment;
 
     /**
      * @param ArgInfo[] $args
@@ -1352,41 +1298,25 @@ class FuncInfo {
      * @param FramelessFunctionInfo[] $framelessFunctionInfos
      */
     public function __construct(
-        FunctionOrMethodName $name,
-        int $classFlags,
-        int $flags,
-        ?string $aliasType,
-        ?FunctionOrMethodName $alias,
-        bool $isDeprecated,
-        bool $supportsCompileTimeEval,
-        bool $verify,
-        array $args,
-        ReturnInfo $return,
-        int $numRequiredArgs,
-        ?string $cond,
-        bool $isUndocumentable,
-        ?int $minimumPhpVersionIdCompatibility,
-        array $attributes,
-        array $framelessFunctionInfos,
-        ?ExposedDocComment $exposedDocComment
+        public readonly FunctionOrMethodName $name,
+        private readonly int $classFlags,
+        public int $flags,
+        public readonly ?string $aliasType,
+        public ?FunctionOrMethodName $alias,
+        private readonly bool $isDeprecated,
+        private bool $supportsCompileTimeEval,
+        private bool $forbidDynamicCalls,
+        public readonly bool $verify,
+        public /* readonly */ array $args,
+        public /* readonly */ ReturnInfo $return,
+        private readonly int $numRequiredArgs,
+        public readonly ?string $cond,
+        public bool $isUndocumentable,
+        private ?int $minimumPhpVersionIdCompatibility,
+        public array $attributes,
+        private array $framelessFunctionInfos,
+        private ?ExposedDocComment $exposedDocComment,
     ) {
-        $this->name = $name;
-        $this->classFlags = $classFlags;
-        $this->flags = $flags;
-        $this->aliasType = $aliasType;
-        $this->alias = $alias;
-        $this->isDeprecated = $isDeprecated;
-        $this->supportsCompileTimeEval = $supportsCompileTimeEval;
-        $this->verify = $verify;
-        $this->args = $args;
-        $this->return = $return;
-        $this->numRequiredArgs = $numRequiredArgs;
-        $this->cond = $cond;
-        $this->isUndocumentable = $isUndocumentable;
-        $this->minimumPhpVersionIdCompatibility = $minimumPhpVersionIdCompatibility;
-        $this->attributes = $attributes;
-        $this->framelessFunctionInfos = $framelessFunctionInfos;
-        $this->exposedDocComment = $exposedDocComment;
         if ($return->tentativeReturnType && $this->isFinalMethod()) {
             throw new Exception("Tentative return inapplicable for final method");
         }
@@ -1439,13 +1369,10 @@ private function getModifierNames(): array
 
     private function hasParamWithUnknownDefaultValue(): bool
     {
-        foreach ($this->args as $arg) {
-            if ($arg->defaultValue && !$arg->hasProperDefaultValue()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->args,
+            static fn (ArgInfo $arg): bool => $arg->defaultValue && !$arg->hasProperDefaultValue()
+        );
     }
 
     private function equalsApartFromNameAndRefcount(FuncInfo $other): bool {
@@ -1666,12 +1593,11 @@ private function getArginfoFlagsByPhpVersions(): VersionFlags
             $flags[] = "ZEND_ACC_DEPRECATED";
         }
 
-        foreach ($this->attributes as $attr) {
-            switch ($attr->class) {
-                case "Deprecated":
-                    $flags[] = "ZEND_ACC_DEPRECATED";
-                    break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+        )) {
+            $flags[] = "ZEND_ACC_DEPRECATED";
         }
 
         $flags = new VersionFlags($flags);
@@ -1680,12 +1606,15 @@ private function getArginfoFlagsByPhpVersions(): VersionFlags
             $flags->addForVersionsAbove("ZEND_ACC_COMPILE_TIME_EVAL", PHP_82_VERSION_ID);
         }
 
-        foreach ($this->attributes as $attr) {
-            switch ($attr->class) {
-                case "NoDiscard":
-                    $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID);
-                    break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "NoDiscard"
+        )) {
+            $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID);
+        }
+
+        if ($this->forbidDynamicCalls) {
+            $flags->addForVersionsAbove("ZEND_ACC2_FORBID_DYN_CALLS", PHP_86_VERSION_ID);
         }
 
         return $flags;
@@ -1703,7 +1632,7 @@ private function generateRefSect1(DOMDocument $doc, string $role): DOMElement {
     }
 
     public function getMethodSynopsisDocument(): ?string {
-        $REFSEC1_SEPERATOR = "\n\n ";
+        $REFSEC1_SEPARATOR = "\n\n ";
 
         $doc = new DOMDocument("1.0", "utf-8");
         $doc->formatOutput = true;
@@ -1713,7 +1642,7 @@ public function getMethodSynopsisDocument(): ?string {
 
         if ($this->isMethod()) {
             assert($this->name instanceof MethodName);
-            /* Namespaces are seperated by '-', '_' must be converted to '-' too.
+            /* Namespaces are separated by '-', '_' must be converted to '-' too.
              * Trim away the __ for magic methods */
             $id = strtolower(
                 str_replace('\\', '-', $this->name->className->__toString())
@@ -1742,7 +1671,7 @@ public function getMethodSynopsisDocument(): ?string {
         $refnamediv->appendChild($refpurpose);
 
         $refnamediv->appendChild(new DOMText("\n "));
-        $refentry->append($refnamediv, $REFSEC1_SEPERATOR);
+        $refentry->append($refnamediv, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $descriptionRefSec = $this->generateRefSect1($doc, 'description');
@@ -1761,16 +1690,16 @@ public function getMethodSynopsisDocument(): ?string {
         $descriptionRefSec->appendChild($returnDescriptionPara);
 
         $descriptionRefSec->appendChild(new DOMText("\n "));
-        $refentry->append($descriptionRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($descriptionRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $parametersRefSec = $this->getParameterSection($doc);
-        $refentry->append($parametersRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($parametersRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         if (!$this->name->isConstructor() && !$this->name->isDestructor()) {
             $returnRefSec = $this->getReturnValueSection($doc);
-            $refentry->append($returnRefSec, $REFSEC1_SEPERATOR);
+            $refentry->append($returnRefSec, $REFSEC1_SEPARATOR);
         }
 
         /* Creation of  */
@@ -1790,14 +1719,14 @@ public function getMethodSynopsisDocument(): ?string {
         $errorsRefSec->appendChild($errorsDescriptionPara);
         $errorsRefSec->appendChild(new DOMText("\n "));
 
-        $refentry->append($errorsRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($errorsRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $changelogRefSec = $this->getChangelogSection($doc);
-        $refentry->append($changelogRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($changelogRefSec, $REFSEC1_SEPARATOR);
 
         $exampleRefSec = $this->getExampleSection($doc, $id);
-        $refentry->append($exampleRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($exampleRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $notesRefSec = $this->generateRefSect1($doc, 'notes');
@@ -1810,7 +1739,7 @@ public function getMethodSynopsisDocument(): ?string {
         $noteTag->append("\n   ", $noteTagSimara, "\n  ");
         $notesRefSec->append($noteTag, "\n ");
 
-        $refentry->append($notesRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($notesRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $seeAlsoRefSec = $this->generateRefSect1($doc, 'seealso');
@@ -1882,56 +1811,56 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
             $noParamEntity = $doc->createEntityReference('no.function.parameters');
             $parametersRefSec->appendChild($noParamEntity);
             return $parametersRefSec;
-        } else {
-            $parametersContainer = $doc->createDocumentFragment();
-
-            $parametersContainer->appendChild(new DOMText("\n  "));
-            $parametersList = $doc->createElement('variablelist');
-            $parametersContainer->appendChild($parametersList);
-
-            /*
-            
-             name
-             
-              
-               Description.
-              
-             
-            
-            */
-            foreach ($this->args as $arg) {
-                $parameter = $doc->createElement('parameter', $arg->name);
-                $parameterTerm = $doc->createElement('term');
-                $parameterTerm->appendChild($parameter);
-
-                $listItemPara = $doc->createElement('simpara');
-                $listItemPara->append(
-                    "\n      ",
-                    "Description.",
-                    "\n     ",
-                );
+        }
+        $parametersContainer = $doc->createDocumentFragment();
+
+        $parametersContainer->appendChild(new DOMText("\n  "));
+        $parametersList = $doc->createElement('variablelist');
+        $parametersContainer->appendChild($parametersList);
+
+        /*
+        
+            name
+            
+            
+            Description.
+            
+            
+        
+        */
+        foreach ($this->args as $arg) {
+            $parameter = $doc->createElement('parameter', $arg->name);
+            $parameterTerm = $doc->createElement('term');
+            $parameterTerm->appendChild($parameter);
+
+            $listItemPara = $doc->createElement('simpara');
+            $listItemPara->append(
+                "\n      ",
+                "Description.",
+                "\n     ",
+            );
 
-                $parameterEntryListItem = $doc->createElement('listitem');
-                $parameterEntryListItem->append(
-                    "\n     ",
-                    $listItemPara,
-                    "\n    ",
-                );
+            $parameterEntryListItem = $doc->createElement('listitem');
+            $parameterEntryListItem->append(
+                "\n     ",
+                $listItemPara,
+                "\n    ",
+            );
 
-                $parameterEntry = $doc->createElement('varlistentry');
-                $parameterEntry->append(
-                    "\n    ",
-                    $parameterTerm,
-                    "\n    ",
-                    $parameterEntryListItem,
-                    "\n   ",
-                );
+            $parameterEntry = $doc->createElement('varlistentry');
+            $parameterEntry->append(
+                "\n    ",
+                $parameterTerm,
+                "\n    ",
+                $parameterEntryListItem,
+                "\n   ",
+            );
 
-                $parametersList->appendChild(new DOMText("\n   "));
-                $parametersList->appendChild($parameterEntry);
-            }
-            $parametersList->appendChild(new DOMText("\n  "));
+            $parametersList->appendChild(new DOMText("\n   "));
+            $parametersList->appendChild($parameterEntry);
         }
+        $parametersList->appendChild(new DOMText("\n  "));
+
         $parametersContainer->appendChild(new DOMText("\n "));
         $parametersRefSec->appendChild($parametersContainer);
         $parametersRefSec->appendChild(new DOMText("\n "));
@@ -1950,20 +1879,12 @@ private function getReturnValueSection(DOMDocument $doc): DOMElement {
         } else if (count($returnType->types) === 1) {
             $type = $returnType->types[0];
 
-            switch ($type->name) {
-                case 'void':
-                    $descriptionNode = $doc->createEntityReference('return.void');
-                    break;
-                case 'true':
-                    $descriptionNode = $doc->createEntityReference('return.true.always');
-                    break;
-                case 'bool':
-                    $descriptionNode = $doc->createEntityReference('return.success');
-                    break;
-                default:
-                    $descriptionNode = new DOMText("Description.");
-                    break;
-            }
+            $descriptionNode = match ($type->name) {
+                'void' => $doc->createEntityReference('return.void'),
+                'true' => $doc->createEntityReference('return.true.always'),
+                'bool' => $doc->createEntityReference('return.success'),
+                default => new DOMText("Description."),
+            };
             $returnDescriptionPara->appendChild($descriptionNode);
         } else {
             $returnDescriptionPara->appendChild(new DOMText("Description."));
@@ -2234,11 +2155,11 @@ public function findEquivalent(array $generatedFuncInfos): ?FuncInfo {
         return null;
     }
 
-    public function toArgInfoCode(?int $minPHPCompatability): string {
+    public function toArgInfoCode(?int $minPHPCompatibility): string {
         $code = $this->return->beginArgInfo(
             $this->getArgInfoName(),
             $this->numRequiredArgs,
-            $minPHPCompatability === null || $minPHPCompatability >= PHP_81_VERSION_ID
+            $minPHPCompatibility === null || $minPHPCompatibility >= PHP_81_VERSION_ID
         );
 
         foreach ($this->args as $argInfo) {
@@ -2251,21 +2172,24 @@ public function toArgInfoCode(?int $minPHPCompatability): string {
 
     public function __clone()
     {
-        foreach ($this->args as $key => $argInfo) {
-            $this->args[$key] = clone $argInfo;
-        }
+        $this->args = array_map((\clone)(...), $this->args);
         $this->return = clone $this->return;
     }
 }
 
 class EvaluatedValue
 {
-    public /* readonly */ /* mixed */ $value;
-    public SimpleType $type;
-    public Expr $expr;
-    public bool $isUnknownConstValue;
-    /** @var ConstInfo[] */
-    public array $originatingConsts;
+
+    /**
+     * @param ConstInfo[] $originatingConsts
+     */
+    private function __construct(
+        public readonly mixed $value,
+        public SimpleType $type,
+        public Expr $expr,
+        public array $originatingConsts,
+        public bool $isUnknownConstValue,
+    ) {}
 
     /**
      * @param array $allConstInfos
@@ -2277,14 +2201,11 @@ public static function createFromExpression(Expr $expr, ?SimpleType $constType,
         {
             /** @var iterable */
             public array $visitedConstants = [];
-            /** @var array */
-            public array $allConstInfos;
 
             /** @param array $allConstInfos */
-            public function __construct(array $allConstInfos)
-            {
-                $this->allConstInfos = $allConstInfos;
-            }
+            public function __construct(
+                public array $allConstInfos,
+            ) {}
 
             /** @return Node|null */
             public function enterNode(Node $expr)
@@ -2373,19 +2294,6 @@ public static function null(): EvaluatedValue
         return new self(null, SimpleType::null(), new Expr\ConstFetch(new Node\Name('null')), [], false);
     }
 
-    /**
-     * @param mixed $value
-     * @param ConstInfo[] $originatingConsts
-     */
-    private function __construct($value, SimpleType $type, Expr $expr, array $originatingConsts, bool $isUnknownConstValue)
-    {
-        $this->value = $value;
-        $this->type = $type;
-        $this->expr = $expr;
-        $this->originatingConsts = $originatingConsts;
-        $this->isUnknownConstValue = $isUnknownConstValue;
-    }
-
     public function initializeZval(string $zvalName, bool $alreadyExists = false, string $forStringDef = ''): string
     {
         $cExpr = $this->getCExpr();
@@ -2437,9 +2345,28 @@ public function getCExpr(): ?string
         // $this->expr has all its PHP constants replaced by C constants
         $prettyPrinter = new Standard;
         $expr = $prettyPrinter->prettyPrintExpr($this->expr);
-        // PHP single-quote to C double-quote string
         if ($this->type->isString()) {
-            $expr = preg_replace("/(^'|'$)/", '"', $expr);
+            // The string in $expr has had the octal, hex, and unicode
+            // backslash sequences already applied for double-quoted strings,
+            // but not the other sequences.
+            //
+            // PHP has single quote strings, C doesn't (they're one char).
+            // Single-quoted strings need handling to replace their escapes
+            // with the double-quoted equivalent; namely single quote escapes.
+            //
+            // Double-quoted strings have similar escape sequences as C does,
+            // so we can pass them through directly. However, C does *not*
+            // support the \$ escape sequence (in ""), so strip that. Variable
+            // interpolation shouldn't be possible in a stub, so we don't need
+            // to worry about mangling such a case.
+            if (preg_match("/(^'|'$)/", $expr)) {
+                $expr = substr($expr, 1, -1); // strip quotes, readd later
+                $expr = str_replace("\\'", "'", $expr);
+                $expr = addcslashes($expr, "\\\"");
+                $expr = "\"$expr\"";
+            } else {
+                $expr = str_replace('\$', "$", $expr);
+            }
         }
         return $expr[0] == '"' ? $expr : preg_replace('(\bnull\b)', 'NULL', str_replace('\\', '', $expr));
     }
@@ -2447,35 +2374,18 @@ public function getCExpr(): ?string
 
 abstract class VariableLike
 {
-    protected int $flags;
-    public ?Type $type;
-    public /* readonly */ ?Type $phpDocType;
-    private /* readonly */ ?string $link;
-    protected ?int $phpVersionIdMinimumCompatibility;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-    protected /* readonly */ ?ExposedDocComment $exposedDocComment;
-
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        int $flags,
-        ?Type $type,
-        ?Type $phpDocType,
-        ?string $link,
-        ?int $phpVersionIdMinimumCompatibility,
-        array $attributes,
-        ?ExposedDocComment $exposedDocComment
-    ) {
-        $this->flags = $flags;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->link = $link;
-        $this->phpVersionIdMinimumCompatibility = $phpVersionIdMinimumCompatibility;
-        $this->attributes = $attributes;
-        $this->exposedDocComment = $exposedDocComment;
-    }
+        protected int $flags,
+        public ?Type $type,
+        public readonly ?Type $phpDocType,
+        private readonly ?string $link,
+        protected ?int $phpVersionIdMinimumCompatibility,
+        public array $attributes,
+        protected readonly ?ExposedDocComment $exposedDocComment,
+    ) {}
 
     abstract protected function getVariableTypeName(): string;
 
@@ -2497,14 +2407,22 @@ protected function getFlagsByPhpVersion(): VersionFlags
             $flags = "ZEND_ACC_PRIVATE";
         }
 
-        return new VersionFlags([$flags]);
+        $versionFlags = new VersionFlags([$flags]);
+
+        if ($this->flags & Modifiers::PUBLIC_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PUBLIC_SET", PHP_84_VERSION_ID);
+        } elseif ($this->flags & Modifiers::PROTECTED_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PROTECTED_SET", PHP_84_VERSION_ID);
+        } elseif ($this->flags & Modifiers::PRIVATE_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PRIVATE_SET", PHP_84_VERSION_ID);
+        }
+
+        return $versionFlags;
     }
 
     protected function getTypeCode(string $variableLikeName, string &$code): string
     {
         $variableLikeType = $this->getVariableTypeName();
-
-        $typeCode = "";
         if ($this->type) {
             $arginfoType = $this->type->toArginfoType();
             if ($arginfoType->hasClassType()) {
@@ -2520,8 +2438,8 @@ protected function getTypeCode(string $variableLikeName, string &$code): string
                     $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->num_types = $classTypeCount;\n";
 
                     foreach ($arginfoType->classTypes as $k => $classType) {
-                        $escapedClassName = $classType->toEscapedName();
-                        $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$escapedClassName}, 0, 0);\n";
+                        $varEscapedClassName = $classType->toVarEscapedName();
+                        $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, 0);\n";
                     }
 
                     $typeMaskCode = $this->type->toArginfoType()->toTypeMask();
@@ -2531,22 +2449,17 @@ protected function getTypeCode(string $variableLikeName, string &$code): string
                     } else {
                         $code .= "\tzend_type {$variableLikeType}_{$variableLikeName}_type = ZEND_TYPE_INIT_UNION({$variableLikeType}_{$variableLikeName}_type_list, $typeMaskCode);\n";
                     }
-                    $typeCode = "{$variableLikeType}_{$variableLikeName}_type";
-                } else {
-                    $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
-                    $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
-                    $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
-
-                    $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
+                    return "{$variableLikeType}_{$variableLikeName}_type";
                 }
-            } else {
-                $typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
+                $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
+                $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
+                $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
+
+                return "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
             }
-        } else {
-            $typeCode = "(zend_type) ZEND_TYPE_INIT_NONE(0)";
+            return "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
         }
-
-        return $typeCode;
+        return "(zend_type) ZEND_TYPE_INIT_NONE(0)";
     }
 
     /** @param array $allConstInfos */
@@ -2600,56 +2513,51 @@ protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fie
             $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "private"));
         }
+
+        if ($this->flags & Modifiers::PUBLIC_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "public(set)"));
+        } elseif ($this->flags & Modifiers::PROTECTED_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "protected(set)"));
+        } elseif ($this->flags & Modifiers::PRIVATE_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "private(set)"));
+        }
     }
 
 }
 
 class ConstInfo extends VariableLike
 {
-    public /* readonly */ AbstractConstName $name;
-    public /* readonly */ Expr $value;
-    private bool $isDeprecated;
-    private /* readonly */ ?string $valueString;
-    public /* readonly */ ?string $cond;
-    public /* readonly */ ?string $cValue;
-    public /* readonly */ bool $isUndocumentable;
-    private /* readonly */ bool $isFileCacheAllowed;
 
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        AbstractConstName $name,
+        public readonly AbstractConstName $name,
         int $flags,
-        Expr $value,
-        ?string $valueString,
+        public readonly Expr $value,
+        private readonly ?string $valueString,
         ?Type $type,
         ?Type $phpDocType,
-        bool $isDeprecated,
-        ?string $cond,
-        ?string $cValue,
-        bool $isUndocumentable,
+        private bool $isDeprecated,
+        public readonly ?string $cond,
+        public readonly ?string $cValue,
+        public readonly bool $isUndocumentable,
         ?string $link,
         ?int $phpVersionIdMinimumCompatibility,
         array $attributes,
         ?ExposedDocComment $exposedDocComment,
-        bool $isFileCacheAllowed
+        private readonly bool $isFileCacheAllowed,
     ) {
-        foreach ($attributes as $attr) {
-            if ($attr->class === "Deprecated") {
-                $isDeprecated = true;
-                break;
-            }
+        if (array_any(
+            $attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+        )) {
+            $this->isDeprecated = true;
         }
 
-        $this->name = $name;
-        $this->value = $value;
-        $this->valueString = $valueString;
-        $this->isDeprecated = $isDeprecated;
-        $this->cond = $cond;
-        $this->cValue = $cValue;
-        $this->isUndocumentable = $isUndocumentable;
-        $this->isFileCacheAllowed = $isFileCacheAllowed;
         parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment);
     }
 
@@ -2759,7 +2667,7 @@ public function getDeclaration(array $allConstInfos): string
         // Condition will be added by generateCodeWithConditions()
 
         if ($this->name instanceof ClassConstName) {
-            $code = $this->getClassConstDeclaration($value, $allConstInfos);
+            $code = $this->getClassConstDeclaration($value);
         } else {
             $code = $this->getGlobalConstDeclaration($value);
         }
@@ -2820,12 +2728,10 @@ private function getGlobalConstDeclaration(EvaluatedValue $value): string
         throw new Exception("Unimplemented constant type");
     }
 
-    /** @param array $allConstInfos */
-    private function getClassConstDeclaration(EvaluatedValue $value, array $allConstInfos): string
+    private function getClassConstDeclaration(EvaluatedValue $value): string
     {
         $constName = $this->name->getDeclarationName();
 
-        // TODO $allConstInfos is unused
         $zvalCode = $value->initializeZval("const_{$constName}_value");
 
         $code = "\n" . $zvalCode;
@@ -3068,6 +2974,12 @@ class StringBuilder {
         '8.5' => 'ZEND_STR_8_DOT_5',
     ];
 
+    // NEW in 8.6
+    private const PHP_86_KNOWN = [
+        "arguments" => "ZEND_STR_ARGUMENTS",
+        "NoDiscard" => "ZEND_STR_NODISCARD",
+    ];
+
     /**
      * Get an array of three strings:
      *   - declaration of zend_string, if needed, or empty otherwise
@@ -3106,6 +3018,10 @@ public static function getString(
         }
         $include = self::PHP_80_KNOWN;
         switch ($minPhp) {
+            case PHP_86_VERSION_ID:
+                $include = array_merge($include, self::PHP_86_KNOWN);
+                // Intentional fall through
+
             case PHP_85_VERSION_ID:
                 $include = array_merge($include, self::PHP_85_KNOWN);
                 // Intentional fall through
@@ -3137,37 +3053,25 @@ public static function getString(
 
 class PropertyInfo extends VariableLike
 {
-    private /* readonly */ int $classFlags;
-    public /* readonly */ PropertyName $name;
-    private /* readonly */ ?Expr $defaultValue;
-    private /* readonly */ ?string $defaultValueString;
-    private /* readonly */ bool $isDocReadonly;
-    private /* readonly */ bool $isVirtual;
 
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        PropertyName $name,
-        int $classFlags,
+        public readonly PropertyName $name,
+        private readonly int $classFlags,
         int $flags,
         ?Type $type,
         ?Type $phpDocType,
-        ?Expr $defaultValue,
-        ?string $defaultValueString,
-        bool $isDocReadonly,
-        bool $isVirtual,
+        private readonly ?Expr $defaultValue,
+        private readonly ?string $defaultValueString,
+        private readonly bool $isDocReadonly,
+        private readonly bool $isVirtual,
         ?string $link,
         ?int $phpVersionIdMinimumCompatibility,
         array $attributes,
         ?ExposedDocComment $exposedDocComment
     ) {
-        $this->name = $name;
-        $this->classFlags = $classFlags;
-        $this->defaultValue = $defaultValue;
-        $this->defaultValueString = $defaultValueString;
-        $this->isDocReadonly = $isDocReadonly;
-        $this->isVirtual = $isVirtual;
         parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment);
     }
 
@@ -3311,65 +3215,108 @@ protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fie
 }
 
 class EnumCaseInfo {
-    public /* readonly */ string $name;
-    private /* readonly */ ?Expr $value;
-
-    public function __construct(string $name, ?Expr $value) {
-        $this->name = $name;
-        $this->value = $value;
-    }
+    public function __construct(
+        public readonly EnumCaseName $name,
+        private readonly ?Expr $value,
+        private readonly ?string $valueString
+    ) {}
 
     /** @param array $allConstInfos */
     public function getDeclaration(array $allConstInfos): string {
-        $escapedName = addslashes($this->name);
+        $escapedName = addslashes($this->name->case);
         if ($this->value === null) {
-            $code = "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
-        } else {
-            $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
-
-            $zvalName = "enum_case_{$escapedName}_value";
-            $code = "\n" . $value->initializeZval($zvalName);
-            $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
+            return "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
         }
+        $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+
+        $zvalName = "enum_case_{$escapedName}_value";
+        $code = "\n" . $value->initializeZval($zvalName);
+        $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
 
         return $code;
     }
-}
 
-// Instances of AttributeInfo are immutable and do not need to be cloned
-// when held by an object that is cloned
-class AttributeInfo {
-    public /* readonly */ string $class;
-    /** @var \PhpParser\Node\Arg[] */
-    private /* readonly */ array $args;
+    /** @param array $allConstInfos */
+    public function getEnumSynopsisItemElement(DOMDocument $doc, array $allConstInfos, int $indentationLevel): DOMElement
+    {
+        $indentation = str_repeat(" ", $indentationLevel);
 
-    /** @param \PhpParser\Node\Arg[] $args */
-    public function __construct(string $class, array $args) {
-        $this->class = $class;
-        $this->args = $args;
-    }
+        $itemElement = $doc->createElement("enumitem");
 
-    /**
-     * @param array $allConstInfos
-     * @param array &$declaredStrings Map of string content to
-     *   the name of a zend_string already created with that content
-     */
-    public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, array &$declaredStrings = []): string {
-        $escapedAttributeName = strtr($this->class, '\\', '_');
-        [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
-            "attribute_name_{$escapedAttributeName}_$nameSuffix",
-            addcslashes($this->class, "\\"),
-            $phpVersionIdMinimumCompatibility,
-            true
-        );
-        $code = "\n";
-        $code .= $stringInit;
-        $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, $nameCode, " . count($this->args) . ");\n";
-        $code .= $stringRelease;
+        $identifierElement = $doc->createElement("enumidentifier", $this->name->case);
 
-        foreach ($this->args as $i => $arg) {
-            $initValue = '';
-            if ($arg->value instanceof Node\Scalar\String_) {
+        $itemElement->appendChild(new DOMText("\n$indentation "));
+        $itemElement->appendChild($identifierElement);
+
+        $valueString = $this->getEnumSynopsisValueString($allConstInfos);
+        if ($valueString) {
+            $itemElement->appendChild(new DOMText("\n$indentation "));
+            $valueElement = $doc->createElement("enumvalue",  $valueString);
+            $itemElement->appendChild($valueElement);
+        }
+
+        $descriptionElement = $doc->createElement("enumitemdescription", "Description.");
+        $itemElement->appendChild(new DOMText("\n$indentation "));
+        $itemElement->appendChild($descriptionElement);
+
+        $itemElement->appendChild(new DOMText("\n$indentation"));
+
+        return $itemElement;
+    }
+
+    /** @param array $allConstInfos */
+    public function getEnumSynopsisValueString(array $allConstInfos): ?string
+    {
+        if ($this->value === null) {
+            return null;
+        }
+
+        $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+        if ($value->isUnknownConstValue) {
+            return null;
+        }
+
+        if ($value->originatingConsts) {
+            return implode("\n", array_map(function (ConstInfo $const) use ($allConstInfos) {
+                return $const->getFieldSynopsisValueString($allConstInfos);
+            }, $value->originatingConsts));
+        }
+
+        return $this->valueString;
+    }
+}
+
+// Instances of AttributeInfo are immutable and do not need to be cloned
+// when held by an object that is cloned
+class AttributeInfo {
+
+    /** @param \PhpParser\Node\Arg[] $args */
+    public function __construct(
+        public readonly string $class,
+        private readonly array $args,
+    ) {}
+
+    /**
+     * @param array $allConstInfos
+     * @param array &$declaredStrings Map of string content to
+     *   the name of a zend_string already created with that content
+     */
+    public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, array &$declaredStrings = []): string {
+        $escapedAttributeName = strtr($this->class, '\\', '_');
+        [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
+            "attribute_name_{$escapedAttributeName}_$nameSuffix",
+            addcslashes($this->class, "\\"),
+            $phpVersionIdMinimumCompatibility,
+            true
+        );
+        $code = "\n";
+        $code .= $stringInit;
+        $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, $nameCode, " . count($this->args) . ");\n";
+        $code .= $stringRelease;
+
+        foreach ($this->args as $i => $arg) {
+            $initValue = '';
+            if ($arg->value instanceof Node\Scalar\String_) {
                 $strVal = $arg->value->value;
                 [$strInit, $strUse, $strRelease] = StringBuilder::getString(
                     'unused',
@@ -3432,83 +3379,40 @@ public static function createFromGroups(array $attributeGroups): array {
 }
 
 class ClassInfo {
-    public /* readonly */ Name $name;
-    private int $flags;
-    public string $type;
-    public /* readonly */ ?string $alias;
-    private /* readonly */ ?SimpleType $enumBackingType;
-    private /* readonly */ bool $isDeprecated;
-    private bool $isStrictProperties;
-    /** @var AttributeInfo[] */
-    private array $attributes;
-    private ?ExposedDocComment $exposedDocComment;
-    private bool $isNotSerializable;
-    /** @var Name[] */
-    private /* readonly */ array $extends;
-    /** @var Name[] */
-    private /* readonly */ array $implements;
-    /** @var ConstInfo[] */
-    public /* readonly */ array $constInfos;
-    /** @var PropertyInfo[] */
-    private /* readonly */ array $propertyInfos;
-    /** @var FuncInfo[] */
-    public array $funcInfos;
-    /** @var EnumCaseInfo[] */
-    private /* readonly */ array $enumCaseInfos;
-    public /* readonly */ ?string $cond;
-    public ?int $phpVersionIdMinimumCompatibility;
-    public /* readonly */ bool $isUndocumentable;
 
     /**
      * @param AttributeInfo[] $attributes
      * @param Name[] $extends
      * @param Name[] $implements
+     * @param Name[] $uses
      * @param ConstInfo[] $constInfos
      * @param PropertyInfo[] $propertyInfos
      * @param FuncInfo[] $funcInfos
      * @param EnumCaseInfo[] $enumCaseInfos
      */
     public function __construct(
-        Name $name,
-        int $flags,
-        string $type,
-        ?string $alias,
-        ?SimpleType $enumBackingType,
-        bool $isDeprecated,
-        bool $isStrictProperties,
-        array $attributes,
-        ?ExposedDocComment $exposedDocComment,
-        bool $isNotSerializable,
-        array $extends,
-        array $implements,
-        array $constInfos,
-        array $propertyInfos,
-        array $funcInfos,
-        array $enumCaseInfos,
-        ?string $cond,
-        ?int $minimumPhpVersionIdCompatibility,
-        bool $isUndocumentable
-    ) {
-        $this->name = $name;
-        $this->flags = $flags;
-        $this->type = $type;
-        $this->alias = $alias;
-        $this->enumBackingType = $enumBackingType;
-        $this->isDeprecated = $isDeprecated;
-        $this->isStrictProperties = $isStrictProperties;
-        $this->attributes = $attributes;
-        $this->exposedDocComment = $exposedDocComment;
-        $this->isNotSerializable = $isNotSerializable;
-        $this->extends = $extends;
-        $this->implements = $implements;
-        $this->constInfos = $constInfos;
-        $this->propertyInfos = $propertyInfos;
-        $this->funcInfos = $funcInfos;
-        $this->enumCaseInfos = $enumCaseInfos;
-        $this->cond = $cond;
-        $this->phpVersionIdMinimumCompatibility = $minimumPhpVersionIdCompatibility;
-        $this->isUndocumentable = $isUndocumentable;
-    }
+        public readonly Name $name,
+        private int $flags,
+        public string $type,
+        public readonly ?string $alias,
+        private readonly ?SimpleType $enumBackingType,
+        private readonly bool $isDeprecated,
+        private bool $isStrictProperties,
+        private array $attributes,
+        private ?ExposedDocComment $exposedDocComment,
+        private bool $isNotSerializable,
+        private readonly array $extends,
+        private readonly array $implements,
+        private readonly array $uses,
+        public /* readonly */ array $constInfos,
+        private /* readonly */ array $propertyInfos,
+        public array $funcInfos,
+        private readonly array $enumCaseInfos,
+        private readonly bool $generateCNameTable,
+        public readonly ?string $cond,
+        public ?int $phpVersionIdMinimumCompatibility,
+        public readonly bool $isUndocumentable,
+    ) {}
 
     /** @param array $allConstInfos */
     public function getRegistration(array $allConstInfos): string
@@ -3520,6 +3424,9 @@ public function getRegistration(array $allConstInfos): string
         foreach ($this->implements as $implements) {
             $params[] = "zend_class_entry *class_entry_" . implode("_", $implements->getParts());
         }
+        foreach ($this->uses as $use) {
+            $params[] = "zend_class_entry *class_entry_" . implode("_", $use->getParts());
+        }
 
         $escapedName = implode("_", $this->name->getParts());
 
@@ -3617,6 +3524,17 @@ function (Name $item) {
             $code .= "\tzend_class_implements(class_entry, " . count($implements) . ", " . implode(", ", $implements) . ");\n";
         }
 
+        $traits = array_map(
+            function (Name $item) {
+                return "class_entry_" . implode("_", $item->getParts());
+            },
+            $this->uses
+        );
+
+        if (!empty($traits)) {
+            $code .= "\tzend_class_use_internal_traits(class_entry, " . count($traits) . ", " . implode(", ", $traits) . ");\n";
+        }
+
         if ($this->alias) {
             $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "\\\\", $this->alias) . "\", class_entry);\n";
         }
@@ -3712,13 +3630,32 @@ public function getCDeclarations(): string
 
         $i = 1;
         foreach ($this->enumCaseInfos as $case) {
-            $cName = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString()) . '_' . $case->name;
+            $cName = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString()) . '_' . $case->name->case;
             $code .= "\t{$cName} = {$i},\n";
             $i++;
         }
 
         $code .= "} {$cEnumName};\n";
 
+        $caseCount = count($this->enumCaseInfos);
+
+        if ($this->generateCNameTable && $caseCount > 0) {
+            $cPrefix = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString());
+            $useGuard = $cPrefix . '_USE_NAME_TABLE';
+
+            $code .= "\n#define {$cPrefix}_CASE_COUNT {$caseCount}\n";
+            $code .= "\n#ifdef {$useGuard}\n";
+            $code .= "static const char *{$cEnumName}_case_names[{$cPrefix}_CASE_COUNT + 1] = {\n";
+
+            foreach ($this->enumCaseInfos as $case) {
+                $cName = $cPrefix . '_' . $case->name->case;
+                $code .= "\t[{$cName}] = \"{$case->name->case}\",\n";
+            }
+
+            $code .= "};\n";
+            $code .= "#endif\n";
+        }
+
         if ($this->cond) {
             $code .= "#endif\n";
         }
@@ -3760,11 +3697,11 @@ private function getFlagsByPhpVersion(): VersionFlags
             $flags->addForVersionsAbove("ZEND_ACC_READONLY_CLASS", PHP_82_VERSION_ID);
         }
 
-        foreach ($this->attributes as $attr) {
-            if ($attr->class === "AllowDynamicProperties") {
-                $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID);
-                break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "AllowDynamicProperties"
+        )) {
+            $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID);
         }
 
         return $flags;
@@ -3805,8 +3742,12 @@ public function getClassSynopsisDocument(array $classMap, array $allConstInfos):
      * @param array $allConstInfos
      */
     public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array $allConstInfos): ?DOMElement {
-        $classSynopsis = $doc->createElement("classsynopsis");
-        $classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class");
+        if ($this->type === "enum") {
+            $classSynopsis = $doc->createElement("enumsynopsis");
+        } else {
+            $classSynopsis = $doc->createElement("classsynopsis");
+            $classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class");
+        }
 
         $namespace = $this->getNamespace();
         if ($namespace) {
@@ -3826,108 +3767,120 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array
             $classSynopsisIndentation = str_repeat(" ", $classSynopsisIndentationLevel);
         }
 
-        $exceptionOverride = $this->type === "class" && $this->isException($classMap) ? "exception" : null;
-        $ooElement = self::createOoElement($doc, $this, $exceptionOverride, true, null, $classSynopsisIndentationLevel + 1);
-        if (!$ooElement) {
-            return null;
-        }
         $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
-        $classSynopsis->appendChild($ooElement);
 
-        foreach ($this->extends as $k => $parent) {
-            $parentInfo = $classMap[$parent->toString()] ?? null;
-            if ($parentInfo === null) {
-                throw new Exception("Missing parent class " . $parent->toString());
-            }
+        if ($this->type === "enum") {
+            $enumName = $doc->createElement("enumname", $this->getClassName());
+            $classSynopsis->appendChild($enumName);
 
-            $ooElement = self::createOoElement(
-                $doc,
-                $parentInfo,
-                null,
-                false,
-                $k === 0 ? "extends" : null,
-                $classSynopsisIndentationLevel + 1
-            );
+            foreach ($this->enumCaseInfos as $enumCaseInfo) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $enumItemElement = $enumCaseInfo->getEnumSynopsisItemElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                $classSynopsis->appendChild($enumItemElement);
+            }
+        } else {
+            $exceptionOverride = $this->type === "class" && $this->isException($classMap) ? "exception" : null;
+            $ooElement = self::createOoElement($doc, $this, $exceptionOverride, true, null, $classSynopsisIndentationLevel + 1);
             if (!$ooElement) {
                 return null;
             }
-
-            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
             $classSynopsis->appendChild($ooElement);
-        }
 
-        foreach ($this->implements as $k => $interface) {
-            $interfaceInfo = $classMap[$interface->toString()] ?? null;
-            if (!$interfaceInfo) {
-                throw new Exception("Missing implemented interface " . $interface->toString());
+            foreach ($this->extends as $k => $parent) {
+                $parentInfo = $classMap[$parent->toString()] ?? null;
+                if ($parentInfo === null) {
+                    throw new Exception("Missing parent class " . $parent->toString());
+                }
+
+                $ooElement = self::createOoElement(
+                    $doc,
+                    $parentInfo,
+                    null,
+                    false,
+                    $k === 0 ? "extends" : null,
+                    $classSynopsisIndentationLevel + 1
+                );
+                if (!$ooElement) {
+                    return null;
+                }
+
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsis->appendChild($ooElement);
             }
 
-            $ooElement = self::createOoElement($doc, $interfaceInfo, null, false, $k === 0 ? "implements" : null, $classSynopsisIndentationLevel + 1);
-            if (!$ooElement) {
-                return null;
+            foreach ($this->implements as $k => $interface) {
+                $interfaceInfo = $classMap[$interface->toString()] ?? null;
+                if (!$interfaceInfo) {
+                    throw new Exception("Missing implemented interface " . $interface->toString());
+                }
+
+                $ooElement = self::createOoElement($doc, $interfaceInfo, null, false, $k === 0 ? "implements" : null, $classSynopsisIndentationLevel + 1);
+                if (!$ooElement) {
+                    return null;
+                }
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsis->appendChild($ooElement);
             }
-            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
-            $classSynopsis->appendChild($ooElement);
-        }
 
-        /** @var array $parentsWithInheritedConstants */
-        $parentsWithInheritedConstants = [];
-        /** @var array $parentsWithInheritedProperties */
-        $parentsWithInheritedProperties = [];
-        /** @var array $parentsWithInheritedMethods */
-        $parentsWithInheritedMethods = [];
+            /** @var array $parentsWithInheritedConstants */
+            $parentsWithInheritedConstants = [];
+            /** @var array $parentsWithInheritedProperties */
+            $parentsWithInheritedProperties = [];
+            /** @var array $parentsWithInheritedMethods */
+            $parentsWithInheritedMethods = [];
 
-        $this->collectInheritedMembers(
-            $parentsWithInheritedConstants,
-            $parentsWithInheritedProperties,
-            $parentsWithInheritedMethods,
-            $this->hasConstructor(),
-            $classMap
-        );
+            $this->collectInheritedMembers(
+                $parentsWithInheritedConstants,
+                $parentsWithInheritedProperties,
+                $parentsWithInheritedMethods,
+                $this->hasConstructor(),
+                $classMap
+            );
 
-        $this->appendInheritedMemberSectionToClassSynopsis(
-            $doc,
-            $classSynopsis,
-            $parentsWithInheritedConstants,
-            "&Constants;",
-            "&InheritedConstants;",
-            $classSynopsisIndentationLevel + 1
-        );
+            $this->appendInheritedMemberSectionToClassSynopsis(
+                $doc,
+                $classSynopsis,
+                $parentsWithInheritedConstants,
+                "&Constants;",
+                "&InheritedConstants;",
+                $classSynopsisIndentationLevel + 1
+            );
 
-        if (!empty($this->constInfos)) {
-            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
-            $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Constants;");
-            $classSynopsisInfo->setAttribute("role", "comment");
-            $classSynopsis->appendChild($classSynopsisInfo);
+            if (!empty($this->constInfos)) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Constants;");
+                $classSynopsisInfo->setAttribute("role", "comment");
+                $classSynopsis->appendChild($classSynopsisInfo);
 
-            foreach ($this->constInfos as $constInfo) {
-                $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
-                $fieldSynopsisElement = $constInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
-                $classSynopsis->appendChild($fieldSynopsisElement);
+                foreach ($this->constInfos as $constInfo) {
+                    $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
+                    $fieldSynopsisElement = $constInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                    $classSynopsis->appendChild($fieldSynopsisElement);
+                }
             }
-        }
 
-        if (!empty($this->propertyInfos)) {
-            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
-            $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Properties;");
-            $classSynopsisInfo->setAttribute("role", "comment");
-            $classSynopsis->appendChild($classSynopsisInfo);
+            if (!empty($this->propertyInfos)) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Properties;");
+                $classSynopsisInfo->setAttribute("role", "comment");
+                $classSynopsis->appendChild($classSynopsisInfo);
 
-            foreach ($this->propertyInfos as $propertyInfo) {
-                $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
-                $fieldSynopsisElement = $propertyInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
-                $classSynopsis->appendChild($fieldSynopsisElement);
+                foreach ($this->propertyInfos as $propertyInfo) {
+                    $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
+                    $fieldSynopsisElement = $propertyInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                    $classSynopsis->appendChild($fieldSynopsisElement);
+                }
             }
-        }
 
-        $this->appendInheritedMemberSectionToClassSynopsis(
-            $doc,
-            $classSynopsis,
-            $parentsWithInheritedProperties,
-            "&Properties;",
-            "&InheritedProperties;",
-            $classSynopsisIndentationLevel + 1
-        );
+            $this->appendInheritedMemberSectionToClassSynopsis(
+                $doc,
+                $classSynopsis,
+                $parentsWithInheritedProperties,
+                "&Properties;",
+                "&InheritedProperties;",
+                $classSynopsisIndentationLevel + 1
+            );
+        }
 
         if (!empty($this->funcInfos)) {
             $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
@@ -4011,7 +3964,7 @@ private static function createOoElement(
         $indentation = str_repeat(" ", $indentationLevel);
 
         if ($classInfo->type !== "class" && $classInfo->type !== "interface") {
-            echo "Class synopsis generation is not implemented for " . $classInfo->type . "\n";
+            echo "Warning: Class synopsis generation is not implemented for " . $classInfo->type . " of type " . $classInfo->name . "\n";
             return null;
         }
 
@@ -4171,46 +4124,34 @@ private function isException(array $classMap): bool
 
     private function hasConstructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isConstructor()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor()
+        );
     }
 
     private function hasNonPrivateConstructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)
+        );
     }
 
     private function hasDestructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isDestructor()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isDestructor()
+        );
     }
 
     private function hasMethods(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if (!$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => !$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()
+        );
     }
 
     public function getNamespace(): ?string {
@@ -4243,17 +4184,9 @@ private function createIncludeElement(DOMDocument $doc, string $query, int $inde
 
     public function __clone()
     {
-        foreach ($this->constInfos as $key => $constInfo) {
-            $this->constInfos[$key] = clone $constInfo;
-        }
-
-        foreach ($this->propertyInfos as $key => $propertyInfo) {
-            $this->propertyInfos[$key] = clone $propertyInfo;
-        }
-
-        foreach ($this->funcInfos as $key => $funcInfo) {
-            $this->funcInfos[$key] = clone $funcInfo;
-        }
+        $this->constInfos = array_map((\clone)(...), $this->constInfos);
+        $this->propertyInfos = array_map((\clone)(...), $this->propertyInfos);
+        $this->funcInfos = array_map((\clone)(...), $this->funcInfos);
     }
 
     /**
@@ -4292,13 +4225,13 @@ class FileInfo {
     /** @var ConstInfo[] */
     public array $constInfos = [];
     /** @var FuncInfo[] */
-    public array $funcInfos = [];
+    private array $funcInfos = [];
     /** @var ClassInfo[] */
     public array $classInfos = [];
-    public bool $generateFunctionEntries = false;
-    public string $declarationPrefix = "";
-    public bool $generateClassEntries = false;
-    public bool $generateCEnums = false;
+    private bool $generateFunctionEntries = false;
+    private string $declarationPrefix = "";
+    private bool $generateClassEntries = false;
+    private bool $generateCEnums = false;
     private bool $isUndocumentable = false;
     private bool $legacyArginfoGeneration = false;
     private ?int $minimumPhpVersionIdCompatibility = null;
@@ -4314,7 +4247,8 @@ public function __construct(array $fileTags) {
                     throw new Exception(
                         "Legacy PHP version must be one of: \"" . PHP_70_VERSION_ID . "\" (PHP 7.0), \"" . PHP_80_VERSION_ID . "\" (PHP 8.0), " .
                         "\"" . PHP_81_VERSION_ID . "\" (PHP 8.1), \"" . PHP_82_VERSION_ID . "\" (PHP 8.2), \"" . PHP_83_VERSION_ID . "\" (PHP 8.3), " .
-                        "\"" . PHP_84_VERSION_ID . "\" (PHP 8.4), \"" . PHP_85_VERSION_ID . "\" (PHP 8.5), \"" . $tag->value . "\" provided"
+                        "\"" . PHP_84_VERSION_ID . "\" (PHP 8.4), \"" . PHP_85_VERSION_ID . "\" (PHP 8.5), \"" . PHP_86_VERSION_ID . "\" (PHP 8.6), " .
+                        $tag->value . "\" provided"
                     );
                 }
 
@@ -4364,20 +4298,12 @@ public function getAllConstInfos(): array {
 
     public function __clone()
     {
-        foreach ($this->constInfos as $key => $constInfo) {
-            $this->constInfos[$key] = clone $constInfo;
-        }
-
-        foreach ($this->funcInfos as $key => $funcInfo) {
-            $this->funcInfos[$key] = clone $funcInfo;
-        }
-
-        foreach ($this->classInfos as $key => $classInfo) {
-            $this->classInfos[$key] = clone $classInfo;
-        }
+        $this->constInfos = array_map((\clone)(...), $this->constInfos);
+        $this->funcInfos = array_map((\clone)(...), $this->funcInfos);
+        $this->classInfos = array_map((\clone)(...), $this->classInfos);
     }
 
-    public function getMinimumPhpVersionIdCompatibility(): ?int {
+    private function getMinimumPhpVersionIdCompatibility(): ?int {
         // Non-legacy arginfo files are always PHP 8.0+ compatible
         if (!$this->legacyArginfoGeneration &&
             $this->minimumPhpVersionIdCompatibility !== null &&
@@ -4456,6 +4382,11 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                 continue;
             }
 
+            if ($stmt instanceof Stmt\Use_ || $stmt instanceof Stmt\GroupUse) {
+                // use statements are resolved by NameResolver before this point
+                continue;
+            }
+
             if ($stmt instanceof Stmt\Const_) {
                 foreach ($stmt->consts as $const) {
                     $this->constInfos[] = parseConstLike(
@@ -4494,6 +4425,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                 $propertyInfos = [];
                 $methodInfos = [];
                 $enumCaseInfos = [];
+                $traitUses = [];
                 foreach ($stmt->stmts as $classStmt) {
                     $cond = self::handlePreprocessorConditions($conds, $classStmt);
                     if ($classStmt instanceof Stmt\Nop) {
@@ -4551,7 +4483,17 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                         );
                     } else if ($classStmt instanceof Stmt\EnumCase) {
                         $enumCaseInfos[] = new EnumCaseInfo(
-                            $classStmt->name->toString(), $classStmt->expr);
+                            new EnumCaseName($className, $classStmt->name->toString()),
+                            $classStmt->expr,
+                            $classStmt->expr ? $prettyPrinter->prettyPrintExpr($classStmt->expr) : null,
+                        );
+                    } else if ($classStmt instanceof TraitUse) {
+                        if ($classStmt->adaptations) {
+                            throw new Exception("Trait adaptations are not supported");
+                        }
+                        foreach ($classStmt->traits as $trait) {
+                            $traitUses[] = $trait;
+                        }
                     } else {
                         throw new Exception("Not implemented {$classStmt->getType()}");
                     }
@@ -4564,6 +4506,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                     $propertyInfos,
                     $methodInfos,
                     $enumCaseInfos,
+                    $traitUses,
                     $cond,
                     $this->getMinimumPhpVersionIdCompatibility(),
                     $this->isUndocumentable
@@ -4641,16 +4584,138 @@ public function generateCDeclarations(): string {
 
         return $code;
     }
+
+
+    /**
+     * @param array $allConstInfos
+     * @return array{string, string}
+     */
+    public function generateArgInfoCode(
+        string $stubFilenameWithoutExtension,
+        array $allConstInfos,
+        string $stubHash
+    ): array {
+        $code = "";
+
+        $generatedFuncInfos = [];
+
+        $argInfoCode = generateCodeWithConditions(
+            $this->getAllFuncInfos(), "\n",
+            function (FuncInfo $funcInfo) use (&$generatedFuncInfos) {
+                /* If there already is an equivalent arginfo structure, only emit a #define */
+                if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
+                    $code = sprintf(
+                        "#define %s %s\n",
+                        $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
+                    );
+                } else {
+                    $code = $funcInfo->toArgInfoCode($this->getMinimumPhpVersionIdCompatibility());
+                }
+
+                $generatedFuncInfos[] = $funcInfo;
+                return $code;
+            }
+        );
+
+        if ($argInfoCode !== "") {
+            $code .= "$argInfoCode\n";
+        }
+
+        if ($this->generateFunctionEntries) {
+            $framelessFunctionCode = generateCodeWithConditions(
+                $this->getAllFuncInfos(), "\n",
+                static function (FuncInfo $funcInfo) {
+                    return $funcInfo->getFramelessDeclaration();
+                }
+            );
+
+            if ($framelessFunctionCode !== "") {
+                $code .= "$framelessFunctionCode\n";
+            }
+
+            $generatedFunctionDeclarations = [];
+            $code .= generateCodeWithConditions(
+                $this->getAllFuncInfos(), "",
+                function (FuncInfo $funcInfo) use (&$generatedFunctionDeclarations) {
+                    $key = $funcInfo->getDeclarationKey();
+                    if (isset($generatedFunctionDeclarations[$key])) {
+                        return null;
+                    }
+
+                    $generatedFunctionDeclarations[$key] = true;
+                    return $this->declarationPrefix . $funcInfo->getDeclaration();
+                }
+            );
+
+            $code .= generateFunctionEntries(null, $this->funcInfos);
+
+            foreach ($this->classInfos as $classInfo) {
+                $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
+            }
+        }
+
+        $php80MinimumCompatibility = $this->getMinimumPhpVersionIdCompatibility() === null || $this->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
+
+        if ($this->generateClassEntries) {
+            $declaredStrings = [];
+            $attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+            $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+            if ($attributeInitializationCode) {
+                if (!$php80MinimumCompatibility) {
+                    $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
+                }
+            }
+
+            if ($attributeInitializationCode !== "" || !empty($this->constInfos)) {
+                $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
+                $code .= "{\n";
+
+                $code .= generateCodeWithConditions(
+                    $this->constInfos,
+                    '',
+                    static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
+                );
+
+                if ($attributeInitializationCode !== "" && $this->constInfos) {
+                    $code .= "\n";
+                }
+
+                $code .= $attributeInitializationCode;
+                $code .= "}\n";
+            }
+
+            $code .= $this->generateClassEntryCode($allConstInfos);
+        }
+
+        $hasDeclFile = false;
+        $declCode = $this->generateCDeclarations();
+        if ($declCode !== '') {
+            $hasDeclFile = true;
+            $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
+            $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+                . " * Stub hash: $stubHash */\n"
+                . "\n"
+                . "#ifndef {$headerName}\n"
+                . "#define {$headerName}\n"
+                . $declCode . "\n"
+                . "#endif /* {$headerName} */\n";
+        }
+
+        $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+            . " * Stub hash: $stubHash"
+            . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
+            . $code;
+
+        return [$code, $declCode];
+    }
 }
 
 class DocCommentTag {
-    public /* readonly */ string $name;
-    public /* readonly */ ?string $value;
 
-    public function __construct(string $name, ?string $value) {
-        $this->name = $name;
-        $this->value = $value;
-    }
+    public function __construct(
+        public readonly string $name,
+        public readonly ?string $value,
+    ) {}
 
     public function getValue(): string {
         if ($this->value === null) {
@@ -4736,11 +4801,10 @@ public static function makeTagMap(array $tags): array {
 // Instances of ExposedDocComment are immutable and do not need to be cloned
 // when held by an object that is cloned
 class ExposedDocComment {
-    private /* readonly */ string $docComment;
 
-    public function __construct(string $docComment) {
-        $this->docComment = $docComment;
-    }
+    public function __construct(
+        private readonly string $docComment,
+    ) {}
 
     public function escape(): string {
         return str_replace("\n", '\n', addslashes($this->docComment));
@@ -4777,7 +4841,7 @@ public static function extractExposedComment(array $comments): ?ExposedDocCommen
 // Instances of FramelessFunctionInfo are immutable and do not need to be cloned
 // when held by an object that is cloned
 class FramelessFunctionInfo {
-    public /* readonly */ int $arity;
+    public readonly int $arity;
 
     public function __construct(string $json) {
         // FIXME: Should have some validation
@@ -4804,6 +4868,7 @@ function parseFunctionLike(
         $alias = null;
         $isDeprecated = false;
         $supportsCompileTimeEval = false;
+        $forbidDynamicCalls = false;
         $verify = true;
         $docReturnType = null;
         $tentativeReturnType = false;
@@ -4819,6 +4884,7 @@ function parseFunctionLike(
             $verify = !array_key_exists('no-verify', $tagMap);
             $tentativeReturnType = array_key_exists('tentative-return-type', $tagMap);
             $supportsCompileTimeEval = array_key_exists('compile-time-eval', $tagMap);
+            $forbidDynamicCalls = array_key_exists('forbid-dynamic-calls', $tagMap);
             $isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
 
             foreach ($tags as $tag) {
@@ -4951,6 +5017,7 @@ function parseFunctionLike(
             $alias,
             $isDeprecated,
             $supportsCompileTimeEval,
+            $forbidDynamicCalls,
             $verify,
             $args,
             $return,
@@ -5126,6 +5193,7 @@ function parseProperty(
  * @param PropertyInfo[] $properties
  * @param FuncInfo[] $methods
  * @param EnumCaseInfo[] $enumCases
+ * @param Name[] $traitUses
  */
 function parseClass(
     Name $name,
@@ -5134,13 +5202,13 @@ function parseClass(
     array $properties,
     array $methods,
     array $enumCases,
+    array $traitUses,
     ?string $cond,
     ?int $minimumPhpVersionIdCompatibility,
     bool $isUndocumentable
 ): ClassInfo {
     $comments = $class->getComments();
     $alias = null;
-    $allowsDynamicProperties = false;
 
     $tags = DocCommentTag::parseDocComments($comments);
     $tagMap = DocCommentTag::makeTagMap($tags);
@@ -5149,6 +5217,7 @@ function parseClass(
     $isStrictProperties = array_key_exists('strict-properties', $tagMap);
     $isNotSerializable = array_key_exists('not-serializable', $tagMap);
     $isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
+    $generateCNameTable = array_key_exists('c-name-table', $tagMap);
     foreach ($tags as $tag) {
         if ($tag->name === 'alias') {
             $alias = $tag->getValue();
@@ -5156,13 +5225,10 @@ function parseClass(
     }
 
     $attributes = AttributeInfo::createFromGroups($class->attrGroups);
-    foreach ($attributes as $attribute) {
-        switch ($attribute->class) {
-            case 'AllowDynamicProperties':
-                $allowsDynamicProperties = true;
-                break 2;
-        }
-    }
+    $allowsDynamicProperties = array_any(
+        $attributes,
+        static fn (AttributeInfo $attribute): bool => $attribute->class === 'AllowDynamicProperties'
+    );
 
     if ($isStrictProperties && $allowsDynamicProperties) {
         throw new Exception("A class may not have '@strict-properties' and '#[\\AllowDynamicProperties]' at the same time.");
@@ -5209,10 +5275,12 @@ function parseClass(
         $isNotSerializable,
         $extends,
         $implements,
+        $traitUses,
         $consts,
         $properties,
         $methods,
         $enumCases,
+        $generateCNameTable,
         $cond,
         $minimumPhpVersionIdCompatibility,
         $isUndocumentable
@@ -5274,130 +5342,6 @@ function generateCodeWithConditions(
     return $code;
 }
 
-/**
- * @param array $allConstInfos
- * @return array{string, string}
- */
-function generateArgInfoCode(
-    string $stubFilenameWithoutExtension,
-    FileInfo $fileInfo,
-    array $allConstInfos,
-    string $stubHash
-): array {
-    $code = "";
-
-    $generatedFuncInfos = [];
-
-    $argInfoCode = generateCodeWithConditions(
-        $fileInfo->getAllFuncInfos(), "\n",
-        static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) {
-            /* If there already is an equivalent arginfo structure, only emit a #define */
-            if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
-                $code = sprintf(
-                    "#define %s %s\n",
-                    $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
-                );
-            } else {
-                $code = $funcInfo->toArgInfoCode($fileInfo->getMinimumPhpVersionIdCompatibility());
-            }
-
-            $generatedFuncInfos[] = $funcInfo;
-            return $code;
-        }
-    );
-
-    if ($argInfoCode !== "") {
-        $code .= "$argInfoCode\n";
-    }
-
-    if ($fileInfo->generateFunctionEntries) {
-        $framelessFunctionCode = generateCodeWithConditions(
-            $fileInfo->getAllFuncInfos(), "\n",
-            static function (FuncInfo $funcInfo) {
-                return $funcInfo->getFramelessDeclaration();
-            }
-        );
-
-        if ($framelessFunctionCode !== "") {
-            $code .= "$framelessFunctionCode\n";
-        }
-
-        $generatedFunctionDeclarations = [];
-        $code .= generateCodeWithConditions(
-            $fileInfo->getAllFuncInfos(), "",
-            static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarations) {
-                $key = $funcInfo->getDeclarationKey();
-                if (isset($generatedFunctionDeclarations[$key])) {
-                    return null;
-                }
-
-                $generatedFunctionDeclarations[$key] = true;
-                return $fileInfo->declarationPrefix . $funcInfo->getDeclaration();
-            }
-        );
-
-        $code .= generateFunctionEntries(null, $fileInfo->funcInfos);
-
-        foreach ($fileInfo->classInfos as $classInfo) {
-            $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
-        }
-    }
-
-    $php80MinimumCompatibility = $fileInfo->getMinimumPhpVersionIdCompatibility() === null || $fileInfo->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
-
-    if ($fileInfo->generateClassEntries) {
-        $declaredStrings = [];
-        $attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
-        $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
-        if ($attributeInitializationCode) {
-            if (!$php80MinimumCompatibility) {
-                $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
-            }
-        }
-
-        if ($attributeInitializationCode !== "" || !empty($fileInfo->constInfos)) {
-            $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
-            $code .= "{\n";
-
-            $code .= generateCodeWithConditions(
-                $fileInfo->constInfos,
-                '',
-                static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
-            );
-
-            if ($attributeInitializationCode !== "" && $fileInfo->constInfos) {
-                $code .= "\n";
-            }
-
-            $code .= $attributeInitializationCode;
-            $code .= "}\n";
-        }
-
-        $code .= $fileInfo->generateClassEntryCode($allConstInfos);
-    }
-
-    $hasDeclFile = false;
-    $declCode = $fileInfo->generateCDeclarations();
-    if ($declCode !== '') {
-        $hasDeclFile = true;
-        $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
-        $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
-            . " * Stub hash: $stubHash */\n"
-            . "\n"
-            . "#ifndef {$headerName}\n"
-            . "#define {$headerName}\n"
-            . $declCode . "\n"
-            . "#endif /* {$headerName} */\n";
-    }
-
-    $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
-          . " * Stub hash: $stubHash"
-          . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
-          . $code;
-
-    return [$code, $declCode];
-}
-
 /** @param FuncInfo[] $funcInfos */
 function generateFunctionEntries(?Name $className, array $funcInfos, ?string $cond = null): string {
     // No need to add anything if there are no function entries
@@ -5646,7 +5590,7 @@ function replacePredefinedConstants(string $targetDirectory, array $constMap, ar
     );
 
     foreach ($it as $file) {
-        $pathName = $file->getPathName();
+        $pathName = $file->getPathname();
         if (!preg_match('/(?:[\w\.]*constants[\w\._]*|tokens).xml$/i', basename($pathName))) {
             continue;
         }
@@ -5827,7 +5771,7 @@ function replaceClassSynopses(
     );
 
     foreach ($it as $file) {
-        $pathName = $file->getPathName();
+        $pathName = $file->getPathname();
         if (!preg_match('/\.xml$/i', $pathName)) {
             continue;
         }
@@ -5837,7 +5781,7 @@ function replaceClassSynopses(
             continue;
         }
 
-        if (stripos($xml, "getElementsByTagName("classsynopsis") as $element) {
-            $classSynopsisElements[] = $element;
+            $synopsisElements[] = $element;
         }
 
-        foreach ($classSynopsisElements as $classSynopsis) {
-            if (!$classSynopsis instanceof DOMElement) {
-                continue;
-            }
+        foreach ($doc->getElementsByTagName("enumsynopsis") as $element) {
+            $synopsisElements[] = $element;
+        }
 
-            $child = $classSynopsis->firstElementChild;
-            if ($child === null) {
+        foreach ($synopsisElements as $synopsis) {
+            if (!$synopsis instanceof DOMElement) {
                 continue;
             }
-            $child = $child->lastElementChild;
-            if ($child === null) {
-                continue;
+
+            if ($synopsis->nodeName === "classsynopsis") {
+                $child = $synopsis->firstElementChild;
+                if ($child === null) {
+                    continue;
+                }
+                $child = $child->lastElementChild;
+                if ($child === null) {
+                    continue;
+                }
+            } elseif ($synopsis->nodeName === "enumsynopsis") {
+                $child = $synopsis->firstElementChild;
+                if ($child === null) {
+                    continue;
+                }
             }
+
             $className = $child->textContent;
+
+            if ($synopsis->parentElement->nodeName === "packagesynopsis" &&
+                $synopsis->parentElement->firstElementChild->nodeName === "package"
+            ) {
+                $package = $synopsis->parentElement->firstElementChild;
+                $namespace = $package->textContent;
+
+                $className = $namespace . "\\" . $className;
+                $elementToReplace = $synopsis->parentElement;
+            } else {
+                $elementToReplace = $synopsis;
+            }
+
             if (!isset($classMap[$className])) {
                 continue;
             }
@@ -5880,17 +5849,32 @@ function replaceClassSynopses(
 
             $classInfo = $classMap[$className];
 
-            $newClassSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap, $allConstInfos);
-            if ($newClassSynopsis === null) {
+            $newSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap, $allConstInfos);
+            if ($newSynopsis === null) {
                 continue;
             }
 
             // Check if there is any change - short circuit if there is not any.
 
-            if (replaceAndCompareXmls($doc, $classSynopsis, $newClassSynopsis)) {
+            if (replaceAndCompareXmls($doc, $elementToReplace, $newSynopsis)) {
                 continue;
             }
 
+            if ($synopsis->nodeName === "enumsynopsis") {
+                $oldEnumCaseDescriptionElements = collectEnumSynopsisItemDescriptions($className, $elementToReplace);
+                $newEnumCaseDescriptionElements = collectEnumSynopsisItemDescriptions($className, $newSynopsis);
+
+                foreach ($newEnumCaseDescriptionElements as $key => $newEnumCaseDescriptionElement) {
+                    if (isset($oldEnumCaseDescriptionElements[$key]) === false) {
+                        continue;
+                    }
+
+                    $oldEnumCaseDescriptionElement = $oldEnumCaseDescriptionElements[$key];
+
+                    $newEnumCaseDescriptionElement->parentElement->replaceChild($oldEnumCaseDescriptionElement, $newEnumCaseDescriptionElement);
+                }
+            }
+
             // Return the updated XML
 
             $replacedXml = $doc->saveXML();
@@ -5926,6 +5910,28 @@ function replaceClassSynopses(
     return $classSynopses;
 }
 
+/**
+ * @return array
+ */
+function collectEnumSynopsisItemDescriptions(string $className, DOMElement $synopsis): array
+{
+    $enumCaseDescriptionElements = [];
+
+    $enumCaseDescriptions = $synopsis->getElementsByTagName("enumitemdescription");
+    foreach ($enumCaseDescriptions as $enumItemDescription) {
+        $enumCaseNames = $enumItemDescription->parentElement->getElementsByTagName("enumidentifier");
+        if (empty($enumCaseNames)) {
+            continue;
+        }
+
+        $enumCaseName = $enumCaseNames[0]->textContent;
+
+        $enumCaseDescriptionElements["$className::$enumCaseName"] = $enumItemDescription;
+    }
+
+    return $enumCaseDescriptionElements;
+}
+
 function getReplacedSynopsisXml(string $xml): string
 {
     return preg_replace(
@@ -5982,7 +5988,7 @@ function replaceMethodSynopses(
     );
 
     foreach ($it as $file) {
-        $pathName = $file->getPathName();
+        $pathName = $file->getPathname();
         if (!preg_match('/\.xml$/i', $pathName)) {
             continue;
         }
@@ -6235,7 +6241,7 @@ function initPhpParser() {
     }
 
     spl_autoload_register(static function(string $class) use ($phpParserDir) {
-        if (strpos($class, "PhpParser\\") === 0) {
+        if (str_starts_with($class, "PhpParser\\")) {
             $fileName = $phpParserDir . "/lib/" . str_replace("\\", "/", $class) . ".php";
             require $fileName;
         }
diff --git a/build/php.m4 b/build/php.m4
index 516e18e1abfb..6d9e3e21387b 100644
--- a/build/php.m4
+++ b/build/php.m4
@@ -938,10 +938,14 @@ AC_DEFUN([PHP_NEW_EXTENSION],[
 
   ifelse($5,,ac_extra=,[ac_extra=$(echo "m4_normalize(m4_expand([$5]))"|$SED s#@ext_srcdir@#$ext_srcdir#g|$SED s#@ext_builddir@#$ext_builddir#g)])
 
+  dnl Statically linked extensions share the engine's _tsrm_ls_cache symbol,
+  dnl so in ZTS builds they can read the TSRMLS cache directly.
+  ac_extra_static="$ac_extra -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
+
   if test "$3" != "shared" && test "$3" != "yes" && test "$4" != "cli"; then
 dnl ---------------------------------------------- Static module
     [PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
-    PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
+    PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,)
     EXT_STATIC="$EXT_STATIC $1;$ext_dir"
     if test "$3" != "nocli"; then
       EXT_CLI_STATIC="$EXT_CLI_STATIC $1;$ext_dir"
@@ -962,11 +966,11 @@ dnl ---------------------------------------------- CLI static module
     [PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
     case "$PHP_SAPI" in
       cgi|embed|phpdbg[)]
-        PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
+        PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,)
         EXT_STATIC="$EXT_STATIC $1;$ext_dir"
         ;;
       *[)]
-        PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,cli)
+        PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,cli)
         ;;
     esac
     EXT_CLI_STATIC="$EXT_CLI_STATIC $1;$ext_dir"
@@ -1382,6 +1386,54 @@ int main(void) {
 ])
 ])
 
+AC_DEFUN([PHP_POLL_MECHANISMS],
+[
+  AC_MSG_CHECKING([for polling mechanisms])
+  poll_mechanisms=""
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+    #include 
+  ], [
+    int fd = epoll_create(1);
+    return fd;
+  ])], [
+    AC_DEFINE([HAVE_EPOLL], [1], [Define if epoll is available])
+    poll_mechanisms="$poll_mechanisms epoll"
+
+    AC_CHECK_FUNCS([epoll_pwait2], [],
+      [AC_CHECK_DECL([epoll_pwait2],
+        [AC_DEFINE([HAVE_EPOLL_PWAIT2], [1])],
+        [],
+        [#include ])])
+  ])
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+    #include 
+    #include 
+  ], [
+    int kq = kqueue();
+    return kq;
+  ])], [
+    AC_DEFINE([HAVE_KQUEUE], [1], [Define if kqueue is available])
+    poll_mechanisms="$poll_mechanisms kqueue"
+  ])
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+    #include 
+  ], [
+    int port = port_create();
+    return port;
+  ])], [
+    AC_DEFINE([HAVE_EVENT_PORTS], [1], [Define if event ports are available])
+    poll_mechanisms="$poll_mechanisms eventport"
+  ])
+
+  dnl Set poll mechanisms including poll that is always available
+  poll_mechanisms="$poll_mechanisms poll"
+
+  AC_MSG_RESULT([$poll_mechanisms])
+])
+
 dnl ----------------------------------------------------------------------------
 dnl Library/function existence and build sanity checks.
 dnl ----------------------------------------------------------------------------
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index 4c7648e738cd..000000000000
--- a/codecov.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-ignore:
-  # bundled libraries
-  - "ext/lexbor/lexbor/core"
-  - "ext/lexbor/lexbor/css"
-  - "ext/lexbor/lexbor/dom"
-  - "ext/lexbor/lexbor/encoding"
-  - "ext/lexbor/lexbor/html"
-  - "ext/lexbor/lexbor/ns"
-  - "ext/lexbor/lexbor/ports"
-  - "ext/lexbor/lexbor/punycode"
-  - "ext/lexbor/lexbor/tag"
-  - "ext/lexbor/lexbor/unicode"
-  - "ext/lexbor/lexbor/url"
-  - "ext/pcre/pcre2lib"
-  - "ext/uri/uriparser"
diff --git a/configure.ac b/configure.ac
index 214c0ab91b2a..ec64637b186b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -369,6 +369,9 @@ AC_SEARCH_LIBS([Pgrab], [proc])
 dnl Haiku does not have network api in libc.
 AC_SEARCH_LIBS([setsockopt], [network])
 
+dnl Solaris/illumos provide sendfile() in libsendfile; libc on Linux/FreeBSD.
+AC_SEARCH_LIBS([sendfile], [sendfile])
+
 dnl Check for openpty. It may require linking against libutil or libbsd.
 AC_CHECK_FUNCS([openpty],,
   [AC_SEARCH_LIBS([openpty], [util bsd], [AC_DEFINE([HAVE_OPENPTY], [1])])])
@@ -444,6 +447,7 @@ AC_CHECK_HEADERS(m4_normalize([
 ])
 
 PHP_FOPENCOOKIE
+PHP_POLL_MECHANISMS
 PHP_BROKEN_GETCWD
 AS_VAR_IF([GCC], [yes], [PHP_BROKEN_GCC_STRLEN_OPT])
 
@@ -587,10 +591,12 @@ AC_CHECK_FUNCS(m4_normalize([
   putenv
   reallocarray
   scandir
+  sendfile
   setenv
   setitimer
   shutdown
   sigprocmask
+  splice
   statfs
   statvfs
   std_syslog
@@ -1538,8 +1544,10 @@ AS_VAR_IF([PHP_ADDRESS_SANITIZER], [yes],
   ]))])
 
   AX_CHECK_COMPILE_FLAG([-fsanitize=address], [
-    CFLAGS="$CFLAGS -fsanitize=address -DZEND_TRACK_ARENA_ALLOC"
-    CXXFLAGS="$CXXFLAGS -fsanitize=address -DZEND_TRACK_ARENA_ALLOC"
+    CFLAGS="$CFLAGS -fsanitize=address"
+    CXXFLAGS="$CXXFLAGS -fsanitize=address"
+    AC_DEFINE([ZEND_TRACK_ARENA_ALLOC], [1],
+      [Whether to track arena allocations individually for AddressSanitizer.])
   ], [AC_MSG_ERROR([AddressSanitizer is not available])])
 ])
 
@@ -1682,6 +1690,26 @@ PHP_ADD_SOURCES_X([main],
   [PHP_FASTCGI_OBJS],
   [no])
 
+PHP_ADD_SOURCES([main/io], m4_normalize([
+    php_io.c
+    php_io_copy_linux.c
+    php_io_copy_freebsd.c
+    php_io_copy_solaris.c
+    php_io_copy_macos.c
+  ]),
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+
+PHP_ADD_SOURCES([main/poll], m4_normalize([
+    poll_backend_epoll.c
+    poll_backend_eventport.c
+    poll_backend_kqueue.c
+    poll_backend_poll.c
+    poll_core.c
+    poll_fd_table.c
+    poll_handle.c
+  ]),
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+
 PHP_ADD_SOURCES([main/streams], m4_normalize([
     cast.c
     filter.c
@@ -1689,6 +1717,7 @@ PHP_ADD_SOURCES([main/streams], m4_normalize([
     memory.c
     mmap.c
     plain_wrapper.c
+    stream_errors.c
     streams.c
     transports.c
     userspace.c
@@ -1774,6 +1803,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
     zend_observer.c
     zend_opcode.c
     zend_operators.c
+    zend_partial.c
     zend_property_hooks.c
     zend_ptr_stack.c
     zend_signal.c
@@ -1804,6 +1834,7 @@ AC_DEFINE([HAVE_BUILD_DEFS_H], [1],
 
 PHP_ADD_BUILD_DIR([
   main
+  main/poll
   main/streams
   scripts
   scripts/man1
@@ -1846,11 +1877,11 @@ cat < Only release tags should have version numbers in these files that do not
    > end in `-dev` (e.g., `8.1.7`, `8.1.7RC1`, `8.2.0alpha1`, etc.).
 
-    Do not forget to merge up PHP-X.Y all the way to master. When resolving
-    the conflicts, ignore the changes from PHP-X.Y in higher branches. It
-    means using something like `git checkout --ours .` when on PHP.X.Y+1 or
-    master after the merge resulting in the conflicts.
+    Do not forget to merge up PHP-X.Y all the way to master.
 
-    Be sure to set up a merge driver for the NEWS file as described in
+    ```shell
+    git switch PHP-X.Y+1 # starting from your release branch
+    git merge PHP-X.Y
+    # repeat             # Merge up all the way
+    git switch master
+    git merge PHP-X.Y+n  # latest release branch
+    ```
+
+    When resolving the conflicts, ignore the changes from PHP-X.Y in higher
+    branches when on PHP.X.Y+1 or master after the merge resulting in the
+    conflicts.
+
+    ```shell
+    git checkout --ours main/php_version.h Zend/zend.h configure.ac
+    git add main/php_version.h Zend/zend.h configure.ac
+    git merge --continue
+    ```
+    
+    Be sure to set up a merge driver for the `NEWS` file as described in
     the [Git FAQ page on the PHP wiki][gitfaq-mandatory].
 
 11. Push the changes to the `php-src`.
@@ -662,31 +678,7 @@ slightly different steps. We'll call attention where the steps differ.
     git push upstream master
     ```
 
-14. Switch to your local clone of the `web-php` repository and update the
-    `web-php-distributions` submodule.
-
-    ```shell
-    cd /path/to/repos/php/web-php
-    git pull --rebase upstream master
-    git submodule init
-    git submodule update
-    cd distributions
-    git fetch --all
-    git pull --rebase upstream master
-    cd ..
-    git commit distributions -m "X.Y.Z tarballs"
-    git push upstream master
-    ```
-
-    > 💬 **Hint** \
-    > This fetches the last commit ID from `web-php-distributions` and pins the
-    > "distributions" submodule in `web-php` to this commit ID.
-    >
-    > When the website syncs, which should happen within an hour, the tarballs
-    > will be available from `https://www.php.net/distributions/php-X.Y.Z.tar.gz`,
-    > etc.
-
-15. Once the release is tagged, contact the release-managers@php.net distribution
+14. Once the release is tagged, contact the release-managers@php.net distribution
     list so that Windows binaries can be created. Once those are made, they may
     be found at https://windows.php.net/qa/.
 
@@ -1087,26 +1079,19 @@ volunteers to begin the selection process for the next release managers.
    * 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
-   the moderators for php-announce@lists.php.net so you are able to moderate
-   your release announcements.
-
-   Provide the following information in a single email:
+4. File a [ticket in the infrastructure](https://github.com/php/infrastructure/issues/new?template=request-release-manager-access.yml)
+   project and provide an SSH key, your @php.net email address, your GitHub
+   account name, and your preferred system account name. Preferrably they're
+   all the same!
 
-   - An SSH public key, preferably a new unique one for PHP systems and
-     projects.
-   - Read [Machine Access](https://wiki.php.net/systems#machine_access) to set
-     up access to downloads.php.net through jump hosts, and provide a
-     `.google_authenticator` file for 2FA.
-   - Your @php.net email address to use for the release-managers@php.net
-     distribution list and php-announce@lists.php.net moderator address. This
-     should preferably not forward to a Gmail address.
-   - Your GitHub account name, so that your membership to the release managers
-     group may be approved.
+5. Read [Logging into Servers](https://github.com/php/infrastructure/blob/main/docs/ServerAccess.rst#logging-into-servers) to set up
+   access to downloads.php.net through jump hosts with 2FA.
 
-   A system admin will then contact you to go through with steps 5 through 8 of
-   [2FA setup instructions](https://wiki.php.net/systems#fa_setup_instructions).
+   Then [create a Google Authenticator file](https://github.com/php/infrastructure/blob/main/docs/ServerAccess.rst#creating-google-authenticator-files),
+   and provide the `.google_authenticator` file that this created, as
+   attachment to an email to systems@php.net. In this email you should also
+   provide a link to the ticket in the infrastructure project that you have
+   created in the previous step
 
    > 💬 **Hint** \
    > To send email from your @php.net address, you will need to use a custom
@@ -1114,7 +1099,7 @@ volunteers to begin the selection process for the next release managers.
    > "[Send emails from a different address or alias][]."
 
 
-5. Create a [GPG key][] for your @php.net address.
+6. Create a [GPG key][] for your @php.net address.
 
    > 💡 **Tip** \
    > If you're new to GPG, follow GitHub's instructions for
@@ -1179,7 +1164,7 @@ volunteers to begin the selection process for the next release managers.
    git push
    ```
 
-6. Make sure you have the following repositories cloned locally:
+7. Make sure you have the following repositories cloned locally:
 
    * https://github.com/php/php-src
    * https://github.com/php/web-php
diff --git a/docs/source/core/data-structures/zend_string.rst b/docs/source/core/data-structures/zend_string.rst
index 2b07611e3425..d6b20a49a74c 100644
--- a/docs/source/core/data-structures/zend_string.rst
+++ b/docs/source/core/data-structures/zend_string.rst
@@ -29,9 +29,9 @@ in bytes, and the ``val`` field contains the actual string data.
 
 You may wonder why the ``val`` field is declared as ``char val[1]``. This is called the `struct
 hack`_ in C. It is used to create structs with a flexible size, namely by allowing the last element
-to be expanded arbitrarily. In this case, the size of ``zend_string`` depends on the strings length,
-which is determined at runtime (see ``_ZSTR_STRUCT_SIZE``). When allocating the string, we append
-enough bytes to the allocation to hold the strings content.
+to be expanded arbitrarily. In this case, the size of ``zend_string`` depends on the string's
+length, which is determined at runtime (see ``_ZSTR_STRUCT_SIZE``). When allocating the string, we
+append enough bytes to the allocation to hold the strings content.
 
 .. _struct hack: https://www.geeksforgeeks.org/struct-hack/
 
@@ -70,7 +70,7 @@ new strings.
    -  -  Function/Macro [#persistent]_
       -  Description
 
-   -  -  ``ZSTR_INIT(s, p)``
+   -  -  ``ZSTR_INIT_LITERAL(s, p)``
       -  Creates a new string from a string literal.
 
    -  -  ``zend_string_init(s, l, p)``
@@ -122,7 +122,7 @@ strings.
 
    -  -  ``ZSTR_HASH``
       -  ``Z_STRHASH[_P]``
-      -  Computes the string has if it hasn't already been, and returns it.
+      -  Computes the string hash if it hasn't already been, and returns it.
 
    -  -  ``ZSTR_H``
       -  \-
diff --git a/docs/source/miscellaneous/writing-tests.rst b/docs/source/miscellaneous/writing-tests.rst
index dae6c1d861ef..fb66db79e57c 100644
--- a/docs/source/miscellaneous/writing-tests.rst
+++ b/docs/source/miscellaneous/writing-tests.rst
@@ -237,7 +237,7 @@ and not in the INI section. This is because of the order in which settings are c
 
 If a TZ environmental variable is found the INI setting will be ignored.
 
-Tests that run, or only have have matching EXPECT output, on 32bit platforms can use a SKIPIF
+Tests that run, or only have matching EXPECT output, on 32bit platforms can use a SKIPIF
 section like:
 
 .. code:: php
diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c
index 63d9cd2a994e..0e0a9a23b94a 100644
--- a/ext/bcmath/bcmath.c
+++ b/ext/bcmath/bcmath.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Andi Gutmans                                   |
    +----------------------------------------------------------------------+
@@ -157,6 +155,16 @@ static zend_always_inline zend_result bcmath_check_scale(zend_long scale, uint32
 	return SUCCESS;
 }
 
+static zend_result bcmath_check_precision(zend_long precision, uint32_t arg_num)
+{
+	if (ZEND_LONG_INT_OVFL(precision)) {
+		zend_argument_value_error(arg_num, "must be between " ZEND_LONG_FMT " and %d",
+			(zend_long) ZEND_LONG_MIN, INT_MAX);
+		return FAILURE;
+	}
+	return SUCCESS;
+}
+
 static void php_long2num(bc_num *num, zend_long lval)
 {
 	*num = bc_long2num(lval);
@@ -195,7 +203,7 @@ static void bc_pow_err(bc_raise_status status, uint32_t arg_num)
 				zend_argument_value_error(arg_num, "exponent is too large, the number of digits overflowed");
 			}
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 }
 
@@ -573,7 +581,7 @@ PHP_FUNCTION(bcpowmod)
 		case OK:
 			RETVAL_NEW_STR(bc_num2str_ex(result, scale));
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	cleanup: {
@@ -797,6 +805,10 @@ PHP_FUNCTION(bcround)
 		Z_PARAM_ENUM(rounding_mode, rounding_mode_ce)
 	ZEND_PARSE_PARAMETERS_END();
 
+	if (bcmath_check_precision(precision, 2) == FAILURE) {
+		RETURN_THROWS();
+	}
+
 	switch (rounding_mode) {
 		case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
 		case ZEND_ENUM_RoundingMode_HalfTowardsZero:
@@ -877,10 +889,7 @@ static int bcmath_number_compare(zval *op1, zval *op2);
 #endif
 #define CHECK_SCALE_OVERFLOW(scale) (scale > INT_MAX)
 
-static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_obj(const zend_object *obj)
-{
-	return (bcmath_number_obj_t*)((char*)(obj) - XtOffsetOf(bcmath_number_obj_t, std));
-}
+#define get_bcmath_number_from_obj(obj) ZEND_CONTAINER_OF(obj, bcmath_number_obj_t, std)
 
 static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_zval(const zval *zv)
 {
@@ -1026,7 +1035,7 @@ static void bcmath_number_register_class(void)
 	bcmath_number_ce->default_object_handlers = &bcmath_number_obj_handlers;
 
 	memcpy(&bcmath_number_obj_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	bcmath_number_obj_handlers.offset = XtOffsetOf(bcmath_number_obj_t, std);
+	bcmath_number_obj_handlers.offset = offsetof(bcmath_number_obj_t, std);
 	bcmath_number_obj_handlers.free_obj = bcmath_number_free;
 	bcmath_number_obj_handlers.clone_obj = bcmath_number_clone;
 	bcmath_number_obj_handlers.do_operation = bcmath_number_do_operation;
@@ -1216,7 +1225,7 @@ static zend_result bc_num_from_obj_or_str_or_long(
 	bc_num *num, size_t *full_scale, const zend_object *obj, const zend_string *str, zend_long lval)
 {
 	if (obj) {
-		bcmath_number_obj_t *intern = get_bcmath_number_from_obj(obj);
+		const bcmath_number_obj_t *intern = get_bcmath_number_from_obj(obj);
 		*num = intern->num;
 		if (full_scale) {
 			*full_scale = intern->scale;
@@ -1306,7 +1315,7 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
 				goto fail;
 			}
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	if (Z_TYPE_P(op1) != IS_OBJECT) {
@@ -1492,7 +1501,7 @@ static void bcmath_number_calc_method(INTERNAL_FUNCTION_PARAMETERS, uint8_t opco
 				goto fail;
 			}
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	if (num_obj == NULL) {
@@ -1652,7 +1661,7 @@ PHP_METHOD(BcMath_Number, powmod)
 			goto cleanup;
 		case OK:
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	bc_rm_trailing_zeros(ret);
@@ -1799,6 +1808,10 @@ PHP_METHOD(BcMath_Number, round)
 		Z_PARAM_ENUM(rounding_mode, rounding_mode_ce);
 	ZEND_PARSE_PARAMETERS_END();
 
+	if (bcmath_check_precision(precision, 1) == FAILURE) {
+		RETURN_THROWS();
+	}
+
 	switch (rounding_mode) {
 		case ZEND_ENUM_RoundingMode_HalfAwayFromZero:
 		case ZEND_ENUM_RoundingMode_HalfTowardsZero:
diff --git a/ext/bcmath/libbcmath/src/convert.c b/ext/bcmath/libbcmath/src/convert.c
index ca5b84efde1b..772223220ef2 100644
--- a/ext/bcmath/libbcmath/src/convert.c
+++ b/ext/bcmath/libbcmath/src/convert.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/bcmath/libbcmath/src/convert.h b/ext/bcmath/libbcmath/src/convert.h
index 73c38cd13010..15af4216f853 100644
--- a/ext/bcmath/libbcmath/src/convert.h
+++ b/ext/bcmath/libbcmath/src/convert.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/bcmath/libbcmath/src/floor_or_ceil.c b/ext/bcmath/libbcmath/src/floor_or_ceil.c
index 98dc94601ac7..f2682951ab82 100644
--- a/ext/bcmath/libbcmath/src/floor_or_ceil.c
+++ b/ext/bcmath/libbcmath/src/floor_or_ceil.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Saki Takamachi                                |
    +----------------------------------------------------------------------+
diff --git a/ext/bcmath/libbcmath/src/long2num.c b/ext/bcmath/libbcmath/src/long2num.c
index 7645045b1fa3..494ec9e93564 100644
--- a/ext/bcmath/libbcmath/src/long2num.c
+++ b/ext/bcmath/libbcmath/src/long2num.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Saki Takamachi                                |
    +----------------------------------------------------------------------+
diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c
index ec0042a9f482..86cc7d085ec2 100644
--- a/ext/bcmath/libbcmath/src/round.c
+++ b/ext/bcmath/libbcmath/src/round.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Saki Takamachi                                |
    +----------------------------------------------------------------------+
@@ -69,12 +67,10 @@ size_t bc_round(bc_num num, zend_long precision, zend_enum_RoundingMode mode, bc
 			return 0;
 		}
 
-		/* If precision is -3, it becomes 1000. */
-		if (UNEXPECTED(precision == ZEND_LONG_MIN)) {
-			*result = bc_new_num((size_t) ZEND_LONG_MAX + 2, 0);
-		} else {
-			*result = bc_new_num(-precision + 1, 0);
-		}
+		/* If precision is -3, it becomes 1000. Negate in unsigned space so
+		 * precision == ZEND_LONG_MIN doesn't overflow signed long. */
+		zend_ulong magnitude = -(zend_ulong) precision;
+		*result = bc_new_num((size_t) magnitude + 1, 0);
 		(*result)->n_value[0] = 1;
 		(*result)->n_sign = num->n_sign;
 		return 0;
@@ -194,7 +190,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_enum_RoundingMode mode, bc
 			}
 			break;
 
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 
 up:
diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
index 11d71ae492ad..b6f3d736f8da 100644
--- a/ext/bcmath/libbcmath/src/str2num.c
+++ b/ext/bcmath/libbcmath/src/str2num.c
@@ -131,7 +131,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
 	const char *decimal_point = (*ptr == '.') ? ptr : NULL;
 
 	/* If a non-digit and non-decimal-point indicator is in the string, i.e. an invalid character */
-	if (UNEXPECTED(!decimal_point && *ptr != '\0')) {
+	if (UNEXPECTED(!decimal_point && ptr != end)) {
 		goto fail;
 	}
 
@@ -140,7 +140,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
 		/* search */
 		fractional_ptr = fractional_end = decimal_point + 1;
 		/* For strings that end with a decimal point, such as "012." */
-		if (UNEXPECTED(*fractional_ptr == '\0')) {
+		if (UNEXPECTED(fractional_ptr == end)) {
 			if (full_scale) {
 				*full_scale = 0;
 			}
@@ -149,7 +149,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
 
 		/* validate */
 		fractional_end = bc_count_digits(fractional_ptr, end);
-		if (UNEXPECTED(*fractional_end != '\0')) {
+		if (UNEXPECTED(fractional_end != end)) {
 			/* invalid num */
 			goto fail;
 		}
diff --git a/ext/bcmath/php_bcmath.h b/ext/bcmath/php_bcmath.h
index 83894fd7ca6b..334f7400c375 100644
--- a/ext/bcmath/php_bcmath.h
+++ b/ext/bcmath/php_bcmath.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Andi Gutmans                                   |
    +----------------------------------------------------------------------+
diff --git a/ext/bcmath/tests/bcround_precision_bounds.phpt b/ext/bcmath/tests/bcround_precision_bounds.phpt
new file mode 100644
index 000000000000..4c4f910476a7
--- /dev/null
+++ b/ext/bcmath/tests/bcround_precision_bounds.phpt
@@ -0,0 +1,28 @@
+--TEST--
+bcround() and BcMath\Number::round() reject $precision above INT_MAX
+--EXTENSIONS--
+bcmath
+--SKIPIF--
+
+--FILE--
+getMessage() . \PHP_EOL;
+}
+try {
+    (new BcMath\Number('1'))->round(PHP_INT_MAX);
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+try {
+    (new BcMath\Number('1'))->round(2147483648); // INT_MAX + 1
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+?>
+--EXPECTF--
+bcround(): Argument #2 ($precision) must be between %i and %d
+BcMath\Number::round(): Argument #1 ($precision) must be between %i and %d
+BcMath\Number::round(): Argument #1 ($precision) must be between %i and %d
diff --git a/ext/bcmath/tests/sec_embedded_null_truncation.phpt b/ext/bcmath/tests/sec_embedded_null_truncation.phpt
new file mode 100644
index 000000000000..157810ecbb3a
--- /dev/null
+++ b/ext/bcmath/tests/sec_embedded_null_truncation.phpt
@@ -0,0 +1,59 @@
+--TEST--
+bcmath strings with embedded null bytes must be rejected as not well-formed
+--EXTENSIONS--
+bcmath
+--FILE--
+ bcadd($s, "0"),
+    fn($s) => bcsub($s, "0"),
+    fn($s) => bcmul($s, "1"),
+    fn($s) => bcdiv($s, "1"),
+    fn($s) => bcmod($s, "7"),
+    fn($s) => bcpow($s, "1"),
+    fn($s) => bccomp($s, "0"),
+    fn($s) => bcsqrt($s),
+];
+
+foreach ($cases as $s) {
+    foreach ($calls as $fn) {
+        try {
+            $fn($s);
+            echo "FAIL: accepted\n";
+        } catch (\ValueError $e) {
+            echo $e->getMessage() . "\n";
+        }
+    }
+}
+?>
+--EXPECT--
+bcadd(): Argument #1 ($num1) is not well-formed
+bcsub(): Argument #1 ($num1) is not well-formed
+bcmul(): Argument #1 ($num1) is not well-formed
+bcdiv(): Argument #1 ($num1) is not well-formed
+bcmod(): Argument #1 ($num1) is not well-formed
+bcpow(): Argument #1 ($num) is not well-formed
+bccomp(): Argument #1 ($num1) is not well-formed
+bcsqrt(): Argument #1 ($num) is not well-formed
+bcadd(): Argument #1 ($num1) is not well-formed
+bcsub(): Argument #1 ($num1) is not well-formed
+bcmul(): Argument #1 ($num1) is not well-formed
+bcdiv(): Argument #1 ($num1) is not well-formed
+bcmod(): Argument #1 ($num1) is not well-formed
+bcpow(): Argument #1 ($num) is not well-formed
+bccomp(): Argument #1 ($num1) is not well-formed
+bcsqrt(): Argument #1 ($num) is not well-formed
+bcadd(): Argument #1 ($num1) is not well-formed
+bcsub(): Argument #1 ($num1) is not well-formed
+bcmul(): Argument #1 ($num1) is not well-formed
+bcdiv(): Argument #1 ($num1) is not well-formed
+bcmod(): Argument #1 ($num1) is not well-formed
+bcpow(): Argument #1 ($num) is not well-formed
+bccomp(): Argument #1 ($num1) is not well-formed
+bcsqrt(): Argument #1 ($num) is not well-formed
diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
index 91e694f58f46..6af8286c5335 100644
--- a/ext/bz2/bz2.c
+++ b/ext/bz2/bz2.c
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author: Sterling Hughes                            |
   +----------------------------------------------------------------------+
@@ -402,7 +400,7 @@ PHP_FUNCTION(bzopen)
 					RETURN_FALSE;
 				}
 				break;
-			EMPTY_SWITCH_DEFAULT_CASE();
+			default: ZEND_UNREACHABLE();
 		}
 
 		if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_FD, (void *) &fd, REPORT_ERRORS)) {
@@ -521,11 +519,15 @@ PHP_FUNCTION(bzdecompress)
 	bzs.bzalloc = NULL;
 	bzs.bzfree = NULL;
 
+	if (source_len > UINT_MAX) {
+		zend_argument_value_error(1, "must have a length less than or equal to %u", UINT_MAX);
+		RETURN_THROWS();
+	}
+
 	if (BZ2_bzDecompressInit(&bzs, 0, (int)small) != BZ_OK) {
 		RETURN_FALSE;
 	}
 
-	// TODO Check source string length fits in unsigned int
 	bzs.next_in = source;
 	bzs.avail_in = source_len;
 
@@ -542,7 +544,7 @@ PHP_FUNCTION(bzdecompress)
 			/* no reason to continue if we're going to drop it anyway */
 			break;
 		}
-		dest = zend_string_safe_realloc(dest, 1, bzs.avail_out+1, (size_t) size, 0);
+		dest = zend_string_safe_realloc(dest, 1, (size_t) bzs.avail_out + 1, (size_t) size, 0);
 		bzs.next_out = ZSTR_VAL(dest) + size;
 	}
 
@@ -594,10 +596,8 @@ static void php_bz2_error(INTERNAL_FUNCTION_PARAMETERS, int opt)
 	switch (opt) {
 		case PHP_BZ_ERRNO:
 			RETURN_LONG(errnum);
-			break;
 		case PHP_BZ_ERRSTR:
 			RETURN_STRING((char*)errstr);
-			break;
 		case PHP_BZ_ERRBOTH:
 			array_init(return_value);
 
diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c
index 27059391dacb..845c11865f15 100644
--- a/ext/bz2/bz2_filter.c
+++ b/ext/bz2/bz2_filter.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sara Golemon (pollita@php.net)                              |
    +----------------------------------------------------------------------+
@@ -23,7 +21,7 @@
 
 /* {{{ data structure */
 
-enum strm_status {
+C23_ENUM(strm_status, uint8_t) {
 	PHP_BZ2_UNINITIALIZED,
 	PHP_BZ2_RUNNING,
 	PHP_BZ2_FINISHED
@@ -36,12 +34,15 @@ typedef struct _php_bz2_filter_data {
 	size_t inbuf_len;
 	size_t outbuf_len;
 
-	enum strm_status status;              /* Decompress option */
-	unsigned int small_footprint : 1;     /* Decompress option */
-	unsigned int expect_concatenated : 1; /* Decompress option */
-	unsigned int is_flushed : 1;          /* only for compression */
+	bool persistent;
+	bool expect_concatenated : 1; /* Decompress option */
+	bool small_footprint : 1;     /* Decompress option */
+	bool is_flushed : 1;          /* only for compression */
+	strm_status status;           /* Decompress option */
 
-	int persistent;
+	/* Configuration for reset - immutable */
+	int blockSize100k;  /* compress only */
+	int workFactor;     /* compress only */
 } php_bz2_filter_data;
 
 /* }}} */
@@ -178,6 +179,36 @@ static php_stream_filter_status_t php_bz2_decompress_filter(
 	return exit_status;
 }
 
+static zend_result php_bz2_decompress_seek(
+	php_stream *stream,
+	php_stream_filter *thisfilter,
+	zend_off_t offset,
+	int whence
+	)
+{
+	if (!Z_PTR(thisfilter->abstract)) {
+		return FAILURE;
+	}
+
+	php_bz2_filter_data *data = Z_PTR(thisfilter->abstract);
+
+	/* End current decompression if running */
+	if (data->status == PHP_BZ2_RUNNING) {
+		BZ2_bzDecompressEnd(&(data->strm));
+	}
+
+	/* Reset stream state */
+	data->strm.next_in = data->inbuf;
+	data->strm.avail_in = 0;
+	data->strm.next_out = data->outbuf;
+	data->strm.avail_out = data->outbuf_len;
+	data->status = PHP_BZ2_UNINITIALIZED;
+
+	/* Note: We don't reinitialize here - it will be done on first use in the filter function */
+
+	return SUCCESS;
+}
+
 static void php_bz2_decompress_dtor(php_stream_filter *thisfilter)
 {
 	if (thisfilter && Z_PTR(thisfilter->abstract)) {
@@ -193,6 +224,7 @@ static void php_bz2_decompress_dtor(php_stream_filter *thisfilter)
 
 static const php_stream_filter_ops php_bz2_decompress_ops = {
 	php_bz2_decompress_filter,
+	php_bz2_decompress_seek,
 	php_bz2_decompress_dtor,
 	"bzip2.decompress"
 };
@@ -288,6 +320,41 @@ static php_stream_filter_status_t php_bz2_compress_filter(
 	return exit_status;
 }
 
+static zend_result php_bz2_compress_seek(
+	php_stream *stream,
+	php_stream_filter *thisfilter,
+	zend_off_t offset,
+	int whence
+	)
+{
+	int status;
+
+	if (!Z_PTR(thisfilter->abstract)) {
+		return FAILURE;
+	}
+
+	php_bz2_filter_data *data = Z_PTR(thisfilter->abstract);
+
+	/* End current compression */
+	BZ2_bzCompressEnd(&(data->strm));
+
+	/* Reset stream state */
+	data->strm.next_in = data->inbuf;
+	data->strm.avail_in = 0;
+	data->strm.next_out = data->outbuf;
+	data->strm.avail_out = data->outbuf_len;
+	data->is_flushed = 1;
+
+	/* Reinitialize compression with saved configuration */
+	status = BZ2_bzCompressInit(&(data->strm), data->blockSize100k, 0, data->workFactor);
+	if (status != BZ_OK) {
+		php_error_docref(NULL, E_WARNING, "bzip2.compress: failed to reset compression state");
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+
 static void php_bz2_compress_dtor(php_stream_filter *thisfilter)
 {
 	if (Z_PTR(thisfilter->abstract)) {
@@ -301,23 +368,15 @@ static void php_bz2_compress_dtor(php_stream_filter *thisfilter)
 
 static const php_stream_filter_ops php_bz2_compress_ops = {
 	php_bz2_compress_filter,
+	php_bz2_compress_seek,
 	php_bz2_compress_dtor,
 	"bzip2.compress"
 };
 
 /* }}} */
 
-/* {{{ bzip2.* common factory */
-
-static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, uint8_t persistent)
-{
-	const php_stream_filter_ops *fops = NULL;
-	php_bz2_filter_data *data;
-	int status = BZ_OK;
-
-	/* Create this filter */
-	data = pecalloc(1, sizeof(php_bz2_filter_data), persistent);
-
+static php_bz2_filter_data *php_bz2_filter_data_new(bool persistent) {
+	php_bz2_filter_data *data = pecalloc(1, sizeof(php_bz2_filter_data), persistent);
 	/* Circular reference */
 	data->strm.opaque = (void *) data;
 
@@ -328,82 +387,143 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
 	data->strm.next_in = data->inbuf = (char *) pemalloc(data->inbuf_len, persistent);
 	data->strm.avail_in = 0;
 	data->strm.next_out = data->outbuf = (char *) pemalloc(data->outbuf_len, persistent);
+	return data;
+}
 
-	if (strcasecmp(filtername, "bzip2.decompress") == 0) {
-		data->small_footprint = 0;
-		data->expect_concatenated = 0;
-
-		if (filterparams) {
-			zval *tmpzval = NULL;
+static php_stream_filter *php_bz2_decompress_filter_create(zval *filter_params, bool persistent) {
+	php_stream_filter_seekable_t write_seekable = PSFS_SEEKABLE_ALWAYS;
+	bool small_footprint = false;
+	bool expect_concatenated = false;
+
+	if (filter_params) {
+		if (UNEXPECTED(
+			Z_TYPE_P(filter_params) != IS_TRUE
+			&& Z_TYPE_P(filter_params) != IS_FALSE
+			&& Z_TYPE_P(filter_params) != IS_ARRAY
+			&& Z_TYPE_P(filter_params) != IS_OBJECT
+		)) {
+			php_error_docref(NULL, E_WARNING,
+				"Filter parameters for bzip2.decompress filter must be of type array|object|bool, %s given",
+				zend_zval_type_name(filter_params)
+			);
+			return NULL;
+		}
 
-			if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) {
-				HashTable *ht = HASH_OF(filterparams);
+		if (Z_TYPE_P(filter_params) == IS_TRUE || Z_TYPE_P(filter_params) == IS_FALSE) {
+			small_footprint = Z_TYPE_P(filter_params) == IS_TRUE;
+		} else {
+			ZEND_ASSERT(Z_TYPE_P(filter_params) == IS_ARRAY || Z_TYPE_P(filter_params) == IS_OBJECT);
 
-				if ((tmpzval = zend_hash_str_find_ind(ht, "concatenated", sizeof("concatenated")-1))) {
-					data->expect_concatenated = zend_is_true(tmpzval);
-					tmpzval = NULL;
-				}
+			const HashTable *filter_params_ht = HASH_OF(filter_params);
+			/* TODO: convert php_stream_filter_parse_write_seek_mode() to take HashTable */
+			if (php_stream_filter_parse_write_seek_mode(filter_params, &write_seekable) == FAILURE) {
+				return NULL;
+			}
 
-				tmpzval = zend_hash_str_find_ind(ht, "small", sizeof("small")-1);
-			} else {
-				tmpzval = filterparams;
+			const zval *concatenated = zend_hash_str_find_ind(filter_params_ht, ZEND_STRL("concatenated"));
+			if (concatenated) {
+				expect_concatenated = zend_is_true(concatenated);
 			}
 
-			if (tmpzval) {
-				data->small_footprint = zend_is_true(tmpzval);
+			const zval *small = zend_hash_str_find_ind(filter_params_ht, ZEND_STRL("small"));
+			if (small) {
+				small_footprint = zend_is_true(small);
 			}
 		}
+	}
 
-		data->status = PHP_BZ2_UNINITIALIZED;
-		fops = &php_bz2_decompress_ops;
-	} else if (strcasecmp(filtername, "bzip2.compress") == 0) {
-		int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE;
-		int workFactor = PHP_BZ2_FILTER_DEFAULT_WORKFACTOR;
-
-		if (filterparams) {
-			zval *tmpzval;
-
-			if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) {
-				HashTable *ht = HASH_OF(filterparams);
-
-				if ((tmpzval = zend_hash_str_find_ind(ht, "blocks", sizeof("blocks")-1))) {
-					/* How much memory to allocate (1 - 9) x 100kb */
-					zend_long blocks = zval_get_long(tmpzval);
-					if (blocks < 1 || blocks > 9) {
-						php_error_docref(NULL, E_WARNING, "Invalid parameter given for number of blocks to allocate (" ZEND_LONG_FMT ")", blocks);
-					} else {
-						blockSize100k = (int) blocks;
-					}
-				}
+	php_bz2_filter_data *data = php_bz2_filter_data_new(persistent);
+	/* Save configuration for reset */
+	data->small_footprint = small_footprint;
+	data->expect_concatenated = expect_concatenated;
+	data->status = PHP_BZ2_UNINITIALIZED;
 
-				if ((tmpzval = zend_hash_str_find_ind(ht, "work", sizeof("work")-1))) {
-					/* Work Factor (0 - 250) */
-					zend_long work = zval_get_long(tmpzval);
-					if (work < 0 || work > 250) {
-						php_error_docref(NULL, E_WARNING, "Invalid parameter given for work factor (" ZEND_LONG_FMT ")", work);
-					} else {
-						workFactor = (int) work;
-					}
-				}
+	return php_stream_filter_alloc(&php_bz2_decompress_ops, data, persistent, PSFS_SEEKABLE_START, write_seekable);
+}
+
+static php_stream_filter *php_bz2_compress_filter_create(zval *filter_params, bool persistent) {
+	php_stream_filter_seekable_t write_seekable = PSFS_SEEKABLE_ALWAYS;
+	int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE;
+	int workFactor = PHP_BZ2_FILTER_DEFAULT_WORKFACTOR;
+
+	if (filter_params) {
+		if (UNEXPECTED(Z_TYPE_P(filter_params) != IS_ARRAY && Z_TYPE_P(filter_params) != IS_OBJECT)) {
+			php_error_docref(NULL, E_WARNING,
+				"Filter parameters for bzip2.compress filter must be of type array|object, %s given",
+				zend_zval_type_name(filter_params)
+			);
+			return NULL;
+		}
+
+		const HashTable *filter_params_ht = HASH_OF(filter_params);
+		/* TODO: convert php_stream_filter_parse_write_seek_mode() to take HashTable */
+		if (php_stream_filter_parse_write_seek_mode(filter_params, &write_seekable) == FAILURE) {
+			return NULL;
+		}
+
+		const zval *blocks_zv = zend_hash_str_find_ind(filter_params_ht, ZEND_STRL("blocks"));
+		if (blocks_zv) {
+			ZEND_ASSERT(Z_TYPE_P(blocks_zv) != IS_INDIRECT);
+			bool failed = false;
+			/* How much memory to allocate (1 - 9) x 100kb */
+			zend_long blocks = zval_try_get_long(blocks_zv, &failed);
+			if (UNEXPECTED(failed)) {
+				php_error_docref(NULL, E_WARNING, "Number of blocks parameter must be of type int, %s given", zend_zval_type_name(blocks_zv));
+				return NULL;
+			} else if (blocks < 1 || blocks > 9) {
+				php_error_docref(NULL, E_WARNING, "Number of blocks to allocate must be between 1 and 9, " ZEND_LONG_FMT " given", blocks);
+				return NULL;
+			} else {
+				blockSize100k = (int) blocks;
 			}
 		}
 
-		status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
-		data->is_flushed = 1;
-		fops = &php_bz2_compress_ops;
-	} else {
-		status = BZ_DATA_ERROR;
+		const zval *work_zv = zend_hash_str_find_ind(filter_params_ht, ZEND_STRL("work"));
+		if (work_zv) {
+			ZEND_ASSERT(Z_TYPE_P(work_zv) != IS_INDIRECT);
+			bool failed = false;
+			/* Work Factor (0 - 250) */
+			zend_long work = zval_try_get_long(work_zv, &failed);
+			if (UNEXPECTED(failed)) {
+				php_error_docref(NULL, E_WARNING, "Work factor parameter must be of type int, %s given", zend_zval_type_name(work_zv));
+				return NULL;
+			} else if (work < 0 || work > 250) {
+				php_error_docref(NULL, E_WARNING, "Work factor must be between 0 and 250, " ZEND_LONG_FMT " given", work);
+				return NULL;
+			} else {
+				workFactor = (int) work;
+			}
+		}
 	}
 
-	if (status != BZ_OK) {
+	php_bz2_filter_data *data = php_bz2_filter_data_new(persistent);
+	/* Save configuration for reset */
+	data->blockSize100k = blockSize100k;
+	data->workFactor = workFactor;
+
+	int status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
+	if (UNEXPECTED(status != BZ_OK)) {
 		/* Unspecified (probably strm) error, let stream-filter error do its own whining */
 		pefree(data->strm.next_in, persistent);
 		pefree(data->strm.next_out, persistent);
 		pefree(data, persistent);
 		return NULL;
 	}
+	data->is_flushed = true;
 
-	return php_stream_filter_alloc(fops, data, persistent);
+	return php_stream_filter_alloc(&php_bz2_compress_ops, data, persistent, PSFS_SEEKABLE_START, write_seekable);
+}
+
+/* {{{ bzip2.* common factory */
+static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, bool persistent)
+{
+	if (strcasecmp(filtername, "bzip2.decompress") == 0) {
+		return php_bz2_decompress_filter_create(filterparams, persistent);
+	} else if (strcasecmp(filtername, "bzip2.compress") == 0) {
+		return php_bz2_compress_filter_create(filterparams, persistent);
+	} else {
+		return NULL;
+	}
 }
 
 const php_stream_filter_factory php_bz2_filter_factory = {
diff --git a/ext/bz2/php_bz2.h b/ext/bz2/php_bz2.h
index 8f1770f2808a..5da17d793059 100644
--- a/ext/bz2/php_bz2.h
+++ b/ext/bz2/php_bz2.h
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author: Sterling Hughes                            |
   +----------------------------------------------------------------------+
diff --git a/ext/bz2/tests/001.phpt b/ext/bz2/tests/001.phpt
index 767a50a27d8b..6323a224c3ac 100644
--- a/ext/bz2/tests/001.phpt
+++ b/ext/bz2/tests/001.phpt
@@ -48,6 +48,6 @@ bzopen(): Argument #2 ($mode) must be either "r" or "w"
 bzopen(): Argument #2 ($mode) must be either "r" or "w"
 bzopen(): Argument #2 ($mode) must be either "r" or "w"
 
-Warning: bzopen(no_such_file): Failed to open stream: No such file or directory in %s on line %d
+Warning: bzopen(): Failed to open stream: No such file or directory in %s on line %d
 bool(false)
 resource(%d) of type (stream)
diff --git a/ext/bz2/tests/002.phpt b/ext/bz2/tests/002.phpt
index f87048f92314..7210f90a4d92 100644
--- a/ext/bz2/tests/002.phpt
+++ b/ext/bz2/tests/002.phpt
@@ -90,10 +90,10 @@ bool(false)
 resource(%d) of type (stream)
 resource(%d) of type (stream)
 
-Warning: fopen(bz_open_002.txt): Failed to open stream: `br' is not a valid mode for fopen in %s on line %d
+Warning: fopen(): Failed to open stream: `br' is not a valid mode for fopen in %s on line %d
 bzopen(): Argument #1 ($file) must be of type string or file-resource, false given
 
-Warning: fopen(bz_open_002.txt): Failed to open stream: `br' is not a valid mode for fopen in %s on line %d
+Warning: fopen(): Failed to open stream: `br' is not a valid mode for fopen in %s on line %d
 bzopen(): Argument #1 ($file) must be of type string or file-resource, false given
 
 Warning: bzopen(): cannot write to a stream opened in read only mode in %s on line %d
diff --git a/ext/bz2/tests/bug72447.phpt b/ext/bz2/tests/bug72447.phpt
index 11f3bd9136b5..8e2fc2b79802 100644
--- a/ext/bz2/tests/bug72447.phpt
+++ b/ext/bz2/tests/bug72447.phpt
@@ -16,4 +16,6 @@ fclose($fp);
 unlink('testfile');
 ?>
 --EXPECTF--
-Warning: stream_filter_append(): Invalid parameter given for number of blocks to allocate (0) in %s%ebug72447.php on line %d
+Warning: stream_filter_append(): Number of blocks parameter must be of type int, string given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
diff --git a/ext/bz2/tests/bz2_filter_compress_errors.phpt b/ext/bz2/tests/bz2_filter_compress_errors.phpt
new file mode 100644
index 000000000000..48f6759d642b
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_compress_errors.phpt
@@ -0,0 +1,67 @@
+--TEST--
+bzip2.compress filter param errors
+--EXTENSIONS--
+bz2
+--FILE--
+ 'not an int'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+$param = ['blocks' => '15'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+$param = ['blocks' => '0'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+$param = ['work' => 'not an int'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+$param = ['work' => '251'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+$param = ['work' => '-1'];
+var_dump(stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param));
+
+fclose($fp);
+
+?>
+--EXPECTF--
+Warning: stream_filter_append(): Filter parameters for bzip2.compress filter must be of type array|object, string given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Number of blocks parameter must be of type int, string given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Number of blocks to allocate must be between 1 and 9, 15 given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Number of blocks to allocate must be between 1 and 9, 0 given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Work factor parameter must be of type int, string given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Work factor must be between 0 and 250, 251 given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
+
+Warning: stream_filter_append(): Work factor must be between 0 and 250, -1 given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s on line %d
+bool(false)
diff --git a/ext/bz2/tests/bz2_filter_decompress_errors.phpt b/ext/bz2/tests/bz2_filter_decompress_errors.phpt
new file mode 100644
index 000000000000..f89029bd50c3
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_decompress_errors.phpt
@@ -0,0 +1,19 @@
+--TEST--
+bzip2.decompress filter param errors
+--EXTENSIONS--
+bz2
+--FILE--
+
+--EXPECTF--
+Warning: stream_filter_append(): Filter parameters for bzip2.decompress filter must be of type array|object|bool, string given in %s on line %d
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.decompress" in %s on line %d
+bool(false)
diff --git a/ext/bz2/tests/bz2_filter_seek_compress.phpt b/ext/bz2/tests/bz2_filter_seek_compress.phpt
new file mode 100644
index 000000000000..557021c9fd0d
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_seek_compress.phpt
@@ -0,0 +1,51 @@
+--TEST--
+bzip2.compress write filter is not reset on seek
+--EXTENSIONS--
+bz2
+--FILE--
+
+--CLEAN--
+
+--EXPECTF--
+Size after write: %d
+Seek to start: SUCCESS
+Seek to middle: SUCCESS
+Decompressed content matches: YES
diff --git a/ext/bz2/tests/bz2_filter_seek_decompress.phpt b/ext/bz2/tests/bz2_filter_seek_decompress.phpt
new file mode 100644
index 000000000000..8ccd224b1a40
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_seek_decompress.phpt
@@ -0,0 +1,43 @@
+--TEST--
+bzip2.decompress filter with seek to start
+--EXTENSIONS--
+bz2
+--FILE--
+
+--CLEAN--
+
+--EXPECTF--
+First read (20 bytes): I am the very model 
+Seek to start: SUCCESS
+Content after seek matches: YES
+
+Warning: fseek(): Stream filter bzip2.decompress is seekable only to start position in %s on line %d
+Seek to middle: FAILURE
diff --git a/ext/bz2/tests/bz2_filter_unknown_errors.phpt b/ext/bz2/tests/bz2_filter_unknown_errors.phpt
new file mode 100644
index 000000000000..7364481185a5
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_unknown_errors.phpt
@@ -0,0 +1,16 @@
+--TEST--
+bzip2 filter error on unknown filter name
+--EXTENSIONS--
+bz2
+--FILE--
+
+--EXPECTF--
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.i_dont_exist" in %s on line %d
+bool(false)
diff --git a/ext/bz2/tests/bz2_filter_write_seek_modes.phpt b/ext/bz2/tests/bz2_filter_write_seek_modes.phpt
new file mode 100644
index 000000000000..b3b4fa39eb16
--- /dev/null
+++ b/ext/bz2/tests/bz2_filter_write_seek_modes.phpt
@@ -0,0 +1,54 @@
+--TEST--
+bzip2.compress write filter: write_seek_mode parameter
+--EXTENSIONS--
+bz2
+--FILE--
+ 'reset']);
+fwrite($fp, $text1);
+ftruncate($fp, 0);
+var_dump(fseek($fp, 0, SEEK_SET) === 0);
+fwrite($fp, $text2);
+fclose($fp);
+
+$fp = fopen($file, 'r');
+stream_filter_append($fp, 'bzip2.decompress', STREAM_FILTER_READ);
+$decoded = stream_get_contents($fp);
+fclose($fp);
+var_dump($decoded === $text2);
+
+/* "strict" */
+$fp = fopen($file, 'w+');
+stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE,
+    ['write_seek_mode' => 'strict']);
+fwrite($fp, $text1);
+var_dump(@fseek($fp, 0, SEEK_SET) === -1);
+fclose($fp);
+
+/* Invalid mode: ValueError */
+$fp = fopen($file, 'w+');
+stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE,
+    ['write_seek_mode' => 'nope']);
+fclose($fp);
+
+?>
+--CLEAN--
+
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+
+Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s
+
+Warning: stream_filter_append(): Unable to create or locate filter "bzip2.compress" in %s
diff --git a/ext/bz2/tests/bzdecompress_input_too_large.phpt b/ext/bz2/tests/bzdecompress_input_too_large.phpt
new file mode 100644
index 000000000000..9774c6dbbfd6
--- /dev/null
+++ b/ext/bz2/tests/bzdecompress_input_too_large.phpt
@@ -0,0 +1,26 @@
+--TEST--
+bzdecompress() rejects input larger than 4294967296
+--EXTENSIONS--
+bz2
+--INI--
+memory_limit=8G
+--SKIPIF--
+
+--CONFLICTS--
+all
+--FILE--
+getMessage(), "\n";
+}
+?>
+--EXPECT--
+bzdecompress(): Argument #1 ($data) must have a length less than or equal to 4294967295
diff --git a/ext/bz2/tests/gh20620.phpt b/ext/bz2/tests/gh20620.phpt
index a7ab0a3c843f..bea0133549ff 100644
--- a/ext/bz2/tests/gh20620.phpt
+++ b/ext/bz2/tests/gh20620.phpt
@@ -8,6 +8,8 @@ if (!getenv('RUN_RESOURCE_HEAVY_TESTS')) die('skip resource-heavy test');
 if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only'); 
 if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request');
 ?>
+--CONFLICTS--
+all
 --INI--
 memory_limit=-1
 --FILE--
diff --git a/ext/calendar/cal_unix.c b/ext/calendar/cal_unix.c
index 915da1c326ae..983857c553d9 100644
--- a/ext/calendar/cal_unix.c
+++ b/ext/calendar/cal_unix.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Shane Caraveo                            |
    |          Colin Viebrock                           |
diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c
index b90e461da49c..f26d611092db 100644
--- a/ext/calendar/calendar.c
+++ b/ext/calendar/calendar.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Shane Caraveo                            |
    |          Colin Viebrock                           |
@@ -574,14 +572,11 @@ PHP_FUNCTION(jddayofweek)
 	switch (mode) {
 	case CAL_DOW_LONG:
 		RETURN_STRING(daynamel);
-		break;
 	case CAL_DOW_SHORT:
 		RETURN_STRING(daynames);
-		break;
 	case CAL_DOW_DAYNO:
 	default:
 		RETURN_LONG(day);
-		break;
 	}
 }
 /* }}} */
diff --git a/ext/calendar/easter.c b/ext/calendar/easter.c
index 7fd8c0b33bb3..198ea7625a1a 100644
--- a/ext/calendar/easter.c
+++ b/ext/calendar/easter.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Shane Caraveo                            |
    |          Colin Viebrock                           |
diff --git a/ext/calendar/gregor.c b/ext/calendar/gregor.c
index 3aef7ae6ac50..eaee9c8c73c7 100644
--- a/ext/calendar/gregor.c
+++ b/ext/calendar/gregor.c
@@ -209,6 +209,7 @@ zend_long GregorianToSdn(
 
 	/* check for invalid dates */
 	if (inputYear == 0 || inputYear < -4714 ||
+		inputYear > INT_MAX - 4800 ||
 		inputMonth <= 0 || inputMonth > 12 ||
 		inputDay <= 0 || inputDay > 31) {
 		return (0);
diff --git a/ext/calendar/jewish.c b/ext/calendar/jewish.c
index 19b87316eb14..b589c4cb2617 100644
--- a/ext/calendar/jewish.c
+++ b/ext/calendar/jewish.c
@@ -710,7 +710,7 @@ zend_long JewishToSdn(
 	int yearLength;
 	int lengthOfAdarIAndII;
 
-	if (year <= 0 || year >= 6000 || day <= 0 || day > 30) {
+	if (year <= 0 || year >= INT_MAX - 1 || day <= 0 || day > 30) {
 		return (0);
 	}
 	switch (month) {
diff --git a/ext/calendar/julian.c b/ext/calendar/julian.c
index baff0771532e..c24527941d3e 100644
--- a/ext/calendar/julian.c
+++ b/ext/calendar/julian.c
@@ -222,6 +222,7 @@ zend_long JulianToSdn(
 
 	/* check for invalid dates */
 	if (inputYear == 0 || inputYear < -4713 ||
+		inputYear > INT_MAX - 4800 ||
 		inputMonth <= 0 || inputMonth > 12 ||
 		inputDay <= 0 || inputDay > 31) {
 		return (0);
diff --git a/ext/calendar/php_calendar.h b/ext/calendar/php_calendar.h
index 38127eb80e24..eee8fbbb6bb3 100644
--- a/ext/calendar/php_calendar.h
+++ b/ext/calendar/php_calendar.h
@@ -1,3 +1,15 @@
+/*
+   +----------------------------------------------------------------------+
+   | Copyright © The PHP Group and Contributors.                          |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
+   +----------------------------------------------------------------------+
+ */
+
 #ifndef PHP_CALENDAR_H
 #define PHP_CALENDAR_H
 
diff --git a/ext/calendar/tests/gh21557.phpt b/ext/calendar/tests/gh21557.phpt
new file mode 100644
index 000000000000..1aa5e65cb342
--- /dev/null
+++ b/ext/calendar/tests/gh21557.phpt
@@ -0,0 +1,24 @@
+--TEST--
+GH-21557 jewishtojd returns 0 for years >= 6000
+--CREDITS--
+oleibman
+--EXTENSIONS--
+calendar
+--FILE--
+
+--EXPECT--
+yh=5995 rh=2537279
+yh=5996 rh=2537633
+yh=5997 rh=2538016
+yh=5998 rh=2538371
+yh=5999 rh=2538725
+yh=6000 rh=2539110
+yh=6001 rh=2539463
+yh=6002 rh=2539818
+yh=6003 rh=2540202
+yh=6004 rh=2540557
diff --git a/ext/calendar/tests/gh22602.phpt b/ext/calendar/tests/gh22602.phpt
new file mode 100644
index 000000000000..d165a0174094
--- /dev/null
+++ b/ext/calendar/tests/gh22602.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug GH-22602: (gregoriantojd() and juliantojd() integer overflow with INT_MAX year)
+--EXTENSIONS--
+calendar
+--FILE--
+ 2147483647 ? 2147483647 : PHP_INT_MAX;
+$min = PHP_INT_MAX > 2147483647 ? -2147483648 : PHP_INT_MIN;
+
+var_dump(gregoriantojd(5, 5, $max));
+var_dump(gregoriantojd(5, 5, $min));
+var_dump(juliantojd(5, 5, 2147483647));
+var_dump(juliantojd(5, 5, -2147483647));
+
+?>
+--EXPECT--
+int(0)
+int(0)
+int(0)
+int(0)
diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c
index 1b8c8a082a05..63fc8f6563b2 100644
--- a/ext/com_dotnet/com_com.c
+++ b/ext/com_dotnet/com_com.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -19,8 +17,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
@@ -324,7 +320,7 @@ PHP_FUNCTION(com_get_active_object)
 		IDispatch_Release(obj);
 	}
 	if (unk) {
-		IUnknown_Release(obj);
+		IUnknown_Release(unk);
 	}
 	efree(module);
 }
diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c
index f8b4a828e154..d96aa0f1b120 100644
--- a/ext/com_dotnet/com_dotnet.c
+++ b/ext/com_dotnet/com_dotnet.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -18,11 +16,9 @@
 #include 
 #endif
 
-#include "php.h"
+# include "php.h"
 
 #ifdef HAVE_MSCOREE_H
-# include "php_ini.h"
-# include "ext/standard/info.h"
 # include "php_com_dotnet.h"
 # include "php_com_dotnet_internal.h"
 # include "Zend/zend_exceptions.h"
@@ -127,7 +123,6 @@ static HRESULT dotnet_bind_runtime(LPVOID FAR *ppv)
 	typedef HRESULT (STDAPICALLTYPE *cbtr_t)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
 	cbtr_t CorBindToRuntime;
 	OLECHAR *oleversion;
-	char *version;
 
 	mscoree = LoadLibraryA("mscoree.dll");
 	if (mscoree == NULL) {
@@ -140,11 +135,11 @@ static HRESULT dotnet_bind_runtime(LPVOID FAR *ppv)
 		return S_FALSE;
 	}
 
-	version = INI_STR("com.dotnet_version");
-	if (version == NULL || *version == '\0') {
+	const zend_string *version = zend_ini_str_literal("com.dotnet_version");
+	if (version == NULL || ZSTR_LEN(version) == 0) {
 		oleversion = NULL;
 	} else {
-		oleversion = php_com_string_to_olestring(version, strlen(version), COMG(code_page));
+		oleversion = php_com_string_to_olestring(ZSTR_VAL(version), ZSTR_LEN(version), COMG(code_page));
 	}
 
 	hr = CorBindToRuntime(oleversion, NULL, &CLSID_CorRuntimeHost, &IID_ICorRuntimeHost, ppv);
diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c
index df8314fa7613..e9c6e46884ce 100644
--- a/ext/com_dotnet/com_extension.c
+++ b/ext/com_dotnet/com_extension.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -118,11 +116,11 @@ static PHP_INI_MH(OnTypeLibFileUpdate)
 		}
 
 		/* Remove leading/training white spaces on search_string */
-		while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
+		while (isspace((unsigned char)*typelib_name)) {/* Ends on '\0' in worst case */
 			typelib_name ++;
 		}
 		ptr = typelib_name + strlen(typelib_name) - 1;
-		while ((ptr != typelib_name) && isspace(*ptr)) {
+		while ((ptr != typelib_name) && isspace((unsigned char)*ptr)) {
 			*ptr = '\0';
 			ptr--;
 		}
diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c
index 638fc5d8a3ae..e4b187b3c98d 100644
--- a/ext/com_dotnet/com_handlers.c
+++ b/ext/com_dotnet/com_handlers.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -19,8 +17,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
@@ -513,7 +509,7 @@ zend_object_handlers php_com_object_handlers = {
 	0,
 	php_com_object_free_storage,
 	zend_objects_destroy_object,
-	php_com_object_clone,
+	NULL, /* clone */
 	NULL, /* clone_with */
 	com_property_read,
 	com_property_write,
@@ -591,30 +587,6 @@ void php_com_object_free_storage(zend_object *object)
 	zend_object_std_dtor(object);
 }
 
-zend_object* php_com_object_clone(zend_object *object)
-{
-	php_com_dotnet_object *cloneobj, *origobject;
-
-	origobject = (php_com_dotnet_object*) object;
-	cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object));
-
-	memcpy(cloneobj, origobject, sizeof(*cloneobj));
-
-	/* VariantCopy will perform VariantClear; we don't want to clobber
-	 * the IDispatch that we memcpy'd, so we init a new variant in the
-	 * clone structure */
-	VariantInit(&cloneobj->v);
-	/* We use the Indirection-following version of the API since we
-	 * want to clone as much as possible */
-	VariantCopyInd(&cloneobj->v, &origobject->v);
-
-	if (cloneobj->typeinfo) {
-		ITypeInfo_AddRef(cloneobj->typeinfo);
-	}
-
-	return (zend_object*)cloneobj;
-}
-
 zend_object* php_com_object_new(zend_class_entry *ce)
 {
 	php_com_dotnet_object *obj;
diff --git a/ext/com_dotnet/com_iterator.c b/ext/com_dotnet/com_iterator.c
index 931e4a9afdd0..ee8f65c12c1a 100644
--- a/ext/com_dotnet/com_iterator.c
+++ b/ext/com_dotnet/com_iterator.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -19,8 +17,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c
index 6c80bd2b9e24..2cca9f11ca3c 100644
--- a/ext/com_dotnet/com_misc.c
+++ b/ext/com_dotnet/com_misc.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -19,8 +17,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
diff --git a/ext/com_dotnet/com_olechar.c b/ext/com_dotnet/com_olechar.c
index d04f8b18c623..c4c7ca7a6a71 100644
--- a/ext/com_dotnet/com_olechar.c
+++ b/ext/com_dotnet/com_olechar.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Harald Radi                                   |
@@ -20,8 +18,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 
diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c
index 1b89aea15e23..916a8b05f139 100644
--- a/ext/com_dotnet/com_persist.c
+++ b/ext/com_dotnet/com_persist.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -27,8 +25,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c
index ec79faa30a32..7cfdef4885f6 100644
--- a/ext/com_dotnet/com_saproxy.c
+++ b/ext/com_dotnet/com_saproxy.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -26,8 +24,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 #include "Zend/zend_exceptions.h"
diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c
index 28306b5609b0..f80075c050ac 100644
--- a/ext/com_dotnet/com_typeinfo.c
+++ b/ext/com_dotnet/com_typeinfo.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Harald Radi                                   |
@@ -20,8 +18,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 
diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c
index 7e63d66b3d3a..82f17d12d9b5 100644
--- a/ext/com_dotnet/com_variant.c
+++ b/ext/com_dotnet/com_variant.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -19,8 +17,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 
diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c
index 3d05e17affae..175a2de33074 100644
--- a/ext/com_dotnet/com_wrapper.c
+++ b/ext/com_dotnet/com_wrapper.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -22,8 +20,6 @@
 #endif
 
 #include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 
diff --git a/ext/com_dotnet/php_com_dotnet.h b/ext/com_dotnet/php_com_dotnet.h
index 556c477799ea..51e24b3e5d2a 100644
--- a/ext/com_dotnet/php_com_dotnet.h
+++ b/ext/com_dotnet/php_com_dotnet.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h
index 09fe49439347..c7e065c24872 100644
--- a/ext/com_dotnet/php_com_dotnet_internal.h
+++ b/ext/com_dotnet/php_com_dotnet_internal.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    +----------------------------------------------------------------------+
@@ -68,7 +66,6 @@ extern zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_e
 
 /* com_handlers.c */
 zend_object* php_com_object_new(zend_class_entry *ce);
-zend_object* php_com_object_clone(zend_object *object);
 void php_com_object_free_storage(zend_object *object);
 extern zend_object_handlers php_com_object_handlers;
 void php_com_object_enable_event_sink(php_com_dotnet_object *obj, bool enable);
@@ -117,9 +114,11 @@ PHP_COM_DOTNET_API zend_result php_com_zval_from_variant(zval *z, VARIANT *v, in
 PHP_COM_DOTNET_API zend_result php_com_copy_variant(VARIANT *dst, VARIANT *src);
 
 /* com_dotnet.c */
+#ifdef HAVE_MSCOREE_H
 PHP_METHOD(dotnet, __construct);
 void php_com_dotnet_rshutdown(void);
 void php_com_dotnet_mshutdown(void);
+#endif
 
 /* com_misc.c */
 void php_com_throw_exception(HRESULT code, char *message);
diff --git a/ext/com_dotnet/tests/bug77177.phpt b/ext/com_dotnet/tests/bug77177.phpt
index 3395f4ed810d..cba12980ad97 100644
--- a/ext/com_dotnet/tests/bug77177.phpt
+++ b/ext/com_dotnet/tests/bug77177.phpt
@@ -2,16 +2,11 @@
 Bug #77177 (Serializing or unserializing COM objects crashes)
 --EXTENSIONS--
 com_dotnet
---SKIPIF--
-
 --FILE--
 
---EXPECTF--
+--EXPECT--
 Exception: Serialization of 'com' is not allowed
-Exception: Serialization of 'dotnet' is not allowed
 Exception: Serialization of 'variant' is not allowed
 Exception: Unserialization of 'com' is not allowed
-Exception: Unserialization of 'dotnet' is not allowed
 Exception: Unserialization of 'variant' is not allowed
 Exception: Unserialization of 'com' is not allowed
-Exception: Unserialization of 'dotnet' is not allowed
 Exception: Unserialization of 'variant' is not allowed
diff --git a/ext/com_dotnet/tests/bug77177_dotnet.phpt b/ext/com_dotnet/tests/bug77177_dotnet.phpt
new file mode 100644
index 000000000000..d80c180ae772
--- /dev/null
+++ b/ext/com_dotnet/tests/bug77177_dotnet.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #77177 (Serializing or unserializing COM objects crashes, dotnet class)
+--EXTENSIONS--
+com_dotnet
+--SKIPIF--
+
+--FILE--
+getMessage()}\n";
+}
+
+try {
+    unserialize('C:6:"dotnet":0:{}');
+} catch (Exception $ex) {
+    echo "Exception: {$ex->getMessage()}\n";
+}
+
+try {
+    unserialize('O:6:"dotnet":0:{}');
+} catch (Exception $ex) {
+    echo "Exception: {$ex->getMessage()}\n";
+}
+?>
+--EXPECT--
+Exception: Serialization of 'dotnet' is not allowed
+Exception: Unserialization of 'dotnet' is not allowed
+Exception: Unserialization of 'dotnet' is not allowed
diff --git a/ext/com_dotnet/tests/comtest/comtest.cpp b/ext/com_dotnet/tests/comtest/comtest.cpp
index a4f91d3121e4..9f6c8c3e466f 100644
--- a/ext/com_dotnet/tests/comtest/comtest.cpp
+++ b/ext/com_dotnet/tests/comtest/comtest.cpp
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Christoph M. Becker                             |
    | Based on:                           |
diff --git a/ext/com_dotnet/tests/sa_proxy_errors.phpt b/ext/com_dotnet/tests/sa_proxy_errors.phpt
new file mode 100644
index 000000000000..99acb0c01521
--- /dev/null
+++ b/ext/com_dotnet/tests/sa_proxy_errors.phpt
@@ -0,0 +1,60 @@
+--TEST--
+com_safearray_proxy errors
+--EXTENSIONS--
+com_dotnet
+--FILE--
+hello));
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+    var_dump($v->hello);
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+    $v->hello = 'blah';
+    var_dump($v);
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+    unset($v->hello);
+    var_dump($v);
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+    $c = clone $v;
+    var_dump($c);
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+try {
+    $s = serialize($v);
+    var_dump($s);
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+object(variant)#1 (0) {
+}
+bool(false)
+com_exception: this variant has no properties
+com_exception: this variant has no properties
+Error: Cannot delete properties from a COM object
+Error: Trying to clone an uncloneable object of class variant
+Exception: Serialization of 'variant' is not allowed
diff --git a/ext/com_dotnet/tests/variant_no_clone.phpt b/ext/com_dotnet/tests/variant_no_clone.phpt
new file mode 100644
index 000000000000..93d49235ed4e
--- /dev/null
+++ b/ext/com_dotnet/tests/variant_no_clone.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Prevent cloning of Variant types as it's broken
+--EXTENSIONS--
+com_dotnet
+--FILE--
+getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+Error: Trying to clone an uncloneable object of class variant
diff --git a/ext/com_dotnet/tests/variants.phpt b/ext/com_dotnet/tests/variants.phpt
index 8547e65efb33..a145fec87ae2 100644
--- a/ext/com_dotnet/tests/variants.phpt
+++ b/ext/com_dotnet/tests/variants.phpt
@@ -43,7 +43,7 @@ foreach ($values as $t => $val) {
 
 echo "OK!";
 ?>
---EXPECT--
+--EXPECTF--
 --
 add: 84
 cat: 4242
@@ -142,8 +142,8 @@ mul: 0
 and: 0
 div:
 	variant_div(42, )
-	exception Division by zero
-	code 80020012
+	exception %s
+	code 800200%x
 
 eqv: -43
 idiv:
@@ -258,8 +258,8 @@ mul: 0
 and: 0
 div:
 	variant_div(3.5, )
-	exception Division by zero
-	code 80020012
+	exception %s
+	code 800200%x
 
 eqv: -5
 idiv:
diff --git a/ext/ctype/ctype.c b/ext/ctype/ctype.c
index b4835019602e..792c5c6679c4 100644
--- a/ext/ctype/ctype.c
+++ b/ext/ctype/ctype.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Hartmut Holzgraefe                         |
    +----------------------------------------------------------------------+
diff --git a/ext/ctype/php_ctype.h b/ext/ctype/php_ctype.h
index 1596514184c0..c0a1337aa7db 100644
--- a/ext/ctype/php_ctype.h
+++ b/ext/ctype/php_ctype.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Hartmut Holzgraefe                         |
    +----------------------------------------------------------------------+
diff --git a/ext/curl/config.w32 b/ext/curl/config.w32
index a4bdce59ccb1..567699f3b748 100644
--- a/ext/curl/config.w32
+++ b/ext/curl/config.w32
@@ -14,6 +14,16 @@ if (PHP_CURL != "no") {
 		 CHECK_LIB("libssh2.lib", "curl", PHP_CURL) &&
 		 CHECK_LIB("nghttp2.lib", "curl", PHP_CURL))
 		) {
+		if (!(CHECK_HEADER("brotli/decode.h", "CFLAGS_CURL") &&
+			CHECK_LIB("brotlidec.lib;brotlidec-static.lib", "curl", PHP_CURL) &&
+			CHECK_LIB("brotlicommon.lib;brotlicommon-static.lib", "curl", PHP_CURL)
+		)) {
+			WARNING("brotli in curl not enabled; libraries or headers not found");
+		}
+		if (!(CHECK_LIB("libzstd.lib;libzstd_a.lib", "curl", PHP_CURL)
+		)) {
+			WARNING("zstd in curl not enabled; library not found");
+		}
 		EXTENSION("curl", "interface.c multi.c share.c curl_file.c");
 		AC_DEFINE('HAVE_CURL', 1, "Define to 1 if the PHP extension 'curl' is available.");
 		ADD_FLAG("CFLAGS_CURL", "/D PHP_CURL_EXPORTS=1");
diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php
index aadab8cb0b0d..70e87cc9b146 100644
--- a/ext/curl/curl.stub.php
+++ b/ext/curl/curl.stub.php
@@ -343,6 +343,11 @@
  * @cvalue CURLOPT_RETURNTRANSFER
  */
 const CURLOPT_RETURNTRANSFER = UNKNOWN;
+/**
+ * @var int
+ * @cvalue CURLOPT_SEEKFUNCTION
+ */
+const CURLOPT_SEEKFUNCTION = UNKNOWN;
 /**
  * @var int
  * @cvalue CURLOPT_SHARE
@@ -1788,6 +1793,21 @@
  * @cvalue CURL_READFUNC_PAUSE
  */
 const CURL_READFUNC_PAUSE = UNKNOWN;
+/**
+ * @var int
+ * @cvalue CURL_SEEKFUNC_OK
+ */
+const CURL_SEEKFUNC_OK = UNKNOWN;
+/**
+ * @var int
+ * @cvalue CURL_SEEKFUNC_FAIL
+ */
+const CURL_SEEKFUNC_FAIL = UNKNOWN;
+/**
+ * @var int
+ * @cvalue CURL_SEEKFUNC_CANTSEEK
+ */
+const CURL_SEEKFUNC_CANTSEEK = UNKNOWN;
 /**
  * @var int
  * @cvalue CURL_WRITEFUNC_PAUSE
@@ -3117,6 +3137,13 @@
  */
 const CURLINFO_CONN_ID = UNKNOWN;
 #endif
+#if LIBCURL_VERSION_NUM >= 0x081400 /* Available since 8.20.0 */
+/**
+ * @var int
+ * @cvalue CURLINFO_SIZE_DELIVERED
+ */
+const CURLINFO_SIZE_DELIVERED = UNKNOWN;
+#endif
 /**
  * @var int
  * @cvalue CURLOPT_DISALLOW_USERNAME_IN_URL
diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h
index 6fb17ed029e3..f2929f60c4e2 100644
--- a/ext/curl/curl_arginfo.h
+++ b/ext/curl/curl_arginfo.h
@@ -1,5 +1,5 @@
 /* This is a generated file, edit curl.stub.php instead.
- * Stub hash: 10ebdc94560ed19ecd6b61a11b3dab5d32989d66 */
+ * Stub hash: d55adb230c533f4dde05e95759477dd9e1dd6efb */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0)
 	ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0)
@@ -294,6 +294,7 @@ static void register_curl_symbols(int module_number)
 	REGISTER_LONG_CONSTANT("CURLOPT_REFERER", CURLOPT_REFERER, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_RETURNTRANSFER", CURLOPT_RETURNTRANSFER, CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_SHARE", CURLOPT_SHARE, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_SSLCERT", CURLOPT_SSLCERT, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD, CONST_PERSISTENT);
@@ -574,6 +575,9 @@ static void register_curl_symbols(int module_number)
 	REGISTER_LONG_CONSTANT("CURLPAUSE_SEND", CURLPAUSE_SEND, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLPAUSE_SEND_CONT", CURLPAUSE_SEND_CONT, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURL_READFUNC_PAUSE", CURL_READFUNC_PAUSE, CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("CURL_SEEKFUNC_OK", CURL_SEEKFUNC_OK, CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("CURL_SEEKFUNC_FAIL", CURL_SEEKFUNC_FAIL, CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("CURL_SEEKFUNC_CANTSEEK", CURL_SEEKFUNC_CANTSEEK, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURL_WRITEFUNC_PAUSE", CURL_WRITEFUNC_PAUSE, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLPROXY_SOCKS4A", CURLPROXY_SOCKS4A, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLPROXY_SOCKS5_HOSTNAME", CURLPROXY_SOCKS5_HOSTNAME, CONST_PERSISTENT);
@@ -830,6 +834,9 @@ static void register_curl_symbols(int module_number)
 #endif
 #if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */
 	REGISTER_LONG_CONSTANT("CURLINFO_CONN_ID", CURLINFO_CONN_ID, CONST_PERSISTENT);
+#endif
+#if LIBCURL_VERSION_NUM >= 0x081400 /* Available since 8.20.0 */
+	REGISTER_LONG_CONSTANT("CURLINFO_SIZE_DELIVERED", CURLINFO_SIZE_DELIVERED, CONST_PERSISTENT);
 #endif
 	REGISTER_LONG_CONSTANT("CURLOPT_DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("CURLOPT_PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CONST_PERSISTENT);
diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c
index fd8baecc6838..b67028566c9c 100644
--- a/ext/curl/curl_file.c
+++ b/ext/curl/curl_file.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Stanislav Malyshev                             |
    +----------------------------------------------------------------------+
diff --git a/ext/curl/curl_private.h b/ext/curl/curl_private.h
index df6fd691a2a7..25cc37b6e458 100644
--- a/ext/curl/curl_private.h
+++ b/ext/curl/curl_private.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sterling Hughes                            |
    |         Wez Furlong                            |
@@ -76,6 +74,7 @@ typedef struct {
 	php_curl_write    *write_header;
 	php_curl_read     *read;
 	zval               std_err;
+	zend_fcall_info_cache seek;
 	zend_fcall_info_cache progress;
 	zend_fcall_info_cache xferinfo;
 	zend_fcall_info_cache fnmatch;
@@ -153,15 +152,11 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source);
 /* Consumes `zv` */
 zend_long php_curl_get_long(zval *zv);
 
-static inline php_curl *curl_from_obj(zend_object *obj) {
-	return (php_curl *)((char *)(obj) - XtOffsetOf(php_curl, std));
-}
+#define curl_from_obj(obj) ZEND_CONTAINER_OF(obj, php_curl, std)
 
 #define Z_CURL_P(zv) curl_from_obj(Z_OBJ_P(zv))
 
-static inline php_curlsh *curl_share_from_obj(zend_object *obj) {
-	return (php_curlsh *)((char *)(obj) - XtOffsetOf(php_curlsh, std));
-}
+#define curl_share_from_obj(obj) ZEND_CONTAINER_OF(obj, php_curlsh, std)
 
 #define Z_CURL_SHARE_P(zv) curl_share_from_obj(Z_OBJ_P(zv))
 
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 6328538241fe..d5d20d825652 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sterling Hughes                            |
    +----------------------------------------------------------------------+
@@ -34,11 +32,6 @@
 #include 
 #include 
 
-/* As of curl 7.11.1 this is no longer defined inside curl.h */
-#ifndef HttpPost
-#define HttpPost curl_httppost
-#endif
-
 #include "zend_smart_str.h"
 #include "ext/standard/info.h"
 #include "ext/standard/file.h"
@@ -359,7 +352,7 @@ PHP_MINIT_FUNCTION(curl)
 	curl_ce->default_object_handlers = &curl_object_handlers;
 
 	memcpy(&curl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	curl_object_handlers.offset = XtOffsetOf(php_curl, std);
+	curl_object_handlers.offset = offsetof(php_curl, std);
 	curl_object_handlers.free_obj = curl_free_obj;
 	curl_object_handlers.get_gc = curl_get_gc;
 	curl_object_handlers.get_constructor = curl_get_constructor;
@@ -458,6 +451,10 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
 		zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write_header->stream);
 	}
 
+	if (ZEND_FCC_INITIALIZED(curl->handlers.seek)) {
+		zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.seek);
+	}
+
 	if (ZEND_FCC_INITIALIZED(curl->handlers.progress)) {
 		zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.progress);
 	}
@@ -520,13 +517,15 @@ PHP_MSHUTDOWN_FUNCTION(curl)
 /* {{{ curl_write */
 static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
 {
+	ZEND_ASSERT(size == 1);
+
 	php_curl *ch = (php_curl *) ctx;
 	php_curl_write *write_handler = ch->handlers.write;
-	size_t length = size * nmemb;
+	size_t length = nmemb;
 
 #if PHP_CURL_DEBUG
 	fprintf(stderr, "curl_write() called\n");
-	fprintf(stderr, "data = %s, size = %d, nmemb = %d, ctx = %x\n", data, size, nmemb, ctx);
+	fprintf(stderr, "data = %s, size = %zu, nmemb = %zu, ctx = %p\n", data, size, nmemb, (void *) ctx);
 #endif
 
 	switch (write_handler->method) {
@@ -608,7 +607,7 @@ static int curl_progress(void *clientp, double dltotal, double dlnow, double ult
 
 #if PHP_CURL_DEBUG
 	fprintf(stderr, "curl_progress() called\n");
-	fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow);
+	fprintf(stderr, "clientp = %p, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow);
 #endif
 	if (!ZEND_FCC_INITIALIZED(ch->handlers.progress)) {
 		return rval;
@@ -649,7 +648,7 @@ static int curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, cu
 
 #if PHP_CURL_DEBUG
 	fprintf(stderr, "curl_xferinfo() called\n");
-	fprintf(stderr, "clientp = %x, dltotal = %ld, dlnow = %ld, ultotal = %ld, ulnow = %ld\n", clientp, dltotal, dlnow, ultotal, ulnow);
+	fprintf(stderr, "clientp = %p, dltotal = %ld, dlnow = %ld, ultotal = %ld, ulnow = %ld\n", clientp, dltotal, dlnow, ultotal, ulnow);
 #endif
 	if (!ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) {
 		return rval;
@@ -744,7 +743,7 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key,
 
 #if PHP_CURL_DEBUG
 	fprintf(stderr, "curl_ssh_hostkeyfunction() called\n");
-	fprintf(stderr, "clientp = %x, keytype = %d, key = %s, keylen = %zu\n", clientp, keytype, key, keylen);
+	fprintf(stderr, "clientp = %p, keytype = %d, key = %s, keylen = %zu\n", clientp, keytype, key, keylen);
 #endif
 
 	zval args[4];
@@ -784,6 +783,8 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key,
 /* {{{ curl_read */
 static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
 {
+	ZEND_ASSERT(size == 1);
+
 	php_curl *ch = (php_curl *)ctx;
 	php_curl_read *read_handler = ch->handlers.read;
 	size_t length = 0;
@@ -806,7 +807,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
 			} else {
 				ZVAL_NULL(&argv[1]);
 			}
-			ZVAL_LONG(&argv[2], (int)size * nmemb);
+			ZVAL_LONG(&argv[2], (zend_long) nmemb);
 
 			ch->in_callback = true;
 			zend_call_known_fcc(&read_handler->fcc, &retval, /* param_count */ 3, argv, /* named_params */ NULL);
@@ -814,7 +815,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
 			if (!Z_ISUNDEF(retval)) {
 				_php_curl_verify_handlers(ch, /* reporterror */ true);
 				if (Z_TYPE(retval) == IS_STRING) {
-					length = MIN(size * nmemb, Z_STRLEN(retval));
+					length = MIN(nmemb, Z_STRLEN(retval));
 					memcpy(data, Z_STRVAL(retval), length);
 				} else if (Z_TYPE(retval) == IS_LONG) {
 					length = Z_LVAL_P(&retval);
@@ -833,12 +834,60 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
 }
 /* }}} */
 
+/* {{{ curl_seek */
+static int curl_seek(void *clientp, curl_off_t offset, int origin)
+{
+	php_curl *ch = (php_curl *)clientp;
+	int rval = CURL_SEEKFUNC_CANTSEEK; /* safe default if unset or the callback misbehaves */
+
+#if PHP_CURL_DEBUG
+	fprintf(stderr, "curl_seek() called\n");
+	fprintf(stderr, "clientp = %p, offset = %ld, origin = %d\n", clientp, offset, origin);
+#endif
+	if (!ZEND_FCC_INITIALIZED(ch->handlers.seek)) {
+		return rval;
+	}
+
+	zval args[3];
+	zval retval;
+
+	GC_ADDREF(&ch->std);
+	ZVAL_OBJ(&args[0], &ch->std);
+	ZVAL_LONG(&args[1], offset);
+	ZVAL_LONG(&args[2], origin);
+
+	ch->in_callback = true;
+	zend_call_known_fcc(&ch->handlers.seek, &retval, /* param_count */ 3, args, /* named_params */ NULL);
+	ch->in_callback = false;
+
+	if (!Z_ISUNDEF(retval)) {
+		_php_curl_verify_handlers(ch, /* reporterror */ true);
+		if (Z_TYPE(retval) == IS_LONG) {
+			zend_long retval_long = Z_LVAL(retval);
+			if (retval_long == CURL_SEEKFUNC_OK || retval_long == CURL_SEEKFUNC_FAIL || retval_long == CURL_SEEKFUNC_CANTSEEK) {
+				rval = retval_long;
+			} else {
+				zend_value_error("The CURLOPT_SEEKFUNCTION callback must return one of CURL_SEEKFUNC_OK, CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK");
+			}
+		} else {
+			zend_type_error("The CURLOPT_SEEKFUNCTION callback must return one of CURL_SEEKFUNC_OK, CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK");
+		}
+		zval_ptr_dtor(&retval);
+	}
+
+	zval_ptr_dtor(&args[0]);
+	return rval;
+}
+/* }}} */
+
 /* {{{ curl_write_header */
 static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx)
 {
+	ZEND_ASSERT(size == 1);
+
 	php_curl *ch = (php_curl *) ctx;
 	php_curl_write *write_handler = ch->handlers.write_header;
-	size_t length = size * nmemb;
+	size_t length = nmemb;
 
 	switch (write_handler->method) {
 		case PHP_CURL_STDOUT:
@@ -1040,6 +1089,7 @@ void init_curl_handle(php_curl *ch)
 	ch->handlers.write = ecalloc(1, sizeof(php_curl_write));
 	ch->handlers.write_header = ecalloc(1, sizeof(php_curl_write));
 	ch->handlers.read = ecalloc(1, sizeof(php_curl_read));
+	ch->handlers.seek = empty_fcall_info_cache;
 	ch->handlers.progress = empty_fcall_info_cache;
 	ch->handlers.xferinfo = empty_fcall_info_cache;
 	ch->handlers.fnmatch = empty_fcall_info_cache;
@@ -1055,7 +1105,7 @@ void init_curl_handle(php_curl *ch)
 
 	memset(&ch->err, 0, sizeof(struct _php_curl_error));
 
-	zend_llist_init(&ch->to_free->post,  sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post,   0);
+	zend_llist_init(&ch->to_free->post,  sizeof(struct curl_httppost *), (llist_dtor_func_t)curl_free_post,   0);
 	zend_llist_init(&ch->to_free->stream, sizeof(struct mime_data_cb_arg *), (llist_dtor_func_t)curl_free_cb_arg, 0);
 
 	zend_hash_init(&ch->to_free->slist, 4, NULL, curl_free_slist, 0);
@@ -1100,8 +1150,6 @@ static void create_certinfo(struct curl_certinfo *ci, zval *listcode)
    Set default options for a handle */
 static void _php_curl_set_default_options(php_curl *ch)
 {
-	char *cainfo;
-
 	curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS,        1L);
 	curl_easy_setopt(ch->cp, CURLOPT_VERBOSE,           0L);
 	curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER,       ch->err.str);
@@ -1114,9 +1162,9 @@ static void _php_curl_set_default_options(php_curl *ch)
 	curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120L);
 	curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20L); /* prevent infinite redirects */
 
-	cainfo = INI_STR("openssl.cafile");
+	const char *cainfo = zend_ini_string_literal("openssl.cafile");
 	if (!(cainfo && cainfo[0] != '\0')) {
-		cainfo = INI_STR("curl.cainfo");
+		cainfo = zend_ini_string_literal("curl.cainfo");
 	}
 	if (cainfo && cainfo[0] != '\0') {
 		curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo);
@@ -1212,6 +1260,7 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
 	curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER,       (void *) ch);
 	curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA,         (void *) ch);
 
+	php_curl_copy_fcc_with_option(ch, CURLOPT_SEEKDATA, &ch->handlers.seek, &source->handlers.seek);
 	php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
 	php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo);
 	php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch);
@@ -1581,6 +1630,7 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
 		HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER(ch, CURLOPT_HEADER, write_header, PHP_CURL_IGNORE);
 		HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER(ch, CURLOPT_READ, read, PHP_CURL_DIRECT);
 
+		HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_SEEK, handlers.seek, curl_seek);
 		HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PROGRESS, handlers.progress, curl_progress);
 		HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_XFERINFO, handlers.xferinfo, curl_xferinfo);
 		HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_FNMATCH_, handlers.fnmatch, curl_fnmatch);
@@ -2034,42 +2084,42 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
 			HashTable *ph;
 			zend_string *val, *tmp_val;
 			struct curl_slist *slist = NULL;
+			const char *name = NULL;
 
-			if (Z_TYPE_P(zvalue) != IS_ARRAY) {
-				const char *name = NULL;
-				switch (option) {
-					case CURLOPT_HTTPHEADER:
-						name = "CURLOPT_HTTPHEADER";
-						break;
-					case CURLOPT_QUOTE:
-						name = "CURLOPT_QUOTE";
-						break;
-					case CURLOPT_HTTP200ALIASES:
-						name = "CURLOPT_HTTP200ALIASES";
-						break;
-					case CURLOPT_POSTQUOTE:
-						name = "CURLOPT_POSTQUOTE";
-						break;
-					case CURLOPT_PREQUOTE:
-						name = "CURLOPT_PREQUOTE";
-						break;
-					case CURLOPT_TELNETOPTIONS:
-						name = "CURLOPT_TELNETOPTIONS";
-						break;
-					case CURLOPT_MAIL_RCPT:
-						name = "CURLOPT_MAIL_RCPT";
-						break;
-					case CURLOPT_RESOLVE:
-						name = "CURLOPT_RESOLVE";
-						break;
-					case CURLOPT_PROXYHEADER:
-						name = "CURLOPT_PROXYHEADER";
-						break;
-					case CURLOPT_CONNECT_TO:
-						name = "CURLOPT_CONNECT_TO";
-						break;
-				}
+			switch (option) {
+				case CURLOPT_HTTPHEADER:
+					name = "CURLOPT_HTTPHEADER";
+					break;
+				case CURLOPT_QUOTE:
+					name = "CURLOPT_QUOTE";
+					break;
+				case CURLOPT_HTTP200ALIASES:
+					name = "CURLOPT_HTTP200ALIASES";
+					break;
+				case CURLOPT_POSTQUOTE:
+					name = "CURLOPT_POSTQUOTE";
+					break;
+				case CURLOPT_PREQUOTE:
+					name = "CURLOPT_PREQUOTE";
+					break;
+				case CURLOPT_TELNETOPTIONS:
+					name = "CURLOPT_TELNETOPTIONS";
+					break;
+				case CURLOPT_MAIL_RCPT:
+					name = "CURLOPT_MAIL_RCPT";
+					break;
+				case CURLOPT_RESOLVE:
+					name = "CURLOPT_RESOLVE";
+					break;
+				case CURLOPT_PROXYHEADER:
+					name = "CURLOPT_PROXYHEADER";
+					break;
+				case CURLOPT_CONNECT_TO:
+					name = "CURLOPT_CONNECT_TO";
+					break;
+			}
 
+			if (Z_TYPE_P(zvalue) != IS_ARRAY) {
 				zend_type_error("%s(): The %s option must have an array value", get_active_function_name(), name);
 				return FAILURE;
 			}
@@ -2078,6 +2128,14 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
 			ZEND_HASH_FOREACH_VAL(ph, current) {
 				ZVAL_DEREF(current);
 				val = zval_get_tmp_string(current, &tmp_val);
+
+				if (zend_str_has_nul_byte(val)) {
+					curl_slist_free_all(slist);
+					zend_tmp_string_release(tmp_val);
+					zend_value_error("%s(): cURL option %s must not contain any null bytes", get_active_function_name(), name);
+					return FAILURE;
+				}
+
 				struct curl_slist *new_slist = curl_slist_append(slist, ZSTR_VAL(val));
 				zend_tmp_string_release(tmp_val);
 				if (!new_slist) {
@@ -2460,6 +2518,11 @@ PHP_FUNCTION(curl_getinfo)
 		if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD, &d_code) == CURLE_OK) {
 			CAAD("size_download", d_code);
 		}
+#if LIBCURL_VERSION_NUM >= 0x081400 /* Available since 8.20.0 */
+		if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DELIVERED , &l_code) == CURLE_OK) {
+			CAAL("size_delivered", l_code);
+		}
+#endif
 		if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD, &d_code) == CURLE_OK) {
 			CAAD("speed_download", d_code);
 		}
@@ -2739,7 +2802,7 @@ static void curl_free_obj(zend_object *object)
 	php_curl *ch = curl_from_obj(object);
 
 #if PHP_CURL_DEBUG
-	fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
+	fprintf(stderr, "DTOR CALLED, ch = %p\n", (void *) ch);
 #endif
 
 	if (!ch->cp) {
@@ -2785,6 +2848,9 @@ static void curl_free_obj(zend_object *object)
 	efree(ch->handlers.write_header);
 	efree(ch->handlers.read);
 
+	if (ZEND_FCC_INITIALIZED(ch->handlers.seek)) {
+		zend_fcc_dtor(&ch->handlers.seek);
+	}
 	if (ZEND_FCC_INITIALIZED(ch->handlers.progress)) {
 		zend_fcc_dtor(&ch->handlers.progress);
 	}
@@ -2869,6 +2935,10 @@ static void _php_curl_reset_handlers(php_curl *ch)
 		ZVAL_UNDEF(&ch->handlers.std_err);
 	}
 
+	if (ZEND_FCC_INITIALIZED(ch->handlers.seek)) {
+		zend_fcc_dtor(&ch->handlers.seek);
+	}
+
 	if (ZEND_FCC_INITIALIZED(ch->handlers.progress)) {
 		zend_fcc_dtor(&ch->handlers.progress);
 	}
diff --git a/ext/curl/multi.c b/ext/curl/multi.c
index 3e6142466e98..0e329e58f977 100644
--- a/ext/curl/multi.c
+++ b/ext/curl/multi.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sterling Hughes                            |
    +----------------------------------------------------------------------+
@@ -50,9 +48,7 @@
 
 zend_class_entry *curl_multi_ce;
 
-static inline php_curlm *curl_multi_from_obj(zend_object *obj) {
-	return (php_curlm *)((char *)(obj) - XtOffsetOf(php_curlm, std));
-}
+#define curl_multi_from_obj(obj) ZEND_CONTAINER_OF(obj, php_curlm, std)
 
 #define Z_CURL_MULTI_P(zv) curl_multi_from_obj(Z_OBJ_P(zv))
 
@@ -607,7 +603,7 @@ void curl_multi_register_handlers(void) {
 	curl_multi_ce->default_object_handlers = &curl_multi_handlers;
 
 	memcpy(&curl_multi_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	curl_multi_handlers.offset = XtOffsetOf(php_curlm, std);
+	curl_multi_handlers.offset = offsetof(php_curlm, std);
 	curl_multi_handlers.free_obj = curl_multi_free_obj;
 	curl_multi_handlers.get_gc = curl_multi_get_gc;
 	curl_multi_handlers.get_constructor = curl_multi_get_constructor;
diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h
index 6084d5935c70..9a70d6466c92 100644
--- a/ext/curl/php_curl.h
+++ b/ext/curl/php_curl.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sterling Hughes                            |
    |         Wez Furlong                            |
diff --git a/ext/curl/share.c b/ext/curl/share.c
index ba23faa46bf5..56cd804658a4 100644
--- a/ext/curl/share.c
+++ b/ext/curl/share.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Pierrick Charron                           |
    +----------------------------------------------------------------------+
@@ -305,7 +303,7 @@ void curl_share_register_handlers(void) {
 	curl_share_ce->default_object_handlers = &curl_share_handlers;
 
 	memcpy(&curl_share_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	curl_share_handlers.offset = XtOffsetOf(php_curlsh, std);
+	curl_share_handlers.offset = offsetof(php_curlsh, std);
 	curl_share_handlers.free_obj = curl_share_free_obj;
 	curl_share_handlers.get_constructor = curl_share_get_constructor;
 	curl_share_handlers.clone_obj = NULL;
@@ -326,7 +324,7 @@ void curl_share_persistent_register_handlers(void) {
 	curl_share_persistent_ce->default_object_handlers = &curl_share_persistent_handlers;
 
 	memcpy(&curl_share_persistent_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	curl_share_persistent_handlers.offset = XtOffsetOf(php_curlsh, std);
+	curl_share_persistent_handlers.offset = offsetof(php_curlsh, std);
 	curl_share_persistent_handlers.get_constructor = curl_share_persistent_get_constructor;
 	curl_share_persistent_handlers.clone_obj = NULL;
 	curl_share_persistent_handlers.compare = zend_objects_not_comparable;
diff --git a/ext/curl/tests/bug71523.phpt b/ext/curl/tests/bug71523.phpt
index 2cf2477409da..1a01209dbb8b 100644
--- a/ext/curl/tests/bug71523.phpt
+++ b/ext/curl/tests/bug71523.phpt
@@ -4,6 +4,7 @@ Bug #71523 (Copied handle with new option CURLOPT_HTTPHEADER crashes while curl_
 curl
 --SKIPIF--
  %r(Yes|No)%r
 PSL => No
 HTTPS_PROXY => Yes
 MULTI_SSL => %s
-BROTLI => %s
+BROTLI => Yes
 ALTSVC => Yes
 HTTP3 => No
 UNICODE => No
-ZSTD => No
+ZSTD => Yes
 HSTS => Yes
 GSASL => No
 Protocols => dict, file, ftp, ftps, gopher, %r(gophers, )?%rhttp, https, imap, imaps, ldap, ldaps, %r(mqtt, )?%rpop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp%r(, ws)?(, wss)?%r
diff --git a/ext/curl/tests/curl_copy_handle_seek.phpt b/ext/curl/tests/curl_copy_handle_seek.phpt
new file mode 100644
index 000000000000..c2a2f37bbe13
--- /dev/null
+++ b/ext/curl/tests/curl_copy_handle_seek.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Test curl_copy_handle() with CURLOPT_SEEKFUNCTION
+--EXTENSIONS--
+curl
+--FILE--
+ 0);
+var_dump(str_contains($response, $body));
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_SIZE_DELIVERED.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_SIZE_DELIVERED.phpt
new file mode 100644
index 000000000000..e33277ff88f8
--- /dev/null
+++ b/ext/curl/tests/curl_getinfo_CURLINFO_SIZE_DELIVERED.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Curlinfo CURLINFO_SIZE_DELIVERED
+--EXTENSIONS--
+curl
+--SKIPIF--
+= 8.20.0");
+?>
+--FILE--
+ 0);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+
diff --git a/ext/curl/tests/curl_seekfunction.phpt b/ext/curl/tests/curl_seekfunction.phpt
new file mode 100644
index 000000000000..d2daa1e7d8dc
--- /dev/null
+++ b/ext/curl/tests/curl_seekfunction.phpt
@@ -0,0 +1,51 @@
+--TEST--
+CURLOPT_SEEKFUNCTION is called to rewind a streamed upload across a redirect
+--EXTENSIONS--
+curl
+--FILE--
+ 0);
+var_dump(str_contains($response, $body));
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/curl/tests/curl_seekfunction_error.phpt b/ext/curl/tests/curl_seekfunction_error.phpt
new file mode 100644
index 000000000000..134e8115dc5f
--- /dev/null
+++ b/ext/curl/tests/curl_seekfunction_error.phpt
@@ -0,0 +1,77 @@
+--TEST--
+CURLOPT_SEEKFUNCTION callback error handling and option validation
+--EXTENSIONS--
+curl
+--FILE--
+ 'not an int');
+} catch (\TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+
+echo "\nReturning an out-of-range int:\n";
+try {
+    run_upload($host, fn($ch, $offset, $origin) => 42);
+} catch (\ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
+echo "\nThrowing from the callback:\n";
+try {
+    run_upload($host, function ($ch, $offset, $origin) {
+        throw new \RuntimeException('boom from seek');
+    });
+} catch (\RuntimeException $e) {
+    echo $e->getMessage(), "\n";
+}
+
+echo "\nSetting the callback to null:\n";
+var_dump(curl_setopt(curl_init(), CURLOPT_SEEKFUNCTION, null));
+
+echo "\nSetting a non-callable scalar:\n";
+try {
+    curl_setopt(curl_init(), CURLOPT_SEEKFUNCTION, 42);
+} catch (\TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+Returning a non-int:
+The CURLOPT_SEEKFUNCTION callback must return one of CURL_SEEKFUNC_OK, CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK
+
+Returning an out-of-range int:
+The CURLOPT_SEEKFUNCTION callback must return one of CURL_SEEKFUNC_OK, CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK
+
+Throwing from the callback:
+boom from seek
+
+Setting the callback to null:
+bool(true)
+
+Setting a non-callable scalar:
+curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_SEEKFUNCTION, no array or string given
diff --git a/ext/curl/tests/curl_setopt_callables.phpt b/ext/curl/tests/curl_setopt_callables.phpt
index aaa83102afac..9de8d6705710 100644
--- a/ext/curl/tests/curl_setopt_callables.phpt
+++ b/ext/curl/tests/curl_setopt_callables.phpt
@@ -27,6 +27,7 @@ testOption($ch, CURLOPT_FNMATCH_FUNCTION);
 testOption($ch, CURLOPT_WRITEFUNCTION);
 testOption($ch, CURLOPT_HEADERFUNCTION);
 testOption($ch, CURLOPT_READFUNCTION);
+testOption($ch, CURLOPT_SEEKFUNCTION);
 
 ?>
 --EXPECT--
@@ -42,3 +43,5 @@ TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for opti
 TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_HEADERFUNCTION, function "undefined" not found or invalid function name
 TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_READFUNCTION, function "undefined" not found or invalid function name
 TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_READFUNCTION, function "undefined" not found or invalid function name
+TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_SEEKFUNCTION, function "undefined" not found or invalid function name
+TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_SEEKFUNCTION, function "undefined" not found or invalid function name
diff --git a/ext/curl/tests/curl_setopt_error_nul_byte.phpt b/ext/curl/tests/curl_setopt_error_nul_byte.phpt
new file mode 100644
index 000000000000..23be973b82c2
--- /dev/null
+++ b/ext/curl/tests/curl_setopt_error_nul_byte.phpt
@@ -0,0 +1,52 @@
+--TEST--
+curl_setopt() throws ValueError for NUL bytes in lists
+--EXTENSIONS--
+curl
+--FILE--
+getMessage() . "\n\n";
+    }
+}
+
+$ch = null;
+?>
+--EXPECT--
+CURLOPT_HTTP200ALIASES: curl_setopt(): cURL option CURLOPT_HTTP200ALIASES must not contain any null bytes
+
+CURLOPT_HTTPHEADER: curl_setopt(): cURL option CURLOPT_HTTPHEADER must not contain any null bytes
+
+CURLOPT_POSTQUOTE: curl_setopt(): cURL option CURLOPT_POSTQUOTE must not contain any null bytes
+
+CURLOPT_PREQUOTE: curl_setopt(): cURL option CURLOPT_PREQUOTE must not contain any null bytes
+
+CURLOPT_QUOTE: curl_setopt(): cURL option CURLOPT_QUOTE must not contain any null bytes
+
+CURLOPT_TELNETOPTIONS: curl_setopt(): cURL option CURLOPT_TELNETOPTIONS must not contain any null bytes
+
+CURLOPT_MAIL_RCPT: curl_setopt(): cURL option CURLOPT_MAIL_RCPT must not contain any null bytes
+
+CURLOPT_RESOLVE: curl_setopt(): cURL option CURLOPT_RESOLVE must not contain any null bytes
+
+CURLOPT_PROXYHEADER: curl_setopt(): cURL option CURLOPT_PROXYHEADER must not contain any null bytes
+
+CURLOPT_CONNECT_TO: curl_setopt(): cURL option CURLOPT_CONNECT_TO must not contain any null bytes
diff --git a/ext/curl/tests/curl_setopt_ssl.phpt b/ext/curl/tests/curl_setopt_ssl.phpt
index 601e09d1f71a..f3b82e1756e3 100644
--- a/ext/curl/tests/curl_setopt_ssl.phpt
+++ b/ext/curl/tests/curl_setopt_ssl.phpt
@@ -37,6 +37,7 @@ function check_response($response, $clientCertSubject) {
 }
 
 $clientCertSubject = "Subject: C=US, ST=TX, L=Clientlocation, O=Clientcompany, CN=clientname/emailAddress=test@example.com";
+$rejectsZeroLengthBlobs = curl_version()['version_number'] >= 0x081300;
 
 // load server cert
 $serverCertPath = __DIR__ . DIRECTORY_SEPARATOR . 'curl_setopt_ssl_servercert.pem';
@@ -91,7 +92,7 @@ try {
     echo "\n";
     echo "case 2: empty client cert and key from string\n";
     $ch = curl_init("https://127.0.0.1:$port/");
-    var_dump(curl_setopt($ch, CURLOPT_SSLCERT_BLOB, ''));
+    var_dump(curl_setopt($ch, CURLOPT_SSLCERT_BLOB, '') === !$rejectsZeroLengthBlobs);
     var_dump(curl_setopt($ch, CURLOPT_SSLKEY_BLOB, $clientKey));
     var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false));
     var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false));
@@ -99,14 +100,14 @@ try {
 
     $response = curl_exec($ch);
     check_response($response, $clientCertSubject);
-    check_error($ch);
+    check_error($ch, $rejectsZeroLengthBlobs ? 56 : 58);
     $ch = null;
 
     echo "\n";
     echo "case 3: client cert and empty key from string\n";
     $ch = curl_init("https://127.0.0.1:$port/");
     var_dump(curl_setopt($ch, CURLOPT_SSLCERT_BLOB, $clientCert));
-    var_dump(curl_setopt($ch, CURLOPT_SSLKEY_BLOB, ''));
+    var_dump(curl_setopt($ch, CURLOPT_SSLKEY_BLOB, '') === !$rejectsZeroLengthBlobs);
     var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false));
     var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false));
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
@@ -166,7 +167,7 @@ try {
     echo "case 7: empty issuer cert from string\n";
     $ch = curl_init("https://127.0.0.1:$port/");
     var_dump(curl_setopt($ch, CURLOPT_CAINFO, $serverCertPath));
-    var_dump(curl_setopt($ch, CURLOPT_ISSUERCERT_BLOB, ''));
+    var_dump(curl_setopt($ch, CURLOPT_ISSUERCERT_BLOB, '') === !$rejectsZeroLengthBlobs);
     var_dump(curl_setopt($ch, CURLOPT_SSLCERT, $clientCertPath));
     var_dump(curl_setopt($ch, CURLOPT_SSLKEY, $clientKeyPath));
     var_dump(curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true));
@@ -174,8 +175,8 @@ try {
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
     $response = curl_exec($ch);
-    check_response($response, $clientCertSubject);
-    check_error($ch);
+    var_dump((is_string($response) && strpos($response, $clientCertSubject) !== false) === $rejectsZeroLengthBlobs);
+    var_dump(curl_errno($ch) === ($rejectsZeroLengthBlobs ? 0 : 83));
     $ch = null;
 
 } finally {
@@ -199,7 +200,7 @@ bool(true)
 bool(true)
 bool(true)
 client cert subject not in response
-CURL ERROR: 58
+CURL ERROR: EXPECTED
 
 case 3: client cert and empty key from string
 bool(true)
@@ -241,5 +242,5 @@ bool(true)
 bool(true)
 bool(true)
 bool(true)
-client cert subject not in response
-CURL ERROR: 83
+bool(true)
+bool(true)
diff --git a/ext/curl/tests/responder/get.inc b/ext/curl/tests/responder/get.inc
index c139c8c7d43a..2ef1e4a89dd3 100644
--- a/ext/curl/tests/responder/get.inc
+++ b/ext/curl/tests/responder/get.inc
@@ -46,6 +46,11 @@
     case 'method':
       echo $_SERVER['REQUEST_METHOD'];
       break;
+    case 'redirect':
+      // A 307 preserves the method and body, so libcurl must rewind the upload
+      // (via CURLOPT_SEEKFUNCTION) before resending it to the new location.
+      header('Location: /get.inc?test=input', true, 307);
+      break;
     default:
       echo "Hello World!\n";
       echo "Hello World!";
diff --git a/ext/date/config.w32 b/ext/date/config.w32
index b053e27aae35..150fb1498f35 100644
--- a/ext/date/config.w32
+++ b/ext/date/config.w32
@@ -1,6 +1,6 @@
 // vim:ft=javascript
 
-EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 /DHAVE_TIMELIB_CONFIG_H=1");
+EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
 PHP_DATE = "yes";
 ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");
 
diff --git a/ext/date/config0.m4 b/ext/date/config0.m4
index c78fcb78e15e..5018f258ab2a 100644
--- a/ext/date/config0.m4
+++ b/ext/date/config0.m4
@@ -9,7 +9,7 @@ AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough],
 
 PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -DHAVE_TIMELIB_CONFIG_H=1"
 PHP_TIMELIB_CFLAGS="$PHP_DATE_CFLAGS"
-PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
+PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib"
 
 AX_CHECK_COMPILE_FLAG([-fwrapv],
   [PHP_TIMELIB_CFLAGS="$PHP_TIMELIB_CFLAGS -fwrapv"])
diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c
index 65d99806642d..eb324f8430c5 100644
--- a/ext/date/lib/parse_date.c
+++ b/ext/date/lib/parse_date.c
@@ -518,7 +518,7 @@ static timelib_sll timelib_get_nr(const char **ptr, int max_length)
 
 static void timelib_skip_day_suffix(const char **ptr)
 {
-	if (isspace(**ptr)) {
+	if (isspace((unsigned char)**ptr)) {
 		return;
 	}
 	if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) {
@@ -859,7 +859,7 @@ static timelib_long timelib_parse_tz_cor(const char **ptr, int *tz_not_found)
 
 	*tz_not_found = 1;
 
-	while (isdigit(**ptr) || **ptr == ':') {
+	while (isdigit((unsigned char)**ptr) || **ptr == ':') {
 		++*ptr;
 	}
 	end = *ptr;
@@ -924,7 +924,7 @@ static timelib_long timelib_parse_tz_minutes(const char **ptr, timelib_time *t)
 	}
 
 	++*ptr;
-	while (isdigit(**ptr)) {
+	while (isdigit((unsigned char)**ptr)) {
 		++*ptr;
 	}
 
diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re
index ffb3e8e35913..07d9c0e73488 100644
--- a/ext/date/lib/parse_date.re
+++ b/ext/date/lib/parse_date.re
@@ -516,7 +516,7 @@ static timelib_sll timelib_get_nr(const char **ptr, int max_length)
 
 static void timelib_skip_day_suffix(const char **ptr)
 {
-	if (isspace(**ptr)) {
+	if (isspace((unsigned char)**ptr)) {
 		return;
 	}
 	if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) {
@@ -555,7 +555,6 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l
 	int len = 0;
 
 	/* Skip over non-numeric chars */
-
 	while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
 		if (**ptr == '\0') {
 			add_error(s, TIMELIB_ERR_UNEXPECTED_DATA, "Found unexpected data");
@@ -569,6 +568,7 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l
 	str[0] = '+'; /* First position is the sign */
 	str_ptr = str + 1;
 
+
 	while ((**ptr == '+') || (**ptr == '-')) {
 		if (**ptr == '-') {
 			str[0] = str[0] == '+' ? '-' : '+';
@@ -857,7 +857,7 @@ static timelib_long timelib_parse_tz_cor(const char **ptr, int *tz_not_found)
 
 	*tz_not_found = 1;
 
-	while (isdigit(**ptr) || **ptr == ':') {
+	while (isdigit((unsigned char)**ptr) || **ptr == ':') {
 		++*ptr;
 	}
 	end = *ptr;
@@ -922,7 +922,7 @@ static timelib_long timelib_parse_tz_minutes(const char **ptr, timelib_time *t)
 	}
 
 	++*ptr;
-	while (isdigit(**ptr)) {
+	while (isdigit((unsigned char)**ptr)) {
 		++*ptr;
 	}
 
@@ -2020,7 +2020,7 @@ timelib_time *timelib_strtotime(const char *s, size_t len, timelib_error_contain
 	in.errors->error_messages = NULL;
 
 	if (len > 0) {
-		while (isspace((unsigned char)*s) && s < e) {
+		while (isspace((unsigned char)*s) && s <= e) {
 			s++;
 		}
 		while (isspace((unsigned char)*e) && e > s) {
diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c
index 1fc0ede9679c..5dcbfe350639 100644
--- a/ext/date/lib/parse_iso_intervals.c
+++ b/ext/date/lib/parse_iso_intervals.c
@@ -985,10 +985,10 @@ void timelib_strtointerval(const char *s, size_t len,
 	in.errors->error_messages = NULL;
 
 	if (len > 0) {
-		while (isspace(*s) && s < e) {
+		while (isspace((unsigned char)*s) && s < e) {
 			s++;
 		}
-		while (isspace(*e) && e > s) {
+		while (isspace((unsigned char)*e) && e > s) {
 			e--;
 		}
 	}
diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re
index 2a394156f98d..009420077513 100644
--- a/ext/date/lib/parse_iso_intervals.re
+++ b/ext/date/lib/parse_iso_intervals.re
@@ -343,10 +343,10 @@ void timelib_strtointerval(const char *s, size_t len,
 	in.errors->error_messages = NULL;
 
 	if (len > 0) {
-		while (isspace(*s) && s < e) {
+		while (isspace((unsigned char)*s) && s < e) {
 			s++;
 		}
-		while (isspace(*e) && e > s) {
+		while (isspace((unsigned char)*e) && e > s) {
 			e--;
 		}
 	}
diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c
index 6473a2798a80..faf383a5fa12 100644
--- a/ext/date/lib/timelib.c
+++ b/ext/date/lib/timelib.c
@@ -126,7 +126,7 @@ void timelib_time_tz_abbr_update(timelib_time* tm, const char* tz_abbr)
 	TIMELIB_TIME_FREE(tm->tz_abbr);
 	tm->tz_abbr = timelib_strdup(tz_abbr);
 	for (i = 0; i < tz_abbr_len; i++) {
-		tm->tz_abbr[i] = toupper(tz_abbr[i]);
+		tm->tz_abbr[i] = toupper((unsigned char)tz_abbr[i]);
 	}
 }
 
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h
index acae8e32533d..d08aa77ea5e5 100644
--- a/ext/date/lib/timelib.h
+++ b/ext/date/lib/timelib.h
@@ -30,9 +30,9 @@
 # include "timelib_config.h"
 #endif
 
-#define TIMELIB_VERSION 202215
-#define TIMELIB_EXTENDED_VERSION 20221501
-#define TIMELIB_ASCII_VERSION "2022.15"
+#define TIMELIB_VERSION 202217
+#define TIMELIB_EXTENDED_VERSION 20221701
+#define TIMELIB_ASCII_VERSION "2022.17"
 
 #include 
 #include 
diff --git a/ext/date/lib/timelib_private.h b/ext/date/lib/timelib_private.h
index 3c5f9b22147c..42cbaa68dbbf 100644
--- a/ext/date/lib/timelib_private.h
+++ b/ext/date/lib/timelib_private.h
@@ -135,6 +135,7 @@
 #ifndef TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW
 # define TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW 0
 #endif
+
 struct _ttinfo
 {
 	int32_t      offset;
@@ -165,6 +166,7 @@ extern "C" {
 #endif
 
 /* From unixtime2tm.c */
+void timelib_date_from_epoch_days(timelib_sll epoch_days, timelib_sll *y, timelib_sll *m, timelib_sll *d);
 int timelib_apply_localtime(timelib_time *t, unsigned int localtime);
 
 /* From parse_posix.c */
diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h
index 453041acabcf..a745e76019ba 100644
--- a/ext/date/lib/timezonedb.h
+++ b/ext/date/lib/timezonedb.h
@@ -20,593 +20,593 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[598] = {
 	{ (char*) "Africa/Bujumbura"                  , 0x000B2A },
 	{ (char*) "Africa/Cairo"                      , 0x000BB9 },
 	{ (char*) "Africa/Casablanca"                 , 0x0010E2 },
-	{ (char*) "Africa/Ceuta"                      , 0x00186D },
-	{ (char*) "Africa/Conakry"                    , 0x001AB9 },
-	{ (char*) "Africa/Dakar"                      , 0x001B63 },
-	{ (char*) "Africa/Dar_es_Salaam"              , 0x001C04 },
-	{ (char*) "Africa/Djibouti"                   , 0x001CB1 },
-	{ (char*) "Africa/Douala"                     , 0x001D40 },
-	{ (char*) "Africa/El_Aaiun"                   , 0x001DCF },
-	{ (char*) "Africa/Freetown"                   , 0x002501 },
-	{ (char*) "Africa/Gaborone"                   , 0x002651 },
-	{ (char*) "Africa/Harare"                     , 0x002711 },
-	{ (char*) "Africa/Johannesburg"               , 0x0027A0 },
-	{ (char*) "Africa/Juba"                       , 0x00286A },
-	{ (char*) "Africa/Kampala"                    , 0x002A40 },
-	{ (char*) "Africa/Khartoum"                   , 0x002B02 },
-	{ (char*) "Africa/Kigali"                     , 0x002CD8 },
-	{ (char*) "Africa/Kinshasa"                   , 0x002D67 },
-	{ (char*) "Africa/Lagos"                      , 0x002E0F },
-	{ (char*) "Africa/Libreville"                 , 0x002ECF },
-	{ (char*) "Africa/Lome"                       , 0x002F5E },
-	{ (char*) "Africa/Luanda"                     , 0x002FEC },
-	{ (char*) "Africa/Lubumbashi"                 , 0x00308A },
-	{ (char*) "Africa/Lusaka"                     , 0x003145 },
-	{ (char*) "Africa/Malabo"                     , 0x0031D4 },
-	{ (char*) "Africa/Maputo"                     , 0x003276 },
-	{ (char*) "Africa/Maseru"                     , 0x003305 },
-	{ (char*) "Africa/Mbabane"                    , 0x0033AE },
-	{ (char*) "Africa/Mogadishu"                  , 0x00343F },
-	{ (char*) "Africa/Monrovia"                   , 0x0034EC },
-	{ (char*) "Africa/Nairobi"                    , 0x00359C },
-	{ (char*) "Africa/Ndjamena"                   , 0x003667 },
-	{ (char*) "Africa/Niamey"                     , 0x003713 },
-	{ (char*) "Africa/Nouakchott"                 , 0x0037C8 },
-	{ (char*) "Africa/Ouagadougou"                , 0x003872 },
-	{ (char*) "Africa/Porto-Novo"                 , 0x003900 },
-	{ (char*) "Africa/Sao_Tome"                   , 0x0039A2 },
-	{ (char*) "Africa/Timbuktu"                   , 0x003A5B },
-	{ (char*) "Africa/Tripoli"                    , 0x003AE9 },
-	{ (char*) "Africa/Tunis"                      , 0x003CA4 },
-	{ (char*) "Africa/Windhoek"                   , 0x003E71 },
-	{ (char*) "America/Adak"                      , 0x0040FB },
-	{ (char*) "America/Anchorage"                 , 0x0044EA },
-	{ (char*) "America/Anguilla"                  , 0x0048DA },
-	{ (char*) "America/Antigua"                   , 0x004968 },
-	{ (char*) "America/Araguaina"                 , 0x004A09 },
-	{ (char*) "America/Argentina/Buenos_Aires"    , 0x004C6E },
-	{ (char*) "America/Argentina/Catamarca"       , 0x004F53 },
-	{ (char*) "America/Argentina/ComodRivadavia"  , 0x00523E },
-	{ (char*) "America/Argentina/Cordoba"         , 0x00550E },
-	{ (char*) "America/Argentina/Jujuy"           , 0x005814 },
-	{ (char*) "America/Argentina/La_Rioja"        , 0x005ADC },
-	{ (char*) "America/Argentina/Mendoza"         , 0x005DC2 },
-	{ (char*) "America/Argentina/Rio_Gallegos"    , 0x00609E },
-	{ (char*) "America/Argentina/Salta"           , 0x00637D },
-	{ (char*) "America/Argentina/San_Juan"        , 0x006651 },
-	{ (char*) "America/Argentina/San_Luis"        , 0x006937 },
-	{ (char*) "America/Argentina/Tucuman"         , 0x006C1D },
-	{ (char*) "America/Argentina/Ushuaia"         , 0x006F0B },
-	{ (char*) "America/Aruba"                     , 0x0071F0 },
-	{ (char*) "America/Asuncion"                  , 0x007293 },
-	{ (char*) "America/Atikokan"                  , 0x0076DC },
-	{ (char*) "America/Atka"                      , 0x0077E9 },
-	{ (char*) "America/Bahia"                     , 0x007BBE },
-	{ (char*) "America/Bahia_Banderas"            , 0x007E79 },
-	{ (char*) "America/Barbados"                  , 0x008152 },
-	{ (char*) "America/Belem"                     , 0x008274 },
-	{ (char*) "America/Belize"                    , 0x00841C },
-	{ (char*) "America/Blanc-Sablon"              , 0x00883D },
-	{ (char*) "America/Boa_Vista"                 , 0x008932 },
-	{ (char*) "America/Bogota"                    , 0x008AF3 },
-	{ (char*) "America/Boise"                     , 0x008BB2 },
-	{ (char*) "America/Buenos_Aires"              , 0x008FC5 },
-	{ (char*) "America/Cambridge_Bay"             , 0x009295 },
-	{ (char*) "America/Campo_Grande"              , 0x009628 },
-	{ (char*) "America/Cancun"                    , 0x0099FE },
-	{ (char*) "America/Caracas"                   , 0x009C30 },
-	{ (char*) "America/Catamarca"                 , 0x009CFA },
-	{ (char*) "America/Cayenne"                   , 0x009FCA },
-	{ (char*) "America/Cayman"                    , 0x00A06D },
-	{ (char*) "America/Chicago"                   , 0x00A10E },
-	{ (char*) "America/Chihuahua"                 , 0x00A808 },
-	{ (char*) "America/Ciudad_Juarez"             , 0x00AADD },
-	{ (char*) "America/Coral_Harbour"             , 0x00ADD3 },
-	{ (char*) "America/Cordoba"                   , 0x00AE74 },
-	{ (char*) "America/Costa_Rica"                , 0x00B144 },
-	{ (char*) "America/Coyhaique"                 , 0x00B238 },
-	{ (char*) "America/Creston"                   , 0x00B7A2 },
-	{ (char*) "America/Cuiaba"                    , 0x00B85E },
-	{ (char*) "America/Curacao"                   , 0x00BC1B },
-	{ (char*) "America/Danmarkshavn"              , 0x00BCBE },
-	{ (char*) "America/Dawson"                    , 0x00BEA3 },
-	{ (char*) "America/Dawson_Creek"              , 0x00C2C6 },
-	{ (char*) "America/Denver"                    , 0x00C59D },
-	{ (char*) "America/Detroit"                   , 0x00C9D0 },
-	{ (char*) "America/Dominica"                  , 0x00CD78 },
-	{ (char*) "America/Edmonton"                  , 0x00CE06 },
-	{ (char*) "America/Eirunepe"                  , 0x00D1FE },
-	{ (char*) "America/El_Salvador"               , 0x00D3CD },
-	{ (char*) "America/Ensenada"                  , 0x00D489 },
-	{ (char*) "America/Fort_Nelson"               , 0x00D9EC },
-	{ (char*) "America/Fort_Wayne"                , 0x00DFB4 },
-	{ (char*) "America/Fortaleza"                 , 0x00E1D3 },
-	{ (char*) "America/Glace_Bay"                 , 0x00E3E9 },
-	{ (char*) "America/Godthab"                   , 0x00E780 },
-	{ (char*) "America/Goose_Bay"                 , 0x00EB51 },
-	{ (char*) "America/Grand_Turk"                , 0x00F1A9 },
-	{ (char*) "America/Grenada"                   , 0x00F50A },
-	{ (char*) "America/Guadeloupe"                , 0x00F598 },
-	{ (char*) "America/Guatemala"                 , 0x00F626 },
-	{ (char*) "America/Guayaquil"                 , 0x00F706 },
-	{ (char*) "America/Guyana"                    , 0x00F7D7 },
-	{ (char*) "America/Halifax"                   , 0x00F898 },
-	{ (char*) "America/Havana"                    , 0x00FF4A },
-	{ (char*) "America/Hermosillo"                , 0x0103B3 },
-	{ (char*) "America/Indiana/Indianapolis"      , 0x0104C7 },
-	{ (char*) "America/Indiana/Knox"              , 0x0106FF },
-	{ (char*) "America/Indiana/Marengo"           , 0x010B18 },
-	{ (char*) "America/Indiana/Petersburg"        , 0x010D72 },
-	{ (char*) "America/Indiana/Tell_City"         , 0x01103C },
-	{ (char*) "America/Indiana/Vevay"             , 0x011266 },
-	{ (char*) "America/Indiana/Vincennes"         , 0x0113FD },
-	{ (char*) "America/Indiana/Winamac"           , 0x011653 },
-	{ (char*) "America/Indianapolis"              , 0x0118D0 },
-	{ (char*) "America/Inuvik"                    , 0x011AEF },
-	{ (char*) "America/Iqaluit"                   , 0x011E40 },
-	{ (char*) "America/Jamaica"                   , 0x0121BC },
-	{ (char*) "America/Jujuy"                     , 0x01231B },
-	{ (char*) "America/Juneau"                    , 0x0125D9 },
-	{ (char*) "America/Kentucky/Louisville"       , 0x0129BF },
-	{ (char*) "America/Kentucky/Monticello"       , 0x012EC3 },
-	{ (char*) "America/Knox_IN"                   , 0x0132AF },
-	{ (char*) "America/Kralendijk"                , 0x0136B3 },
-	{ (char*) "America/La_Paz"                    , 0x013770 },
-	{ (char*) "America/Lima"                      , 0x013826 },
-	{ (char*) "America/Los_Angeles"               , 0x01394D },
-	{ (char*) "America/Louisville"                , 0x013E6E },
-	{ (char*) "America/Lower_Princes"             , 0x014354 },
-	{ (char*) "America/Maceio"                    , 0x014411 },
-	{ (char*) "America/Managua"                   , 0x014623 },
-	{ (char*) "America/Manaus"                    , 0x014756 },
-	{ (char*) "America/Marigot"                   , 0x01490D },
-	{ (char*) "America/Martinique"                , 0x0149CA },
-	{ (char*) "America/Matamoros"                 , 0x014A88 },
-	{ (char*) "America/Mazatlan"                  , 0x014C75 },
-	{ (char*) "America/Mendoza"                   , 0x014F65 },
-	{ (char*) "America/Menominee"                 , 0x015235 },
-	{ (char*) "America/Merida"                    , 0x0155F5 },
-	{ (char*) "America/Metlakatla"                , 0x0158A0 },
-	{ (char*) "America/Mexico_City"               , 0x015B0D },
-	{ (char*) "America/Miquelon"                  , 0x015E2C },
-	{ (char*) "America/Moncton"                   , 0x01605E },
-	{ (char*) "America/Monterrey"                 , 0x016657 },
-	{ (char*) "America/Montevideo"                , 0x01695E },
-	{ (char*) "America/Montreal"                  , 0x016D33 },
-	{ (char*) "America/Montserrat"                , 0x0173F4 },
-	{ (char*) "America/Nassau"                    , 0x017482 },
-	{ (char*) "America/New_York"                  , 0x01787C },
-	{ (char*) "America/Nipigon"                   , 0x017F6C },
-	{ (char*) "America/Nome"                      , 0x01862D },
-	{ (char*) "America/Noronha"                   , 0x018A15 },
-	{ (char*) "America/North_Dakota/Beulah"       , 0x018C15 },
-	{ (char*) "America/North_Dakota/Center"       , 0x019049 },
-	{ (char*) "America/North_Dakota/New_Salem"    , 0x019448 },
-	{ (char*) "America/Nuuk"                      , 0x01984D },
-	{ (char*) "America/Ojinaga"                   , 0x019C2F },
-	{ (char*) "America/Panama"                    , 0x019F25 },
-	{ (char*) "America/Pangnirtung"               , 0x019FC6 },
-	{ (char*) "America/Paramaribo"                , 0x01A329 },
-	{ (char*) "America/Phoenix"                   , 0x01A3F0 },
-	{ (char*) "America/Port-au-Prince"            , 0x01A504 },
-	{ (char*) "America/Port_of_Spain"             , 0x01A745 },
-	{ (char*) "America/Porto_Acre"                , 0x01A7D3 },
-	{ (char*) "America/Porto_Velho"               , 0x01A981 },
-	{ (char*) "America/Puerto_Rico"               , 0x01AB1F },
-	{ (char*) "America/Punta_Arenas"              , 0x01ABDC },
-	{ (char*) "America/Rainy_River"               , 0x01B0BB },
-	{ (char*) "America/Rankin_Inlet"              , 0x01B5D5 },
-	{ (char*) "America/Recife"                    , 0x01B91E },
-	{ (char*) "America/Regina"                    , 0x01BB18 },
-	{ (char*) "America/Resolute"                  , 0x01BDB7 },
-	{ (char*) "America/Rio_Branco"                , 0x01C101 },
-	{ (char*) "America/Rosario"                   , 0x01C2B3 },
-	{ (char*) "America/Santa_Isabel"              , 0x01C583 },
-	{ (char*) "America/Santarem"                  , 0x01CAE6 },
-	{ (char*) "America/Santiago"                  , 0x01CC96 },
-	{ (char*) "America/Santo_Domingo"             , 0x01D1F9 },
-	{ (char*) "America/Sao_Paulo"                 , 0x01D342 },
-	{ (char*) "America/Scoresbysund"              , 0x01D73C },
-	{ (char*) "America/Shiprock"                  , 0x01DB3D },
-	{ (char*) "America/Sitka"                     , 0x01DF5B },
-	{ (char*) "America/St_Barthelemy"             , 0x01E336 },
-	{ (char*) "America/St_Johns"                  , 0x01E3F3 },
-	{ (char*) "America/St_Kitts"                  , 0x01EB70 },
-	{ (char*) "America/St_Lucia"                  , 0x01EBFE },
-	{ (char*) "America/St_Thomas"                 , 0x01EC9F },
-	{ (char*) "America/St_Vincent"                , 0x01ED2D },
-	{ (char*) "America/Swift_Current"             , 0x01EDCE },
-	{ (char*) "America/Tegucigalpa"               , 0x01EF5C },
-	{ (char*) "America/Thule"                     , 0x01F02A },
-	{ (char*) "America/Thunder_Bay"               , 0x01F20B },
-	{ (char*) "America/Tijuana"                   , 0x01F8CC },
-	{ (char*) "America/Toronto"                   , 0x01FE3E },
-	{ (char*) "America/Tortola"                   , 0x02051D },
-	{ (char*) "America/Vancouver"                 , 0x0205AB },
-	{ (char*) "America/Virgin"                    , 0x020B02 },
-	{ (char*) "America/Whitehorse"                , 0x020BBF },
-	{ (char*) "America/Winnipeg"                  , 0x020FE2 },
-	{ (char*) "America/Yakutat"                   , 0x021519 },
-	{ (char*) "America/Yellowknife"               , 0x0218E7 },
-	{ (char*) "Antarctica/Casey"                  , 0x021CBD },
-	{ (char*) "Antarctica/Davis"                  , 0x021DED },
-	{ (char*) "Antarctica/DumontDUrville"         , 0x021EC3 },
-	{ (char*) "Antarctica/Macquarie"              , 0x021F77 },
-	{ (char*) "Antarctica/Mawson"                 , 0x022363 },
-	{ (char*) "Antarctica/McMurdo"                , 0x02240D },
-	{ (char*) "Antarctica/Palmer"                 , 0x02273F },
-	{ (char*) "Antarctica/Rothera"                , 0x022AC8 },
-	{ (char*) "Antarctica/South_Pole"             , 0x022B5F },
-	{ (char*) "Antarctica/Syowa"                  , 0x022F7E },
-	{ (char*) "Antarctica/Troll"                  , 0x023014 },
-	{ (char*) "Antarctica/Vostok"                 , 0x0230C3 },
-	{ (char*) "Arctic/Longyearbyen"               , 0x02317F },
-	{ (char*) "Asia/Aden"                         , 0x02344C },
-	{ (char*) "Asia/Almaty"                       , 0x0234DD },
-	{ (char*) "Asia/Amman"                        , 0x023765 },
-	{ (char*) "Asia/Anadyr"                       , 0x023B11 },
-	{ (char*) "Asia/Aqtau"                        , 0x023E17 },
-	{ (char*) "Asia/Aqtobe"                       , 0x024096 },
-	{ (char*) "Asia/Ashgabat"                     , 0x024316 },
-	{ (char*) "Asia/Ashkhabad"                    , 0x024499 },
-	{ (char*) "Asia/Atyrau"                       , 0x02461C },
-	{ (char*) "Asia/Baghdad"                      , 0x0248A5 },
-	{ (char*) "Asia/Bahrain"                      , 0x024B27 },
-	{ (char*) "Asia/Baku"                         , 0x024BE0 },
-	{ (char*) "Asia/Bangkok"                      , 0x024ED4 },
-	{ (char*) "Asia/Barnaul"                      , 0x024F78 },
-	{ (char*) "Asia/Beirut"                       , 0x025283 },
-	{ (char*) "Asia/Bishkek"                      , 0x02556B },
-	{ (char*) "Asia/Brunei"                       , 0x0257E1 },
-	{ (char*) "Asia/Calcutta"                     , 0x025887 },
-	{ (char*) "Asia/Chita"                        , 0x02596F },
-	{ (char*) "Asia/Choibalsan"                   , 0x025C7D },
-	{ (char*) "Asia/Chongqing"                    , 0x025EDB },
-	{ (char*) "Asia/Chungking"                    , 0x026070 },
-	{ (char*) "Asia/Colombo"                      , 0x026205 },
-	{ (char*) "Asia/Dacca"                        , 0x026308 },
-	{ (char*) "Asia/Damascus"                     , 0x0263FB },
-	{ (char*) "Asia/Dhaka"                        , 0x0268D9 },
-	{ (char*) "Asia/Dili"                         , 0x0269CC },
-	{ (char*) "Asia/Dubai"                        , 0x026A82 },
-	{ (char*) "Asia/Dushanbe"                     , 0x026B13 },
-	{ (char*) "Asia/Famagusta"                    , 0x026C8D },
-	{ (char*) "Asia/Gaza"                         , 0x027054 },
-	{ (char*) "Asia/Harbin"                       , 0x027BF0 },
-	{ (char*) "Asia/Hebron"                       , 0x027D85 },
-	{ (char*) "Asia/Ho_Chi_Minh"                  , 0x028932 },
-	{ (char*) "Asia/Hong_Kong"                    , 0x028A2A },
-	{ (char*) "Asia/Hovd"                         , 0x028D3D },
-	{ (char*) "Asia/Irkutsk"                      , 0x028FB1 },
-	{ (char*) "Asia/Istanbul"                     , 0x0292CF },
-	{ (char*) "Asia/Jakarta"                      , 0x02978B },
-	{ (char*) "Asia/Jayapura"                     , 0x02989C },
-	{ (char*) "Asia/Jerusalem"                    , 0x029989 },
-	{ (char*) "Asia/Kabul"                        , 0x029DC7 },
-	{ (char*) "Asia/Kamchatka"                    , 0x029E72 },
-	{ (char*) "Asia/Karachi"                      , 0x02A167 },
-	{ (char*) "Asia/Kashgar"                      , 0x02A27D },
-	{ (char*) "Asia/Kathmandu"                    , 0x02A30E },
-	{ (char*) "Asia/Katmandu"                     , 0x02A3BB },
-	{ (char*) "Asia/Khandyga"                     , 0x02A468 },
-	{ (char*) "Asia/Kolkata"                      , 0x02A799 },
-	{ (char*) "Asia/Krasnoyarsk"                  , 0x02A881 },
-	{ (char*) "Asia/Kuala_Lumpur"                 , 0x02AB8B },
-	{ (char*) "Asia/Kuching"                      , 0x02ACAB },
-	{ (char*) "Asia/Kuwait"                       , 0x02AE05 },
-	{ (char*) "Asia/Macao"                        , 0x02AE96 },
-	{ (char*) "Asia/Macau"                        , 0x02B1B9 },
-	{ (char*) "Asia/Magadan"                      , 0x02B4DC },
-	{ (char*) "Asia/Makassar"                     , 0x02B7E7 },
-	{ (char*) "Asia/Manila"                       , 0x02B8FA },
-	{ (char*) "Asia/Muscat"                       , 0x02BA18 },
-	{ (char*) "Asia/Nicosia"                      , 0x02BAA9 },
-	{ (char*) "Asia/Novokuznetsk"                 , 0x02BD18 },
-	{ (char*) "Asia/Novosibirsk"                  , 0x02C00B },
-	{ (char*) "Asia/Omsk"                         , 0x02C31C },
-	{ (char*) "Asia/Oral"                         , 0x02C61A },
-	{ (char*) "Asia/Phnom_Penh"                   , 0x02C8A6 },
-	{ (char*) "Asia/Pontianak"                    , 0x02C97A },
-	{ (char*) "Asia/Pyongyang"                    , 0x02CA93 },
-	{ (char*) "Asia/Qatar"                        , 0x02CB56 },
-	{ (char*) "Asia/Qostanay"                     , 0x02CBFA },
-	{ (char*) "Asia/Qyzylorda"                    , 0x02CE90 },
-	{ (char*) "Asia/Rangoon"                      , 0x02D129 },
-	{ (char*) "Asia/Riyadh"                       , 0x02D1F0 },
-	{ (char*) "Asia/Saigon"                       , 0x02D281 },
-	{ (char*) "Asia/Sakhalin"                     , 0x02D379 },
-	{ (char*) "Asia/Samarkand"                    , 0x02D690 },
-	{ (char*) "Asia/Seoul"                        , 0x02D81B },
-	{ (char*) "Asia/Shanghai"                     , 0x02D9C6 },
-	{ (char*) "Asia/Singapore"                    , 0x02DB67 },
-	{ (char*) "Asia/Srednekolymsk"                , 0x02DC73 },
-	{ (char*) "Asia/Taipei"                       , 0x02DF83 },
-	{ (char*) "Asia/Tashkent"                     , 0x02E18E },
-	{ (char*) "Asia/Tbilisi"                      , 0x02E319 },
-	{ (char*) "Asia/Tehran"                       , 0x02E591 },
-	{ (char*) "Asia/Tel_Aviv"                     , 0x02E8C9 },
-	{ (char*) "Asia/Thimbu"                       , 0x02ED07 },
-	{ (char*) "Asia/Thimphu"                      , 0x02EDAD },
-	{ (char*) "Asia/Tokyo"                        , 0x02EE53 },
-	{ (char*) "Asia/Tomsk"                        , 0x02EF34 },
-	{ (char*) "Asia/Ujung_Pandang"                , 0x02F23F },
-	{ (char*) "Asia/Ulaanbaatar"                  , 0x02F309 },
-	{ (char*) "Asia/Ulan_Bator"                   , 0x02F577 },
-	{ (char*) "Asia/Urumqi"                       , 0x02F7D5 },
-	{ (char*) "Asia/Ust-Nera"                     , 0x02F873 },
-	{ (char*) "Asia/Vientiane"                    , 0x02FB96 },
-	{ (char*) "Asia/Vladivostok"                  , 0x02FC7C },
-	{ (char*) "Asia/Yakutsk"                      , 0x02FF81 },
-	{ (char*) "Asia/Yangon"                       , 0x030285 },
-	{ (char*) "Asia/Yekaterinburg"                , 0x03034C },
-	{ (char*) "Asia/Yerevan"                      , 0x03065E },
-	{ (char*) "Atlantic/Azores"                   , 0x03092E },
-	{ (char*) "Atlantic/Bermuda"                  , 0x030EB9 },
-	{ (char*) "Atlantic/Canary"                   , 0x0312C5 },
-	{ (char*) "Atlantic/Cape_Verde"               , 0x0314BD },
-	{ (char*) "Atlantic/Faeroe"                   , 0x031578 },
-	{ (char*) "Atlantic/Faroe"                    , 0x03173D },
-	{ (char*) "Atlantic/Jan_Mayen"                , 0x031902 },
-	{ (char*) "Atlantic/Madeira"                  , 0x031BCF },
-	{ (char*) "Atlantic/Reykjavik"                , 0x032146 },
-	{ (char*) "Atlantic/South_Georgia"            , 0x032443 },
-	{ (char*) "Atlantic/St_Helena"                , 0x0324D3 },
-	{ (char*) "Atlantic/Stanley"                  , 0x032574 },
-	{ (char*) "Australia/ACT"                     , 0x032895 },
-	{ (char*) "Australia/Adelaide"                , 0x032C29 },
-	{ (char*) "Australia/Brisbane"                , 0x032FDD },
-	{ (char*) "Australia/Broken_Hill"             , 0x033121 },
-	{ (char*) "Australia/Canberra"                , 0x0334F6 },
-	{ (char*) "Australia/Currie"                  , 0x03388A },
-	{ (char*) "Australia/Darwin"                  , 0x033C81 },
-	{ (char*) "Australia/Eucla"                   , 0x033D89 },
-	{ (char*) "Australia/Hobart"                  , 0x033EE8 },
-	{ (char*) "Australia/LHI"                     , 0x0342E7 },
-	{ (char*) "Australia/Lindeman"                , 0x0345A7 },
-	{ (char*) "Australia/Lord_Howe"               , 0x034717 },
-	{ (char*) "Australia/Melbourne"               , 0x0349E7 },
-	{ (char*) "Australia/North"                   , 0x034D83 },
-	{ (char*) "Australia/NSW"                     , 0x034E79 },
-	{ (char*) "Australia/Perth"                   , 0x03520D },
-	{ (char*) "Australia/Queensland"              , 0x035369 },
-	{ (char*) "Australia/South"                   , 0x035496 },
-	{ (char*) "Australia/Sydney"                  , 0x03583B },
-	{ (char*) "Australia/Tasmania"                , 0x035BEB },
-	{ (char*) "Australia/Victoria"                , 0x035FE2 },
-	{ (char*) "Australia/West"                    , 0x036376 },
-	{ (char*) "Australia/Yancowinna"              , 0x0364B4 },
-	{ (char*) "Brazil/Acre"                       , 0x03686D },
-	{ (char*) "Brazil/DeNoronha"                  , 0x036A1B },
-	{ (char*) "Brazil/East"                       , 0x036C0B },
-	{ (char*) "Brazil/West"                       , 0x036FCF },
-	{ (char*) "Canada/Atlantic"                   , 0x037177 },
-	{ (char*) "Canada/Central"                    , 0x03780B },
-	{ (char*) "Canada/Eastern"                    , 0x037D25 },
-	{ (char*) "Canada/Mountain"                   , 0x0383E6 },
-	{ (char*) "Canada/Newfoundland"               , 0x0387BC },
-	{ (char*) "Canada/Pacific"                    , 0x038F1E },
-	{ (char*) "Canada/Saskatchewan"               , 0x03945C },
-	{ (char*) "Canada/Yukon"                      , 0x0396E6 },
-	{ (char*) "CET"                               , 0x039AF7 },
-	{ (char*) "Chile/Continental"                 , 0x039F52 },
-	{ (char*) "Chile/EasterIsland"                , 0x03A4A8 },
-	{ (char*) "CST6CDT"                           , 0x03A94A },
-	{ (char*) "Cuba"                              , 0x03B030 },
-	{ (char*) "EET"                               , 0x03B499 },
-	{ (char*) "Egypt"                             , 0x03B74F },
-	{ (char*) "Eire"                              , 0x03BC78 },
-	{ (char*) "EST"                               , 0x03C25C },
-	{ (char*) "EST5EDT"                           , 0x03C2FD },
-	{ (char*) "Etc/GMT"                           , 0x03C9D9 },
-	{ (char*) "Etc/GMT+0"                         , 0x03CA54 },
-	{ (char*) "Etc/GMT+1"                         , 0x03CACF },
-	{ (char*) "Etc/GMT+10"                        , 0x03CB4C },
-	{ (char*) "Etc/GMT+11"                        , 0x03CBCA },
-	{ (char*) "Etc/GMT+12"                        , 0x03CC48 },
-	{ (char*) "Etc/GMT+2"                         , 0x03CCC6 },
-	{ (char*) "Etc/GMT+3"                         , 0x03CD43 },
-	{ (char*) "Etc/GMT+4"                         , 0x03CDC0 },
-	{ (char*) "Etc/GMT+5"                         , 0x03CE3D },
-	{ (char*) "Etc/GMT+6"                         , 0x03CEBA },
-	{ (char*) "Etc/GMT+7"                         , 0x03CF37 },
-	{ (char*) "Etc/GMT+8"                         , 0x03CFB4 },
-	{ (char*) "Etc/GMT+9"                         , 0x03D031 },
-	{ (char*) "Etc/GMT-0"                         , 0x03D0AE },
-	{ (char*) "Etc/GMT-1"                         , 0x03D129 },
-	{ (char*) "Etc/GMT-10"                        , 0x03D1A7 },
-	{ (char*) "Etc/GMT-11"                        , 0x03D226 },
-	{ (char*) "Etc/GMT-12"                        , 0x03D2A5 },
-	{ (char*) "Etc/GMT-13"                        , 0x03D324 },
-	{ (char*) "Etc/GMT-14"                        , 0x03D3A3 },
-	{ (char*) "Etc/GMT-2"                         , 0x03D422 },
-	{ (char*) "Etc/GMT-3"                         , 0x03D4A0 },
-	{ (char*) "Etc/GMT-4"                         , 0x03D51E },
-	{ (char*) "Etc/GMT-5"                         , 0x03D59C },
-	{ (char*) "Etc/GMT-6"                         , 0x03D61A },
-	{ (char*) "Etc/GMT-7"                         , 0x03D698 },
-	{ (char*) "Etc/GMT-8"                         , 0x03D716 },
-	{ (char*) "Etc/GMT-9"                         , 0x03D794 },
-	{ (char*) "Etc/GMT0"                          , 0x03D812 },
-	{ (char*) "Etc/Greenwich"                     , 0x03D88D },
-	{ (char*) "Etc/UCT"                           , 0x03D908 },
-	{ (char*) "Etc/Universal"                     , 0x03D983 },
-	{ (char*) "Etc/UTC"                           , 0x03D9FE },
-	{ (char*) "Etc/Zulu"                          , 0x03DA79 },
-	{ (char*) "Europe/Amsterdam"                  , 0x03DAF4 },
-	{ (char*) "Europe/Andorra"                    , 0x03DF2F },
-	{ (char*) "Europe/Astrakhan"                  , 0x03E0C0 },
-	{ (char*) "Europe/Athens"                     , 0x03E3B4 },
-	{ (char*) "Europe/Belfast"                    , 0x03E66A },
-	{ (char*) "Europe/Belgrade"                   , 0x03ECB5 },
-	{ (char*) "Europe/Berlin"                     , 0x03EE9F },
-	{ (char*) "Europe/Bratislava"                 , 0x03F17B },
-	{ (char*) "Europe/Brussels"                   , 0x03F45A },
-	{ (char*) "Europe/Bucharest"                  , 0x03F8B5 },
-	{ (char*) "Europe/Budapest"                   , 0x03FB56 },
-	{ (char*) "Europe/Busingen"                   , 0x03FE60 },
-	{ (char*) "Europe/Chisinau"                   , 0x040065 },
-	{ (char*) "Europe/Copenhagen"                 , 0x040528 },
-	{ (char*) "Europe/Dublin"                     , 0x0407A3 },
-	{ (char*) "Europe/Gibraltar"                  , 0x040D87 },
-	{ (char*) "Europe/Guernsey"                   , 0x041257 },
-	{ (char*) "Europe/Helsinki"                   , 0x0418AE },
-	{ (char*) "Europe/Isle_of_Man"                , 0x041A9B },
-	{ (char*) "Europe/Istanbul"                   , 0x0420E6 },
-	{ (char*) "Europe/Jersey"                     , 0x0425A2 },
-	{ (char*) "Europe/Kaliningrad"                , 0x042BF9 },
-	{ (char*) "Europe/Kiev"                       , 0x042FA1 },
-	{ (char*) "Europe/Kirov"                      , 0x0431DB },
-	{ (char*) "Europe/Kyiv"                       , 0x0434D4 },
-	{ (char*) "Europe/Lisbon"                     , 0x04371D },
-	{ (char*) "Europe/Ljubljana"                  , 0x043CF3 },
-	{ (char*) "Europe/London"                     , 0x043EDD },
-	{ (char*) "Europe/Luxembourg"                 , 0x044528 },
-	{ (char*) "Europe/Madrid"                     , 0x044973 },
-	{ (char*) "Europe/Malta"                      , 0x044D10 },
-	{ (char*) "Europe/Mariehamn"                  , 0x0450BC },
-	{ (char*) "Europe/Minsk"                      , 0x0452A9 },
-	{ (char*) "Europe/Monaco"                     , 0x0455DD },
-	{ (char*) "Europe/Moscow"                     , 0x045A43 },
-	{ (char*) "Europe/Nicosia"                    , 0x045DEF },
-	{ (char*) "Europe/Oslo"                       , 0x046050 },
-	{ (char*) "Europe/Paris"                      , 0x046300 },
-	{ (char*) "Europe/Podgorica"                  , 0x04675D },
-	{ (char*) "Europe/Prague"                     , 0x046947 },
-	{ (char*) "Europe/Riga"                       , 0x046C26 },
-	{ (char*) "Europe/Rome"                       , 0x046EE8 },
-	{ (char*) "Europe/Samara"                     , 0x0472A7 },
-	{ (char*) "Europe/San_Marino"                 , 0x0475A8 },
-	{ (char*) "Europe/Sarajevo"                   , 0x047967 },
-	{ (char*) "Europe/Saratov"                    , 0x047B51 },
-	{ (char*) "Europe/Simferopol"                 , 0x047E43 },
-	{ (char*) "Europe/Skopje"                     , 0x0481B6 },
-	{ (char*) "Europe/Sofia"                      , 0x0483A0 },
-	{ (char*) "Europe/Stockholm"                  , 0x0485FC },
-	{ (char*) "Europe/Tallinn"                    , 0x0487F9 },
-	{ (char*) "Europe/Tirane"                     , 0x048AA8 },
-	{ (char*) "Europe/Tiraspol"                   , 0x048D10 },
-	{ (char*) "Europe/Ulyanovsk"                  , 0x0491D3 },
-	{ (char*) "Europe/Uzhgorod"                   , 0x0494E9 },
-	{ (char*) "Europe/Vaduz"                      , 0x049723 },
-	{ (char*) "Europe/Vatican"                    , 0x04990D },
-	{ (char*) "Europe/Vienna"                     , 0x049CCC },
-	{ (char*) "Europe/Vilnius"                    , 0x049F6A },
-	{ (char*) "Europe/Volgograd"                  , 0x04A21A },
-	{ (char*) "Europe/Warsaw"                     , 0x04A529 },
-	{ (char*) "Europe/Zagreb"                     , 0x04A8D0 },
-	{ (char*) "Europe/Zaporozhye"                 , 0x04AABA },
-	{ (char*) "Europe/Zurich"                     , 0x04ACF4 },
-	{ (char*) "Factory"                           , 0x04AEF1 },
-	{ (char*) "GB"                                , 0x04AF6E },
-	{ (char*) "GB-Eire"                           , 0x04B5B9 },
-	{ (char*) "GMT"                               , 0x04BC04 },
-	{ (char*) "GMT+0"                             , 0x04BC7F },
-	{ (char*) "GMT-0"                             , 0x04BCFA },
-	{ (char*) "GMT0"                              , 0x04BD75 },
-	{ (char*) "Greenwich"                         , 0x04BDF0 },
-	{ (char*) "Hongkong"                          , 0x04BE6B },
-	{ (char*) "HST"                               , 0x04C17E },
-	{ (char*) "Iceland"                           , 0x04C267 },
-	{ (char*) "Indian/Antananarivo"               , 0x04C2F5 },
-	{ (char*) "Indian/Chagos"                     , 0x04C3A1 },
-	{ (char*) "Indian/Christmas"                  , 0x04C445 },
-	{ (char*) "Indian/Cocos"                      , 0x04C4D6 },
-	{ (char*) "Indian/Comoro"                     , 0x04C56E },
-	{ (char*) "Indian/Kerguelen"                  , 0x04C5FD },
-	{ (char*) "Indian/Mahe"                       , 0x04C68E },
-	{ (char*) "Indian/Maldives"                   , 0x04C71F },
-	{ (char*) "Indian/Mauritius"                  , 0x04C7C3 },
-	{ (char*) "Indian/Mayotte"                    , 0x04C882 },
-	{ (char*) "Indian/Reunion"                    , 0x04C911 },
-	{ (char*) "Iran"                              , 0x04C9A2 },
-	{ (char*) "Israel"                            , 0x04CCDA },
-	{ (char*) "Jamaica"                           , 0x04D118 },
-	{ (char*) "Japan"                             , 0x04D277 },
-	{ (char*) "Kwajalein"                         , 0x04D358 },
-	{ (char*) "Libya"                             , 0x04D43F },
-	{ (char*) "MET"                               , 0x04D5FA },
-	{ (char*) "Mexico/BajaNorte"                  , 0x04DA55 },
-	{ (char*) "Mexico/BajaSur"                    , 0x04DFB8 },
-	{ (char*) "Mexico/General"                    , 0x04E276 },
-	{ (char*) "MST"                               , 0x04E587 },
-	{ (char*) "MST7MDT"                           , 0x04E683 },
-	{ (char*) "Navajo"                            , 0x04EAA1 },
-	{ (char*) "NZ"                                , 0x04EEBF },
-	{ (char*) "NZ-CHAT"                           , 0x04F2DE },
-	{ (char*) "Pacific/Apia"                      , 0x04F612 },
-	{ (char*) "Pacific/Auckland"                  , 0x04F7B5 },
-	{ (char*) "Pacific/Bougainville"              , 0x04FBE7 },
-	{ (char*) "Pacific/Chatham"                   , 0x04FCC8 },
-	{ (char*) "Pacific/Chuuk"                     , 0x05000B },
-	{ (char*) "Pacific/Easter"                    , 0x0500E9 },
-	{ (char*) "Pacific/Efate"                     , 0x050598 },
-	{ (char*) "Pacific/Enderbury"                 , 0x0506FA },
-	{ (char*) "Pacific/Fakaofo"                   , 0x0507B2 },
-	{ (char*) "Pacific/Fiji"                      , 0x050857 },
-	{ (char*) "Pacific/Funafuti"                  , 0x0509EF },
-	{ (char*) "Pacific/Galapagos"                 , 0x050A81 },
-	{ (char*) "Pacific/Gambier"                   , 0x050B4D },
-	{ (char*) "Pacific/Guadalcanal"               , 0x050BEC },
-	{ (char*) "Pacific/Guam"                      , 0x050C7E },
-	{ (char*) "Pacific/Honolulu"                  , 0x050DE8 },
-	{ (char*) "Pacific/Johnston"                  , 0x050ED7 },
-	{ (char*) "Pacific/Kanton"                    , 0x050FC0 },
-	{ (char*) "Pacific/Kiritimati"                , 0x051087 },
-	{ (char*) "Pacific/Kosrae"                    , 0x05114D },
-	{ (char*) "Pacific/Kwajalein"                 , 0x051251 },
-	{ (char*) "Pacific/Majuro"                    , 0x051341 },
-	{ (char*) "Pacific/Marquesas"                 , 0x05143F },
-	{ (char*) "Pacific/Midway"                    , 0x0514E7 },
-	{ (char*) "Pacific/Nauru"                     , 0x0515AA },
-	{ (char*) "Pacific/Niue"                      , 0x05166D },
-	{ (char*) "Pacific/Norfolk"                   , 0x051713 },
-	{ (char*) "Pacific/Noumea"                    , 0x05180C },
-	{ (char*) "Pacific/Pago_Pago"                 , 0x0518DE },
-	{ (char*) "Pacific/Palau"                     , 0x05197C },
-	{ (char*) "Pacific/Pitcairn"                  , 0x051A1C },
-	{ (char*) "Pacific/Pohnpei"                   , 0x051AC1 },
-	{ (char*) "Pacific/Ponape"                    , 0x051BB1 },
-	{ (char*) "Pacific/Port_Moresby"              , 0x051C43 },
-	{ (char*) "Pacific/Rarotonga"                 , 0x051D01 },
-	{ (char*) "Pacific/Saipan"                    , 0x051EA3 },
-	{ (char*) "Pacific/Samoa"                     , 0x052004 },
-	{ (char*) "Pacific/Tahiti"                    , 0x0520A2 },
-	{ (char*) "Pacific/Tarawa"                    , 0x052142 },
-	{ (char*) "Pacific/Tongatapu"                 , 0x0521E3 },
-	{ (char*) "Pacific/Truk"                      , 0x0522DC },
-	{ (char*) "Pacific/Wake"                      , 0x052382 },
-	{ (char*) "Pacific/Wallis"                    , 0x05241F },
-	{ (char*) "Pacific/Yap"                       , 0x0524B1 },
-	{ (char*) "Poland"                            , 0x052557 },
-	{ (char*) "Portugal"                          , 0x0528FE },
-	{ (char*) "PRC"                               , 0x052EC1 },
-	{ (char*) "PST8PDT"                           , 0x053056 },
-	{ (char*) "ROC"                               , 0x053570 },
-	{ (char*) "ROK"                               , 0x05377B },
-	{ (char*) "Singapore"                         , 0x053926 },
-	{ (char*) "Turkey"                            , 0x053A32 },
-	{ (char*) "UCT"                               , 0x053EEE },
-	{ (char*) "Universal"                         , 0x053F69 },
-	{ (char*) "US/Alaska"                         , 0x053FE4 },
-	{ (char*) "US/Aleutian"                       , 0x0543C1 },
-	{ (char*) "US/Arizona"                        , 0x054796 },
-	{ (char*) "US/Central"                        , 0x054892 },
-	{ (char*) "US/East-Indiana"                   , 0x054F78 },
-	{ (char*) "US/Eastern"                        , 0x055197 },
-	{ (char*) "US/Hawaii"                         , 0x055873 },
-	{ (char*) "US/Indiana-Starke"                 , 0x05595C },
-	{ (char*) "US/Michigan"                       , 0x055D60 },
-	{ (char*) "US/Mountain"                       , 0x0560EF },
-	{ (char*) "US/Pacific"                        , 0x05650D },
-	{ (char*) "US/Samoa"                          , 0x056A27 },
-	{ (char*) "UTC"                               , 0x056AC5 },
-	{ (char*) "W-SU"                              , 0x056B40 },
-	{ (char*) "WET"                               , 0x056ED8 },
-	{ (char*) "Zulu"                              , 0x05749B },
+	{ (char*) "Africa/Ceuta"                      , 0x001407 },
+	{ (char*) "Africa/Conakry"                    , 0x001653 },
+	{ (char*) "Africa/Dakar"                      , 0x0016FD },
+	{ (char*) "Africa/Dar_es_Salaam"              , 0x00179E },
+	{ (char*) "Africa/Djibouti"                   , 0x00184B },
+	{ (char*) "Africa/Douala"                     , 0x0018DA },
+	{ (char*) "Africa/El_Aaiun"                   , 0x001969 },
+	{ (char*) "Africa/Freetown"                   , 0x001C35 },
+	{ (char*) "Africa/Gaborone"                   , 0x001D85 },
+	{ (char*) "Africa/Harare"                     , 0x001E45 },
+	{ (char*) "Africa/Johannesburg"               , 0x001ED4 },
+	{ (char*) "Africa/Juba"                       , 0x001F9E },
+	{ (char*) "Africa/Kampala"                    , 0x002174 },
+	{ (char*) "Africa/Khartoum"                   , 0x002236 },
+	{ (char*) "Africa/Kigali"                     , 0x00240C },
+	{ (char*) "Africa/Kinshasa"                   , 0x00249B },
+	{ (char*) "Africa/Lagos"                      , 0x002543 },
+	{ (char*) "Africa/Libreville"                 , 0x002603 },
+	{ (char*) "Africa/Lome"                       , 0x002692 },
+	{ (char*) "Africa/Luanda"                     , 0x002720 },
+	{ (char*) "Africa/Lubumbashi"                 , 0x0027BE },
+	{ (char*) "Africa/Lusaka"                     , 0x002879 },
+	{ (char*) "Africa/Malabo"                     , 0x002908 },
+	{ (char*) "Africa/Maputo"                     , 0x0029AA },
+	{ (char*) "Africa/Maseru"                     , 0x002A39 },
+	{ (char*) "Africa/Mbabane"                    , 0x002AE2 },
+	{ (char*) "Africa/Mogadishu"                  , 0x002B73 },
+	{ (char*) "Africa/Monrovia"                   , 0x002C20 },
+	{ (char*) "Africa/Nairobi"                    , 0x002CD0 },
+	{ (char*) "Africa/Ndjamena"                   , 0x002D9B },
+	{ (char*) "Africa/Niamey"                     , 0x002E47 },
+	{ (char*) "Africa/Nouakchott"                 , 0x002EFC },
+	{ (char*) "Africa/Ouagadougou"                , 0x002FA6 },
+	{ (char*) "Africa/Porto-Novo"                 , 0x003034 },
+	{ (char*) "Africa/Sao_Tome"                   , 0x0030D6 },
+	{ (char*) "Africa/Timbuktu"                   , 0x00318F },
+	{ (char*) "Africa/Tripoli"                    , 0x00321D },
+	{ (char*) "Africa/Tunis"                      , 0x0033D8 },
+	{ (char*) "Africa/Windhoek"                   , 0x0035A5 },
+	{ (char*) "America/Adak"                      , 0x00382F },
+	{ (char*) "America/Anchorage"                 , 0x003C1E },
+	{ (char*) "America/Anguilla"                  , 0x00400E },
+	{ (char*) "America/Antigua"                   , 0x00409C },
+	{ (char*) "America/Araguaina"                 , 0x00413D },
+	{ (char*) "America/Argentina/Buenos_Aires"    , 0x0043A2 },
+	{ (char*) "America/Argentina/Catamarca"       , 0x004687 },
+	{ (char*) "America/Argentina/ComodRivadavia"  , 0x004972 },
+	{ (char*) "America/Argentina/Cordoba"         , 0x004C42 },
+	{ (char*) "America/Argentina/Jujuy"           , 0x004F48 },
+	{ (char*) "America/Argentina/La_Rioja"        , 0x005210 },
+	{ (char*) "America/Argentina/Mendoza"         , 0x0054F6 },
+	{ (char*) "America/Argentina/Rio_Gallegos"    , 0x0057D2 },
+	{ (char*) "America/Argentina/Salta"           , 0x005AB1 },
+	{ (char*) "America/Argentina/San_Juan"        , 0x005D85 },
+	{ (char*) "America/Argentina/San_Luis"        , 0x00606B },
+	{ (char*) "America/Argentina/Tucuman"         , 0x006351 },
+	{ (char*) "America/Argentina/Ushuaia"         , 0x00663F },
+	{ (char*) "America/Aruba"                     , 0x006924 },
+	{ (char*) "America/Asuncion"                  , 0x0069C7 },
+	{ (char*) "America/Atikokan"                  , 0x006E10 },
+	{ (char*) "America/Atka"                      , 0x006F1D },
+	{ (char*) "America/Bahia"                     , 0x0072F2 },
+	{ (char*) "America/Bahia_Banderas"            , 0x0075AD },
+	{ (char*) "America/Barbados"                  , 0x007886 },
+	{ (char*) "America/Belem"                     , 0x0079A8 },
+	{ (char*) "America/Belize"                    , 0x007B50 },
+	{ (char*) "America/Blanc-Sablon"              , 0x007F71 },
+	{ (char*) "America/Boa_Vista"                 , 0x008066 },
+	{ (char*) "America/Bogota"                    , 0x008227 },
+	{ (char*) "America/Boise"                     , 0x0082E6 },
+	{ (char*) "America/Buenos_Aires"              , 0x0086F9 },
+	{ (char*) "America/Cambridge_Bay"             , 0x0089C9 },
+	{ (char*) "America/Campo_Grande"              , 0x008D5C },
+	{ (char*) "America/Cancun"                    , 0x009132 },
+	{ (char*) "America/Caracas"                   , 0x009364 },
+	{ (char*) "America/Catamarca"                 , 0x00942E },
+	{ (char*) "America/Cayenne"                   , 0x0096FE },
+	{ (char*) "America/Cayman"                    , 0x0097A1 },
+	{ (char*) "America/Chicago"                   , 0x009842 },
+	{ (char*) "America/Chihuahua"                 , 0x009F3C },
+	{ (char*) "America/Ciudad_Juarez"             , 0x00A211 },
+	{ (char*) "America/Coral_Harbour"             , 0x00A507 },
+	{ (char*) "America/Cordoba"                   , 0x00A5A8 },
+	{ (char*) "America/Costa_Rica"                , 0x00A878 },
+	{ (char*) "America/Coyhaique"                 , 0x00A96C },
+	{ (char*) "America/Creston"                   , 0x00AED6 },
+	{ (char*) "America/Cuiaba"                    , 0x00AF92 },
+	{ (char*) "America/Curacao"                   , 0x00B34F },
+	{ (char*) "America/Danmarkshavn"              , 0x00B3F2 },
+	{ (char*) "America/Dawson"                    , 0x00B5D7 },
+	{ (char*) "America/Dawson_Creek"              , 0x00B9FA },
+	{ (char*) "America/Denver"                    , 0x00BCD1 },
+	{ (char*) "America/Detroit"                   , 0x00C104 },
+	{ (char*) "America/Dominica"                  , 0x00C4AC },
+	{ (char*) "America/Edmonton"                  , 0x00C53A },
+	{ (char*) "America/Eirunepe"                  , 0x00CA84 },
+	{ (char*) "America/El_Salvador"               , 0x00CC53 },
+	{ (char*) "America/Ensenada"                  , 0x00CD0F },
+	{ (char*) "America/Fort_Nelson"               , 0x00D272 },
+	{ (char*) "America/Fort_Wayne"                , 0x00D83A },
+	{ (char*) "America/Fortaleza"                 , 0x00DA59 },
+	{ (char*) "America/Glace_Bay"                 , 0x00DC6F },
+	{ (char*) "America/Godthab"                   , 0x00E006 },
+	{ (char*) "America/Goose_Bay"                 , 0x00E3D7 },
+	{ (char*) "America/Grand_Turk"                , 0x00EA2F },
+	{ (char*) "America/Grenada"                   , 0x00ED90 },
+	{ (char*) "America/Guadeloupe"                , 0x00EE1E },
+	{ (char*) "America/Guatemala"                 , 0x00EEAC },
+	{ (char*) "America/Guayaquil"                 , 0x00EF8C },
+	{ (char*) "America/Guyana"                    , 0x00F05D },
+	{ (char*) "America/Halifax"                   , 0x00F11E },
+	{ (char*) "America/Havana"                    , 0x00F7D0 },
+	{ (char*) "America/Hermosillo"                , 0x00FC39 },
+	{ (char*) "America/Indiana/Indianapolis"      , 0x00FD4D },
+	{ (char*) "America/Indiana/Knox"              , 0x00FF85 },
+	{ (char*) "America/Indiana/Marengo"           , 0x01039E },
+	{ (char*) "America/Indiana/Petersburg"        , 0x0105F8 },
+	{ (char*) "America/Indiana/Tell_City"         , 0x0108C2 },
+	{ (char*) "America/Indiana/Vevay"             , 0x010AEC },
+	{ (char*) "America/Indiana/Vincennes"         , 0x010C83 },
+	{ (char*) "America/Indiana/Winamac"           , 0x010ED9 },
+	{ (char*) "America/Indianapolis"              , 0x011156 },
+	{ (char*) "America/Inuvik"                    , 0x011375 },
+	{ (char*) "America/Iqaluit"                   , 0x0116C6 },
+	{ (char*) "America/Jamaica"                   , 0x011A42 },
+	{ (char*) "America/Jujuy"                     , 0x011BA1 },
+	{ (char*) "America/Juneau"                    , 0x011E5F },
+	{ (char*) "America/Kentucky/Louisville"       , 0x012245 },
+	{ (char*) "America/Kentucky/Monticello"       , 0x012749 },
+	{ (char*) "America/Knox_IN"                   , 0x012B35 },
+	{ (char*) "America/Kralendijk"                , 0x012F39 },
+	{ (char*) "America/La_Paz"                    , 0x012FF6 },
+	{ (char*) "America/Lima"                      , 0x0130AC },
+	{ (char*) "America/Los_Angeles"               , 0x0131D3 },
+	{ (char*) "America/Louisville"                , 0x0136F4 },
+	{ (char*) "America/Lower_Princes"             , 0x013BDA },
+	{ (char*) "America/Maceio"                    , 0x013C97 },
+	{ (char*) "America/Managua"                   , 0x013EA9 },
+	{ (char*) "America/Manaus"                    , 0x013FDC },
+	{ (char*) "America/Marigot"                   , 0x014193 },
+	{ (char*) "America/Martinique"                , 0x014250 },
+	{ (char*) "America/Matamoros"                 , 0x01430E },
+	{ (char*) "America/Mazatlan"                  , 0x0144FB },
+	{ (char*) "America/Mendoza"                   , 0x0147EB },
+	{ (char*) "America/Menominee"                 , 0x014ABB },
+	{ (char*) "America/Merida"                    , 0x014E7B },
+	{ (char*) "America/Metlakatla"                , 0x015126 },
+	{ (char*) "America/Mexico_City"               , 0x015393 },
+	{ (char*) "America/Miquelon"                  , 0x0156B2 },
+	{ (char*) "America/Moncton"                   , 0x0158E4 },
+	{ (char*) "America/Monterrey"                 , 0x015EDD },
+	{ (char*) "America/Montevideo"                , 0x0161E4 },
+	{ (char*) "America/Montreal"                  , 0x0165B9 },
+	{ (char*) "America/Montserrat"                , 0x016C7A },
+	{ (char*) "America/Nassau"                    , 0x016D08 },
+	{ (char*) "America/New_York"                  , 0x017102 },
+	{ (char*) "America/Nipigon"                   , 0x0177F2 },
+	{ (char*) "America/Nome"                      , 0x017EB3 },
+	{ (char*) "America/Noronha"                   , 0x01829B },
+	{ (char*) "America/North_Dakota/Beulah"       , 0x01849B },
+	{ (char*) "America/North_Dakota/Center"       , 0x0188CF },
+	{ (char*) "America/North_Dakota/New_Salem"    , 0x018CCE },
+	{ (char*) "America/Nuuk"                      , 0x0190D3 },
+	{ (char*) "America/Ojinaga"                   , 0x0194B5 },
+	{ (char*) "America/Panama"                    , 0x0197AB },
+	{ (char*) "America/Pangnirtung"               , 0x01984C },
+	{ (char*) "America/Paramaribo"                , 0x019BAF },
+	{ (char*) "America/Phoenix"                   , 0x019C76 },
+	{ (char*) "America/Port-au-Prince"            , 0x019D8A },
+	{ (char*) "America/Port_of_Spain"             , 0x019FCB },
+	{ (char*) "America/Porto_Acre"                , 0x01A059 },
+	{ (char*) "America/Porto_Velho"               , 0x01A207 },
+	{ (char*) "America/Puerto_Rico"               , 0x01A3A5 },
+	{ (char*) "America/Punta_Arenas"              , 0x01A462 },
+	{ (char*) "America/Rainy_River"               , 0x01A941 },
+	{ (char*) "America/Rankin_Inlet"              , 0x01AE5B },
+	{ (char*) "America/Recife"                    , 0x01B1A4 },
+	{ (char*) "America/Regina"                    , 0x01B39E },
+	{ (char*) "America/Resolute"                  , 0x01B63D },
+	{ (char*) "America/Rio_Branco"                , 0x01B987 },
+	{ (char*) "America/Rosario"                   , 0x01BB39 },
+	{ (char*) "America/Santa_Isabel"              , 0x01BE09 },
+	{ (char*) "America/Santarem"                  , 0x01C36C },
+	{ (char*) "America/Santiago"                  , 0x01C51C },
+	{ (char*) "America/Santo_Domingo"             , 0x01CA7F },
+	{ (char*) "America/Sao_Paulo"                 , 0x01CBC8 },
+	{ (char*) "America/Scoresbysund"              , 0x01CFC2 },
+	{ (char*) "America/Shiprock"                  , 0x01D3C3 },
+	{ (char*) "America/Sitka"                     , 0x01D7E1 },
+	{ (char*) "America/St_Barthelemy"             , 0x01DBBC },
+	{ (char*) "America/St_Johns"                  , 0x01DC79 },
+	{ (char*) "America/St_Kitts"                  , 0x01E3F6 },
+	{ (char*) "America/St_Lucia"                  , 0x01E484 },
+	{ (char*) "America/St_Thomas"                 , 0x01E525 },
+	{ (char*) "America/St_Vincent"                , 0x01E5B3 },
+	{ (char*) "America/Swift_Current"             , 0x01E654 },
+	{ (char*) "America/Tegucigalpa"               , 0x01E7E2 },
+	{ (char*) "America/Thule"                     , 0x01E8B0 },
+	{ (char*) "America/Thunder_Bay"               , 0x01EA91 },
+	{ (char*) "America/Tijuana"                   , 0x01F152 },
+	{ (char*) "America/Toronto"                   , 0x01F6C4 },
+	{ (char*) "America/Tortola"                   , 0x01FDA3 },
+	{ (char*) "America/Vancouver"                 , 0x01FE31 },
+	{ (char*) "America/Virgin"                    , 0x0204DB },
+	{ (char*) "America/Whitehorse"                , 0x020598 },
+	{ (char*) "America/Winnipeg"                  , 0x0209BB },
+	{ (char*) "America/Yakutat"                   , 0x020EF2 },
+	{ (char*) "America/Yellowknife"               , 0x0212C0 },
+	{ (char*) "Antarctica/Casey"                  , 0x0217ED },
+	{ (char*) "Antarctica/Davis"                  , 0x02191D },
+	{ (char*) "Antarctica/DumontDUrville"         , 0x0219F3 },
+	{ (char*) "Antarctica/Macquarie"              , 0x021AA7 },
+	{ (char*) "Antarctica/Mawson"                 , 0x021E93 },
+	{ (char*) "Antarctica/McMurdo"                , 0x021F3D },
+	{ (char*) "Antarctica/Palmer"                 , 0x02226F },
+	{ (char*) "Antarctica/Rothera"                , 0x0225F8 },
+	{ (char*) "Antarctica/South_Pole"             , 0x02268F },
+	{ (char*) "Antarctica/Syowa"                  , 0x022AAE },
+	{ (char*) "Antarctica/Troll"                  , 0x022B44 },
+	{ (char*) "Antarctica/Vostok"                 , 0x022BF3 },
+	{ (char*) "Arctic/Longyearbyen"               , 0x022CAF },
+	{ (char*) "Asia/Aden"                         , 0x022F7C },
+	{ (char*) "Asia/Almaty"                       , 0x02300D },
+	{ (char*) "Asia/Amman"                        , 0x023295 },
+	{ (char*) "Asia/Anadyr"                       , 0x023641 },
+	{ (char*) "Asia/Aqtau"                        , 0x023947 },
+	{ (char*) "Asia/Aqtobe"                       , 0x023BC6 },
+	{ (char*) "Asia/Ashgabat"                     , 0x023E46 },
+	{ (char*) "Asia/Ashkhabad"                    , 0x023FC9 },
+	{ (char*) "Asia/Atyrau"                       , 0x02414C },
+	{ (char*) "Asia/Baghdad"                      , 0x0243D5 },
+	{ (char*) "Asia/Bahrain"                      , 0x024657 },
+	{ (char*) "Asia/Baku"                         , 0x024710 },
+	{ (char*) "Asia/Bangkok"                      , 0x024A04 },
+	{ (char*) "Asia/Barnaul"                      , 0x024AA8 },
+	{ (char*) "Asia/Beirut"                       , 0x024DB3 },
+	{ (char*) "Asia/Bishkek"                      , 0x02509B },
+	{ (char*) "Asia/Brunei"                       , 0x025311 },
+	{ (char*) "Asia/Calcutta"                     , 0x0253B7 },
+	{ (char*) "Asia/Chita"                        , 0x02549F },
+	{ (char*) "Asia/Choibalsan"                   , 0x0257AD },
+	{ (char*) "Asia/Chongqing"                    , 0x025A0B },
+	{ (char*) "Asia/Chungking"                    , 0x025BA0 },
+	{ (char*) "Asia/Colombo"                      , 0x025D35 },
+	{ (char*) "Asia/Dacca"                        , 0x025E38 },
+	{ (char*) "Asia/Damascus"                     , 0x025F2B },
+	{ (char*) "Asia/Dhaka"                        , 0x026409 },
+	{ (char*) "Asia/Dili"                         , 0x0264FC },
+	{ (char*) "Asia/Dubai"                        , 0x0265B2 },
+	{ (char*) "Asia/Dushanbe"                     , 0x026643 },
+	{ (char*) "Asia/Famagusta"                    , 0x0267BD },
+	{ (char*) "Asia/Gaza"                         , 0x026B84 },
+	{ (char*) "Asia/Harbin"                       , 0x027720 },
+	{ (char*) "Asia/Hebron"                       , 0x0278B5 },
+	{ (char*) "Asia/Ho_Chi_Minh"                  , 0x028462 },
+	{ (char*) "Asia/Hong_Kong"                    , 0x028556 },
+	{ (char*) "Asia/Hovd"                         , 0x028869 },
+	{ (char*) "Asia/Irkutsk"                      , 0x028ADD },
+	{ (char*) "Asia/Istanbul"                     , 0x028DFB },
+	{ (char*) "Asia/Jakarta"                      , 0x0292B7 },
+	{ (char*) "Asia/Jayapura"                     , 0x0293C8 },
+	{ (char*) "Asia/Jerusalem"                    , 0x0294B5 },
+	{ (char*) "Asia/Kabul"                        , 0x0298F3 },
+	{ (char*) "Asia/Kamchatka"                    , 0x02999E },
+	{ (char*) "Asia/Karachi"                      , 0x029C93 },
+	{ (char*) "Asia/Kashgar"                      , 0x029DA9 },
+	{ (char*) "Asia/Kathmandu"                    , 0x029E3A },
+	{ (char*) "Asia/Katmandu"                     , 0x029EE7 },
+	{ (char*) "Asia/Khandyga"                     , 0x029F94 },
+	{ (char*) "Asia/Kolkata"                      , 0x02A2C5 },
+	{ (char*) "Asia/Krasnoyarsk"                  , 0x02A3AD },
+	{ (char*) "Asia/Kuala_Lumpur"                 , 0x02A6B7 },
+	{ (char*) "Asia/Kuching"                      , 0x02A7D7 },
+	{ (char*) "Asia/Kuwait"                       , 0x02A931 },
+	{ (char*) "Asia/Macao"                        , 0x02A9C2 },
+	{ (char*) "Asia/Macau"                        , 0x02ACE5 },
+	{ (char*) "Asia/Magadan"                      , 0x02B008 },
+	{ (char*) "Asia/Makassar"                     , 0x02B313 },
+	{ (char*) "Asia/Manila"                       , 0x02B426 },
+	{ (char*) "Asia/Muscat"                       , 0x02B544 },
+	{ (char*) "Asia/Nicosia"                      , 0x02B5D5 },
+	{ (char*) "Asia/Novokuznetsk"                 , 0x02B844 },
+	{ (char*) "Asia/Novosibirsk"                  , 0x02BB37 },
+	{ (char*) "Asia/Omsk"                         , 0x02BE48 },
+	{ (char*) "Asia/Oral"                         , 0x02C146 },
+	{ (char*) "Asia/Phnom_Penh"                   , 0x02C3D2 },
+	{ (char*) "Asia/Pontianak"                    , 0x02C4A2 },
+	{ (char*) "Asia/Pyongyang"                    , 0x02C5BB },
+	{ (char*) "Asia/Qatar"                        , 0x02C67E },
+	{ (char*) "Asia/Qostanay"                     , 0x02C722 },
+	{ (char*) "Asia/Qyzylorda"                    , 0x02C9B8 },
+	{ (char*) "Asia/Rangoon"                      , 0x02CC51 },
+	{ (char*) "Asia/Riyadh"                       , 0x02CD18 },
+	{ (char*) "Asia/Saigon"                       , 0x02CDA9 },
+	{ (char*) "Asia/Sakhalin"                     , 0x02CE9D },
+	{ (char*) "Asia/Samarkand"                    , 0x02D1B4 },
+	{ (char*) "Asia/Seoul"                        , 0x02D33F },
+	{ (char*) "Asia/Shanghai"                     , 0x02D4EA },
+	{ (char*) "Asia/Singapore"                    , 0x02D68B },
+	{ (char*) "Asia/Srednekolymsk"                , 0x02D797 },
+	{ (char*) "Asia/Taipei"                       , 0x02DAA7 },
+	{ (char*) "Asia/Tashkent"                     , 0x02DCB2 },
+	{ (char*) "Asia/Tbilisi"                      , 0x02DE3D },
+	{ (char*) "Asia/Tehran"                       , 0x02E0B5 },
+	{ (char*) "Asia/Tel_Aviv"                     , 0x02E3ED },
+	{ (char*) "Asia/Thimbu"                       , 0x02E82B },
+	{ (char*) "Asia/Thimphu"                      , 0x02E8D1 },
+	{ (char*) "Asia/Tokyo"                        , 0x02E977 },
+	{ (char*) "Asia/Tomsk"                        , 0x02EA58 },
+	{ (char*) "Asia/Ujung_Pandang"                , 0x02ED63 },
+	{ (char*) "Asia/Ulaanbaatar"                  , 0x02EE2D },
+	{ (char*) "Asia/Ulan_Bator"                   , 0x02F09B },
+	{ (char*) "Asia/Urumqi"                       , 0x02F2F9 },
+	{ (char*) "Asia/Ust-Nera"                     , 0x02F397 },
+	{ (char*) "Asia/Vientiane"                    , 0x02F6BA },
+	{ (char*) "Asia/Vladivostok"                  , 0x02F79C },
+	{ (char*) "Asia/Yakutsk"                      , 0x02FAA1 },
+	{ (char*) "Asia/Yangon"                       , 0x02FDA5 },
+	{ (char*) "Asia/Yekaterinburg"                , 0x02FE6C },
+	{ (char*) "Asia/Yerevan"                      , 0x03017E },
+	{ (char*) "Atlantic/Azores"                   , 0x03044E },
+	{ (char*) "Atlantic/Bermuda"                  , 0x0309D9 },
+	{ (char*) "Atlantic/Canary"                   , 0x030DE5 },
+	{ (char*) "Atlantic/Cape_Verde"               , 0x030FDD },
+	{ (char*) "Atlantic/Faeroe"                   , 0x031098 },
+	{ (char*) "Atlantic/Faroe"                    , 0x03125D },
+	{ (char*) "Atlantic/Jan_Mayen"                , 0x031422 },
+	{ (char*) "Atlantic/Madeira"                  , 0x0316EF },
+	{ (char*) "Atlantic/Reykjavik"                , 0x031C66 },
+	{ (char*) "Atlantic/South_Georgia"            , 0x031F63 },
+	{ (char*) "Atlantic/St_Helena"                , 0x031FF3 },
+	{ (char*) "Atlantic/Stanley"                  , 0x032094 },
+	{ (char*) "Australia/ACT"                     , 0x0323B5 },
+	{ (char*) "Australia/Adelaide"                , 0x032749 },
+	{ (char*) "Australia/Brisbane"                , 0x032AFD },
+	{ (char*) "Australia/Broken_Hill"             , 0x032C41 },
+	{ (char*) "Australia/Canberra"                , 0x033016 },
+	{ (char*) "Australia/Currie"                  , 0x0333AA },
+	{ (char*) "Australia/Darwin"                  , 0x0337A1 },
+	{ (char*) "Australia/Eucla"                   , 0x0338A9 },
+	{ (char*) "Australia/Hobart"                  , 0x033A08 },
+	{ (char*) "Australia/LHI"                     , 0x033E07 },
+	{ (char*) "Australia/Lindeman"                , 0x0340C7 },
+	{ (char*) "Australia/Lord_Howe"               , 0x034237 },
+	{ (char*) "Australia/Melbourne"               , 0x034507 },
+	{ (char*) "Australia/North"                   , 0x0348A3 },
+	{ (char*) "Australia/NSW"                     , 0x034999 },
+	{ (char*) "Australia/Perth"                   , 0x034D2D },
+	{ (char*) "Australia/Queensland"              , 0x034E89 },
+	{ (char*) "Australia/South"                   , 0x034FB6 },
+	{ (char*) "Australia/Sydney"                  , 0x03535B },
+	{ (char*) "Australia/Tasmania"                , 0x03570B },
+	{ (char*) "Australia/Victoria"                , 0x035B02 },
+	{ (char*) "Australia/West"                    , 0x035E96 },
+	{ (char*) "Australia/Yancowinna"              , 0x035FD4 },
+	{ (char*) "Brazil/Acre"                       , 0x03638D },
+	{ (char*) "Brazil/DeNoronha"                  , 0x03653B },
+	{ (char*) "Brazil/East"                       , 0x03672B },
+	{ (char*) "Brazil/West"                       , 0x036AEF },
+	{ (char*) "Canada/Atlantic"                   , 0x036C97 },
+	{ (char*) "Canada/Central"                    , 0x03732B },
+	{ (char*) "Canada/Eastern"                    , 0x037845 },
+	{ (char*) "Canada/Mountain"                   , 0x037F06 },
+	{ (char*) "Canada/Newfoundland"               , 0x038433 },
+	{ (char*) "Canada/Pacific"                    , 0x038B95 },
+	{ (char*) "Canada/Saskatchewan"               , 0x03922A },
+	{ (char*) "Canada/Yukon"                      , 0x0394B4 },
+	{ (char*) "CET"                               , 0x0398C5 },
+	{ (char*) "Chile/Continental"                 , 0x039D20 },
+	{ (char*) "Chile/EasterIsland"                , 0x03A276 },
+	{ (char*) "CST6CDT"                           , 0x03A718 },
+	{ (char*) "Cuba"                              , 0x03ADFE },
+	{ (char*) "EET"                               , 0x03B267 },
+	{ (char*) "Egypt"                             , 0x03B51D },
+	{ (char*) "Eire"                              , 0x03BA46 },
+	{ (char*) "EST"                               , 0x03C02A },
+	{ (char*) "EST5EDT"                           , 0x03C0CB },
+	{ (char*) "Etc/GMT"                           , 0x03C7A7 },
+	{ (char*) "Etc/GMT+0"                         , 0x03C822 },
+	{ (char*) "Etc/GMT+1"                         , 0x03C89D },
+	{ (char*) "Etc/GMT+10"                        , 0x03C91A },
+	{ (char*) "Etc/GMT+11"                        , 0x03C998 },
+	{ (char*) "Etc/GMT+12"                        , 0x03CA16 },
+	{ (char*) "Etc/GMT+2"                         , 0x03CA94 },
+	{ (char*) "Etc/GMT+3"                         , 0x03CB11 },
+	{ (char*) "Etc/GMT+4"                         , 0x03CB8E },
+	{ (char*) "Etc/GMT+5"                         , 0x03CC0B },
+	{ (char*) "Etc/GMT+6"                         , 0x03CC88 },
+	{ (char*) "Etc/GMT+7"                         , 0x03CD05 },
+	{ (char*) "Etc/GMT+8"                         , 0x03CD82 },
+	{ (char*) "Etc/GMT+9"                         , 0x03CDFF },
+	{ (char*) "Etc/GMT-0"                         , 0x03CE7C },
+	{ (char*) "Etc/GMT-1"                         , 0x03CEF7 },
+	{ (char*) "Etc/GMT-10"                        , 0x03CF75 },
+	{ (char*) "Etc/GMT-11"                        , 0x03CFF4 },
+	{ (char*) "Etc/GMT-12"                        , 0x03D073 },
+	{ (char*) "Etc/GMT-13"                        , 0x03D0F2 },
+	{ (char*) "Etc/GMT-14"                        , 0x03D171 },
+	{ (char*) "Etc/GMT-2"                         , 0x03D1F0 },
+	{ (char*) "Etc/GMT-3"                         , 0x03D26E },
+	{ (char*) "Etc/GMT-4"                         , 0x03D2EC },
+	{ (char*) "Etc/GMT-5"                         , 0x03D36A },
+	{ (char*) "Etc/GMT-6"                         , 0x03D3E8 },
+	{ (char*) "Etc/GMT-7"                         , 0x03D466 },
+	{ (char*) "Etc/GMT-8"                         , 0x03D4E4 },
+	{ (char*) "Etc/GMT-9"                         , 0x03D562 },
+	{ (char*) "Etc/GMT0"                          , 0x03D5E0 },
+	{ (char*) "Etc/Greenwich"                     , 0x03D65B },
+	{ (char*) "Etc/UCT"                           , 0x03D6D6 },
+	{ (char*) "Etc/Universal"                     , 0x03D751 },
+	{ (char*) "Etc/UTC"                           , 0x03D7CC },
+	{ (char*) "Etc/Zulu"                          , 0x03D847 },
+	{ (char*) "Europe/Amsterdam"                  , 0x03D8C2 },
+	{ (char*) "Europe/Andorra"                    , 0x03DCFD },
+	{ (char*) "Europe/Astrakhan"                  , 0x03DE8E },
+	{ (char*) "Europe/Athens"                     , 0x03E182 },
+	{ (char*) "Europe/Belfast"                    , 0x03E438 },
+	{ (char*) "Europe/Belgrade"                   , 0x03EA83 },
+	{ (char*) "Europe/Berlin"                     , 0x03EC6D },
+	{ (char*) "Europe/Bratislava"                 , 0x03EF49 },
+	{ (char*) "Europe/Brussels"                   , 0x03F228 },
+	{ (char*) "Europe/Bucharest"                  , 0x03F683 },
+	{ (char*) "Europe/Budapest"                   , 0x03F924 },
+	{ (char*) "Europe/Busingen"                   , 0x03FC2E },
+	{ (char*) "Europe/Chisinau"                   , 0x03FE33 },
+	{ (char*) "Europe/Copenhagen"                 , 0x0402F6 },
+	{ (char*) "Europe/Dublin"                     , 0x040571 },
+	{ (char*) "Europe/Gibraltar"                  , 0x040B55 },
+	{ (char*) "Europe/Guernsey"                   , 0x041025 },
+	{ (char*) "Europe/Helsinki"                   , 0x04167C },
+	{ (char*) "Europe/Isle_of_Man"                , 0x041869 },
+	{ (char*) "Europe/Istanbul"                   , 0x041EB4 },
+	{ (char*) "Europe/Jersey"                     , 0x042370 },
+	{ (char*) "Europe/Kaliningrad"                , 0x0429C7 },
+	{ (char*) "Europe/Kiev"                       , 0x042D6F },
+	{ (char*) "Europe/Kirov"                      , 0x042FA9 },
+	{ (char*) "Europe/Kyiv"                       , 0x0432A2 },
+	{ (char*) "Europe/Lisbon"                     , 0x0434EB },
+	{ (char*) "Europe/Ljubljana"                  , 0x043AC1 },
+	{ (char*) "Europe/London"                     , 0x043CAB },
+	{ (char*) "Europe/Luxembourg"                 , 0x0442F6 },
+	{ (char*) "Europe/Madrid"                     , 0x044741 },
+	{ (char*) "Europe/Malta"                      , 0x044ADE },
+	{ (char*) "Europe/Mariehamn"                  , 0x044E8A },
+	{ (char*) "Europe/Minsk"                      , 0x045077 },
+	{ (char*) "Europe/Monaco"                     , 0x0453AB },
+	{ (char*) "Europe/Moscow"                     , 0x045811 },
+	{ (char*) "Europe/Nicosia"                    , 0x045BBD },
+	{ (char*) "Europe/Oslo"                       , 0x045E1E },
+	{ (char*) "Europe/Paris"                      , 0x0460CE },
+	{ (char*) "Europe/Podgorica"                  , 0x04652B },
+	{ (char*) "Europe/Prague"                     , 0x046715 },
+	{ (char*) "Europe/Riga"                       , 0x0469F4 },
+	{ (char*) "Europe/Rome"                       , 0x046CB6 },
+	{ (char*) "Europe/Samara"                     , 0x047075 },
+	{ (char*) "Europe/San_Marino"                 , 0x047376 },
+	{ (char*) "Europe/Sarajevo"                   , 0x047735 },
+	{ (char*) "Europe/Saratov"                    , 0x04791F },
+	{ (char*) "Europe/Simferopol"                 , 0x047C11 },
+	{ (char*) "Europe/Skopje"                     , 0x047F84 },
+	{ (char*) "Europe/Sofia"                      , 0x04816E },
+	{ (char*) "Europe/Stockholm"                  , 0x0483CA },
+	{ (char*) "Europe/Tallinn"                    , 0x0485C7 },
+	{ (char*) "Europe/Tirane"                     , 0x048876 },
+	{ (char*) "Europe/Tiraspol"                   , 0x048ADE },
+	{ (char*) "Europe/Ulyanovsk"                  , 0x048FA1 },
+	{ (char*) "Europe/Uzhgorod"                   , 0x0492B7 },
+	{ (char*) "Europe/Vaduz"                      , 0x0494F1 },
+	{ (char*) "Europe/Vatican"                    , 0x0496DB },
+	{ (char*) "Europe/Vienna"                     , 0x049A9A },
+	{ (char*) "Europe/Vilnius"                    , 0x049D38 },
+	{ (char*) "Europe/Volgograd"                  , 0x049FE8 },
+	{ (char*) "Europe/Warsaw"                     , 0x04A2F7 },
+	{ (char*) "Europe/Zagreb"                     , 0x04A69E },
+	{ (char*) "Europe/Zaporozhye"                 , 0x04A888 },
+	{ (char*) "Europe/Zurich"                     , 0x04AAC2 },
+	{ (char*) "Factory"                           , 0x04ACBF },
+	{ (char*) "GB"                                , 0x04AD3C },
+	{ (char*) "GB-Eire"                           , 0x04B387 },
+	{ (char*) "GMT"                               , 0x04B9D2 },
+	{ (char*) "GMT+0"                             , 0x04BA4D },
+	{ (char*) "GMT-0"                             , 0x04BAC8 },
+	{ (char*) "GMT0"                              , 0x04BB43 },
+	{ (char*) "Greenwich"                         , 0x04BBBE },
+	{ (char*) "Hongkong"                          , 0x04BC39 },
+	{ (char*) "HST"                               , 0x04BF4C },
+	{ (char*) "Iceland"                           , 0x04C035 },
+	{ (char*) "Indian/Antananarivo"               , 0x04C0C3 },
+	{ (char*) "Indian/Chagos"                     , 0x04C16F },
+	{ (char*) "Indian/Christmas"                  , 0x04C213 },
+	{ (char*) "Indian/Cocos"                      , 0x04C2A4 },
+	{ (char*) "Indian/Comoro"                     , 0x04C33C },
+	{ (char*) "Indian/Kerguelen"                  , 0x04C3CB },
+	{ (char*) "Indian/Mahe"                       , 0x04C45C },
+	{ (char*) "Indian/Maldives"                   , 0x04C4ED },
+	{ (char*) "Indian/Mauritius"                  , 0x04C591 },
+	{ (char*) "Indian/Mayotte"                    , 0x04C650 },
+	{ (char*) "Indian/Reunion"                    , 0x04C6DF },
+	{ (char*) "Iran"                              , 0x04C770 },
+	{ (char*) "Israel"                            , 0x04CAA8 },
+	{ (char*) "Jamaica"                           , 0x04CEE6 },
+	{ (char*) "Japan"                             , 0x04D045 },
+	{ (char*) "Kwajalein"                         , 0x04D126 },
+	{ (char*) "Libya"                             , 0x04D20D },
+	{ (char*) "MET"                               , 0x04D3C8 },
+	{ (char*) "Mexico/BajaNorte"                  , 0x04D823 },
+	{ (char*) "Mexico/BajaSur"                    , 0x04DD86 },
+	{ (char*) "Mexico/General"                    , 0x04E044 },
+	{ (char*) "MST"                               , 0x04E355 },
+	{ (char*) "MST7MDT"                           , 0x04E451 },
+	{ (char*) "Navajo"                            , 0x04E86F },
+	{ (char*) "NZ"                                , 0x04EC8D },
+	{ (char*) "NZ-CHAT"                           , 0x04F0AC },
+	{ (char*) "Pacific/Apia"                      , 0x04F3E0 },
+	{ (char*) "Pacific/Auckland"                  , 0x04F583 },
+	{ (char*) "Pacific/Bougainville"              , 0x04F9B5 },
+	{ (char*) "Pacific/Chatham"                   , 0x04FA96 },
+	{ (char*) "Pacific/Chuuk"                     , 0x04FDD9 },
+	{ (char*) "Pacific/Easter"                    , 0x04FEB7 },
+	{ (char*) "Pacific/Efate"                     , 0x050366 },
+	{ (char*) "Pacific/Enderbury"                 , 0x0504C8 },
+	{ (char*) "Pacific/Fakaofo"                   , 0x050580 },
+	{ (char*) "Pacific/Fiji"                      , 0x050625 },
+	{ (char*) "Pacific/Funafuti"                  , 0x0507BD },
+	{ (char*) "Pacific/Galapagos"                 , 0x05084F },
+	{ (char*) "Pacific/Gambier"                   , 0x05091B },
+	{ (char*) "Pacific/Guadalcanal"               , 0x0509BA },
+	{ (char*) "Pacific/Guam"                      , 0x050A4C },
+	{ (char*) "Pacific/Honolulu"                  , 0x050BB6 },
+	{ (char*) "Pacific/Johnston"                  , 0x050CA5 },
+	{ (char*) "Pacific/Kanton"                    , 0x050D8E },
+	{ (char*) "Pacific/Kiritimati"                , 0x050E55 },
+	{ (char*) "Pacific/Kosrae"                    , 0x050F1B },
+	{ (char*) "Pacific/Kwajalein"                 , 0x05101F },
+	{ (char*) "Pacific/Majuro"                    , 0x05110F },
+	{ (char*) "Pacific/Marquesas"                 , 0x05120D },
+	{ (char*) "Pacific/Midway"                    , 0x0512B5 },
+	{ (char*) "Pacific/Nauru"                     , 0x051378 },
+	{ (char*) "Pacific/Niue"                      , 0x05143B },
+	{ (char*) "Pacific/Norfolk"                   , 0x0514E1 },
+	{ (char*) "Pacific/Noumea"                    , 0x0515DA },
+	{ (char*) "Pacific/Pago_Pago"                 , 0x0516AC },
+	{ (char*) "Pacific/Palau"                     , 0x05174A },
+	{ (char*) "Pacific/Pitcairn"                  , 0x0517EA },
+	{ (char*) "Pacific/Pohnpei"                   , 0x05188F },
+	{ (char*) "Pacific/Ponape"                    , 0x05197F },
+	{ (char*) "Pacific/Port_Moresby"              , 0x051A11 },
+	{ (char*) "Pacific/Rarotonga"                 , 0x051ACF },
+	{ (char*) "Pacific/Saipan"                    , 0x051C71 },
+	{ (char*) "Pacific/Samoa"                     , 0x051DD2 },
+	{ (char*) "Pacific/Tahiti"                    , 0x051E70 },
+	{ (char*) "Pacific/Tarawa"                    , 0x051F10 },
+	{ (char*) "Pacific/Tongatapu"                 , 0x051FB1 },
+	{ (char*) "Pacific/Truk"                      , 0x0520AA },
+	{ (char*) "Pacific/Wake"                      , 0x052150 },
+	{ (char*) "Pacific/Wallis"                    , 0x0521ED },
+	{ (char*) "Pacific/Yap"                       , 0x05227F },
+	{ (char*) "Poland"                            , 0x052325 },
+	{ (char*) "Portugal"                          , 0x0526CC },
+	{ (char*) "PRC"                               , 0x052C8F },
+	{ (char*) "PST8PDT"                           , 0x052E24 },
+	{ (char*) "ROC"                               , 0x05333E },
+	{ (char*) "ROK"                               , 0x053549 },
+	{ (char*) "Singapore"                         , 0x0536F4 },
+	{ (char*) "Turkey"                            , 0x053800 },
+	{ (char*) "UCT"                               , 0x053CBC },
+	{ (char*) "Universal"                         , 0x053D37 },
+	{ (char*) "US/Alaska"                         , 0x053DB2 },
+	{ (char*) "US/Aleutian"                       , 0x05418F },
+	{ (char*) "US/Arizona"                        , 0x054564 },
+	{ (char*) "US/Central"                        , 0x054660 },
+	{ (char*) "US/East-Indiana"                   , 0x054D46 },
+	{ (char*) "US/Eastern"                        , 0x054F65 },
+	{ (char*) "US/Hawaii"                         , 0x055641 },
+	{ (char*) "US/Indiana-Starke"                 , 0x05572A },
+	{ (char*) "US/Michigan"                       , 0x055B2E },
+	{ (char*) "US/Mountain"                       , 0x055EBD },
+	{ (char*) "US/Pacific"                        , 0x0562DB },
+	{ (char*) "US/Samoa"                          , 0x0567F5 },
+	{ (char*) "UTC"                               , 0x056893 },
+	{ (char*) "W-SU"                              , 0x05690E },
+	{ (char*) "WET"                               , 0x056CA6 },
+	{ (char*) "Zulu"                              , 0x057269 },
 };
 
 
-const unsigned char timelib_timezone_db_data_builtin[357654] = {
+const unsigned char timelib_timezone_db_data_builtin[357092] = {
 
 /* Africa/Abidjan */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -919,7 +919,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0xFF,
 0xFF, 0xFF, 0xFF, 0x96, 0x51, 0xF9, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xFF, 0x14, 0x80, 0xFF,
 0xFF, 0xFF, 0xFF, 0xC7, 0x58, 0xAC, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xD9, 0xED, 0x80, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0xA1, 0x32, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x35, 0xA4, 0x00, 0xFF,
@@ -955,86 +955,16 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x64, 0x44, 0x91, 0x20, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20, 0x00,
 0x00, 0x00, 0x00, 0x66, 0x1B, 0x38, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20, 0x00,
 0x00, 0x00, 0x00, 0x67, 0xF1, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x69, 0xBF, 0x4D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x67, 0xD0, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x6B, 0x95, 0xF4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x35, 0x3D, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x6D, 0x6C, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x0B, 0xE4, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x6F, 0x3A, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0xD9, 0x51, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x71, 0x10, 0xB0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x72, 0xAF, 0xF9, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x72, 0xDE, 0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xA0, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x74, 0xB4, 0xC5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x76, 0x54, 0x0D, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x76, 0x8B, 0x6C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x2A, 0xB5, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x78, 0x58, 0xD9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8, 0x22, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x7A, 0x2F, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xCE, 0xC9, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x7C, 0x06, 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xA5, 0x71, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x7D, 0xD3, 0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x72, 0xDE, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x7F, 0xAA, 0x3D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x81, 0x49, 0x85, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x81, 0x77, 0xAA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x83, 0x20, 0x2D, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x83, 0x4E, 0x51, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x84, 0xED, 0x9A, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x85, 0x24, 0xF9, 0x20, 0x00, 0x00, 0x00, 0x00, 0x86, 0xC4, 0x41, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x86, 0xF2, 0x66, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x91, 0xAE, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x88, 0xC9, 0x0D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x68, 0x56, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x8A, 0x9F, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x3E, 0xFD, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x8C, 0x6D, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x0C, 0x6A, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x8E, 0x43, 0xC9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xE3, 0x12, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x90, 0x11, 0x36, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x91, 0xB9, 0xB9, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x91, 0xE7, 0xDE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x93, 0x87, 0x26, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x93, 0xBE, 0x85, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x95, 0x5D, 0xCE, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x95, 0x8B, 0xF2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x97, 0x2B, 0x3B, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x97, 0x62, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0xE2, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x99, 0x39, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xD8, 0x8A, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x9B, 0x06, 0xAE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xA5, 0xF7, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x9C, 0xDD, 0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x7C, 0x9E, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x9E, 0xAA, 0xC3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x53, 0x46, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA0, 0x81, 0x6A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x20, 0xB3, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA2, 0x58, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xF7, 0x5A, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xA4, 0x25, 0x7F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC4, 0xC7, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xA5, 0xFC, 0x26, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA7, 0x9B, 0x6F, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA7, 0xD2, 0xCE, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x72, 0x16, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xA9, 0xA0, 0x3B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x3F, 0x83, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xAB, 0x76, 0xE2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x16, 0x2B, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xAD, 0x44, 0x4F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAE, 0xEC, 0xD2, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xAF, 0x1A, 0xF7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xBA, 0x3F, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB0, 0xF1, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x90, 0xE7, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xB2, 0xBF, 0x0B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x5E, 0x54, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xB4, 0x95, 0xB3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x34, 0xFB, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB6, 0x6C, 0x5A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x0B, 0xA3, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xB8, 0x39, 0xC7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB9, 0xD9, 0x10, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xBA, 0x10, 0x6F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xAF, 0xB7, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xBB, 0xDD, 0xDC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x86, 0x5F, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xBD, 0xB4, 0x83, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x53, 0xCC, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xBF, 0x8B, 0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x2A, 0x73, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xC1, 0x58, 0x98, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xF7, 0xE0, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xC3, 0x2F, 0x3F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xCE, 0x88, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xC5, 0x05, 0xE7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xA5, 0x2F, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xC6, 0xD3, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x72, 0x9C, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xC8, 0xA9, 0xFB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x49, 0x44, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xCA, 0x77, 0x68, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x1F, 0xEB, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xCC, 0x4E, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xED, 0x58, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xCE, 0x24, 0xB7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xC4, 0x00, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xCF, 0xF2, 0x24, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x91, 0x6D, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD1, 0xC8, 0xCC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x68, 0x14, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xD3, 0x96, 0x39, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x3E, 0xBC, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD5, 0x6C, 0xE0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x0C, 0x29, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD7, 0x43, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xE2, 0xD0, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xD9, 0x10, 0xF5, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xB9, 0x78, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xDA, 0xE7, 0x9C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x86, 0xE5, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xDC, 0xBE, 0x44, 0x20, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xF8, 0xE4,
-0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
-0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30,
-0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x31, 0x3E, 0x2D, 0x31, 0x0A, 0x00,
-0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16, 0x42, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x69, 0xBF, 0x4D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAF, 0x30, 0x10, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
+0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x02, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E,
+0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30,
+0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x30, 0x3E, 0x30, 0x0A, 0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16,
+0x42, 0x00, 0x00, 0x00, 0x00, 
 
 /* Africa/Ceuta */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1142,7 +1072,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0xFF,
 0xFF, 0xFF, 0xFF, 0xBC, 0x48, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xD1, 0xB0, 0x90, 0x00,
 0x00, 0x00, 0x00, 0x0B, 0xE8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x61, 0x47, 0xF0, 0x00,
 0x00, 0x00, 0x00, 0x0D, 0xC9, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x8E, 0xF2, 0x70, 0x00,
@@ -1173,86 +1103,15 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x66, 0x1B, 0x38, 0xA0, 0x00,
 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x67, 0xF1, 0xE0, 0x20, 0x00,
 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0xBF, 0x4D, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x6B, 0x67, 0xD0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x95, 0xF4, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x6D, 0x35, 0x3D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x6C, 0x9C, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x6F, 0x0B, 0xE4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x3A, 0x09, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x70, 0xD9, 0x51, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x71, 0x10, 0xB0, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x72, 0xAF, 0xF9, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0xDE, 0x1D, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x74, 0x86, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x74, 0xB4, 0xC5, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x76, 0x54, 0x0D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x8B, 0x6C, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x78, 0x2A, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x78, 0x58, 0xD9, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x79, 0xF8, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x2F, 0x81, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x7B, 0xCE, 0xC9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x28, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x7D, 0xA5, 0x71, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xD3, 0x95, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x7F, 0x72, 0xDE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xAA, 0x3D, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x81, 0x49, 0x85, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x81, 0x77, 0xAA, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x83, 0x20, 0x2D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x83, 0x4E, 0x51, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x84, 0xED, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x85, 0x24, 0xF9, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x86, 0xC4, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x86, 0xF2, 0x66, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x88, 0x91, 0xAE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x88, 0xC9, 0x0D, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x8A, 0x68, 0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x9F, 0xB5, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x8C, 0x3E, 0xFD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x6D, 0x22, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x8E, 0x0C, 0x6A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x43, 0xC9, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x8F, 0xE3, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x90, 0x11, 0x36, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x91, 0xB9, 0xB9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x91, 0xE7, 0xDE, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x93, 0x87, 0x26, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x93, 0xBE, 0x85, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x95, 0x5D, 0xCE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x95, 0x8B, 0xF2, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x97, 0x2B, 0x3B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x97, 0x62, 0x9A, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x99, 0x01, 0xE2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x99, 0x39, 0x41, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x9A, 0xD8, 0x8A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x06, 0xAE, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0x9C, 0xA5, 0xF7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xDD, 0x56, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x9E, 0x7C, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9E, 0xAA, 0xC3, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA0, 0x53, 0x46, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x81, 0x6A, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xA2, 0x20, 0xB3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x58, 0x12, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA3, 0xF7, 0x5A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x25, 0x7F, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA5, 0xC4, 0xC7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xFC, 0x26, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xA7, 0x9B, 0x6F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xD2, 0xCE, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xA9, 0x72, 0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xA0, 0x3B, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xAB, 0x3F, 0x83, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x76, 0xE2, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xAD, 0x16, 0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x44, 0x4F, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xAE, 0xEC, 0xD2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x1A, 0xF7, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xB0, 0xBA, 0x3F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xF1, 0x9E, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB2, 0x90, 0xE7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xBF, 0x0B, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB4, 0x5E, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x95, 0xB3, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xB6, 0x34, 0xFB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x6C, 0x5A, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB8, 0x0B, 0xA3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x39, 0xC7, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xB9, 0xD9, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x10, 0x6F, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xBB, 0xAF, 0xB7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xDD, 0xDC, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xBD, 0x86, 0x5F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xB4, 0x83, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xBF, 0x53, 0xCC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x8B, 0x2B, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xC1, 0x2A, 0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x58, 0x98, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xC2, 0xF7, 0xE0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x2F, 0x3F, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xC4, 0xCE, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x05, 0xE7, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xC6, 0xA5, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xD3, 0x54, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xC8, 0x72, 0x9C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xA9, 0xFB, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xCA, 0x49, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x77, 0x68, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xCC, 0x1F, 0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x4E, 0x10, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xCD, 0xED, 0x58, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x24, 0xB7, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xCF, 0xC4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xF2, 0x24, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xD1, 0x91, 0x6D, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xC8, 0xCC, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD3, 0x68, 0x14, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x96, 0x39, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD5, 0x3E, 0xBC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x6C, 0xE0, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xD7, 0x0C, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x43, 0x88, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xD8, 0xE2, 0xD0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x10, 0xF5, 0x20, 0x00,
-0x00, 0x00, 0x00, 0xDA, 0xB9, 0x78, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xE7, 0x9C, 0xA0, 0x00,
-0x00, 0x00, 0x00, 0xDC, 0x86, 0xE5, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xBE, 0x44, 0x20, 0x01,
+0x00, 0x00, 0x00, 0x6A, 0xAF, 0x30, 0x10, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
-0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
-0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF,
-0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x4C, 0x4D, 0x54,
-0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C, 0x2B,
-0x30, 0x31, 0x3E, 0x2D, 0x31, 0x0A, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE, 0x84, 0x40, 0x00, 0x00,
-0x00, 0x00, 
+0x03, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
+0x05, 0x04, 0x05, 0x03, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04,
+0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x31, 0x00,
+0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x30, 0x3E, 0x30, 0x0A,
+0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00, 
 
 /* Africa/Freetown */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x53, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -4186,7 +4045,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90, 0xFF,
@@ -4231,20 +4090,41 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
-0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D,
-0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50,
-0x54, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E,
-0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0xDB, 0x0A, 0x38, 0x00, 0x65,
-0x85, 0x95, 0x00, 0x00, 0x00, 0x22, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x2D,
-0x20, 0x41, 0x42, 0x2C, 0x20, 0x42, 0x43, 0x28, 0x45, 0x29, 0x2C, 0x20, 0x4E, 0x54, 0x28, 0x45,
-0x29, 0x2C, 0x20, 0x53, 0x4B, 0x28, 0x57, 0x29, 
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF,
+0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00,
+0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB,
+0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D,
+0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36,
+0x0A, 0x00, 0xDB, 0x0A, 0x38, 0x00, 0x65, 0x85, 0x95, 0x00, 0x00, 0x00, 0x1D, 0x43, 0x53, 0x54,
+0x20, 0x2D, 0x20, 0x41, 0x42, 0x2C, 0x20, 0x42, 0x43, 0x28, 0x45, 0x29, 0x2C, 0x20, 0x4E, 0x54,
+0x28, 0x45, 0x29, 0x2C, 0x20, 0x53, 0x4B, 0x28, 0x57, 0x29, 
 
 /* America/Eirunepe */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -9445,7 +9325,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF,
 0xFF, 0xFF, 0xFF, 0x5E, 0x3D, 0x76, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF,
 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x15, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF,
@@ -9510,7 +9390,27 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x40, 0x6F, 0xDC, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00,
 0x00, 0x00, 0x00, 0x42, 0x4F, 0xBE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00,
 0x00, 0x00, 0x00, 0x44, 0x2F, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01,
+0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x47, 0xD3, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x49, 0xB3, 0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x4B, 0x9C, 0xB3, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x4D, 0x7C, 0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x4F, 0x5C, 0x77, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x51, 0x3C, 0x59, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x53, 0x1C, 0x3B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x54, 0xFC, 0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x56, 0xE5, 0x3A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x58, 0xC5, 0x1C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5A, 0xA4, 0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5C, 0x84, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5E, 0x64, 0xC2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x60, 0x4D, 0xDE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x2D, 0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x64, 0x0D, 0xA2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x65, 0xED, 0x84, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x67, 0xCD, 0x66, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x69, 0xAD, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x02,
+0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
@@ -9518,14 +9418,15 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF,
-0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C,
-0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53,
-0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x0A, 0x50, 0x53, 0x54, 0x38, 0x50,
-0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E,
-0x30, 0x0A, 0x00, 0xD4, 0x81, 0x0A, 0x00, 0x56, 0xCC, 0x0D, 0x00, 0x00, 0x00, 0x19, 0x50, 0x61,
-0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x2D, 0x20, 0x42, 0x43, 0x20, 0x28, 0x6D, 0x6F, 0x73, 0x74,
-0x20, 0x61, 0x72, 0x65, 0x61, 0x73, 0x29, 
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D,
+0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF,
+0xFF, 0x9D, 0x90, 0x01, 0x10, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50,
+0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D,
+0x53, 0x54, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x0A, 0x00, 0xD4, 0x81, 0x0A, 0x00, 0x56, 0xCC,
+0x0D, 0x00, 0x00, 0x00, 0x15, 0x4D, 0x53, 0x54, 0x20, 0x2D, 0x20, 0x42, 0x43, 0x20, 0x28, 0x6D,
+0x6F, 0x73, 0x74, 0x20, 0x61, 0x72, 0x65, 0x61, 0x73, 0x29, 
 
 /* America/Virgin */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -9765,7 +9666,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90, 0xFF,
@@ -9810,18 +9711,39 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
-0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D,
-0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50,
-0x54, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E,
-0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF,
+0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00,
+0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB,
+0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D,
+0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Antarctica/Casey */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -11681,17 +11603,17 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF,
 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF,
 0xFF, 0xFF, 0xFF, 0xE4, 0xB6, 0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x0A, 0x3D, 0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02,
-0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70,
-0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x4C, 0x4D,
-0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B,
-0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x99, 0xBB, 0x78,
-0x01, 0xB5, 0x6B, 0x2A, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x63, 0xF6, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70,
+0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x50, 0x4C,
+0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A,
+0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x99, 0xBB, 0x78, 0x01, 0xB5, 0x6B, 0x2A,
+0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Hong_Kong */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x48, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -12775,15 +12697,15 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x45, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF,
 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00, 0x00, 0x62, 0x5C,
-0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00,
-0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C,
-0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A,
-0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x9A, 0xF3, 0xF8, 0x01, 0xB2, 0xBF, 0x92,
-0x00, 0x00, 0x00, 0x00, 
+0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00,
+0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B,
+0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37,
+0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x9A, 0xF3, 0xF8, 0x01, 0xB2, 0xBF, 0x92, 0x00, 0x00, 0x00, 0x00,
+
 
 /* Asia/Pontianak */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -12954,17 +12876,17 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF,
 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF,
 0xFF, 0xFF, 0xFF, 0xE4, 0xB6, 0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x0A, 0x3D, 0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02,
-0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70,
-0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x4C, 0x4D,
-0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B,
-0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x63, 0xF6, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70,
+0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x50, 0x4C,
+0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A,
+0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Sakhalin */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -13663,16 +13585,16 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x15, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x47, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF,
 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF,
 0xFF, 0xFF, 0xFF, 0xE4, 0x51, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x00, 0x00,
-0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09,
-0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00,
-0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39,
-0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0xA4, 0xBE, 0x7A, 0x01, 0xAF,
-0x36, 0xA0, 0x00, 0x00, 0x00, 0x00, 
+0x60, 0x30, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05,
+0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x50, 0x4C, 0x4D, 0x54,
+0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B,
+0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0xA4, 0xBE, 0x7A, 0x01, 0xAF, 0x36, 0xA0, 0x00, 0x00,
+0x00, 0x00, 
 
 /* Asia/Vladivostok */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -15969,7 +15891,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF,
 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90, 0xFF,
 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90, 0xFF,
@@ -16014,18 +15936,39 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80, 0x00,
 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
-0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D,
-0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50,
-0x54, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E,
-0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF,
+0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00,
+0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB,
+0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D,
+0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Canada/Newfoundland */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -16154,7 +16097,7 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF,
 0xFF, 0xFF, 0xFF, 0x5E, 0x3D, 0x76, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF,
 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x15, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF,
 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF,
@@ -16219,7 +16162,27 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x00, 0x00, 0x00, 0x40, 0x6F, 0xDC, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00,
 0x00, 0x00, 0x00, 0x42, 0x4F, 0xBE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00,
 0x00, 0x00, 0x00, 0x44, 0x2F, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01,
+0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x47, 0xD3, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x49, 0xB3, 0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x4B, 0x9C, 0xB3, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x4D, 0x7C, 0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x4F, 0x5C, 0x77, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x51, 0x3C, 0x59, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x53, 0x1C, 0x3B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x54, 0xFC, 0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x56, 0xE5, 0x3A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x58, 0xC5, 0x1C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5A, 0xA4, 0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5C, 0x84, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x5E, 0x64, 0xC2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x60, 0x4D, 0xDE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x2D, 0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x64, 0x0D, 0xA2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x65, 0xED, 0x84, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x67, 0xCD, 0x66, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x69, 0xAD, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x02,
+0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
@@ -16227,12 +16190,14 @@ const unsigned char timelib_timezone_db_data_builtin[357654] = {
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF,
-0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C,
-0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53,
-0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x0A, 0x50, 0x53, 0x54, 0x38, 0x50,
-0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E, 0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E,
-0x30, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D,
+0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF,
+0xFF, 0x9D, 0x90, 0x01, 0x10, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50,
+0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D,
+0x53, 0x54, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Canada/Saskatchewan */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -24474,593 +24439,593 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[598] = {
 	{ (char*) "Africa/Bujumbura"                  , 0x000F1A },
 	{ (char*) "Africa/Cairo"                      , 0x000FBB },
 	{ (char*) "Africa/Casablanca"                 , 0x001926 },
-	{ (char*) "Africa/Ceuta"                      , 0x0022AF },
-	{ (char*) "Africa/Conakry"                    , 0x002ACD },
-	{ (char*) "Africa/Dakar"                      , 0x002BA9 },
-	{ (char*) "Africa/Dar_es_Salaam"              , 0x002C6B },
-	{ (char*) "Africa/Djibouti"                   , 0x002D4C },
-	{ (char*) "Africa/Douala"                     , 0x002DED },
-	{ (char*) "Africa/El_Aaiun"                   , 0x002E8E },
-	{ (char*) "Africa/Freetown"                   , 0x003791 },
-	{ (char*) "Africa/Gaborone"                   , 0x00396D },
-	{ (char*) "Africa/Harare"                     , 0x003A64 },
-	{ (char*) "Africa/Johannesburg"               , 0x003B05 },
-	{ (char*) "Africa/Juba"                       , 0x003C07 },
-	{ (char*) "Africa/Kampala"                    , 0x003EBA },
-	{ (char*) "Africa/Khartoum"                   , 0x003FC1 },
-	{ (char*) "Africa/Kigali"                     , 0x004274 },
-	{ (char*) "Africa/Kinshasa"                   , 0x004315 },
-	{ (char*) "Africa/Lagos"                      , 0x0043CF },
-	{ (char*) "Africa/Libreville"                 , 0x0044C6 },
-	{ (char*) "Africa/Lome"                       , 0x004567 },
-	{ (char*) "Africa/Luanda"                     , 0x004607 },
-	{ (char*) "Africa/Lubumbashi"                 , 0x0046CE },
-	{ (char*) "Africa/Lusaka"                     , 0x0047AA },
-	{ (char*) "Africa/Malabo"                     , 0x00484B },
-	{ (char*) "Africa/Maputo"                     , 0x00490E },
-	{ (char*) "Africa/Maseru"                     , 0x0049AF },
-	{ (char*) "Africa/Mbabane"                    , 0x004A7B },
-	{ (char*) "Africa/Mogadishu"                  , 0x004B1F },
-	{ (char*) "Africa/Monrovia"                   , 0x004C00 },
-	{ (char*) "Africa/Nairobi"                    , 0x004CDC },
-	{ (char*) "Africa/Ndjamena"                   , 0x004DF1 },
-	{ (char*) "Africa/Niamey"                     , 0x004EC4 },
-	{ (char*) "Africa/Nouakchott"                 , 0x004FA9 },
-	{ (char*) "Africa/Ouagadougou"                , 0x005085 },
-	{ (char*) "Africa/Porto-Novo"                 , 0x005125 },
-	{ (char*) "Africa/Sao_Tome"                   , 0x0051E8 },
-	{ (char*) "Africa/Timbuktu"                   , 0x0052F2 },
-	{ (char*) "Africa/Tripoli"                    , 0x005392 },
-	{ (char*) "Africa/Tunis"                      , 0x00560F },
-	{ (char*) "Africa/Windhoek"                   , 0x0058CC },
-	{ (char*) "America/Adak"                      , 0x005C93 },
-	{ (char*) "America/Anchorage"                 , 0x0065ED },
-	{ (char*) "America/Anguilla"                  , 0x006F4F },
-	{ (char*) "America/Antigua"                   , 0x006FEF },
-	{ (char*) "America/Araguaina"                 , 0x0070B1 },
-	{ (char*) "America/Argentina/Buenos_Aires"    , 0x00742C },
-	{ (char*) "America/Argentina/Catamarca"       , 0x007873 },
-	{ (char*) "America/Argentina/ComodRivadavia"  , 0x007CC0 },
-	{ (char*) "America/Argentina/Cordoba"         , 0x0080F2 },
-	{ (char*) "America/Argentina/Jujuy"           , 0x00855A },
-	{ (char*) "America/Argentina/La_Rioja"        , 0x00897A },
-	{ (char*) "America/Argentina/Mendoza"         , 0x008DC7 },
-	{ (char*) "America/Argentina/Rio_Gallegos"    , 0x009205 },
-	{ (char*) "America/Argentina/Salta"           , 0x009646 },
-	{ (char*) "America/Argentina/San_Juan"        , 0x009A72 },
-	{ (char*) "America/Argentina/San_Luis"        , 0x009EBF },
-	{ (char*) "America/Argentina/Tucuman"         , 0x00A318 },
-	{ (char*) "America/Argentina/Ushuaia"         , 0x00A772 },
-	{ (char*) "America/Aruba"                     , 0x00ABB9 },
-	{ (char*) "America/Asuncion"                  , 0x00AC7F },
-	{ (char*) "America/Atikokan"                  , 0x00B2F7 },
-	{ (char*) "America/Atka"                      , 0x00B474 },
-	{ (char*) "America/Bahia"                     , 0x00BDB4 },
-	{ (char*) "America/Bahia_Banderas"            , 0x00C1B7 },
-	{ (char*) "America/Barbados"                  , 0x00C620 },
-	{ (char*) "America/Belem"                     , 0x00C7E0 },
-	{ (char*) "America/Belize"                    , 0x00CA30 },
-	{ (char*) "America/Blanc-Sablon"              , 0x00D08A },
-	{ (char*) "America/Boa_Vista"                 , 0x00D1DC },
-	{ (char*) "America/Bogota"                    , 0x00D459 },
-	{ (char*) "America/Boise"                     , 0x00D54D },
-	{ (char*) "America/Buenos_Aires"              , 0x00DEE3 },
-	{ (char*) "America/Cambridge_Bay"             , 0x00E315 },
-	{ (char*) "America/Campo_Grande"              , 0x00EC03 },
-	{ (char*) "America/Cancun"                    , 0x00F1B7 },
-	{ (char*) "America/Caracas"                   , 0x00F52F },
-	{ (char*) "America/Catamarca"                 , 0x00F635 },
-	{ (char*) "America/Cayenne"                   , 0x00FA67 },
-	{ (char*) "America/Cayman"                    , 0x00FB2B },
-	{ (char*) "America/Chicago"                   , 0x00FBED },
-	{ (char*) "America/Chihuahua"                 , 0x010A15 },
-	{ (char*) "America/Ciudad_Juarez"             , 0x010E85 },
-	{ (char*) "America/Coral_Harbour"             , 0x0114AF },
-	{ (char*) "America/Cordoba"                   , 0x011571 },
-	{ (char*) "America/Costa_Rica"                , 0x0119A3 },
-	{ (char*) "America/Coyhaique"                 , 0x011AEB },
-	{ (char*) "America/Creston"                   , 0x012351 },
-	{ (char*) "America/Cuiaba"                    , 0x01243F },
-	{ (char*) "America/Curacao"                   , 0x0129D0 },
-	{ (char*) "America/Danmarkshavn"              , 0x012A96 },
-	{ (char*) "America/Dawson"                    , 0x012D76 },
-	{ (char*) "America/Dawson_Creek"              , 0x0133E2 },
-	{ (char*) "America/Denver"                    , 0x013828 },
-	{ (char*) "America/Detroit"                   , 0x0141E5 },
-	{ (char*) "America/Dominica"                  , 0x014AC0 },
-	{ (char*) "America/Edmonton"                  , 0x014B60 },
-	{ (char*) "America/Eirunepe"                  , 0x0154AA },
-	{ (char*) "America/El_Salvador"               , 0x015747 },
-	{ (char*) "America/Ensenada"                  , 0x015833 },
-	{ (char*) "America/Fort_Nelson"               , 0x016399 },
-	{ (char*) "America/Fort_Wayne"                , 0x016C79 },
-	{ (char*) "America/Fortaleza"                 , 0x017317 },
-	{ (char*) "America/Glace_Bay"                 , 0x017607 },
-	{ (char*) "America/Godthab"                   , 0x017EBE },
-	{ (char*) "America/Goose_Bay"                 , 0x01862B },
-	{ (char*) "America/Grand_Turk"                , 0x0192E1 },
-	{ (char*) "America/Grenada"                   , 0x019A17 },
-	{ (char*) "America/Guadeloupe"                , 0x019AB7 },
-	{ (char*) "America/Guatemala"                 , 0x019B57 },
-	{ (char*) "America/Guayaquil"                 , 0x019C7B },
-	{ (char*) "America/Guyana"                    , 0x019D81 },
-	{ (char*) "America/Halifax"                   , 0x019E85 },
-	{ (char*) "America/Havana"                    , 0x01AC0F },
-	{ (char*) "America/Hermosillo"                , 0x01B58B },
-	{ (char*) "America/Indiana/Indianapolis"      , 0x01B721 },
-	{ (char*) "America/Indiana/Knox"              , 0x01BDD8 },
-	{ (char*) "America/Indiana/Marengo"           , 0x01C785 },
-	{ (char*) "America/Indiana/Petersburg"        , 0x01CE72 },
-	{ (char*) "America/Indiana/Tell_City"         , 0x01D611 },
-	{ (char*) "America/Indiana/Vevay"             , 0x01DCD5 },
-	{ (char*) "America/Indiana/Vincennes"         , 0x01E291 },
-	{ (char*) "America/Indiana/Winamac"           , 0x01E967 },
-	{ (char*) "America/Indianapolis"              , 0x01F08B },
-	{ (char*) "America/Inuvik"                    , 0x01F729 },
-	{ (char*) "America/Iqaluit"                   , 0x01FF63 },
-	{ (char*) "America/Jamaica"                   , 0x020822 },
-	{ (char*) "America/Jujuy"                     , 0x020A10 },
-	{ (char*) "America/Juneau"                    , 0x020E26 },
-	{ (char*) "America/Kentucky/Louisville"       , 0x021777 },
-	{ (char*) "America/Kentucky/Monticello"       , 0x022285 },
-	{ (char*) "America/Knox_IN"                   , 0x022BE5 },
-	{ (char*) "America/Kralendijk"                , 0x02357D },
-	{ (char*) "America/La_Paz"                    , 0x02367F },
-	{ (char*) "America/Lima"                      , 0x023765 },
-	{ (char*) "America/Los_Angeles"               , 0x0238F9 },
-	{ (char*) "America/Louisville"                , 0x024430 },
-	{ (char*) "America/Lower_Princes"             , 0x024F20 },
-	{ (char*) "America/Maceio"                    , 0x025022 },
-	{ (char*) "America/Managua"                   , 0x025318 },
-	{ (char*) "America/Manaus"                    , 0x0254D2 },
-	{ (char*) "America/Marigot"                   , 0x02573B },
-	{ (char*) "America/Martinique"                , 0x02583D },
-	{ (char*) "America/Matamoros"                 , 0x025931 },
-	{ (char*) "America/Mazatlan"                  , 0x025EF3 },
-	{ (char*) "America/Mendoza"                   , 0x026355 },
-	{ (char*) "America/Menominee"                 , 0x026787 },
-	{ (char*) "America/Merida"                    , 0x027094 },
-	{ (char*) "America/Metlakatla"                , 0x02749D },
-	{ (char*) "America/Mexico_City"               , 0x027A4F },
-	{ (char*) "America/Miquelon"                  , 0x027F2F },
-	{ (char*) "America/Moncton"                   , 0x0285AF },
-	{ (char*) "America/Monterrey"                 , 0x029225 },
-	{ (char*) "America/Montevideo"                , 0x0296C1 },
-	{ (char*) "America/Montreal"                  , 0x029CA5 },
-	{ (char*) "America/Montserrat"                , 0x02AA57 },
-	{ (char*) "America/Nassau"                    , 0x02AAF7 },
-	{ (char*) "America/New_York"                  , 0x02B457 },
-	{ (char*) "America/Nipigon"                   , 0x02C257 },
-	{ (char*) "America/Nome"                      , 0x02D009 },
-	{ (char*) "America/Noronha"                   , 0x02D961 },
-	{ (char*) "America/North_Dakota/Beulah"       , 0x02DC3B },
-	{ (char*) "America/North_Dakota/Center"       , 0x02E5B8 },
-	{ (char*) "America/North_Dakota/New_Salem"    , 0x02EF35 },
-	{ (char*) "America/Nuuk"                      , 0x02F8B8 },
-	{ (char*) "America/Ojinaga"                   , 0x030036 },
-	{ (char*) "America/Panama"                    , 0x030652 },
-	{ (char*) "America/Pangnirtung"               , 0x030714 },
-	{ (char*) "America/Paramaribo"                , 0x030FBA },
-	{ (char*) "America/Phoenix"                   , 0x0310BE },
-	{ (char*) "America/Port-au-Prince"            , 0x03124A },
-	{ (char*) "America/Port_of_Spain"             , 0x0317F0 },
-	{ (char*) "America/Porto_Acre"                , 0x031890 },
-	{ (char*) "America/Porto_Velho"               , 0x031B02 },
-	{ (char*) "America/Puerto_Rico"               , 0x031D48 },
-	{ (char*) "America/Punta_Arenas"              , 0x031E4A },
-	{ (char*) "America/Rainy_River"               , 0x0325D5 },
-	{ (char*) "America/Rankin_Inlet"              , 0x033115 },
-	{ (char*) "America/Recife"                    , 0x033949 },
-	{ (char*) "America/Regina"                    , 0x033C1D },
-	{ (char*) "America/Resolute"                  , 0x034012 },
-	{ (char*) "America/Rio_Branco"                , 0x034847 },
-	{ (char*) "America/Rosario"                   , 0x034ABD },
-	{ (char*) "America/Santa_Isabel"              , 0x034EEF },
-	{ (char*) "America/Santarem"                  , 0x035A55 },
-	{ (char*) "America/Santiago"                  , 0x035CB8 },
-	{ (char*) "America/Santo_Domingo"             , 0x0366A4 },
-	{ (char*) "America/Sao_Paulo"                 , 0x03687A },
-	{ (char*) "America/Scoresbysund"              , 0x036E52 },
-	{ (char*) "America/Shiprock"                  , 0x03760A },
-	{ (char*) "America/Sitka"                     , 0x037FB2 },
-	{ (char*) "America/St_Barthelemy"             , 0x0388EA },
-	{ (char*) "America/St_Johns"                  , 0x0389EC },
-	{ (char*) "America/St_Kitts"                  , 0x03985A },
-	{ (char*) "America/St_Lucia"                  , 0x0398FA },
-	{ (char*) "America/St_Thomas"                 , 0x0399BC },
-	{ (char*) "America/St_Vincent"                , 0x039A5C },
-	{ (char*) "America/Swift_Current"             , 0x039B1E },
-	{ (char*) "America/Tegucigalpa"               , 0x039D6C },
-	{ (char*) "America/Thule"                     , 0x039E74 },
-	{ (char*) "America/Thunder_Bay"               , 0x03A46C },
-	{ (char*) "America/Tijuana"                   , 0x03B21E },
-	{ (char*) "America/Toronto"                   , 0x03BD93 },
-	{ (char*) "America/Tortola"                   , 0x03CB63 },
-	{ (char*) "America/Vancouver"                 , 0x03CC03 },
-	{ (char*) "America/Virgin"                    , 0x03D774 },
-	{ (char*) "America/Whitehorse"                , 0x03D876 },
-	{ (char*) "America/Winnipeg"                  , 0x03DEE2 },
-	{ (char*) "America/Yakutat"                   , 0x03EA3F },
-	{ (char*) "America/Yellowknife"               , 0x03F35C },
-	{ (char*) "Antarctica/Casey"                  , 0x03FC84 },
-	{ (char*) "Antarctica/Davis"                  , 0x03FE3C },
-	{ (char*) "Antarctica/DumontDUrville"         , 0x03FF68 },
-	{ (char*) "Antarctica/Macquarie"              , 0x040038 },
-	{ (char*) "Antarctica/Mawson"                 , 0x040928 },
-	{ (char*) "Antarctica/McMurdo"                , 0x0409F3 },
-	{ (char*) "Antarctica/Palmer"                 , 0x0411EE },
-	{ (char*) "Antarctica/Rothera"                , 0x04177C },
-	{ (char*) "Antarctica/South_Pole"             , 0x041825 },
-	{ (char*) "Antarctica/Syowa"                  , 0x0421B6 },
-	{ (char*) "Antarctica/Troll"                  , 0x04225E },
-	{ (char*) "Antarctica/Vostok"                 , 0x0426EB },
-	{ (char*) "Arctic/Longyearbyen"               , 0x0427D2 },
-	{ (char*) "Asia/Aden"                         , 0x0430D8 },
-	{ (char*) "Asia/Almaty"                       , 0x04317B },
-	{ (char*) "Asia/Amman"                        , 0x043570 },
-	{ (char*) "Asia/Anadyr"                       , 0x043B15 },
-	{ (char*) "Asia/Aqtau"                        , 0x043FCA },
-	{ (char*) "Asia/Aqtobe"                       , 0x0443B4 },
-	{ (char*) "Asia/Ashgabat"                     , 0x0447B2 },
-	{ (char*) "Asia/Ashkhabad"                    , 0x044A1B },
-	{ (char*) "Asia/Atyrau"                       , 0x044C84 },
-	{ (char*) "Asia/Baghdad"                      , 0x045076 },
-	{ (char*) "Asia/Bahrain"                      , 0x04544B },
-	{ (char*) "Asia/Baku"                         , 0x045536 },
-	{ (char*) "Asia/Bangkok"                      , 0x0459FF },
-	{ (char*) "Asia/Barnaul"                      , 0x045AC4 },
-	{ (char*) "Asia/Beirut"                       , 0x045F95 },
-	{ (char*) "Asia/Bishkek"                      , 0x04680B },
-	{ (char*) "Asia/Brunei"                       , 0x046BE0 },
-	{ (char*) "Asia/Calcutta"                     , 0x046CA9 },
-	{ (char*) "Asia/Chita"                        , 0x046DD2 },
-	{ (char*) "Asia/Choibalsan"                   , 0x0472A9 },
-	{ (char*) "Asia/Chongqing"                    , 0x047622 },
-	{ (char*) "Asia/Chungking"                    , 0x04785F },
-	{ (char*) "Asia/Colombo"                      , 0x047A9C },
-	{ (char*) "Asia/Dacca"                        , 0x047C0E },
-	{ (char*) "Asia/Damascus"                     , 0x047D5D },
-	{ (char*) "Asia/Dhaka"                        , 0x0484BA },
-	{ (char*) "Asia/Dili"                         , 0x048609 },
-	{ (char*) "Asia/Dubai"                        , 0x048716 },
-	{ (char*) "Asia/Dushanbe"                     , 0x0487B9 },
-	{ (char*) "Asia/Famagusta"                    , 0x048A06 },
-	{ (char*) "Asia/Gaza"                         , 0x04920D },
-	{ (char*) "Asia/Harbin"                       , 0x04A127 },
-	{ (char*) "Asia/Hebron"                       , 0x04A364 },
-	{ (char*) "Asia/Ho_Chi_Minh"                  , 0x04B299 },
-	{ (char*) "Asia/Hong_Kong"                    , 0x04B3F6 },
-	{ (char*) "Asia/Hovd"                         , 0x04B8D3 },
-	{ (char*) "Asia/Irkutsk"                      , 0x04BC62 },
-	{ (char*) "Asia/Istanbul"                     , 0x04C155 },
-	{ (char*) "Asia/Jakarta"                      , 0x04C8EE },
-	{ (char*) "Asia/Jayapura"                     , 0x04CA86 },
-	{ (char*) "Asia/Jerusalem"                    , 0x04CBA5 },
-	{ (char*) "Asia/Kabul"                        , 0x04D505 },
-	{ (char*) "Asia/Kamchatka"                    , 0x04D5D3 },
-	{ (char*) "Asia/Karachi"                      , 0x04DA71 },
-	{ (char*) "Asia/Kashgar"                      , 0x04DBF8 },
-	{ (char*) "Asia/Kathmandu"                    , 0x04DC9B },
-	{ (char*) "Asia/Katmandu"                     , 0x04DD6D },
-	{ (char*) "Asia/Khandyga"                     , 0x04DE3F },
-	{ (char*) "Asia/Kolkata"                      , 0x04E352 },
-	{ (char*) "Asia/Krasnoyarsk"                  , 0x04E47B },
-	{ (char*) "Asia/Kuala_Lumpur"                 , 0x04E949 },
-	{ (char*) "Asia/Kuching"                      , 0x04EAFA },
-	{ (char*) "Asia/Kuwait"                       , 0x04ECE9 },
-	{ (char*) "Asia/Macao"                        , 0x04ED8C },
-	{ (char*) "Asia/Macau"                        , 0x04F263 },
-	{ (char*) "Asia/Magadan"                      , 0x04F73A },
-	{ (char*) "Asia/Makassar"                     , 0x04FC0E },
-	{ (char*) "Asia/Manila"                       , 0x04FD61 },
-	{ (char*) "Asia/Muscat"                       , 0x04FF13 },
-	{ (char*) "Asia/Nicosia"                      , 0x04FFB6 },
-	{ (char*) "Asia/Novokuznetsk"                 , 0x0507A2 },
-	{ (char*) "Asia/Novosibirsk"                  , 0x050C3E },
-	{ (char*) "Asia/Omsk"                         , 0x051115 },
-	{ (char*) "Asia/Oral"                         , 0x0515D7 },
-	{ (char*) "Asia/Phnom_Penh"                   , 0x0519D1 },
-	{ (char*) "Asia/Pontianak"                    , 0x051AF6 },
-	{ (char*) "Asia/Pyongyang"                    , 0x051C79 },
-	{ (char*) "Asia/Qatar"                        , 0x051D72 },
-	{ (char*) "Asia/Qostanay"                     , 0x051E37 },
-	{ (char*) "Asia/Qyzylorda"                    , 0x05225E },
-	{ (char*) "Asia/Rangoon"                      , 0x05267A },
-	{ (char*) "Asia/Riyadh"                       , 0x052784 },
-	{ (char*) "Asia/Saigon"                       , 0x052827 },
-	{ (char*) "Asia/Sakhalin"                     , 0x052984 },
-	{ (char*) "Asia/Samarkand"                    , 0x052E4C },
-	{ (char*) "Asia/Seoul"                        , 0x05309C },
-	{ (char*) "Asia/Shanghai"                     , 0x053311 },
-	{ (char*) "Asia/Singapore"                    , 0x05355A },
-	{ (char*) "Asia/Srednekolymsk"                , 0x0536F7 },
-	{ (char*) "Asia/Taipei"                       , 0x053BCB },
-	{ (char*) "Asia/Tashkent"                     , 0x053ED0 },
-	{ (char*) "Asia/Tbilisi"                      , 0x05412E },
-	{ (char*) "Asia/Tehran"                       , 0x054529 },
-	{ (char*) "Asia/Tel_Aviv"                     , 0x054A15 },
-	{ (char*) "Asia/Thimbu"                       , 0x055375 },
-	{ (char*) "Asia/Thimphu"                      , 0x05543E },
-	{ (char*) "Asia/Tokyo"                        , 0x055507 },
-	{ (char*) "Asia/Tomsk"                        , 0x055648 },
-	{ (char*) "Asia/Ujung_Pandang"                , 0x055B19 },
-	{ (char*) "Asia/Ulaanbaatar"                  , 0x055C23 },
-	{ (char*) "Asia/Ulan_Bator"                   , 0x055FAC },
-	{ (char*) "Asia/Urumqi"                       , 0x056325 },
-	{ (char*) "Asia/Ust-Nera"                     , 0x0563D5 },
-	{ (char*) "Asia/Vientiane"                    , 0x0568CB },
-	{ (char*) "Asia/Vladivostok"                  , 0x056A0C },
-	{ (char*) "Asia/Yakutsk"                      , 0x056ED5 },
-	{ (char*) "Asia/Yangon"                       , 0x05739D },
-	{ (char*) "Asia/Yekaterinburg"                , 0x0574A7 },
-	{ (char*) "Asia/Yerevan"                      , 0x05798E },
-	{ (char*) "Atlantic/Azores"                   , 0x057E0B },
-	{ (char*) "Atlantic/Bermuda"                  , 0x058B8F },
-	{ (char*) "Atlantic/Canary"                   , 0x0594F7 },
-	{ (char*) "Atlantic/Cape_Verde"               , 0x059C7A },
-	{ (char*) "Atlantic/Faeroe"                   , 0x059D86 },
-	{ (char*) "Atlantic/Faroe"                    , 0x05A4A9 },
-	{ (char*) "Atlantic/Jan_Mayen"                , 0x05ABCC },
-	{ (char*) "Atlantic/Madeira"                  , 0x05B4D2 },
-	{ (char*) "Atlantic/Reykjavik"                , 0x05C21E },
-	{ (char*) "Atlantic/South_Georgia"            , 0x05C6B4 },
-	{ (char*) "Atlantic/St_Helena"                , 0x05C756 },
-	{ (char*) "Atlantic/Stanley"                  , 0x05C818 },
-	{ (char*) "Australia/ACT"                     , 0x05CCD4 },
-	{ (char*) "Australia/Adelaide"                , 0x05D56E },
-	{ (char*) "Australia/Brisbane"                , 0x05DE29 },
-	{ (char*) "Australia/Broken_Hill"             , 0x05DFEF },
-	{ (char*) "Australia/Canberra"                , 0x05E8CC },
-	{ (char*) "Australia/Currie"                  , 0x05F166 },
-	{ (char*) "Australia/Darwin"                  , 0x05FAA8 },
-	{ (char*) "Australia/Eucla"                   , 0x05FC0B },
-	{ (char*) "Australia/Hobart"                  , 0x05FDF8 },
-	{ (char*) "Australia/LHI"                     , 0x060742 },
-	{ (char*) "Australia/Lindeman"                , 0x060E84 },
-	{ (char*) "Australia/Lord_Howe"               , 0x06108A },
-	{ (char*) "Australia/Melbourne"               , 0x0617DC },
-	{ (char*) "Australia/North"                   , 0x06207E },
-	{ (char*) "Australia/NSW"                     , 0x0621CF },
-	{ (char*) "Australia/Perth"                   , 0x062A69 },
-	{ (char*) "Australia/Queensland"              , 0x062C51 },
-	{ (char*) "Australia/South"                   , 0x062E00 },
-	{ (char*) "Australia/Sydney"                  , 0x0636AC },
-	{ (char*) "Australia/Tasmania"                , 0x063F62 },
-	{ (char*) "Australia/Victoria"                , 0x0648A4 },
-	{ (char*) "Australia/West"                    , 0x06513E },
-	{ (char*) "Australia/Yancowinna"              , 0x065308 },
-	{ (char*) "Brazil/Acre"                       , 0x065BC9 },
-	{ (char*) "Brazil/DeNoronha"                  , 0x065E3B },
-	{ (char*) "Brazil/East"                       , 0x066105 },
-	{ (char*) "Brazil/West"                       , 0x0666A7 },
-	{ (char*) "Canada/Atlantic"                   , 0x066901 },
-	{ (char*) "Canada/Central"                    , 0x06766D },
-	{ (char*) "Canada/Eastern"                    , 0x0681AD },
-	{ (char*) "Canada/Mountain"                   , 0x068F5F },
-	{ (char*) "Canada/Newfoundland"               , 0x069887 },
-	{ (char*) "Canada/Pacific"                    , 0x06A6DA },
-	{ (char*) "Canada/Saskatchewan"               , 0x06B232 },
-	{ (char*) "Canada/Yukon"                      , 0x06B612 },
-	{ (char*) "CET"                               , 0x06BC6C },
-	{ (char*) "Chile/Continental"                 , 0x06C7ED },
-	{ (char*) "Chile/EasterIsland"                , 0x06D1CC },
-	{ (char*) "CST6CDT"                           , 0x06DA83 },
-	{ (char*) "Cuba"                              , 0x06E897 },
-	{ (char*) "EET"                               , 0x06F213 },
-	{ (char*) "Egypt"                             , 0x06FAF5 },
-	{ (char*) "Eire"                              , 0x070460 },
-	{ (char*) "EST"                               , 0x071210 },
-	{ (char*) "EST5EDT"                           , 0x0712D2 },
-	{ (char*) "Etc/GMT"                           , 0x0720BE },
-	{ (char*) "Etc/GMT+0"                         , 0x07213C },
-	{ (char*) "Etc/GMT+1"                         , 0x0721BA },
-	{ (char*) "Etc/GMT+10"                        , 0x07223A },
-	{ (char*) "Etc/GMT+11"                        , 0x0722BB },
-	{ (char*) "Etc/GMT+12"                        , 0x07233C },
-	{ (char*) "Etc/GMT+2"                         , 0x0723BD },
-	{ (char*) "Etc/GMT+3"                         , 0x07243D },
-	{ (char*) "Etc/GMT+4"                         , 0x0724BD },
-	{ (char*) "Etc/GMT+5"                         , 0x07253D },
-	{ (char*) "Etc/GMT+6"                         , 0x0725BD },
-	{ (char*) "Etc/GMT+7"                         , 0x07263D },
-	{ (char*) "Etc/GMT+8"                         , 0x0726BD },
-	{ (char*) "Etc/GMT+9"                         , 0x07273D },
-	{ (char*) "Etc/GMT-0"                         , 0x0727BD },
-	{ (char*) "Etc/GMT-1"                         , 0x07283B },
-	{ (char*) "Etc/GMT-10"                        , 0x0728BC },
-	{ (char*) "Etc/GMT-11"                        , 0x07293E },
-	{ (char*) "Etc/GMT-12"                        , 0x0729C0 },
-	{ (char*) "Etc/GMT-13"                        , 0x072A42 },
-	{ (char*) "Etc/GMT-14"                        , 0x072AC4 },
-	{ (char*) "Etc/GMT-2"                         , 0x072B46 },
-	{ (char*) "Etc/GMT-3"                         , 0x072BC7 },
-	{ (char*) "Etc/GMT-4"                         , 0x072C48 },
-	{ (char*) "Etc/GMT-5"                         , 0x072CC9 },
-	{ (char*) "Etc/GMT-6"                         , 0x072D4A },
-	{ (char*) "Etc/GMT-7"                         , 0x072DCB },
-	{ (char*) "Etc/GMT-8"                         , 0x072E4C },
-	{ (char*) "Etc/GMT-9"                         , 0x072ECD },
-	{ (char*) "Etc/GMT0"                          , 0x072F4E },
-	{ (char*) "Etc/Greenwich"                     , 0x072FCC },
-	{ (char*) "Etc/UCT"                           , 0x07304A },
-	{ (char*) "Etc/Universal"                     , 0x0730C8 },
-	{ (char*) "Etc/UTC"                           , 0x073146 },
-	{ (char*) "Etc/Zulu"                          , 0x0731C4 },
-	{ (char*) "Europe/Amsterdam"                  , 0x073242 },
-	{ (char*) "Europe/Andorra"                    , 0x073DAC },
-	{ (char*) "Europe/Astrakhan"                  , 0x074486 },
-	{ (char*) "Europe/Athens"                     , 0x074923 },
-	{ (char*) "Europe/Belfast"                    , 0x075205 },
-	{ (char*) "Europe/Belgrade"                   , 0x076061 },
-	{ (char*) "Europe/Berlin"                     , 0x0767ED },
-	{ (char*) "Europe/Bratislava"                 , 0x077102 },
-	{ (char*) "Europe/Brussels"                   , 0x077A0B },
-	{ (char*) "Europe/Bucharest"                  , 0x07858C },
-	{ (char*) "Europe/Budapest"                   , 0x078E20 },
-	{ (char*) "Europe/Busingen"                   , 0x07976C },
-	{ (char*) "Europe/Chisinau"                   , 0x079EF5 },
-	{ (char*) "Europe/Copenhagen"                 , 0x07A879 },
-	{ (char*) "Europe/Dublin"                     , 0x07B0DE },
-	{ (char*) "Europe/Gibraltar"                  , 0x07BE8E },
-	{ (char*) "Europe/Guernsey"                   , 0x07CA96 },
-	{ (char*) "Europe/Helsinki"                   , 0x07D936 },
-	{ (char*) "Europe/Isle_of_Man"                , 0x07E0AE },
-	{ (char*) "Europe/Istanbul"                   , 0x07EEFA },
-	{ (char*) "Europe/Jersey"                     , 0x07F693 },
-	{ (char*) "Europe/Kaliningrad"                , 0x080533 },
-	{ (char*) "Europe/Kiev"                       , 0x080B28 },
-	{ (char*) "Europe/Kirov"                      , 0x08137C },
-	{ (char*) "Europe/Kyiv"                       , 0x081837 },
-	{ (char*) "Europe/Lisbon"                     , 0x08209A },
-	{ (char*) "Europe/Ljubljana"                  , 0x082E80 },
-	{ (char*) "Europe/London"                     , 0x08360C },
-	{ (char*) "Europe/Luxembourg"                 , 0x084468 },
-	{ (char*) "Europe/Madrid"                     , 0x084FF6 },
-	{ (char*) "Europe/Malta"                      , 0x085A48 },
-	{ (char*) "Europe/Mariehamn"                  , 0x086490 },
-	{ (char*) "Europe/Minsk"                      , 0x086C08 },
-	{ (char*) "Europe/Monaco"                     , 0x08712F },
-	{ (char*) "Europe/Moscow"                     , 0x087CBB },
-	{ (char*) "Europe/Nicosia"                    , 0x0882DA },
-	{ (char*) "Europe/Oslo"                       , 0x088AB8 },
-	{ (char*) "Europe/Paris"                      , 0x089378 },
-	{ (char*) "Europe/Podgorica"                  , 0x089F16 },
-	{ (char*) "Europe/Prague"                     , 0x08A6A2 },
-	{ (char*) "Europe/Riga"                       , 0x08AFAB },
-	{ (char*) "Europe/Rome"                       , 0x08B84D },
-	{ (char*) "Europe/Samara"                     , 0x08C2AA },
-	{ (char*) "Europe/San_Marino"                 , 0x08C780 },
-	{ (char*) "Europe/Sarajevo"                   , 0x08D1DD },
-	{ (char*) "Europe/Saratov"                    , 0x08D969 },
-	{ (char*) "Europe/Simferopol"                 , 0x08DE16 },
-	{ (char*) "Europe/Skopje"                     , 0x08E3E5 },
-	{ (char*) "Europe/Sofia"                      , 0x08EB71 },
-	{ (char*) "Europe/Stockholm"                  , 0x08F39A },
-	{ (char*) "Europe/Tallinn"                    , 0x08FB1B },
-	{ (char*) "Europe/Tirane"                     , 0x09038B },
-	{ (char*) "Europe/Tiraspol"                   , 0x090BBB },
-	{ (char*) "Europe/Ulyanovsk"                  , 0x09153F },
-	{ (char*) "Europe/Uzhgorod"                   , 0x091A42 },
-	{ (char*) "Europe/Vaduz"                      , 0x092296 },
-	{ (char*) "Europe/Vatican"                    , 0x092A02 },
-	{ (char*) "Europe/Vienna"                     , 0x09345F },
-	{ (char*) "Europe/Vilnius"                    , 0x093D03 },
-	{ (char*) "Europe/Volgograd"                  , 0x094581 },
-	{ (char*) "Europe/Warsaw"                     , 0x094A48 },
-	{ (char*) "Europe/Zagreb"                     , 0x0954B2 },
-	{ (char*) "Europe/Zaporozhye"                 , 0x095C3E },
-	{ (char*) "Europe/Zurich"                     , 0x096492 },
-	{ (char*) "Factory"                           , 0x096C13 },
-	{ (char*) "GB"                                , 0x096C93 },
-	{ (char*) "GB-Eire"                           , 0x097AEF },
-	{ (char*) "GMT"                               , 0x09894B },
-	{ (char*) "GMT+0"                             , 0x0989C9 },
-	{ (char*) "GMT-0"                             , 0x098A47 },
-	{ (char*) "GMT0"                              , 0x098AC5 },
-	{ (char*) "Greenwich"                         , 0x098B43 },
-	{ (char*) "Hongkong"                          , 0x098BC1 },
-	{ (char*) "HST"                               , 0x09909E },
-	{ (char*) "Iceland"                           , 0x0991F3 },
-	{ (char*) "Indian/Antananarivo"               , 0x099293 },
-	{ (char*) "Indian/Chagos"                     , 0x09937A },
-	{ (char*) "Indian/Christmas"                  , 0x09943F },
-	{ (char*) "Indian/Cocos"                      , 0x0994E2 },
-	{ (char*) "Indian/Comoro"                     , 0x09958E },
-	{ (char*) "Indian/Kerguelen"                  , 0x09962F },
-	{ (char*) "Indian/Mahe"                       , 0x0996D2 },
-	{ (char*) "Indian/Maldives"                   , 0x099775 },
-	{ (char*) "Indian/Mauritius"                  , 0x09983A },
-	{ (char*) "Indian/Mayotte"                    , 0x099929 },
-	{ (char*) "Indian/Reunion"                    , 0x0999CA },
-	{ (char*) "Iran"                              , 0x099A6D },
-	{ (char*) "Israel"                            , 0x099F59 },
-	{ (char*) "Jamaica"                           , 0x09A8B9 },
-	{ (char*) "Japan"                             , 0x09AAA7 },
-	{ (char*) "Kwajalein"                         , 0x09ABE8 },
-	{ (char*) "Libya"                             , 0x09AD22 },
-	{ (char*) "MET"                               , 0x09AF9F },
-	{ (char*) "Mexico/BajaNorte"                  , 0x09BB20 },
-	{ (char*) "Mexico/BajaSur"                    , 0x09C686 },
-	{ (char*) "Mexico/General"                    , 0x09CAB6 },
-	{ (char*) "MST"                               , 0x09CF88 },
-	{ (char*) "MST7MDT"                           , 0x09D0FC },
-	{ (char*) "Navajo"                            , 0x09DAA4 },
-	{ (char*) "NZ"                                , 0x09E44C },
-	{ (char*) "NZ-CHAT"                           , 0x09EDDD },
-	{ (char*) "Pacific/Apia"                      , 0x09F5EF },
-	{ (char*) "Pacific/Auckland"                  , 0x09F851 },
-	{ (char*) "Pacific/Bougainville"              , 0x0A01F5 },
-	{ (char*) "Pacific/Chatham"                   , 0x0A030B },
-	{ (char*) "Pacific/Chuuk"                     , 0x0A0B2C },
-	{ (char*) "Pacific/Easter"                    , 0x0A0C46 },
-	{ (char*) "Pacific/Efate"                     , 0x0A150A },
-	{ (char*) "Pacific/Enderbury"                 , 0x0A1722 },
-	{ (char*) "Pacific/Fakaofo"                   , 0x0A180A },
-	{ (char*) "Pacific/Fiji"                      , 0x0A18D0 },
-	{ (char*) "Pacific/Funafuti"                  , 0x0A1B10 },
-	{ (char*) "Pacific/Galapagos"                 , 0x0A1BB4 },
-	{ (char*) "Pacific/Gambier"                   , 0x0A1CB1 },
-	{ (char*) "Pacific/Guadalcanal"               , 0x0A1D62 },
-	{ (char*) "Pacific/Guam"                      , 0x0A1E06 },
-	{ (char*) "Pacific/Honolulu"                  , 0x0A2000 },
-	{ (char*) "Pacific/Johnston"                  , 0x0A215B },
-	{ (char*) "Pacific/Kanton"                    , 0x0A22B0 },
-	{ (char*) "Pacific/Kiritimati"                , 0x0A23A7 },
-	{ (char*) "Pacific/Kosrae"                    , 0x0A249F },
-	{ (char*) "Pacific/Kwajalein"                 , 0x0A2602 },
-	{ (char*) "Pacific/Majuro"                    , 0x0A2745 },
-	{ (char*) "Pacific/Marquesas"                 , 0x0A2891 },
-	{ (char*) "Pacific/Midway"                    , 0x0A294D },
-	{ (char*) "Pacific/Nauru"                     , 0x0A2A40 },
-	{ (char*) "Pacific/Niue"                      , 0x0A2B3A },
-	{ (char*) "Pacific/Norfolk"                   , 0x0A2C03 },
-	{ (char*) "Pacific/Noumea"                    , 0x0A2F71 },
-	{ (char*) "Pacific/Pago_Pago"                 , 0x0A309F },
-	{ (char*) "Pacific/Palau"                     , 0x0A315A },
-	{ (char*) "Pacific/Pitcairn"                  , 0x0A320C },
-	{ (char*) "Pacific/Pohnpei"                   , 0x0A32D4 },
-	{ (char*) "Pacific/Ponape"                    , 0x0A340F },
-	{ (char*) "Pacific/Port_Moresby"              , 0x0A34B3 },
-	{ (char*) "Pacific/Rarotonga"                 , 0x0A3583 },
-	{ (char*) "Pacific/Saipan"                    , 0x0A37DC },
-	{ (char*) "Pacific/Samoa"                     , 0x0A39C8 },
-	{ (char*) "Pacific/Tahiti"                    , 0x0A3A83 },
-	{ (char*) "Pacific/Tarawa"                    , 0x0A3B35 },
-	{ (char*) "Pacific/Tongatapu"                 , 0x0A3BE8 },
-	{ (char*) "Pacific/Truk"                      , 0x0A3D5A },
-	{ (char*) "Pacific/Wake"                      , 0x0A3E12 },
-	{ (char*) "Pacific/Wallis"                    , 0x0A3EC1 },
-	{ (char*) "Pacific/Yap"                       , 0x0A3F65 },
-	{ (char*) "Poland"                            , 0x0A401D },
-	{ (char*) "Portugal"                          , 0x0A4A87 },
-	{ (char*) "PRC"                               , 0x0A585A },
-	{ (char*) "PST8PDT"                           , 0x0A5A97 },
-	{ (char*) "ROC"                               , 0x0A65C7 },
-	{ (char*) "ROK"                               , 0x0A68CC },
-	{ (char*) "Singapore"                         , 0x0A6B41 },
-	{ (char*) "Turkey"                            , 0x0A6CDE },
-	{ (char*) "UCT"                               , 0x0A7477 },
-	{ (char*) "Universal"                         , 0x0A74F5 },
-	{ (char*) "US/Alaska"                         , 0x0A7573 },
-	{ (char*) "US/Aleutian"                       , 0x0A7EC2 },
-	{ (char*) "US/Arizona"                        , 0x0A8802 },
-	{ (char*) "US/Central"                        , 0x0A8976 },
-	{ (char*) "US/East-Indiana"                   , 0x0A978A },
-	{ (char*) "US/Eastern"                        , 0x0A9E28 },
-	{ (char*) "US/Hawaii"                         , 0x0AAC14 },
-	{ (char*) "US/Indiana-Starke"                 , 0x0AAD69 },
-	{ (char*) "US/Michigan"                       , 0x0AB701 },
-	{ (char*) "US/Mountain"                       , 0x0ABFC3 },
-	{ (char*) "US/Pacific"                        , 0x0AC96B },
-	{ (char*) "US/Samoa"                          , 0x0AD49B },
-	{ (char*) "UTC"                               , 0x0AD556 },
-	{ (char*) "W-SU"                              , 0x0AD5D4 },
-	{ (char*) "WET"                               , 0x0ADBDF },
-	{ (char*) "Zulu"                              , 0x0AE9B2 },
+	{ (char*) "Africa/Ceuta"                      , 0x001DE2 },
+	{ (char*) "Africa/Conakry"                    , 0x002600 },
+	{ (char*) "Africa/Dakar"                      , 0x0026DC },
+	{ (char*) "Africa/Dar_es_Salaam"              , 0x00279E },
+	{ (char*) "Africa/Djibouti"                   , 0x00287F },
+	{ (char*) "Africa/Douala"                     , 0x002920 },
+	{ (char*) "Africa/El_Aaiun"                   , 0x0029C1 },
+	{ (char*) "Africa/Freetown"                   , 0x002DF7 },
+	{ (char*) "Africa/Gaborone"                   , 0x002FD3 },
+	{ (char*) "Africa/Harare"                     , 0x0030CA },
+	{ (char*) "Africa/Johannesburg"               , 0x00316B },
+	{ (char*) "Africa/Juba"                       , 0x00326D },
+	{ (char*) "Africa/Kampala"                    , 0x003520 },
+	{ (char*) "Africa/Khartoum"                   , 0x003627 },
+	{ (char*) "Africa/Kigali"                     , 0x0038DA },
+	{ (char*) "Africa/Kinshasa"                   , 0x00397B },
+	{ (char*) "Africa/Lagos"                      , 0x003A35 },
+	{ (char*) "Africa/Libreville"                 , 0x003B2C },
+	{ (char*) "Africa/Lome"                       , 0x003BCD },
+	{ (char*) "Africa/Luanda"                     , 0x003C6D },
+	{ (char*) "Africa/Lubumbashi"                 , 0x003D34 },
+	{ (char*) "Africa/Lusaka"                     , 0x003E10 },
+	{ (char*) "Africa/Malabo"                     , 0x003EB1 },
+	{ (char*) "Africa/Maputo"                     , 0x003F74 },
+	{ (char*) "Africa/Maseru"                     , 0x004015 },
+	{ (char*) "Africa/Mbabane"                    , 0x0040E1 },
+	{ (char*) "Africa/Mogadishu"                  , 0x004185 },
+	{ (char*) "Africa/Monrovia"                   , 0x004266 },
+	{ (char*) "Africa/Nairobi"                    , 0x004342 },
+	{ (char*) "Africa/Ndjamena"                   , 0x004457 },
+	{ (char*) "Africa/Niamey"                     , 0x00452A },
+	{ (char*) "Africa/Nouakchott"                 , 0x00460F },
+	{ (char*) "Africa/Ouagadougou"                , 0x0046EB },
+	{ (char*) "Africa/Porto-Novo"                 , 0x00478B },
+	{ (char*) "Africa/Sao_Tome"                   , 0x00484E },
+	{ (char*) "Africa/Timbuktu"                   , 0x004958 },
+	{ (char*) "Africa/Tripoli"                    , 0x0049F8 },
+	{ (char*) "Africa/Tunis"                      , 0x004C75 },
+	{ (char*) "Africa/Windhoek"                   , 0x004F32 },
+	{ (char*) "America/Adak"                      , 0x0052F9 },
+	{ (char*) "America/Anchorage"                 , 0x005C53 },
+	{ (char*) "America/Anguilla"                  , 0x0065B5 },
+	{ (char*) "America/Antigua"                   , 0x006655 },
+	{ (char*) "America/Araguaina"                 , 0x006717 },
+	{ (char*) "America/Argentina/Buenos_Aires"    , 0x006A92 },
+	{ (char*) "America/Argentina/Catamarca"       , 0x006ED9 },
+	{ (char*) "America/Argentina/ComodRivadavia"  , 0x007326 },
+	{ (char*) "America/Argentina/Cordoba"         , 0x007758 },
+	{ (char*) "America/Argentina/Jujuy"           , 0x007BC0 },
+	{ (char*) "America/Argentina/La_Rioja"        , 0x007FE0 },
+	{ (char*) "America/Argentina/Mendoza"         , 0x00842D },
+	{ (char*) "America/Argentina/Rio_Gallegos"    , 0x00886B },
+	{ (char*) "America/Argentina/Salta"           , 0x008CAC },
+	{ (char*) "America/Argentina/San_Juan"        , 0x0090D8 },
+	{ (char*) "America/Argentina/San_Luis"        , 0x009525 },
+	{ (char*) "America/Argentina/Tucuman"         , 0x00997E },
+	{ (char*) "America/Argentina/Ushuaia"         , 0x009DD8 },
+	{ (char*) "America/Aruba"                     , 0x00A21F },
+	{ (char*) "America/Asuncion"                  , 0x00A2E5 },
+	{ (char*) "America/Atikokan"                  , 0x00A95D },
+	{ (char*) "America/Atka"                      , 0x00AADA },
+	{ (char*) "America/Bahia"                     , 0x00B41A },
+	{ (char*) "America/Bahia_Banderas"            , 0x00B81D },
+	{ (char*) "America/Barbados"                  , 0x00BC86 },
+	{ (char*) "America/Belem"                     , 0x00BE46 },
+	{ (char*) "America/Belize"                    , 0x00C096 },
+	{ (char*) "America/Blanc-Sablon"              , 0x00C6F0 },
+	{ (char*) "America/Boa_Vista"                 , 0x00C842 },
+	{ (char*) "America/Bogota"                    , 0x00CABF },
+	{ (char*) "America/Boise"                     , 0x00CBB3 },
+	{ (char*) "America/Buenos_Aires"              , 0x00D549 },
+	{ (char*) "America/Cambridge_Bay"             , 0x00D97B },
+	{ (char*) "America/Campo_Grande"              , 0x00E269 },
+	{ (char*) "America/Cancun"                    , 0x00E81D },
+	{ (char*) "America/Caracas"                   , 0x00EB95 },
+	{ (char*) "America/Catamarca"                 , 0x00EC9B },
+	{ (char*) "America/Cayenne"                   , 0x00F0CD },
+	{ (char*) "America/Cayman"                    , 0x00F191 },
+	{ (char*) "America/Chicago"                   , 0x00F253 },
+	{ (char*) "America/Chihuahua"                 , 0x01007B },
+	{ (char*) "America/Ciudad_Juarez"             , 0x0104EB },
+	{ (char*) "America/Coral_Harbour"             , 0x010B15 },
+	{ (char*) "America/Cordoba"                   , 0x010BD7 },
+	{ (char*) "America/Costa_Rica"                , 0x011009 },
+	{ (char*) "America/Coyhaique"                 , 0x011151 },
+	{ (char*) "America/Creston"                   , 0x0119B7 },
+	{ (char*) "America/Cuiaba"                    , 0x011AA5 },
+	{ (char*) "America/Curacao"                   , 0x012036 },
+	{ (char*) "America/Danmarkshavn"              , 0x0120FC },
+	{ (char*) "America/Dawson"                    , 0x0123DC },
+	{ (char*) "America/Dawson_Creek"              , 0x012A48 },
+	{ (char*) "America/Denver"                    , 0x012E8E },
+	{ (char*) "America/Detroit"                   , 0x01384B },
+	{ (char*) "America/Dominica"                  , 0x014126 },
+	{ (char*) "America/Edmonton"                  , 0x0141C6 },
+	{ (char*) "America/Eirunepe"                  , 0x0149DD },
+	{ (char*) "America/El_Salvador"               , 0x014C7A },
+	{ (char*) "America/Ensenada"                  , 0x014D66 },
+	{ (char*) "America/Fort_Nelson"               , 0x0158CC },
+	{ (char*) "America/Fort_Wayne"                , 0x0161AC },
+	{ (char*) "America/Fortaleza"                 , 0x01684A },
+	{ (char*) "America/Glace_Bay"                 , 0x016B3A },
+	{ (char*) "America/Godthab"                   , 0x0173F1 },
+	{ (char*) "America/Goose_Bay"                 , 0x017B5E },
+	{ (char*) "America/Grand_Turk"                , 0x018814 },
+	{ (char*) "America/Grenada"                   , 0x018F4A },
+	{ (char*) "America/Guadeloupe"                , 0x018FEA },
+	{ (char*) "America/Guatemala"                 , 0x01908A },
+	{ (char*) "America/Guayaquil"                 , 0x0191AE },
+	{ (char*) "America/Guyana"                    , 0x0192B4 },
+	{ (char*) "America/Halifax"                   , 0x0193B8 },
+	{ (char*) "America/Havana"                    , 0x01A142 },
+	{ (char*) "America/Hermosillo"                , 0x01AABE },
+	{ (char*) "America/Indiana/Indianapolis"      , 0x01AC54 },
+	{ (char*) "America/Indiana/Knox"              , 0x01B30B },
+	{ (char*) "America/Indiana/Marengo"           , 0x01BCB8 },
+	{ (char*) "America/Indiana/Petersburg"        , 0x01C3A5 },
+	{ (char*) "America/Indiana/Tell_City"         , 0x01CB44 },
+	{ (char*) "America/Indiana/Vevay"             , 0x01D208 },
+	{ (char*) "America/Indiana/Vincennes"         , 0x01D7C4 },
+	{ (char*) "America/Indiana/Winamac"           , 0x01DE9A },
+	{ (char*) "America/Indianapolis"              , 0x01E5BE },
+	{ (char*) "America/Inuvik"                    , 0x01EC5C },
+	{ (char*) "America/Iqaluit"                   , 0x01F496 },
+	{ (char*) "America/Jamaica"                   , 0x01FD55 },
+	{ (char*) "America/Jujuy"                     , 0x01FF43 },
+	{ (char*) "America/Juneau"                    , 0x020359 },
+	{ (char*) "America/Kentucky/Louisville"       , 0x020CAA },
+	{ (char*) "America/Kentucky/Monticello"       , 0x0217B8 },
+	{ (char*) "America/Knox_IN"                   , 0x022118 },
+	{ (char*) "America/Kralendijk"                , 0x022AB0 },
+	{ (char*) "America/La_Paz"                    , 0x022BB2 },
+	{ (char*) "America/Lima"                      , 0x022C98 },
+	{ (char*) "America/Los_Angeles"               , 0x022E2C },
+	{ (char*) "America/Louisville"                , 0x023963 },
+	{ (char*) "America/Lower_Princes"             , 0x024453 },
+	{ (char*) "America/Maceio"                    , 0x024555 },
+	{ (char*) "America/Managua"                   , 0x02484B },
+	{ (char*) "America/Manaus"                    , 0x024A05 },
+	{ (char*) "America/Marigot"                   , 0x024C6E },
+	{ (char*) "America/Martinique"                , 0x024D70 },
+	{ (char*) "America/Matamoros"                 , 0x024E64 },
+	{ (char*) "America/Mazatlan"                  , 0x025426 },
+	{ (char*) "America/Mendoza"                   , 0x025888 },
+	{ (char*) "America/Menominee"                 , 0x025CBA },
+	{ (char*) "America/Merida"                    , 0x0265C7 },
+	{ (char*) "America/Metlakatla"                , 0x0269D0 },
+	{ (char*) "America/Mexico_City"               , 0x026F82 },
+	{ (char*) "America/Miquelon"                  , 0x027462 },
+	{ (char*) "America/Moncton"                   , 0x027AE2 },
+	{ (char*) "America/Monterrey"                 , 0x028758 },
+	{ (char*) "America/Montevideo"                , 0x028BF4 },
+	{ (char*) "America/Montreal"                  , 0x0291D8 },
+	{ (char*) "America/Montserrat"                , 0x029F8A },
+	{ (char*) "America/Nassau"                    , 0x02A02A },
+	{ (char*) "America/New_York"                  , 0x02A98A },
+	{ (char*) "America/Nipigon"                   , 0x02B78A },
+	{ (char*) "America/Nome"                      , 0x02C53C },
+	{ (char*) "America/Noronha"                   , 0x02CE94 },
+	{ (char*) "America/North_Dakota/Beulah"       , 0x02D16E },
+	{ (char*) "America/North_Dakota/Center"       , 0x02DAEB },
+	{ (char*) "America/North_Dakota/New_Salem"    , 0x02E468 },
+	{ (char*) "America/Nuuk"                      , 0x02EDEB },
+	{ (char*) "America/Ojinaga"                   , 0x02F569 },
+	{ (char*) "America/Panama"                    , 0x02FB85 },
+	{ (char*) "America/Pangnirtung"               , 0x02FC47 },
+	{ (char*) "America/Paramaribo"                , 0x0304ED },
+	{ (char*) "America/Phoenix"                   , 0x0305F1 },
+	{ (char*) "America/Port-au-Prince"            , 0x03077D },
+	{ (char*) "America/Port_of_Spain"             , 0x030D23 },
+	{ (char*) "America/Porto_Acre"                , 0x030DC3 },
+	{ (char*) "America/Porto_Velho"               , 0x031035 },
+	{ (char*) "America/Puerto_Rico"               , 0x03127B },
+	{ (char*) "America/Punta_Arenas"              , 0x03137D },
+	{ (char*) "America/Rainy_River"               , 0x031B08 },
+	{ (char*) "America/Rankin_Inlet"              , 0x032648 },
+	{ (char*) "America/Recife"                    , 0x032E7C },
+	{ (char*) "America/Regina"                    , 0x033150 },
+	{ (char*) "America/Resolute"                  , 0x033545 },
+	{ (char*) "America/Rio_Branco"                , 0x033D7A },
+	{ (char*) "America/Rosario"                   , 0x033FF0 },
+	{ (char*) "America/Santa_Isabel"              , 0x034422 },
+	{ (char*) "America/Santarem"                  , 0x034F88 },
+	{ (char*) "America/Santiago"                  , 0x0351EB },
+	{ (char*) "America/Santo_Domingo"             , 0x035BD7 },
+	{ (char*) "America/Sao_Paulo"                 , 0x035DAD },
+	{ (char*) "America/Scoresbysund"              , 0x036385 },
+	{ (char*) "America/Shiprock"                  , 0x036B3D },
+	{ (char*) "America/Sitka"                     , 0x0374E5 },
+	{ (char*) "America/St_Barthelemy"             , 0x037E1D },
+	{ (char*) "America/St_Johns"                  , 0x037F1F },
+	{ (char*) "America/St_Kitts"                  , 0x038D8D },
+	{ (char*) "America/St_Lucia"                  , 0x038E2D },
+	{ (char*) "America/St_Thomas"                 , 0x038EEF },
+	{ (char*) "America/St_Vincent"                , 0x038F8F },
+	{ (char*) "America/Swift_Current"             , 0x039051 },
+	{ (char*) "America/Tegucigalpa"               , 0x03929F },
+	{ (char*) "America/Thule"                     , 0x0393A7 },
+	{ (char*) "America/Thunder_Bay"               , 0x03999F },
+	{ (char*) "America/Tijuana"                   , 0x03A751 },
+	{ (char*) "America/Toronto"                   , 0x03B2C6 },
+	{ (char*) "America/Tortola"                   , 0x03C096 },
+	{ (char*) "America/Vancouver"                 , 0x03C136 },
+	{ (char*) "America/Virgin"                    , 0x03CB75 },
+	{ (char*) "America/Whitehorse"                , 0x03CC77 },
+	{ (char*) "America/Winnipeg"                  , 0x03D2E3 },
+	{ (char*) "America/Yakutat"                   , 0x03DE40 },
+	{ (char*) "America/Yellowknife"               , 0x03E75D },
+	{ (char*) "Antarctica/Casey"                  , 0x03EF57 },
+	{ (char*) "Antarctica/Davis"                  , 0x03F10F },
+	{ (char*) "Antarctica/DumontDUrville"         , 0x03F23B },
+	{ (char*) "Antarctica/Macquarie"              , 0x03F30B },
+	{ (char*) "Antarctica/Mawson"                 , 0x03FBFB },
+	{ (char*) "Antarctica/McMurdo"                , 0x03FCC6 },
+	{ (char*) "Antarctica/Palmer"                 , 0x0404C1 },
+	{ (char*) "Antarctica/Rothera"                , 0x040A4F },
+	{ (char*) "Antarctica/South_Pole"             , 0x040AF8 },
+	{ (char*) "Antarctica/Syowa"                  , 0x041489 },
+	{ (char*) "Antarctica/Troll"                  , 0x041531 },
+	{ (char*) "Antarctica/Vostok"                 , 0x0419BE },
+	{ (char*) "Arctic/Longyearbyen"               , 0x041AA5 },
+	{ (char*) "Asia/Aden"                         , 0x0423AB },
+	{ (char*) "Asia/Almaty"                       , 0x04244E },
+	{ (char*) "Asia/Amman"                        , 0x042843 },
+	{ (char*) "Asia/Anadyr"                       , 0x042DE8 },
+	{ (char*) "Asia/Aqtau"                        , 0x04329D },
+	{ (char*) "Asia/Aqtobe"                       , 0x043687 },
+	{ (char*) "Asia/Ashgabat"                     , 0x043A85 },
+	{ (char*) "Asia/Ashkhabad"                    , 0x043CEE },
+	{ (char*) "Asia/Atyrau"                       , 0x043F57 },
+	{ (char*) "Asia/Baghdad"                      , 0x044349 },
+	{ (char*) "Asia/Bahrain"                      , 0x04471E },
+	{ (char*) "Asia/Baku"                         , 0x044809 },
+	{ (char*) "Asia/Bangkok"                      , 0x044CD2 },
+	{ (char*) "Asia/Barnaul"                      , 0x044D97 },
+	{ (char*) "Asia/Beirut"                       , 0x045268 },
+	{ (char*) "Asia/Bishkek"                      , 0x045ADE },
+	{ (char*) "Asia/Brunei"                       , 0x045EB3 },
+	{ (char*) "Asia/Calcutta"                     , 0x045F7C },
+	{ (char*) "Asia/Chita"                        , 0x0460A5 },
+	{ (char*) "Asia/Choibalsan"                   , 0x04657C },
+	{ (char*) "Asia/Chongqing"                    , 0x0468F5 },
+	{ (char*) "Asia/Chungking"                    , 0x046B32 },
+	{ (char*) "Asia/Colombo"                      , 0x046D6F },
+	{ (char*) "Asia/Dacca"                        , 0x046EE1 },
+	{ (char*) "Asia/Damascus"                     , 0x047030 },
+	{ (char*) "Asia/Dhaka"                        , 0x04778D },
+	{ (char*) "Asia/Dili"                         , 0x0478DC },
+	{ (char*) "Asia/Dubai"                        , 0x0479E9 },
+	{ (char*) "Asia/Dushanbe"                     , 0x047A8C },
+	{ (char*) "Asia/Famagusta"                    , 0x047CD9 },
+	{ (char*) "Asia/Gaza"                         , 0x0484E0 },
+	{ (char*) "Asia/Harbin"                       , 0x0493FA },
+	{ (char*) "Asia/Hebron"                       , 0x049637 },
+	{ (char*) "Asia/Ho_Chi_Minh"                  , 0x04A56C },
+	{ (char*) "Asia/Hong_Kong"                    , 0x04A6C1 },
+	{ (char*) "Asia/Hovd"                         , 0x04AB9E },
+	{ (char*) "Asia/Irkutsk"                      , 0x04AF2D },
+	{ (char*) "Asia/Istanbul"                     , 0x04B420 },
+	{ (char*) "Asia/Jakarta"                      , 0x04BBB9 },
+	{ (char*) "Asia/Jayapura"                     , 0x04BD51 },
+	{ (char*) "Asia/Jerusalem"                    , 0x04BE70 },
+	{ (char*) "Asia/Kabul"                        , 0x04C7D0 },
+	{ (char*) "Asia/Kamchatka"                    , 0x04C89E },
+	{ (char*) "Asia/Karachi"                      , 0x04CD3C },
+	{ (char*) "Asia/Kashgar"                      , 0x04CEC3 },
+	{ (char*) "Asia/Kathmandu"                    , 0x04CF66 },
+	{ (char*) "Asia/Katmandu"                     , 0x04D038 },
+	{ (char*) "Asia/Khandyga"                     , 0x04D10A },
+	{ (char*) "Asia/Kolkata"                      , 0x04D61D },
+	{ (char*) "Asia/Krasnoyarsk"                  , 0x04D746 },
+	{ (char*) "Asia/Kuala_Lumpur"                 , 0x04DC14 },
+	{ (char*) "Asia/Kuching"                      , 0x04DDC5 },
+	{ (char*) "Asia/Kuwait"                       , 0x04DFB4 },
+	{ (char*) "Asia/Macao"                        , 0x04E057 },
+	{ (char*) "Asia/Macau"                        , 0x04E52E },
+	{ (char*) "Asia/Magadan"                      , 0x04EA05 },
+	{ (char*) "Asia/Makassar"                     , 0x04EED9 },
+	{ (char*) "Asia/Manila"                       , 0x04F02C },
+	{ (char*) "Asia/Muscat"                       , 0x04F1DE },
+	{ (char*) "Asia/Nicosia"                      , 0x04F281 },
+	{ (char*) "Asia/Novokuznetsk"                 , 0x04FA6D },
+	{ (char*) "Asia/Novosibirsk"                  , 0x04FF09 },
+	{ (char*) "Asia/Omsk"                         , 0x0503E0 },
+	{ (char*) "Asia/Oral"                         , 0x0508A2 },
+	{ (char*) "Asia/Phnom_Penh"                   , 0x050C9C },
+	{ (char*) "Asia/Pontianak"                    , 0x050DB9 },
+	{ (char*) "Asia/Pyongyang"                    , 0x050F3C },
+	{ (char*) "Asia/Qatar"                        , 0x051035 },
+	{ (char*) "Asia/Qostanay"                     , 0x0510FA },
+	{ (char*) "Asia/Qyzylorda"                    , 0x051521 },
+	{ (char*) "Asia/Rangoon"                      , 0x05193D },
+	{ (char*) "Asia/Riyadh"                       , 0x051A47 },
+	{ (char*) "Asia/Saigon"                       , 0x051AEA },
+	{ (char*) "Asia/Sakhalin"                     , 0x051C3F },
+	{ (char*) "Asia/Samarkand"                    , 0x052107 },
+	{ (char*) "Asia/Seoul"                        , 0x052357 },
+	{ (char*) "Asia/Shanghai"                     , 0x0525CC },
+	{ (char*) "Asia/Singapore"                    , 0x052815 },
+	{ (char*) "Asia/Srednekolymsk"                , 0x0529B2 },
+	{ (char*) "Asia/Taipei"                       , 0x052E86 },
+	{ (char*) "Asia/Tashkent"                     , 0x05318B },
+	{ (char*) "Asia/Tbilisi"                      , 0x0533E9 },
+	{ (char*) "Asia/Tehran"                       , 0x0537E4 },
+	{ (char*) "Asia/Tel_Aviv"                     , 0x053CD0 },
+	{ (char*) "Asia/Thimbu"                       , 0x054630 },
+	{ (char*) "Asia/Thimphu"                      , 0x0546F9 },
+	{ (char*) "Asia/Tokyo"                        , 0x0547C2 },
+	{ (char*) "Asia/Tomsk"                        , 0x054903 },
+	{ (char*) "Asia/Ujung_Pandang"                , 0x054DD4 },
+	{ (char*) "Asia/Ulaanbaatar"                  , 0x054EDE },
+	{ (char*) "Asia/Ulan_Bator"                   , 0x055267 },
+	{ (char*) "Asia/Urumqi"                       , 0x0555E0 },
+	{ (char*) "Asia/Ust-Nera"                     , 0x055690 },
+	{ (char*) "Asia/Vientiane"                    , 0x055B86 },
+	{ (char*) "Asia/Vladivostok"                  , 0x055CBF },
+	{ (char*) "Asia/Yakutsk"                      , 0x056188 },
+	{ (char*) "Asia/Yangon"                       , 0x056650 },
+	{ (char*) "Asia/Yekaterinburg"                , 0x05675A },
+	{ (char*) "Asia/Yerevan"                      , 0x056C41 },
+	{ (char*) "Atlantic/Azores"                   , 0x0570BE },
+	{ (char*) "Atlantic/Bermuda"                  , 0x057E42 },
+	{ (char*) "Atlantic/Canary"                   , 0x0587AA },
+	{ (char*) "Atlantic/Cape_Verde"               , 0x058F2D },
+	{ (char*) "Atlantic/Faeroe"                   , 0x059039 },
+	{ (char*) "Atlantic/Faroe"                    , 0x05975C },
+	{ (char*) "Atlantic/Jan_Mayen"                , 0x059E7F },
+	{ (char*) "Atlantic/Madeira"                  , 0x05A785 },
+	{ (char*) "Atlantic/Reykjavik"                , 0x05B4D1 },
+	{ (char*) "Atlantic/South_Georgia"            , 0x05B967 },
+	{ (char*) "Atlantic/St_Helena"                , 0x05BA09 },
+	{ (char*) "Atlantic/Stanley"                  , 0x05BACB },
+	{ (char*) "Australia/ACT"                     , 0x05BF87 },
+	{ (char*) "Australia/Adelaide"                , 0x05C821 },
+	{ (char*) "Australia/Brisbane"                , 0x05D0DC },
+	{ (char*) "Australia/Broken_Hill"             , 0x05D2A2 },
+	{ (char*) "Australia/Canberra"                , 0x05DB7F },
+	{ (char*) "Australia/Currie"                  , 0x05E419 },
+	{ (char*) "Australia/Darwin"                  , 0x05ED5B },
+	{ (char*) "Australia/Eucla"                   , 0x05EEBE },
+	{ (char*) "Australia/Hobart"                  , 0x05F0AB },
+	{ (char*) "Australia/LHI"                     , 0x05F9F5 },
+	{ (char*) "Australia/Lindeman"                , 0x060137 },
+	{ (char*) "Australia/Lord_Howe"               , 0x06033D },
+	{ (char*) "Australia/Melbourne"               , 0x060A8F },
+	{ (char*) "Australia/North"                   , 0x061331 },
+	{ (char*) "Australia/NSW"                     , 0x061482 },
+	{ (char*) "Australia/Perth"                   , 0x061D1C },
+	{ (char*) "Australia/Queensland"              , 0x061F04 },
+	{ (char*) "Australia/South"                   , 0x0620B3 },
+	{ (char*) "Australia/Sydney"                  , 0x06295F },
+	{ (char*) "Australia/Tasmania"                , 0x063215 },
+	{ (char*) "Australia/Victoria"                , 0x063B57 },
+	{ (char*) "Australia/West"                    , 0x0643F1 },
+	{ (char*) "Australia/Yancowinna"              , 0x0645BB },
+	{ (char*) "Brazil/Acre"                       , 0x064E7C },
+	{ (char*) "Brazil/DeNoronha"                  , 0x0650EE },
+	{ (char*) "Brazil/East"                       , 0x0653B8 },
+	{ (char*) "Brazil/West"                       , 0x06595A },
+	{ (char*) "Canada/Atlantic"                   , 0x065BB4 },
+	{ (char*) "Canada/Central"                    , 0x066920 },
+	{ (char*) "Canada/Eastern"                    , 0x067460 },
+	{ (char*) "Canada/Mountain"                   , 0x068212 },
+	{ (char*) "Canada/Newfoundland"               , 0x068A0C },
+	{ (char*) "Canada/Pacific"                    , 0x06985F },
+	{ (char*) "Canada/Saskatchewan"               , 0x06A289 },
+	{ (char*) "Canada/Yukon"                      , 0x06A669 },
+	{ (char*) "CET"                               , 0x06ACC3 },
+	{ (char*) "Chile/Continental"                 , 0x06B844 },
+	{ (char*) "Chile/EasterIsland"                , 0x06C223 },
+	{ (char*) "CST6CDT"                           , 0x06CADA },
+	{ (char*) "Cuba"                              , 0x06D8EE },
+	{ (char*) "EET"                               , 0x06E26A },
+	{ (char*) "Egypt"                             , 0x06EB4C },
+	{ (char*) "Eire"                              , 0x06F4B7 },
+	{ (char*) "EST"                               , 0x070267 },
+	{ (char*) "EST5EDT"                           , 0x070329 },
+	{ (char*) "Etc/GMT"                           , 0x071115 },
+	{ (char*) "Etc/GMT+0"                         , 0x071193 },
+	{ (char*) "Etc/GMT+1"                         , 0x071211 },
+	{ (char*) "Etc/GMT+10"                        , 0x071291 },
+	{ (char*) "Etc/GMT+11"                        , 0x071312 },
+	{ (char*) "Etc/GMT+12"                        , 0x071393 },
+	{ (char*) "Etc/GMT+2"                         , 0x071414 },
+	{ (char*) "Etc/GMT+3"                         , 0x071494 },
+	{ (char*) "Etc/GMT+4"                         , 0x071514 },
+	{ (char*) "Etc/GMT+5"                         , 0x071594 },
+	{ (char*) "Etc/GMT+6"                         , 0x071614 },
+	{ (char*) "Etc/GMT+7"                         , 0x071694 },
+	{ (char*) "Etc/GMT+8"                         , 0x071714 },
+	{ (char*) "Etc/GMT+9"                         , 0x071794 },
+	{ (char*) "Etc/GMT-0"                         , 0x071814 },
+	{ (char*) "Etc/GMT-1"                         , 0x071892 },
+	{ (char*) "Etc/GMT-10"                        , 0x071913 },
+	{ (char*) "Etc/GMT-11"                        , 0x071995 },
+	{ (char*) "Etc/GMT-12"                        , 0x071A17 },
+	{ (char*) "Etc/GMT-13"                        , 0x071A99 },
+	{ (char*) "Etc/GMT-14"                        , 0x071B1B },
+	{ (char*) "Etc/GMT-2"                         , 0x071B9D },
+	{ (char*) "Etc/GMT-3"                         , 0x071C1E },
+	{ (char*) "Etc/GMT-4"                         , 0x071C9F },
+	{ (char*) "Etc/GMT-5"                         , 0x071D20 },
+	{ (char*) "Etc/GMT-6"                         , 0x071DA1 },
+	{ (char*) "Etc/GMT-7"                         , 0x071E22 },
+	{ (char*) "Etc/GMT-8"                         , 0x071EA3 },
+	{ (char*) "Etc/GMT-9"                         , 0x071F24 },
+	{ (char*) "Etc/GMT0"                          , 0x071FA5 },
+	{ (char*) "Etc/Greenwich"                     , 0x072023 },
+	{ (char*) "Etc/UCT"                           , 0x0720A1 },
+	{ (char*) "Etc/Universal"                     , 0x07211F },
+	{ (char*) "Etc/UTC"                           , 0x07219D },
+	{ (char*) "Etc/Zulu"                          , 0x07221B },
+	{ (char*) "Europe/Amsterdam"                  , 0x072299 },
+	{ (char*) "Europe/Andorra"                    , 0x072E03 },
+	{ (char*) "Europe/Astrakhan"                  , 0x0734DD },
+	{ (char*) "Europe/Athens"                     , 0x07397A },
+	{ (char*) "Europe/Belfast"                    , 0x07425C },
+	{ (char*) "Europe/Belgrade"                   , 0x0750B8 },
+	{ (char*) "Europe/Berlin"                     , 0x075844 },
+	{ (char*) "Europe/Bratislava"                 , 0x076159 },
+	{ (char*) "Europe/Brussels"                   , 0x076A62 },
+	{ (char*) "Europe/Bucharest"                  , 0x0775E3 },
+	{ (char*) "Europe/Budapest"                   , 0x077E77 },
+	{ (char*) "Europe/Busingen"                   , 0x0787C3 },
+	{ (char*) "Europe/Chisinau"                   , 0x078F4C },
+	{ (char*) "Europe/Copenhagen"                 , 0x0798D0 },
+	{ (char*) "Europe/Dublin"                     , 0x07A135 },
+	{ (char*) "Europe/Gibraltar"                  , 0x07AEE5 },
+	{ (char*) "Europe/Guernsey"                   , 0x07BAED },
+	{ (char*) "Europe/Helsinki"                   , 0x07C98D },
+	{ (char*) "Europe/Isle_of_Man"                , 0x07D105 },
+	{ (char*) "Europe/Istanbul"                   , 0x07DF51 },
+	{ (char*) "Europe/Jersey"                     , 0x07E6EA },
+	{ (char*) "Europe/Kaliningrad"                , 0x07F58A },
+	{ (char*) "Europe/Kiev"                       , 0x07FB7F },
+	{ (char*) "Europe/Kirov"                      , 0x0803D3 },
+	{ (char*) "Europe/Kyiv"                       , 0x08088E },
+	{ (char*) "Europe/Lisbon"                     , 0x0810F1 },
+	{ (char*) "Europe/Ljubljana"                  , 0x081ED7 },
+	{ (char*) "Europe/London"                     , 0x082663 },
+	{ (char*) "Europe/Luxembourg"                 , 0x0834BF },
+	{ (char*) "Europe/Madrid"                     , 0x08404D },
+	{ (char*) "Europe/Malta"                      , 0x084A9F },
+	{ (char*) "Europe/Mariehamn"                  , 0x0854E7 },
+	{ (char*) "Europe/Minsk"                      , 0x085C5F },
+	{ (char*) "Europe/Monaco"                     , 0x086186 },
+	{ (char*) "Europe/Moscow"                     , 0x086D12 },
+	{ (char*) "Europe/Nicosia"                    , 0x087331 },
+	{ (char*) "Europe/Oslo"                       , 0x087B0F },
+	{ (char*) "Europe/Paris"                      , 0x0883CF },
+	{ (char*) "Europe/Podgorica"                  , 0x088F6D },
+	{ (char*) "Europe/Prague"                     , 0x0896F9 },
+	{ (char*) "Europe/Riga"                       , 0x08A002 },
+	{ (char*) "Europe/Rome"                       , 0x08A8A4 },
+	{ (char*) "Europe/Samara"                     , 0x08B301 },
+	{ (char*) "Europe/San_Marino"                 , 0x08B7D7 },
+	{ (char*) "Europe/Sarajevo"                   , 0x08C234 },
+	{ (char*) "Europe/Saratov"                    , 0x08C9C0 },
+	{ (char*) "Europe/Simferopol"                 , 0x08CE6D },
+	{ (char*) "Europe/Skopje"                     , 0x08D43C },
+	{ (char*) "Europe/Sofia"                      , 0x08DBC8 },
+	{ (char*) "Europe/Stockholm"                  , 0x08E3F1 },
+	{ (char*) "Europe/Tallinn"                    , 0x08EB72 },
+	{ (char*) "Europe/Tirane"                     , 0x08F3E2 },
+	{ (char*) "Europe/Tiraspol"                   , 0x08FC12 },
+	{ (char*) "Europe/Ulyanovsk"                  , 0x090596 },
+	{ (char*) "Europe/Uzhgorod"                   , 0x090A99 },
+	{ (char*) "Europe/Vaduz"                      , 0x0912ED },
+	{ (char*) "Europe/Vatican"                    , 0x091A59 },
+	{ (char*) "Europe/Vienna"                     , 0x0924B6 },
+	{ (char*) "Europe/Vilnius"                    , 0x092D5A },
+	{ (char*) "Europe/Volgograd"                  , 0x0935D8 },
+	{ (char*) "Europe/Warsaw"                     , 0x093A9F },
+	{ (char*) "Europe/Zagreb"                     , 0x094509 },
+	{ (char*) "Europe/Zaporozhye"                 , 0x094C95 },
+	{ (char*) "Europe/Zurich"                     , 0x0954E9 },
+	{ (char*) "Factory"                           , 0x095C6A },
+	{ (char*) "GB"                                , 0x095CEA },
+	{ (char*) "GB-Eire"                           , 0x096B46 },
+	{ (char*) "GMT"                               , 0x0979A2 },
+	{ (char*) "GMT+0"                             , 0x097A20 },
+	{ (char*) "GMT-0"                             , 0x097A9E },
+	{ (char*) "GMT0"                              , 0x097B1C },
+	{ (char*) "Greenwich"                         , 0x097B9A },
+	{ (char*) "Hongkong"                          , 0x097C18 },
+	{ (char*) "HST"                               , 0x0980F5 },
+	{ (char*) "Iceland"                           , 0x09824A },
+	{ (char*) "Indian/Antananarivo"               , 0x0982EA },
+	{ (char*) "Indian/Chagos"                     , 0x0983D1 },
+	{ (char*) "Indian/Christmas"                  , 0x098496 },
+	{ (char*) "Indian/Cocos"                      , 0x098539 },
+	{ (char*) "Indian/Comoro"                     , 0x0985E5 },
+	{ (char*) "Indian/Kerguelen"                  , 0x098686 },
+	{ (char*) "Indian/Mahe"                       , 0x098729 },
+	{ (char*) "Indian/Maldives"                   , 0x0987CC },
+	{ (char*) "Indian/Mauritius"                  , 0x098891 },
+	{ (char*) "Indian/Mayotte"                    , 0x098980 },
+	{ (char*) "Indian/Reunion"                    , 0x098A21 },
+	{ (char*) "Iran"                              , 0x098AC4 },
+	{ (char*) "Israel"                            , 0x098FB0 },
+	{ (char*) "Jamaica"                           , 0x099910 },
+	{ (char*) "Japan"                             , 0x099AFE },
+	{ (char*) "Kwajalein"                         , 0x099C3F },
+	{ (char*) "Libya"                             , 0x099D79 },
+	{ (char*) "MET"                               , 0x099FF6 },
+	{ (char*) "Mexico/BajaNorte"                  , 0x09AB77 },
+	{ (char*) "Mexico/BajaSur"                    , 0x09B6DD },
+	{ (char*) "Mexico/General"                    , 0x09BB0D },
+	{ (char*) "MST"                               , 0x09BFDF },
+	{ (char*) "MST7MDT"                           , 0x09C153 },
+	{ (char*) "Navajo"                            , 0x09CAFB },
+	{ (char*) "NZ"                                , 0x09D4A3 },
+	{ (char*) "NZ-CHAT"                           , 0x09DE34 },
+	{ (char*) "Pacific/Apia"                      , 0x09E646 },
+	{ (char*) "Pacific/Auckland"                  , 0x09E8A8 },
+	{ (char*) "Pacific/Bougainville"              , 0x09F24C },
+	{ (char*) "Pacific/Chatham"                   , 0x09F362 },
+	{ (char*) "Pacific/Chuuk"                     , 0x09FB83 },
+	{ (char*) "Pacific/Easter"                    , 0x09FC9D },
+	{ (char*) "Pacific/Efate"                     , 0x0A0561 },
+	{ (char*) "Pacific/Enderbury"                 , 0x0A0779 },
+	{ (char*) "Pacific/Fakaofo"                   , 0x0A0861 },
+	{ (char*) "Pacific/Fiji"                      , 0x0A0927 },
+	{ (char*) "Pacific/Funafuti"                  , 0x0A0B67 },
+	{ (char*) "Pacific/Galapagos"                 , 0x0A0C0B },
+	{ (char*) "Pacific/Gambier"                   , 0x0A0D08 },
+	{ (char*) "Pacific/Guadalcanal"               , 0x0A0DB9 },
+	{ (char*) "Pacific/Guam"                      , 0x0A0E5D },
+	{ (char*) "Pacific/Honolulu"                  , 0x0A1057 },
+	{ (char*) "Pacific/Johnston"                  , 0x0A11B2 },
+	{ (char*) "Pacific/Kanton"                    , 0x0A1307 },
+	{ (char*) "Pacific/Kiritimati"                , 0x0A13FE },
+	{ (char*) "Pacific/Kosrae"                    , 0x0A14F6 },
+	{ (char*) "Pacific/Kwajalein"                 , 0x0A1659 },
+	{ (char*) "Pacific/Majuro"                    , 0x0A179C },
+	{ (char*) "Pacific/Marquesas"                 , 0x0A18E8 },
+	{ (char*) "Pacific/Midway"                    , 0x0A19A4 },
+	{ (char*) "Pacific/Nauru"                     , 0x0A1A97 },
+	{ (char*) "Pacific/Niue"                      , 0x0A1B91 },
+	{ (char*) "Pacific/Norfolk"                   , 0x0A1C5A },
+	{ (char*) "Pacific/Noumea"                    , 0x0A1FC8 },
+	{ (char*) "Pacific/Pago_Pago"                 , 0x0A20F6 },
+	{ (char*) "Pacific/Palau"                     , 0x0A21B1 },
+	{ (char*) "Pacific/Pitcairn"                  , 0x0A2263 },
+	{ (char*) "Pacific/Pohnpei"                   , 0x0A232B },
+	{ (char*) "Pacific/Ponape"                    , 0x0A2466 },
+	{ (char*) "Pacific/Port_Moresby"              , 0x0A250A },
+	{ (char*) "Pacific/Rarotonga"                 , 0x0A25DA },
+	{ (char*) "Pacific/Saipan"                    , 0x0A2833 },
+	{ (char*) "Pacific/Samoa"                     , 0x0A2A1F },
+	{ (char*) "Pacific/Tahiti"                    , 0x0A2ADA },
+	{ (char*) "Pacific/Tarawa"                    , 0x0A2B8C },
+	{ (char*) "Pacific/Tongatapu"                 , 0x0A2C3F },
+	{ (char*) "Pacific/Truk"                      , 0x0A2DB1 },
+	{ (char*) "Pacific/Wake"                      , 0x0A2E69 },
+	{ (char*) "Pacific/Wallis"                    , 0x0A2F18 },
+	{ (char*) "Pacific/Yap"                       , 0x0A2FBC },
+	{ (char*) "Poland"                            , 0x0A3074 },
+	{ (char*) "Portugal"                          , 0x0A3ADE },
+	{ (char*) "PRC"                               , 0x0A48B1 },
+	{ (char*) "PST8PDT"                           , 0x0A4AEE },
+	{ (char*) "ROC"                               , 0x0A561E },
+	{ (char*) "ROK"                               , 0x0A5923 },
+	{ (char*) "Singapore"                         , 0x0A5B98 },
+	{ (char*) "Turkey"                            , 0x0A5D35 },
+	{ (char*) "UCT"                               , 0x0A64CE },
+	{ (char*) "Universal"                         , 0x0A654C },
+	{ (char*) "US/Alaska"                         , 0x0A65CA },
+	{ (char*) "US/Aleutian"                       , 0x0A6F19 },
+	{ (char*) "US/Arizona"                        , 0x0A7859 },
+	{ (char*) "US/Central"                        , 0x0A79CD },
+	{ (char*) "US/East-Indiana"                   , 0x0A87E1 },
+	{ (char*) "US/Eastern"                        , 0x0A8E7F },
+	{ (char*) "US/Hawaii"                         , 0x0A9C6B },
+	{ (char*) "US/Indiana-Starke"                 , 0x0A9DC0 },
+	{ (char*) "US/Michigan"                       , 0x0AA758 },
+	{ (char*) "US/Mountain"                       , 0x0AB01A },
+	{ (char*) "US/Pacific"                        , 0x0AB9C2 },
+	{ (char*) "US/Samoa"                          , 0x0AC4F2 },
+	{ (char*) "UTC"                               , 0x0AC5AD },
+	{ (char*) "W-SU"                              , 0x0AC62B },
+	{ (char*) "WET"                               , 0x0ACC36 },
+	{ (char*) "Zulu"                              , 0x0ADA09 },
 };
 
 
-const unsigned char timelib_timezone_db_data_builtin[715312] = {
+const unsigned char timelib_timezone_db_data_builtin[711303] = {
 
 /* Africa/Abidjan */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -25504,7 +25469,7 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Africa/Casablanca */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x4D, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0x96, 0x51, 0xF9, 0x9C,
+0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x96, 0x51, 0xF9, 0x9C,
 0xC6, 0xFF, 0x14, 0x80, 0xC7, 0x58, 0xAC, 0x70, 0xC7, 0xD9, 0xED, 0x80, 0xD2, 0xA1, 0x32, 0xF0,
 0xDB, 0x35, 0xA4, 0x00, 0xDB, 0xEE, 0x27, 0xF0, 0xFB, 0x25, 0x72, 0x40, 0xFB, 0xC2, 0xEF, 0x70,
 0x08, 0x6B, 0x84, 0x80, 0x08, 0xC6, 0x6D, 0xF0, 0x0B, 0xE8, 0x0C, 0x00, 0x0C, 0x61, 0x47, 0xF0,
@@ -25522,139 +25487,62 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5E, 0x9B, 0xB0, 0xA0, 0x5E, 0xD3, 0x0F, 0xA0, 0x60, 0x72, 0x58, 0x20, 0x60, 0xA0, 0x7C, 0xA0,
 0x62, 0x3F, 0xC5, 0x20, 0x62, 0x77, 0x24, 0x20, 0x64, 0x16, 0x6C, 0xA0, 0x64, 0x44, 0x91, 0x20,
 0x65, 0xED, 0x14, 0x20, 0x66, 0x1B, 0x38, 0xA0, 0x67, 0xBA, 0x81, 0x20, 0x67, 0xF1, 0xE0, 0x20,
-0x69, 0x91, 0x28, 0xA0, 0x69, 0xBF, 0x4D, 0x20, 0x6B, 0x67, 0xD0, 0x20, 0x6B, 0x95, 0xF4, 0xA0,
-0x6D, 0x35, 0x3D, 0x20, 0x6D, 0x6C, 0x9C, 0x20, 0x6F, 0x0B, 0xE4, 0xA0, 0x6F, 0x3A, 0x09, 0x20,
-0x70, 0xD9, 0x51, 0xA0, 0x71, 0x10, 0xB0, 0xA0, 0x72, 0xAF, 0xF9, 0x20, 0x72, 0xDE, 0x1D, 0xA0,
-0x74, 0x86, 0xA0, 0xA0, 0x74, 0xB4, 0xC5, 0x20, 0x76, 0x54, 0x0D, 0xA0, 0x76, 0x8B, 0x6C, 0xA0,
-0x78, 0x2A, 0xB5, 0x20, 0x78, 0x58, 0xD9, 0xA0, 0x79, 0xF8, 0x22, 0x20, 0x7A, 0x2F, 0x81, 0x20,
-0x7B, 0xCE, 0xC9, 0xA0, 0x7C, 0x06, 0x28, 0xA0, 0x7D, 0xA5, 0x71, 0x20, 0x7D, 0xD3, 0x95, 0xA0,
-0x7F, 0x72, 0xDE, 0x20, 0x7F, 0xAA, 0x3D, 0x20, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x69, 0x91, 0x28, 0xA0, 0x69, 0xBF, 0x4D, 0x20, 0x6A, 0xAF, 0x30, 0x10, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01,
 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x04,
-0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E,
-0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30,
-0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+0x03, 0x04, 0x03, 0x02, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x31, 0x00,
+0x2B, 0x30, 0x30, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF,
-0xFF, 0x96, 0x51, 0xF9, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xFF, 0x14, 0x80, 0xFF, 0xFF, 0xFF,
-0xFF, 0xC7, 0x58, 0xAC, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xD9, 0xED, 0x80, 0xFF, 0xFF, 0xFF,
-0xFF, 0xD2, 0xA1, 0x32, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x35, 0xA4, 0x00, 0xFF, 0xFF, 0xFF,
-0xFF, 0xDB, 0xEE, 0x27, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x25, 0x72, 0x40, 0xFF, 0xFF, 0xFF,
-0xFF, 0xFB, 0xC2, 0xEF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6B, 0x84, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x08, 0xC6, 0x6D, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE8, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0C, 0x61, 0x47, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC9, 0x3F, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x0E, 0x8E, 0xF2, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD3, 0x51, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x27, 0xA3, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xB7, 0xA6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1E, 0x18, 0x6F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0xE6, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x48, 0xBB, 0x22, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x23, 0x1A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x4A, 0x8D, 0xD5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xDC, 0xC0, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x4C, 0x5D, 0xE5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x97, 0xB8, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x4E, 0x34, 0x8C, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9C, 0xA0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x50, 0x08, 0xBB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x31, 0x9A, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x50, 0x67, 0xA7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x51, 0x7C, 0x82, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x51, 0xD8, 0xCB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x9E, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x52, 0x6C, 0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x7A, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x53, 0xAE, 0x21, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0xDC, 0x46, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x54, 0x4C, 0x55, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x5C, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x55, 0x7C, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAB, 0x04, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x56, 0x2C, 0x37, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x3E, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x57, 0x53, 0x87, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xAC, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x58, 0x15, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x20, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x59, 0x20, 0xF4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59, 0x58, 0x53, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x59, 0xF5, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB7, 0x02, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x5A, 0xF7, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x25, 0xC0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x5B, 0xD5, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xCE, 0x43, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x5C, 0xFC, 0x68, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x9B, 0xB0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x5E, 0xD3, 0x0F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x72, 0x58, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x60, 0xA0, 0x7C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xC5, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x62, 0x77, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x64, 0x16, 0x6C, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x64, 0x44, 0x91, 0x20, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x66, 0x1B, 0x38, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x67, 0xF1, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x69, 0xBF, 0x4D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x67, 0xD0, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x6B, 0x95, 0xF4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x35, 0x3D, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x6D, 0x6C, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x0B, 0xE4, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x6F, 0x3A, 0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0xD9, 0x51, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x71, 0x10, 0xB0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x72, 0xAF, 0xF9, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x72, 0xDE, 0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xA0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x74, 0xB4, 0xC5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x76, 0x54, 0x0D, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x76, 0x8B, 0x6C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x2A, 0xB5, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x78, 0x58, 0xD9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8, 0x22, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x7A, 0x2F, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xCE, 0xC9, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x7C, 0x06, 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xA5, 0x71, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x7D, 0xD3, 0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x72, 0xDE, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x7F, 0xAA, 0x3D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x81, 0x49, 0x85, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x81, 0x77, 0xAA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x83, 0x20, 0x2D, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x83, 0x4E, 0x51, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x84, 0xED, 0x9A, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x85, 0x24, 0xF9, 0x20, 0x00, 0x00, 0x00, 0x00, 0x86, 0xC4, 0x41, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x86, 0xF2, 0x66, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x91, 0xAE, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x88, 0xC9, 0x0D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x68, 0x56, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x8A, 0x9F, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x3E, 0xFD, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x8C, 0x6D, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x0C, 0x6A, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x8E, 0x43, 0xC9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xE3, 0x12, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x90, 0x11, 0x36, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x91, 0xB9, 0xB9, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x91, 0xE7, 0xDE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x93, 0x87, 0x26, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x93, 0xBE, 0x85, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x95, 0x5D, 0xCE, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x95, 0x8B, 0xF2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x97, 0x2B, 0x3B, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x97, 0x62, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0xE2, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x99, 0x39, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xD8, 0x8A, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x9B, 0x06, 0xAE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xA5, 0xF7, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x9C, 0xDD, 0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x7C, 0x9E, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x9E, 0xAA, 0xC3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x53, 0x46, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xA0, 0x81, 0x6A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x20, 0xB3, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xA2, 0x58, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xF7, 0x5A, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xA4, 0x25, 0x7F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC4, 0xC7, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xA5, 0xFC, 0x26, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA7, 0x9B, 0x6F, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xA7, 0xD2, 0xCE, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x72, 0x16, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xA9, 0xA0, 0x3B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x3F, 0x83, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xAB, 0x76, 0xE2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x16, 0x2B, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xAD, 0x44, 0x4F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAE, 0xEC, 0xD2, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xAF, 0x1A, 0xF7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xBA, 0x3F, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xB0, 0xF1, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x90, 0xE7, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xB2, 0xBF, 0x0B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x5E, 0x54, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xB4, 0x95, 0xB3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x34, 0xFB, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xB6, 0x6C, 0x5A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x0B, 0xA3, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xB8, 0x39, 0xC7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB9, 0xD9, 0x10, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xBA, 0x10, 0x6F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xAF, 0xB7, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xBB, 0xDD, 0xDC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x86, 0x5F, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xBD, 0xB4, 0x83, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x53, 0xCC, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xBF, 0x8B, 0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x2A, 0x73, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xC1, 0x58, 0x98, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xF7, 0xE0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xC3, 0x2F, 0x3F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xCE, 0x88, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xC5, 0x05, 0xE7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xA5, 0x2F, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xC6, 0xD3, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x72, 0x9C, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xC8, 0xA9, 0xFB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x49, 0x44, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xCA, 0x77, 0x68, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x1F, 0xEB, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xCC, 0x4E, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xED, 0x58, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xCE, 0x24, 0xB7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xC4, 0x00, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xCF, 0xF2, 0x24, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x91, 0x6D, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xD1, 0xC8, 0xCC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x68, 0x14, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xD3, 0x96, 0x39, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x3E, 0xBC, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xD5, 0x6C, 0xE0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x0C, 0x29, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xD7, 0x43, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xE2, 0xD0, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0xD9, 0x10, 0xF5, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xB9, 0x78, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xDA, 0xE7, 0x9C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x86, 0xE5, 0x20, 0x00, 0x00, 0x00,
-0x00, 0xDC, 0xBE, 0x44, 0x20, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03,
-0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00,
-0x00, 0x00, 0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x10,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x31, 0x00,
-0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x31, 0x3E, 0x2D, 0x31, 0x0A, 0x00, 0xBC, 0xAC,
-0xC8, 0x01, 0x07, 0x16, 0x42, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C,
+0xFF, 0xFF, 0xFF, 0xFF, 0x96, 0x51, 0xF9, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0xFF, 0x14, 0x80,
+0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x58, 0xAC, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xD9, 0xED, 0x80,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xA1, 0x32, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x35, 0xA4, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xEE, 0x27, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x25, 0x72, 0x40,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xC2, 0xEF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6B, 0x84, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x08, 0xC6, 0x6D, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE8, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x61, 0x47, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC9, 0x3F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x8E, 0xF2, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD3, 0x51, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0xA3, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xB7, 0xA6, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x6F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0xE6, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x48, 0xBB, 0x22, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x23, 0x1A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x4A, 0x8D, 0xD5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xDC, 0xC0, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0x5D, 0xE5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x97, 0xB8, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4E, 0x34, 0x8C, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9C, 0xA0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x08, 0xBB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x31, 0x9A, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x67, 0xA7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x51, 0x7C, 0x82, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x51, 0xD8, 0xCB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x9E, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x52, 0x6C, 0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x7A, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x53, 0xAE, 0x21, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0xDC, 0x46, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x54, 0x4C, 0x55, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x5C, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x55, 0x7C, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAB, 0x04, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x56, 0x2C, 0x37, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x3E, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x57, 0x53, 0x87, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xAC, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x58, 0x15, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x20, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0xF4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59, 0x58, 0x53, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x59, 0xF5, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB7, 0x02, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x5A, 0xF7, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x25, 0xC0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x5B, 0xD5, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xCE, 0x43, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0xFC, 0x68, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x9B, 0xB0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x5E, 0xD3, 0x0F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x72, 0x58, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x60, 0xA0, 0x7C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xC5, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x62, 0x77, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x64, 0x16, 0x6C, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x64, 0x44, 0x91, 0x20, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x66, 0x1B, 0x38, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x67, 0xF1, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x69, 0xBF, 0x4D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAF, 0x30, 0x10,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
+0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x02, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00,
+0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00,
+0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x30, 0x3E, 0x30, 0x0A,
+0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16, 0x42, 0x00, 0x00, 0x00, 0x00, 
 
 /* Africa/Ceuta */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -25865,7 +25753,7 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Africa/El_Aaiun */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0xBC, 0x48, 0xF0, 0xE0,
+0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0xBC, 0x48, 0xF0, 0xE0,
 0x0B, 0xD1, 0xB0, 0x90, 0x0B, 0xE8, 0x0C, 0x00, 0x0C, 0x61, 0x47, 0xF0, 0x0D, 0xC9, 0x3F, 0x80,
 0x0E, 0x8E, 0xF2, 0x70, 0x0F, 0xD3, 0x51, 0x80, 0x10, 0x27, 0xA3, 0x70, 0x48, 0x41, 0xE6, 0x80,
 0x48, 0xBB, 0x22, 0x70, 0x4A, 0x23, 0x1A, 0x00, 0x4A, 0x8D, 0xD5, 0x70, 0x4B, 0xDC, 0xC0, 0x80,
@@ -25880,134 +25768,57 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5C, 0xFC, 0x68, 0x20, 0x5E, 0x9B, 0xB0, 0xA0, 0x5E, 0xD3, 0x0F, 0xA0, 0x60, 0x72, 0x58, 0x20,
 0x60, 0xA0, 0x7C, 0xA0, 0x62, 0x3F, 0xC5, 0x20, 0x62, 0x77, 0x24, 0x20, 0x64, 0x16, 0x6C, 0xA0,
 0x64, 0x44, 0x91, 0x20, 0x65, 0xED, 0x14, 0x20, 0x66, 0x1B, 0x38, 0xA0, 0x67, 0xBA, 0x81, 0x20,
-0x67, 0xF1, 0xE0, 0x20, 0x69, 0x91, 0x28, 0xA0, 0x69, 0xBF, 0x4D, 0x20, 0x6B, 0x67, 0xD0, 0x20,
-0x6B, 0x95, 0xF4, 0xA0, 0x6D, 0x35, 0x3D, 0x20, 0x6D, 0x6C, 0x9C, 0x20, 0x6F, 0x0B, 0xE4, 0xA0,
-0x6F, 0x3A, 0x09, 0x20, 0x70, 0xD9, 0x51, 0xA0, 0x71, 0x10, 0xB0, 0xA0, 0x72, 0xAF, 0xF9, 0x20,
-0x72, 0xDE, 0x1D, 0xA0, 0x74, 0x86, 0xA0, 0xA0, 0x74, 0xB4, 0xC5, 0x20, 0x76, 0x54, 0x0D, 0xA0,
-0x76, 0x8B, 0x6C, 0xA0, 0x78, 0x2A, 0xB5, 0x20, 0x78, 0x58, 0xD9, 0xA0, 0x79, 0xF8, 0x22, 0x20,
-0x7A, 0x2F, 0x81, 0x20, 0x7B, 0xCE, 0xC9, 0xA0, 0x7C, 0x06, 0x28, 0xA0, 0x7D, 0xA5, 0x71, 0x20,
-0x7D, 0xD3, 0x95, 0xA0, 0x7F, 0x72, 0xDE, 0x20, 0x7F, 0xAA, 0x3D, 0x20, 0x01, 0x03, 0x02, 0x03,
-0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03,
-0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03,
-0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10,
-0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00,
-0x0E, 0x10, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00,
-0x2B, 0x30, 0x30, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10,
-0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x48, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xD1, 0xB0, 0x90,
-0x00, 0x00, 0x00, 0x00, 0x0B, 0xE8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x61, 0x47, 0xF0,
-0x00, 0x00, 0x00, 0x00, 0x0D, 0xC9, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x8E, 0xF2, 0x70,
-0x00, 0x00, 0x00, 0x00, 0x0F, 0xD3, 0x51, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0xA3, 0x70,
-0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0xE6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x48, 0xBB, 0x22, 0x70,
-0x00, 0x00, 0x00, 0x00, 0x4A, 0x23, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x8D, 0xD5, 0x70,
-0x00, 0x00, 0x00, 0x00, 0x4B, 0xDC, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x5D, 0xE5, 0x70,
-0x00, 0x00, 0x00, 0x00, 0x4D, 0x97, 0xB8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x34, 0x8C, 0xF0,
-0x00, 0x00, 0x00, 0x00, 0x4F, 0x9C, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x08, 0xBB, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x50, 0x31, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x50, 0x67, 0xA7, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x51, 0x7C, 0x82, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x51, 0xD8, 0xCB, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6C, 0x73, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x7A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0xAE, 0x21, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x53, 0xDC, 0x46, 0x20, 0x00, 0x00, 0x00, 0x00, 0x54, 0x4C, 0x55, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x5C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x55, 0x7C, 0xE0, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x55, 0xAB, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x2C, 0x37, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x3E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x57, 0x53, 0x87, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xAC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0x15, 0x54, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x20, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0xF4, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x59, 0x58, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59, 0xF5, 0x36, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x5A, 0xB7, 0x02, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xF7, 0x9C, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x5B, 0x25, 0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xD5, 0x18, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x5C, 0xCE, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xFC, 0x68, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x5E, 0x9B, 0xB0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xD3, 0x0F, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x60, 0x72, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x60, 0xA0, 0x7C, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xC5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x62, 0x77, 0x24, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x64, 0x16, 0x6C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x64, 0x44, 0x91, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x66, 0x1B, 0x38, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x67, 0xF1, 0xE0, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0xBF, 0x4D, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x6B, 0x67, 0xD0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x95, 0xF4, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x6D, 0x35, 0x3D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x6C, 0x9C, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x6F, 0x0B, 0xE4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x3A, 0x09, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x70, 0xD9, 0x51, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x71, 0x10, 0xB0, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x72, 0xAF, 0xF9, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0xDE, 0x1D, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x74, 0xB4, 0xC5, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x76, 0x54, 0x0D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x8B, 0x6C, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x78, 0x2A, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x78, 0x58, 0xD9, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x79, 0xF8, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x2F, 0x81, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x7B, 0xCE, 0xC9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x28, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x7D, 0xA5, 0x71, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xD3, 0x95, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x7F, 0x72, 0xDE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xAA, 0x3D, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x49, 0x85, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x81, 0x77, 0xAA, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x83, 0x20, 0x2D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x83, 0x4E, 0x51, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x84, 0xED, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x85, 0x24, 0xF9, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x86, 0xC4, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x86, 0xF2, 0x66, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x88, 0x91, 0xAE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x88, 0xC9, 0x0D, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x8A, 0x68, 0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x9F, 0xB5, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x8C, 0x3E, 0xFD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x6D, 0x22, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x8E, 0x0C, 0x6A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x43, 0xC9, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x8F, 0xE3, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x90, 0x11, 0x36, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x91, 0xB9, 0xB9, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x91, 0xE7, 0xDE, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x93, 0x87, 0x26, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x93, 0xBE, 0x85, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x95, 0x5D, 0xCE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x95, 0x8B, 0xF2, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x97, 0x2B, 0x3B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x97, 0x62, 0x9A, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0xE2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x99, 0x39, 0x41, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x9A, 0xD8, 0x8A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x06, 0xAE, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x9C, 0xA5, 0xF7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xDD, 0x56, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x9E, 0x7C, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9E, 0xAA, 0xC3, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xA0, 0x53, 0x46, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x81, 0x6A, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xA2, 0x20, 0xB3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x58, 0x12, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xA3, 0xF7, 0x5A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x25, 0x7F, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xA5, 0xC4, 0xC7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xFC, 0x26, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xA7, 0x9B, 0x6F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xD2, 0xCE, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xA9, 0x72, 0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xA0, 0x3B, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xAB, 0x3F, 0x83, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x76, 0xE2, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xAD, 0x16, 0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x44, 0x4F, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xAE, 0xEC, 0xD2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x1A, 0xF7, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xB0, 0xBA, 0x3F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xF1, 0x9E, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xB2, 0x90, 0xE7, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xBF, 0x0B, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xB4, 0x5E, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x95, 0xB3, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xB6, 0x34, 0xFB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x6C, 0x5A, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xB8, 0x0B, 0xA3, 0x20, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x39, 0xC7, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xB9, 0xD9, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x10, 0x6F, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xBB, 0xAF, 0xB7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xDD, 0xDC, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xBD, 0x86, 0x5F, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xB4, 0x83, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xBF, 0x53, 0xCC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x8B, 0x2B, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xC1, 0x2A, 0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x58, 0x98, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xC2, 0xF7, 0xE0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x2F, 0x3F, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xC4, 0xCE, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x05, 0xE7, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xC6, 0xA5, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xD3, 0x54, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xC8, 0x72, 0x9C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xA9, 0xFB, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xCA, 0x49, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x77, 0x68, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xCC, 0x1F, 0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x4E, 0x10, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xCD, 0xED, 0x58, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x24, 0xB7, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xCF, 0xC4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xF2, 0x24, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xD1, 0x91, 0x6D, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xC8, 0xCC, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xD3, 0x68, 0x14, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x96, 0x39, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xD5, 0x3E, 0xBC, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x6C, 0xE0, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xD7, 0x0C, 0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x43, 0x88, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xD8, 0xE2, 0xD0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x10, 0xF5, 0x20,
-0x00, 0x00, 0x00, 0x00, 0xDA, 0xB9, 0x78, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xE7, 0x9C, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0xDC, 0x86, 0xE5, 0x20, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xBE, 0x44, 0x20,
+0x67, 0xF1, 0xE0, 0x20, 0x69, 0x91, 0x28, 0xA0, 0x69, 0xBF, 0x4D, 0x20, 0x6A, 0xAF, 0x30, 0x10,
 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03,
 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03,
 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05,
-0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00,
-0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x4C, 0x4D,
-0x54, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x0A, 0x3C,
-0x2B, 0x30, 0x31, 0x3E, 0x2D, 0x31, 0x0A, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE, 0x84, 0x40, 0x00,
-0x00, 0x00, 0x00, 
+0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x03, 0xFF, 0xFF, 0xF3,
+0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B,
+0x30, 0x31, 0x00, 0x2B, 0x30, 0x30, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x07, 0x00,
+0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x48, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0B,
+0xD1, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
+0x61, 0x47, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC9, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0E,
+0x8E, 0xF2, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD3, 0x51, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x27, 0xA3, 0x70, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0xE6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x48,
+0xBB, 0x22, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x23, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A,
+0x8D, 0xD5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4B, 0xDC, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4C,
+0x5D, 0xE5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x97, 0xB8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4E,
+0x34, 0x8C, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x9C, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50,
+0x08, 0xBB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x31, 0x9A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x50,
+0x67, 0xA7, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x51, 0x7C, 0x82, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x51,
+0xD8, 0xCB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x9E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52,
+0x6C, 0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x7A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53,
+0xAE, 0x21, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x53, 0xDC, 0x46, 0x20, 0x00, 0x00, 0x00, 0x00, 0x54,
+0x4C, 0x55, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x5C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x55,
+0x7C, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAB, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56,
+0x2C, 0x37, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0xF7, 0x3E, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x57,
+0x53, 0x87, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xAC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58,
+0x15, 0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0xD7, 0x20, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59,
+0x20, 0xF4, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59, 0x58, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x59,
+0xF5, 0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xB7, 0x02, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5A,
+0xF7, 0x9C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x25, 0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5B,
+0xD5, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5C, 0xCE, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5C,
+0xFC, 0x68, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x9B, 0xB0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x5E,
+0xD3, 0x0F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x72, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x60,
+0xA0, 0x7C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x62, 0x3F, 0xC5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x62,
+0x77, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x64, 0x16, 0x6C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x64,
+0x44, 0x91, 0x20, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x66,
+0x1B, 0x38, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0xBA, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x67,
+0xF1, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x69, 0x91, 0x28, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69,
+0xBF, 0x4D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAF, 0x30, 0x10, 0x01, 0x03, 0x02, 0x03, 0x02,
+0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
+0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
+0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04,
+0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x03, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF,
+0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x2D, 0x30, 0x31, 0x00, 0x2B, 0x30, 0x31, 0x00, 0x2B, 0x30,
+0x30, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x30, 0x3E, 0x30, 0x0A, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE,
+0x84, 0x40, 0x00, 0x00, 0x00, 0x00, 
 
 /* Africa/Freetown */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x53, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -30652,8 +30463,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 
 /* America/Edmonton */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x88, 0xDE, 0xCE, 0xE0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x88, 0xDE, 0xCE, 0xE0,
 0x9E, 0xB8, 0xAF, 0x90, 0x9F, 0xBB, 0x07, 0x80, 0xA0, 0x98, 0x91, 0x90, 0xA0, 0xD2, 0x85, 0x80,
 0xA2, 0x8A, 0xE8, 0x90, 0xA3, 0x84, 0x06, 0x00, 0xA4, 0x6A, 0xCA, 0x90, 0xA5, 0x35, 0xC3, 0x80,
 0xA6, 0x53, 0xE7, 0x10, 0xA7, 0x15, 0xA5, 0x80, 0xA8, 0x33, 0xC9, 0x10, 0xA8, 0xFE, 0xC2, 0x00,
@@ -30685,121 +30496,102 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5D, 0xBE, 0x89, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x5F, 0x9E, 0x6B, 0x00, 0x60, 0x4D, 0xD0, 0x90,
 0x61, 0x87, 0x87, 0x80, 0x62, 0x2D, 0xB2, 0x90, 0x63, 0x67, 0x69, 0x80, 0x64, 0x0D, 0x94, 0x90,
 0x65, 0x47, 0x4B, 0x80, 0x65, 0xED, 0x76, 0x90, 0x67, 0x27, 0x2D, 0x80, 0x67, 0xCD, 0x58, 0x90,
-0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x6B, 0x96, 0x57, 0x10,
-0x6C, 0xD0, 0x0E, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x6E, 0xAF, 0xF0, 0x00, 0x6F, 0x56, 0x1B, 0x10,
-0x70, 0x8F, 0xD2, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x72, 0x6F, 0xB4, 0x00, 0x73, 0x15, 0xDF, 0x10,
-0x74, 0x4F, 0x96, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x76, 0x38, 0xB2, 0x80, 0x76, 0xDE, 0xDD, 0x90,
-0x78, 0x18, 0x94, 0x80, 0x78, 0xBE, 0xBF, 0x90, 0x79, 0xF8, 0x76, 0x80, 0x7A, 0x9E, 0xA1, 0x90,
-0x7B, 0xD8, 0x58, 0x80, 0x7C, 0x7E, 0x83, 0x90, 0x7D, 0xB8, 0x3A, 0x80, 0x7E, 0x5E, 0x65, 0x90,
-0x7F, 0x98, 0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0,
-0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00,
-0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8,
-0xAF, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98,
-0x91, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A,
-0xE8, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A,
-0xCA, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53,
-0xE7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33,
-0xC9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89,
-0x0C, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61,
-0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20,
-0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50,
-0xFC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30,
-0xDE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10,
-0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0,
-0xA2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9,
-0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9,
-0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99,
-0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79,
-0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59,
-0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39,
-0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22,
-0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02,
-0x27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2,
-0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1,
-0xEB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1,
-0xCD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81,
-0xAF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A,
-0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A,
-0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A,
-0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A,
-0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA,
-0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3,
-0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3,
-0x52, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93,
-0x34, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73,
-0x16, 0x80, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52,
-0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32,
-0xDA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B,
-0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB,
-0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB,
-0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB,
-0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B,
-0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84,
-0x9B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64,
-0x7D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44,
-0x5F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D,
-0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D,
-0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6,
-0x5C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6,
-0x3E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96,
-0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76,
-0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55,
-0xE4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35,
-0xC6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E,
-0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE,
-0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE,
-0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE,
-0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E,
-0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87,
-0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67,
-0x69, 0x80, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47,
-0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27,
-0x2D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07,
-0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6,
-0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x96, 0x57, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xD0,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF,
-0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x56, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8F,
-0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F,
-0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4F,
-0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38,
-0xB2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDE, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18,
-0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0xBE, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8,
-0x76, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x9E, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xD8,
-0x58, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xB8,
-0x3A, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5E, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x98,
-0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03,
-0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x95, 0xA0,
+0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF,
+0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14,
+0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00,
+0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
+0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A, 0xCA, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53, 0xE7, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33, 0xC9, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x0C, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x18, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xDC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xFC, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xDE, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xC0, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xA2, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xBF, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xA1, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x83, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x65, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x47, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x29, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x45, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x27, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x09, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xEB, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xCD, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xAF, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xCC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xAE, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x72, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x54, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x70, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x52, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x34, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x16, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0xF8, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xDA, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B, 0xF7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xD9, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xBB, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0x9D, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x7F, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF,
-0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53,
-0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E,
-0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0xDB, 0x0A, 0x38,
-0x00, 0x65, 0x85, 0x95, 0x00, 0x00, 0x00, 0x22, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E,
-0x20, 0x2D, 0x20, 0x41, 0x42, 0x2C, 0x20, 0x42, 0x43, 0x28, 0x45, 0x29, 0x2C, 0x20, 0x4E, 0x54,
-0x28, 0x45, 0x29, 0x2C, 0x20, 0x53, 0x4B, 0x28, 0x57, 0x29, 
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05,
+0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
+0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF,
+0xAB, 0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00,
+0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36, 0x0A, 0x00, 0xDB,
+0x0A, 0x38, 0x00, 0x65, 0x85, 0x95, 0x00, 0x00, 0x00, 0x1D, 0x43, 0x53, 0x54, 0x20, 0x2D, 0x20,
+0x41, 0x42, 0x2C, 0x20, 0x42, 0x43, 0x28, 0x45, 0x29, 0x2C, 0x20, 0x4E, 0x54, 0x28, 0x45, 0x29,
+0x2C, 0x20, 0x53, 0x4B, 0x28, 0x57, 0x29, 
 
 /* America/Eirunepe */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -41185,8 +40977,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 
 /* America/Vancouver */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x00,
 0x9E, 0xB8, 0xBD, 0xA0, 0x9F, 0xBB, 0x15, 0x90, 0xCB, 0x89, 0x1A, 0xA0, 0xD2, 0x23, 0xF4, 0x70,
 0xD2, 0x61, 0x26, 0x10, 0xD3, 0x76, 0x0F, 0x20, 0xD4, 0x41, 0x08, 0x10, 0xD5, 0x55, 0xF1, 0x20,
 0xD6, 0x20, 0xEA, 0x10, 0xD7, 0x35, 0xD3, 0x20, 0xD8, 0x00, 0xCC, 0x10, 0xD9, 0x15, 0xB5, 0x20,
@@ -41228,13 +41020,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5D, 0xBE, 0x97, 0x10, 0x5E, 0x64, 0xC2, 0x20, 0x5F, 0x9E, 0x79, 0x10, 0x60, 0x4D, 0xDE, 0xA0,
 0x61, 0x87, 0x95, 0x90, 0x62, 0x2D, 0xC0, 0xA0, 0x63, 0x67, 0x77, 0x90, 0x64, 0x0D, 0xA2, 0xA0,
 0x65, 0x47, 0x59, 0x90, 0x65, 0xED, 0x84, 0xA0, 0x67, 0x27, 0x3B, 0x90, 0x67, 0xCD, 0x66, 0xA0,
-0x69, 0x07, 0x1D, 0x90, 0x69, 0xAD, 0x48, 0xA0, 0x6A, 0xE6, 0xFF, 0x90, 0x6B, 0x96, 0x65, 0x20,
-0x6C, 0xD0, 0x1C, 0x10, 0x6D, 0x76, 0x47, 0x20, 0x6E, 0xAF, 0xFE, 0x10, 0x6F, 0x56, 0x29, 0x20,
-0x70, 0x8F, 0xE0, 0x10, 0x71, 0x36, 0x0B, 0x20, 0x72, 0x6F, 0xC2, 0x10, 0x73, 0x15, 0xED, 0x20,
-0x74, 0x4F, 0xA4, 0x10, 0x74, 0xFF, 0x09, 0xA0, 0x76, 0x38, 0xC0, 0x90, 0x76, 0xDE, 0xEB, 0xA0,
-0x78, 0x18, 0xA2, 0x90, 0x78, 0xBE, 0xCD, 0xA0, 0x79, 0xF8, 0x84, 0x90, 0x7A, 0x9E, 0xAF, 0xA0,
-0x7B, 0xD8, 0x66, 0x90, 0x7C, 0x7E, 0x91, 0xA0, 0x7D, 0xB8, 0x48, 0x90, 0x7E, 0x5E, 0x73, 0xA0,
-0x7F, 0x98, 0x2A, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x69, 0x07, 0x1D, 0x90, 0x69, 0xAD, 0x48, 0xA0, 0x6A, 0xE6, 0xFF, 0x90, 0x02, 0x01, 0x02, 0x03,
+0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
@@ -41244,130 +41031,115 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04,
+0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90,
+0x01, 0x10, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00,
+0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66,
+0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
+0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0x5E, 0x3D, 0x76, 0xEC,
+0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x15, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x76, 0x0F, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x41, 0x08, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xF1, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xEA, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x35, 0xD3, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0xCC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x15, 0xB5, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0xE0, 0xAE, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xFE, 0xD1, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xC0, 0x90, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDE, 0xB3, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xA9, 0xAC, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xBE, 0x95, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x89, 0x8E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x9E, 0x77, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x69, 0x70, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x7E, 0x59, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x49, 0x52, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x5E, 0x3B, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x29, 0x34, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x47, 0x58, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x12, 0x51, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x27, 0x3A, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xF2, 0x33, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x07, 0x1C, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xD2, 0x15, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xE6, 0xFE, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xB1, 0xF7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xC6, 0xE0, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x91, 0xD9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xAF, 0xFC, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x71, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8F, 0xDE, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x7F, 0xC1, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x6F, 0xC0, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x5F, 0xA3, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x4F, 0xA2, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x3F, 0x85, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x2F, 0x84, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x28, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x0F, 0x66, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x08, 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xF8, 0x83, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE8, 0x66, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xD8, 0x65, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xC8, 0x48, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xB8, 0x47, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x29, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x0B, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x27, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41, 0x09, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xEB, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xCD, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xAF, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xCD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x91, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xAF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xAE, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x90, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x72, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x54, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x36, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x18, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x34, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x17, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x16, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xF9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xF8, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xDB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x2B, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xBD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x22, 0x56, 0x0D, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xDA, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xEF, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xBC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xD1, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x9E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xED, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xCF, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xB1, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x7E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x93, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x75, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x92, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x74, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x53, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x56, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xE8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x38, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x38, 0x1C, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x1A, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xFC, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xC9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x18, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0xAB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xFA, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x8D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xDC, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xBE, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0xA0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xB5, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x97, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xB3, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x95, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x77, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x59, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x3B, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x1D, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x3A, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x1C, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xFE, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xE0, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xC2, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xDE, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xC0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0xA2, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x84, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x66, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x48, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF,
-0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10,
-0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00,
-0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x5A,
-0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xBE, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x5E, 0x3D,
-0x76, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB,
-0x15, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23,
-0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x76,
-0x0F, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x41, 0x08, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55,
-0xF1, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xEA, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x35,
-0xD3, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0xCC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x15,
-0xB5, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0xE0, 0xAE, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xFE,
-0xD1, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xC0, 0x90, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDE,
-0xB3, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xA9, 0xAC, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xBE,
-0x95, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x89, 0x8E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x9E,
-0x77, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x69, 0x70, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x7E,
-0x59, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x49, 0x52, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x5E,
-0x3B, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x29, 0x34, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x47,
-0x58, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x12, 0x51, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x27,
-0x3A, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xF2, 0x33, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x07,
-0x1C, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xD2, 0x15, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xE6,
-0xFE, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xB1, 0xF7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xC6,
-0xE0, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x91, 0xD9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xAF,
-0xFC, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x71, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8F,
-0xDE, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x7F, 0xC1, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x6F,
-0xC0, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x5F, 0xA3, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x4F,
-0xA2, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x3F, 0x85, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x2F,
-0x84, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x28, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x0F,
-0x66, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x08, 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xF8,
-0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE8, 0x66, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xD8,
-0x65, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xC8, 0x48, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xB8,
-0x47, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
-0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78,
-0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61,
-0x27, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41,
-0x09, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20,
-0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
-0xCD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0,
-0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xCD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0,
-0x91, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xAF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9,
-0xAE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89,
-0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69,
-0x72, 0x20, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49,
-0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29,
-0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09,
-0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2,
-0x34, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x17, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2,
-0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xF9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1,
-0xF8, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xDB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76,
-0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xBD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x22, 0x56,
-0x0D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xDA, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35,
-0xEF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xBC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15,
-0xD1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x9E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE,
-0xED, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE,
-0xCF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE,
-0xB1, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x7E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E,
-0x93, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E,
-0x75, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67,
-0x92, 0x20, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47,
-0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x34, 0x53, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27,
-0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xE8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07,
-0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1C, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7,
-0x1A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6,
-0xFC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xC9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0,
-0x18, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0xAB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F,
-0xFA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x8D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F,
-0xDC, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F,
-0xBE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F,
-0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3,
-0xD3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3,
-0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3,
-0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C,
-0xB3, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C,
-0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C,
-0x77, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C,
-0x59, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C,
-0x3B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC,
-0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5,
-0x3A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5,
-0x1C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4,
-0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84,
-0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64,
-0xC2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D,
-0xDE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D,
-0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D,
-0xA2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED,
-0x84, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD,
-0x66, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD,
-0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x96,
-0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xD0, 0x1C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x76,
-0x47, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF, 0xFE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x56,
-0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8F, 0xE0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x36,
-0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F, 0xC2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15,
-0xED, 0x20, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4F, 0xA4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0xFF,
-0x09, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0xC0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDE,
-0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xBE,
-0xCD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x9E,
-0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xD8, 0x66, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E,
-0x91, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xB8, 0x48, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5E,
-0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x98, 0x2A, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF,
-0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C,
-0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53,
-0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x0A, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E,
-0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0xD4, 0x81, 0x0A,
-0x00, 0x56, 0xCC, 0x0D, 0x00, 0x00, 0x00, 0x19, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20,
-0x2D, 0x20, 0x42, 0x43, 0x20, 0x28, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x61, 0x72, 0x65, 0x61, 0x73,
-0x29, 
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05,
+0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80,
+0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0xFF, 0xFF,
+0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00,
+0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x0A, 0x00, 0xD4,
+0x81, 0x0A, 0x00, 0x56, 0xCC, 0x0D, 0x00, 0x00, 0x00, 0x15, 0x4D, 0x53, 0x54, 0x20, 0x2D, 0x20,
+0x42, 0x43, 0x20, 0x28, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x61, 0x72, 0x65, 0x61, 0x73, 0x29, 
 
 /* America/Virgin */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -41827,8 +41599,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 
 /* America/Yellowknife */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x88, 0xDE, 0xCE, 0xE0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x88, 0xDE, 0xCE, 0xE0,
 0x9E, 0xB8, 0xAF, 0x90, 0x9F, 0xBB, 0x07, 0x80, 0xA0, 0x98, 0x91, 0x90, 0xA0, 0xD2, 0x85, 0x80,
 0xA2, 0x8A, 0xE8, 0x90, 0xA3, 0x84, 0x06, 0x00, 0xA4, 0x6A, 0xCA, 0x90, 0xA5, 0x35, 0xC3, 0x80,
 0xA6, 0x53, 0xE7, 0x10, 0xA7, 0x15, 0xA5, 0x80, 0xA8, 0x33, 0xC9, 0x10, 0xA8, 0xFE, 0xC2, 0x00,
@@ -41860,119 +41632,100 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5D, 0xBE, 0x89, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x5F, 0x9E, 0x6B, 0x00, 0x60, 0x4D, 0xD0, 0x90,
 0x61, 0x87, 0x87, 0x80, 0x62, 0x2D, 0xB2, 0x90, 0x63, 0x67, 0x69, 0x80, 0x64, 0x0D, 0x94, 0x90,
 0x65, 0x47, 0x4B, 0x80, 0x65, 0xED, 0x76, 0x90, 0x67, 0x27, 0x2D, 0x80, 0x67, 0xCD, 0x58, 0x90,
-0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x6B, 0x96, 0x57, 0x10,
-0x6C, 0xD0, 0x0E, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x6E, 0xAF, 0xF0, 0x00, 0x6F, 0x56, 0x1B, 0x10,
-0x70, 0x8F, 0xD2, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x72, 0x6F, 0xB4, 0x00, 0x73, 0x15, 0xDF, 0x10,
-0x74, 0x4F, 0x96, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x76, 0x38, 0xB2, 0x80, 0x76, 0xDE, 0xDD, 0x90,
-0x78, 0x18, 0x94, 0x80, 0x78, 0xBE, 0xBF, 0x90, 0x79, 0xF8, 0x76, 0x80, 0x7A, 0x9E, 0xA1, 0x90,
-0x7B, 0xD8, 0x58, 0x80, 0x7C, 0x7E, 0x83, 0x90, 0x7D, 0xB8, 0x3A, 0x80, 0x7E, 0x5E, 0x65, 0x90,
-0x7F, 0x98, 0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0,
-0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00,
-0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8,
-0xAF, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98,
-0x91, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A,
-0xE8, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A,
-0xCA, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53,
-0xE7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33,
-0xC9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89,
-0x0C, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61,
-0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20,
-0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50,
-0xFC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30,
-0xDE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10,
-0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0,
-0xA2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9,
-0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9,
-0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99,
-0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79,
-0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59,
-0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39,
-0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22,
-0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02,
-0x27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2,
-0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1,
-0xEB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1,
-0xCD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81,
-0xAF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A,
-0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A,
-0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A,
-0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A,
-0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA,
-0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3,
-0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3,
-0x52, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93,
-0x34, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73,
-0x16, 0x80, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52,
-0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32,
-0xDA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B,
-0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB,
-0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB,
-0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB,
-0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B,
-0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84,
-0x9B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64,
-0x7D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44,
-0x5F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D,
-0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D,
-0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6,
-0x5C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6,
-0x3E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96,
-0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76,
-0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55,
-0xE4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35,
-0xC6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E,
-0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE,
-0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE,
-0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE,
-0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E,
-0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87,
-0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67,
-0x69, 0x80, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47,
-0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27,
-0x2D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07,
-0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6,
-0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x96, 0x57, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xD0,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF,
-0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x56, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8F,
-0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F,
-0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4F,
-0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38,
-0xB2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDE, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18,
-0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0xBE, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8,
-0x76, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x9E, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xD8,
-0x58, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xB8,
-0x3A, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5E, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x98,
-0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03,
-0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x95, 0xA0,
+0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF,
+0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14,
+0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00,
+0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
+0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A, 0xCA, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53, 0xE7, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33, 0xC9, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x0C, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x18, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xDC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xFC, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xDE, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xC0, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xA2, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xBF, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xA1, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x83, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x65, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x47, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x29, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x45, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x27, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x09, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xEB, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xCD, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xAF, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xCC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xAE, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x72, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x54, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x70, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x52, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x34, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x16, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0xF8, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xDA, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B, 0xF7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xD9, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xBB, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0x9D, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x7F, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF,
-0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53,
-0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E,
-0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05,
+0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
+0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF,
+0xAB, 0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00,
+0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Antarctica/Casey */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -45005,26 +44758,26 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Asia/Ho_Chi_Minh */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x56, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x88, 0x8C, 0x43, 0x8A,
+0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x88, 0x8C, 0x43, 0x8A,
 0x91, 0xA3, 0x2B, 0x0A, 0xCD, 0x35, 0xE6, 0x80, 0xD1, 0x59, 0xCE, 0x70, 0xD2, 0x3B, 0x3E, 0xF0,
 0xD5, 0x32, 0xBB, 0x10, 0xE4, 0xB6, 0xF2, 0x90, 0xED, 0x2F, 0x98, 0x00, 0x0A, 0x3D, 0xC7, 0x00,
-0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00,
-0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00,
-0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54,
-0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30,
-0x39, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x01, 0x00,
+0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00,
+0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D,
+0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A,
+0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF,
-0xFF, 0xFF, 0x88, 0x8C, 0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF,
-0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF,
-0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF, 0xFF,
-0xFF, 0xFF, 0xE4, 0xB6, 0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0A, 0x3D, 0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00,
-0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00,
-0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62,
-0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00,
-0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37,
-0x0A, 0x00, 0x99, 0xBB, 0x78, 0x01, 0xB5, 0x6B, 0x2A, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C,
+0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35,
+0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B,
+0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xB6,
+0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x3D,
+0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00,
+0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70,
+0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50,
+0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00,
+0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x99, 0xBB, 0x78, 0x01, 0xB5, 0x6B,
+0x2A, 0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Hong_Kong */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x48, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -46735,23 +46488,22 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Asia/Phnom_Penh */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x4B, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x88, 0x8C, 0x45, 0x24,
+0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x88, 0x8C, 0x45, 0x24,
 0x91, 0xA3, 0x2B, 0x0A, 0xCD, 0x35, 0xE6, 0x80, 0xD1, 0x59, 0xCE, 0x70, 0xD2, 0x3B, 0x3E, 0xF0,
-0x01, 0x02, 0x03, 0x04, 0x02, 0x00, 0x00, 0x62, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00,
-0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E,
-0x90, 0x00, 0x11, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C, 0x4D,
-0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A,
-0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x02, 0x03, 0x04, 0x02, 0x00, 0x00, 0x62, 0x5C, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00,
+0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E,
+0x90, 0x00, 0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30,
+0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C,
-0x45, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35,
-0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B,
-0x3E, 0xF0, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00, 0x00, 0x62, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x63,
-0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00,
-0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50,
-0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00,
-0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x9A, 0xF3, 0xF8, 0x01, 0xB2, 0xBF,
-0x92, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x45, 0x24, 0xFF, 0xFF,
+0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF,
+0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0x01, 0x02,
+0x03, 0x04, 0x02, 0x00, 0x00, 0x62, 0x5C, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00,
+0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00,
+0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00,
+0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37,
+0x0A, 0x00, 0x9A, 0xF3, 0xF8, 0x01, 0xB2, 0xBF, 0x92, 0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Pontianak */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -46985,26 +46737,26 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Asia/Saigon */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x88, 0x8C, 0x43, 0x8A,
+0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x88, 0x8C, 0x43, 0x8A,
 0x91, 0xA3, 0x2B, 0x0A, 0xCD, 0x35, 0xE6, 0x80, 0xD1, 0x59, 0xCE, 0x70, 0xD2, 0x3B, 0x3E, 0xF0,
 0xD5, 0x32, 0xBB, 0x10, 0xE4, 0xB6, 0xF2, 0x90, 0xED, 0x2F, 0x98, 0x00, 0x0A, 0x3D, 0xC7, 0x00,
-0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00,
-0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00,
-0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54,
-0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30,
-0x39, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x01, 0x00,
+0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70, 0x80, 0x00,
+0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D,
+0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A,
+0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF,
-0xFF, 0xFF, 0x88, 0x8C, 0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF,
-0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF,
-0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF, 0xFF,
-0xFF, 0xFF, 0xE4, 0xB6, 0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0A, 0x3D, 0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00,
-0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00,
-0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62,
-0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00,
-0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C,
+0x43, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35,
+0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B,
+0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xB6,
+0xF2, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x2F, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x3D,
+0xC7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x63, 0xF6, 0x00,
+0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x00, 0x00, 0x70,
+0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62, 0x70, 0x00, 0x05, 0x50,
+0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00,
+0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Sakhalin */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -48073,25 +47825,24 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 /* Asia/Vientiane */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x4C, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x88, 0x8C, 0x47, 0x50,
+0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x88, 0x8C, 0x47, 0x50,
 0x91, 0xA3, 0x2B, 0x0A, 0xCD, 0x35, 0xE6, 0x80, 0xD1, 0x59, 0xCE, 0x70, 0xD2, 0x3B, 0x3E, 0xF0,
 0xD5, 0x32, 0xBB, 0x10, 0xE4, 0x51, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x00,
-0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00,
-0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x11, 0x00, 0x00, 0x62,
-0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00,
-0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x15, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x47, 0x50, 0xFF, 0xFF, 0xFF, 0xFF,
-0x91, 0xA3, 0x2B, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
-0xD1, 0x59, 0xCE, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
-0xD5, 0x32, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x51, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04,
-0x02, 0x03, 0x02, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x04, 0x00,
-0x00, 0x62, 0x70, 0x00, 0x09, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x7E, 0x90, 0x00,
-0x11, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4C, 0x4D, 0x54, 0x00,
-0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00, 0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30,
-0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0xA4, 0xBE, 0x7A, 0x01, 0xAF, 0x36, 0xA0, 0x00, 0x00, 0x00,
-0x00, 
+0x00, 0x60, 0x30, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00,
+0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62,
+0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00,
+0x2B, 0x30, 0x39, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11,
+0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0x8C, 0x47, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x91, 0xA3, 0x2B, 0x0A,
+0xFF, 0xFF, 0xFF, 0xFF, 0xCD, 0x35, 0xE6, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x59, 0xCE, 0x70,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x3B, 0x3E, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x32, 0xBB, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x51, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x02, 0x03, 0x02, 0x00,
+0x00, 0x60, 0x30, 0x00, 0x01, 0x00, 0x00, 0x63, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00,
+0x05, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x62,
+0x70, 0x00, 0x05, 0x50, 0x4C, 0x4D, 0x54, 0x00, 0x2B, 0x30, 0x37, 0x00, 0x2B, 0x30, 0x38, 0x00,
+0x2B, 0x30, 0x39, 0x00, 0x0A, 0x3C, 0x2B, 0x30, 0x37, 0x3E, 0x2D, 0x37, 0x0A, 0x00, 0xA4, 0xBE,
+0x7A, 0x01, 0xAF, 0x36, 0xA0, 0x00, 0x00, 0x00, 0x00, 
 
 /* Asia/Vladivostok */
 0x50, 0x48, 0x50, 0x32, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -52909,8 +52660,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 
 /* Canada/Mountain */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x88, 0xDE, 0xCE, 0xE0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x88, 0xDE, 0xCE, 0xE0,
 0x9E, 0xB8, 0xAF, 0x90, 0x9F, 0xBB, 0x07, 0x80, 0xA0, 0x98, 0x91, 0x90, 0xA0, 0xD2, 0x85, 0x80,
 0xA2, 0x8A, 0xE8, 0x90, 0xA3, 0x84, 0x06, 0x00, 0xA4, 0x6A, 0xCA, 0x90, 0xA5, 0x35, 0xC3, 0x80,
 0xA6, 0x53, 0xE7, 0x10, 0xA7, 0x15, 0xA5, 0x80, 0xA8, 0x33, 0xC9, 0x10, 0xA8, 0xFE, 0xC2, 0x00,
@@ -52942,119 +52693,100 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5D, 0xBE, 0x89, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x5F, 0x9E, 0x6B, 0x00, 0x60, 0x4D, 0xD0, 0x90,
 0x61, 0x87, 0x87, 0x80, 0x62, 0x2D, 0xB2, 0x90, 0x63, 0x67, 0x69, 0x80, 0x64, 0x0D, 0x94, 0x90,
 0x65, 0x47, 0x4B, 0x80, 0x65, 0xED, 0x76, 0x90, 0x67, 0x27, 0x2D, 0x80, 0x67, 0xCD, 0x58, 0x90,
-0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x6B, 0x96, 0x57, 0x10,
-0x6C, 0xD0, 0x0E, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x6E, 0xAF, 0xF0, 0x00, 0x6F, 0x56, 0x1B, 0x10,
-0x70, 0x8F, 0xD2, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x72, 0x6F, 0xB4, 0x00, 0x73, 0x15, 0xDF, 0x10,
-0x74, 0x4F, 0x96, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x76, 0x38, 0xB2, 0x80, 0x76, 0xDE, 0xDD, 0x90,
-0x78, 0x18, 0x94, 0x80, 0x78, 0xBE, 0xBF, 0x90, 0x79, 0xF8, 0x76, 0x80, 0x7A, 0x9E, 0xA1, 0x90,
-0x7B, 0xD8, 0x58, 0x80, 0x7C, 0x7E, 0x83, 0x90, 0x7D, 0xB8, 0x3A, 0x80, 0x7E, 0x5E, 0x65, 0x90,
-0x7F, 0x98, 0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01,
-0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x69, 0x07, 0x0F, 0x80, 0x69, 0xAD, 0x3A, 0x90, 0x6A, 0xE6, 0xF1, 0x80, 0x02, 0x01, 0x02, 0x01,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0,
-0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00,
-0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
-0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8,
-0xAF, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98,
-0x91, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A,
-0xE8, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A,
-0xCA, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53,
-0xE7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33,
-0xC9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89,
-0x0C, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61,
-0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20,
-0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50,
-0xFC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30,
-0xDE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10,
-0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0,
-0xA2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9,
-0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9,
-0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99,
-0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79,
-0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59,
-0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39,
-0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22,
-0x45, 0x80, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02,
-0x27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2,
-0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1,
-0xEB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1,
-0xCD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81,
-0xAF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A,
-0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A,
-0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A,
-0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A,
-0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA,
-0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3,
-0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3,
-0x52, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93,
-0x34, 0x80, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73,
-0x16, 0x80, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52,
-0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32,
-0xDA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B,
-0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB,
-0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB,
-0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB,
-0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B,
-0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84,
-0x9B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64,
-0x7D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44,
-0x5F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D,
-0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D,
-0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6,
-0x5C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6,
-0x3E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96,
-0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76,
-0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55,
-0xE4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35,
-0xC6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E,
-0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE,
-0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE,
-0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE,
-0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E,
-0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87,
-0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67,
-0x69, 0x80, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47,
-0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27,
-0x2D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07,
-0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6,
-0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x96, 0x57, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xD0,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x76, 0x39, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF,
-0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x56, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8F,
-0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x35, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F,
-0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15, 0xDF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4F,
-0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xFE, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38,
-0xB2, 0x80, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDE, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18,
-0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0xBE, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8,
-0x76, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x9E, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xD8,
-0x58, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xB8,
-0x3A, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5E, 0x65, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x98,
-0x1C, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03,
-0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x95, 0xA0,
+0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF,
+0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14,
+0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00,
+0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18,
+0xFF, 0xFF, 0xFF, 0xFF, 0x88, 0xDE, 0xCE, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xAF, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x98, 0x91, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xD2, 0x85, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2, 0x8A, 0xE8, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA3, 0x84, 0x06, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x6A, 0xCA, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x35, 0xC3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA6, 0x53, 0xE7, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x15, 0xA5, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x33, 0xC9, 0x10,
+0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0xFE, 0xC2, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x0C, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x18, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xE3, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xDC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x19, 0x90, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0xFC, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xDE, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xDD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xC0, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xBF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xA2, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xA1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xBF, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xA1, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x83, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x65, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x47, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x29, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x45, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x27, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x26, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x09, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xEB, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xCD, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xAF, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x22, 0x55, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xCC, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xE1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xAE, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x90, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xDF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x72, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xC1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x54, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x70, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x52, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x34, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x16, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x66, 0x10, 0x00, 0x00, 0x00, 0x00, 0x34, 0x52, 0xF8, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xDA, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1B, 0xF7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xD9, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xEE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xBB, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0x9D, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x7F, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0x9B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x7D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0x92, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x5F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xC5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x7C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xA7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x5E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xA5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x5C, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x3E, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x69, 0x90, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x20, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x4B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x02, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x2D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xE4, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x0F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xC6, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x2C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xE3, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xC5, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xA7, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xD2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x89, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xB4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x6B, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xD0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x87, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xB2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x69, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x4B, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x76, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x2D, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x58, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x0F, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x3A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xF1, 0x80,
+0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF,
-0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C,
-0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53,
-0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x4D, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E,
-0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05,
+0xFF, 0xFF, 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90,
+0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF,
+0xAB, 0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00,
+0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x43, 0x53, 0x54, 0x36, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Canada/Newfoundland */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -53290,8 +53022,8 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 
 /* Canada/Pacific */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x00,
 0x9E, 0xB8, 0xBD, 0xA0, 0x9F, 0xBB, 0x15, 0x90, 0xCB, 0x89, 0x1A, 0xA0, 0xD2, 0x23, 0xF4, 0x70,
 0xD2, 0x61, 0x26, 0x10, 0xD3, 0x76, 0x0F, 0x20, 0xD4, 0x41, 0x08, 0x10, 0xD5, 0x55, 0xF1, 0x20,
 0xD6, 0x20, 0xEA, 0x10, 0xD7, 0x35, 0xD3, 0x20, 0xD8, 0x00, 0xCC, 0x10, 0xD9, 0x15, 0xB5, 0x20,
@@ -53333,13 +53065,9 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x5D, 0xBE, 0x97, 0x10, 0x5E, 0x64, 0xC2, 0x20, 0x5F, 0x9E, 0x79, 0x10, 0x60, 0x4D, 0xDE, 0xA0,
 0x61, 0x87, 0x95, 0x90, 0x62, 0x2D, 0xC0, 0xA0, 0x63, 0x67, 0x77, 0x90, 0x64, 0x0D, 0xA2, 0xA0,
 0x65, 0x47, 0x59, 0x90, 0x65, 0xED, 0x84, 0xA0, 0x67, 0x27, 0x3B, 0x90, 0x67, 0xCD, 0x66, 0xA0,
-0x69, 0x07, 0x1D, 0x90, 0x69, 0xAD, 0x48, 0xA0, 0x6A, 0xE6, 0xFF, 0x90, 0x6B, 0x96, 0x65, 0x20,
-0x6C, 0xD0, 0x1C, 0x10, 0x6D, 0x76, 0x47, 0x20, 0x6E, 0xAF, 0xFE, 0x10, 0x6F, 0x56, 0x29, 0x20,
-0x70, 0x8F, 0xE0, 0x10, 0x71, 0x36, 0x0B, 0x20, 0x72, 0x6F, 0xC2, 0x10, 0x73, 0x15, 0xED, 0x20,
-0x74, 0x4F, 0xA4, 0x10, 0x74, 0xFF, 0x09, 0xA0, 0x76, 0x38, 0xC0, 0x90, 0x76, 0xDE, 0xEB, 0xA0,
-0x78, 0x18, 0xA2, 0x90, 0x78, 0xBE, 0xCD, 0xA0, 0x79, 0xF8, 0x84, 0x90, 0x7A, 0x9E, 0xAF, 0xA0,
-0x7B, 0xD8, 0x66, 0x90, 0x7C, 0x7E, 0x91, 0xA0, 0x7D, 0xB8, 0x48, 0x90, 0x7E, 0x5E, 0x73, 0xA0,
-0x7F, 0x98, 0x2A, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x69, 0x07, 0x1D, 0x90, 0x69, 0xAD, 0x48, 0xA0, 0x6A, 0xE6, 0xFF, 0x90, 0x02, 0x01, 0x02, 0x03,
+0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
@@ -53348,129 +53076,114 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x05, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04,
+0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90,
+0x01, 0x10, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00,
+0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x5A, 0x69, 0x66,
+0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
+0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0x5E, 0x3D, 0x76, 0xEC,
+0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB, 0x15, 0x90,
+0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23, 0xF4, 0x70,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x76, 0x0F, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x41, 0x08, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55, 0xF1, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xEA, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x35, 0xD3, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0xCC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x15, 0xB5, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0xE0, 0xAE, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xFE, 0xD1, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xC0, 0x90, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDE, 0xB3, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xA9, 0xAC, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xBE, 0x95, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x89, 0x8E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x9E, 0x77, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x69, 0x70, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x7E, 0x59, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x49, 0x52, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x5E, 0x3B, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x29, 0x34, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x47, 0x58, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x12, 0x51, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x27, 0x3A, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xF2, 0x33, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x07, 0x1C, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xD2, 0x15, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xE6, 0xFE, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xB1, 0xF7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xC6, 0xE0, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x91, 0xD9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xAF, 0xFC, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x71, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8F, 0xDE, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x7F, 0xC1, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x6F, 0xC0, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x5F, 0xA3, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x4F, 0xA2, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x3F, 0x85, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x2F, 0x84, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x28, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x0F, 0x66, 0xA0,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x08, 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xF8, 0x83, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE8, 0x66, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xD8, 0x65, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xC8, 0x48, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xB8, 0x47, 0x20,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x29, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x0B, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61, 0x27, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41, 0x09, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xEB, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xCD, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0xAF, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xCD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x91, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xAF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9, 0xAE, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89, 0x90, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69, 0x72, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49, 0x54, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29, 0x36, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09, 0x18, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2, 0x34, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x17, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2, 0x16, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xF9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1, 0xF8, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xDB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76, 0x2B, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xBD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x22, 0x56, 0x0D, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xDA, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35, 0xEF, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xBC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15, 0xD1, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x9E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE, 0xED, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE, 0xCF, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE, 0xB1, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x7E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E, 0x93, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E, 0x75, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67, 0x92, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47, 0x74, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x53, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27, 0x56, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xE8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07, 0x38, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x38, 0x1C, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7, 0x1A, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6, 0xFC, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xC9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0, 0x18, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0xAB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F, 0xFA, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x8D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0xDC, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F, 0xBE, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F, 0xA0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3, 0xD3, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3, 0xB5, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3, 0x97, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C, 0xB3, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C, 0x95, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C, 0x77, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C, 0x59, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C, 0x3B, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC, 0x1D, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5, 0x3A, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5, 0x1C, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4, 0xFE, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84, 0xE0, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64, 0xC2, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D, 0xDE, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D, 0xC0, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D, 0xA2, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED, 0x84, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD, 0x66, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD, 0x48, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF,
-0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10,
-0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00,
-0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x5A,
-0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xBE, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0x5E, 0x3D,
-0x76, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xB8, 0xBD, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBB,
-0x15, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x89, 0x1A, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x23,
-0xF4, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x61, 0x26, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x76,
-0x0F, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD4, 0x41, 0x08, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x55,
-0xF1, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x20, 0xEA, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0x35,
-0xD3, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0xCC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0x15,
-0xB5, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9, 0xE0, 0xAE, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0xFE,
-0xD1, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xC0, 0x90, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xDE,
-0xB3, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xA9, 0xAC, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xBE,
-0x95, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x89, 0x8E, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x9E,
-0x77, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x69, 0x70, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0x7E,
-0x59, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x49, 0x52, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x5E,
-0x3B, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x29, 0x34, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x47,
-0x58, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x12, 0x51, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0x27,
-0x3A, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xF2, 0x33, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x07,
-0x1C, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xD2, 0x15, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xE6,
-0xFE, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xB1, 0xF7, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xC6,
-0xE0, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x91, 0xD9, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xAF,
-0xFC, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x71, 0xBB, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8F,
-0xDE, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x7F, 0xC1, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x6F,
-0xC0, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x5F, 0xA3, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x4F,
-0xA2, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x3F, 0x85, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x2F,
-0x84, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x28, 0xA2, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x0F,
-0x66, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x08, 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xF8,
-0x83, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE8, 0x66, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xD8,
-0x65, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xC8, 0x48, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xB8,
-0x47, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8, 0x2A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
-0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78,
-0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x71, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x61,
-0x27, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x51, 0x0A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41,
-0x09, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20,
-0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, 0xCE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
-0xCD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF0, 0xB0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xE0,
-0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xD9, 0xCD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xC0,
-0x91, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xB9, 0xAF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xA9,
-0xAE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x99, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00, 0x11, 0x89,
-0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x79, 0x73, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x69,
-0x72, 0x20, 0x00, 0x00, 0x00, 0x00, 0x14, 0x59, 0x55, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15, 0x49,
-0x54, 0x20, 0x00, 0x00, 0x00, 0x00, 0x16, 0x39, 0x37, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17, 0x29,
-0x36, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x22, 0x53, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0x09,
-0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x02, 0x35, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xF2,
-0x34, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE2, 0x17, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xD2,
-0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xC1, 0xF9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xB1,
-0xF8, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xA1, 0xDB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x20, 0x76,
-0x2B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0xBD, 0x90, 0x00, 0x00, 0x00, 0x00, 0x22, 0x56,
-0x0D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6A, 0xDA, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x35,
-0xEF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4A, 0xBC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x15,
-0xD1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x27, 0x2A, 0x9E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x27, 0xFE,
-0xED, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0A, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x29, 0xDE,
-0xCF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xEA, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2B, 0xBE,
-0xB1, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xD3, 0x7E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x9E,
-0x93, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xB3, 0x60, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x7E,
-0x75, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x93, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x31, 0x67,
-0x92, 0x20, 0x00, 0x00, 0x00, 0x00, 0x32, 0x73, 0x24, 0x90, 0x00, 0x00, 0x00, 0x00, 0x33, 0x47,
-0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x34, 0x53, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x35, 0x27,
-0x56, 0x20, 0x00, 0x00, 0x00, 0x00, 0x36, 0x32, 0xE8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x37, 0x07,
-0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1C, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE7,
-0x1A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x39, 0xFB, 0xE7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xC6,
-0xFC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xDB, 0xC9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xB0,
-0x18, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xBB, 0xAB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x8F,
-0xFA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x9B, 0x8D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F,
-0xDC, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xA9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4F,
-0xBE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x64, 0x8B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x44, 0x2F,
-0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x45, 0x44, 0x6D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x45, 0xF3,
-0xD3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x47, 0x2D, 0x8A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0xD3,
-0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x49, 0x0D, 0x6C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0xB3,
-0x97, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xED, 0x4E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x9C,
-0xB3, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xD6, 0x6A, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x7C,
-0x95, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xB6, 0x4C, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x5C,
-0x77, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x2E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x51, 0x3C,
-0x59, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x52, 0x76, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x1C,
-0x3B, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xF2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFC,
-0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x56, 0x35, 0xD4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x56, 0xE5,
-0x3A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1E, 0xF1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x58, 0xC5,
-0x1C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x59, 0xFE, 0xD3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA4,
-0xFE, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xDE, 0xB5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x84,
-0xE0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xBE, 0x97, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x64,
-0xC2, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x9E, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4D,
-0xDE, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x87, 0x95, 0x90, 0x00, 0x00, 0x00, 0x00, 0x62, 0x2D,
-0xC0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x67, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0D,
-0xA2, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x65, 0x47, 0x59, 0x90, 0x00, 0x00, 0x00, 0x00, 0x65, 0xED,
-0x84, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x67, 0x27, 0x3B, 0x90, 0x00, 0x00, 0x00, 0x00, 0x67, 0xCD,
-0x66, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x69, 0x07, 0x1D, 0x90, 0x00, 0x00, 0x00, 0x00, 0x69, 0xAD,
-0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xE6, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x96,
-0x65, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xD0, 0x1C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x76,
-0x47, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xAF, 0xFE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x56,
-0x29, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8F, 0xE0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x71, 0x36,
-0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6F, 0xC2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x73, 0x15,
-0xED, 0x20, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4F, 0xA4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74, 0xFF,
-0x09, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x76, 0x38, 0xC0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDE,
-0xEB, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0xBE,
-0xCD, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF8, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x9E,
-0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xD8, 0x66, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E,
-0x91, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xB8, 0x48, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5E,
-0x73, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x98, 0x2A, 0x90, 0x02, 0x01, 0x02, 0x03, 0x04, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
-0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF,
-0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C,
-0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53,
-0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x0A, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x2C, 0x4D, 0x33, 0x2E,
-0x32, 0x2E, 0x30, 0x2C, 0x4D, 0x31, 0x31, 0x2E, 0x31, 0x2E, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02,
+0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x05,
+0xFF, 0xFF, 0x8C, 0x94, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x04, 0xFF, 0xFF, 0x8F, 0x80,
+0x00, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x10, 0xFF, 0xFF,
+0x9D, 0x90, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00,
+0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x4D, 0x53, 0x54, 0x37, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 
 /* Canada/Saskatchewan */
 0x50, 0x48, 0x50, 0x32, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -71315,4 +71028,4 @@ const unsigned char timelib_timezone_db_data_builtin[715312] = {
 };
 #endif
 
-const timelib_tzdb timezonedb_builtin = { "2026.1", 598, timezonedb_idx_builtin, timelib_timezone_db_data_builtin };
+const timelib_tzdb timezonedb_builtin = { "2026.3", 598, timezonedb_idx_builtin, timelib_timezone_db_data_builtin };
diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c
index f13a9412406f..4c0252e244dd 100644
--- a/ext/date/lib/tm2unixtime.c
+++ b/ext/date/lib/tm2unixtime.c
@@ -197,32 +197,6 @@ void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt)
 	do_range_limit(0, 12, 12, &rt->m, &rt->y);
 }
 
-static void magic_date_calc(timelib_time *time)
-{
-	timelib_sll y, ddd, mi, mm, dd, g;
-
-	/* The algorithm doesn't work before the year 1 */
-	if (time->d < -719498) {
-		return;
-	}
-
-	g = time->d + HINNANT_EPOCH_SHIFT - 1;
-
-	y = (10000 * g + 14780) / 3652425;
-	ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
-	if (ddd < 0) {
-		y--;
-		ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
-	}
-	mi = (100 * ddd + 52) / 3060;
-	mm = ((mi + 2) % 12) + 1;
-	y = y + (mi + 2) / 12;
-	dd = ddd - ((mi * 306 + 5) / 10) + 1;
-	time->y = y;
-	time->m = mm;
-	time->d = dd;
-}
-
 void timelib_do_normalize(timelib_time* time)
 {
 	if (time->us != TIMELIB_UNSET) do_range_limit(0, 1000000, 1000000, &time->us, &time->s);
@@ -232,8 +206,9 @@ void timelib_do_normalize(timelib_time* time)
 	do_range_limit(1, 13, 12, &time->m, &time->y);
 
 	/* Short cut if we're doing things against the Epoch */
-	if (time->y == 1970 && time->m == 1 && time->d != 1) {
-		magic_date_calc(time);
+	if (time->y == 1970 && time->m == 1) {
+		timelib_date_from_epoch_days(time->d - 1, &time->y, &time->m, &time->d);
+		return;
 	}
 
 	do {} while (do_range_limit_days(&time->y, &time->m, &time->d));
diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c
index 30b3d00c7f44..9c4ba901a93d 100644
--- a/ext/date/lib/unixtime2tm.c
+++ b/ext/date/lib/unixtime2tm.c
@@ -26,20 +26,16 @@
 #include "timelib.h"
 #include "timelib_private.h"
 
-void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timelib_sll *d)
+/* Converts Unix epoch days (days since 1970-01-01) to a date. Algorithm from:
+ * http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
+void timelib_date_from_epoch_days(timelib_sll epoch_days, timelib_sll *y, timelib_sll *m, timelib_sll *d)
 {
-	timelib_sll days, era, t;
+	timelib_sll days, era;
 	timelib_ull day_of_era, year_of_era, day_of_year, month_portion;
 
 	/* Calculate days since algorithm's epoch (0000-03-01) */
-	days = ts / SECS_PER_DAY + HINNANT_EPOCH_SHIFT;
-
-	/* Adjustment for a negative time portion */
-	t = ts % SECS_PER_DAY;
-	days += (t < 0) ? -1 : 0;
+	days = epoch_days + HINNANT_EPOCH_SHIFT;
 
-	/* Calculate year, month, and day. Algorithm from:
-	 * http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
 	era = (days >= 0 ? days : days - DAYS_PER_ERA + 1) / DAYS_PER_ERA;
 	day_of_era = days - era * DAYS_PER_ERA;
 	year_of_era = (day_of_era - day_of_era / 1460 + day_of_era / 36524 - day_of_era / 146096) / DAYS_PER_YEAR;
@@ -49,6 +45,19 @@ void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timel
 	*d = day_of_year - (153 * month_portion + 2) / 5 + 1;
 	*m = month_portion + (month_portion < 10 ? 3 : -9);
 	*y += (*m <= 2);
+}
+
+void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timelib_sll *d)
+{
+	timelib_sll epoch_days, t;
+
+	epoch_days = ts / SECS_PER_DAY;
+
+	/* Adjustment for a negative time portion */
+	t = ts % SECS_PER_DAY;
+	epoch_days += (t < 0) ? -1 : 0;
+
+	timelib_date_from_epoch_days(epoch_days, y, m, d);
 
 	TIMELIB_DEBUG(printf("A: ts=%lld, year=%lld, month=%lld, day=%lld,", ts, *y, *m, *d););
 }
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index ddc7d315784b..0e24e4450641 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Derick Rethans                     |
    +----------------------------------------------------------------------+
@@ -31,13 +29,7 @@
 #include "win32/time.h"
 #endif
 
-#ifdef PHP_WIN32
-static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
-#elif defined(__GNUC__) && __GNUC__ < 3
-static __inline __int64_t php_date_llabs( __int64_t i ) { return i >= 0 ? i : -i; }
-#else
-static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i; }
-#endif
+static inline uint64_t php_date_llabs(int64_t i) { return i >= 0 ? (uint64_t)i : -(uint64_t)i; }
 
 #ifdef PHP_WIN32
 #define DATE_I64_BUF_LEN 65
@@ -742,9 +734,9 @@ static zend_string *date_format(const char *format, size_t format_len, const tim
 			/* year */
 			case 'L': length = slprintf(buffer, sizeof(buffer), "%d", timelib_is_leap((int) t->y)); break;
 			case 'y': length = slprintf(buffer, sizeof(buffer), "%02d", (int) (t->y % 100)); break;
-			case 'Y': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break;
-			case 'x': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : (t->y >= 10000 ? "+" : ""), php_date_llabs((timelib_sll) t->y)); break;
-			case 'X': length = slprintf(buffer, sizeof(buffer), "%s%04lld", t->y < 0 ? "-" : "+", php_date_llabs((timelib_sll) t->y)); break;
+			case 'Y': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break;
+			case 'x': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : (t->y >= 10000 ? "+" : ""), php_date_llabs((timelib_sll) t->y)); break;
+			case 'X': length = slprintf(buffer, sizeof(buffer), "%s%04" PRIu64, t->y < 0 ? "-" : "+", php_date_llabs((timelib_sll) t->y)); break;
 
 			/* time */
 			case 'a': length = slprintf(buffer, sizeof(buffer), "%s", t->h >= 12 ? "pm" : "am"); break;
@@ -909,13 +901,13 @@ PHPAPI zend_string *php_format_date(const char *format, size_t format_len, time_
 /* }}} */
 
 /* {{{ php_idate */
-PHPAPI int php_idate(char format, time_t ts, bool localtime)
+PHPAPI bool php_idate(char format, time_t ts, bool localtime, int *result)
 {
 	timelib_time   *t;
 	timelib_tzinfo *tzi;
-	int retval = -1;
 	timelib_time_offset *offset = NULL;
 	timelib_sll isoweek, isoyear;
+	bool success = true;
 
 	t = timelib_time_ctor();
 
@@ -955,46 +947,49 @@ PHPAPI int php_idate(char format, time_t ts, bool localtime)
 
 	switch (format) {
 		/* day */
-		case 'd': case 'j': retval = (int) t->d; break;
+		case 'd': case 'j': *result = (int) t->d; break;
 
-		case 'N': retval = (int) timelib_iso_day_of_week(t->y, t->m, t->d); break;
-		case 'w': retval = (int) timelib_day_of_week(t->y, t->m, t->d); break;
-		case 'z': retval = (int) timelib_day_of_year(t->y, t->m, t->d); break;
+		case 'N': *result = (int) timelib_iso_day_of_week(t->y, t->m, t->d); break;
+		case 'w': *result = (int) timelib_day_of_week(t->y, t->m, t->d); break;
+		case 'z': *result = (int) timelib_day_of_year(t->y, t->m, t->d); break;
 
 		/* week */
-		case 'W': retval = (int) isoweek; break; /* iso weeknr */
+		case 'W': *result = (int) isoweek; break; /* iso weeknr */
 
 		/* month */
-		case 'm': case 'n': retval = (int) t->m; break;
-		case 't': retval = (int) timelib_days_in_month(t->y, t->m); break;
+		case 'm': case 'n': *result = (int) t->m; break;
+		case 't': *result = (int) timelib_days_in_month(t->y, t->m); break;
 
 		/* year */
-		case 'L': retval = (int) timelib_is_leap((int) t->y); break;
-		case 'y': retval = (int) (t->y % 100); break;
-		case 'Y': retval = (int) t->y; break;
-		case 'o': retval = (int) isoyear; break; /* iso year */
+		case 'L': *result = (int) timelib_is_leap((int) t->y); break;
+		case 'y': *result = (int) (t->y % 100); break;
+		case 'Y': *result = (int) t->y; break;
+		case 'o': *result = (int) isoyear; break; /* iso year */
 
 		/* Swatch Beat a.k.a. Internet Time */
 		case 'B':
-			retval = ((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10);
-			if (retval < 0) {
-				retval += 864000;
+			*result = ((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10);
+			if (*result < 0) {
+				*result += 864000;
 			}
 			/* Make sure to do this on a positive int to avoid rounding errors */
-			retval = (retval / 864) % 1000;
+			*result = (*result / 864) % 1000;
 			break;
 
 		/* time */
-		case 'g': case 'h': retval = (int) ((t->h % 12) ? (int) t->h % 12 : 12); break;
-		case 'H': case 'G': retval = (int) t->h; break;
-		case 'i': retval = (int) t->i; break;
-		case 's': retval = (int) t->s; break;
+		case 'g': case 'h': *result = (int) ((t->h % 12) ? (int) t->h % 12 : 12); break;
+		case 'H': case 'G': *result = (int) t->h; break;
+		case 'i': *result = (int) t->i; break;
+		case 's': *result = (int) t->s; break;
 
 		/* timezone */
-		case 'I': retval = (int) (!localtime ? offset->is_dst : 0); break;
-		case 'Z': retval = (int) (!localtime ? offset->offset : 0); break;
+		case 'I': *result = (int) (!localtime ? offset->is_dst : 0); break;
+		case 'Z': *result = (int) (!localtime ? offset->offset : 0); break;
+
+		case 'U': *result = (int) t->sse; break;
 
-		case 'U': retval = (int) t->sse; break;
+		default:
+			success = false;
 	}
 
 	if (!localtime) {
@@ -1002,7 +997,7 @@ PHPAPI int php_idate(char format, time_t ts, bool localtime)
 	}
 	timelib_time_dtor(t);
 
-	return retval;
+	return success;
 }
 /* }}} */
 
@@ -1026,7 +1021,7 @@ PHP_FUNCTION(idate)
 	zend_string *format;
 	zend_long    ts;
 	bool    ts_is_null = 1;
-	int ret;
+	int ret = 0;
 
 	ZEND_PARSE_PARAMETERS_START(1, 2)
 		Z_PARAM_STR(format)
@@ -1043,8 +1038,8 @@ PHP_FUNCTION(idate)
 		ts = php_time();
 	}
 
-	ret = php_idate(ZSTR_VAL(format)[0], ts, 0);
-	if (ret == -1) {
+	bool ok = php_idate(ZSTR_VAL(format)[0], ts, 0, &ret);
+	if (!ok) {
 		php_error_docref(NULL, E_WARNING, "Unrecognized date format token");
 		RETURN_FALSE;
 	}
@@ -1756,7 +1751,7 @@ static void date_register_classes(void) /* {{{ */
 	date_ce_date->create_object = date_object_new_date;
 	date_ce_date->default_object_handlers = &date_object_handlers_date;
 	memcpy(&date_object_handlers_date, &std_object_handlers, sizeof(zend_object_handlers));
-	date_object_handlers_date.offset = XtOffsetOf(php_date_obj, std);
+	date_object_handlers_date.offset = offsetof(php_date_obj, std);
 	date_object_handlers_date.free_obj = date_object_free_storage_date;
 	date_object_handlers_date.clone_obj = date_object_clone_date;
 	date_object_handlers_date.compare = date_object_compare_date;
@@ -1776,7 +1771,7 @@ static void date_register_classes(void) /* {{{ */
 	date_ce_timezone->create_object = date_object_new_timezone;
 	date_ce_timezone->default_object_handlers = &date_object_handlers_timezone;
 	memcpy(&date_object_handlers_timezone, &std_object_handlers, sizeof(zend_object_handlers));
-	date_object_handlers_timezone.offset = XtOffsetOf(php_timezone_obj, std);
+	date_object_handlers_timezone.offset = offsetof(php_timezone_obj, std);
 	date_object_handlers_timezone.free_obj = date_object_free_storage_timezone;
 	date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
 	date_object_handlers_timezone.get_properties_for = date_object_get_properties_for_timezone;
@@ -1788,7 +1783,7 @@ static void date_register_classes(void) /* {{{ */
 	date_ce_interval->create_object = date_object_new_interval;
 	date_ce_interval->default_object_handlers = &date_object_handlers_interval;
 	memcpy(&date_object_handlers_interval, &std_object_handlers, sizeof(zend_object_handlers));
-	date_object_handlers_interval.offset = XtOffsetOf(php_interval_obj, std);
+	date_object_handlers_interval.offset = offsetof(php_interval_obj, std);
 	date_object_handlers_interval.free_obj = date_object_free_storage_interval;
 	date_object_handlers_interval.clone_obj = date_object_clone_interval;
 	date_object_handlers_interval.has_property = date_interval_has_property;
@@ -1804,7 +1799,7 @@ static void date_register_classes(void) /* {{{ */
 	date_ce_period->default_object_handlers = &date_object_handlers_period;
 	date_ce_period->get_iterator = date_object_period_get_iterator;
 	memcpy(&date_object_handlers_period, &std_object_handlers, sizeof(zend_object_handlers));
-	date_object_handlers_period.offset = XtOffsetOf(php_period_obj, std);
+	date_object_handlers_period.offset = offsetof(php_period_obj, std);
 	date_object_handlers_period.free_obj = date_object_free_storage_period;
 	date_object_handlers_period.clone_obj = date_object_clone_period;
 	date_object_handlers_period.get_gc = date_object_get_gc_period;
@@ -1839,7 +1834,7 @@ static zend_object *date_object_new_date(zend_class_entry *class_type) /* {{{ */
 
 static zend_object *date_object_clone_date(zend_object *this_ptr) /* {{{ */
 {
-	php_date_obj *old_obj = php_date_obj_from_obj(this_ptr);
+	const php_date_obj *old_obj = php_date_obj_from_obj(this_ptr);
 	php_date_obj *new_obj = php_date_obj_from_obj(date_object_new_date(old_obj->std.ce));
 
 	zend_objects_clone_members(&new_obj->std, &old_obj->std);
@@ -1963,12 +1958,22 @@ static HashTable *date_object_get_properties_for(zend_object *object, zend_prop_
 	php_date_obj *dateobj;
 
 	switch (purpose) {
-		case ZEND_PROP_PURPOSE_DEBUG:
 		case ZEND_PROP_PURPOSE_SERIALIZE:
 		case ZEND_PROP_PURPOSE_VAR_EXPORT:
 		case ZEND_PROP_PURPOSE_JSON:
 		case ZEND_PROP_PURPOSE_ARRAY_CAST:
 			break;
+		case ZEND_PROP_PURPOSE_DEBUG: {
+			if (object->ce->__debugInfo) {
+				int is_temp = 0;
+				HashTable *ht = zend_std_get_debug_info(object, &is_temp);
+				if (ht && !is_temp) {
+					GC_TRY_ADDREF(ht);
+				}
+				return ht;
+			}
+			break;
+		}
 		default:
 			return zend_std_get_properties_for(object, purpose);
 	}
@@ -1996,7 +2001,7 @@ static zend_object *date_object_new_timezone(zend_class_entry *class_type) /* {{
 
 static zend_object *date_object_clone_timezone(zend_object *this_ptr) /* {{{ */
 {
-	php_timezone_obj *old_obj = php_timezone_obj_from_obj(this_ptr);
+	const php_timezone_obj *old_obj = php_timezone_obj_from_obj(this_ptr);
 	php_timezone_obj *new_obj = php_timezone_obj_from_obj(date_object_new_timezone(old_obj->std.ce));
 
 	zend_objects_clone_members(&new_obj->std, &old_obj->std);
@@ -2049,7 +2054,7 @@ static int date_object_compare_timezone(zval *tz1, zval *tz2) /* {{{ */
 			return strcmp(o1->tzi.z.abbr, o2->tzi.z.abbr) ? 1 : 0;
 		case TIMELIB_ZONETYPE_ID:
 			return strcmp(o1->tzi.tz->name, o2->tzi.tz->name) ? 1 : 0;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 } /* }}} */
 
@@ -2085,12 +2090,22 @@ static HashTable *date_object_get_properties_for_timezone(zend_object *object, z
 	php_timezone_obj *tzobj;
 
 	switch (purpose) {
-		case ZEND_PROP_PURPOSE_DEBUG:
 		case ZEND_PROP_PURPOSE_SERIALIZE:
 		case ZEND_PROP_PURPOSE_VAR_EXPORT:
 		case ZEND_PROP_PURPOSE_JSON:
 		case ZEND_PROP_PURPOSE_ARRAY_CAST:
 			break;
+		case ZEND_PROP_PURPOSE_DEBUG: {
+			if (object->ce->__debugInfo) {
+				int is_temp = 0;
+				HashTable *ht = zend_std_get_debug_info(object, &is_temp);
+				if (ht && !is_temp) {
+					GC_TRY_ADDREF(ht);
+				}
+				return ht;
+			}
+			break;
+		}
 		default:
 			return zend_std_get_properties_for(object, purpose);
 	}
@@ -2139,7 +2154,7 @@ static zend_object *date_object_new_interval(zend_class_entry *class_type) /* {{
 
 static zend_object *date_object_clone_interval(zend_object *this_ptr) /* {{{ */
 {
-	php_interval_obj *old_obj = php_interval_obj_from_obj(this_ptr);
+	const php_interval_obj *old_obj = php_interval_obj_from_obj(this_ptr);
 	php_interval_obj *new_obj = php_interval_obj_from_obj(date_object_new_interval(old_obj->std.ce));
 
 	zend_objects_clone_members(&new_obj->std, &old_obj->std);
@@ -2230,7 +2245,7 @@ static zend_object *date_object_new_period(zend_class_entry *class_type) /* {{{
 
 static zend_object *date_object_clone_period(zend_object *this_ptr) /* {{{ */
 {
-	php_period_obj *old_obj = php_period_obj_from_obj(this_ptr);
+	const php_period_obj *old_obj = php_period_obj_from_obj(this_ptr);
 	php_period_obj *new_obj = php_period_obj_from_obj(date_object_new_period(old_obj->std.ce));
 
 	zend_objects_clone_members(&new_obj->std, &old_obj->std);
@@ -2744,7 +2759,7 @@ PHP_METHOD(DateTime, createFromTimestamp)
 			}
 			break;
 
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	RETURN_OBJ(Z_OBJ(new_object));
@@ -2825,7 +2840,7 @@ PHP_METHOD(DateTimeImmutable, createFromTimestamp)
 			}
 			break;
 
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	RETURN_OBJ(Z_OBJ(new_object));
@@ -4266,10 +4281,8 @@ PHP_FUNCTION(timezone_offset_get)
 			break;
 		case TIMELIB_ZONETYPE_OFFSET:
 			RETURN_LONG(tzobj->tzi.utc_offset);
-			break;
 		case TIMELIB_ZONETYPE_ABBR:
 			RETURN_LONG(tzobj->tzi.z.utc_offset + (tzobj->tzi.z.dst * 3600));
-			break;
 	}
 }
 /* }}} */
@@ -5068,7 +5081,7 @@ static bool date_period_init_iso8601_string(php_period_obj *dpobj, zend_class_en
 		zend_string_release(func);
 		return false;
 	}
-	if (dpobj->end == NULL && recurrences == 0) {
+	if (dpobj->end == NULL && *recurrences == 0) {
 		zend_string *func = get_active_function_or_method_name();
 		zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr);
 		zend_string_release(func);
@@ -5147,6 +5160,23 @@ PHP_METHOD(DatePeriod, createFromISO8601String)
 	}
 }
 
+static void date_period_reset(php_period_obj *period_obj)
+{
+	if (period_obj->start) {
+		timelib_time_dtor(period_obj->start);
+	}
+	if (period_obj->current) {
+		timelib_time_dtor(period_obj->current);
+	}
+	if (period_obj->end) {
+		timelib_time_dtor(period_obj->end);
+	}
+	if (period_obj->interval) {
+		timelib_rel_time_dtor(period_obj->interval);
+	}
+	memset(period_obj, 0, offsetof(php_period_obj, std));
+}
+
 /* {{{ Creates new DatePeriod object. */
 PHP_METHOD(DatePeriod, __construct)
 {
@@ -5168,7 +5198,7 @@ PHP_METHOD(DatePeriod, __construct)
 	}
 
 	dpobj = Z_PHPPERIOD_P(ZEND_THIS);
-	dpobj->current = NULL;
+	date_period_reset(dpobj);
 
 	if (isostr) {
 		zend_error(E_DEPRECATED, "Calling DatePeriod::__construct(string $isostr, int $options = 0) is deprecated, "
@@ -5186,6 +5216,7 @@ PHP_METHOD(DatePeriod, __construct)
 		if (end) {
 			DATE_CHECK_INITIALIZED(Z_PHPDATE_P(end)->time, date_ce_interface);
 		}
+		DATE_CHECK_INITIALIZED(Z_PHPINTERVAL_P(interval)->initialized, Z_OBJCE_P(interval));
 
 		/* init */
 		php_interval_obj *intobj = Z_PHPINTERVAL_P(interval);
@@ -5480,18 +5511,18 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, bool calc_s
 	ZEND_PARSE_PARAMETERS_END();
 
 	if (latitude_is_null) {
-		latitude = INI_FLT("date.default_latitude");
+		latitude = zend_ini_double_literal("date.default_latitude");
 	}
 
 	if (longitude_is_null) {
-		longitude = INI_FLT("date.default_longitude");
+		longitude = zend_ini_double_literal("date.default_longitude");
 	}
 
 	if (zenith_is_null) {
 		if (calc_sunset) {
-			zenith = INI_FLT("date.sunset_zenith");
+			zenith = zend_ini_double_literal("date.sunset_zenith");
 		} else {
-			zenith = INI_FLT("date.sunrise_zenith");
+			zenith = zend_ini_double_literal("date.sunrise_zenith");
 		}
 	}
 
@@ -5545,10 +5576,8 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, bool calc_s
 		case SUNFUNCS_RET_STRING:
 			retstr = strpprintf(0, "%02d:%02d", (int) N, (int) (60 * (N - (int) N)));
 			RETURN_NEW_STR(retstr);
-			break;
 		case SUNFUNCS_RET_DOUBLE:
 			RETURN_DOUBLE(N);
-			break;
 	}
 }
 /* }}} */
@@ -5973,7 +6002,7 @@ static int date_period_has_property(zend_object *object, zend_string *name, int
 				return 0;
 			case ZEND_PROPERTY_EXISTS:
 				return 1;
-			EMPTY_SWITCH_DEFAULT_CASE()
+			default: ZEND_UNREACHABLE();
 		}
 	}
 
@@ -6060,6 +6089,17 @@ static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *
 
 static HashTable *date_period_get_properties_for(zend_object *object, zend_prop_purpose purpose)
 {
+	if (purpose == ZEND_PROP_PURPOSE_DEBUG) {
+		if (object->ce->__debugInfo) {
+			int is_temp = 0;
+			HashTable *ht = zend_std_get_debug_info(object, &is_temp);
+			if (ht && !is_temp) {
+				GC_TRY_ADDREF(ht);
+			}
+			return ht;
+		}
+	}
+
 	php_period_obj *period_obj = php_period_obj_from_obj(object);
 	HashTable *props = zend_array_dup(zend_std_get_properties(object));
 	if (!period_obj->initialized) {
diff --git a/ext/date/php_date.h b/ext/date/php_date.h
index f5f43bc7dfb0..651cc28225fd 100644
--- a/ext/date/php_date.h
+++ b/ext/date/php_date.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Derick Rethans                     |
    +----------------------------------------------------------------------+
@@ -60,9 +58,7 @@ struct _php_date_obj {
 	zend_object   std;
 };
 
-static inline php_date_obj *php_date_obj_from_obj(zend_object *obj) {
-	return (php_date_obj*)((char*)(obj) - XtOffsetOf(php_date_obj, std));
-}
+#define php_date_obj_from_obj(obj) ZEND_CONTAINER_OF(obj, php_date_obj, std)
 
 #define Z_PHPDATE_P(zv)  php_date_obj_from_obj(Z_OBJ_P((zv)))
 
@@ -77,9 +73,7 @@ struct _php_timezone_obj {
 	zend_object std;
 };
 
-static inline php_timezone_obj *php_timezone_obj_from_obj(zend_object *obj) {
-	return (php_timezone_obj*)((char*)(obj) - XtOffsetOf(php_timezone_obj, std));
-}
+#define php_timezone_obj_from_obj(obj) ZEND_CONTAINER_OF(obj, php_timezone_obj, std)
 
 #define Z_PHPTIMEZONE_P(zv)  php_timezone_obj_from_obj(Z_OBJ_P((zv)))
 
@@ -95,9 +89,7 @@ struct _php_interval_obj {
 	zend_object       std;
 };
 
-static inline php_interval_obj *php_interval_obj_from_obj(zend_object *obj) {
-	return (php_interval_obj*)((char*)(obj) - XtOffsetOf(php_interval_obj, std));
-}
+#define php_interval_obj_from_obj(obj) ZEND_CONTAINER_OF(obj, php_interval_obj, std)
 
 #define Z_PHPINTERVAL_P(zv)  php_interval_obj_from_obj(Z_OBJ_P((zv)))
 
@@ -114,9 +106,7 @@ struct _php_period_obj {
 	zend_object       std;
 };
 
-static inline php_period_obj *php_period_obj_from_obj(zend_object *obj) {
-	return (php_period_obj*)((char*)(obj) - XtOffsetOf(php_period_obj, std));
-}
+#define php_period_obj_from_obj(obj) ZEND_CONTAINER_OF(obj, php_period_obj, std)
 
 #define Z_PHPPERIOD_P(zv)  php_period_obj_from_obj(Z_OBJ_P((zv)))
 
@@ -134,7 +124,7 @@ PHPAPI time_t php_time(void);
 /* Backwards compatibility wrapper */
 PHPAPI zend_long php_parse_date(const char *string, zend_long *now);
 PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, bool gmt);
-PHPAPI int php_idate(char format, time_t ts, bool localtime);
+PHPAPI bool php_idate(char format, time_t ts, bool localtime, int *result);
 
 #define _php_strftime php_strftime
 
diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h
index 4a5a4ad32dec..db2b4d5ea9e1 100644
--- a/ext/date/php_date_arginfo.h
+++ b/ext/date/php_date_arginfo.h
@@ -1025,65 +1025,47 @@ static zend_class_entry *register_class_DateTimeImmutable(zend_class_entry *clas
 	ZVAL_STR(&attribute_Deprecated_func___wakeup_0->args[1].value, attribute_Deprecated_func___wakeup_0_arg1_str);
 	attribute_Deprecated_func___wakeup_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_modify_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_modify_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "modify", sizeof("modify") - 1), attribute_name_NoDiscard_func_modify_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_modify_0, true);
+	zend_attribute *attribute_NoDiscard_func_modify_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "modify", sizeof("modify") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_modify_0_arg0_str = zend_string_init("as DateTimeImmutable::modify() does not modify the object itself", strlen("as DateTimeImmutable::modify() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_modify_0->args[0].value, attribute_NoDiscard_func_modify_0_arg0_str);
 	attribute_NoDiscard_func_modify_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_add_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_add_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "add", sizeof("add") - 1), attribute_name_NoDiscard_func_add_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_add_0, true);
+	zend_attribute *attribute_NoDiscard_func_add_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "add", sizeof("add") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_add_0_arg0_str = zend_string_init("as DateTimeImmutable::add() does not modify the object itself", strlen("as DateTimeImmutable::add() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_add_0->args[0].value, attribute_NoDiscard_func_add_0_arg0_str);
 	attribute_NoDiscard_func_add_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_sub_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_sub_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "sub", sizeof("sub") - 1), attribute_name_NoDiscard_func_sub_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_sub_0, true);
+	zend_attribute *attribute_NoDiscard_func_sub_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "sub", sizeof("sub") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_sub_0_arg0_str = zend_string_init("as DateTimeImmutable::sub() does not modify the object itself", strlen("as DateTimeImmutable::sub() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_sub_0->args[0].value, attribute_NoDiscard_func_sub_0_arg0_str);
 	attribute_NoDiscard_func_sub_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_settimezone_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_settimezone_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimezone", sizeof("settimezone") - 1), attribute_name_NoDiscard_func_settimezone_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_settimezone_0, true);
+	zend_attribute *attribute_NoDiscard_func_settimezone_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimezone", sizeof("settimezone") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_settimezone_0_arg0_str = zend_string_init("as DateTimeImmutable::setTimezone() does not modify the object itself", strlen("as DateTimeImmutable::setTimezone() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_settimezone_0->args[0].value, attribute_NoDiscard_func_settimezone_0_arg0_str);
 	attribute_NoDiscard_func_settimezone_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_settime_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_settime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settime", sizeof("settime") - 1), attribute_name_NoDiscard_func_settime_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_settime_0, true);
+	zend_attribute *attribute_NoDiscard_func_settime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settime", sizeof("settime") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_settime_0_arg0_str = zend_string_init("as DateTimeImmutable::setTime() does not modify the object itself", strlen("as DateTimeImmutable::setTime() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_settime_0->args[0].value, attribute_NoDiscard_func_settime_0_arg0_str);
 	attribute_NoDiscard_func_settime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_setdate_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_setdate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setdate", sizeof("setdate") - 1), attribute_name_NoDiscard_func_setdate_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_setdate_0, true);
+	zend_attribute *attribute_NoDiscard_func_setdate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setdate", sizeof("setdate") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_setdate_0_arg0_str = zend_string_init("as DateTimeImmutable::setDate() does not modify the object itself", strlen("as DateTimeImmutable::setDate() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_setdate_0->args[0].value, attribute_NoDiscard_func_setdate_0_arg0_str);
 	attribute_NoDiscard_func_setdate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_setisodate_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_setisodate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setisodate", sizeof("setisodate") - 1), attribute_name_NoDiscard_func_setisodate_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_setisodate_0, true);
+	zend_attribute *attribute_NoDiscard_func_setisodate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setisodate", sizeof("setisodate") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_setisodate_0_arg0_str = zend_string_init("as DateTimeImmutable::setISODate() does not modify the object itself", strlen("as DateTimeImmutable::setISODate() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_setisodate_0->args[0].value, attribute_NoDiscard_func_setisodate_0_arg0_str);
 	attribute_NoDiscard_func_setisodate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_settimestamp_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_settimestamp_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimestamp", sizeof("settimestamp") - 1), attribute_name_NoDiscard_func_settimestamp_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_settimestamp_0, true);
+	zend_attribute *attribute_NoDiscard_func_settimestamp_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "settimestamp", sizeof("settimestamp") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_settimestamp_0_arg0_str = zend_string_init("as DateTimeImmutable::setTimestamp() does not modify the object itself", strlen("as DateTimeImmutable::setTimestamp() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_settimestamp_0->args[0].value, attribute_NoDiscard_func_settimestamp_0_arg0_str);
 	attribute_NoDiscard_func_settimestamp_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
 
-	zend_string *attribute_name_NoDiscard_func_setmicrosecond_0 = zend_string_init_interned("NoDiscard", sizeof("NoDiscard") - 1, true);
-	zend_attribute *attribute_NoDiscard_func_setmicrosecond_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setmicrosecond", sizeof("setmicrosecond") - 1), attribute_name_NoDiscard_func_setmicrosecond_0, 1);
-	zend_string_release_ex(attribute_name_NoDiscard_func_setmicrosecond_0, true);
+	zend_attribute *attribute_NoDiscard_func_setmicrosecond_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setmicrosecond", sizeof("setmicrosecond") - 1), ZSTR_KNOWN(ZEND_STR_NODISCARD), 1);
 	zend_string *attribute_NoDiscard_func_setmicrosecond_0_arg0_str = zend_string_init("as DateTimeImmutable::setMicrosecond() does not modify the object itself", strlen("as DateTimeImmutable::setMicrosecond() does not modify the object itself"), 1);
 	ZVAL_STR(&attribute_NoDiscard_func_setmicrosecond_0->args[0].value, attribute_NoDiscard_func_setmicrosecond_0_arg0_str);
 	attribute_NoDiscard_func_setmicrosecond_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
diff --git a/ext/date/tests/DatePeriod_double_constructor_call.phpt b/ext/date/tests/DatePeriod_double_constructor_call.phpt
new file mode 100644
index 000000000000..551d2727282d
--- /dev/null
+++ b/ext/date/tests/DatePeriod_double_constructor_call.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Double DatePeriod::__construct() call
+--FILE--
+__construct($start, $interval, 1);
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/date/tests/bug-gh11310-1.phpt b/ext/date/tests/bug-gh11310-1.phpt
new file mode 100644
index 000000000000..c12b0201294d
--- /dev/null
+++ b/ext/date/tests/bug-gh11310-1.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug GH-11310: __debugInfo does nothing on userland classes extending Date classes
+--FILE--
+ 'zzz']; } }
+class UDateTimeImmutable extends DateTimeImmutable { public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDateTimeZone extends DateTimeZone { public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDateInterval extends DateInterval { public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDatePeriod extends DatePeriod { public function __debugInfo(): array { return ['value' => 'zzz']; } }
+
+$d = new UDateTime(); var_dump($d);
+$d = new UDateTimeImmutable(); var_dump($d);
+$d = new UDateTimeZone("Europe/Kyiv"); var_dump($d);
+$d = new UDateInterval("P3D"); var_dump($d);
+$d = UDatePeriod::createFromISO8601String("2026-07-09T17:23:06Z/P3D/R5"); var_dump($d);
+?>
+--EXPECTF--
+object(UDateTime)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateTimeImmutable)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateTimeZone)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateInterval)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDatePeriod)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
diff --git a/ext/date/tests/bug-gh11310-2.phpt b/ext/date/tests/bug-gh11310-2.phpt
new file mode 100644
index 000000000000..8dce510a19d6
--- /dev/null
+++ b/ext/date/tests/bug-gh11310-2.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug GH-11310: __debugInfo does nothing on userland classes extending Date classes
+--FILE--
+ 'zzz']; } }
+class UDateTimeImmutable extends DateTimeImmutable { public function __construct() {} public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDateTimeZone extends DateTimeZone { public function __construct() {} public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDateInterval extends DateInterval { public function __construct() {} public function __debugInfo(): array { return ['value' => 'zzz']; } }
+class UDatePeriod extends DatePeriod { public function __construct() {} public function __debugInfo(): array { return ['value' => 'zzz']; } }
+
+$d = new UDateTime(); var_dump($d);
+$d = new UDateTimeImmutable(); var_dump($d);
+$d = new UDateTimeZone("Europe/Kyiv"); var_dump($d);
+$d = new UDateInterval("P3D"); var_dump($d);
+$d = UDatePeriod::createFromISO8601String("2026-07-09T17:23:06Z/P3D/R5"); var_dump($d);
+?>
+--EXPECTF--
+object(UDateTime)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateTimeImmutable)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateTimeZone)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDateInterval)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
+object(UDatePeriod)#%d (1) {
+  ["value"]=>
+  string(3) "zzz"
+}
diff --git a/ext/date/tests/date_period_bad_iso_format.phpt b/ext/date/tests/date_period_bad_iso_format.phpt
index cf2025bef0e3..1ab8197d76c9 100644
--- a/ext/date/tests/date_period_bad_iso_format.phpt
+++ b/ext/date/tests/date_period_bad_iso_format.phpt
@@ -50,5 +50,5 @@ DateMalformedPeriodStringException: DatePeriod::__construct(): ISO interval must
 DateMalformedPeriodStringException: DatePeriod::createFromISO8601String(): ISO interval must contain an interval, "R4/2012-07-01T00:00:00Z" given
 
 Deprecated: Calling DatePeriod::__construct(string $isostr, int $options = 0) is deprecated, use DatePeriod::createFromISO8601String() instead in %s on line %d
-DateMalformedPeriodStringException: DatePeriod::__construct(): Recurrence count must be greater or equal to 1 and lower than %d
-DateMalformedPeriodStringException: DatePeriod::createFromISO8601String(): Recurrence count must be greater or equal to 1 and lower than %d
+DateMalformedPeriodStringException: DatePeriod::__construct(): ISO interval must contain an end date or a recurrence count, "2012-07-01T00:00:00Z/P7D" given
+DateMalformedPeriodStringException: DatePeriod::createFromISO8601String(): ISO interval must contain an end date or a recurrence count, "2012-07-01T00:00:00Z/P7D" given
diff --git a/ext/date/tests/gh-124.phpt b/ext/date/tests/gh-124.phpt
index 074e519d4399..30cccd74ef1f 100644
--- a/ext/date/tests/gh-124.phpt
+++ b/ext/date/tests/gh-124.phpt
@@ -4,7 +4,7 @@ Test for timelib #124: Problem with large negative timestamps
 date.timezone=UTC
 --SKIPIF--
 
 --FILE--
diff --git a/ext/date/tests/gh18422.phpt b/ext/date/tests/gh18422.phpt
new file mode 100644
index 000000000000..643476615277
--- /dev/null
+++ b/ext/date/tests/gh18422.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-18422 (int overflow in Date extension)
+--FILE--
+format("Y"), "\n";
+echo $dto->format("x"), "\n";
+echo $dto->format("X"), "\n";
+
+echo date_create("2024-06-15")->format("Y"), "\n";
+echo date_create("-0042-01-01")->format("Y"), "\n";
+?>
+--EXPECTF--
+-%d
+-%d
+-%d
+2024
+-0042
diff --git a/ext/dba/dba.c b/ext/dba/dba.c
index fb6017fbab88..a9114753a8a6 100644
--- a/ext/dba/dba.c
+++ b/ext/dba/dba.c
@@ -1,14 +1,12 @@
 /*
-+----------------------------------------------------------------------+
-   | 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.               |
+   | Copyright © The PHP Group and Contributors.                          |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sascha Schumann                         |
    |          Marcus Boerger                               |
@@ -337,10 +335,7 @@ static zend_result dba_connection_cast_object(zend_object *obj, zval *result, in
 	return zend_std_cast_object_tostring(obj, result, type);
 }
 
-static inline dba_connection *dba_connection_from_obj(zend_object *obj)
-{
-	return (dba_connection *)((char *)(obj) - XtOffsetOf(dba_connection, std));
-}
+#define dba_connection_from_obj(obj) ZEND_CONTAINER_OF(obj, dba_connection, std)
 
 #define Z_DBA_CONNECTION_P(zv) dba_connection_from_obj(Z_OBJ_P(zv))
 #define Z_DBA_INFO_P(zv) Z_DBA_CONNECTION_P(zv)->info
@@ -411,7 +406,7 @@ PHP_MINIT_FUNCTION(dba)
 	dba_connection_ce->default_object_handlers = &dba_connection_object_handlers;
 
 	memcpy(&dba_connection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	dba_connection_object_handlers.offset = XtOffsetOf(dba_connection, std);
+	dba_connection_object_handlers.offset = offsetof(dba_connection, std);
 	dba_connection_object_handlers.free_obj = dba_connection_free_obj;
 	dba_connection_object_handlers.get_constructor = dba_connection_get_constructor;
 	dba_connection_object_handlers.clone_obj = NULL;
@@ -1287,10 +1282,8 @@ PHP_FUNCTION(dba_handlers)
 
 	for (const dba_handler *hptr = handler; hptr->name; hptr++) {
 		if (full_info) {
-			// TODO: avoid reallocation ???
-			char *str = hptr->info(hptr, NULL);
+			const char *str = hptr->info(hptr, NULL);
 			add_assoc_string(return_value, hptr->name, str);
-			efree(str);
 		} else {
 			add_next_index_string(return_value, hptr->name);
 		}
diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c
index 10a381b579da..3578866b546c 100644
--- a/ext/dba/dba_cdb.c
+++ b/ext/dba/dba_cdb.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sascha Schumann                         |
    |          Marcus Boerger                               |
@@ -321,12 +319,12 @@ DBA_INFO_FUNC(cdb)
 {
 #ifdef DBA_CDB_BUILTIN
 	if (!strcmp(hnd->name, "cdb")) {
-		return estrdup(cdb_version());
+		return cdb_version();
 	} else {
-		return estrdup(cdb_make_version());
+		return cdb_make_version();
 	}
 #else
-	return estrdup("External");
+	return "External";
 #endif
 }
 
diff --git a/ext/dba/dba_db1.c b/ext/dba/dba_db1.c
index e4b83fcb55f3..59846c90a4c8 100644
--- a/ext/dba/dba_db1.c
+++ b/ext/dba/dba_db1.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Shen Cheng-Da                             |
    +----------------------------------------------------------------------+
@@ -179,7 +177,7 @@ DBA_SYNC_FUNC(db1)
 
 DBA_INFO_FUNC(db1)
 {
-	return estrdup(DB1_VERSION);
+	return DB1_VERSION;
 }
 
 #endif
diff --git a/ext/dba/dba_db2.c b/ext/dba/dba_db2.c
index 5ec3df182e84..50893d8458c8 100644
--- a/ext/dba/dba_db2.c
+++ b/ext/dba/dba_db2.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -189,7 +187,7 @@ DBA_SYNC_FUNC(db2)
 
 DBA_INFO_FUNC(db2)
 {
-	return estrdup(DB_VERSION_STRING);
+	return DB_VERSION_STRING;
 }
 
 #endif
diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c
index 8efc8d45b3ba..d4111e8c41fc 100644
--- a/ext/dba/dba_db3.c
+++ b/ext/dba/dba_db3.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -227,7 +225,7 @@ DBA_SYNC_FUNC(db3)
 
 DBA_INFO_FUNC(db3)
 {
-	return estrdup(DB_VERSION_STRING);
+	return DB_VERSION_STRING;
 }
 
 #endif
diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c
index f64db5540ee9..fbd5f8191b44 100644
--- a/ext/dba/dba_db4.c
+++ b/ext/dba/dba_db4.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    |          Sascha Schumann                         |
@@ -284,7 +282,7 @@ DBA_SYNC_FUNC(db4)
 
 DBA_INFO_FUNC(db4)
 {
-	return estrdup(DB_VERSION_STRING);
+	return DB_VERSION_STRING;
 }
 
 #endif
diff --git a/ext/dba/dba_dbm.c b/ext/dba/dba_dbm.c
index b6d98d22893e..73f137e9891f 100644
--- a/ext/dba/dba_dbm.c
+++ b/ext/dba/dba_dbm.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -194,7 +192,7 @@ DBA_INFO_FUNC(dbm)
 		return dba_info_gdbm(hnd, info);
 	}
 #endif
-	return estrdup(DBM_VERSION);
+	return DBM_VERSION;
 }
 
 #endif
diff --git a/ext/dba/dba_flatfile.c b/ext/dba/dba_flatfile.c
index 997e6b9cc112..5e8bae223f9e 100644
--- a/ext/dba/dba_flatfile.c
+++ b/ext/dba/dba_flatfile.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
@@ -169,7 +167,7 @@ DBA_SYNC_FUNC(flatfile)
 
 DBA_INFO_FUNC(flatfile)
 {
-	return estrdup(flatfile_version());
+	return flatfile_version();
 }
 
 #endif
diff --git a/ext/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c
index 245c79e0e62d..64877eb289c4 100644
--- a/ext/dba/dba_gdbm.c
+++ b/ext/dba/dba_gdbm.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -191,7 +189,7 @@ DBA_SYNC_FUNC(gdbm)
 
 DBA_INFO_FUNC(gdbm)
 {
-	return estrdup(gdbm_version);
+	return gdbm_version;
 }
 
 #endif
diff --git a/ext/dba/dba_inifile.c b/ext/dba/dba_inifile.c
index 75a267055d96..bf5ef322759d 100644
--- a/ext/dba/dba_inifile.c
+++ b/ext/dba/dba_inifile.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
@@ -188,7 +186,7 @@ DBA_SYNC_FUNC(inifile)
 
 DBA_INFO_FUNC(inifile)
 {
-	return estrdup(inifile_version());
+	return inifile_version();
 }
 
 #endif
diff --git a/ext/dba/dba_lmdb.c b/ext/dba/dba_lmdb.c
index f6bdc7838a6a..6e6a78ad5e24 100644
--- a/ext/dba/dba_lmdb.c
+++ b/ext/dba/dba_lmdb.c
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author: Anatol Belski                                    |
   +----------------------------------------------------------------------+
@@ -362,7 +360,7 @@ DBA_SYNC_FUNC(lmdb)
 
 DBA_INFO_FUNC(lmdb)
 {
-	return estrdup(MDB_VERSION_STRING);
+	return MDB_VERSION_STRING;
 }
 
 #endif
diff --git a/ext/dba/dba_ndbm.c b/ext/dba/dba_ndbm.c
index 40ae304cb7d2..c60ab7e5f428 100644
--- a/ext/dba/dba_ndbm.c
+++ b/ext/dba/dba_ndbm.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -149,7 +147,7 @@ DBA_SYNC_FUNC(ndbm)
 
 DBA_INFO_FUNC(ndbm)
 {
-	return estrdup("NDBM");
+	return "NDBM";
 }
 
 #endif
diff --git a/ext/dba/dba_qdbm.c b/ext/dba/dba_qdbm.c
index 5cbfeee874d5..cc97cd9757f4 100644
--- a/ext/dba/dba_qdbm.c
+++ b/ext/dba/dba_qdbm.c
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author: Marcin Gibula                                   |
   +----------------------------------------------------------------------+
@@ -175,7 +173,7 @@ DBA_SYNC_FUNC(qdbm)
 
 DBA_INFO_FUNC(qdbm)
 {
-	return estrdup(dpversion);
+	return dpversion;
 }
 
 #endif
diff --git a/ext/dba/dba_tcadb.c b/ext/dba/dba_tcadb.c
index 6f4cb01e69e5..5f4ed5eeabdc 100644
--- a/ext/dba/dba_tcadb.c
+++ b/ext/dba/dba_tcadb.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author:  Michael Maclean                               |
    +----------------------------------------------------------------------+
@@ -195,7 +193,7 @@ DBA_SYNC_FUNC(tcadb)
 
 DBA_INFO_FUNC(tcadb)
 {
-	return estrdup(tcversion);
+	return tcversion;
 }
 
 #endif
diff --git a/ext/dba/libcdb/cdb.c b/ext/dba/libcdb/cdb.c
index e694d6a6eb12..e258e8fe2d5a 100644
--- a/ext/dba/libcdb/cdb.c
+++ b/ext/dba/libcdb/cdb.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libcdb/cdb.h b/ext/dba/libcdb/cdb.h
index 4a94b81f832d..cc645196a983 100644
--- a/ext/dba/libcdb/cdb.h
+++ b/ext/dba/libcdb/cdb.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libcdb/cdb_make.c b/ext/dba/libcdb/cdb_make.c
index 570e3625b0ce..b216b904e9bd 100644
--- a/ext/dba/libcdb/cdb_make.c
+++ b/ext/dba/libcdb/cdb_make.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libcdb/cdb_make.h b/ext/dba/libcdb/cdb_make.h
index 96dbd43d1e56..aa94c1747267 100644
--- a/ext/dba/libcdb/cdb_make.h
+++ b/ext/dba/libcdb/cdb_make.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libcdb/uint32.c b/ext/dba/libcdb/uint32.c
index 6f2507204aad..e5ba93fed2af 100644
--- a/ext/dba/libcdb/uint32.c
+++ b/ext/dba/libcdb/uint32.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libcdb/uint32.h b/ext/dba/libcdb/uint32.h
index 41041853fdbf..fe9ffba847a5 100644
--- a/ext/dba/libcdb/uint32.h
+++ b/ext/dba/libcdb/uint32.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libflatfile/flatfile.c b/ext/dba/libflatfile/flatfile.c
index bd76ecfdd0ae..a5a9bf70c23b 100644
--- a/ext/dba/libflatfile/flatfile.c
+++ b/ext/dba/libflatfile/flatfile.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    | based on ext/db/db.c by:                                             |
@@ -37,6 +35,18 @@
 
 #define FLATFILE_BLOCK_SIZE 1024
 
+/* Parse the length prefix in `buf` into `num` and grow `buf` to hold it.
+ * atoi() narrows a malformed (e.g. negative) length to a huge size_t whose
+ * `+ FLATFILE_BLOCK_SIZE` would overflow erealloc(); the macro yields true in
+ * that case so the caller stops reading and the read stays within `buf_size`. */
+#define FLATFILE_GROW_BUF(num, buf, buf_size) ( \
+	(num) = atoi(buf), \
+	(num) >= (buf_size) && ( \
+		(num) > SIZE_MAX - FLATFILE_BLOCK_SIZE \
+		|| ((buf) = erealloc((buf), (buf_size) = (num) + FLATFILE_BLOCK_SIZE), 0) \
+	) \
+)
+
 /*
  * ret = -1 means that database was opened for read-only
  * ret = 0  success
@@ -112,10 +122,8 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		pos = php_stream_tell(dba->fp);
 
@@ -135,10 +143,8 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		/* read in the value */
 		num = php_stream_read(dba->fp, buf, num);
@@ -162,10 +168,8 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 
@@ -178,10 +182,8 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 	}
@@ -202,10 +204,8 @@ datum flatfile_firstkey(flatfile *dba) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 
@@ -218,10 +218,8 @@ datum flatfile_firstkey(flatfile *dba) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 	}
@@ -244,20 +242,16 @@ datum flatfile_nextkey(flatfile *dba) {
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 
 		if (!php_stream_gets(dba->fp, buf, 15)) {
 			break;
 		}
-		num = atoi(buf);
-		if (num >= buf_size) {
-			buf_size = num + FLATFILE_BLOCK_SIZE;
-			buf = erealloc(buf, buf_size);
+		if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
+			break;
 		}
 		num = php_stream_read(dba->fp, buf, num);
 
diff --git a/ext/dba/libflatfile/flatfile.h b/ext/dba/libflatfile/flatfile.h
index 801ec8054f4f..ee3e5380b72b 100644
--- a/ext/dba/libflatfile/flatfile.h
+++ b/ext/dba/libflatfile/flatfile.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/libinifile/inifile.c b/ext/dba/libinifile/inifile.c
index c5467396d4bf..fa2b05a715e2 100644
--- a/ext/dba/libinifile/inifile.c
+++ b/ext/dba/libinifile/inifile.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
@@ -111,7 +109,7 @@ void inifile_free(inifile *dba, int persistent)
 key_type inifile_key_split(const char *group_name)
 {
 	key_type key;
-	char *name;
+	const char *name;
 
 	if (group_name[0] == '[' && (name = strchr(group_name, ']')) != NULL) {
 		key.group = estrndup(group_name+1, name - (group_name + 1));
@@ -249,7 +247,7 @@ val_type inifile_fetch(inifile *dba, const key_type *key, int skip) {
 		ln.key.group = estrdup(dba->next.key.group);
 	} else {
 		/* specific instance or not same key -> restart search */
-		/* the slow way: restart and seacrch */
+		/* the slow way: restart and search */
 		php_stream_rewind(dba->fp);
 		inifile_line_free(&dba->next);
 	}
@@ -471,7 +469,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons
 	 * 8) Append temporary stream
 	 */
 
-	assert(!append || (key->name && value)); /* missuse */
+	assert(!append || (key->name && value)); /* misuse */
 
 	/* 1 - 3 */
 	inifile_find_group(dba, key, &pos_grp_start);
diff --git a/ext/dba/libinifile/inifile.h b/ext/dba/libinifile/inifile.h
index e931c70bcbf6..75cf22d53fdd 100644
--- a/ext/dba/libinifile/inifile.h
+++ b/ext/dba/libinifile/inifile.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Marcus Boerger                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h
index 033aed59c9ea..38ad3ea2820b 100644
--- a/ext/dba/php_dba.h
+++ b/ext/dba/php_dba.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
@@ -91,7 +89,7 @@ typedef struct dba_handler {
 	zend_string* (*nextkey)(dba_info *);
 	zend_result (*optimize)(dba_info *);
 	zend_result (*sync)(dba_info *);
-	char* (*info)(const struct dba_handler *hnd, dba_info *);
+	const char* (*info)(const struct dba_handler *hnd, dba_info *);
 		/* dba_info==NULL: Handler info, dba_info!=NULL: Database info */
 } dba_handler;
 
@@ -118,7 +116,7 @@ typedef struct dba_handler {
 #define DBA_SYNC_FUNC(x) \
 	zend_result dba_sync_##x(dba_info *info)
 #define DBA_INFO_FUNC(x) \
-	char *dba_info_##x(const dba_handler *hnd, dba_info *info)
+	const char *dba_info_##x(const dba_handler *hnd, dba_info *info)
 
 #define DBA_FUNCS(x) \
 	DBA_OPEN_FUNC(x); \
diff --git a/ext/dba/php_tcadb.h b/ext/dba/php_tcadb.h
index 6bfecf7d6d96..038440c7607e 100644
--- a/ext/dba/php_tcadb.h
+++ b/ext/dba/php_tcadb.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Michael Maclean                                |
    +----------------------------------------------------------------------+
diff --git a/ext/dba/tests/dba_cdb_creation_matrix.phpt b/ext/dba/tests/dba_cdb_creation_matrix.phpt
index 36880911c89c..c7dda5b61b68 100644
--- a/ext/dba/tests/dba_cdb_creation_matrix.phpt
+++ b/ext/dba/tests/dba_cdb_creation_matrix.phpt
@@ -25,35 +25,35 @@ clean_creation_tests($handler);
 === OPENING NON-EXISTING FILE ===
 Mode parameter is "rl":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "rd":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r-":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wl":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wd":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w-":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w":
 
-Warning: dba_open(cdb_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "cl":
 
diff --git a/ext/dba/tests/dba_flatfile_creation_matrix.phpt b/ext/dba/tests/dba_flatfile_creation_matrix.phpt
index 6009c0778941..d10523f9b1e4 100644
--- a/ext/dba/tests/dba_flatfile_creation_matrix.phpt
+++ b/ext/dba/tests/dba_flatfile_creation_matrix.phpt
@@ -25,35 +25,35 @@ clean_creation_tests($handler);
 === OPENING NON-EXISTING FILE ===
 Mode parameter is "rl":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "rd":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r-":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wl":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wd":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w-":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w":
 
-Warning: dba_open(flatfile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "cl":
 This is a test insert
diff --git a/ext/dba/tests/dba_flatfile_oob.phpt b/ext/dba/tests/dba_flatfile_oob.phpt
new file mode 100644
index 000000000000..3328e1dcba90
--- /dev/null
+++ b/ext/dba/tests/dba_flatfile_oob.phpt
@@ -0,0 +1,31 @@
+--TEST--
+DBA FlatFile handler bounds with a malformed (negative) length field
+--EXTENSIONS--
+dba
+--SKIPIF--
+
+--FILE--
+
+--CLEAN--
+
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
+done
diff --git a/ext/dba/tests/dba_inifile_creation_matrix.phpt b/ext/dba/tests/dba_inifile_creation_matrix.phpt
index aff1fdfb4f16..2e93e865e3e6 100644
--- a/ext/dba/tests/dba_inifile_creation_matrix.phpt
+++ b/ext/dba/tests/dba_inifile_creation_matrix.phpt
@@ -25,35 +25,35 @@ clean_creation_tests($handler);
 === OPENING NON-EXISTING FILE ===
 Mode parameter is "rl":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "rd":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r-":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wl":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wd":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w-":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w":
 
-Warning: dba_open(inifile_not_existing.db): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "cl":
 This is a test insert
diff --git a/ext/dba/tests/dba_tcadb_creation_matrix.phpt b/ext/dba/tests/dba_tcadb_creation_matrix.phpt
index e86efce75cae..928729777741 100644
--- a/ext/dba/tests/dba_tcadb_creation_matrix.phpt
+++ b/ext/dba/tests/dba_tcadb_creation_matrix.phpt
@@ -29,7 +29,7 @@ Warning: dba_open(): Driver initialization failed for handler: tcadb in %s on li
 Opening DB failed
 Mode parameter is "rd":
 
-Warning: dba_open(tcadb_not_existing.tch): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "r-":
 
@@ -37,7 +37,7 @@ Warning: dba_open(): Driver initialization failed for handler: tcadb in %s on li
 Opening DB failed
 Mode parameter is "r":
 
-Warning: dba_open(tcadb_not_existing.tch): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "wl":
 
@@ -45,7 +45,7 @@ Warning: dba_open(): Driver initialization failed for handler: tcadb in %s on li
 Opening DB failed
 Mode parameter is "wd":
 
-Warning: dba_open(tcadb_not_existing.tch): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "w-":
 
@@ -53,7 +53,7 @@ Warning: dba_open(): Driver initialization failed for handler: tcadb in %s on li
 Opening DB failed
 Mode parameter is "w":
 
-Warning: dba_open(tcadb_not_existing.tch): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_open(): Failed to open stream: No such file or directory in %s on line %d
 Opening DB failed
 Mode parameter is "cl":
 This is a test insert
diff --git a/ext/dba/tests/gh18247.phpt b/ext/dba/tests/gh18247.phpt
index bb757452321d..c7bc0277dc20 100644
--- a/ext/dba/tests/gh18247.phpt
+++ b/ext/dba/tests/gh18247.phpt
@@ -8,5 +8,5 @@ var_dump(dba_popen('/inexistent', 'r'));
 ?>
 --EXPECTF--
 
-Warning: dba_popen(/inexistent): Failed to open stream: No such file or directory in %s on line %d
+Warning: dba_popen(): Failed to open stream: No such file or directory in %s on line %d
 bool(false)
diff --git a/ext/dl_test/dl_test.c b/ext/dl_test/dl_test.c
index 10afdb0720f2..4346e868c1e5 100644
--- a/ext/dl_test/dl_test.c
+++ b/ext/dl_test/dl_test.c
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author: Arnaud Le Blanc                         |
   +----------------------------------------------------------------------+
diff --git a/ext/dl_test/php_dl_test.h b/ext/dl_test/php_dl_test.h
index c12a43fe165b..133d513cbf99 100644
--- a/ext/dl_test/php_dl_test.h
+++ b/ext/dl_test/php_dl_test.h
@@ -1,14 +1,12 @@
 /*
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | 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.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Author:                                                              |
   +----------------------------------------------------------------------+
diff --git a/ext/dom/CREDITS b/ext/dom/CREDITS
index 106446a4730b..0c567fca9828 100644
--- a/ext/dom/CREDITS
+++ b/ext/dom/CREDITS
@@ -1,2 +1,2 @@
 DOM
-Christian Stocker, Rob Richards, Marcus Boerger, Niels Dossche
+Christian Stocker, Rob Richards, Marcus Boerger, Nora Dossche
diff --git a/ext/dom/attr.c b/ext/dom/attr.c
index 3107f5a21a2b..aa613a9f6d37 100644
--- a/ext/dom/attr.c
+++ b/ext/dom/attr.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c
index 6d063e19d43e..b735a93f3bee 100644
--- a/ext/dom/cdatasection.c
+++ b/ext/dom/cdatasection.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c
index e6b050a35867..80dce80cf2f0 100644
--- a/ext/dom/characterdata.c
+++ b/ext/dom/characterdata.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/comment.c b/ext/dom/comment.c
index 211d27d2c319..b8ee8780d926 100644
--- a/ext/dom/comment.c
+++ b/ext/dom/comment.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/config.w32 b/ext/dom/config.w32
index e045e29c6bab..e1cbccecf608 100644
--- a/ext/dom/config.w32
+++ b/ext/dom/config.w32
@@ -36,8 +36,7 @@ if (PHP_DOM == "yes") {
 			"dom_ce.h " +
 			"namespace_compat.h " +
 			"xml_common.h " +
-			"xpath_callbacks.h " +
-			"lexbor/selectors-adapted/selectors.h "
+			"xpath_callbacks.h "
 		);
 	} else {
 		WARNING("dom support can't be enabled, libxml is not enabled")
diff --git a/ext/dom/document.c b/ext/dom/document.c
index 9d7213a64df2..bad0dd9feb1b 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
@@ -1672,7 +1670,9 @@ static void dom_document_save_xml(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry
 	}
 
 	if (!res) {
-		php_error_docref(NULL, E_WARNING, "Could not save document");
+		if (!EG(exception)) {
+			php_error_docref(NULL, E_WARNING, "Could not save document");
+		}
 		RETURN_FALSE;
 	} else {
 		RETURN_NEW_STR(res);
@@ -1751,6 +1751,35 @@ static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long fl
 	return err;
 }
 
+/* For modern DOM, namespace declarations are stored as attributes (node->nsDef
+ * is NULL), so libxml's native validators can't resolve prefixed QNames found in
+ * content (e.g. an xs:QName attribute value). Temporarily relink them, mirroring
+ * what C14N does in dom_canonicalization(). */
+typedef struct {
+	HashTable links;
+	bool active;
+} dom_validate_ns_guard;
+
+static void dom_validate_ns_guard_begin(dom_validate_ns_guard *guard, xmlDocPtr docp)
+{
+	guard->active = php_dom_follow_spec_node((const xmlNode *) docp);
+	if (guard->active) {
+		zend_hash_init(&guard->links, 0, NULL, NULL, false);
+		xmlNodePtr root_element = xmlDocGetRootElement(docp);
+		if (root_element) {
+			dom_relink_ns_decls(&guard->links, root_element);
+		}
+	}
+}
+
+static void dom_validate_ns_guard_end(dom_validate_ns_guard *guard)
+{
+	if (guard->active) {
+		dom_unlink_ns_decls(&guard->links);
+		zend_hash_destroy(&guard->links);
+	}
+}
+
 /* {{{ Substitutues xincludes in a DomDocument */
 PHP_METHOD(DOMDocument, xinclude)
 {
@@ -1824,8 +1853,11 @@ PHP_METHOD(DOMDocument, validate)
 	cvp->userData = NULL;
 	cvp->error    = (xmlValidityErrorFunc) php_libxml_error_handler;
 	cvp->warning  = (xmlValidityErrorFunc) php_libxml_error_handler;
-
-	if (xmlValidateDocument(cvp, docp)) {
+	dom_validate_ns_guard guard;
+	dom_validate_ns_guard_begin(&guard, docp);
+	int dtd_valid = xmlValidateDocument(cvp, docp);
+	dom_validate_ns_guard_end(&guard);
+	if (dtd_valid) {
 		RETVAL_TRUE;
 	} else {
 		RETVAL_FALSE;
@@ -1922,7 +1954,10 @@ static void dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
 	PHP_LIBXML_SANITIZE_GLOBALS(validate);
 	xmlSchemaSetValidOptions(vptr, valid_opts);
 	xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+	dom_validate_ns_guard guard;
+	dom_validate_ns_guard_begin(&guard, docp);
 	is_valid = xmlSchemaValidateDoc(vptr, docp);
+	dom_validate_ns_guard_end(&guard);
 	xmlSchemaFree(sptr);
 	xmlSchemaFreeValidCtxt(vptr);
 	PHP_LIBXML_RESTORE_GLOBALS(validate);
@@ -2020,7 +2055,10 @@ static void dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type
 	}
 
 	xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+	dom_validate_ns_guard guard;
+	dom_validate_ns_guard_begin(&guard, docp);
 	is_valid = xmlRelaxNGValidateDoc(vptr, docp);
+	dom_validate_ns_guard_end(&guard);
 	xmlRelaxNGFree(sptr);
 	xmlRelaxNGFreeValidCtxt(vptr);
 
diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c
index 65538b711f2d..01af436c69ed 100644
--- a/ext/dom/documentfragment.c
+++ b/ext/dom/documentfragment.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c
index 958559801a53..03f471493777 100644
--- a/ext/dom/documenttype.c
+++ b/ext/dom/documenttype.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h
index 5106738a0afd..8959d6013c7b 100644
--- a/ext/dom/dom_ce.h
+++ b/ext/dom/dom_ce.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
index 9134b107925a..7566dd8b61a8 100644
--- a/ext/dom/dom_iterators.c
+++ b/ext/dom/dom_iterators.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
@@ -56,7 +54,7 @@ static dom_nnodemap_object *php_dom_iterator_get_nnmap(const php_dom_iterator *i
 	return nnmap->ptr;
 }
 
-xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
+xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
 {
 	xmlEntityPtr ret = xmlMalloc(sizeof(xmlEntity));
 	memset(ret, 0, sizeof(xmlEntity));
@@ -64,18 +62,39 @@ xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const
 	ret->name = xmlStrdup(name);
 	ret->ExternalID = xmlStrdup(ExternalID);
 	ret->SystemID = xmlStrdup(SystemID);
+	if (parent_dtd != NULL) {
+		ret->parent = parent_dtd;
+		ret->doc = parent_dtd->doc;
+	}
 	return (xmlNodePtr) ret;
 }
 /* }}} */
 
-xmlNodePtr php_dom_libxml_hash_iter(xmlHashTable *ht, int index)
+void dom_free_notation(xmlEntityPtr entity) /* {{{ */
+{
+	xmlFree((xmlChar *) entity->name);
+	xmlFree((xmlChar *) entity->ExternalID);
+	xmlFree((xmlChar *) entity->SystemID);
+	xmlFree(entity);
+}
+/* }}} */
+
+xmlNodePtr php_dom_libxml_hash_iter(xmlHashTable *ht, zend_long index)
 {
 	int htsize;
 
+	if (index < 0) {
+		return NULL;
+	}
+	if (UNEXPECTED(ZEND_LONG_INT_OVFL(index))) {
+		zend_value_error("must be between 0 and %d", INT_MAX);
+		return NULL;
+	}
+
 	if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
 		nodeIterator iter;
 		iter.cur = 0;
-		iter.index = index;
+		iter.index = (int) index;
 		iter.node = NULL;
 		xmlHashScan(ht, itemHashScanner, &iter);
 		return iter.node;
diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h
index 53113b04005a..918bf0c62f78 100644
--- a/ext/dom/dom_properties.h
+++ b/ext/dom/dom_properties.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c
index 86eecd579b2b..a7bea009dabc 100644
--- a/ext/dom/domexception.c
+++ b/ext/dom/domexception.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/domexception.h b/ext/dom/domexception.h
index 574e164424d6..3e3c7abed894 100644
--- a/ext/dom/domexception.h
+++ b/ext/dom/domexception.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
index 0737be5fa5c9..e7fc2a414834 100644
--- a/ext/dom/domimplementation.c
+++ b/ext/dom/domimplementation.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/element.c b/ext/dom/element.c
index 4d0099b2c641..2a0aa3a4d0e7 100644
--- a/ext/dom/element.c
+++ b/ext/dom/element.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
@@ -466,7 +464,9 @@ PHP_METHOD(DOMElement, setAttribute)
 					break;
 				case XML_NAMESPACE_DECL:
 					RETURN_FALSE;
-				EMPTY_SWITCH_DEFAULT_CASE();
+				case XML_ATTRIBUTE_DECL:
+					break;
+				default: ZEND_UNREACHABLE();
 			}
 		}
 
@@ -593,7 +593,9 @@ static bool dom_remove_attribute(xmlNodePtr thisp, xmlNodePtr attrp)
 
 			break;
 		}
-		EMPTY_SWITCH_DEFAULT_CASE();
+		case XML_ATTRIBUTE_DECL:
+			return false;
+		default: ZEND_UNREACHABLE();
 	}
 	return true;
 }
@@ -718,11 +720,17 @@ static void dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAMETERS,
 	nsp = attrp->ns;
 	if (use_ns && nsp != NULL) {
 		existattrp = xmlHasNsProp(nodep, attrp->name, nsp->href);
+	} else if (nsp == NULL) {
+		existattrp = xmlHasNsProp(nodep, attrp->name, NULL);
 	} else {
 		existattrp = xmlHasProp(nodep, attrp->name);
 	}
 
-	if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
+	if (existattrp != NULL && existattrp->type == XML_ATTRIBUTE_DECL) {
+		existattrp = NULL;
+	}
+
+	if (existattrp != NULL) {
 		if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
 			((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
 		{
@@ -1819,7 +1827,7 @@ PHP_METHOD(Dom_Element, insertAdjacentHTML)
 			/* Set context to this. */
 			context = thisp;
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	/* 4. If context is not an Element or all of the following are true: (...) */
@@ -1858,7 +1866,7 @@ PHP_METHOD(Dom_Element, insertAdjacentHTML)
 		case ZEND_ENUM_Dom_AdjacentPosition_BeforeEnd:
 			php_dom_node_append(this_intern->document, fragment, thisp);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 err:
@@ -1935,8 +1943,7 @@ PHP_METHOD(DOMElement, toggleAttribute)
 
 	/* Step 5 */
 	if (force_is_null || !force) {
-		dom_remove_attribute(thisp, attribute);
-		retval = false;
+		retval = !dom_remove_attribute(thisp, attribute);
 		goto out;
 	}
 
diff --git a/ext/dom/entity.c b/ext/dom/entity.c
index 3cfcbb5ae808..acccda98de0c 100644
--- a/ext/dom/entity.c
+++ b/ext/dom/entity.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c
index 215df208f530..a669fd2aa791 100644
--- a/ext/dom/entityreference.c
+++ b/ext/dom/entityreference.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c
index d5fe3d5c2773..667db5acb074 100644
--- a/ext/dom/html5_parser.c
+++ b/ext/dom/html5_parser.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
@@ -117,6 +115,7 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
 	php_dom_libxml_ns_mapper *ns_mapper = php_dom_ns_mapper_from_private(private_data);
     xmlNsPtr html_ns = php_dom_libxml_ns_mapper_ensure_html_ns(ns_mapper);
     xmlNsPtr xlink_ns = NULL;
+    xmlNsPtr xml_ns = NULL;
     xmlNsPtr prefixed_xmlns_ns = NULL;
 
     lexbor_array_obj_t work_list;
@@ -256,6 +255,12 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
                         xlink_ns->_private = (void *) php_dom_ns_is_xlink_magic_token;
                     }
                     lxml_attr->ns = xlink_ns;
+                } else if (attr->node.ns == LXB_NS_XML) {
+                    if (xml_ns == NULL) {
+                        xml_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xml", DOM_XML_NS_URI);
+                        xml_ns->_private = (void *) php_dom_ns_is_xml_magic_token;
+                    }
+                    lxml_attr->ns = xml_ns;
                 }
 
                 if (last_added_attr == NULL) {
@@ -455,7 +460,7 @@ static php_libxml_quirks_mode dom_translate_quirks_mode(lxb_dom_document_cmode_t
 		case LXB_DOM_DOCUMENT_CMODE_NO_QUIRKS: return PHP_LIBXML_NO_QUIRKS;
 		case LXB_DOM_DOCUMENT_CMODE_LIMITED_QUIRKS: return PHP_LIBXML_LIMITED_QUIRKS;
 		case LXB_DOM_DOCUMENT_CMODE_QUIRKS: return PHP_LIBXML_QUIRKS;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 }
 
diff --git a/ext/dom/html5_parser.h b/ext/dom/html5_parser.h
index a56166639a60..6824052957aa 100644
--- a/ext/dom/html5_parser.h
+++ b/ext/dom/html5_parser.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c
index 26eef9d5f968..2276a53f14fd 100644
--- a/ext/dom/html5_serializer.c
+++ b/ext/dom/html5_serializer.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/html5_serializer.h b/ext/dom/html5_serializer.h
index 27fd1c92f24f..aeffa67af02a 100644
--- a/ext/dom/html5_serializer.h
+++ b/ext/dom/html5_serializer.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/html_collection.c b/ext/dom/html_collection.c
index a4e2d6ad6fbe..2aed253ab8d3 100644
--- a/ext/dom/html_collection.c
+++ b/ext/dom/html_collection.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/html_collection.h b/ext/dom/html_collection.h
index 59ab50abc1b0..5f9f5948873f 100644
--- a/ext/dom/html_collection.h
+++ b/ext/dom/html_collection.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c
index 954403ca1c5d..ddf8f3f66f80 100644
--- a/ext/dom/html_document.c
+++ b/ext/dom/html_document.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/infra.c b/ext/dom/infra.c
index 9bb1942fe01d..fe7dd97de40d 100644
--- a/ext/dom/infra.c
+++ b/ext/dom/infra.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/infra.h b/ext/dom/infra.h
index d84ad5a2a0ef..890654bcd1c3 100644
--- a/ext/dom/infra.h
+++ b/ext/dom/infra.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/inner_outer_html_mixin.c b/ext/dom/inner_outer_html_mixin.c
index 85124d41689a..2a38e966ad79 100644
--- a/ext/dom/inner_outer_html_mixin.c
+++ b/ext/dom/inner_outer_html_mixin.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
@@ -100,7 +98,9 @@ static zend_string *dom_element_html_fragment_serialize(dom_object *obj, xmlNode
 		}
 		if (UNEXPECTED(status < 0)) {
 			smart_str_free_ex(&str, false);
-			php_dom_throw_error_with_message(SYNTAX_ERR, "The resulting XML serialization is not well-formed", true);
+			if (!EG(exception)) {
+				php_dom_throw_error_with_message(SYNTAX_ERR, "The resulting XML serialization is not well-formed", true);
+			}
 			return NULL;
 		}
 		return smart_str_extract(&str);
@@ -181,7 +181,7 @@ static lxb_dom_document_cmode_t dom_translate_quirks_mode(php_libxml_quirks_mode
 		case PHP_LIBXML_NO_QUIRKS: return LXB_DOM_DOCUMENT_CMODE_NO_QUIRKS;
 		case PHP_LIBXML_LIMITED_QUIRKS: return LXB_DOM_DOCUMENT_CMODE_LIMITED_QUIRKS;
 		case PHP_LIBXML_QUIRKS: return LXB_DOM_DOCUMENT_CMODE_QUIRKS;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 }
 
diff --git a/ext/dom/internal_helpers.h b/ext/dom/internal_helpers.h
index c87ea49c6143..f64ac57fc097 100644
--- a/ext/dom/internal_helpers.h
+++ b/ext/dom/internal_helpers.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/lexbor/selectors-adapted/selectors.c b/ext/dom/lexbor/selectors-adapted/selectors.c
index 0bb285b39e99..242433fb444f 100644
--- a/ext/dom/lexbor/selectors-adapted/selectors.c
+++ b/ext/dom/lexbor/selectors-adapted/selectors.c
@@ -1,9 +1,9 @@
 /*
- * Copyright (C) 2021-2025 Alexander Borisov
+ * Copyright (C) 2021-2026 Alexander Borisov
  *
  * Author: Alexander Borisov 
- * Adapted for PHP + libxml2 by: Niels Dossche 
- * Based on Lexbor (upstream commit 971faf11a5f45433b9193a143e2897d8c0fd5611)
+ * Adapted for PHP + libxml2 by: Nora Dossche  
+ * Based on Lexbor (upstream commit 5291cde0d40f77e7c4ea364b7cd726269e0bf1f9)
  */
 
 #include 
@@ -1356,8 +1356,8 @@ lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors,
 	current = selectors->current;
 
 	if (current->index == 0) {
-		selectors->state = lxb_selectors_state_not_found;
 		selectors->current = selectors->current->parent;
+		lxb_selectors_switch_to_not_found(selectors, selectors->current);
 
 		return selectors->current->entry;
 	}
@@ -1453,7 +1453,7 @@ lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry,
 		case LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT_FUNCTION:
 			return false;
 
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	return false;
@@ -1635,7 +1635,7 @@ lxb_selectors_match_attribute_value(const lxb_css_selector_attribute_t *attr, bo
 
 			return lexbor_str_data_ncmp_contain(trg->data, trg->length,
 												src->data, src->length);
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	return false;
diff --git a/ext/dom/lexbor/selectors-adapted/selectors.h b/ext/dom/lexbor/selectors-adapted/selectors.h
index b64a9e49ee26..b349b24a80b0 100644
--- a/ext/dom/lexbor/selectors-adapted/selectors.h
+++ b/ext/dom/lexbor/selectors-adapted/selectors.h
@@ -2,7 +2,7 @@
  * Copyright (C) 2021-2025 Alexander Borisov
  *
  * Author: Alexander Borisov 
- * Adapted for PHP libxml2 by: Niels Dossche 
+ * Adapted for PHP libxml2 by: Nora Dossche  
  */
 
 
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index 4964f836407c..c6d8157881a3 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/namespace_compat.c b/ext/dom/namespace_compat.c
index ee32ec39dbeb..1815b2dd4413 100644
--- a/ext/dom/namespace_compat.c
+++ b/ext/dom/namespace_compat.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
@@ -61,7 +59,7 @@ static HashTable *php_dom_libxml_ns_mapper_ensure_prefix_map(php_dom_libxml_ns_m
 		zend_hash_add_new(&mapper->uri_to_prefix_map, *uri, &zv_prefix_map);
 	} else {
 		/* cast to Bucket* only works if this holds, I would prefer a static assert but we're stuck at C99. */
-		ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0);
+		ZEND_ASSERT(offsetof(Bucket, val) == 0);
 		ZEND_ASSERT(Z_TYPE_P(zv) == IS_ARRAY);
 		Bucket *bucket = (Bucket *) zv;
 		/* Make sure we take the value from the key string that lives long enough. */
@@ -494,4 +492,142 @@ PHP_DOM_EXPORT void php_dom_in_scope_ns_destroy(php_dom_in_scope_ns *in_scope_ns
 	}
 }
 
+static xmlNsPtr dom_alloc_ns_decl(HashTable *links, xmlNodePtr node)
+{
+	xmlNsPtr ns = xmlMalloc(sizeof(*ns));
+	if (!ns) {
+		return NULL;
+	}
+
+	zval *zv = zend_hash_index_lookup(links, (zend_ulong) node);
+	if (Z_ISNULL_P(zv)) {
+		ZVAL_LONG(zv, 1);
+	} else {
+		Z_LVAL_P(zv)++;
+	}
+
+	memset(ns, 0, sizeof(*ns));
+	ns->type = XML_LOCAL_NAMESPACE;
+	ns->next = node->nsDef;
+	node->nsDef = ns;
+
+	return ns;
+}
+
+/* Mint a temporary nsDef entry so C14N finds namespaces that live on node->ns
+ * but have no matching xmlns attribute (typical for createElementNS). */
+static void dom_add_synthetic_ns_decl(HashTable *links, xmlNodePtr node, xmlNsPtr src_ns)
+{
+	xmlNsPtr ns = dom_alloc_ns_decl(links, node);
+	if (!ns) {
+		return;
+	}
+
+	ns->href = xmlStrdup(src_ns->href);
+	ns->prefix = src_ns->prefix ? xmlStrdup(src_ns->prefix) : NULL;
+}
+
+/* Same, but for attribute namespaces, which may collide by prefix with the
+ * element's own ns or with a sibling attribute's ns. */
+static void dom_add_synthetic_ns_decl_for_attr(HashTable *links, xmlNodePtr node, xmlNsPtr src_ns)
+{
+	for (xmlNsPtr existing = node->nsDef; existing; existing = existing->next) {
+		if (xmlStrEqual(existing->prefix, src_ns->prefix)) {
+			return;
+		}
+	}
+
+	dom_add_synthetic_ns_decl(links, node, src_ns);
+}
+
+static void dom_relink_ns_decls_element(HashTable *links, xmlNodePtr node)
+{
+	if (node->type == XML_ELEMENT_NODE) {
+		for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) {
+			if (php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xmlns_magic_token)) {
+				xmlNsPtr ns = dom_alloc_ns_decl(links, node);
+				if (!ns) {
+					return;
+				}
+
+				bool should_free;
+				xmlChar *attr_value = php_libxml_attr_value(attr, &should_free);
+
+				ns->href = should_free ? attr_value : xmlStrdup(attr_value);
+				ns->prefix = attr->ns->prefix ? xmlStrdup(attr->name) : NULL;
+				ns->_private = attr;
+				if (attr->prev) {
+					attr->prev->next = attr->next;
+				} else {
+					node->properties = attr->next;
+				}
+				if (attr->next) {
+					attr->next->prev = attr->prev;
+				}
+			}
+		}
+
+		/* The default namespace is handled separately from the other namespaces in C14N.
+		 * The default namespace is explicitly looked up while the other namespaces are
+		 * deduplicated and compared to a list of visible namespaces. */
+		if (node->ns && !node->ns->prefix) {
+			/* Workaround for the behaviour where the xmlSearchNs() call inside c14n.c
+			 * can return the current namespace. */
+			zend_hash_index_add_new_ptr(links, (zend_ulong) node | 1, node->ns);
+			node->ns = xmlSearchNs(node->doc, node, NULL);
+		} else if (node->ns) {
+			dom_add_synthetic_ns_decl(links, node, node->ns);
+		}
+
+		for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) {
+			if (attr->ns && !php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xmlns_magic_token)) {
+				dom_add_synthetic_ns_decl_for_attr(links, node, attr->ns);
+			}
+		}
+	}
+}
+
+void dom_relink_ns_decls(HashTable *links, xmlNodePtr root)
+{
+	dom_relink_ns_decls_element(links, root);
+
+	xmlNodePtr base = root;
+	xmlNodePtr node = base->children;
+	while (node != NULL) {
+		dom_relink_ns_decls_element(links, node);
+		node = php_dom_next_in_tree_order(node, base);
+	}
+}
+
+void dom_unlink_ns_decls(HashTable *links)
+{
+	ZEND_HASH_MAP_FOREACH_NUM_KEY_VAL(links, zend_ulong h, zval *data) {
+		if (h & 1) {
+			xmlNodePtr node = (xmlNodePtr) (h ^ 1);
+			node->ns = Z_PTR_P(data);
+		} else {
+			xmlNodePtr node = (xmlNodePtr) h;
+			while (Z_LVAL_P(data)-- > 0) {
+				xmlNsPtr ns = node->nsDef;
+				node->nsDef = ns->next;
+
+				xmlAttrPtr attr = ns->_private;
+				if (attr) {
+					if (attr->prev) {
+						attr->prev->next = attr;
+					} else {
+						node->properties = attr;
+					}
+					if (attr->next) {
+						attr->next->prev = attr;
+					}
+				}
+
+				xmlFreeNs(ns);
+			}
+		}
+	} ZEND_HASH_FOREACH_END();
+}
+
+
 #endif  /* HAVE_LIBXML && HAVE_DOM */
diff --git a/ext/dom/namespace_compat.h b/ext/dom/namespace_compat.h
index 23c80acc7fd7..dac7de88353a 100644
--- a/ext/dom/namespace_compat.h
+++ b/ext/dom/namespace_compat.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/node.c b/ext/dom/node.c
index 19b6c2eeae3b..e0af66227014 100644
--- a/ext/dom/node.c
+++ b/ext/dom/node.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
@@ -138,7 +136,7 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval)
 		case XML_TEXT_NODE:
 			ZVAL_STRING(retval, "#text");
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 
 	return SUCCESS;
@@ -972,7 +970,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
 			xmlAttrPtr lastattr;
 
 			if (child->ns == NULL)
-				lastattr = xmlHasProp(refp->parent, child->name);
+				lastattr = xmlHasNsProp(refp->parent, child->name, NULL);
 			else
 				lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
 			if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
@@ -1019,7 +1017,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
 			xmlAttrPtr lastattr;
 
 			if (child->ns == NULL)
-				lastattr = xmlHasProp(parentp, child->name);
+				lastattr = xmlHasNsProp(parentp, child->name, NULL);
 			else
 				lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
 			if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
@@ -1381,7 +1379,7 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern,
 		xmlAttrPtr lastattr;
 
 		if (child->ns == NULL)
-			lastattr = xmlHasProp(nodep, child->name);
+			lastattr = xmlHasNsProp(nodep, child->name, NULL);
 		else
 			lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
 		if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
@@ -2103,97 +2101,6 @@ PHP_METHOD(DOMNode, lookupNamespaceURI)
 }
 /* }}} end dom_node_lookup_namespace_uri */
 
-static void dom_relink_ns_decls_element(HashTable *links, xmlNodePtr node)
-{
-	if (node->type == XML_ELEMENT_NODE) {
-		for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) {
-			if (php_dom_ns_is_fast((const xmlNode *) attr, php_dom_ns_is_xmlns_magic_token)) {
-				xmlNsPtr ns = xmlMalloc(sizeof(*ns));
-				if (!ns) {
-					return;
-				}
-
-				zval *zv = zend_hash_index_lookup(links, (zend_ulong) node);
-				if (Z_ISNULL_P(zv)) {
-					ZVAL_LONG(zv, 1);
-				} else {
-					Z_LVAL_P(zv)++;
-				}
-
-				bool should_free;
-				xmlChar *attr_value = php_libxml_attr_value(attr, &should_free);
-
-				memset(ns, 0, sizeof(*ns));
-				ns->type = XML_LOCAL_NAMESPACE;
-				ns->href = should_free ? attr_value : xmlStrdup(attr_value);
-				ns->prefix = attr->ns->prefix ? xmlStrdup(attr->name) : NULL;
-				ns->next = node->nsDef;
-				node->nsDef = ns;
-
-				ns->_private = attr;
-				if (attr->prev) {
-					attr->prev = attr->next;
-				} else {
-					node->properties = attr->next;
-				}
-				if (attr->next) {
-					attr->next->prev = attr->prev;
-				}
-			}
-		}
-
-		/* The default namespace is handled separately from the other namespaces in C14N.
-		 * The default namespace is explicitly looked up while the other namespaces are
-		 * deduplicated and compared to a list of visible namespaces. */
-		if (node->ns && !node->ns->prefix) {
-			/* Workaround for the behaviour where the xmlSearchNs() call inside c14n.c
-			 * can return the current namespace. */
-			zend_hash_index_add_new_ptr(links, (zend_ulong) node | 1, node->ns);
-			node->ns = xmlSearchNs(node->doc, node, NULL);
-		}
-	}
-}
-
-static void dom_relink_ns_decls(HashTable *links, xmlNodePtr root)
-{
-	dom_relink_ns_decls_element(links, root);
-
-	xmlNodePtr base = root;
-	xmlNodePtr node = base->children;
-	while (node != NULL) {
-		dom_relink_ns_decls_element(links, node);
-		node = php_dom_next_in_tree_order(node, base);
-	}
-}
-
-static void dom_unlink_ns_decls(HashTable *links)
-{
-	ZEND_HASH_MAP_FOREACH_NUM_KEY_VAL(links, zend_ulong h, zval *data) {
-		if (h & 1) {
-			xmlNodePtr node = (xmlNodePtr) (h ^ 1);
-			node->ns = Z_PTR_P(data);
-		} else {
-			xmlNodePtr node = (xmlNodePtr) h;
-			while (Z_LVAL_P(data)-- > 0) {
-				xmlNsPtr ns = node->nsDef;
-				node->nsDef = ns->next;
-
-				xmlAttrPtr attr = ns->_private;
-				if (attr->prev) {
-					attr->prev->next = attr;
-				} else {
-					node->properties = attr;
-				}
-				if (attr->next) {
-					attr->next->prev = attr;
-				}
-
-				xmlFreeNs(ns);
-			}
-		}
-	} ZEND_HASH_FOREACH_END();
-}
-
 static int dom_canonicalize_node_parent_lookup_cb(void *user_data, xmlNodePtr node, xmlNodePtr parent)
 {
 	xmlNodePtr root = user_data;
@@ -2263,7 +2170,11 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
 		}
 
 		zend_hash_init(&links, 0, NULL, NULL, false);
-		dom_relink_ns_decls(&links, xmlDocGetRootElement(docp));
+		xmlNodePtr root_element = xmlDocGetRootElement(docp);
+
+		if (root_element) {
+			dom_relink_ns_decls(&links, root_element);
+		}
 	} else if (!docp) {
 		/* Note: not triggerable with modern DOM */
 		zend_throw_error(NULL, "Node must be associated with a document");
diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c
index 5e3de728e4fa..197ff3ceb880 100644
--- a/ext/dom/nodelist.c
+++ b/ext/dom/nodelist.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/nodelist.h b/ext/dom/nodelist.h
index 5c5653eea6dc..3e60c4daa023 100644
--- a/ext/dom/nodelist.h
+++ b/ext/dom/nodelist.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/notation.c b/ext/dom/notation.c
index f83b31428e16..73d0d6b083a5 100644
--- a/ext/dom/notation.c
+++ b/ext/dom/notation.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/obj_map.c b/ext/dom/obj_map.c
index 84fae3bad572..4d6479e003f9 100644
--- a/ext/dom/obj_map.c
+++ b/ext/dom/obj_map.c
@@ -1,18 +1,16 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
-   |          Niels Dossche                             |
+   |          Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
@@ -178,7 +176,8 @@ static void dom_map_get_notation_item(dom_nnodemap_object *map, zend_long index,
 	xmlNodePtr node = map->ht ? php_dom_libxml_hash_iter(map->ht, index) : NULL;
 	if (node) {
 		xmlNotation *notation = (xmlNotation *) node;
-		node = create_notation(notation->name, notation->PublicID, notation->SystemID);
+		xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
+		node = create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
 	}
 	dom_ret_node_to_zobj(map, node, return_value);
 }
@@ -346,22 +345,20 @@ static void dom_map_get_by_class_name_item(dom_nnodemap_object *map, zend_long i
 	if (nodep && index >= 0) {
 		dom_node_idx_pair start_point = dom_obj_map_get_start_point(map, nodep, index);
 		if (start_point.node) {
-			if (start_point.index > 0) {
-				/* Only start iteration at next point if we actually have an index to seek to. */
-				itemnode = php_dom_next_in_tree_order(start_point.node, nodep);
-			} else {
-				itemnode = start_point.node;
-			}
+			itemnode = start_point.node;
 		} else {
 			itemnode = php_dom_first_child_of_container_node(nodep);
+			while (itemnode != NULL && !dom_matches_class_name(map, itemnode)) {
+				itemnode = php_dom_next_in_tree_order(itemnode, nodep);
+			}
 		}
 
-		do {
-			--start_point.index;
+		for (; start_point.index > 0 && itemnode != NULL; --start_point.index) {
+			itemnode = php_dom_next_in_tree_order(itemnode, nodep);
 			while (itemnode != NULL && !dom_matches_class_name(map, itemnode)) {
 				itemnode = php_dom_next_in_tree_order(itemnode, nodep);
 			}
-		} while (start_point.index > 0 && itemnode);
+		}
 	}
 	dom_ret_node_to_zobj(map, itemnode, return_value);
 	if (itemnode) {
@@ -506,7 +503,8 @@ static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, c
 {
 	xmlNotationPtr notation = xmlHashLookup(map->ht, BAD_CAST ZSTR_VAL(named));
 	if (notation) {
-		return create_notation(notation->name, notation->PublicID, notation->SystemID);
+		xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
+		return create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
 	}
 	return NULL;
 }
diff --git a/ext/dom/obj_map.h b/ext/dom/obj_map.h
index e7231eb7b10a..f6306fc4ab91 100644
--- a/ext/dom/obj_map.h
+++ b/ext/dom/obj_map.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/parentnode/css_selectors.c b/ext/dom/parentnode/css_selectors.c
index 4f77359835ce..0fc0cc1ef0f6 100644
--- a/ext/dom/parentnode/css_selectors.c
+++ b/ext/dom/parentnode/css_selectors.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/parentnode/tree.c b/ext/dom/parentnode/tree.c
index c51bd2753cd8..13a99023781f 100644
--- a/ext/dom/parentnode/tree.c
+++ b/ext/dom/parentnode/tree.c
@@ -1,17 +1,15 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Benjamin Eberlei                          |
-   |          Niels Dossche                             |
+   |          Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 57fa5e71f6bc..eccbe4ed2984 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
@@ -414,11 +412,6 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo
 	const dom_prop_handler *hnd = dom_get_prop_handler(obj, name, cache_slot);
 
 	if (hnd) {
-		if (UNEXPECTED(!hnd->write_func)) {
-			zend_readonly_property_modification_error_ex(ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
-			return &EG(error_zval);
-		}
-
 		zend_property_info *prop = NULL;
 		if (cache_slot) {
 			ZEND_ASSERT(*cache_slot == obj->prop_handler);
@@ -431,6 +424,16 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo
 			}
 		}
 
+		if (UNEXPECTED(!hnd->write_func)) {
+			if (prop && (prop->flags & ZEND_ACC_PPP_SET_MASK) &&
+			    !zend_asymmetric_property_has_set_access(prop)) {
+				zend_asymmetric_visibility_property_modification_error(prop, "modify");
+			} else {
+				zend_readonly_property_modification_error_ex(ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
+			}
+			return &EG(error_zval);
+		}
+
 		ZEND_ASSERT(prop && ZEND_TYPE_IS_SET(prop->type));
 		zval tmp;
 		ZVAL_COPY(&tmp, value);
@@ -789,7 +792,7 @@ HashTable *dom_xpath_get_gc(zend_object *object, zval **table, int *n);
 PHP_MINIT_FUNCTION(dom)
 {
 	memcpy(&dom_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
-	dom_object_handlers.offset = XtOffsetOf(dom_object, std);
+	dom_object_handlers.offset = offsetof(dom_object, std);
 	dom_object_handlers.free_obj = dom_objects_free_storage;
 	dom_object_handlers.read_property = dom_read_property;
 	dom_object_handlers.write_property = dom_write_property;
@@ -834,12 +837,12 @@ PHP_MINIT_FUNCTION(dom)
 	dom_html_collection_object_handlers.get_gc = dom_html_collection_get_gc;
 
 	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);
+	dom_object_namespace_node_handlers.offset = offsetof(dom_object_namespace_node, dom.std);
 	dom_object_namespace_node_handlers.free_obj = dom_object_namespace_node_free_storage;
 	dom_object_namespace_node_handlers.clone_obj = dom_object_namespace_node_clone_obj;
 
 	memcpy(&dom_token_list_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
-	dom_token_list_object_handlers.offset = XtOffsetOf(dom_token_list_object, dom.std);
+	dom_token_list_object_handlers.offset = offsetof(dom_token_list_object, dom.std);
 	dom_token_list_object_handlers.free_obj = dom_token_list_free_obj;
 	/* The Web IDL (Web Interface Description Language - https://webidl.spec.whatwg.org) has the [SameObject] constraint
 	 * for this object, which is incompatible with cloning because it imposes that there is only one instance
@@ -1330,7 +1333,7 @@ PHP_MINIT_FUNCTION(dom)
 
 #ifdef LIBXML_XPATH_ENABLED
 	memcpy(&dom_xpath_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
-	dom_xpath_object_handlers.offset = XtOffsetOf(dom_xpath_object, dom) + XtOffsetOf(dom_object, std);
+	dom_xpath_object_handlers.offset = offsetof(dom_xpath_object, dom) + offsetof(dom_object, std);
 	dom_xpath_object_handlers.free_obj = dom_xpath_objects_free_storage;
 	dom_xpath_object_handlers.get_gc = dom_xpath_get_gc;
 	dom_xpath_object_handlers.clone_obj = NULL;
@@ -1483,7 +1486,13 @@ void dom_objects_free_storage(zend_object *object)
 	if (ptr != NULL && ptr->node != NULL) {
 		xmlNodePtr node = ptr->node;
 
-		if (node->type != XML_DOCUMENT_NODE && node->type != XML_HTML_DOCUMENT_NODE) {
+		if (node->type == XML_NOTATION_NODE) {
+			unsigned int refcount = php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
+			php_libxml_decrement_doc_ref((php_libxml_node_object *) intern);
+			if (refcount == 0) {
+				dom_free_notation((xmlEntityPtr) node);
+			}
+		} else if (node->type != XML_DOCUMENT_NODE && node->type != XML_HTML_DOCUMENT_NODE) {
 			php_libxml_node_decrement_resource((php_libxml_node_object *) intern);
 		} else {
 			php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
@@ -1496,7 +1505,7 @@ void dom_objects_free_storage(zend_object *object)
 
 static void dom_objects_set_class_ex(zend_class_entry *class_type, dom_object *intern)
 {
-	zend_class_entry *base_class = class_type;
+	const zend_class_entry *base_class = class_type;
 	while ((base_class->type != ZEND_INTERNAL_CLASS || base_class->info.internal.module->module_number != dom_module_entry.module_number) && base_class->parent != NULL) {
 		base_class = base_class->parent;
 	}
@@ -1561,7 +1570,7 @@ zend_object *dom_xpath_objects_new(zend_class_entry *class_type)
 
 /* The char pointer MUST refer to the char* of a zend_string struct */
 static void dom_zend_string_release_from_char_pointer(xmlChar *ptr) {
-	zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val)));
+	zend_string_release((zend_string*) (ptr - offsetof(zend_string, val)));
 }
 
 void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
index e93000044f00..6f4b5075b659 100644
--- a/ext/dom/php_dom.h
+++ b/ext/dom/php_dom.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards 							  |
@@ -70,7 +68,7 @@ typedef struct dom_xpath_object {
 
 static inline dom_xpath_object *php_xpath_obj_from_obj(zend_object *obj) {
 	return (dom_xpath_object*)((char*)(obj)
-		- XtOffsetOf(dom_xpath_object, dom) - XtOffsetOf(dom_object, std));
+		- offsetof(dom_xpath_object, dom) - offsetof(dom_object, std));
 }
 
 #define Z_XPATHOBJ_P(zv)  php_xpath_obj_from_obj(Z_OBJ_P((zv)))
@@ -96,7 +94,7 @@ struct php_dom_libxml_ns_mapper;
 typedef struct php_dom_libxml_ns_mapper php_dom_libxml_ns_mapper;
 
 static inline dom_object_namespace_node *php_dom_namespace_node_obj_from_obj(zend_object *obj) {
-	return (dom_object_namespace_node*)((char*)(obj) - XtOffsetOf(dom_object_namespace_node, dom.std));
+	return (dom_object_namespace_node*)((char*)(obj) - offsetof(dom_object_namespace_node, dom.std));
 }
 
 #include "domexception.h"
@@ -127,8 +125,9 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
 bool dom_has_feature(zend_string *feature, zend_string *version);
 bool dom_node_is_read_only(const xmlNode *node);
 bool dom_node_children_valid(const xmlNode *node);
-xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
-xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
+xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
+void dom_free_notation(xmlEntityPtr entity);
+xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, zend_long index);
 zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
 void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce);
 xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern);
@@ -162,6 +161,12 @@ void dom_set_document_ref_pointers_attr(xmlAttrPtr attr, php_libxml_ref_obj *doc
 
 /* Prop getters by offset */
 zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name);
+/* Temporarily materialize namespace declarations as nsDef entries on the tree so
+ * that libxml's native validators/canonicalizers can resolve prefixed QNames that
+ * appear in element/attribute *content*. Modern DOM keeps declarations off the
+ * tree (node->nsDef == NULL), which xmlSearchNs() cannot follow. Internal only. */
+void dom_relink_ns_decls(HashTable *links, xmlNodePtr root);
+void dom_unlink_ns_decls(HashTable *links);
 zval *dom_element_class_list_zval(dom_object *obj);
 zval *dom_parent_node_children(dom_object *obj);
 
diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php
index 71aa5f4ec0fa..521e3cd99c2e 100644
--- a/ext/dom/php_dom.stub.php
+++ b/ext/dom/php_dom.stub.php
@@ -237,41 +237,23 @@
 
     class DOMDocumentType extends DOMNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $name;
+        /** @virtual */
+        public private(set) string $name;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DOMNamedNodeMap $entities;
+        /** @virtual */
+        public private(set) DOMNamedNodeMap $entities;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DOMNamedNodeMap $notations;
+        /** @virtual */
+        public private(set) DOMNamedNodeMap $notations;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $publicId;
+        /** @virtual */
+        public private(set) string $publicId;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $systemId;
+        /** @virtual */
+        public private(set) string $systemId;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $internalSubset;
+        /** @virtual */
+        public private(set) ?string $internalSubset;
     }
 
     class DOMCdataSection extends DOMText
@@ -319,101 +301,56 @@ class DOMNode
         public const int DOCUMENT_POSITION_CONTAINED_BY = 0x10;
         public const int DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $nodeName;
+        /** @virtual */
+        public private(set) string $nodeName;
 
         /** @virtual */
         public ?string $nodeValue;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $nodeType;
+        /** @virtual */
+        public private(set) int $nodeType;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $parentNode;
+        /** @virtual */
+        public private(set) ?DOMNode $parentNode;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $parentElement;
+        /** @virtual */
+        public private(set) ?DOMElement $parentElement;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DOMNodeList $childNodes;
+        /** @virtual */
+        public private(set) DOMNodeList $childNodes;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $firstChild;
+        /** @virtual */
+        public private(set) ?DOMNode $firstChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $lastChild;
+        /** @virtual */
+        public private(set) ?DOMNode $lastChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $previousSibling;
+        /** @virtual */
+        public private(set) ?DOMNode $previousSibling;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $nextSibling;
+        /** @virtual */
+        public private(set) ?DOMNode $nextSibling;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNamedNodeMap $attributes;
+        /** @virtual */
+        public private(set) ?DOMNamedNodeMap $attributes;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public bool $isConnected;
+        /** @virtual */
+        public private(set) bool $isConnected;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMDocument $ownerDocument;
+        /** @virtual */
+        public private(set) ?DOMDocument $ownerDocument;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $namespaceURI;
+        /** @virtual */
+        public private(set) ?string $namespaceURI;
 
         /** @virtual */
         public string $prefix;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $localName;
+        /** @virtual */
+        public private(set) ?string $localName;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $baseURI;
+        /** @virtual */
+        public private(set) ?string $baseURI;
 
         /** @virtual */
         public string $textContent;
@@ -484,65 +421,35 @@ public function __wakeup(): void {}
 
     class DOMNameSpaceNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $nodeName;
+        /** @virtual */
+        public private(set) string $nodeName;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $nodeValue;
+        /** @virtual */
+        public private(set) ?string $nodeValue;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $nodeType;
+        /** @virtual */
+        public private(set) int $nodeType;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $prefix;
+        /** @virtual */
+        public private(set) string $prefix;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $localName;
+        /** @virtual */
+        public private(set) ?string $localName;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $namespaceURI;
+        /** @virtual */
+        public private(set) ?string $namespaceURI;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public bool $isConnected;
+        /** @virtual */
+        public private(set) bool $isConnected;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMDocument $ownerDocument;
+        /** @virtual */
+        public private(set) ?DOMDocument $ownerDocument;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMNode $parentNode;
+        /** @virtual */
+        public private(set) ?DOMNode $parentNode;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $parentElement;
+        /** @virtual */
+        public private(set) ?DOMElement $parentElement;
 
         /** @implementation-alias DOMNode::__sleep */
         public function __sleep(): array {}
@@ -565,23 +472,14 @@ public function createDocument(?string $namespace = null, string $qualifiedName
 
     class DOMDocumentFragment extends DOMNode implements DOMParentNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $firstElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $firstElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $lastElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $lastElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $childElementCount;
+        /** @virtual */
+        public private(set) int $childElementCount;
 
         public function __construct() {}
 
@@ -609,11 +507,8 @@ public function replaceChildren(...$nodes): void {}
 
     class DOMNodeList implements IteratorAggregate, Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @tentative-return-type */
         public function count(): int {}
@@ -629,23 +524,14 @@ class DOMCharacterData extends DOMNode implements DOMChildNode
         /** @virtual */
         public string $data;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $previousElementSibling;
+        /** @virtual */
+        public private(set) ?DOMElement $previousElementSibling;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $nextElementSibling;
+        /** @virtual */
+        public private(set) ?DOMElement $nextElementSibling;
 
         /** @tentative-return-type */
         public function appendData(string $data): true {}
@@ -686,32 +572,20 @@ public function after(...$nodes): void {}
 
     class DOMAttr extends DOMNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $name;
+        /** @virtual */
+        public private(set) string $name;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public bool $specified;
+        /** @virtual */
+        public private(set) bool $specified;
 
         /** @virtual */
         public string $value;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $ownerElement;
+        /** @virtual */
+        public private(set) ?DOMElement $ownerElement;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public mixed $schemaTypeInfo;
+        /** @virtual */
+        public private(set) mixed $schemaTypeInfo;
 
         public function __construct(string $name, string $value = "") {}
 
@@ -721,11 +595,8 @@ public function isId(): bool {}
 
     class DOMElement extends DOMNode implements \DOMParentNode, \DOMChildNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $tagName;
+        /** @virtual */
+        public private(set) string $tagName;
 
         /** @virtual */
         public string $className;
@@ -733,41 +604,23 @@ class DOMElement extends DOMNode implements \DOMParentNode, \DOMChildNode
         /** @virtual */
         public string $id;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public mixed $schemaTypeInfo;
+        /** @virtual */
+        public private(set) mixed $schemaTypeInfo;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $firstElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $firstElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $lastElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $lastElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $childElementCount;
+        /** @virtual */
+        public private(set) int $childElementCount;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $previousElementSibling;
+        /** @virtual */
+        public private(set) ?DOMElement $previousElementSibling;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $nextElementSibling;
+        /** @virtual */
+        public private(set) ?DOMElement $nextElementSibling;
 
         public function __construct(string $qualifiedName, ?string $value = null, string $namespace = "") {}
 
@@ -856,39 +709,26 @@ public function insertAdjacentText(string $where, string $data): void {}
 
     class DOMDocument extends DOMNode implements DOMParentNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMDocumentType $doctype;
+        /** @virtual */
+        public private(set) ?DOMDocumentType $doctype;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DOMImplementation $implementation;
+        /** @virtual */
+        public private(set) DOMImplementation $implementation;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $documentElement;
+        /** @virtual */
+        public private(set) ?DOMElement $documentElement;
 
         /**
-         * @readonly
          * @deprecated
          * @virtual
          */
-        public ?string $actualEncoding;
+        public private(set) ?string $actualEncoding;
 
         /** @virtual */
         public ?string $encoding;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $xmlEncoding;
+        /** @virtual */
+        public private(set) ?string $xmlEncoding;
 
         /** @virtual */
         public bool $standalone;
@@ -909,11 +749,10 @@ class DOMDocument extends DOMNode implements DOMParentNode
         public ?string $documentURI;
 
         /**
-         * @readonly
          * @deprecated
          * @virtual
          */
-        public mixed $config;
+        public private(set) mixed $config;
 
         /** @virtual */
         public bool $formatOutput;
@@ -933,23 +772,14 @@ class DOMDocument extends DOMNode implements DOMParentNode
         /** @virtual */
         public bool $substituteEntities;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $firstElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $firstElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DOMElement $lastElementChild;
+        /** @virtual */
+        public private(set) ?DOMElement $lastElementChild;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $childElementCount;
+        /** @virtual */
+        public private(set) int $childElementCount;
 
         public function __construct(string $version = "1.0", string $encoding = "") {}
 
@@ -1082,11 +912,8 @@ final class DOMException extends Exception
 
     class DOMText extends DOMCharacterData
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $wholeText;
+        /** @virtual */
+        public private(set) string $wholeText;
 
         public function __construct(string $data = "") {}
 
@@ -1105,11 +932,8 @@ public function splitText(int $offset) {}
 
     class DOMNamedNodeMap implements IteratorAggregate, Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @tentative-return-type */
         public function getNamedItem(string $qualifiedName): ?DOMNode {}
@@ -1128,44 +952,32 @@ public function getIterator(): Iterator {}
 
     class DOMEntity extends DOMNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $publicId;
+        /** @virtual */
+        public private(set) ?string $publicId;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $systemId;
+        /** @virtual */
+        public private(set) ?string $systemId;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $notationName;
+        /** @virtual */
+        public private(set) ?string $notationName;
 
         /**
-         * @readonly
          * @deprecated
          * @virtual
          */
-        public ?string $actualEncoding;
+        public private(set) ?string $actualEncoding;
 
         /**
-         * @readonly
          * @deprecated
          * @virtual
          */
-        public ?string $encoding;
+        public private(set) ?string $encoding;
 
         /**
-         * @readonly
          * @deprecated
          * @virtual
          */
-        public ?string $version;
+        public private(set) ?string $version;
     }
 
     class DOMEntityReference extends DOMNode
@@ -1175,26 +987,17 @@ public function __construct(string $name) {}
 
     class DOMNotation extends DOMNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $publicId;
+        /** @virtual */
+        public private(set) string $publicId;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $systemId;
+        /** @virtual */
+        public private(set) string $systemId;
     }
 
     class DOMProcessingInstruction extends DOMNode
-    {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $target;
+    {
+        /** @virtual */
+        public private(set) string $target;
 
         /** @virtual */
         public string $data;
@@ -1206,11 +1009,8 @@ public function __construct(string $name, string $value = "") {}
     /** @not-serializable */
     class DOMXPath
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DOMDocument $document;
+        /** @virtual */
+        public private(set) DOMDocument $document;
 
         /** @virtual */
         public bool $registerNodeNamespaces;
@@ -1358,73 +1158,37 @@ class Node
     {
         private final function __construct() {}
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $nodeType;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $nodeName;
+        /** @virtual */
+        public private(set) int $nodeType;
+        /** @virtual */
+        public private(set) string $nodeName;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $baseURI;
+        /** @virtual */
+        public private(set) string $baseURI;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public bool $isConnected;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Document $ownerDocument;
+        /** @virtual */
+        public private(set) bool $isConnected;
+        /** @virtual */
+        public private(set) ?Document $ownerDocument;
 
         /** @implementation-alias DOMNode::getRootNode */
         public function getRootNode(array $options = []): Node {}
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Node $parentNode;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $parentElement;
+        /** @virtual */
+        public private(set) ?Node $parentNode;
+        /** @virtual */
+        public private(set) ?Element $parentElement;
         /** @implementation-alias DOMNode::hasChildNodes */
         public function hasChildNodes(): bool {}
-        /**
-         * @readonly
-         * @virtual
-         */
-        public NodeList $childNodes;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Node $firstChild;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Node $lastChild;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Node $previousSibling;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Node $nextSibling;
+        /** @virtual */
+        public private(set) NodeList $childNodes;
+        /** @virtual */
+        public private(set) ?Node $firstChild;
+        /** @virtual */
+        public private(set) ?Node $lastChild;
+        /** @virtual */
+        public private(set) ?Node $previousSibling;
+        /** @virtual */
+        public private(set) ?Node $nextSibling;
 
         /** @virtual */
         public ?string $nodeValue;
@@ -1474,11 +1238,8 @@ public function __wakeup(): void {}
 
     class NodeList implements \IteratorAggregate, \Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @implementation-alias DOMNodeList::count */
         public function count(): int {}
@@ -1492,11 +1253,8 @@ public function item(int $index): ?Node {}
 
     class NamedNodeMap implements \IteratorAggregate, \Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @implementation-alias DOMNamedNodeMap::item */
         public function item(int $index): ?Attr {}
@@ -1514,11 +1272,8 @@ public function getIterator(): \Iterator {}
 
     class DtdNamedNodeMap implements \IteratorAggregate, \Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @implementation-alias DOMNamedNodeMap::item */
         public function item(int $index): Entity|Notation|null {}
@@ -1536,11 +1291,8 @@ public function getIterator(): \Iterator {}
 
     class HTMLCollection implements \IteratorAggregate, \Countable
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
 
         /** @implementation-alias DOMNodeList::item */
         public function item(int $index): ?Element {}
@@ -1564,71 +1316,37 @@ enum AdjacentPosition : string
 
     class Element extends Node implements ParentNode, ChildNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $namespaceURI;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $prefix;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $localName;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $tagName;
+        /** @virtual */
+        public private(set) ?string $namespaceURI;
+        /** @virtual */
+        public private(set) ?string $prefix;
+        /** @virtual */
+        public private(set) string $localName;
+        /** @virtual */
+        public private(set) 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;
+        public private(set) HTMLCollection $children;
+        /** @virtual */
+        public private(set) ?Element $firstElementChild;
+        /** @virtual */
+        public private(set) ?Element $lastElementChild;
+        /** @virtual */
+        public private(set) int $childElementCount;
+        /** @virtual */
+        public private(set) ?Element $previousElementSibling;
+        /** @virtual */
+        public private(set) ?Element $nextElementSibling;
 
         /** @virtual */
         public string $id;
         /** @virtual */
         public string $className;
-        /** @readonly */
-        public TokenList $classList;
+        public private(set) TokenList $classList;
 
         /** @implementation-alias DOMNode::hasAttributes */
         public function hasAttributes(): bool {}
-        /**
-         * @readonly
-         * @virtual
-         */
-        public NamedNodeMap $attributes;
+        /** @virtual */
+        public private(set) NamedNodeMap $attributes;
         /** @implementation-alias DOMElement::getAttributeNames */
         public function getAttributeNames(): array {}
         /** @implementation-alias DOMElement::getAttribute */
@@ -1716,40 +1434,22 @@ class HTMLElement extends Element
 
     class Attr extends Node
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $namespaceURI;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $prefix;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $localName;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $name;
+        /** @virtual */
+        public private(set) ?string $namespaceURI;
+        /** @virtual */
+        public private(set) ?string $prefix;
+        /** @virtual */
+        public private(set) string $localName;
+        /** @virtual */
+        public private(set) string $name;
         /** @virtual */
         public string $value;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $ownerElement;
+        /** @virtual */
+        public private(set) ?Element $ownerElement;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public bool $specified;
+        /** @virtual */
+        public private(set) bool $specified;
 
         /** @implementation-alias DOMAttr::isId */
         public function isId(): bool {}
@@ -1760,24 +1460,15 @@ public function rename(?string $namespaceURI, string $qualifiedName): void {}
 
     class CharacterData extends Node implements ChildNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $previousElementSibling;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $nextElementSibling;
+        /** @virtual */
+        public private(set) ?Element $previousElementSibling;
+        /** @virtual */
+        public private(set) ?Element $nextElementSibling;
 
         /** @virtual */
         public string $data;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
         /** @implementation-alias DOMCharacterData::substringData */
         public function substringData(int $offset, int $count): string {}
         public function appendData(string $data): void {}
@@ -1801,22 +1492,16 @@ class Text extends CharacterData
 
         /** @implementation-alias DOMText::splitText */
         public function splitText(int $offset): Text {}
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $wholeText;
+        /** @virtual */
+        public private(set) string $wholeText;
     }
 
     class CDATASection extends Text {}
 
     class ProcessingInstruction extends CharacterData
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $target;
+        /** @virtual */
+        public private(set) string $target;
     }
 
     class Comment extends CharacterData
@@ -1826,36 +1511,18 @@ class Comment extends CharacterData
 
     class DocumentType extends Node implements ChildNode
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $name;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DtdNamedNodeMap $entities;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public DtdNamedNodeMap $notations;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $publicId;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $systemId;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $internalSubset;
+        /** @virtual */
+        public private(set) string $name;
+        /** @virtual */
+        public private(set) DtdNamedNodeMap $entities;
+        /** @virtual */
+        public private(set) DtdNamedNodeMap $notations;
+        /** @virtual */
+        public private(set) string $publicId;
+        /** @virtual */
+        public private(set) string $systemId;
+        /** @virtual */
+        public private(set) ?string $internalSubset;
 
         /** @implementation-alias DOMElement::remove */
         public function remove(): void {}
@@ -1869,25 +1536,13 @@ public function replaceWith(Node|string ...$nodes): void {}
 
     class DocumentFragment extends Node implements ParentNode
     {
-        /**
-         * @readonly
-         */
-        public HTMLCollection $children;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $firstElementChild;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $lastElementChild;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $childElementCount;
+        public private(set) HTMLCollection $children;
+        /** @virtual */
+        public private(set) ?Element $firstElementChild;
+        /** @virtual */
+        public private(set) ?Element $lastElementChild;
+        /** @virtual */
+        public private(set) int $childElementCount;
 
         /** @implementation-alias DOMDocumentFragment::appendXML */
         public function appendXml(string $data): bool {}
@@ -1906,63 +1561,35 @@ public function querySelectorAll(string $selectors): NodeList {}
 
     class Entity extends Node
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $publicId;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $systemId;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?string $notationName;
+        /** @virtual */
+        public private(set) ?string $publicId;
+        /** @virtual */
+        public private(set) ?string $systemId;
+        /** @virtual */
+        public private(set) ?string $notationName;
     }
 
     class EntityReference extends Node {}
 
     class Notation extends Node
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $publicId;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $systemId;
+        /** @virtual */
+        public private(set) string $publicId;
+        /** @virtual */
+        public private(set) string $systemId;
     }
 
     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;
+        public private(set) HTMLCollection $children;
+        /** @virtual */
+        public private(set) ?Element $firstElementChild;
+        /** @virtual */
+        public private(set) ?Element $lastElementChild;
+        /** @virtual */
+        public private(set) int $childElementCount;
 
-        /** @readonly */
-        public Implementation $implementation;
+        public private(set) Implementation $implementation;
         /** @virtual */
         public string $URL;
         /** @virtual */
@@ -1974,16 +1601,10 @@ abstract class Document extends Node implements ParentNode
         /** @virtual */
         public string $inputEncoding;
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?DocumentType $doctype;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?Element $documentElement;
+        /** @virtual */
+        public private(set) ?DocumentType $doctype;
+        /** @virtual */
+        public private(set) ?Element $documentElement;
         /** @implementation-alias Dom\Element::getElementsByTagName */
         public function getElementsByTagName(string $qualifiedName): HTMLCollection {}
         /** @implementation-alias Dom\Element::getElementsByTagNameNS */
@@ -2043,11 +1664,8 @@ public function querySelectorAll(string $selectors): NodeList {}
 
         /** @virtual */
         public ?HTMLElement $body;
-        /**
-         * @readonly
-         * @virtual
-         */
-        public ?HTMLElement $head;
+        /** @virtual */
+        public private(set) ?HTMLElement $head;
         /** @virtual */
         public string $title;
     }
@@ -2083,11 +1701,8 @@ public static function createFromFile(string $path, int $options = 0, ?string $o
 
         public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): XMLDocument {}
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public string $xmlEncoding;
+        /** @virtual */
+        public private(set) string $xmlEncoding;
 
         /** @virtual */
         public bool $xmlStandalone;
@@ -2121,11 +1736,8 @@ final class TokenList implements \IteratorAggregate, \Countable
         /** @implementation-alias Dom\Node::__construct */
         private function __construct() {}
 
-        /**
-         * @readonly
-         * @virtual
-         */
-        public int $length;
+        /** @virtual */
+        public private(set) int $length;
         public function item(int $index): ?string {}
         public function contains(string $token): bool {}
         public function add(string ...$tokens): void {}
@@ -2159,11 +1771,8 @@ private function __construct() {}
     /** @not-serializable */
     final class XPath
     {
-        /**
-         * @readonly
-         * @virtual
-         */
-        public Document $document;
+        /** @virtual */
+        public private(set) Document $document;
 
         /** @virtual */
         public bool $registerNodeNamespaces;
diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h
index 1c90f920cdd8..0274186380dc 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 php_dom.stub.php instead.
- * Stub hash: e00668999f4fe9afee1f78f6986467a315f831a5
+ * Stub hash: 8d7713834c924709155ed7acc554c9efc55e96c1
  * Has decl header: yes */
 
 ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_dom_import_simplexml, 0, 1, DOMAttr|DOMElement, 0)
@@ -1887,38 +1887,38 @@ static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_
 
 	zval property_name_default_value;
 	ZVAL_UNDEF(&property_name_default_value);
-	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 
 	zval property_entities_default_value;
 	ZVAL_UNDEF(&property_entities_default_value);
 	zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, true);
 	zend_string *property_entities_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1);
-	zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0));
+	zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0));
 	zend_string_release_ex(property_entities_name, true);
 
 	zval property_notations_default_value;
 	ZVAL_UNDEF(&property_notations_default_value);
 	zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, true);
 	zend_string *property_notations_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1);
-	zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0));
+	zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0));
 	zend_string_release_ex(property_notations_name, true);
 
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_systemId_name, true);
 
 	zval property_internalSubset_default_value;
 	ZVAL_UNDEF(&property_internalSubset_default_value);
 	zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, true);
-	zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_internalSubset_name, true);
 
 	return class_entry;
@@ -2010,7 +2010,7 @@ static zend_class_entry *register_class_DOMNode(void)
 	zval property_nodeName_default_value;
 	ZVAL_UNDEF(&property_nodeName_default_value);
 	zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_nodeName_name, true);
 
 	zval property_nodeValue_default_value;
@@ -2022,82 +2022,82 @@ static zend_class_entry *register_class_DOMNode(void)
 	zval property_nodeType_default_value;
 	ZVAL_UNDEF(&property_nodeType_default_value);
 	zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_nodeType_name, true);
 
 	zval property_parentNode_default_value;
 	ZVAL_UNDEF(&property_parentNode_default_value);
 	zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, true);
 	zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentNode_name, true);
 
 	zval property_parentElement_default_value;
 	ZVAL_UNDEF(&property_parentElement_default_value);
 	zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, true);
 	zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentElement_name, true);
 
 	zval property_childNodes_default_value;
 	ZVAL_UNDEF(&property_childNodes_default_value);
 	zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, true);
 	zend_string *property_childNodes_class_DOMNodeList = zend_string_init("DOMNodeList", sizeof("DOMNodeList")-1, 1);
-	zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0));
+	zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0));
 	zend_string_release_ex(property_childNodes_name, true);
 
 	zval property_firstChild_default_value;
 	ZVAL_UNDEF(&property_firstChild_default_value);
 	zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, true);
 	zend_string *property_firstChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstChild_name, true);
 
 	zval property_lastChild_default_value;
 	ZVAL_UNDEF(&property_lastChild_default_value);
 	zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, true);
 	zend_string *property_lastChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastChild_name, true);
 
 	zval property_previousSibling_default_value;
 	ZVAL_UNDEF(&property_previousSibling_default_value);
 	zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, true);
 	zend_string *property_previousSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousSibling_name, true);
 
 	zval property_nextSibling_default_value;
 	ZVAL_UNDEF(&property_nextSibling_default_value);
 	zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, true);
 	zend_string *property_nextSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextSibling_name, true);
 
 	zval property_attributes_default_value;
 	ZVAL_UNDEF(&property_attributes_default_value);
 	zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true);
 	zend_string *property_attributes_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1);
-	zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_attributes_name, true);
 
 	zval property_isConnected_default_value;
 	ZVAL_UNDEF(&property_isConnected_default_value);
 	zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, true);
-	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
 	zend_string_release_ex(property_isConnected_name, true);
 
 	zval property_ownerDocument_default_value;
 	ZVAL_UNDEF(&property_ownerDocument_default_value);
 	zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, true);
 	zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1);
-	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_ownerDocument_name, true);
 
 	zval property_namespaceURI_default_value;
 	ZVAL_UNDEF(&property_namespaceURI_default_value);
 	zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_namespaceURI_name, true);
 
 	zval property_prefix_default_value;
@@ -2109,13 +2109,13 @@ static zend_class_entry *register_class_DOMNode(void)
 	zval property_localName_default_value;
 	ZVAL_UNDEF(&property_localName_default_value);
 	zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, true);
-	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_localName_name, true);
 
 	zval property_baseURI_default_value;
 	ZVAL_UNDEF(&property_baseURI_default_value);
 	zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_baseURI_name, true);
 
 	zval property_textContent_default_value;
@@ -2137,64 +2137,64 @@ static zend_class_entry *register_class_DOMNameSpaceNode(void)
 	zval property_nodeName_default_value;
 	ZVAL_UNDEF(&property_nodeName_default_value);
 	zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_nodeName_name, true);
 
 	zval property_nodeValue_default_value;
 	ZVAL_UNDEF(&property_nodeValue_default_value);
 	zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_nodeValue_name, true);
 
 	zval property_nodeType_default_value;
 	ZVAL_UNDEF(&property_nodeType_default_value);
 	zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_nodeType_name, true);
 
 	zval property_prefix_default_value;
 	ZVAL_UNDEF(&property_prefix_default_value);
 	zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, true);
-	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_prefix_name, true);
 
 	zval property_localName_default_value;
 	ZVAL_UNDEF(&property_localName_default_value);
 	zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, true);
-	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_localName_name, true);
 
 	zval property_namespaceURI_default_value;
 	ZVAL_UNDEF(&property_namespaceURI_default_value);
 	zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_namespaceURI_name, true);
 
 	zval property_isConnected_default_value;
 	ZVAL_UNDEF(&property_isConnected_default_value);
 	zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, true);
-	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
 	zend_string_release_ex(property_isConnected_name, true);
 
 	zval property_ownerDocument_default_value;
 	ZVAL_UNDEF(&property_ownerDocument_default_value);
 	zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, true);
 	zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1);
-	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_ownerDocument_name, true);
 
 	zval property_parentNode_default_value;
 	ZVAL_UNDEF(&property_parentNode_default_value);
 	zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, true);
 	zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentNode_name, true);
 
 	zval property_parentElement_default_value;
 	ZVAL_UNDEF(&property_parentElement_default_value);
 	zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, true);
 	zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentElement_name, true);
 
 	return class_entry;
@@ -2222,20 +2222,20 @@ static zend_class_entry *register_class_DOMDocumentFragment(zend_class_entry *cl
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	return class_entry;
@@ -2252,7 +2252,7 @@ static zend_class_entry *register_class_DOMNodeList(zend_class_entry *class_entr
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2275,21 +2275,21 @@ static zend_class_entry *register_class_DOMCharacterData(zend_class_entry *class
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	zval property_previousElementSibling_default_value;
 	ZVAL_UNDEF(&property_previousElementSibling_default_value);
 	zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, true);
 	zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousElementSibling_name, true);
 
 	zval property_nextElementSibling_default_value;
 	ZVAL_UNDEF(&property_nextElementSibling_default_value);
 	zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, true);
 	zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextElementSibling_name, true);
 
 	return class_entry;
@@ -2304,12 +2304,12 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO
 
 	zval property_name_default_value;
 	ZVAL_UNDEF(&property_name_default_value);
-	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 
 	zval property_specified_default_value;
 	ZVAL_UNDEF(&property_specified_default_value);
 	zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, true);
-	zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+	zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
 	zend_string_release_ex(property_specified_name, true);
 
 	zval property_value_default_value;
@@ -2320,13 +2320,13 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO
 	ZVAL_UNDEF(&property_ownerElement_default_value);
 	zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, true);
 	zend_string *property_ownerElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_ownerElement_name, true);
 
 	zval property_schemaTypeInfo_default_value;
 	ZVAL_UNDEF(&property_schemaTypeInfo_default_value);
 	zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, true);
-	zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
+	zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
 	zend_string_release_ex(property_schemaTypeInfo_name, true);
 
 	return class_entry;
@@ -2343,7 +2343,7 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry
 	zval property_tagName_default_value;
 	ZVAL_UNDEF(&property_tagName_default_value);
 	zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, true);
-	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_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_tagName_name, true);
 
 	zval property_className_default_value;
@@ -2361,41 +2361,41 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry
 	zval property_schemaTypeInfo_default_value;
 	ZVAL_UNDEF(&property_schemaTypeInfo_default_value);
 	zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, true);
-	zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
+	zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
 	zend_string_release_ex(property_schemaTypeInfo_name, true);
 
 	zval property_firstElementChild_default_value;
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	zval property_previousElementSibling_default_value;
 	ZVAL_UNDEF(&property_previousElementSibling_default_value);
 	zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, true);
 	zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousElementSibling_name, true);
 
 	zval property_nextElementSibling_default_value;
 	ZVAL_UNDEF(&property_nextElementSibling_default_value);
 	zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, true);
 	zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextElementSibling_name, true);
 
 	return class_entry;
@@ -2413,27 +2413,27 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
 	ZVAL_UNDEF(&property_doctype_default_value);
 	zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, true);
 	zend_string *property_doctype_class_DOMDocumentType = zend_string_init("DOMDocumentType", sizeof("DOMDocumentType")-1, 1);
-	zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_doctype_name, true);
 
 	zval property_implementation_default_value;
 	ZVAL_UNDEF(&property_implementation_default_value);
 	zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, true);
 	zend_string *property_implementation_class_DOMImplementation = zend_string_init("DOMImplementation", sizeof("DOMImplementation")-1, 1);
-	zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0));
+	zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0));
 	zend_string_release_ex(property_implementation_name, true);
 
 	zval property_documentElement_default_value;
 	ZVAL_UNDEF(&property_documentElement_default_value);
 	zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, true);
 	zend_string *property_documentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_documentElement_name, true);
 
 	zval property_actualEncoding_default_value;
 	ZVAL_UNDEF(&property_actualEncoding_default_value);
 	zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, true);
-	zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_actualEncoding_name, true);
 
 	zval property_encoding_default_value;
@@ -2445,7 +2445,7 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
 	zval property_xmlEncoding_default_value;
 	ZVAL_UNDEF(&property_xmlEncoding_default_value);
 	zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, true);
-	zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_xmlEncoding_name, true);
 
 	zval property_standalone_default_value;
@@ -2487,7 +2487,7 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
 	zval property_config_default_value;
 	ZVAL_UNDEF(&property_config_default_value);
 	zend_string *property_config_name = zend_string_init("config", sizeof("config") - 1, true);
-	zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
+	zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
 	zend_string_release_ex(property_config_name, true);
 
 	zval property_formatOutput_default_value;
@@ -2530,20 +2530,20 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	return class_entry;
@@ -2574,7 +2574,7 @@ static zend_class_entry *register_class_DOMText(zend_class_entry *class_entry_DO
 	zval property_wholeText_default_value;
 	ZVAL_UNDEF(&property_wholeText_default_value);
 	zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, true);
-	zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_wholeText_name, true);
 
 	return class_entry;
@@ -2591,7 +2591,7 @@ static zend_class_entry *register_class_DOMNamedNodeMap(zend_class_entry *class_
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2607,37 +2607,37 @@ static zend_class_entry *register_class_DOMEntity(zend_class_entry *class_entry_
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_systemId_name, true);
 
 	zval property_notationName_default_value;
 	ZVAL_UNDEF(&property_notationName_default_value);
 	zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, true);
-	zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_notationName_name, true);
 
 	zval property_actualEncoding_default_value;
 	ZVAL_UNDEF(&property_actualEncoding_default_value);
 	zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, true);
-	zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_actualEncoding_name, true);
 
 	zval property_encoding_default_value;
 	ZVAL_UNDEF(&property_encoding_default_value);
 	zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, true);
-	zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_encoding_name, true);
 
 	zval property_version_default_value;
 	ZVAL_UNDEF(&property_version_default_value);
 	zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, true);
-	zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_version_name, true);
 
 	return class_entry;
@@ -2663,13 +2663,13 @@ static zend_class_entry *register_class_DOMNotation(zend_class_entry *class_entr
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_systemId_name, true);
 
 	return class_entry;
@@ -2685,7 +2685,7 @@ static zend_class_entry *register_class_DOMProcessingInstruction(zend_class_entr
 	zval property_target_default_value;
 	ZVAL_UNDEF(&property_target_default_value);
 	zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, true);
-	zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_target_name, true);
 
 	zval property_data_default_value;
@@ -2709,7 +2709,7 @@ static zend_class_entry *register_class_DOMXPath(void)
 	ZVAL_UNDEF(&property_document_default_value);
 	zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, true);
 	zend_string *property_document_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1);
-	zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0));
+	zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0));
 	zend_string_release_ex(property_document_name, true);
 
 	zval property_registerNodeNamespaces_default_value;
@@ -2798,81 +2798,81 @@ static zend_class_entry *register_class_Dom_Node(void)
 	zval property_nodeType_default_value;
 	ZVAL_UNDEF(&property_nodeType_default_value);
 	zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_nodeType_name, true);
 
 	zval property_nodeName_default_value;
 	ZVAL_UNDEF(&property_nodeName_default_value);
 	zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, true);
-	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_nodeName_name, true);
 
 	zval property_baseURI_default_value;
 	ZVAL_UNDEF(&property_baseURI_default_value);
 	zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_baseURI_name, true);
 
 	zval property_isConnected_default_value;
 	ZVAL_UNDEF(&property_isConnected_default_value);
 	zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, true);
-	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+	zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
 	zend_string_release_ex(property_isConnected_name, true);
 
 	zval property_ownerDocument_default_value;
 	ZVAL_UNDEF(&property_ownerDocument_default_value);
 	zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, true);
 	zend_string *property_ownerDocument_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1);
-	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_ownerDocument_name, true);
 
 	zval property_parentNode_default_value;
 	ZVAL_UNDEF(&property_parentNode_default_value);
 	zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, true);
 	zend_string *property_parentNode_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentNode_name, true);
 
 	zval property_parentElement_default_value;
 	ZVAL_UNDEF(&property_parentElement_default_value);
 	zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, true);
 	zend_string *property_parentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_parentElement_name, true);
 
 	zval property_childNodes_default_value;
 	ZVAL_UNDEF(&property_childNodes_default_value);
 	zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, true);
 	zend_string *property_childNodes_class_Dom_NodeList = zend_string_init("Dom\\\116odeList", sizeof("Dom\\\116odeList")-1, 1);
-	zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0));
+	zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0));
 	zend_string_release_ex(property_childNodes_name, true);
 
 	zval property_firstChild_default_value;
 	ZVAL_UNDEF(&property_firstChild_default_value);
 	zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, true);
 	zend_string *property_firstChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1);
-	zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstChild_name, true);
 
 	zval property_lastChild_default_value;
 	ZVAL_UNDEF(&property_lastChild_default_value);
 	zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, true);
 	zend_string *property_lastChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1);
-	zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastChild_name, true);
 
 	zval property_previousSibling_default_value;
 	ZVAL_UNDEF(&property_previousSibling_default_value);
 	zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, true);
 	zend_string *property_previousSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousSibling_name, true);
 
 	zval property_nextSibling_default_value;
 	ZVAL_UNDEF(&property_nextSibling_default_value);
 	zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, true);
 	zend_string *property_nextSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextSibling_name, true);
 
 	zval property_nodeValue_default_value;
@@ -2901,7 +2901,7 @@ static zend_class_entry *register_class_Dom_NodeList(zend_class_entry *class_ent
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2918,7 +2918,7 @@ static zend_class_entry *register_class_Dom_NamedNodeMap(zend_class_entry *class
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2935,7 +2935,7 @@ static zend_class_entry *register_class_Dom_DtdNamedNodeMap(zend_class_entry *cl
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2952,7 +2952,7 @@ static zend_class_entry *register_class_Dom_HTMLCollection(zend_class_entry *cla
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -2996,66 +2996,66 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr
 	zval property_namespaceURI_default_value;
 	ZVAL_UNDEF(&property_namespaceURI_default_value);
 	zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_namespaceURI_name, true);
 
 	zval property_prefix_default_value;
 	ZVAL_UNDEF(&property_prefix_default_value);
 	zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, true);
-	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_prefix_name, true);
 
 	zval property_localName_default_value;
 	ZVAL_UNDEF(&property_localName_default_value);
 	zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, true);
-	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_localName_name, true);
 
 	zval property_tagName_default_value;
 	ZVAL_UNDEF(&property_tagName_default_value);
 	zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, true);
-	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_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_tagName_name, true);
 
 	zval property_children_default_value;
 	ZVAL_UNDEF(&property_children_default_value);
 	zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, true);
 	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_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0));
 	zend_string_release_ex(property_children_name, true);
 
 	zval property_firstElementChild_default_value;
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	zval property_previousElementSibling_default_value;
 	ZVAL_UNDEF(&property_previousElementSibling_default_value);
 	zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, true);
 	zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousElementSibling_name, true);
 
 	zval property_nextElementSibling_default_value;
 	ZVAL_UNDEF(&property_nextElementSibling_default_value);
 	zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, true);
 	zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextElementSibling_name, true);
 
 	zval property_id_default_value;
@@ -3074,14 +3074,14 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr
 	ZVAL_UNDEF(&property_classList_default_value);
 	zend_string *property_classList_name = zend_string_init("classList", sizeof("classList") - 1, true);
 	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_declare_typed_property(class_entry, property_classList_name, &property_classList_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_classList_class_Dom_TokenList, 0, 0));
 	zend_string_release_ex(property_classList_name, true);
 
 	zval property_attributes_default_value;
 	ZVAL_UNDEF(&property_attributes_default_value);
 	zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, true);
 	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_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0));
 	zend_string_release_ex(property_attributes_name, true);
 
 	zval property_innerHTML_default_value;
@@ -3125,24 +3125,24 @@ static zend_class_entry *register_class_Dom_Attr(zend_class_entry *class_entry_D
 	zval property_namespaceURI_default_value;
 	ZVAL_UNDEF(&property_namespaceURI_default_value);
 	zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, true);
-	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_namespaceURI_name, true);
 
 	zval property_prefix_default_value;
 	ZVAL_UNDEF(&property_prefix_default_value);
 	zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, true);
-	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_prefix_name, true);
 
 	zval property_localName_default_value;
 	ZVAL_UNDEF(&property_localName_default_value);
 	zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, true);
-	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_localName_name, true);
 
 	zval property_name_default_value;
 	ZVAL_UNDEF(&property_name_default_value);
-	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 
 	zval property_value_default_value;
 	ZVAL_UNDEF(&property_value_default_value);
@@ -3152,13 +3152,13 @@ static zend_class_entry *register_class_Dom_Attr(zend_class_entry *class_entry_D
 	ZVAL_UNDEF(&property_ownerElement_default_value);
 	zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, true);
 	zend_string *property_ownerElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_ownerElement_name, true);
 
 	zval property_specified_default_value;
 	ZVAL_UNDEF(&property_specified_default_value);
 	zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, true);
-	zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+	zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
 	zend_string_release_ex(property_specified_name, true);
 
 	return class_entry;
@@ -3176,14 +3176,14 @@ static zend_class_entry *register_class_Dom_CharacterData(zend_class_entry *clas
 	ZVAL_UNDEF(&property_previousElementSibling_default_value);
 	zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, true);
 	zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_previousElementSibling_name, true);
 
 	zval property_nextElementSibling_default_value;
 	ZVAL_UNDEF(&property_nextElementSibling_default_value);
 	zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, true);
 	zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_nextElementSibling_name, true);
 
 	zval property_data_default_value;
@@ -3195,7 +3195,7 @@ static zend_class_entry *register_class_Dom_CharacterData(zend_class_entry *clas
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	return class_entry;
@@ -3211,7 +3211,7 @@ static zend_class_entry *register_class_Dom_Text(zend_class_entry *class_entry_D
 	zval property_wholeText_default_value;
 	ZVAL_UNDEF(&property_wholeText_default_value);
 	zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, true);
-	zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_wholeText_name, true);
 
 	return class_entry;
@@ -3237,7 +3237,7 @@ static zend_class_entry *register_class_Dom_ProcessingInstruction(zend_class_ent
 	zval property_target_default_value;
 	ZVAL_UNDEF(&property_target_default_value);
 	zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, true);
-	zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_target_name, true);
 
 	return class_entry;
@@ -3263,38 +3263,38 @@ static zend_class_entry *register_class_Dom_DocumentType(zend_class_entry *class
 
 	zval property_name_default_value;
 	ZVAL_UNDEF(&property_name_default_value);
-	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 
 	zval property_entities_default_value;
 	ZVAL_UNDEF(&property_entities_default_value);
 	zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, true);
 	zend_string *property_entities_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1);
-	zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0));
+	zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0));
 	zend_string_release_ex(property_entities_name, true);
 
 	zval property_notations_default_value;
 	ZVAL_UNDEF(&property_notations_default_value);
 	zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, true);
 	zend_string *property_notations_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1);
-	zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0));
+	zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0));
 	zend_string_release_ex(property_notations_name, true);
 
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_systemId_name, true);
 
 	zval property_internalSubset_default_value;
 	ZVAL_UNDEF(&property_internalSubset_default_value);
 	zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, true);
-	zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_internalSubset_name, true);
 
 	return class_entry;
@@ -3312,27 +3312,27 @@ static zend_class_entry *register_class_Dom_DocumentFragment(zend_class_entry *c
 	ZVAL_UNDEF(&property_children_default_value);
 	zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, true);
 	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_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0));
 	zend_string_release_ex(property_children_name, true);
 
 	zval property_firstElementChild_default_value;
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	return class_entry;
@@ -3348,19 +3348,19 @@ static zend_class_entry *register_class_Dom_Entity(zend_class_entry *class_entry
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_systemId_name, true);
 
 	zval property_notationName_default_value;
 	ZVAL_UNDEF(&property_notationName_default_value);
 	zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, true);
-	zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
 	zend_string_release_ex(property_notationName_name, true);
 
 	return class_entry;
@@ -3386,13 +3386,13 @@ static zend_class_entry *register_class_Dom_Notation(zend_class_entry *class_ent
 	zval property_publicId_default_value;
 	ZVAL_UNDEF(&property_publicId_default_value);
 	zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, true);
-	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_publicId_name, true);
 
 	zval property_systemId_default_value;
 	ZVAL_UNDEF(&property_systemId_default_value);
 	zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, true);
-	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_systemId_name, true);
 
 	return class_entry;
@@ -3410,34 +3410,34 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent
 	ZVAL_UNDEF(&property_children_default_value);
 	zend_string *property_children_name = zend_string_init("children", sizeof("children") - 1, true);
 	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_declare_typed_property(class_entry, property_children_name, &property_children_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_children_class_Dom_HTMLCollection, 0, 0));
 	zend_string_release_ex(property_children_name, true);
 
 	zval property_firstElementChild_default_value;
 	ZVAL_UNDEF(&property_firstElementChild_default_value);
 	zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_firstElementChild_name, true);
 
 	zval property_lastElementChild_default_value;
 	ZVAL_UNDEF(&property_lastElementChild_default_value);
 	zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, true);
 	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_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_lastElementChild_name, true);
 
 	zval property_childElementCount_default_value;
 	ZVAL_UNDEF(&property_childElementCount_default_value);
 	zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, true);
-	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_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_childElementCount_name, true);
 
 	zval property_implementation_default_value;
 	ZVAL_UNDEF(&property_implementation_default_value);
 	zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, true);
 	zend_string *property_implementation_class_Dom_Implementation = zend_string_init("Dom\\Implementation", sizeof("Dom\\Implementation")-1, 1);
-	zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_Dom_Implementation, 0, 0));
+	zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_Dom_Implementation, 0, 0));
 	zend_string_release_ex(property_implementation_name, true);
 
 	zval property_URL_default_value;
@@ -3474,14 +3474,14 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent
 	ZVAL_UNDEF(&property_doctype_default_value);
 	zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, true);
 	zend_string *property_doctype_class_Dom_DocumentType = zend_string_init("Dom\\DocumentType", sizeof("Dom\\DocumentType")-1, 1);
-	zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_doctype_name, true);
 
 	zval property_documentElement_default_value;
 	ZVAL_UNDEF(&property_documentElement_default_value);
 	zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, true);
 	zend_string *property_documentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
-	zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_documentElement_name, true);
 
 	zval property_body_default_value;
@@ -3495,7 +3495,7 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent
 	ZVAL_UNDEF(&property_head_default_value);
 	zend_string *property_head_name = zend_string_init("head", sizeof("head") - 1, true);
 	zend_string *property_head_class_Dom_HTMLElement = zend_string_init("Dom\\HTMLElement", sizeof("Dom\\HTMLElement")-1, 1);
-	zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL));
+	zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL));
 	zend_string_release_ex(property_head_name, true);
 
 	zval property_title_default_value;
@@ -3527,7 +3527,7 @@ static zend_class_entry *register_class_Dom_XMLDocument(zend_class_entry *class_
 	zval property_xmlEncoding_default_value;
 	ZVAL_UNDEF(&property_xmlEncoding_default_value);
 	zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, true);
-	zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
+	zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
 	zend_string_release_ex(property_xmlEncoding_name, true);
 
 	zval property_xmlStandalone_default_value;
@@ -3562,7 +3562,7 @@ static zend_class_entry *register_class_Dom_TokenList(zend_class_entry *class_en
 	zval property_length_default_value;
 	ZVAL_UNDEF(&property_length_default_value);
 	zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, true);
-	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
+	zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
 	zend_string_release_ex(property_length_name, true);
 
 	zval property_value_default_value;
@@ -3613,7 +3613,7 @@ static zend_class_entry *register_class_Dom_XPath(void)
 	ZVAL_UNDEF(&property_document_default_value);
 	zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, true);
 	zend_string *property_document_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1);
-	zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0));
+	zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_PRIVATE_SET|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0));
 	zend_string_release_ex(property_document_name, true);
 
 	zval property_registerNodeNamespaces_default_value;
diff --git a/ext/dom/php_dom_decl.h b/ext/dom/php_dom_decl.h
index f918637ab52d..e42fe5969595 100644
--- a/ext/dom/php_dom_decl.h
+++ b/ext/dom/php_dom_decl.h
@@ -1,8 +1,8 @@
 /* This is a generated file, edit php_dom.stub.php instead.
- * Stub hash: e00668999f4fe9afee1f78f6986467a315f831a5 */
+ * Stub hash: 8d7713834c924709155ed7acc554c9efc55e96c1 */
 
-#ifndef ZEND_PHP_DOM_DECL_e00668999f4fe9afee1f78f6986467a315f831a5_H
-#define ZEND_PHP_DOM_DECL_e00668999f4fe9afee1f78f6986467a315f831a5_H
+#ifndef ZEND_PHP_DOM_DECL_8d7713834c924709155ed7acc554c9efc55e96c1_H
+#define ZEND_PHP_DOM_DECL_8d7713834c924709155ed7acc554c9efc55e96c1_H
 
 typedef enum zend_enum_Dom_AdjacentPosition {
 	ZEND_ENUM_Dom_AdjacentPosition_BeforeBegin = 1,
@@ -11,4 +11,4 @@ typedef enum zend_enum_Dom_AdjacentPosition {
 	ZEND_ENUM_Dom_AdjacentPosition_AfterEnd = 4,
 } zend_enum_Dom_AdjacentPosition;
 
-#endif /* ZEND_PHP_DOM_DECL_e00668999f4fe9afee1f78f6986467a315f831a5_H */
+#endif /* ZEND_PHP_DOM_DECL_8d7713834c924709155ed7acc554c9efc55e96c1_H */
diff --git a/ext/dom/private_data.c b/ext/dom/private_data.c
index bb20093b8ebb..dd624a2c2e9c 100644
--- a/ext/dom/private_data.c
+++ b/ext/dom/private_data.c
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/private_data.h b/ext/dom/private_data.h
index ead6c75caf24..086cd7bfc59c 100644
--- a/ext/dom/private_data.h
+++ b/ext/dom/private_data.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c
index eda15720eab0..94e5d5b35067 100644
--- a/ext/dom/processinginstruction.c
+++ b/ext/dom/processinginstruction.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker                           |
    |          Rob Richards                             |
diff --git a/ext/dom/serialize_common.h b/ext/dom/serialize_common.h
index ed967c98a9ee..c6566e2f37cd 100644
--- a/ext/dom/serialize_common.h
+++ b/ext/dom/serialize_common.h
@@ -1,16 +1,14 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | 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.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
-   | Authors: Niels Dossche                             |
+   | Authors: Nora Dossche                              |
    +----------------------------------------------------------------------+
 */
 
diff --git a/ext/dom/tests/gh22077.phpt b/ext/dom/tests/gh22077.phpt
new file mode 100644
index 000000000000..fd4e42cc8aaf
--- /dev/null
+++ b/ext/dom/tests/gh22077.phpt
@@ -0,0 +1,20 @@
+--TEST--
+GH-22077 (UAF in custom XPath function)
+--FILE--
+registerNamespace("my", "my.ns");
+$xpath->registerPHPFunctionNS('my.ns', 'include', function(): DOMElement {
+    $includedDocument = new DOMDocument;
+    $includedDocument->loadXML('');
+    return $includedDocument->documentElement;
+});
+$nodeset = $xpath->query('my:include()/uaf');
+$node = $nodeset->item(0);
+var_dump($nodeset->length);
+var_dump($node->ownerDocument->saveXML($node));
+?>
+--EXPECT--
+int(2)
+string(6) ""
diff --git a/ext/dom/tests/gh22219.phpt b/ext/dom/tests/gh22219.phpt
new file mode 100644
index 000000000000..637a47039c35
--- /dev/null
+++ b/ext/dom/tests/gh22219.phpt
@@ -0,0 +1,54 @@
+--TEST--
+GH-22219 (Dom\XMLDocument::schemaValidate fails to resolve xs:QName value from an in-scope prefix)
+--EXTENSIONS--
+dom
+--SKIPIF--
+
+--FILE--
+
+
+  
+
+XML;
+
+// The 'ref' prefix is declared on  but only used inside the xs:QName
+// attribute value, never as an element or attribute namespace.
+$xsd = <<
+
+  
+    
+      
+        
+          
+            
+          
+        
+      
+    
+  
+
+XSD;
+
+libxml_use_internal_errors(true);
+
+$modern = Dom\XMLDocument::createFromString($xml, LIBXML_NSCLEAN);
+var_dump($modern->schemaValidateSource($xsd));
+
+$legacy = new DOMDocument();
+$legacy->loadXML($xml, LIBXML_NSCLEAN);
+var_dump($legacy->schemaValidateSource($xsd));
+
+foreach (libxml_get_errors() as $error) {
+    echo trim($error->message), PHP_EOL;
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/dom/tests/gh22447.phpt b/ext/dom/tests/gh22447.phpt
new file mode 100644
index 000000000000..396a0ff1ee1c
--- /dev/null
+++ b/ext/dom/tests/gh22447.phpt
@@ -0,0 +1,25 @@
+--TEST--
+GH-22447 (UAF at dom_objects_free_storage when setAttributeNode collides with a namespaced attribute of the same local name)
+--EXTENSIONS--
+dom
+--FILE--
+createAttribute("my-attribute");
+$container  = $dom->appendChild($dom->createElement("container"));
+$attribute2 = $dom->createAttribute("my-attribute");
+$attribute4 = $dom->createAttributeNS("urn:a", "my-attribute");
+
+$container->setAttributeNode($attribute1);
+$container->setAttributeNode($attribute4);
+
+var_dump($container->setAttributeNode($attribute2) === $attribute1);
+var_dump($container->setAttributeNode($attribute1) === $attribute2);
+
+echo $dom->saveXml($container), PHP_EOL;
+?>
+--EXPECT--
+bool(true)
+bool(true)
+
diff --git a/ext/dom/tests/gh22554.phpt b/ext/dom/tests/gh22554.phpt
new file mode 100644
index 000000000000..c8db1d87390b
--- /dev/null
+++ b/ext/dom/tests/gh22554.phpt
@@ -0,0 +1,38 @@
+--TEST--
+GH-22554 (Use-after-free when an XPath callback returns a node from a document created inside the callback)
+--CREDITS--
+waseem-cve
+--EXTENSIONS--
+dom
+--FILE--
+loadXML('');
+
+$xp = new DOMXPath($doc);
+$xp->registerNamespace('my', 'my.ns');
+
+$xp->registerPHPFunctionNS('my.ns', 'include', function () {
+    $d = new DOMDocument;
+    $d->loadXML('');
+
+    return $d->documentElement;
+});
+
+$xp->registerPHPFunctionNS('my.ns', 'process', function ($arg) {
+    echo "process arg: ", get_class($arg[0]), " ", $arg[0]->nodeName, "\n";
+    return 'x';
+});
+
+$result = $xp->query('my:process(my:include()/uaf)');
+var_dump($result->length);
+unset($xp);
+
+echo "Done\n";
+
+?>
+--EXPECT--
+process arg: DOMElement uaf
+int(0)
+Done
diff --git a/ext/dom/tests/gh22825.phpt b/ext/dom/tests/gh22825.phpt
new file mode 100644
index 000000000000..987ed57a1454
--- /dev/null
+++ b/ext/dom/tests/gh22825.phpt
@@ -0,0 +1,98 @@
+--TEST--
+GH-22825 (DOMElement::setAttribute() reaches EMPTY_SWITCH_DEFAULT_CASE() with DTD #FIXED default attributes)
+--EXTENSIONS--
+dom
+--FILE--
+', '', 'A'],
+    ['', '', 'A'],
+    ['', '', 'p:A'],
+];
+
+function element(string $attlist, string $root): DOMElement {
+    $doc = new DOMDocument();
+    $doc->loadXML("$root");
+    return $doc->documentElement;
+}
+
+foreach ($cases as [$attlist, $root, $name]) {
+    echo "--- $attlist ---\n";
+
+    $el = element($attlist, $root);
+    echo "hasAttribute: ";
+    var_dump($el->hasAttribute($name));
+    echo "getAttribute: ";
+    var_dump($el->getAttribute($name));
+
+    $el = element($attlist, $root);
+    $result = $el->setAttribute($name, 'v');
+    echo "setAttribute: ", is_object($result) ? $result::class : var_export($result, true), "\n";
+    echo "after setAttribute: ", trim($el->ownerDocument->saveXML($el)), "\n";
+
+    $el = element($attlist, $root);
+    echo "removeAttribute: ";
+    var_dump($el->removeAttribute($name));
+    echo "still present after removeAttribute: ";
+    var_dump($el->hasAttribute($name));
+
+    $el = element($attlist, $root);
+    echo "toggleAttribute(false): ";
+    var_dump($el->toggleAttribute($name, false));
+    echo "still present after toggleAttribute(false): ";
+    var_dump($el->hasAttribute($name));
+
+    $el = element($attlist, $root);
+    echo "toggleAttribute(true): ";
+    var_dump($el->toggleAttribute($name, true));
+    echo "still present after toggleAttribute(true): ";
+    var_dump($el->hasAttribute($name));
+
+    $el = element($attlist, $root);
+    $attr = $el->ownerDocument->createAttribute($name);
+    $attr->value = 'z';
+    echo "setAttributeNode: ";
+    var_dump($el->setAttributeNode($attr));
+    echo "after setAttributeNode: ", trim($el->ownerDocument->saveXML($el)), "\n";
+}
+?>
+--EXPECT--
+---  ---
+hasAttribute: bool(true)
+getAttribute: string(1) "d"
+setAttribute: DOMAttr
+after setAttribute: 
+removeAttribute: bool(false)
+still present after removeAttribute: bool(true)
+toggleAttribute(false): bool(true)
+still present after toggleAttribute(false): bool(true)
+toggleAttribute(true): bool(true)
+still present after toggleAttribute(true): bool(true)
+setAttributeNode: NULL
+after setAttributeNode: 
+---  ---
+hasAttribute: bool(true)
+getAttribute: string(1) "d"
+setAttribute: DOMAttr
+after setAttribute: 
+removeAttribute: bool(false)
+still present after removeAttribute: bool(true)
+toggleAttribute(false): bool(true)
+still present after toggleAttribute(false): bool(true)
+toggleAttribute(true): bool(true)
+still present after toggleAttribute(true): bool(true)
+setAttributeNode: NULL
+after setAttributeNode: 
+---  ---
+hasAttribute: bool(true)
+getAttribute: string(1) "d"
+setAttribute: DOMAttr
+after setAttribute: 
+removeAttribute: bool(false)
+still present after removeAttribute: bool(true)
+toggleAttribute(false): bool(true)
+still present after toggleAttribute(false): bool(true)
+toggleAttribute(true): bool(true)
+still present after toggleAttribute(true): bool(true)
+setAttributeNode: NULL
+after setAttributeNode: 
diff --git a/ext/dom/tests/modern/common/Element_getElementsByClassName_item_random_access.phpt b/ext/dom/tests/modern/common/Element_getElementsByClassName_item_random_access.phpt
new file mode 100644
index 000000000000..005ad45d3c25
--- /dev/null
+++ b/ext/dom/tests/modern/common/Element_getElementsByClassName_item_random_access.phpt
@@ -0,0 +1,84 @@
+--TEST--
+Dom\Element::getElementsByClassName() item() random access (cold and backwards)
+--EXTENSIONS--
+dom
+--FILE--
+
+
+    
+    
+ +

+ + +HTML); + +$body = $dom->getElementsByTagName('body')->item(0); + +function id(?Dom\Element $e): string { + return $e === null ? 'NULL' : $e->id; +} + +echo "-- cold random access (fresh collection per call) --\n"; +foreach ([0, 1, 2, 3, 4, 5] as $i) { + $collection = $body->getElementsByClassName('x'); + echo "item($i) = ", id($collection->item($i)), "\n"; +} + +echo "-- backwards seek on one collection --\n"; +$collection = $body->getElementsByClassName('x'); +foreach ([4, 2, 0, 3, 1] as $i) { + echo "item($i) = ", id($collection->item($i)), "\n"; +} + +echo "-- item() seed then foreach --\n"; +$collection = $body->getElementsByClassName('x'); +$collection->item(3); +$ids = []; +foreach ($collection as $node) { + $ids[] = $node->id; +} +echo implode(" ", $ids), "\n"; + +echo "-- last-element idiom --\n"; +$collection = $body->getElementsByClassName('x'); +echo "length = ", $collection->length, ", last = ", id($collection->item($collection->length - 1)), "\n"; + +echo "-- live collection after mutation --\n"; +$collection = $body->getElementsByClassName('x'); +echo "item(1) = ", id($collection->item(1)), "\n"; +$dom->getElementById('E1')->remove(); +echo "item(1) = ", id($collection->item(1)), ", length = ", $collection->length, "\n"; + +?> +--EXPECT-- +-- cold random access (fresh collection per call) -- +item(0) = E0 +item(1) = E1 +item(2) = E2 +item(3) = E3 +item(4) = E4 +item(5) = NULL +-- backwards seek on one collection -- +item(4) = E4 +item(2) = E2 +item(0) = E0 +item(3) = E3 +item(1) = E1 +-- item() seed then foreach -- +E0 E1 E2 E3 E4 +-- last-element idiom -- +length = 5, last = E4 +-- live collection after mutation -- +item(1) = E1 +item(1) = E2, length = 4 diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt index 5c602b87f23e..5164ac68041d 100644 --- a/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt +++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_createFromFile_http_header.phpt @@ -46,6 +46,7 @@ $tests = [ "text/html; ;; ; ;; Charset=\"ISO-8859-1\"", "text/html;Charset=\"ISO-8859-1", "tex.t/h#\$%!&'*%2B-.^_`|~tml;Charset=\"ISO-8859-1\"", // Note: have to encode + as 2B because of implementation details of http_server() + "text/html; abcd=ef;charset=ISO-8859-1", ], "Valid input, but invalid encoding name" => [ "text/html;Charset=\"ISO-8859-1\\", @@ -100,6 +101,7 @@ foreach ($tests as $name => $headers) { äöü äöü äöü +äöü --- Valid input, but invalid encoding name --- ��� ��� diff --git a/ext/dom/tests/modern/html/gh21688.phpt b/ext/dom/tests/modern/html/gh21688.phpt new file mode 100644 index 000000000000..ddfb4d326c63 --- /dev/null +++ b/ext/dom/tests/modern/html/gh21688.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-21688 (SEGV in C14N on empty HTMLDocument) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +dom +--FILE-- +C14N()); +?> +--EXPECT-- +string(0) "" diff --git a/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt b/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt index 058d4432b49d..89574b7a631f 100644 --- a/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt +++ b/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt @@ -60,6 +60,6 @@ echo $dom->saveXML(), "\n"; - + diff --git a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_local_file_does_not_exist.phpt b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_local_file_does_not_exist.phpt index ce96afd69eb3..52e709e4a0ca 100644 --- a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_local_file_does_not_exist.phpt +++ b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_local_file_does_not_exist.phpt @@ -10,7 +10,7 @@ echo $dom->saveHtml(), "\n"; ?> --EXPECTF-- -Warning: Dom\HTMLDocument::createFromFile(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: Dom\HTMLDocument::createFromFile(): Failed to open stream: No such file or directory in %s on line %d Fatal error: Uncaught Exception: Cannot open file '%s' in %s:%d Stack trace: diff --git a/ext/dom/tests/modern/html/parser/gh21486.phpt b/ext/dom/tests/modern/html/parser/gh21486.phpt new file mode 100644 index 000000000000..62df1e5ca6bd --- /dev/null +++ b/ext/dom/tests/modern/html/parser/gh21486.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-21486 (Dom\HTMLDocument parser mangles xml:space and xml:lang attributes) +--EXTENSIONS-- +dom +--CREDITS-- +JKingweb +--FILE-- +"); +$e = $d->getElementsByTagName("div")[0]; +$e->innerHTML = ''; +$svg = $d->querySelector("svg"); +echo $e->innerHTML."\n"; +echo $svg->attributes[0]->localName." ".var_export($svg->attributes[0]->namespaceURI, true)."\n"; +?> +--EXPECT-- + +space 'http://www.w3.org/XML/1998/namespace' diff --git a/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt b/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt index 78625fcb6f7d..cb623f702983 100644 --- a/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt +++ b/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt @@ -14,5 +14,5 @@ try { echo $dom->saveXml(); ?> --EXPECT-- -Cannot modify readonly property Dom\HTMLElement::$prefix +Cannot modify private(set) property Dom\Element::$prefix from global scope diff --git a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt index f9bb1f7a996e..4ac15a029e37 100644 --- a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt +++ b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt @@ -21,7 +21,6 @@ var_dump($doctype); var_dump($doctype->entities["test"]); var_dump($doctype->entities["myimage"]); -// TODO: isConnected returning false is a bug var_dump($doctype->notations["GIF"]); ?> @@ -142,17 +141,19 @@ object(Dom\Entity)#3 (17) { ["textContent"]=> NULL } -object(Dom\Notation)#4 (13) { +object(Dom\Notation)#4 (14) { ["nodeType"]=> int(12) ["nodeName"]=> string(3) "GIF" ["baseURI"]=> - string(11) "about:blank" + string(%d) "%s" ["isConnected"]=> - bool(false) + bool(true) + ["ownerDocument"]=> + string(22) "(object value omitted)" ["parentNode"]=> - NULL + string(22) "(object value omitted)" ["parentElement"]=> NULL ["childNodes"]=> @@ -168,5 +169,5 @@ object(Dom\Notation)#4 (13) { ["nodeValue"]=> NULL ["textContent"]=> - string(0) "" + NULL } diff --git a/ext/dom/tests/modern/xml/DtdNamedNodeMap_dimension_index_overflow_64.phpt b/ext/dom/tests/modern/xml/DtdNamedNodeMap_dimension_index_overflow_64.phpt new file mode 100644 index 000000000000..cc2d7a06a2ca --- /dev/null +++ b/ext/dom/tests/modern/xml/DtdNamedNodeMap_dimension_index_overflow_64.phpt @@ -0,0 +1,41 @@ +--TEST-- +Dom\DtdNamedNodeMap dimension access handles invalid integer indexes +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- + + +]> + +XML); + +$overflow = 4294967296; + +function dump_access(Closure $callback): void { + try { + var_dump($callback()?->nodeName); + } catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; + } +} + +dump_access(fn() => $doc->doctype->entities[-1]); +dump_access(fn() => $doc->doctype->entities[$overflow]); + +dump_access(fn() => $doc->doctype->notations[-1]); +dump_access(fn() => $doc->doctype->notations[$overflow]); +?> +--EXPECT-- +NULL +must be between 0 and 2147483647 +NULL +must be between 0 and 2147483647 diff --git a/ext/dom/tests/modern/xml/XMLDocument_node_notation_wiring.phpt b/ext/dom/tests/modern/xml/XMLDocument_node_notation_wiring.phpt new file mode 100644 index 000000000000..dd74a2737594 --- /dev/null +++ b/ext/dom/tests/modern/xml/XMLDocument_node_notation_wiring.phpt @@ -0,0 +1,101 @@ +--TEST-- +Dom\XMLDocument: Dom\Notation nodes are connected to their document and doctype +--EXTENSIONS-- +dom +--FILE-- + '', + 'JPEG' => '', + 'HTML' => '', +]; + +foreach ($cases as $name => $declaration) { + $xml = << + +XML; + + $dom = Dom\XMLDocument::createFromString($xml); + $doctype = $dom->doctype; + $notations = $doctype->notations; + + echo "=== $name ===\n"; + + $namedNotation = $notations->getNamedItem($name); + foreach ($notations as $iteratedNotation) { + // getNamedItem + var_dump($namedNotation->nodeName); + var_dump($namedNotation->textContent); + var_dump($namedNotation->nodeValue); + var_dump($namedNotation->isConnected); + var_dump($namedNotation->ownerDocument === $dom); + var_dump($namedNotation->parentNode === $doctype); + var_dump($namedNotation->parentElement); + + // iteration + var_dump($iteratedNotation->nodeName); + var_dump($iteratedNotation->textContent); + var_dump($iteratedNotation->nodeValue); + var_dump($iteratedNotation->isConnected); + var_dump($iteratedNotation->ownerDocument === $dom); + var_dump($iteratedNotation->parentNode === $doctype); + var_dump($iteratedNotation->parentElement); + + // wiring + // getNamedItem and iteration each allocate a fresh Notation instance + var_dump($namedNotation !== $iteratedNotation); + } +} +?> +--EXPECT-- +=== GIF === +string(3) "GIF" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(3) "GIF" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) +=== JPEG === +string(4) "JPEG" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(4) "JPEG" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) +=== HTML === +string(4) "HTML" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(4) "HTML" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) diff --git a/ext/dom/tests/modern/xml/gh21544.phpt b/ext/dom/tests/modern/xml/gh21544.phpt new file mode 100644 index 000000000000..b76742ae84a5 --- /dev/null +++ b/ext/dom/tests/modern/xml/gh21544.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-21544 (Dom\XMLDocument::C14N() drops namespace declarations on DOM-built documents) +--CREDITS-- +Toon Verwerft (veewee) +--EXTENSIONS-- +dom +--FILE-- +createElementNS("urn:envelope", "env:Root"); +$doc->appendChild($root); +$child = $doc->createElementNS("urn:child", "x:Child"); +$root->appendChild($child); + +$parsed = Dom\XMLDocument::createFromString( + '' +); + +echo "DOM-built C14N: " . $doc->C14N() . PHP_EOL; +echo "Parsed C14N: " . $parsed->C14N() . PHP_EOL; +var_dump($doc->C14N() === $parsed->C14N()); + +?> +--EXPECT-- +DOM-built C14N: +Parsed C14N: +bool(true) diff --git a/ext/dom/tests/modern/xml/gh21548.phpt b/ext/dom/tests/modern/xml/gh21548.phpt new file mode 100644 index 000000000000..55299c8d6e67 --- /dev/null +++ b/ext/dom/tests/modern/xml/gh21548.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-21548 (Dom\XMLDocument::C14N() emits duplicate xmlns declarations after setAttributeNS()) +--CREDITS-- +Toon Verwerft (veewee) +--EXTENSIONS-- +dom +--FILE-- +'); +$doc->documentElement->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns1", "urn:a"); + +echo $doc->C14N() . PHP_EOL; + +?> +--EXPECT-- + diff --git a/ext/dom/tests/modern/xml/gh22570.phpt b/ext/dom/tests/modern/xml/gh22570.phpt new file mode 100644 index 000000000000..3d648aac5e4d --- /dev/null +++ b/ext/dom/tests/modern/xml/gh22570.phpt @@ -0,0 +1,42 @@ +--TEST-- +GH-22570 (Stack overflow when serializing a deeply nested Dom\XMLDocument) +--EXTENSIONS-- +dom +--SKIPIF-- + +--INI-- +zend.max_allowed_stack_size=512K +--FILE-- +createElement('a'); +for ($i = 0; $i < 100000; $i++) { + $parent = $doc->createElement('a'); + $parent->appendChild($node); + $node = $parent; +} +$doc->appendChild($node); + +try { + $doc->saveXml(); +} catch (\Error $e) { + echo "saveXml: ", $e::class, ": ", $e->getMessage(), "\n"; +} + +try { + $doc->documentElement->innerHTML; +} catch (\Error $e) { + echo "innerHTML: ", $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +saveXml: Error: Maximum call stack size reached. Infinite recursion? +innerHTML: Error: Maximum call stack size reached. Infinite recursion? diff --git a/ext/dom/tests/property_write_errors.phpt b/ext/dom/tests/property_write_errors.phpt index 58cf800728a6..7d2af3b10555 100644 --- a/ext/dom/tests/property_write_errors.phpt +++ b/ext/dom/tests/property_write_errors.phpt @@ -49,8 +49,8 @@ try { ?> --EXPECT-- Cannot assign array to property DOMNode::$nodeValue of type ?string -Cannot modify readonly property DOMDocument::$nodeType -Cannot modify readonly property DOMDocument::$xmlEncoding -Cannot modify readonly property DOMEntity::$actualEncoding -Cannot modify readonly property DOMEntity::$encoding -Cannot modify readonly property DOMEntity::$version +Cannot modify private(set) property DOMNode::$nodeType from global scope +Cannot modify private(set) property DOMDocument::$xmlEncoding from global scope +Cannot modify private(set) property DOMEntity::$actualEncoding from global scope +Cannot modify private(set) property DOMEntity::$encoding from global scope +Cannot modify private(set) property DOMEntity::$version from global scope diff --git a/ext/dom/tests/xpath_php_function_removes_argument_node.phpt b/ext/dom/tests/xpath_php_function_removes_argument_node.phpt new file mode 100644 index 000000000000..e6696617be25 --- /dev/null +++ b/ext/dom/tests/xpath_php_function_removes_argument_node.phpt @@ -0,0 +1,33 @@ +--TEST-- +DOMXPath: a php:function callback that removes its argument node must not free it mid-evaluation +--EXTENSIONS-- +dom +--FILE-- +loadXML('1234'); +$xp = new DOMXPath($doc); +$xp->registerNamespace('php', 'http://php.net/xpath'); +$xp->registerPhpFunctions(); + +function cb($nodes) { + foreach ($nodes as $n) { + if ($n->parentNode) { + $n->parentNode->removeChild($n); + } + } + return true; +} + +$res = $xp->query('//a[php:function("cb", .)]'); +foreach ($res as $r) { + var_dump($r->nodeName); +} +echo "done\n"; +?> +--EXPECT-- +string(1) "a" +string(1) "a" +string(1) "a" +string(1) "a" +done diff --git a/ext/dom/text.c b/ext/dom/text.c index 4c503201c8bf..357ff1969490 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | diff --git a/ext/dom/token_list.c b/ext/dom/token_list.c index 84a3dc10afeb..0e7797616554 100644 --- a/ext/dom/token_list.c +++ b/ext/dom/token_list.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ @@ -486,7 +484,7 @@ static bool dom_validate_tokens_varargs(const zval *args, uint32_t argc) { for (uint32_t i = 0; i < argc; i++) { if (Z_TYPE(args[i]) != IS_STRING) { - zend_argument_type_error(i + 1, "must be of type string, %s given", zend_zval_value_name(&args[i])); + zend_wrong_parameter_type_error(i + 1, Z_EXPECTED_STRING, &args[i]); return false; } @@ -577,7 +575,7 @@ PHP_METHOD(Dom_TokenList, toggle) HashTable *token_set = TOKEN_LIST_GET_SET(intern); zval *found_token = zend_hash_find(token_set, token); if (found_token != NULL) { - ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0 && "the cast only works if this is true"); + ZEND_ASSERT(offsetof(Bucket, val) == 0 && "the cast only works if this is true"); Bucket *bucket = (Bucket *) found_token; /* 3.1. If force is either not given or is false, then remove token from this’s token set, @@ -627,7 +625,7 @@ PHP_METHOD(Dom_TokenList, replace) } /* 4. Replace token in this’s token set with newToken. */ - ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0 && "the cast only works if this is true"); + ZEND_ASSERT(offsetof(Bucket, val) == 0 && "the cast only works if this is true"); Bucket *bucket = (Bucket *) found_token; if (zend_hash_set_bucket_key(token_set, bucket, new_token) == NULL) { /* It already exists, remove token instead. */ diff --git a/ext/dom/token_list.h b/ext/dom/token_list.h index 7c8a6f612ffa..80cc094ddd83 100644 --- a/ext/dom/token_list.h +++ b/ext/dom/token_list.h @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ @@ -27,12 +25,12 @@ typedef struct dom_token_list_object { static inline dom_token_list_object *php_dom_token_list_from_obj(zend_object *obj) { - return (dom_token_list_object *)((char *) obj - XtOffsetOf(dom_token_list_object, dom.std)); + return (dom_token_list_object *)((char *) obj - offsetof(dom_token_list_object, dom.std)); } static inline dom_token_list_object *php_dom_token_list_from_dom_obj(dom_object *obj) { - return (dom_token_list_object *)((char *) obj - XtOffsetOf(dom_token_list_object, dom)); + return ZEND_CONTAINER_OF(obj, dom_token_list_object, dom); } void dom_ordered_set_parser(HashTable *token_set, const char *position, bool to_lowercase); diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index a63e43e92a77..ec45fcc08342 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -29,9 +27,7 @@ typedef struct _dom_object { zend_object std; } dom_object; -static inline dom_object *php_dom_obj_from_obj(zend_object *obj) { - return (dom_object*)((char*)(obj) - XtOffsetOf(dom_object, std)); -} +#define php_dom_obj_from_obj(obj) ZEND_CONTAINER_OF(obj, dom_object, std) #define Z_DOMOBJ_P(zv) php_dom_obj_from_obj(Z_OBJ_P((zv))) diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c index 66fd1d707aa0..707356227afe 100644 --- a/ext/dom/xml_document.c +++ b/ext/dom/xml_document.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ @@ -147,7 +145,7 @@ static void load_from_helper(INTERNAL_FUNCTION_PARAMETERS, int mode) } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/xml_serializer.c b/ext/dom/xml_serializer.c index 7684057a391c..0d6b320dd0ef 100644 --- a/ext/dom/xml_serializer.c +++ b/ext/dom/xml_serializer.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ @@ -1250,6 +1248,15 @@ static int dom_xml_serializing_a_document_node( return 0; } +static zend_always_inline bool dom_xml_serialize_check_stack_limit(void) +{ +#ifdef ZEND_CHECK_STACK_LIMIT + return zend_call_stack_overflowed(EG(stack_limit)); +#else + return false; +#endif +} + /* https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-algorithm */ static int dom_xml_serialization_algorithm( dom_xml_serialize_ctx *ctx, @@ -1261,6 +1268,11 @@ static int dom_xml_serialization_algorithm( bool require_well_formed ) { + if (UNEXPECTED(dom_xml_serialize_check_stack_limit())) { + zend_throw_error(NULL, "Maximum call stack size reached. Infinite recursion?"); + return -1; + } + /* If node's interface is: */ switch (node->type) { case XML_ELEMENT_NODE: diff --git a/ext/dom/xml_serializer.h b/ext/dom/xml_serializer.h index 2d5c3bd84277..4ada97f0e796 100644 --- a/ext/dom/xml_serializer.h +++ b/ext/dom/xml_serializer.h @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index ce17c0810835..dc9e1b852fae 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -35,6 +33,24 @@ #ifdef LIBXML_XPATH_ENABLED +static dom_object *dom_xpath_intern_for_doc(dom_xpath_object *xpath_obj, xmlDocPtr doc) +{ + if (xpath_obj->dom.document && xpath_obj->dom.document->ptr == doc) { + return &xpath_obj->dom; + } + HashTable *node_list = xpath_obj->xpath_callbacks.node_list; + if (node_list) { + zval *entry; + ZEND_HASH_PACKED_FOREACH_VAL(node_list, entry) { + dom_object *obj = Z_DOMOBJ_P(entry); + if (obj->document && obj->document->ptr == doc) { + return obj; + } + } ZEND_HASH_FOREACH_END(); + } + return &xpath_obj->dom; +} + void dom_xpath_objects_free_storage(zend_object *object) { dom_xpath_object *intern = php_xpath_obj_from_obj(object); @@ -61,7 +77,8 @@ static void dom_xpath_proxy_factory(xmlNodePtr node, zval *child, dom_object *in ZEND_ASSERT(node->type != XML_NAMESPACE_DECL); - php_dom_create_object(node, child, intern); + dom_xpath_object *xobj = php_xpath_obj_from_obj(&intern->std); + php_dom_create_object(node, child, dom_xpath_intern_for_doc(xobj, node->doc)); } static dom_xpath_object *dom_xpath_ext_fetch_intern(xmlXPathParserContextPtr ctxt) @@ -191,7 +208,7 @@ zend_result dom_xpath_document_read(dom_object *obj, zval *retval) /* {{{ registerNodeNamespaces bool*/ static inline dom_xpath_object *php_xpath_obj_from_dom_obj(dom_object *obj) { - return (dom_xpath_object*)((char*)(obj) - XtOffsetOf(dom_xpath_object, dom)); + return ZEND_CONTAINER_OF(obj, dom_xpath_object, dom); } zend_result dom_xpath_register_node_ns_read(dom_object *obj, zval *retval) @@ -354,7 +371,8 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) node = php_dom_create_fake_namespace_decl(nsparent, original, &child, parent_intern); } else { - php_dom_create_object(node, &child, &intern->dom); + dom_object *parent = dom_xpath_intern_for_doc(intern, node->doc); + php_dom_create_object(node, &child, parent); } add_next_index_zval(&retval, &child); } diff --git a/ext/dom/xpath_callbacks.c b/ext/dom/xpath_callbacks.c index 816c925435ae..349c304c9f25 100644 --- a/ext/dom/xpath_callbacks.c +++ b/ext/dom/xpath_callbacks.c @@ -1,18 +1,16 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | - | Niels Dossche | + | Nora Dossche | +----------------------------------------------------------------------+ */ @@ -349,15 +347,15 @@ static zval *php_dom_xpath_callback_fetch_args(xmlXPathParserContextPtr ctxt, ui xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; if (UNEXPECTED(node->type == XML_NAMESPACE_DECL)) { - xmlNodePtr nsparent = node->_private; xmlNsPtr original = (xmlNsPtr) node; /* Make sure parent dom object exists, so we can take an extra reference. */ zval parent_zval; /* don't destroy me, my lifetime is transferred to the fake namespace decl */ - php_dom_create_object(nsparent, &parent_zval, intern); + proxy_factory(node->_private, &parent_zval, intern, ctxt); dom_object *parent_intern = Z_DOMOBJ_P(&parent_zval); + xmlNodePtr parent = dom_object_get_node(parent_intern); - php_dom_create_fake_namespace_decl(nsparent, original, &child, parent_intern); + php_dom_create_fake_namespace_decl(parent, original, &child, parent_intern); } else { proxy_factory(node, &child, intern, ctxt); } @@ -381,11 +379,19 @@ static zval *php_dom_xpath_callback_fetch_args(xmlXPathParserContextPtr ctxt, ui return params; } -static void php_dom_xpath_callback_cleanup_args(zval *params, uint32_t param_count) +static void php_dom_xpath_callback_cleanup_args(php_dom_xpath_callbacks *xpath_callbacks, zval *params, uint32_t param_count) { if (params) { for (uint32_t i = 0; i < param_count; i++) { - zval_ptr_dtor(¶ms[i]); + zval *param = ¶ms[i]; + if (Z_TYPE_P(param) == IS_OBJECT || Z_TYPE_P(param) == IS_ARRAY) { + if (xpath_callbacks->node_list == NULL) { + xpath_callbacks->node_list = zend_new_array(0); + } + zend_hash_next_index_insert_new(xpath_callbacks->node_list, param); + } else { + zval_ptr_dtor(param); + } } efree(params); } @@ -408,6 +414,7 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat fci.param_count = param_count; fci.params = params; fci.named_params = NULL; + fci.consumed_args = 0; ZVAL_STRINGL(&fci.function_name, function_name, function_name_length); zend_call_function(&fci, NULL); @@ -479,7 +486,7 @@ PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_call_php_ns(php_dom_xpath_cal cleanup: xmlXPathFreeObject(obj); - php_dom_xpath_callback_cleanup_args(params, param_count); + php_dom_xpath_callback_cleanup_args(xpath_callbacks, params, param_count); cleanup_no_obj: if (UNEXPECTED(result != SUCCESS)) { /* Push sentinel value */ @@ -507,7 +514,7 @@ PHP_DOM_EXPORT zend_result php_dom_xpath_callbacks_call_custom_ns(php_dom_xpath_ zend_result result = php_dom_xpath_callback_dispatch(xpath_callbacks, ns, ctxt, params, param_count, function_name, function_name_length); - php_dom_xpath_callback_cleanup_args(params, param_count); + php_dom_xpath_callback_cleanup_args(xpath_callbacks, params, param_count); if (UNEXPECTED(result != SUCCESS)) { /* Push sentinel value */ valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); diff --git a/ext/dom/xpath_callbacks.h b/ext/dom/xpath_callbacks.h index 3a4d8731f474..4bf79b5df84f 100644 --- a/ext/dom/xpath_callbacks.h +++ b/ext/dom/xpath_callbacks.h @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 43547ab9b5dc..a109c24062f0 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre-Alain Joye | | Ilia Alshanetsky | @@ -50,9 +48,7 @@ typedef struct _dict_struct { zend_class_entry *enchant_broker_ce; static zend_object_handlers enchant_broker_handlers; -static inline enchant_broker *enchant_broker_from_obj(zend_object *obj) { - return (enchant_broker *)((char *)(obj) - XtOffsetOf(enchant_broker, std)); -} +#define enchant_broker_from_obj(obj) ZEND_CONTAINER_OF(obj, enchant_broker, std) #define Z_ENCHANT_BROKER_P(zv) enchant_broker_from_obj(Z_OBJ_P(zv)) @@ -68,9 +64,7 @@ static zend_object *enchant_broker_create_object(zend_class_entry *class_type) { zend_class_entry *enchant_dict_ce; static zend_object_handlers enchant_dict_handlers; -static inline enchant_dict *enchant_dict_from_obj(zend_object *obj) { - return (enchant_dict *)((char *)(obj) - XtOffsetOf(enchant_dict, std)); -} +#define enchant_dict_from_obj(obj) ZEND_CONTAINER_OF(obj, enchant_dict, std) #define Z_ENCHANT_DICT_P(zv) enchant_dict_from_obj(Z_OBJ_P(zv)) @@ -192,7 +186,7 @@ PHP_MINIT_FUNCTION(enchant) enchant_broker_ce->default_object_handlers = &enchant_broker_handlers; memcpy(&enchant_broker_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - enchant_broker_handlers.offset = XtOffsetOf(enchant_broker, std); + enchant_broker_handlers.offset = offsetof(enchant_broker, std); enchant_broker_handlers.free_obj = php_enchant_broker_free; enchant_broker_handlers.clone_obj = NULL; enchant_broker_handlers.compare = zend_objects_not_comparable; @@ -202,7 +196,7 @@ PHP_MINIT_FUNCTION(enchant) enchant_dict_ce->default_object_handlers = &enchant_dict_handlers; memcpy(&enchant_dict_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - enchant_dict_handlers.offset = XtOffsetOf(enchant_dict, std); + enchant_dict_handlers.offset = offsetof(enchant_dict, std); enchant_dict_handlers.free_obj = php_enchant_dict_free; enchant_dict_handlers.clone_obj = NULL; enchant_dict_handlers.compare = zend_objects_not_comparable; @@ -346,12 +340,10 @@ PHP_FUNCTION(enchant_broker_set_dict_path) case PHP_ENCHANT_MYSPELL: enchant_broker_set_param(pbroker->pbroker, "enchant.myspell.dictionary.path", value); RETURN_TRUE; - break; case PHP_ENCHANT_ISPELL: enchant_broker_set_param(pbroker->pbroker, "enchant.ispell.dictionary.path", value); RETURN_TRUE; - break; default: RETURN_FALSE; diff --git a/ext/enchant/php_enchant.h b/ext/enchant/php_enchant.h index 81150648d119..d87b2b6550ad 100644 --- a/ext/enchant/php_enchant.h +++ b/ext/enchant/php_enchant.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre-Alain Joye | +----------------------------------------------------------------------+ diff --git a/ext/enchant/tests/bug53070.phpt b/ext/enchant/tests/bug53070.phpt index 437565d58977..e3ff8a63012f 100644 --- a/ext/enchant/tests/bug53070.phpt +++ b/ext/enchant/tests/bug53070.phpt @@ -13,16 +13,16 @@ var_dump(enchant_broker_get_dict_path($broker, ENCHANT_MYSPELL)); var_dump(enchant_broker_get_dict_path($broker, ENCHANT_ISPELL)); ?> --EXPECTF-- -Deprecated: Constant ENCHANT_MYSPELL is deprecated in %s +Deprecated: Constant ENCHANT_MYSPELL is deprecated since 8.0, as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated in %s on line %d -Deprecated: Function enchant_broker_get_dict_path() is deprecated since 8.0 in %s +Deprecated: Function enchant_broker_get_dict_path() is deprecated since 8.0 in %s on line %d Warning: enchant_broker_get_dict_path(): dict_path not set in %s on line %d bool(false) -Deprecated: Constant ENCHANT_ISPELL is deprecated in %s +Deprecated: Constant ENCHANT_ISPELL is deprecated since 8.0, as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated in %s on line %d -Deprecated: Function enchant_broker_get_dict_path() is deprecated since 8.0 in %s +Deprecated: Function enchant_broker_get_dict_path() is deprecated since 8.0 in %s on line %d Warning: enchant_broker_get_dict_path(): dict_path not set in %s on line %d bool(false) diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 17dadc7539ba..a156a3a63ad2 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | @@ -71,7 +69,7 @@ PHP_MINFO_FUNCTION(exif) php_info_print_table_start(); php_info_print_table_row(2, "EXIF Support", "enabled"); php_info_print_table_row(2, "Supported EXIF Version", "0220"); - php_info_print_table_row(2, "Supported filetypes", "JPEG, TIFF"); + php_info_print_table_row(2, "Supported filetypes", "JPEG, TIFF, HEIF, WebP"); if (USE_MBSTRING) { php_info_print_table_row(2, "Multibyte decoding support using mbstring", "enabled"); @@ -2038,11 +2036,11 @@ static void exif_error_docref(const char *docref EXIFERR_DC, image_info_type *Im char *buf; spprintf(&buf, 0, "%s(%ld): %s", _file, _line, format); - php_verror(docref, ImageInfo && ImageInfo->FileName ? ImageInfo->FileName:"", type, buf, args); + php_verror(docref, type, buf, args); efree(buf); } #else - php_verror(docref, ImageInfo && ImageInfo->FileName ? ImageInfo->FileName:"", type, format, args); + php_verror(docref, type, format, args); #endif va_end(args); } @@ -2217,7 +2215,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c switch (format) { case TAG_FMT_STRING: if (length > value_len) { - exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len); + exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len); value = NULL; } if (value) { @@ -2247,7 +2245,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c ZEND_FALLTHROUGH; case TAG_FMT_UNDEFINED: if (length > value_len) { - exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len); + exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len); value = NULL; } if (value) { @@ -2320,13 +2318,13 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c #ifdef EXIF_DEBUG php_error_docref(NULL, E_WARNING, "Found value of type single"); #endif - info_value->f = php_ifd_get_float(value); + info_value->f = php_ifd_get_float(vptr); break; case TAG_FMT_DOUBLE: #ifdef EXIF_DEBUG php_error_docref(NULL, E_WARNING, "Found value of type double"); #endif - info_value->d = php_ifd_get_double(value); + info_value->d = php_ifd_get_double(vptr); break; } } @@ -3306,7 +3304,7 @@ static bool exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entr * relative to the start of the TIFF header in APP1 section. */ // TODO: Shouldn't we also be taking "displacement" into account here? if (byte_count > ImageInfo->FileSize || offset_val>ImageInfo->FileSize-byte_count || (ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_II && ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_MM && ImageInfo->FileType!=IMAGE_FILETYPE_JPEG)) { - exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname_debug(tag, tag_table), offset_val, byte_count, offset_val+byte_count, ImageInfo->FileSize); + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal pointer offset(x%04zX + x%04zX = x%04zX > x%04zX)", tag, exif_get_tagname_debug(tag, tag_table), offset_val, byte_count, offset_val+byte_count, ImageInfo->FileSize); return false; } if (byte_count>sizeof(cbuf)) { @@ -3328,7 +3326,7 @@ static bool exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entr size_t fgot = php_stream_tell(ImageInfo->infile); if (fgot!=displacement+offset_val) { EFREE_IF(outside); - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Wrong file pointer: 0x%08X != 0x%08X", fgot, displacement+offset_val); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Wrong file pointer: 0x%08zX != 0x%08zX", fgot, displacement+offset_val); return false; } fgot = exif_read_from_stream_file_looped(ImageInfo->infile, value_ptr, byte_count); @@ -3652,8 +3650,14 @@ static bool exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail */ if (!exif_offset_info_contains(info, dir_start+2+NumDirEntries*12, 4)) { - exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size"); - return false; + /* + * A TIFF/EXIF IFD ends with a 4-byte offset to the next IFD (IFD1 here, + * which links the thumbnail), or zero when there is none. Some files end + * the EXIF segment right after the entries and omit those 4 bytes. A + * missing offset is valid and just means there is no next IFD, so stop + * here instead of reporting the size as illegal. + */ + return true; } if (tag != TAG_EXIF_IFD_POINTER && tag != TAG_GPS_IFD_POINTER) { @@ -3752,7 +3756,7 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf, static void exif_process_APP1(image_info_type *ImageInfo, char *CharBuf, size_t length, size_t displacement) { /* Check the APP1 for Exif Identifier Code */ - static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + static const uchar ExifHeader[] = {'E', 'x', 'i', 'f', 0, 0}; if (length <= 8 || memcmp(CharBuf+2, ExifHeader, 6)) { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Incorrect APP1 Exif Identifier Code"); return; @@ -3862,7 +3866,7 @@ static bool exif_scan_JPEG_header(image_info_type *ImageInfo) got = exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(Data+2), itemlen-2); /* Read the whole section. */ if (got != itemlen-2) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error reading from file: got=x%04X(=%d) != itemlen-2=x%04X(=%d)", got, got, itemlen-2, itemlen-2); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error reading from file: got=x%04zX(=%zu) != itemlen-2=x%04zX(=%zu)", got, got, itemlen-2, itemlen-2); return false; } @@ -4026,7 +4030,6 @@ static bool exif_scan_thumbnail(image_info_type *ImageInfo) case M_EOI: exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Could not compute size of thumbnail"); return false; - break; default: /* just skip */ @@ -4147,7 +4150,7 @@ static bool exif_process_IFD_in_TIFF_impl(image_info_type *ImageInfo, size_t dir if (ImageInfo->FileSize >= ImageInfo->file.list[sn].size && ImageInfo->FileSize - ImageInfo->file.list[sn].size >= dir_offset) { if (ifd_size > dir_size) { if (ImageInfo->FileSize < ifd_size || dir_offset > ImageInfo->FileSize - ifd_size) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD(x%04zX + x%04zX)", ImageInfo->FileSize, dir_offset, ifd_size); return false; } if (exif_file_sections_realloc(ImageInfo, sn, ifd_size)) { @@ -4263,15 +4266,15 @@ static bool exif_process_IFD_in_TIFF_impl(image_info_type *ImageInfo, size_t dir } return true; } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X)", ImageInfo->FileSize, dir_offset+ImageInfo->file.list[sn].size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD(x%04zX)", ImageInfo->FileSize, dir_offset+ImageInfo->file.list[sn].size); return false; } } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+dir_size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD dir(x%04zX)", ImageInfo->FileSize, dir_offset+dir_size); return false; } } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than start of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+2); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than start of IFD dir(x%04zX)", ImageInfo->FileSize, dir_offset+2); return false; } } @@ -4448,6 +4451,53 @@ static bool exif_scan_HEIF_header(image_info_type *ImageInfo, unsigned char *buf return ret; } +static bool exif_scan_WEBP_header(image_info_type *ImageInfo, size_t riff_size) +{ + static const uchar ExifHeader[] = {'E', 'x', 'i', 'f', 0, 0}; + unsigned char chunk_header[8]; + size_t offset = 12; + size_t riff_end = riff_size <= ImageInfo->FileSize - 8 ? riff_size + 8 : ImageInfo->FileSize; + + while (offset + 8 <= riff_end) { + if ((php_stream_seek(ImageInfo->infile, offset, SEEK_SET) < 0) || + (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)chunk_header, 8) != 8)) { + return false; + } + + size_t chunk_size = php_ifd_get32u(chunk_header + 4, 0); + size_t payload_offset = offset + 8; + + if (chunk_size > riff_end - payload_offset) { + return false; + } + + if (!memcmp(chunk_header, "EXIF", 4)) { + size_t skip = 0; + bool ret = false; + + if (chunk_size < 8) { + return false; + } + + char *data = emalloc(chunk_size); + if (exif_read_from_stream_file_looped(ImageInfo->infile, data, chunk_size) == chunk_size) { + if (chunk_size >= sizeof(ExifHeader) + 8 && !memcmp(data, ExifHeader, sizeof(ExifHeader))) { + skip = sizeof(ExifHeader); + } + exif_process_TIFF_in_JPEG(ImageInfo, data + skip, chunk_size - skip, payload_offset + skip); + ret = true; + } + efree(data); + return ret; + } + + /* RIFF chunks are word-aligned: an odd payload is followed by a pad byte. */ + offset = payload_offset + chunk_size + (chunk_size & 1); + } + + return false; +} + /* {{{ exif_scan_FILE_header * Parse the marker stream until SOS or EOI is seen; */ static bool exif_scan_FILE_header(image_info_type *ImageInfo) @@ -4457,7 +4507,7 @@ static bool exif_scan_FILE_header(image_info_type *ImageInfo) ImageInfo->FileType = IMAGE_FILETYPE_UNKNOWN; if (UNEXPECTED(ImageInfo->FileSize < 2)) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File too small (%d)", ImageInfo->FileSize); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File too small (%zu)", ImageInfo->FileSize); return false; } @@ -4524,6 +4574,17 @@ static bool exif_scan_FILE_header(image_info_type *ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid HEIF file"); return false; } + } else if ((ImageInfo->FileSize >= 16) && + (!memcmp(file_header, "RIFF", 4)) && + (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(file_header + 8), 4) == 4) && + (!memcmp(file_header + 8, "WEBP", 4))) { + if (exif_scan_WEBP_header(ImageInfo, php_ifd_get32u(file_header + 4, 0))) { + ImageInfo->FileType = IMAGE_FILETYPE_WEBP; + return true; + } else { + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid WebP file"); + return false; + } } else { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File not supported"); return false; @@ -4877,7 +4938,7 @@ PHP_FUNCTION(exif_read_data) exif_discard_imageinfo(&ImageInfo); #ifdef EXIF_DEBUG - php_error_docref1(NULL, (Z_TYPE_P(stream) == IS_RESOURCE ? "" : Z_STRVAL_P(stream)), E_NOTICE, "Done"); + php_error_docref(NULL, E_NOTICE, "Done"); #endif } /* }}} */ @@ -4965,7 +5026,7 @@ PHP_FUNCTION(exif_thumbnail) exif_discard_imageinfo(&ImageInfo); #ifdef EXIF_DEBUG - php_error_docref1(NULL, (Z_TYPE_P(stream) == IS_RESOURCE ? "" : Z_STRVAL_P(stream)), E_NOTICE, "Done"); + php_error_docref(NULL, E_NOTICE, "Done"); #endif } /* }}} */ diff --git a/ext/exif/php_exif.h b/ext/exif/php_exif.h index 4ae5894f9036..5a4d2ec4d2a5 100644 --- a/ext/exif/php_exif.h +++ b/ext/exif/php_exif.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | diff --git a/ext/exif/tests/bug48378.phpt b/ext/exif/tests/bug48378.phpt index f626727dab15..64bb13a7f51a 100644 --- a/ext/exif/tests/bug48378.phpt +++ b/ext/exif/tests/bug48378.phpt @@ -10,8 +10,8 @@ __DIR__ . "/bug48378.jpg", ); ?> --EXPECTF-- -Warning: exif_read_data(%s): Invalid IFD start in %s48378.php on line %d +Warning: exif_read_data(): Invalid IFD start in %s48378.php on line %d -Warning: exif_read_data(%s): Error reading from file: got=x08B4(=2228) != itemlen-2=x1FFE(=8190) in %s48378.php on line %d +Warning: exif_read_data(): Error reading from file: got=x08B4(=2228) != itemlen-2=x1FFE(=8190) in %s48378.php on line %d -Warning: exif_read_data(%s): Invalid JPEG file in %s48378.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %s48378.php on line %d diff --git a/ext/exif/tests/bug54002.phpt b/ext/exif/tests/bug54002.phpt index 73b7bdc3fc9a..acc8a5c908d7 100644 --- a/ext/exif/tests/bug54002.phpt +++ b/ext/exif/tests/bug54002.phpt @@ -11,6 +11,6 @@ exif_read_data(__DIR__ . '/bug54002_2.jpg'); ?> --EXPECTF-- -Warning: exif_read_data(bug54002_1.jpg): Process tag(x0205=UndefinedTag): Illegal byte_count in %sbug54002.php on line %d +Warning: exif_read_data(): Process tag(x0205=UndefinedTag): Illegal byte_count in %sbug54002.php on line %d -Warning: exif_read_data(bug54002_2.jpg): Process tag(x0205=UndefinedTag): Illegal byte_count in %sbug54002.php on line %d +Warning: exif_read_data(): Process tag(x0205=UndefinedTag): Illegal byte_count in %sbug54002.php on line %d diff --git a/ext/exif/tests/bug60150.phpt b/ext/exif/tests/bug60150.phpt index 755834adb8b1..bc74a73e7f35 100644 --- a/ext/exif/tests/bug60150.phpt +++ b/ext/exif/tests/bug60150.phpt @@ -11,9 +11,9 @@ $infile = __DIR__.'/bug60150.jpg'; var_dump(exif_read_data($infile)); ?> --EXPECTF-- -Warning: exif_read_data(bug60150.jpg): Process tag(x9003=DateTimeOriginal): Illegal pointer offset(%s) in %s on line %d +Warning: exif_read_data(): Process tag(x9003=DateTimeOriginal): Illegal pointer offset(%s) in %s on line %d -Warning: exif_read_data(bug60150.jpg): Error reading from file: got=x%x(=%d) != itemlen-%d=x%x(=%d) in %s on line %d +Warning: exif_read_data(): Error reading from file: got=x%x(=%d) != itemlen-%d=x%x(=%d) in %s on line %d -Warning: exif_read_data(bug60150.jpg): Invalid JPEG file in %s on line %d +Warning: exif_read_data(): Invalid JPEG file in %s on line %d bool(false) diff --git a/ext/exif/tests/bug62523_3.phpt b/ext/exif/tests/bug62523_3.phpt index 6e433ff5307f..ae1330120cfe 100644 --- a/ext/exif/tests/bug62523_3.phpt +++ b/ext/exif/tests/bug62523_3.phpt @@ -11,6 +11,6 @@ Done --EXPECTF-- Test -Warning: exif_read_data(bug62523_3.jpg): File not supported in %sbug62523_3.php on line %d +Warning: exif_read_data(): File not supported in %sbug62523_3.php on line %d bool(false) Done diff --git a/ext/exif/tests/bug68113-mb.phpt b/ext/exif/tests/bug68113-mb.phpt index 1c3a2b651127..b05c7a4ef15b 100644 --- a/ext/exif/tests/bug68113-mb.phpt +++ b/ext/exif/tests/bug68113-mb.phpt @@ -8,8 +8,8 @@ var_dump(exif_thumbnail(__DIR__."/bug68113私はガラスを食べられます.j ?> Done --EXPECTF-- -Warning: exif_thumbnail(bug68113私はガラスを食べられます.jpg): File structure corrupted in %s%ebug68113-mb.php on line 2 +Warning: exif_thumbnail(): File structure corrupted in %s%ebug68113-mb.php on line 2 -Warning: exif_thumbnail(bug68113私はガラスを食べられます.jpg): Invalid JPEG file in %s%ebug68113-mb.php on line 2 +Warning: exif_thumbnail(): Invalid JPEG file in %s%ebug68113-mb.php on line 2 bool(false) Done diff --git a/ext/exif/tests/bug68113.phpt b/ext/exif/tests/bug68113.phpt index a617fdcb5167..3892dc6566e0 100644 --- a/ext/exif/tests/bug68113.phpt +++ b/ext/exif/tests/bug68113.phpt @@ -8,8 +8,8 @@ var_dump(exif_thumbnail(__DIR__."/bug68113.jpg")); ?> Done --EXPECTF-- -Warning: exif_thumbnail(bug68113.jpg): File structure corrupted in %s%ebug68113.php on line 2 +Warning: exif_thumbnail(): File structure corrupted in %s%ebug68113.php on line 2 -Warning: exif_thumbnail(bug68113.jpg): Invalid JPEG file in %s%ebug68113.php on line 2 +Warning: exif_thumbnail(): Invalid JPEG file in %s%ebug68113.php on line 2 bool(false) Done diff --git a/ext/exif/tests/bug72094.phpt b/ext/exif/tests/bug72094.phpt index c13a85f93f04..0fb24c8a391d 100644 --- a/ext/exif/tests/bug72094.phpt +++ b/ext/exif/tests/bug72094.phpt @@ -11,51 +11,49 @@ print_r(exif_read_data(__DIR__ . '/bug72094_4.jpg')); ?> DONE --EXPECTF-- -Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Process tag(x8298=Copyright): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x8298=Copyright): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Illegal IFD offset in %sbug72094.php on line %d +Warning: exif_read_data(): Illegal IFD offset in %sbug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): File structure corrupted in %s%ebug72094.php on line %d +Warning: exif_read_data(): File structure corrupted in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Invalid JPEG file in %s%ebug72094.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_2.jpg): Illegal IFD size in %s%ebug72094.php on line %d +Warning: exif_read_data(): Illegal IFD size in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_2.jpg): File structure corrupted in %s%ebug72094.php on line %d +Warning: exif_read_data(): File structure corrupted in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_2.jpg): Invalid JPEG file in %s%ebug72094.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Illegal IFD size in %s%ebug72094.php on line %d +Warning: exif_read_data(): File structure corrupted in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): File structure corrupted in %s%ebug72094.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Invalid JPEG file in %s%ebug72094.php on line %d +Warning: exif_read_data(): Invalid TIFF start (1) in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_4.jpg): Invalid TIFF start (1) in %s%ebug72094.php on line %d +Warning: exif_read_data(): File structure corrupted in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_4.jpg): File structure corrupted in %s%ebug72094.php on line %d - -Warning: exif_read_data(bug72094_4.jpg): Invalid JPEG file in %s%ebug72094.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %s%ebug72094.php on line %d DONE diff --git a/ext/exif/tests/bug72603.phpt b/ext/exif/tests/bug72603.phpt index d18790082a9c..43e1e322271f 100644 --- a/ext/exif/tests/bug72603.phpt +++ b/ext/exif/tests/bug72603.phpt @@ -7,5 +7,5 @@ exif var_dump(count(exif_read_data(__DIR__ . "/bug72603.jpg"))); ?> --EXPECTF-- -Warning: exif_read_data(bug72603.jpg): %s in %s%ebug72603.php on line %d +Warning: exif_read_data(): %s in %s%ebug72603.php on line %d int(%d) diff --git a/ext/exif/tests/bug72618.phpt b/ext/exif/tests/bug72618.phpt index 0625b5333d3e..287324a86fed 100644 --- a/ext/exif/tests/bug72618.phpt +++ b/ext/exif/tests/bug72618.phpt @@ -7,5 +7,5 @@ exif var_dump(count(exif_read_data(__DIR__ . "/bug72618.jpg"))); ?> --EXPECTF-- -Warning: exif_read_data(bug72618.jpg): %s in %s%ebug72618.php on line %d +Warning: exif_read_data(): %s in %s%ebug72618.php on line %d int(%d) diff --git a/ext/exif/tests/bug72627.phpt b/ext/exif/tests/bug72627.phpt index b0bc50777bba..b08ea3e61a52 100644 --- a/ext/exif/tests/bug72627.phpt +++ b/ext/exif/tests/bug72627.phpt @@ -8,11 +8,11 @@ exif var_dump($exif); ?> --EXPECTF-- -Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d +Warning: exif_read_data(): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d -Warning: exif_read_data(%s): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d +Warning: exif_read_data(): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d -Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d +Warning: exif_read_data(): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d array(11) { ["FileName"]=> string(13) "bug72627.tiff" diff --git a/ext/exif/tests/bug73737.phpt b/ext/exif/tests/bug73737.phpt index a5a03cb67594..7700ef510bc3 100644 --- a/ext/exif/tests/bug73737.phpt +++ b/ext/exif/tests/bug73737.phpt @@ -8,7 +8,7 @@ exif var_dump($exif); ?> --EXPECTF-- -Warning: exif_thumbnail(bug73737.tiff): Process tag(x0100=ImageWidth): Cannot be empty in %s on line %d +Warning: exif_thumbnail(): Process tag(x0100=ImageWidth): Cannot be empty in %s on line %d -Warning: exif_thumbnail(bug73737.tiff): Error in TIFF: filesize(x0030) less than start of IFD dir(x10102) in %s line %d +Warning: exif_thumbnail(): Error in TIFF: filesize(x0030) less than start of IFD dir(x10102) in %s line %d bool(false) diff --git a/ext/exif/tests/bug76423.phpt b/ext/exif/tests/bug76423.phpt index 425e679ec9b9..8177073a542d 100644 --- a/ext/exif/tests/bug76423.phpt +++ b/ext/exif/tests/bug76423.phpt @@ -7,8 +7,8 @@ exif exif_read_data(__DIR__ . '/bug76423.jpg', 0, true, true); ?> --EXPECTF-- -Warning: exif_read_data(%s.jpg): Thumbnail goes IFD boundary or end of file reached in %s on line %d +Warning: exif_read_data(): Thumbnail goes IFD boundary or end of file reached in %s on line %d -Warning: exif_read_data(%s.jpg): File structure corrupted in %s on line %d +Warning: exif_read_data(): File structure corrupted in %s on line %d -Warning: exif_read_data(%s.jpg): Invalid JPEG file in %s on line %d +Warning: exif_read_data(): Invalid JPEG file in %s on line %d diff --git a/ext/exif/tests/bug76557.phpt b/ext/exif/tests/bug76557.phpt index 64a5d5e5e219..a27f9b3805ab 100644 --- a/ext/exif/tests/bug76557.phpt +++ b/ext/exif/tests/bug76557.phpt @@ -8,25 +8,25 @@ var_dump(exif_read_data(__DIR__ . "/bug76557.jpg")); ?> DONE --EXPECTF-- -Warning: exif_read_data(bug76557.jpg): Process tag(x010F=Make): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x010F=Make): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d +Warning: exif_read_data(): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d Warning: exif_read_data(): Further exif parsing errors have been suppressed in %s on line %d bool(false) diff --git a/ext/exif/tests/bug77563.phpt b/ext/exif/tests/bug77563.phpt index d78f6213ecde..b93b5c2542b7 100644 --- a/ext/exif/tests/bug77563.phpt +++ b/ext/exif/tests/bug77563.phpt @@ -8,11 +8,11 @@ $s = exif_thumbnail(__DIR__."/bug77563.jpg"); ?> DONE --EXPECTF-- -Warning: exif_thumbnail(bug77563.jpg): IFD data too short: 0x0009 offset 0x0008 in %s%ebug77563.php on line %d +Warning: exif_thumbnail(): IFD data too short: 0x0009 offset 0x0008 in %s%ebug77563.php on line %d -Warning: exif_thumbnail(bug77563.jpg): Illegal IFD offset in %s%ebug77563.php on line %d +Warning: exif_thumbnail(): Illegal IFD offset in %s%ebug77563.php on line %d -Warning: exif_thumbnail(bug77563.jpg): File structure corrupted in %s%ebug77563.php on line %d +Warning: exif_thumbnail(): File structure corrupted in %s%ebug77563.php on line %d -Warning: exif_thumbnail(bug77563.jpg): Invalid JPEG file in %s%ebug77563.php on line %d +Warning: exif_thumbnail(): Invalid JPEG file in %s%ebug77563.php on line %d DONE diff --git a/ext/exif/tests/bug77564/bug77564.phpt b/ext/exif/tests/bug77564/bug77564.phpt index d940c525ef4c..0ae9bb5f01d7 100644 --- a/ext/exif/tests/bug77564/bug77564.phpt +++ b/ext/exif/tests/bug77564/bug77564.phpt @@ -9,10 +9,10 @@ var_dump(exif_read_data(__DIR__ . '/bug77564.jpg')); DONE --EXPECTF-- -Warning: exif_read_data(bug77564.jpg): Illegal IFD offset in %sbug77564.php on line %d +Warning: exif_read_data(): Illegal IFD offset in %sbug77564.php on line %d -Warning: exif_read_data(bug77564.jpg): File structure corrupted in %sbug77564.php on line %d +Warning: exif_read_data(): File structure corrupted in %sbug77564.php on line %d -Warning: exif_read_data(bug77564.jpg): Invalid JPEG file in %sbug77564.php on line %d +Warning: exif_read_data(): Invalid JPEG file in %sbug77564.php on line %d bool(false) DONE diff --git a/ext/exif/tests/exif_imagetype_error.phpt b/ext/exif/tests/exif_imagetype_error.phpt index 2d78234c2f0c..36fe66adb095 100644 --- a/ext/exif/tests/exif_imagetype_error.phpt +++ b/ext/exif/tests/exif_imagetype_error.phpt @@ -17,5 +17,5 @@ var_dump( exif_imagetype(__DIR__.'/foo.jpg') ); -- Testing exif_imagetype() function with an unknown file -- -Warning: exif_imagetype(%s/foo.jpg): Failed to open stream: No such file or directory in %s on line %d +Warning: exif_imagetype(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/exif/tests/gh11020.jpg b/ext/exif/tests/gh11020.jpg new file mode 100644 index 000000000000..1f978a757613 Binary files /dev/null and b/ext/exif/tests/gh11020.jpg differ diff --git a/ext/exif/tests/gh11020.phpt b/ext/exif/tests/gh11020.phpt new file mode 100644 index 000000000000..0c88605749b8 --- /dev/null +++ b/ext/exif/tests/gh11020.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-11020 (exif_read_data() emits a spurious "Illegal IFD size" warning when an IFD is not followed by a next-IFD offset) +--EXTENSIONS-- +exif +--FILE-- + +--EXPECT-- +bool(true) +int(1) diff --git a/ext/exif/tests/gh19904.phpt b/ext/exif/tests/gh19904.phpt new file mode 100644 index 000000000000..cc13d88dd98b --- /dev/null +++ b/ext/exif/tests/gh19904.phpt @@ -0,0 +1,82 @@ +--TEST-- +GH-19904 (exif_read_data() reads EXIF metadata from WebP images) +--EXTENSIONS-- +exif +--INI-- +output_handler= +zlib.output_compression=0 +--FILE-- + +--EXPECTF-- +array(26) { + ["FileName"]=> + string(12) "gh19904.webp" + ["FileDateTime"]=> + int(%d) + ["FileSize"]=> + int(526) + ["FileType"]=> + int(18) + ["MimeType"]=> + string(10) "image/webp" + ["SectionsFound"]=> + string(24) "ANY_TAG, IFD0, EXIF, GPS" + ["COMPUTED"]=> + array(4) { + ["IsColor"]=> + int(0) + ["ByteOrderMotorola"]=> + int(0) + ["UserComment"]=> + string(17) "Created with GIMP" + ["UserCommentEncoding"]=> + string(9) "UNDEFINED" + } + ["ImageWidth"]=> + int(100) + ["ImageLength"]=> + int(100) + ["BitsPerSample"]=> + array(3) { + [0]=> + int(8) + [1]=> + int(8) + [2]=> + int(8) + } + ["ImageDescription"]=> + string(17) "Created with GIMP" + ["XResolution"]=> + string(5) "300/1" + ["YResolution"]=> + string(5) "300/1" + ["ResolutionUnit"]=> + int(2) + ["Software"]=> + string(10) "GIMP 3.0.4" + ["DateTime"]=> + string(19) "2025:09:21 15:30:30" + ["Exif_IFD_Pointer"]=> + int(250) + ["GPS_IFD_Pointer"]=> + int(430) + ["DateTimeOriginal"]=> + string(19) "2025:09:21 15:29:27" + ["DateTimeDigitized"]=> + string(19) "2025:09:21 15:29:27" + ["OffsetTime"]=> + string(6) "+02:00" + ["OffsetTimeOriginal"]=> + string(6) "+02:00" + ["OffsetTimeDigitized"]=> + string(6) "+02:00" + ["UserComment"]=> + string(25) "%sCreated with GIMP" + ["ColorSpace"]=> + int(1) + ["GPSAltitude"]=> + string(5) "0/100" +} diff --git a/ext/exif/tests/gh19904.webp b/ext/exif/tests/gh19904.webp new file mode 100644 index 000000000000..12dbe96a845c Binary files /dev/null and b/ext/exif/tests/gh19904.webp differ diff --git a/ext/exif/tests/heic_box_overflow.phpt b/ext/exif/tests/heic_box_overflow.phpt index b3a5e42df91f..0291cea2bde3 100644 --- a/ext/exif/tests/heic_box_overflow.phpt +++ b/ext/exif/tests/heic_box_overflow.phpt @@ -23,5 +23,5 @@ var_dump(exif_read_data(__DIR__."/heic_box_overflow")); @unlink(__DIR__."/heic_box_overflow"); ?> --EXPECTF-- -Warning: exif_read_data(heic_box_overflow): Invalid HEIF file in %s on line %d +Warning: exif_read_data(): Invalid HEIF file in %s on line %d bool(false) diff --git a/ext/exif/tests/heic_iloc_underflow.phpt b/ext/exif/tests/heic_iloc_underflow.phpt index 9dd1878b60dd..49b498e1063f 100644 --- a/ext/exif/tests/heic_iloc_underflow.phpt +++ b/ext/exif/tests/heic_iloc_underflow.phpt @@ -15,5 +15,5 @@ var_dump(exif_read_data(__DIR__."/heic_iloc_underflow.heic")); @unlink(__DIR__."/heic_iloc_underflow.heic"); ?> --EXPECTF-- -Warning: exif_read_data(heic_iloc_underflow.heic): Invalid HEIF file in %s on line %d +Warning: exif_read_data(): Invalid HEIF file in %s on line %d bool(false) diff --git a/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt b/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt index 131b2c5be980..2857040ffa21 100644 --- a/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt +++ b/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt @@ -7,4 +7,4 @@ exif exif_read_data(__DIR__."/input"); ?> --EXPECTF-- -Warning: exif_read_data(%s): Invalid HEIF file in %s on line %d +Warning: exif_read_data(): Invalid HEIF file in %s on line %d diff --git a/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt b/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt index b03635400f0a..050ef5b47112 100644 --- a/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt +++ b/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt @@ -7,4 +7,4 @@ exif exif_read_data(__DIR__."/input"); ?> --EXPECTF-- -Warning: exif_read_data(%s): Invalid HEIF file in %s on line %d +Warning: exif_read_data(): Invalid HEIF file in %s on line %d diff --git a/ext/exif/tests/tag_with_illegal_zero_components.phpt b/ext/exif/tests/tag_with_illegal_zero_components.phpt index 68edb7ce3cb3..2605d6f595b3 100644 --- a/ext/exif/tests/tag_with_illegal_zero_components.phpt +++ b/ext/exif/tests/tag_with_illegal_zero_components.phpt @@ -9,9 +9,9 @@ var_dump(exif_read_data(__DIR__ . '/tag_with_illegal_zero_components.jpeg')); ?> --EXPECTF-- -Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): Process tag(x0202=JPEGInterchangeFormatLength): Cannot be empty in %s on line %d +Warning: exif_read_data(): Process tag(x0202=JPEGInterchangeFormatLength): Cannot be empty in %s on line %d -Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): File structure corrupted in %s on line %d +Warning: exif_read_data(): File structure corrupted in %s on line %d -Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): Invalid JPEG file in %s on line %d +Warning: exif_read_data(): Invalid JPEG file in %s on line %d bool(false) diff --git a/ext/ext_skel.php b/ext/ext_skel.php index d396dfa3da74..3237ca625c99 100755 --- a/ext/ext_skel.php +++ b/ext/ext_skel.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kalle Sommer Nielsen | +----------------------------------------------------------------------+ @@ -257,15 +255,13 @@ function process_source_tags($file, $short_name) { $header = <<<"HEADER" /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: $credits | +----------------------------------------------------------------------+ diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index d5b8eb59f0c9..c3c08327fbe2 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -36,11 +34,9 @@ #ifdef HAVE_LIBDL #ifdef PHP_WIN32 -#include "win32/param.h" #include "win32/winutil.h" #define GET_DL_ERROR() php_win_err() #else -#include #define GET_DL_ERROR() DL_ERROR() #endif #endif @@ -950,6 +946,7 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v fci.object = NULL; fci.param_count = callback_data->arg_count; fci.named_params = NULL; + fci.consumed_args = 0; if (callback_data->type->func.args) { int n = 0; @@ -1253,10 +1250,8 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name type = ZEND_FFI_TYPE(type->pointer.type); } if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name)); - return &EG(uninitialized_zval); - } + zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name)); + return &EG(uninitialized_zval); } field = zend_hash_find_ptr(&type->record.fields, field_name); @@ -1331,10 +1326,8 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam type = ZEND_FFI_TYPE(type->pointer.type); } if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name)); - return value; - } + zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name)); + return value; } field = zend_hash_find_ptr(&type->record.fields, field_name); @@ -2090,7 +2083,6 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) zend_hash_str_add(ht, "cdata", sizeof("cdata")-1, &tmp); *is_temp = 1; return ht; - break; case ZEND_FFI_TYPE_POINTER: if (*(void**)ptr == NULL) { ZVAL_NULL(&tmp); @@ -2145,7 +2137,6 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) // TODO: function name ??? *is_temp = 1; return ht; - break; default: ZEND_UNREACHABLE(); break; @@ -3107,17 +3098,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ FFI_G(default_type_attr) = ZEND_FFI_ATTR_STORED; if (zend_ffi_parse_decl(ZSTR_VAL(code), ZSTR_LEN(code)) == FAILURE) { - if (FFI_G(symbols)) { - zend_hash_destroy(FFI_G(symbols)); - efree(FFI_G(symbols)); - FFI_G(symbols) = NULL; - } - if (FFI_G(tags)) { - zend_hash_destroy(FFI_G(tags)); - efree(FFI_G(tags)); - FFI_G(tags) = NULL; - } - RETURN_THROWS(); + goto cleanup; } if (FFI_G(symbols)) { @@ -3130,7 +3111,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ addr = DL_FETCH_SYMBOL(handle, ZSTR_VAL(name)); if (!addr) { zend_throw_error(zend_ffi_exception_ce, "Failed resolving C variable '%s'", ZSTR_VAL(name)); - RETURN_THROWS(); + goto cleanup; } sym->addr = addr; } else if (sym->kind == ZEND_FFI_SYM_FUNC) { @@ -3140,7 +3121,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ zend_string_release(mangled_name); if (!addr) { zend_throw_error(zend_ffi_exception_ce, "Failed resolving C function '%s'", ZSTR_VAL(name)); - RETURN_THROWS(); + goto cleanup; } sym->addr = addr; } @@ -3157,6 +3138,22 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ FFI_G(tags) = NULL; RETURN_OBJ(&ffi->std); + +cleanup: + if (lib && handle) { + DL_UNLOAD(handle); + } + if (FFI_G(symbols)) { + zend_hash_destroy(FFI_G(symbols)); + efree(FFI_G(symbols)); + FFI_G(symbols) = NULL; + } + if (FFI_G(tags)) { + zend_hash_destroy(FFI_G(tags)); + efree(FFI_G(tags)); + FFI_G(tags) = NULL; + } + RETURN_THROWS(); } /* }}} */ @@ -7084,7 +7081,6 @@ static zend_result zend_ffi_nested_type(zend_ffi_type *type, zend_ffi_type *nest nested_type->size = nested_type->array.length * ZEND_FFI_TYPE(nested_type->array.type)->size; nested_type->align = ZEND_FFI_TYPE(nested_type->array.type)->align; return SUCCESS; - break; case ZEND_FFI_TYPE_FUNC: /* "char" is used as a terminator of nested declaration */ if (nested_type->func.ret_type == &zend_ffi_type_char) { diff --git a/ext/ffi/ffi.g b/ext/ffi/ffi.g index 364837242890..9ab8ee404edf 100644 --- a/ext/ffi/ffi.g +++ b/ext/ffi/ffi.g @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -30,15 +28,13 @@ php llk.php ffi.g %{ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/ffi/ffi_parser.c b/ext/ffi/ffi_parser.c index 1067f80939f3..27f1469133fe 100644 --- a/ext/ffi/ffi_parser.c +++ b/ext/ffi/ffi_parser.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/ffi/php_ffi.h b/ext/ffi/php_ffi.h index ba92947e62bf..02fdb221c3df 100644 --- a/ext/ffi/php_ffi.h +++ b/ext/ffi/php_ffi.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/ffi/tests/gh10403.phpt b/ext/ffi/tests/gh10403.phpt index 6bac0da92584..1c5c69113eef 100644 --- a/ext/ffi/tests/gh10403.phpt +++ b/ext/ffi/tests/gh10403.phpt @@ -3,7 +3,7 @@ GH-10403: Fix incorrect bitshifting and masking in ffi bitfield --EXTENSIONS-- ffi --SKIPIF-- - + --FILE-- --INI-- ffi.enable=1 --FILE-- diff --git a/ext/ffi/tests/gh18629_cdef_resolve_func.phpt b/ext/ffi/tests/gh18629_cdef_resolve_func.phpt new file mode 100644 index 000000000000..ae81412efa63 --- /dev/null +++ b/ext/ffi/tests/gh18629_cdef_resolve_func.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-18629 (FFI::cdef() leaks on function resolution failure) +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Failed resolving C function 'nonexistent_ffi_test_func' diff --git a/ext/ffi/tests/gh18629_read_field_non_struct.phpt b/ext/ffi/tests/gh18629_read_field_non_struct.phpt new file mode 100644 index 000000000000..307fde1a53b8 --- /dev/null +++ b/ext/ffi/tests/gh18629_read_field_non_struct.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-18629 (Read field of non C struct/union) +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +new("int*"); +try { + $y = $x->foo; +} catch (\FFI\Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Attempt to read field 'foo' of non C struct/union diff --git a/ext/fileinfo/config.m4 b/ext/fileinfo/config.m4 index 346061411e08..2d6139f06dff 100644 --- a/ext/fileinfo/config.m4 +++ b/ext/fileinfo/config.m4 @@ -29,11 +29,6 @@ if test "$PHP_FILEINFO" != "no"; then AC_CHECK_HEADERS([sys/sysmacros.h]) - AC_CHECK_FUNCS([strcasestr],,[ - AC_MSG_NOTICE([using libmagic strcasestr implementation]) - libmagic_sources="$libmagic_sources libmagic/strcasestr.c" - ]) - AX_GCC_FUNC_ATTRIBUTE([visibility]) PHP_NEW_EXTENSION([fileinfo], diff --git a/ext/fileinfo/config.w32 b/ext/fileinfo/config.w32 index 2a42dc45a1d1..34670e7451e4 100644 --- a/ext/fileinfo/config.w32 +++ b/ext/fileinfo/config.w32 @@ -8,7 +8,7 @@ if (PHP_FILEINFO != 'no') { encoding.c fsmagic.c funcs.c \ is_json.c is_tar.c is_simh.c magic.c print.c \ readcdf.c softmagic.c der.c \ - strcasestr.c buffer.c is_csv.c"; + buffer.c is_csv.c"; EXTENSION('fileinfo', 'fileinfo.c php_libmagic.c', true, "/I" + configure_module_dirname + "/libmagic /I" + configure_module_dirname); ADD_EXTENSION_DEP('fileinfo', 'pcre'); diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 50695981796e..4c5c0e88c5ce 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ @@ -45,9 +43,7 @@ typedef struct _finfo_object { zend_object zo; } finfo_object; -static inline finfo_object *php_finfo_fetch_object(zend_object *obj) { - return (finfo_object *)((char*)(obj) - XtOffsetOf(finfo_object, zo)); -} +#define php_finfo_fetch_object(obj) ZEND_CONTAINER_OF(obj, finfo_object, zo) #define Z_FINFO_P(zv) php_finfo_fetch_object(Z_OBJ_P((zv))) @@ -84,7 +80,7 @@ PHP_MINIT_FUNCTION(finfo) /* copy the standard object handlers to you handler table */ memcpy(&finfo_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - finfo_object_handlers.offset = XtOffsetOf(finfo_object, zo); + finfo_object_handlers.offset = offsetof(finfo_object, zo); finfo_object_handlers.free_obj = finfo_objects_free; finfo_object_handlers.clone_obj = NULL; diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index 4eb7ccd336f8..0f69e732fdd5 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ---- libmagic.orig/apprentice.c 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/apprentice.c 2025-02-09 02:25:02.364884555 +0100 +--- libmagic.orig/apprentice.c 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/apprentice.c 2026-03-20 12:10:19.777614667 -0400 @@ -32,7 +32,7 @@ #include "file.h" @@ -325,14 +325,14 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c // Don't warn for DER if (mpa.type == FILE_DER) return 0; -@@ -1151,6 +1075,7 @@ +@@ -1150,6 +1074,7 @@ + ma->mp->desc); file_mdump(ma->mp); file_mdump(mb->mp); +#endif return 0; } return x > 0 ? -1 : 1; - } @@ -1303,7 +1228,7 @@ size_t incr = mset[i].max + ALLOC_INCR; @@ -954,8 +954,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (ma[j].cont_level == 0) break; diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c ---- libmagic.orig/ascmagic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/ascmagic.c 2025-02-09 01:20:19.757840211 +0100 +--- libmagic.orig/ascmagic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/ascmagic.c 2026-03-19 16:25:42.998672674 -0400 @@ -96,7 +96,7 @@ rv = file_ascmagic_with_encoding(ms, &bb, ubuf, ulen, code, type, text); @@ -996,8 +996,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c return rv; } diff -u libmagic.orig/buffer.c libmagic/buffer.c ---- libmagic.orig/buffer.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/buffer.c 2025-02-09 01:20:19.757910844 +0100 +--- libmagic.orig/buffer.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/buffer.c 2026-03-19 16:25:42.998672674 -0400 @@ -31,19 +31,21 @@ #endif /* lint */ @@ -1055,8 +1055,8 @@ diff -u libmagic.orig/buffer.c libmagic/buffer.c goto out; } diff -u libmagic.orig/cdf.c libmagic/cdf.c ---- libmagic.orig/cdf.c 2024-11-25 22:24:59.000000000 +0100 -+++ libmagic/cdf.c 2025-02-09 01:25:00.187641434 +0100 +--- libmagic.orig/cdf.c 2024-11-25 16:24:59.000000000 -0500 ++++ libmagic/cdf.c 2026-03-19 16:25:42.998672674 -0400 @@ -43,7 +43,9 @@ #include #endif @@ -1286,8 +1286,8 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c #endif diff -u libmagic.orig/cdf.h libmagic/cdf.h ---- libmagic.orig/cdf.h 2024-11-25 22:18:55.000000000 +0100 -+++ libmagic/cdf.h 2025-02-09 01:23:35.871635744 +0100 +--- libmagic.orig/cdf.h 2024-11-25 16:18:55.000000000 -0500 ++++ libmagic/cdf.h 2026-03-19 16:25:42.990672671 -0400 @@ -37,8 +37,6 @@ #ifdef WIN32 @@ -1439,8 +1439,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h diff -u libmagic.orig/compress.c libmagic/compress.c ---- libmagic.orig/compress.c 2024-11-10 17:52:27.000000000 +0100 -+++ libmagic/compress.c 2025-02-09 01:59:42.978538071 +0100 +--- libmagic.orig/compress.c 2024-11-10 11:52:27.000000000 -0500 ++++ libmagic/compress.c 2026-03-20 12:10:19.777614667 -0400 @@ -64,13 +64,14 @@ #if defined(HAVE_SYS_TIME_H) #include @@ -1666,8 +1666,8 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #endif +#endif diff -u libmagic.orig/der.c libmagic/der.c ---- libmagic.orig/der.c 2024-11-25 23:31:53.000000000 +0100 -+++ libmagic/der.c 2025-02-09 01:20:19.770853011 +0100 +--- libmagic.orig/der.c 2024-11-25 17:31:53.000000000 -0500 ++++ libmagic/der.c 2026-03-19 16:25:43.002672676 -0400 @@ -54,7 +54,9 @@ #include "magic.h" #include "der.h" @@ -1679,8 +1679,8 @@ diff -u libmagic.orig/der.c libmagic/der.c #include #endif diff -u libmagic.orig/der.h libmagic/der.h ---- libmagic.orig/der.h 2024-11-25 22:26:18.000000000 +0100 -+++ libmagic/der.h 2023-04-09 22:21:58.195018580 +0200 +--- libmagic.orig/der.h 2024-11-25 16:26:18.000000000 -0500 ++++ libmagic/der.h 2026-03-19 16:25:43.006672678 -0400 @@ -24,5 +24,5 @@ * POSSIBILITY OF SUCH DAMAGE. */ @@ -1690,8 +1690,8 @@ diff -u libmagic.orig/der.h libmagic/der.h +extern int der_offs(struct magic_set *, struct magic *, size_t); +extern int der_cmp(struct magic_set *, struct magic *); diff -u libmagic.orig/encoding.c libmagic/encoding.c ---- libmagic.orig/encoding.c 2024-10-29 21:56:48.000000000 +0100 -+++ libmagic/encoding.c 2025-02-09 01:20:19.770879123 +0100 +--- libmagic.orig/encoding.c 2024-10-29 16:56:48.000000000 -0400 ++++ libmagic/encoding.c 2026-03-19 16:25:43.010672679 -0400 @@ -97,7 +97,7 @@ nbytes = ms->encoding_max; @@ -1726,8 +1726,8 @@ diff -u libmagic.orig/encoding.c libmagic/encoding.c return rv; } diff -u libmagic.orig/file.h libmagic/file.h ---- libmagic.orig/file.h 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/file.h 2025-02-09 01:47:36.242811911 +0100 +--- libmagic.orig/file.h 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/file.h 2026-03-25 16:14:40.128668705 -0400 @@ -27,15 +27,13 @@ */ /* @@ -1767,6 +1767,21 @@ diff -u libmagic.orig/file.h libmagic/file.h #define ENABLE_CONDITIONALS +@@ -109,12 +102,12 @@ + + #if HAVE_VISIBILITY + # if defined(WIN32) +-# define file_public __declspec(dllexport) ++# define file_public + # ifndef file_protected + # define file_protected + # endif + # else +-# define file_public __attribute__((__visibility__("default"))) ++# define file_public __attribute__((__visibility__("hidden"))) + # ifndef file_protected + # define file_protected __attribute__((__visibility__("hidden"))) + # endif @@ -179,7 +172,7 @@ #define MAXstring 128 /* max len of "string" types */ @@ -1883,7 +1898,7 @@ diff -u libmagic.orig/file.h libmagic/file.h typedef struct { char *buf; size_t blen; -@@ -649,19 +629,6 @@ +@@ -649,28 +629,12 @@ extern file_protected const size_t file_nnames; #endif @@ -1903,7 +1918,16 @@ diff -u libmagic.orig/file.h libmagic/file.h #ifndef HAVE_STRLCPY size_t strlcpy(char *, const char *, size_t); #endif -@@ -681,31 +648,6 @@ + #ifndef HAVE_STRLCAT + size_t strlcat(char *, const char *, size_t); + #endif +-#ifndef HAVE_STRCASESTR +-char *strcasestr(const char *, const char *); +-#endif + #ifndef HAVE_GETLINE + ssize_t getline(char **, size_t *, FILE *); + ssize_t getdelim(char **, size_t *, int, FILE *); +@@ -681,31 +645,6 @@ #ifndef HAVE_ASCTIME_R char *asctime_r(const struct tm *, char *); #endif @@ -1936,8 +1960,8 @@ diff -u libmagic.orig/file.h libmagic/file.h #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c ---- libmagic.orig/fsmagic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/fsmagic.c 2025-02-09 01:20:19.770987982 +0100 +--- libmagic.orig/fsmagic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/fsmagic.c 2026-03-19 16:25:43.006672678 -0400 @@ -66,26 +66,10 @@ # define minor(dev) ((dev) & 0xff) #endif @@ -2229,8 +2253,8 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c #ifndef __COHERENT__ case S_IFSOCK: diff -u libmagic.orig/funcs.c libmagic/funcs.c ---- libmagic.orig/funcs.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/funcs.c 2025-02-09 01:29:25.403659334 +0100 +--- libmagic.orig/funcs.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/funcs.c 2026-03-19 16:25:42.990672671 -0400 @@ -66,7 +66,7 @@ file_private void file_clearbuf(struct magic_set *ms) @@ -2592,8 +2616,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c file_protected int file_clear_closexec(int fd) { diff -u libmagic.orig/magic.c libmagic/magic.c ---- libmagic.orig/magic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/magic.c 2025-02-09 01:20:19.771155033 +0100 +--- libmagic.orig/magic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/magic.c 2026-03-20 12:10:19.777614667 -0400 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -3066,8 +3090,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c } return file_getbuffer(ms); diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2025-02-09 12:43:22.903059789 +0100 -+++ libmagic/magic.h 2025-02-09 01:39:57.110146603 +0100 +--- libmagic.orig/magic.h 2026-03-25 16:14:49.284673536 -0400 ++++ libmagic/magic.h 2026-03-20 12:10:19.777614667 -0400 @@ -47,8 +47,6 @@ * extensions */ #define MAGIC_COMPRESS_TRANSP 0x2000000 /* Check inside compressed files @@ -3109,8 +3133,8 @@ diff -u libmagic.orig/magic.h libmagic/magic.h const char *magic_buffer(magic_t, const void *, size_t); diff -u libmagic.orig/print.c libmagic/print.c ---- libmagic.orig/print.c 2024-10-06 19:04:42.000000000 +0200 -+++ libmagic/print.c 2025-02-09 01:36:41.713156291 +0100 +--- libmagic.orig/print.c 2024-10-06 13:04:42.000000000 -0400 ++++ libmagic/print.c 2026-03-19 16:25:42.982672668 -0400 @@ -74,7 +74,7 @@ if (m->mask_op & FILE_OPINVERSE) (void) fputc('~', stderr); @@ -3187,8 +3211,8 @@ diff -u libmagic.orig/print.c libmagic/print.c if (pp == NULL) goto out; diff -u libmagic.orig/readcdf.c libmagic/readcdf.c ---- libmagic.orig/readcdf.c 2024-11-25 22:07:46.000000000 +0100 -+++ libmagic/readcdf.c 2025-02-09 01:20:19.771337672 +0100 +--- libmagic.orig/readcdf.c 2024-11-25 16:07:46.000000000 -0500 ++++ libmagic/readcdf.c 2026-03-19 16:25:43.002672676 -0400 @@ -31,7 +31,9 @@ #include @@ -3307,8 +3331,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c /* If we handled it already, return */ if (i != -1) diff -u libmagic.orig/softmagic.c libmagic/softmagic.c ---- libmagic.orig/softmagic.c 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/softmagic.c 2025-02-09 01:21:46.845689318 +0100 +--- libmagic.orig/softmagic.c 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/softmagic.c 2026-03-19 16:25:42.986672670 -0400 @@ -32,7 +32,7 @@ #include "file.h" diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h index f8fe58895002..5357578c6a77 100644 --- a/ext/fileinfo/libmagic/file.h +++ b/ext/fileinfo/libmagic/file.h @@ -102,12 +102,12 @@ #if HAVE_VISIBILITY # if defined(WIN32) -# define file_public __declspec(dllexport) +# define file_public # ifndef file_protected # define file_protected # endif # else -# define file_public __attribute__((__visibility__("default"))) +# define file_public __attribute__((__visibility__("hidden"))) # ifndef file_protected # define file_protected __attribute__((__visibility__("hidden"))) # endif @@ -635,9 +635,6 @@ size_t strlcpy(char *, const char *, size_t); #ifndef HAVE_STRLCAT size_t strlcat(char *, const char *, size_t); #endif -#ifndef HAVE_STRCASESTR -char *strcasestr(const char *, const char *); -#endif #ifndef HAVE_GETLINE ssize_t getline(char **, size_t *, FILE *); ssize_t getdelim(char **, size_t *, int, FILE *); diff --git a/ext/fileinfo/php_fileinfo.h b/ext/fileinfo/php_fileinfo.h index a0536294429b..50de6f79a537 100644 --- a/ext/fileinfo/php_fileinfo.h +++ b/ext/fileinfo/php_fileinfo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/php_libmagic.c b/ext/fileinfo/php_libmagic.c index 05123fa8133a..efb78653c211 100644 --- a/ext/fileinfo/php_libmagic.c +++ b/ext/fileinfo/php_libmagic.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/php_libmagic.h b/ext/fileinfo/php_libmagic.h index 23d0c3e8eaa1..59e8e091a487 100644 --- a/ext/fileinfo/php_libmagic.h +++ b/ext/fileinfo/php_libmagic.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/tests/bug68996.phpt b/ext/fileinfo/tests/bug68996.phpt index 7dbbf4f7f07a..4f4716336e8e 100644 --- a/ext/fileinfo/tests/bug68996.phpt +++ b/ext/fileinfo/tests/bug68996.phpt @@ -10,8 +10,8 @@ finfo_open(FILEINFO_MIME_TYPE, "\xfc\x63"); ?> --EXPECTF--
-Warning: finfo_open(%s�c): Failed to open stream: No such file or directory in %sbug68996.php on line %d
+Warning: finfo_open(): Failed to open stream: No such file or directory in %sbug68996.php on line %d

-Warning: finfo_open(%s�c): Failed to open stream: No such file or directory in %sbug68996.php on line %d
+Warning: finfo_open(): Failed to open stream: No such file or directory in %sbug68996.php on line %d

Warning: finfo_open(): Failed to load magic database at "%s�c" in %s on line %d
diff --git a/ext/fileinfo/tests/finfo_file_001.phpt b/ext/fileinfo/tests/finfo_file_001.phpt index 737b8db53ff7..91b9b69717f6 100644 --- a/ext/fileinfo/tests/finfo_file_001.phpt +++ b/ext/fileinfo/tests/finfo_file_001.phpt @@ -25,5 +25,5 @@ finfo_file(): Argument #2 ($filename) must not contain any null bytes finfo_file(): Argument #2 ($filename) must not be empty string(9) "directory" -Warning: finfo_file(&): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/fileinfo/tests/finfo_open_001.phpt b/ext/fileinfo/tests/finfo_open_001.phpt index 21b90042f0fd..2ed7168e90d3 100644 --- a/ext/fileinfo/tests/finfo_open_001.phpt +++ b/ext/fileinfo/tests/finfo_open_001.phpt @@ -44,23 +44,23 @@ object(finfo)#%d (0) { object(finfo)#%d (0) { } -Warning: finfo_open(%s123): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d -Warning: finfo_open(%s123): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d Warning: finfo_open(): Failed to load magic database at "%s123" in %s on line %d bool(false) -Warning: finfo_open(%s1): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d -Warning: finfo_open(%s1): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d Warning: finfo_open(): Failed to load magic database at "%s1" in %s on line %d bool(false) -Warning: finfo_open(%sinexistent): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d -Warning: finfo_open(%sinexistent): Failed to open stream: No such file or directory in %s on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %s on line %d Warning: finfo_open(): Failed to load magic database at "%sinexistent" in %s on line %d bool(false) @@ -68,6 +68,6 @@ object(finfo)#%d (%d) { } object(finfo)#%d (%d) { } -finfo::__construct(%s123): Failed to open stream: No such file or directory -finfo::__construct(%s1): Failed to open stream: No such file or directory -finfo::__construct(%sinexistent): Failed to open stream: No such file or directory +finfo::__construct(): Failed to open stream: No such file or directory +finfo::__construct(): Failed to open stream: No such file or directory +finfo::__construct(): Failed to open stream: No such file or directory diff --git a/ext/fileinfo/tests/finfo_open_error.phpt b/ext/fileinfo/tests/finfo_open_error.phpt index c4aa082111d7..7c6fc9766372 100644 --- a/ext/fileinfo/tests/finfo_open_error.phpt +++ b/ext/fileinfo/tests/finfo_open_error.phpt @@ -27,9 +27,9 @@ try { --EXPECTF-- *** Testing finfo_open() : error functionality *** -Warning: finfo_open(%sfoobarfile): Failed to open stream: No such file or directory in %sfinfo_open_error.php on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %sfinfo_open_error.php on line %d -Warning: finfo_open(%sfoobarfile): Failed to open stream: No such file or directory in %sfinfo_open_error.php on line %d +Warning: finfo_open(): Failed to open stream: No such file or directory in %sfinfo_open_error.php on line %d Warning: finfo_open(): Failed to load magic database at "%sfoobarfile" in %sfinfo_open_error.php on line %d bool(false) diff --git a/ext/fileinfo/tests/mime_content_type_001.phpt b/ext/fileinfo/tests/mime_content_type_001.phpt index 98c1325959d8..93b145768141 100644 --- a/ext/fileinfo/tests/mime_content_type_001.phpt +++ b/ext/fileinfo/tests/mime_content_type_001.phpt @@ -46,6 +46,6 @@ mime_content_type(): Argument #1 ($filename) must be of type resource|string, nu mime_content_type(): Argument #1 ($filename) must be of type resource|string, stdClass given mime_content_type(): Argument #1 ($filename) must be of type resource|string, array given -Warning: mime_content_type(foo/inexistent): Failed to open stream: No such file or directory in %s on line %d +Warning: mime_content_type(): Failed to open stream: No such file or directory in %s on line %d mime_content_type(): Argument #1 ($filename) must not be empty mime_content_type(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/filter/callback_filter.c b/ext/filter/callback_filter.c index dea39c6cc7c3..688cbf072175 100644 --- a/ext/filter/callback_filter.c +++ b/ext/filter/callback_filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ diff --git a/ext/filter/filter.c b/ext/filter/filter.c index 03f0f7887f92..30821411a326 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Derick Rethans | @@ -298,10 +296,10 @@ static void php_zval_filter(zval *value, zend_long filter, zend_long flags, zval filter_func.name, ZSTR_VAL(copy_for_throwing) ); - zend_string_delref(copy_for_throwing); + zend_string_release(copy_for_throwing); return; } - zend_string_delref(copy_for_throwing); + zend_string_release(copy_for_throwing); copy_for_throwing = NULL; } @@ -380,15 +378,18 @@ static unsigned int php_sapi_filter(int arg, const char *var, char **val, size_t } if (retval) { + zend_string *tmp_str; + zend_string *str = zval_get_tmp_string(&new_var, &tmp_str); if (new_val_len) { - *new_val_len = Z_STRLEN(new_var); + *new_val_len = ZSTR_LEN(str); } efree(*val); - if (Z_STRLEN(new_var)) { - *val = estrndup(Z_STRVAL(new_var), Z_STRLEN(new_var)); + if (ZSTR_LEN(str)) { + *val = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); } else { *val = estrdup(""); } + zend_tmp_string_release(tmp_str); zval_ptr_dtor(&new_var); } diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h index 709b7fbc45ed..14975e7911a4 100644 --- a/ext/filter/filter_private.h +++ b/ext/filter/filter_private.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 20760e656e76..45acf6d47541 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | | Pierre-A. Joye | @@ -535,21 +533,21 @@ static bool php_filter_validate_domain_ex(const zend_string *domain, zend_long f } /* First char must be alphanumeric */ - if(*s == '.' || (hostname && !isalnum((int)*(unsigned char *)s))) { + if(*s == '.' || (hostname && !isalnum((unsigned char)*s))) { return false; } while (s < e) { if (*s == '.') { /* The first and the last character of a label must be alphanumeric */ - if (*(s + 1) == '.' || (hostname && (!isalnum((int)*(unsigned char *)(s - 1)) || !isalnum((int)*(unsigned char *)(s + 1))))) { + if (*(s + 1) == '.' || (hostname && (!isalnum((unsigned char)s[-1]) || !isalnum((unsigned char)s[1])))) { return false; } /* Reset label length counter */ i = 1; } else { - if (i > 63 || (hostname && (*s != '-' || *(s + 1) == '\0') && !isalnum((int)*(unsigned char *)s))) { + if (i > 63 || (hostname && (*s != '-' || *(s + 1) == '\0') && !isalnum((unsigned char)*s))) { return false; } @@ -577,9 +575,9 @@ static bool is_userinfo_valid(const zend_string *str) const char *p = ZSTR_VAL(str); while (p - ZSTR_VAL(str) < ZSTR_LEN(str)) { static const char *valid = "-._~!$&'()*+,;=:"; - if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { + if (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || strchr(valid, *p)) { p++; - } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { + } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit((unsigned char)p[1]) && isxdigit((unsigned char)p[2])) { p += 3; } else { return false; diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h index 48ad5cc07943..ccf8b6b4883f 100644 --- a/ext/filter/php_filter.h +++ b/ext/filter/php_filter.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Derick Rethans | diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c index 94cbd0c34bba..bdf4e7681ca1 100644 --- a/ext/filter/sanitizing_filters.c +++ b/ext/filter/sanitizing_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ @@ -70,7 +68,7 @@ static void php_filter_encode_url(zval *value, const unsigned char* chars, const const unsigned char *e = s + char_len; zend_string *str; - memset(tmp, 1, sizeof(tmp)-1); + memset(tmp, 1, sizeof(tmp)); while (s < e) { tmp[*s++] = '\0'; diff --git a/ext/filter/tests/filter_default_parse_str.phpt b/ext/filter/tests/filter_default_parse_str.phpt new file mode 100644 index 000000000000..71563060db36 --- /dev/null +++ b/ext/filter/tests/filter_default_parse_str.phpt @@ -0,0 +1,19 @@ +--TEST-- +filter.default with parse_str must not crash on non-string filter results +--EXTENSIONS-- +filter +--INI-- +filter.default=int +--FILE-- + +--EXPECTF-- +Deprecated: The filter.default ini setting is deprecated in %s on line %d +array(2) { + ["a"]=> + string(1) "1" + ["b"]=> + string(0) "" +} diff --git a/ext/filter/tests/filter_sanitize_encoded_0xff.phpt b/ext/filter/tests/filter_sanitize_encoded_0xff.phpt new file mode 100644 index 000000000000..1ee61aba7b70 --- /dev/null +++ b/ext/filter/tests/filter_sanitize_encoded_0xff.phpt @@ -0,0 +1,12 @@ +--TEST-- +FILTER_SANITIZE_ENCODED percent-encodes 0xFF +--EXTENSIONS-- +filter +--FILE-- + +--EXPECT-- +string(3) "%FF" +string(10) "%FE%FF%00A" diff --git a/ext/filter/tests/filter_throw_on_failure_leak.phpt b/ext/filter/tests/filter_throw_on_failure_leak.phpt new file mode 100644 index 000000000000..d42896a94e8f --- /dev/null +++ b/ext/filter/tests/filter_throw_on_failure_leak.phpt @@ -0,0 +1,37 @@ +--TEST-- +filter: FILTER_THROW_ON_FAILURE does not leak the preserved input string +--EXTENSIONS-- +filter +--FILE-- + exception thrown. +var_dump(leakcheck(function () { + try { + filter_var(1.5, FILTER_VALIDATE_INT, ['flags' => FILTER_THROW_ON_FAILURE]); + } catch (\Filter\FilterFailedException $e) { + } +})); + +// Validation succeeds. +var_dump(leakcheck(function () { + filter_var(15, FILTER_VALIDATE_INT, ['flags' => FILTER_THROW_ON_FAILURE]); +})); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 0c1287a3e705..0035e8508da1 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | @@ -485,7 +483,7 @@ void ftp_raw(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len, zval *return_ array_init(return_value); while (ftp_readline(ftp)) { add_next_index_string(return_value, ftp->inbuf); - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { return; } } @@ -791,7 +789,7 @@ bool ftp_pasv(ftpbuf_t *ftp, int pasv) return false; } /* parse out the IP and port */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%lu,%lu,%lu,%lu,%lu,%lu", &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]); if (n != 6) { return false; @@ -819,6 +817,11 @@ bool ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ if (ftp == NULL) { return false; } + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return false; + } + ftp->in_use = true; if (!ftp_type(ftp, type)) { goto bail; } @@ -852,6 +855,7 @@ bool ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ goto bail; } + bool pending_cr = false; while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) { if (rcvd == (size_t)-1) { goto bail; @@ -871,13 +875,30 @@ bool ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ php_stream_write(outstream, ptr, (e - ptr)); ptr = e; #else - while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) { - php_stream_write(outstream, ptr, (s - ptr)); - if (*(s + 1) == '\n') { - s++; + if (pending_cr) { + pending_cr = false; + if (*ptr == '\n') { php_stream_putc(outstream, '\n'); + ptr++; + } else { + php_stream_putc(outstream, '\r'); + } + } + while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) { + if (s + 1 < e) { + if (*(s + 1) == '\n') { + php_stream_write(outstream, ptr, (s - ptr)); + php_stream_putc(outstream, '\n'); + ptr = s + 2; + } else { + php_stream_write(outstream, ptr, (s - ptr) + 1); + ptr = s + 1; + } + } else { + php_stream_write(outstream, ptr, (s - ptr)); + pending_cr = true; + ptr = s + 1; } - ptr = s + 1; } #endif if (ptr < e) { @@ -887,6 +908,9 @@ bool ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ goto bail; } } + if (pending_cr) { + php_stream_putc(outstream, '\r'); + } data_close(ftp); @@ -894,9 +918,11 @@ bool ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ goto bail; } + ftp->in_use = false; return true; bail: data_close(ftp); + ftp->in_use = false; return false; } @@ -981,6 +1007,11 @@ bool ftp_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream if (ftp == NULL) { return false; } + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return false; + } + ftp->in_use = true; if (!ftp_type(ftp, type)) { goto bail; } @@ -1021,9 +1052,11 @@ bool ftp_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250 && ftp->resp != 200)) { goto bail; } + ftp->in_use = false; return true; bail: data_close(ftp); + ftp->in_use = false; return false; } @@ -1034,6 +1067,11 @@ bool ftp_append(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stre if (ftp == NULL) { return false; } + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return false; + } + ftp->in_use = true; if (!ftp_type(ftp, type)) { goto bail; } @@ -1061,9 +1099,11 @@ bool ftp_append(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stre if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250 && ftp->resp != 200)) { goto bail; } + ftp->in_use = false; return true; bail: data_close(ftp); + ftp->in_use = false; return false; } @@ -1102,7 +1142,7 @@ time_t ftp_mdtm(ftpbuf_t *ftp, const char *path, const size_t path_len) return -1; } /* parse out the timestamp */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); if (n != 6) { return -1; @@ -1254,7 +1294,7 @@ static bool ftp_readline(ftpbuf_t *ftp) } data = eol; - if ((rcvd = my_recv(ftp, ftp->fd, data, size)) < 1) { + if (size < 2 || (rcvd = my_recv(ftp, ftp->fd, data, size - 1)) < 1) { *data = 0; return false; } @@ -1278,13 +1318,13 @@ static bool ftp_getresp(ftpbuf_t *ftp) } /* Break out when the end-tag is found */ - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { break; } } /* translate the tag */ - if (!isdigit(ftp->inbuf[0]) || !isdigit(ftp->inbuf[1]) || !isdigit(ftp->inbuf[2])) { + if (!isdigit((unsigned char)ftp->inbuf[0]) || !isdigit((unsigned char)ftp->inbuf[1]) || !isdigit((unsigned char)ftp->inbuf[2])) { return false; } @@ -1920,6 +1960,10 @@ static char** ftp_genlist(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len, char **entry; char *text; + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return NULL; + } if ((tmpstream = php_stream_fopen_tmpfile()) == NULL) { php_error_docref(NULL, E_WARNING, "Unable to create temporary file. Check permissions in temporary files directory."); @@ -2018,6 +2062,11 @@ int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const siz return PHP_FTP_FAILED; } + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return PHP_FTP_FAILED; + } + if (ftp->data != NULL) { /* If there is a transfer in action, abort it. * If we don't, we get an invalid state and memory leaks when the new connection gets opened. */ @@ -2082,11 +2131,17 @@ int ftp_nb_continue_read(ftpbuf_t *ftp) data = ftp->data; + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return PHP_FTP_FAILED; + } + /* check if there is already more data */ if (!data_available(ftp, data->fd, false)) { return PHP_FTP_MOREDATA; } + ftp->in_use = true; type = ftp->type; lastch = ftp->lastch; @@ -2110,6 +2165,7 @@ int ftp_nb_continue_read(ftpbuf_t *ftp) } ftp->lastch = lastch; + ftp->in_use = false; return PHP_FTP_MOREDATA; } @@ -2124,9 +2180,11 @@ int ftp_nb_continue_read(ftpbuf_t *ftp) } ftp->nb = false; + ftp->in_use = false; return PHP_FTP_FINISHED; bail: ftp->nb = false; + ftp->in_use = false; data_close(ftp); return PHP_FTP_FAILED; } @@ -2139,6 +2197,10 @@ int ftp_nb_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_strea if (ftp == NULL) { return 0; } + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return PHP_FTP_FAILED; + } if (!ftp_type(ftp, type)) { goto bail; } @@ -2182,16 +2244,24 @@ int ftp_nb_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_strea int ftp_nb_continue_write(ftpbuf_t *ftp) { + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + return PHP_FTP_FAILED; + } + /* check if we can write more data */ if (!data_writeable(ftp, ftp->data->fd)) { return PHP_FTP_MOREDATA; } + ftp->in_use = true; + if (ftp_send_stream_to_data_socket(ftp, ftp->data, ftp->stream, ftp->type, true) != SUCCESS) { goto bail; } if (!php_stream_eof(ftp->stream)) { + ftp->in_use = false; return PHP_FTP_MOREDATA; } @@ -2201,9 +2271,11 @@ int ftp_nb_continue_write(ftpbuf_t *ftp) goto bail; } ftp->nb = false; + ftp->in_use = false; return PHP_FTP_FINISHED; bail: data_close(ftp); ftp->nb = false; + ftp->in_use = false; return PHP_FTP_FAILED; } diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h index 241f92f57ec3..1c8d45460ca6 100644 --- a/ext/ftp/ftp.h +++ b/ext/ftp/ftp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | @@ -72,6 +70,7 @@ typedef struct ftpbuf databuf_t *data; /* Data connection for "nonblocking" transfers */ php_stream *stream; /* output stream for "nonblocking" transfers */ bool nb; /* "nonblocking" transfer in progress */ + bool in_use; /* engine transfer in progress; blocks re-entrant ftp_close */ char lastch; /* last char of previous call */ bool direction; /* recv = 0 / send = 1 */ bool closestream;/* close or not close stream */ diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 245d95bf1260..56938459bb33 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | @@ -36,6 +34,8 @@ #include "ftp.h" #include "ftp_arginfo.h" +#define PHP_FTP_TIMEOUT_SEC_MAX ((uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0)) + static zend_class_entry *php_ftp_ce = NULL; static zend_object_handlers ftp_object_handlers; @@ -101,7 +101,7 @@ PHP_MINIT_FUNCTION(ftp) php_ftp_ce->create_object = ftp_object_create; memcpy(&ftp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ftp_object_handlers.offset = XtOffsetOf(php_ftp_object, std); + ftp_object_handlers.offset = offsetof(php_ftp_object, std); ftp_object_handlers.get_constructor = ftp_object_get_constructor; ftp_object_handlers.free_obj = ftp_object_destroy; ftp_object_handlers.clone_obj = NULL; @@ -145,15 +145,13 @@ PHP_FUNCTION(ftp_connect) RETURN_THROWS(); } - const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0); - if (timeout_sec <= 0) { zend_argument_value_error(3, "must be greater than 0"); RETURN_THROWS(); } - if (timeout_sec >= timeoutmax) { - zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax); + if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX); RETURN_THROWS(); } @@ -194,6 +192,11 @@ PHP_FUNCTION(ftp_ssl_connect) RETURN_THROWS(); } + if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX); + RETURN_THROWS(); + } + /* connect */ if (!(ftp = ftp_open(host, (short)port, timeout_sec))) { RETURN_FALSE; @@ -652,6 +655,11 @@ PHP_FUNCTION(ftp_nb_fget) } /* configuration */ + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + RETURN_FALSE; + } + ftp->direction = 0; /* recv */ ftp->closestream = 0; /* do not close */ @@ -762,6 +770,10 @@ PHP_FUNCTION(ftp_nb_get) RETURN_THROWS(); } GET_FTPBUF(ftp, z_ftp); + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + RETURN_FALSE; + } XTYPE(xtype, mode); /* ignore autoresume if autoseek is switched off */ @@ -799,8 +811,8 @@ PHP_FUNCTION(ftp_nb_get) ftp->closestream = true; /* do close */ if ((ret = ftp_nb_get(ftp, outstream, remote, remote_len, xtype, resumepos)) == PHP_FTP_FAILED) { - php_stream_close(outstream); ftp->stream = NULL; + php_stream_close(outstream); VCWD_UNLINK(local); if (*ftp->inbuf) { php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf); @@ -809,8 +821,8 @@ PHP_FUNCTION(ftp_nb_get) } if (ret == PHP_FTP_FINISHED){ - php_stream_close(outstream); ftp->stream = NULL; + php_stream_close(outstream); } RETURN_LONG(ret); @@ -948,6 +960,11 @@ PHP_FUNCTION(ftp_nb_fput) } /* configuration */ + if (ftp->in_use) { + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + RETURN_FALSE; + } + ftp->direction = true; /* send */ ftp->closestream = false; /* do not close */ @@ -1088,6 +1105,12 @@ PHP_FUNCTION(ftp_nb_put) } } + if (ftp->in_use) { + php_stream_close(instream); + php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); + RETURN_FALSE; + } + /* configuration */ ftp->direction = true; /* send */ ftp->closestream = true; /* do close */ @@ -1095,8 +1118,8 @@ PHP_FUNCTION(ftp_nb_put) ret = ftp_nb_put(ftp, remote, remote_len, instream, xtype, startpos); if (ret != PHP_FTP_MOREDATA) { - php_stream_close(instream); ftp->stream = NULL; + php_stream_close(instream); } if (ret == PHP_FTP_FAILED) { @@ -1231,6 +1254,10 @@ PHP_FUNCTION(ftp_close) obj = ftp_object_from_zend_object(Z_OBJ_P(z_ftp)); if (obj->ftp) { + if (obj->ftp->in_use) { + zend_throw_error(NULL, "Cannot close FTP\\Connection while a transfer is in progress"); + RETURN_THROWS(); + } success = ftp_quit(obj->ftp); ftp_close(obj->ftp); obj->ftp = NULL; @@ -1262,9 +1289,12 @@ PHP_FUNCTION(ftp_set_option) zend_argument_value_error(3, "must be greater than 0 for the FTP_TIMEOUT_SEC option"); RETURN_THROWS(); } + if ((uint64_t) Z_LVAL_P(z_value) >= PHP_FTP_TIMEOUT_SEC_MAX) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT " for the FTP_TIMEOUT_SEC option", PHP_FTP_TIMEOUT_SEC_MAX); + RETURN_THROWS(); + } ftp->timeout_sec = Z_LVAL_P(z_value); RETURN_TRUE; - break; case PHP_FTP_OPT_AUTOSEEK: if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) { zend_argument_type_error(3, "must be of type bool for the FTP_AUTOSEEK option, %s given", zend_zval_value_name(z_value)); @@ -1272,7 +1302,6 @@ PHP_FUNCTION(ftp_set_option) } ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0; RETURN_TRUE; - break; case PHP_FTP_OPT_USEPASVADDRESS: if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) { zend_argument_type_error(3, "must be of type bool for the FTP_USEPASVADDRESS option, %s given", zend_zval_value_name(z_value)); @@ -1280,11 +1309,9 @@ PHP_FUNCTION(ftp_set_option) } ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0; RETURN_TRUE; - break; default: zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS"); RETURN_THROWS(); - break; } } /* }}} */ @@ -1304,13 +1331,10 @@ PHP_FUNCTION(ftp_get_option) switch (option) { case PHP_FTP_OPT_TIMEOUT_SEC: RETURN_LONG(ftp->timeout_sec); - break; case PHP_FTP_OPT_AUTOSEEK: RETURN_BOOL(ftp->autoseek); - break; case PHP_FTP_OPT_USEPASVADDRESS: RETURN_BOOL(ftp->usepasvaddress); - break; default: zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS"); RETURN_THROWS(); diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h index b701f1331d0b..ee9cb50c4382 100644 --- a/ext/ftp/php_ftp.h +++ b/ext/ftp/php_ftp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | diff --git a/ext/ftp/tests/bug80901.phpt b/ext/ftp/tests/bug80901.phpt index e2a58fa0668a..a1c0e479c6ae 100644 --- a/ext/ftp/tests/bug80901.phpt +++ b/ext/ftp/tests/bug80901.phpt @@ -16,4 +16,4 @@ ftp_systype($ftp); --EXPECTF-- bool(true) -Warning: ftp_systype(): **************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d +Warning: ftp_systype(): *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d diff --git a/ext/ftp/tests/cert.pem b/ext/ftp/tests/cert.pem index 2bb30614ed60..9508018e1709 100644 --- a/ext/ftp/tests/cert.pem +++ b/ext/ftp/tests/cert.pem @@ -1,49 +1,50 @@ -----BEGIN CERTIFICATE----- -MIIDhTCCAm2gAwIBAgIJAN75FFz+owOAMA0GCSqGSIb3DQEBCwUAMFkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCTEyNy4wLjAuMTAeFw0xNjA3MjUxMjM3 -MTJaFw0yNjA3MjMxMjM3MTJaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l -LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV -BAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtG -AIrNUDItISfpAqztL2TFEWEHLGTzCEh5Ag2sdMD7UYbqIPHLOE4EINv+dqEMM0Nz -LYnw7ChtVegXT907xCaQcmeDFSdhqze4L8zawDfnn4syB8XAwGYJfpstYwe3nO6+ -0WvLSb1A5TYNeyoXjwlAUKElxkeWAo51uhR41GDhDQ9GgpqX1ccAhmSoUhgIRSzf -6f4KE3WTdzl1p12ZtkYHB8Jo2jB/JXnwGOz6isLnpRvkex4B7sUX+7u1MqK/e1X7 -Hi1G/VkaAfC2SOfjTePtGBDBXrQ1arYXDPRA04sgFzSh55l7lC/4HasQ/jAb3h95 -dcEIqyc69iioaN1c1NcCAwEAAaNQME4wHQYDVR0OBBYEFNv3kefb1H+6/6CpjiBi -+I2s9E90MB8GA1UdIwQYMBaAFNv3kefb1H+6/6CpjiBi+I2s9E90MAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIzSEWpHSaBs7KduBRXX5+qFxBN6OCPl -7ID0rxAOYfw7ruzbmwgOpBgMIHGn+KqA6CmQI0jh9bZbv5TV2aFpFsUihugPc2lW -5EshCozxlEPmIJNsO8jDqPE4w3m4KiVTscRWjBa5cco+lwLDqboerm2l7vvrtr6B -pgLaZct1c73MouvoJSCGK5EOGW7jsgaxjxJ3UZug+24Ko1wulO2cgBLhda9Ilrnx -CIKI9h8Z2WVWuVQfyCyO1g7XkJgkBec77OhxD+m4onzPY6waqnnhmFOBcS+gKgBV -jHeK9DCvZ9zet3EyEp6fyQOOtsC+gU0piYgfsQL7aCp5oLe+fjTiuUY= +MIIDlTCCAn2gAwIBAgIUb9Avckyt1MHYsaBDGCpNBX2DtJowDQYJKoZIhvcNAQEL +BQAwWTESMBAGA1UEAwwJMTI3LjAuMC4xMQswCQYDVQQGEwJBVTETMBEGA1UECAwK +U29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMCAX +DTI1MDEwMTAwMDAwMFoYDzIwOTkxMjMxMjM1OTU5WjBZMRIwEAYDVQQDDAkxMjcu +MC4wLjExCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK +DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDChB5LljS2j20SXa+VHvEpsjmPtLEiuel4CDibe0v2yMBXzX+U +FhHUutrMSVpLRnk2s+WJ8voBPb7jTICm3u5VYnOjbmWAyC5ViuGhBNdhxOMCjiJs +3qEauNu+oQDS3cQeEVBHK4U05fxOKaXS+B3r1FvIiJUjj7yf5RfT1Rw3EvV5oDLj +fgv53tfD6CdQPf3d7XR5NdkZmiP/GDgNBkiaW/u/8i424l1TWHTd878CdxXUhZo5 +Cmu2ZoJm/JsVrnJ2FdovE3N+R+0FtKbaZZYK60R0jFb95oSzJI11IRK+Leij+4dS +2c5nlkS+7Ew3/1VlHZJt99aoD2JPh2Ea+56PAgMBAAGjUzBRMB0GA1UdDgQWBBQ2 +qPSBOmDn3biSI5Nhc5mdcUUrtjAfBgNVHSMEGDAWgBQ2qPSBOmDn3biSI5Nhc5md +cUUrtjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgQgPjZDV4 +xJySpf18XqnuQlteoxFQIFEe3edg7W7aC9E4g6L9ZtqnopmSDw1+RRT2bzBc1Uuz +MSs77OJlnM/OxrEBqP73GZXG5VvnOj36d4ZVJjh5NWBTdqegkNhkyMOBHLpGLWMv +wYOzXew4Q1yH6iIxZGUUu/BdV+cr933pAFZSaEGrXWWiYL2WI0eirALrMleuZpXL +qaQfMX8dnFrIzo7lkXZIPQjAkeL6HleJPIW6WhoLvhxAyOU1vPzNmXRjFItiMQqN +o567EM5VXKsJ40L27NfslzrgGA7SO6aiALoITX3zSZJ7qyNi9c5wpl1jKqspprjk +PWgM+zxSgE3x -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7RgCKzVAyLSEn -6QKs7S9kxRFhByxk8whIeQINrHTA+1GG6iDxyzhOBCDb/nahDDNDcy2J8OwobVXo -F0/dO8QmkHJngxUnYas3uC/M2sA355+LMgfFwMBmCX6bLWMHt5zuvtFry0m9QOU2 -DXsqF48JQFChJcZHlgKOdboUeNRg4Q0PRoKal9XHAIZkqFIYCEUs3+n+ChN1k3c5 -daddmbZGBwfCaNowfyV58Bjs+orC56Ub5HseAe7FF/u7tTKiv3tV+x4tRv1ZGgHw -tkjn403j7RgQwV60NWq2Fwz0QNOLIBc0oeeZe5Qv+B2rEP4wG94feXXBCKsnOvYo -qGjdXNTXAgMBAAECggEAD7yDISa9fWnjZlojGmrX16zjl/alWVo+sPBSJtn9+ZVk -tWSJHihIc+3O4Q2R5FiFGj7cbcHr5j3BwT3sPRfflKoAowgVx/hiDc2RXrJnAouZ -EXZDxu86e5iCpgF7V9OrATjRmjA74wZH/HHHjrLqFwnrfI8TCULmthfYag35Mqax -qrIEzvSuYdaGxblNe+ZfnVEDW2F9DLBGcma0ffUlJp8AvV7bpo8Rj/JovPxit/VS -UdwSRxwSAugctFpmcGlFkoQfxUx1WdEy8hjopLrayMjCCJvRUL4+C4zT9r9PBHOj -fCSbJ+ajQIoRrgaL9bURk8BFMHY8+yMUsWEYVSmFAQKBgQDtOvPkhvZsNocUB5nJ -ti3SXyDQ6OZQuKKHPSeDV/EvmZKeNlrQ1ZnwXLP3vkcedDOkt1nEVq/hUewpjt08 -2MvmMwJBQEnmbTzMf43DtlXsStdP1lhYaFbU4iMM5zRfyBHDu1GPZEPXvKKpJUk0 -M+jYIyTAP3mcZhqDKn0mPVP7VwKBgQDKFy9DtWFKxCvhFQvHx7YeZiVWJbIst/O4 -ZyuPVAErni0hzSeCkmm7+F9hgEdPSLRcSaeTWP4L0u1cixECKboIhoNs38aft7o3 -MdnI2RDSEKtKX2uVuhvpGDNuGpBAc8Qu8iCiv5INSC36ZhD1h++O/TiiUdgRJ3yX -yeG7ej+CgQKBgCR5F95e0aw5hfMSaBaXJ9xcO9Niu2ZVvMdGI7kR4EcNOXmRqczJ -ym0mE5VXb9/Cxd3hQq/pFAl0avbIvEMKoe62kPYvSC1hRiO6yLT6Z6N4rjncHqEZ -CaCZVAI72dWQEQsi1ZtSMwwMOIYA8YxRHs98N75HBA+DszfPZIZoj2zpAoGBAJHp -B3ElhmeLF/tdTLIj2bQ9H/wBH5H2Bvw/UU4c4vNxMzjSfRJjUAAtpgAptFLkNYTk -kR9sA5DZ7BMDPXaIVg9Nv5peP3SWHNc5IPtI7kIdUu9R0cW7J+e2V3vJphlC/ITA -wRuAoZ0BXmEKTHhae3aMEdXwrcZE8kpNsrO/4hcBAoGBAMISiPJPuxAX1UtqcxTa -mDJfnQ2gxRu6AK9VmXqo0X4IBxDSnTjcL0huUlS849wgsE5oTXgdYb2hn+TXM5JJ -NsEXLhV09X1mrk4M4LV1npd0mYxvFsO4+p+IX5YLiahInmQtq0gx3DWE8wouVFER -4yzfp27z8MZT8Qvr/ZI9lzWd +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDChB5LljS2j20S +Xa+VHvEpsjmPtLEiuel4CDibe0v2yMBXzX+UFhHUutrMSVpLRnk2s+WJ8voBPb7j +TICm3u5VYnOjbmWAyC5ViuGhBNdhxOMCjiJs3qEauNu+oQDS3cQeEVBHK4U05fxO +KaXS+B3r1FvIiJUjj7yf5RfT1Rw3EvV5oDLjfgv53tfD6CdQPf3d7XR5NdkZmiP/ +GDgNBkiaW/u/8i424l1TWHTd878CdxXUhZo5Cmu2ZoJm/JsVrnJ2FdovE3N+R+0F +tKbaZZYK60R0jFb95oSzJI11IRK+Leij+4dS2c5nlkS+7Ew3/1VlHZJt99aoD2JP +h2Ea+56PAgMBAAECggEAWDGUFNxxYRbNsuaUbi3d1XRwAdbA+8hEcX50wBZavnWO +NCFCB5AsHIJuIvLdREUbP3C4kd//d6GZ07BDoqVwdXlSihbLYeUhkPqLy7iIuVUO +QoHUXP1iGV4YkCmq2HDhc2qRNfunBXGDgKMEgw+pbVxXEyjOShXpRawXLh4xkUw1 +tGdgt4WSufui+5vCEQed1zrq1Q3vImZTJkoqyHwbc/VyirZsPP5jexRtJeAoS4cc +6IJntjN7SKQRu/S6bAm4OdX2ArCbeOZ3ss1wycENpLz4md25Sr7J+uszDQRS3JZS +buG7N1Ihm0oY3aMGCF10Q0yEU5pKqzLaAyoBE4rF0QKBgQDzGmwyZ9chHL5Zut+5 +s5AQchY+8kIZ1Ud35VzkqlE9S8JOsDmfAP4WR4DntqIPbE2F+9tNt1+hrQztfCG3 +in1FXX3nzJe7Sk93GMPsYC+lIBTmB09weXlbP7P9J2i0jVAUpHo1Pa1C+NVy2dOk +cU81vmVea6EJ9dBJYNVgdLeI/wKBgQDM1dXdkxibfqBqz/i4jvzywn/9yC5GEWXr +IRUKbxwiuirylNUQSlFKrqRpxay495FnJpwSs3qxvYGWiXAGgtIy1VluWWolrqG4 +gbnL3aDrHeC8BmTcfCnjIYGl7ACBTJFH4qR1FzMt2FYm+lI0SwGrvinqbLUF5dW4 +uHzRbbHacQKBgQDqh+E+N8PqJArYEltokn04AHjJvXpb5dEPMG4QBOhfVElfFNBi +P9jhsZYA9ccfTgL0ceg+79wI5CSGsKzun2L/mpSvHkh73dMQOQo7bwhIK809pmvT +PL4BdFG2t2BiX7qUT6G+34PaCqoSJWfzS4V5effdwcQZEdciE5OHfNLcDQKBgQCS +mRgPFI+v+dhlmaKws+Vk+L8Rqoszqo/+0BZ2+T5xvDuwkcRLfGThxkv1R3xuhQCT +ipZ46+sL+k0cqBB9GHPH3dm7mFLX1Tv5CR8oQN5CZ4fICet1wYdY/0oCrf1OjLYN +dK+u/YOrdAF0tALRWj0/5UGqfVKxfeSP57mtSYzYgQKBgQChNy3y9sFp4WcRBjWE +2IJtTMD682rrxnJQCND6tOgYi+8hGCnbt9wJes4Z73UjTMwNDohImOaC9VImPVYC +GdSaWzpHru18PcKExq6SFRYbZXagwCXMAXB4v17h/Vm4PsjJZFTgrnFTb5FUIMDR +yaWMV5Lt8jgV/NINDPcq2P58Ow== -----END PRIVATE KEY----- diff --git a/ext/ftp/tests/ftp_close_during_transfer.phpt b/ext/ftp/tests/ftp_close_during_transfer.phpt new file mode 100644 index 000000000000..72e410603921 --- /dev/null +++ b/ext/ftp/tests/ftp_close_during_transfer.phpt @@ -0,0 +1,44 @@ +--TEST-- +ftp_close() from a stream wrapper during a transfer throws instead of freeing the connection +--EXTENSIONS-- +ftp +pcntl +--FILE-- +getMessage(), "\n"; +} + +ftp_close($ftp); +echo "closed\n"; +?> +--EXPECT-- +bool(true) +Cannot close FTP\Connection while a transfer is in progress +closed diff --git a/ext/ftp/tests/ftp_get_ascii_bare_cr.phpt b/ext/ftp/tests/ftp_get_ascii_bare_cr.phpt new file mode 100644 index 000000000000..1fe92bf8de7e --- /dev/null +++ b/ext/ftp/tests/ftp_get_ascii_bare_cr.phpt @@ -0,0 +1,32 @@ +--TEST-- +ftp_get() ASCII mode: bare CR is preserved, CRLF folds to LF +--EXTENSIONS-- +ftp +pcntl +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt b/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt new file mode 100644 index 000000000000..4c3a70b647c6 --- /dev/null +++ b/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt @@ -0,0 +1,25 @@ +--TEST-- +ftp_get() ASCII mode: CRLF straddling the FTP_BUFSIZE read boundary +--EXTENSIONS-- +ftp +pcntl +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/ftp/tests/ftp_nb_close_during_transfer.phpt b/ext/ftp/tests/ftp_nb_close_during_transfer.phpt new file mode 100644 index 000000000000..702648f69592 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_close_during_transfer.phpt @@ -0,0 +1,44 @@ +--TEST-- +ftp_close() from a stream wrapper during a non-blocking transfer throws instead of freeing the connection +--EXTENSIONS-- +ftp +pcntl +--FILE-- +getMessage(), "\n"; +} + +ftp_close($ftp); +echo "closed\n"; +?> +--EXPECT-- +bool(true) +Cannot close FTP\Connection while a transfer is in progress +closed diff --git a/ext/ftp/tests/ftp_nb_get_during_nb_transfer.phpt b/ext/ftp/tests/ftp_nb_get_during_nb_transfer.phpt new file mode 100644 index 000000000000..deb1698c77c5 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_get_during_nb_transfer.phpt @@ -0,0 +1,44 @@ +--TEST-- +Re-entrant ftp_nb_get() from a stream wrapper during an active non-blocking ftp_nb_get() must not corrupt the outer transfer +--EXTENSIONS-- +ftp +pcntl +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +closed diff --git a/ext/ftp/tests/ftp_nb_get_during_transfer.phpt b/ext/ftp/tests/ftp_nb_get_during_transfer.phpt new file mode 100644 index 000000000000..c7920496feb4 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_get_during_transfer.phpt @@ -0,0 +1,40 @@ +--TEST-- +Re-entrant ftp_nb_get() from a stream wrapper during a blocking ftp_get() must not free the active data connection +--EXTENSIONS-- +ftp +pcntl +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +closed diff --git a/ext/ftp/tests/gh20601_set_option.phpt b/ext/ftp/tests/gh20601_set_option.phpt new file mode 100644 index 000000000000..3317d4b5f2a0 --- /dev/null +++ b/ext/ftp/tests/gh20601_set_option.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-20601 (ftp_set_option FTP_TIMEOUT_SEC timeout overflow) +--EXTENSIONS-- +ftp +pcntl +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +ftp_set_option(): Argument #3 ($value) must be less than %d for the FTP_TIMEOUT_SEC option diff --git a/ext/ftp/tests/gh20601_ssl.phpt b/ext/ftp/tests/gh20601_ssl.phpt new file mode 100644 index 000000000000..005f866e18e0 --- /dev/null +++ b/ext/ftp/tests/gh20601_ssl.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-20601 (ftp_ssl_connect timeout overflow) +--EXTENSIONS-- +ftp +openssl +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +ftp_ssl_connect(): Argument #3 ($timeout) must be less than %d diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 97f4f07d0020..2c7a3a8a5643 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -290,7 +290,7 @@ if ($pid) { } if (empty($m[1]) || $m[1] !== 'emptydir') { - fputs($fs, "file1\r\nfile1\r\nfile\nb0rk\r\n"); + fputs($fs, $nlst_data ?? "file1\r\nfile1\r\nfile\nb0rk\r\n"); } fputs($s, "226 Closing data Connection.\r\n"); @@ -391,6 +391,27 @@ if ($pid) { // Just a side channel for getting the received file size. fputs($s, "425 Can't open data connection (".$GLOBALS['rest_pos'].").\r\n"); break; + case "crlf_boundary": + // A CRLF whose CR lands on the final byte of the first + // FTP_BUFSIZE (4096) read, so the LF arrives in the next read. + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, str_repeat("A", 4095) . "\r\n" . str_repeat("B", 10)); + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "bare_cr": + // A bare CR (not part of CRLF) mid-stream, plus a bare CR on + // the final byte of the first FTP_BUFSIZE (4096) read followed + // by a non-LF byte in the next read. + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, "line1\r\nba\rre\r\nend" . str_repeat("X", 4078) . "\r" . str_repeat("Y", 10)); + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "trailing_cr": + // The whole transfer ends on a bare CR. + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, "trail\r"); + fputs($s, "226 Closing data Connection.\r\n"); + break; default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index a997238b7f75..17f508be2a9a 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -20,6 +20,13 @@ PHP_ARG_WITH([avif], [no], [no]) +PHP_ARG_WITH([uhdr], + [for libuhdr], + [AS_HELP_STRING([--with-uhdr], + [GD: Enable UltraHDR support (only for bundled libgd)])], + [no], + [no]) + PHP_ARG_WITH([webp], [for libwebp], [AS_HELP_STRING([--with-webp], @@ -55,6 +62,27 @@ PHP_ARG_ENABLE([gd-jis-conv], [no], [no]) +PHP_ARG_WITH([heif], + [for libheif], + [AS_HELP_STRING([--with-heif], + [GD: Enable HEIF support (only for bundled libgd)])], + [no], + [no]) + +PHP_ARG_WITH([imagequant], + [for libimagequant], + [AS_HELP_STRING([--with-imagequant], + [GD: Enable libimagequant support (only for bundled libgd)])], + [no], + [no]) + +PHP_ARG_WITH([tiff], + [for libtiff], + [AS_HELP_STRING([--with-tiff], + [GD: Enable TIFF support (only for bundled libgd)])], + [no], + [no]) + dnl dnl Checks for the configure options dnl @@ -70,7 +98,7 @@ AC_DEFUN([PHP_GD_PNG],[ AC_DEFUN([PHP_GD_AVIF], [ AS_VAR_IF([PHP_AVIF], [no],, [ - PKG_CHECK_MODULES([AVIF], [libavif >= 0.8.2]) + PKG_CHECK_MODULES([AVIF], [libavif >= 1.0.0]) PHP_EVAL_LIBLINE([$AVIF_LIBS], [GD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$AVIF_CFLAGS]) AC_DEFINE([HAVE_LIBAVIF], [1], @@ -80,9 +108,39 @@ AC_DEFUN([PHP_GD_AVIF], [ ]) ]) +AC_DEFUN([PHP_GD_HEIF], [ + AS_VAR_IF([PHP_HEIF], [no],, [ + PKG_CHECK_MODULES([HEIF], [libheif >= 1.7.0]) + PHP_EVAL_LIBLINE([$HEIF_LIBS], [GD_SHARED_LIBADD]) + PHP_EVAL_INCLINE([$HEIF_CFLAGS]) + AC_DEFINE([HAVE_LIBHEIF], [1], + [Define to 1 if you have the libheif library.]) + AC_DEFINE([HAVE_GD_HEIF], [1], + [Define to 1 if gd extension has HEIF support.]) + ]) +]) + +AC_DEFUN([PHP_GD_UHDR], [ + AS_VAR_IF([PHP_UHDR], [no],, [ + PKG_CHECK_MODULES([UHDR], [libuhdr >= 1.4.0]) + PHP_EVAL_LIBLINE([$UHDR_LIBS], [GD_SHARED_LIBADD]) + PHP_EVAL_INCLINE([$UHDR_CFLAGS]) + + PKG_CHECK_VAR([UHDR_WRITE_XMP], [libuhdr], [UHDR_WRITE_XMP]) + AS_VAR_IF([UHDR_WRITE_XMP], [], [], + [AC_MSG_ERROR([libuhdr was compiled with UHDR_WRITE_XMP enabled, but this extension requires it to be OFF.])]) + + AC_DEFINE([HAVE_LIBUHDR], [1], + [Define to 1 if you have the libuhdr library.]) + AC_DEFINE([HAVE_GD_UHDR], [1], + [Define to 1 if gd extension has UltraHDR support.]) + ]) +]) + AC_DEFUN([PHP_GD_WEBP],[ AS_VAR_IF([PHP_WEBP], [no],, [ - PKG_CHECK_MODULES([WEBP], [libwebp >= 0.2.0]) + PKG_CHECK_MODULES([WEBP], + [libwebp >= 0.2.0 libwebpdemux libwebpmux]) PHP_EVAL_LIBLINE([$WEBP_LIBS], [GD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$WEBP_CFLAGS]) AC_DEFINE([HAVE_LIBWEBP], [1], @@ -110,6 +168,7 @@ AC_DEFUN([PHP_GD_XPM],[ PHP_EVAL_LIBLINE([$XPM_LIBS], [GD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$XPM_CFLAGS]) AC_DEFINE([HAVE_XPM], [1], [Define to 1 if you have the xpm library.]) + AC_DEFINE([HAVE_LIBXPM], [1], [Define to 1 if you have the xpm library.]) AC_DEFINE([HAVE_GD_XPM], [1], [Define to 1 if gd extension has XPM support.]) ]) @@ -136,6 +195,35 @@ AC_DEFUN([PHP_GD_JISX0208],[ ]) ]) +AC_DEFUN([PHP_GD_IMAGEQUANT], [ + AS_VAR_IF([PHP_IMAGEQUANT], [no],, [ + AC_CHECK_HEADER([libimagequant.h], [], + [AC_MSG_ERROR([libimagequant header not found])]) + PHP_CHECK_LIBRARY([imagequant], [liq_attr_create], + [ + PHP_ADD_LIBRARY([imagequant], [], [GD_SHARED_LIBADD]) + AC_DEFINE([HAVE_LIBIMAGEQUANT], [1], + [Define to 1 if you have the libimagequant library.]) + AC_DEFINE([HAVE_GD_IMAGEQUANT], [1], + [Define to 1 if gd extension has libimagequant support.]) + ], + [AC_MSG_ERROR([libimagequant library not found])], + [-limagequant]) + ]) +]) + +AC_DEFUN([PHP_GD_TIFF], [ + AS_VAR_IF([PHP_TIFF], [no],, [ + PKG_CHECK_MODULES([TIFF], [libtiff-4]) + PHP_EVAL_LIBLINE([$TIFF_LIBS], [GD_SHARED_LIBADD]) + PHP_EVAL_INCLINE([$TIFF_CFLAGS]) + AC_DEFINE([HAVE_LIBTIFF], [1], + [Define to 1 if you have the libtiff library.]) + AC_DEFINE([HAVE_GD_TIFF], [1], + [Define to 1 if gd extension has TIFF support.]) + ]) +]) + dnl dnl PHP_GD_CHECK_FORMAT(format, [action-if-found]) dnl @@ -194,6 +282,7 @@ AS_VAR_POPDEF([php_var]) AC_DEFUN([PHP_GD_CHECK_VERSION],[ PHP_GD_CHECK_FORMAT([Png], [AC_DEFINE([HAVE_GD_PNG], [1])]) PHP_GD_CHECK_FORMAT([Avif], [AC_DEFINE([HAVE_GD_AVIF], [1])]) + PHP_GD_CHECK_FORMAT([Heif], [AC_DEFINE([HAVE_GD_HEIF], [1])]) PHP_GD_CHECK_FORMAT([Webp], [AC_DEFINE([HAVE_GD_WEBP], [1])]) PHP_GD_CHECK_FORMAT([Jpeg], [AC_DEFINE([HAVE_GD_JPG], [1])]) PHP_GD_CHECK_FORMAT([Xpm], [AC_DEFINE([HAVE_GD_XPM], [1])]) @@ -206,6 +295,11 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ [Define to 1 if GD library has the 'gdVersionString' function.])], [], [$GD_SHARED_LIBADD]) + PHP_CHECK_LIBRARY([gd], [gdPngGetVersionString], + [AC_DEFINE([HAVE_GD_PNG_GET_VERSION_STRING], [1], + [Define to 1 if GD library has the 'gdPngGetVersionString' function.])], + [], + [$GD_SHARED_LIBADD]) PHP_CHECK_LIBRARY([gd], [gdImageGetInterpolationMethod], [AC_DEFINE([HAVE_GD_GET_INTERPOLATION], [1], [Define to 1 if GD library has the 'gdImageGetInterpolationMethod' @@ -237,6 +331,7 @@ if test "$PHP_GD" != "no"; then libgd/gd_io.c libgd/gd_jpeg.c libgd/gd_matrix.c + libgd/gd_metadata.c libgd/gd_png.c libgd/gd_rotate.c libgd/gd_security.c @@ -260,6 +355,33 @@ if test "$PHP_GD" != "no"; then libgd/gdtables.c libgd/gdxpm.c libgd/wbmp.c + libgd/gd_qoi.c + libgd/gd_jxl.c + libgd/gd_color_map.c + libgd/gd_heif.c + libgd/gd_uhdr.c + libgd/gd_nnquant.c + libgd/gd_color.c + libgd/gd_tiff.c + libgd/gd_readimage.c + libgd/gd_filename.c + libgd/ftraster/gd_ft_math.c + libgd/ftraster/gd_ft_raster.c + libgd/ftraster/gd_ft_stroker.c + libgd/gd_array.c + libgd/gd_span_rle.c + libgd/gd_surface.c + libgd/gd_version.c + libgd/gd_compositor.c + libgd/gd_gradient.c + libgd/gd_path.c + libgd/gd_path_arc.c + libgd/gd_path_dash.c + libgd/gd_path_matrix.c + libgd/gd_path_stroke.c + libgd/gd_draw.c + libgd/gd_draw_blend.c + libgd/gd_perceptual_diff.c "]) AC_DEFINE([HAVE_GD_BUNDLED], [1], @@ -269,21 +391,37 @@ if test "$PHP_GD" != "no"; then [Define to 1 if GD library has the 'gdImageGetInterpolationMethod' function.]) + AC_DEFINE([HAVE_GD_PNG_GET_VERSION_STRING], [1], + [Define to 1 if GD library has the 'gdPngGetVersionString' function.]) + + dnl Some systems (e.g. Solaris) declare iconv_t in as something + dnl other than 'void *'. The bundled libgd/gdkanji.c only falls back to its + dnl own 'typedef void *iconv_t' when HAVE_ICONV_T_DEF is undefined, so detect + dnl the system definition to avoid a conflicting typedef. + AC_EGREP_HEADER([typedef.*iconv_t], [iconv.h], + [AC_DEFINE([HAVE_ICONV_T_DEF], [1], + [Define to 1 if defines iconv_t.])]) + dnl Various checks for GD features PHP_SETUP_ZLIB([GD_SHARED_LIBADD]) PHP_GD_PNG PHP_GD_AVIF + PHP_GD_HEIF + PHP_GD_UHDR PHP_GD_WEBP PHP_GD_JPEG PHP_GD_XPM PHP_GD_FREETYPE2 PHP_GD_JISX0208 + PHP_GD_IMAGEQUANT + PHP_GD_TIFF PHP_NEW_EXTENSION([gd], [gd.c $extra_sources], [$ext_shared],, [-Wno-strict-prototypes -I@ext_srcdir@/libgd]) PHP_ADD_BUILD_DIR([$ext_builddir/libgd]) + PHP_ADD_BUILD_DIR([$ext_builddir/libgd/ftraster]) PHP_INSTALL_HEADERS([ext/gd], [php_gd.h libgd/]) diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 506bb05cf2e0..a34e9ea8a555 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -3,6 +3,11 @@ ARG_WITH("gd", "Bundled GD support", "yes,shared"); ARG_WITH("libwebp", "webp support", "yes"); ARG_WITH("libavif", "avif support", "yes"); +ARG_WITH("heif", "HEIF support", "yes"); +ARG_WITH("uhdr", "UltraHDR support", "yes"); +ARG_WITH("jxl", "JPEG XL support", "yes"); +ARG_WITH("imagequant", "libimagequant support", "no"); +ARG_WITH("tiff", "TIFF support", "no"); if (PHP_GD != "no") { if ( @@ -25,12 +30,17 @@ if (PHP_GD != "no") { CHECK_HEADER("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11") ) { AC_DEFINE('HAVE_XPM', 1, "Define to 1 if you have the xpm library."); + AC_DEFINE('HAVE_LIBXPM', 1, "Define to 1 if you have the xpm library."); AC_DEFINE('HAVE_GD_XPM', 1, "Define to 1 if gd extension has XPM support."); } if (PHP_LIBWEBP != "no") { if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) && + (CHECK_LIB("libwebpdemux_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebpdemux.lib", "gd", PHP_GD)) && + (CHECK_LIB("libwebpmux_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebpmux.lib", "gd", PHP_GD)) && CHECK_HEADER("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && - CHECK_HEADER("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { + CHECK_HEADER("demux.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && + CHECK_HEADER("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && + CHECK_HEADER("mux.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { AC_DEFINE("HAVE_LIBWEBP", 1, "Define to 1 if you have the libwebp library."); AC_DEFINE("HAVE_GD_WEBP", 1, "Define to 1 if gd extension has WebP support."); } else { @@ -49,18 +59,105 @@ if (PHP_GD != "no") { WARNING("libavif not enabled; libraries and headers not found"); } } + + if (PHP_HEIF != "no") { + var heif_location = CHECK_LIB("heif_a.lib;heif.lib", "gd", PHP_GD); + if (!CHECK_HEADER("libheif/heif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) { + heif_location = false; + } + if (heif_location && heif_location.match(/heif_a\.lib$/)) { + if (!(CHECK_LIB("aom_a.lib", "gd", PHP_GD) && + CHECK_LIB("dav1d_a.lib", "gd", PHP_GD))) { + WARNING("static libheif not enabled; codec libraries not found"); + heif_location = false; + } else { + ADD_FLAG("CFLAGS_GD", "/D LIBHEIF_STATIC_BUILD"); + } + } + if (heif_location) { + ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBHEIF /D HAVE_GD_HEIF"); + } else { + WARNING("libheif not enabled; library and headers not found"); + } + } + + // requires UHDR_WRITE_XMP=Off, for the windows build team, when adding/updating libuhdr + if (PHP_UHDR != "no") { + var uhdr_location = CHECK_LIB("uhdr_a.lib;uhdr.lib", "gd", PHP_GD); + if (uhdr_location && + CHECK_HEADER("ultrahdr_api.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) { + if (uhdr_location.match(/uhdr\.lib$/)) { + ADD_FLAG("CFLAGS_GD", "/D UHDR_USING_SHARED_LIBRARY"); + } + ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBUHDR /D HAVE_GD_UHDR"); + } else { + WARNING("libuhdr not enabled; library and headers not found"); + } + } + + if (PHP_JXL != "no") { + var jxl_location = CHECK_LIB("jxl_a.lib;jxl.lib", "gd", PHP_GD); + if (jxl_location && jxl_location.match(/jxl_a\.lib$/)) { + if (!(CHECK_LIB("jxl_cms_a.lib", "gd", PHP_GD) && + CHECK_LIB("hwy_a.lib", "gd", PHP_GD) && + CHECK_LIB("brotlienc.lib;brotlienc-static.lib", "gd", PHP_GD) && + CHECK_LIB("brotlidec.lib;brotlidec-static.lib", "gd", PHP_GD) && + CHECK_LIB("brotlicommon.lib;brotlicommon-static.lib", "gd", PHP_GD))) { + WARNING("static libjxl not enabled; dependency libraries not found"); + jxl_location = false; + } else { + ADD_FLAG("CFLAGS_GD", "/D JXL_STATIC_DEFINE /D JXL_CMS_STATIC_DEFINE"); + } + } + if (jxl_location && + CHECK_HEADER("jxl/decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include") && + CHECK_HEADER("jxl/encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) { + ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBJXL /D HAVE_GD_JXL"); + } else { + WARNING("libjxl not enabled; library and headers not found"); + } + } + + if (PHP_IMAGEQUANT != "no") { + if (CHECK_LIB("imagequant.lib", "gd", PHP_GD) && + CHECK_HEADER("libimagequant.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) { + ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBIMAGEQUANT /D HAVE_GD_IMAGEQUANT"); + } else { + WARNING("libimagequant not enabled; library and headers not found"); + } + } + + if (PHP_TIFF != "no") { + if (CHECK_LIB("tiff_a.lib;tiff.lib", "gd", PHP_GD) && + CHECK_LIB("liblzma_a.lib;liblzma.lib", "gd", PHP_GD) && + CHECK_LIB("libzstd_a.lib;libzstd.lib", "gd", PHP_GD) && + CHECK_LIB("libwebp_a.lib;libwebp.lib", "gd", PHP_GD) && + CHECK_HEADER("tiff.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) { + ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBTIFF /D HAVE_GD_TIFF"); + } else { + WARNING("libtiff not enabled; library and headers not found"); + } + } + CHECK_LIB("User32.lib", "gd", PHP_GD); CHECK_LIB("Gdi32.lib", "gd", PHP_GD); + CHECK_LIB("Advapi32.lib", "gd", PHP_GD); EXTENSION("gd", "gd.c", null, "-Iext/gd/libgd"); ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd.c \ gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \ gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \ - gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \ + gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_metadata.c gd_png.c gd_ss.c \ gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \ gd_filter.c gd_rotate.c gd_color_match.c gd_webp.c gd_avif.c \ - gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd"); + gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c gd_qoi.c gd_jxl.c gd_color_map.c \ + gd_heif.c gd_uhdr.c gd_tiff.c gd_nnquant.c gd_color.c gd_readimage.c gd_filename.c \ + gd_array.c gd_span_rle.c \ + gd_surface.c gd_version.c gd_compositor.c gd_gradient.c gd_path.c gd_path_arc.c gd_path_dash.c \ + gd_path_matrix.c gd_path_stroke.c gd_draw.c gd_draw_blend.c gd_perceptual_diff.c", "gd"); + ADD_SOURCES("ext/gd/libgd/ftraster", "gd_ft_math.c gd_ft_raster.c gd_ft_stroker.c", "gd"); AC_DEFINE('HAVE_GD_BUNDLED', 1, "Define to 1 if gd extension uses GD library bundled in PHP."); + AC_DEFINE('HAVE_GD_PNG_GET_VERSION_STRING', 1, "Define to 1 if GD library has the 'gdPngGetVersionString' function."); AC_DEFINE('HAVE_GD_PNG', 1, "Define to 1 if gd extension has PNG support."); AC_DEFINE('HAVE_LIBPNG', 1, "Define to 1 if you have the libpng library."); AC_DEFINE('HAVE_LIBJPEG', 1, "Define to 1 if you have the libjpeg library."); diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 81f442f33348..24da05548cb4 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -146,14 +144,7 @@ static zend_function *php_gd_image_object_get_constructor(zend_object *object) return NULL; } -/** - * Returns the underlying php_gd_image_object from a zend_object - */ - -static zend_always_inline php_gd_image_object* php_gd_exgdimage_from_zobj_p(zend_object* obj) -{ - return (php_gd_image_object *) ((char *) (obj) - XtOffsetOf(php_gd_image_object, std)); -} +#define php_gd_exgdimage_from_zobj_p(obj) ZEND_CONTAINER_OF(obj, php_gd_image_object, std) /** * Converts an extension GdImage instance contained within a zval into the gdImagePtr @@ -208,7 +199,7 @@ static void php_gd_object_minit_helper(void) php_gd_image_object_handlers.free_obj = php_gd_image_object_free; php_gd_image_object_handlers.get_constructor = php_gd_image_object_get_constructor; php_gd_image_object_handlers.compare = zend_objects_not_comparable; - php_gd_image_object_handlers.offset = XtOffsetOf(php_gd_image_object, std); + php_gd_image_object_handlers.offset = offsetof(php_gd_image_object, std); } static zend_class_entry *gd_font_ce = NULL; @@ -273,7 +264,7 @@ static void php_gd_font_minit_helper(void) php_gd_font_object_handlers.clone_obj = NULL; php_gd_font_object_handlers.free_obj = php_gd_font_object_free; php_gd_font_object_handlers.get_constructor = php_gd_font_object_get_constructor; - php_gd_font_object_handlers.offset = XtOffsetOf(php_gd_font_object, std); + php_gd_font_object_handlers.offset = offsetof(php_gd_font_object, std); } /********************************************************* @@ -308,6 +299,15 @@ PHP_INI_END() /* {{{ php_gd_error_method */ void php_gd_error_method(int type, const char *format, va_list args) { + /* Keep PHP's historical PNG warning text while bundled gd_png.c stays + * identical to upstream libgd. */ + if (strcmp(format, "gd-png: fatal libpng error: %s\n") == 0) { + format = "gd-png: fatal libpng error: %s"; + } else if (strncmp(format, "gd-png error: setjmp returns error condition", + sizeof("gd-png error: setjmp returns error condition") - 1) == 0) { + format = "gd-png error: setjmp returns error condition"; + } + switch (type) { #ifndef PHP_WIN32 case GD_DEBUG: @@ -322,7 +322,7 @@ void php_gd_error_method(int type, const char *format, va_list args) default: type = E_ERROR; } - php_verror(NULL, "", type, format, args); + php_verror(NULL, type, format, args); } /* }}} */ @@ -367,7 +367,7 @@ PHP_RSHUTDOWN_FUNCTION(gd) /* }}} */ #ifdef HAVE_GD_BUNDLED -#define PHP_GD_VERSION_STRING "bundled (2.1.0 compatible)" +#define PHP_GD_VERSION_STRING "bundled (2.4.0 compatible)" #else # define PHP_GD_VERSION_STRING GD_VERSION_STRING #endif @@ -422,7 +422,7 @@ PHP_MINFO_FUNCTION(gd) #ifdef HAVE_GD_PNG php_info_print_table_row(2, "PNG Support", "enabled"); -#ifdef HAVE_GD_BUNDLED +#ifdef HAVE_GD_PNG_GET_VERSION_STRING php_info_print_table_row(2, "libPNG Version", gdPngGetVersionString()); #endif #endif @@ -542,7 +542,7 @@ PHP_FUNCTION(imageloadfont) */ font = (gdFontPtr) emalloc(sizeof(gdFont)); b = 0; - while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size - b)) > 0) { + while (b < hdr_size && (n = php_stream_read(stream, (char *) font + b, hdr_size - b)) > 0) { b += n; } @@ -640,7 +640,20 @@ PHP_FUNCTION(imagesetstyle) stylearr = safe_emalloc(num_styles, sizeof(int), 0); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(styles), item) { - stylearr[index++] = zval_get_long(item); + bool failed = false; + ZVAL_DEREF(item); + zend_long tmp = zval_try_get_long(item, &failed); + if (failed) { + efree(stylearr); + zend_argument_type_error(2, "must only have elements of type int, %s given", zend_zval_type_name(item)); + RETURN_THROWS(); + } + if (ZEND_LONG_EXCEEDS_INT(tmp)) { + efree(stylearr); + zend_argument_value_error(2, "elements must be between %d and %d", INT_MIN, INT_MAX); + RETURN_THROWS(); + } + stylearr[index++] = (int) tmp; } ZEND_HASH_FOREACH_END(); gdImageSetStyle(im, stylearr, index); @@ -719,6 +732,10 @@ PHP_FUNCTION(imagetruecolortopalette) RETURN_THROWS(); } + /* Preserve PHP's historical palette conversion behavior regardless of + * whether bundled libgd was built with libimagequant support. */ + gdImageTrueColorToPaletteSetMethod(im, GD_QUANT_JQUANT, 0); + if (gdImageTrueColorToPalette(im, dither, (int)ncolors)) { RETURN_TRUE; } else { @@ -764,19 +781,15 @@ PHP_FUNCTION(imagecolormatch) case -1: zend_argument_value_error(1, "must be TrueColor"); RETURN_THROWS(); - break; case -2: zend_argument_value_error(2, "must be Palette"); RETURN_THROWS(); - break; case -3: zend_argument_value_error(2, "must be the same size as argument #1 ($im1)"); RETURN_THROWS(); - break; case -4: zend_argument_value_error(2, "must have at least one color"); RETURN_THROWS(); - break; } RETURN_TRUE; @@ -1599,7 +1612,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: - ignore_warning = INI_INT("gd.jpeg_ignore_warning"); + ignore_warning = zend_ini_bool_literal("gd.jpeg_ignore_warning"); im = gdImageCreateFromJpegEx(fp, ignore_warning); break; #endif @@ -1750,7 +1763,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type) RETURN_THROWS(); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } /* quality must fit in an int */ @@ -1780,7 +1793,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type) } gdImageGd2(im, fp, quality, type); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } fflush(fp); fclose(fp); @@ -1806,7 +1819,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type) } gdImageGd2(im, tmp, quality, type); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } fseek(tmp, 0, SEEK_SET); @@ -1880,6 +1893,8 @@ PHP_FUNCTION(imagegif) gdImagePtr im; gdIOCtx *ctx; zval *to_zval = NULL; + int quantization_method; + int quantization_speed; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!", &imgind, gd_image_ce, &to_zval) == FAILURE) { RETURN_THROWS(); @@ -1892,7 +1907,18 @@ PHP_FUNCTION(imagegif) RETURN_FALSE; } + quantization_method = im->paletteQuantizationMethod; + quantization_speed = im->paletteQuantizationSpeed; + if (im->trueColor) { + /* GIF conversion historically used JQUANT in PHP. Keep output stable + * when bundled libgd has a build-dependent default such as LIQ. */ + gdImageTrueColorToPaletteSetMethod(im, GD_QUANT_JQUANT, 0); + } gdImageGifCtx(im, ctx); + if (im->trueColor) { + gdImageTrueColorToPaletteSetMethod(im, quantization_method, + quantization_speed); + } ctx->gd_free(ctx); @@ -1928,7 +1954,28 @@ PHP_FUNCTION(imagepng) } #ifdef HAVE_GD_BUNDLED - gdImagePngCtxEx(im, ctx, (int) quality, (int) basefilter); + { + gdPngWriteOptions options; + unsigned int filters = GD_PNG_FILTER_NONE; + unsigned int unknown_filters; + + gdPngWriteOptionsInit(&options); + options.compression_level = (int) quality; + if (basefilter >= 0) { + unsigned long php_filters = (unsigned long) basefilter; + if (php_filters & 0x08) filters |= GD_PNG_FILTER_NONE; + if (php_filters & 0x10) filters |= GD_PNG_FILTER_SUB; + if (php_filters & 0x20) filters |= GD_PNG_FILTER_UP; + if (php_filters & 0x40) filters |= GD_PNG_FILTER_AVERAGE; + if (php_filters & 0x80) filters |= GD_PNG_FILTER_PAETH; + unknown_filters = (unsigned int) (php_filters & ~0xf8UL); + if (unknown_filters != 0) { + filters |= 1U << 31; + } + } + options.filters = filters; + (void) gdImagePngCtxWithOptions(im, ctx, &options); + } #else gdImagePngCtxEx(im, ctx, (int) quality); #endif @@ -3599,7 +3646,20 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS) colors = safe_emalloc(num_colors, sizeof(int), 0); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(hash_colors), color) { - *(colors + i++) = (int) zval_get_long(color); + bool failed = false; + ZVAL_DEREF(color); + zend_long tmp = zval_try_get_long(color, &failed); + if (failed) { + efree(colors); + zend_argument_type_error(5, "must be of type int, %s given", zend_zval_type_name(color)); + RETURN_THROWS(); + } + if (tmp < 0 || ZEND_LONG_INT_OVFL(tmp)) { + efree(colors); + zend_argument_value_error(5, "value must be between 0 and %d", INT_MAX); + RETURN_THROWS(); + } + colors[i++] = (int) tmp; } ZEND_HASH_FOREACH_END(); RETVAL_BOOL(gdImageScatterColor(im, (int)scatter_sub, (int)scatter_plus, colors, num_colors)); @@ -3767,6 +3827,23 @@ PHP_FUNCTION(imageantialias) } /* }}} */ +static bool php_gd_zval_try_get_c_int(zval *tmp, const char *field, int *res) { + zend_long r; + bool failed = false; + ZVAL_DEREF(tmp); + r = zval_try_get_long(tmp, &failed); + if (failed) { + zend_argument_type_error(2, "\"%s\" key must be of type int, %s given", field, zend_zval_type_name(tmp)); + return false; + } + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(r))) { + zend_argument_value_error(2, "\"%s\" key must be between %d and %d", field, INT_MIN, INT_MAX); + return false; + } + *res = (int)r; + return true; +} + /* {{{ Crop an image using the given coordinates and size, x, y, width and height. */ PHP_FUNCTION(imagecrop) { @@ -3785,28 +3862,36 @@ PHP_FUNCTION(imagecrop) im = php_gd_libgdimageptr_from_zval_p(IM); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") -1)) != NULL) { - rect.x = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "x", &rect.x)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have an \"x\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) { - rect.y = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "y", &rect.y)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"y\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) { - rect.width = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "width", &rect.width)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"width\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) { - rect.height = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "height", &rect.height)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"height\" key"); RETURN_THROWS(); diff --git a/ext/gd/libgd/.clang-format b/ext/gd/libgd/.clang-format new file mode 100644 index 000000000000..ce71740440b3 --- /dev/null +++ b/ext/gd/libgd/.clang-format @@ -0,0 +1,22 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +UseTab: Never +ColumnLimit: 100 +PointerAlignment: Right +SpaceBeforeParens: ControlStatements + +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true + AfterControlStatement: false + AfterEnum: false + AfterStruct: false + AfterUnion: false + AfterNamespace: false + AfterExternBlock: false + BeforeElse: false + BeforeCatch: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false \ No newline at end of file diff --git a/ext/gd/libgd/bmp.h b/ext/gd/libgd/bmp.h index cecde0383f53..6864a670e7e0 100644 --- a/ext/gd/libgd/bmp.h +++ b/ext/gd/libgd/bmp.h @@ -1,32 +1,34 @@ -/* $Id$ */ +#ifndef BMP_H +#define BMP_H 1 + #ifdef __cplusplus extern "C" { #endif - /* - gd_bmp.c +/* + gd_bmp.c - Bitmap format support for libgd + Bitmap format support for libgd - * Written 2007, Scott MacVicar - --------------------------------------------------------------------------- + * Written 2007, Scott MacVicar + --------------------------------------------------------------------------- - Todo: + Todo: - RLE4, RLE8 and Bitfield encoding - Add full support for Windows v4 and Windows v5 header formats + RLE4, RLE8 and Bitfield encoding + Add full support for Windows v4 and Windows v5 header formats - ---------------------------------------------------------------------------- - */ - -#ifndef BMP_H -#define BMP_H 1 + ---------------------------------------------------------------------------- + */ #define BMP_PALETTE_3 1 #define BMP_PALETTE_4 2 #define BMP_WINDOWS_V3 40 +#define BMP_WINDOWS_V2 52 +#define BMP_WINDOWS_V3_ALPHA 56 #define BMP_OS2_V1 12 +#define BMP_OS2_V2_SHORT 16 #define BMP_OS2_V2 64 #define BMP_WINDOWS_V4 108 #define BMP_WINDOWS_V5 124 @@ -37,6 +39,7 @@ extern "C" { #define BMP_BI_BITFIELDS 3 #define BMP_BI_JPEG 4 #define BMP_BI_PNG 5 +#define BMP_BI_ALPHABITFIELDS 6 #define BMP_RLE_COMMAND 0 #define BMP_RLE_ENDOFLINE 0 @@ -46,67 +49,78 @@ extern "C" { #define BMP_RLE_TYPE_RAW 0 #define BMP_RLE_TYPE_RLE 1 - /* BMP header. */ - typedef struct { - /* 16 bit - header identifying the type */ - signed short int magic; +/* BMP header. */ +typedef struct { + /* 16 bit - header identifying the type */ + signed short int magic; + + /* 32bit - size of the file */ + int size; - /* 32bit - size of the file */ - int size; + /* 16bit - these two are in the spec but "reserved" */ + signed short int reserved1; + signed short int reserved2; - /* 16bit - these two are in the spec but "reserved" */ - signed short int reserved1; - signed short int reserved2; + /* 32 bit - offset of the bitmap header from data in bytes */ + signed int off; - /* 32 bit - offset of the bitmap header from data in bytes */ - signed int off; +} bmp_hdr_t; - } bmp_hdr_t; +/* BMP info. */ +typedef struct { + /* 16bit - Type, ie Windows or OS/2 for the palette info */ + signed short int type; + /* 32bit - The length of the bitmap information header in bytes. */ + signed int len; - /* BMP info. */ - typedef struct { - /* 16bit - Type, ie Windows or OS/2 for the palette info */ - signed short int type; - /* 32bit - The length of the bitmap information header in bytes. */ - signed int len; + /* 32bit - The width of the bitmap in pixels. */ + signed int width; - /* 32bit - The width of the bitmap in pixels. */ - signed int width; + /* 32bit - The height of the bitmap in pixels. */ + signed int height; - /* 32bit - The height of the bitmap in pixels. */ - signed int height; + /* 8 bit - The bitmap data is specified in top-down order. */ + signed char topdown; - /* 8 bit - The bitmap data is specified in top-down order. */ - signed char topdown; + /* 16 bit - The number of planes. This must be set to a value of one. */ + signed short int numplanes; - /* 16 bit - The number of planes. This must be set to a value of one. */ - signed short int numplanes; + /* 16 bit - The number of bits per pixel. */ + signed short int depth; - /* 16 bit - The number of bits per pixel. */ - signed short int depth; + /* 32bit - The type of compression used. */ + signed int enctype; - /* 32bit - The type of compression used. */ - signed int enctype; + /* 32bit - The size of the image in bytes. */ + signed int size; - /* 32bit - The size of the image in bytes. */ - signed int size; + /* 32bit - The horizontal resolution in pixels/metre. */ + signed int hres; - /* 32bit - The horizontal resolution in pixels/metre. */ - signed int hres; + /* 32bit - The vertical resolution in pixels/metre. */ + signed int vres; - /* 32bit - The vertical resolution in pixels/metre. */ - signed int vres; + /* 32bit - The number of color indices used by the bitmap. */ + signed int numcolors; - /* 32bit - The number of color indices used by the bitmap. */ - signed int numcolors; + /* 32bit - The number of color indices important for displaying the bitmap. + */ + signed int mincolors; - /* 32bit - The number of color indices important for displaying the bitmap. */ - signed int mincolors; + /* 32bit - Color masks for BI_BITFIELDS and v4/v5 headers. */ + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + unsigned int alpha_mask; - } bmp_info_t; +} bmp_info_t; #endif #ifdef __cplusplus } #endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/gd/libgd/entities.h b/ext/gd/libgd/entities.h new file mode 100644 index 000000000000..37be6c85a8da --- /dev/null +++ b/ext/gd/libgd/entities.h @@ -0,0 +1,76 @@ +/* + * Generated file - do not edit directly. + * + * This file was generated from: + * http://www.w3.org/TR/REC-html40/sgml/entities.html + * by means of the script: + * entities.tcl + */ + +#ifdef __cplusplus +extern "C" { +#endif + +static struct entities_s { + char *name; + int value; +} entities[] = { + {"AElig", 198}, {"Aacute", 193}, {"Acirc", 194}, {"Agrave", 192}, {"Alpha", 913}, + {"Aring", 197}, {"Atilde", 195}, {"Auml", 196}, {"Beta", 914}, {"Ccedil", 199}, + {"Chi", 935}, {"Dagger", 8225}, {"Delta", 916}, {"ETH", 208}, {"Eacute", 201}, + {"Ecirc", 202}, {"Egrave", 200}, {"Epsilon", 917}, {"Eta", 919}, {"Euml", 203}, + {"Gamma", 915}, {"Iacute", 205}, {"Icirc", 206}, {"Igrave", 204}, {"Iota", 921}, + {"Iuml", 207}, {"Kappa", 922}, {"Lambda", 923}, {"Mu", 924}, {"Ntilde", 209}, + {"Nu", 925}, {"OElig", 338}, {"Oacute", 211}, {"Ocirc", 212}, {"Ograve", 210}, + {"Omega", 937}, {"Omicron", 927}, {"Oslash", 216}, {"Otilde", 213}, {"Ouml", 214}, + {"Phi", 934}, {"Pi", 928}, {"Prime", 8243}, {"Psi", 936}, {"Rho", 929}, + {"Scaron", 352}, {"Sigma", 931}, {"THORN", 222}, {"Tau", 932}, {"Theta", 920}, + {"Uacute", 218}, {"Ucirc", 219}, {"Ugrave", 217}, {"Upsilon", 933}, {"Uuml", 220}, + {"Xi", 926}, {"Yacute", 221}, {"Yuml", 376}, {"Zeta", 918}, {"aacute", 225}, + {"acirc", 226}, {"acute", 180}, {"aelig", 230}, {"agrave", 224}, {"alefsym", 8501}, + {"alpha", 945}, {"amp", 38}, {"and", 8743}, {"ang", 8736}, {"aring", 229}, + {"asymp", 8776}, {"atilde", 227}, {"auml", 228}, {"bdquo", 8222}, {"beta", 946}, + {"brvbar", 166}, {"bull", 8226}, {"cap", 8745}, {"ccedil", 231}, {"cedil", 184}, + {"cent", 162}, {"chi", 967}, {"circ", 710}, {"clubs", 9827}, {"cong", 8773}, + {"copy", 169}, {"crarr", 8629}, {"cup", 8746}, {"curren", 164}, {"dArr", 8659}, + {"dagger", 8224}, {"darr", 8595}, {"deg", 176}, {"delta", 948}, {"diams", 9830}, + {"divide", 247}, {"eacute", 233}, {"ecirc", 234}, {"egrave", 232}, {"empty", 8709}, + {"emsp", 8195}, {"ensp", 8194}, {"epsilon", 949}, {"equiv", 8801}, {"eta", 951}, + {"eth", 240}, {"euml", 235}, {"euro", 8364}, {"exist", 8707}, {"fnof", 402}, + {"forall", 8704}, {"frac12", 189}, {"frac14", 188}, {"frac34", 190}, {"frasl", 8260}, + {"gamma", 947}, {"ge", 8805}, {"gt", 62}, {"hArr", 8660}, {"harr", 8596}, + {"hearts", 9829}, {"hellip", 8230}, {"iacute", 237}, {"icirc", 238}, {"iexcl", 161}, + {"igrave", 236}, {"image", 8465}, {"infin", 8734}, {"int", 8747}, {"iota", 953}, + {"iquest", 191}, {"isin", 8712}, {"iuml", 239}, {"kappa", 954}, {"lArr", 8656}, + {"lambda", 955}, {"lang", 9001}, {"laquo", 171}, {"larr", 8592}, {"lceil", 8968}, + {"ldquo", 8220}, {"le", 8804}, {"lfloor", 8970}, {"lowast", 8727}, {"loz", 9674}, + {"lrm", 8206}, {"lsaquo", 8249}, {"lsquo", 8216}, {"lt", 60}, {"macr", 175}, + {"mdash", 8212}, {"micro", 181}, {"middot", 183}, {"minus", 8722}, {"mu", 956}, + {"nabla", 8711}, {"nbsp", 160}, {"ndash", 8211}, {"ne", 8800}, {"ni", 8715}, + {"not", 172}, {"notin", 8713}, {"nsub", 8836}, {"ntilde", 241}, {"nu", 957}, + {"oacute", 243}, {"ocirc", 244}, {"oelig", 339}, {"ograve", 242}, {"oline", 8254}, + {"omega", 969}, {"omicron", 959}, {"oplus", 8853}, {"or", 8744}, {"ordf", 170}, + {"ordm", 186}, {"oslash", 248}, {"otilde", 245}, {"otimes", 8855}, {"ouml", 246}, + {"para", 182}, {"part", 8706}, {"permil", 8240}, {"perp", 8869}, {"phi", 966}, + {"pi", 960}, {"piv", 982}, {"plusmn", 177}, {"pound", 163}, {"prime", 8242}, + {"prod", 8719}, {"prop", 8733}, {"psi", 968}, {"quot", 34}, {"rArr", 8658}, + {"radic", 8730}, {"rang", 9002}, {"raquo", 187}, {"rarr", 8594}, {"rceil", 8969}, + {"rdquo", 8221}, {"real", 8476}, {"reg", 174}, {"rfloor", 8971}, {"rho", 961}, + {"rlm", 8207}, {"rsaquo", 8250}, {"rsquo", 8217}, {"sbquo", 8218}, {"scaron", 353}, + {"sdot", 8901}, {"sect", 167}, {"shy", 173}, {"sigma", 963}, {"sigmaf", 962}, + {"sim", 8764}, {"spades", 9824}, {"sub", 8834}, {"sube", 8838}, {"sum", 8721}, + {"sup", 8835}, {"sup1", 185}, {"sup2", 178}, {"sup3", 179}, {"supe", 8839}, + {"szlig", 223}, {"tau", 964}, {"there4", 8756}, {"theta", 952}, {"thetasym", 977}, + {"thinsp", 8201}, {"thorn", 254}, {"tilde", 732}, {"times", 215}, {"trade", 8482}, + {"uArr", 8657}, {"uacute", 250}, {"uarr", 8593}, {"ucirc", 251}, {"ugrave", 249}, + {"uml", 168}, {"upsih", 978}, {"upsilon", 965}, {"uuml", 252}, {"weierp", 8472}, + {"xi", 958}, {"yacute", 253}, {"yen", 165}, {"yuml", 255}, {"zeta", 950}, + {"zwj", 8205}, {"zwnj", 8204}, +}; + +#define ENTITY_NAME_LENGTH_MAX 8 +#define NR_OF_ENTITIES 252 + +#ifdef __cplusplus +} +#endif diff --git a/ext/gd/libgd/ftraster/gd_ft_math.c b/ext/gd/libgd/ftraster/gd_ft_math.c new file mode 100644 index 000000000000..95cd4e5d7ac1 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_math.c @@ -0,0 +1,456 @@ +/***************************************************************************/ +/* */ +/* fttrigon.c */ +/* */ +/* FreeType trigonometric functions (body). */ +/* */ +/* Copyright 2001-2005, 2012-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include "gd_ft_math.h" +#include + +#if defined(_MSC_VER) +#include +static unsigned int __inline clz(unsigned int x) +{ + unsigned long r = 0; + if (x != 0) { + _BitScanReverse(&r, x); + } + return r; +} +#define GD_FT_MSB(x) (clz(x)) +#elif defined(__GNUC__) +#define GD_FT_MSB(x) (31 - __builtin_clz(x)) +#else +static unsigned int __inline clz(unsigned int x) +{ + int c = 31; + x &= ~x + 1; + if (n & 0x0000FFFF) + c -= 16; + if (n & 0x00FF00FF) + c -= 8; + if (n & 0x0F0F0F0F) + c -= 4; + if (n & 0x33333333) + c -= 2; + if (n & 0x55555555) + c -= 1; + return c; +} +#define GD_FT_MSB(x) (clz(x)) +#endif + +#define GD_FT_PAD_FLOOR(x, n) ((x) & ~((n) - 1)) +#define GD_FT_PAD_ROUND(x, n) GD_FT_PAD_FLOOR((x) + ((n) / 2), n) +#define GD_FT_PAD_CEIL(x, n) GD_FT_PAD_FLOOR((x) + ((n) - 1), n) + +#define GD_FT_BEGIN_STMNT do { +#define GD_FT_END_STMNT \ + } \ + while (0) +/* transfer sign leaving a positive number */ +#define GD_FT_MOVE_SIGN(x, s) \ + GD_FT_BEGIN_STMNT \ + if (x < 0) { \ + x = -x; \ + s = -s; \ + } \ + GD_FT_END_STMNT + +GD_FT_Long GD_FT_MulFix(GD_FT_Long a, GD_FT_Long b) +{ + GD_FT_Int s = 1; + GD_FT_Long c; + + GD_FT_MOVE_SIGN(a, s); + GD_FT_MOVE_SIGN(b, s); + + c = (GD_FT_Long)(((GD_FT_Int64)a * b + 0x8000L) >> 16); + + return (s > 0) ? c : -c; +} + +GD_FT_Long GD_FT_MulDiv(GD_FT_Long a, GD_FT_Long b, GD_FT_Long c) +{ + GD_FT_Int s = 1; + GD_FT_Long d; + + GD_FT_MOVE_SIGN(a, s); + GD_FT_MOVE_SIGN(b, s); + GD_FT_MOVE_SIGN(c, s); + + d = (GD_FT_Long)(c > 0 ? ((GD_FT_Int64)a * b + (c >> 1)) / c : 0x7FFFFFFFL); + + return (s > 0) ? d : -d; +} + +GD_FT_Long GD_FT_DivFix(GD_FT_Long a, GD_FT_Long b) +{ + GD_FT_Int s = 1; + GD_FT_Long q; + + GD_FT_MOVE_SIGN(a, s); + GD_FT_MOVE_SIGN(b, s); + + q = (GD_FT_Long)(b > 0 ? (((GD_FT_UInt64)a << 16) + (b >> 1)) / b : 0x7FFFFFFFL); + + return (s < 0 ? -q : q); +} + +/*************************************************************************/ +/* */ +/* This is a fixed-point CORDIC implementation of trigonometric */ +/* functions as well as transformations between Cartesian and polar */ +/* coordinates. The angles are represented as 16.16 fixed-point values */ +/* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ +/* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ +/* discrete Cartesian grid can have the same or better angular */ +/* resolution. Therefore, to maintain this precision, some functions */ +/* require an interim upscaling of the vectors, whereas others operate */ +/* with 24-bit long vectors directly. */ +/* */ +/*************************************************************************/ + +/* the Cordic shrink factor 0.858785336480436 * 2^32 */ +#define GD_FT_TRIG_SCALE 0xDBD95B16UL + +/* the highest bit in overflow-safe vector components, */ +/* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ +#define GD_FT_TRIG_SAFE_MSB 29 + +/* this table was generated for GD_FT_PI = 180L << 16, i.e. degrees */ +#define GD_FT_TRIG_MAX_ITERS 23 + +static const GD_FT_Fixed ft_trig_arctan_table[] = { + 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, + 917L, 458L, 229L, 115L, 57L, 29L, 14L, 7L, 4L, 2L, 1L}; + +/* multiply a given value by the CORDIC shrink factor */ +static GD_FT_Fixed ft_trig_downscale(GD_FT_Fixed val) +{ + GD_FT_Fixed s; + GD_FT_Int64 v; + + s = val; + val = GD_FT_ABS(val); + + v = (val * (GD_FT_Int64)GD_FT_TRIG_SCALE) + 0x100000000UL; + val = (GD_FT_Fixed)(v >> 32); + + return (s >= 0) ? val : -val; +} + +/* undefined and never called for zero vector */ +static GD_FT_Int ft_trig_prenorm(GD_FT_Vector *vec) +{ + GD_FT_Pos x, y; + GD_FT_Int shift; + + x = vec->x; + y = vec->y; + + shift = GD_FT_MSB(GD_FT_ABS(x) | GD_FT_ABS(y)); + + if (shift <= GD_FT_TRIG_SAFE_MSB) { + shift = GD_FT_TRIG_SAFE_MSB - shift; + vec->x = (GD_FT_Pos)((GD_FT_ULong)x << shift); + vec->y = (GD_FT_Pos)((GD_FT_ULong)y << shift); + } else { + shift -= GD_FT_TRIG_SAFE_MSB; + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + + return shift; +} + +static void ft_trig_pseudo_rotate(GD_FT_Vector *vec, GD_FT_Angle theta) +{ + GD_FT_Int i; + GD_FT_Fixed x, y, xtemp, b; + const GD_FT_Fixed *arctanptr; + + x = vec->x; + y = vec->y; + + /* Rotate inside [-PI/4,PI/4] sector */ + while (theta < -GD_FT_ANGLE_PI4) { + xtemp = y; + y = -x; + x = xtemp; + theta += GD_FT_ANGLE_PI2; + } + + while (theta > GD_FT_ANGLE_PI4) { + xtemp = -y; + y = x; + x = xtemp; + theta -= GD_FT_ANGLE_PI2; + } + + arctanptr = ft_trig_arctan_table; + + /* Pseudorotations, with right shifts */ + for (i = 1, b = 1; i < GD_FT_TRIG_MAX_ITERS; b <<= 1, i++) { + GD_FT_Fixed v1 = ((y + b) >> i); + GD_FT_Fixed v2 = ((x + b) >> i); + if (theta < 0) { + xtemp = x + v1; + y = y - v2; + x = xtemp; + theta += *arctanptr++; + } else { + xtemp = x - v1; + y = y + v2; + x = xtemp; + theta -= *arctanptr++; + } + } + + vec->x = x; + vec->y = y; +} + +static void ft_trig_pseudo_polarize(GD_FT_Vector *vec) +{ + GD_FT_Angle theta; + GD_FT_Int i; + GD_FT_Fixed x, y, xtemp, b; + const GD_FT_Fixed *arctanptr; + + x = vec->x; + y = vec->y; + + /* Get the vector into [-PI/4,PI/4] sector */ + if (y > x) { + if (y > -x) { + theta = GD_FT_ANGLE_PI2; + xtemp = y; + y = -x; + x = xtemp; + } else { + theta = y > 0 ? GD_FT_ANGLE_PI : -GD_FT_ANGLE_PI; + x = -x; + y = -y; + } + } else { + if (y < -x) { + theta = -GD_FT_ANGLE_PI2; + xtemp = -y; + y = x; + x = xtemp; + } else { + theta = 0; + } + } + + arctanptr = ft_trig_arctan_table; + + /* Pseudorotations, with right shifts */ + for (i = 1, b = 1; i < GD_FT_TRIG_MAX_ITERS; b <<= 1, i++) { + GD_FT_Fixed v1 = ((y + b) >> i); + GD_FT_Fixed v2 = ((x + b) >> i); + if (y > 0) { + xtemp = x + v1; + y = y - v2; + x = xtemp; + theta += *arctanptr++; + } else { + xtemp = x - v1; + y = y + v2; + x = xtemp; + theta -= *arctanptr++; + } + } + + /* round theta */ + if (theta >= 0) + theta = GD_FT_PAD_ROUND(theta, 32); + else + theta = -GD_FT_PAD_ROUND(-theta, 32); + + vec->x = x; + vec->y = theta; +} + +/* documentation is in fttrigon.h */ + +GD_FT_Fixed GD_FT_Cos(GD_FT_Angle angle) +{ + GD_FT_Vector v; + + v.x = GD_FT_TRIG_SCALE >> 8; + v.y = 0; + ft_trig_pseudo_rotate(&v, angle); + + return (v.x + 0x80L) >> 8; +} + +/* documentation is in fttrigon.h */ + +GD_FT_Fixed GD_FT_Sin(GD_FT_Angle angle) { return GD_FT_Cos(GD_FT_ANGLE_PI2 - angle); } + +/* documentation is in fttrigon.h */ + +GD_FT_Fixed GD_FT_Tan(GD_FT_Angle angle) +{ + GD_FT_Vector v; + + v.x = GD_FT_TRIG_SCALE >> 8; + v.y = 0; + ft_trig_pseudo_rotate(&v, angle); + + return GD_FT_DivFix(v.y, v.x); +} + +/* documentation is in fttrigon.h */ + +GD_FT_Angle GD_FT_Atan2(GD_FT_Fixed dx, GD_FT_Fixed dy) +{ + GD_FT_Vector v; + + if (dx == 0 && dy == 0) + return 0; + + v.x = dx; + v.y = dy; + ft_trig_prenorm(&v); + ft_trig_pseudo_polarize(&v); + + return v.y; +} + +/* documentation is in fttrigon.h */ + +void GD_FT_Vector_Unit(GD_FT_Vector *vec, GD_FT_Angle angle) +{ + vec->x = GD_FT_TRIG_SCALE >> 8; + vec->y = 0; + ft_trig_pseudo_rotate(vec, angle); + vec->x = (vec->x + 0x80L) >> 8; + vec->y = (vec->y + 0x80L) >> 8; +} + +/* these macros return 0 for positive numbers, + and -1 for negative ones */ +#define GD_FT_SIGN_LONG(x) ((x) >> (GD_FT_SIZEOF_LONG * 8 - 1)) +#define GD_FT_SIGN_INT(x) ((x) >> (GD_FT_SIZEOF_INT * 8 - 1)) +#define GD_FT_SIGN_INT32(x) ((x) >> 31) +#define GD_FT_SIGN_INT16(x) ((x) >> 15) + +/* documentation is in fttrigon.h */ + +void GD_FT_Vector_Rotate(GD_FT_Vector *vec, GD_FT_Angle angle) +{ + GD_FT_Int shift; + GD_FT_Vector v; + + v.x = vec->x; + v.y = vec->y; + + if (angle && (v.x != 0 || v.y != 0)) { + shift = ft_trig_prenorm(&v); + ft_trig_pseudo_rotate(&v, angle); + v.x = ft_trig_downscale(v.x); + v.y = ft_trig_downscale(v.y); + + if (shift > 0) { + GD_FT_Int32 half = (GD_FT_Int32)1L << (shift - 1); + + vec->x = (v.x + half + GD_FT_SIGN_LONG(v.x)) >> shift; + vec->y = (v.y + half + GD_FT_SIGN_LONG(v.y)) >> shift; + } else { + shift = -shift; + vec->x = (GD_FT_Pos)((GD_FT_ULong)v.x << shift); + vec->y = (GD_FT_Pos)((GD_FT_ULong)v.y << shift); + } + } +} + +/* documentation is in fttrigon.h */ + +GD_FT_Fixed GD_FT_Vector_Length(GD_FT_Vector *vec) +{ + GD_FT_Int shift; + GD_FT_Vector v; + + v = *vec; + + /* handle trivial cases */ + if (v.x == 0) { + return GD_FT_ABS(v.y); + } else if (v.y == 0) { + return GD_FT_ABS(v.x); + } + + /* general case */ + shift = ft_trig_prenorm(&v); + ft_trig_pseudo_polarize(&v); + + v.x = ft_trig_downscale(v.x); + + if (shift > 0) + return (v.x + (1 << (shift - 1))) >> shift; + + return (GD_FT_Fixed)((GD_FT_UInt32)v.x << -shift); +} + +/* documentation is in fttrigon.h */ + +void GD_FT_Vector_Polarize(GD_FT_Vector *vec, GD_FT_Fixed *length, GD_FT_Angle *angle) +{ + GD_FT_Int shift; + GD_FT_Vector v; + + v = *vec; + + if (v.x == 0 && v.y == 0) + return; + + shift = ft_trig_prenorm(&v); + ft_trig_pseudo_polarize(&v); + + v.x = ft_trig_downscale(v.x); + + *length = (shift >= 0) ? (v.x >> shift) : (GD_FT_Fixed)((GD_FT_UInt32)v.x << -shift); + *angle = v.y; +} + +/* documentation is in fttrigon.h */ + +void GD_FT_Vector_From_Polar(GD_FT_Vector *vec, GD_FT_Fixed length, GD_FT_Angle angle) +{ + vec->x = length; + vec->y = 0; + + GD_FT_Vector_Rotate(vec, angle); +} + +/* documentation is in fttrigon.h */ + +GD_FT_Angle GD_FT_Angle_Diff(GD_FT_Angle angle1, GD_FT_Angle angle2) +{ + GD_FT_Angle delta = angle2 - angle1; + + while (delta <= -GD_FT_ANGLE_PI) + delta += GD_FT_ANGLE_2PI; + + while (delta > GD_FT_ANGLE_PI) + delta -= GD_FT_ANGLE_2PI; + + return delta; +} + +/* END */ diff --git a/ext/gd/libgd/ftraster/gd_ft_math.h b/ext/gd/libgd/ftraster/gd_ft_math.h new file mode 100644 index 000000000000..da332c1ff407 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_math.h @@ -0,0 +1,391 @@ +#ifndef GD_FT_MATH_H +#define GD_FT_MATH_H + +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001, 2003, 2005, 2007, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include "gd_ft_types.h" + +/*************************************************************************/ +/* */ +/* The min and max functions missing in C. As usual, be careful not to */ +/* write things like GD_FT_MIN( a++, b++ ) to avoid side effects. */ +/* */ +#define GD_FT_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define GD_FT_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define GD_FT_ABS(a) ((a) < 0 ? -(a) : (a)) + +/* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define GD_FT_HYPOT(x, y) \ + (x = GD_FT_ABS(x), y = GD_FT_ABS(y), x > y ? x + (3 * y >> 3) : y + (3 * x >> 3)) + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_MulFix */ +/* */ +/* */ +/* A very simple function used to perform the computation */ +/* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ +/* used to multiply a given value by a 16.16 fixed-point factor. */ +/* */ +/* */ +/* a :: The first multiplier. */ +/* b :: The second multiplier. Use a 16.16 factor here whenever */ +/* possible (see note below). */ +/* */ +/* */ +/* The result of `(a*b)/0x10000'. */ +/* */ +/* */ +/* This function has been optimized for the case where the absolute */ +/* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ +/* As this happens mainly when scaling from notional units to */ +/* fractional pixels in FreeType, it resulted in noticeable speed */ +/* improvements between versions 2.x and 1.x. */ +/* */ +/* As a conclusion, always try to place a 16.16 factor as the */ +/* _second_ argument of this function; this can make a great */ +/* difference. */ +/* */ +GD_FT_Long GD_FT_MulFix(GD_FT_Long a, GD_FT_Long b); + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_MulDiv */ +/* */ +/* */ +/* A very simple function used to perform the computation `(a*b)/c' */ +/* with maximum accuracy (it uses a 64-bit intermediate integer */ +/* whenever necessary). */ +/* */ +/* This function isn't necessarily as fast as some processor specific */ +/* operations, but is at least completely portable. */ +/* */ +/* */ +/* a :: The first multiplier. */ +/* b :: The second multiplier. */ +/* c :: The divisor. */ +/* */ +/* */ +/* The result of `(a*b)/c'. This function never traps when trying to */ +/* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ +/* on the signs of `a' and `b'. */ +/* */ +GD_FT_Long GD_FT_MulDiv(GD_FT_Long a, GD_FT_Long b, GD_FT_Long c); + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_DivFix */ +/* */ +/* */ +/* A very simple function used to perform the computation */ +/* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ +/* used to divide a given value by a 16.16 fixed-point factor. */ +/* */ +/* */ +/* a :: The numerator. */ +/* b :: The denominator. Use a 16.16 factor here. */ +/* */ +/* */ +/* The result of `(a*0x10000)/b'. */ +/* */ +GD_FT_Long GD_FT_DivFix(GD_FT_Long a, GD_FT_Long b); + +/*************************************************************************/ +/* */ +/*
*/ +/* computations */ +/* */ +/*************************************************************************/ + +/************************************************************************* + * + * @type: + * GD_FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed-point value expressed in degrees. + * + */ +typedef GD_FT_Fixed GD_FT_Angle; + +/************************************************************************* + * + * @macro: + * GD_FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @GD_FT_Angle units. + * + */ +#define GD_FT_ANGLE_PI (180L << 16) + +/************************************************************************* + * + * @macro: + * GD_FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @GD_FT_Angle units. + * + */ +#define GD_FT_ANGLE_2PI (GD_FT_ANGLE_PI * 2) + +/************************************************************************* + * + * @macro: + * GD_FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @GD_FT_Angle units. + * + */ +#define GD_FT_ANGLE_PI2 (GD_FT_ANGLE_PI / 2) + +/************************************************************************* + * + * @macro: + * GD_FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @GD_FT_Angle units. + * + */ +#define GD_FT_ANGLE_PI4 (GD_FT_ANGLE_PI / 4) + +/************************************************************************* + * + * @function: + * GD_FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @GD_FT_Vector_Unit. + * + */ +GD_FT_Fixed GD_FT_Sin(GD_FT_Angle angle); + +/************************************************************************* + * + * @function: + * GD_FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @GD_FT_Vector_Unit. + * + */ +GD_FT_Fixed GD_FT_Cos(GD_FT_Angle angle); + +/************************************************************************* + * + * @function: + * GD_FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ +GD_FT_Fixed GD_FT_Tan(GD_FT_Angle angle); + +/************************************************************************* + * + * @function: + * GD_FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ +GD_FT_Angle GD_FT_Atan2(GD_FT_Fixed x, GD_FT_Fixed y); + +/************************************************************************* + * + * @function: + * GD_FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ +GD_FT_Angle GD_FT_Angle_Diff(GD_FT_Angle angle1, GD_FT_Angle angle2); + +/************************************************************************* + * + * @function: + * GD_FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `sin(angle)', and the value of + * `vec.y' will be `cos(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ +void GD_FT_Vector_Unit(GD_FT_Vector *vec, GD_FT_Angle angle); + +/************************************************************************* + * + * @function: + * GD_FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ +void GD_FT_Vector_Rotate(GD_FT_Vector *vec, GD_FT_Angle angle); + +/************************************************************************* + * + * @function: + * GD_FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ +GD_FT_Fixed GD_FT_Vector_Length(GD_FT_Vector *vec); + +/************************************************************************* + * + * @function: + * GD_FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ +void GD_FT_Vector_Polarize(GD_FT_Vector *vec, GD_FT_Fixed *length, GD_FT_Angle *angle); + +/************************************************************************* + * + * @function: + * GD_FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ +void GD_FT_Vector_From_Polar(GD_FT_Vector *vec, GD_FT_Fixed length, GD_FT_Angle angle); + +#endif // GD_FT_MATH_H diff --git a/ext/gd/libgd/ftraster/gd_ft_raster.c b/ext/gd/libgd/ftraster/gd_ft_raster.c new file mode 100644 index 000000000000..6891f7da2c32 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_raster.c @@ -0,0 +1,1723 @@ +/**************************************************************************** + * + * ftgrays.c + * + * A new `perfect' anti-aliasing renderer (body). + * + * Copyright (C) 2000-2020 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/*************************************************************************/ +/* */ +/* This is a new anti-aliasing scan-converter for FreeType 2. The */ +/* algorithm used here is _very_ different from the one in the standard */ +/* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ +/* coverage of the outline on each pixel cell. */ +/* */ +/* It is based on ideas that I initially found in Raph Levien's */ +/* excellent LibArt graphics library (see http://www.levien.com/libart */ +/* for more information, though the web pages do not tell anything */ +/* about the renderer; you'll have to dive into the source code to */ +/* understand how it works). */ +/* */ +/* Note, however, that this is a _very_ different implementation */ +/* compared to Raph's. Coverage information is stored in a very */ +/* different way, and I don't use sorted vector paths. Also, it doesn't */ +/* use floating point values. */ +/* */ +/* This renderer has the following advantages: */ +/* */ +/* - It doesn't need an intermediate bitmap. Instead, one can supply a */ +/* callback function that will be called by the renderer to draw gray */ +/* spans on any target surface. You can thus do direct composition on */ +/* any kind of bitmap, provided that you give the renderer the right */ +/* callback. */ +/* */ +/* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ +/* each pixel cell. */ +/* */ +/* - It performs a single pass on the outline (the `standard' FT2 */ +/* renderer makes two passes). */ +/* */ +/* - It can easily be modified to render to _any_ number of gray levels */ +/* cheaply. */ +/* */ +/* - For small (< 20) pixel sizes, it is faster than the standard */ +/* renderer. */ +/* */ +/*************************************************************************/ + +#include "gd_ft_raster.h" +#include "gd_ft_math.h" +#include "gd_path_matrix.h" +#include "gd_vector2d_private.h" + +/* Auxiliary macros for token concatenation. */ +#define GD_FT_ERR_XCAT(x, y) x##y +#define GD_FT_ERR_CAT(x, y) GD_FT_ERR_XCAT(x, y) + +#define GD_FT_BEGIN_STMNT do { +#define GD_FT_END_STMNT \ + } \ + while (0) + +#include +#include +#include +#include +#define GD_FT_UINT_MAX UINT_MAX +#define GD_FT_INT_MAX INT_MAX +#define GD_FT_ULONG_MAX ULONG_MAX +#define GD_FT_CHAR_BIT CHAR_BIT + +#define ft_memset memset + +#define ft_setjmp setjmp +#define ft_longjmp longjmp +#define ft_jmp_buf jmp_buf + +typedef ptrdiff_t GD_FT_PtrDist; + +#define ErrRaster_Invalid_Mode -2 +#define ErrRaster_Invalid_Outline -1 +#define ErrRaster_Invalid_Argument -3 +#define ErrRaster_Memory_Overflow -4 + +#define GD_FT_BEGIN_HEADER +#define GD_FT_END_HEADER + +/* This macro is used to indicate that a function parameter is unused. */ +/* Its purpose is simply to reduce compiler warnings. Note also that */ +/* simply defining it as `(void)x' doesn't avoid warnings with certain */ +/* ANSI compilers (e.g. LCC). */ +#define GD_FT_UNUSED(x) (x) = (x) + +#define GD_FT_THROW(e) GD_FT_ERR_CAT(ErrRaster_, e) + +/* The size in bytes of the render pool used by the scan-line converter */ +/* to do all of its work. */ +#define GD_FT_RENDER_POOL_SIZE 16384L + +typedef int (*GD_FT_Outline_MoveToFunc)(const GD_FT_Vector *to, void *user); + +#define GD_FT_Outline_MoveTo_Func GD_FT_Outline_MoveToFunc + +typedef int (*GD_FT_Outline_LineToFunc)(const GD_FT_Vector *to, void *user); + +#define GD_FT_Outline_LineTo_Func GD_FT_Outline_LineToFunc + +typedef int (*GD_FT_Outline_ConicToFunc)(const GD_FT_Vector *control, const GD_FT_Vector *to, + void *user); + +#define GD_FT_Outline_ConicTo_Func GD_FT_Outline_ConicToFunc + +typedef int (*GD_FT_Outline_CubicToFunc)(const GD_FT_Vector *control1, const GD_FT_Vector *control2, + const GD_FT_Vector *to, void *user); + +#define GD_FT_Outline_CubicTo_Func GD_FT_Outline_CubicToFunc + +typedef struct GD_FT_Outline_Funcs_ { + GD_FT_Outline_MoveToFunc move_to; + GD_FT_Outline_LineToFunc line_to; + GD_FT_Outline_ConicToFunc conic_to; + GD_FT_Outline_CubicToFunc cubic_to; + + int shift; + GD_FT_Pos delta; + +} GD_FT_Outline_Funcs; + +#define GD_FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, cubic_to_, shift_, \ + delta_) \ + static const GD_FT_Outline_Funcs class_ = {move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_}; + +#define GD_FT_DEFINE_RASTER_FUNCS(class_, raster_new_, raster_reset_, raster_render_, \ + raster_done_) \ + const GD_FT_Raster_Funcs class_ = {raster_new_, raster_reset_, raster_render_, raster_done_}; + +#ifndef GD_FT_MEM_SET +#define GD_FT_MEM_SET(d, s, c) ft_memset(d, s, c) +#endif + +#ifndef GD_FT_MEM_ZERO +#define GD_FT_MEM_ZERO(dest, count) GD_FT_MEM_SET(dest, 0, count) +#endif + +/* as usual, for the speed hungry :-) */ + +#undef RAS_ARG +#undef RAS_ARG_ +#undef RAS_VAR +#undef RAS_VAR_ + +#ifndef GD_FT_STATIC_RASTER + +#define RAS_ARG gray_PWorker worker +#define RAS_ARG_ gray_PWorker worker, + +#define RAS_VAR worker +#define RAS_VAR_ worker, + +#else /* GD_FT_STATIC_RASTER */ + +#define RAS_ARG /* empty */ +#define RAS_ARG_ /* empty */ +#define RAS_VAR /* empty */ +#define RAS_VAR_ /* empty */ + +#endif /* GD_FT_STATIC_RASTER */ + +/* must be at least 6 bits! */ +#define PIXEL_BITS 8 + +#undef FLOOR +#undef CEILING +#undef TRUNC +#undef SCALED + +#define ONE_PIXEL (1L << PIXEL_BITS) +#define PIXEL_MASK (-1L << PIXEL_BITS) +#define TRUNC(x) ((TCoord)((x) >> PIXEL_BITS)) +#define SUBPIXELS(x) ((TPos)(x) * ONE_PIXEL) +#define FLOOR(x) ((x) & -ONE_PIXEL) +#define CEILING(x) (((x) + ONE_PIXEL - 1) & -ONE_PIXEL) +#define ROUND(x) (((x) + ONE_PIXEL / 2) & -ONE_PIXEL) + +#if PIXEL_BITS >= 6 +#define UPSCALE(x) ((x) * (1L << (PIXEL_BITS - 6))) +#define DOWNSCALE(x) ((x) >> (PIXEL_BITS - 6)) +#else +#define UPSCALE(x) ((x) >> (6 - PIXEL_BITS)) +#define DOWNSCALE(x) ((x) * (1L << (6 - PIXEL_BITS))) +#endif + +/* Compute `dividend / divisor' and return both its quotient and */ +/* remainder, cast to a specific type. This macro also ensures that */ +/* the remainder is always positive. */ +#define GD_FT_DIV_MOD(type, dividend, divisor, quotient, remainder) \ + GD_FT_BEGIN_STMNT(quotient) = (type)((dividend) / (divisor)); \ + (remainder) = (type)((dividend) % (divisor)); \ + if ((remainder) < 0) { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + GD_FT_END_STMNT + +#ifdef __arm__ +/* Work around a bug specific to GCC which make the compiler fail to */ +/* optimize a division and modulo operation on the same parameters */ +/* into a single call to `__aeabi_idivmod'. See */ +/* */ +/* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ +#undef GD_FT_DIV_MOD +#define GD_FT_DIV_MOD(type, dividend, divisor, quotient, remainder) \ + GD_FT_BEGIN_STMNT(quotient) = (type)((dividend) / (divisor)); \ + (remainder) = (type)((dividend) - (quotient) * (divisor)); \ + if ((remainder) < 0) { \ + (quotient)--; \ + (remainder) += (type)(divisor); \ + } \ + GD_FT_END_STMNT +#endif /* __arm__ */ + +/* These macros speed up repetitive divisions by replacing them */ +/* with multiplications and right shifts. */ +#define GD_FT_UDIVPREP(b) long b##_r = (long)(GD_FT_ULONG_MAX >> PIXEL_BITS) / (b) +#define GD_FT_UDIV(a, b) \ + (((unsigned long)(a) * (unsigned long)(b##_r)) >> (sizeof(long) * GD_FT_CHAR_BIT - PIXEL_BITS)) + +/*************************************************************************/ +/* */ +/* TYPE DEFINITIONS */ +/* */ + +/* don't change the following types to GD_FT_Int or GD_FT_Pos, since we might */ +/* need to define them to "float" or "double" when experimenting with */ +/* new algorithms */ + +typedef long TCoord; /* integer scanline/pixel coordinate */ +typedef long TPos; /* sub-pixel coordinate */ + +/* determine the type used to store cell areas. This normally takes at */ +/* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ +/* `long' instead of `int', otherwise bad things happen */ + +#if PIXEL_BITS <= 7 + +typedef int TArea; + +#else /* PIXEL_BITS >= 8 */ + +/* approximately determine the size of integers using an ANSI-C header */ +#if GD_FT_UINT_MAX == 0xFFFFU +typedef long TArea; +#else +typedef int TArea; +#endif + +#endif /* PIXEL_BITS >= 8 */ + +/* maximum number of gray spans in a call to the span callback */ +#define GD_FT_MAX_GRAY_SPANS 256 + +typedef struct TCell_ *PCell; + +typedef struct TCell_ { + TPos x; /* same with gray_TWorker.ex */ + TCoord cover; /* same with gray_TWorker.cover */ + TArea area; + PCell next; + +} TCell; + +#if defined(_MSC_VER) /* Visual C++ (and Intel C++) */ +/* We disable the warning `structure was padded due to */ +/* __declspec(align())' in order to compile cleanly with */ +/* the maximum level of warnings. */ +#pragma warning(push) +#pragma warning(disable : 4324) +#endif /* _MSC_VER */ + +typedef struct gray_TWorker_ { + TCoord ex, ey; + TPos min_ex, max_ex; + TPos min_ey, max_ey; + TPos count_ex, count_ey; + + TArea area; + TCoord cover; + int invalid; + + PCell cells; + GD_FT_PtrDist max_cells; + GD_FT_PtrDist num_cells; + + TPos x, y; + + GD_FT_Vector bez_stack[32 * 3 + 1]; + int lev_stack[32]; + + GD_FT_Outline outline; + GD_FT_BBox clip_box; + + int bound_left; + int bound_top; + int bound_right; + int bound_bottom; + + GD_FT_Span gray_spans[GD_FT_MAX_GRAY_SPANS]; + int num_gray_spans; + + GD_FT_Raster_Span_Func render_span; + void *render_span_data; + + int band_size; + int band_shoot; + + ft_jmp_buf jump_buffer; + + void *buffer; + long buffer_size; + + PCell *ycells; + TPos ycount; + + /* Source abstraction for direct path rendering */ + struct gray_TSource_ *source; +} gray_TWorker, *gray_PWorker; + +typedef struct gray_TSource_ { + int (*get_cbox)(void *source, GD_FT_BBox *box); + int (*decompose)(void *source, void *worker); + void *source; +} gray_TSource; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#ifndef GD_FT_STATIC_RASTER +#define ras (*worker) +#else +static gray_TWorker ras; +#endif + +typedef struct gray_TRaster_ { + void *memory; + +} gray_TRaster, *gray_PRaster; + +/*************************************************************************/ +/* */ +/* Initialize the cells table. */ +/* */ +static void gray_init_cells(RAS_ARG_ void *buffer, long byte_size) +{ + ras.buffer = buffer; + ras.buffer_size = byte_size; + + ras.ycells = (PCell *)buffer; + ras.cells = NULL; + ras.max_cells = 0; + ras.num_cells = 0; + ras.area = 0; + ras.cover = 0; + ras.invalid = 1; + + ras.bound_left = INT_MAX; + ras.bound_top = INT_MAX; + ras.bound_right = INT_MIN; + ras.bound_bottom = INT_MIN; +} + +/*************************************************************************/ +/* */ +/* Compute the outline bounding box. */ +/* */ +static void gray_compute_cbox(RAS_ARG) +{ + if (ras.source && ras.source->get_cbox) { + GD_FT_BBox box; + int error = ras.source->get_cbox(ras.source->source, &box); + if (!error) { + ras.min_ex = box.xMin >> 6; + ras.min_ey = box.yMin >> 6; + ras.max_ex = (box.xMax + 63) >> 6; + ras.max_ey = (box.yMax + 63) >> 6; + return; + } + } + + /* Fallback to outline */ + GD_FT_Outline *outline = &ras.outline; + GD_FT_Vector *vec = outline->points; + GD_FT_Vector *limit = vec + outline->n_points; + + if (outline->n_points <= 0) { + ras.min_ex = ras.max_ex = 0; + ras.min_ey = ras.max_ey = 0; + return; + } + + ras.min_ex = ras.max_ex = vec->x; + ras.min_ey = ras.max_ey = vec->y; + + vec++; + + for (; vec < limit; vec++) { + TPos x = vec->x; + TPos y = vec->y; + + if (x < ras.min_ex) + ras.min_ex = x; + if (x > ras.max_ex) + ras.max_ex = x; + if (y < ras.min_ey) + ras.min_ey = y; + if (y > ras.max_ey) + ras.max_ey = y; + } + + /* truncate the bounding box to integer pixels */ + ras.min_ex = ras.min_ex >> 6; + ras.min_ey = ras.min_ey >> 6; + ras.max_ex = (ras.max_ex + 63) >> 6; + ras.max_ey = (ras.max_ey + 63) >> 6; +} + +/*************************************************************************/ +/* */ +/* Record the current cell in the table. */ +/* */ +static PCell gray_find_cell(RAS_ARG) +{ + PCell *pcell, cell; + TPos x = ras.ex; + + if (x > ras.count_ex) + x = ras.count_ex; + + pcell = &ras.ycells[ras.ey]; + for (;;) { + cell = *pcell; + if (cell == NULL || cell->x > x) + break; + + if (cell->x == x) + goto Exit; + + pcell = &cell->next; + } + + if (ras.num_cells >= ras.max_cells) + ft_longjmp(ras.jump_buffer, 1); + + cell = ras.cells + ras.num_cells++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + + cell->next = *pcell; + *pcell = cell; + +Exit: + return cell; +} + +static void gray_record_cell(RAS_ARG) +{ + if (ras.area | ras.cover) { + PCell cell = gray_find_cell(RAS_VAR); + + cell->area += ras.area; + cell->cover += ras.cover; + } +} + +/*************************************************************************/ +/* */ +/* Set the current cell to a new position. */ +/* */ +static void gray_set_cell(RAS_ARG_ TCoord ex, TCoord ey) +{ + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + /* All cells that are on the left of the clipping region go to the */ + /* min_ex - 1 horizontal position. */ + ey -= ras.min_ey; + + if (ex > ras.max_ex) + ex = ras.max_ex; + + ex -= ras.min_ex; + if (ex < 0) + ex = -1; + + /* are we moving to a different cell ? */ + if (ex != ras.ex || ey != ras.ey) { + /* record the current one if it is valid */ + if (!ras.invalid) + gray_record_cell(RAS_VAR); + + ras.area = 0; + ras.cover = 0; + ras.ex = ex; + ras.ey = ey; + } + + ras.invalid = ((unsigned)ey >= (unsigned)ras.count_ey || ex >= ras.count_ex); +} + +/*************************************************************************/ +/* */ +/* Start a new contour at a given cell. */ +/* */ +static void gray_start_cell(RAS_ARG_ TCoord ex, TCoord ey) +{ + if (ex > ras.max_ex) + ex = (TCoord)(ras.max_ex); + + if (ex < ras.min_ex) + ex = (TCoord)(ras.min_ex - 1); + + ras.area = 0; + ras.cover = 0; + ras.ex = ex - ras.min_ex; + ras.ey = ey - ras.min_ey; + ras.invalid = 0; + + gray_set_cell(RAS_VAR_ ex, ey); +} + +/*************************************************************************/ +/* */ +/* Render a straight line across multiple cells in any direction. */ +/* */ +static void gray_render_line(RAS_ARG_ TPos to_x, TPos to_y) +{ + TPos dx, dy, fx1, fy1, fx2, fy2; + TCoord ex1, ex2, ey1, ey2; + + ex1 = TRUNC(ras.x); + ex2 = TRUNC(to_x); + ey1 = TRUNC(ras.y); + ey2 = TRUNC(to_y); + + /* perform vertical clipping */ + if ((ey1 >= ras.max_ey && ey2 >= ras.max_ey) || (ey1 < ras.min_ey && ey2 < ras.min_ey)) + goto End; + + dx = to_x - ras.x; + dy = to_y - ras.y; + + fx1 = ras.x - SUBPIXELS(ex1); + fy1 = ras.y - SUBPIXELS(ey1); + + if (ex1 == ex2 && ey1 == ey2) /* inside one cell */ + ; + else if (dy == 0) /* ex1 != ex2 */ /* any horizontal line */ + { + ex1 = ex2; + gray_set_cell(RAS_VAR_ ex1, ey1); + } else if (dx == 0) { + if (dy > 0) /* vertical line up */ + do { + fy2 = ONE_PIXEL; + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * fx1 * 2; + fy1 = 0; + ey1++; + gray_set_cell(RAS_VAR_ ex1, ey1); + } while (ey1 != ey2); + else /* vertical line down */ + do { + fy2 = 0; + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * fx1 * 2; + fy1 = ONE_PIXEL; + ey1--; + gray_set_cell(RAS_VAR_ ex1, ey1); + } while (ey1 != ey2); + } else /* any other line */ + { + TArea prod = dx * fy1 - dy * fx1; + GD_FT_UDIVPREP(dx); + GD_FT_UDIVPREP(dy); + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do { + if (prod <= 0 && prod - dx * ONE_PIXEL > 0) /* left */ + { + fx2 = 0; + fy2 = (TPos)GD_FT_UDIV(-prod, -dx); + prod -= dy * ONE_PIXEL; + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * (fx1 + fx2); + fx1 = ONE_PIXEL; + fy1 = fy2; + ex1--; + } else if (prod - dx * ONE_PIXEL <= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0) /* up */ + { + prod -= dx * ONE_PIXEL; + fx2 = (TPos)GD_FT_UDIV(-prod, dy); + fy2 = ONE_PIXEL; + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * (fx1 + fx2); + fx1 = fx2; + fy1 = 0; + ey1++; + } else if (prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && + prod + dy * ONE_PIXEL >= 0) /* right */ + { + prod += dy * ONE_PIXEL; + fx2 = ONE_PIXEL; + fy2 = (TPos)GD_FT_UDIV(prod, dx); + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * (fx1 + fx2); + fx1 = 0; + fy1 = fy2; + ex1++; + } else /* ( prod + dy * ONE_PIXEL < 0 && + prod > 0 ) down */ + { + fx2 = (TPos)GD_FT_UDIV(prod, -dy); + fy2 = 0; + prod += dx * ONE_PIXEL; + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * (fx1 + fx2); + fx1 = fx2; + fy1 = ONE_PIXEL; + ey1--; + } + + gray_set_cell(RAS_VAR_ ex1, ey1); + } while (ex1 != ex2 || ey1 != ey2); + } + + fx2 = to_x - SUBPIXELS(ex2); + fy2 = to_y - SUBPIXELS(ey2); + + ras.cover += (fy2 - fy1); + ras.area += (fy2 - fy1) * (fx1 + fx2); + +End: + ras.x = to_x; + ras.y = to_y; +} + +static void gray_split_conic(GD_FT_Vector *base) +{ + TPos a, b; + + base[4].x = base[2].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b >> 1; + base[2].x = (a + b) >> 2; + base[1].x = a >> 1; + + base[4].y = base[2].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b >> 1; + base[2].y = (a + b) >> 2; + base[1].y = a >> 1; +} + +static void gray_render_conic(RAS_ARG_ const GD_FT_Vector *control, const GD_FT_Vector *to) +{ + TPos dx, dy; + TPos min, max, y; + int top, level; + int *levels; + GD_FT_Vector *arc; + + levels = ras.lev_stack; + + arc = ras.bez_stack; + arc[0].x = UPSCALE(to->x); + arc[0].y = UPSCALE(to->y); + arc[1].x = UPSCALE(control->x); + arc[1].y = UPSCALE(control->y); + arc[2].x = ras.x; + arc[2].y = ras.y; + top = 0; + + dx = GD_FT_ABS(arc[2].x + arc[0].x - 2 * arc[1].x); + dy = GD_FT_ABS(arc[2].y + arc[0].y - 2 * arc[1].y); + if (dx < dy) + dx = dy; + + if (dx < ONE_PIXEL / 4) + goto Draw; + + /* short-cut the arc that crosses the current band */ + min = max = arc[0].y; + + y = arc[1].y; + if (y < min) + min = y; + if (y > max) + max = y; + + y = arc[2].y; + if (y < min) + min = y; + if (y > max) + max = y; + + if (TRUNC(min) >= ras.max_ey || TRUNC(max) < ras.min_ey) + goto Draw; + + level = 0; + do { + dx >>= 2; + level++; + } while (dx > ONE_PIXEL / 4); + + levels[0] = level; + + do { + level = levels[top]; + if (level > 0) { + gray_split_conic(arc); + arc += 2; + top++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + gray_render_line(RAS_VAR_ arc[0].x, arc[0].y); + top--; + arc -= 2; + + } while (top >= 0); +} + +static void gray_split_cubic(GD_FT_Vector *base) +{ + TPos a, b, c; + + base[6].x = base[3].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c >> 1; + c += b; + base[4].x = c >> 2; + base[1].x = a >> 1; + a += b; + base[2].x = a >> 2; + base[3].x = (a + c) >> 3; + + base[6].y = base[3].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c >> 1; + c += b; + base[4].y = c >> 2; + base[1].y = a >> 1; + a += b; + base[2].y = a >> 2; + base[3].y = (a + c) >> 3; +} + +static void gray_render_cubic(RAS_ARG_ const GD_FT_Vector *control1, const GD_FT_Vector *control2, + const GD_FT_Vector *to) +{ + GD_FT_Vector *arc = ras.bez_stack; + + arc[0].x = UPSCALE(to->x); + arc[0].y = UPSCALE(to->y); + arc[1].x = UPSCALE(control2->x); + arc[1].y = UPSCALE(control2->y); + arc[2].x = UPSCALE(control1->x); + arc[2].y = UPSCALE(control1->y); + arc[3].x = ras.x; + arc[3].y = ras.y; + + /* short-cut the arc that crosses the current band */ + if ((TRUNC(arc[0].y) >= ras.max_ey && TRUNC(arc[1].y) >= ras.max_ey && + TRUNC(arc[2].y) >= ras.max_ey && TRUNC(arc[3].y) >= ras.max_ey) || + (TRUNC(arc[0].y) < ras.min_ey && TRUNC(arc[1].y) < ras.min_ey && + TRUNC(arc[2].y) < ras.min_ey && TRUNC(arc[3].y) < ras.min_ey)) { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } + + for (;;) { + /* with each split, control points quickly converge towards */ + /* chord trisection points and the vanishing distances below */ + /* indicate when the segment is flat enough to draw */ + if (GD_FT_ABS(2 * arc[0].x - 3 * arc[1].x + arc[3].x) > ONE_PIXEL / 2 || + GD_FT_ABS(2 * arc[0].y - 3 * arc[1].y + arc[3].y) > ONE_PIXEL / 2 || + GD_FT_ABS(arc[0].x - 3 * arc[2].x + 2 * arc[3].x) > ONE_PIXEL / 2 || + GD_FT_ABS(arc[0].y - 3 * arc[2].y + 2 * arc[3].y) > ONE_PIXEL / 2) + goto Split; + + gray_render_line(RAS_VAR_ arc[0].x, arc[0].y); + + if (arc == ras.bez_stack) + return; + + arc -= 3; + continue; + + Split: + gray_split_cubic(arc); + arc += 3; + } +} + +static int gray_move_to(const GD_FT_Vector *to, gray_PWorker worker) +{ + TPos x, y; + + /* record current cell, if any */ + if (!ras.invalid) + gray_record_cell(RAS_VAR); + + /* start to a new position */ + x = UPSCALE(to->x); + y = UPSCALE(to->y); + + gray_start_cell(RAS_VAR_ TRUNC(x), TRUNC(y)); + + worker->x = x; + worker->y = y; + return 0; +} + +static int gray_line_to(const GD_FT_Vector *to, gray_PWorker worker) +{ + gray_render_line(RAS_VAR_ UPSCALE(to->x), UPSCALE(to->y)); + return 0; +} + +static int gray_conic_to(const GD_FT_Vector *control, const GD_FT_Vector *to, gray_PWorker worker) +{ + gray_render_conic(RAS_VAR_ control, to); + return 0; +} + +static int gray_cubic_to(const GD_FT_Vector *control1, const GD_FT_Vector *control2, + const GD_FT_Vector *to, gray_PWorker worker) +{ + gray_render_cubic(RAS_VAR_ control1, control2, to); + return 0; +} + +static void gray_hline(RAS_ARG_ TCoord x, TCoord y, TPos area, TCoord acount) +{ + int coverage; + + /* compute the coverage line's coverage, depending on the */ + /* outline fill rule */ + /* */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + /* */ + coverage = (int)(area >> (PIXEL_BITS * 2 + 1 - 8)); + /* use range 0..256 */ + if (coverage < 0) + coverage = -coverage; + + if (ras.outline.flags & GD_FT_OUTLINE_EVEN_ODD_FILL) { + coverage &= 511; + + if (coverage > 256) + coverage = 512 - coverage; + else if (coverage == 256) + coverage = 255; + } else { + /* normal non-zero winding rule */ + if (coverage >= 256) + coverage = 255; + } + + y += (TCoord)ras.min_ey; + x += (TCoord)ras.min_ex; + + /* GD_FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ + if (x >= 32767) + x = 32767; + + /* GD_FT_Span.y is an integer, so limit our coordinates appropriately */ + if (y >= GD_FT_INT_MAX) + y = GD_FT_INT_MAX; + + if (coverage) { + GD_FT_Span *span; + int count; + + // update bounding box. + if (x < ras.bound_left) + ras.bound_left = x; + if (y < ras.bound_top) + ras.bound_top = y; + if (y > ras.bound_bottom) + ras.bound_bottom = y; + if (x + acount > ras.bound_right) + ras.bound_right = x + acount; + + /* see whether we can add this span to the current list */ + count = ras.num_gray_spans; + span = ras.gray_spans + count - 1; + if (count > 0 && span->y == y && (int)span->x + span->len == (int)x && + span->coverage == coverage) { + span->len = (unsigned short)(span->len + acount); + return; + } + + if (count >= GD_FT_MAX_GRAY_SPANS) { + if (ras.render_span && count > 0) + ras.render_span(count, ras.gray_spans, ras.render_span_data); + +#ifdef DEBUG_GRAYS + + if (1) { + int n; + + fprintf(stderr, "count = %3d ", count); + span = ras.gray_spans; + for (n = 0; n < count; n++, span++) + fprintf(stderr, "[%d , %d..%d] : %d ", span->y, span->x, + span->x + span->len - 1, span->coverage); + fprintf(stderr, "\n"); + } + +#endif /* DEBUG_GRAYS */ + + ras.num_gray_spans = 0; + + span = ras.gray_spans; + } else + span++; + + /* add a gray span to the current list */ + span->x = (short)x; + span->y = (short)y; + span->len = (unsigned short)acount; + span->coverage = (unsigned char)coverage; + + ras.num_gray_spans++; + } +} + +static void gray_sweep(RAS_ARG) +{ + int yindex; + + if (ras.num_cells == 0) + return; + + ras.num_gray_spans = 0; + + for (yindex = 0; yindex < ras.ycount; yindex++) { + PCell cell = ras.ycells[yindex]; + TCoord cover = 0; + TCoord x = 0; + + for (; cell != NULL; cell = cell->next) { + TPos area; + + if (cell->x > x && cover != 0) + gray_hline(RAS_VAR_ x, yindex, cover * (ONE_PIXEL * 2), cell->x - x); + + cover += cell->cover; + area = cover * (ONE_PIXEL * 2) - cell->area; + + if (area != 0 && cell->x >= 0) + gray_hline(RAS_VAR_ cell->x, yindex, area, 1); + + x = cell->x + 1; + } + + if (cover != 0) + gray_hline(RAS_VAR_ x, yindex, cover * (ONE_PIXEL * 2), ras.count_ex - x); + } + + if (ras.render_span && ras.num_gray_spans > 0) + ras.render_span(ras.num_gray_spans, ras.gray_spans, ras.render_span_data); +} + +/*************************************************************************/ +/* */ +/* The following function should only compile in stand-alone mode, */ +/* i.e., when building this component without the rest of FreeType. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Outline_Decompose */ +/* */ +/* */ +/* Walk over an outline's structure to decompose it into individual */ +/* segments and Bézier arcs. This function is also able to emit */ +/* `move to' and `close to' operations to indicate the start and end */ +/* of new contours in the outline. */ +/* */ +/* */ +/* outline :: A pointer to the source target. */ +/* */ +/* func_interface :: A table of `emitters', i.e., function pointers */ +/* called during decomposition to indicate path */ +/* operations. */ +/* */ +/* */ +/* user :: A typeless pointer which is passed to each */ +/* emitter during the decomposition. It can be */ +/* used to store the state during the */ +/* decomposition. */ +/* */ +/* */ +/* Error code. 0 means success. */ +/* */ +static int GD_FT_Outline_Decompose(const GD_FT_Outline *outline, + const GD_FT_Outline_Funcs *func_interface, void *user) +{ +#undef SCALED +#define SCALED(x) (((TPos)(x) * (1L << shift)) - delta) + + GD_FT_Vector v_last; + GD_FT_Vector v_control; + GD_FT_Vector v_start; + + GD_FT_Vector *point; + GD_FT_Vector *limit; + char *tags; + + int error; + + int n; /* index of contour in outline */ + int first; /* index of first point in contour */ + char tag; /* current point's state */ + + int shift; + TPos delta; + + if (!outline || !func_interface) + return GD_FT_THROW(Invalid_Argument); + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for (n = 0; n < outline->n_contours; n++) { + int last; /* index of last point in contour */ + + last = outline->contours[n]; + if (last < 0) + goto Invalid_Outline; + limit = outline->points + last; + + v_start = outline->points[first]; + v_start.x = SCALED(v_start.x); + v_start.y = SCALED(v_start.y); + + v_last = outline->points[last]; + v_last.x = SCALED(v_last.x); + v_last.y = SCALED(v_last.y); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = GD_FT_CURVE_TAG(tags[0]); + + /* A contour cannot start with a cubic control point! */ + if (tag == GD_FT_CURVE_TAG_CUBIC) + goto Invalid_Outline; + + /* check first point to determine origin */ + if (tag == GD_FT_CURVE_TAG_CONIC) { + /* first point is conic control. Yes, this happens. */ + if (GD_FT_CURVE_TAG(outline->tags[last]) == GD_FT_CURVE_TAG_ON) { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } else { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = (v_start.x + v_last.x) / 2; + v_start.y = (v_start.y + v_last.y) / 2; + } + point--; + tags--; + } + + error = func_interface->move_to(&v_start, user); + if (error) + goto Exit; + + while (point < limit) { + point++; + tags++; + + tag = GD_FT_CURVE_TAG(tags[0]); + switch (tag) { + case GD_FT_CURVE_TAG_ON: /* emit a single line_to */ + { + GD_FT_Vector vec; + + vec.x = SCALED(point->x); + vec.y = SCALED(point->y); + + error = func_interface->line_to(&vec, user); + if (error) + goto Exit; + continue; + } + + case GD_FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED(point->x); + v_control.y = SCALED(point->y); + + Do_Conic: + if (point < limit) { + GD_FT_Vector vec; + GD_FT_Vector v_middle; + + point++; + tags++; + tag = GD_FT_CURVE_TAG(tags[0]); + + vec.x = SCALED(point->x); + vec.y = SCALED(point->y); + + if (tag == GD_FT_CURVE_TAG_ON) { + error = func_interface->conic_to(&v_control, &vec, user); + if (error) + goto Exit; + continue; + } + + if (tag != GD_FT_CURVE_TAG_CONIC) + goto Invalid_Outline; + + v_middle.x = (v_control.x + vec.x) / 2; + v_middle.y = (v_control.y + vec.y) / 2; + + error = func_interface->conic_to(&v_control, &v_middle, user); + if (error) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = func_interface->conic_to(&v_control, &v_start, user); + goto Close; + + default: /* GD_FT_CURVE_TAG_CUBIC */ + { + GD_FT_Vector vec1, vec2; + + if (point + 1 > limit || GD_FT_CURVE_TAG(tags[1]) != GD_FT_CURVE_TAG_CUBIC) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED(point[-2].x); + vec1.y = SCALED(point[-2].y); + + vec2.x = SCALED(point[-1].x); + vec2.y = SCALED(point[-1].y); + + if (point <= limit) { + GD_FT_Vector vec; + + vec.x = SCALED(point->x); + vec.y = SCALED(point->y); + + error = func_interface->cubic_to(&vec1, &vec2, &vec, user); + if (error) + goto Exit; + continue; + } + + error = func_interface->cubic_to(&vec1, &vec2, &v_start, user); + goto Close; + } + } + } + + /* close the contour with a line segment */ + error = func_interface->line_to(&v_start, user); + + Close: + if (error) + goto Exit; + + first = last + 1; + } + + return 0; + +Exit: + return error; + +Invalid_Outline: + return GD_FT_THROW(Invalid_Outline); +} + +typedef struct gray_TBand_ { + TPos min, max; + +} gray_TBand; + +GD_FT_DEFINE_OUTLINE_FUNCS(func_interface, (GD_FT_Outline_MoveTo_Func)gray_move_to, + (GD_FT_Outline_LineTo_Func)gray_line_to, + (GD_FT_Outline_ConicTo_Func)gray_conic_to, + (GD_FT_Outline_CubicTo_Func)gray_cubic_to, 0, 0) + +static int gray_convert_glyph_inner(RAS_ARG) +{ + volatile int error = 0; + + if (ft_setjmp(ras.jump_buffer) == 0) { + if (ras.source && ras.source->decompose) { + error = ras.source->decompose(ras.source->source, &ras); + } else { + error = GD_FT_Outline_Decompose(&ras.outline, &func_interface, &ras); + } + if (!ras.invalid) + gray_record_cell(RAS_VAR); + } else + error = GD_FT_THROW(Memory_Overflow); + + return error; +} + +static int gray_convert_glyph(RAS_ARG) +{ + gray_TBand bands[40]; + gray_TBand *volatile band; + int volatile n, num_bands; + TPos volatile min, max, max_y; + GD_FT_BBox *clip; + + /* Set up state in the raster object */ + gray_compute_cbox(RAS_VAR); + + /* clip to target bitmap, exit if nothing to do */ + clip = &ras.clip_box; + + if (ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || ras.max_ey <= clip->yMin || + ras.min_ey >= clip->yMax) + return 0; + + if (ras.min_ex < clip->xMin) + ras.min_ex = clip->xMin; + if (ras.min_ey < clip->yMin) + ras.min_ey = clip->yMin; + + if (ras.max_ex > clip->xMax) + ras.max_ex = clip->xMax; + if (ras.max_ey > clip->yMax) + ras.max_ey = clip->yMax; + + ras.count_ex = ras.max_ex - ras.min_ex; + ras.count_ey = ras.max_ey - ras.min_ey; + + /* set up vertical bands */ + num_bands = (int)((ras.max_ey - ras.min_ey) / ras.band_size); + if (num_bands == 0) + num_bands = 1; + if (num_bands >= 39) + num_bands = 39; + + ras.band_shoot = 0; + + min = ras.min_ey; + max_y = ras.max_ey; + + for (n = 0; n < num_bands; n++, min = max) { + max = min + ras.band_size; + if (n == num_bands - 1 || max > max_y) + max = max_y; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while (band >= bands) { + TPos bottom, top, middle; + int error; + + { + PCell cells_max; + int yindex; + long cell_start, cell_end, cell_mod; + + ras.ycells = (PCell *)ras.buffer; + ras.ycount = band->max - band->min; + + cell_start = sizeof(PCell) * ras.ycount; + cell_mod = cell_start % sizeof(TCell); + if (cell_mod > 0) + cell_start += sizeof(TCell) - cell_mod; + + cell_end = ras.buffer_size; + cell_end -= cell_end % sizeof(TCell); + + cells_max = (PCell)((char *)ras.buffer + cell_end); + ras.cells = (PCell)((char *)ras.buffer + cell_start); + if (ras.cells >= cells_max) + goto ReduceBands; + + ras.max_cells = cells_max - ras.cells; + if (ras.max_cells < 2) + goto ReduceBands; + + for (yindex = 0; yindex < ras.ycount; yindex++) + ras.ycells[yindex] = NULL; + } + + ras.num_cells = 0; + ras.invalid = 1; + ras.min_ey = band->min; + ras.max_ey = band->max; + ras.count_ey = band->max - band->min; + + error = gray_convert_glyph_inner(RAS_VAR); + + if (!error) { + gray_sweep(RAS_VAR); + band--; + continue; + } else if (error != ErrRaster_Memory_Overflow) + return 1; + + ReduceBands: + /* render pool overflow; we will reduce the render band by half */ + bottom = band->min; + top = band->max; + middle = bottom + ((top - bottom) >> 1); + + /* This is too complex for a single scanline; there must */ + /* be some problems. */ + if (middle == bottom) { + return 1; + } + + if (bottom - top >= ras.band_size) + ras.band_shoot++; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + band++; + } + } + + if (ras.band_shoot > 8 && ras.band_size > 16) + ras.band_size = ras.band_size / 2; + + return 0; +} + +static int gray_raster_render(gray_PRaster raster, const GD_FT_Raster_Params *params) +{ + GD_FT_UNUSED(raster); + const GD_FT_Outline *outline = (const GD_FT_Outline *)params->source; + + gray_TWorker worker[1]; + + TCell buffer[GD_FT_RENDER_POOL_SIZE / sizeof(TCell)]; + long buffer_size = sizeof(buffer); + int band_size = (int)(buffer_size / (long)(sizeof(TCell) * 8)); + + if (!outline) + return GD_FT_THROW(Invalid_Outline); + + /* return immediately if the outline is empty */ + if (outline->n_points == 0 || outline->n_contours <= 0) + return 0; + + if (!outline->contours || !outline->points) + return GD_FT_THROW(Invalid_Outline); + + if (outline->n_points != outline->contours[outline->n_contours - 1] + 1) + return GD_FT_THROW(Invalid_Outline); + + if (params->flags & GD_FT_RASTER_FLAG_CLIP) + ras.clip_box = params->clip_box; + else { + ras.clip_box.xMin = -32768L; + ras.clip_box.yMin = -32768L; + ras.clip_box.xMax = 32767L; + ras.clip_box.yMax = 32767L; + } + + gray_init_cells(RAS_VAR_ buffer, buffer_size); + + ras.outline = *outline; + ras.source = NULL; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = band_size; + ras.num_gray_spans = 0; + + ras.render_span = (GD_FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + + gray_convert_glyph(RAS_VAR); + if (ras.bound_right > ras.bound_left && ras.bound_bottom > ras.bound_top) { + params->bbox_cb(ras.bound_left, ras.bound_top, ras.bound_right - ras.bound_left, + ras.bound_bottom - ras.bound_top + 1, params->user); + } + return 1; +} + +/**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ +/**** a static object. *****/ + +static int gray_raster_new(GD_FT_Raster *araster) +{ + static gray_TRaster the_raster; + + *araster = (GD_FT_Raster)&the_raster; + GD_FT_MEM_ZERO(&the_raster, sizeof(the_raster)); + + return 0; +} + +static void gray_raster_done(GD_FT_Raster raster) +{ + /* nothing */ + GD_FT_UNUSED(raster); +} + +static void gray_raster_reset(GD_FT_Raster raster, char *pool_base, long pool_size) +{ + GD_FT_UNUSED(raster); + GD_FT_UNUSED(pool_base); + GD_FT_UNUSED(pool_size); +} + +GD_FT_DEFINE_RASTER_FUNCS(gd_ft_grays_raster, + + (GD_FT_Raster_New_Func)gray_raster_new, + (GD_FT_Raster_Reset_Func)gray_raster_reset, + (GD_FT_Raster_Render_Func)gray_raster_render, + (GD_FT_Raster_Done_Func)gray_raster_done) + +typedef struct gdPathRasterSource_ { + gdPathPtr path; + gdPathMatrixPtr matrix; +} gdPathRasterSource; + +static void gdpath_include_point(GD_FT_BBox *box, int *first, const gdPointF *point) +{ + TPos x = (TPos)(point->x * 64.0); + TPos y = (TPos)(point->y * 64.0); + + if (*first) { + box->xMin = box->xMax = x; + box->yMin = box->yMax = y; + *first = 0; + return; + } + + if (x < box->xMin) + box->xMin = x; + if (x > box->xMax) + box->xMax = x; + if (y < box->yMin) + box->yMin = y; + if (y > box->yMax) + box->yMax = y; +} + +static GD_FT_Vector gdpath_vector(const gdPointF *point) +{ + GD_FT_Vector vector = {(GD_FT_Pos)(point->x * 64.0), (GD_FT_Pos)(point->y * 64.0)}; + return vector; +} + +static int gdpath_get_cbox(void *source, GD_FT_BBox *box) +{ + const gdPathRasterSource *path_source = source; + gdPathPtr path = path_source->path; + gdPathMatrixPtr matrix = path_source->matrix; + unsigned int numElements = gdArrayNumElements(&path->elements); + unsigned int pointsIndex = 0; + int first = 1; + gdPointF p[3]; + + for (unsigned int i = 0; i < numElements; i++) { + gdPathOpsPtr element = (gdPathOpsPtr)gdArrayIndex(&path->elements, i); + gdPointFPtr point = gdArrayIndex(&path->points, pointsIndex); + + switch (*element) { + case gdPathOpsMoveTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + gdpath_include_point(box, &first, &p[0]); + pointsIndex += 1; + break; + case gdPathOpsLineTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + gdpath_include_point(box, &first, &p[0]); + pointsIndex += 1; + break; + case gdPathOpsCubicTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + point = gdArrayIndex(&path->points, pointsIndex + 2); + gdPathMatrixMapPoint(matrix, point, &p[2]); + gdpath_include_point(box, &first, &p[0]); + gdpath_include_point(box, &first, &p[1]); + gdpath_include_point(box, &first, &p[2]); + pointsIndex += 3; + break; + case gdPathOpsQuadTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + gdpath_include_point(box, &first, &p[0]); + gdpath_include_point(box, &first, &p[1]); + pointsIndex += 2; + break; + case gdPathOpsClose: + pointsIndex += 1; + break; + } + } + + if (first) { + return -1; + } + + return 0; +} + +static int gdpath_decompose(void *source, void *worker_data) +{ + const gdPathRasterSource *path_source = source; + gdPathPtr path = path_source->path; + gdPathMatrixPtr matrix = path_source->matrix; + gray_PWorker worker = worker_data; + unsigned int pointsIndex = 0; + gdPointF p[3]; + GD_FT_Vector contour_start = {0, 0}; + int contour_open = 0; + + for (unsigned int i = 0; i < gdArrayNumElements(&path->elements); i++) { + gdPathOpsPtr element = (gdPathOpsPtr)gdArrayIndex(&path->elements, i); + gdPointFPtr point = gdArrayIndex(&path->points, pointsIndex); + + switch (*element) { + case gdPathOpsMoveTo: + if (contour_open) + gray_line_to(&contour_start, worker); + gdPathMatrixMapPoint(matrix, point, &p[0]); + { + GD_FT_Vector v = gdpath_vector(&p[0]); + gray_move_to(&v, worker); + contour_start = v; + contour_open = 1; + } + pointsIndex += 1; + break; + case gdPathOpsLineTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + { + GD_FT_Vector v = gdpath_vector(&p[0]); + if (contour_open) { + gray_line_to(&v, worker); + } else { + gray_move_to(&v, worker); + contour_start = v; + contour_open = 1; + } + } + pointsIndex += 1; + break; + case gdPathOpsCubicTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + point = gdArrayIndex(&path->points, pointsIndex + 2); + gdPathMatrixMapPoint(matrix, point, &p[2]); + { + GD_FT_Vector v1 = gdpath_vector(&p[0]); + GD_FT_Vector v2 = gdpath_vector(&p[1]); + GD_FT_Vector v3 = gdpath_vector(&p[2]); + if (contour_open) { + gray_cubic_to(&v1, &v2, &v3, worker); + } else { + gray_move_to(&v3, worker); + contour_start = v3; + contour_open = 1; + } + } + pointsIndex += 3; + break; + case gdPathOpsQuadTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + { + GD_FT_Vector v1 = gdpath_vector(&p[0]); + GD_FT_Vector v2 = gdpath_vector(&p[1]); + if (contour_open) { + gray_conic_to(&v1, &v2, worker); + } else { + gray_move_to(&v2, worker); + contour_start = v2; + contour_open = 1; + } + } + pointsIndex += 2; + break; + case gdPathOpsClose: + if (contour_open) { + gdPathMatrixMapPoint(matrix, point, &p[0]); + { + GD_FT_Vector v = gdpath_vector(&p[0]); + gray_line_to(&v, worker); + } + contour_open = 0; + } + pointsIndex += 1; + break; + } + } + + if (contour_open) + gray_line_to(&contour_start, worker); + return 0; +} + +/* END */ + +GD_FT_Error gd_ft_raster_render_path(const gdPathPtr path, gdPathMatrixPtr matrix, + GD_FT_Raster_Params *params, int outline_flags) +{ + if (!path || !params) + return GD_FT_THROW(Invalid_Argument); + +#ifndef GD_FT_STATIC_RASTER + gray_TWorker worker_storage; + gray_PWorker worker = &worker_storage; +#else + gray_TWorker save_ras = ras; +#endif + + gdPathRasterSource path_source = {path, matrix}; + gray_TSource source = {gdpath_get_cbox, gdpath_decompose, &path_source}; + ras.source = &source; + + params->flags |= GD_FT_RASTER_FLAG_DIRECT | GD_FT_RASTER_FLAG_AA; + if (params->flags & GD_FT_RASTER_FLAG_CLIP) { + ras.clip_box = params->clip_box; + } else { + ras.clip_box.xMin = -32768L; + ras.clip_box.yMin = -32768L; + ras.clip_box.xMax = 32767L; + ras.clip_box.yMax = 32767L; + } + + TCell buffer[GD_FT_RENDER_POOL_SIZE / sizeof(TCell)]; + long buffer_size = sizeof(buffer); + int band_size = (int)(buffer_size / (long)(sizeof(TCell) * 8)); + + gray_init_cells(RAS_VAR_ buffer, buffer_size); + ras.outline.n_contours = 0; + ras.outline.n_points = 0; + ras.outline.flags = outline_flags; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = band_size; + ras.num_gray_spans = 0; + ras.render_span = (GD_FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + + int error = gray_convert_glyph(RAS_VAR); + int bound_left = ras.bound_left; + int bound_top = ras.bound_top; + int bound_right = ras.bound_right; + int bound_bottom = ras.bound_bottom; + +#ifdef GD_FT_STATIC_RASTER + ras = save_ras; +#endif + + if (!error && params->bbox_cb && bound_right > bound_left && bound_bottom > bound_top) { + params->bbox_cb(bound_left, bound_top, bound_right - bound_left, + bound_bottom - bound_top + 1, params->user); + } + + if (error) + return error; + return gdArrayNumElements(&path->elements) > 0 ? 1 : 0; +} diff --git a/ext/gd/libgd/ftraster/gd_ft_raster.h b/ext/gd/libgd/ftraster/gd_ft_raster.h new file mode 100644 index 000000000000..96e974419752 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_raster.h @@ -0,0 +1,579 @@ +#ifndef GD_FT_IMG_H +#define GD_FT_IMG_H +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/*************************************************************************/ +/* */ +/* Note: A `raster' is simply a scan-line converter, used to render */ +/* GD_FT_Outlines into GD_FT_Bitmaps. */ +/* */ +/*************************************************************************/ + +#include "gd_ft_types.h" + +typedef struct gdPathStruct *gdPathPtr; +typedef struct gdPathMatrixStruct *gdPathMatrixPtr; + +/*************************************************************************/ +/* */ +/* */ +/* FT_BBox */ +/* */ +/* */ +/* A structure used to hold an outline's bounding box, i.e., the */ +/* coordinates of its extrema in the horizontal and vertical */ +/* directions. */ +/* */ +/* */ +/* xMin :: The horizontal minimum (left-most). */ +/* */ +/* yMin :: The vertical minimum (bottom-most). */ +/* */ +/* xMax :: The horizontal maximum (right-most). */ +/* */ +/* yMax :: The vertical maximum (top-most). */ +/* */ +/* */ +/* The bounding box is specified with the coordinates of the lower */ +/* left and the upper right corner. In PostScript, those values are */ +/* often called (llx,lly) and (urx,ury), respectively. */ +/* */ +/* If `yMin' is negative, this value gives the glyph's descender. */ +/* Otherwise, the glyph doesn't descend below the baseline. */ +/* Similarly, if `ymax' is positive, this value gives the glyph's */ +/* ascender. */ +/* */ +/* `xMin' gives the horizontal distance from the glyph's origin to */ +/* the left edge of the glyph's bounding box. If `xMin' is negative, */ +/* the glyph extends to the left of the origin. */ +/* */ +typedef struct GD_FT_BBox_ { + GD_FT_Pos xMin, yMin; + GD_FT_Pos xMax, yMax; + +} GD_FT_BBox; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Outline */ +/* */ +/* */ +/* This structure is used to describe an outline to the scan-line */ +/* converter. */ +/* */ +/* */ +/* n_contours :: The number of contours in the outline. */ +/* */ +/* n_points :: The number of points in the outline. */ +/* */ +/* points :: A pointer to an array of `n_points' @GD_FT_Vector */ +/* elements, giving the outline's point coordinates. */ +/* */ +/* tags :: A pointer to an array of `n_points' chars, giving */ +/* each outline point's type. */ +/* */ +/* If bit~0 is unset, the point is `off' the curve, */ +/* i.e., a Bézier control point, while it is `on' if */ +/* set. */ +/* */ +/* Bit~1 is meaningful for `off' points only. If set, */ +/* it indicates a third-order Bézier arc control point; */ +/* and a second-order control point if unset. */ +/* */ +/* If bit~2 is set, bits 5-7 contain the drop-out mode */ +/* (as defined in the OpenType specification; the value */ +/* is the same as the argument to the SCANMODE */ +/* instruction). */ +/* */ +/* Bits 3 and~4 are reserved for internal purposes. */ +/* */ +/* contours :: An array of `n_contours' shorts, giving the end */ +/* point of each contour within the outline. For */ +/* example, the first contour is defined by the points */ +/* `0' to `contours[0]', the second one is defined by */ +/* the points `contours[0]+1' to `contours[1]', etc. */ +/* */ +/* flags :: A set of bit flags used to characterize the outline */ +/* and give hints to the scan-converter and hinter on */ +/* how to convert/grid-fit it. See @GD_FT_OUTLINE_FLAGS.*/ +/* */ +typedef struct GD_FT_Outline_ { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + GD_FT_Vector *points; /* the outline's points */ + char *tags; /* the points flags */ + short *contours; /* the contour end points */ + char *contours_flag; /* the contour open flags */ + + int flags; /* outline masks */ + +} GD_FT_Outline; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_OUTLINE_FLAGS */ +/* */ +/* */ +/* A list of bit-field constants use for the flags in an outline's */ +/* `flags' field. */ +/* */ +/* */ +/* GD_FT_OUTLINE_NONE :: */ +/* Value~0 is reserved. */ +/* */ +/* GD_FT_OUTLINE_OWNER :: */ +/* If set, this flag indicates that the outline's field arrays */ +/* (i.e., `points', `flags', and `contours') are `owned' by the */ +/* outline object, and should thus be freed when it is destroyed. */ +/* */ +/* GD_FT_OUTLINE_EVEN_ODD_FILL :: */ +/* By default, outlines are filled using the non-zero winding rule. */ +/* If set to 1, the outline will be filled using the even-odd fill */ +/* rule (only works with the smooth rasterizer). */ +/* */ +/* GD_FT_OUTLINE_REVERSE_FILL :: */ +/* By default, outside contours of an outline are oriented in */ +/* clock-wise direction, as defined in the TrueType specification. */ +/* This flag is set if the outline uses the opposite direction */ +/* (typically for Type~1 fonts). This flag is ignored by the scan */ +/* converter. */ +/* */ +/* */ +/* */ +/* There exists a second mechanism to pass the drop-out mode to the */ +/* B/W rasterizer; see the `tags' field in @GD_FT_Outline. */ +/* */ +/* Please refer to the description of the `SCANTYPE' instruction in */ +/* the OpenType specification (in file `ttinst1.doc') how simple */ +/* drop-outs, smart drop-outs, and stubs are defined. */ +/* */ +#define GD_FT_OUTLINE_NONE 0x0 +#define GD_FT_OUTLINE_OWNER 0x1 +#define GD_FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define GD_FT_OUTLINE_REVERSE_FILL 0x4 + +/* */ + +#define GD_FT_CURVE_TAG(flag) (flag & 3) + +#define GD_FT_CURVE_TAG_ON 1 +#define GD_FT_CURVE_TAG_CONIC 0 +#define GD_FT_CURVE_TAG_CUBIC 2 + +#define GD_FT_Curve_Tag_On GD_FT_CURVE_TAG_ON +#define GD_FT_Curve_Tag_Conic GD_FT_CURVE_TAG_CONIC +#define GD_FT_Curve_Tag_Cubic GD_FT_CURVE_TAG_CUBIC + +/*************************************************************************/ +/* */ +/* A raster is a scan converter, in charge of rendering an outline into */ +/* a a bitmap. This section contains the public API for rasters. */ +/* */ +/* Note that in FreeType 2, all rasters are now encapsulated within */ +/* specific modules called `renderers'. See `ftrender.h' for more */ +/* details on renderers. */ +/* */ +/*************************************************************************/ + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster */ +/* */ +/* */ +/* A handle (pointer) to a raster object. Each object can be used */ +/* independently to convert an outline into a bitmap or pixmap. */ +/* */ +typedef struct GD_FT_RasterRec_ *GD_FT_Raster; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Span */ +/* */ +/* */ +/* A structure used to model a single span of gray (or black) pixels */ +/* when rendering a monochrome or anti-aliased bitmap. */ +/* */ +/* */ +/* x :: The span's horizontal start position. */ +/* */ +/* len :: The span's length in pixels. */ +/* */ +/* coverage :: The span color/coverage, ranging from 0 (background) */ +/* to 255 (foreground). Only used for anti-aliased */ +/* rendering. */ +/* */ +/* */ +/* This structure is used by the span drawing callback type named */ +/* @GD_FT_SpanFunc that takes the y~coordinate of the span as a */ +/* parameter. */ +/* */ +/* The coverage value is always between 0 and 255. If you want less */ +/* gray values, the callback function has to reduce them. */ +/* */ +typedef struct GD_FT_Span_ { + short x; + short y; + unsigned short len; + unsigned char coverage; + +} GD_FT_Span; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_SpanFunc */ +/* */ +/* */ +/* A function used as a call-back by the anti-aliased renderer in */ +/* order to let client applications draw themselves the gray pixel */ +/* spans on each scan line. */ +/* */ +/* */ +/* y :: The scanline's y~coordinate. */ +/* */ +/* count :: The number of spans to draw on this scanline. */ +/* */ +/* spans :: A table of `count' spans to draw on the scanline. */ +/* */ +/* user :: User-supplied data that is passed to the callback. */ +/* */ +/* */ +/* This callback allows client applications to directly render the */ +/* gray spans of the anti-aliased bitmap to any kind of surfaces. */ +/* */ +/* This can be used to write anti-aliased outlines directly to a */ +/* given background bitmap, and even perform translucency. */ +/* */ +/* Note that the `count' field cannot be greater than a fixed value */ +/* defined by the `GD_FT_MAX_GRAY_SPANS' configuration macro in */ +/* `ftoption.h'. By default, this value is set to~32, which means */ +/* that if there are more than 32~spans on a given scanline, the */ +/* callback is called several times with the same `y' parameter in */ +/* order to draw all callbacks. */ +/* */ +/* Otherwise, the callback is only called once per scan-line, and */ +/* only for those scanlines that do have `gray' pixels on them. */ +/* */ +typedef void (*GD_FT_SpanFunc)(int count, const GD_FT_Span *spans, void *user); + +typedef void (*GD_FT_BboxFunc)(int x, int y, int w, int h, void *user); + +#define GD_FT_Raster_Span_Func GD_FT_SpanFunc + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_RASTER_FLAG_XXX */ +/* */ +/* */ +/* A list of bit flag constants as used in the `flags' field of a */ +/* @GD_FT_Raster_Params structure. */ +/* */ +/* */ +/* GD_FT_RASTER_FLAG_DEFAULT :: This value is 0. */ +/* */ +/* GD_FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ +/* anti-aliased glyph image should be */ +/* generated. Otherwise, it will be */ +/* monochrome (1-bit). */ +/* */ +/* GD_FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ +/* rendering. In this mode, client */ +/* applications must provide their own span */ +/* callback. This lets them directly */ +/* draw or compose over an existing bitmap. */ +/* If this bit is not set, the target */ +/* pixmap's buffer _must_ be zeroed before */ +/* rendering. */ +/* */ +/* Note that for now, direct rendering is */ +/* only possible with anti-aliased glyphs. */ +/* */ +/* GD_FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ +/* rendering mode. If set, the output will */ +/* be clipped to a box specified in the */ +/* `clip_box' field of the */ +/* @GD_FT_Raster_Params structure. */ +/* */ +/* Note that by default, the glyph bitmap */ +/* is clipped to the target pixmap, except */ +/* in direct rendering mode where all spans */ +/* are generated if no clipping box is set. */ +/* */ +#define GD_FT_RASTER_FLAG_DEFAULT 0x0 +#define GD_FT_RASTER_FLAG_AA 0x1 +#define GD_FT_RASTER_FLAG_DIRECT 0x2 +#define GD_FT_RASTER_FLAG_CLIP 0x4 + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_Params */ +/* */ +/* */ +/* A structure to hold the arguments used by a raster's render */ +/* function. */ +/* */ +/* */ +/* target :: The target bitmap. */ +/* */ +/* source :: A pointer to the source glyph image (e.g., an */ +/* @GD_FT_Outline). */ +/* */ +/* flags :: The rendering flags. */ +/* */ +/* gray_spans :: The gray span drawing callback. */ +/* */ +/* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ +/* */ +/* bit_test :: The bit test callback. UNIMPLEMENTED! */ +/* */ +/* bit_set :: The bit set callback. UNIMPLEMENTED! */ +/* */ +/* user :: User-supplied data that is passed to each drawing */ +/* callback. */ +/* */ +/* clip_box :: An optional clipping box. It is only used in */ +/* direct rendering mode. Note that coordinates here */ +/* should be expressed in _integer_ pixels (and not in */ +/* 26.6 fixed-point units). */ +/* */ +/* */ +/* An anti-aliased glyph bitmap is drawn if the @GD_FT_RASTER_FLAG_AA */ +/* bit flag is set in the `flags' field, otherwise a monochrome */ +/* bitmap is generated. */ +/* */ +/* If the @GD_FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ +/* raster will call the `gray_spans' callback to draw gray pixel */ +/* spans, in the case of an aa glyph bitmap, it will call */ +/* `black_spans', and `bit_test' and `bit_set' in the case of a */ +/* monochrome bitmap. This allows direct composition over a */ +/* pre-existing bitmap through user-provided callbacks to perform the */ +/* span drawing/composition. */ +/* */ +/* Note that the `bit_test' and `bit_set' callbacks are required when */ +/* rendering a monochrome bitmap, as they are crucial to implement */ +/* correct drop-out control as defined in the TrueType specification. */ +/* */ +typedef struct GD_FT_Raster_Params_ { + const void *source; + int flags; + GD_FT_SpanFunc gray_spans; + GD_FT_BboxFunc bbox_cb; + void *user; + GD_FT_BBox clip_box; + +} GD_FT_Raster_Params; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Outline_Check */ +/* */ +/* */ +/* Check the contents of an outline descriptor. */ +/* */ +/* */ +/* outline :: A handle to a source outline. */ +/* */ +/* */ +/* FreeType error code. 0~means success. */ +/* */ +GD_FT_Error GD_FT_Outline_Check(GD_FT_Outline *outline); + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Outline_Get_CBox */ +/* */ +/* */ +/* Return an outline's `control box'. The control box encloses all */ +/* the outline's points, including Bézier control points. Though it */ +/* coincides with the exact bounding box for most glyphs, it can be */ +/* slightly larger in some situations (like when rotating an outline */ +/* that contains Bézier outside arcs). */ +/* */ +/* Computing the control box is very fast, while getting the bounding */ +/* box can take much more time as it needs to walk over all segments */ +/* and arcs in the outline. To get the latter, you can use the */ +/* `ftbbox' component, which is dedicated to this single task. */ +/* */ +/* */ +/* outline :: A pointer to the source outline descriptor. */ +/* */ +/* */ +/* acbox :: The outline's control box. */ +/* */ +/* */ +/* See @GD_FT_Glyph_Get_CBox for a discussion of tricky fonts. */ +/* */ +void GD_FT_Outline_Get_CBox(const GD_FT_Outline *outline, GD_FT_BBox *acbox); + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_NewFunc */ +/* */ +/* */ +/* A function used to create a new raster object. */ +/* */ +/* */ +/* memory :: A handle to the memory allocator. */ +/* */ +/* */ +/* raster :: A handle to the new raster object. */ +/* */ +/* */ +/* Error code. 0~means success. */ +/* */ +/* */ +/* The `memory' parameter is a typeless pointer in order to avoid */ +/* un-wanted dependencies on the rest of the FreeType code. In */ +/* practice, it is an @GD_FT_Memory object, i.e., a handle to the */ +/* standard FreeType memory allocator. However, this field can be */ +/* completely ignored by a given raster implementation. */ +/* */ +typedef int (*GD_FT_Raster_NewFunc)(GD_FT_Raster *raster); + +#define GD_FT_Raster_New_Func GD_FT_Raster_NewFunc + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_DoneFunc */ +/* */ +/* */ +/* A function used to destroy a given raster object. */ +/* */ +/* */ +/* raster :: A handle to the raster object. */ +/* */ +typedef void (*GD_FT_Raster_DoneFunc)(GD_FT_Raster raster); + +#define GD_FT_Raster_Done_Func GD_FT_Raster_DoneFunc + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_ResetFunc */ +/* */ +/* */ +/* FreeType provides an area of memory called the `render pool', */ +/* available to all registered rasters. This pool can be freely used */ +/* during a given scan-conversion but is shared by all rasters. Its */ +/* content is thus transient. */ +/* */ +/* This function is called each time the render pool changes, or just */ +/* after a new raster object is created. */ +/* */ +/* */ +/* raster :: A handle to the new raster object. */ +/* */ +/* pool_base :: The address in memory of the render pool. */ +/* */ +/* pool_size :: The size in bytes of the render pool. */ +/* */ +/* */ +/* Rasters can ignore the render pool and rely on dynamic memory */ +/* allocation if they want to (a handle to the memory allocator is */ +/* passed to the raster constructor). However, this is not */ +/* recommended for efficiency purposes. */ +/* */ +typedef void (*GD_FT_Raster_ResetFunc)(GD_FT_Raster raster, unsigned char *pool_base, + unsigned long pool_size); + +#define GD_FT_Raster_Reset_Func GD_FT_Raster_ResetFunc + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_RenderFunc */ +/* */ +/* */ +/* Invoke a given raster to scan-convert a given glyph image into a */ +/* target bitmap. */ +/* */ +/* */ +/* raster :: A handle to the raster object. */ +/* */ +/* params :: A pointer to an @GD_FT_Raster_Params structure used to */ +/* store the rendering parameters. */ +/* */ +/* */ +/* Error code. 0~means success. */ +/* */ +/* */ +/* The exact format of the source image depends on the raster's glyph */ +/* format defined in its @GD_FT_Raster_Funcs structure. It can be an */ +/* @GD_FT_Outline or anything else in order to support a large array of */ +/* glyph formats. */ +/* */ +/* Note also that the render function can fail and return a */ +/* `GD_FT_Err_Unimplemented_Feature' error code if the raster used does */ +/* not support direct composition. */ +/* */ +/* XXX: For now, the standard raster doesn't support direct */ +/* composition but this should change for the final release (see */ +/* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ +/* for examples of distinct implementations that support direct */ +/* composition). */ +/* */ +typedef int (*GD_FT_Raster_RenderFunc)(GD_FT_Raster raster, const GD_FT_Raster_Params *params); + +#define GD_FT_Raster_Render_Func GD_FT_Raster_RenderFunc + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Raster_Funcs */ +/* */ +/* */ +/* A structure used to describe a given raster class to the library. */ +/* */ +/* */ +/* glyph_format :: The supported glyph format for this raster. */ +/* */ +/* raster_new :: The raster constructor. */ +/* */ +/* raster_reset :: Used to reset the render pool within the raster. */ +/* */ +/* raster_render :: A function to render a glyph into a given bitmap. */ +/* */ +/* raster_done :: The raster destructor. */ +/* */ +typedef struct GD_FT_Raster_Funcs_ { + GD_FT_Raster_NewFunc raster_new; + GD_FT_Raster_ResetFunc raster_reset; + GD_FT_Raster_RenderFunc raster_render; + GD_FT_Raster_DoneFunc raster_done; + +} GD_FT_Raster_Funcs; + +extern const GD_FT_Raster_Funcs gd_ft_grays_raster; + +/* Direct path rendering without FT_Outline intermediate */ +GD_FT_Error gd_ft_raster_render_path(const gdPathPtr path, gdPathMatrixPtr matrix, + GD_FT_Raster_Params *params, int outline_flags); + +#endif // GD_FT_IMG_H diff --git a/ext/gd/libgd/ftraster/gd_ft_stroker.c b/ext/gd/libgd/ftraster/gd_ft_stroker.c new file mode 100644 index 000000000000..ca77586c34f5 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_stroker.c @@ -0,0 +1,1892 @@ + +/***************************************************************************/ +/* */ +/* ftstroke.c */ +/* */ +/* FreeType path stroker (body). */ +/* */ +/* Copyright 2002-2006, 2008-2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include "gd_ft_stroker.h" +#include "gd_ft_math.h" +#include +#include +#include + +/*************************************************************************/ +/*************************************************************************/ +/***** *****/ +/***** BEZIER COMPUTATIONS *****/ +/***** *****/ +/*************************************************************************/ +/*************************************************************************/ + +#define GD_FT_SMALL_CONIC_THRESHOLD (GD_FT_ANGLE_PI / 6) +#define GD_FT_SMALL_CUBIC_THRESHOLD (GD_FT_ANGLE_PI / 8) + +#define GD_FT_EPSILON 2 + +#define GD_FT_IS_SMALL(x) ((x) > -GD_FT_EPSILON && (x) < GD_FT_EPSILON) + +static inline GD_FT_Pos ft_pos_abs(GD_FT_Pos x) { return x >= 0 ? x : -x; } + +static void ft_conic_split(GD_FT_Vector *base) +{ + GD_FT_Pos a, b; + + base[4].x = base[2].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b >> 1; + base[2].x = (a + b) >> 2; + base[1].x = a >> 1; + + base[4].y = base[2].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b >> 1; + base[2].y = (a + b) >> 2; + base[1].y = a >> 1; +} + +static GD_FT_Bool ft_conic_is_small_enough(GD_FT_Vector *base, GD_FT_Angle *angle_in, + GD_FT_Angle *angle_out) +{ + GD_FT_Vector d1, d2; + GD_FT_Angle theta; + GD_FT_Int close1, close2; + + d1.x = base[1].x - base[2].x; + d1.y = base[1].y - base[2].y; + d2.x = base[0].x - base[1].x; + d2.y = base[0].y - base[1].y; + + close1 = GD_FT_IS_SMALL(d1.x) && GD_FT_IS_SMALL(d1.y); + close2 = GD_FT_IS_SMALL(d2.x) && GD_FT_IS_SMALL(d2.y); + + if (close1) { + if (close2) { + /* basically a point; */ + /* do nothing to retain original direction */ + } else { + *angle_in = *angle_out = GD_FT_Atan2(d2.x, d2.y); + } + } else /* !close1 */ + { + if (close2) { + *angle_in = *angle_out = GD_FT_Atan2(d1.x, d1.y); + } else { + *angle_in = GD_FT_Atan2(d1.x, d1.y); + *angle_out = GD_FT_Atan2(d2.x, d2.y); + } + } + + theta = ft_pos_abs(GD_FT_Angle_Diff(*angle_in, *angle_out)); + + return GD_FT_BOOL(theta < GD_FT_SMALL_CONIC_THRESHOLD); +} + +static void ft_cubic_split(GD_FT_Vector *base) +{ + GD_FT_Pos a, b, c; + + base[6].x = base[3].x; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c >> 1; + c += b; + base[4].x = c >> 2; + base[1].x = a >> 1; + a += b; + base[2].x = a >> 2; + base[3].x = (a + c) >> 3; + + base[6].y = base[3].y; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c >> 1; + c += b; + base[4].y = c >> 2; + base[1].y = a >> 1; + a += b; + base[2].y = a >> 2; + base[3].y = (a + c) >> 3; +} + +/* Return the average of `angle1' and `angle2'. */ +/* This gives correct result even if `angle1' and `angle2' */ +/* have opposite signs. */ +static GD_FT_Angle ft_angle_mean(GD_FT_Angle angle1, GD_FT_Angle angle2) +{ + return angle1 + GD_FT_Angle_Diff(angle1, angle2) / 2; +} + +static GD_FT_Bool ft_cubic_is_small_enough(GD_FT_Vector *base, GD_FT_Angle *angle_in, + GD_FT_Angle *angle_mid, GD_FT_Angle *angle_out) +{ + GD_FT_Vector d1, d2, d3; + GD_FT_Angle theta1, theta2; + GD_FT_Int close1, close2, close3; + + d1.x = base[2].x - base[3].x; + d1.y = base[2].y - base[3].y; + d2.x = base[1].x - base[2].x; + d2.y = base[1].y - base[2].y; + d3.x = base[0].x - base[1].x; + d3.y = base[0].y - base[1].y; + + close1 = GD_FT_IS_SMALL(d1.x) && GD_FT_IS_SMALL(d1.y); + close2 = GD_FT_IS_SMALL(d2.x) && GD_FT_IS_SMALL(d2.y); + close3 = GD_FT_IS_SMALL(d3.x) && GD_FT_IS_SMALL(d3.y); + + if (close1) { + if (close2) { + if (close3) { + /* basically a point; */ + /* do nothing to retain original direction */ + } else /* !close3 */ + { + *angle_in = *angle_mid = *angle_out = GD_FT_Atan2(d3.x, d3.y); + } + } else /* !close2 */ + { + if (close3) { + *angle_in = *angle_mid = *angle_out = GD_FT_Atan2(d2.x, d2.y); + } else /* !close3 */ + { + *angle_in = *angle_mid = GD_FT_Atan2(d2.x, d2.y); + *angle_out = GD_FT_Atan2(d3.x, d3.y); + } + } + } else /* !close1 */ + { + if (close2) { + if (close3) { + *angle_in = *angle_mid = *angle_out = GD_FT_Atan2(d1.x, d1.y); + } else /* !close3 */ + { + *angle_in = GD_FT_Atan2(d1.x, d1.y); + *angle_out = GD_FT_Atan2(d3.x, d3.y); + *angle_mid = ft_angle_mean(*angle_in, *angle_out); + } + } else /* !close2 */ + { + if (close3) { + *angle_in = GD_FT_Atan2(d1.x, d1.y); + *angle_mid = *angle_out = GD_FT_Atan2(d2.x, d2.y); + } else /* !close3 */ + { + *angle_in = GD_FT_Atan2(d1.x, d1.y); + *angle_mid = GD_FT_Atan2(d2.x, d2.y); + *angle_out = GD_FT_Atan2(d3.x, d3.y); + } + } + } + + theta1 = ft_pos_abs(GD_FT_Angle_Diff(*angle_in, *angle_mid)); + theta2 = ft_pos_abs(GD_FT_Angle_Diff(*angle_mid, *angle_out)); + + return GD_FT_BOOL(theta1 < GD_FT_SMALL_CUBIC_THRESHOLD && theta2 < GD_FT_SMALL_CUBIC_THRESHOLD); +} + +/*************************************************************************/ +/*************************************************************************/ +/***** *****/ +/***** STROKE BORDERS *****/ +/***** *****/ +/*************************************************************************/ +/*************************************************************************/ + +typedef enum GD_FT_StrokeTags_ { + GD_FT_STROKE_TAG_ON = 1, /* on-curve point */ + GD_FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ + GD_FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ + GD_FT_STROKE_TAG_END = 8 /* sub-path end */ + +} GD_FT_StrokeTags; + +#define GD_FT_STROKE_TAG_BEGIN_END (GD_FT_STROKE_TAG_BEGIN | GD_FT_STROKE_TAG_END) + +typedef struct GD_FT_StrokeBorderRec_ { + GD_FT_UInt num_points; + GD_FT_UInt max_points; + GD_FT_Vector *points; + GD_FT_Byte *tags; + GD_FT_Bool movable; /* TRUE for ends of lineto borders */ + GD_FT_Int start; /* index of current sub-path start point */ + GD_FT_Bool valid; + +} GD_FT_StrokeBorderRec, *GD_FT_StrokeBorder; + +GD_FT_Error GD_FT_Outline_Check(GD_FT_Outline *outline) +{ + if (outline) { + GD_FT_Int n_points = outline->n_points; + GD_FT_Int n_contours = outline->n_contours; + GD_FT_Int end0, end; + GD_FT_Int n; + + /* empty glyph? */ + if (n_points == 0 && n_contours == 0) + return 0; + + /* check point and contour counts */ + if (n_points <= 0 || n_contours <= 0) + goto Bad; + + end0 = end = -1; + for (n = 0; n < n_contours; n++) { + end = outline->contours[n]; + + /* note that we don't accept empty contours */ + if (end <= end0 || end >= n_points) + goto Bad; + + end0 = end; + } + + if (end != n_points - 1) + goto Bad; + + /* XXX: check the tags array */ + return 0; + } + +Bad: + return -1; // GD_FT_THROW( Invalid_Argument ); +} + +void GD_FT_Outline_Get_CBox(const GD_FT_Outline *outline, GD_FT_BBox *acbox) +{ + GD_FT_Pos xMin, yMin, xMax, yMax; + + if (outline && acbox) { + if (outline->n_points == 0) { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } else { + GD_FT_Vector *vec = outline->points; + GD_FT_Vector *limit = vec + outline->n_points; + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for (; vec < limit; vec++) { + GD_FT_Pos x, y; + + x = vec->x; + if (x < xMin) + xMin = x; + if (x > xMax) + xMax = x; + + y = vec->y; + if (y < yMin) + yMin = y; + if (y > yMax) + yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } +} + +static GD_FT_Error ft_stroke_border_grow(GD_FT_StrokeBorder border, GD_FT_UInt new_points) +{ + GD_FT_UInt old_max = border->max_points; + GD_FT_UInt new_max = border->num_points + new_points; + GD_FT_Error error = 0; + + if (new_max > old_max) { + GD_FT_UInt cur_max = old_max; + + while (cur_max < new_max) + cur_max += (cur_max >> 1) + 16; + + border->points = (GD_FT_Vector *)realloc(border->points, cur_max * sizeof(GD_FT_Vector)); + border->tags = (GD_FT_Byte *)realloc(border->tags, cur_max * sizeof(GD_FT_Byte)); + + if (!border->points || !border->tags) + goto Exit; + + border->max_points = cur_max; + } + +Exit: + return error; +} + +static void ft_stroke_border_close(GD_FT_StrokeBorder border, GD_FT_Bool reverse) +{ + GD_FT_UInt start = border->start; + GD_FT_UInt count = border->num_points; + + assert(border->start >= 0); + + /* don't record empty paths! */ + if (count <= start + 1U) + border->num_points = start; + else { + /* copy the last point to the start of this sub-path, since */ + /* it contains the `adjusted' starting coordinates */ + border->num_points = --count; + border->points[start] = border->points[count]; + + if (reverse) { + /* reverse the points */ + { + GD_FT_Vector *vec1 = border->points + start + 1; + GD_FT_Vector *vec2 = border->points + count - 1; + + for (; vec1 < vec2; vec1++, vec2--) { + GD_FT_Vector tmp; + + tmp = *vec1; + *vec1 = *vec2; + *vec2 = tmp; + } + } + + /* then the tags */ + { + GD_FT_Byte *tag1 = border->tags + start + 1; + GD_FT_Byte *tag2 = border->tags + count - 1; + + for (; tag1 < tag2; tag1++, tag2--) { + GD_FT_Byte tmp; + + tmp = *tag1; + *tag1 = *tag2; + *tag2 = tmp; + } + } + } + + border->tags[start] |= GD_FT_STROKE_TAG_BEGIN; + border->tags[count - 1] |= GD_FT_STROKE_TAG_END; + } + + border->start = -1; + border->movable = FALSE; +} + +static GD_FT_Error ft_stroke_border_lineto(GD_FT_StrokeBorder border, GD_FT_Vector *to, + GD_FT_Bool movable) +{ + GD_FT_Error error = 0; + + assert(border->start >= 0); + + if (border->movable) { + /* move last point */ + border->points[border->num_points - 1] = *to; + } else { + /* don't add zero-length lineto */ + if (border->num_points > 0 && + GD_FT_IS_SMALL(border->points[border->num_points - 1].x - to->x) && + GD_FT_IS_SMALL(border->points[border->num_points - 1].y - to->y)) + return error; + + /* add one point */ + error = ft_stroke_border_grow(border, 1); + if (!error) { + GD_FT_Vector *vec = border->points + border->num_points; + GD_FT_Byte *tag = border->tags + border->num_points; + + vec[0] = *to; + tag[0] = GD_FT_STROKE_TAG_ON; + + border->num_points += 1; + } + } + border->movable = movable; + return error; +} + +static GD_FT_Error ft_stroke_border_conicto(GD_FT_StrokeBorder border, GD_FT_Vector *control, + GD_FT_Vector *to) +{ + GD_FT_Error error; + + assert(border->start >= 0); + + error = ft_stroke_border_grow(border, 2); + if (!error) { + GD_FT_Vector *vec = border->points + border->num_points; + GD_FT_Byte *tag = border->tags + border->num_points; + + vec[0] = *control; + vec[1] = *to; + + tag[0] = 0; + tag[1] = GD_FT_STROKE_TAG_ON; + + border->num_points += 2; + } + + border->movable = FALSE; + + return error; +} + +static GD_FT_Error ft_stroke_border_cubicto(GD_FT_StrokeBorder border, GD_FT_Vector *control1, + GD_FT_Vector *control2, GD_FT_Vector *to) +{ + GD_FT_Error error; + + assert(border->start >= 0); + + error = ft_stroke_border_grow(border, 3); + if (!error) { + GD_FT_Vector *vec = border->points + border->num_points; + GD_FT_Byte *tag = border->tags + border->num_points; + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + + tag[0] = GD_FT_STROKE_TAG_CUBIC; + tag[1] = GD_FT_STROKE_TAG_CUBIC; + tag[2] = GD_FT_STROKE_TAG_ON; + + border->num_points += 3; + } + + border->movable = FALSE; + + return error; +} + +#define GD_FT_ARC_CUBIC_ANGLE (GD_FT_ANGLE_PI / 2) + +static GD_FT_Error ft_stroke_border_arcto(GD_FT_StrokeBorder border, GD_FT_Vector *center, + GD_FT_Fixed radius, GD_FT_Angle angle_start, + GD_FT_Angle angle_diff) +{ + GD_FT_Fixed coef; + GD_FT_Vector a0, a1, a2, a3; + GD_FT_Int i, arcs = 1; + GD_FT_Error error = 0; + + /* number of cubic arcs to draw */ + while (angle_diff > GD_FT_ARC_CUBIC_ANGLE * arcs || -angle_diff > GD_FT_ARC_CUBIC_ANGLE * arcs) + arcs++; + + /* control tangents */ + coef = GD_FT_Tan(angle_diff / (4 * arcs)); + coef += coef / 3; + + /* compute start and first control point */ + GD_FT_Vector_From_Polar(&a0, radius, angle_start); + a1.x = GD_FT_MulFix(-a0.y, coef); + a1.y = GD_FT_MulFix(a0.x, coef); + + a0.x += center->x; + a0.y += center->y; + a1.x += a0.x; + a1.y += a0.y; + + for (i = 1; i <= arcs; i++) { + /* compute end and second control point */ + GD_FT_Vector_From_Polar(&a3, radius, angle_start + i * angle_diff / arcs); + a2.x = GD_FT_MulFix(a3.y, coef); + a2.y = GD_FT_MulFix(-a3.x, coef); + + a3.x += center->x; + a3.y += center->y; + a2.x += a3.x; + a2.y += a3.y; + + /* add cubic arc */ + error = ft_stroke_border_cubicto(border, &a1, &a2, &a3); + if (error) + break; + + /* a0 = a3; */ + a1.x = a3.x - a2.x + a3.x; + a1.y = a3.y - a2.y + a3.y; + } + + return error; +} + +static GD_FT_Error ft_stroke_border_moveto(GD_FT_StrokeBorder border, GD_FT_Vector *to) +{ + /* close current open path if any ? */ + if (border->start >= 0) + ft_stroke_border_close(border, FALSE); + + border->start = border->num_points; + border->movable = FALSE; + + return ft_stroke_border_lineto(border, to, FALSE); +} + +static void ft_stroke_border_init(GD_FT_StrokeBorder border) +{ + border->points = NULL; + border->tags = NULL; + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; +} + +static void ft_stroke_border_reset(GD_FT_StrokeBorder border) +{ + border->num_points = 0; + border->start = -1; + border->valid = FALSE; +} + +static void ft_stroke_border_done(GD_FT_StrokeBorder border) +{ + free(border->points); + free(border->tags); + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; +} + +static GD_FT_Error ft_stroke_border_get_counts(GD_FT_StrokeBorder border, GD_FT_UInt *anum_points, + GD_FT_UInt *anum_contours) +{ + GD_FT_Error error = 0; + GD_FT_UInt num_points = 0; + GD_FT_UInt num_contours = 0; + + GD_FT_UInt count = border->num_points; + GD_FT_Vector *point = border->points; + GD_FT_Byte *tags = border->tags; + GD_FT_Int in_contour = 0; + + for (; count > 0; count--, num_points++, point++, tags++) { + if (tags[0] & GD_FT_STROKE_TAG_BEGIN) { + if (in_contour != 0) + goto Fail; + + in_contour = 1; + } else if (in_contour == 0) + goto Fail; + + if (tags[0] & GD_FT_STROKE_TAG_END) { + in_contour = 0; + num_contours++; + } + } + + if (in_contour != 0) + goto Fail; + + border->valid = TRUE; + +Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + +Fail: + num_points = 0; + num_contours = 0; + goto Exit; +} + +static void ft_stroke_border_export(GD_FT_StrokeBorder border, GD_FT_Outline *outline) +{ + /* copy point locations */ + memcpy(outline->points + outline->n_points, border->points, + border->num_points * sizeof(GD_FT_Vector)); + + /* copy tags */ + { + GD_FT_UInt count = border->num_points; + GD_FT_Byte *read = border->tags; + GD_FT_Byte *write = (GD_FT_Byte *)outline->tags + outline->n_points; + + for (; count > 0; count--, read++, write++) { + if (*read & GD_FT_STROKE_TAG_ON) + *write = GD_FT_CURVE_TAG_ON; + else if (*read & GD_FT_STROKE_TAG_CUBIC) + *write = GD_FT_CURVE_TAG_CUBIC; + else + *write = GD_FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + GD_FT_UInt count = border->num_points; + GD_FT_Byte *tags = border->tags; + GD_FT_Short *write = outline->contours + outline->n_contours; + GD_FT_Short idx = (GD_FT_Short)outline->n_points; + + for (; count > 0; count--, tags++, idx++) { + if (*tags & GD_FT_STROKE_TAG_END) { + *write++ = idx; + outline->n_contours++; + } + } + } + + outline->n_points = (short)(outline->n_points + border->num_points); + + assert(GD_FT_Outline_Check(outline) == 0); +} + +/*************************************************************************/ +/*************************************************************************/ +/***** *****/ +/***** STROKER *****/ +/***** *****/ +/*************************************************************************/ +/*************************************************************************/ + +#define GD_FT_SIDE_TO_ROTATE(s) (GD_FT_ANGLE_PI2 - (s) * GD_FT_ANGLE_PI) + +typedef struct GD_FT_StrokerRec_ { + GD_FT_Angle angle_in; /* direction into curr join */ + GD_FT_Angle angle_out; /* direction out of join */ + GD_FT_Vector center; /* current position */ + GD_FT_Fixed line_length; /* length of last lineto */ + GD_FT_Bool first_point; /* is this the start? */ + GD_FT_Bool subpath_open; /* is the subpath open? */ + GD_FT_Angle subpath_angle; /* subpath start direction */ + GD_FT_Vector subpath_start; /* subpath start position */ + GD_FT_Fixed subpath_line_length; /* subpath start lineto len */ + GD_FT_Bool handle_wide_strokes; /* use wide strokes logic? */ + + GD_FT_Stroker_LineCap line_cap; + GD_FT_Stroker_LineJoin line_join; + GD_FT_Stroker_LineJoin line_join_saved; + GD_FT_Fixed miter_limit; + GD_FT_Fixed radius; + + GD_FT_StrokeBorderRec borders[2]; +} GD_FT_StrokerRec; + +/* documentation is in ftstroke.h */ +GD_FT_Error GD_FT_Stroker_New(GD_FT_Stroker *astroker) +{ + GD_FT_Error error = 0; /* assigned in SW_FT_NEW */ + GD_FT_Stroker stroker = NULL; + + stroker = (GD_FT_StrokerRec *)calloc(1, sizeof(GD_FT_StrokerRec)); + if (stroker) { + ft_stroke_border_init(&stroker->borders[0]); + ft_stroke_border_init(&stroker->borders[1]); + } + + *astroker = stroker; + + return error; +} + +void GD_FT_Stroker_Rewind(GD_FT_Stroker stroker) +{ + if (stroker) { + ft_stroke_border_reset(&stroker->borders[0]); + ft_stroke_border_reset(&stroker->borders[1]); + } +} + +/* documentation is in ftstroke.h */ + +void GD_FT_Stroker_Set(GD_FT_Stroker stroker, GD_FT_Fixed radius, GD_FT_Stroker_LineCap line_cap, + GD_FT_Stroker_LineJoin line_join, GD_FT_Fixed miter_limit) +{ + stroker->radius = radius; + stroker->line_cap = line_cap; + stroker->line_join = line_join; + stroker->miter_limit = miter_limit; + + /* ensure miter limit has sensible value */ + if (stroker->miter_limit < 0x10000) + stroker->miter_limit = 0x10000; + + /* save line join style: */ + /* line join style can be temporarily changed when stroking curves */ + stroker->line_join_saved = line_join; + + GD_FT_Stroker_Rewind(stroker); +} + +/* documentation is in ftstroke.h */ + +void GD_FT_Stroker_Done(GD_FT_Stroker stroker) +{ + if (stroker) { + ft_stroke_border_done(&stroker->borders[0]); + ft_stroke_border_done(&stroker->borders[1]); + + free(stroker); + } +} + +/* create a circular arc at a corner or cap */ +static GD_FT_Error ft_stroker_arcto(GD_FT_Stroker stroker, GD_FT_Int side) +{ + GD_FT_Angle total, rotate; + GD_FT_Fixed radius = stroker->radius; + GD_FT_Error error = 0; + GD_FT_StrokeBorder border = stroker->borders + side; + + rotate = GD_FT_SIDE_TO_ROTATE(side); + + total = GD_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); + if (total == GD_FT_ANGLE_PI) + total = -rotate * 2; + + error = + ft_stroke_border_arcto(border, &stroker->center, radius, stroker->angle_in + rotate, total); + border->movable = FALSE; + return error; +} + +/* add a cap at the end of an opened path */ +static GD_FT_Error ft_stroker_cap(GD_FT_Stroker stroker, GD_FT_Angle angle, GD_FT_Int side) +{ + GD_FT_Error error = 0; + + if (stroker->line_cap == GD_FT_STROKER_LINECAP_ROUND) { + /* add a round cap */ + stroker->angle_in = angle; + stroker->angle_out = angle + GD_FT_ANGLE_PI; + + error = ft_stroker_arcto(stroker, side); + } else { + /* add a square or butt cap */ + GD_FT_Vector middle, delta; + GD_FT_Fixed radius = stroker->radius; + GD_FT_StrokeBorder border = stroker->borders + side; + + /* compute middle point and first angle point */ + GD_FT_Vector_From_Polar(&middle, radius, angle); + delta.x = side ? middle.y : -middle.y; + delta.y = side ? -middle.x : middle.x; + + if (stroker->line_cap == GD_FT_STROKER_LINECAP_SQUARE) { + middle.x += stroker->center.x; + middle.y += stroker->center.y; + } else /* GD_FT_STROKER_LINECAP_BUTT */ + { + middle.x = stroker->center.x; + middle.y = stroker->center.y; + } + + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + + /* compute second angle point */ + delta.x = middle.x - delta.x + middle.x; + delta.y = middle.y - delta.y + middle.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + } + +Exit: + return error; +} + +/* process an inside corner, i.e. compute intersection */ +static GD_FT_Error ft_stroker_inside(GD_FT_Stroker stroker, GD_FT_Int side, GD_FT_Fixed line_length) +{ + GD_FT_StrokeBorder border = stroker->borders + side; + GD_FT_Angle phi, theta, rotate; + GD_FT_Fixed length; + GD_FT_Vector sigma, delta; + GD_FT_Error error = 0; + GD_FT_Bool intersect; /* use intersection of lines? */ + + rotate = GD_FT_SIDE_TO_ROTATE(side); + + theta = GD_FT_Angle_Diff(stroker->angle_in, stroker->angle_out) / 2; + + /* Only intersect borders if between two lineto's and both */ + /* lines are long enough (line_length is zero for curves). */ + if (!border->movable || line_length == 0 || theta > 0x59C000 || theta < -0x59C000) + intersect = FALSE; + else { + /* compute minimum required length of lines */ + GD_FT_Fixed min_length; + + GD_FT_Vector_Unit(&sigma, theta); + min_length = ft_pos_abs(GD_FT_MulDiv(stroker->radius, sigma.y, sigma.x)); + + intersect = GD_FT_BOOL(min_length && stroker->line_length >= min_length && + line_length >= min_length); + } + + if (!intersect) { + GD_FT_Vector_From_Polar(&delta, stroker->radius, stroker->angle_out + rotate); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + border->movable = FALSE; + } else { + /* compute median angle */ + phi = stroker->angle_in + theta + rotate; + + length = GD_FT_DivFix(stroker->radius, sigma.x); + + GD_FT_Vector_From_Polar(&delta, length, phi); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + } + + error = ft_stroke_border_lineto(border, &delta, FALSE); + + return error; +} + +/* process an outside corner, i.e. compute bevel/miter/round */ +static GD_FT_Error ft_stroker_outside(GD_FT_Stroker stroker, GD_FT_Int side, + GD_FT_Fixed line_length) +{ + GD_FT_StrokeBorder border = stroker->borders + side; + GD_FT_Error error; + GD_FT_Angle rotate; + + if (stroker->line_join == GD_FT_STROKER_LINEJOIN_ROUND) + error = ft_stroker_arcto(stroker, side); + else { + /* this is a mitered (pointed) or beveled (truncated) corner */ + GD_FT_Fixed radius = stroker->radius; + GD_FT_Vector sigma; + GD_FT_Angle theta = 0, phi = 0; + GD_FT_Bool bevel, fixed_bevel; + + rotate = GD_FT_SIDE_TO_ROTATE(side); + + bevel = GD_FT_BOOL(stroker->line_join == GD_FT_STROKER_LINEJOIN_BEVEL); + + fixed_bevel = GD_FT_BOOL(stroker->line_join != GD_FT_STROKER_LINEJOIN_MITER_VARIABLE); + + /* check miter limit first */ + if (!bevel) { + theta = GD_FT_Angle_Diff(stroker->angle_in, stroker->angle_out) / 2; + + if (theta == GD_FT_ANGLE_PI2) + theta = -rotate; + + phi = stroker->angle_in + theta + rotate; + + GD_FT_Vector_From_Polar(&sigma, stroker->miter_limit, theta); + + /* is miter limit exceeded? */ + if (sigma.x < 0x10000L) { + /* don't create variable bevels for very small deviations; */ + /* FT_Sin(x) = 0 for x <= 57 */ + if (fixed_bevel || ft_pos_abs(theta) > 57) + bevel = TRUE; + } + } + + if (bevel) /* this is a bevel (broken angle) */ + { + if (fixed_bevel) { + /* the outer corners are simply joined together */ + GD_FT_Vector delta; + + /* add bevel */ + GD_FT_Vector_From_Polar(&delta, radius, stroker->angle_out + rotate); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + border->movable = FALSE; + error = ft_stroke_border_lineto(border, &delta, FALSE); + } else /* variable bevel or clipped miter */ + { + /* the miter is truncated */ + GD_FT_Vector middle, delta; + GD_FT_Fixed coef; + + /* compute middle point and first angle point */ + GD_FT_Vector_From_Polar(&middle, GD_FT_MulFix(radius, stroker->miter_limit), phi); + + coef = GD_FT_DivFix(0x10000L - sigma.x, sigma.y); + delta.x = GD_FT_MulFix(middle.y, coef); + delta.y = GD_FT_MulFix(-middle.x, coef); + + middle.x += stroker->center.x; + middle.y += stroker->center.y; + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + + /* compute second angle point */ + delta.x = middle.x - delta.x + middle.x; + delta.y = middle.y - delta.y + middle.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + + /* finally, add an end point; only needed if not lineto */ + /* (line_length is zero for curves) */ + if (line_length == 0) { + GD_FT_Vector_From_Polar(&delta, radius, stroker->angle_out + rotate); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + } + } + } else /* this is a miter (intersection) */ + { + GD_FT_Fixed length; + GD_FT_Vector delta; + + length = GD_FT_MulDiv(stroker->radius, stroker->miter_limit, sigma.x); + + GD_FT_Vector_From_Polar(&delta, length, phi); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + + /* now add an end point; only needed if not lineto */ + /* (line_length is zero for curves) */ + if (line_length == 0) { + GD_FT_Vector_From_Polar(&delta, stroker->radius, stroker->angle_out + rotate); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto(border, &delta, FALSE); + } + } + } + +Exit: + return error; +} + +static GD_FT_Error ft_stroker_process_corner(GD_FT_Stroker stroker, GD_FT_Fixed line_length) +{ + GD_FT_Error error = 0; + GD_FT_Angle turn; + GD_FT_Int inside_side; + + turn = GD_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); + + /* no specific corner processing is required if the turn is 0 */ + if (turn == 0) + goto Exit; + + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if (turn < 0) + inside_side = 1; + + /* process the inside side */ + error = ft_stroker_inside(stroker, inside_side, line_length); + if (error) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside(stroker, 1 - inside_side, line_length); + +Exit: + return error; +} + +/* add two points to the left and right borders corresponding to the */ +/* start of the subpath */ +static GD_FT_Error ft_stroker_subpath_start(GD_FT_Stroker stroker, GD_FT_Angle start_angle, + GD_FT_Fixed line_length) +{ + GD_FT_Vector delta; + GD_FT_Vector point; + GD_FT_Error error; + GD_FT_StrokeBorder border; + + GD_FT_Vector_From_Polar(&delta, stroker->radius, start_angle + GD_FT_ANGLE_PI2); + + point.x = stroker->center.x + delta.x; + point.y = stroker->center.y + delta.y; + + border = stroker->borders; + error = ft_stroke_border_moveto(border, &point); + if (error) + goto Exit; + + point.x = stroker->center.x - delta.x; + point.y = stroker->center.y - delta.y; + + border++; + error = ft_stroke_border_moveto(border, &point); + + /* save angle, position, and line length for last join */ + /* (line_length is zero for curves) */ + stroker->subpath_angle = start_angle; + stroker->first_point = FALSE; + stroker->subpath_line_length = line_length; + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_LineTo(GD_FT_Stroker stroker, GD_FT_Vector *to) +{ + GD_FT_Error error = 0; + GD_FT_StrokeBorder border; + GD_FT_Vector delta; + GD_FT_Angle angle; + GD_FT_Int side; + GD_FT_Fixed line_length; + + delta.x = to->x - stroker->center.x; + delta.y = to->y - stroker->center.y; + + /* a zero-length lineto is a no-op; avoid creating a spurious corner */ + if (delta.x == 0 && delta.y == 0) + goto Exit; + + /* compute length of line */ + line_length = GD_FT_Vector_Length(&delta); + + angle = GD_FT_Atan2(delta.x, delta.y); + GD_FT_Vector_From_Polar(&delta, stroker->radius, angle + GD_FT_ANGLE_PI2); + + /* process corner if necessary */ + if (stroker->first_point) { + /* This is the first segment of a subpath. We need to */ + /* add a point to each border at their respective starting */ + /* point locations. */ + error = ft_stroker_subpath_start(stroker, angle, line_length); + if (error) + goto Exit; + } else { + /* process the current corner */ + stroker->angle_out = angle; + error = ft_stroker_process_corner(stroker, line_length); + if (error) + goto Exit; + } + + /* now add a line segment to both the `inside' and `outside' paths */ + for (border = stroker->borders, side = 1; side >= 0; side--, border++) { + GD_FT_Vector point; + + point.x = to->x + delta.x; + point.y = to->y + delta.y; + + /* the ends of lineto borders are movable */ + error = ft_stroke_border_lineto(border, &point, TRUE); + if (error) + goto Exit; + + delta.x = -delta.x; + delta.y = -delta.y; + } + + stroker->angle_in = angle; + stroker->center = *to; + stroker->line_length = line_length; + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_ConicTo(GD_FT_Stroker stroker, GD_FT_Vector *control, GD_FT_Vector *to) +{ + GD_FT_Error error = 0; + GD_FT_Vector bez_stack[34]; + GD_FT_Vector *arc; + GD_FT_Vector *limit = bez_stack + 30; + GD_FT_Bool first_arc = TRUE; + + /* if all control points are coincident, this is a no-op; */ + /* avoid creating a spurious corner */ + if (GD_FT_IS_SMALL(stroker->center.x - control->x) && + GD_FT_IS_SMALL(stroker->center.y - control->y) && GD_FT_IS_SMALL(control->x - to->x) && + GD_FT_IS_SMALL(control->y - to->y)) { + stroker->center = *to; + goto Exit; + } + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control; + arc[2] = stroker->center; + + while (arc >= bez_stack) { + GD_FT_Angle angle_in, angle_out; + + /* initialize with current direction */ + angle_in = angle_out = stroker->angle_in; + + if (arc < limit && !ft_conic_is_small_enough(arc, &angle_in, &angle_out)) { + if (stroker->first_point) + stroker->angle_in = angle_in; + + ft_conic_split(arc); + arc += 2; + continue; + } + + if (first_arc) { + first_arc = FALSE; + + /* process corner if necessary */ + if (stroker->first_point) + error = ft_stroker_subpath_start(stroker, angle_in, 0); + else { + stroker->angle_out = angle_in; + error = ft_stroker_process_corner(stroker, 0); + } + } else if (ft_pos_abs(GD_FT_Angle_Diff(stroker->angle_in, angle_in)) > + GD_FT_SMALL_CONIC_THRESHOLD / 4) { + /* if the deviation from one arc to the next is too great, */ + /* add a round corner */ + stroker->center = arc[2]; + stroker->angle_out = angle_in; + stroker->line_join = GD_FT_STROKER_LINEJOIN_ROUND; + + error = ft_stroker_process_corner(stroker, 0); + + /* reinstate line join style */ + stroker->line_join = stroker->line_join_saved; + } + + if (error) + goto Exit; + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + GD_FT_Vector ctrl, end; + GD_FT_Angle theta, phi, rotate, alpha0 = 0; + GD_FT_Fixed length; + GD_FT_StrokeBorder border; + GD_FT_Int side; + + theta = GD_FT_Angle_Diff(angle_in, angle_out) / 2; + phi = angle_in + theta; + length = GD_FT_DivFix(stroker->radius, GD_FT_Cos(theta)); + + /* compute direction of original arc */ + if (stroker->handle_wide_strokes) + alpha0 = GD_FT_Atan2(arc[0].x - arc[2].x, arc[0].y - arc[2].y); + + for (border = stroker->borders, side = 0; side <= 1; side++, border++) { + rotate = GD_FT_SIDE_TO_ROTATE(side); + + /* compute control point */ + GD_FT_Vector_From_Polar(&ctrl, length, phi + rotate); + ctrl.x += arc[1].x; + ctrl.y += arc[1].y; + + /* compute end point */ + GD_FT_Vector_From_Polar(&end, stroker->radius, angle_out + rotate); + end.x += arc[0].x; + end.y += arc[0].y; + + if (stroker->handle_wide_strokes) { + GD_FT_Vector start; + GD_FT_Angle alpha1; + + /* determine whether the border radius is greater than the + */ + /* radius of curvature of the original arc */ + start = border->points[border->num_points - 1]; + + alpha1 = GD_FT_Atan2(end.x - start.x, end.y - start.y); + + /* is the direction of the border arc opposite to */ + /* that of the original arc? */ + if (ft_pos_abs(GD_FT_Angle_Diff(alpha0, alpha1)) > GD_FT_ANGLE_PI / 2) { + GD_FT_Angle beta, gamma; + GD_FT_Vector bvec, delta; + GD_FT_Fixed blen, sinA, sinB, alen; + + /* use the sine rule to find the intersection point */ + beta = GD_FT_Atan2(arc[2].x - start.x, arc[2].y - start.y); + gamma = GD_FT_Atan2(arc[0].x - end.x, arc[0].y - end.y); + + bvec.x = end.x - start.x; + bvec.y = end.y - start.y; + + blen = GD_FT_Vector_Length(&bvec); + + sinA = ft_pos_abs(GD_FT_Sin(alpha1 - gamma)); + sinB = ft_pos_abs(GD_FT_Sin(beta - gamma)); + + alen = GD_FT_MulDiv(blen, sinA, sinB); + + GD_FT_Vector_From_Polar(&delta, alen, beta); + delta.x += start.x; + delta.y += start.y; + + /* circumnavigate the negative sector backwards */ + border->movable = FALSE; + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + error = ft_stroke_border_lineto(border, &end, FALSE); + if (error) + goto Exit; + error = ft_stroke_border_conicto(border, &ctrl, &start); + if (error) + goto Exit; + /* and then move to the endpoint */ + error = ft_stroke_border_lineto(border, &end, FALSE); + if (error) + goto Exit; + + continue; + } + + /* else fall through */ + } + + /* simply add an arc */ + error = ft_stroke_border_conicto(border, &ctrl, &end); + if (error) + goto Exit; + } + } + + arc -= 2; + + stroker->angle_in = angle_out; + } + + stroker->center = *to; + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_CubicTo(GD_FT_Stroker stroker, GD_FT_Vector *control1, + GD_FT_Vector *control2, GD_FT_Vector *to) +{ + GD_FT_Error error = 0; + GD_FT_Vector bez_stack[37]; + GD_FT_Vector *arc; + GD_FT_Vector *limit = bez_stack + 32; + GD_FT_Bool first_arc = TRUE; + + /* if all control points are coincident, this is a no-op; */ + /* avoid creating a spurious corner */ + if (GD_FT_IS_SMALL(stroker->center.x - control1->x) && + GD_FT_IS_SMALL(stroker->center.y - control1->y) && + GD_FT_IS_SMALL(control1->x - control2->x) && GD_FT_IS_SMALL(control1->y - control2->y) && + GD_FT_IS_SMALL(control2->x - to->x) && GD_FT_IS_SMALL(control2->y - to->y)) { + stroker->center = *to; + goto Exit; + } + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control2; + arc[2] = *control1; + arc[3] = stroker->center; + + while (arc >= bez_stack) { + GD_FT_Angle angle_in, angle_mid, angle_out; + + /* initialize with current direction */ + angle_in = angle_out = angle_mid = stroker->angle_in; + + if (arc < limit && !ft_cubic_is_small_enough(arc, &angle_in, &angle_mid, &angle_out)) { + if (stroker->first_point) + stroker->angle_in = angle_in; + + ft_cubic_split(arc); + arc += 3; + continue; + } + + if (first_arc) { + first_arc = FALSE; + + /* process corner if necessary */ + if (stroker->first_point) + error = ft_stroker_subpath_start(stroker, angle_in, 0); + else { + stroker->angle_out = angle_in; + error = ft_stroker_process_corner(stroker, 0); + } + } else if (ft_pos_abs(GD_FT_Angle_Diff(stroker->angle_in, angle_in)) > + GD_FT_SMALL_CUBIC_THRESHOLD / 4) { + /* if the deviation from one arc to the next is too great, */ + /* add a round corner */ + stroker->center = arc[3]; + stroker->angle_out = angle_in; + stroker->line_join = GD_FT_STROKER_LINEJOIN_ROUND; + + error = ft_stroker_process_corner(stroker, 0); + + /* reinstate line join style */ + stroker->line_join = stroker->line_join_saved; + } + + if (error) + goto Exit; + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + GD_FT_Vector ctrl1, ctrl2, end; + GD_FT_Angle theta1, phi1, theta2, phi2, rotate, alpha0 = 0; + GD_FT_Fixed length1, length2; + GD_FT_StrokeBorder border; + GD_FT_Int side; + + theta1 = GD_FT_Angle_Diff(angle_in, angle_mid) / 2; + theta2 = GD_FT_Angle_Diff(angle_mid, angle_out) / 2; + phi1 = ft_angle_mean(angle_in, angle_mid); + phi2 = ft_angle_mean(angle_mid, angle_out); + length1 = GD_FT_DivFix(stroker->radius, GD_FT_Cos(theta1)); + length2 = GD_FT_DivFix(stroker->radius, GD_FT_Cos(theta2)); + + /* compute direction of original arc */ + if (stroker->handle_wide_strokes) + alpha0 = GD_FT_Atan2(arc[0].x - arc[3].x, arc[0].y - arc[3].y); + + for (border = stroker->borders, side = 0; side <= 1; side++, border++) { + rotate = GD_FT_SIDE_TO_ROTATE(side); + + /* compute control points */ + GD_FT_Vector_From_Polar(&ctrl1, length1, phi1 + rotate); + ctrl1.x += arc[2].x; + ctrl1.y += arc[2].y; + + GD_FT_Vector_From_Polar(&ctrl2, length2, phi2 + rotate); + ctrl2.x += arc[1].x; + ctrl2.y += arc[1].y; + + /* compute end point */ + GD_FT_Vector_From_Polar(&end, stroker->radius, angle_out + rotate); + end.x += arc[0].x; + end.y += arc[0].y; + + if (stroker->handle_wide_strokes) { + GD_FT_Vector start; + GD_FT_Angle alpha1; + + /* determine whether the border radius is greater than the + */ + /* radius of curvature of the original arc */ + start = border->points[border->num_points - 1]; + + alpha1 = GD_FT_Atan2(end.x - start.x, end.y - start.y); + + /* is the direction of the border arc opposite to */ + /* that of the original arc? */ + if (ft_pos_abs(GD_FT_Angle_Diff(alpha0, alpha1)) > GD_FT_ANGLE_PI / 2) { + GD_FT_Angle beta, gamma; + GD_FT_Vector bvec, delta; + GD_FT_Fixed blen, sinA, sinB, alen; + + /* use the sine rule to find the intersection point */ + beta = GD_FT_Atan2(arc[3].x - start.x, arc[3].y - start.y); + gamma = GD_FT_Atan2(arc[0].x - end.x, arc[0].y - end.y); + + bvec.x = end.x - start.x; + bvec.y = end.y - start.y; + + blen = GD_FT_Vector_Length(&bvec); + + sinA = ft_pos_abs(GD_FT_Sin(alpha1 - gamma)); + sinB = ft_pos_abs(GD_FT_Sin(beta - gamma)); + + alen = GD_FT_MulDiv(blen, sinA, sinB); + + GD_FT_Vector_From_Polar(&delta, alen, beta); + delta.x += start.x; + delta.y += start.y; + + /* circumnavigate the negative sector backwards */ + border->movable = FALSE; + error = ft_stroke_border_lineto(border, &delta, FALSE); + if (error) + goto Exit; + error = ft_stroke_border_lineto(border, &end, FALSE); + if (error) + goto Exit; + error = ft_stroke_border_cubicto(border, &ctrl2, &ctrl1, &start); + if (error) + goto Exit; + /* and then move to the endpoint */ + error = ft_stroke_border_lineto(border, &end, FALSE); + if (error) + goto Exit; + + continue; + } + + /* else fall through */ + } + + /* simply add an arc */ + error = ft_stroke_border_cubicto(border, &ctrl1, &ctrl2, &end); + if (error) + goto Exit; + } + } + + arc -= 3; + + stroker->angle_in = angle_out; + } + + stroker->center = *to; + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_BeginSubPath(GD_FT_Stroker stroker, GD_FT_Vector *to, GD_FT_Bool open) +{ + /* We cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the `GD_FT_Stroker_EndSubPath' routine. */ + /* */ + stroker->first_point = TRUE; + stroker->center = *to; + stroker->subpath_open = open; + + /* Determine if we need to check whether the border radius is greater */ + /* than the radius of curvature of a curve, to handle this case */ + /* specially. This is only required if bevel joins or butt caps may */ + /* be created, because round & miter joins and round & square caps */ + /* cover the negative sector created with wide strokes. */ + stroker->handle_wide_strokes = + GD_FT_BOOL(stroker->line_join != GD_FT_STROKER_LINEJOIN_ROUND || + (stroker->subpath_open && stroker->line_cap == GD_FT_STROKER_LINECAP_BUTT)); + + /* record the subpath start point for each border */ + stroker->subpath_start = *to; + + stroker->angle_in = 0; + + return 0; +} + +static GD_FT_Error ft_stroker_add_reverse_left(GD_FT_Stroker stroker, GD_FT_Bool open) +{ + GD_FT_StrokeBorder right = stroker->borders + 0; + GD_FT_StrokeBorder left = stroker->borders + 1; + GD_FT_Int new_points; + GD_FT_Error error = 0; + + assert(left->start >= 0); + + new_points = left->num_points - left->start; + if (new_points > 0) { + error = ft_stroke_border_grow(right, (GD_FT_UInt)new_points); + if (error) + goto Exit; + + { + GD_FT_Vector *dst_point = right->points + right->num_points; + GD_FT_Byte *dst_tag = right->tags + right->num_points; + GD_FT_Vector *src_point = left->points + left->num_points - 1; + GD_FT_Byte *src_tag = left->tags + left->num_points - 1; + + while (src_point >= left->points + left->start) { + *dst_point = *src_point; + *dst_tag = *src_tag; + + if (open) + dst_tag[0] &= ~GD_FT_STROKE_TAG_BEGIN_END; + else { + GD_FT_Byte ttag = (GD_FT_Byte)(dst_tag[0] & GD_FT_STROKE_TAG_BEGIN_END); + + /* switch begin/end tags if necessary */ + if (ttag == GD_FT_STROKE_TAG_BEGIN || ttag == GD_FT_STROKE_TAG_END) + dst_tag[0] ^= GD_FT_STROKE_TAG_BEGIN_END; + } + + src_point--; + src_tag--; + dst_point++; + dst_tag++; + } + } + + left->num_points = left->start; + right->num_points += new_points; + + right->movable = FALSE; + left->movable = FALSE; + } + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +/* there's a lot of magic in this function! */ +GD_FT_Error GD_FT_Stroker_EndSubPath(GD_FT_Stroker stroker) +{ + GD_FT_Error error = 0; + + if (stroker->subpath_open) { + GD_FT_StrokeBorder right = stroker->borders; + + /* All right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap */ + /* between left & right. */ + error = ft_stroker_cap(stroker, stroker->angle_in, 0); + if (error) + goto Exit; + + /* add reversed points from `left' to `right' */ + error = ft_stroker_add_reverse_left(stroker, TRUE); + if (error) + goto Exit; + + /* now add the final cap */ + stroker->center = stroker->subpath_start; + error = ft_stroker_cap(stroker, stroker->subpath_angle + GD_FT_ANGLE_PI, 0); + if (error) + goto Exit; + + /* Now end the right subpath accordingly. The left one is */ + /* rewind and doesn't need further processing. */ + ft_stroke_border_close(right, FALSE); + } else { + GD_FT_Angle turn; + GD_FT_Int inside_side; + + /* close the path if needed */ + if (stroker->center.x != stroker->subpath_start.x || + stroker->center.y != stroker->subpath_start.y) { + error = GD_FT_Stroker_LineTo(stroker, &stroker->subpath_start); + if (error) + goto Exit; + } + + /* process the corner */ + stroker->angle_out = stroker->subpath_angle; + turn = GD_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); + + /* no specific corner processing is required if the turn is 0 */ + if (turn != 0) { + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if (turn < 0) + inside_side = 1; + + error = ft_stroker_inside(stroker, inside_side, stroker->subpath_line_length); + if (error) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside(stroker, 1 - inside_side, stroker->subpath_line_length); + if (error) + goto Exit; + } + + /* then end our two subpaths */ + ft_stroke_border_close(stroker->borders + 0, FALSE); + ft_stroke_border_close(stroker->borders + 1, TRUE); + } + +Exit: + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_GetBorderCounts(GD_FT_Stroker stroker, GD_FT_StrokerBorder border, + GD_FT_UInt *anum_points, GD_FT_UInt *anum_contours) +{ + GD_FT_UInt num_points = 0, num_contours = 0; + GD_FT_Error error; + + if (!stroker || border > 1) { + error = -1; // GD_FT_THROW( Invalid_Argument ); + goto Exit; + } + + error = ft_stroke_border_get_counts(stroker->borders + border, &num_points, &num_contours); +Exit: + if (anum_points) + *anum_points = num_points; + + if (anum_contours) + *anum_contours = num_contours; + + return error; +} + +/* documentation is in ftstroke.h */ + +GD_FT_Error GD_FT_Stroker_GetCounts(GD_FT_Stroker stroker, GD_FT_UInt *anum_points, + GD_FT_UInt *anum_contours) +{ + GD_FT_UInt count1, count2, num_points = 0; + GD_FT_UInt count3, count4, num_contours = 0; + GD_FT_Error error; + + error = ft_stroke_border_get_counts(stroker->borders + 0, &count1, &count2); + if (error) + goto Exit; + + error = ft_stroke_border_get_counts(stroker->borders + 1, &count3, &count4); + if (error) + goto Exit; + + num_points = count1 + count3; + num_contours = count2 + count4; + +Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; +} + +/* documentation is in ftstroke.h */ + +void GD_FT_Stroker_ExportBorder(GD_FT_Stroker stroker, GD_FT_StrokerBorder border, + GD_FT_Outline *outline) +{ + if (border == GD_FT_STROKER_BORDER_LEFT || border == GD_FT_STROKER_BORDER_RIGHT) { + GD_FT_StrokeBorder sborder = &stroker->borders[border]; + + if (sborder->valid) + ft_stroke_border_export(sborder, outline); + } +} + +/* documentation is in ftstroke.h */ + +void GD_FT_Stroker_Export(GD_FT_Stroker stroker, GD_FT_Outline *outline) +{ + GD_FT_Stroker_ExportBorder(stroker, GD_FT_STROKER_BORDER_LEFT, outline); + GD_FT_Stroker_ExportBorder(stroker, GD_FT_STROKER_BORDER_RIGHT, outline); +} + +/* documentation is in ftstroke.h */ + +/* + * The following is very similar to GD_FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. + */ +GD_FT_Error GD_FT_Stroker_ParseOutline(GD_FT_Stroker stroker, const GD_FT_Outline *outline) +{ + GD_FT_Vector v_last; + GD_FT_Vector v_control; + GD_FT_Vector v_start; + + GD_FT_Vector *point; + GD_FT_Vector *limit; + char *tags; + + GD_FT_Error error; + + GD_FT_Int n; /* index of contour in outline */ + GD_FT_UInt first; /* index of first point in contour */ + GD_FT_Int tag; /* current point's state */ + + if (!outline || !stroker) + return -1; // GD_FT_THROW( Invalid_Argument ); + + GD_FT_Stroker_Rewind(stroker); + + first = 0; + + for (n = 0; n < outline->n_contours; n++) { + GD_FT_UInt last; /* index of last point in contour */ + + last = outline->contours[n]; + limit = outline->points + last; + + /* skip empty points; we don't stroke these */ + if (last <= first) { + first = last + 1; + continue; + } + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = GD_FT_CURVE_TAG(tags[0]); + + /* A contour cannot start with a cubic control point! */ + if (tag == GD_FT_CURVE_TAG_CUBIC) + goto Invalid_Outline; + + /* check first point to determine origin */ + if (tag == GD_FT_CURVE_TAG_CONIC) { + /* First point is conic control. Yes, this happens. */ + if (GD_FT_CURVE_TAG(outline->tags[last]) == GD_FT_CURVE_TAG_ON) { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } else { + /* if both first and last points are conic, */ + /* start at their middle */ + v_start.x = (v_start.x + v_last.x) / 2; + v_start.y = (v_start.y + v_last.y) / 2; + } + point--; + tags--; + } + + error = GD_FT_Stroker_BeginSubPath(stroker, &v_start, outline->contours_flag[n]); + if (error) + goto Exit; + + while (point < limit) { + point++; + tags++; + + tag = GD_FT_CURVE_TAG(tags[0]); + switch (tag) { + case GD_FT_CURVE_TAG_ON: /* emit a single line_to */ + { + GD_FT_Vector vec; + + vec.x = point->x; + vec.y = point->y; + + error = GD_FT_Stroker_LineTo(stroker, &vec); + if (error) + goto Exit; + continue; + } + + case GD_FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if (point < limit) { + GD_FT_Vector vec; + GD_FT_Vector v_middle; + + point++; + tags++; + tag = GD_FT_CURVE_TAG(tags[0]); + + vec = point[0]; + + if (tag == GD_FT_CURVE_TAG_ON) { + error = GD_FT_Stroker_ConicTo(stroker, &v_control, &vec); + if (error) + goto Exit; + continue; + } + + if (tag != GD_FT_CURVE_TAG_CONIC) + goto Invalid_Outline; + + v_middle.x = (v_control.x + vec.x) / 2; + v_middle.y = (v_control.y + vec.y) / 2; + + error = GD_FT_Stroker_ConicTo(stroker, &v_control, &v_middle); + if (error) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = GD_FT_Stroker_ConicTo(stroker, &v_control, &v_start); + goto Close; + + default: /* GD_FT_CURVE_TAG_CUBIC */ + { + GD_FT_Vector vec1, vec2; + + if (point + 1 > limit || GD_FT_CURVE_TAG(tags[1]) != GD_FT_CURVE_TAG_CUBIC) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1 = point[-2]; + vec2 = point[-1]; + + if (point <= limit) { + GD_FT_Vector vec; + + vec = point[0]; + + error = GD_FT_Stroker_CubicTo(stroker, &vec1, &vec2, &vec); + if (error) + goto Exit; + continue; + } + + error = GD_FT_Stroker_CubicTo(stroker, &vec1, &vec2, &v_start); + goto Close; + } + } + } + + Close: + if (error) + goto Exit; + + /* don't try to end the path if no segments have been generated */ + if (!stroker->first_point) { + error = GD_FT_Stroker_EndSubPath(stroker); + if (error) + goto Exit; + } + + first = last + 1; + } + + return 0; + +Exit: + return error; + +Invalid_Outline: + return -2; // GD_FT_THROW( Invalid_Outline ); +} + +/* END */ diff --git a/ext/gd/libgd/ftraster/gd_ft_stroker.h b/ext/gd/libgd/ftraster/gd_ft_stroker.h new file mode 100644 index 000000000000..2af3c872ac96 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_stroker.h @@ -0,0 +1,320 @@ +#ifndef GD_FT_STROKER_H +#define GD_FT_STROKER_H +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include "gd_ft_raster.h" + +/************************************************************** + * + * @type: + * GD_FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + */ +typedef struct GD_FT_StrokerRec_ *GD_FT_Stroker; + +/************************************************************** + * + * @enum: + * GD_FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * GD_FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * GD_FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins. The outer corner of + * the joined lines is filled by enclosing the triangular + * region of the corner with a straight line between the + * outer corners of each stroke. + * + * GD_FT_STROKER_LINEJOIN_MITER_FIXED :: + * Used to render mitered line joins, with fixed bevels if the + * miter limit is exceeded. The outer edges of the strokes + * for the two segments are extended until they meet at an + * angle. If the segments meet at too sharp an angle (such + * that the miter would extend from the intersection of the + * segments a distance greater than the product of the miter + * limit value and the border radius), then a bevel join (see + * above) is used instead. This prevents long spikes being + * created. GD_FT_STROKER_LINEJOIN_MITER_FIXED generates a miter + * line join as used in PostScript and PDF. + * + * GD_FT_STROKER_LINEJOIN_MITER_VARIABLE :: + * GD_FT_STROKER_LINEJOIN_MITER :: + * Used to render mitered line joins, with variable bevels if + * the miter limit is exceeded. The intersection of the + * strokes is clipped at a line perpendicular to the bisector + * of the angle between the strokes, at the distance from the + * intersection of the segments equal to the product of the + * miter limit value and the border radius. This prevents + * long spikes being created. + * GD_FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line + * join as used in XPS. GD_FT_STROKER_LINEJOIN_MITER is an alias + * for GD_FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for + * backwards compatibility. + */ +typedef enum GD_FT_Stroker_LineJoin_ { + GD_FT_STROKER_LINEJOIN_ROUND = 0, + GD_FT_STROKER_LINEJOIN_BEVEL = 1, + GD_FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, + GD_FT_STROKER_LINEJOIN_MITER = GD_FT_STROKER_LINEJOIN_MITER_VARIABLE, + GD_FT_STROKER_LINEJOIN_MITER_FIXED = 3 + +} GD_FT_Stroker_LineJoin; + +/************************************************************** + * + * @enum: + * GD_FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * GD_FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * GD_FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * GD_FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ +typedef enum GD_FT_Stroker_LineCap_ { + GD_FT_STROKER_LINECAP_BUTT = 0, + GD_FT_STROKER_LINECAP_ROUND, + GD_FT_STROKER_LINECAP_SQUARE + +} GD_FT_Stroker_LineCap; + +/************************************************************** + * + * @enum: + * GD_FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @GD_FT_Stroker_GetBorderCounts and @GD_FT_Stroker_ExportBorder. + * + * @values: + * GD_FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * GD_FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @GD_FT_Outline_GetInsideBorder and + * @GD_FT_Outline_GetOutsideBorder to get these. + */ +typedef enum GD_FT_StrokerBorder_ { + GD_FT_STROKER_BORDER_LEFT = 0, + GD_FT_STROKER_BORDER_RIGHT + +} GD_FT_StrokerBorder; + +/************************************************************** + * + * @function: + * GD_FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ +GD_FT_Error GD_FT_Stroker_New(GD_FT_Stroker *astroker); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the GD_FT_STROKER_LINEJOIN_MITER_FIXED and + * GD_FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, + * expressed as 16.16 fixed-point value. + * + * @note: + * The radius is expressed in the same units as the outline + * coordinates. + */ +void GD_FT_Stroker_Set(GD_FT_Stroker stroker, GD_FT_Fixed radius, GD_FT_Stroker_LineCap line_cap, + GD_FT_Stroker_LineJoin line_join, GD_FT_Fixed miter_limit); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @GD_FT_Stroker_GetCounts and @GD_FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. + * + * + * This function calls @GD_FT_Stroker_Rewind automatically. + */ +GD_FT_Error GD_FT_Stroker_ParseOutline(GD_FT_Stroker stroker, const GD_FT_Outline *outline); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ +GD_FT_Error GD_FT_Stroker_GetCounts(GD_FT_Stroker stroker, GD_FT_UInt *anum_points, + GD_FT_UInt *anum_contours); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_ExportBorder + * + * @description: + * Export a single border of a stroked outline. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border to export (LEFT or RIGHT). + * + * outline :: + * The target outline handle. + * + * @note: + * Call this after GD_FT_Stroker_GetCounts to get individual borders. + * The outline must be pre-allocated with sufficient space. + */ +void GD_FT_Stroker_ExportBorder(GD_FT_Stroker stroker, GD_FT_StrokerBorder border, + GD_FT_Outline *outline); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_Export + * + * @description: + * Call this function after @GD_FT_Stroker_GetBorderCounts to + * export all borders to your own @GD_FT_Outline structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ +void GD_FT_Stroker_Export(GD_FT_Stroker stroker, GD_FT_Outline *outline); + +/************************************************************** + * + * @function: + * GD_FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ +void GD_FT_Stroker_Done(GD_FT_Stroker stroker); + +#endif // GD_FT_STROKER_H diff --git a/ext/gd/libgd/ftraster/gd_ft_types.h b/ext/gd/libgd/ftraster/gd_ft_types.h new file mode 100644 index 000000000000..4e30d2b38694 --- /dev/null +++ b/ext/gd/libgd/ftraster/gd_ft_types.h @@ -0,0 +1,146 @@ +#ifndef GD_FT_TYPES_H +#define GD_FT_TYPES_H + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Fixed */ +/* */ +/* */ +/* This type is used to store 16.16 fixed-point values, like scaling */ +/* values or matrix coefficients. */ +/* */ +typedef signed long GD_FT_Fixed; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Int */ +/* */ +/* */ +/* A typedef for the int type. */ +/* */ +typedef signed int GD_FT_Int; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_UInt */ +/* */ +/* */ +/* A typedef for the unsigned int type. */ +/* */ +typedef unsigned int GD_FT_UInt; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Long */ +/* */ +/* */ +/* A typedef for signed long. */ +/* */ +typedef signed long GD_FT_Long; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_ULong */ +/* */ +/* */ +/* A typedef for unsigned long. */ +/* */ +typedef unsigned long GD_FT_ULong; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Short */ +/* */ +/* */ +/* A typedef for signed short. */ +/* */ +typedef signed short GD_FT_Short; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Byte */ +/* */ +/* */ +/* A simple typedef for the _unsigned_ char type. */ +/* */ +typedef unsigned char GD_FT_Byte; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Bool */ +/* */ +/* */ +/* A typedef of unsigned char, used for simple booleans. As usual, */ +/* values 1 and~0 represent true and false, respectively. */ +/* */ +typedef unsigned char GD_FT_Bool; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Error */ +/* */ +/* */ +/* The FreeType error code type. A value of~0 is always interpreted */ +/* as a successful operation. */ +/* */ +typedef int GD_FT_Error; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Pos */ +/* */ +/* */ +/* The type GD_FT_Pos is used to store vectorial coordinates. Depending */ +/* on the context, these can represent distances in integer font */ +/* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ +/* */ +typedef signed long GD_FT_Pos; + +/*************************************************************************/ +/* */ +/* */ +/* GD_FT_Vector */ +/* */ +/* */ +/* A simple structure used to store a 2D vector; coordinates are of */ +/* the GD_FT_Pos type. */ +/* */ +/* */ +/* x :: The horizontal coordinate. */ +/* y :: The vertical coordinate. */ +/* */ +typedef struct GD_FT_Vector_ { + GD_FT_Pos x; + GD_FT_Pos y; + +} GD_FT_Vector; + +typedef long long int GD_FT_Int64; +typedef unsigned long long int GD_FT_UInt64; + +typedef signed int GD_FT_Int32; +typedef unsigned int GD_FT_UInt32; + +#define GD_FT_BOOL(x) ((GD_FT_Bool)(x)) + +#define GD_FT_SIZEOF_LONG 4 + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif // GD_FT_TYPES_H diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 71a0e9ea63f2..ccdf95a0a2ac 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1,3003 +1,3994 @@ -#include -#include -#include #include "gd.h" -#include "gdhelpers.h" +#include "gd_color.h" #include "gd_errors.h" +#include "gd_intern.h" +#include "gdhelpers.h" +#include +#include +#include +#include +#include + +#if ENABLE_CORRECTED_LEGACY_COMPOSITING +#include "gd_compositor.h" +#endif #include "php.h" +/* 2.0.12: this now checks the clipping rectangle */ +#define gdImageBoundsSafeMacro(im, x, y) \ + (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2)))) -#ifdef _OSD_POSIX /* BS2000 uses the EBCDIC char set instead of ASCII */ +#ifdef _OSD_POSIX /* BS2000 uses the EBCDIC char set instead of ASCII */ #define CHARSET_EBCDIC -#define __attribute__(any) /*nothing */ +#define __attribute__(any) /*nothing */ #endif /*_OSD_POSIX*/ #ifndef CHARSET_EBCDIC -#define ASC(ch) ch +#define ASC(ch) ch #else /*CHARSET_EBCDIC */ #define ASC(ch) gd_toascii[(unsigned char)ch] -static const unsigned char gd_toascii[256] = -{ -/*00 */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, - 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................ */ -/*10 */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, - 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................ */ -/*20 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................ */ -/*30 */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, - 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................ */ -/*40 */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, - 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */ -/*50 */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, - 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);. */ -/*60 */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, - 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, -/*-/........^,%_>?*/ -/*70 */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, - 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'=" */ -/*80 */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi...... */ -/*90 */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, - 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr...... */ -/*a0 */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz...... */ -/*b0 */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, - 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\].. */ -/*c0 */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI...... */ -/*d0 */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR...... */ -/*e0 */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ...... */ -/*f0 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~ */ +static const unsigned char gd_toascii[256] = { + /*00 */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, /*................ */ + /*10 */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, + 0x1e, 0x1f, /*................ */ + /*20 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, + 0x06, 0x07, /*................ */ + /*30 */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, + 0x9e, 0x1a, /*................ */ + /*40 */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, + 0x2b, 0x7c, /* .........`.<(+| */ + /*50 */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, + 0x3b, 0x9f, /*&.........!$*);. */ + /*60 */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, + 0x3e, 0x3f, + /*-/........^,%_>?*/ + /*70 */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, + 0x3d, 0x22, /*..........:#@'=" */ + /*80 */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, + 0xfe, 0xb1, /*.abcdefghi...... */ + /*90 */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, + 0xc6, 0xa4, /*.jklmnopqr...... */ + /*a0 */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, + 0xde, 0xae, /*..stuvwxyz...... */ + /*b0 */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, + 0xb4, 0xd7, /*...........[\].. */ + /*c0 */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, + 0xf3, 0xf5, /*.ABCDEFGHI...... */ + /*d0 */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, + 0xfa, 0xff, /*.JKLMNOPQR...... */ + /*e0 */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, + 0xd3, 0xd5, /*..STUVWXYZ...... */ + /*f0 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, + 0xda, 0x7e /*0123456789.{.}.~ */ }; #endif /*CHARSET_EBCDIC */ - /* 2.0.10: cast instead of floor() yields 35% performance improvement. Thanks to John Buckman. */ -#define floor_cast(exp) ((long) exp) - -extern int gdCosT[]; -extern int gdSinT[]; +#define floor_cast(exp) ((long)exp) +extern const int gdCosT[]; +extern const int gdSinT[]; /** * Group: Error Handling */ -void gd_stderr_error(int priority, const char *format, va_list args) -{ - switch (priority) { - case GD_ERROR: - fputs("GD Error: ", stderr); - break; - case GD_WARNING: - fputs("GD Warning: ", stderr); - break; - case GD_NOTICE: - fputs("GD Notice: ", stderr); - break; +static void gd_stderr_error(int priority, const char *format, va_list args) +{ + switch (priority) { + case GD_ERROR: + fputs("GD Error: ", stderr); + break; + case GD_WARNING: + fputs("GD Warning: ", stderr); + break; + case GD_NOTICE: + fputs("GD Notice: ", stderr); + break; #ifndef PHP_WIN32 - case GD_INFO: - fputs("GD Info: ", stderr); - break; - case GD_DEBUG: - fputs("GD Debug: ", stderr); - break; + case GD_INFO: + fputs("GD Info: ", stderr); + break; + case GD_DEBUG: + fputs("GD Debug: ", stderr); + break; #endif - } - vfprintf(stderr, format, args); - fflush(stderr); + } + vfprintf(stderr, format, args); + fflush(stderr); } static gdErrorMethod gd_error_method = gd_stderr_error; static void _gd_error_ex(int priority, const char *format, va_list args) { - if (gd_error_method) { - gd_error_method(priority, format, args); - } + if (gd_error_method) { + gd_error_method(priority, format, args); + } } void gd_error(const char *format, ...) { - va_list args; + va_list args; - va_start(args, format); - _gd_error_ex(GD_WARNING, format, args); - va_end(args); + va_start(args, format); + _gd_error_ex(GD_WARNING, format, args); + va_end(args); } void gd_error_ex(int priority, const char *format, ...) { - va_list args; + va_list args; - va_start(args, format); - _gd_error_ex(priority, format, args); - va_end(args); + va_start(args, format); + _gd_error_ex(priority, format, args); + va_end(args); } /* - Function: gdSetErrorMethod + Function: gdSetErrorMethod */ -void gdSetErrorMethod(gdErrorMethod error_method) -{ - gd_error_method = error_method; -} +BGD_DECLARE(void) gdSetErrorMethod(gdErrorMethod error_method) { gd_error_method = error_method; } /* - Function: gdClearErrorMethod + Function: gdClearErrorMethod */ -void gdClearErrorMethod(void) -{ - gd_error_method = gd_stderr_error; -} +BGD_DECLARE(void) gdClearErrorMethod(void) { gd_error_method = gd_stderr_error; } static void gdImageBrushApply(gdImagePtr im, int x, int y); static void gdImageTileApply(gdImagePtr im, int x, int y); static int gdAlphaOverlayColor(int src, int dst, int max); -int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); - -gdImagePtr gdImageCreate (int sx, int sy) -{ - int i; - gdImagePtr im; - - if (overflow2(sx, sy)) { - return NULL; - } - if (overflow2(sizeof(unsigned char *), sy)) { - return NULL; - } - if (overflow2(sizeof(unsigned char), sx)) { - return NULL; - } - - im = (gdImage *) gdCalloc(1, sizeof(gdImage)); - - /* Row-major ever since gd 1.3 */ - im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); - im->polyInts = 0; - im->polyAllocated = 0; - im->brush = 0; - im->tile = 0; - im->style = 0; - for (i = 0; i < sy; i++) { - /* Row-major ever since gd 1.3 */ - im->pixels[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); - } - im->sx = sx; - im->sy = sy; - im->colorsTotal = 0; - im->transparent = (-1); - im->interlace = 0; - im->thick = 1; - im->AA = 0; - for (i = 0; i < gdMaxColors; i++) { - im->open[i] = 1; - im->red[i] = 0; - im->green[i] = 0; - im->blue[i] = 0; - } - im->trueColor = 0; - im->tpixels = 0; - im->cx1 = 0; - im->cy1 = 0; - im->cx2 = im->sx - 1; - im->cy2 = im->sy - 1; - im->res_x = GD_RESOLUTION; - im->res_y = GD_RESOLUTION; - im->interpolation = NULL; - im->interpolation_id = GD_BILINEAR_FIXED; - return im; -} - -gdImagePtr gdImageCreateTrueColor (int sx, int sy) -{ - int i; - gdImagePtr im; - - if (overflow2(sx, sy)) { - return NULL; - } - if (overflow2(sizeof(int *), sy)) { - return NULL; - } - if (overflow2(sizeof(int), sx)) { - return NULL; - } - - im = (gdImage *) gdMalloc(sizeof(gdImage)); - memset(im, 0, sizeof(gdImage)); - im->tpixels = (int **) gdMalloc(sizeof(int *) * sy); - im->polyInts = 0; - im->polyAllocated = 0; - im->brush = 0; - im->tile = 0; - im->style = 0; - for (i = 0; i < sy; i++) { - im->tpixels[i] = (int *) gdCalloc(sx, sizeof(int)); - } - im->sx = sx; - im->sy = sy; - im->transparent = (-1); - im->interlace = 0; - im->trueColor = 1; - /* 2.0.2: alpha blending is now on by default, and saving of alpha is - * off by default. This allows font antialiasing to work as expected - * on the first try in JPEGs -- quite important -- and also allows - * for smaller PNGs when saving of alpha channel is not really - * desired, which it usually isn't! - */ - im->saveAlphaFlag = 0; - im->alphaBlendingFlag = 1; - im->thick = 1; - im->AA = 0; - im->cx1 = 0; - im->cy1 = 0; - im->cx2 = im->sx - 1; - im->cy2 = im->sy - 1; - im->res_x = GD_RESOLUTION; - im->res_y = GD_RESOLUTION; - im->interpolation = NULL; - im->interpolation_id = GD_BILINEAR_FIXED; - return im; -} - -void gdImageDestroy (gdImagePtr im) -{ - int i; - if (im->pixels) { - for (i = 0; i < im->sy; i++) { - gdFree(im->pixels[i]); - } - gdFree(im->pixels); - } - if (im->tpixels) { - for (i = 0; i < im->sy; i++) { - gdFree(im->tpixels[i]); - } - gdFree(im->tpixels); - } - if (im->polyInts) { - gdFree(im->polyInts); - } - if (im->style) { - gdFree(im->style); - } - gdFree(im); -} - -int gdImageColorClosest (gdImagePtr im, int r, int g, int b) -{ - return gdImageColorClosestAlpha (im, r, g, b, gdAlphaOpaque); -} - -int gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a) -{ - int i; - long rd, gd, bd, ad; - int ct = (-1); - int first = 1; - long mindist = 0; - - if (im->trueColor) { - return gdTrueColorAlpha(r, g, b, a); - } - for (i = 0; i < im->colorsTotal; i++) { - long dist; - if (im->open[i]) { - continue; - } - rd = im->red[i] - r; - gd = im->green[i] - g; - bd = im->blue[i] - b; - /* gd 2.02: whoops, was - b (thanks to David Marwood) */ - ad = im->alpha[i] - a; - dist = rd * rd + gd * gd + bd * bd + ad * ad; - if (first || (dist < mindist)) { - mindist = dist; - ct = i; - first = 0; - } - } - return ct; -} - -/* This code is taken from http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article - * on colour conversion to/from RBG and HWB colour systems. - * It has been modified to return the converted value as a * parameter. - */ -#define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;} -#define RETURN_RGB(r, g, b) {RGB->R = r; RGB->G = g; RGB->B = b; return RGB;} -#define HWB_UNDEFINED -1 -#define SETUP_RGB(s, r, g, b) {s.R = r/255.0f; s.G = g/255.0f; s.B = b/255.0f;} - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif -#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c))) -#ifndef MAX -#define MAX(a,b) ((a)<(b)?(b):(a)) -#endif -#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c))) +BGD_DECLARE(int) gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); +/** + * Group: Creation and Destruction + */ /* - * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure - * red always maps to 6 in this implementation. Therefore UNDEFINED can be - * defined as 0 in situations where only unsigned numbers are desired. - */ -typedef struct -{ - float R, G, B; -} -RGBType; -typedef struct -{ - float H, W, B; -} -HWBType; + Function: gdImageCreate -static HWBType * RGB_to_HWB (RGBType RGB, HWBType * HWB) -{ - /* - * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is - * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B. - */ + gdImageCreate is called to create palette-based images, with no + more than 256 colors. The image must eventually be destroyed using + gdImageDestroy(). - float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f; - int i; + Parameters: - w = MIN3 (R, G, B); - v = MAX3 (R, G, B); - b = 1 - v; - if (v == w) { - RETURN_HWB(HWB_UNDEFINED, w, b); - } - f = (R == w) ? G - B : ((G == w) ? B - R : R - G); - i = (R == w) ? 3 : ((G == w) ? 5 : 1); + sx - The image width. + sy - The image height. - RETURN_HWB(i - f / (v - w), w, b); -} + Returns: -static float HWB_Diff (int r1, int g1, int b1, int r2, int g2, int b2) -{ - RGBType RGB1, RGB2; - HWBType HWB1, HWB2; - float diff; + A pointer to the new image or NULL if an error occurred. - SETUP_RGB(RGB1, r1, g1, b1); - SETUP_RGB(RGB2, r2, g2, b2); + Example: + (start code) - RGB_to_HWB(RGB1, &HWB1); - RGB_to_HWB(RGB2, &HWB2); + gdImagePtr im; + im = gdImageCreate(64, 64); + // ... Use the image ... + gdImageDestroy(im); - /* - * I made this bit up; it seems to produce OK results, and it is certainly - * more visually correct than the current RGB metric. (PJW) - */ + (end code) - if ((HWB1.H == HWB_UNDEFINED) || (HWB2.H == HWB_UNDEFINED)) { - diff = 0.0f; /* Undefined hues always match... */ - } else { - diff = fabsf(HWB1.H - HWB2.H); - if (diff > 3.0f) { - diff = 6.0f - diff; /* Remember, it's a colour circle */ - } - } + See Also: - diff = diff * diff + (HWB1.W - HWB2.W) * (HWB1.W - HWB2.W) + (HWB1.B - HWB2.B) * (HWB1.B - HWB2.B); + - return diff; -} + */ +BGD_DECLARE(gdImagePtr) gdImageCreate(int sx, int sy) +{ + int i; + gdImagePtr im; + if (overflow2(sx, sy)) { + return NULL; + } -#if 0 -/* - * This is not actually used, but is here for completeness, in case someone wants to - * use the HWB stuff for anything else... - */ -static RGBType * HWB_to_RGB (HWBType HWB, RGBType * RGB) -{ - /* - * H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1]. - * RGB are each returned on [0, 1]. - */ - - float h = HWB.H, w = HWB.W, b = HWB.B, v, n, f; - int i; - - v = 1 - b; - if (h == HWB_UNDEFINED) { - RETURN_RGB(v, v, v); - } - i = floor(h); - f = h - i; - if (i & 1) { - f = 1 - f; /* if i is odd */ - } - n = w + f * (v - w); /* linear interpolation between w and v */ - switch (i) { - case 6: - case 0: - RETURN_RGB(v, n, w); - case 1: - RETURN_RGB(n, v, w); - case 2: - RETURN_RGB(w, v, n); - case 3: - RETURN_RGB(w, n, v); - case 4: - RETURN_RGB(n, w, v); - case 5: - RETURN_RGB(v, w, n); - } - - return RGB; -} -#endif + if (overflow2(sizeof(unsigned char *), sy)) { + return NULL; + } + if (overflow2(sizeof(unsigned char), sx)) { + return NULL; + } -int gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b) -{ - int i; - /* long rd, gd, bd; */ - int ct = (-1); - int first = 1; - float mindist = 0; - if (im->trueColor) { - return gdTrueColor(r, g, b); - } - for (i = 0; i < im->colorsTotal; i++) { - float dist; - if (im->open[i]) { - continue; - } - dist = HWB_Diff(im->red[i], im->green[i], im->blue[i], r, g, b); - if (first || (dist < mindist)) { - mindist = dist; - ct = i; - first = 0; - } - } - return ct; -} - -int gdImageColorExact (gdImagePtr im, int r, int g, int b) -{ - return gdImageColorExactAlpha (im, r, g, b, gdAlphaOpaque); -} - -int gdImageColorExactAlpha (gdImagePtr im, int r, int g, int b, int a) -{ - int i; - if (im->trueColor) { - return gdTrueColorAlpha(r, g, b, a); - } - for (i = 0; i < im->colorsTotal; i++) { - if (im->open[i]) { - continue; - } - if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b) && (im->alpha[i] == a)) { - return i; - } - } - return -1; -} - -int gdImageColorAllocate (gdImagePtr im, int r, int g, int b) -{ - return gdImageColorAllocateAlpha (im, r, g, b, gdAlphaOpaque); -} - -int gdImageColorAllocateAlpha (gdImagePtr im, int r, int g, int b, int a) -{ - int i; - int ct = (-1); - if (im->trueColor) { - return gdTrueColorAlpha(r, g, b, a); - } - for (i = 0; i < im->colorsTotal; i++) { - if (im->open[i]) { - ct = i; - break; - } - } - if (ct == (-1)) { - ct = im->colorsTotal; - if (ct == gdMaxColors) { - return -1; - } - im->colorsTotal++; - } - im->red[ct] = r; - im->green[ct] = g; - im->blue[ct] = b; - im->alpha[ct] = a; - im->open[ct] = 0; - - return ct; -} + im = (gdImage *)gdCalloc(1, sizeof(gdImage)); + if (!im) { + return NULL; + } -/* - * gdImageColorResolve is an alternative for the code fragment: - * - * if ((color=gdImageColorExact(im,R,G,B)) < 0) - * if ((color=gdImageColorAllocate(im,R,G,B)) < 0) - * color=gdImageColorClosest(im,R,G,B); - * - * in a single function. Its advantage is that it is guaranteed to - * return a color index in one search over the color table. - */ + /* Row-major ever since gd 1.3 */ + im->pixels = (unsigned char **)gdMalloc(sizeof(unsigned char *) * sy); + if (!im->pixels) { + gdFree(im); + return NULL; + } -int gdImageColorResolve (gdImagePtr im, int r, int g, int b) -{ - return gdImageColorResolveAlpha(im, r, g, b, gdAlphaOpaque); -} - -int gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a) -{ - int c; - int ct = -1; - int op = -1; - long rd, gd, bd, ad, dist; - long mindist = 4 * 255 * 255; /* init to max poss dist */ - if (im->trueColor) - { - return gdTrueColorAlpha (r, g, b, a); - } - - for (c = 0; c < im->colorsTotal; c++) - { - if (im->open[c]) - { - op = c; /* Save open slot */ - continue; /* Color not in use */ - } - if (c == im->transparent) - { - /* don't ever resolve to the color that has - * been designated as the transparent color */ - continue; - } - rd = (long) (im->red[c] - r); - gd = (long) (im->green[c] - g); - bd = (long) (im->blue[c] - b); - ad = (long) (im->alpha[c] - a); - dist = rd * rd + gd * gd + bd * bd + ad * ad; - if (dist < mindist) - { - if (dist == 0) - { - return c; /* Return exact match color */ - } - mindist = dist; - ct = c; - } - } - /* no exact match. We now know closest, but first try to allocate exact */ - if (op == -1) - { - op = im->colorsTotal; - if (op == gdMaxColors) - { /* No room for more colors */ - return ct; /* Return closest available color */ - } - im->colorsTotal++; - } - im->red[op] = r; - im->green[op] = g; - im->blue[op] = b; - im->alpha[op] = a; - im->open[op] = 0; - return op; /* Return newly allocated color */ -} - -void gdImageColorDeallocate (gdImagePtr im, int color) -{ - if (im->trueColor) { - return; - } - /* Mark it open. */ - im->open[color] = 1; -} - -void gdImageColorTransparent (gdImagePtr im, int color) -{ - if (color < 0) { - return; - } - if (!im->trueColor) { - if((color >= im->colorsTotal)) { - return; - } - /* Make the old transparent color opaque again */ - if (im->transparent != -1) { - im->alpha[im->transparent] = gdAlphaOpaque; - } - im->alpha[color] = gdAlphaTransparent; - } - im->transparent = color; -} - -void gdImagePaletteCopy (gdImagePtr to, gdImagePtr from) -{ - int i; - int x, y, p; - int xlate[256]; - if (to->trueColor || from->trueColor) { - return; - } - - for (i = 0; i < 256; i++) { - xlate[i] = -1; - } - - for (y = 0; y < to->sy; y++) { - for (x = 0; x < to->sx; x++) { - p = gdImageGetPixel(to, x, y); - if (xlate[p] == -1) { - /* This ought to use HWB, but we don't have an alpha-aware version of that yet. */ - xlate[p] = gdImageColorClosestAlpha (from, to->red[p], to->green[p], to->blue[p], to->alpha[p]); - } - gdImageSetPixel(to, x, y, xlate[p]); - } - } + im->polyInts = 0; + im->polyAllocated = 0; + im->brush = 0; + im->tile = 0; + im->style = 0; + for (i = 0; (i < sy); i++) { + /* Row-major ever since gd 1.3 */ + im->pixels[i] = (unsigned char *)gdCalloc(sx, sizeof(unsigned char)); + if (!im->pixels[i]) { + for (--i; i >= 0; i--) { + gdFree(im->pixels[i]); + } + gdFree(im->pixels); + gdFree(im); + return NULL; + } + } + im->sx = sx; + im->sy = sy; + im->colorsTotal = 0; + im->transparent = (-1); + im->interlace = 0; + im->thick = 1; + im->AA = 0; + for (i = 0; (i < gdMaxColors); i++) { + im->open[i] = 1; + im->red[i] = 0; + im->green[i] = 0; + im->blue[i] = 0; + }; + im->trueColor = 0; + im->tpixels = 0; + im->cx1 = 0; + im->cy1 = 0; + im->cx2 = im->sx - 1; + im->cy2 = im->sy - 1; + im->res_x = GD_RESOLUTION; + im->res_y = GD_RESOLUTION; + im->interpolation = NULL; + im->interpolation_id = GD_BILINEAR_FIXED; + return im; +} - for (i = 0; i < from->colorsTotal; i++) { - to->red[i] = from->red[i]; - to->blue[i] = from->blue[i]; - to->green[i] = from->green[i]; - to->alpha[i] = from->alpha[i]; - to->open[i] = 0; - } +/* + Function: gdImageCreateTrueColor - for (i = from->colorsTotal; i < to->colorsTotal; i++) { - to->open[i] = 1; - } + is called to create truecolor images, + with an essentially unlimited number of colors. Invoke + with the x and y dimensions of the + desired image. returns a + to the new image, or NULL if unable to allocate the image. The + image must eventually be destroyed using (). - to->colorsTotal = from->colorsTotal; -} + Truecolor images are always filled with black at creation + time. There is no concept of a "background" color index. -/* 2.0.10: before the drawing routines, some code to clip points that are - * outside the drawing window. Nick Atty (nick@canalplan.org.uk) - * - * This is the Sutherland Hodgman Algorithm, as implemented by - * Duvanenko, Robbins and Gyurcsik - SH(DRG) for short. See Dr Dobb's - * Journal, January 1996, pp107-110 and 116-117 - * - * Given the end points of a line, and a bounding rectangle (which we - * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on - * the edges of the rectangle if the line should be drawn at all, - * otherwise return a failure code - */ + Parameters: -/* this does "one-dimensional" clipping: note that the second time it - * is called, all the x parameters refer to height and the y to width - * - the comments ignore this (if you can understand it when it's - * looking at the X parameters, it should become clear what happens on - * the second call!) The code is simplified from that in the article, - * as we know that gd images always start at (0,0) - */ -/* 2.0.26, TBB: we now have to respect a clipping rectangle, it won't - necessarily start at 0. */ - -static int clip_1d(int *x0, int *y0, int *x1, int *y1, int mindim, int maxdim) { - double m; /* gradient of line */ - - if (*x0 < mindim) { /* start of line is left of window */ - if(*x1 < mindim) { /* as is the end, so the line never cuts the window */ - return 0; - } - m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */ - /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */ - *y0 -= (int)(m * (*x0 - mindim)); - *x0 = mindim; - /* now, perhaps, adjust the far end of the line as well */ - if (*x1 > maxdim) { - *y1 += (int)(m * (maxdim - *x1)); - *x1 = maxdim; - } - return 1; - } - if (*x0 > maxdim) { /* start of line is right of window - complement of above */ - if (*x1 > maxdim) { /* as is the end, so the line misses the window */ - return 0; - } - m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */ - *y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right boundary */ - *x0 = maxdim; - /* now, perhaps, adjust the end of the line */ - if (*x1 < mindim) { - *y1 -= (int)(m * (*x1 - mindim)); - *x1 = mindim; - } - return 1; - } - /* the final case - the start of the line is inside the window */ - if (*x1 > maxdim) { /* other end is outside to the right */ - m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */ - *y1 += (int)(m * (maxdim - *x1)); - *x1 = maxdim; - return 1; - } - if (*x1 < mindim) { /* other end is outside to the left */ - m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */ - *y1 -= (int)(m * (*x1 - mindim)); - *x1 = mindim; - return 1; - } - /* only get here if both points are inside the window */ - return 1; -} - -void gdImageSetPixel (gdImagePtr im, int x, int y, int color) -{ - int p; - switch (color) { - case gdStyled: - if (!im->style) { - /* Refuse to draw if no style is set. */ - return; - } else { - p = im->style[im->stylePos++]; - } - if (p != gdTransparent) { - gdImageSetPixel(im, x, y, p); - } - im->stylePos = im->stylePos % im->styleLength; - break; - case gdStyledBrushed: - if (!im->style) { - /* Refuse to draw if no style is set. */ - return; - } - p = im->style[im->stylePos++]; - if (p != gdTransparent && p != 0) { - gdImageSetPixel(im, x, y, gdBrushed); - } - im->stylePos = im->stylePos % im->styleLength; - break; - case gdBrushed: - gdImageBrushApply(im, x, y); - break; - case gdTiled: - gdImageTileApply(im, x, y); - break; - case gdAntiAliased: - /* This shouldn't happen (2.0.26) because we just call - gdImageAALine now, but do something sane. */ - gdImageSetPixel(im, x, y, im->AA_color); - break; - default: - if (gdImageBoundsSafe(im, x, y)) { - if (im->trueColor) { - switch (im->alphaBlendingFlag) { - default: - case gdEffectReplace: - im->tpixels[y][x] = color; - break; - case gdEffectAlphaBlend: - case gdEffectNormal: - im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); - break; - case gdEffectOverlay : - im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color); - break; - case gdEffectMultiply : - im->tpixels[y][x] = gdLayerMultiply(im->tpixels[y][x], color); - break; - } - } else { - im->pixels[y][x] = color; - } - } - break; - } -} - -int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y) -{ - int p = gdImageGetPixel(im, x, y); - - if (!im->trueColor) { - return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]); - } else { - return p; - } -} - -static void gdImageBrushApply (gdImagePtr im, int x, int y) -{ - int lx, ly; - int hy, hx; - int x1, y1, x2, y2; - int srcx, srcy; - - if (!im->brush) { - return; - } - - hy = gdImageSY(im->brush) / 2; - y1 = y - hy; - y2 = y1 + gdImageSY(im->brush); - hx = gdImageSX(im->brush) / 2; - x1 = x - hx; - x2 = x1 + gdImageSX(im->brush); - srcy = 0; - - if (im->trueColor) { - if (im->brush->trueColor) { - for (ly = y1; ly < y2; ly++) { - srcx = 0; - for (lx = x1; (lx < x2); lx++) { - int p; - p = gdImageGetTrueColorPixel(im->brush, srcx, srcy); - /* 2.0.9, Thomas Winzig: apply simple full transparency */ - if (p != gdImageGetTransparent(im->brush)) { - gdImageSetPixel(im, lx, ly, p); - } - srcx++; - } - srcy++; - } - } else { - /* 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger for pointing out the issue) */ - for (ly = y1; ly < y2; ly++) { - srcx = 0; - for (lx = x1; lx < x2; lx++) { - int p, tc; - p = gdImageGetPixel(im->brush, srcx, srcy); - tc = gdImageGetTrueColorPixel(im->brush, srcx, srcy); - /* 2.0.9, Thomas Winzig: apply simple full transparency */ - if (p != gdImageGetTransparent(im->brush)) { - gdImageSetPixel(im, lx, ly, tc); - } - srcx++; - } - srcy++; - } - } - } else { - for (ly = y1; ly < y2; ly++) { - srcx = 0; - for (lx = x1; lx < x2; lx++) { - int p; - p = gdImageGetPixel(im->brush, srcx, srcy); - /* Allow for non-square brushes! */ - if (p != gdImageGetTransparent(im->brush)) { - /* Truecolor brush. Very slow on a palette destination. */ - if (im->brush->trueColor) { - gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p), - gdTrueColorGetGreen(p), - gdTrueColorGetBlue(p), - gdTrueColorGetAlpha(p))); - } else { - gdImageSetPixel(im, lx, ly, im->brushColorMap[p]); - } - } - srcx++; - } - srcy++; - } - } -} - -static void gdImageTileApply (gdImagePtr im, int x, int y) -{ - gdImagePtr tile = im->tile; - int srcx, srcy; - int p; - if (!tile) { - return; - } - srcx = x % gdImageSX(tile); - srcy = y % gdImageSY(tile); - if (im->trueColor) { - p = gdImageGetPixel(tile, srcx, srcy); - if (p != gdImageGetTransparent (tile)) { - if (!tile->trueColor) { - p = gdTrueColorAlpha(tile->red[p], tile->green[p], tile->blue[p], tile->alpha[p]); - } - gdImageSetPixel(im, x, y, p); - } - } else { - p = gdImageGetPixel(tile, srcx, srcy); - /* Allow for transparency */ - if (p != gdImageGetTransparent(tile)) { - if (tile->trueColor) { - /* Truecolor tile. Very slow on a palette destination. */ - gdImageSetPixel(im, x, y, gdImageColorResolveAlpha(im, - gdTrueColorGetRed(p), - gdTrueColorGetGreen(p), - gdTrueColorGetBlue(p), - gdTrueColorGetAlpha(p))); - } else { - gdImageSetPixel(im, x, y, im->tileColorMap[p]); - } - } - } -} - - -static int gdImageTileGet (gdImagePtr im, int x, int y) -{ - int srcx, srcy; - int tileColor,p; - if (!im->tile) { - return -1; - } - srcx = x % gdImageSX(im->tile); - srcy = y % gdImageSY(im->tile); - p = gdImageGetPixel(im->tile, srcx, srcy); - - if (p == im->tile->transparent) { - tileColor = im->transparent; - } else if (im->trueColor) { - if (im->tile->trueColor) { - tileColor = p; - } else { - tileColor = gdTrueColorAlpha( gdImageRed(im->tile,p), gdImageGreen(im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p)); - } - } else { - if (im->tile->trueColor) { - tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed (p), gdTrueColorGetGreen (p), gdTrueColorGetBlue (p), gdTrueColorGetAlpha (p)); - } else { - tileColor = p; - tileColor = gdImageColorResolveAlpha(im, gdImageRed (im->tile,p), gdImageGreen (im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p)); - } - } - return tileColor; -} - - -int gdImageGetPixel (gdImagePtr im, int x, int y) -{ - if (gdImageBoundsSafe(im, x, y)) { - if (im->trueColor) { - return im->tpixels[y][x]; - } else { - return im->pixels[y][x]; - } - } else { - return 0; - } -} - -void gdImageAABlend (gdImagePtr im) -{ - (void)im; -} - -static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color); - -gdImagePtr gdImageClone (gdImagePtr src) { - gdImagePtr dst; - register int i, x; - - if (src->trueColor) { - dst = gdImageCreateTrueColor(src->sx , src->sy); - } else { - dst = gdImageCreate(src->sx , src->sy); - } - - if (dst == NULL) { - return NULL; - } - - if (src->trueColor == 0) { - dst->colorsTotal = src->colorsTotal; - for (i = 0; i < gdMaxColors; i++) { - dst->red[i] = src->red[i]; - dst->green[i] = src->green[i]; - dst->blue[i] = src->blue[i]; - dst->alpha[i] = src->alpha[i]; - dst->open[i] = src->open[i]; - } - for (i = 0; i < src->sy; i++) { - for (x = 0; x < src->sx; x++) { - dst->pixels[i][x] = src->pixels[i][x]; - } - } - } else { - for (i = 0; i < src->sy; i++) { - for (x = 0; x < src->sx; x++) { - dst->tpixels[i][x] = src->tpixels[i][x]; - } - } - } + sx - The image width. + sy - The image height. - dst->interlace = src->interlace; + Returns: - dst->alphaBlendingFlag = src->alphaBlendingFlag; - dst->saveAlphaFlag = src->saveAlphaFlag; - dst->AA = src->AA; - dst->AA_color = src->AA_color; - dst->AA_dont_blend = src->AA_dont_blend; + A pointer to the new image or NULL if an error occurred. - dst->cx1 = src->cx1; - dst->cy1 = src->cy1; - dst->cx2 = src->cx2; - dst->cy2 = src->cy2; + Example: + (start code) - dst->res_x = src->res_x; - dst->res_y = src->res_y; + gdImagePtr im; + im = gdImageCreateTrueColor(64, 64); + // ... Use the image ... + gdImageDestroy(im); - dst->interpolation_id = src->interpolation_id; - dst->interpolation = src->interpolation; + (end code) - if (src->brush) { - dst->brush = gdImageClone(src->brush); - } + See Also: - if (src->tile) { - dst->tile = gdImageClone(src->tile); - } + - if (src->style) { - gdImageSetStyle(dst, src->style, src->styleLength); - dst->stylePos = src->stylePos; - } +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor(int sx, int sy) +{ + int i; + gdImagePtr im; - for (i = 0; i < gdMaxColors; i++) { - dst->brushColorMap[i] = src->brushColorMap[i]; - dst->tileColorMap[i] = src->tileColorMap[i]; - } + if (overflow2(sx, sy)) { + return NULL; + } + if (overflow2(sizeof(int *), sy)) { + return NULL; + } + if (overflow2(sizeof(int), sx)) { + return NULL; + } - if (src->polyAllocated > 0 && overflow2(sizeof(int), src->polyAllocated) == 0) { - dst->polyInts = gdMalloc (sizeof (int) * src->polyAllocated); - dst->polyAllocated = src->polyAllocated; - for (i = 0; i < src->polyAllocated; i++) { - dst->polyInts[i] = src->polyInts[i]; - } - } + im = (gdImage *)gdMalloc(sizeof(gdImage)); + if (!im) { + return 0; + } + memset(im, 0, sizeof(gdImage)); - return dst; + im->tpixels = (int **)gdMalloc(sizeof(int *) * sy); + if (!im->tpixels) { + gdFree(im); + return 0; + } + im->polyInts = 0; + im->polyAllocated = 0; + im->brush = 0; + im->tile = 0; + im->style = 0; + for (i = 0; (i < sy); i++) { + im->tpixels[i] = (int *)gdCalloc(sx, sizeof(int)); + if (!im->tpixels[i]) { + /* 2.0.34 */ + i--; + while (i >= 0) { + gdFree(im->tpixels[i]); + i--; + } + gdFree(im->tpixels); + gdFree(im); + return 0; + } + } + im->sx = sx; + im->sy = sy; + im->transparent = (-1); + im->interlace = 0; + im->trueColor = 1; + /* 2.0.2: alpha blending is now on by default, and saving of alpha is + off by default. This allows font antialiasing to work as expected + on the first try in JPEGs -- quite important -- and also allows + for smaller PNGs when saving of alpha channel is not really + desired, which it usually isn't! */ + im->saveAlphaFlag = 0; + im->alphaBlendingFlag = 1; + im->thick = 1; + im->AA = 0; + im->cx1 = 0; + im->cy1 = 0; + im->cx2 = im->sx - 1; + im->cy2 = im->sy - 1; + im->res_x = GD_RESOLUTION; + im->res_y = GD_RESOLUTION; + im->interpolation = NULL; + im->interpolation_id = GD_BILINEAR_FIXED; + return im; } -static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col) -{ - if (im->thick > 1) { - int thickhalf = im->thick >> 1; - _gdImageFilledHRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col); - } else { - if (x2 < x1) { - int t = x2; - x2 = x1; - x1 = t; - } +/* + Function: gdImageDestroy - for (;x1 <= x2; x1++) { - gdImageSetPixel(im, x1, y, col); - } - } - return; -} + is used to free the memory associated with an + image. It is important to invoke before exiting + your program or assigning a new image to a variable. -static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col) -{ - if (im->thick > 1) { - int thickhalf = im->thick >> 1; - gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col); - } else { - if (y2 < y1) { - int t = y1; - y1 = y2; - y2 = t; - } - - for (;y1 <= y2; y1++) { - gdImageSetPixel(im, x, y1, col); - } - } - return; -} - -/* Bresenham as presented in Foley & Van Dam */ -void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) -{ - int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; - int wid; - int w, wstart; - int thick = im->thick; - - if (color == gdAntiAliased) { - /* - gdAntiAliased passed as color: use the much faster, much cheaper - and equally attractive gdImageAALine implementation. That - clips too, so don't clip twice. - */ - gdImageAALine(im, x1, y1, x2, y2, im->AA_color); - return; - } - /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no - points need to be drawn. 2.0.26, TBB: clip to edges of clipping - rectangle. We were getting away with this because gdImageSetPixel - is used for actual drawing, but this is still more efficient and opens - the way to skip per-pixel bounds checking in the future. */ - - if (clip_1d (&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0) - return; - if (clip_1d (&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0) - return; - - dx = abs (x2 - x1); - dy = abs (y2 - y1); - - if (dx == 0) { - gdImageVLine(im, x1, y1, y2, color); - return; - } else if (dy == 0) { - gdImageHLine(im, y1, x1, x2, color); - return; - } - - if (dy <= dx) { - /* More-or-less horizontal. use wid for vertical stroke */ - /* Doug Claar: watch out for NaN in atan2 (2.0.5) */ - if ((dx == 0) && (dy == 0)) { - wid = 1; - } else { - /* 2.0.12: Michael Schwartz: divide rather than multiply; -TBB: but watch out for /0! */ - double ac = cos (atan2 (dy, dx)); - if (ac != 0) { - wid = thick / ac; - } else { - wid = 1; - } - if (wid == 0) { - wid = 1; - } - } - d = 2 * dy - dx; - incr1 = 2 * dy; - incr2 = 2 * (dy - dx); - if (x1 > x2) { - x = x2; - y = y2; - ydirflag = (-1); - xend = x1; - } else { - x = x1; - y = y1; - ydirflag = 1; - xend = x2; - } - - /* Set up line thickness */ - wstart = y - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel(im, x, w, color); - } - - if (((y2 - y1) * ydirflag) > 0) { - while (x < xend) { - x++; - if (d < 0) { - d += incr1; - } else { - y++; - d += incr2; - } - wstart = y - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel (im, x, w, color); - } - } - } else { - while (x < xend) { - x++; - if (d < 0) { - d += incr1; - } else { - y--; - d += incr2; - } - wstart = y - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel (im, x, w, color); - } - } - } - } else { - /* More-or-less vertical. use wid for horizontal stroke */ - /* 2.0.12: Michael Schwartz: divide rather than multiply; - TBB: but watch out for /0! */ - double as = sin (atan2 (dy, dx)); - if (as != 0) { - wid = thick / as; - } else { - wid = 1; - } - if (wid == 0) { - wid = 1; - } - - d = 2 * dx - dy; - incr1 = 2 * dx; - incr2 = 2 * (dx - dy); - if (y1 > y2) { - y = y2; - x = x2; - yend = y1; - xdirflag = (-1); - } else { - y = y1; - x = x1; - yend = y2; - xdirflag = 1; - } - - /* Set up line thickness */ - wstart = x - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel (im, w, y, color); - } - - if (((x2 - x1) * xdirflag) > 0) { - while (y < yend) { - y++; - if (d < 0) { - d += incr1; - } else { - x++; - d += incr2; - } - wstart = x - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel (im, w, y, color); - } - } - } else { - while (y < yend) { - y++; - if (d < 0) { - d += incr1; - } else { - x--; - d += incr2; - } - wstart = x - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel (im, w, y, color); - } - } - } - } -} + Parameters: + im - Pointer to the gdImage to delete. -/* - * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org) - * */ -#define BLEND_COLOR(a, nc, c, cc) \ -nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8); + Returns: -inline static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t) -{ - int dr,dg,db,p,r,g,b; - dr = gdTrueColorGetRed(color); - dg = gdTrueColorGetGreen(color); - db = gdTrueColorGetBlue(color); + Nothing. - p = gdImageGetPixel(im,x,y); - r = gdTrueColorGetRed(p); - g = gdTrueColorGetGreen(p); - b = gdTrueColorGetBlue(p); + Example: + (start code) - BLEND_COLOR(t, dr, r, dr); - BLEND_COLOR(t, dg, g, dg); - BLEND_COLOR(t, db, b, db); - im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque); -} + gdImagePtr im; + im = gdImageCreate(10, 10); + // ... Use the image ... + // Now destroy it + gdImageDestroy(im); -/* - * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org) - **/ -void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col) -{ - /* keep them as 32bits */ - long x, y, inc, frac; - long dx, dy,tmp; - - if (!im->trueColor) { - /* TBB: don't crash when the image is of the wrong type */ - gdImageLine(im, x1, y1, x2, y2, col); - return; - } - - /* TBB: use the clipping rectangle */ - if (clip_1d (&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0) - return; - if (clip_1d (&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0) - return; - - dx = x2 - x1; - dy = y2 - y1; - - if (dx == 0 && dy == 0) { - return; - } - if (abs((int)dx) > abs((int)dy)) { - if (dx < 0) { - tmp = x1; - x1 = x2; - x2 = tmp; - tmp = y1; - y1 = y2; - y2 = tmp; - dx = x2 - x1; - dy = y2 - y1; - } - y = y1; - inc = (dy * 65536) / dx; - frac = 0; - for (x = x1; x <= x2; x++) { - gdImageSetAAPixelColor(im, x, y, col, (frac >> 8) & 0xFF); - if (y + 1 < im->sy) { - gdImageSetAAPixelColor(im, x, y + 1, col, (~frac >> 8) & 0xFF); - } - frac += inc; - if (frac >= 65536) { - frac -= 65536; - y++; - } else if (frac < 0) { - frac += 65536; - y--; - } - } - } else { - if (dy < 0) { - tmp = x1; - x1 = x2; - x2 = tmp; - tmp = y1; - y1 = y2; - y2 = tmp; - dx = x2 - x1; - dy = y2 - y1; - } - x = x1; - inc = (dx * 65536) / dy; - frac = 0; - for (y = y1; y <= y2; y++) { - gdImageSetAAPixelColor(im, x, y, col, (frac >> 8) & 0xFF); - if (x + 1 < im->sx) { - gdImageSetAAPixelColor(im, x + 1, y, col, (~frac >> 8) & 0xFF); - } - frac += inc; - if (frac >= 65536) { - frac -= 65536; - x++; - } else if (frac < 0) { - frac += 65536; - x--; - } - } - } -} - -static void dashedSet (gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, int vert); - -void gdImageDashedLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) -{ - int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; - int dashStep = 0; - int on = 1; - int wid; - int vert; - int thick = im->thick; - - dx = abs(x2 - x1); - dy = abs(y2 - y1); - if (dy <= dx) { - /* More-or-less horizontal. use wid for vertical stroke */ - /* 2.0.12: Michael Schwartz: divide rather than multiply; - TBB: but watch out for /0! */ - double as = sin(atan2(dy, dx)); - if (as != 0) { - wid = thick / as; - } else { - wid = 1; - } - vert = 1; - - d = 2 * dy - dx; - incr1 = 2 * dy; - incr2 = 2 * (dy - dx); - if (x1 > x2) { - x = x2; - y = y2; - ydirflag = (-1); - xend = x1; - } else { - x = x1; - y = y1; - ydirflag = 1; - xend = x2; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - if (((y2 - y1) * ydirflag) > 0) { - while (x < xend) { - x++; - if (d < 0) { - d += incr1; - } else { - y++; - d += incr2; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - } - } else { - while (x < xend) { - x++; - if (d < 0) { - d += incr1; - } else { - y--; - d += incr2; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - } - } - } else { - /* 2.0.12: Michael Schwartz: divide rather than multiply; - TBB: but watch out for /0! */ - double as = sin (atan2 (dy, dx)); - if (as != 0) { - wid = thick / as; - } else { - wid = 1; - } - vert = 0; - - d = 2 * dx - dy; - incr1 = 2 * dx; - incr2 = 2 * (dx - dy); - if (y1 > y2) { - y = y2; - x = x2; - yend = y1; - xdirflag = (-1); - } else { - y = y1; - x = x1; - yend = y2; - xdirflag = 1; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - if (((x2 - x1) * xdirflag) > 0) { - while (y < yend) { - y++; - if (d < 0) { - d += incr1; - } else { - x++; - d += incr2; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - } - } else { - while (y < yend) { - y++; - if (d < 0) { - d += incr1; - } else { - x--; - d += incr2; - } - dashedSet(im, x, y, color, &on, &dashStep, wid, vert); - } - } - } -} - -static void dashedSet (gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, int vert) -{ - int dashStep = *dashStepP; - int on = *onP; - int w, wstart; - - dashStep++; - if (dashStep == gdDashSize) { - dashStep = 0; - on = !on; - } - if (on) { - if (vert) { - wstart = y - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel(im, x, w, color); - } - } else { - wstart = x - wid / 2; - for (w = wstart; w < wstart + wid; w++) { - gdImageSetPixel(im, w, y, color); - } - } - } - *dashStepP = dashStep; - *onP = on; -} + (end code) + +*/ -void gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color) +BGD_DECLARE(void) gdImageDestroy(gdImagePtr im) { - int cx, cy; - int px, py; - int fline; - const int xuppper = (x > INT_MAX - f->w) ? INT_MAX : x + f->w; - const int yuppper = (y > INT_MAX - f->h) ? INT_MAX : y + f->h; - cx = 0; - cy = 0; -#ifdef CHARSET_EBCDIC - c = ASC (c); -#endif /*CHARSET_EBCDIC */ - if ((c < f->offset) || (c >= (f->offset + f->nchars))) { - return; - } - fline = (c - f->offset) * f->h * f->w; - for (py = y; py < yuppper; py++) { - for (px = x; px < xuppper; px++) { - if (f->data[fline + cy * f->w + cx]) { - gdImageSetPixel(im, px, py, color); - } - cx++; - } - cx = 0; - cy++; - } -} - -void gdImageCharUp (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color) -{ - int cx, cy; - int px, py; - int fline; - const int xuppper = (x > INT_MAX - f->h) ? INT_MAX : x + f->h; - const int ylower = (y < INT_MIN + f->w) ? INT_MIN : y - f->w; - cx = 0; - cy = 0; -#ifdef CHARSET_EBCDIC - c = ASC (c); -#endif /*CHARSET_EBCDIC */ - if ((c < f->offset) || (c >= (f->offset + f->nchars))) { - return; - } - fline = (c - f->offset) * f->h * f->w; - for (py = y; py > ylower; py--) { - for (px = x; px < xuppper; px++) { - if (f->data[fline + cy * f->w + cx]) { - gdImageSetPixel(im, px, py, color); - } - cy++; - } - cy = 0; - cx++; - } + int i; + if (im->pixels) { + for (i = 0; (i < im->sy); i++) { + gdFree(im->pixels[i]); + } + gdFree(im->pixels); + } + if (im->tpixels) { + for (i = 0; (i < im->sy); i++) { + gdFree(im->tpixels[i]); + } + gdFree(im->tpixels); + } + if (im->polyInts) { + gdFree(im->polyInts); + } + if (im->style) { + gdFree(im->style); + } + gdFree(im); } -void gdImageString (gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color) +/** + * Group: Color + */ + +/** + * Function: gdImageColorClosest + * + * Gets the closest color of the image + * + * This is a simplified variant of where the alpha + * channel is always opaque. + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * + * Returns: + * The closest color already available in the palette for palette images; + * the color value of the given components for truecolor images. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImageColorClosest(gdImagePtr im, int r, int g, int b) { - int i; - int l; - l = strlen ((char *) s); - for (i = 0; (i < l); i++) { - gdImageChar(im, f, x, y, s[i], color); - x += f->w; - } + return gdImageColorClosestAlpha(im, r, g, b, gdAlphaOpaque); } -void gdImageStringUp (gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color) +/** + * Function: gdImageColorClosestAlpha + * + * Gets the closest color of the image + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * a - The value of the alpha component. + * + * Returns: + * The closest color already available in the palette for palette images; + * the color value of the given components for truecolor images. + * + * See also: + * - + */ +BGD_DECLARE(int) +gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a) { - int i; - int l; - l = strlen ((char *) s); - for (i = 0; (i < l); i++) { - gdImageCharUp(im, f, x, y, s[i], color); - y -= f->w; - } + int i; + long rd, gd, bd, ad; + int ct = (-1); + int first = 1; + long mindist = 0; + + if (im->trueColor) { + return gdTrueColorAlpha(r, g, b, a); + } + for (i = 0; (i < (im->colorsTotal)); i++) { + long dist; + if (im->open[i]) { + continue; + } + rd = (im->red[i] - r); + gd = (im->green[i] - g); + bd = (im->blue[i] - b); + /* gd 2.02: whoops, was - b (thanks to David Marwood) */ + /* gd 2.16: was blue rather than alpha! Geez! Thanks to + Artur Jakub Jerzak */ + ad = (im->alpha[i] - a); + dist = rd * rd + gd * gd + bd * bd + ad * ad; + if (first || (dist < mindist)) { + mindist = dist; + ct = i; + first = 0; + } + } + return ct; } -static int strlen16 (unsigned short *s); +/* This code is taken from + * http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article on colour + * conversion to/from RBG and HWB colour systems. It has been modified to return + * the converted value as a * parameter. + */ +#define RETURN_HWB(h, w, b) \ + { \ + HWB->H = h; \ + HWB->W = w; \ + HWB->B = b; \ + return HWB; \ + } +#define RETURN_RGB(r, g, b) \ + { \ + RGB->R = r; \ + RGB->G = g; \ + RGB->B = b; \ + return RGB; \ + } +#define HWB_UNDEFINED -1 +#define SETUP_RGB(s, r, g, b) \ + { \ + s.R = r / 255.0; \ + s.G = g / 255.0; \ + s.B = b / 255.0; \ + } -void gdImageString16 (gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color) +/* + * Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. + * Pure red always maps to 6 in this implementation. Therefore UNDEFINED can be + * defined as 0 in situations where only unsigned numbers are desired. + */ +typedef struct { + float R, G, B; +} RGBType; +typedef struct { + float H, W, B; +} HWBType; + +static HWBType *RGB_to_HWB(RGBType RGB, HWBType *HWB) { - int i; - int l; - l = strlen16(s); - for (i = 0; (i < l); i++) { - gdImageChar(im, f, x, y, s[i], color); - x += f->w; - } + + /* + * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is + * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B. + */ + + float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f; + int i; + + w = MIN3(R, G, B); + v = MAX3(R, G, B); + b = 1 - v; + if (v == w) + RETURN_HWB(HWB_UNDEFINED, w, b); + f = (R == w) ? G - B : ((G == w) ? B - R : R - G); + i = (R == w) ? 3 : ((G == w) ? 5 : 1); + + RETURN_HWB(i - f / (v - w), w, b); } -void gdImageStringUp16 (gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color) +static float HWB_Diff(int r1, int g1, int b1, int r2, int g2, int b2) { - int i; - int l; - l = strlen16(s); - for (i = 0; i < l; i++) { - gdImageCharUp(im, f, x, y, s[i], color); - y -= f->w; - } + RGBType RGB1, RGB2; + HWBType HWB1, HWB2; + float diff; + + SETUP_RGB(RGB1, r1, g1, b1); + SETUP_RGB(RGB2, r2, g2, b2); + + RGB_to_HWB(RGB1, &HWB1); + RGB_to_HWB(RGB2, &HWB2); + + /* + * I made this bit up; it seems to produce OK results, and it is certainly + * more visually correct than the current RGB metric. (PJW) + */ + + if ((HWB1.H == HWB_UNDEFINED) || (HWB2.H == HWB_UNDEFINED)) { + diff = 0; /* Undefined hues always match... */ + } else { + diff = fabs(HWB1.H - HWB2.H); + if (diff > 3) { + diff = 6 - diff; /* Remember, it's a colour circle */ + } + } + + diff = + diff * diff + (HWB1.W - HWB2.W) * (HWB1.W - HWB2.W) + (HWB1.B - HWB2.B) * (HWB1.B - HWB2.B); + + return diff; } -static int strlen16 (unsigned short *s) +/* + Function: gdImageColorClosestHWB +*/ +BGD_DECLARE(int) gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b) { - int len = 0; - while (*s) { - s++; - len++; - } - return len; + int i; + /* long rd, gd, bd; */ + int ct = (-1); + int first = 1; + float mindist = 0; + if (im->trueColor) { + return gdTrueColor(r, g, b); + } + for (i = 0; (i < (im->colorsTotal)); i++) { + float dist; + if (im->open[i]) { + continue; + } + dist = HWB_Diff(im->red[i], im->green[i], im->blue[i], r, g, b); + if (first || (dist < mindist)) { + mindist = dist; + ct = i; + first = 0; + } + } + return ct; } -#ifndef HAVE_LSQRT -/* If you don't have a nice square root function for longs, you can use - ** this hack +/** + * Function: gdImageColorExact + * + * Gets the exact color of the image + * + * This is a simplified variant of where the alpha + * channel is always opaque. + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * + * Returns: + * The exact color already available in the palette for palette images; if + * there is no exact color, -1 is returned. + * For truecolor images the color value of the given components is returned. + * + * See also: + * - */ -long lsqrt (long n) +BGD_DECLARE(int) gdImageColorExact(gdImagePtr im, int r, int g, int b) { - long result = (long) sqrt ((double) n); - return result; + return gdImageColorExactAlpha(im, r, g, b, gdAlphaOpaque); } -#endif -/* s and e are integers modulo 360 (degrees), with 0 degrees - being the rightmost extreme and degrees changing clockwise. - cx and cy are the center in pixels; w and h are the horizontal - and vertical diameter in pixels. */ +/** + * Function: gdImageColorExactAlpha + * + * Gets the exact color of the image + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * a - The value of the alpha component. + * + * Returns: + * The exact color already available in the palette for palette images; if + * there is no exact color, -1 is returned. + * For truecolor images the color value of the given components is returned. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) +gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a) +{ + int i; + if (im->trueColor) { + return gdTrueColorAlpha(r, g, b, a); + } + for (i = 0; (i < (im->colorsTotal)); i++) { + if (im->open[i]) { + continue; + } + if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b) && (im->alpha[i] == a)) { + return i; + } + } + return -1; +} -void gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color) -{ - gdImageFilledArc(im, cx, cy, w, h, s, e, color, gdNoFill); -} - -void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style) -{ - gdPoint pts[363]; - int i, pti; - int lx = 0, ly = 0; - int fx = 0, fy = 0; - int startx = -1, starty = -1, endx = -1, endy = -1; - - if ((s % 360) == (e % 360)) { - s = 0; e = 360; - } else { - if (s > 360) { - s = s % 360; - } - - if (e > 360) { - e = e % 360; - } - - while (s < 0) { - s += 360; - } - - while (e < s) { - e += 360; - } - if (s == e) { - s = 0; e = 360; - } - } - - for (i = s, pti = 1; i <= e; i++, pti++) { - int x, y; - x = endx = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx; - y = endy = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy; - if (i != s) { - if (!(style & gdChord)) { - if (style & gdNoFill) { - gdImageLine(im, lx, ly, x, y, color); - } else { - if (y == ly) { - pti--; /* don't add this point */ - if (((i > 270 || i < 90) && x > lx) || ((i > 90 && i < 270) && x < lx)) { - /* replace the old x coord, if increasing on the - right side or decreasing on the left side */ - pts[pti].x = x; - } - } else { - pts[pti].x = x; - pts[pti].y = y; - } - } - } - } else { - fx = x; - fy = y; - if (!(style & (gdChord | gdNoFill))) { - pts[0].x = cx; - pts[0].y = cy; - pts[pti].x = startx = x; - pts[pti].y = starty = y; - } - } - lx = x; - ly = y; - } - if (style & gdChord) { - if (style & gdNoFill) { - if (style & gdEdged) { - gdImageLine(im, cx, cy, lx, ly, color); - gdImageLine(im, cx, cy, fx, fy, color); - } - gdImageLine(im, fx, fy, lx, ly, color); - } else { - pts[0].x = fx; - pts[0].y = fy; - pts[1].x = lx; - pts[1].y = ly; - pts[2].x = cx; - pts[2].y = cy; - gdImageFilledPolygon(im, pts, 3, color); - } - } else { - if (style & gdNoFill) { - if (style & gdEdged) { - gdImageLine(im, cx, cy, lx, ly, color); - gdImageLine(im, cx, cy, fx, fy, color); - } - } else { - if (e - s < 360) { - if (pts[1].x != startx && pts[1].y == starty) { - /* start point has been removed due to y-coord fix => insert it */ - for (i = pti; i > 1; i--) { - pts[i].x = pts[i-1].x; - pts[i].y = pts[i-1].y; - } - pts[1].x = startx; - pts[1].y = starty; - pti++; - } - if (pts[pti-1].x != endx && pts[pti-1].y == endy) { - /* end point has been removed due to y-coord fix => insert it */ - pts[pti].x = endx; - pts[pti].y = endy; - pti++; - } - } - pts[pti].x = cx; - pts[pti].y = cy; - gdImageFilledPolygon(im, pts, pti+1, color); - } - } +/** + * Function: gdImageColorAllocate + * + * Allocates a color + * + * This is a simplified variant of where the alpha + * channel is always opaque. + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * + * Returns: + * The color value. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImageColorAllocate(gdImagePtr im, int r, int g, int b) +{ + return gdImageColorAllocateAlpha(im, r, g, b, gdAlphaOpaque); } /** - * Integer Ellipse functions (gdImageEllipse and gdImageFilledEllipse) - * Function added by Pierre-Alain Joye 02/08/2003 (paj@pearfr.org) - * See the ellipse function simplification for the equation - * as well as the midpoint algorithm. + * Function: gdImageColorAllocateAlpha + * + * Allocates a color + * + * This is typically used for palette images, but can be used for truecolor + * images as well. + * + * Parameters: + * im - The image. + * r - The value of the red component. + * g - The value of the green component. + * b - The value of the blue component. + * + * Returns: + * The color value. + * + * See also: + * - */ +BGD_DECLARE(int) +gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a) +{ + int i; + int ct = (-1); + if (im->trueColor) { + return gdTrueColorAlpha(r, g, b, a); + } + for (i = 0; (i < (im->colorsTotal)); i++) { + if (im->open[i]) { + ct = i; + break; + } + } + if (ct == (-1)) { + ct = im->colorsTotal; + if (ct == gdMaxColors) { + return -1; + } + im->colorsTotal++; + } + im->red[ct] = r; + im->green[ct] = g; + im->blue[ct] = b; + im->alpha[ct] = a; + im->open[ct] = 0; -void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) -{ - int x=0,mx1=0,mx2=0,my1=0,my2=0; - int64_t aq,bq,dx,dy,r,rx,ry,a,b; - - a=w>>1; - b=h>>1; - gdImageSetPixel(im,mx+a, my, c); - gdImageSetPixel(im,mx-a, my, c); - mx1 = mx-a;my1 = my; - mx2 = mx+a;my2 = my; - - aq = a * a; - bq = b * b; - dx = aq << 1; - dy = bq << 1; - r = a * bq; - rx = r << 1; - ry = 0; - x = a; - while (x > 0){ - if (r > 0) { - my1++;my2--; - ry +=dx; - r -=ry; - } - if (r <= 0){ - x--; - mx1++;mx2--; - rx -=dy; - r +=rx; - } - gdImageSetPixel(im,mx1, my1, c); - gdImageSetPixel(im,mx1, my2, c); - gdImageSetPixel(im,mx2, my1, c); - gdImageSetPixel(im,mx2, my2, c); - } -} - -void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) -{ - int x=0,mx1=0,mx2=0,my1=0,my2=0; - int64_t aq,bq,dx,dy,r,rx,ry,a,b; - int i; - int old_y2; - - a=w>>1; - b=h>>1; - - for (x = mx-a; x <= mx+a; x++) { - gdImageSetPixel(im, x, my, c); - } - - mx1 = mx-a;my1 = my; - mx2 = mx+a;my2 = my; - - aq = a * a; - bq = b * b; - dx = aq << 1; - dy = bq << 1; - r = a * bq; - rx = r << 1; - ry = 0; - x = a; - old_y2=-2; - while (x > 0){ - if (r > 0) { - my1++;my2--; - ry +=dx; - r -=ry; - } - if (r <= 0){ - x--; - mx1++;mx2--; - rx -=dy; - r +=rx; - } - if(old_y2!=my2){ - for(i=mx1;i<=mx2;i++){ - gdImageSetPixel(im,i,my1,c); - gdImageSetPixel(im,i,my2,c); - } - } - old_y2 = my2; - } -} - -void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) -{ - int lastBorder; - /* Seek left */ - int leftLimit = -1, rightLimit; - int i, restoreAlphaBlending = 0; - - if (border < 0 || color < 0) { - /* Refuse to fill to a non-solid border */ - return; - } - - if (!im->trueColor) { - if ((color > (im->colorsTotal - 1)) || (border > (im->colorsTotal - 1)) || (color < 0)) { - return; - } - } - - restoreAlphaBlending = im->alphaBlendingFlag; - im->alphaBlendingFlag = 0; - - if (x >= im->sx) { - x = im->sx - 1; - } else if (x < 0) { - x = 0; - } - if (y >= im->sy) { - y = im->sy - 1; - } else if (y < 0) { - y = 0; - } - - for (i = x; i >= 0; i--) { - if (gdImageGetPixel(im, i, y) == border) { - break; - } - gdImageSetPixel(im, i, y, color); - leftLimit = i; - } - if (leftLimit == -1) { - im->alphaBlendingFlag = restoreAlphaBlending; - return; - } - /* Seek right */ - rightLimit = x; - for (i = (x + 1); i < im->sx; i++) { - if (gdImageGetPixel(im, i, y) == border) { - break; - } - gdImageSetPixel(im, i, y, color); - rightLimit = i; - } - /* Look at lines above and below and start paints */ - /* Above */ - if (y > 0) { - lastBorder = 1; - for (i = leftLimit; i <= rightLimit; i++) { - int c = gdImageGetPixel(im, i, y - 1); - if (lastBorder) { - if ((c != border) && (c != color)) { - gdImageFillToBorder(im, i, y - 1, border, color); - lastBorder = 0; - } - } else if ((c == border) || (c == color)) { - lastBorder = 1; - } - } - } - - /* Below */ - if (y < ((im->sy) - 1)) { - lastBorder = 1; - for (i = leftLimit; i <= rightLimit; i++) { - int c = gdImageGetPixel(im, i, y + 1); - - if (lastBorder) { - if ((c != border) && (c != color)) { - gdImageFillToBorder(im, i, y + 1, border, color); - lastBorder = 0; - } - } else if ((c == border) || (c == color)) { - lastBorder = 1; - } - } - } - im->alphaBlendingFlag = restoreAlphaBlending; + return ct; } /* - * set the pixel at (x,y) and its 4-connected neighbors - * with the same pixel value to the new pixel value nc (new color). - * A 4-connected neighbor: pixel above, below, left, or right of a pixel. - * ideas from comp.graphics discussions. - * For tiled fill, the use of a flag buffer is mandatory. As the tile image can - * contain the same color as the color to fill. To do not bloat normal filling - * code I added a 2nd private function. + Function: gdImageColorResolve + + gdImageColorResolve is an alternative for the code fragment + (start code) + if ((color=gdImageColorExact(im,R,G,B)) < 0) + if ((color=gdImageColorAllocate(im,R,G,B)) < 0) + color=gdImageColorClosest(im,R,G,B); + (end code) + in a single function. Its advantage is that it is guaranteed to + return a color index in one search over the color table. */ -/* horizontal segment of scan line y */ -struct seg {int y, xl, xr, dy;}; - -/* max depth of stack */ -#define FILL_MAX ((int)(im->sy*im->sx)/4) -#define FILL_PUSH(Y, XL, XR, DY) \ - if (sp=0 && Y+(DY)y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;} - -#define FILL_POP(Y, XL, XR, DY) \ - {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;} - -static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc); - -void gdImageFill(gdImagePtr im, int x, int y, int nc) -{ - int l, x1, x2, dy; - int oc; /* old pixel value */ - int wx2,wy2; - - int alphablending_bak; - - /* stack of filled segments */ - /* struct seg stack[FILL_MAX],*sp = stack; */ - struct seg *stack = NULL; - struct seg *sp; - - if (!im->trueColor && nc > (im->colorsTotal -1)) { - return; - } - - alphablending_bak = im->alphaBlendingFlag; - im->alphaBlendingFlag = 0; - - if (nc==gdTiled){ - _gdImageFillTiled(im,x,y,nc); - im->alphaBlendingFlag = alphablending_bak; - return; - } - - wx2=im->sx;wy2=im->sy; - oc = gdImageGetPixel(im, x, y); - if (oc==nc || x<0 || x>wx2 || y<0 || y>wy2) { - im->alphaBlendingFlag = alphablending_bak; - return; - } - - /* Do not use the 4 neighbors implementation with - * small images - */ - if (im->sx < 4) { - int ix = x, iy = y, c; - do { - do { - c = gdImageGetPixel(im, ix, iy); - if (c != oc) { - goto done; - } - gdImageSetPixel(im, ix, iy, nc); - } while(ix++ < (im->sx -1)); - ix = x; - } while(iy++ < (im->sy -1)); - goto done; - } - - if(overflow2(im->sy, im->sx)) { - return; - } - - if(overflow2(sizeof(struct seg), ((im->sy * im->sx) / 4))) { - return; - } - - stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); - sp = stack; - - /* required! */ - FILL_PUSH(y,x,x,1); - /* seed segment (popped 1st) */ - FILL_PUSH(y+1, x, x, -1); - while (sp>stack) { - FILL_POP(y, x1, x2, dy); - - for (x=x1; x>=0 && gdImageGetPixel(im,x, y)==oc; x--) { - gdImageSetPixel(im,x, y, nc); - } - if (x>=x1) { - goto skip; - } - l = x+1; - - /* leak on left? */ - if (lx2+1) { - FILL_PUSH(y, x2+1, x-1, -dy); - } -skip: - for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++); - - l = x; - } while (x<=x2); - } - - efree(stack); - -done: - im->alphaBlendingFlag = alphablending_bak; +BGD_DECLARE(int) gdImageColorResolve(gdImagePtr im, int r, int g, int b) +{ + return gdImageColorResolveAlpha(im, r, g, b, gdAlphaOpaque); } -static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) +/* + Function: gdImageColorResolveAlpha +*/ +BGD_DECLARE(int) gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a) { - int l, x1, x2, dy; - int oc; /* old pixel value */ - int wx2,wy2; - /* stack of filled segments */ - struct seg *stack; - struct seg *sp; - char *pts; - - if (!im->tile) { - return; - } - - wx2=im->sx;wy2=im->sy; - - nc = gdImageTileGet(im,x,y); - - if(overflow2(im->sy, im->sx)) { - return; - } - - if(overflow2(sizeof(struct seg), ((im->sy * im->sx) / 4))) { - return; - } - - pts = (char *) ecalloc(im->sy * im->sx, sizeof(char)); - - stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); - sp = stack; - - oc = gdImageGetPixel(im, x, y); - - /* required! */ - FILL_PUSH(y,x,x,1); - /* seed segment (popped 1st) */ - FILL_PUSH(y+1, x, x, -1); - while (sp>stack) { - FILL_POP(y, x1, x2, dy); - for (x=x1; x>=0 && (!pts[y + x*wy2] && gdImageGetPixel(im,x,y)==oc); x--) { - nc = gdImageTileGet(im,x,y); - pts[y + x*wy2] = 1; - gdImageSetPixel(im,x, y, nc); - } - if (x>=x1) { - goto skip; - } - l = x+1; - - /* leak on left? */ - if (lx2+1) { - FILL_PUSH(y, x2+1, x-1, -dy); - } -skip: - for(x++; x<=x2 && (pts[y + x*wy2] || gdImageGetPixel(im,x, y)!=oc); x++); - l = x; - } while (x<=x2); - } + int c; + int ct = -1; + int op = -1; + long rd, gd, bd, ad, dist; + long mindist = 4 * 255 * 255; /* init to max poss dist */ + if (im->trueColor) { + return gdTrueColorAlpha(r, g, b, a); + } - efree(pts); - efree(stack); + for (c = 0; c < im->colorsTotal; c++) { + if (im->open[c]) { + op = c; /* Save open slot */ + continue; /* Color not in use */ + } + if (c == im->transparent) { + /* don't ever resolve to the color that has + * been designated as the transparent color */ + continue; + } + rd = (long)(im->red[c] - r); + gd = (long)(im->green[c] - g); + bd = (long)(im->blue[c] - b); + ad = (long)(im->alpha[c] - a); + dist = rd * rd + gd * gd + bd * bd + ad * ad; + if (dist < mindist) { + if (dist == 0) { + return c; /* Return exact match color */ + } + mindist = dist; + ct = c; + } + } + /* no exact match. We now know closest, but first try to allocate exact */ + if (op == -1) { + op = im->colorsTotal; + if (op == gdMaxColors) { + /* No room for more colors */ + return ct; /* Return closest available color */ + } + im->colorsTotal++; + } + im->red[op] = r; + im->green[op] = g; + im->blue[op] = b; + im->alpha[op] = a; + im->open[op] = 0; + return op; /* Return newly allocated color */ } - - -void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) +/** + * Function: gdImageColorDeallocate + * + * Removes a palette entry + * + * This is a no-op for truecolor images. + * The function does not alter the image data nor the transparent color or any + * other places where this color index could have been referenced. + * The index is marked as open and will be used too for any subsequent + * or calls. Other lower + * index may be open as well, the fist open index found will be used. + * + * Parameters: + * im - The image. + * color - The palette index. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) gdImageColorDeallocate(gdImagePtr im, int color) { - int thick = im->thick; - int t; - - if (x1 == x2 && y1 == y2 && thick == 1) { - gdImageSetPixel(im, x1, y1, color); - return; - } + if (im->trueColor || (color >= gdMaxColors) || (color < 0)) { + return; + } + /* Mark it open. */ + im->open[color] = 1; +} - if (y2 < y1) { - t=y1; - y1 = y2; - y2 = t; - } +/** + * Function: gdImageColorTransparent + * + * Sets the transparent color of the image + * + * Parameter: + * im - The image. + * color - The color. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageColorTransparent(gdImagePtr im, int color) +{ + // Reset ::transparent + if (color == -1) { + im->transparent = -1; + return; + } + if (color < -1) { + return; + } - if (x2 < x1) { - t = x1; - x1 = x2; - x2 = t; - } + if (im->trueColor) { + im->transparent = color; + return; + } - if (thick > 1) { - int cx, cy, x1ul, y1ul, x2lr, y2lr; - int half = thick >> 1; + // Palette Image + if (color >= gdMaxColors) { + return; + } + if (im->transparent != -1) { + im->alpha[im->transparent] = gdAlphaOpaque; + } + im->alpha[color] = gdAlphaTransparent; + im->transparent = color; +} - x1ul = x1 - half; - y1ul = y1 - half; +/* + Function: gdImagePaletteCopy +*/ +BGD_DECLARE(void) gdImagePaletteCopy(gdImagePtr to, gdImagePtr from) +{ + int i; + int x, y, p; + int xlate[256]; + if (to->trueColor || from->trueColor) { + return; + } + for (i = 0; i < 256; i++) { + xlate[i] = -1; + }; + + for (y = 0; y < (to->sy); y++) { + for (x = 0; x < (to->sx); x++) { + /* Optimization: no gdImageGetPixel */ + p = to->pixels[y][x]; + if (xlate[p] == -1) { + /* This ought to use HWB, but we don't have an alpha-aware + version of that yet. */ + xlate[p] = gdImageColorClosestAlpha(from, to->red[p], to->green[p], to->blue[p], + to->alpha[p]); + /*printf("Mapping %d (%d, %d, %d, %d) to %d (%d, %d, %d, %d)\n", + */ + /* p, to->red[p], to->green[p], to->blue[p], to->alpha[p], + */ + /* xlate[p], from->red[xlate[p]], from->green[xlate[p]], + * from->blue[xlate[p]], from->alpha[xlate[p]]); */ + }; + /* Optimization: no gdImageSetPixel */ + to->pixels[y][x] = xlate[p]; + }; + }; + + for (i = 0; (i < (from->colorsTotal)); i++) { + to->red[i] = from->red[i]; + to->blue[i] = from->blue[i]; + to->green[i] = from->green[i]; + to->alpha[i] = from->alpha[i]; + to->open[i] = 0; + }; + + for (i = from->colorsTotal; (i < to->colorsTotal); i++) { + to->open[i] = 1; + }; + + to->colorsTotal = from->colorsTotal; +} - x2lr = x2 + half; - y2lr = y2 + half; +/* + Function: gdImageColorReplace +*/ +BGD_DECLARE(int) gdImageColorReplace(gdImagePtr im, int src, int dst) +{ + register int x, y; + int n = 0; - cy = y1ul + thick; - while (cy-- > y1ul) { - cx = x1ul - 1; - while (cx++ < x2lr) { - gdImageSetPixel(im, cx, cy, color); - } - } + if (src == dst) { + return 0; + } - cy = y2lr - thick; - while (cy++ < y2lr) { - cx = x1ul - 1; - while (cx++ < x2lr) { - gdImageSetPixel(im, cx, cy, color); - } - } +#define REPLACING_LOOP(pixel) \ + do { \ + for (y = im->cy1; y <= im->cy2; y++) { \ + for (x = im->cx1; x <= im->cx2; x++) { \ + if (pixel(im, x, y) == src) { \ + gdImageSetPixel(im, x, y, dst); \ + n++; \ + } \ + } \ + } \ + } while (0) + + if (im->trueColor) { + REPLACING_LOOP(gdImageTrueColorPixel); + } else { + REPLACING_LOOP(gdImagePalettePixel); + } - cy = y1ul + thick - 1; - while (cy++ < y2lr -thick) { - cx = x1ul - 1; - while (cx++ < x1ul + thick) { - gdImageSetPixel(im, cx, cy, color); - } - } +#undef REPLACING_LOOP - cy = y1ul + thick - 1; - while (cy++ < y2lr -thick) { - cx = x2lr - thick - 1; - while (cx++ < x2lr) { - gdImageSetPixel(im, cx, cy, color); - } - } - - return; - } else { - if (x1 == x2 || y1 == y2) { - gdImageLine(im, x1, y1, x2, y2, color); - } else { - gdImageLine(im, x1, y1, x2, y1, color); - gdImageLine(im, x1, y2, x2, y2, color); - gdImageLine(im, x1, y1 + 1, x1, y2 - 1, color); - gdImageLine(im, x2, y1 + 1, x2, y2 - 1, color); - } - } + return n; +} + +/* + Function: gdImageColorReplaceThreshold + Note: threshold semantics changed in versions >=2.3.4 — the value now scales + linearly with perceptual color distance. Callers using threshold values + tuned against the old behavior should apply new_t = sqrt(old_t / 100) * 100 + to approximate the previous behavior. This is due to a bug fix in the color + distance calculation, which previously did not take the square root + of the sum of squares, and thus returned a value that was the square + of the actual perceptual color distance. + The new behavior is more intuitive and consistent with common color distance + metrics +*/ +BGD_DECLARE(int) +gdImageColorReplaceThreshold(gdImagePtr im, int src, int dst, float threshold) +{ + register int x, y; + int n = 0; + + if (src == dst) { + return 0; + } + +#define REPLACING_LOOP(pixel) \ + do { \ + for (y = im->cy1; y <= im->cy2; y++) { \ + for (x = im->cx1; x <= im->cx2; x++) { \ + if (gdColorMatch(im, src, pixel(im, x, y), threshold)) { \ + gdImageSetPixel(im, x, y, dst); \ + n++; \ + } \ + } \ + } \ + } while (0) + + if (im->trueColor) { + REPLACING_LOOP(gdImageTrueColorPixel); + } else { + REPLACING_LOOP(gdImagePalettePixel); + } + +#undef REPLACING_LOOP + + return n; +} + +static int colorCmp(const void *x, const void *y) +{ + int a = *(int const *)x; + int b = *(int const *)y; + return (a > b) - (a < b); +} + +/* + Function: gdImageColorReplaceArray +*/ +BGD_DECLARE(int) +gdImageColorReplaceArray(gdImagePtr im, int len, int *src, int *dst) +{ + register int x, y; + int c, *d, *base; + int i, n = 0; + + if (len <= 0 || src == dst) { + return 0; + } + if (len == 1) { + return gdImageColorReplace(im, src[0], dst[0]); + } + if (overflow2(len, sizeof(int) << 1)) { + return -1; + } + base = (int *)gdMalloc(len * (sizeof(int) << 1)); + if (!base) { + return -1; + } + for (i = 0; i < len; i++) { + base[(i << 1)] = src[i]; + base[(i << 1) + 1] = dst[i]; + } + qsort(base, len, sizeof(int) << 1, colorCmp); + +#define REPLACING_LOOP(pixel) \ + do { \ + for (y = im->cy1; y <= im->cy2; y++) { \ + for (x = im->cx1; x <= im->cx2; x++) { \ + c = pixel(im, x, y); \ + if ((d = (int *)bsearch(&c, base, len, sizeof(int) << 1, colorCmp))) { \ + gdImageSetPixel(im, x, y, d[1]); \ + n++; \ + } \ + } \ + } \ + } while (0) + + if (im->trueColor) { + REPLACING_LOOP(gdImageTrueColorPixel); + } else { + REPLACING_LOOP(gdImagePalettePixel); + } + +#undef REPLACING_LOOP + + gdFree(base); + return n; +} + +/* + Function: gdImageColorReplaceCallback +*/ +BGD_DECLARE(int) +gdImageColorReplaceCallback(gdImagePtr im, gdCallbackImageColor callback) +{ + int c, d, n = 0; + + if (!callback) { + return 0; + } + if (im->trueColor) { + register int x, y; + + for (y = im->cy1; y <= im->cy2; y++) { + for (x = im->cx1; x <= im->cx2; x++) { + c = gdImageTrueColorPixel(im, x, y); + if ((d = callback(im, c)) != c) { + gdImageSetPixel(im, x, y, d); + n++; + } + } + } + } else { /* palette */ + int *sarr, *darr; + int k, len = 0; + + sarr = (int *)gdCalloc(im->colorsTotal, sizeof(int)); + if (!sarr) { + return -1; + } + for (c = 0; c < im->colorsTotal; c++) { + if (!im->open[c]) { + sarr[len++] = c; + } + } + darr = (int *)gdCalloc(len, sizeof(int)); + if (!darr) { + gdFree(sarr); + return -1; + } + for (k = 0; k < len; k++) { + darr[k] = callback(im, sarr[k]); + } + n = gdImageColorReplaceArray(im, k, sarr, darr); + gdFree(darr); + gdFree(sarr); + } + return n; +} + +/* 2.0.10: before the drawing routines, some code to clip points that are + * outside the drawing window. Nick Atty (nick@canalplan.org.uk) + * + * This is the Sutherland Hodgman Algorithm, as implemented by + * Duvanenko, Robbins and Gyurcsik - SH(DRG) for short. See Dr Dobb's + * Journal, January 1996, pp107-110 and 116-117 + * + * Given the end points of a line, and a bounding rectangle (which we + * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on + * the edges of the rectangle if the line should be drawn at all, + * otherwise return a failure code */ + +/* this does "one-dimensional" clipping: note that the second time it + is called, all the x parameters refer to height and the y to width + - the comments ignore this (if you can understand it when it's + looking at the X parameters, it should become clear what happens on + the second call!) The code is simplified from that in the article, + as we know that gd images always start at (0,0) */ + +/* 2.0.26, TBB: we now have to respect a clipping rectangle, it won't + necessarily start at 0. */ + +static int clip_1d(int *x0, int *y0, int *x1, int *y1, int mindim, int maxdim) +{ + double m; /* gradient of line */ + if (*x0 < mindim) { + /* start of line is left of window */ + if (*x1 < mindim) /* as is the end, so the line never cuts the window */ + return 0; + m = (*y1 - *y0) / (double)(*x1 - *x0); /* calculate the slope of the line */ + /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match + */ + *y0 -= (int)(m * (*x0 - mindim)); + *x0 = mindim; + /* now, perhaps, adjust the far end of the line as well */ + if (*x1 > maxdim) { + *y1 += (int)(m * (maxdim - *x1)); + *x1 = maxdim; + } + return 1; + } + if (*x0 > maxdim) { + /* start of line is right of window - + complement of above */ + if (*x1 > maxdim) /* as is the end, so the line misses the window */ + return 0; + m = (*y1 - *y0) / (double)(*x1 - *x0); /* calculate the slope of the line */ + *y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right + boundary */ + *x0 = maxdim; + /* now, perhaps, adjust the end of the line */ + if (*x1 < mindim) { + *y1 -= (int)(m * (*x1 - mindim)); + *x1 = mindim; + } + return 1; + } + /* the final case - the start of the line is inside the window */ + if (*x1 > maxdim) { + /* other end is outside to the right */ + m = (*y1 - *y0) / (double)(*x1 - *x0); /* calculate the slope of the line */ + *y1 += (int)(m * (maxdim - *x1)); + *x1 = maxdim; + return 1; + } + if (*x1 < mindim) { + /* other end is outside to the left */ + m = (*y1 - *y0) / (double)(*x1 - *x0); /* calculate the slope of the line */ + *y1 -= (int)(m * (*x1 - mindim)); + *x1 = mindim; + return 1; + } + /* only get here if both points are inside the window */ + return 1; +} + +/** + * Group: Pixels + */ + +/* + Function: gdImageSetPixel +*/ +BGD_DECLARE(void) gdImageSetPixel(gdImagePtr im, int x, int y, int color) +{ + int p; + switch (color) { + case gdStyled: + if (!im->style) { + /* Refuse to draw if no style is set. */ + return; + } else { + p = im->style[im->stylePos++]; + } + if (p != (gdTransparent)) { + gdImageSetPixel(im, x, y, p); + } + im->stylePos = im->stylePos % im->styleLength; + break; + case gdStyledBrushed: + if (!im->style) { + /* Refuse to draw if no style is set. */ + return; + } + p = im->style[im->stylePos++]; + if ((p != gdTransparent) && (p != 0)) { + gdImageSetPixel(im, x, y, gdBrushed); + } + im->stylePos = im->stylePos % im->styleLength; + break; + case gdBrushed: + gdImageBrushApply(im, x, y); + break; + case gdTiled: + gdImageTileApply(im, x, y); + break; + case gdAntiAliased: + /* This shouldn't happen (2.0.26) because we just call + gdImageAALine now, but do something sane. */ + gdImageSetPixel(im, x, y, im->AA_color); + break; + default: + if (gdImageBoundsSafeMacro(im, x, y)) { + if (im->trueColor) { + switch (im->alphaBlendingFlag) { + default: + case gdEffectReplace: + im->tpixels[y][x] = color; + break; + case gdEffectAlphaBlend: + case gdEffectNormal: + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); + break; + case gdEffectOverlay: + im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color); + break; + case gdEffectMultiply: + im->tpixels[y][x] = gdLayerMultiply(im->tpixels[y][x], color); + break; + } + } else { + im->pixels[y][x] = color; + } + } + break; + } +} + +static void gdImageBrushApply(gdImagePtr im, int x, int y) +{ + int lx, ly; + int hy; + int hx; + int x1, y1, x2, y2; + int srcx, srcy; + + if (!im->brush) { + return; + } + hy = gdImageSY(im->brush) / 2; + y1 = y - hy; + y2 = y1 + gdImageSY(im->brush); + hx = gdImageSX(im->brush) / 2; + x1 = x - hx; + x2 = x1 + gdImageSX(im->brush); + srcy = 0; + if (im->trueColor) { + if (im->brush->trueColor) { + for (ly = y1; (ly < y2); ly++) { + srcx = 0; + for (lx = x1; (lx < x2); lx++) { + int p; + p = gdImageGetTrueColorPixel(im->brush, srcx, srcy); + /* 2.0.9, Thomas Winzig: apply simple full transparency */ + if (p != gdImageGetTransparent(im->brush)) { + gdImageSetPixel(im, lx, ly, p); + } + srcx++; + } + srcy++; + } + } else { + /* 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger for pointing out + * the issue) */ + for (ly = y1; (ly < y2); ly++) { + srcx = 0; + for (lx = x1; (lx < x2); lx++) { + int p, tc; + p = gdImageGetPixel(im->brush, srcx, srcy); + tc = gdImageGetTrueColorPixel(im->brush, srcx, srcy); + /* 2.0.9, Thomas Winzig: apply simple full transparency */ + if (p != gdImageGetTransparent(im->brush)) { + gdImageSetPixel(im, lx, ly, tc); + } + srcx++; + } + srcy++; + } + } + } else { + for (ly = y1; (ly < y2); ly++) { + srcx = 0; + for (lx = x1; (lx < x2); lx++) { + int p; + p = gdImageGetPixel(im->brush, srcx, srcy); + /* Allow for non-square brushes! */ + if (p != gdImageGetTransparent(im->brush)) { + if (im->brush->trueColor) { + gdImageSetPixel(im, lx, ly, + gdImageColorResolveAlpha( + im, gdTrueColorGetRed(p), gdTrueColorGetGreen(p), + gdTrueColorGetBlue(p), gdTrueColorGetAlpha(p))); + } else { + gdImageSetPixel(im, lx, ly, im->brushColorMap[p]); + } + } + srcx++; + } + srcy++; + } + } +} + +static void gdImageTileApply(gdImagePtr im, int x, int y) +{ + gdImagePtr tile = im->tile; + int srcx, srcy; + int p; + if (!tile) { + return; + } + srcx = x % gdImageSX(tile); + srcy = y % gdImageSY(tile); + if (im->trueColor) { + p = gdImageGetPixel(tile, srcx, srcy); + if (p != gdImageGetTransparent(tile)) { + if (!tile->trueColor) { + p = gdTrueColorAlpha(tile->red[p], tile->green[p], tile->blue[p], tile->alpha[p]); + } + gdImageSetPixel(im, x, y, p); + } + } else { + p = gdImageGetPixel(tile, srcx, srcy); + /* Allow for transparency */ + if (p != gdImageGetTransparent(tile)) { + if (tile->trueColor) { + /* Truecolor tile. Very slow on a palette destination. */ + gdImageSetPixel( + im, x, y, + gdImageColorResolveAlpha(im, gdTrueColorGetRed(p), gdTrueColorGetGreen(p), + gdTrueColorGetBlue(p), gdTrueColorGetAlpha(p))); + } else { + gdImageSetPixel(im, x, y, im->tileColorMap[p]); + } + } + } +} + +/** + * Function: gdImageGetPixel + * + * Gets a pixel color as stored in the image. + * + * Parameters: + * im - The image. + * x - The x-coordinate. + * y - The y-coordinate. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(int) gdImageGetPixel(gdImagePtr im, int x, int y) +{ + if (gdImageBoundsSafeMacro(im, x, y)) { + if (im->trueColor) { + return im->tpixels[y][x]; + } else { + return im->pixels[y][x]; + } + } else { + return 0; + } +} + +/** + * Function: gdImageGetTrueColorPixel + * + * Gets a pixel color always as truecolor value. + * + * Parameters: + * im - The image. + * x - The x-coordinate. + * y - The y-coordinate. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) gdImageGetTrueColorPixel(gdImagePtr im, int x, int y) +{ + int p = gdImageGetPixel(im, x, y); + if (!im->trueColor) { + return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], + (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]); + } else { + return p; + } +} + +/** + * Group: Primitives + */ + +/* + Function: gdImageAABlend + + NO-OP, kept for library compatibility. +*/ +BGD_DECLARE(void) gdImageAABlend(gdImagePtr im) { (void)im; } +static void _gdImageFilledHRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); + +static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col) +{ + if (im->thick > 1) { + int thickhalf = im->thick >> 1; + _gdImageFilledHRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col); + } else { + if (x2 < x1) { + int t = x2; + x2 = x1; + x1 = t; + } + + for (; x1 <= x2; x1++) { + gdImageSetPixel(im, x1, y, col); + } + } + return; +} + +static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col) +{ + if (im->thick > 1) { + int thickhalf = im->thick >> 1; + gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col); + } else { + if (y2 < y1) { + int t = y1; + y1 = y2; + y2 = t; + } + + for (; y1 <= y2; y1++) { + gdImageSetPixel(im, x, y1, col); + } + } + return; +} + +/* + Function: gdImageLine + + Bresenham as presented in Foley & Van Dam. +*/ +BGD_DECLARE(void) gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; + int wid; + int w, wstart; + int thick = im->thick; + + if (color == gdAntiAliased) { + /* + gdAntiAliased passed as color: use the much faster, much cheaper + and equally attractive gdImageAALine implementation. That + clips too, so don't clip twice. + */ + gdImageAALine(im, x1, y1, x2, y2, im->AA_color); + return; + } + /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no + points need to be drawn. 2.0.26, TBB: clip to edges of clipping + rectangle. We were getting away with this because gdImageSetPixel + is used for actual drawing, but this is still more efficient and opens + the way to skip per-pixel bounds checking in the future. */ + + if (clip_1d(&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0) + return; + if (clip_1d(&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0) + return; + + dx = abs(x2 - x1); + dy = abs(y2 - y1); + + if (dx == 0) { + gdImageVLine(im, x1, y1, y2, color); + return; + } else if (dy == 0) { + gdImageHLine(im, y1, x1, x2, color); + return; + } + + if (dy <= dx) { + /* More-or-less horizontal. use wid for vertical stroke */ + /* Doug Claar: watch out for NaN in atan2 (2.0.5) */ + if ((dx == 0) && (dy == 0)) { + wid = 1; + } else { + /* 2.0.12: Michael Schwartz: divide rather than multiply; +TBB: but watch out for /0! */ + double ac = cos(atan2(dy, dx)); + if (ac != 0) { + wid = thick / ac; + } else { + wid = 1; + } + if (wid == 0) { + wid = 1; + } + } + d = 2 * dy - dx; + incr1 = 2 * dy; + incr2 = 2 * (dy - dx); + if (x1 > x2) { + x = x2; + y = y2; + ydirflag = (-1); + xend = x1; + } else { + x = x1; + y = y1; + ydirflag = 1; + xend = x2; + } + + /* Set up line thickness */ + wstart = y - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, x, w, color); + } + + if (((y2 - y1) * ydirflag) > 0) { + while (x < xend) { + x++; + if (d < 0) { + d += incr1; + } else { + y++; + d += incr2; + } + wstart = y - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, x, w, color); + } + } + } else { + while (x < xend) { + x++; + if (d < 0) { + d += incr1; + } else { + y--; + d += incr2; + } + wstart = y - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, x, w, color); + } + } + } + } else { + /* More-or-less vertical. use wid for horizontal stroke */ + /* 2.0.12: Michael Schwartz: divide rather than multiply; + TBB: but watch out for /0! */ + double as = sin(atan2(dy, dx)); + if (as != 0) { + wid = thick / as; + } else { + wid = 1; + } + if (wid == 0) { + wid = 1; + } + + d = 2 * dx - dy; + incr1 = 2 * dx; + incr2 = 2 * (dx - dy); + if (y1 > y2) { + y = y2; + x = x2; + yend = y1; + xdirflag = (-1); + } else { + y = y1; + x = x1; + yend = y2; + xdirflag = 1; + } + + /* Set up line thickness */ + wstart = x - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, w, y, color); + } + + if (((x2 - x1) * xdirflag) > 0) { + while (y < yend) { + y++; + if (d < 0) { + d += incr1; + } else { + x++; + d += incr2; + } + wstart = x - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, w, y, color); + } + } + } else { + while (y < yend) { + y++; + if (d < 0) { + d += incr1; + } else { + x--; + d += incr2; + } + wstart = x - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, w, y, color); + } + } + } + } +} + +static void dashedSet(gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, + int vert); + +/* + Function: gdImageDashedLine +*/ +BGD_DECLARE(void) gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; + int dashStep = 0; + int on = 1; + int wid; + int vert; + int thick = im->thick; + + dx = abs(x2 - x1); + dy = abs(y2 - y1); + if (dy <= dx) { + /* More-or-less horizontal. use wid for vertical stroke */ + /* 2.0.12: Michael Schwartz: divide rather than multiply; + TBB: but watch out for /0! */ + double as = sin(atan2(dy, dx)); + if (as != 0) { + wid = thick / as; + } else { + wid = 1; + } + vert = 1; + + d = 2 * dy - dx; + incr1 = 2 * dy; + incr2 = 2 * (dy - dx); + if (x1 > x2) { + x = x2; + y = y2; + ydirflag = (-1); + xend = x1; + } else { + x = x1; + y = y1; + ydirflag = 1; + xend = x2; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + if (((y2 - y1) * ydirflag) > 0) { + while (x < xend) { + x++; + if (d < 0) { + d += incr1; + } else { + y++; + d += incr2; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + } + } else { + while (x < xend) { + x++; + if (d < 0) { + d += incr1; + } else { + y--; + d += incr2; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + } + } + } else { + /* 2.0.12: Michael Schwartz: divide rather than multiply; + TBB: but watch out for /0! */ + double as = sin(atan2(dy, dx)); + if (as != 0) { + wid = thick / as; + } else { + wid = 1; + } + vert = 0; + + d = 2 * dx - dy; + incr1 = 2 * dx; + incr2 = 2 * (dx - dy); + if (y1 > y2) { + y = y2; + x = x2; + yend = y1; + xdirflag = (-1); + } else { + y = y1; + x = x1; + yend = y2; + xdirflag = 1; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + if (((x2 - x1) * xdirflag) > 0) { + while (y < yend) { + y++; + if (d < 0) { + d += incr1; + } else { + x++; + d += incr2; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + } + } else { + while (y < yend) { + y++; + if (d < 0) { + d += incr1; + } else { + x--; + d += incr2; + } + dashedSet(im, x, y, color, &on, &dashStep, wid, vert); + } + } + } +} + +static void dashedSet(gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, + int vert) +{ + int dashStep = *dashStepP; + int on = *onP; + int w, wstart; + + dashStep++; + if (dashStep == gdDashSize) { + dashStep = 0; + on = !on; + } + if (on) { + if (vert) { + wstart = y - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, x, w, color); + } + } else { + wstart = x - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetPixel(im, w, y, color); + } + } + } + *dashStepP = dashStep; + *onP = on; +} + +/** + * Function: gdImageChar + * + * Draws a single character. + * + * Parameters: + * im - The image to draw onto. + * f - The raster font. + * x - The x coordinate of the upper left pixel. + * y - The y coordinate of the upper left pixel. + * c - The character. + * color - The color. + * + * Variants: + * - + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color) +{ + int cx, cy; + int px, py; + int fline; + const int xuppper = (x > INT_MAX - f->w) ? INT_MAX : x + f->w; + const int yuppper = (y > INT_MAX - f->h) ? INT_MAX : y + f->h; + cx = 0; + cy = 0; +#ifdef CHARSET_EBCDIC + c = ASC(c); +#endif /*CHARSET_EBCDIC */ + if ((c < f->offset) || (c >= (f->offset + f->nchars))) { + return; + } + fline = (c - f->offset) * f->h * f->w; + for (py = y; py < yuppper; py++) { + for (px = x; px < xuppper; px++) { + if (f->data[fline + cy * f->w + cx]) { + gdImageSetPixel(im, px, py, color); + } + cx++; + } + cx = 0; + cy++; + } +} + +/** + * Function: gdImageCharUp + */ +BGD_DECLARE(void) gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color) +{ + int cx, cy; + int px, py; + int fline; + const int xuppper = (x > INT_MAX - f->h) ? INT_MAX : x + f->h; + const int ylower = (y < INT_MIN + f->w) ? INT_MIN : y - f->w; + cx = 0; + cy = 0; +#ifdef CHARSET_EBCDIC + c = ASC(c); +#endif /*CHARSET_EBCDIC */ + if ((c < f->offset) || (c >= (f->offset + f->nchars))) { + return; + } + fline = (c - f->offset) * f->h * f->w; + for (py = y; py > ylower; py--) { + for (px = x; px < xuppper; px++) { + if (f->data[fline + cy * f->w + cx]) { + gdImageSetPixel(im, px, py, color); + } + cy++; + } + cy = 0; + cx++; + } +} + +/** + * Function: gdImageString + * + * Draws a character string. + * + * Parameters: + * im - The image to draw onto. + * f - The raster font. + * x - The x coordinate of the upper left pixel. + * y - The y coordinate of the upper left pixel. + * c - The character string. + * color - The color. + * + * Variants: + * - + * - + * - + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color) +{ + int i; + int l; + l = strlen((char *)s); + for (i = 0; (i < l); i++) { + gdImageChar(im, f, x, y, s[i], color); + x += f->w; + } +} + +/** + * Function: gdImageStringUp + */ +BGD_DECLARE(void) +gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color) +{ + int i; + int l; + l = strlen((char *)s); + for (i = 0; (i < l); i++) { + gdImageCharUp(im, f, x, y, s[i], color); + y -= f->w; + } +} + +static int strlen16(unsigned short *s); + +/** + * Function: gdImageString16 + */ +BGD_DECLARE(void) +gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color) +{ + int i; + int l; + l = strlen16(s); + for (i = 0; (i < l); i++) { + gdImageChar(im, f, x, y, s[i], color); + x += f->w; + } +} + +/** + * Function: gdImageStringUp16 + */ +BGD_DECLARE(void) +gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color) +{ + int i; + int l; + l = strlen16(s); + for (i = 0; (i < l); i++) { + gdImageCharUp(im, f, x, y, s[i], color); + y -= f->w; + } +} + +static int strlen16(unsigned short *s) +{ + int len = 0; + while (*s) { + s++; + len++; + } + return len; +} + +#ifndef HAVE_LSQRT +/* If you don't have a nice square root function for longs, you can use + ** this hack + */ +long lsqrt(long n) +{ + long result = (long)sqrt((double)n); + return result; +} +#endif + +/* s and e are integers modulo 360 (degrees), with 0 degrees + being the rightmost extreme and degrees changing clockwise. + cx and cy are the center in pixels; w and h are the horizontal + and vertical diameter in pixels. */ + +/* + Function: gdImageArc +*/ +BGD_DECLARE(void) +gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color) +{ + gdImageFilledArc(im, cx, cy, w, h, s, e, color, gdNoFill); +} + +/* + Function: gdImageFilledArc +*/ +BGD_DECLARE(void) +gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style) +{ + gdPoint pts[363]; + int i, pti; + int lx = 0, ly = 0; + int fx = 0, fy = 0; + int startx = -1, starty = -1, endx = -1, endy = -1; + + if ((s % 360) == (e % 360)) { + s = 0; + e = 360; + } else { + if (s > 360) { + s = s % 360; + } + + if (e > 360) { + e = e % 360; + } + + while (s < 0) { + s += 360; + } + + while (e < s) { + e += 360; + } + if (s == e) { + s = 0; + e = 360; + } + } + + for (i = s, pti = 1; (i <= e); i++, pti++) { + int x, y; + x = endx = ((long)gdCosT[i % 360] * (long)w / (2 * 1024)) + cx; + y = endy = ((long)gdSinT[i % 360] * (long)h / (2 * 1024)) + cy; + if (i != s) { + if (!(style & gdChord)) { + if (style & gdNoFill) { + gdImageLine(im, lx, ly, x, y, color); + } else { + if (y == ly) { + pti--; /* don't add this point */ + if (((i > 270 || i < 90) && x > lx) || ((i > 90 && i < 270) && x < lx)) { + /* replace the old x coord, if increasing on the + right side or decreasing on the left side */ + pts[pti].x = x; + } + } else { + pts[pti].x = x; + pts[pti].y = y; + } + } + } + } else { + fx = x; + fy = y; + if (!(style & (gdChord | gdNoFill))) { + pts[0].x = cx; + pts[0].y = cy; + pts[pti].x = startx = x; + pts[pti].y = starty = y; + } + } + lx = x; + ly = y; + } + if (style & gdChord) { + if (style & gdNoFill) { + if (style & gdEdged) { + gdImageLine(im, cx, cy, lx, ly, color); + gdImageLine(im, cx, cy, fx, fy, color); + } + gdImageLine(im, fx, fy, lx, ly, color); + } else { + pts[0].x = fx; + pts[0].y = fy; + pts[1].x = lx; + pts[1].y = ly; + pts[2].x = cx; + pts[2].y = cy; + gdImageFilledPolygon(im, pts, 3, color); + } + } else { + if (style & gdNoFill) { + if (style & gdEdged) { + gdImageLine(im, cx, cy, lx, ly, color); + gdImageLine(im, cx, cy, fx, fy, color); + } + } else { + if (e - s < 360) { + if (pts[1].x != startx && pts[1].y == starty) { + /* start point has been removed due to y-coord fix => insert it */ + for (i = pti; i > 1; i--) { + pts[i].x = pts[i - 1].x; + pts[i].y = pts[i - 1].y; + } + pts[1].x = startx; + pts[1].y = starty; + pti++; + } + if (pts[pti - 1].x != endx && pts[pti - 1].y == endy) { + /* end point has been removed due to y-coord fix => insert it */ + pts[pti].x = endx; + pts[pti].y = endy; + pti++; + } + } + pts[pti].x = cx; + pts[pti].y = cy; + gdImageFilledPolygon(im, pts, pti + 1, color); + } + } } -static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) +/* + * Function: gdImageEllipse + * + * Draw an ellipse, stroke only. + * + * Note: + * This function does not support . GD 3.0 supports + * actual 2D vectors operation, you may rely on it if you need better 2D drawing + * operations. + * + * Parameters: + * im - The destination image. + * src - The source image. + * mx - x-coordinate of the center. + * my - y-coordinate of the center. + * w - The ellipse width. + * h - The ellipse height. + * c - The color of the ellipse. A color identifier created with one of the + * image color allocate functions. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) +{ + int x = 0, mx1 = 0, mx2 = 0, my1 = 0, my2 = 0; + int64_t aq, bq, dx, dy, r, rx, ry, a, b; + + a = w >> 1; + b = h >> 1; + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } + gdImageSetPixel(im, mx + a, my, c); + gdImageSetPixel(im, mx - a, my, c); + mx1 = mx - a; + my1 = my; + mx2 = mx + a; + my2 = my; + + aq = a * a; + bq = b * b; + dx = aq << 1; + dy = bq << 1; + r = a * bq; + rx = r << 1; + ry = 0; + x = a; + while (x > 0) { + if (r > 0) { + my1++; + my2--; + ry += dx; + r -= ry; + } + if (r <= 0) { + x--; + mx1++; + mx2--; + rx -= dy; + r += rx; + } + gdImageSetPixel(im, mx1, my1, c); + gdImageSetPixel(im, mx1, my2, c); + gdImageSetPixel(im, mx2, my1, c); + gdImageSetPixel(im, mx2, my2, c); + } +} + +/* + Function: gdImageFilledEllipse +*/ +BGD_DECLARE(void) +gdImageFilledEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) +{ + int x = 0, mx1 = 0, mx2 = 0, my1 = 0, my2 = 0; + int64_t aq, bq, dx, dy, r, rx, ry, a, b; + int i; + int old_y2; + + a = w >> 1; + b = h >> 1; + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } + for (x = mx - a; x <= mx + a; x++) { + gdImageSetPixel(im, x, my, c); + } + + mx1 = mx - a; + my1 = my; + mx2 = mx + a; + my2 = my; + + aq = a * a; + bq = b * b; + dx = aq << 1; + dy = bq << 1; + r = a * bq; + rx = r << 1; + ry = 0; + x = a; + old_y2 = -2; + while (x > 0) { + if (r > 0) { + my1++; + my2--; + ry += dx; + r -= ry; + } + if (r <= 0) { + x--; + mx1++; + mx2--; + rx -= dy; + r += rx; + } + if (old_y2 != my2) { + for (i = mx1; i <= mx2; i++) { + gdImageSetPixel(im, i, my1, c); + gdImageSetPixel(im, i, my2, c); + } + } + old_y2 = my2; + } +} + +/* + Function: gdImageFillToBorder +*/ +BGD_DECLARE(void) gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color) +{ + int lastBorder; + /* Seek left */ + int leftLimit, rightLimit; + int i; + int restoreAlphaBlending = 0; + + if (border < 0 || color < 0) { + /* Refuse to fill to a non-solid border */ + return; + } + + if (!im->trueColor) { + if ((color > (im->colorsTotal - 1)) || (border > (im->colorsTotal - 1)) || (color < 0)) { + return; + } + } + + leftLimit = (-1); + + restoreAlphaBlending = im->alphaBlendingFlag; + im->alphaBlendingFlag = 0; + + if (x >= im->sx) { + x = im->sx - 1; + } else if (x < 0) { + x = 0; + } + if (y >= im->sy) { + y = im->sy - 1; + } else if (y < 0) { + y = 0; + } + + for (i = x; (i >= 0); i--) { + if (gdImageGetPixel(im, i, y) == border) { + break; + } + gdImageSetPixel(im, i, y, color); + leftLimit = i; + } + if (leftLimit == (-1)) { + im->alphaBlendingFlag = restoreAlphaBlending; + return; + } + /* Seek right */ + rightLimit = x; + for (i = (x + 1); (i < im->sx); i++) { + if (gdImageGetPixel(im, i, y) == border) { + break; + } + gdImageSetPixel(im, i, y, color); + rightLimit = i; + } + /* Look at lines above and below and start paints */ + /* Above */ + if (y > 0) { + lastBorder = 1; + for (i = leftLimit; (i <= rightLimit); i++) { + int c = gdImageGetPixel(im, i, y - 1); + if (lastBorder) { + if ((c != border) && (c != color)) { + gdImageFillToBorder(im, i, y - 1, border, color); + lastBorder = 0; + } + } else if ((c == border) || (c == color)) { + lastBorder = 1; + } + } + } + /* Below */ + if (y < ((im->sy) - 1)) { + lastBorder = 1; + for (i = leftLimit; (i <= rightLimit); i++) { + int c = gdImageGetPixel(im, i, y + 1); + if (lastBorder) { + if ((c != border) && (c != color)) { + gdImageFillToBorder(im, i, y + 1, border, color); + lastBorder = 0; + } + } else if ((c == border) || (c == color)) { + lastBorder = 1; + } + } + } + im->alphaBlendingFlag = restoreAlphaBlending; +} + +/* + * set the pixel at (x,y) and its 4-connected neighbors + * with the same pixel value to the new pixel value nc (new color). + * A 4-connected neighbor: pixel above, below, left, or right of a pixel. + * ideas from comp.graphics discussions. + * For tiled fill, the use of a flag buffer is mandatory. As the tile image can + * contain the same color as the color to fill. To do not bloat normal filling + * code I added a 2nd private function. + */ + +static int gdImageTileGet(gdImagePtr im, int x, int y) +{ + int srcx, srcy; + int tileColor, p; + if (!im->tile) { + return -1; + } + srcx = x % gdImageSX(im->tile); + srcy = y % gdImageSY(im->tile); + p = gdImageGetPixel(im->tile, srcx, srcy); + if (p == im->tile->transparent) { + tileColor = im->transparent; + } else if (im->trueColor) { + if (im->tile->trueColor) { + tileColor = p; + } else { + tileColor = gdTrueColorAlpha(gdImageRed(im->tile, p), gdImageGreen(im->tile, p), + gdImageBlue(im->tile, p), gdImageAlpha(im->tile, p)); + } + } else { + if (im->tile->trueColor) { + tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed(p), gdTrueColorGetGreen(p), + gdTrueColorGetBlue(p), gdTrueColorGetAlpha(p)); + } else { + tileColor = + gdImageColorResolveAlpha(im, gdImageRed(im->tile, p), gdImageGreen(im->tile, p), + gdImageBlue(im->tile, p), gdImageAlpha(im->tile, p)); + } + } + return tileColor; +} + +/* horizontal segment of scan line y */ +struct seg { + int y, xl, xr, dy; +}; + +/* max depth of stack */ +#define FILL_MAX ((int)(im->sy * im->sx) / 4) +#define FILL_PUSH(Y, XL, XR, DY) \ + if (sp < stack + FILL_MAX && Y + (DY) >= 0 && Y + (DY) < wy2) { \ + sp->y = Y; \ + sp->xl = XL; \ + sp->xr = XR; \ + sp->dy = DY; \ + sp++; \ + } + +#define FILL_POP(Y, XL, XR, DY) \ + { \ + sp--; \ + Y = sp->y + (DY = sp->dy); \ + XL = sp->xl; \ + XR = sp->xr; \ + } + +static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc); + +/* + Function: gdImageFill +*/ +BGD_DECLARE(void) gdImageFill(gdImagePtr im, int x, int y, int nc) +{ + int l, x1, x2, dy; + int oc; /* old pixel value */ + int wx2, wy2; + + int alphablending_bak; + + /* stack of filled segments */ + /* struct seg stack[FILL_MAX],*sp = stack; */ + struct seg *stack = NULL; + struct seg *sp; + + if (!im->trueColor && nc > (im->colorsTotal - 1)) { + return; + } + + alphablending_bak = im->alphaBlendingFlag; + im->alphaBlendingFlag = 0; + + if (nc == gdTiled) { + _gdImageFillTiled(im, x, y, nc); + im->alphaBlendingFlag = alphablending_bak; + return; + } + + wx2 = im->sx; + wy2 = im->sy; + oc = gdImageGetPixel(im, x, y); + if (oc == nc || x < 0 || x > wx2 || y < 0 || y > wy2) { + im->alphaBlendingFlag = alphablending_bak; + return; + } + + /* Do not use the 4 neighbors implementation with + * small images + */ + if (im->sx < 4) { + int ix = x, iy = y, c; + do { + do { + c = gdImageGetPixel(im, ix, iy); + if (c != oc) { + goto done; + } + gdImageSetPixel(im, ix, iy, nc); + } while (ix++ < (im->sx - 1)); + ix = x; + } while (iy++ < (im->sy - 1)); + goto done; + } + + if (overflow2(im->sy, im->sx)) { + return; + } + + if (overflow2(sizeof(struct seg), ((im->sy * im->sx) / 4))) { + return; + } + + stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy * im->sx) / 4)); + if (!stack) { + return; + } + sp = stack; + + /* required! */ + FILL_PUSH(y, x, x, 1); + /* seed segment (popped 1st) */ + FILL_PUSH(y + 1, x, x, -1); + while (sp > stack) { + FILL_POP(y, x1, x2, dy); + + for (x = x1; x >= 0 && gdImageGetPixel(im, x, y) == oc; x--) { + gdImageSetPixel(im, x, y, nc); + } + if (x >= x1) { + goto skip; + } + l = x + 1; + + /* leak on left? */ + if (l < x1) { + FILL_PUSH(y, l, x1 - 1, -dy); + } + x = x1 + 1; + do { + for (; x <= wx2 && gdImageGetPixel(im, x, y) == oc; x++) { + gdImageSetPixel(im, x, y, nc); + } + FILL_PUSH(y, l, x - 1, dy); + /* leak on right? */ + if (x > x2 + 1) { + FILL_PUSH(y, x2 + 1, x - 1, -dy); + } + skip: + for (x++; x <= x2 && (gdImageGetPixel(im, x, y) != oc); x++) + ; + + l = x; + } while (x <= x2); + } + + gdFree(stack); + +done: + im->alphaBlendingFlag = alphablending_bak; +} + +static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) +{ + int l, x1, x2, dy; + int oc; /* old pixel value */ + int wx2, wy2; + /* stack of filled segments */ + struct seg *stack; + struct seg *sp; + char *pts; + + if (!im->tile) { + return; + } + + wx2 = im->sx; + wy2 = im->sy; + oc = gdImageGetPixel(im, x, y); + if (oc == nc || x < 0 || x > wx2 || y < 0 || y > wy2) { + return; + } + + if (overflow2(im->sy, im->sx)) { + return; + } + + if (overflow2(sizeof(struct seg), ((im->sy * im->sx) / 4))) { + return; + } + + pts = (char *)gdCalloc(im->sy * im->sx, sizeof(char)); + if (!pts) { + return; + } + + stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy * im->sx) / 4)); + if (!stack) { + gdFree(pts); + return; + } + sp = stack; + + oc = gdImageGetPixel(im, x, y); + + /* required! */ + FILL_PUSH(y, x, x, 1); + /* seed segment (popped 1st) */ + FILL_PUSH(y + 1, x, x, -1); + while (sp > stack) { + FILL_POP(y, x1, x2, dy); + for (x = x1; x >= 0 && (!pts[y + x * wy2] && gdImageGetPixel(im, x, y) == oc); x--) { + nc = gdImageTileGet(im, x, y); + pts[y + x * wy2] = 1; + gdImageSetPixel(im, x, y, nc); + } + if (x >= x1) { + goto skip; + } + l = x + 1; + + /* leak on left? */ + if (l < x1) { + FILL_PUSH(y, l, x1 - 1, -dy); + } + x = x1 + 1; + do { + for (; x < wx2 && (!pts[y + x * wy2] && gdImageGetPixel(im, x, y) == oc); x++) { + if (pts[y + x * wy2]) { + /* we should never be here */ + break; + } + nc = gdImageTileGet(im, x, y); + pts[y + x * wy2] = 1; + gdImageSetPixel(im, x, y, nc); + } + FILL_PUSH(y, l, x - 1, dy); + /* leak on right? */ + if (x > x2 + 1) { + FILL_PUSH(y, x2 + 1, x - 1, -dy); + } + skip: + for (x++; x <= x2 && (pts[y + x * wy2] || gdImageGetPixel(im, x, y) != oc); x++) + ; + l = x; + } while (x <= x2); + } + + gdFree(pts); + gdFree(stack); +} + +/** + * Function: gdImageRectangle + * + * Draws a rectangle. + * + * Parameters: + * im - The image. + * x1 - The x-coordinate of one of the corners. + * y1 - The y-coordinate of one of the corners. + * x2 - The x-coordinate of another corner. + * y2 - The y-coordinate of another corner. + * color - The color. + * + * See also: + * - + */ +BGD_DECLARE(void) +gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int thick = im->thick; + + if (x1 == x2 && y1 == y2 && thick == 1) { + gdImageSetPixel(im, x1, y1, color); + return; + } + + if (y2 < y1) { + int t = y1; + y1 = y2; + y2 = t; + } + + if (x2 < x1) { + int t = x1; + x1 = x2; + x2 = t; + } + + if (thick > 1) { + int cx, cy, x1ul, y1ul, x2lr, y2lr; + int half = thick >> 1; + + x1ul = x1 - half; + y1ul = y1 - half; + + x2lr = x2 + half; + y2lr = y2 + half; + + cy = y1ul + thick; + while (cy-- > y1ul) { + cx = x1ul - 1; + while (cx++ < x2lr) { + gdImageSetPixel(im, cx, cy, color); + } + } + + cy = y2lr - thick; + while (cy++ < y2lr) { + cx = x1ul - 1; + while (cx++ < x2lr) { + gdImageSetPixel(im, cx, cy, color); + } + } + + cy = y1ul + thick - 1; + while (cy++ < y2lr - thick) { + cx = x1ul - 1; + while (cx++ < x1ul + thick) { + gdImageSetPixel(im, cx, cy, color); + } + } + + cy = y1ul + thick - 1; + while (cy++ < y2lr - thick) { + cx = x2lr - thick - 1; + while (cx++ < x2lr) { + gdImageSetPixel(im, cx, cy, color); + } + } + + return; + } else { + if (x1 == x2 || y1 == y2) { + gdImageLine(im, x1, y1, x2, y2, color); + } else { + gdImageLine(im, x1, y1, x2, y1, color); + gdImageLine(im, x1, y2, x2, y2, color); + gdImageLine(im, x1, y1 + 1, x1, y2 - 1, color); + gdImageLine(im, x2, y1 + 1, x2, y2 - 1, color); + } + } +} + +static void _gdImageFilledHRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int x, y; + + if (x1 == x2 && y1 == y2) { + gdImageSetPixel(im, x1, y1, color); + return; + } + + if (x1 > x2) { + x = x1; + x1 = x2; + x2 = x; + } + + if (y1 > y2) { + y = y1; + y1 = y2; + y2 = y; + } + + if (x1 < 0) { + x1 = 0; + } + + if (x2 >= gdImageSX(im)) { + x2 = gdImageSX(im) - 1; + } + + if (y1 < 0) { + y1 = 0; + } + + if (y2 >= gdImageSY(im)) { + y2 = gdImageSY(im) - 1; + } + + for (x = x1; (x <= x2); x++) { + for (y = y1; (y <= y2); y++) { + gdImageSetPixel(im, x, y, color); + } + } +} + +static void _gdImageFilledVRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int x, y; + + if (x1 == x2 && y1 == y2) { + gdImageSetPixel(im, x1, y1, color); + return; + } + + if (x1 > x2) { + x = x1; + x1 = x2; + x2 = x; + } + + if (y1 > y2) { + y = y1; + y1 = y2; + y2 = y; + } + + if (x1 < 0) { + x1 = 0; + } + + if (x2 >= gdImageSX(im)) { + x2 = gdImageSX(im) - 1; + } + + if (y1 < 0) { + y1 = 0; + } + + if (y2 >= gdImageSY(im)) { + y2 = gdImageSY(im) - 1; + } + + for (y = y1; (y <= y2); y++) { + for (x = x1; (x <= x2); x++) { + gdImageSetPixel(im, x, y, color); + } + } +} + +/* + Function: gdImageFilledRectangle +*/ +BGD_DECLARE(void) gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + _gdImageFilledVRectangle(im, x1, y1, x2, y2, color); +} + +/** + * Group: Cloning and Copying + */ + +/** + * Function: gdImageClone + * + * Clones an image + * + * Creates an exact duplicate of the given image. + * + * Parameters: + * src - The source image. + * + * Returns: + * The cloned image on success, NULL on failure. + */ +BGD_DECLARE(gdImagePtr) gdImageClone(gdImagePtr src) +{ + gdImagePtr dst; + register int i, x; + + if (src->trueColor) { + dst = gdImageCreateTrueColor(src->sx, src->sy); + } else { + dst = gdImageCreate(src->sx, src->sy); + } + + if (dst == NULL) { + return NULL; + } + + if (src->trueColor == 0) { + dst->colorsTotal = src->colorsTotal; + for (i = 0; i < gdMaxColors; i++) { + dst->red[i] = src->red[i]; + dst->green[i] = src->green[i]; + dst->blue[i] = src->blue[i]; + dst->alpha[i] = src->alpha[i]; + dst->open[i] = src->open[i]; + } + for (i = 0; i < src->sy; i++) { + for (x = 0; x < src->sx; x++) { + dst->pixels[i][x] = src->pixels[i][x]; + } + } + } else { + for (i = 0; i < src->sy; i++) { + for (x = 0; x < src->sx; x++) { + dst->tpixels[i][x] = src->tpixels[i][x]; + } + } + } + + dst->interlace = src->interlace; + + dst->alphaBlendingFlag = src->alphaBlendingFlag; + dst->saveAlphaFlag = src->saveAlphaFlag; + dst->AA = src->AA; + dst->AA_color = src->AA_color; + dst->AA_dont_blend = src->AA_dont_blend; + + dst->cx1 = src->cx1; + dst->cy1 = src->cy1; + dst->cx2 = src->cx2; + dst->cy2 = src->cy2; + + dst->res_x = src->res_x; + dst->res_y = src->res_y; + + dst->paletteQuantizationMethod = src->paletteQuantizationMethod; + dst->paletteQuantizationSpeed = src->paletteQuantizationSpeed; + dst->paletteQuantizationMinQuality = src->paletteQuantizationMinQuality; + dst->paletteQuantizationMaxQuality = src->paletteQuantizationMaxQuality; + + dst->interpolation_id = src->interpolation_id; + dst->interpolation = src->interpolation; + + if (src->brush) { + dst->brush = gdImageClone(src->brush); + } + + if (src->tile) { + dst->tile = gdImageClone(src->tile); + } + + if (src->style) { + gdImageSetStyle(dst, src->style, src->styleLength); + dst->stylePos = src->stylePos; + } + + for (i = 0; i < gdMaxColors; i++) { + dst->brushColorMap[i] = src->brushColorMap[i]; + dst->tileColorMap[i] = src->tileColorMap[i]; + } + + if (src->polyAllocated > 0 && overflow2(sizeof(int), src->polyAllocated) == 0) { + dst->polyInts = gdMalloc(sizeof(int) * src->polyAllocated); + dst->polyAllocated = src->polyAllocated; + for (i = 0; i < src->polyAllocated; i++) { + dst->polyInts[i] = src->polyInts[i]; + } + } + + return dst; +} + +/** + * Function: gdImageCopy + * + * Copy an area of an image to another image + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the upper left corner to copy to. + * dstY - The y-coordinate of the upper left corner to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * w - The width of the area to copy. + * h - The height of the area to copy. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h) +{ + int c; + int x, y; + int tox, toy; + int i; + int colorMap[gdMaxColors]; + if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) { + return; + } + if (dst->trueColor) { + /* 2.0: much easier when the destination is truecolor. */ + /* 2.0.10: needs a transparent-index check that is still valid if + * the source is not truecolor. Thanks to Frank Warmerdam. + */ + + if (src->trueColor) { + for (y = 0; (y < h); y++) { + for (x = 0; (x < w); x++) { + int c = gdImageGetTrueColorPixel(src, srcX + x, srcY + y); + if (c != src->transparent) { + gdImageSetPixel(dst, dstX + x, dstY + y, c); + } + } + } + } else { + /* source is palette based */ + for (y = 0; (y < h); y++) { + for (x = 0; (x < w); x++) { + int c = gdImageGetPixel(src, srcX + x, srcY + y); + if (c != src->transparent) { + gdImageSetPixel(dst, dstX + x, dstY + y, + gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], + src->alpha[c])); + } + } + } + } + return; + } + + /* Palette based to palette based */ + for (i = 0; i < gdMaxColors; i++) { + colorMap[i] = (-1); + } + toy = dstY; + for (y = srcY; (y < (srcY + h)); y++) { + tox = dstX; + for (x = srcX; (x < (srcX + w)); x++) { + int nc; + int mapTo; + c = gdImageGetPixel(src, x, y); + /* Added 7/24/95: support transparent copies */ + if (gdImageGetTransparent(src) == c) { + tox++; + continue; + } + /* Have we established a mapping for this color? */ + if (src->trueColor) { + /* 2.05: remap to the palette available in the destination image. This is slow and + * works badly, but it beats crashing! Thanks to Padhrig McCarthy. + */ + mapTo = gdImageColorResolveAlpha(dst, gdTrueColorGetRed(c), gdTrueColorGetGreen(c), + gdTrueColorGetBlue(c), gdTrueColorGetAlpha(c)); + } else if (colorMap[c] == (-1)) { + /* If it's the same image, mapping is trivial */ + if (dst == src) { + nc = c; + } else { + /* Get best match possible. This function never returns error. */ + nc = gdImageColorResolveAlpha(dst, src->red[c], src->green[c], src->blue[c], + src->alpha[c]); + } + colorMap[c] = nc; + mapTo = colorMap[c]; + } else { + mapTo = colorMap[c]; + } + gdImageSetPixel(dst, tox, toy, mapTo); + tox++; + } + toy++; + } +} + +/** + * Function: gdImageCopyMerge + * + * Copy an area of an image to another image ignoring alpha + * + * The source area will be copied to the destination are by merging the pixels. + * + * Note: + * This function is a substitute for real alpha channel operations, + * so it doesn't pay attention to the alpha channel. + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the upper left corner to copy to. + * dstY - The y-coordinate of the upper left corner to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * w - The width of the area to copy. + * h - The height of the area to copy. + * pct - The percentage in range 0..100. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, + int h, int pct) +{ + int c, dc; + int x, y; + int tox, toy; + int ncR, ncG, ncB; + if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) { + return; + } + toy = dstY; + for (y = srcY; (y < (srcY + h)); y++) { + tox = dstX; + for (x = srcX; (x < (srcX + w)); x++) { + int nc; + c = gdImageGetPixel(src, x, y); + /* Added 7/24/95: support transparent copies */ + if (gdImageGetTransparent(src) == c) { + tox++; + continue; + } + /* If it's the same image, mapping is trivial */ + if (dst == src) { + nc = c; + } else { + dc = gdImageGetPixel(dst, tox, toy); + + ncR = gdImageRed(src, c) * (pct / 100.0) + + gdImageRed(dst, dc) * ((100 - pct) / 100.0); + ncG = gdImageGreen(src, c) * (pct / 100.0) + + gdImageGreen(dst, dc) * ((100 - pct) / 100.0); + ncB = gdImageBlue(src, c) * (pct / 100.0) + + gdImageBlue(dst, dc) * ((100 - pct) / 100.0); + + /* Find a reasonable color */ + nc = gdImageColorResolve(dst, ncR, ncG, ncB); + } + gdImageSetPixel(dst, tox, toy, nc); + tox++; + } + toy++; + } +} + +/** + * Function: gdImageCopyMergeGray + * + * Copy an area of an image to another image ignoring alpha + * + * The source area will be copied to the grayscaled destination area by merging + * the pixels. + * + * Note: + * This function is a substitute for real alpha channel operations, + * so it doesn't pay attention to the alpha channel. + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the upper left corner to copy to. + * dstY - The y-coordinate of the upper left corner to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * w - The width of the area to copy. + * h - The height of the area to copy. + * pct - The percentage of the source color intensity in range 0..100. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, + int h, int pct) +{ + int c, dc; + int x, y; + int tox, toy; + int ncR, ncG, ncB; + float g; + + if (!gdImageClipCopy(dst, &dstX, &dstY, &srcX, &srcY, &w, &h)) { + return; + } + + toy = dstY; + for (y = srcY; (y < (srcY + h)); y++) { + tox = dstX; + for (x = srcX; (x < (srcX + w)); x++) { + int nc; + c = gdImageGetPixel(src, x, y); + /* Added 7/24/95: support transparent copies */ + if (gdImageGetTransparent(src) == c) { + tox++; + continue; + } + /* + * If it's the same image, mapping is NOT trivial since we + * merge with greyscale target, but if pct is 100, the grey + * value is not used, so it becomes trivial. pjw 2.0.12. + */ + if (dst == src && pct == 100) { + nc = c; + } else { + dc = gdImageGetPixel(dst, tox, toy); + g = 0.29900 * gdImageRed(dst, dc) + 0.58700 * gdImageGreen(dst, dc) + + 0.11400 * gdImageBlue(dst, dc); + + ncR = gdImageRed(src, c) * (pct / 100.0) + g * ((100 - pct) / 100.0); + ncG = gdImageGreen(src, c) * (pct / 100.0) + g * ((100 - pct) / 100.0); + ncB = gdImageBlue(src, c) * (pct / 100.0) + g * ((100 - pct) / 100.0); + + /* First look for an exact match */ + nc = gdImageColorExact(dst, ncR, ncG, ncB); + if (nc == (-1)) { + /* No, so try to allocate it */ + nc = gdImageColorAllocate(dst, ncR, ncG, ncB); + /* If we're out of colors, go for the closest color */ + if (nc == (-1)) { + nc = gdImageColorClosest(dst, ncR, ncG, ncB); + } + } + } + gdImageSetPixel(dst, tox, toy, nc); + tox++; + } + toy++; + } +} + +/** + * Function: gdImageCopyResized + * + * Copy a resized area from an image to another image + * + * If the source and destination area differ in size, the area will be resized + * using nearest-neighbor interpolation. + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the upper left corner to copy to. + * dstY - The y-coordinate of the upper left corner to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * dstW - The width of the area to copy to. + * dstH - The height of the area to copy to. + * srcW - The width of the area to copy from. + * srcH - The height of the area to copy from. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, + int dstH, int srcW, int srcH) { - int x, y; + int c; + int x, y; + int tox, toy; + int ydest; + int i; + int colorMap[gdMaxColors]; + /* Stretch vectors */ + int *stx; + int *sty; + /* We only need to use floating point to determine the correct + stretch vector for one line's worth. */ + if (overflow2(sizeof(int), srcW)) { + return; + } + if (overflow2(sizeof(int), srcH)) { + return; + } + if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) { + return; + } + stx = (int *)gdMalloc(sizeof(int) * srcW); + if (!stx) { + return; + } - if (x1 == x2 && y1 == y2) { - gdImageSetPixel(im, x1, y1, color); - return; - } + sty = (int *)gdMalloc(sizeof(int) * srcH); + if (!sty) { + gdFree(stx); + return; + } - if (x1 > x2) { - x = x1; - x1 = x2; - x2 = x; - } - - if (y1 > y2) { - y = y1; - y1 = y2; - y2 = y; - } - - if (x1 < 0) { - x1 = 0; - } - - if (x2 >= gdImageSX(im)) { - x2 = gdImageSX(im) - 1; - } - - if (y1 < 0) { - y1 = 0; - } - - if (y2 >= gdImageSY(im)) { - y2 = gdImageSY(im) - 1; - } - - for (x = x1; (x <= x2); x++) { - for (y = y1; (y <= y2); y++) { - gdImageSetPixel (im, x, y, color); - } - } -} - -static void _gdImageFilledVRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) -{ - int x, y; - - if (x1 == x2 && y1 == y2) { - gdImageSetPixel(im, x1, y1, color); - return; - } - - if (x1 > x2) { - x = x1; - x1 = x2; - x2 = x; - } - - if (y1 > y2) { - y = y1; - y1 = y2; - y2 = y; - } - - if (x1 < 0) { - x1 = 0; - } - - if (x2 >= gdImageSX(im)) { - x2 = gdImageSX(im) - 1; - } - - if (y1 < 0) { - y1 = 0; - } - - if (y2 >= gdImageSY(im)) { - y2 = gdImageSY(im) - 1; - } - - for (y = y1; (y <= y2); y++) { - for (x = x1; (x <= x2); x++) { - gdImageSetPixel (im, x, y, color); - } - } -} - -void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) -{ - _gdImageFilledVRectangle(im, x1, y1, x2, y2, color); -} + /* Fixed by Mao Morimoto 2.0.16 */ + for (i = 0; (i < srcW); i++) { + stx[i] = dstW * (i + 1) / srcW - dstW * i / srcW; + } + for (i = 0; (i < srcH); i++) { + sty[i] = dstH * (i + 1) / srcH - dstH * i / srcH; + } + for (i = 0; (i < gdMaxColors); i++) { + colorMap[i] = (-1); + } + toy = dstY; + for (y = srcY; (y < (srcY + srcH)); y++) { + for (ydest = 0; (ydest < sty[y - srcY]); ydest++) { + tox = dstX; + for (x = srcX; (x < (srcX + srcW)); x++) { + int nc = 0; + int mapTo; + if (!stx[x - srcX]) { + continue; + } + if (dst->trueColor) { + if (!src->trueColor) { + int tmp = gdImageGetPixel(src, x, y); + mapTo = gdImageGetTrueColorPixel(src, x, y); + if (gdImageGetTransparent(src) == tmp) { + /* 2.0.21, TK: not tox++ */ + tox += stx[x - srcX]; + continue; + } + } else { + /* TK: old code follows */ + mapTo = gdImageGetTrueColorPixel(src, x, y); + /* Added 7/24/95: support transparent copies */ + if (gdImageGetTransparent(src) == mapTo) { + /* 2.0.21, TK: not tox++ */ + tox += stx[x - srcX]; + continue; + } + } + } else { + c = gdImageGetPixel(src, x, y); + /* Added 7/24/95: support transparent copies */ + if (gdImageGetTransparent(src) == c) { + tox += stx[x - srcX]; + continue; + } + if (src->trueColor) { + /* Remap to the palette available in the destination image. This is slow and + * works badly. */ + mapTo = gdImageColorResolveAlpha( + dst, gdTrueColorGetRed(c), gdTrueColorGetGreen(c), + gdTrueColorGetBlue(c), gdTrueColorGetAlpha(c)); + } else { + /* Have we established a mapping for this color? */ + if (colorMap[c] == (-1)) { + /* If it's the same image, mapping is trivial */ + if (dst == src) { + nc = c; + } else { + /* Find or create the best match */ + nc = gdImageColorResolveAlpha( + dst, gdImageRed(src, c), gdImageGreen(src, c), + gdImageBlue(src, c), gdImageAlpha(src, c)); + } + colorMap[c] = nc; + } + mapTo = colorMap[c]; + } + } + for (i = 0; (i < stx[x - srcX]); i++) { + gdImageSetPixel(dst, tox, toy, mapTo); + tox++; + } + } + toy++; + } + } + gdFree(stx); + gdFree(sty); +} -void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h) +/** + * Function: gdImageCopyRotated + * + * Copy a rotated area from an image to another image + * + * The area is counter-clockwise rotated using nearest-neighbor interpolation. + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the center of the area to copy to. + * dstY - The y-coordinate of the center of the area to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * srcW - The width of the area to copy from. + * srcH - The height of the area to copy from. + * angle - The angle in degrees. + * + * See also: + * - + */ +BGD_DECLARE(void) +gdImageCopyRotated(gdImagePtr dst, gdImagePtr src, double dstX, double dstY, int srcX, int srcY, + int srcWidth, int srcHeight, int angle) { - int c; - int x, y; - int tox, toy; - int i; - int colorMap[gdMaxColors]; + double dx, dy; + double radius = sqrt(srcWidth * srcWidth + srcHeight * srcHeight); + double aCos = cos(angle * .0174532925); + double aSin = sin(angle * .0174532925); + double scX = srcX + ((double)srcWidth) / 2; + double scY = srcY + ((double)srcHeight) / 2; + int cmap[gdMaxColors]; + int i; + const double safe_max = (double)INT_MAX / 2.0; + const double safe_min = (double)INT_MIN / 2.0; + double dyMin, dyMax, dxMin, dxMax; + + /* + 2.0.34: transparency preservation. The transparentness of + the transparent color is more important than its hue. + */ + if (src->transparent != -1) { + if (dst->transparent == -1) { + dst->transparent = src->transparent; + } + } - if (dst->trueColor) { - /* 2.0: much easier when the destination is truecolor. */ - /* 2.0.10: needs a transparent-index check that is still valid if - * the source is not truecolor. Thanks to Frank Warmerdam. - */ - - if (src->trueColor) { - for (y = 0; (y < h); y++) { - for (x = 0; (x < w); x++) { - int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y); - if (c != src->transparent) { - gdImageSetPixel (dst, dstX + x, dstY + y, c); - } - } - } - } else { - /* source is palette based */ - for (y = 0; (y < h); y++) { - for (x = 0; (x < w); x++) { - int c = gdImageGetPixel (src, srcX + x, srcY + y); - if (c != src->transparent) { - gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c])); - } - } - } - } - return; - } - - /* Palette based to palette based */ - for (i = 0; i < gdMaxColors; i++) { - colorMap[i] = (-1); - } - toy = dstY; - for (y = srcY; y < (srcY + h); y++) { - tox = dstX; - for (x = srcX; x < (srcX + w); x++) { - int nc; - int mapTo; - c = gdImageGetPixel (src, x, y); - /* Added 7/24/95: support transparent copies */ - if (gdImageGetTransparent (src) == c) { - tox++; - continue; - } - /* Have we established a mapping for this color? */ - if (src->trueColor) { - /* 2.05: remap to the palette available in the destination image. This is slow and - * works badly, but it beats crashing! Thanks to Padhrig McCarthy. - */ - mapTo = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), gdTrueColorGetAlpha (c)); - } else if (colorMap[c] == (-1)) { - /* If it's the same image, mapping is trivial */ - if (dst == src) { - nc = c; - } else { - /* Get best match possible. This function never returns error. */ - nc = gdImageColorResolveAlpha (dst, src->red[c], src->green[c], src->blue[c], src->alpha[c]); - } - colorMap[c] = nc; - mapTo = colorMap[c]; - } else { - mapTo = colorMap[c]; - } - gdImageSetPixel (dst, tox, toy, mapTo); - tox++; - } - toy++; - } -} - -/* This function is a substitute for real alpha channel operations, - so it doesn't pay attention to the alpha channel. */ -void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) -{ - int c, dc; - int x, y; - int tox, toy; - int ncR, ncG, ncB; - toy = dstY; - - for (y = srcY; y < (srcY + h); y++) { - tox = dstX; - for (x = srcX; x < (srcX + w); x++) { - int nc; - c = gdImageGetPixel(src, x, y); - /* Added 7/24/95: support transparent copies */ - if (gdImageGetTransparent(src) == c) { - tox++; - continue; - } - /* If it's the same image, mapping is trivial */ - if (dst == src) { - nc = c; - } else { - dc = gdImageGetPixel(dst, tox, toy); - - ncR = (int)(gdImageRed (src, c) * (pct / 100.0) + gdImageRed (dst, dc) * ((100 - pct) / 100.0)); - ncG = (int)(gdImageGreen (src, c) * (pct / 100.0) + gdImageGreen (dst, dc) * ((100 - pct) / 100.0)); - ncB = (int)(gdImageBlue (src, c) * (pct / 100.0) + gdImageBlue (dst, dc) * ((100 - pct) / 100.0)); - - /* Find a reasonable color */ - nc = gdImageColorResolve (dst, ncR, ncG, ncB); - } - gdImageSetPixel (dst, tox, toy, nc); - tox++; - } - toy++; - } -} - -/* This function is a substitute for real alpha channel operations, - so it doesn't pay attention to the alpha channel. */ -void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h, int pct) -{ - int c, dc; - int x, y; - int tox, toy; - int ncR, ncG, ncB; - float g; - toy = dstY; - - for (y = srcY; (y < (srcY + h)); y++) { - tox = dstX; - for (x = srcX; (x < (srcX + w)); x++) { - int nc; - c = gdImageGetPixel (src, x, y); - /* Added 7/24/95: support transparent copies */ - if (gdImageGetTransparent(src) == c) { - tox++; - continue; - } + for (i = 0; (i < gdMaxColors); i++) { + cmap[i] = (-1); + } - /* - * If it's the same image, mapping is NOT trivial since we - * merge with greyscale target, but if pct is 100, the grey - * value is not used, so it becomes trivial. pjw 2.0.12. - */ - if (dst == src && pct == 100) { - nc = c; - } else { - dc = gdImageGetPixel(dst, tox, toy); - g = (0.29900f * gdImageRed(dst, dc)) + (0.58700f * gdImageGreen(dst, dc)) + (0.11400f * gdImageBlue(dst, dc)); - - ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); - ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); - ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0)); - - - /* First look for an exact match */ - nc = gdImageColorExact(dst, ncR, ncG, ncB); - if (nc == (-1)) { - /* No, so try to allocate it */ - nc = gdImageColorAllocate(dst, ncR, ncG, ncB); - /* If we're out of colors, go for the closest color */ - if (nc == (-1)) { - nc = gdImageColorClosest(dst, ncR, ncG, ncB); - } - } - } - gdImageSetPixel(dst, tox, toy, nc); - tox++; - } - toy++; - } -} - -void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) -{ - int c; - int x, y; - int tox, toy; - int ydest; - int i; - int colorMap[gdMaxColors]; - /* Stretch vectors */ - int *stx, *sty; - - if (overflow2(sizeof(int), srcW)) { - return; - } - if (overflow2(sizeof(int), srcH)) { - return; - } - - stx = (int *) gdMalloc (sizeof (int) * srcW); - sty = (int *) gdMalloc (sizeof (int) * srcH); - - /* Fixed by Mao Morimoto 2.0.16 */ - for (i = 0; (i < srcW); i++) { - stx[i] = dstW * (i+1) / srcW - dstW * i / srcW ; - } - for (i = 0; (i < srcH); i++) { - sty[i] = dstH * (i+1) / srcH - dstH * i / srcH ; - } - for (i = 0; (i < gdMaxColors); i++) { - colorMap[i] = (-1); - } - toy = dstY; - for (y = srcY; (y < (srcY + srcH)); y++) { - for (ydest = 0; (ydest < sty[y - srcY]); ydest++) { - tox = dstX; - for (x = srcX; (x < (srcX + srcW)); x++) { - int nc = 0; - int mapTo; - if (!stx[x - srcX]) { - continue; - } - if (dst->trueColor) { - /* 2.0.9: Thorben Kundinger: Maybe the source image is not a truecolor image */ - if (!src->trueColor) { - int tmp = gdImageGetPixel (src, x, y); - mapTo = gdImageGetTrueColorPixel (src, x, y); - if (gdImageGetTransparent (src) == tmp) { - /* 2.0.21, TK: not tox++ */ - tox += stx[x - srcX]; - continue; - } - } else { - /* TK: old code follows */ - mapTo = gdImageGetTrueColorPixel (src, x, y); - /* Added 7/24/95: support transparent copies */ - if (gdImageGetTransparent (src) == mapTo) { - /* 2.0.21, TK: not tox++ */ - tox += stx[x - srcX]; - continue; - } - } - } else { - c = gdImageGetPixel (src, x, y); - /* Added 7/24/95: support transparent copies */ - if (gdImageGetTransparent (src) == c) { - tox += stx[x - srcX]; - continue; - } - if (src->trueColor) { - /* Remap to the palette available in the destination image. This is slow and works badly. */ - mapTo = gdImageColorResolveAlpha(dst, gdTrueColorGetRed(c), - gdTrueColorGetGreen(c), - gdTrueColorGetBlue(c), - gdTrueColorGetAlpha (c)); - } else { - /* Have we established a mapping for this color? */ - if (colorMap[c] == (-1)) { - /* If it's the same image, mapping is trivial */ - if (dst == src) { - nc = c; - } else { - /* Find or create the best match */ - /* 2.0.5: can't use gdTrueColorGetRed, etc with palette */ - nc = gdImageColorResolveAlpha(dst, gdImageRed(src, c), - gdImageGreen(src, c), - gdImageBlue(src, c), - gdImageAlpha(src, c)); - } - colorMap[c] = nc; - } - mapTo = colorMap[c]; - } - } - for (i = 0; (i < stx[x - srcX]); i++) { - gdImageSetPixel (dst, tox, toy, mapTo); - tox++; - } - } - toy++; - } - } - gdFree (stx); - gdFree (sty); + dyMin = dstY - radius; + dyMax = dstY + radius; + dxMin = dstX - radius; + dxMax = dstX + radius; + + /* clamp loop bounds so sx/sy casts are always safe */ + if (dxMin < safe_min + radius + scX) + dxMin = safe_min + radius + scX; + if (dxMax > safe_max - radius - scX) + dxMax = safe_max - radius - scX; + if (dyMin < safe_min + radius + scY) + dyMin = safe_min + radius + scY; + if (dyMax > safe_max - radius - scY) + dyMax = safe_max - radius - scY; + + for (dy = dyMin; dy <= dyMax; dy++) { + for (dx = dxMin; dx <= dxMax; dx++) { + // for (dy = dstY - radius; (dy <= dstY + radius); dy++) { + // for (dx = dstX - radius; (dx <= dstX + radius); dx++) { + double sxd = (dx - dstX) * aCos - (dy - dstY) * aSin; + double syd = (dy - dstY) * aCos + (dx - dstX) * aSin; + int sx = sxd + scX; + int sy = syd + scY; + if ((sx >= srcX) && (sx < srcX + srcWidth) && (sy >= srcY) && (sy < srcY + srcHeight)) { + int c = gdImageGetPixel(src, sx, sy); + /* 2.0.34: transparency wins */ + if (c == src->transparent) { + gdImageSetPixel(dst, dx, dy, dst->transparent); + } else if (!src->trueColor) { + /* Use a table to avoid an expensive + lookup on every single pixel */ + if (cmap[c] == -1) { + cmap[c] = + gdImageColorResolveAlpha(dst, gdImageRed(src, c), gdImageGreen(src, c), + gdImageBlue(src, c), gdImageAlpha(src, c)); + } + gdImageSetPixel(dst, dx, dy, cmap[c]); + } else { + gdImageSetPixel( + dst, dx, dy, + gdImageColorResolveAlpha(dst, gdImageRed(src, c), gdImageGreen(src, c), + gdImageBlue(src, c), gdImageAlpha(src, c))); + } + } + } + } } /* When gd 1.x was first created, floating point was to be avoided. These days it is often faster than table lookups or integer arithmetic. The routine below is shamelessly, gloriously floating point. TBB */ - -void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) -{ - int x, y; - double sy1, sy2, sx1, sx2; - - if (!dst->trueColor) { - gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH); - return; - } - for (y = dstY; (y < dstY + dstH); y++) { - sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH; - sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH; - for (x = dstX; (x < dstX + dstW); x++) { - double sx, sy; - double spixels = 0; - double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; - double alpha_factor, alpha_sum = 0.0, contrib_sum = 0.0; - sx1 = ((double) x - (double) dstX) * (double) srcW / dstW; - sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW; - sy = sy1; - do { - double yportion; - if (floor_cast(sy) == floor_cast(sy1)) { - yportion = 1.0f - (sy - floor_cast(sy)); - if (yportion > sy2 - sy1) { - yportion = sy2 - sy1; - } - sy = floor_cast(sy); - } else if (sy == floorf(sy2)) { - yportion = sy2 - floor_cast(sy2); - } else { - yportion = 1.0f; - } - sx = sx1; - do { - double xportion; - double pcontribution; - int p; - if (floorf(sx) == floor_cast(sx1)) { - xportion = 1.0f - (sx - floor_cast(sx)); - if (xportion > sx2 - sx1) { - xportion = sx2 - sx1; - } - sx = floor_cast(sx); - } else if (sx == floorf(sx2)) { - xportion = sx2 - floor_cast(sx2); - } else { - xportion = 1.0f; - } - pcontribution = xportion * yportion; - p = gdImageGetTrueColorPixel(src, (int) sx + srcX, (int) sy + srcY); - - alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution; - red += gdTrueColorGetRed (p) * alpha_factor; - green += gdTrueColorGetGreen (p) * alpha_factor; - blue += gdTrueColorGetBlue (p) * alpha_factor; - alpha += gdTrueColorGetAlpha (p) * pcontribution; - alpha_sum += alpha_factor; - contrib_sum += pcontribution; - spixels += xportion * yportion; - sx += 1.0f; - } - while (sx < sx2); - - sy += 1.0f; - } - - while (sy < sy2); - - if (spixels != 0.0f) { - red /= spixels; - green /= spixels; - blue /= spixels; - alpha /= spixels; - } - if ( alpha_sum != 0.0f) { - if( contrib_sum != 0.0f) { - alpha_sum /= contrib_sum; - } - red /= alpha_sum; - green /= alpha_sum; - blue /= alpha_sum; - } - /* Round up closest next channel value and clamp to max channel value */ - red = red >= 255.5 ? 255 : red+0.5; - blue = blue >= 255.5 ? 255 : blue+0.5; - green = green >= 255.5 ? 255 : green+0.5; - alpha = alpha >= gdAlphaMax+0.5 ? gdAlphaMax : alpha+0.5; - gdImageSetPixel(dst, x, y, gdTrueColorAlpha ((int)red, (int)green, (int)blue, (int)alpha)); - } - } +#define floor2(exp) ((long)exp) +/** + * Function: gdImageCopyResampled + * + * Copy a resampled area from an image to another image + * + * If the source and destination area differ in size, the area will be resized + * using bilinear interpolation for truecolor images, and nearest-neighbor + * interpolation for palette images. + * + * Parameters: + * dst - The destination image. + * src - The source image. + * dstX - The x-coordinate of the upper left corner to copy to. + * dstY - The y-coordinate of the upper left corner to copy to. + * srcX - The x-coordinate of the upper left corner to copy from. + * srcY - The y-coordinate of the upper left corner to copy from. + * dstW - The width of the area to copy to. + * dstH - The height of the area to copy to. + * srcW - The width of the area to copy from. + * srcH - The height of the area to copy from. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, + int dstW, int dstH, int srcW, int srcH) +{ + int x, y; + if (!dst->trueColor) { + gdImageCopyResized(dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH); + return; + } + if (!gdImageClipCopyResized(dst, &dstX, &dstY, &dstW, &dstH, &srcX, &srcY, &srcW, &srcH)) { + return; + } + for (y = dstY; (y < dstY + dstH); y++) { + for (x = dstX; (x < dstX + dstW); x++) { + float sy1, sy2, sx1, sx2; + float sx, sy; + float spixels = 0.0; + float red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; + float alpha_factor, alpha_sum = 0.0, contrib_sum = 0.0; + sy1 = ((float)(y - dstY)) * (float)srcH / (float)dstH; + sy2 = ((float)(y + 1 - dstY)) * (float)srcH / (float)dstH; + sy = sy1; + do { + float yportion; + if (floorf(sy) == floorf(sy1)) { + yportion = 1.0 - (sy - floorf(sy)); + if (yportion > sy2 - sy1) { + yportion = sy2 - sy1; + } + sy = floorf(sy); + } else if (sy == floorf(sy2)) { + yportion = sy2 - floorf(sy2); + } else { + yportion = 1.0; + } + sx1 = ((float)(x - dstX)) * (float)srcW / dstW; + sx2 = ((float)(x + 1 - dstX)) * (float)srcW / dstW; + sx = sx1; + do { + float xportion; + float pcontribution; + int p; + if (floorf(sx) == floorf(sx1)) { + xportion = 1.0 - (sx - floorf(sx)); + if (xportion > sx2 - sx1) { + xportion = sx2 - sx1; + } + sx = floorf(sx); + } else if (sx == floorf(sx2)) { + xportion = sx2 - floorf(sx2); + } else { + xportion = 1.0; + } + pcontribution = xportion * yportion; + p = gdImageGetTrueColorPixel(src, (int)sx + srcX, (int)sy + srcY); + + alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution; + red += gdTrueColorGetRed(p) * alpha_factor; + green += gdTrueColorGetGreen(p) * alpha_factor; + blue += gdTrueColorGetBlue(p) * alpha_factor; + alpha += gdTrueColorGetAlpha(p) * pcontribution; + alpha_sum += alpha_factor; + contrib_sum += pcontribution; + spixels += xportion * yportion; + sx += 1.0; + } while (sx < sx2); + sy += 1.0f; + } while (sy < sy2); + + if (spixels != 0.0) { + red /= spixels; + green /= spixels; + blue /= spixels; + alpha /= spixels; + } + if (alpha_sum != 0.0) { + if (contrib_sum != 0.0) { + alpha_sum /= contrib_sum; + } + red /= alpha_sum; + green /= alpha_sum; + blue /= alpha_sum; + } + /* Round up closest next channel value and clamp to max channel value */ + red = red >= 255.5 ? 255 : red + 0.5; + blue = blue >= 255.5 ? 255 : blue + 0.5; + green = green >= 255.5 ? 255 : green + 0.5; + alpha = alpha >= gdAlphaMax + 0.5 ? gdAlphaMax : alpha + 0.5; + gdImageSetPixel(dst, x, y, + gdTrueColorAlpha((int)red, (int)green, (int)blue, (int)alpha)); + } + } } -void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c) -{ - if (n <= 0) { - return; - } +/** + * Group: Polygons + */ +/** + * Function: gdImagePolygon + * + * Draws a closed polygon + * + * Parameters: + * im - The image. + * p - The vertices as array of s. + * n - The number of vertices. + * c - The color. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c) +{ + if (n <= 0) { + return; + } - gdImageLine (im, p->x, p->y, p[n - 1].x, p[n - 1].y, c); - gdImageOpenPolygon (im, p, n, c); + gdImageLine(im, p->x, p->y, p[n - 1].x, p[n - 1].y, c); + gdImageOpenPolygon(im, p, n, c); } -void gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c) +/** + * Function: gdImageOpenPolygon + * + * Draws an open polygon + * + * Parameters: + * im - The image. + * p - The vertices as array of s. + * n - The number of vertices. + * c - The color + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageOpenPolygon(gdImagePtr im, gdPointPtr p, int n, int c) { - int i; - int lx, ly; + int i; + int lx, ly; - if (n <= 0) { - return; - } + if (n <= 0) { + return; + } - lx = p->x; - ly = p->y; - for (i = 1; i < n; i++) { - p++; - gdImageLine(im, lx, ly, p->x, p->y, c); - lx = p->x; - ly = p->y; - } + lx = p->x; + ly = p->y; + for (i = 1; (i < n); i++) { + p++; + gdImageLine(im, lx, ly, p->x, p->y, c); + lx = p->x; + ly = p->y; + } } /* THANKS to Kirsten Schulz for the polygon fixes! */ -/* The intersection finding technique of this code could be improved - * by remembering the previous intertersection, and by using the slope. - * That could help to adjust intersections to produce a nice - * interior_extrema. - */ +/* The intersection finding technique of this code could be improved */ +/* by remembering the previous intersection, and by using the slope. */ +/* That could help to adjust intersections to produce a nice */ +/* interior_extrema. */ -void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c) -{ - int i; - int j; - int index; - int y; - int miny, maxy, pmaxy; - int x1, y1; - int x2, y2; - int ind1, ind2; - int ints; - int fill_color; - - if (n <= 0) { - return; - } - - if (overflow2(sizeof(int), n)) { - return; - } - - if (c == gdAntiAliased) { - fill_color = im->AA_color; - } else { - fill_color = c; - } - - if (!im->polyAllocated) { - im->polyInts = (int *) gdMalloc(sizeof(int) * n); - im->polyAllocated = n; - } - if (im->polyAllocated < n) { - while (im->polyAllocated < n) { - im->polyAllocated *= 2; - } - if (overflow2(sizeof(int), im->polyAllocated)) { - return; - } - im->polyInts = (int *) gdRealloc(im->polyInts, sizeof(int) * im->polyAllocated); - } - miny = p[0].y; - maxy = p[0].y; - for (i = 1; i < n; i++) { - if (p[i].y < miny) { - miny = p[i].y; - } - if (p[i].y > maxy) { - maxy = p[i].y; - } - } - /* necessary special case: horizontal line */ - if (n > 1 && miny == maxy) { - x1 = x2 = p[0].x; - for (i = 1; (i < n); i++) { - if (p[i].x < x1) { - x1 = p[i].x; - } else if (p[i].x > x2) { - x2 = p[i].x; - } - } - gdImageLine(im, x1, miny, x2, miny, c); - return; - } - pmaxy = maxy; - /* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */ - /* 2.0.26: clipping rectangle is even better */ - if (miny < im->cy1) { - miny = im->cy1; - } - if (maxy > im->cy2) { - maxy = im->cy2; - } - /* Fix in 1.3: count a vertex only once */ - for (y = miny; y <= maxy; y++) { - /*1.4 int interLast = 0; */ - /* int dirLast = 0; */ - /* int interFirst = 1; */ - ints = 0; - for (i = 0; i < n; i++) { - if (!i) { - ind1 = n - 1; - ind2 = 0; - } else { - ind1 = i - 1; - ind2 = i; - } - y1 = p[ind1].y; - y2 = p[ind2].y; - if (y1 < y2) { - x1 = p[ind1].x; - x2 = p[ind2].x; - } else if (y1 > y2) { - y2 = p[ind1].y; - y1 = p[ind2].y; - x2 = p[ind1].x; - x1 = p[ind2].x; - } else { - continue; - } - /* Do the following math as float intermediately, and round to ensure - * that Polygon and FilledPolygon for the same set of points have the - * same footprint. - */ - if (y >= y1 && y < y2) { - im->polyInts[ints++] = (float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1; - } else if (y == pmaxy && y == y2) { - im->polyInts[ints++] = x2; - } - } - /* - 2.0.26: polygons pretty much always have less than 100 points, - and most of the time they have considerably less. For such trivial - cases, insertion sort is a good choice. Also a good choice for - future implementations that may wish to indirect through a table. - */ - for (i = 1; (i < ints); i++) { - index = im->polyInts[i]; - j = i; - while ((j > 0) && (im->polyInts[j - 1] > index)) { - im->polyInts[j] = im->polyInts[j - 1]; - j--; - } - im->polyInts[j] = index; - } - for (i = 0; i < ints - 1; i += 2) { - gdImageLine(im, im->polyInts[i], y, im->polyInts[i + 1], y, fill_color); - } - } +/** + * Function: gdImageFilledPolygon + * + * Draws a filled polygon + * + * The polygon is filled using the even-odd fillrule what can leave unfilled + * regions inside of self-intersecting polygons. This behavior might change in + * a future version. + * + * Parameters: + * im - The image. + * p - The vertices as array of s. + * n - The number of vertices. + * c - The color + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c) +{ + int i; + int j; + int index; + int y; + int miny, maxy, pmaxy; + int x1, y1; + int x2, y2; + int ind1, ind2; + int ints; + int fill_color; + + if (n <= 0) { + return; + } - /* If we are drawing this AA, then redraw the border with AA lines. */ - if (c == gdAntiAliased) { - gdImagePolygon(im, p, n, c); - } + if (c == gdAntiAliased) { + fill_color = im->AA_color; + } else { + fill_color = c; + } + if (!im->polyAllocated) { + if (overflow2(sizeof(int), n)) { + return; + } + im->polyInts = (int *)gdMalloc(sizeof(int) * n); + if (!im->polyInts) { + return; + } + im->polyAllocated = n; + } + if (im->polyAllocated < n) { + while (im->polyAllocated < n) { + im->polyAllocated *= 2; + } + if (overflow2(sizeof(int), im->polyAllocated)) { + return; + } + im->polyInts = (int *)gdReallocEx(im->polyInts, sizeof(int) * im->polyAllocated); + if (!im->polyInts) { + return; + } + } + miny = p[0].y; + maxy = p[0].y; + for (i = 1; (i < n); i++) { + if (p[i].y < miny) { + miny = p[i].y; + } + if (p[i].y > maxy) { + maxy = p[i].y; + } + } + /* necessary special case: horizontal line */ + if (n > 1 && miny == maxy) { + x1 = x2 = p[0].x; + for (i = 1; (i < n); i++) { + if (p[i].x < x1) { + x1 = p[i].x; + } else if (p[i].x > x2) { + x2 = p[i].x; + } + } + gdImageLine(im, x1, miny, x2, miny, c); + return; + } + pmaxy = maxy; + /* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */ + /* 2.0.26: clipping rectangle is even better */ + if (miny < im->cy1) { + miny = im->cy1; + } + if (maxy > im->cy2) { + maxy = im->cy2; + } + /* Fix in 1.3: count a vertex only once */ + for (y = miny; (y <= maxy); y++) { + ints = 0; + for (i = 0; (i < n); i++) { + if (!i) { + ind1 = n - 1; + ind2 = 0; + } else { + ind1 = i - 1; + ind2 = i; + } + y1 = p[ind1].y; + y2 = p[ind2].y; + if (y1 < y2) { + x1 = p[ind1].x; + x2 = p[ind2].x; + } else if (y1 > y2) { + y2 = p[ind1].y; + y1 = p[ind2].y; + x2 = p[ind1].x; + x1 = p[ind2].x; + } else { + continue; + } + + /* Do the following math as float intermediately, and round to + * ensure that Polygon and FilledPolygon for the same set of points + * have the same footprint. */ + + if ((y >= y1) && (y < y2)) { + im->polyInts[ints++] = + (int)((float)((y - y1) * (x2 - x1)) / (float)(y2 - y1) + 0.5 + x1); + } else if ((y == pmaxy) && (y == y2)) { + im->polyInts[ints++] = x2; + } + } + /* + 2.0.26: polygons pretty much always have less than 100 points, + and most of the time they have considerably less. For such trivial + cases, insertion sort is a good choice. Also a good choice for + future implementations that may wish to indirect through a table. + */ + for (i = 1; (i < ints); i++) { + index = im->polyInts[i]; + j = i; + while ((j > 0) && (im->polyInts[j - 1] > index)) { + im->polyInts[j] = im->polyInts[j - 1]; + j--; + } + im->polyInts[j] = index; + } + for (i = 0; (i < (ints - 1)); i += 2) { + gdImageLine(im, im->polyInts[i], y, im->polyInts[i + 1], y, fill_color); + } + } + /* If we are drawing this AA, then redraw the border with AA lines. */ + if (c == gdAntiAliased) { + gdImagePolygon(im, p, n, c); + } } -void gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels) -{ - if (im->style) { - gdFree(im->style); - } - if (overflow2(sizeof (int), noOfPixels)) { - return; - } - im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); - memcpy(im->style, style, sizeof(int) * noOfPixels); - im->styleLength = noOfPixels; - im->stylePos = 0; -} +/** + * Group: other + */ -void gdImageSetThickness (gdImagePtr im, int thickness) +static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t); + +/** + * Function: gdImageSetStyle + * + * Sets the style for following drawing operations + * + * Parameters: + * im - The image. + * style - An array of color values. + * noOfPixel - The number of color values. + */ +BGD_DECLARE(void) gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels) { - im->thick = thickness; + if (overflow2(sizeof(int), noOfPixels)) { + return; + } + if (im->style) { + gdFree(im->style); + } + im->style = (int *)gdMalloc(sizeof(int) * noOfPixels); + if (!im->style) { + return; + } + memcpy(im->style, style, sizeof(int) * noOfPixels); + im->styleLength = noOfPixels; + im->stylePos = 0; } -void gdImageSetBrush (gdImagePtr im, gdImagePtr brush) +/** + * Function: gdImageSetThickness + * + * Sets the thickness for following drawing operations + * + * Parameters: + * im - The image. + * thickness - The thickness in pixels. + */ +BGD_DECLARE(void) gdImageSetThickness(gdImagePtr im, int thickness) { im->thick = thickness; } + +/** + * Function: gdImageSetBrush + * + * Sets the brush for following drawing operations + * + * Parameters: + * im - The image. + * brush - The brush image. + */ +BGD_DECLARE(void) gdImageSetBrush(gdImagePtr im, gdImagePtr brush) { - int i; - im->brush = brush; - if (!im->trueColor && !im->brush->trueColor) { - for (i = 0; i < gdImageColorsTotal(brush); i++) { - int index; - index = gdImageColorResolveAlpha(im, gdImageRed(brush, i), gdImageGreen(brush, i), gdImageBlue(brush, i), gdImageAlpha(brush, i)); - im->brushColorMap[i] = index; - } - } + int i; + im->brush = brush; + if ((!im->trueColor) && (!im->brush->trueColor)) { + for (i = 0; (i < gdImageColorsTotal(brush)); i++) { + int index; + index = gdImageColorResolveAlpha(im, gdImageRed(brush, i), gdImageGreen(brush, i), + gdImageBlue(brush, i), gdImageAlpha(brush, i)); + im->brushColorMap[i] = index; + } + } } -void gdImageSetTile (gdImagePtr im, gdImagePtr tile) +/* + Function: gdImageSetTile +*/ +BGD_DECLARE(void) gdImageSetTile(gdImagePtr im, gdImagePtr tile) { - int i; - im->tile = tile; - if (!im->trueColor && !im->tile->trueColor) { - for (i = 0; i < gdImageColorsTotal(tile); i++) { - int index; - index = gdImageColorResolveAlpha(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i), gdImageAlpha(tile, i)); - im->tileColorMap[i] = index; - } - } + int i; + im->tile = tile; + if ((!im->trueColor) && (!im->tile->trueColor)) { + for (i = 0; (i < gdImageColorsTotal(tile)); i++) { + int index; + index = gdImageColorResolveAlpha(im, gdImageRed(tile, i), gdImageGreen(tile, i), + gdImageBlue(tile, i), gdImageAlpha(tile, i)); + im->tileColorMap[i] = index; + } + } } -void gdImageSetAntiAliased (gdImagePtr im, int c) +/** + * Function: gdImageSetAntiAliased + * + * Set the color for subsequent anti-aliased drawing + * + * If is passed as color to drawing operations that support + * anti-aliased drawing (such as and ), the actual + * color to be used can be set with this function. + * + * Example: draw an anti-aliased blue line: + * | gdImageSetAntiAliased(im, gdTrueColorAlpha(0, 0, gdBlueMax, + * gdAlphaOpaque)); | gdImageLine(im, 10,10, 20,20, gdAntiAliased); + * + * Parameters: + * im - The image. + * c - The color. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageSetAntiAliased(gdImagePtr im, int c) { - im->AA = 1; - im->AA_color = c; - im->AA_dont_blend = -1; + im->AA = 1; + im->AA_color = c; + im->AA_dont_blend = -1; } -void gdImageSetAntiAliasedDontBlend (gdImagePtr im, int c, int dont_blend) +/** + * Function: gdImageSetAntiAliasedDontBlend + * + * Set the color and "dont_blend" color for subsequent anti-aliased drawing + * + * This extended variant of allows to also specify a + * (background) color that will not be blended in anti-aliased drawing + * operations. + * + * Parameters: + * im - The image. + * c - The color. + * dont_blend - Whether to blend. + */ +BGD_DECLARE(void) gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c, int dont_blend) { - im->AA = 1; - im->AA_color = c; - im->AA_dont_blend = dont_blend; + im->AA = 1; + im->AA_color = c; + im->AA_dont_blend = dont_blend; } - -void gdImageInterlace (gdImagePtr im, int interlaceArg) +/** + * Function: gdImageInterlace + * + * Sets whether an image is interlaced + * + * This is relevant only when saving the image in a format that supports + * interlacing. + * + * Parameters: + * im - The image. + * interlaceArg - Whether the image is interlaced. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageInterlace(gdImagePtr im, int interlaceArg) { - im->interlace = interlaceArg; + im->interlace = interlaceArg; } -int gdImageCompare (gdImagePtr im1, gdImagePtr im2) +/** + * Function: gdImageCompare + * + * Compare two images + * + * Parameters: + * im1 - An image. + * im2 - Another image. + * + * Returns: + * A bitmask of flags where each set flag signals + * which attributes of the images are different. + */ +BGD_DECLARE(int) gdImageCompare(gdImagePtr im1, gdImagePtr im2) { - int x, y; - int p1, p2; - int cmpStatus = 0; - int sx, sy; - - if (im1->interlace != im2->interlace) { - cmpStatus |= GD_CMP_INTERLACE; - } + int x, y; + int p1, p2; + int cmpStatus = 0; + int sx, sy; - if (im1->transparent != im2->transparent) { - cmpStatus |= GD_CMP_TRANSPARENT; - } + if (im1->interlace != im2->interlace) { + cmpStatus |= GD_CMP_INTERLACE; + } - if (im1->trueColor != im2->trueColor) { - cmpStatus |= GD_CMP_TRUECOLOR; - } + if (im1->transparent != im2->transparent) { + cmpStatus |= GD_CMP_TRANSPARENT; + } - sx = im1->sx; - if (im1->sx != im2->sx) { - cmpStatus |= GD_CMP_SIZE_X + GD_CMP_IMAGE; - if (im2->sx < im1->sx) { - sx = im2->sx; - } - } + if (im1->trueColor != im2->trueColor) { + cmpStatus |= GD_CMP_TRUECOLOR; + } - sy = im1->sy; - if (im1->sy != im2->sy) { - cmpStatus |= GD_CMP_SIZE_Y + GD_CMP_IMAGE; - if (im2->sy < im1->sy) { - sy = im2->sy; - } - } + sx = im1->sx; + if (im1->sx != im2->sx) { + cmpStatus |= GD_CMP_SIZE_X + GD_CMP_IMAGE; + if (im2->sx < im1->sx) { + sx = im2->sx; + } + } - if (im1->colorsTotal != im2->colorsTotal) { - cmpStatus |= GD_CMP_NUM_COLORS; - } + sy = im1->sy; + if (im1->sy != im2->sy) { + cmpStatus |= GD_CMP_SIZE_Y + GD_CMP_IMAGE; + if (im2->sy < im1->sy) { + sy = im2->sy; + } + } - for (y = 0; y < sy; y++) { - for (x = 0; x < sx; x++) { - p1 = im1->trueColor ? gdImageTrueColorPixel(im1, x, y) : gdImagePalettePixel(im1, x, y); - p2 = im2->trueColor ? gdImageTrueColorPixel(im2, x, y) : gdImagePalettePixel(im2, x, y); + if (im1->colorsTotal != im2->colorsTotal) { + cmpStatus |= GD_CMP_NUM_COLORS; + } - if (gdImageRed(im1, p1) != gdImageRed(im2, p2)) { - cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; - break; - } - if (gdImageGreen(im1, p1) != gdImageGreen(im2, p2)) { - cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; - break; - } - if (gdImageBlue(im1, p1) != gdImageBlue(im2, p2)) { - cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; - break; - } + for (y = 0; (y < sy); y++) { + for (x = 0; (x < sx); x++) { + p1 = im1->trueColor ? gdImageTrueColorPixel(im1, x, y) : gdImagePalettePixel(im1, x, y); + p2 = im2->trueColor ? gdImageTrueColorPixel(im2, x, y) : gdImagePalettePixel(im2, x, y); + if (gdImageRed(im1, p1) != gdImageRed(im2, p2)) { + cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; + break; + } + if (gdImageGreen(im1, p1) != gdImageGreen(im2, p2)) { + cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; + break; + } + if (gdImageBlue(im1, p1) != gdImageBlue(im2, p2)) { + cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; + break; + } #if 0 /* Soon we'll add alpha channel to palettes */ if (gdImageAlpha(im1, p1) != gdImageAlpha(im2, p2)) { @@ -3005,241 +3996,532 @@ int gdImageCompare (gdImagePtr im1, gdImagePtr im2) break; } #endif - } - if (cmpStatus & GD_CMP_COLOR) { - break; - } - } + } + if (cmpStatus & GD_CMP_COLOR) { + break; + }; + } - return cmpStatus; + return cmpStatus; } -int gdAlphaBlend (int dst, int src) { +/* Thanks to Frank Warmerdam for this superior implementation + of gdAlphaBlend(), which merges alpha in the + destination color much better. */ + +/** + * Function: gdAlphaBlend + * + * Blend two colors + * + * Parameters: + * dst - The color to blend onto. + * src - The color to blend. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(int) gdAlphaBlend(int dst, int src) +{ +#if ENABLE_CORRECTED_LEGACY_COMPOSITING + return gdCompositePixelToGd(gdCompositePixel(GD_OP_OVER, gdCompositePixelFromGd(src), + gdCompositePixelFromGd(dst), 1.0f)); +#else int src_alpha = gdTrueColorGetAlpha(src); int dst_alpha, alpha, red, green, blue; int src_weight, dst_weight, tot_weight; -/* -------------------------------------------------------------------- */ -/* Simple cases we want to handle fast. */ -/* -------------------------------------------------------------------- */ - if( src_alpha == gdAlphaOpaque ) + /* -------------------------------------------------------------------- */ + /* Simple cases we want to handle fast. */ + /* -------------------------------------------------------------------- */ + if (src_alpha == gdAlphaOpaque) return src; dst_alpha = gdTrueColorGetAlpha(dst); - if( src_alpha == gdAlphaTransparent ) + if (src_alpha == gdAlphaTransparent) return dst; - if( dst_alpha == gdAlphaTransparent ) + if (dst_alpha == gdAlphaTransparent) return src; -/* -------------------------------------------------------------------- */ -/* What will the source and destination alphas be? Note that */ -/* the destination weighting is substantially reduced as the */ -/* overlay becomes quite opaque. */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* What will the source and destination alphas be? Note that */ + /* the destination weighting is substantially reduced as the */ + /* overlay becomes quite opaque. */ + /* -------------------------------------------------------------------- */ src_weight = gdAlphaTransparent - src_alpha; dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax; tot_weight = src_weight + dst_weight; -/* -------------------------------------------------------------------- */ -/* What red, green and blue result values will we use? */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* What red, green and blue result values will we use? */ + /* -------------------------------------------------------------------- */ alpha = src_alpha * dst_alpha / gdAlphaMax; - red = (gdTrueColorGetRed(src) * src_weight - + gdTrueColorGetRed(dst) * dst_weight) / tot_weight; - green = (gdTrueColorGetGreen(src) * src_weight - + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight; - blue = (gdTrueColorGetBlue(src) * src_weight - + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight; + red = (gdTrueColorGetRed(src) * src_weight + gdTrueColorGetRed(dst) * dst_weight) / tot_weight; + green = (gdTrueColorGetGreen(src) * src_weight + gdTrueColorGetGreen(dst) * dst_weight) / + tot_weight; + blue = + (gdTrueColorGetBlue(src) * src_weight + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight; -/* -------------------------------------------------------------------- */ -/* Return merged result. */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* Return merged result. */ + /* -------------------------------------------------------------------- */ return ((alpha << 24) + (red << 16) + (green << 8) + blue); +#endif +} + +#if !ENABLE_CORRECTED_LEGACY_COMPOSITING +static int gdAlphaOverlayColor(int src, int dst, int max); +#endif + +/** + * Function: gdLayerOverlay + * + * Overlay two colors + * + * Parameters: + * dst - The color to overlay onto. + * src - The color to overlay. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(int) gdLayerOverlay(int dst, int src) +{ +#if ENABLE_CORRECTED_LEGACY_COMPOSITING + return gdCompositePixelToGd(gdCompositePixel(GD_OP_OVERLAY, gdCompositePixelFromGd(src), + gdCompositePixelFromGd(dst), 1.0f)); +#else + int a1, a2; + a1 = gdAlphaMax - gdTrueColorGetAlpha(dst); + a2 = gdAlphaMax - gdTrueColorGetAlpha(src); + return ( + ((gdAlphaMax - a1 * a2 / gdAlphaMax) << 24) + + (gdAlphaOverlayColor(gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax) << 16) + + (gdAlphaOverlayColor(gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax) << 8) + + (gdAlphaOverlayColor(gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax))); +#endif +} + +/* Apply 'overlay' effect - background pixels are colourised by the foreground + * colour */ +#if !ENABLE_CORRECTED_LEGACY_COMPOSITING +static int gdAlphaOverlayColor(int src, int dst, int max) +{ + dst = dst << 1; + if (dst > max) { + /* in the "light" zone */ + return dst + (src << 1) - (dst * src / max) - max; + } else { + /* in the "dark" zone */ + return dst * src / max; + } +} +#endif + +/** + * Function: gdLayerMultiply + * + * Overlay two colors with multiply effect + * + * Parameters: + * dst - The color to overlay onto. + * src - The color to overlay. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(int) gdLayerMultiply(int dst, int src) +{ +#if ENABLE_CORRECTED_LEGACY_COMPOSITING + return gdCompositePixelToGd(gdCompositePixel(GD_OP_MULTIPLY, gdCompositePixelFromGd(src), + gdCompositePixelFromGd(dst), 1.0f)); +#else + int a1, a2, r1, r2, g1, g2, b1, b2; + a1 = gdAlphaMax - gdTrueColorGetAlpha(src); + a2 = gdAlphaMax - gdTrueColorGetAlpha(dst); + + r1 = gdRedMax - (a1 * (gdRedMax - gdTrueColorGetRed(src))) / gdAlphaMax; + r2 = gdRedMax - (a2 * (gdRedMax - gdTrueColorGetRed(dst))) / gdAlphaMax; + g1 = gdGreenMax - (a1 * (gdGreenMax - gdTrueColorGetGreen(src))) / gdAlphaMax; + g2 = gdGreenMax - (a2 * (gdGreenMax - gdTrueColorGetGreen(dst))) / gdAlphaMax; + b1 = gdBlueMax - (a1 * (gdBlueMax - gdTrueColorGetBlue(src))) / gdAlphaMax; + b2 = gdBlueMax - (a2 * (gdBlueMax - gdTrueColorGetBlue(dst))) / gdAlphaMax; + + a1 = gdAlphaMax - a1; + a2 = gdAlphaMax - a2; + return (((a1 * a2 / gdAlphaMax) << 24) + ((r1 * r2 / gdRedMax) << 16) + + ((g1 * g2 / gdGreenMax) << 8) + ((b1 * b2 / gdBlueMax))); +#endif +} + +/** + * Function: gdImageAlphaBlending + * + * Set the effect for subsequent drawing operations + * + * Note that the effect is used for truecolor images only. + * + * Parameters: + * im - The image. + * alphaBlendingArg - The effect. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg) +{ + im->alphaBlendingFlag = alphaBlendingArg; +} + +/** + * Function: gdImageSaveAlpha + * + * Sets the save alpha flag + * + * The save alpha flag specifies whether the alpha channel of the pixels should + * be saved. This is supported only for image formats that support full alpha + * transparency, e.g. PNG. + */ +BGD_DECLARE(void) gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg) +{ + im->saveAlphaFlag = saveAlphaArg; +} +/** + * Function: gdImageSetClip + * + * Sets the clipping rectangle + * + * The clipping rectangle restricts the drawing area for following drawing + * operations. + * + * Parameters: + * im - The image. + * x1 - The x-coordinate of the upper left corner. + * y1 - The y-coordinate of the upper left corner. + * x2 - The x-coordinate of the lower right corner. + * y2 - The y-coordinate of the lower right corner. + * + * See also: + * - + */ +BGD_DECLARE(void) +gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2) +{ + if (x1 < 0) { + x1 = 0; + } + if (x1 >= im->sx) { + x1 = im->sx - 1; + } + if (x2 < 0) { + x2 = 0; + } + if (x2 >= im->sx) { + x2 = im->sx - 1; + } + if (y1 < 0) { + y1 = 0; + } + if (y1 >= im->sy) { + y1 = im->sy - 1; + } + if (y2 < 0) { + y2 = 0; + } + if (y2 >= im->sy) { + y2 = im->sy - 1; + } + im->cx1 = x1; + im->cy1 = y1; + im->cx2 = x2; + im->cy2 = y2; } -void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg) -{ - im->alphaBlendingFlag = alphaBlendingArg; +/** + * Function: gdImageGetClip + * + * Gets the current clipping rectangle + * + * Parameters: + * im - The image. + * x1P - (out) The x-coordinate of the upper left corner. + * y1P - (out) The y-coordinate of the upper left corner. + * x2P - (out) The x-coordinate of the lower right corner. + * y2P - (out) The y-coordinate of the lower right corner. + * + * See also: + * - + */ +BGD_DECLARE(void) gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P) +{ + *x1P = im->cx1; + *y1P = im->cy1; + *x2P = im->cx2; + *y2P = im->cy2; } -void gdImageSaveAlpha (gdImagePtr im, int saveAlphaArg) +/** + * Function: gdImageSetResolution + * + * Sets the resolution of an image. + * + * Parameters: + * im - The image. + * res_x - The horizontal resolution in DPI. + * res_y - The vertical resolution in DPI. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y) { - im->saveAlphaFlag = saveAlphaArg; + if (res_x > 0) + im->res_x = res_x; + if (res_y > 0) + im->res_y = res_y; } -int gdLayerOverlay (int dst, int src) +#define BLEND_COLOR(a, nc, c, cc) \ + nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8); + +static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t) { - int a1, a2; - a1 = gdAlphaMax - gdTrueColorGetAlpha(dst); - a2 = gdAlphaMax - gdTrueColorGetAlpha(src); - return ( ((gdAlphaMax - a1*a2/gdAlphaMax) << 24) + - (gdAlphaOverlayColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax ) << 16) + - (gdAlphaOverlayColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax ) << 8) + - (gdAlphaOverlayColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax )) - ); + int dr, dg, db, p, r, g, b; + + /* 2.0.34: watch out for out of range calls */ + if (!gdImageBoundsSafeMacro(im, x, y)) { + return; + } + p = gdImageGetPixel(im, x, y); + /* TBB: we have to implement the dont_blend stuff to provide + the full feature set of the old implementation */ + if ((p == color) || ((p == im->AA_dont_blend) && (t != 0x00))) { + return; + } + dr = gdTrueColorGetRed(color); + dg = gdTrueColorGetGreen(color); + db = gdTrueColorGetBlue(color); + + r = gdTrueColorGetRed(p); + g = gdTrueColorGetGreen(p); + b = gdTrueColorGetBlue(p); + + BLEND_COLOR(t, dr, r, dr); + BLEND_COLOR(t, dg, g, dg); + BLEND_COLOR(t, db, b, db); + im->tpixels[y][x] = gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque); } -static int gdAlphaOverlayColor (int src, int dst, int max ) +BGD_DECLARE(void) gdImageAALine(gdImagePtr im, int x1, int y1, int x2, int y2, int col) { - /* this function implements the algorithm - * - * for dst[rgb] < 0.5, - * c[rgb] = 2.src[rgb].dst[rgb] - * and for dst[rgb] > 0.5, - * c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1 - * - */ + /* keep them as 32bits */ + long x, y, inc, frac; + long dx, dy, tmp; + int w, wid, wstart; + int thick = im->thick; + + if (!im->trueColor) { + /* TBB: don't crash when the image is of the wrong type */ + gdImageLine(im, x1, y1, x2, y2, col); + return; + } + + /* TBB: use the clipping rectangle */ + if (clip_1d(&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0) + return; + if (clip_1d(&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0) + return; + + dx = x2 - x1; + dy = y2 - y1; + + if (dx == 0 && dy == 0) { + /* TBB: allow setting points */ + gdImageSetPixel(im, x1, y1, col); + return; + } else { + double ag; + /* Cast the long to an int to avoid compiler warnings about truncation. + * This isn't a problem as computed dy/dx values came from ints above. + */ + ag = fabs(abs((int)dy) < abs((int)dx) ? cos(atan2(dy, dx)) : sin(atan2(dy, dx))); + if (ag != 0) { + wid = thick / ag; + } else { + wid = 1; + } + if (wid == 0) { + wid = 1; + } + } - dst = dst << 1; - if( dst > max ) { - /* in the "light" zone */ - return dst + (src << 1) - (dst * src / max) - max; - } else { - /* in the "dark" zone */ - return dst * src / max; - } + /* Axis aligned lines */ + if (dx == 0) { + gdImageVLine(im, x1, y1, y2, col); + return; + } else if (dy == 0) { + gdImageHLine(im, y1, x1, x2, col); + return; + } + + if (abs((int)dx) > abs((int)dy)) { + if (dx < 0) { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = x2 - x1; + dy = y2 - y1; + } + y = y1; + inc = (dy * 65536) / dx; + frac = 0; + /* TBB: set the last pixel for consistency (<=) */ + for (x = x1; x <= x2; x++) { + wstart = y - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetAAPixelColor(im, x, w, col, (frac >> 8) & 0xFF); + gdImageSetAAPixelColor(im, x, w + 1, col, (~frac >> 8) & 0xFF); + } + frac += inc; + if (frac >= 65536) { + frac -= 65536; + y++; + } else if (frac < 0) { + frac += 65536; + y--; + } + } + } else { + if (dy < 0) { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = x2 - x1; + dy = y2 - y1; + } + x = x1; + inc = (dx * 65536) / dy; + frac = 0; + /* TBB: set the last pixel for consistency (<=) */ + for (y = y1; y <= y2; y++) { + wstart = x - wid / 2; + for (w = wstart; w < wstart + wid; w++) { + gdImageSetAAPixelColor(im, w, y, col, (frac >> 8) & 0xFF); + gdImageSetAAPixelColor(im, w + 1, y, col, (~frac >> 8) & 0xFF); + } + frac += inc; + if (frac >= 65536) { + frac -= 65536; + x++; + } else if (frac < 0) { + frac += 65536; + x--; + } + } + } } -int gdLayerMultiply (int dst, int src) -{ - int a1, a2, r1, r2, g1, g2, b1, b2; - a1 = gdAlphaMax - gdTrueColorGetAlpha(src); - a2 = gdAlphaMax - gdTrueColorGetAlpha(dst); - - r1 = gdRedMax - (a1 * (gdRedMax - gdTrueColorGetRed(src))) / gdAlphaMax; - r2 = gdRedMax - (a2 * (gdRedMax - gdTrueColorGetRed(dst))) / gdAlphaMax; - g1 = gdGreenMax - (a1 * (gdGreenMax - gdTrueColorGetGreen(src))) / gdAlphaMax; - g2 = gdGreenMax - (a2 * (gdGreenMax - gdTrueColorGetGreen(dst))) / gdAlphaMax; - b1 = gdBlueMax - (a1 * (gdBlueMax - gdTrueColorGetBlue(src))) / gdAlphaMax; - b2 = gdBlueMax - (a2 * (gdBlueMax - gdTrueColorGetBlue(dst))) / gdAlphaMax ; - - a1 = gdAlphaMax - a1; - a2 = gdAlphaMax - a2; - return ( ((a1*a2/gdAlphaMax) << 24) + - ((r1*r2/gdRedMax) << 16) + - ((g1*g2/gdGreenMax) << 8) + - ((b1*b2/gdBlueMax)) - ); -} - -void gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2) -{ - if (x1 < 0) { - x1 = 0; - } - if (x1 >= im->sx) { - x1 = im->sx - 1; - } - if (x2 < 0) { - x2 = 0; - } - if (x2 >= im->sx) { - x2 = im->sx - 1; - } - if (y1 < 0) { - y1 = 0; - } - if (y1 >= im->sy) { - y1 = im->sy - 1; - } - if (y2 < 0) { - y2 = 0; - } - if (y2 >= im->sy) { - y2 = im->sy - 1; - } - im->cx1 = x1; - im->cy1 = y1; - im->cx2 = x2; - im->cy2 = y2; -} - -void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P) -{ - *x1P = im->cx1; - *y1P = im->cy1; - *x2P = im->cx2; - *y2P = im->cy2; -} - -void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y) -{ - if (res_x > 0) im->res_x = res_x; - if (res_y > 0) im->res_y = res_y; -} - -/* convert a palette image to true color */ -int gdImagePaletteToTrueColor(gdImagePtr src) -{ - unsigned int y; - unsigned int yy; - - if (src == NULL) { - return 0; - } - - if (src->trueColor == 1) { - return 1; - } else { - unsigned int x; - const unsigned int sy = gdImageSY(src); - const unsigned int sx = gdImageSX(src); - - // Note: do not revert back to gdMalloc() below ; reason here, - // due to a bug with a certain memory_limit INI value treshold, - // imagepalettetotruecolor crashes with even unrelated ZendMM allocations. - // See GH-17772 for a use case. - src->tpixels = (int **) gdCalloc(sy, sizeof(int *)); - if (src->tpixels == NULL) { - return 0; - } - - for (y = 0; y < sy; y++) { - const unsigned char *src_row = src->pixels[y]; - int * dst_row; - - /* no need to calloc it, we overwrite all pxl anyway */ - src->tpixels[y] = (int *) gdMalloc(sx * sizeof(int)); - if (src->tpixels[y] == NULL) { - goto clean_on_error; - } +/** + * Function: gdImagePaletteToTrueColor + * + * Convert a palette image to true color + * + * Parameters: + * src - The image. + * + * Returns: + * Non-zero if the conversion succeeded, zero otherwise. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImagePaletteToTrueColor(gdImagePtr src) +{ + unsigned int y; + unsigned int yy; - dst_row = src->tpixels[y]; - for (x = 0; x < sx; x++) { - const unsigned char c = *(src_row + x); - if (c == src->transparent) { - *(dst_row + x) = gdTrueColorAlpha(0, 0, 0, 127); - } else { - *(dst_row + x) = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]); - } - } - } - } - - /* free old palette buffer (y is sy) */ - for (yy = 0; yy < y; yy++) { - gdFree(src->pixels[yy]); - } - gdFree(src->pixels); - src->trueColor = 1; - src->pixels = NULL; - src->alphaBlendingFlag = 0; - src->saveAlphaFlag = 1; - - if (src->transparent >= 0) { - const unsigned char c = src->transparent; - src->transparent = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]); - } - - return 1; + if (src == NULL) { + return 0; + } + + if (src->trueColor == 1) { + return 1; + } else { + unsigned int x; + const unsigned int sy = gdImageSY(src); + const unsigned int sx = gdImageSX(src); + + // Note: do not revert back to gdMalloc() below ; reason here, + // due to a bug with a certain memory_limit INI value treshold, + // imagepalettetotruecolor crashes with even unrelated ZendMM allocations. + // See GH-17772 for a use case. + src->tpixels = (int **)gdCalloc(sy, sizeof(int *)); + if (src->tpixels == NULL) { + return 0; + } + + for (y = 0; y < sy; y++) { + const unsigned char *src_row = src->pixels[y]; + int *dst_row; + + /* no need to calloc it, we overwrite all pxl anyway */ + src->tpixels[y] = (int *)gdMalloc(sx * sizeof(int)); + if (src->tpixels[y] == NULL) { + goto clean_on_error; + } + + dst_row = src->tpixels[y]; + for (x = 0; x < sx; x++) { + const unsigned char c = *(src_row + x); + if (c == src->transparent) { + *(dst_row + x) = gdTrueColorAlpha(0, 0, 0, 127); + } else { + *(dst_row + x) = + gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]); + } + } + } + } + + /* free old palette buffer (y is sy) */ + for (yy = 0; yy < y; yy++) { + gdFree(src->pixels[yy]); + } + gdFree(src->pixels); + src->trueColor = 1; + src->pixels = NULL; + src->alphaBlendingFlag = 0; + src->saveAlphaFlag = 1; + + if (src->transparent >= 0) { + const unsigned char c = src->transparent; + src->transparent = + gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]); + } + + return 1; clean_on_error: - /* free new true color buffer (y is not allocated, have failed) */ - for (yy = 0; yy < y; yy++) { - gdFree(src->tpixels[yy]); - } - gdFree(src->tpixels); - return 0; + /* free new true color buffer (y is not allocated, have failed) */ + for (yy = 0; yy < y; yy++) { + gdFree(src->tpixels[yy]); + } + gdFree(src->tpixels); + return 0; } diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 5325a6370925..dc8728fcaec1 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -12,10 +12,25 @@ extern "C" { #include "php_compat.h" #define GD_MAJOR_VERSION 2 -#define GD_MINOR_VERSION 0 -#define GD_RELEASE_VERSION 35 +#define GD_MINOR_VERSION 4 +#define GD_RELEASE_VERSION 0 #define GD_EXTRA_VERSION "" -#define GD_VERSION_STRING "2.0.35" + +/* Bundled libgd has no separate symbol visibility requirements. */ +#ifndef BGD_EXPORT_DATA_PROT +#define BGD_EXPORT_DATA_PROT +#endif +#ifndef BGD_STDCALL +#define BGD_STDCALL +#endif +#ifndef BGD_DECLARE +#define BGD_DECLARE(rt) rt +#endif +#ifndef ARG_NOT_USED +#define ARG_NOT_USED(arg) (void)(arg) +#endif + +#define GD_VERSION_STRING "2.4.0" /* gd.h: declarations file for the graphic-draw module. * Permission to use, copy, modify, and distribute this software and its @@ -29,38 +44,36 @@ extern "C" { * documentation. */ /* stdio is needed for file I/O. */ -#include #include "gd_io.h" - -/* va_list needed in gdErrorMethod */ #include +#include /* The maximum number of palette entries in palette-based images. - In the wonderful new world of gd 2.0, you can of course have - many more colors when using truecolor mode. */ + In the wonderful new world of gd 2.0, you can of course have + many more colors when using truecolor mode. */ #define gdMaxColors 256 /* Image type. See functions below; you will not need to change - the elements directly. Use the provided macros to - access sx, sy, the color table, and colorsTotal for - read-only purposes. */ + the elements directly. Use the provided macros to + access sx, sy, the color table, and colorsTotal for + read-only purposes. */ /* If 'truecolor' is set true, the image is truecolor; - pixels are represented by integers, which - must be 32 bits wide or more. + pixels are represented by integers, which + must be 32 bits wide or more. - True colors are repsented as follows: + True colors are represented as follows: - ARGB + ARGB - Where 'A' (alpha channel) occupies only the - LOWER 7 BITS of the MSB. This very small - loss of alpha channel resolution allows gd 2.x - to keep backwards compatibility by allowing - signed integers to be used to represent colors, - and negative numbers to represent special cases, - just as in gd 1.x. */ + Where 'A' (alpha channel) occupies only the + LOWER 7 BITS of the MSB. This very small + loss of alpha channel resolution allows gd 2.x + to keep backwards compatibility by allowing + signed integers to be used to represent colors, + and negative numbers to represent special cases, + just as in gd 1.x. */ #define gdAlphaMax 127 #define gdAlphaOpaque 0 @@ -68,10 +81,85 @@ extern "C" { #define gdRedMax 255 #define gdGreenMax 255 #define gdBlueMax 255 + +/** + * Group: Color Decomposition + */ + +/** + * Macro: gdTrueColorGetAlpha + * + * Gets the alpha channel value + * + * Parameters: + * c - The color + * + * See also: + * - + */ #define gdTrueColorGetAlpha(c) (((c) & 0x7F000000) >> 24) + +/** + * Macro: gdTrueColorGetRed + * + * Gets the red channel value + * + * Parameters: + * c - The color + * + * See also: + * - + */ #define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16) + +/** + * Macro: gdTrueColorGetGreen + * + * Gets the green channel value + * + * Parameters: + * c - The color + * + * See also: + * - + */ #define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8) + +/** + * Macro: gdTrueColorGetBlue + * + * Gets the blue channel value + * + * Parameters: + * c - The color + * + * See also: + * - + */ #define gdTrueColorGetBlue(c) ((c) & 0x0000FF) + +/** + * Group: Effects + * + * The layering effect + * + * When pixels are drawn the new colors are "mixed" with the background + * depending on the effect. + * + * Note that the effect does not apply to palette images, where pixels + * are always replaced. + * + * Modes: + * gdEffectReplace - replace pixels + * gdEffectAlphaBlend - blend pixels, see + * gdEffectNormal - default mode; same as gdEffectAlphaBlend + * gdEffectOverlay - overlay pixels, see + * gdEffectMultiply - overlay pixels with multiply effect, see + * + * + * See also: + * - + */ #define gdEffectReplace 0 #define gdEffectAlphaBlend 1 #define gdEffectNormal 2 @@ -82,157 +170,250 @@ extern "C" { #define GD_FALSE 0 #define GD_EPSILON 1e-6 +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif /* This function accepts truecolor pixel values only. The - source color is composited with the destination color - based on the alpha channel value of the source color. - The resulting color is opaque. */ + source color is composited with the destination color + based on the alpha channel value of the source color. + The resulting color is opaque. */ -int gdAlphaBlend(int dest, int src); -int gdLayerOverlay(int dst, int src); -int gdLayerMultiply(int dest, int src); +BGD_DECLARE(int) gdAlphaBlend(int dest, int src); +BGD_DECLARE(int) gdLayerOverlay(int dest, int src); +BGD_DECLARE(int) gdLayerMultiply(int dest, int src); /** * Group: Transform * * Constants: gdInterpolationMethod - - * GD_BELL - Bell + * + * GD_BELL - Bell * GD_BESSEL - Bessel - * GD_BILINEAR_FIXED - fixed point bilinear + * GD_BILINEAR_FIXED - compatibility alias for bilinear * GD_BICUBIC - Bicubic - * GD_BICUBIC_FIXED - fixed point bicubic integer + * GD_BICUBIC_FIXED - compatibility alias for bicubic * GD_BLACKMAN - Blackman - * GD_BOX - Box + * GD_BOX - Box * GD_BSPLINE - BSpline * GD_CATMULLROM - Catmullrom * GD_GAUSSIAN - Gaussian - * GD_GENERALIZED_CUBIC - Generalized cubic + * GD_GENERALIZED_CUBIC - Generalized cubic * GD_HERMITE - Hermite * GD_HAMMING - Hamming * GD_HANNING - Hannig * GD_MITCHELL - Mitchell - * GD_NEAREST_NEIGHBOUR - Nearest neighbour interpolation + * GD_NEAREST_NEIGHBOUR - Nearest neighbour interpolation * GD_POWER - Power * GD_QUADRATIC - Quadratic - * GD_SINC - Sinc + * GD_SINC - Sinc * GD_TRIANGLE - Triangle * GD_WEIGHTED4 - 4 pixels weighted bilinear interpolation + * GD_LINEAR - bilinear interpolation * * See also: - * - **/ + * - + */ typedef enum { - GD_DEFAULT = 0, - GD_BELL, - GD_BESSEL, - GD_BILINEAR_FIXED, - GD_BICUBIC, - GD_BICUBIC_FIXED, - GD_BLACKMAN, - GD_BOX, - GD_BSPLINE, - GD_CATMULLROM, - GD_GAUSSIAN, - GD_GENERALIZED_CUBIC, - GD_HERMITE, - GD_HAMMING, - GD_HANNING, - GD_MITCHELL, - GD_NEAREST_NEIGHBOUR, - GD_POWER, - GD_QUADRATIC, - GD_SINC, - GD_TRIANGLE, - GD_WEIGHTED4, - GD_LINEAR, - GD_METHOD_COUNT = 22 + GD_DEFAULT = 0, + GD_BELL, + GD_BESSEL, + GD_BILINEAR_FIXED, + GD_BICUBIC, + GD_BICUBIC_FIXED, + GD_BLACKMAN, + GD_BOX, + GD_BSPLINE, + GD_CATMULLROM, + GD_GAUSSIAN, + GD_GENERALIZED_CUBIC, + GD_HERMITE, + GD_HAMMING, + GD_HANNING, + GD_MITCHELL, + GD_NEAREST_NEIGHBOUR, + GD_POWER, + GD_QUADRATIC, + GD_SINC, + GD_TRIANGLE, + GD_WEIGHTED4, + GD_LINEAR, + GD_LANCZOS3, + GD_LANCZOS8, + GD_BLACKMAN_BESSEL, + GD_BLACKMAN_SINC, + GD_QUADRATIC_BSPLINE, + GD_CUBIC_SPLINE, + GD_COSINE, + GD_WELSH, + GD_METHOD_COUNT = 30 } gdInterpolationMethod; -/* define struct with name and func ptr and add it to gdImageStruct gdInterpolationMethod interpolation; */ +/* define struct with name and func ptr and add it to gdImageStruct + * gdInterpolationMethod interpolation; */ /* Interpolation function ptr */ -typedef double (* interpolation_method )(double); +typedef double (*interpolation_method)(double, double); + +/* + Group: Types + + typedef: gdImage + + typedef: gdImagePtr + The data structure in which gd stores images. , + and the various image file-loading functions + return a pointer to this type, and the other functions expect to + receive a pointer to this type as their first argument. + + *gdImagePtr* is a pointer to *gdImage*. + + See also: + + + (Previous versions of this library encouraged directly manipulating + the contents of the struct but we are attempting to move away from + this practice so the fields are no longer documented here. If you + need to poke at the internals of this struct, feel free to look at + *gd.h*.) +*/ typedef struct gdImageStruct { - /* Palette-based image pixels */ - unsigned char ** pixels; - int sx; - int sy; - /* These are valid in palette images only. See also - 'alpha', which appears later in the structure to - preserve binary backwards compatibility */ - int colorsTotal; - int red[gdMaxColors]; - int green[gdMaxColors]; - int blue[gdMaxColors]; - int open[gdMaxColors]; - /* For backwards compatibility, this is set to the - first palette entry with 100% transparency, - and is also set and reset by the - gdImageColorTransparent function. Newer - applications can allocate palette entries - with any desired level of transparency; however, - bear in mind that many viewers, notably - many web browsers, fail to implement - full alpha channel for PNG and provide - support for full opacity or transparency only. */ - int transparent; - int *polyInts; - int polyAllocated; - struct gdImageStruct *brush; - struct gdImageStruct *tile; - int brushColorMap[gdMaxColors]; - int tileColorMap[gdMaxColors]; - int styleLength; - int stylePos; - int *style; - int interlace; - /* New in 2.0: thickness of line. Initialized to 1. */ - int thick; - /* New in 2.0: alpha channel for palettes. Note that only - Macintosh Internet Explorer and (possibly) Netscape 6 - really support multiple levels of transparency in - palettes, to my knowledge, as of 2/15/01. Most - common browsers will display 100% opaque and - 100% transparent correctly, and do something - unpredictable and/or undesirable for levels - in between. TBB */ - int alpha[gdMaxColors]; - /* Truecolor flag and pixels. New 2.0 fields appear here at the - end to minimize breakage of existing object code. */ - int trueColor; - int ** tpixels; - /* Should alpha channel be copied, or applied, each time a - pixel is drawn? This applies to truecolor images only. - No attempt is made to alpha-blend in palette images, - even if semitransparent palette entries exist. - To do that, build your image as a truecolor image, - then quantize down to 8 bits. */ - int alphaBlendingFlag; - /* Should the alpha channel of the image be saved? This affects - PNG at the moment; other future formats may also - have that capability. JPEG doesn't. */ - int saveAlphaFlag; - - /* 2.0.12: anti-aliased globals. 2.0.26: just a few vestiges after - switching to the fast, memory-cheap implementation from PHP-gd. */ - int AA; - int AA_color; - int AA_dont_blend; - - /* 2.0.12: simple clipping rectangle. These values must be checked for safety when set; please use gdImageSetClip */ - int cx1; - int cy1; - int cx2; - int cy2; - unsigned int res_x; - unsigned int res_y; - gdInterpolationMethod interpolation_id; - interpolation_method interpolation; + /* Palette-based image pixels */ + unsigned char **pixels; + int sx; + int sy; + /* These are valid in palette images only. See also + 'alpha', which appears later in the structure to + preserve binary backwards compatibility */ + int colorsTotal; + int red[gdMaxColors]; + int green[gdMaxColors]; + int blue[gdMaxColors]; + int open[gdMaxColors]; + /* For backwards compatibility, this is set to the + first palette entry with 100% transparency, + and is also set and reset by the + gdImageColorTransparent function. Newer + applications can allocate palette entries + with any desired level of transparency; however, + bear in mind that many viewers, notably + many web browsers, fail to implement + full alpha channel for PNG and provide + support for full opacity or transparency only. */ + int transparent; + int *polyInts; + int polyAllocated; + struct gdImageStruct *brush; + struct gdImageStruct *tile; + int brushColorMap[gdMaxColors]; + int tileColorMap[gdMaxColors]; + int styleLength; + int stylePos; + int *style; + int interlace; + /* New in 2.0: thickness of line. Initialized to 1. */ + int thick; + /* New in 2.0: alpha channel for palettes. Note that only + Macintosh Internet Explorer and (possibly) Netscape 6 + really support multiple levels of transparency in + palettes, to my knowledge, as of 2/15/01. Most + common browsers will display 100% opaque and + 100% transparent correctly, and do something + unpredictable and/or undesirable for levels + in between. TBB */ + int alpha[gdMaxColors]; + /* Truecolor flag and pixels. New 2.0 fields appear here at the + end to minimize breakage of existing object code. */ + int trueColor; + int **tpixels; + /* Should alpha channel be copied, or applied, each time a + pixel is drawn? This applies to truecolor images only. + No attempt is made to alpha-blend in palette images, + even if semitransparent palette entries exist. + To do that, build your image as a truecolor image, + then quantize down to 8 bits. */ + int alphaBlendingFlag; + /* Should the alpha channel of the image be saved? This affects + PNG at the moment; other future formats may also + have that capability. JPEG doesn't. */ + int saveAlphaFlag; + + /* There should NEVER BE ACCESSOR MACROS FOR ITEMS BELOW HERE, so this + part of the structure can be safely changed in new releases. */ + + /* 2.0.12: anti-aliased globals. 2.0.26: just a few vestiges after + switching to the fast, memory-cheap implementation from PHP-gd. */ + int AA; + int AA_color; + int AA_dont_blend; + + /* 2.0.12: simple clipping rectangle. These values + must be checked for safety when set; please use + gdImageSetClip */ + int cx1; + int cy1; + int cx2; + int cy2; + + /* 2.1.0: allows to specify resolution in dpi */ + unsigned int res_x; + unsigned int res_y; + + /* Selects quantization method, see gdImageTrueColorToPaletteSetMethod() and + * gdPaletteQuantizationMethod enum. */ + int paletteQuantizationMethod; + /* speed/quality trade-off. 1 = best quality, 10 = best speed. 0 = + method-specific default. Applicable to GD_QUANT_LIQ and + GD_QUANT_NEUQUANT. */ + int paletteQuantizationSpeed; + /* Image will remain true-color if conversion to palette cannot achieve + given quality. Value from 1 to 100, 1 = ugly, 100 = perfect. Applicable + to GD_QUANT_LIQ.*/ + int paletteQuantizationMinQuality; + /* Image will use minimum number of palette colors needed to achieve given + quality. Must be higher than paletteQuantizationMinQuality Value from 1 + to 100, 1 = ugly, 100 = perfect. Applicable to GD_QUANT_LIQ.*/ + int paletteQuantizationMaxQuality; + gdInterpolationMethod interpolation_id; + interpolation_method interpolation; } gdImage; -typedef gdImage * gdImagePtr; +typedef gdImage *gdImagePtr; + +typedef struct gdImageMetadata gdImageMetadata; + +#define GD_META_OK 0 +#define GD_META_ERR_FORMAT -1 +#define GD_META_ERR_PARSE -2 +#define GD_META_ERR_NOMEM -3 +#define GD_META_ERR_LIMIT -4 +#define GD_META_ERR_UNSUPPORTED -5 +#define GD_META_ERR_INVALID -6 + +#define GD_METADATA_DEFAULT_MAX_PROFILE_SIZE ((size_t)64 * 1024 * 1024) +#define GD_METADATA_DEFAULT_MAX_TOTAL_SIZE ((size_t)256 * 1024 * 1024) + +BGD_DECLARE(gdImageMetadata *) gdImageMetadataCreate(void); +BGD_DECLARE(void) gdImageMetadataFree(gdImageMetadata *metadata); +BGD_DECLARE(void) gdImageMetadataReset(gdImageMetadata *metadata); +BGD_DECLARE(int) +gdImageMetadataSetLimits(gdImageMetadata *metadata, size_t max_profile_size, size_t max_total_size); +BGD_DECLARE(void) +gdImageMetadataGetLimits(const gdImageMetadata *metadata, size_t *max_profile_size, + size_t *max_total_size); +BGD_DECLARE(int) +gdImageMetadataSetProfile(gdImageMetadata *metadata, const char *key, const unsigned char *data, + size_t size); +BGD_DECLARE(const unsigned char *) +gdImageMetadataGetProfile(const gdImageMetadata *metadata, const char *key, size_t *size); +BGD_DECLARE(int) +gdImageMetadataRemoveProfile(gdImageMetadata *metadata, const char *key); +BGD_DECLARE(size_t) +gdImageMetadataGetProfileCount(const gdImageMetadata *metadata); +BGD_DECLARE(int) +gdImageMetadataGetProfileAt(const gdImageMetadata *metadata, size_t index, const char **key, + const unsigned char **data, size_t *size); /* Point type for use in polygon drawing. */ @@ -251,64 +432,104 @@ typedef gdImage * gdImagePtr; * See also: * , , **/ -typedef struct -{ - double x, y; -} -gdPointF, *gdPointFPtr; +typedef struct { + double x, y; +} gdPointF, *gdPointFPtr; + +/* + Group: Types + + typedef: gdFont + + typedef: gdFontPtr + + A font structure, containing the bitmaps of all characters in a + font. Used to declare the characteristics of a font. Text-output + functions expect these as their second argument, following the + argument. and both + return one. + + You can provide your own font data by providing such a structure and + the associated pixel array. You can determine the width and height + of a single character in a font by examining the w and h members of + the structure. If you will not be creating your own fonts, you will + not need to concern yourself with the rest of the components of this + structure. + + Please see the files gdfontl.c and gdfontl.h for an example of + the proper declaration of this structure. + + > typedef struct { + > // # of characters in font + > int nchars; + > // First character is numbered... (usually 32 = space) + > int offset; + > // Character width and height + > int w; + > int h; + > // Font data; array of characters, one row after another. + > // Easily included in code, also easily loaded from + > // data files. + > char *data; + > } gdFont; + + gdFontPtr is a pointer to gdFont. +*/ typedef struct { - /* # of characters in font */ - int nchars; - /* First character is numbered... (usually 32 = space) */ - int offset; - /* Character width and height */ - int w; - int h; - /* Font data; array of characters, one row after another. - Easily included in code, also easily loaded from - data files. */ - char *data; + /* # of characters in font */ + int nchars; + /* First character is numbered... (usually 32 = space) */ + int offset; + /* Character width and height */ + int w; + int h; + /* Font data; array of characters, one row after another. + Easily included in code, also easily loaded from + data files. */ + char *data; } gdFont; /* Text functions take these. */ typedef gdFont *gdFontPtr; -typedef void(*gdErrorMethod)(int, const char *, va_list); +typedef void (*gdErrorMethod)(int, const char *, va_list); + +BGD_DECLARE(void) gdSetErrorMethod(gdErrorMethod); +BGD_DECLARE(void) gdClearErrorMethod(void); -void gdSetErrorMethod(gdErrorMethod); -void gdClearErrorMethod(void); +/* For backwards compatibility only. Use gdImageSetStyle() + for MUCH more flexible line drawing. Also see + gdImageSetBrush(). */ +#define gdDashSize 4 /** - * Group: Types - * - * typedef: gdRect - * Defines a rectilinear region. + * Group: Colors * - * x - left position - * y - right position - * width - Rectangle width - * height - Rectangle height + * Colors are always of type int which is supposed to be at least 32 bit large. * - * typedef: gdRectPtr - * Pointer to a + * Kinds of colors: + * true colors - ARGB values where the alpha channel is stored as most + * significant, and the blue channel as least significant + * byte. Note that the alpha channel only uses the 7 least + * significant bits. + * Don't rely on the internal representation, though, and + * use to compose a truecolor value, and + * , , + * and to access + * the respective channels. + * palette indexes - The index of a color palette entry (0-255). + * special colors - As listed in the following section. * - * See also: - * - **/ -typedef struct -{ - int x, y; - int width, height; -} -gdRect, *gdRectPtr; - -/* For backwards compatibility only. Use gdImageSetStyle() - for MUCH more flexible line drawing. Also see - gdImageSetBrush(). */ -#define gdDashSize 4 - -/* Special colors. */ + * Constants: Special Colors + * gdStyled - use the current style, see + * gdBrushed - use the current brush, see + * gdStyledBrushed - use the current style and brush + * gdTiled - use the current tile, see + * gdTransparent - indicate transparency, what is not the same as the + * transparent color index; used for lines only + * gdAntiAliased - draw anti aliased + */ #define gdStyled (-2) #define gdBrushed (-3) @@ -316,7 +537,7 @@ gdRect, *gdRectPtr; #define gdTiled (-5) /* NOT the same as the transparent color index. - This is used in line styles only. */ + This is used in line styles only. */ #define gdTransparent (-6) #define gdAntiAliased (-7) @@ -324,287 +545,768 @@ gdRect, *gdRectPtr; /* Functions to manipulate images. */ /* Creates a palette-based image (up to 256 colors). */ -gdImagePtr gdImageCreate(int sx, int sy); +BGD_DECLARE(gdImagePtr) gdImageCreate(int sx, int sy); /* An alternate name for the above (2.0). */ #define gdImageCreatePalette gdImageCreate /* Creates a truecolor image (millions of colors). */ -gdImagePtr gdImageCreateTrueColor(int sx, int sy); +BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor(int sx, int sy); /* Creates an image from various file types. These functions - return a palette or truecolor image based on the - nature of the file being loaded. Truecolor PNG - stays truecolor; palette PNG stays palette-based; - JPEG is always truecolor. */ -gdImagePtr gdImageCreateFromPng(FILE *fd); -gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromWBMP(FILE *inFile); -gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile); -gdImagePtr gdImageCreateFromJpeg(FILE *infile); -gdImagePtr gdImageCreateFromJpegEx(FILE *infile, int ignore_warning); -gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile); -gdImagePtr gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning); -gdImagePtr gdImageCreateFromJpegPtr (int size, void *data); -gdImagePtr gdImageCreateFromJpegPtrEx (int size, void *data, int ignore_warning); -gdImagePtr gdImageCreateFromWebp(FILE *fd); -gdImagePtr gdImageCreateFromWebpCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromWebpPtr (int size, void *data); - -gdImagePtr gdImageCreateFromAvif(FILE *infile); -gdImagePtr gdImageCreateFromAvifPtr(int size, void *data); -gdImagePtr gdImageCreateFromAvifCtx(gdIOCtx *infile); - -gdImagePtr gdImageCreateFromTga( FILE * fp ); -gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx* ctx); -gdImagePtr gdImageCreateFromTgaPtr(int size, void *data); - -gdImagePtr gdImageCreateFromBmp (FILE * inFile); -gdImagePtr gdImageCreateFromBmpPtr (int size, void *data); -gdImagePtr gdImageCreateFromBmpCtx (gdIOCtxPtr infile); - -const char * gdPngGetVersionString(void); - -const char * gdJpegGetVersionString(void); - -/* A custom data source. */ -/* The source function must return -1 on error, otherwise the number - of bytes fetched. 0 is EOF, not an error! */ -/* context will be passed to your source function. */ + return a palette or truecolor image based on the + nature of the file being loaded. Truecolor PNG + stays truecolor; palette PNG stays palette-based; + JPEG is always truecolor. */ +/* PNG */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPng(FILE *fd); +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx(gdIOCtxPtr in); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngCtxWithMetadata(gdIOCtxPtr in, gdImageMetadata *metadata); +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngPtrWithMetadata(int size, void *data, gdImageMetadata *metadata); +BGD_DECLARE(void) gdImagePng(gdImagePtr im, FILE *out); +BGD_DECLARE(void) gdImagePngCtx(gdImagePtr im, gdIOCtxPtr out); +/* 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all, + 1 is FASTEST but produces larger files, 9 provides the best + compression (smallest files) but takes a long time to compress, and + -1 selects the default compiled into the zlib library. */ +BGD_DECLARE(void) gdImagePngEx(gdImagePtr im, FILE *out, int level); +BGD_DECLARE(void) gdImagePngCtxEx(gdImagePtr im, gdIOCtxPtr out, int level); +BGD_DECLARE(void) +gdImagePngCtxWithMetadata(gdImagePtr im, gdIOCtxPtr out, const gdImageMetadata *metadata); +BGD_DECLARE(void) +gdImagePngCtxExWithMetadata(gdImagePtr im, gdIOCtxPtr out, int level, + const gdImageMetadata *metadata); + +/* Best to free this memory with gdFree(), not free() */ +BGD_DECLARE(void *) gdImagePngPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) gdImagePngPtrEx(gdImagePtr im, int *size, int level); +BGD_DECLARE(void *) +gdImagePngPtrWithMetadata(gdImagePtr im, int *size, const gdImageMetadata *metadata); +BGD_DECLARE(void *) +gdImagePngPtrExWithMetadata(gdImagePtr im, int *size, int level, const gdImageMetadata *metadata); +BGD_DECLARE(int) +gdImageMetadataInjectPng(void **data, int *size, const gdImageMetadata *metadata); + +#define GD_PNG_FILTER_AUTO 0U +#define GD_PNG_FILTER_NONE (1U << 0) +#define GD_PNG_FILTER_SUB (1U << 1) +#define GD_PNG_FILTER_UP (1U << 2) +#define GD_PNG_FILTER_AVERAGE (1U << 3) +#define GD_PNG_FILTER_PAETH (1U << 4) +#define GD_PNG_FILTER_ALL \ + (GD_PNG_FILTER_NONE | GD_PNG_FILTER_SUB | GD_PNG_FILTER_UP | GD_PNG_FILTER_AVERAGE | \ + GD_PNG_FILTER_PAETH) + +enum { + GD_PNG_COMPRESSION_STRATEGY_DEFAULT = 0, + GD_PNG_COMPRESSION_STRATEGY_FILTERED, + GD_PNG_COMPRESSION_STRATEGY_HUFFMAN_ONLY, + GD_PNG_COMPRESSION_STRATEGY_RLE, + GD_PNG_COMPRESSION_STRATEGY_FIXED +}; typedef struct { - int (*source) (void *context, char *buffer, int len); - void *context; -} gdSource, *gdSourcePtr; + size_t struct_size; + int compression_level; + unsigned int filters; + int compression_strategy; + const gdImageMetadata *metadata; +} gdPngWriteOptions; + +BGD_DECLARE(void) gdPngWriteOptionsInit(gdPngWriteOptions *options); +BGD_DECLARE(int) gdImagePngWithOptions(gdImagePtr im, FILE *out, const gdPngWriteOptions *options); +BGD_DECLARE(int) +gdImagePngCtxWithOptions(gdImagePtr im, gdIOCtxPtr out, const gdPngWriteOptions *options); +BGD_DECLARE(void *) +gdImagePngPtrWithOptions(gdImagePtr im, int *size, const gdPngWriteOptions *options); +BGD_DECLARE(const char *) gdPngGetVersionString(void); + +/* QOI */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoi(FILE *fd); +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiCtx(gdIOCtxPtr in); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromQoiCtxWithMetadata(gdIOCtxPtr in, gdImageMetadata *metadata); +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromQoiPtrWithMetadata(int size, void *data, gdImageMetadata *metadata); +BGD_DECLARE(void *) gdImageQoiPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) gdImageQoiPtrEx(gdImagePtr im, int *size, int colorspace); +BGD_DECLARE(void *) +gdImageQoiPtrWithMetadata(gdImagePtr im, int *size, const gdImageMetadata *metadata); +BGD_DECLARE(void *) +gdImageQoiPtrExWithMetadata(gdImagePtr im, int *size, int colorspace, + const gdImageMetadata *metadata); +BGD_DECLARE(int) gdImageMetadataInjectQoi(void **data, int *size, const gdImageMetadata *metadata); + +BGD_DECLARE(void) gdImageQoi(gdImagePtr im, FILE *out); +BGD_DECLARE(void) gdImageQoiCtx(gdImagePtr im, gdIOCtxPtr out); +BGD_DECLARE(void) +gdImageQoiCtxWithMetadata(gdImagePtr im, gdIOCtxPtr out, const gdImageMetadata *metadata); +enum { GD_QOI_SRGB = 0, GD_QOI_LINEAR = 1 }; + +BGD_DECLARE(void) gdImageQoi(gdImagePtr im, FILE *out); +BGD_DECLARE(void) gdImageQoiCtx(gdImagePtr im, gdIOCtxPtr out); +BGD_DECLARE(void) +gdImageQoiCtxWithMetadata(gdImagePtr im, gdIOCtxPtr out, const gdImageMetadata *metadata); +BGD_DECLARE(void) gdImageQoiEx(gdImagePtr im, FILE *out, int colorspace); +BGD_DECLARE(void) +gdImageQoiCtxEx(gdImagePtr im, gdIOCtxPtr out, int colorspace); +BGD_DECLARE(void) +gdImageQoiCtxExWithMetadata(gdImagePtr im, gdIOCtxPtr out, int colorspace, + const gdImageMetadata *metadata); +/* GIF */ +/* These read the first frame only */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGif(FILE *fd); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGifPtr(int size, void *data); +BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out); +BGD_DECLARE(void) gdImageGif(gdImagePtr im, FILE *out); +/* Best to free this memory with gdFree(), not free() */ +BGD_DECLARE(void *) gdImageGifPtr(gdImagePtr im, int *size); -gdImagePtr gdImageCreateFromPngSource(gdSourcePtr in); +/* Anims, frames or compositions */ +typedef struct gdGifReadStruct *gdGifReadPtr; -gdImagePtr gdImageCreateFromGd(FILE *in); -gdImagePtr gdImageCreateFromGdCtx(gdIOCtxPtr in); +typedef struct { + int width; + int height; + int backgroundIndex; + int globalColorTable; + int loopCount; +} gdGifInfo; -gdImagePtr gdImageCreateFromGd2(FILE *in); -gdImagePtr gdImageCreateFromGd2Ctx(gdIOCtxPtr in); +typedef struct { + int frameIndex; + int x; + int y; + int width; + int height; + int delay; + int disposal; + int transparentIndex; + int localColorTable; + int interlace; +} gdGifFrameInfo; + +BGD_DECLARE(int) gdGifIsAnimated(FILE *fd); +BGD_DECLARE(int) gdGifIsAnimatedCtx(gdIOCtxPtr in); +BGD_DECLARE(int) gdGifIsAnimatedPtr(int size, void *data); +BGD_DECLARE(gdGifReadPtr) gdGifReadOpen(FILE *fd); +BGD_DECLARE(gdGifReadPtr) gdGifReadOpenCtx(gdIOCtxPtr in); +BGD_DECLARE(gdGifReadPtr) gdGifReadOpenPtr(int size, void *data); +BGD_DECLARE(void) gdGifReadClose(gdGifReadPtr gif); +BGD_DECLARE(int) gdGifReadGetInfo(gdGifReadPtr gif, gdGifInfo *info); +BGD_DECLARE(int) +gdGifReadNextFrame(gdGifReadPtr gif, gdGifFrameInfo *info, gdImagePtr *frame); +BGD_DECLARE(int) +gdGifReadNextImage(gdGifReadPtr gif, gdGifFrameInfo *info, gdImagePtr *image); +BGD_DECLARE(gdImagePtr) gdGifReadCloneImage(gdGifReadPtr gif); -gdImagePtr gdImageCreateFromGd2Part(FILE *in, int srcx, int srcy, int w, int h); -gdImagePtr gdImageCreateFromGd2PartCtx(gdIOCtxPtr in, int srcx, int srcy, int w, int h); +/** + * Group: GifAnim + * + * Legal values for Disposal. gdDisposalNone is always used by + * the built-in optimizer if previm is passed. + * + * Constants: gdImageGifAnim + * + * gdDisposalUnknown - Not recommended + * gdDisposalNone - Preserve previous frame + * gdDisposalRestoreBackground - First allocated color of palette + * gdDisposalRestorePrevious - Restore to before start of frame + * + * See also: + * - + */ +enum { gdDisposalUnknown, gdDisposalNone, gdDisposalRestoreBackground, gdDisposalRestorePrevious }; + +BGD_DECLARE(void) +gdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops); +BGD_DECLARE(void) +gdImageGifAnimAdd(gdImagePtr im, FILE *outFile, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm); +BGD_DECLARE(void) gdImageGifAnimEnd(FILE *outFile); +BGD_DECLARE(void) +gdImageGifAnimBeginCtx(gdImagePtr im, gdIOCtxPtr out, int GlobalCM, int Loops); +BGD_DECLARE(void) +gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm); +BGD_DECLARE(void) gdImageGifAnimEndCtx(gdIOCtxPtr out); +BGD_DECLARE(void *) +gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM, int Loops); +BGD_DECLARE(void *) +gdImageGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm); +BGD_DECLARE(void *) gdImageGifAnimEndPtr(int *size); + +/* WBMP */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMP(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPCtx(gdIOCtxPtr infile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPPtr(int size, void *data); + +/* JPEG */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *infile); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegEx(FILE *infile, int ignore_warning); +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtxPtr infile); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxEx(gdIOCtxPtr infile, int ignore_warning); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxWithMetadata(gdIOCtxPtr infile, gdImageMetadata *metadata); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxExWithMetadata(gdIOCtxPtr infile, int ignore_warning, + gdImageMetadata *metadata); +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrWithMetadata(int size, void *data, gdImageMetadata *metadata); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrExWithMetadata(int size, void *data, int ignore_warning, + gdImageMetadata *metadata); +BGD_DECLARE(const char *) gdJpegGetVersionString(); + +/* WEBP */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebp(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpCtx(gdIOCtxPtr infile); + +typedef struct gdWebpReadStruct *gdWebpReadPtr; +typedef struct gdWebpWriteStruct *gdWebpWritePtr; -gdImagePtr gdImageCreateFromXbm(FILE *fd); -void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out); +typedef struct { + int width; + int height; + int frameCount; + int loopCount; + int backgroundColor; + int formatFlags; +} gdWebpInfo; -gdImagePtr gdImageCreateFromXpm (char *filename); +typedef struct { + int frameIndex; + int x; + int y; + int width; + int height; + int duration; + int timestamp; + int dispose; + int blend; + int hasAlpha; + int complete; +} gdWebpFrameInfo; -void gdImageDestroy(gdImagePtr im); +typedef struct { + int canvasWidth; + int canvasHeight; + int loopCount; + int backgroundColor; + int quality; + int lossless; + int method; + int minimizeSize; + int kmin; + int kmax; + int allowMixed; +} gdWebpWriteOptions; + +enum { gdWebpDisposeNone, gdWebpDisposeBackground }; +enum { gdWebpBlendAlpha, gdWebpBlendNone }; + +BGD_DECLARE(int) gdWebpIsAnimated(FILE *fd); +BGD_DECLARE(int) gdWebpIsAnimatedCtx(gdIOCtxPtr in); +BGD_DECLARE(int) gdWebpIsAnimatedPtr(int size, void *data); +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpen(FILE *fd); +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenCtx(gdIOCtxPtr in); +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenPtr(int size, void *data); +BGD_DECLARE(void) gdWebpReadClose(gdWebpReadPtr webp); +BGD_DECLARE(int) gdWebpReadGetInfo(gdWebpReadPtr webp, gdWebpInfo *info); +BGD_DECLARE(int) +gdWebpReadNextFrame(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *frame); +BGD_DECLARE(int) +gdWebpReadNextImage(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *image); +BGD_DECLARE(gdImagePtr) gdWebpReadCloneImage(gdWebpReadPtr webp); +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpen(FILE *outFile, const gdWebpWriteOptions *options); +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenCtx(gdIOCtxPtr out, const gdWebpWriteOptions *options); +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenPtr(const gdWebpWriteOptions *options); +BGD_DECLARE(int) +gdWebpWriteAddImage(gdWebpWritePtr webp, gdImagePtr image, int durationMs); +BGD_DECLARE(void) gdWebpWriteClose(gdWebpWritePtr webp); +BGD_DECLARE(void *) gdWebpWritePtrFinish(gdWebpWritePtr webp, int *size); + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxl(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlCtx(gdIOCtxPtr infile); + +BGD_DECLARE(void) gdImageJxl(gdImagePtr im, FILE *outFile); +BGD_DECLARE(void) +gdImageJxlEx(gdImagePtr im, FILE *outFile, int lossless, float distance, int effort); +BGD_DECLARE(void *) gdImageJxlPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) +gdImageJxlPtrEx(gdImagePtr im, int *size, int lossless, float distance, int effort); +BGD_DECLARE(void) gdImageJxlCtx(gdImagePtr im, gdIOCtxPtr outfile); +BGD_DECLARE(void) +gdImageJxlCtxEx(gdImagePtr im, gdIOCtxPtr outfile, int lossless, float distance, int effort); + +/* Animation API */ +typedef struct gdJxlAnimReader *gdJxlAnimReaderPtr; +typedef struct gdJxlAnim *gdJxlAnimPtr; -/* Replaces or blends with the background depending on the - most recent call to gdImageAlphaBlending and the - alpha channel value of 'color'; default is to overwrite. - Tiling and line styling are also implemented - here. All other gd drawing functions pass through this call, - allowing for many useful effects. */ +typedef struct { + int delay_ms; + int x_offset; + int y_offset; + int width; + int height; + int blend_mode; + int is_last; +} gdJxlFrameInfo; -void gdImageSetPixel(gdImagePtr im, int x, int y, int color); +#define GD_JXL_BLEND_REPLACE 0 +#define GD_JXL_BLEND_ADD 1 +#define GD_JXL_BLEND_BLEND 2 +#define GD_JXL_BLEND_MULADD 3 +#define GD_JXL_BLEND_MUL 4 -int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y); -int gdImageGetPixel(gdImagePtr im, int x, int y); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreate(FILE *inFile); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreatePtr(int size, void *data); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateCtx(gdIOCtxPtr inCtx); -void gdImageAABlend(gdImagePtr im); +BGD_DECLARE(gdImagePtr) gdJxlReadNextImage(gdJxlAnimReaderPtr reader, int *delay_ms); -void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -void gdImageAALine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateRaw(FILE *inFile); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateRawPtr(int size, void *data); +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateRawCtx(gdIOCtxPtr inCtx); -/* For backwards compatibility only. Use gdImageSetStyle() - for much more flexible line drawing. */ -void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -/* Corners specified (not width and height). Upper left first, lower right - second. */ -void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -/* Solid bar. Upper left corner first, lower right corner second. */ -void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); -void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2); -void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P); -void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y); -void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); -void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); -void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); -void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); -void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); -void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +BGD_DECLARE(gdImagePtr) gdJxlReadNextFrame(gdJxlAnimReaderPtr reader, gdJxlFrameInfo *info); -/* - * The following functions are required to be called prior to the - * use of any sort of threads in a module load / shutdown function - * respectively. - */ -void gdFontCacheMutexSetup(void); -void gdFontCacheMutexShutdown(void); +BGD_DECLARE(void) gdImageJxlAnimReaderDestroy(gdJxlAnimReaderPtr reader); -/* 2.0.16: for thread-safe use of gdImageStringFT and friends, - * call this before allowing any thread to call gdImageStringFT. - * Otherwise it is invoked by the first thread to invoke - * gdImageStringFT, with a very small but real risk of a race condition. - * Return 0 on success, nonzero on failure to initialize freetype. +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBegin(FILE *outFile, int width, int height, int lossless, float distance, int effort); + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginCtx(gdIOCtxPtr outCtx, int width, int height, int lossless, float distance, + int effort); + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginPtr(int width, int height, int lossless, float distance, int effort); + +BGD_DECLARE(int) gdImageJxlAnimAddFrame(gdJxlAnimPtr anim, gdImagePtr im, int delay_ms); + +BGD_DECLARE(int) gdImageJxlAnimEnd(gdJxlAnimPtr anim); +BGD_DECLARE(void *) gdImageJxlAnimEndPtr(gdJxlAnimPtr anim, int *size); + +/* HEIF */ + +/** + * Group: HEIF Coding Format + * + * Values that select the HEIF coding format. + * + * Constants: gdHeifCodec + * + * GD_HEIF_CODEC_UNKNOWN + * GD_HEIF_CODEC_HEVC + * GD_HEIF_CODEC_AV1 + * + * See also: + * - */ -int gdFontCacheSetup(void); +typedef enum { + GD_HEIF_CODEC_UNKNOWN = 0, + GD_HEIF_CODEC_HEVC, + GD_HEIF_CODEC_AV1 = 4, +} gdHeifCodec; -/* Optional: clean up after application is done using fonts in gdImageStringFT(). */ -void gdFontCacheShutdown(void); +/** + * Group: HEIF Chroma Subsampling + * + * Values that select the HEIF chroma subsampling. + * + * Constants: gdHeifCompression + * + * GD_HEIF_CHROMA_420 + * GD_HEIF_CHROMA_422 + * GD_HEIF_CHROMA_444 + * + * See also: + * - + */ +typedef const char *gdHeifChroma; + +#define GD_HEIF_CHROMA_420 "420" +#define GD_HEIF_CHROMA_422 "422" +#define GD_HEIF_CHROMA_444 "444" + +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeif(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifCtx(gdIOCtxPtr infile); + +BGD_DECLARE(void) +gdImageHeifEx(gdImagePtr im, FILE *outFile, int quality, gdHeifCodec codec, gdHeifChroma chroma); +BGD_DECLARE(void) gdImageHeif(gdImagePtr im, FILE *outFile); +BGD_DECLARE(void *) gdImageHeifPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) +gdImageHeifPtrEx(gdImagePtr im, int *size, int quality, gdHeifCodec codec, gdHeifChroma chroma); +BGD_DECLARE(void) +gdImageHeifCtx(gdImagePtr im, gdIOCtxPtr outfile, int quality, gdHeifCodec codec, + gdHeifChroma chroma); + +/* AVIF */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvif(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifCtx(gdIOCtxPtr infile); + +BGD_DECLARE(void) gdImageAvif(gdImagePtr im, FILE *outFile); +BGD_DECLARE(void) +gdImageAvifEx(gdImagePtr im, FILE *outFile, int quality, int speed); +BGD_DECLARE(void *) gdImageAvifPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) +gdImageAvifPtrEx(gdImagePtr im, int *size, int quality, int speed); +BGD_DECLARE(void) +gdImageAvifCtx(gdImagePtr im, gdIOCtxPtr outfile, int quality, int speed); + +/* TIFF */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiff(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffCtx(gdIOCtxPtr infile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffPtr(int size, void *data); + +typedef struct gdTiffReadStruct *gdTiffReadPtr; -/* Calls gdImageStringFT. Provided for backwards compatibility only. */ -char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string); +typedef struct { + int width; + int height; + int pageCount; + int bitsPerSample; + int samplesPerPixel; + int compression; + int photometric; + float xResolution; + float yResolution; + int resolutionUnit; +} gdTiffInfo; -/* FreeType 2 text output */ -char *gdImageStringFT(gdImage *im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string); +typedef struct { + int pageIndex; + int width; + int height; + int bitsPerSample; + int samplesPerPixel; + int compression; + int photometric; + int planar; + int hasAlpha; + int isTiled; + float xResolution; + float yResolution; + int resolutionUnit; +} gdTiffPageInfo; + +BGD_DECLARE(int) gdTiffIsMultiPage(FILE *fd); +BGD_DECLARE(int) gdTiffIsMultiPageCtx(gdIOCtxPtr in); +BGD_DECLARE(int) gdTiffIsMultiPagePtr(int size, void *data); +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpen(FILE *fd); +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenCtx(gdIOCtxPtr in); +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenPtr(int size, void *data); +BGD_DECLARE(void) gdTiffReadClose(gdTiffReadPtr tiff); +BGD_DECLARE(int) gdTiffReadGetInfo(gdTiffReadPtr tiff, gdTiffInfo *info); +BGD_DECLARE(int) +gdTiffReadNextImage(gdTiffReadPtr tiff, gdTiffPageInfo *info, gdImagePtr *image); +BGD_DECLARE(gdImagePtr) gdTiffReadCloneImage(gdTiffReadPtr tiff); + +/* TIFF Write API */ +#define GD_TIFF_RGB 1 +#define GD_TIFF_RGBA 2 +#define GD_TIFF_GRAY 3 +#define GD_TIFF_BILEVEL 4 + +#define GD_TIFF_RESUNIT_NONE 1 +#define GD_TIFF_RESUNIT_INCH 2 +#define GD_TIFF_RESUNIT_CENTIMETER 3 + +#define GD_TIFF_ALPHA_UNASSOCIATED 1 +#define GD_TIFF_ALPHA_ASSOCIATED 2 typedef struct { - double linespacing; /* fine tune line spacing for '\n' */ - int flags; /* Logical OR of gdFTEX_ values */ - int charmap; /* TBB: 2.0.12: may be gdFTEX_Unicode, - gdFTEX_Shift_JIS, gdFTEX_Big5 or gdFTEX_MacRoman; - when not specified, maps are searched - for in the above order. */ - int hdpi; - int vdpi; -} - gdFTStringExtra, *gdFTStringExtraPtr; + int bitDepth; + int colorspace; + int compression; + int jpegQuality; + int minIsWhite; + int resolutionUnit; + float xResolution; + float yResolution; + int alphaType; +} gdTiffWriteOptions; + +typedef struct gdTiffWriteStruct *gdTiffWritePtr; + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpen(FILE *outFile, const gdTiffWriteOptions *options); +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenCtx(gdIOCtxPtr out, const gdTiffWriteOptions *options); +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenPtr(const gdTiffWriteOptions *options); +BGD_DECLARE(int) gdTiffWriteAddImage(gdTiffWritePtr write, gdImagePtr image); +BGD_DECLARE(void) gdTiffWriteClose(gdTiffWritePtr write); +BGD_DECLARE(void *) gdTiffWritePtrFinish(gdTiffWritePtr write, int *size); + +BGD_DECLARE(void) gdImageTiff(gdImagePtr im, FILE *outFile); +BGD_DECLARE(void *) gdImageTiffPtr(gdImagePtr im, int *size); +BGD_DECLARE(void) gdImageTiffCtx(gdImagePtr image, gdIOCtxPtr out); + +/* TGA */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromTga(FILE *fp); +BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtxPtr ctx); +BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaPtr(int size, void *data); + +/* BMP */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmp(FILE *inFile); +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpPtr(int size, void *data); +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpCtx(gdIOCtxPtr infile); + +/* UltraHDR */ -#define gdFTEX_LINESPACE 1 -#define gdFTEX_CHARMAP 2 -#define gdFTEX_RESOLUTION 4 +/** + * Group: UltraHDR + * + * UltraHDR (gain map) APIs are separate from . The UltraHDR handle + * type is opaque and cannot be passed to existing functions. + */ -/* These are NOT flags; set one in 'charmap' if you set the gdFTEX_CHARMAP bit in 'flags'. */ -#define gdFTEX_Unicode 0 -#define gdFTEX_Shift_JIS 1 -#define gdFTEX_Big5 2 -#define gdFTEX_MacRoman 3 +/** + * Constants: gdUhdrStatus + * + * Return status values used by UltraHDR APIs. + * + * GD_UHDR_SUCCESS - operation succeeded + * GD_UHDR_NOT_AVAILABLE - libgd was built without UltraHDR support + * GD_UHDR_E_INVALID - invalid argument or state + * GD_UHDR_E_UNSUPPORTED - unsupported format or operation + * GD_UHDR_E_ENCODE - encode failure + * GD_UHDR_E_DECODE - decode failure + */ +#define GD_UHDR_SUCCESS 0 +#define GD_UHDR_NOT_AVAILABLE -1 +#define GD_UHDR_E_INVALID -2 +#define GD_UHDR_E_UNSUPPORTED -3 +#define GD_UHDR_E_ENCODE -4 +#define GD_UHDR_E_DECODE -5 -/* FreeType 2 text output with fine tuning */ -char * -gdImageStringFTEx(gdImage * im, int *brect, int fg, char * fontlist, - double ptsize, double angle, int x, int y, char * string, - gdFTStringExtraPtr strex); +/** + * Constants: gdUhdrMirrorAxis + * + * Mirror axis values used by . + * + * GD_UHDR_MIRROR_HORIZONTAL + * GD_UHDR_MIRROR_VERTICAL + */ +#define GD_UHDR_MIRROR_HORIZONTAL 0 +#define GD_UHDR_MIRROR_VERTICAL 1 +/** + * Enum: gdUhdrFormat + * + * UltraHDR container format selector. + * + * GD_UHDR_FORMAT_JPEG - UltraHDR JPEG (currently supported) + * GD_UHDR_FORMAT_WEBP - reserved for future support + * GD_UHDR_FORMAT_HEIF - reserved for future support + */ +typedef enum { + GD_UHDR_FORMAT_JPEG = 0, + GD_UHDR_FORMAT_WEBP = 1, + GD_UHDR_FORMAT_HEIF = 2 +} gdUhdrFormat; -/* Point type for use in polygon drawing. */ +/** + * Typedef: gdUhdrImage + * + * Opaque UltraHDR image handle. + */ +typedef struct gdUhdrImageStruct gdUhdrImage; + +/** + * Typedef: gdUhdrImagePtr + * + * Pointer to . + */ +typedef gdUhdrImage *gdUhdrImagePtr; + +/** + * Typedef: gdUhdrError + * + * Structured error details for UltraHDR APIs. + * + * Fields: + * code - libgd UltraHDR status code (GD_UHDR_*) + * provider_code - underlying provider error code, if any + * message - optional human-readable detail string + */ typedef struct { - int x, y; -} gdPoint, *gdPointPtr; + int code; + int provider_code; + char message[128]; +} gdUhdrError; -void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c); -void gdImageOpenPolygon(gdImagePtr im, gdPointPtr p, int n, int c); -void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c); +/** + * Typedef: gdUhdrErrorPtr + * + * Pointer to . + */ +typedef gdUhdrError *gdUhdrErrorPtr; -/* These functions still work with truecolor images, - for which they never return error. */ -int gdImageColorAllocate(gdImagePtr im, int r, int g, int b); -/* gd 2.0: palette entries with non-opaque transparency are permitted. */ -int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a); -/* Assumes opaque is the preferred alpha channel value */ -int gdImageColorClosest(gdImagePtr im, int r, int g, int b); -/* Closest match taking all four parameters into account. - A slightly different color with the same transparency - beats the exact same color with radically different - transparency */ -int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a); -/* An alternate method */ -int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b); -/* Returns exact, 100% opaque matches only */ -int gdImageColorExact(gdImagePtr im, int r, int g, int b); -/* Returns an exact match only, including alpha */ -int gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a); -/* Opaque only */ -int gdImageColorResolve(gdImagePtr im, int r, int g, int b); -/* Based on gdImageColorExactAlpha and gdImageColorClosestAlpha */ -int gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a); +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromFile(const char *filename, int format, gdUhdrErrorPtr err); +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromCtx(gdIOCtxPtr ctx, int format, gdUhdrErrorPtr err); +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromPtr(int size, void *data, int format, gdUhdrErrorPtr err); +BGD_DECLARE(void) gdUhdrImageDestroy(gdUhdrImagePtr im); -/* A simpler way to obtain an opaque truecolor value for drawing on a - truecolor image. Not for use with palette images! */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromFile(const char *filename); +BGD_DECLARE(gdImagePtr) gdImageReadFile(const char *filename); +BGD_DECLARE(gdImagePtr) gdImageReadCtx(gdIOCtxPtr ctx); -#define gdTrueColor(r, g, b) (((r) << 16) + \ - ((g) << 8) + \ - (b)) +/* + Group: Types -/* Returns a truecolor value with an alpha channel component. - gdAlphaMax (127, **NOT 255**) is transparent, 0 is completely - opaque. */ + typedef: gdSource -#define gdTrueColorAlpha(r, g, b, a) (((a) << 24) + \ - ((r) << 16) + \ - ((g) << 8) + \ - (b)) + typedef: gdSourcePtr -void gdImageColorDeallocate(gdImagePtr im, int color); + *Note:* This interface is *obsolete* and kept only for + *compatibility. Use instead. -/* Converts a truecolor image to a palette-based image, - using a high-quality two-pass quantization routine - which attempts to preserve alpha channel information - as well as R/G/B color information when creating - a palette. If ditherFlag is set, the image will be - dithered to approximate colors better, at the expense - of some obvious "speckling." colorsWanted can be - anything up to 256. If the original source image - includes photographic information or anything that - came out of a JPEG, 256 is strongly recommended. - - Better yet, don't use this function -- write real - truecolor PNGs and JPEGs. The disk space gain of - conversion to palette is not great (for small images - it can be negative) and the quality loss is ugly. */ + Represents a source from which a PNG can be read. Programmers who + do not wish to read PNGs from a file can provide their own + alternate input mechanism, using the + function. See the documentation of that function for an example of + the proper use of this type. -gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted); + > typedef struct { + > int (*source) (void *context, char *buffer, int len); + > void *context; + > } gdSource, *gdSourcePtr; -int gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted); -int gdImagePaletteToTrueColor(gdImagePtr src); + The source function must return -1 on error, otherwise the number + of bytes fetched. 0 is EOF, not an error! -/* An attempt at getting the results of gdImageTrueColorToPalette - to look a bit more like the original (im1 is the original - and im2 is the palette version */ -int gdImageColorMatch(gdImagePtr im1, gdImagePtr im2); + 'context' will be passed to your source function. -/* Specifies a color index (if a palette image) or an - RGB color (if a truecolor image) which should be - considered 100% transparent. FOR TRUECOLOR IMAGES, - THIS IS IGNORED IF AN ALPHA CHANNEL IS BEING - SAVED. Use gdImageSaveAlpha(im, 0); to - turn off the saving of a full alpha channel in - a truecolor image. Note that gdImageColorTransparent - is usually compatible with older browsers that - do not understand full alpha channels well. TBB */ -void gdImageColorTransparent(gdImagePtr im, int color); - -void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src); -void gdImagePng(gdImagePtr im, FILE *out); -void gdImagePngCtx(gdImagePtr im, gdIOCtx *out); -void gdImageGif(gdImagePtr im, FILE *out); -void gdImageGifCtx(gdImagePtr im, gdIOCtx *out); - -void * gdImageBmpPtr(gdImagePtr im, int *size, int compression); -void gdImageBmp(gdImagePtr im, FILE *outFile, int compression); -void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression); +*/ +typedef struct { + int (*source)(void *context, char *buffer, int len); + void *context; +} gdSource, *gdSourcePtr; -/* 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all, - * 1 is FASTEST but produces larger files, 9 provides the best - * compression (smallest files) but takes a long time to compress, and - * -1 selects the default compiled into the zlib library. - */ -void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter); -void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter); +/* Deprecated in favor of gdImageCreateFromPngCtx */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngSource(gdSourcePtr in); +/* for completeness with Sink 2.x APIs, will be removed in 3.0 with all Sink APIs */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiSource(gdSourcePtr in); -void gdImageWBMP(gdImagePtr image, int fg, FILE *out); -void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGifSource(gdSourcePtr in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd(FILE *in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGdCtx(gdIOCtxPtr in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGdPtr(int size, void *data); +/* Best to free this memory with gdFree(), not free() */ +BGD_DECLARE(void *) gdImageGdPtr(gdImagePtr im, int *size); +BGD_DECLARE(void) gdImageGd(gdImagePtr im, FILE *out); + +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2(FILE *in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx(gdIOCtxPtr in); +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ptr(int size, void *data); + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromGd2Part(FILE *in, int srcx, int srcy, int w, int h); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromGd2PartCtx(gdIOCtxPtr in, int srcx, int srcy, int w, int h); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromGd2PartPtr(int size, void *data, int srcx, int srcy, int w, int h); + +BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE *in); +BGD_DECLARE(void) +gdImageXbmCtx(gdImagePtr image, char *file_name, int fg, gdIOCtxPtr out); + +/* NOTE: filename, not FILE */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename); + +BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size, int compression); +BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile, int compression); +BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression); + +#define GD_BMP_COMPRESS_NONE 0 +#define GD_BMP_COMPRESS_RLE8 1 +#define GD_BMP_COMPRESS_RLE4 2 + +#define GD_BMP_FLAG_NONE 0 +#define GD_BMP_FLAG_FORCE_V4HDR (1 << 0) +#define GD_BMP_FLAG_QUANTIZE (1 << 1) +#define GD_BMP_FLAG_RGB555 (1 << 2) + +BGD_DECLARE(void *) +gdImageBmpPtrEx(gdImagePtr im, int *size, int bpp, int compression, int flags); +BGD_DECLARE(void) +gdImageBmpEx(gdImagePtr im, FILE *outFile, int bpp, int compression, int flags); +BGD_DECLARE(void) +gdImageBmpCtxEx(gdImagePtr im, gdIOCtxPtr out, int bpp, int compression, int flags); + +BGD_DECLARE(void) gdImageWBMP(gdImagePtr image, int fg, FILE *out); +BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtxPtr out); + +BGD_DECLARE(int) gdUhdrIsAvailable(void); +BGD_DECLARE(int) gdUhdrImageWidth(gdUhdrImagePtr im); +BGD_DECLARE(int) gdUhdrImageHeight(gdUhdrImagePtr im); +BGD_DECLARE(int) gdUhdrImageHasGainMap(gdUhdrImagePtr im); +BGD_DECLARE(int) +gdUhdrImageResize(gdUhdrImagePtr im, int width, int height, gdUhdrErrorPtr err); +BGD_DECLARE(int) +gdUhdrImageCrop(gdUhdrImagePtr im, int left, int top, int width, int height, gdUhdrErrorPtr err); +BGD_DECLARE(int) +gdUhdrImageRotate(gdUhdrImagePtr im, int degrees, gdUhdrErrorPtr err); +BGD_DECLARE(int) +gdUhdrImageMirror(gdUhdrImagePtr im, int axis, gdUhdrErrorPtr err); +BGD_DECLARE(int) +gdUhdrImageFile(gdUhdrImagePtr im, const char *filename, int format, int quality, + gdUhdrErrorPtr err); +BGD_DECLARE(int) +gdUhdrImageCtx(gdUhdrImagePtr im, gdIOCtxPtr ctx, int format, int quality, gdUhdrErrorPtr err); +BGD_DECLARE(void *) +gdUhdrImageWritePtr(gdUhdrImagePtr im, int *size, int format, int quality, gdUhdrErrorPtr err); +BGD_DECLARE(gdImagePtr) +gdUhdrImageGetSdr(gdUhdrImagePtr im, gdUhdrErrorPtr err); + + +BGD_DECLARE(int) gdImageFile(gdImagePtr im, const char *filename); +BGD_DECLARE(int) gdSupportsFileType(const char *filename, int writing); /* Guaranteed to correctly free memory returned - by the gdImage*Ptr functions */ + by the gdImage*Ptr functions */ void gdFree(void *m); /* Best to free this memory with gdFree(), not free() */ -void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); +BGD_DECLARE(void *) gdImageWBMPPtr(gdImagePtr im, int *size, int fg); /* 100 is highest quality (there is always a little loss with JPEG). 0 is lowest. 10 is about the lowest useful setting. */ -void gdImageJpeg(gdImagePtr im, FILE *out, int quality); -void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); +BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *out, int quality); +BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtxPtr out, int quality); +BGD_DECLARE(void) +gdImageJpegCtxWithMetadata(gdImagePtr im, gdIOCtxPtr out, int quality, + const gdImageMetadata *metadata); + +/* Best to free this memory with gdFree(), not free() */ +BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality); +BGD_DECLARE(void *) +gdImageJpegPtrWithMetadata(gdImagePtr im, int *size, int quality, const gdImageMetadata *metadata); /** * Group: WebP @@ -615,309 +1317,908 @@ void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); * , the image will be written in the lossless WebP format. * * See also: - * - + * - */ #define gdWebpLossless 101 -void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality); +BGD_DECLARE(void) gdImageWebpEx(gdImagePtr im, FILE *outFile, int quantization); +BGD_DECLARE(void) gdImageWebp(gdImagePtr im, FILE *outFile); +BGD_DECLARE(void *) gdImageWebpPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) +gdImageWebpPtrEx(gdImagePtr im, int *size, int quantization); +BGD_DECLARE(void) +gdImageWebpCtx(gdImagePtr im, gdIOCtxPtr outfile, int quantization); + + +/* + Group: Types + + typedef: gdSink + + typedef: gdSinkPtr + + *Note:* This interface is *obsolete* and kept only for + *compatibility*. Use instead. + + Represents a "sink" (destination) to which a PNG can be + written. Programmers who do not wish to write PNGs to a file can + provide their own alternate output mechanism, using the + function. See the documentation of that + function for an example of the proper use of this type. + + > typedef struct { + > int (*sink) (void *context, char *buffer, int len); + > void *context; + > } gdSink, *gdSinkPtr; + + The _sink_ function must return -1 on error, otherwise the number of + bytes written, which must be equal to len. + + _context_ will be passed to your sink function. + +*/ -/* Best to free this memory with gdFree(), not free() */ -void *gdImageJpegPtr(gdImagePtr im, int *size, int quality); - -gdImagePtr gdImageCreateFromGif(FILE *fd); -gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr in); -gdImagePtr gdImageCreateFromGifSource(gdSourcePtr in); - -void gdImageAvif(gdImagePtr im, FILE *outfile); -void gdImageAvifEx(gdImagePtr im, FILE *outfile, int quality, int speed); -void *gdImageAvifPtr(gdImagePtr im, int *size); -void *gdImageAvifPtrEx(gdImagePtr im, int *size, int quality, int speed); -void gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed); - -/* A custom data sink. For backwards compatibility. Use - gdIOCtx instead. */ -/* The sink function must return -1 on error, otherwise the number - of bytes written, which must be equal to len. */ -/* context will be passed to your sink function. */ typedef struct { - int (*sink) (void *context, const char *buffer, int len); - void *context; + int (*sink)(void *context, const char *buffer, int len); + void *context; } gdSink, *gdSinkPtr; -void gdImagePngToSink(gdImagePtr im, gdSinkPtr out); +BGD_DECLARE(void) gdImagePngToSink(gdImagePtr im, gdSinkPtr out); +BGD_DECLARE(void) gdImageQoiToSink(gdImagePtr im, gdSinkPtr out); -void gdImageGd(gdImagePtr im, FILE *out); -void gdImageGd2(gdImagePtr im, FILE *out, int cs, int fmt); +BGD_DECLARE(void) gdImageGd2(gdImagePtr im, FILE *out, int cs, int fmt); /* Best to free this memory with gdFree(), not free() */ -void* gdImagePngPtr(gdImagePtr im, int *size); +BGD_DECLARE(void *) gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size); -/* Best to free this memory with gdFree(), not free() */ -void* gdImageGdPtr(gdImagePtr im, int *size); -void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter); +BGD_DECLARE(void) gdImageDestroy(gdImagePtr im); -/* Best to free this memory with gdFree(), not free() */ -void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size); +/* These functions still work with truecolor images, + for which they never return error. */ +BGD_DECLARE(int) gdImageColorAllocate(gdImagePtr im, int r, int g, int b); +/* gd 2.0: palette entries with non-opaque transparency are permitted. */ +BGD_DECLARE(int) +gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a); +/* Assumes opaque is the preferred alpha channel value */ +BGD_DECLARE(int) gdImageColorClosest(gdImagePtr im, int r, int g, int b); +/* Closest match taking all four parameters into account. + A slightly different color with the same transparency + beats the exact same color with radically different + transparency */ +BGD_DECLARE(int) +gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a); +/* An alternate method */ +BGD_DECLARE(int) gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b); +/* Returns exact, 100% opaque matches only */ +BGD_DECLARE(int) gdImageColorExact(gdImagePtr im, int r, int g, int b); +/* Returns an exact match only, including alpha */ +BGD_DECLARE(int) +gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a); +/* Opaque only */ +BGD_DECLARE(int) gdImageColorResolve(gdImagePtr im, int r, int g, int b); +/* Based on gdImageColorExactAlpha and gdImageColorClosestAlpha */ +BGD_DECLARE(int) +gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a); + +/* A simpler way to obtain an opaque truecolor value for drawing on a + truecolor image. Not for use with palette images! */ -void gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int c); +#define gdTrueColor(r, g, b) (((r) << 16) + ((g) << 8) + (b)) + +/** + * Group: Color Composition + * + * Macro: gdTrueColorAlpha + * + * Compose a truecolor value from its components + * + * Parameters: + * r - The red channel (0-255) + * g - The green channel (0-255) + * b - The blue channel (0-255) + * a - The alpha channel (0-127, where 127 is fully transparent, and 0 is + * completely opaque). + * + * See also: + * - + * - + * - + * - + * - + */ +#define gdTrueColorAlpha(r, g, b, a) (((a) << 24) + ((r) << 16) + ((g) << 8) + (b)) + +BGD_DECLARE(void) gdImageColorDeallocate(gdImagePtr im, int color); + +/* Converts a truecolor image to a palette-based image, + using a high-quality two-pass quantization routine + which attempts to preserve alpha channel information + as well as R/G/B color information when creating + a palette. If ditherFlag is set, the image will be + dithered to approximate colors better, at the expense + of some obvious "speckling." colorsWanted can be + anything up to 256. If the original source image + includes photographic information or anything that + came out of a JPEG, 256 is strongly recommended. + + Better yet, don't use these function -- write real + truecolor PNGs and JPEGs. The disk space gain of + conversion to palette is not great (for small images + it can be negative) and the quality loss is ugly. + + DIFFERENCES: gdImageCreatePaletteFromTrueColor creates and + returns a new image. gdImageTrueColorToPalette modifies + an existing image, and the truecolor pixels are discarded. + + gdImageTrueColorToPalette() returns TRUE on success, FALSE on failure. +*/ +BGD_DECLARE(gdImagePtr) +gdImageCreatePaletteFromTrueColor(gdImagePtr im, int ditherFlag, int colorsWanted); + +BGD_DECLARE(int) +gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted); + +BGD_DECLARE(int) gdImagePaletteToTrueColor(gdImagePtr src); + +/* An attempt at getting the results of gdImageTrueColorToPalette to + * look a bit more like the original (im1 is the original and im2 is + * the palette version */ + +BGD_DECLARE(int) gdImageColorMatch(gdImagePtr im1, gdImagePtr im2); + +/* Selects quantization method used for subsequent gdImageTrueColorToPalette + calls. See gdPaletteQuantizationMethod enum (e.g. GD_QUANT_NEUQUANT, + GD_QUANT_LIQ). Speed is from 1 (highest quality) to 10 (fastest). Speed 0 + selects method-specific default (recommended). + + Returns FALSE if the given method is invalid or not available. +*/ +BGD_DECLARE(int) +gdImageTrueColorToPaletteSetMethod(gdImagePtr im, int method, int speed); + +/* + Chooses quality range that subsequent call to gdImageTrueColorToPalette will + aim for. Min and max quality is in range 1-100 (1 = ugly, 100 = perfect). Max + must be higher than min. If palette cannot represent image with at least + min_quality, then image will remain true-color. If palette can represent image + with quality better than max_quality, then lower number of colors will be + used. This function has effect only when GD_QUANT_LIQ method has been selected + and the source image is true-color. +*/ +BGD_DECLARE(void) +gdImageTrueColorToPaletteSetQuality(gdImagePtr im, int min_quality, int max_quality); + +/* Specifies a color index (if a palette image) or an + RGB color (if a truecolor image) which should be + considered 100% transparent. FOR TRUECOLOR IMAGES, + THIS IS IGNORED IF AN ALPHA CHANNEL IS BEING + SAVED. Use gdImageSaveAlpha(im, 0); to + turn off the saving of a full alpha channel in + a truecolor image. Note that gdImageColorTransparent + is usually compatible with older browsers that + do not understand full alpha channels well. TBB */ +BGD_DECLARE(void) gdImageColorTransparent(gdImagePtr im, int color); + +BGD_DECLARE(void) gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src); + +typedef int (*gdCallbackImageColor)(gdImagePtr im, int src); + +BGD_DECLARE(int) gdImageColorReplace(gdImagePtr im, int src, int dst); +BGD_DECLARE(int) +gdImageColorReplaceThreshold(gdImagePtr im, int src, int dst, float threshold); +BGD_DECLARE(int) +gdImageColorReplaceArray(gdImagePtr im, int len, int *src, int *dst); +BGD_DECLARE(int) +gdImageColorReplaceCallback(gdImagePtr im, gdCallbackImageColor callback); + +/* Replaces or blends with the background depending on the + most recent call to gdImageAlphaBlending and the + alpha channel value of 'color'; default is to overwrite. + Tiling and line styling are also implemented + here. All other gd drawing functions pass through this call, + allowing for many useful effects. + Overlay and multiply effects are used when gdImageAlphaBlending + is passed gdEffectOverlay and gdEffectMultiply */ + +BGD_DECLARE(void) gdImageSetPixel(gdImagePtr im, int x, int y, int color); + +BGD_DECLARE(int) gdImageGetPixel(gdImagePtr im, int x, int y); +BGD_DECLARE(int) gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); + +BGD_DECLARE(void) gdImageAABlend(gdImagePtr im); + +BGD_DECLARE(void) gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); +BGD_DECLARE(void) gdImageAALine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); + +/* For backwards compatibility only. Use gdImageSetStyle() + for much more flexible line drawing. */ +BGD_DECLARE(void) gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color); +/* Corners specified (not width and height). Upper left first, lower right + second. */ +BGD_DECLARE(void) gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); +/* Solid bar. Upper left corner first, lower right corner second. */ +BGD_DECLARE(void) gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); +BGD_DECLARE(void) gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2); +BGD_DECLARE(void) gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P); +BGD_DECLARE(void) +gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y); +BGD_DECLARE(void) gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); +BGD_DECLARE(void) gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); +BGD_DECLARE(void) +gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); +BGD_DECLARE(void) +gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); +BGD_DECLARE(void) +gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +BGD_DECLARE(void) +gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); + +/* + * The following functions are required to be called prior to the + * use of any sort of threads in a module load / shutdown function + * respectively. + */ +void gdFontCacheMutexSetup(void); +void gdFontCacheMutexShutdown(void); + +/* 2.0.16: for thread-safe use of gdImageStringFT and friends, + * call this before allowing any thread to call gdImageStringFT. + * Otherwise it is invoked by the first thread to invoke + * gdImageStringFT, with a very small but real risk of a race condition. + * Return 0 on success, nonzero on failure to initialize freetype. + */ +int gdFontCacheSetup(void); + +/* Optional: clean up after application is done using fonts in gdImageStringFT(). */ +void gdFontCacheShutdown(void); + +BGD_DECLARE(void) gdFreeFontCache(void); + +/* Calls gdImageStringFT. Provided for backwards compatibility only. */ +BGD_DECLARE(char *) +gdImageStringTTF(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string); + +/* FreeType 2 text output */ +BGD_DECLARE(char *) +gdImageStringFT(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string); + +/* + Group: Types + + typedef: gdFTStringExtra + + typedef: gdFTStringExtraPtr + + A structure and associated pointer type used to pass additional + parameters to the function. See + for the structure definition. + + Thanks to Wez Furlong. +*/ + +/* 2.0.5: provides an extensible way to pass additional parameters. + Thanks to Wez Furlong, sorry for the delay. */ +typedef struct { + int flags; /* Logical OR of gdFTEX_ values */ + double linespacing; /* fine tune line spacing for '\n' */ + int charmap; /* gdFTEX_Unicode, gdFTEX_Shift_JIS, gdFTEX_Big5, + or gdFTEX_Adobe_Custom/gdFTEX_MacRoman */ + int hdpi; /* if (flags & gdFTEX_RESOLUTION) */ + int vdpi; /* if (flags & gdFTEX_RESOLUTION) */ + char *xshow; /* gdMalloc'ed result if gdFTEX_XSHOW is set */ + char *fontpath; /* gdMalloc'ed result if gdFTEX_RETURNFONTPATHNAME is set */ +} gdFTStringExtra, *gdFTStringExtraPtr; + +#define gdFTEX_LINESPACE 1 +#define gdFTEX_CHARMAP 2 +#define gdFTEX_RESOLUTION 4 +#define gdFTEX_DISABLE_KERNING 8 +#define gdFTEX_XSHOW 16 +#define gdFTEX_FONTPATHNAME 32 +#define gdFTEX_FONTCONFIG 64 +#define gdFTEX_RETURNFONTPATHNAME 128 + +BGD_DECLARE(int) gdFTUseFontConfig(int flag); + +/* These are NOT flags; set one in 'charmap' if you set the + gdFTEX_CHARMAP bit in 'flags'. */ +#define gdFTEX_Unicode 0 +#define gdFTEX_Shift_JIS 1 +#define gdFTEX_Big5 2 +#define gdFTEX_Adobe_Custom 3 +#define gdFTEX_MacRoman gdFTEX_Adobe_Custom + +BGD_DECLARE(char *) +gdImageStringFTEx(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string, gdFTStringExtraPtr strex); + +/* + Group: Types + + typedef: gdPoint + + typedef: gdPointPtr + + Represents a point in the coordinate space of the image; used by + , and + for polygon drawing. + + > typedef struct { + > int x, y; + > } gdPoint, *gdPointPtr; + +*/ +typedef struct { + int x, y; +} gdPoint, *gdPointPtr; + +/** + * Typedef: gdRect + * + * A rectangle in the coordinate space of the image + * + * Members: + * x - The x-coordinate of the upper left corner. + * y - The y-coordinate of the upper left corner. + * width - The width. + * height - The height. + * + * Typedef: gdRectPtr + * + * A pointer to a + */ +typedef struct { + int x, y; + int width, height; +} gdRect, *gdRectPtr; + +BGD_DECLARE(void) gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c); +BGD_DECLARE(void) gdImageOpenPolygon(gdImagePtr im, gdPointPtr p, int n, int c); +BGD_DECLARE(void) +gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c); + +BGD_DECLARE(void) +gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style); +BGD_DECLARE(void) +gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color); +BGD_DECLARE(void) +gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color); +BGD_DECLARE(void) +gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color); /* Style is a bitwise OR ( | operator ) of these. - gdArc and gdChord are mutually exclusive; - gdChord just connects the starting and ending - angles with a straight line, while gdArc produces - a rounded edge. gdPie is a synonym for gdArc. - gdNoFill indicates that the arc or chord should be - outlined, not filled. gdEdged, used together with - gdNoFill, indicates that the beginning and ending - angles should be connected to the center; this is - a good way to outline (rather than fill) a - 'pie slice'. */ -#define gdArc 0 -#define gdPie gdArc + gdArc and gdChord are mutually exclusive; + gdChord just connects the starting and ending + angles with a straight line, while gdArc produces + a rounded edge. gdPie is a synonym for gdArc. + gdNoFill indicates that the arc or chord should be + outlined, not filled. gdEdged, used together with + gdNoFill, indicates that the beginning and ending + angles should be connected to the center; this is + a good way to outline (rather than fill) a + 'pie slice'. */ +#define gdArc 0 +#define gdPie gdArc #define gdChord 1 #define gdNoFill 2 #define gdEdged 4 -void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style); -void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color); -void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color); -void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color); -void gdImageFill(gdImagePtr im, int x, int y, int color); -void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h); -void gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, - int srcX, int srcY, int w, int h, int pct); -void gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, - int srcX, int srcY, int w, int h, int pct); +BGD_DECLARE(void) +gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color); +BGD_DECLARE(void) gdImageFill(gdImagePtr im, int x, int y, int color); +BGD_DECLARE(void) +gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h); +BGD_DECLARE(void) +gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, + int h, int pct); +BGD_DECLARE(void) +gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, + int h, int pct); /* Stretches or shrinks to fit, as needed. Does NOT attempt - to average the entire set of source pixels that scale down onto the - destination pixel. */ -void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH); + to average the entire set of source pixels that scale down onto the + destination pixel. */ +BGD_DECLARE(void) +gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, + int dstH, int srcW, int srcH); /* gd 2.0: stretches or shrinks to fit, as needed. When called with a - truecolor destination image, this function averages the - entire set of source pixels that scale down onto the - destination pixel, taking into account what portion of the - destination pixel each source pixel represents. This is a - floating point operation, but this is not a performance issue - on modern hardware, except for some embedded devices. If the - destination is a palette image, gdImageCopyResized is - substituted automatically. */ -void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH); - -gdImagePtr gdImageClone(gdImagePtr src); - -void gdImageSetBrush(gdImagePtr im, gdImagePtr brush); -void gdImageSetTile(gdImagePtr im, gdImagePtr tile); -void gdImageSetAntiAliased(gdImagePtr im, int c); -void gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c, int dont_blend); -void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels); + truecolor destination image, this function averages the + entire set of source pixels that scale down onto the + destination pixel, taking into account what portion of the + destination pixel each source pixel represents. This is a + floating point operation, but this is not a performance issue + on modern hardware, except for some embedded devices. If the + destination is a palette image, gdImageCopyResized is + substituted automatically. */ +BGD_DECLARE(void) +gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, + int dstW, int dstH, int srcW, int srcH); + +/* Source is a rectangle, with its upper left corner at + srcX and srcY. Destination is the *center* of + the rotated copy. Angle is in degrees, same as + gdImageArc. Floating point destination center + coordinates allow accurate rotation of + objects of odd-numbered width or height. */ +BGD_DECLARE(void) +gdImageCopyRotated(gdImagePtr dst, gdImagePtr src, double dstX, double dstY, int srcX, int srcY, + int srcWidth, int srcHeight, int angle); + +BGD_DECLARE(gdImagePtr) gdImageClone(gdImagePtr src); + +BGD_DECLARE(void) gdImageSetBrush(gdImagePtr im, gdImagePtr brush); +BGD_DECLARE(void) gdImageSetTile(gdImagePtr im, gdImagePtr tile); +BGD_DECLARE(void) gdImageSetAntiAliased(gdImagePtr im, int c); +BGD_DECLARE(void) gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c, int dont_blend); +BGD_DECLARE(void) gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels); + /* Line thickness (defaults to 1). Affects lines, ellipses, - rectangles, polygons and so forth. */ -void gdImageSetThickness(gdImagePtr im, int thickness); + rectangles, polygons and so forth. */ +BGD_DECLARE(void) gdImageSetThickness(gdImagePtr im, int thickness); /* On or off (1 or 0) for all three of these. */ -void gdImageInterlace(gdImagePtr im, int interlaceArg); -void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg); -void gdImageAntialias(gdImagePtr im, int antialias); -void gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg); - -enum gdPixelateMode { - GD_PIXELATE_UPPERLEFT, - GD_PIXELATE_AVERAGE +BGD_DECLARE(void) gdImageInterlace(gdImagePtr im, int interlaceArg); +BGD_DECLARE(void) gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg); +BGD_DECLARE(void) gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg); + +/** + * Group: Color Quantization + * + * Enum: gdPaletteQuantizationMethod + * + * Constants: + * GD_QUANT_DEFAULT - GD_QUANT_LIQ if libimagequant is available, + * GD_QUANT_JQUANT otherwise. + * GD_QUANT_JQUANT - libjpeg's old median cut. Fast, but only uses 16-bit + * color. + * GD_QUANT_NEUQUANT - NeuQuant - approximation using Kohonen neural network. + * GD_QUANT_LIQ - A combination of algorithms used in libimagequant + * aiming for the highest quality at cost of speed. + * + * Note that GD_QUANT_JQUANT does not retain the alpha channel, and + * GD_QUANT_NEUQUANT does not support dithering. + * + * See also: + * - + */ +enum gdPaletteQuantizationMethod { + GD_QUANT_DEFAULT = 0, + GD_QUANT_JQUANT = 1, + GD_QUANT_NEUQUANT = 2, + GD_QUANT_LIQ = 3 }; +BGD_DECLARE(gdImagePtr) +gdImageNeuQuant(gdImagePtr im, const int max_color, int sample_factor); + +/* filters section + * + * Negate the imag src, white becomes black, + * The red, green, and blue intensities of an image are negated. + * White becomes black, yellow becomes blue, etc. + */ + +enum gdPixelateMode { GD_PIXELATE_UPPERLEFT, GD_PIXELATE_AVERAGE }; -int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode); +BGD_DECLARE(int) +gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode); typedef struct { - int sub; - int plus; - unsigned int num_colors; - int *colors; - unsigned int seed; + int sub; + int plus; + unsigned int num_colors; + int *colors; + unsigned int seed; } gdScatter, *gdScatterPtr; -int gdImageScatter(gdImagePtr im, int sub, int plus); -int gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors); -int gdImageScatterEx(gdImagePtr im, gdScatterPtr s); +BGD_DECLARE(int) gdImageScatter(gdImagePtr im, int sub, int plus); +BGD_DECLARE(int) +gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors); +BGD_DECLARE(int) gdImageScatterEx(gdImagePtr im, gdScatterPtr s); +BGD_DECLARE(int) gdImageSmooth(gdImagePtr im, float weight); +BGD_DECLARE(int) gdImageMeanRemoval(gdImagePtr im); +BGD_DECLARE(int) gdImageEmboss(gdImagePtr im); +BGD_DECLARE(int) gdImageGaussianBlur(gdImagePtr im); +BGD_DECLARE(int) gdImageEdgeDetectQuick(gdImagePtr src); +BGD_DECLARE(int) gdImageSelectiveBlur(gdImagePtr src); +BGD_DECLARE(int) +gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset); +BGD_DECLARE(int) +gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha); +BGD_DECLARE(int) gdImageContrast(gdImagePtr src, double contrast); +BGD_DECLARE(int) gdImageBrightness(gdImagePtr src, int brightness); +BGD_DECLARE(int) gdImageGrayScale(gdImagePtr src); +BGD_DECLARE(int) gdImageNegate(gdImagePtr src); + +BGD_DECLARE(gdImagePtr) +gdImageCopyGaussianBlurred(gdImagePtr src, int radius, double sigma); -/* Macros to access information about images. */ - -/* Returns nonzero if the image is a truecolor image, - zero for a palette image. */ +/** + * Group: Accessor Macros + */ +/** + * Macro: gdImageTrueColor + * + * Whether an image is a truecolor image. + * + * Parameters: + * im - The image. + * + * Returns: + * Non-zero if the image is a truecolor image, zero for palette images. + */ #define gdImageTrueColor(im) ((im)->trueColor) +/** + * Macro: gdImageSX + * + * Gets the width (in pixels) of an image. + * + * Parameters: + * im - The image. + */ #define gdImageSX(im) ((im)->sx) -#define gdImageSY(im) ((im)->sy) -#define gdImageColorsTotal(im) ((im)->colorsTotal) -#define gdImageRed(im, c) ((im)->trueColor ? gdTrueColorGetRed(c) : \ - (im)->red[(c)]) -#define gdImageGreen(im, c) ((im)->trueColor ? gdTrueColorGetGreen(c) : \ - (im)->green[(c)]) -#define gdImageBlue(im, c) ((im)->trueColor ? gdTrueColorGetBlue(c) : \ - (im)->blue[(c)]) -#define gdImageAlpha(im, c) ((im)->trueColor ? gdTrueColorGetAlpha(c) : \ - (im)->alpha[(c)]) -#define gdImageGetTransparent(im) ((im)->transparent) -#define gdImageGetInterlaced(im) ((im)->interlace) -/* These macros provide direct access to pixels in - palette-based and truecolor images, respectively. - If you use these macros, you must perform your own - bounds checking. Use of the macro for the correct type - of image is also your responsibility. */ -#define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)] -#define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)] -#define gdImageResolutionX(im) (im)->res_x -#define gdImageResolutionY(im) (im)->res_y - -/* I/O Support routines. */ +/** + * Macro: gdImageSY + * + * Gets the height (in pixels) of an image. + * + * Parameters: + * im - The image. + */ +#define gdImageSY(im) ((im)->sy) -gdIOCtx* gdNewFileCtx(FILE*); -gdIOCtx* gdNewDynamicCtx(int, void*); -gdIOCtx *gdNewDynamicCtxEx(int size, void *data, int freeFlag); -gdIOCtx* gdNewSSCtx(gdSourcePtr in, gdSinkPtr out); -void* gdDPExtractData(struct gdIOCtx* ctx, int *size); +/** + * Macro: gdImageColorsTotal + * + * Gets the number of colors in the palette. + * + * This macro is only valid for palette images. + * + * Parameters: + * im - The image + */ +#define gdImageColorsTotal(im) ((im)->colorsTotal) -#define GD2_CHUNKSIZE 128 -#define GD2_CHUNKSIZE_MIN 64 -#define GD2_CHUNKSIZE_MAX 4096 +/** + * Macro: gdImageRed + * + * Gets the red component value of a given color. + * + * Parameters: + * im - The image. + * c - The color. + */ +#define gdImageRed(im, c) ((im)->trueColor ? gdTrueColorGetRed(c) : (im)->red[(c)]) -#define GD2_VERS 2 -#define GD2_ID "gd2" -#define GD2_FMT_RAW 1 -#define GD2_FMT_COMPRESSED 2 +/** + * Macro: gdImageGreen + * + * Gets the green component value of a given color. + * + * Parameters: + * im - The image. + * c - The color. + */ +#define gdImageGreen(im, c) ((im)->trueColor ? gdTrueColorGetGreen(c) : (im)->green[(c)]) +/** + * Macro: gdImageBlue + * + * Gets the blue component value of a given color. + * + * Parameters: + * im - The image. + * c - The color. + */ +#define gdImageBlue(im, c) ((im)->trueColor ? gdTrueColorGetBlue(c) : (im)->blue[(c)]) -/* filters section +/** + * Macro: gdImageAlpha * - * Negate the imag src, white becomes black, - * The red, green, and blue intensities of an image are negated. - * White becomes black, yellow becomes blue, etc. + * Gets the alpha component value of a given color. + * + * Parameters: + * im - The image. + * c - The color. */ -int gdImageNegate(gdImagePtr src); +#define gdImageAlpha(im, c) ((im)->trueColor ? gdTrueColorGetAlpha(c) : (im)->alpha[(c)]) -/* Convert the image src to a grayscale image */ -int gdImageGrayScale(gdImagePtr src); +/** + * Macro: gdImageGetTransparent + * + * Gets the transparent color of the image. + * + * Parameters: + * im - The image. + * + * See also: + * - + */ +#define gdImageGetTransparent(im) ((im)->transparent) -/* Set the brightness level for the image src */ -int gdImageBrightness(gdImagePtr src, int brightness); +/** + * Macro: gdImageGetInterlaced + * + * Whether an image is interlaced. + * + * Parameters: + * im - The image. + * + * Returns: + * Non-zero for interlaced images, zero otherwise. + * + * See also: + * - + */ +#define gdImageGetInterlaced(im) ((im)->interlace) -/* Set the contrast level for the image */ -int gdImageContrast(gdImagePtr src, double contrast); +/** + * Macro: gdImagePalettePixel + * + * Gets the color of a pixel. + * + * Calling this macro is only valid for palette images. + * No bounds checking is done for the coordinates. + * + * Parameters: + * im - The image. + * x - The x-coordinate. + * y - The y-coordinate. + * + * See also: + * - + * - + */ +#define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)] -/* Simply adds or subtracts respectively red, green or blue to a pixel */ -int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha); +/** + * Macro: gdImageTrueColorPixel + * + * Gets the color of a pixel. + * + * Calling this macro is only valid for truecolor images. + * No bounds checking is done for the coordinates. + * + * Parameters: + * im - The image. + * x - The x-coordinate. + * y - The y-coordinate. + * + * See also: + * - + * - + */ +#define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)] -/* Image convolution by a 3x3 custom matrix */ -int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset); +/** + * Macro: gdImageResolutionX + * + * Gets the horizontal resolution in DPI. + * + * Parameters: + * im - The image. + * + * See also: + * - + * - + */ +#define gdImageResolutionX(im) (im)->res_x -int gdImageEdgeDetectQuick(gdImagePtr src); +/** + * Macro: gdImageResolutionY + * + * Gets the vertical resolution in DPI. + * + * Parameters: + * im - The image. + * + * See also: + * - + * - + */ +#define gdImageResolutionY(im) (im)->res_y -int gdImageGaussianBlur(gdImagePtr im); +/* I/O Support routines. */ -int gdImageSelectiveBlur( gdImagePtr src); +BGD_DECLARE(gdIOCtxPtr) gdNewFileCtx(FILE *); +/* If data is null, size is ignored and an initial data buffer is + allocated automatically. NOTE: this function assumes gd has the right + to free or reallocate "data" at will! Also note that gd will free + "data" when the IO context is freed. If data is not null, it must point + to memory allocated with gdMalloc, or by a call to gdImage[something]Ptr. + If not, see gdNewDynamicCtxEx for an alternative. */ +BGD_DECLARE(gdIOCtxPtr) gdNewDynamicCtx(int size, void *data); +/* 2.0.21: if freeFlag is nonzero, gd will free and/or reallocate "data" as + needed as described above. If freeFlag is zero, gd will never free + or reallocate "data", which means that the context should only be used + for *reading* an image from a memory buffer, or writing an image to a + memory buffer which is already large enough. If the memory buffer is + not large enough and an image write is attempted, the write operation + will fail. Those wishing to write an image to a buffer in memory have + a much simpler alternative in the gdImage[something]Ptr functions. */ +BGD_DECLARE(gdIOCtxPtr) gdNewDynamicCtxEx(int size, void *data, int freeFlag); +BGD_DECLARE(gdIOCtxPtr) gdNewSSCtx(gdSourcePtr in, gdSinkPtr out); +BGD_DECLARE(void *) gdDPExtractData(gdIOCtxPtr ctx, int *size); + +#define GD2_CHUNKSIZE 128 +#define GD2_CHUNKSIZE_MIN 64 +#define GD2_CHUNKSIZE_MAX 4096 + +#define GD2_VERS 2 +#define GD2_ID "gd2" +#define GD2_FMT_RAW 1 +#define GD2_FMT_COMPRESSED 2 -int gdImageEmboss(gdImagePtr im); +/* Image comparison definitions */ +BGD_DECLARE(int) gdImageCompare(gdImagePtr im1, gdImagePtr im2); -int gdImageMeanRemoval(gdImagePtr im); +typedef enum { + GD_IMAGE_DIFF_NONE, + GD_IMAGE_DIFF_OVERLAY, + GD_IMAGE_DIFF_MASK +} gdImageDiffMode; -int gdImageSmooth(gdImagePtr im, float weight); +typedef struct { + gdImageDiffMode mode; + int highlight_color; +} gdImagePerceptualDiffOptions; -/* Image comparison definitions */ -int gdImageCompare(gdImagePtr im1, gdImagePtr im2); +typedef struct { + unsigned int pixels_changed; + /* Largest normalized perceptual distance, in the range 0.0 to 1.0. */ + double maximum_delta; +} gdImagePerceptualDiffResult; -void gdImageFlipHorizontal(gdImagePtr im); -void gdImageFlipVertical(gdImagePtr im); -void gdImageFlipBoth(gdImagePtr im); +/* + * Compare two equally sized images using a perceptual YIQ distance. + * + * A NULL options pointer selects an overlay with opaque red highlights. A + * non-NULL diff_image receives a newly allocated truecolor image for overlay + * and mask modes; the caller owns it and must call gdImageDestroy(). Passing + * NULL for diff_image computes statistics only. The result is always reset, + * including on failure. + * + * Returns 1 on success, or 0 for invalid arguments or allocation failure. + */ +BGD_DECLARE(int) +gdImagePerceptualDiff(gdImagePtr image1, gdImagePtr image2, double threshold, + const gdImagePerceptualDiffOptions *options, + gdImagePtr *diff_image, + gdImagePerceptualDiffResult *result); -#define GD_FLIP_HORIZONTAL 1 -#define GD_FLIP_VERTICAL 2 -#define GD_FLIP_BOTH 3 +BGD_DECLARE(void) gdImageFlipHorizontal(gdImagePtr im); +BGD_DECLARE(void) gdImageFlipVertical(gdImagePtr im); +BGD_DECLARE(void) gdImageFlipBoth(gdImagePtr im); /** * Group: Crop * * Constants: gdCropMode - * GD_CROP_DEFAULT - Default crop mode (4 corners or background) + * GD_CROP_DEFAULT - Same as GD_CROP_TRANSPARENT * GD_CROP_TRANSPARENT - Crop using the transparent color * GD_CROP_BLACK - Crop black borders * GD_CROP_WHITE - Crop white borders * GD_CROP_SIDES - Crop using colors of the 4 corners * * See also: - * + * - **/ enum gdCropMode { - GD_CROP_DEFAULT = 0, - GD_CROP_TRANSPARENT, - GD_CROP_BLACK, - GD_CROP_WHITE, - GD_CROP_SIDES, - GD_CROP_THRESHOLD + GD_CROP_DEFAULT = 0, + GD_CROP_TRANSPARENT, + GD_CROP_BLACK, + GD_CROP_WHITE, + GD_CROP_SIDES, + GD_CROP_THRESHOLD }; -gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop); -gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode); -gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold); +BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop); +BGD_DECLARE(gdImagePtr) gdImageCropAuto(gdImagePtr im, const unsigned int mode); +BGD_DECLARE(gdImagePtr) +gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold); -int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id); -gdInterpolationMethod gdImageGetInterpolationMethod(gdImagePtr im); +BGD_DECLARE(int) +gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id); +BGD_DECLARE(gdInterpolationMethod) gdImageGetInterpolationMethod(gdImagePtr im); -gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height); +BGD_DECLARE(gdImagePtr) +gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height); -gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor); +BGD_DECLARE(gdImagePtr) +gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor); typedef enum { - GD_AFFINE_TRANSLATE = 0, - GD_AFFINE_SCALE, - GD_AFFINE_ROTATE, - GD_AFFINE_SHEAR_HORIZONTAL, - GD_AFFINE_SHEAR_VERTICAL, + GD_AFFINE_TRANSLATE = 0, + GD_AFFINE_SCALE, + GD_AFFINE_ROTATE, + GD_AFFINE_SHEAR_HORIZONTAL, + GD_AFFINE_SHEAR_VERTICAL } gdAffineStandardMatrix; -int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, const double affine[6]); -int gdAffineInvert (double dst[6], const double src[6]); -int gdAffineFlip (double dst_affine[6], const double src_affine[6], const int flip_h, const int flip_v); -int gdAffineConcat (double dst[6], const double m1[6], const double m2[6]); - -int gdAffineIdentity (double dst[6]); -int gdAffineScale (double dst[6], const double scale_x, const double scale_y); -int gdAffineRotate (double dst[6], const double angle); -int gdAffineShearHorizontal (double dst[6], const double angle); -int gdAffineShearVertical(double dst[6], const double angle); -int gdAffineTranslate (double dst[6], const double offset_x, const double offset_y); -double gdAffineExpansion (const double src[6]); -int gdAffineRectilinear (const double src[6]); -int gdAffineEqual (const double matrix1[6], const double matrix2[6]); -int gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, const double affine[6]); -int gdTransformAffineCopy(gdImagePtr dst, int dst_x, int dst_y, const gdImagePtr src, gdRectPtr src_region, const double affine[6]); +BGD_DECLARE(int) +gdAffineApplyToPointF(gdPointFPtr dst, const gdPointFPtr src, const double affine[6]); +BGD_DECLARE(int) gdAffineInvert(double dst[6], const double src[6]); +BGD_DECLARE(int) +gdAffineFlip(double dst_affine[6], const double src_affine[6], const int flip_h, const int flip_v); +BGD_DECLARE(int) +gdAffineConcat(double dst[6], const double m1[6], const double m2[6]); + +BGD_DECLARE(int) gdAffineIdentity(double dst[6]); +BGD_DECLARE(int) +gdAffineScale(double dst[6], const double scale_x, const double scale_y); +BGD_DECLARE(int) gdAffineRotate(double dst[6], const double angle); +BGD_DECLARE(int) gdAffineShearHorizontal(double dst[6], const double angle); +BGD_DECLARE(int) gdAffineShearVertical(double dst[6], const double angle); +BGD_DECLARE(int) +gdAffineTranslate(double dst[6], const double offset_x, const double offset_y); +BGD_DECLARE(double) gdAffineExpansion(const double src[6]); +BGD_DECLARE(int) gdAffineRectilinear(const double src[6]); +BGD_DECLARE(int) +gdAffineEqual(const double matrix1[6], const double matrix2[6]); +BGD_DECLARE(int) +gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, + const double affine[6]); +BGD_DECLARE(int) +gdTransformAffineCopy(gdImagePtr dst, int dst_x, int dst_y, const gdImagePtr src, + gdRectPtr src_region, const double affine[6]); /* gdTransformAffineCopy(gdImagePtr dst, int x0, int y0, int x1, int y1, - const gdImagePtr src, int src_width, int src_height, - const double affine[6]); + const gdImagePtr src, int src_width, int src_height, + const double affine[6]); */ -int gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox); - +BGD_DECLARE(int) +gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox); -#define GD_CMP_IMAGE 1 /* Actual image IS different */ -#define GD_CMP_NUM_COLORS 2 /* Number of Colours in palette differ */ -#define GD_CMP_COLOR 4 /* Image colours differ */ -#define GD_CMP_SIZE_X 8 /* Image width differs */ -#define GD_CMP_SIZE_Y 16 /* Image heights differ */ -#define GD_CMP_TRANSPARENT 32 /* Transparent colour */ -#define GD_CMP_BACKGROUND 64 /* Background colour */ -#define GD_CMP_INTERLACE 128 /* Interlaced setting */ -#define GD_CMP_TRUECOLOR 256 /* Truecolor vs palette differs */ +/** + * Group: Image Comparison + * + * Constants: + * GD_CMP_IMAGE - Actual image IS different + * GD_CMP_NUM_COLORS - Number of colors in pallette differ + * GD_CMP_COLOR - Image colors differ + * GD_CMP_SIZE_X - Image width differs + * GD_CMP_SIZE_Y - Image heights differ + * GD_CMP_TRANSPARENT - Transparent color differs + * GD_CMP_BACKGROUND - Background color differs + * GD_CMP_INTERLACE - Interlaced setting differs + * GD_CMP_TRUECOLOR - Truecolor vs palette differs + * + * See also: + * - + */ +#define GD_CMP_IMAGE 1 +#define GD_CMP_NUM_COLORS 2 +#define GD_CMP_COLOR 4 +#define GD_CMP_SIZE_X 8 +#define GD_CMP_SIZE_Y 16 +#define GD_CMP_TRANSPARENT 32 +#define GD_CMP_BACKGROUND 64 +#define GD_CMP_INTERLACE 128 +#define GD_CMP_TRUECOLOR 256 /* resolution affects ttf font rendering, particularly hinting */ -#define GD_RESOLUTION 96 /* pixels per inch */ +#define GD_RESOLUTION 96 /* pixels per inch */ + +/* Version information functions */ +BGD_DECLARE(int) gdMajorVersion(void); +BGD_DECLARE(int) gdMinorVersion(void); +BGD_DECLARE(int) gdReleaseVersion(void); +BGD_DECLARE(const char *) gdExtraVersion(void); +BGD_DECLARE(const char *) gdVersionString(void); + +/* newfangled special effects */ +#include "gdfx.h" #ifdef __cplusplus } #endif /* 2.0.12: this now checks the clipping rectangle */ -#define gdImageBoundsSafe(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2)))) +#define gdImageBoundsSafe(im, x, y) \ + (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2)))) #endif /* GD_H */ diff --git a/ext/gd/libgd/gd2copypal.c b/ext/gd/libgd/gd2copypal.c index ae9b559f17b2..16a441ddb8a7 100644 --- a/ext/gd/libgd/gd2copypal.c +++ b/ext/gd/libgd/gd2copypal.c @@ -1,6 +1,6 @@ -#include #include "gd.h" +#include #include /* A short program which converts a .png file into a .gd file, for @@ -8,58 +8,51 @@ basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - gdImagePtr pal; - FILE *in, *out; - if (argc != 3) - { - fprintf (stderr, "Usage: gd2copypal palettefile.gd2 filename.gd2\n"); - exit (1); + gdImagePtr im; + gdImagePtr pal; + FILE *in, *out; + if (argc != 3) { + fprintf(stderr, "Usage: gd2copypal palettefile.gd2 filename.gd2\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Palette file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Palette file does not exist!\n"); + exit(1); } - pal = gdImageCreateFromGd2 (in); - fclose (in); - if (!pal) - { - fprintf (stderr, "Palette is not in GD2 format!\n"); - exit (1); + pal = gdImageCreateFromGd2(in); + fclose(in); + if (!pal) { + fprintf(stderr, "Palette is not in GD2 format!\n"); + exit(1); } - in = fopen (argv[2], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[2], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromGd2 (in); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in GD2 format!\n"); - exit (1); + im = gdImageCreateFromGd2(in); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in GD2 format!\n"); + exit(1); } - gdImagePaletteCopy (im, pal); + gdImagePaletteCopy(im, pal); - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } - gdImageGd2 (im, out, 128, 2); - fclose (out); - gdImageDestroy (pal); - gdImageDestroy (im); + gdImageGd2(im, out, 128, 2); + fclose(out); + gdImageDestroy(pal); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/gd2time.c b/ext/gd/libgd/gd2time.c index 18e6c0c9e4c2..63bbf29b020e 100644 --- a/ext/gd/libgd/gd2time.c +++ b/ext/gd/libgd/gd2time.c @@ -1,60 +1,55 @@ -#include -#include /* for atoi */ -#include /* For time */ #include "gd.h" +#include +#include /* for atoi */ +#include /* For time */ /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in; - int x, y, w, h; - int c; - int i; - int t0; - - if (argc != 7) - { - fprintf (stderr, "Usage: gd2time filename.gd count x y w h\n"); - exit (1); + gdImagePtr im; + FILE *in; + int x, y, w, h; + int c; + int i; + int t0; + + if (argc != 7) { + fprintf(stderr, "Usage: gd2time filename.gd count x y w h\n"); + exit(1); } - c = atoi (argv[2]); - x = atoi (argv[3]); - y = atoi (argv[4]); - w = atoi (argv[5]); - h = atoi (argv[6]); - - printf ("Extracting %d times from (%d, %d), size is %dx%d\n", c, x, y, w, h); - - t0 = time (0); - for (i = 0; i < c; i++) - { - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); - } - - im = gdImageCreateFromGd2Part (in, x, y, w, h); - fclose (in); - - if (!im) - { - fprintf (stderr, "Error reading source file!\n"); - exit (1); - } - gdImageDestroy (im); + c = atoi(argv[2]); + x = atoi(argv[3]); + y = atoi(argv[4]); + w = atoi(argv[5]); + h = atoi(argv[6]); + + printf("Extracting %d times from (%d, %d), size is %dx%d\n", c, x, y, w, h); + + t0 = time(0); + for (i = 0; i < c; i++) { + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); + } + + im = gdImageCreateFromGd2Part(in, x, y, w, h); + fclose(in); + + if (!im) { + fprintf(stderr, "Error reading source file!\n"); + exit(1); + } + gdImageDestroy(im); }; - t0 = time (0) - t0; - printf ("%d seconds to extract (& destroy) %d times\n", t0, c); + t0 = time(0) - t0; + printf("%d seconds to extract (& destroy) %d times\n", t0, c); - return 0; + return 0; } diff --git a/ext/gd/libgd/gd2topng.c b/ext/gd/libgd/gd2topng.c index 6db5eb30037b..05954b658b42 100644 --- a/ext/gd/libgd/gd2topng.c +++ b/ext/gd/libgd/gd2topng.c @@ -1,49 +1,44 @@ -#include #include "gd.h" +#include /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in, *out; - if (argc != 3) - { - fprintf (stderr, "Usage: gd2topng filename.gd2 filename.png\n"); - exit (1); + gdImagePtr im; + FILE *in, *out; + if (argc != 3) { + fprintf(stderr, "Usage: gd2topng filename.gd2 filename.png\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromGd2 (in); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in GD2 format!\n"); - exit (1); + im = gdImageCreateFromGd2(in); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in GD2 format!\n"); + exit(1); } - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } #ifdef HAVE_LIBPNG - gdImagePng (im, out); + gdImagePng(im, out); #else - fprintf(stderr, "No PNG library support available.\n"); + fprintf(stderr, "No PNG library support available.\n"); #endif - fclose (out); - gdImageDestroy (im); + fclose(out); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/gd_array.c b/ext/gd/libgd/gd_array.c new file mode 100644 index 000000000000..3471a5631d71 --- /dev/null +++ b/ext/gd/libgd/gd_array.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd.h" +#include "gd_array.h" +#include "gd_color.h" +#include "gd_errors.h" +#include "gdhelpers.h" + +void gdArrayInit(gdArrayPtr array, unsigned int element_size) +{ + array->size = 0; + array->cnt_elements = 0; + array->element_size = element_size; + array->elements = NULL; +} + +void gdArrayDestroy(gdArrayPtr array) { gdFree(array->elements); } + +void gdArrayTruncate(gdArrayPtr array, unsigned int cnt_elements) +{ + if (cnt_elements < array->cnt_elements) + array->cnt_elements = cnt_elements; +} + +void *gdArrayIndex(gdArrayPtr array, unsigned int index) +{ + if (index == 0 && array->cnt_elements == 0) + return NULL; + + return (unsigned char *)array->elements + index * array->element_size; +} + +const void *gdArrayIndexConst(gdArrayPtr array, unsigned int index) +{ + if (index == 0 && array->cnt_elements == 0) + return NULL; + + if (index >= array->cnt_elements) + return NULL; + + return (const unsigned char *)array->elements + index * array->element_size; +} + +int gdArrayReallocBy(gdArrayPtr array, unsigned int additional) +{ + char *new_elements; + unsigned int old_size = array->size; + unsigned int required_size = array->cnt_elements + additional; + unsigned int new_size; + + /* check for integer overflow */ + if (required_size > INT_MAX || required_size < array->cnt_elements) + return 0; + + if (required_size <= old_size) + return 1; + + if (old_size == 0) + new_size = 1; + else + new_size = old_size * 2; + + while (new_size <= required_size) { + if (new_size > (unsigned int)INT_MAX / 2) { + new_size = required_size; + break; + } + new_size *= 2; + } + + array->size = new_size; + + if (array->size > (unsigned int)INT_MAX || array->element_size > (unsigned int)INT_MAX || + overflow2((int)array->size, (int)array->element_size)) { + array->size = old_size; + return 0; + } + new_elements = gdRealloc(array->elements, (size_t)array->size * array->element_size); + + if (new_elements == NULL) { + array->size = old_size; + return 0; + } + + array->elements = new_elements; + + return 1; +} + +int gdArrayAppend(gdArrayPtr array, const void *element) +{ + return gdArrayAppendMultiple(array, element, 1); +} + +int gdArrayAppendMultiple(gdArrayPtr array, const void *elements, unsigned int cnt_elements) +{ + int status; + void *dest; + + status = gdArrayAlloc(array, cnt_elements, &dest); + if (!status) + return status; + memcpy(dest, elements, (size_t)cnt_elements * array->element_size); + + return 1; +} + +int gdArrayAlloc(gdArrayPtr array, unsigned int cnt_elements, void **elements) +{ + int status; + + status = gdArrayReallocBy(array, cnt_elements); + if (!status) + return status; + + *elements = + (unsigned char *)array->elements + (size_t)array->cnt_elements * array->element_size; + + array->cnt_elements += cnt_elements; + + return 1; +} + +unsigned int gdArrayNumElements(const gdArrayPtr array) { return array->cnt_elements; } + +unsigned int gdArraySize(const gdArrayPtr array) { return array->size; } + +void *gdArrayGetData(const gdArrayPtr array) { return array->elements; } diff --git a/ext/gd/libgd/gd_array.h b/ext/gd/libgd/gd_array.h new file mode 100644 index 000000000000..d9408637cbc4 --- /dev/null +++ b/ext/gd/libgd/gd_array.h @@ -0,0 +1,57 @@ +#ifndef GD_ARRAY_H +#define GD_ARRAY_H 1 + +typedef struct gdArrayStruct { + unsigned int size; + unsigned int cnt_elements; + unsigned int element_size; + void *elements; +} gdArray; +typedef gdArray *gdArrayPtr; + +/* +C++ Vect like for C. +element_size is f.e. sizeof(gdPath) equivalent to +gdPathPtr path; +or +gdPathPtr path[12]; for a fixed length + +Each function takes a pointers to the array. +*/ + +/* Initialize a gdArray, gdArrayarray allocation and freed is the caller's responsability */ +void gdArrayInit(gdArrayPtr array, unsigned int element_size); + +/* Destroy the internal data of a gdArray, gdArrayarray has to be freed by the caller */ +void gdArrayDestroy(gdArrayPtr array); + +/* Growth the internal data storage to be able to store the additional requested amount (of + * elements) */ +int gdArrayReallocBy(gdArrayPtr array, unsigned int additional); + +/* Reduce the elements to cnt_elements (storage will remain the same until more are +requested) */ +void gdArrayTruncate(gdArrayPtr array, unsigned int cnt_elements); + +/* Append an element at the end of the array */ +int gdArrayAppend(gdArrayPtr array, const void *element); + +/* Append cnt_elements elements to the array. + *elements is the actual gdSpanPtr[12] for 12 elements */ +int gdArrayAppendMultiple(gdArrayPtr array, const void *elements, unsigned int cnt_elements); + +/* Returns the elements at the given index */ +void *gdArrayIndex(gdArrayPtr array, unsigned int index); + +/* Same as gdArrayIndex but immutable pointer */ +const void *gdArrayIndexConst(gdArrayPtr array, unsigned int index); + +/* Return the current storage size. Storage size is the available space, not the actual +amount of elements stored. Use gdArrayNumElements to know the actual stored elements count */ +unsigned int gdArraySize(const gdArrayPtr array); +unsigned int gdArrayNumElements(const gdArrayPtr array); + +/* Private for internal usage in gdArray */ +int gdArrayAlloc(gdArrayPtr array, unsigned int cnt_elements, void **elements); +void *gdArrayGetData(const gdArrayPtr array); +#endif /* GD_ARRAY_H */ diff --git a/ext/gd/libgd/gd_avif.c b/ext/gd/libgd/gd_avif.c index 9c1ffdc34bc6..fa876b072b24 100644 --- a/ext/gd/libgd/gd_avif.c +++ b/ext/gd/libgd/gd_avif.c @@ -1,33 +1,43 @@ +/** + * File: AVIF IO + * + * Read and write AVIF images using libavif + * (https://github.com/AOMediaCodec/libavif) . Currently, the only ICC profile + * we support is sRGB. Since that's what web browsers use, it's sufficient for + * now. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include +#include #include #include #include -#include -#include #include "gd.h" #include "gd_errors.h" -#include "gdhelpers.h" #include "gd_intern.h" +#include "gdhelpers.h" #ifdef HAVE_LIBAVIF #include /* - Define defaults for encoding images: - CHROMA_SUBSAMPLING_DEFAULT: 4:2:0 is commonly used for Chroma subsampling. - CHROMA_SUBAMPLING_HIGH_QUALITY: Use 4:4:4, or no subsampling, when a sufficient high quality is requested. - SUBAMPLING_HIGH_QUALITY_THRESHOLD: At or above this value, use CHROMA_SUBAMPLING_HIGH_QUALITY - QUANTIZER_DEFAULT: - We need more testing to really know what quantizer settings are optimal, - but teams at Google have been using maximum=30 as a starting point. - QUALITY_DEFAULT: following gd conventions, -1 indicates the default. - SPEED_DEFAULT: - AVIF_SPEED_DEFAULT is simply the default encoding speed of the AV1 codec. - This could be as slow as 0. So we use 6, which is currently considered to be a fine default. + Define defaults for encoding images: + CHROMA_SUBSAMPLING_DEFAULT: 4:2:0 is commonly used for Chroma + subsampling. CHROMA_SUBAMPLING_HIGH_QUALITY: Use 4:4:4, or no subsampling, + when a sufficient high quality is requested. + SUBAMPLING_HIGH_QUALITY_THRESHOLD: At or above this value, use + CHROMA_SUBAMPLING_HIGH_QUALITY QUANTIZER_DEFAULT: We need more testing to + really know what quantizer settings are optimal, but teams at Google have + been using maximum=30 as a starting point. QUALITY_DEFAULT: following gd + conventions, -1 indicates the default. SPEED_DEFAULT: AVIF_SPEED_DEFAULT is + simply the default encoding speed of the AV1 codec. This could be as slow as + 0. So we use 6, which is currently considered to be a fine default. + */ #define CHROMA_SUBSAMPLING_DEFAULT AVIF_PIXEL_FORMAT_YUV420 @@ -37,15 +47,18 @@ #define QUALITY_DEFAULT -1 #define SPEED_DEFAULT 6 -// This initial size for the gdIOCtx is standard among GD image conversion functions. +// This initial size for the gdIOCtx is standard among GD image conversion +// functions. #define NEW_DYNAMIC_CTX_SIZE 2048 // Our quality param ranges from 0 to 100. -// To calculate quality, we convert from AVIF's quantizer scale, which runs from 63 to 0. +// To calculate quality, we convert from AVIF's quantizer scale, which runs from +// 63 to 0. #define MAX_QUALITY 100 -// These constants are for computing the number of tiles and threads to use during encoding. -// Maximum threads are from libavif/contrib/gkd-pixbuf/loader.c. +// These constants are for computing the number of tiles and threads to use +// during encoding. Maximum threads are from +// libavif/contrib/gkd-pixbuf/loader.c. #define MIN_TILE_AREA (512 * 512) #define MAX_TILES 8 #define MAX_THREADS 64 @@ -53,604 +66,723 @@ /*** Macros ***/ /* - From gd_png.c: - convert the 7-bit alpha channel to an 8-bit alpha channel. - We do a little bit-flipping magic, repeating the MSB - as the LSB, to ensure that 0 maps to 0 and - 127 maps to 255. We also have to invert to match - PNG's convention in which 255 is opaque. + From gd_png.c: + convert the 7-bit alpha channel to an 8-bit alpha channel. + We do a little bit-flipping magic, repeating the MSB + as the LSB, to ensure that 0 maps to 0 and + 127 maps to 255. We also have to invert to match + PNG's convention in which 255 is opaque. */ -#define alpha7BitTo8Bit(alpha7Bit) \ - (alpha7Bit == 127 ? \ - 0 : \ - 255 - ((alpha7Bit << 1) + (alpha7Bit >> 6))) +#define alpha7BitTo8Bit(alpha7Bit) \ + (alpha7Bit == 127 ? 0 : 255 - ((alpha7Bit << 1) + (alpha7Bit >> 6))) #define alpha8BitTo7Bit(alpha8Bit) (gdAlphaMax - (alpha8Bit >> 1)) - /*** Helper functions ***/ /* Convert the quality param we expose to the quantity params used by libavif. - The *Quantizer* params values can range from 0 to 63, with 0 = highest quality and 63 = worst. - We make the scale 0-100, and we reverse this, so that 0 = worst quality and 100 = highest. + The *Quantizer* params values can range from 0 to 63, with 0 = highest + quality and 63 = worst. We make the scale 0-100, and we reverse this, so that + 0 = worst quality and 100 = highest. - Values below 0 are set to 0, and values below MAX_QUALITY are set to MAX_QUALITY. + Values below 0 are set to 0, and values below MAX_QUALITY are set to + MAX_QUALITY. */ -static int quality2Quantizer(int quality) { - int clampedQuality = CLAMP(quality, 0, MAX_QUALITY); +static int quality2Quantizer(int quality) +{ + int clampedQuality = CLAMP(quality, 0, MAX_QUALITY); - float scaleFactor = (float) AVIF_QUANTIZER_WORST_QUALITY / (float) MAX_QUALITY; + float scaleFactor = (float)AVIF_QUANTIZER_WORST_QUALITY / (float)MAX_QUALITY; - return round(scaleFactor * (MAX_QUALITY - clampedQuality)); + return round(scaleFactor * (MAX_QUALITY - clampedQuality)); } /* - As of February 2021, this algorithm reflects the latest research on how many tiles - and threads to include for a given image size. - This is subject to change as research continues. + As of February 2021, this algorithm reflects the latest research on how + many tiles and threads to include for a given image size. This is subject to + change as research continues. - Returns false if there was an error, true if all was well. + Returns false if there was an error, true if all was well. */ -static avifBool setEncoderTilesAndThreads(avifEncoder *encoder, avifRGBImage *rgb) { - int imageArea, tiles, tilesLog2, encoderTiles; +static avifBool setEncoderTilesAndThreads(avifEncoder *encoder, avifRGBImage *rgb) +{ + int imageArea, tiles, tilesLog2, encoderTiles; - // _gdImageAvifCtx(), the calling function, checks this operation for overflow - imageArea = rgb->width * rgb->height; + // _gdImageAvifCtx(), the calling function, checks this operation for + // overflow + imageArea = rgb->width * rgb->height; - tiles = (int) ceil((double) imageArea / MIN_TILE_AREA); - tiles = MIN(tiles, MAX_TILES); - tiles = MIN(tiles, MAX_THREADS); + tiles = (int)ceil((double)imageArea / MIN_TILE_AREA); + tiles = MIN(tiles, MAX_TILES); + tiles = MIN(tiles, MAX_THREADS); - // The number of tiles in any dimension will always be a power of 2. We can only specify log(2)tiles. + // The number of tiles in any dimension will always be a power of 2. We can + // only specify log(2)tiles. - tilesLog2 = floor(log2(tiles)); + tilesLog2 = floor(log2(tiles)); - // If the image's width is greater than the height, use more tile columns - // than tile rows to make the tile size close to a square. + // If the image's width is greater than the height, use more tile columns + // than tile rows to make the tile size close to a square. - if (rgb->width >= rgb->height) { - encoder->tileRowsLog2 = tilesLog2 / 2; - encoder->tileColsLog2 = tilesLog2 - encoder->tileRowsLog2; - } else { - encoder->tileColsLog2 = tilesLog2 / 2; - encoder->tileRowsLog2 = tilesLog2 - encoder->tileColsLog2; - } + if (rgb->width >= rgb->height) { + encoder->tileRowsLog2 = tilesLog2 / 2; + encoder->tileColsLog2 = tilesLog2 - encoder->tileRowsLog2; + } else { + encoder->tileColsLog2 = tilesLog2 / 2; + encoder->tileRowsLog2 = tilesLog2 - encoder->tileColsLog2; + } - // It's good to have one thread per tile. - encoderTiles = (1 << encoder->tileRowsLog2) * (1 << encoder->tileColsLog2); - encoder->maxThreads = encoderTiles; + // It's good to have one thread per tile. + encoderTiles = (1 << encoder->tileRowsLog2) * (1 << encoder->tileColsLog2); + encoder->maxThreads = encoderTiles; - return AVIF_TRUE; + return AVIF_TRUE; } /* - We can handle AVIF images whose color profile is sRGB, or whose color profile isn't set. + We can handle AVIF images whose color profile is sRGB, or whose color + profile isn't set. */ -static avifBool isAvifSrgbImage(avifImage *avifIm) { - return - (avifIm->colorPrimaries == AVIF_COLOR_PRIMARIES_BT709 || - avifIm->colorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED) && - (avifIm->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_SRGB || - avifIm->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED) - ; +static avifBool isAvifSrgbImage(avifImage *avifIm) +{ + return (avifIm->colorPrimaries == AVIF_COLOR_PRIMARIES_BT709 || + avifIm->colorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED) && + (avifIm->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_SRGB || + avifIm->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED); } /* - Check the result from an Avif function to see if it's an error. - If so, decode the error and output it, and return true. - Otherwise, return false. + Check the result from an Avif function to see if it's an error. + If so, decode the error and output it, and return true. + Otherwise, return false. */ -static avifBool isAvifError(avifResult result, const char *msg) { - if (result != AVIF_RESULT_OK) { - gd_error("avif error - %s: %s\n", msg, avifResultToString(result)); - return AVIF_TRUE; - } +static avifBool isAvifError(avifResult result, const char *msg) +{ + if (result != AVIF_RESULT_OK) { + gd_error("avif error - %s: %s\n", msg, avifResultToString(result)); + return AVIF_TRUE; + } - return AVIF_FALSE; + return AVIF_FALSE; } - typedef struct avifIOCtxReader { - avifIO io; // this must be the first member for easy casting to avifIO* - avifROData rodata; + avifIO io; // this must be the first member for easy casting to avifIO* + avifROData rodata; } avifIOCtxReader; /* - implements the avifIOReadFunc interface by calling the relevant functions - in the gdIOCtx. Our logic is inspired by avifIOMemoryReaderRead() and avifIOFileReaderRead(). - We don't know whether we're reading from a file or from memory. We don't have to know, - since we rely on the helper functions in the gdIOCtx. - We assume we've stashed the gdIOCtx in io->data, as we do in createAvifIOFromCtx(). - - We ignore readFlags, just as the avifIO*ReaderRead() functions do. - - If there's a problem, this returns an avifResult error. - If things go well, return AVIF_RESULT_OK. - Of course these AVIF codes shouldn't be returned by any top-level GD function. + implements the avifIOReadFunc interface by calling the + relevant functions in the gdIOCtx. Our logic is inspired by + avifIOMemoryReaderRead() and avifIOFileReaderRead(). We don't know whether + we're reading from a file or from memory. We don't have to know, since we + rely on the helper functions in the gdIOCtx. We assume we've stashed the + gdIOCtx in io->data, as we do in createAvifIOFromCtx(). + + We ignore readFlags, just as the avifIO*ReaderRead() functions do. + + If there's a problem, this returns an avifResult error. + If things go well, return AVIF_RESULT_OK. + Of course these AVIF codes shouldn't be returned by any top-level GD + function. */ -static avifResult readFromCtx(avifIO *io, uint32_t readFlags, uint64_t offset, size_t size, avifROData *out) +static avifResult readFromCtx(avifIO *io, uint32_t readFlags, uint64_t offset, size_t size, + avifROData *out) { - gdIOCtx *ctx = (gdIOCtx *) io->data; - avifIOCtxReader *reader = (avifIOCtxReader *) io; - - // readFlags is unsupported - if (readFlags != 0) { - return AVIF_RESULT_IO_ERROR; - } - - // TODO: if we set sizeHint, this will be more efficient. - - if (offset > INT_MAX || size > INT_MAX) - return AVIF_RESULT_IO_ERROR; - - // Try to seek offset bytes forward. If we pass the end of the buffer, throw an error. - if (!ctx->seek(ctx, (int) offset)) - return AVIF_RESULT_IO_ERROR; - - if (size > reader->rodata.size) { - reader->rodata.data = gdRealloc((void *) reader->rodata.data, size); - reader->rodata.size = size; - } - if (!reader->rodata.data) { - gd_error("avif error - couldn't allocate memory"); - return AVIF_RESULT_UNKNOWN_ERROR; - } - - // Read the number of bytes requested. - // If getBuf() returns a negative value, that means there was an error. - int charsRead = ctx->getBuf(ctx, (void *) reader->rodata.data, (int) size); - if (charsRead < 0) { - return AVIF_RESULT_IO_ERROR; - } - - out->data = reader->rodata.data; - out->size = charsRead; - return AVIF_RESULT_OK; + gdIOCtx *ctx = (gdIOCtx *)io->data; + avifIOCtxReader *reader = (avifIOCtxReader *)io; + + // readFlags is unsupported + if (readFlags != 0) { + return AVIF_RESULT_IO_ERROR; + } + + // TODO: if we set sizeHint, this will be more efficient. + + if (offset > INT_MAX || size > INT_MAX) + return AVIF_RESULT_IO_ERROR; + + // Try to seek offset bytes forward. If we pass the end of the buffer, throw + // an error. + if (!ctx->seek(ctx, (int)offset)) + return AVIF_RESULT_IO_ERROR; + + if (size > reader->rodata.size) { + reader->rodata.data = gdRealloc((void *)reader->rodata.data, size); + reader->rodata.size = size; + } + if (!reader->rodata.data) { + gd_error("avif error - couldn't allocate memory"); + return AVIF_RESULT_UNKNOWN_ERROR; + } + + // Read the number of bytes requested. + // If getBuf() returns a negative value, that means there was an error. + int charsRead = ctx->getBuf(ctx, (void *)reader->rodata.data, (int)size); + if (charsRead < 0) { + return AVIF_RESULT_IO_ERROR; + } + + out->data = reader->rodata.data; + out->size = charsRead; + return AVIF_RESULT_OK; } // avif.h says this is optional, but it seemed easy to implement. -static void destroyAvifIO(struct avifIO *io) { - avifIOCtxReader *reader = (avifIOCtxReader *) io; - if (reader->rodata.data != NULL) { - gdFree((void *) reader->rodata.data); - } - gdFree(reader); +static void destroyAvifIO(struct avifIO *io) +{ + avifIOCtxReader *reader = (avifIOCtxReader *)io; + if (reader->rodata.data != NULL) { + gdFree((void *)reader->rodata.data); + } + gdFree(reader); } /* Set up an avifIO object. - The functions in the gdIOCtx struct may point either to a file or a memory buffer. - To us, that's immaterial. - Our task is simply to assign avifIO functions to the proper functions from gdIOCtx. - The destroy function needs to destroy the avifIO object and anything else it uses. + The functions in the gdIOCtx struct may point either to a file or a memory + buffer. To us, that's immaterial. Our task is simply to assign avifIO + functions to the proper functions from gdIOCtx. The destroy function needs to + destroy the avifIO object and anything else it uses. - Returns NULL if memory for the object can't be allocated. + Returns NULL if memory for the object can't be allocated. */ // TODO: can we get sizeHint somehow? -static avifIO *createAvifIOFromCtx(gdIOCtx *ctx) { - struct avifIOCtxReader *reader; - - reader = gdMalloc(sizeof(*reader)); - if (reader == NULL) - return NULL; - - // TODO: setting persistent=FALSE is safe, but it's less efficient. Is it necessary? - reader->io.persistent = AVIF_FALSE; - reader->io.read = readFromCtx; - reader->io.write = NULL; // this function is currently unused; see avif.h - reader->io.destroy = destroyAvifIO; - reader->io.sizeHint = 0; // sadly, we don't get this information from the gdIOCtx. - reader->io.data = ctx; - reader->rodata.data = NULL; - reader->rodata.size = 0; - - return (avifIO *) reader; +static avifIO *createAvifIOFromCtx(gdIOCtx *ctx) +{ + struct avifIOCtxReader *reader; + + reader = gdMalloc(sizeof(*reader)); + if (reader == NULL) + return NULL; + + // TODO: setting persistent=FALSE is safe, but it's less efficient. Is it + // necessary? + reader->io.persistent = AVIF_FALSE; + reader->io.read = readFromCtx; + reader->io.write = NULL; // this function is currently unused; see avif.h + reader->io.destroy = destroyAvifIO; + reader->io.sizeHint = 0; // sadly, we don't get this information from the gdIOCtx. + reader->io.data = ctx; + reader->rodata.data = NULL; + reader->rodata.size = 0; + + return (avifIO *)reader; } - /*** Decoding functions ***/ /* - Function: gdImageCreateFromAvif + Function: gdImageCreateFromAvif - is called to load truecolor images from - AVIF format files. Invoke with an - already opened pointer to a file containing the desired - image. returns a to the new - truecolor image, or NULL if unable to load the image (most often - because the file is corrupt or does not contain a AVIF - image). does not close the file. + is called to load truecolor images from + AVIF format files. Invoke with an + already opened pointer to a file containing the desired + image. returns a to the new + truecolor image, or NULL if unable to load the image (most often + because the file is corrupt or does not contain a AVIF + image). does not close the file. - This function creates a gdIOCtx struct from the file pointer it's passed. - And then it relies on to do the real decoding work. - If the file contains an image sequence, we simply read the first one, discarding the rest. + This function creates a gdIOCtx struct from the file pointer it's + passed. And then it relies on to do the real + decoding work. If the file contains an image sequence, we simply read the + first one, discarding the rest. - Variants: + Variants: - creates an image from AVIF data - already in memory. + creates an image from AVIF data + already in memory. - reads data from the function - pointers in a structure. + reads data from the function + pointers in a structure. - Parameters: + Parameters: - infile - pointer to the input file + infile - pointer to the input file - Returns: + Returns: - A pointer to the new truecolor image. This will need to be - destroyed with once it is no longer needed. + A pointer to the new truecolor image. This will need to be + destroyed with once it is no longer needed. - On error, returns 0. + On error, returns 0. */ -gdImagePtr gdImageCreateFromAvif(FILE *infile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvif(FILE *infile) { - gdImagePtr im; - gdIOCtx *ctx = gdNewFileCtx(infile); + gdImagePtr im; + gdIOCtx *ctx = gdNewFileCtx(infile); - if (!ctx) - return NULL; + if (!ctx) + return NULL; - im = gdImageCreateFromAvifCtx(ctx); - ctx->gd_free(ctx); + im = gdImageCreateFromAvifCtx(ctx); + ctx->gd_free(ctx); - return im; + return im; } /* - Function: gdImageCreateFromAvifPtr + Function: gdImageCreateFromAvifPtr - See . + See . - Parameters: + Parameters: - size - size of Avif data in bytes. - data - pointer to Avif data. + size - size of Avif data in bytes. + data - pointer to Avif data. */ -gdImagePtr gdImageCreateFromAvifPtr(int size, void *data) +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifPtr(int size, void *data) { - gdImagePtr im; - gdIOCtx *ctx = gdNewDynamicCtxEx(size, data, 0); + gdImagePtr im; + gdIOCtx *ctx = gdNewDynamicCtxEx(size, data, 0); - if (!ctx) - return 0; + if (!ctx) + return 0; - im = gdImageCreateFromAvifCtx(ctx); - ctx->gd_free(ctx); + im = gdImageCreateFromAvifCtx(ctx); + ctx->gd_free(ctx); - return im; + return im; } /* - Function: gdImageCreateFromAvifCtx + Function: gdImageCreateFromAvifCtx - See . + See . - Additional details: the AVIF library comes with functions to create an IO object from - a file and from a memory pointer. Of course, it doesn't have a way to create an IO object - from a gdIOCtx. So, here, we use our own helper function, . + Additional details: the AVIF library comes with functions to create an + IO object from a file and from a memory pointer. Of course, it doesn't have a + way to create an IO object from a gdIOCtx. So, here, we use our own helper + function, . - Otherwise, we create the image by calling AVIF library functions in order: - * avifDecoderCreate(), to create the decoder - * avifDecoderSetIO(), to tell libavif how to read from our data structure - * avifDecoderParse(), to parse the image - * avifDecoderNextImage(), to read the first image from the decoder - * avifRGBImageSetDefaults(), to create the avifRGBImage - * avifRGBImageAllocatePixels(), to allocate memory for the pixels - * avifImageYUVToRGB(), to convert YUV to RGB + Otherwise, we create the image by calling AVIF library functions in + order: + * avifDecoderCreate(), to create the decoder + * avifDecoderSetIO(), to tell libavif how to read from our data + structure + * avifDecoderParse(), to parse the image + * avifDecoderNextImage(), to read the first image from the decoder + * avifRGBImageSetDefaults(), to create the avifRGBImage + * avifRGBImageAllocatePixels(), to allocate memory for the pixels + * avifImageYUVToRGB(), to convert YUV to RGB - Finally, we create a new gd image and copy over the pixel data. + Finally, we create a new gd image and copy over the pixel data. - Parameters: + Parameters: - ctx - a gdIOCtx struct + ctx - a gdIOCtx struct */ -gdImagePtr gdImageCreateFromAvifCtx (gdIOCtx *ctx) +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifCtx(gdIOCtx *ctx) { - uint32_t x, y; - gdImage *im = NULL; - avifResult result; - avifIO *io; - avifDecoder *decoder; - avifRGBImage rgb; + uint32_t x, y; + gdImage *im = NULL; + avifResult result; + avifIO *io; + avifDecoder *decoder; + avifRGBImage rgb; - // this lets us know that memory hasn't been allocated yet for the pixels - rgb.pixels = NULL; + // this lets us know that memory hasn't been allocated yet for the pixels + rgb.pixels = NULL; - decoder = avifDecoderCreate(); + decoder = avifDecoderCreate(); - // Check if libavif version is >= 0.9.1 - // If so, allow the PixelInformationProperty ('pixi') to be missing in AV1 image - // items. libheif v1.11.0 or older does not add the 'pixi' item property to - // AV1 image items. (This issue has been corrected in libheif v1.12.0.) + // Check if libavif version is >= 0.9.1. + // If so, allow the PixelInformationProperty ('pixi') to be missing in AV1 + // image items. libheif v1.11.0 or older does not add the 'pixi' item + // property to AV1 image items. (This issue has been corrected in libheif + // v1.12.0.) #if AVIF_VERSION >= 90100 - decoder->strictFlags &= ~AVIF_STRICT_PIXI_REQUIRED; + decoder->strictFlags &= ~AVIF_STRICT_PIXI_REQUIRED; #endif - io = createAvifIOFromCtx(ctx); - if (!io) { - gd_error("avif error - Could not allocate memory"); - goto cleanup; - } + io = createAvifIOFromCtx(ctx); + if (!io) { + gd_error("avif error - Could not allocate memory"); + goto cleanup; + } - avifDecoderSetIO(decoder, io); + avifDecoderSetIO(decoder, io); - result = avifDecoderParse(decoder); - if (isAvifError(result, "Could not parse image")) - goto cleanup; + result = avifDecoderParse(decoder); + if (isAvifError(result, "Could not parse image")) + goto cleanup; - // Note again that, for an image sequence, we read only the first image, ignoring the rest. - result = avifDecoderNextImage(decoder); - if (isAvifError(result, "Could not decode image")) - goto cleanup; + // Note again that, for an image sequence, we read only the first image, + // ignoring the rest. + result = avifDecoderNextImage(decoder); + if (isAvifError(result, "Could not decode image")) + goto cleanup; - if (!isAvifSrgbImage(decoder->image)) - gd_error_ex(GD_NOTICE, "Image's color profile is not sRGB"); + if (!isAvifSrgbImage(decoder->image)) + gd_error_ex(LOG_NOTICE, "Image's color profile is not sRGB"); - // Set up the avifRGBImage, and convert it from YUV to an 8-bit RGB image. - // (While AVIF image pixel depth can be 8, 10, or 12 bits, GD truecolor images are 8-bit.) - avifRGBImageSetDefaults(&rgb, decoder->image); - rgb.depth = 8; + // Set up the avifRGBImage, and convert it from YUV to an 8-bit RGB image. + // (While AVIF image pixel depth can be 8, 10, or 12 bits, GD truecolor + // images are 8-bit.) + avifRGBImageSetDefaults(&rgb, decoder->image); + rgb.depth = 8; #if AVIF_VERSION >= 1000000 - result = avifRGBImageAllocatePixels(&rgb); - if (isAvifError(result, "Allocating RGB pixels failed")) - goto cleanup; + result = avifRGBImageAllocatePixels(&rgb); + if (isAvifError(result, "Allocating RGB pixels failed")) + goto cleanup; #else - avifRGBImageAllocatePixels(&rgb); + avifRGBImageAllocatePixels(&rgb); #endif - result = avifImageYUVToRGB(decoder->image, &rgb); - if (isAvifError(result, "Conversion from YUV to RGB failed")) - goto cleanup; + result = avifImageYUVToRGB(decoder->image, &rgb); + if (isAvifError(result, "Conversion from YUV to RGB failed")) + goto cleanup; - im = gdImageCreateTrueColor(decoder->image->width, decoder->image->height); - if (!im) { - gd_error("avif error - Could not create GD truecolor image"); - goto cleanup; - } + im = gdImageCreateTrueColor(decoder->image->width, decoder->image->height); + if (!im) { + gd_error("avif error - Could not create GD truecolor image"); + goto cleanup; + } - im->saveAlphaFlag = 1; + im->saveAlphaFlag = 1; - // Read the pixels from the AVIF image and copy them into the GD image. + // Read the pixels from the AVIF image and copy them into the GD image. - uint8_t *p = rgb.pixels; + uint8_t *p = rgb.pixels; - for (y = 0; y < decoder->image->height; y++) { - for (x = 0; x < decoder->image->width; x++) { - uint8_t r = *(p++); - uint8_t g = *(p++); - uint8_t b = *(p++); - uint8_t a = alpha8BitTo7Bit(*(p++)); - im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a); - } - } + for (y = 0; y < decoder->image->height; y++) { + for (x = 0; x < decoder->image->width; x++) { + uint8_t r = *(p++); + uint8_t g = *(p++); + uint8_t b = *(p++); + uint8_t a = alpha8BitTo7Bit(*(p++)); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a); + } + } cleanup: - // if io has been allocated, this frees it - avifDecoderDestroy(decoder); + // if io has been allocated, this frees it + avifDecoderDestroy(decoder); - if (rgb.pixels) - avifRGBImageFreePixels(&rgb); + if (rgb.pixels) + avifRGBImageFreePixels(&rgb); - return im; + return im; } - /*** Encoding functions ***/ /* - Function: gdImageAvifEx + Function: gdImageAvifEx - outputs the specified image to the specified file in - AVIF format. The file must be open for writing. Under MSDOS and - all versions of Windows, it is important to use "wb" as opposed to - simply "w" as the mode when opening the file, and under Unix there - is no penalty for doing so. does not close the file; - your code must do so. + outputs the specified image to the specified file in + AVIF format. The file must be open for writing. Under MSDOS and + all versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. - Variants: + Variants: - writes the image to a file, encoding with the default quality and speed. + writes the image to a file, encoding with the default + quality and speed. - stores the image in RAM. + stores the image in RAM. - stores the image in RAM, encoding with the default quality and speed. + stores the image in RAM, encoding with the default + quality and speed. - stores the image using a struct. + stores the image using a struct. - Parameters: + Parameters: - im - The image to save. - outFile - The FILE pointer to write to. - quality - Compression quality (0-100). 0 is lowest-quality, 100 is highest. - speed - The speed of compression (0-10). 0 is slowest, 10 is fastest. + im - The image to save. + outFile - The FILE pointer to write to. + quality - Compression quality (0-100). 0 is lowest-quality, 100 is + highest. speed - The speed of compression (0-10). 0 is slowest, 10 is + fastest. - Notes on parameters: - quality - If quality = -1, we use a default quality as defined in QUALITY_DEFAULT. - For information on how we convert this quality to libavif's quantity param, see . + Notes on parameters: + quality - If quality = -1, we use a default quality as defined in + QUALITY_DEFAULT. For information on how we convert this quality to libavif's + quantity param, see . - speed - At slower speeds, encoding may be quite slow. Use judiciously. + speed - At slower speeds, encoding may be quite slow. Use judiciously. - Qualities or speeds that are lower than the minimum value get clamped to the minimum value, - and qualities or speeds that are lower than the maximum value get clamped to the maxmum value. - Note that AVIF_SPEED_DEFAULT is -1. If we ever set SPEED_DEFAULT = AVIF_SPEED_DEFAULT, - we'd want to add a conditional to ensure that value doesn't get clamped. + Qualities or speeds that are lower than the minimum value get clamped to + the minimum value, and qualities or speeds that are lower than the maximum + value get clamped to the maximum value. Note that AVIF_SPEED_DEFAULT is -1. + If we ever set SPEED_DEFAULT = AVIF_SPEED_DEFAULT, we'd want to add a + conditional to ensure that value doesn't get clamped. - Returns: + Returns: - * for , , and , nothing. - * for and , a pointer to the image in memory. + * for , , and , nothing. + * for and , a pointer to the image in + memory. */ /* - If we're passed the QUALITY_DEFAULT of -1, set the quantizer params to QUANTIZER_DEFAULT. -*/ -void gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed) -{ - avifResult result; - avifRGBImage rgb; - avifRWData avifOutput = AVIF_DATA_EMPTY; - avifBool lossless = quality == 100; - avifEncoder *encoder = NULL; + Private subobject + Function: _gdImageAvifCtx - uint32_t val; - uint8_t *p; - uint32_t x, y; + We need this underscored function because gdImageAvifCtx() can't return + anything. And our functions that operate on a memory buffer need to know + whether the encoding has succeeded. - if (im == NULL) - return; + If we're passed the QUALITY_DEFAULT of -1, set the quantizer params to + QUANTIZER_DEFAULT. - if (!gdImageTrueColor(im)) { - gd_error("avif error - avif doesn't support palette images"); - return; - } - - if (!gdImageSX(im) || !gdImageSY(im)) { - gd_error("avif error - image dimensions must not be zero"); - return; - } - - if (overflow2(gdImageSX(im), gdImageSY(im))) { - gd_error("avif error - image dimensions are too large"); - return; - } - - speed = CLAMP(speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST); - - avifPixelFormat subsampling = quality >= HIGH_QUALITY_SUBSAMPLING_THRESHOLD ? - CHROMA_SUBAMPLING_HIGH_QUALITY : CHROMA_SUBSAMPLING_DEFAULT; - - // Create the AVIF image. - // Set the ICC to sRGB, as that's what gd supports right now. - // Note that MATRIX_COEFFICIENTS_IDENTITY enables lossless conversion from RGB to YUV. - - avifImage *avifIm = avifImageCreate(gdImageSX(im), gdImageSY(im), 8, subsampling); -#if AVIF_VERSION >= 1000000 - if (avifIm == NULL) { - gd_error("avif error - Creating image failed\n"); - goto cleanup; - } -#endif - avifIm->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709; - avifIm->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB; - avifIm->matrixCoefficients = lossless ? AVIF_MATRIX_COEFFICIENTS_IDENTITY : AVIF_MATRIX_COEFFICIENTS_BT709; + This function returns 0 on success, or 1 on failure. +*/ +static avifBool _gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed) +{ + avifResult result; + avifRGBImage rgb = {0}; + avifRWData avifOutput = AVIF_DATA_EMPTY; + avifBool failed = AVIF_FALSE; + avifBool lossless = quality == 100; + avifEncoder *encoder = NULL; + avifImage *avifIm = NULL; + + uint32_t val; + uint8_t *p; + uint32_t x, y; + + if (im == NULL) + return 1; + + if (!gdImageTrueColor(im)) { + gd_error("avif doesn't support palette images"); + return 1; + } + + if (!gdImageSX(im) || !gdImageSY(im)) { + gd_error("image dimensions must not be zero"); + return 1; + } + + if (overflow2(gdImageSX(im), gdImageSY(im))) { + gd_error("image dimensions are too large"); + return 1; + } + + speed = CLAMP(speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST); + + avifPixelFormat subsampling = quality >= HIGH_QUALITY_SUBSAMPLING_THRESHOLD + ? CHROMA_SUBAMPLING_HIGH_QUALITY + : CHROMA_SUBSAMPLING_DEFAULT; + + // Create the AVIF image. + // Set the ICC to sRGB, as that's what gd supports right now. + // Note that MATRIX_COEFFICIENTS_IDENTITY enables lossless conversion from + // RGB to YUV. + + avifIm = avifImageCreate(gdImageSX(im), gdImageSY(im), 8, subsampling); + if (avifIm == NULL) { + gd_error("avif error - Creating image failed\n"); + goto cleanup; + } + + avifIm->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709; + avifIm->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB; + avifIm->matrixCoefficients = + lossless ? AVIF_MATRIX_COEFFICIENTS_IDENTITY : AVIF_MATRIX_COEFFICIENTS_BT709; + + avifRGBImageSetDefaults(&rgb, avifIm); + // this allocates memory, and sets rgb.rowBytes and rgb.pixels. + result = avifRGBImageAllocatePixels(&rgb); + if (isAvifError(result, "Allocating RGB pixels failed")) + goto cleanup; + + // Parse RGB data from the GD image, and copy it into the AVIF RGB image. + // Convert 7-bit GD alpha channel values to 8-bit AVIF values. + + p = rgb.pixels; + for (y = 0; y < rgb.height; y++) { + for (x = 0; x < rgb.width; x++) { + val = im->tpixels[y][x]; + + *(p++) = gdTrueColorGetRed(val); + *(p++) = gdTrueColorGetGreen(val); + *(p++) = gdTrueColorGetBlue(val); + *(p++) = alpha7BitTo8Bit(gdTrueColorGetAlpha(val)); + } + } + + // Convert the RGB image to YUV. + + result = avifImageRGBToYUV(avifIm, &rgb); + failed = isAvifError(result, "Could not convert image to YUV"); + if (failed) + goto cleanup; + + // Encode the image in AVIF format. + + encoder = avifEncoderCreate(); + if (encoder == NULL) { + gd_error("avif error - Creating encoder failed\n"); + goto cleanup; + } + + int quantizerQuality = + quality == QUALITY_DEFAULT ? QUANTIZER_DEFAULT : quality2Quantizer(quality); + + encoder->minQuantizer = quantizerQuality; + encoder->maxQuantizer = quantizerQuality; + encoder->minQuantizerAlpha = quantizerQuality; + encoder->maxQuantizerAlpha = quantizerQuality; + encoder->speed = speed; + + failed = !setEncoderTilesAndThreads(encoder, &rgb); + if (failed) + goto cleanup; + + // TODO: is there a reason to use timeSscales != 1? + result = avifEncoderAddImage(encoder, avifIm, 1, AVIF_ADD_IMAGE_FLAG_SINGLE); + failed = isAvifError(result, "Could not encode image"); + if (failed) + goto cleanup; + + result = avifEncoderFinish(encoder, &avifOutput); + failed = isAvifError(result, "Could not finish encoding"); + if (failed) + goto cleanup; + + // Write the AVIF image bytes to the GD ctx. + + gdPutBuf(avifOutput.data, avifOutput.size, outfile); - avifRGBImageSetDefaults(&rgb, avifIm); - // this allocates memory, and sets rgb.rowBytes and rgb.pixels. -#if AVIF_VERSION >= 1000000 - result = avifRGBImageAllocatePixels(&rgb); - if (isAvifError(result, "Allocating RGB pixels failed")) - goto cleanup; -#else - avifRGBImageAllocatePixels(&rgb); -#endif +cleanup: + if (rgb.pixels) + avifRGBImageFreePixels(&rgb); - // Parse RGB data from the GD image, and copy it into the AVIF RGB image. - // Convert 7-bit GD alpha channel values to 8-bit AVIF values. + if (encoder) + avifEncoderDestroy(encoder); - p = rgb.pixels; - for (y = 0; y < rgb.height; y++) { - for (x = 0; x < rgb.width; x++) { - val = im->tpixels[y][x]; + if (avifOutput.data) + avifRWDataFree(&avifOutput); - *(p++) = gdTrueColorGetRed(val); - *(p++) = gdTrueColorGetGreen(val); - *(p++) = gdTrueColorGetBlue(val); - *(p++) = alpha7BitTo8Bit(gdTrueColorGetAlpha(val)); - } - } + if (avifIm) + avifImageDestroy(avifIm); - // Convert the RGB image to YUV. + return failed; +} - result = avifImageRGBToYUV(avifIm, &rgb); - if (isAvifError(result, "Could not convert image to YUV")) - goto cleanup; +BGD_DECLARE(void) +gdImageAvifEx(gdImagePtr im, FILE *outFile, int quality, int speed) +{ + gdIOCtx *out = gdNewFileCtx(outFile); - // Encode the image in AVIF format. + if (out == NULL) + return; - encoder = avifEncoderCreate(); -#if AVIF_VERSION >= 1000000 - if (encoder == NULL) { - gd_error("avif error - Creating encoder failed\n"); - goto cleanup; - } -#endif - int quantizerQuality = quality == QUALITY_DEFAULT ? - QUANTIZER_DEFAULT : quality2Quantizer(quality); + gdImageAvifCtx(im, out, quality, speed); + out->gd_free(out); +} - encoder->minQuantizer = quantizerQuality; - encoder->maxQuantizer = quantizerQuality; - encoder->minQuantizerAlpha = quantizerQuality; - encoder->maxQuantizerAlpha = quantizerQuality; - encoder->speed = speed; +BGD_DECLARE(void) gdImageAvif(gdImagePtr im, FILE *outFile) +{ + gdImageAvifEx(im, outFile, QUALITY_DEFAULT, SPEED_DEFAULT); +} - if (!setEncoderTilesAndThreads(encoder, &rgb)) - goto cleanup; +BGD_DECLARE(void *) +gdImageAvifPtrEx(gdImagePtr im, int *size, int quality, int speed) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(NEW_DYNAMIC_CTX_SIZE, NULL); - //TODO: is there a reason to use timeSscales != 1? - result = avifEncoderAddImage(encoder, avifIm, 1, AVIF_ADD_IMAGE_FLAG_SINGLE); - if (isAvifError(result, "Could not encode image")) - goto cleanup; + if (out == NULL) { + return NULL; + } - result = avifEncoderFinish(encoder, &avifOutput); - if (isAvifError(result, "Could not finish encoding")) - goto cleanup; + if (_gdImageAvifCtx(im, out, quality, speed)) + rv = NULL; + else + rv = gdDPExtractData(out, size); - // Write the AVIF image bytes to the GD ctx. + out->gd_free(out); + return rv; +} - gdPutBuf(avifOutput.data, avifOutput.size, outfile); +BGD_DECLARE(void *) gdImageAvifPtr(gdImagePtr im, int *size) +{ + return gdImageAvifPtrEx(im, size, QUALITY_DEFAULT, AVIF_SPEED_DEFAULT); +} -cleanup: - if (rgb.pixels) - avifRGBImageFreePixels(&rgb); +BGD_DECLARE(void) +gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed) +{ + _gdImageAvifCtx(im, outfile, quality, speed); +} - if (encoder) - avifEncoderDestroy(encoder); +#else /* !HAVE_LIBAVIF */ - if (avifOutput.data) - avifRWDataFree(&avifOutput); +static void *_noAvifError(void) +{ + gd_error("AVIF image support has been disabled\n"); + return NULL; +} - if (avifIm) - avifImageDestroy(avifIm); +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvif(FILE *ctx) +{ + ARG_NOT_USED(ctx); + return _noAvifError(); } -void gdImageAvifEx(gdImagePtr im, FILE *outFile, int quality, int speed) +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifPtr(int size, void *data) { - gdIOCtx *out = gdNewFileCtx(outFile); + ARG_NOT_USED(size); + ARG_NOT_USED(data); + return _noAvifError(); +} - if (out != NULL) { - gdImageAvifCtx(im, out, quality, speed); - out->gd_free(out); - } +BGD_DECLARE(gdImagePtr) gdImageCreateFromAvifCtx(gdIOCtx *ctx) +{ + ARG_NOT_USED(ctx); + return _noAvifError(); } -void gdImageAvif(gdImagePtr im, FILE *outFile) +BGD_DECLARE(void) +gdImageAvifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, int speed) { - gdImageAvifEx(im, outFile, QUALITY_DEFAULT, SPEED_DEFAULT); + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(quality); + ARG_NOT_USED(speed); + _noAvifError(); } -void * gdImageAvifPtrEx(gdImagePtr im, int *size, int quality, int speed) +BGD_DECLARE(void) +gdImageAvifEx(gdImagePtr im, FILE *outfile, int quality, int speed) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(NEW_DYNAMIC_CTX_SIZE, NULL); + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(quality); + ARG_NOT_USED(speed); + _noAvifError(); +} - if (out == NULL) { - return NULL; - } +BGD_DECLARE(void) gdImageAvif(gdImagePtr im, FILE *outfile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + _noAvifError(); +} - gdImageAvifCtx(im, out, quality, speed); - rv = gdDPExtractData(out, size); +BGD_DECLARE(void *) gdImageAvifPtr(gdImagePtr im, int *size) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); - out->gd_free(out); - return rv; + return _noAvifError(); } -void * gdImageAvifPtr(gdImagePtr im, int *size) +BGD_DECLARE(void *) +gdImageAvifPtrEx(gdImagePtr im, int *size, int quality, int speed) { - return gdImageAvifPtrEx(im, size, QUALITY_DEFAULT, AVIF_SPEED_DEFAULT); + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(quality); + ARG_NOT_USED(speed); + return _noAvifError(); } #endif /* HAVE_LIBAVIF */ diff --git a/ext/gd/libgd/gd_bmp.c b/ext/gd/libgd/gd_bmp.c index c7c9cc9d8c1e..dac69b092c3f 100644 --- a/ext/gd/libgd/gd_bmp.c +++ b/ext/gd/libgd/gd_bmp.c @@ -1,29 +1,48 @@ /* - gd_bmp.c + gd_bmp.c - Bitmap format support for libgd + Bitmap format support for libgd - * Written 2007, Scott MacVicar - --------------------------------------------------------------------------- + * Written 2007, Scott MacVicar + --------------------------------------------------------------------------- - Todo: + Todo: - Bitfield encoding + Bitfield encoding - ---------------------------------------------------------------------------- + ---------------------------------------------------------------------------- */ -/* $Id$ */ + +/** + * File: BMP IO + * + * Read and write BMP images. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include -#include -#include +#include "bmp.h" #include "gd.h" +#include "gd_errors.h" #include "gdhelpers.h" -#include "bmp.h" +#include +#include +#include +#include +#include +#if defined(__has_builtin) && __has_builtin(__builtin_assume) +#define GD_ASSUME(expr) __builtin_assume(expr) +#elif defined(__GNUC__) +#define GD_ASSUME(expr) \ + do { \ + if (!(expr)) \ + __builtin_unreachable(); \ + } while (0) +#else +#define GD_ASSUME(expr) ((void)(expr)) +#endif static int compress_row(unsigned char *uncompressed_row, int length); static int build_rle_packet(unsigned char *row, int packet_type, int length, unsigned char *data); @@ -36,1065 +55,2135 @@ static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info); static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); +static int bmp_read_2bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info); -static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression); +typedef struct { + int bpp; + int compression; + int header_ver; + int row_stride; + int bitmap_size; + int info_size; + int palette_size; + int mask_size; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + unsigned int alpha_mask; +} bmp_write_ctx_t; + +static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int bpp, int compression, int flags); +static int bmp_resolve_write_ctx(gdImagePtr im, int bpp_hint, int compression, int flags, + bmp_write_ctx_t *ctx); +static int bmp_auto_bpp(gdImagePtr im); +static int bmp_has_alpha(gdImagePtr im); +static int bmp_prepare_write_image(gdImagePtr im, int bpp, int flags, gdImagePtr *write_im); +static void bmp_write_file_header(gdIOCtxPtr out, bmp_write_ctx_t *ctx); +static void bmp_write_info_header(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static void bmp_write_palette(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_1bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_4bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_8bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_16bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_24bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_pixels_32bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx); +static int bmp_write_rle4_row(gdIOCtxPtr out, gdImagePtr im, int row); +static int bmp_write_padding(gdIOCtxPtr out, int count); +static int bmp_write_tmpfile_to_ctx(gdIOCtxPtr out, gdIOCtxPtr out_original); + +static int bmp_validate_info(bmp_info_t *info, bmp_hdr_t *hdr); +static int bmp_read_bitfield_masks(gdIOCtxPtr infile, bmp_info_t *info, int read_alpha); +static int bmp_skip_bytes(gdIOCtxPtr infile, int count); +static int bmp_check_palette_index(gdImagePtr im, int index); +static int bmp_row_padding(int width, int depth, int *padding); +static int bmp_image_size(int width, int height, int depth, int *size); +static int bmp_get_mask_shift(unsigned int mask); +static int bmp_get_mask_bits(unsigned int mask); +static int bmp_extract_mask(unsigned int pixel, unsigned int mask); +static unsigned int bmp_pack_mask(int channel_8bit, unsigned int mask); +static int bmp_alpha_to_gd(int alpha); +static int bmp_gd_to_alpha(int gd_alpha); #define BMP_DEBUG(s) static int gdBMPPutWord(gdIOCtx *out, int w) { - /* Byte order is little-endian */ - gdPutC(w & 0xFF, out); - gdPutC((w >> 8) & 0xFF, out); - return 0; + /* Byte order is little-endian */ + gdPutC(w & 0xFF, out); + gdPutC((w >> 8) & 0xFF, out); + return 0; } static int gdBMPPutInt(gdIOCtx *out, int w) { - /* Byte order is little-endian */ - gdPutC(w & 0xFF, out); - gdPutC((w >> 8) & 0xFF, out); - gdPutC((w >> 16) & 0xFF, out); - gdPutC((w >> 24) & 0xFF, out); - return 0; + /* Byte order is little-endian */ + gdPutC(w & 0xFF, out); + gdPutC((w >> 8) & 0xFF, out); + gdPutC((w >> 16) & 0xFF, out); + gdPutC((w >> 24) & 0xFF, out); + return 0; } /* - Function: gdImageBmpPtr + Function: gdImageBmpPtr + + Outputs the given image as BMP data, but using a instead + of a file. See . + + This is the legacy BMP memory API. A zero value writes + uncompressed BMP data. A nonzero value requests legacy + RLE output when the automatically selected BMP bit depth supports RLE. + For explicit bit depth, compression, and conversion control, use + . + + Parameters: + im - the image to save. + size - Output: size in bytes of the result. + compression - whether to apply RLE or not. + + Returns: + + A pointer to memory containing the image data or NULL on error. */ -void * gdImageBmpPtr(gdImagePtr im, int *size, int compression) +BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size, int compression) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - if (out == NULL) return NULL; - if (!_gdImageBmpCtx(im, out, compression)) - rv = gdDPExtractData(out, size); - else - rv = NULL; - out->gd_free(out); - return rv; + return gdImageBmpPtrEx(im, size, 0, compression ? -1 : GD_BMP_COMPRESS_NONE, GD_BMP_FLAG_NONE); } /* - Function: gdImageBmp + Function: gdImageBmpPtrEx + + outputs the given image as BMP data in memory. + See for the meaning of , , and + . + + Parameters: + + im - The image to save. + size - Output: size in bytes of the returned data. + bpp - Requested output bit depth, or 0 for automatic selection. + compression - Requested BMP compression mode. + flags - BMP writer option flags. + + Returns: + + A pointer to memory containing the image data, or NULL on error. + The returned memory must be freed with . +*/ +BGD_DECLARE(void *) +gdImageBmpPtrEx(gdImagePtr im, int *size, int bpp, int compression, int flags) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageBmpCtx(im, out, bpp, compression, flags)) + rv = gdDPExtractData(out, size); + else + rv = NULL; + out->gd_free(out); + return rv; +} + +/* + Function: gdImageBmp + + outputs the specified image to the specified file in + BMP format. The file must be open for writing. Under MSDOS and all + versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + In addition, allows to specify whether RLE compression + should be applied. + + This is the legacy BMP file API. A zero value writes + uncompressed BMP data. A nonzero value requests legacy + RLE output when the automatically selected BMP bit depth supports RLE. + For explicit bit depth, compression, and conversion control, use + . + + Variants: + + write via a instead of a file handle. + + store the image file to memory. + + Parameters: + + im - the image to save. + outFile - the output FILE* object. + compression - whether to apply RLE or not. + + Returns: + nothing */ -void gdImageBmp(gdImagePtr im, FILE *outFile, int compression) +BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile, int compression) { - gdIOCtx *out = gdNewFileCtx(outFile); - if (out == NULL) return; - gdImageBmpCtx(im, out, compression); - out->gd_free(out); + gdImageBmpEx(im, outFile, 0, compression ? -1 : GD_BMP_COMPRESS_NONE, GD_BMP_FLAG_NONE); } /* - Function: gdImageBmpCtx + Function: gdImageBmpEx + + outputs the specified image to the specified file in + BMP format. The file must be open for writing. Under MSDOS and all + versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + This extended BMP writer supports 1, 4, 8, 16, 24, and 32 bits per + pixel. It writes Windows BMP headers only: BITMAPINFOHEADER for most + outputs, BITMAPV4HEADER for 32 bpp alpha output or when + is set. It does not write OS/2 BMP + headers, 2 bpp BMPs, top-down BMPs, custom bit masks, V5 color + profiles, embedded JPEG/PNG BMP data, or non-standard high-depth + bitfield formats. + + Bit depth: + + Pass 0 for automatic bit depth selection. Automatic selection writes + truecolor images with non-opaque pixels as 32 bpp, opaque truecolor + images as 24 bpp, palette images with 2 or fewer colors as 1 bpp, + palette images with 16 or fewer colors as 4 bpp, and other palette + images as 8 bpp. + + Explicit values must be one of 1, 4, 8, 16, 24, or 32. + Indexed output at 1, 4, or 8 bpp requires a palette image with no + more colors than the selected bit depth can store. If the source is + truecolor, explicit indexed output is a lossy conversion and fails + unless is set. With that flag, the writer + clones the image, converts the clone with , + writes the clone, and leaves the caller's image unchanged. + + Compression: + + writes uncompressed BMP pixels. + is valid only for 4 bpp output and writes + BI_RLE4. is valid only for 8 bpp output and + writes BI_RLE8. Any invalid bit depth/compression combination fails + before producing a valid BMP. + + 16 bpp and 32 bpp output use BI_BITFIELDS automatically, regardless + of the requested compression. 16 bpp defaults to RGB565 masks; set + to write RGB555 masks instead. 32 bpp writes + red, green, blue, and alpha masks and stores alpha as BMP opacity + (255 is opaque), converted from gd's alpha representation. + + Palette alpha is not preserved in 1, 4, or 8 bpp BMP output. The + writer stores indexed palettes as B, G, R, reserved byte entries, + and writes the reserved byte as zero. Truecolor images that need + alpha preservation should be written as 32 bpp, either explicitly or + by using automatic bit depth selection on an image with non-opaque + pixels. If a truecolor image is quantized to indexed BMP with + , alpha is not preserved in the indexed BMP. + + Flags: + + selects default behavior. + allows explicit lossy truecolor to indexed + conversion for 1, 4, or 8 bpp output. + selects RGB555 masks for 16 bpp output. + writes a BITMAPV4HEADER even when it is + not otherwise required. + + Variants: + + stores the image in RAM. + + writes using a struct. + + , , and are legacy + wrappers using automatic bit depth selection and no flags. + + Parameters: + + im - The image to save. + outFile - The FILE pointer to write to. + bpp - Requested bit depth, or 0 for automatic selection. + compression - One of , + , or . + flags - A bitwise OR of , + , , + and . + + Returns: + + For and , nothing. + For , a pointer to the image in memory, or NULL + on error. */ -void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) +BGD_DECLARE(void) +gdImageBmpEx(gdImagePtr im, FILE *outFile, int bpp, int compression, int flags) { - _gdImageBmpCtx(im, out, compression); + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageBmpCtxEx(im, out, bpp, compression, flags); + out->gd_free(out); } -static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression){ - int bitmap_size = 0, info_size, total_size, padding; - int i, row, xpos, pixel; - int error = 0; - unsigned char *uncompressed_row = NULL, *uncompressed_row_start = NULL; - FILE *tmpfile_for_compression = NULL; - gdIOCtxPtr out_original = NULL; - int ret = 1; - - /* No compression if its true colour or we don't support seek */ - if (im->trueColor) { - compression = 0; - } - - if (compression == 1 && !out->seek) { - /* Try to create a temp file where we can seek */ - if ((tmpfile_for_compression = tmpfile()) == NULL) { - compression = 0; - } else { - out_original = out; - if ((out = (gdIOCtxPtr)gdNewFileCtx(tmpfile_for_compression)) == NULL) { - out = out_original; - out_original = NULL; - compression = 0; - } - } - } - - bitmap_size = ((im->sx * (im->trueColor ? 24 : 8)) / 8) * im->sy; - - /* 40 byte Windows v3 header */ - info_size = BMP_WINDOWS_V3; - - /* data for the palette */ - if (!im->trueColor) { - info_size += im->colorsTotal * 4; - if (compression) { - bitmap_size = 0; - } - } - - /* bitmap header + info header + data */ - total_size = 14 + info_size + bitmap_size; - - /* write bmp header info */ - gdPutBuf("BM", 2, out); - gdBMPPutInt(out, total_size); - gdBMPPutWord(out, 0); - gdBMPPutWord(out, 0); - gdBMPPutInt(out, 14 + info_size); - - /* write Windows v3 headers */ - gdBMPPutInt(out, BMP_WINDOWS_V3); /* header size */ - gdBMPPutInt(out, im->sx); /* width */ - gdBMPPutInt(out, im->sy); /* height */ - gdBMPPutWord(out, 1); /* colour planes */ - gdBMPPutWord(out, (im->trueColor ? 24 : 8)); /* bit count */ - gdBMPPutInt(out, (compression ? BMP_BI_RLE8 : BMP_BI_RGB)); /* compression */ - gdBMPPutInt(out, bitmap_size); /* image size */ - gdBMPPutInt(out, 0); /* H resolution */ - gdBMPPutInt(out, 0); /* V ressolution */ - gdBMPPutInt(out, im->colorsTotal); /* colours used */ - gdBMPPutInt(out, 0); /* important colours */ - - /* The line must be divisible by 4, else it's padded with NULLs */ - padding = ((int)(im->trueColor ? 3 : 1) * im->sx) % 4; - if (padding) { - padding = 4 - padding; - } - - /* 8-bit colours */ - if (!im->trueColor) { - for(i = 0; i< im->colorsTotal; ++i) { - Putchar(gdImageBlue(im, i), out); - Putchar(gdImageGreen(im, i), out); - Putchar(gdImageRed(im, i), out); - Putchar(0, out); - } - - if (compression) { - /* Can potentially change this to X + ((X / 128) * 3) */ - uncompressed_row = uncompressed_row_start = (unsigned char *) gdCalloc(gdImageSX(im) * 2, sizeof(char)); - if (!uncompressed_row) { - /* malloc failed */ - goto cleanup; - } - } - - for (row = (im->sy - 1); row >= 0; row--) { - if (compression) { - memset (uncompressed_row, 0, gdImageSX(im)); - } - - for (xpos = 0; xpos < im->sx; xpos++) { - if (compression) { - *uncompressed_row++ = (unsigned char)gdImageGetPixel(im, xpos, row); - } else { - Putchar(gdImageGetPixel(im, xpos, row), out); - } - } - - if (!compression) { - /* Add padding to make sure we have n mod 4 == 0 bytes per row */ - for (xpos = padding; xpos > 0; --xpos) { - Putchar('\0', out); - } - } else { - int compressed_size = 0; - uncompressed_row = uncompressed_row_start; - if ((compressed_size = compress_row(uncompressed_row, gdImageSX(im))) < 0) { - error = 1; - break; - } - bitmap_size += compressed_size; - - - gdPutBuf(uncompressed_row, compressed_size, out); - Putchar(BMP_RLE_COMMAND, out); - Putchar(BMP_RLE_ENDOFLINE, out); - bitmap_size += 2; - } - } - - if (compression && uncompressed_row) { - gdFree(uncompressed_row); - if (error != 0) { - goto cleanup; - } - /* Update filesize based on new values and set compression flag */ - Putchar(BMP_RLE_COMMAND, out); - Putchar(BMP_RLE_ENDOFBITMAP, out); - bitmap_size += 2; - - /* Write new total bitmap size */ - gdSeek(out, 2); - gdBMPPutInt(out, total_size + bitmap_size); - - /* Total length of image data */ - gdSeek(out, 34); - gdBMPPutInt(out, bitmap_size); - } - - } else { - for (row = (im->sy - 1); row >= 0; row--) { - for (xpos = 0; xpos < im->sx; xpos++) { - pixel = gdImageGetPixel(im, xpos, row); - - Putchar(gdTrueColorGetBlue(pixel), out); - Putchar(gdTrueColorGetGreen(pixel), out); - Putchar(gdTrueColorGetRed(pixel), out); - } - - /* Add padding to make sure we have n mod 4 == 0 bytes per row */ - for (xpos = padding; xpos > 0; --xpos) { - Putchar('\0', out); - } - } - } - - - /* If we needed a tmpfile for compression copy it over to out_original */ - if (tmpfile_for_compression) { - unsigned char* copy_buffer = NULL; - int buffer_size = 0; - - gdSeek(out, 0); - copy_buffer = (unsigned char *) gdMalloc(1024 * sizeof(unsigned char)); - if (copy_buffer == NULL) { - goto cleanup; - } - - while ((buffer_size = gdGetBuf(copy_buffer, 1024, out)) != EOF) { - if (buffer_size == 0) { - break; - } - gdPutBuf(copy_buffer , buffer_size, out_original); - } - gdFree(copy_buffer); - - /* Replace the temp with the original which now has data */ - out->gd_free(out); - out = out_original; - out_original = NULL; - } - - ret = 0; +/* + Function: gdImageBmpCtx + + Outputs the given image as BMP data, but using a instead + of a file. See . + + This is the legacy BMP context API. A zero value writes + uncompressed BMP data. A nonzero value requests legacy + RLE output when the automatically selected BMP bit depth supports RLE. + For explicit bit depth, compression, and conversion control, use + . + + Parameters: + im - the image to save. + out - the to write to. + compression - whether to apply RLE or not. +*/ +BGD_DECLARE(void) +gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) +{ + gdImageBmpCtxEx(im, out, 0, compression ? -1 : GD_BMP_COMPRESS_NONE, GD_BMP_FLAG_NONE); +} + +/* + Function: gdImageBmpCtxEx + + outputs the given image as BMP data using a + structure. See for the meaning of , + , and , including automatic bit depth selection, + RLE restrictions, quantization behavior, bitfield output, and + unsupported BMP variants. + + Parameters: + + im - The image to save. + out - The to write to. + bpp - Requested output bit depth, or 0 for automatic selection. + compression - Requested BMP compression mode. + flags - BMP writer option flags. +*/ +BGD_DECLARE(void) +gdImageBmpCtxEx(gdImagePtr im, gdIOCtxPtr out, int bpp, int compression, int flags) +{ + _gdImageBmpCtx(im, out, bpp, compression, flags); +} + +static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int bpp, int compression, int flags) +{ + bmp_write_ctx_t ctx; + int error = 0; + FILE *tmpfile_for_compression = NULL; + gdIOCtxPtr out_original = NULL; + int ret = 1; + gdImagePtr write_im = im; + + if (im == NULL || out == NULL) { + return 1; + } + + if (gdImageSX(im) <= 0 || gdImageSY(im) <= 0) { + gd_error("image dimensions must be greater than 0"); + return 1; + } + + if (overflow2(gdImageSX(im), gdImageSY(im))) { + gd_error("image dimensions are too large"); + return 1; + } + + if (bmp_prepare_write_image(im, bpp, flags, &write_im)) { + return 1; + } + + if (bmp_resolve_write_ctx(write_im, bpp, compression, flags, &ctx)) { + goto cleanup; + } + + if ((ctx.compression == BMP_BI_RLE8 || ctx.compression == BMP_BI_RLE4) && !out->seek) { + /* Try to create a temp file where we can seek */ + if ((tmpfile_for_compression = tmpfile()) == NULL) { + ctx.compression = BMP_BI_RGB; + if (ctx.bpp == 4 || ctx.bpp == 8) { + ctx.bitmap_size = ctx.row_stride * write_im->sy; + } + } else { + out_original = out; + if ((out = (gdIOCtxPtr)gdNewFileCtx(tmpfile_for_compression)) == NULL) { + out = out_original; + out_original = NULL; + ctx.compression = BMP_BI_RGB; + if (ctx.bpp == 4 || ctx.bpp == 8) { + ctx.bitmap_size = ctx.row_stride * write_im->sy; + } + } + } + } + + bmp_write_file_header(out, &ctx); + bmp_write_info_header(out, write_im, &ctx); + if (ctx.palette_size) { + bmp_write_palette(out, write_im, &ctx); + } + + error = bmp_write_pixels(out, write_im, &ctx); + + if (!error && (ctx.compression == BMP_BI_RLE8 || ctx.compression == BMP_BI_RLE4)) { + gdPutC(BMP_RLE_COMMAND, out); + gdPutC(BMP_RLE_ENDOFBITMAP, out); + ctx.bitmap_size += 2; + + gdSeek(out, 2); + gdBMPPutInt(out, 14 + ctx.info_size + ctx.bitmap_size); + + gdSeek(out, 34); + gdBMPPutInt(out, ctx.bitmap_size); + } + + /* If we needed a tmpfile for compression copy it over to out_original */ + if (!error && tmpfile_for_compression && bmp_write_tmpfile_to_ctx(out, out_original)) { + error = 1; + } + if (tmpfile_for_compression && out_original) { + out->gd_free(out); + out = out_original; + out_original = NULL; + } + + ret = error; cleanup: - if (tmpfile_for_compression) { + if (tmpfile_for_compression) { #ifdef _WIN32 - _rmtmp(); + _rmtmp(); #else - fclose(tmpfile_for_compression); + fclose(tmpfile_for_compression); #endif - tmpfile_for_compression = NULL; - } + tmpfile_for_compression = NULL; + } + + if (out_original) { + out_original->gd_free(out_original); + } + if (write_im != im) { + gdImageDestroy(write_im); + } + return ret; +} + +static int bmp_prepare_write_image(gdImagePtr im, int bpp, int flags, gdImagePtr *write_im) +{ + gdImagePtr clone; + + *write_im = im; + if ((bpp == 1 || bpp == 4 || bpp == 8) && im->trueColor) { + if (!(flags & GD_BMP_FLAG_QUANTIZE)) { + return 1; + } + clone = gdImageClone(im); + if (clone == NULL) { + return 1; + } + if (!gdImageTrueColorToPalette(clone, 0, 1 << bpp)) { + gdImageDestroy(clone); + return 1; + } + *write_im = clone; + } + return 0; +} + +static int bmp_auto_bpp(gdImagePtr im) +{ + if (im->trueColor) { + return bmp_has_alpha(im) ? 32 : 24; + } + if (im->colorsTotal <= 2) { + return 1; + } + if (im->colorsTotal <= 16) { + return 4; + } + return 8; +} + +static int bmp_has_alpha(gdImagePtr im) +{ + int x, y; + + for (y = 0; y < im->sy; y++) { + for (x = 0; x < im->sx; x++) { + if (gdTrueColorGetAlpha(gdImageGetPixel(im, x, y)) != gdAlphaOpaque) { + return 1; + } + } + } + return 0; +} + +static int bmp_resolve_write_ctx(gdImagePtr im, int bpp_hint, int compression, int flags, + bmp_write_ctx_t *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->bpp = (bpp_hint > 0) ? bpp_hint : bmp_auto_bpp(im); + switch (ctx->bpp) { + case 1: + case 4: + case 8: + case 16: + case 24: + case 32: + break; + default: + return 1; + } + + if ((ctx->bpp == 1 || ctx->bpp == 4 || ctx->bpp == 8) && im->trueColor) { + return 1; + } + if ((ctx->bpp == 1 || ctx->bpp == 4 || ctx->bpp == 8) && im->colorsTotal > (1 << ctx->bpp)) { + return 1; + } + + if (compression == -1) { + if (ctx->bpp == 8) { + ctx->compression = BMP_BI_RLE8; + } else if (ctx->bpp == 4) { + ctx->compression = BMP_BI_RLE4; + } else { + ctx->compression = BMP_BI_RGB; + } + } else { + switch (compression) { + case GD_BMP_COMPRESS_NONE: + ctx->compression = BMP_BI_RGB; + break; + case GD_BMP_COMPRESS_RLE8: + if (ctx->bpp != 8) { + return 1; + } + ctx->compression = BMP_BI_RLE8; + break; + case GD_BMP_COMPRESS_RLE4: + if (ctx->bpp != 4) { + return 1; + } + ctx->compression = BMP_BI_RLE4; + break; + default: + return 1; + } + } + + if (ctx->bpp == 16) { + if (flags & GD_BMP_FLAG_RGB555) { + ctx->red_mask = 0x7C00; + ctx->green_mask = 0x03E0; + ctx->blue_mask = 0x001F; + } else { + ctx->red_mask = 0xF800; + ctx->green_mask = 0x07E0; + ctx->blue_mask = 0x001F; + } + ctx->compression = BMP_BI_BITFIELDS; + } else if (ctx->bpp == 32) { + ctx->red_mask = 0x00FF0000; + ctx->green_mask = 0x0000FF00; + ctx->blue_mask = 0x000000FF; + ctx->alpha_mask = 0xFF000000; + ctx->compression = BMP_BI_BITFIELDS; + } + + ctx->header_ver = ((ctx->bpp == 32 && ctx->alpha_mask) || (flags & GD_BMP_FLAG_FORCE_V4HDR)) + ? BMP_WINDOWS_V4 + : BMP_WINDOWS_V3; + ctx->palette_size = (ctx->bpp <= 8) ? (1 << ctx->bpp) * 4 : 0; + ctx->mask_size = + (ctx->header_ver == BMP_WINDOWS_V3 && ctx->compression == BMP_BI_BITFIELDS) ? 12 : 0; + ctx->info_size = ctx->header_ver + ctx->mask_size + ctx->palette_size; + ctx->row_stride = (((ctx->bpp * im->sx) + 31) / 32) * 4; + if (ctx->compression != BMP_BI_RLE8 && ctx->compression != BMP_BI_RLE4) { + ctx->bitmap_size = ctx->row_stride * im->sy; + } + return 0; +} + +static void bmp_write_file_header(gdIOCtxPtr out, bmp_write_ctx_t *ctx) +{ + gdPutBuf("BM", 2, out); + gdBMPPutInt(out, 14 + ctx->info_size + ctx->bitmap_size); + gdBMPPutWord(out, 0); + gdBMPPutWord(out, 0); + gdBMPPutInt(out, 14 + ctx->info_size); +} + +static void bmp_write_info_header(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int i; + + gdBMPPutInt(out, ctx->header_ver); + gdBMPPutInt(out, im->sx); + gdBMPPutInt(out, im->sy); + gdBMPPutWord(out, 1); + gdBMPPutWord(out, ctx->bpp); + gdBMPPutInt(out, ctx->compression); + gdBMPPutInt(out, ctx->bitmap_size); + gdBMPPutInt(out, 0); + gdBMPPutInt(out, 0); + gdBMPPutInt(out, ctx->palette_size ? (ctx->palette_size / 4) : 0); + gdBMPPutInt(out, 0); + + if (ctx->header_ver == BMP_WINDOWS_V4) { + gdBMPPutInt(out, ctx->red_mask); + gdBMPPutInt(out, ctx->green_mask); + gdBMPPutInt(out, ctx->blue_mask); + gdBMPPutInt(out, ctx->alpha_mask); + gdBMPPutInt(out, 0x73524742); + for (i = 0; i < 9; i++) { + gdBMPPutInt(out, 0); + } + gdBMPPutInt(out, 0); + gdBMPPutInt(out, 0); + gdBMPPutInt(out, 0); + } else if (ctx->mask_size) { + gdBMPPutInt(out, ctx->red_mask); + gdBMPPutInt(out, ctx->green_mask); + gdBMPPutInt(out, ctx->blue_mask); + } +} + +static void bmp_write_palette(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int i, count; + + count = 1 << ctx->bpp; + for (i = 0; i < count; i++) { + if (i < im->colorsTotal) { + gdPutC(gdImageBlue(im, i), out); + gdPutC(gdImageGreen(im, i), out); + gdPutC(gdImageRed(im, i), out); + } else { + gdPutC(0, out); + gdPutC(0, out); + gdPutC(0, out); + } + gdPutC(0, out); + } +} + +static int bmp_write_pixels(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + switch (ctx->bpp) { + case 1: + return bmp_write_pixels_1bit(out, im, ctx); + case 4: + return bmp_write_pixels_4bit(out, im, ctx); + case 8: + return bmp_write_pixels_8bit(out, im, ctx); + case 16: + return bmp_write_pixels_16bit(out, im, ctx); + case 24: + return bmp_write_pixels_24bit(out, im, ctx); + case 32: + return bmp_write_pixels_32bit(out, im, ctx); + default: + return 1; + } +} + +static int bmp_write_padding(gdIOCtxPtr out, int count) +{ + while (count-- > 0) { + gdPutC(0, out); + } + return 0; +} + +static int bmp_write_pixels_1bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos, bit, byte, bytes_written, index; + + for (row = im->sy - 1; row >= 0; row--) { + bytes_written = 0; + for (xpos = 0; xpos < im->sx; xpos += 8) { + byte = 0; + for (bit = 0; bit < 8 && xpos + bit < im->sx; bit++) { + index = gdImageGetPixel(im, xpos + bit, row); + if (index < 0 || index > 1) { + return 1; + } + byte |= (index & 0x01) << (7 - bit); + } + gdPutC(byte, out); + bytes_written++; + } + bmp_write_padding(out, ctx->row_stride - bytes_written); + } + return 0; +} - if (out_original) { - out_original->gd_free(out_original); - } - return ret; +static int bmp_write_pixels_4bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos, high, low, bytes_written; + + if (ctx->compression == BMP_BI_RLE4) { + for (row = im->sy - 1; row >= 0; row--) { + int compressed_size = bmp_write_rle4_row(out, im, row); + if (compressed_size < 0) { + return 1; + } + ctx->bitmap_size += compressed_size; + ctx->bitmap_size += 2; + gdPutC(BMP_RLE_COMMAND, out); + gdPutC(BMP_RLE_ENDOFLINE, out); + } + return 0; + } + + for (row = im->sy - 1; row >= 0; row--) { + bytes_written = 0; + for (xpos = 0; xpos < im->sx; xpos += 2) { + high = gdImageGetPixel(im, xpos, row); + if (high < 0 || high > 15) { + return 1; + } + if (xpos + 1 < im->sx) { + low = gdImageGetPixel(im, xpos + 1, row); + if (low < 0 || low > 15) { + return 1; + } + } else { + low = 0; + } + gdPutC(((high & 0x0f) << 4) | (low & 0x0f), out); + bytes_written++; + } + bmp_write_padding(out, ctx->row_stride - bytes_written); + } + return 0; +} + +static int bmp_write_rle4_row(gdIOCtxPtr out, gdImagePtr im, int row) +{ + int xpos, chunk, i, value, next; + int bytes; + int total = 0; + + for (xpos = 0; xpos < im->sx;) { + chunk = im->sx - xpos; + if (chunk > 255) { + chunk = 255; + } + if (chunk < 3) { + value = gdImageGetPixel(im, xpos, row); + if (value < 0 || value > 15) { + return 1; + } + next = value; + if (chunk == 2) { + next = gdImageGetPixel(im, xpos + 1, row); + if (next < 0 || next > 15) { + return 1; + } + } + gdPutC(chunk, out); + gdPutC(((value & 0x0f) << 4) | (next & 0x0f), out); + total += 2; + xpos += chunk; + continue; + } + gdPutC(BMP_RLE_COMMAND, out); + gdPutC(chunk, out); + total += 2; + bytes = (chunk + 1) / 2; + for (i = 0; i < chunk; i += 2) { + value = gdImageGetPixel(im, xpos + i, row); + if (value < 0 || value > 15) { + return 1; + } + if (i + 1 < chunk) { + next = gdImageGetPixel(im, xpos + i + 1, row); + if (next < 0 || next > 15) { + return 1; + } + } else { + next = 0; + } + gdPutC(((value & 0x0f) << 4) | (next & 0x0f), out); + total++; + } + if (bytes & 1) { + gdPutC(0, out); + total++; + } + xpos += chunk; + } + return total; +} + +static int bmp_write_pixels_8bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos; + unsigned char *uncompressed_row = NULL; + + if (ctx->compression == BMP_BI_RLE8) { + uncompressed_row = (unsigned char *)gdCalloc(gdImageSX(im) * 2, sizeof(char)); + if (!uncompressed_row) { + return 1; + } + for (row = im->sy - 1; row >= 0; row--) { + int compressed_size; + for (xpos = 0; xpos < im->sx; xpos++) { + uncompressed_row[xpos] = (unsigned char)gdImageGetPixel(im, xpos, row); + } + compressed_size = compress_row(uncompressed_row, gdImageSX(im)); + if (compressed_size < 0) { + gdFree(uncompressed_row); + return 1; + } + ctx->bitmap_size += compressed_size; + if (gdPutBuf(uncompressed_row, compressed_size, out) != compressed_size) { + gd_error("gd-bmp write error\n"); + gdFree(uncompressed_row); + return 1; + } + gdPutC(BMP_RLE_COMMAND, out); + gdPutC(BMP_RLE_ENDOFLINE, out); + ctx->bitmap_size += 2; + } + gdFree(uncompressed_row); + return 0; + } + + for (row = im->sy - 1; row >= 0; row--) { + for (xpos = 0; xpos < im->sx; xpos++) { + gdPutC(gdImageGetPixel(im, xpos, row), out); + } + bmp_write_padding(out, ctx->row_stride - im->sx); + } + return 0; +} + +static int bmp_write_pixels_16bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos, pixel, red, green, blue; + unsigned int packed; + + for (row = im->sy - 1; row >= 0; row--) { + for (xpos = 0; xpos < im->sx; xpos++) { + pixel = gdImageGetPixel(im, xpos, row); + if (im->trueColor) { + red = gdTrueColorGetRed(pixel); + green = gdTrueColorGetGreen(pixel); + blue = gdTrueColorGetBlue(pixel); + } else { + red = gdImageRed(im, pixel); + green = gdImageGreen(im, pixel); + blue = gdImageBlue(im, pixel); + } + packed = bmp_pack_mask(red, ctx->red_mask) | bmp_pack_mask(green, ctx->green_mask) | + bmp_pack_mask(blue, ctx->blue_mask); + gdBMPPutWord(out, (int)packed); + } + bmp_write_padding(out, ctx->row_stride - im->sx * 2); + } + return 0; +} + +static int bmp_write_pixels_24bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos, pixel; + + for (row = im->sy - 1; row >= 0; row--) { + for (xpos = 0; xpos < im->sx; xpos++) { + pixel = gdImageGetPixel(im, xpos, row); + if (im->trueColor) { + gdPutC(gdTrueColorGetBlue(pixel), out); + gdPutC(gdTrueColorGetGreen(pixel), out); + gdPutC(gdTrueColorGetRed(pixel), out); + } else { + gdPutC(gdImageBlue(im, pixel), out); + gdPutC(gdImageGreen(im, pixel), out); + gdPutC(gdImageRed(im, pixel), out); + } + } + bmp_write_padding(out, ctx->row_stride - im->sx * 3); + } + return 0; +} + +static int bmp_write_pixels_32bit(gdIOCtxPtr out, gdImagePtr im, bmp_write_ctx_t *ctx) +{ + int row, xpos, pixel, red, green, blue, alpha; + unsigned int packed; + + for (row = im->sy - 1; row >= 0; row--) { + for (xpos = 0; xpos < im->sx; xpos++) { + pixel = gdImageGetPixel(im, xpos, row); + if (im->trueColor) { + red = gdTrueColorGetRed(pixel); + green = gdTrueColorGetGreen(pixel); + blue = gdTrueColorGetBlue(pixel); + alpha = bmp_gd_to_alpha(gdTrueColorGetAlpha(pixel)); + } else { + red = gdImageRed(im, pixel); + green = gdImageGreen(im, pixel); + blue = gdImageBlue(im, pixel); + alpha = bmp_gd_to_alpha(im->alpha[pixel]); + } + packed = bmp_pack_mask(red, ctx->red_mask) | bmp_pack_mask(green, ctx->green_mask) | + bmp_pack_mask(blue, ctx->blue_mask) | bmp_pack_mask(alpha, ctx->alpha_mask); + gdBMPPutInt(out, (int)packed); + } + } + return 0; +} + +static int bmp_write_tmpfile_to_ctx(gdIOCtxPtr out, gdIOCtxPtr out_original) +{ + unsigned char *copy_buffer = NULL; + int buffer_size = 0; + + gdSeek(out, 0); + copy_buffer = (unsigned char *)gdMalloc(1024 * sizeof(unsigned char)); + if (copy_buffer == NULL) { + return 1; + } + + while ((buffer_size = gdGetBuf(copy_buffer, 1024, out)) != EOF) { + if (buffer_size == 0) { + break; + } + if (gdPutBuf(copy_buffer, buffer_size, out_original) != buffer_size) { + gd_error("gd-bmp write error\n"); + gdFree(copy_buffer); + return 1; + } + } + gdFree(copy_buffer); + return 0; } static int compress_row(unsigned char *row, int length) { - int rle_type = 0; - int compressed_length = 0; - int pixel = 0, compressed_run = 0, rle_compression = 0; - unsigned char *uncompressed_row = NULL, *uncompressed_rowp = NULL, *uncompressed_start = NULL; - - uncompressed_row = (unsigned char *) gdMalloc(length); - if (!uncompressed_row) { - return -1; - } - - memcpy(uncompressed_row, row, length); - uncompressed_start = uncompressed_rowp = uncompressed_row; - - for (pixel = 0; pixel < length; pixel++) { - if (compressed_run == 0) { - uncompressed_row = uncompressed_rowp; - compressed_run++; - uncompressed_rowp++; - rle_type = BMP_RLE_TYPE_RAW; - continue; - } - - if (compressed_run == 1) { - /* Compare next byte */ - if (memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { - rle_type = BMP_RLE_TYPE_RLE; - } - } - - if (rle_type == BMP_RLE_TYPE_RLE) { - if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) != 0) { - /* more than what we can store in a single run or run is over due to non match, force write */ - rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - row += rle_compression; - compressed_length += rle_compression; - compressed_run = 0; - pixel--; - } else { - compressed_run++; - uncompressed_rowp++; - } - } else { - if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { - /* more than what we can store in a single run or run is over due to match, force write */ - rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - row += rle_compression; - compressed_length += rle_compression; - compressed_run = 0; - pixel--; - } else { - /* add this pixel to the row */ - compressed_run++; - uncompressed_rowp++; - } - - } - } - - if (compressed_run) { - compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - } - - gdFree(uncompressed_start); - - return compressed_length; + int rle_type = 0; + int compressed_length = 0; + int pixel = 0, compressed_run = 0, rle_compression = 0; + unsigned char *uncompressed_row = NULL, *uncompressed_rowp = NULL, *uncompressed_start = NULL; + GD_ASSUME(length > 0); + uncompressed_row = (unsigned char *)gdMalloc(length); + if (!uncompressed_row) { + return -1; + } + + memcpy(uncompressed_row, row, length); + uncompressed_start = uncompressed_rowp = uncompressed_row; + + for (pixel = 0; pixel < length; pixel++) { + if (compressed_run == 0) { + uncompressed_row = uncompressed_rowp; + compressed_run++; + uncompressed_rowp++; + rle_type = BMP_RLE_TYPE_RAW; + continue; + } + + if (compressed_run == 1) { + /* Compare next byte */ + if (memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { + rle_type = BMP_RLE_TYPE_RLE; + } + } + + if (rle_type == BMP_RLE_TYPE_RLE) { + if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) != 0) { + /* more than what we can store in a single run or run is over + * due to non match, force write */ + rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); + row += rle_compression; + compressed_length += rle_compression; + compressed_run = 0; + pixel--; + } else { + compressed_run++; + uncompressed_rowp++; + } + } else { + if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { + /* more than what we can store in a single run or run is over + * due to match, force write */ + rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); + row += rle_compression; + compressed_length += rle_compression; + compressed_run = 0; + pixel--; + } else { + /* add this pixel to the row */ + compressed_run++; + uncompressed_rowp++; + } + } + } + + if (compressed_run) { + compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row); + } + + gdFree(uncompressed_start); + + return compressed_length; } static int build_rle_packet(unsigned char *row, int packet_type, int length, unsigned char *data) { - int compressed_size = 0; - if (length < 1 || length > 128) { - return 0; - } - - /* Bitmap specific cases is that we can't have uncompressed rows of length 1 or 2 */ - if (packet_type == BMP_RLE_TYPE_RAW && length < 3) { - int i = 0; - for (i = 0; i < length; i++) { - compressed_size += 2; - memset(row, 1, 1); - row++; - - memcpy(row, data++, 1); - row++; - } - } else if (packet_type == BMP_RLE_TYPE_RLE) { - compressed_size = 2; - memset(row, length, 1); - row++; - - memcpy(row, data, 1); - row++; - } else { - compressed_size = 2 + length; - memset(row, BMP_RLE_COMMAND, 1); - row++; - - memset(row, length, 1); - row++; - - memcpy(row, data, length); - row += length; - - /* Must be an even number for an uncompressed run */ - if (length % 2) { - memset(row, 0, 1); - row++; - compressed_size++; - } - } - return compressed_size; + int compressed_size = 0; + if (length < 1 || length > 128) { + return 0; + } + + /* Bitmap specific cases is that we can't have uncompressed rows of length 1 + * or 2 */ + if (packet_type == BMP_RLE_TYPE_RAW && length < 3) { + int i = 0; + for (i = 0; i < length; i++) { + compressed_size += 2; + memset(row, 1, 1); + row++; + + memcpy(row, data++, 1); + row++; + } + } else if (packet_type == BMP_RLE_TYPE_RLE) { + compressed_size = 2; + memset(row, length, 1); + row++; + + memcpy(row, data, 1); + row++; + } else { + compressed_size = 2 + length; + memset(row, BMP_RLE_COMMAND, 1); + row++; + + memset(row, length, 1); + row++; + + memcpy(row, data, length); + row += length; + + /* Must be an even number for an uncompressed run */ + if (length % 2) { + memset(row, 0, 1); + row++; + compressed_size++; + } + } + return compressed_size; } /* - Function: gdImageCreateFromBmp + Function: gdImageCreateFromBmp */ -gdImagePtr gdImageCreateFromBmp(FILE * inFile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmp(FILE *inFile) { - gdImagePtr im = 0; - gdIOCtx *in = gdNewFileCtx(inFile); - if (in == NULL) return NULL; - im = gdImageCreateFromBmpCtx(in); - in->gd_free(in); - return im; + gdImagePtr im = 0; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromBmpCtx(in); + in->gd_free(in); + return im; } /* - Function: gdImageCreateFromBmpPtr + Function: gdImageCreateFromBmpPtr */ -gdImagePtr gdImageCreateFromBmpPtr(int size, void *data) +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpPtr(int size, void *data) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - if (in == NULL) return NULL; - im = gdImageCreateFromBmpCtx(in); - in->gd_free(in); - return im; + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) + return NULL; + im = gdImageCreateFromBmpCtx(in); + in->gd_free(in); + return im; } /* - Function: gdImageCreateFromBmpCtx + Function: gdImageCreateFromBmpCtx */ -gdImagePtr gdImageCreateFromBmpCtx(gdIOCtxPtr infile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpCtx(gdIOCtxPtr infile) { - bmp_hdr_t *hdr; - bmp_info_t *info; - gdImagePtr im = NULL; - int error = 0; - - if (!(hdr= (bmp_hdr_t *)gdCalloc(1, sizeof(bmp_hdr_t)))) { - return NULL; - } - - if (bmp_read_header(infile, hdr)) { - gdFree(hdr); - return NULL; - } - - if (hdr->magic != 0x4d42) { - gdFree(hdr); - return NULL; - } - - if (!(info = (bmp_info_t *)gdCalloc(1, sizeof(bmp_info_t)))) { - gdFree(hdr); - return NULL; - } - - if (bmp_read_info(infile, info)) { - gdFree(hdr); - gdFree(info); - return NULL; - } - - BMP_DEBUG(printf("Numcolours: %d\n", info->numcolors)); - BMP_DEBUG(printf("Width: %d\n", info->width)); - BMP_DEBUG(printf("Height: %d\n", info->height)); - BMP_DEBUG(printf("Planes: %d\n", info->numplanes)); - BMP_DEBUG(printf("Depth: %d\n", info->depth)); - BMP_DEBUG(printf("Offset: %d\n", hdr->off)); - - if (info->depth >= 16) { - im = gdImageCreateTrueColor(info->width, info->height); - } else { - im = gdImageCreate(info->width, info->height); - } - - if (!im) { - gdFree(hdr); - gdFree(info); - return NULL; - } - - switch (info->depth) { - case 1: - BMP_DEBUG(printf("1-bit image\n")); - error = bmp_read_1bit(im, infile, info, hdr); - break; - case 4: - BMP_DEBUG(printf("4-bit image\n")); - error = bmp_read_4bit(im, infile, info, hdr); - break; - case 8: - BMP_DEBUG(printf("8-bit image\n")); - error = bmp_read_8bit(im, infile, info, hdr); - break; - case 16: - case 24: - case 32: - BMP_DEBUG(printf("Direct BMP image\n")); - error = bmp_read_direct(im, infile, info, hdr); - break; - default: - BMP_DEBUG(printf("Unknown bit count\n")); - error = 1; - } - - gdFree(hdr); - gdFree(info); - - if (error) { - gdImageDestroy(im); - return NULL; - } - - return im; + bmp_hdr_t *hdr; + bmp_info_t *info; + gdImagePtr im = NULL; + int error = 0; + + if (!(hdr = (bmp_hdr_t *)gdCalloc(1, sizeof(bmp_hdr_t)))) { + return NULL; + } + + if (bmp_read_header(infile, hdr)) { + gdFree(hdr); + return NULL; + } + + if (hdr->magic != 0x4d42) { + gdFree(hdr); + return NULL; + } + + if (!(info = (bmp_info_t *)gdCalloc(1, sizeof(bmp_info_t)))) { + gdFree(hdr); + return NULL; + } + + if (bmp_read_info(infile, info)) { + gdFree(hdr); + gdFree(info); + return NULL; + } + + if (bmp_validate_info(info, hdr)) { + gdFree(hdr); + gdFree(info); + return NULL; + } + + BMP_DEBUG(printf("Numcolours: %d\n", info->numcolors)); + BMP_DEBUG(printf("Width: %d\n", info->width)); + BMP_DEBUG(printf("Height: %d\n", info->height)); + BMP_DEBUG(printf("Planes: %d\n", info->numplanes)); + BMP_DEBUG(printf("Depth: %d\n", info->depth)); + BMP_DEBUG(printf("Offset: %d\n", hdr->off)); + + if (info->depth >= 16) { + im = gdImageCreateTrueColor(info->width, info->height); + } else { + im = gdImageCreate(info->width, info->height); + } + + if (!im) { + gdFree(hdr); + gdFree(info); + return NULL; + } + + switch (info->depth) { + case 1: + BMP_DEBUG(printf("1-bit image\n")); + error = bmp_read_1bit(im, infile, info, hdr); + break; + case 2: + BMP_DEBUG(printf("2-bit image\n")); + error = bmp_read_2bit(im, infile, info, hdr); + break; + case 4: + BMP_DEBUG(printf("4-bit image\n")); + error = bmp_read_4bit(im, infile, info, hdr); + break; + case 8: + BMP_DEBUG(printf("8-bit image\n")); + error = bmp_read_8bit(im, infile, info, hdr); + break; + case 16: + case 24: + case 32: + BMP_DEBUG(printf("Direct BMP image\n")); + error = bmp_read_direct(im, infile, info, hdr); + break; + default: + BMP_DEBUG(printf("Unknown bit count\n")); + error = 1; + } + + gdFree(hdr); + gdFree(info); + + if (error) { + gdImageDestroy(im); + return NULL; + } + + return im; } static int bmp_read_header(gdIOCtx *infile, bmp_hdr_t *hdr) { - if( - !gdGetWordLSB(&hdr->magic, infile) || - !gdGetIntLSB(&hdr->size, infile) || - !gdGetWordLSB(&hdr->reserved1, infile) || - !gdGetWordLSB(&hdr->reserved2 , infile) || - !gdGetIntLSB(&hdr->off , infile) - ) { - return 1; - } - return 0; + if (!gdGetWordLSB(&hdr->magic, infile) || !gdGetIntLSB(&hdr->size, infile) || + !gdGetWordLSB(&hdr->reserved1, infile) || !gdGetWordLSB(&hdr->reserved2, infile) || + !gdGetIntLSB(&hdr->off, infile)) { + return 1; + } + return 0; } static int bmp_read_info(gdIOCtx *infile, bmp_info_t *info) { - /* read BMP length so we can work out the version */ - if (!gdGetIntLSB(&info->len, infile)) { - return 1; - } - - switch (info->len) { - /* For now treat Windows v4 + v5 as v3 */ - case BMP_WINDOWS_V3: - case BMP_WINDOWS_V4: - case BMP_WINDOWS_V5: - BMP_DEBUG(printf("Reading Windows Header\n")); - if (bmp_read_windows_v3_info(infile, info)) { - return 1; - } - break; - case BMP_OS2_V1: - if (bmp_read_os2_v1_info(infile, info)) { - return 1; - } - break; - case BMP_OS2_V2: - if (bmp_read_os2_v2_info(infile, info)) { - return 1; - } - break; - default: - BMP_DEBUG(printf("Unhandled bitmap\n")); - return 1; - } - return 0; + /* read BMP length so we can work out the version */ + if (!gdGetIntLSB(&info->len, infile)) { + return 1; + } + + switch (info->len) { + /* For now treat Windows v4 + v5 as v3 */ + case BMP_WINDOWS_V3: + case BMP_WINDOWS_V2: + case BMP_WINDOWS_V3_ALPHA: + case BMP_WINDOWS_V4: + case BMP_WINDOWS_V5: + BMP_DEBUG(printf("Reading Windows Header\n")); + if (bmp_read_windows_v3_info(infile, info)) { + return 1; + } + break; + case BMP_OS2_V1: + if (bmp_read_os2_v1_info(infile, info)) { + return 1; + } + break; + case BMP_OS2_V2_SHORT: + case BMP_OS2_V2: + if (bmp_read_os2_v2_info(infile, info)) { + return 1; + } + break; + default: + BMP_DEBUG(printf("Unhandled bitmap\n")); + return 1; + } + return 0; +} + +static int bmp_skip_bytes(gdIOCtxPtr infile, int count) +{ + int i, c; + + for (i = 0; i < count; i++) { + if (!gdGetByte(&c, infile)) { + return 1; + } + } + return 0; +} + +static int bmp_read_bitfield_masks(gdIOCtxPtr infile, bmp_info_t *info, int read_alpha) +{ + int red, green, blue, alpha; + + if (!gdGetIntLSB(&red, infile) || !gdGetIntLSB(&green, infile) || !gdGetIntLSB(&blue, infile)) { + return 1; + } + + info->red_mask = (unsigned int)red; + info->green_mask = (unsigned int)green; + info->blue_mask = (unsigned int)blue; + + if (read_alpha) { + if (!gdGetIntLSB(&alpha, infile)) { + return 1; + } + info->alpha_mask = (unsigned int)alpha; + } + + return 0; +} + +static int bmp_validate_info(bmp_info_t *info, bmp_hdr_t *hdr) +{ + int image_size; + int min_size; + + if (hdr->off < 14 + info->len || hdr->size < 0 || hdr->off < 0) { + return 1; + } + + if (info->numplanes != 1) { + return 1; + } + + if (info->depth != 1 && info->depth != 2 && info->depth != 4 && info->depth != 8 && + info->depth != 16 && info->depth != 24 && info->depth != 32) { + return 1; + } + + if (info->topdown && (info->enctype == BMP_BI_RLE4 || info->enctype == BMP_BI_RLE8)) { + return 1; + } + + if (overflow2(info->width, info->height)) { + return 1; + } + + if (info->hres < 0 || info->vres < 0) { + return 1; + } + if (info->hres > 0 && info->vres > 0 && + (info->hres / info->vres > 1000 || info->vres / info->hres > 1000)) { + return 1; + } + + if (info->enctype == BMP_BI_RGB || info->enctype == BMP_BI_BITFIELDS || + info->enctype == BMP_BI_ALPHABITFIELDS) { + if (bmp_image_size(info->width, info->height, info->depth, &image_size)) { + return 1; + } + if (info->size != 0 && info->size != image_size) { + return 1; + } + if (hdr->size != 0) { + min_size = hdr->off + image_size; + if (min_size < hdr->off) { + return 1; + } + if (hdr->size < min_size && hdr->size != 14 + info->len) { + return 1; + } + if (hdr->size > min_size && hdr->size - min_size > 1024 * 1024) { + return 1; + } + } + } + + return 0; } static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info) { - if ( - !gdGetIntLSB(&info->width, infile) || - !gdGetIntLSB(&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) || - !gdGetIntLSB(&info->enctype, infile) || - !gdGetIntLSB(&info->size, infile) || - !gdGetIntLSB(&info->hres, infile) || - !gdGetIntLSB(&info->vres, infile) || - !gdGetIntLSB(&info->numcolors, infile) || - !gdGetIntLSB(&info->mincolors, infile) - ) { - return 1; - } - - if (info->height < 0) { - info->topdown = 1; - info->height = -info->height; - } else { - info->topdown = 0; - } - - info->type = BMP_PALETTE_4; - - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { - return 1; - } - - return 0; + int extra = info->len - BMP_WINDOWS_V3; + + if (!gdGetIntLSB(&info->width, infile) || !gdGetIntLSB(&info->height, infile) || + !gdGetWordLSB(&info->numplanes, infile) || !gdGetWordLSB(&info->depth, infile) || + !gdGetIntLSB(&info->enctype, infile) || !gdGetIntLSB(&info->size, infile) || + !gdGetIntLSB(&info->hres, infile) || !gdGetIntLSB(&info->vres, infile) || + !gdGetIntLSB(&info->numcolors, infile) || !gdGetIntLSB(&info->mincolors, infile)) { + return 1; + } + + /* Unlikely, but possible -- largest signed value won't fit in unsigned. */ + if (info->height == 0 || info->height == INT_MIN) + return 1; + if (info->height < 0) { + info->topdown = 1; + info->height = -info->height; + } else { + info->topdown = 0; + } + + info->type = BMP_PALETTE_4; + + if (extra > 0) { + if (extra < 12 || bmp_read_bitfield_masks(infile, info, extra >= 16)) { + return 1; + } + extra -= (extra >= 16) ? 16 : 12; + if (bmp_skip_bytes(infile, extra)) { + return 1; + } + } + + /* Height was checked above. */ + if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 || info->numcolors < 0 || + info->mincolors < 0) { + return 1; + } + + return 0; } static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info) { - if ( - !gdGetWordLSB((signed short int *)&info->width, infile) || - !gdGetWordLSB((signed short int *)&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) - ) { - return 1; - } - - /* OS2 v1 doesn't support topdown */ - info->topdown = 0; - - info->numcolors = 1 << info->depth; - info->type = BMP_PALETTE_3; - - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0) { - return 1; - } - - return 0; + if (!gdGetWordLSB((signed short int *)&info->width, infile) || + !gdGetWordLSB((signed short int *)&info->height, infile) || + !gdGetWordLSB(&info->numplanes, infile) || !gdGetWordLSB(&info->depth, infile)) { + return 1; + } + + /* OS2 v1 doesn't support topdown */ + info->topdown = 0; + + /* The spec says the depth can only be a few value values. */ + if (info->depth != 1 && info->depth != 4 && info->depth != 8 && info->depth != 16 && + info->depth != 24) { + return 1; + } + + info->numcolors = (info->depth <= 8) ? (1 << info->depth) : 0; + info->type = BMP_PALETTE_3; + + if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0) { + return 1; + } + + return 0; } static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info) { - char useless_bytes[24]; - if ( - !gdGetIntLSB(&info->width, infile) || - !gdGetIntLSB(&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) || - !gdGetIntLSB(&info->enctype, infile) || - !gdGetIntLSB(&info->size, infile) || - !gdGetIntLSB(&info->hres, infile) || - !gdGetIntLSB(&info->vres, infile) || - !gdGetIntLSB(&info->numcolors, infile) || - !gdGetIntLSB(&info->mincolors, infile) - ) { - return 1; - } - - /* Let's seek the next 24 pointless bytes, we don't care too much about it */ - if (!gdGetBuf(useless_bytes, 24, infile)) { - return 1; - } - - if (info->height < 0) { - info->topdown = 1; - info->height = -info->height; - } else { - info->topdown = 0; - } - - info->type = BMP_PALETTE_4; - - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { - return 1; - } - - - return 0; + char useless_bytes[24]; + if (!gdGetIntLSB(&info->width, infile) || !gdGetIntLSB(&info->height, infile) || + !gdGetWordLSB(&info->numplanes, infile) || !gdGetWordLSB(&info->depth, infile)) { + return 1; + } + + if (info->len == BMP_OS2_V2_SHORT) { + info->enctype = BMP_BI_RGB; + info->size = 0; + info->hres = 0; + info->vres = 0; + info->numcolors = (info->depth <= 8) ? (1 << info->depth) : 0; + info->mincolors = 0; + goto done; + } + + if (!gdGetIntLSB(&info->enctype, infile) || !gdGetIntLSB(&info->size, infile) || + !gdGetIntLSB(&info->hres, infile) || !gdGetIntLSB(&info->vres, infile) || + !gdGetIntLSB(&info->numcolors, infile) || !gdGetIntLSB(&info->mincolors, infile)) { + return 1; + } + + /* Lets seek the next 24 pointless bytes, we don't care too much about it */ + if (!gdGetBuf(useless_bytes, 24, infile)) { + return 1; + } + +done: + /* Unlikely, but possible -- largest signed value won't fit in unsigned. */ + if (info->height == 0 || info->height == INT_MIN) + return 1; + if (info->height < 0) { + info->topdown = 1; + info->height = -info->height; + } else { + info->topdown = 0; + } + + info->type = BMP_PALETTE_4; + + /* Height was checked above. */ + if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 || info->numcolors < 0 || + info->mincolors < 0) { + return 1; + } + + return 0; } static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) { - int ypos = 0, xpos = 0, row = 0; - int padding = 0, alpha = 0, red = 0, green = 0, blue = 0; - signed short int data = 0; - - switch(info->enctype) { - case BMP_BI_RGB: - /* no-op */ - break; - - case BMP_BI_BITFIELDS: - if (info->depth == 24) { - BMP_DEBUG(printf("Bitfield compression isn't supported for 24-bit\n")); - return 1; - } - BMP_DEBUG(printf("Currently no bitfield support\n")); - return 1; - break; - - case BMP_BI_RLE8: - if (info->depth != 8) { - BMP_DEBUG(printf("RLE is only valid for 8-bit images\n")); - return 1; - } - break; - case BMP_BI_RLE4: - if (info->depth != 4) { - BMP_DEBUG(printf("RLE is only valid for 4-bit images\n")); - return 1; - } - break; - case BMP_BI_JPEG: - case BMP_BI_PNG: - default: - BMP_DEBUG(printf("Unsupported BMP compression format\n")); - return 1; - } - - /* There is a chance the data isn't until later, would be weird but it is possible */ - if (gdTell(infile) != header->off) { - /* Should make sure we don't seek past the file size */ - if (!gdSeek(infile, header->off)) { - return 1; - } - } - - /* The line must be divisible by 4, else it's padded with NULLs */ - padding = ((int)(info->depth / 8) * info->width) % 4; - if (padding) { - padding = 4 - padding; - } - - - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos++) { - if (info->depth == 16) { - if (!gdGetWordLSB(&data, infile)) { - return 1; - } - BMP_DEBUG(printf("Data: %X\n", data)); - red = ((data & 0x7C00) >> 10) << 3; - green = ((data & 0x3E0) >> 5) << 3; - blue = (data & 0x1F) << 3; - BMP_DEBUG(printf("R: %d, G: %d, B: %d\n", red, green, blue)); - } else if (info->depth == 24) { - if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile)) { - return 1; - } - } else { - if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile) || !gdGetByte(&alpha, infile)) { - return 1; - } - } - /*alpha = gdAlphaMax - (alpha >> 1);*/ - gdImageSetPixel(im, xpos, row, gdTrueColor(red, green, blue)); - } - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&red, infile)) { - return 1; - } - } - } - - return 0; + int ypos = 0, xpos = 0, row = 0; + int padding = 0, red = 0, green = 0, blue = 0; + int alpha = gdAlphaOpaque; + signed short int data16 = 0; + int data32 = 0; + unsigned int mask = 0; + + if (info->depth == 16 && info->enctype == BMP_BI_RGB) { + info->red_mask = 0x7C00; + info->green_mask = 0x03E0; + info->blue_mask = 0x001F; + } else if (info->depth == 32 && info->enctype == BMP_BI_RGB) { + info->red_mask = 0x00FF0000; + info->green_mask = 0x0000FF00; + info->blue_mask = 0x000000FF; + } + + switch (info->enctype) { + case BMP_BI_RGB: + /* no-op */ + break; + + case BMP_BI_BITFIELDS: + if (info->depth == 24) { + BMP_DEBUG(printf("Bitfield compression isn't supported for 24-bit\n")); + return 1; + } + if (info->len == BMP_WINDOWS_V3 && bmp_read_bitfield_masks(infile, info, 0)) { + return 1; + } + break; + case BMP_BI_ALPHABITFIELDS: + if (info->depth != 16 && info->depth != 32) { + return 1; + } + if (info->len == BMP_WINDOWS_V3 && bmp_read_bitfield_masks(infile, info, 1)) { + return 1; + } + break; + + case BMP_BI_RLE8: + if (info->depth != 8) { + BMP_DEBUG(printf("RLE is only valid for 8-bit images\n")); + return 1; + } + break; + case BMP_BI_RLE4: + if (info->depth != 4) { + BMP_DEBUG(printf("RLE is only valid for 4-bit images\n")); + return 1; + } + break; + case BMP_BI_JPEG: + case BMP_BI_PNG: + default: + BMP_DEBUG(printf("Unsupported BMP compression format\n")); + return 1; + } + + if (info->depth == 16 || info->depth == 32) { + mask = info->red_mask | info->green_mask | info->blue_mask; + if (info->red_mask == 0 || info->green_mask == 0 || info->blue_mask == 0) { + return 1; + } + if ((info->red_mask & info->green_mask) || (info->red_mask & info->blue_mask) || + (info->green_mask & info->blue_mask)) { + return 1; + } + if (info->depth == 16 && (mask & 0xFFFF0000U)) { + return 1; + } + } + + /* There is a chance the data isn't until later, would be weird but it is + * possible */ + if (gdTell(infile) != header->off) { + /* Should make sure we don't seek past the file size */ + if (!gdSeek(infile, header->off)) { + return 1; + } + } + + /* The line must be divisible by 4, else its padded with NULLs */ + if (bmp_row_padding(info->width, info->depth, &padding)) { + return 1; + } + + for (ypos = 0; ypos < info->height; ++ypos) { + if (info->topdown) { + row = ypos; + } else { + row = info->height - ypos - 1; + } + + for (xpos = 0; xpos < info->width; xpos++) { + if (info->depth == 16) { + if (!gdGetWordLSB(&data16, infile)) { + return 1; + } + BMP_DEBUG(printf("Data: %X\n", data16)); + red = bmp_extract_mask((unsigned short)data16, info->red_mask); + green = bmp_extract_mask((unsigned short)data16, info->green_mask); + blue = bmp_extract_mask((unsigned short)data16, info->blue_mask); + alpha = info->alpha_mask ? bmp_alpha_to_gd(bmp_extract_mask((unsigned short)data16, + info->alpha_mask)) + : gdAlphaOpaque; + BMP_DEBUG(printf("R: %d, G: %d, B: %d\n", red, green, blue)); + } else if (info->depth == 24) { + if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || + !gdGetByte(&red, infile)) { + return 1; + } + alpha = gdAlphaOpaque; + } else { + if (!gdGetIntLSB(&data32, infile)) { + return 1; + } + red = bmp_extract_mask((unsigned int)data32, info->red_mask); + green = bmp_extract_mask((unsigned int)data32, info->green_mask); + blue = bmp_extract_mask((unsigned int)data32, info->blue_mask); + alpha = + info->alpha_mask + ? bmp_alpha_to_gd(bmp_extract_mask((unsigned int)data32, info->alpha_mask)) + : gdAlphaOpaque; + } + gdImageSetPixel(im, xpos, row, gdTrueColorAlpha(red, green, blue, alpha)); + } + for (xpos = padding; xpos > 0; --xpos) { + if (!gdGetByte(&red, infile)) { + return 1; + } + } + } + + return 0; } static int bmp_read_palette(gdImagePtr im, gdIOCtxPtr infile, int count, int read_four) { - int i; - int r, g, b, z; - - for (i = 0; i < count; i++) { - if ( - !gdGetByte(&b, infile) || - !gdGetByte(&g, infile) || - !gdGetByte(&r, infile) || - (read_four && !gdGetByte(&z, infile)) - ) { - return 1; - } - im->red[i] = r; - im->green[i] = g; - im->blue[i] = b; - im->open[i] = 1; - } - return 0; + int i; + int r, g, b, z; + + for (i = 0; i < count; i++) { + if (!gdGetByte(&b, infile) || !gdGetByte(&g, infile) || !gdGetByte(&r, infile) || + (read_four && !gdGetByte(&z, infile))) { + return 1; + } + im->red[i] = r; + im->green[i] = g; + im->blue[i] = b; + im->open[i] = 1; + } + return 0; +} + +static int bmp_check_palette_index(gdImagePtr im, int index) +{ + return index >= 0 && index < im->colorsTotal; +} + +static int bmp_row_padding(int width, int depth, int *padding) +{ + int bits_per_row; + int bytes_per_row; + + if (overflow2(width, depth)) { + return 1; + } + bits_per_row = width * depth; + if (bits_per_row > INT_MAX - 31) { + return 1; + } + bytes_per_row = ((bits_per_row + 31) / 32) * 4; + *padding = bytes_per_row - ((bits_per_row + 7) / 8); + return 0; +} + +static int bmp_image_size(int width, int height, int depth, int *size) +{ + int bits_per_row; + int bytes_per_row; + + if (overflow2(width, depth)) { + return 1; + } + bits_per_row = width * depth; + if (bits_per_row > INT_MAX - 31) { + return 1; + } + bytes_per_row = ((bits_per_row + 31) / 32) * 4; + if (overflow2(bytes_per_row, height)) { + return 1; + } + *size = bytes_per_row * height; + return 0; +} + +static int bmp_get_mask_shift(unsigned int mask) +{ + int shift = 0; + + if (mask == 0) { + return 0; + } + while ((mask & 1U) == 0) { + mask >>= 1; + shift++; + } + return shift; +} + +static int bmp_get_mask_bits(unsigned int mask) +{ + int bits = 0; + + if (mask == 0) { + return 0; + } + mask >>= bmp_get_mask_shift(mask); + while (mask & 1U) { + bits++; + mask >>= 1; + } + return bits; +} + +static int bmp_extract_mask(unsigned int pixel, unsigned int mask) +{ + unsigned int value; + int bits; + + if (mask == 0) { + return 0; + } + value = (pixel & mask) >> bmp_get_mask_shift(mask); + bits = bmp_get_mask_bits(mask); + if (bits <= 0) { + return 0; + } + if (bits >= 32) { + return (int)(value >> 24); + } + if (bits >= 8) { + return (int)((value * 255U) / ((1U << bits) - 1U)); + } + return (int)((value * 255U + ((1U << bits) - 1U) / 2U) / ((1U << bits) - 1U)); +} + +static unsigned int bmp_pack_mask(int channel_8bit, unsigned int mask) +{ + int bits; + int shift; + unsigned int max_val; + unsigned int value; + + if (mask == 0) { + return 0; + } + bits = bmp_get_mask_bits(mask); + shift = bmp_get_mask_shift(mask); + if (bits <= 0) { + return 0; + } + if (bits >= 32) { + value = (unsigned int)channel_8bit << 24; + } else { + max_val = (1U << bits) - 1U; + value = ((unsigned int)channel_8bit * max_val + 127U) / 255U; + } + return (value << shift) & mask; +} + +static int bmp_alpha_to_gd(int alpha) +{ + if (alpha <= 0) { + return gdAlphaTransparent; + } + if (alpha >= 255) { + return gdAlphaOpaque; + } + return gdAlphaMax - (alpha * gdAlphaMax + 127) / 255; +} + +static int bmp_gd_to_alpha(int gd_alpha) +{ + if (gd_alpha <= gdAlphaOpaque) { + return 255; + } + if (gd_alpha >= gdAlphaTransparent) { + return 0; + } + return (gdAlphaMax - gd_alpha) * 255 / gdAlphaMax; } static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) { - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0, current_byte = 0, bit = 0; - - if (info->enctype != BMP_BI_RGB) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 2; - } else if (info->numcolors < 0 || info->numcolors > 2) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be weird but it is possible */ - if (gdTell(infile) != header->off) { - /* Should make sure we don't seek past the file size */ - if (!gdSeek(infile, header->off)) { - return 1; - } - } - - /* The line must be aligned on a 32 bits word, else it is padded with zeros */ - padding = (info->width + 7) / 8 % 4; - if (padding) { - padding = 4 - padding; - } - - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos += 8) { - /* Bitmaps are always aligned in bytes so we'll never overflow */ - if (!gdGetByte(¤t_byte, infile)) { - return 1; - } - - for (bit = 0; bit < 8; bit++) { - index = ((current_byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00); - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos + bit, row, index); - /* No need to read anything extra */ - if ((xpos + bit) >= info->width) { - break; - } - } - } - - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - return 0; + int ypos = 0, xpos = 0, row = 0, index = 0; + int padding = 0, current_byte = 0, bit = 0; + + if (info->enctype != BMP_BI_RGB) { + return 1; + } + + if (!info->numcolors) { + info->numcolors = 2; + } else if (info->numcolors < 0 || info->numcolors > 2) { + return 1; + } + + if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { + return 1; + } + + im->colorsTotal = info->numcolors; + + /* There is a chance the data isn't until later, would be weird but it is + * possible */ + if (gdTell(infile) != header->off) { + /* Should make sure we don't seek past the file size */ + if (!gdSeek(infile, header->off)) { + return 1; + } + } + + if (bmp_row_padding(info->width, info->depth, &padding)) { + return 1; + } + + for (ypos = 0; ypos < info->height; ++ypos) { + if (info->topdown) { + row = ypos; + } else { + row = info->height - ypos - 1; + } + + for (xpos = 0; xpos < info->width; xpos += 8) { + /* Bitmaps are always aligned in bytes so we'll never overflow */ + if (!gdGetByte(¤t_byte, infile)) { + return 1; + } + + for (bit = 0; bit < 8; bit++) { + index = ((current_byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00); + /* No need to read anything extra */ + if ((xpos + bit) >= info->width) { + break; + } + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos + bit, row, index); + } + } + + for (xpos = padding; xpos > 0; --xpos) { + if (!gdGetByte(&index, infile)) { + return 1; + } + } + } + return 0; +} + +static int bmp_read_2bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) +{ + int ypos = 0, xpos = 0, row = 0, index = 0; + int padding = 0, current_byte = 0, shift = 0; + + if (info->enctype != BMP_BI_RGB) { + return 1; + } + + if (!info->numcolors) { + info->numcolors = 4; + } else if (info->numcolors < 0 || info->numcolors > 4) { + return 1; + } + + if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { + return 1; + } + + im->colorsTotal = info->numcolors; + + if (gdTell(infile) != header->off) { + if (!gdSeek(infile, header->off)) { + return 1; + } + } + + if (bmp_row_padding(info->width, info->depth, &padding)) { + return 1; + } + + for (ypos = 0; ypos < info->height; ++ypos) { + if (info->topdown) { + row = ypos; + } else { + row = info->height - ypos - 1; + } + + for (xpos = 0; xpos < info->width; xpos += 4) { + if (!gdGetByte(¤t_byte, infile)) { + return 1; + } + + for (shift = 6; shift >= 0; shift -= 2) { + if (xpos + ((6 - shift) / 2) >= info->width) { + break; + } + index = (current_byte >> shift) & 0x03; + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos + ((6 - shift) / 2), row, index); + } + } + + for (xpos = padding; xpos > 0; --xpos) { + if (!gdGetByte(&index, infile)) { + return 1; + } + } + } + return 0; } static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) { - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0, current_byte = 0; - - if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE4) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 16; - } else if (info->numcolors < 0 || info->numcolors > 16) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be weird but it is possible */ - if (gdTell(infile) != header->off) { - /* Should make sure we don't seek past the file size */ - if (!gdSeek(infile, header->off)) { - return 1; - } - } - - /* The line must be divisible by 4, else it's padded with NULLs */ - padding = ((int)ceil(0.5 * info->width)) % 4; - if (padding) { - padding = 4 - padding; - } - - switch (info->enctype) { - case BMP_BI_RGB: - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos += 2) { - if (!gdGetByte(¤t_byte, infile)) { - return 1; - } - - index = (current_byte >> 4) & 0x0f; - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - - /* This condition may get called often, potential optimsations */ - if (xpos >= info->width) { - break; - } - - index = current_byte & 0x0f; - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos + 1, row, index); - } - - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - break; - - case BMP_BI_RLE4: - if (bmp_read_rle(im, infile, info)) { - return 1; - } - break; - - default: - return 1; - } - return 0; + int ypos = 0, xpos = 0, row = 0, index = 0; + int padding = 0, current_byte = 0; + + if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE4) { + return 1; + } + + if (!info->numcolors) { + info->numcolors = 16; + } else if (info->numcolors < 0 || info->numcolors > 16) { + return 1; + } + + if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { + return 1; + } + + im->colorsTotal = info->numcolors; + + /* There is a chance the data isn't until later, would be weird but it is + * possible */ + if (gdTell(infile) != header->off) { + /* Should make sure we don't seek past the file size */ + if (!gdSeek(infile, header->off)) { + return 1; + } + } + + if (bmp_row_padding(info->width, info->depth, &padding)) { + return 1; + } + + switch (info->enctype) { + case BMP_BI_RGB: + for (ypos = 0; ypos < info->height; ++ypos) { + if (info->topdown) { + row = ypos; + } else { + row = info->height - ypos - 1; + } + + for (xpos = 0; xpos < info->width; xpos += 2) { + if (!gdGetByte(¤t_byte, infile)) { + return 1; + } + + index = (current_byte >> 4) & 0x0f; + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos, row, index); + + /* This condition may get called often, potential optimsations + */ + if (xpos + 1 >= info->width) { + break; + } + + index = current_byte & 0x0f; + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos + 1, row, index); + } + + for (xpos = padding; xpos > 0; --xpos) { + if (!gdGetByte(&index, infile)) { + return 1; + } + } + } + break; + + case BMP_BI_RLE4: + if (bmp_read_rle(im, infile, info)) { + return 1; + } + break; + + default: + return 1; + } + return 0; } static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) { - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0; - - if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE8) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 256; - } else if (info->numcolors < 0 || info->numcolors > 256) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be weird but it is possible */ - if (gdTell(infile) != header->off) { - /* Should make sure we don't seek past the file size */ - if (!gdSeek(infile, header->off)) { - return 1; - } - } - - /* The line must be divisible by 4, else it's padded with NULLs */ - padding = (1 * info->width) % 4; - if (padding) { - padding = 4 - padding; - } - - switch (info->enctype) { - case BMP_BI_RGB: - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; ++xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - } - /* Could create a new variable, but it isn't really worth it */ - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - break; - - case BMP_BI_RLE8: - if (bmp_read_rle(im, infile, info)) { - return 1; - } - break; - - default: - return 1; - } - return 0; + int ypos = 0, xpos = 0, row = 0, index = 0; + int padding = 0; + int palette_entries = 0; + int palette_entry_size = (info->type == BMP_PALETTE_4) ? 4 : 3; + + if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE8) { + return 1; + } + + if (!info->numcolors) { + info->numcolors = 256; + } else if (info->numcolors < 0 || info->numcolors > 1024) { + return 1; + } + + palette_entries = (header->off - (14 + info->len)) / palette_entry_size; + if (palette_entries <= 0) { + return 1; + } + if (info->numcolors > palette_entries) { + info->numcolors = palette_entries; + } + if (info->numcolors > gdMaxColors) { + info->numcolors = gdMaxColors; + } + + if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { + return 1; + } + + im->colorsTotal = info->numcolors; + + /* There is a chance the data isn't until later, would be weird but it is + * possible */ + if (gdTell(infile) != header->off) { + /* Should make sure we don't seek past the file size */ + if (!gdSeek(infile, header->off)) { + return 1; + } + } + + if (bmp_row_padding(info->width, info->depth, &padding)) { + return 1; + } + + switch (info->enctype) { + case BMP_BI_RGB: + for (ypos = 0; ypos < info->height; ++ypos) { + if (info->topdown) { + row = ypos; + } else { + row = info->height - ypos - 1; + } + + for (xpos = 0; xpos < info->width; ++xpos) { + if (!gdGetByte(&index, infile)) { + return 1; + } + + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos, row, index); + } + /* Could create a new variable, but it isn't really worth it */ + for (xpos = padding; xpos > 0; --xpos) { + if (!gdGetByte(&index, infile)) { + return 1; + } + } + } + break; + + case BMP_BI_RLE8: + if (bmp_read_rle(im, infile, info)) { + return 1; + } + break; + + default: + return 1; + } + return 0; } static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info) { - int ypos = 0, xpos = 0, row = 0, index = 0; - int rle_length = 0, rle_data = 0; - int padding = 0; - int i = 0, j = 0; - int pixels_per_byte = 8 / info->depth; - - for (ypos = 0; ypos < info->height && xpos <= info->width;) { - if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { - return 1; - } - row = info->height - ypos - 1; - - if (rle_length != BMP_RLE_COMMAND) { - if (im->open[rle_data]) { - im->open[rle_data] = 0; - } - - for (i = 0; (i < rle_length) && (xpos < info->width);) { - for (j = 1; (j <= pixels_per_byte) && (xpos < info->width) && (i < rle_length); j++, xpos++, i++) { - index = (rle_data & (((1 << info->depth) - 1) << (8 - (j * info->depth)))) >> (8 - (j * info->depth)); - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - } - } - } else if (rle_length == BMP_RLE_COMMAND && rle_data > 2) { - /* Uncompressed RLE needs to be even */ - padding = 0; - for (i = 0; (i < rle_data) && (xpos < info->width); i += pixels_per_byte) { - int max_pixels = pixels_per_byte; - - if (!gdGetByte(&index, infile)) { - return 1; - } - padding++; - - if (rle_data - i < max_pixels) { - max_pixels = rle_data - i; - } - - for (j = 1; (j <= max_pixels) && (xpos < info->width); j++, xpos++) { - int temp = (index >> (8 - (j * info->depth))) & ((1 << info->depth) - 1); - if (im->open[temp]) { - im->open[temp] = 0; - } - gdImageSetPixel(im, xpos, row, temp); - } - } - - /* Make sure the bytes read are even */ - if (padding % 2 && !gdGetByte(&index, infile)) { - return 1; - } - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFLINE) { - /* Next Line */ - xpos = 0; - ypos++; - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_DELTA) { - /* Delta Record, used for bmp files that contain other data*/ - if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { - return 1; - } - xpos += rle_length; - ypos += rle_data; - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFBITMAP) { - /* End of bitmap */ - break; - } - } - return 0; + int ypos = 0, xpos = 0, row = 0, index = 0; + int rle_length = 0, rle_data = 0; + int padding = 0; + int i = 0, j = 0; + int pixels_per_byte = 8 / info->depth; + + if (info->topdown) { + return 1; + } + + for (ypos = 0; ypos < info->height && xpos <= info->width;) { + if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { + return 1; + } + row = info->height - ypos - 1; + if (row < 0 || row >= info->height) { + return 1; + } + + if (rle_length != BMP_RLE_COMMAND) { + for (i = 0; i < rle_length;) { + for (j = 1; (j <= pixels_per_byte) && (i < rle_length); j++, xpos++, i++) { + index = (rle_data & (((1 << info->depth) - 1) << (8 - (j * info->depth)))) >> + (8 - (j * info->depth)); + if (xpos >= info->width) { + return 1; + } + if (!bmp_check_palette_index(im, index)) { + return 1; + } + if (im->open[index]) { + im->open[index] = 0; + } + gdImageSetPixel(im, xpos, row, index); + } + } + } else if (rle_length == BMP_RLE_COMMAND && rle_data > 2) { + /* Uncompressed RLE needs to be even */ + padding = 0; + for (i = 0; i < rle_data; i += pixels_per_byte) { + int max_pixels = pixels_per_byte; + + if (!gdGetByte(&index, infile)) { + return 1; + } + padding++; + + if (rle_data - i < max_pixels) { + max_pixels = rle_data - i; + } + + for (j = 1; j <= max_pixels; j++) { + int temp = (index >> (8 - (j * info->depth))) & ((1 << info->depth) - 1); + if (xpos >= info->width) { + return 1; + } + if (!bmp_check_palette_index(im, temp)) { + return 1; + } + if (im->open[temp]) { + im->open[temp] = 0; + } + gdImageSetPixel(im, xpos, row, temp); + xpos++; + } + } + + /* Make sure the bytes read are even */ + if (padding % 2 && !gdGetByte(&index, infile)) { + return 1; + } + } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFLINE) { + /* Next Line */ + xpos = 0; + ypos++; + } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_DELTA) { + /* Delta Record, used for bmp files that contain other data*/ + if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { + return 1; + } + if (xpos + rle_length > info->width || ypos + rle_data >= info->height) { + return 1; + } + xpos += rle_length; + ypos += rle_data; + } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFBITMAP) { + /* End of bitmap */ + break; + } + } + return 0; } diff --git a/ext/gd/libgd/gd_color.c b/ext/gd/libgd/gd_color.c new file mode 100644 index 000000000000..88c0cfff3fbf --- /dev/null +++ b/ext/gd/libgd/gd_color.c @@ -0,0 +1,38 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd.h" +#include "gd_color.h" +#define GD_MAX_COLOR_DIST_SQ 260100 + +/** + * The threshold method works relatively well for border cropping purposes. + * A perceptually uniform metric (L*a*b* + Delta-E) would give better + * color discrimination but at significant computational cost per pixel, + * which is hard to justify for this use case. + */ +int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold) +{ + const int dr = gdImageRed(im, col1) - gdImageRed(im, col2); + const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2); + const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2); + const int da = (gdImageAlpha(im, col1) - gdImageAlpha(im, col2)) * 2; + const int dist = dr * dr + dg * dg + db * db + da * da; + + const float t = threshold / 100.0f; + return dist <= (int)(t * t * GD_MAX_COLOR_DIST_SQ); +} + +/* + * To be implemented when we have more image formats. + * Buffer like gray8 gray16 or rgb8 will require some tweak + * and can be done in this function (called from the autocrop + * function. (Pierre) + */ +#if 0 +static int colors_equal (const int col1, const in col2) +{ + +} +#endif diff --git a/ext/gd/libgd/gd_color.h b/ext/gd/libgd/gd_color.h new file mode 100644 index 000000000000..834f45ec8adc --- /dev/null +++ b/ext/gd/libgd/gd_color.h @@ -0,0 +1,14 @@ +#ifndef GD_COLOR_H +#define GD_COLOR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/gd/libgd/gd_color_map.c b/ext/gd/libgd/gd_color_map.c new file mode 100644 index 000000000000..b1785e2eafa3 --- /dev/null +++ b/ext/gd/libgd/gd_color_map.c @@ -0,0 +1,793 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "gd.h" +#include "gd_color_map.h" + +static const gdColorMapEntry GD_COLOR_MAP_X11_ENTRIES[] = { + {"AliceBlue", 240, 248, 255}, + {"AntiqueWhite", 250, 235, 215}, + {"AntiqueWhite1", 255, 239, 219}, + {"AntiqueWhite2", 238, 223, 204}, + {"AntiqueWhite3", 205, 192, 176}, + {"AntiqueWhite4", 139, 131, 120}, + {"BlanchedAlmond", 255, 235, 205}, + {"BlueViolet", 138, 43, 226}, + {"CadetBlue", 95, 158, 160}, + {"CadetBlue1", 152, 245, 255}, + {"CadetBlue2", 142, 229, 238}, + {"CadetBlue3", 122, 197, 205}, + {"CadetBlue4", 83, 134, 139}, + {"CornflowerBlue", 100, 149, 237}, + {"DarkBlue", 0, 0, 139}, + {"DarkCyan", 0, 139, 139}, + {"DarkGoldenrod", 184, 134, 11}, + {"DarkGoldenrod1", 255, 185, 15}, + {"DarkGoldenrod2", 238, 173, 14}, + {"DarkGoldenrod3", 205, 149, 12}, + {"DarkGoldenrod4", 139, 101, 8}, + {"DarkGray", 169, 169, 169}, + {"DarkGreen", 0, 100, 0}, + {"DarkGrey", 169, 169, 169}, + {"DarkKhaki", 189, 183, 107}, + {"DarkMagenta", 139, 0, 139}, + {"DarkOliveGreen", 85, 107, 47}, + {"DarkOliveGreen1", 202, 255, 112}, + {"DarkOliveGreen2", 188, 238, 104}, + {"DarkOliveGreen3", 162, 205, 90}, + {"DarkOliveGreen4", 110, 139, 61}, + {"DarkOrange", 255, 140, 0}, + {"DarkOrange1", 255, 127, 0}, + {"DarkOrange2", 238, 118, 0}, + {"DarkOrange3", 205, 102, 0}, + {"DarkOrange4", 139, 69, 0}, + {"DarkOrchid", 153, 50, 204}, + {"DarkOrchid1", 191, 62, 255}, + {"DarkOrchid2", 178, 58, 238}, + {"DarkOrchid3", 154, 50, 205}, + {"DarkOrchid4", 104, 34, 139}, + {"DarkRed", 139, 0, 0}, + {"DarkSalmon", 233, 150, 122}, + {"DarkSeaGreen", 143, 188, 143}, + {"DarkSeaGreen1", 193, 255, 193}, + {"DarkSeaGreen2", 180, 238, 180}, + {"DarkSeaGreen3", 155, 205, 155}, + {"DarkSeaGreen4", 105, 139, 105}, + {"DarkSlateBlue", 72, 61, 139}, + {"DarkSlateGray", 47, 79, 79}, + {"DarkSlateGray1", 151, 255, 255}, + {"DarkSlateGray2", 141, 238, 238}, + {"DarkSlateGray3", 121, 205, 205}, + {"DarkSlateGray4", 82, 139, 139}, + {"DarkSlateGrey", 47, 79, 79}, + {"DarkTurquoise", 0, 206, 209}, + {"DarkViolet", 148, 0, 211}, + {"DeepPink", 255, 20, 147}, + {"DeepPink1", 255, 20, 147}, + {"DeepPink2", 238, 18, 137}, + {"DeepPink3", 205, 16, 118}, + {"DeepPink4", 139, 10, 80}, + {"DeepSkyBlue", 0, 191, 255}, + {"DeepSkyBlue1", 0, 191, 255}, + {"DeepSkyBlue2", 0, 178, 238}, + {"DeepSkyBlue3", 0, 154, 205}, + {"DeepSkyBlue4", 0, 104, 139}, + {"DimGray", 105, 105, 105}, + {"DimGrey", 105, 105, 105}, + {"DodgerBlue", 30, 144, 255}, + {"DodgerBlue1", 30, 144, 255}, + {"DodgerBlue2", 28, 134, 238}, + {"DodgerBlue3", 24, 116, 205}, + {"DodgerBlue4", 16, 78, 139}, + {"FloralWhite", 255, 250, 240}, + {"ForestGreen", 34, 139, 34}, + {"GhostWhite", 248, 248, 255}, + {"GreenYellow", 173, 255, 47}, + {"HotPink", 255, 105, 180}, + {"HotPink1", 255, 110, 180}, + {"HotPink2", 238, 106, 167}, + {"HotPink3", 205, 96, 144}, + {"HotPink4", 139, 58, 98}, + {"IndianRed", 205, 92, 92}, + {"IndianRed1", 255, 106, 106}, + {"IndianRed2", 238, 99, 99}, + {"IndianRed3", 205, 85, 85}, + {"IndianRed4", 139, 58, 58}, + {"LavenderBlush", 255, 240, 245}, + {"LavenderBlush1", 255, 240, 245}, + {"LavenderBlush2", 238, 224, 229}, + {"LavenderBlush3", 205, 193, 197}, + {"LavenderBlush4", 139, 131, 134}, + {"LawnGreen", 124, 252, 0}, + {"LemonChiffon", 255, 250, 205}, + {"LemonChiffon1", 255, 250, 205}, + {"LemonChiffon2", 238, 233, 191}, + {"LemonChiffon3", 205, 201, 165}, + {"LemonChiffon4", 139, 137, 112}, + {"LightBlue", 173, 216, 230}, + {"LightBlue1", 191, 239, 255}, + {"LightBlue2", 178, 223, 238}, + {"LightBlue3", 154, 192, 205}, + {"LightBlue4", 104, 131, 139}, + {"LightCoral", 240, 128, 128}, + {"LightCyan", 224, 255, 255}, + {"LightCyan1", 224, 255, 255}, + {"LightCyan2", 209, 238, 238}, + {"LightCyan3", 180, 205, 205}, + {"LightCyan4", 122, 139, 139}, + {"LightGoldenrod", 238, 221, 130}, + {"LightGoldenrod1", 255, 236, 139}, + {"LightGoldenrod2", 238, 220, 130}, + {"LightGoldenrod3", 205, 190, 112}, + {"LightGoldenrod4", 139, 129, 76}, + {"LightGoldenrodYellow", 250, 250, 210}, + {"LightGray", 211, 211, 211}, + {"LightGreen", 144, 238, 144}, + {"LightGrey", 211, 211, 211}, + {"LightPink", 255, 182, 193}, + {"LightPink1", 255, 174, 185}, + {"LightPink2", 238, 162, 173}, + {"LightPink3", 205, 140, 149}, + {"LightPink4", 139, 95, 101}, + {"LightSalmon", 255, 160, 122}, + {"LightSalmon1", 255, 160, 122}, + {"LightSalmon2", 238, 149, 114}, + {"LightSalmon3", 205, 129, 98}, + {"LightSalmon4", 139, 87, 66}, + {"LightSeaGreen", 32, 178, 170}, + {"LightSkyBlue", 135, 206, 250}, + {"LightSkyBlue1", 176, 226, 255}, + {"LightSkyBlue2", 164, 211, 238}, + {"LightSkyBlue3", 141, 182, 205}, + {"LightSkyBlue4", 96, 123, 139}, + {"LightSlateBlue", 132, 112, 255}, + {"LightSlateGray", 119, 136, 153}, + {"LightSlateGrey", 119, 136, 153}, + {"LightSteelBlue", 176, 196, 222}, + {"LightSteelBlue1", 202, 225, 255}, + {"LightSteelBlue2", 188, 210, 238}, + {"LightSteelBlue3", 162, 181, 205}, + {"LightSteelBlue4", 110, 123, 139}, + {"LightYellow", 255, 255, 224}, + {"LightYellow1", 255, 255, 224}, + {"LightYellow2", 238, 238, 209}, + {"LightYellow3", 205, 205, 180}, + {"LightYellow4", 139, 139, 122}, + {"LimeGreen", 50, 205, 50}, + {"MediumAquamarine", 102, 205, 170}, + {"MediumBlue", 0, 0, 205}, + {"MediumOrchid", 186, 85, 211}, + {"MediumOrchid1", 224, 102, 255}, + {"MediumOrchid2", 209, 95, 238}, + {"MediumOrchid3", 180, 82, 205}, + {"MediumOrchid4", 122, 55, 139}, + {"MediumPurple", 147, 112, 219}, + {"MediumPurple1", 171, 130, 255}, + {"MediumPurple2", 159, 121, 238}, + {"MediumPurple3", 137, 104, 205}, + {"MediumPurple4", 93, 71, 139}, + {"MediumSeaGreen", 60, 179, 113}, + {"MediumSlateBlue", 123, 104, 238}, + {"MediumSpringGreen", 0, 250, 154}, + {"MediumTurquoise", 72, 209, 204}, + {"MediumVioletRed", 199, 21, 133}, + {"MidnightBlue", 25, 25, 112}, + {"MintCream", 245, 255, 250}, + {"MistyRose", 255, 228, 225}, + {"MistyRose1", 255, 228, 225}, + {"MistyRose2", 238, 213, 210}, + {"MistyRose3", 205, 183, 181}, + {"MistyRose4", 139, 125, 123}, + {"NavajoWhite", 255, 222, 173}, + {"NavajoWhite1", 255, 222, 173}, + {"NavajoWhite2", 238, 207, 161}, + {"NavajoWhite3", 205, 179, 139}, + {"NavajoWhite4", 139, 121, 94}, + {"NavyBlue", 0, 0, 128}, + {"OldLace", 253, 245, 230}, + {"OliveDrab", 107, 142, 35}, + {"OliveDrab1", 192, 255, 62}, + {"OliveDrab2", 179, 238, 58}, + {"OliveDrab3", 154, 205, 50}, + {"OliveDrab4", 105, 139, 34}, + {"OrangeRed", 255, 69, 0}, + {"OrangeRed1", 255, 69, 0}, + {"OrangeRed2", 238, 64, 0}, + {"OrangeRed3", 205, 55, 0}, + {"OrangeRed4", 139, 37, 0}, + {"PaleGoldenrod", 238, 232, 170}, + {"PaleGreen", 152, 251, 152}, + {"PaleGreen1", 154, 255, 154}, + {"PaleGreen2", 144, 238, 144}, + {"PaleGreen3", 124, 205, 124}, + {"PaleGreen4", 84, 139, 84}, + {"PaleTurquoise", 175, 238, 238}, + {"PaleTurquoise1", 187, 255, 255}, + {"PaleTurquoise2", 174, 238, 238}, + {"PaleTurquoise3", 150, 205, 205}, + {"PaleTurquoise4", 102, 139, 139}, + {"PaleVioletRed", 219, 112, 147}, + {"PaleVioletRed1", 255, 130, 171}, + {"PaleVioletRed2", 238, 121, 159}, + {"PaleVioletRed3", 205, 104, 137}, + {"PaleVioletRed4", 139, 71, 93}, + {"PapayaWhip", 255, 239, 213}, + {"PeachPuff", 255, 218, 185}, + {"PeachPuff1", 255, 218, 185}, + {"PeachPuff2", 238, 203, 173}, + {"PeachPuff3", 205, 175, 149}, + {"PeachPuff4", 139, 119, 101}, + {"PowderBlue", 176, 224, 230}, + {"RosyBrown", 188, 143, 143}, + {"RosyBrown1", 255, 193, 193}, + {"RosyBrown2", 238, 180, 180}, + {"RosyBrown3", 205, 155, 155}, + {"RosyBrown4", 139, 105, 105}, + {"RoyalBlue", 65, 105, 225}, + {"RoyalBlue1", 72, 118, 255}, + {"RoyalBlue2", 67, 110, 238}, + {"RoyalBlue3", 58, 95, 205}, + {"RoyalBlue4", 39, 64, 139}, + {"SaddleBrown", 139, 69, 19}, + {"SandyBrown", 244, 164, 96}, + {"SeaGreen", 46, 139, 87}, + {"SeaGreen1", 84, 255, 159}, + {"SeaGreen2", 78, 238, 148}, + {"SeaGreen3", 67, 205, 128}, + {"SeaGreen4", 46, 139, 87}, + {"SkyBlue", 135, 206, 235}, + {"SkyBlue1", 135, 206, 255}, + {"SkyBlue2", 126, 192, 238}, + {"SkyBlue3", 108, 166, 205}, + {"SkyBlue4", 74, 112, 139}, + {"SlateBlue", 106, 90, 205}, + {"SlateBlue1", 131, 111, 255}, + {"SlateBlue2", 122, 103, 238}, + {"SlateBlue3", 105, 89, 205}, + {"SlateBlue4", 71, 60, 139}, + {"SlateGray", 112, 128, 144}, + {"SlateGray1", 198, 226, 255}, + {"SlateGray2", 185, 211, 238}, + {"SlateGray3", 159, 182, 205}, + {"SlateGray4", 108, 123, 139}, + {"SlateGrey", 112, 128, 144}, + {"SpringGreen", 0, 255, 127}, + {"SpringGreen1", 0, 255, 127}, + {"SpringGreen2", 0, 238, 118}, + {"SpringGreen3", 0, 205, 102}, + {"SpringGreen4", 0, 139, 69}, + {"SteelBlue", 70, 130, 180}, + {"SteelBlue1", 99, 184, 255}, + {"SteelBlue2", 92, 172, 238}, + {"SteelBlue3", 79, 148, 205}, + {"SteelBlue4", 54, 100, 139}, + {"VioletRed", 208, 32, 144}, + {"VioletRed1", 255, 62, 150}, + {"VioletRed2", 238, 58, 140}, + {"VioletRed3", 205, 50, 120}, + {"VioletRed4", 139, 34, 82}, + {"WhiteSmoke", 245, 245, 245}, + {"YellowGreen", 154, 205, 50}, + {"alice blue", 240, 248, 255}, + {"antique white", 250, 235, 215}, + {"aquamarine", 127, 255, 212}, + {"aquamarine1", 127, 255, 212}, + {"aquamarine2", 118, 238, 198}, + {"aquamarine3", 102, 205, 170}, + {"aquamarine4", 69, 139, 116}, + {"azure", 240, 255, 255}, + {"azure1", 240, 255, 255}, + {"azure2", 224, 238, 238}, + {"azure3", 193, 205, 205}, + {"azure4", 131, 139, 139}, + {"beige", 245, 245, 220}, + {"bisque", 255, 228, 196}, + {"bisque1", 255, 228, 196}, + {"bisque2", 238, 213, 183}, + {"bisque3", 205, 183, 158}, + {"bisque4", 139, 125, 107}, + {"black", 0, 0, 0}, + {"blanched almond", 255, 235, 205}, + {"blue", 0, 0, 255}, + {"blue violet", 138, 43, 226}, + {"blue1", 0, 0, 255}, + {"blue2", 0, 0, 238}, + {"blue3", 0, 0, 205}, + {"blue4", 0, 0, 139}, + {"brown", 165, 42, 42}, + {"brown1", 255, 64, 64}, + {"brown2", 238, 59, 59}, + {"brown3", 205, 51, 51}, + {"brown4", 139, 35, 35}, + {"burlywood", 222, 184, 135}, + {"burlywood1", 255, 211, 155}, + {"burlywood2", 238, 197, 145}, + {"burlywood3", 205, 170, 125}, + {"burlywood4", 139, 115, 85}, + {"cadet blue", 95, 158, 160}, + {"chartreuse", 127, 255, 0}, + {"chartreuse1", 127, 255, 0}, + {"chartreuse2", 118, 238, 0}, + {"chartreuse3", 102, 205, 0}, + {"chartreuse4", 69, 139, 0}, + {"chocolate", 210, 105, 30}, + {"chocolate1", 255, 127, 36}, + {"chocolate2", 238, 118, 33}, + {"chocolate3", 205, 102, 29}, + {"chocolate4", 139, 69, 19}, + {"coral", 255, 127, 80}, + {"coral1", 255, 114, 86}, + {"coral2", 238, 106, 80}, + {"coral3", 205, 91, 69}, + {"coral4", 139, 62, 47}, + {"cornflower blue", 100, 149, 237}, + {"cornsilk", 255, 248, 220}, + {"cornsilk1", 255, 248, 220}, + {"cornsilk2", 238, 232, 205}, + {"cornsilk3", 205, 200, 177}, + {"cornsilk4", 139, 136, 120}, + {"cyan", 0, 255, 255}, + {"cyan1", 0, 255, 255}, + {"cyan2", 0, 238, 238}, + {"cyan3", 0, 205, 205}, + {"cyan4", 0, 139, 139}, + {"dark blue", 0, 0, 139}, + {"dark cyan", 0, 139, 139}, + {"dark goldenrod", 184, 134, 11}, + {"dark gray", 169, 169, 169}, + {"dark green", 0, 100, 0}, + {"dark grey", 169, 169, 169}, + {"dark khaki", 189, 183, 107}, + {"dark magenta", 139, 0, 139}, + {"dark olive green", 85, 107, 47}, + {"dark orange", 255, 140, 0}, + {"dark orchid", 153, 50, 204}, + {"dark red", 139, 0, 0}, + {"dark salmon", 233, 150, 122}, + {"dark sea green", 143, 188, 143}, + {"dark slate blue", 72, 61, 139}, + {"dark slate gray", 47, 79, 79}, + {"dark slate grey", 47, 79, 79}, + {"dark turquoise", 0, 206, 209}, + {"dark violet", 148, 0, 211}, + {"deep pink", 255, 20, 147}, + {"deep sky blue", 0, 191, 255}, + {"dim gray", 105, 105, 105}, + {"dim grey", 105, 105, 105}, + {"dodger blue", 30, 144, 255}, + {"firebrick", 178, 34, 34}, + {"firebrick1", 255, 48, 48}, + {"firebrick2", 238, 44, 44}, + {"firebrick3", 205, 38, 38}, + {"firebrick4", 139, 26, 26}, + {"floral white", 255, 250, 240}, + {"forest green", 34, 139, 34}, + {"gainsboro", 220, 220, 220}, + {"ghost white", 248, 248, 255}, + {"gold", 255, 215, 0}, + {"gold1", 255, 215, 0}, + {"gold2", 238, 201, 0}, + {"gold3", 205, 173, 0}, + {"gold4", 139, 117, 0}, + {"goldenrod", 218, 165, 32}, + {"goldenrod1", 255, 193, 37}, + {"goldenrod2", 238, 180, 34}, + {"goldenrod3", 205, 155, 29}, + {"goldenrod4", 139, 105, 20}, + {"gray", 190, 190, 190}, + {"gray0", 0, 0, 0}, + {"gray1", 3, 3, 3}, + {"gray10", 26, 26, 26}, + {"gray100", 255, 255, 255}, + {"gray11", 28, 28, 28}, + {"gray12", 31, 31, 31}, + {"gray13", 33, 33, 33}, + {"gray14", 36, 36, 36}, + {"gray15", 38, 38, 38}, + {"gray16", 41, 41, 41}, + {"gray17", 43, 43, 43}, + {"gray18", 46, 46, 46}, + {"gray19", 48, 48, 48}, + {"gray2", 5, 5, 5}, + {"gray20", 51, 51, 51}, + {"gray21", 54, 54, 54}, + {"gray22", 56, 56, 56}, + {"gray23", 59, 59, 59}, + {"gray24", 61, 61, 61}, + {"gray25", 64, 64, 64}, + {"gray26", 66, 66, 66}, + {"gray27", 69, 69, 69}, + {"gray28", 71, 71, 71}, + {"gray29", 74, 74, 74}, + {"gray3", 8, 8, 8}, + {"gray30", 77, 77, 77}, + {"gray31", 79, 79, 79}, + {"gray32", 82, 82, 82}, + {"gray33", 84, 84, 84}, + {"gray34", 87, 87, 87}, + {"gray35", 89, 89, 89}, + {"gray36", 92, 92, 92}, + {"gray37", 94, 94, 94}, + {"gray38", 97, 97, 97}, + {"gray39", 99, 99, 99}, + {"gray4", 10, 10, 10}, + {"gray40", 102, 102, 102}, + {"gray41", 105, 105, 105}, + {"gray42", 107, 107, 107}, + {"gray43", 110, 110, 110}, + {"gray44", 112, 112, 112}, + {"gray45", 115, 115, 115}, + {"gray46", 117, 117, 117}, + {"gray47", 120, 120, 120}, + {"gray48", 122, 122, 122}, + {"gray49", 125, 125, 125}, + {"gray5", 13, 13, 13}, + {"gray50", 127, 127, 127}, + {"gray51", 130, 130, 130}, + {"gray52", 133, 133, 133}, + {"gray53", 135, 135, 135}, + {"gray54", 138, 138, 138}, + {"gray55", 140, 140, 140}, + {"gray56", 143, 143, 143}, + {"gray57", 145, 145, 145}, + {"gray58", 148, 148, 148}, + {"gray59", 150, 150, 150}, + {"gray6", 15, 15, 15}, + {"gray60", 153, 153, 153}, + {"gray61", 156, 156, 156}, + {"gray62", 158, 158, 158}, + {"gray63", 161, 161, 161}, + {"gray64", 163, 163, 163}, + {"gray65", 166, 166, 166}, + {"gray66", 168, 168, 168}, + {"gray67", 171, 171, 171}, + {"gray68", 173, 173, 173}, + {"gray69", 176, 176, 176}, + {"gray7", 18, 18, 18}, + {"gray70", 179, 179, 179}, + {"gray71", 181, 181, 181}, + {"gray72", 184, 184, 184}, + {"gray73", 186, 186, 186}, + {"gray74", 189, 189, 189}, + {"gray75", 191, 191, 191}, + {"gray76", 194, 194, 194}, + {"gray77", 196, 196, 196}, + {"gray78", 199, 199, 199}, + {"gray79", 201, 201, 201}, + {"gray8", 20, 20, 20}, + {"gray80", 204, 204, 204}, + {"gray81", 207, 207, 207}, + {"gray82", 209, 209, 209}, + {"gray83", 212, 212, 212}, + {"gray84", 214, 214, 214}, + {"gray85", 217, 217, 217}, + {"gray86", 219, 219, 219}, + {"gray87", 222, 222, 222}, + {"gray88", 224, 224, 224}, + {"gray89", 227, 227, 227}, + {"gray9", 23, 23, 23}, + {"gray90", 229, 229, 229}, + {"gray91", 232, 232, 232}, + {"gray92", 235, 235, 235}, + {"gray93", 237, 237, 237}, + {"gray94", 240, 240, 240}, + {"gray95", 242, 242, 242}, + {"gray96", 245, 245, 245}, + {"gray97", 247, 247, 247}, + {"gray98", 250, 250, 250}, + {"gray99", 252, 252, 252}, + {"green", 0, 255, 0}, + {"green yellow", 173, 255, 47}, + {"green1", 0, 255, 0}, + {"green2", 0, 238, 0}, + {"green3", 0, 205, 0}, + {"green4", 0, 139, 0}, + {"grey", 190, 190, 190}, + {"grey0", 0, 0, 0}, + {"grey1", 3, 3, 3}, + {"grey10", 26, 26, 26}, + {"grey100", 255, 255, 255}, + {"grey11", 28, 28, 28}, + {"grey12", 31, 31, 31}, + {"grey13", 33, 33, 33}, + {"grey14", 36, 36, 36}, + {"grey15", 38, 38, 38}, + {"grey16", 41, 41, 41}, + {"grey17", 43, 43, 43}, + {"grey18", 46, 46, 46}, + {"grey19", 48, 48, 48}, + {"grey2", 5, 5, 5}, + {"grey20", 51, 51, 51}, + {"grey21", 54, 54, 54}, + {"grey22", 56, 56, 56}, + {"grey23", 59, 59, 59}, + {"grey24", 61, 61, 61}, + {"grey25", 64, 64, 64}, + {"grey26", 66, 66, 66}, + {"grey27", 69, 69, 69}, + {"grey28", 71, 71, 71}, + {"grey29", 74, 74, 74}, + {"grey3", 8, 8, 8}, + {"grey30", 77, 77, 77}, + {"grey31", 79, 79, 79}, + {"grey32", 82, 82, 82}, + {"grey33", 84, 84, 84}, + {"grey34", 87, 87, 87}, + {"grey35", 89, 89, 89}, + {"grey36", 92, 92, 92}, + {"grey37", 94, 94, 94}, + {"grey38", 97, 97, 97}, + {"grey39", 99, 99, 99}, + {"grey4", 10, 10, 10}, + {"grey40", 102, 102, 102}, + {"grey41", 105, 105, 105}, + {"grey42", 107, 107, 107}, + {"grey43", 110, 110, 110}, + {"grey44", 112, 112, 112}, + {"grey45", 115, 115, 115}, + {"grey46", 117, 117, 117}, + {"grey47", 120, 120, 120}, + {"grey48", 122, 122, 122}, + {"grey49", 125, 125, 125}, + {"grey5", 13, 13, 13}, + {"grey50", 127, 127, 127}, + {"grey51", 130, 130, 130}, + {"grey52", 133, 133, 133}, + {"grey53", 135, 135, 135}, + {"grey54", 138, 138, 138}, + {"grey55", 140, 140, 140}, + {"grey56", 143, 143, 143}, + {"grey57", 145, 145, 145}, + {"grey58", 148, 148, 148}, + {"grey59", 150, 150, 150}, + {"grey6", 15, 15, 15}, + {"grey60", 153, 153, 153}, + {"grey61", 156, 156, 156}, + {"grey62", 158, 158, 158}, + {"grey63", 161, 161, 161}, + {"grey64", 163, 163, 163}, + {"grey65", 166, 166, 166}, + {"grey66", 168, 168, 168}, + {"grey67", 171, 171, 171}, + {"grey68", 173, 173, 173}, + {"grey69", 176, 176, 176}, + {"grey7", 18, 18, 18}, + {"grey70", 179, 179, 179}, + {"grey71", 181, 181, 181}, + {"grey72", 184, 184, 184}, + {"grey73", 186, 186, 186}, + {"grey74", 189, 189, 189}, + {"grey75", 191, 191, 191}, + {"grey76", 194, 194, 194}, + {"grey77", 196, 196, 196}, + {"grey78", 199, 199, 199}, + {"grey79", 201, 201, 201}, + {"grey8", 20, 20, 20}, + {"grey80", 204, 204, 204}, + {"grey81", 207, 207, 207}, + {"grey82", 209, 209, 209}, + {"grey83", 212, 212, 212}, + {"grey84", 214, 214, 214}, + {"grey85", 217, 217, 217}, + {"grey86", 219, 219, 219}, + {"grey87", 222, 222, 222}, + {"grey88", 224, 224, 224}, + {"grey89", 227, 227, 227}, + {"grey9", 23, 23, 23}, + {"grey90", 229, 229, 229}, + {"grey91", 232, 232, 232}, + {"grey92", 235, 235, 235}, + {"grey93", 237, 237, 237}, + {"grey94", 240, 240, 240}, + {"grey95", 242, 242, 242}, + {"grey96", 245, 245, 245}, + {"grey97", 247, 247, 247}, + {"grey98", 250, 250, 250}, + {"grey99", 252, 252, 252}, + {"honeydew", 240, 255, 240}, + {"honeydew1", 240, 255, 240}, + {"honeydew2", 224, 238, 224}, + {"honeydew3", 193, 205, 193}, + {"honeydew4", 131, 139, 131}, + {"hot pink", 255, 105, 180}, + {"indian red", 205, 92, 92}, + {"ivory", 255, 255, 240}, + {"ivory1", 255, 255, 240}, + {"ivory2", 238, 238, 224}, + {"ivory3", 205, 205, 193}, + {"ivory4", 139, 139, 131}, + {"khaki", 240, 230, 140}, + {"khaki1", 255, 246, 143}, + {"khaki2", 238, 230, 133}, + {"khaki3", 205, 198, 115}, + {"khaki4", 139, 134, 78}, + {"lavender", 230, 230, 250}, + {"lavender blush", 255, 240, 245}, + {"lawn green", 124, 252, 0}, + {"lemon chiffon", 255, 250, 205}, + {"light blue", 173, 216, 230}, + {"light coral", 240, 128, 128}, + {"light cyan", 224, 255, 255}, + {"light goldenrod", 238, 221, 130}, + {"light goldenrod yellow", 250, 250, 210}, + {"light gray", 211, 211, 211}, + {"light green", 144, 238, 144}, + {"light grey", 211, 211, 211}, + {"light pink", 255, 182, 193}, + {"light salmon", 255, 160, 122}, + {"light sea green", 32, 178, 170}, + {"light sky blue", 135, 206, 250}, + {"light slate blue", 132, 112, 255}, + {"light slate gray", 119, 136, 153}, + {"light slate grey", 119, 136, 153}, + {"light steel blue", 176, 196, 222}, + {"light yellow", 255, 255, 224}, + {"lime green", 50, 205, 50}, + {"linen", 250, 240, 230}, + {"magenta", 255, 0, 255}, + {"magenta1", 255, 0, 255}, + {"magenta2", 238, 0, 238}, + {"magenta3", 205, 0, 205}, + {"magenta4", 139, 0, 139}, + {"maroon", 176, 48, 96}, + {"maroon1", 255, 52, 179}, + {"maroon2", 238, 48, 167}, + {"maroon3", 205, 41, 144}, + {"maroon4", 139, 28, 98}, + {"medium aquamarine", 102, 205, 170}, + {"medium blue", 0, 0, 205}, + {"medium orchid", 186, 85, 211}, + {"medium purple", 147, 112, 219}, + {"medium sea green", 60, 179, 113}, + {"medium slate blue", 123, 104, 238}, + {"medium spring green", 0, 250, 154}, + {"medium turquoise", 72, 209, 204}, + {"medium violet red", 199, 21, 133}, + {"midnight blue", 25, 25, 112}, + {"mint cream", 245, 255, 250}, + {"misty rose", 255, 228, 225}, + {"moccasin", 255, 228, 181}, + {"navajo white", 255, 222, 173}, + {"navy", 0, 0, 128}, + {"navy blue", 0, 0, 128}, + {"old lace", 253, 245, 230}, + {"olive drab", 107, 142, 35}, + {"orange", 255, 165, 0}, + {"orange red", 255, 69, 0}, + {"orange1", 255, 165, 0}, + {"orange2", 238, 154, 0}, + {"orange3", 205, 133, 0}, + {"orange4", 139, 90, 0}, + {"orchid", 218, 112, 214}, + {"orchid1", 255, 131, 250}, + {"orchid2", 238, 122, 233}, + {"orchid3", 205, 105, 201}, + {"orchid4", 139, 71, 137}, + {"pale goldenrod", 238, 232, 170}, + {"pale green", 152, 251, 152}, + {"pale turquoise", 175, 238, 238}, + {"pale violet red", 219, 112, 147}, + {"papaya whip", 255, 239, 213}, + {"peach puff", 255, 218, 185}, + {"peru", 205, 133, 63}, + {"pink", 255, 192, 203}, + {"pink1", 255, 181, 197}, + {"pink2", 238, 169, 184}, + {"pink3", 205, 145, 158}, + {"pink4", 139, 99, 108}, + {"plum", 221, 160, 221}, + {"plum1", 255, 187, 255}, + {"plum2", 238, 174, 238}, + {"plum3", 205, 150, 205}, + {"plum4", 139, 102, 139}, + {"powder blue", 176, 224, 230}, + {"purple", 160, 32, 240}, + {"purple1", 155, 48, 255}, + {"purple2", 145, 44, 238}, + {"purple3", 125, 38, 205}, + {"purple4", 85, 26, 139}, + {"red", 255, 0, 0}, + {"red1", 255, 0, 0}, + {"red2", 238, 0, 0}, + {"red3", 205, 0, 0}, + {"red4", 139, 0, 0}, + {"rosy brown", 188, 143, 143}, + {"royal blue", 65, 105, 225}, + {"saddle brown", 139, 69, 19}, + {"salmon", 250, 128, 114}, + {"salmon1", 255, 140, 105}, + {"salmon2", 238, 130, 98}, + {"salmon3", 205, 112, 84}, + {"salmon4", 139, 76, 57}, + {"sandy brown", 244, 164, 96}, + {"sea green", 46, 139, 87}, + {"seashell", 255, 245, 238}, + {"seashell1", 255, 245, 238}, + {"seashell2", 238, 229, 222}, + {"seashell3", 205, 197, 191}, + {"seashell4", 139, 134, 130}, + {"sienna", 160, 82, 45}, + {"sienna1", 255, 130, 71}, + {"sienna2", 238, 121, 66}, + {"sienna3", 205, 104, 57}, + {"sienna4", 139, 71, 38}, + {"sky blue", 135, 206, 235}, + {"slate blue", 106, 90, 205}, + {"slate gray", 112, 128, 144}, + {"slate grey", 112, 128, 144}, + {"snow", 255, 250, 250}, + {"snow1", 255, 250, 250}, + {"snow2", 238, 233, 233}, + {"snow3", 205, 201, 201}, + {"snow4", 139, 137, 137}, + {"spring green", 0, 255, 127}, + {"steel blue", 70, 130, 180}, + {"tan", 210, 180, 140}, + {"tan1", 255, 165, 79}, + {"tan2", 238, 154, 73}, + {"tan3", 205, 133, 63}, + {"tan4", 139, 90, 43}, + {"thistle", 216, 191, 216}, + {"thistle1", 255, 225, 255}, + {"thistle2", 238, 210, 238}, + {"thistle3", 205, 181, 205}, + {"thistle4", 139, 123, 139}, + {"tomato", 255, 99, 71}, + {"tomato1", 255, 99, 71}, + {"tomato2", 238, 92, 66}, + {"tomato3", 205, 79, 57}, + {"tomato4", 139, 54, 38}, + {"turquoise", 64, 224, 208}, + {"turquoise1", 0, 245, 255}, + {"turquoise2", 0, 229, 238}, + {"turquoise3", 0, 197, 205}, + {"turquoise4", 0, 134, 139}, + {"violet", 238, 130, 238}, + {"violet red", 208, 32, 144}, + {"wheat", 245, 222, 179}, + {"wheat1", 255, 231, 186}, + {"wheat2", 238, 216, 174}, + {"wheat3", 205, 186, 150}, + {"wheat4", 139, 126, 102}, + {"white", 255, 255, 255}, + {"white smoke", 245, 245, 245}, + {"yellow", 255, 255, 0}, + {"yellow green", 154, 205, 50}, + {"yellow1", 255, 255, 0}, + {"yellow2", 238, 238, 0}, + {"yellow3", 205, 205, 0}, + {"yellow4", 139, 139, 0}, +}; + +BGD_EXPORT_DATA_PROT gdColorMap GD_COLOR_MAP_X11 = {sizeof(GD_COLOR_MAP_X11_ENTRIES) / + sizeof(gdColorMapEntry), + (gdColorMapEntry *)GD_COLOR_MAP_X11_ENTRIES}; + +/* + Function: gdColorMapLookup +*/ +BGD_DECLARE(int) +gdColorMapLookup(const gdColorMap color_map, const char *color_name, int *r, int *g, int *b) +{ + gdColorMapEntry *entries = color_map.entries; + int low = 0; + int high = color_map.num_entries - 1; + while (low <= high) { + int i = (low + high) / 2; + int result = strcmp(color_name, entries[i].color_name); + if (result == 0) { + *r = entries[i].red; + *g = entries[i].green; + *b = entries[i].blue; + return 1; + } else if (result < 0) { + high = i - 1; + } else { + low = i + 1; + } + } + return 0; +} diff --git a/ext/gd/libgd/gd_color_map.h b/ext/gd/libgd/gd_color_map.h new file mode 100644 index 000000000000..48e2fa280a2b --- /dev/null +++ b/ext/gd/libgd/gd_color_map.h @@ -0,0 +1,31 @@ +#ifndef GD_COLOR_MAP_H +#define GD_COLOR_MAP_H 1 + +#include "gd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *color_name; + int red; + int green; + int blue; +} gdColorMapEntry; + +typedef struct { + int num_entries; + gdColorMapEntry *entries; +} gdColorMap; + +extern BGD_EXPORT_DATA_PROT gdColorMap GD_COLOR_MAP_X11; + +BGD_DECLARE(int) +gdColorMapLookup(const gdColorMap color_map, const char *color_name, int *r, int *g, int *b); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/gd/libgd/gd_color_match.c b/ext/gd/libgd/gd_color_match.c index 19fdfe6d031d..217498a37a1d 100644 --- a/ext/gd/libgd/gd_color_match.c +++ b/ext/gd/libgd/gd_color_match.c @@ -1,62 +1,63 @@ #include "gd.h" #include "gdhelpers.h" +#include #include "gd_intern.h" #include "php.h" -/* bring the palette colors in im2 to be closer to im1 - * +/* + Function: gdImageColorMatch + + Bring the palette colors in im2 to be closer to im1. */ -int gdImageColorMatch (gdImagePtr im1, gdImagePtr im2) +BGD_DECLARE(int) gdImageColorMatch(gdImagePtr im1, gdImagePtr im2) { - unsigned long *buf; /* stores our calculations */ - unsigned long *bp; /* buf ptr */ - int color, rgb; - int x,y; - int count; - - if( !im1->trueColor ) { - return -1; /* im1 must be True Color */ - } - if( im2->trueColor ) { - return -2; /* im2 must be indexed */ - } - if( (im1->sx != im2->sx) || (im1->sy != im2->sy) ) { - return -3; /* the images are meant to be the same dimensions */ - } - if (im2->colorsTotal<1) { - return -4; /* At least 1 color must be allocated */ - } + unsigned long *buf; /* stores our calculations */ + unsigned long *bp; /* buf ptr */ + int color, rgb; + int x, y; + int count; - buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * gdMaxColors, 0); - memset( buf, 0, sizeof(unsigned long) * 5 * gdMaxColors ); + if (!im1->trueColor) { + return -1; /* im1 must be True Color */ + } + if (im2->trueColor) { + return -2; /* im2 must be indexed */ + } + if ((im1->sx != im2->sx) || (im1->sy != im2->sy)) { + return -3; /* the images are meant to be the same dimensions */ + } + if (im2->colorsTotal < 1) { + return -4; /* At least 1 color must be allocated */ + } + // gdMaxColors == 255 + buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * gdMaxColors); + memset(buf, 0, sizeof(unsigned long) * 5 * gdMaxColors); - for (x=0; xsx; x++) { - for( y=0; ysy; y++ ) { - color = im2->pixels[y][x]; - rgb = im1->tpixels[y][x]; - bp = buf + (color * 5); - (*(bp++))++; - *(bp++) += gdTrueColorGetRed(rgb); - *(bp++) += gdTrueColorGetGreen(rgb); - *(bp++) += gdTrueColorGetBlue(rgb); - *(bp++) += gdTrueColorGetAlpha(rgb); - } - } - bp = buf; - for (color=0; colorcolorsTotal; color++) { - count = *(bp++); - if( count > 0 ) { - im2->red[color] = *(bp++) / count; - im2->green[color] = *(bp++) / count; - im2->blue[color] = *(bp++) / count; - im2->alpha[color] = *(bp++) / count; - } else { - bp += 4; - } - } - gdFree(buf); - return 0; + for (x = 0; x < im1->sx; x++) { + for (y = 0; y < im1->sy; y++) { + color = im2->pixels[y][x]; + rgb = im1->tpixels[y][x]; + bp = buf + (color * 5); + (*(bp++))++; + *(bp++) += gdTrueColorGetRed(rgb); + *(bp++) += gdTrueColorGetGreen(rgb); + *(bp++) += gdTrueColorGetBlue(rgb); + *(bp++) += gdTrueColorGetAlpha(rgb); + } + } + bp = buf; + for (color = 0; color < im2->colorsTotal; color++) { + count = *(bp++); + if (count > 0) { + im2->red[color] = *(bp++) / count; + im2->green[color] = *(bp++) / count; + im2->blue[color] = *(bp++) / count; + im2->alpha[color] = *(bp++) / count; + } else { + bp += 4; + } + } + gdFree(buf); + return 0; } - - diff --git a/ext/gd/libgd/gd_compositor.c b/ext/gd/libgd/gd_compositor.c new file mode 100644 index 000000000000..66c50b64b4c2 --- /dev/null +++ b/ext/gd/libgd/gd_compositor.c @@ -0,0 +1,339 @@ +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd_compositor.h" +#include "gd_vector2d_private.h" + +typedef enum { + FACTOR_ZERO, + FACTOR_ONE, + FACTOR_SRC_ALPHA, + FACTOR_DST_ALPHA, + FACTOR_ONE_MINUS_SRC_ALPHA, + FACTOR_ONE_MINUS_DST_ALPHA, + FACTOR_SATURATE +} FactorKind; + +typedef struct { + FactorKind src, dst; +} Factors; + +static const Factors porter_duff[] = {{FACTOR_ZERO, FACTOR_ZERO}, + {FACTOR_ONE, FACTOR_ZERO}, + {FACTOR_ONE, FACTOR_ONE_MINUS_SRC_ALPHA}, + {FACTOR_DST_ALPHA, FACTOR_ZERO}, + {FACTOR_ONE_MINUS_DST_ALPHA, FACTOR_ZERO}, + {FACTOR_DST_ALPHA, FACTOR_ONE_MINUS_SRC_ALPHA}, + {FACTOR_ZERO, FACTOR_ONE}, + {FACTOR_ONE_MINUS_DST_ALPHA, FACTOR_ONE}, + {FACTOR_ZERO, FACTOR_SRC_ALPHA}, + {FACTOR_ZERO, FACTOR_ONE_MINUS_SRC_ALPHA}, + {FACTOR_ONE_MINUS_DST_ALPHA, FACTOR_SRC_ALPHA}, + {FACTOR_ONE_MINUS_DST_ALPHA, FACTOR_ONE_MINUS_SRC_ALPHA}, + {FACTOR_ONE, FACTOR_ONE}, + {FACTOR_SATURATE, FACTOR_ONE}}; + +static float clamp01(float v) { return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v); } + +static gdPremulPixelF clamp_pixel(gdPremulPixelF p) +{ + p.a = clamp01(p.a); + p.r = fminf(clamp01(p.r), p.a); + p.g = fminf(clamp01(p.g), p.a); + p.b = fminf(clamp01(p.b), p.a); + return p; +} + +static gdPremulPixelF scale_pixel(gdPremulPixelF p, float scale) +{ + p.r *= scale; + p.g *= scale; + p.b *= scale; + p.a *= scale; + return p; +} + +static gdPremulPixelF lerp_pixel(gdPremulPixelF a, gdPremulPixelF b, float t) +{ + gdPremulPixelF r; + t = clamp01(t); + r.r = a.r + (b.r - a.r) * t; + r.g = a.g + (b.g - a.g) * t; + r.b = a.b + (b.b - a.b) * t; + r.a = a.a + (b.a - a.a) * t; + return clamp_pixel(r); +} + +static float factor(FactorKind kind, float sa, float da) +{ + switch (kind) { + case FACTOR_ZERO: + return 0.0f; + case FACTOR_ONE: + return 1.0f; + case FACTOR_SRC_ALPHA: + return sa; + case FACTOR_DST_ALPHA: + return da; + case FACTOR_ONE_MINUS_SRC_ALPHA: + return 1.0f - sa; + case FACTOR_ONE_MINUS_DST_ALPHA: + return 1.0f - da; + case FACTOR_SATURATE: + return sa > 0.0f ? fminf(1.0f, (1.0f - da) / sa) : 0.0f; + } + return 0.0f; +} + +static gdPremulPixelF composite_porter_duff(gdCompositeOperator op, gdPremulPixelF s, + gdPremulPixelF d) +{ + const Factors f = porter_duff[op]; + const float sf = factor(f.src, s.a, d.a); + const float df = factor(f.dst, s.a, d.a); + gdPremulPixelF r; + r.r = s.r * sf + d.r * df; + r.g = s.g * sf + d.g * df; + r.b = s.b * sf + d.b * df; + r.a = s.a * sf + d.a * df; + return clamp_pixel(r); +} + +static float blend_channel(gdCompositeOperator op, float s, float d) +{ + switch (op) { + case GD_OP_MULTIPLY: + return s * d; + case GD_OP_SCREEN: + return s + d - s * d; + case GD_OP_OVERLAY: + return d <= 0.5f ? 2.0f * s * d : 1.0f - 2.0f * (1.0f - s) * (1.0f - d); + case GD_OP_DARKEN: + return fminf(s, d); + case GD_OP_LIGHTEN: + return fmaxf(s, d); + case GD_OP_COLOR_DODGE: + return s >= 1.0f ? 1.0f : fminf(1.0f, d / (1.0f - s)); + case GD_OP_COLOR_BURN: + return s <= 0.0f ? 0.0f : 1.0f - fminf(1.0f, (1.0f - d) / s); + case GD_OP_HARD_LIGHT: + return s <= 0.5f ? 2.0f * s * d : 1.0f - 2.0f * (1.0f - s) * (1.0f - d); + case GD_OP_SOFT_LIGHT: + if (s <= 0.5f) + return d - (1.0f - 2.0f * s) * d * (1.0f - d); + else { + float g = d <= 0.25f ? ((16.0f * d - 12.0f) * d + 4.0f) * d : sqrtf(d); + return d + (2.0f * s - 1.0f) * (g - d); + } + case GD_OP_DIFFERENCE: + return fabsf(d - s); + case GD_OP_EXCLUSION: + return s + d - 2.0f * s * d; + default: + return s; + } +} + +typedef struct { + float r, g, b; +} StraightColor; + +static float color_lum(StraightColor c) { return 0.30f * c.r + 0.59f * c.g + 0.11f * c.b; } + +static float color_sat(StraightColor c) +{ + return fmaxf(c.r, fmaxf(c.g, c.b)) - fminf(c.r, fminf(c.g, c.b)); +} + +static StraightColor clip_color(StraightColor c) +{ + float l = color_lum(c); + float n = fminf(c.r, fminf(c.g, c.b)); + float x = fmaxf(c.r, fmaxf(c.g, c.b)); + if (n < 0.0f) { + float k = l / (l - n); + c.r = l + (c.r - l) * k; + c.g = l + (c.g - l) * k; + c.b = l + (c.b - l) * k; + } + x = fmaxf(c.r, fmaxf(c.g, c.b)); + if (x > 1.0f) { + float k = (1.0f - l) / (x - l); + c.r = l + (c.r - l) * k; + c.g = l + (c.g - l) * k; + c.b = l + (c.b - l) * k; + } + return c; +} + +static StraightColor set_lum(StraightColor c, float l) +{ + float d = l - color_lum(c); + c.r += d; + c.g += d; + c.b += d; + return clip_color(c); +} + +static StraightColor set_sat(StraightColor c, float s) +{ + float *v[3] = {&c.r, &c.g, &c.b}; + float *tmp; + if (*v[0] > *v[1]) { + tmp = v[0]; + v[0] = v[1]; + v[1] = tmp; + } + if (*v[1] > *v[2]) { + tmp = v[1]; + v[1] = v[2]; + v[2] = tmp; + } + if (*v[0] > *v[1]) { + tmp = v[0]; + v[0] = v[1]; + v[1] = tmp; + } + if (*v[2] > *v[0]) { + *v[1] = (*v[1] - *v[0]) * s / (*v[2] - *v[0]); + *v[2] = s; + } else { + *v[1] = *v[2] = 0.0f; + } + *v[0] = 0.0f; + return c; +} + +static StraightColor blend_hsl(gdCompositeOperator op, StraightColor s, StraightColor d) +{ + switch (op) { + case GD_OP_HSL_HUE: + return set_lum(set_sat(s, color_sat(d)), color_lum(d)); + case GD_OP_HSL_SATURATION: + return set_lum(set_sat(d, color_sat(s)), color_lum(d)); + case GD_OP_HSL_COLOR: + return set_lum(s, color_lum(d)); + case GD_OP_HSL_LUMINOSITY: + return set_lum(d, color_lum(s)); + default: + return s; + } +} + +static gdPremulPixelF composite_blend(gdCompositeOperator op, gdPremulPixelF s, gdPremulPixelF d) +{ + StraightColor cs = {0, 0, 0}, cd = {0, 0, 0}, b; + gdPremulPixelF r; + if (s.a > 0.0f) { + cs.r = s.r / s.a; + cs.g = s.g / s.a; + cs.b = s.b / s.a; + } + if (d.a > 0.0f) { + cd.r = d.r / d.a; + cd.g = d.g / d.a; + cd.b = d.b / d.a; + } + if (op >= GD_OP_HSL_HUE) + b = blend_hsl(op, cs, cd); + else { + b.r = blend_channel(op, cs.r, cd.r); + b.g = blend_channel(op, cs.g, cd.g); + b.b = blend_channel(op, cs.b, cd.b); + } + r.a = s.a + d.a * (1.0f - s.a); + r.r = (1.0f - d.a) * s.r + (1.0f - s.a) * d.r + s.a * d.a * b.r; + r.g = (1.0f - d.a) * s.g + (1.0f - s.a) * d.g + s.a * d.a * b.g; + r.b = (1.0f - d.a) * s.b + (1.0f - s.a) * d.b + s.a * d.a * b.b; + return clamp_pixel(r); +} + +int gdCompositeOperatorIsValid(gdCompositeOperator op) +{ + return op >= GD_OP_CLEAR && op < GD_OP_COUNT; +} + +int gdCompositeOperatorIsUnbounded(gdCompositeOperator op) +{ + return op == GD_OP_IN || op == GD_OP_OUT || op == GD_OP_DEST_IN || op == GD_OP_DEST_ATOP; +} + +gdPremulPixelF gdCompositePixel(gdCompositeOperator op, gdPremulPixelF src, gdPremulPixelF dst, + float coverage) +{ + gdPremulPixelF result; + coverage = clamp01(coverage); + src = clamp_pixel(src); + dst = clamp_pixel(dst); + if (!gdCompositeOperatorIsValid(op)) + return dst; + if (op == GD_OP_CLEAR || op == GD_OP_SOURCE) { + result = composite_porter_duff(op, src, dst); + return lerp_pixel(dst, result, coverage); + } + src = scale_pixel(src, coverage); + if (op <= GD_OP_SATURATE) + return composite_porter_duff(op, src, dst); + return composite_blend(op, src, dst); +} + +void gdCompositeSpan(gdCompositeOperator op, const gdPremulPixelF *src, ptrdiff_t src_stride, + gdPremulPixelF *dst, const float *coverage, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) { + float c = coverage ? coverage[i] : 1.0f; + dst[i] = gdCompositePixel(op, *src, dst[i], c); + src = (const gdPremulPixelF *)((const char *)src + src_stride); + } +} + +gdPremulPixelF gdCompositePixelFromArgb32(uint32_t p) +{ + gdPremulPixelF r; + r.a = ((p >> 24) & 255) / 255.0f; + r.r = ((p >> 16) & 255) / 255.0f; + r.g = ((p >> 8) & 255) / 255.0f; + r.b = (p & 255) / 255.0f; + return clamp_pixel(r); +} + +uint32_t gdCompositePixelToArgb32(gdPremulPixelF p) +{ + uint32_t a, r, g, b; + p = clamp_pixel(p); + a = (uint32_t)floorf(p.a * 255.0f + 0.5f); + r = (uint32_t)floorf(p.r * 255.0f + 0.5f); + g = (uint32_t)floorf(p.g * 255.0f + 0.5f); + b = (uint32_t)floorf(p.b * 255.0f + 0.5f); + return (a << 24) | (r << 16) | (g << 8) | b; +} + +gdPremulPixelF gdCompositePixelFromGd(int p) +{ + float a = (gdAlphaMax - gdTrueColorGetAlpha(p)) / (float)gdAlphaMax; + gdPremulPixelF r; + r.a = a; + r.r = gdTrueColorGetRed(p) / 255.0f * a; + r.g = gdTrueColorGetGreen(p) / 255.0f * a; + r.b = gdTrueColorGetBlue(p) / 255.0f * a; + return clamp_pixel(r); +} + +int gdCompositePixelToGd(gdPremulPixelF p) +{ + int a, r = 0, g = 0, b = 0; + p = clamp_pixel(p); + a = (int)floorf((1.0f - p.a) * gdAlphaMax + 0.5f); + if (p.a > 0.0f) { + r = (int)floorf(p.r / p.a * 255.0f + 0.5f); + g = (int)floorf(p.g / p.a * 255.0f + 0.5f); + b = (int)floorf(p.b / p.a * 255.0f + 0.5f); + } + return gdTrueColorAlpha(r, g, b, a); +} diff --git a/ext/gd/libgd/gd_compositor.h b/ext/gd/libgd/gd_compositor.h new file mode 100644 index 000000000000..e5fedf57fc8d --- /dev/null +++ b/ext/gd/libgd/gd_compositor.h @@ -0,0 +1,23 @@ +#ifndef GD_COMPOSITOR_H +#define GD_COMPOSITOR_H + +#include "gd_vector2d_private.h" +#include +#include + +typedef struct { + float r, g, b, a; +} gdPremulPixelF; + +int gdCompositeOperatorIsValid(gdCompositeOperator op); +int gdCompositeOperatorIsUnbounded(gdCompositeOperator op); +gdPremulPixelF gdCompositePixel(gdCompositeOperator op, gdPremulPixelF src, gdPremulPixelF dst, + float coverage); +void gdCompositeSpan(gdCompositeOperator op, const gdPremulPixelF *src, ptrdiff_t src_stride, + gdPremulPixelF *dst, const float *coverage, size_t n); +gdPremulPixelF gdCompositePixelFromArgb32(uint32_t pixel); +uint32_t gdCompositePixelToArgb32(gdPremulPixelF pixel); +gdPremulPixelF gdCompositePixelFromGd(int pixel); +int gdCompositePixelToGd(gdPremulPixelF pixel); + +#endif diff --git a/ext/gd/libgd/gd_crop.c b/ext/gd/libgd/gd_crop.c index 676545c4dbc9..fc4bf2e4a8ef 100644 --- a/ext/gd/libgd/gd_crop.c +++ b/ext/gd/libgd/gd_crop.c @@ -1,249 +1,271 @@ /** - * Title: Crop + * File: Cropping * - * A couple of functions to crop images, automatically (auto detection of - * the borders color), using a given color (with or without tolerance) - * or using a selection. + * Crop an image * - * The threshold method works relatively well but it can be improved. - * Maybe L*a*b* and Delta-E will give better results (and a better - * granularity). + * Some functions to crop images, automatically (auto detection of the border + * color), using a given color (with or without tolerance) or using a given + * rectangle. * * Example: * (start code) * im2 = gdImageAutoCrop(im, GD_CROP_SIDES); * if (im2) { - + * gdImageDestroy(im); // unless you need the original image subsequently + * // do something with the cropped image * } * gdImageDestroy(im2); * (end code) **/ +#include #include #include -#include #include "gd.h" +#include "gd_color.h" +#include static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color); -static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold); /** * Function: gdImageCrop - * Crops the src image using the area defined by the rectangle. - * The result is returned as a new image. * + * Crop an image to a given rectangle * * Parameters: - * src - Source image - * crop - Rectangular region to crop + * src - The image. + * crop - The cropping rectangle, see . * * Returns: - * on success or NULL + * The newly created cropped image, or NULL on failure. + * + * See also: + * - + * - */ -gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop) +BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop) { - gdImagePtr dst; - int alphaBlendingFlag; - - if (gdImageTrueColor(src)) { - dst = gdImageCreateTrueColor(crop->width, crop->height); - } else { - dst = gdImageCreate(crop->width, crop->height); - } - if (!dst) return NULL; - alphaBlendingFlag = dst->alphaBlendingFlag; - gdImageAlphaBlending(dst, gdEffectReplace); - gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height); - gdImageAlphaBlending(dst, alphaBlendingFlag); - - return dst; + gdImagePtr dst; + int alphaBlendingFlag; + + if (gdImageTrueColor(src)) { + dst = gdImageCreateTrueColor(crop->width, crop->height); + } else { + dst = gdImageCreate(crop->width, crop->height); + } + if (!dst) + return NULL; + alphaBlendingFlag = dst->alphaBlendingFlag; + gdImageAlphaBlending(dst, gdEffectReplace); + gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height); + gdImageAlphaBlending(dst, alphaBlendingFlag); + + return dst; } /** - * Function: gdImageAutoCrop - * Automatic croping of the src image using the given mode - * (see ) + * Function: gdImageCropAuto + * + * Crop an image automatically * + * This function detects the cropping area according to the given _mode_. * * Parameters: - * im - Source image - * mode - crop mode + * im - The image. + * mode - The cropping mode, see . * * Returns: - * on success or NULL + * The newly created cropped image, or NULL on failure. * * See also: - * + * - + * - */ -gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode) +BGD_DECLARE(gdImagePtr) +gdImageCropAuto(gdImagePtr im, const unsigned int mode) { - const int width = gdImageSX(im); - const int height = gdImageSY(im); - - int x,y; - int color, match; - gdRect crop; - - crop.x = 0; - crop.y = 0; - crop.width = 0; - crop.height = 0; - - switch (mode) { - case GD_CROP_TRANSPARENT: - color = gdImageGetTransparent(im); - break; - - case GD_CROP_BLACK: - color = gdImageColorClosestAlpha(im, 0, 0, 0, 0); - break; - - case GD_CROP_WHITE: - color = gdImageColorClosestAlpha(im, 255, 255, 255, 0); - break; - - case GD_CROP_SIDES: - gdGuessBackgroundColorFromCorners(im, &color); - break; - - case GD_CROP_DEFAULT: - default: - color = gdImageGetTransparent(im); - break; - } - - /* TODO: Add gdImageGetRowPtr and works with ptr at the row level - * for the true color and palette images - * new formats will simply work with ptr - */ - match = 1; - for (y = 0; match && y < height; y++) { - for (x = 0; match && x < width; x++) { - int c2 = gdImageGetPixel(im, x, y); - match = (color == c2); - } - } - - /* Whole image would be cropped > bye */ - if (match) { - return NULL; - } - - crop.y = y - 1; - - match = 1; - for (y = height - 1; match && y >= 0; y--) { - for (x = 0; match && x < width; x++) { - match = (color == gdImageGetPixel(im, x,y)); - } - } - crop.height = y - crop.y + 2; - - match = 1; - for (x = 0; match && x < width; x++) { - for (y = 0; match && y < crop.y + crop.height; y++) { - match = (color == gdImageGetPixel(im, x,y)); - } - } - crop.x = x - 1; - - match = 1; - for (x = width - 1; match && x >= 0; x--) { - for (y = 0; match && y < crop.y + crop.height; y++) { - match = (color == gdImageGetPixel(im, x,y)); - } - } - crop.width = x - crop.x + 2; - - return gdImageCrop(im, &crop); + const int width = gdImageSX(im); + const int height = gdImageSY(im); + + int x, y; + int color; + gdRect crop; + + crop.x = 0; + crop.y = 0; + crop.width = 0; + crop.height = 0; + + switch (mode) { + case GD_CROP_TRANSPARENT: + color = gdImageGetTransparent(im); + break; + + case GD_CROP_BLACK: + color = gdImageColorClosestAlpha(im, 0, 0, 0, 0); + break; + + case GD_CROP_WHITE: + color = gdImageColorClosestAlpha(im, 255, 255, 255, 0); + break; + + case GD_CROP_SIDES: + gdGuessBackgroundColorFromCorners(im, &color); + break; + + case GD_CROP_DEFAULT: + default: + color = gdImageGetTransparent(im); + break; + } + + for (x = 0, y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if (color != gdImageGetPixel(im, x, y)) { + goto break1; + } + } + } +break1: + + /* Whole image would be cropped > bye */ + if (y == height && x == width) { + return NULL; + } + + crop.y = y; + + for (y = height - 1; y >= 0; y--) { + for (x = 0; x < width; x++) { + if (color != gdImageGetPixel(im, x, y)) { + goto break2; + } + } + } +break2: + + crop.height = y - crop.y + 1; + + for (x = 0; x < width; x++) { + for (y = crop.y; y < crop.y + crop.height; y++) { + if (color != gdImageGetPixel(im, x, y)) { + goto break3; + } + } + } +break3: + + crop.x = x; + + for (x = width - 1; x >= 0; x--) { + for (y = crop.y; y < crop.y + crop.height; y++) { + if (color != gdImageGetPixel(im, x, y)) { + goto break4; + } + } + } +break4: + + crop.width = x - crop.x + 1; + + return gdImageCrop(im, &crop); } -/*TODOs: Implement DeltaE instead, way better perceptual differences */ + /** - * Function: gdImageThresholdCrop - * Crop an image using a given color. The threshold argument defines - * the tolerance to be used while comparing the image color and the - * color to crop. The method used to calculate the color difference - * is based on the color distance in the RGB(a) cube. + * Function: gdImageCropThreshold + * + * Crop an image using a given color * + * The _threshold_ defines the tolerance to be used while comparing the image + * color and the color to crop. The method used to calculate the color + * difference is based on the color distance in the RGB(A) cube. * * Parameters: - * im - Source image - * color - color to crop - * threshold - tolerance (0..100) + * im - The image. + * color - The crop color. + * threshold - The crop threshold. * * Returns: - * on success or NULL + * The newly created cropped image, or NULL on failure. * * See also: - * , or + * - + * - */ -gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold) +BGD_DECLARE(gdImagePtr) +gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold) { - const int width = gdImageSX(im); - const int height = gdImageSY(im); - - int x,y; - int match; - gdRect crop; - - crop.x = 0; - crop.y = 0; - crop.width = 0; - crop.height = 0; - - /* Pierre: crop everything sounds bad */ - if (threshold > 100.0) { - return NULL; - } - - if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) { - return NULL; - } - - /* TODO: Add gdImageGetRowPtr and works with ptr at the row level - * for the true color and palette images - * new formats will simply work with ptr - */ - match = 1; - for (y = 0; match && y < height; y++) { - for (x = 0; match && x < width; x++) { - match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; - } - } - - /* Whole image would be cropped > bye */ - if (match) { - return NULL; - } - - crop.y = y - 1; - - match = 1; - for (y = height - 1; match && y >= 0; y--) { - for (x = 0; match && x < width; x++) { - match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0; - } - } - crop.height = y - crop.y + 2; - - match = 1; - for (x = 0; match && x < width; x++) { - for (y = 0; match && y < crop.y + crop.height; y++) { - match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; - } - } - crop.x = x - 1; - - match = 1; - for (x = width - 1; match && x >= 0; x--) { - for (y = 0; match && y < crop.y + crop.height; y++) { - match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; - } - } - crop.width = x - crop.x + 2; - - return gdImageCrop(im, &crop); + const int width = gdImageSX(im); + const int height = gdImageSY(im); + + int x, y; + gdRect crop; + + crop.x = 0; + crop.y = 0; + crop.width = 0; + crop.height = 0; + + /* To crop everything sounds bad */ + if (threshold > 100.0) { + return NULL; + } + + if (!gdImageTrueColor(im) && color >= (unsigned int)gdImageColorsTotal(im)) { + return NULL; + } + + for (x = 0, y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if (!gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) { + goto break1; + } + } + } +break1: + + /* Whole image would be cropped > bye */ + if (y == height && x == width) { + return NULL; + } + + crop.y = y; + + for (y = height - 1; y >= 0; y--) { + for (x = 0; x < width; x++) { + if (!gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) { + goto break2; + } + } + } +break2: + + crop.height = y - crop.y + 1; + + for (x = 0; x < width; x++) { + for (y = crop.y; y < crop.y + crop.height; y++) { + if (!gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) { + goto break3; + } + } + } +break3: + + crop.x = x; + + for (x = width - 1; x >= 0; x--) { + for (y = crop.y; y < crop.y + crop.height; y++) { + if (!gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) { + goto break4; + } + } + } +break4: + + crop.width = x - crop.x + 1; + + return gdImageCrop(im, &crop); } /* This algorithm comes from pnmcrop (http://netpbm.sourceforge.net/) @@ -254,64 +276,48 @@ gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const f */ static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color) { - const int tl = gdImageGetPixel(im, 0, 0); - const int tr = gdImageGetPixel(im, gdImageSX(im) - 1, 0); - const int bl = gdImageGetPixel(im, 0, gdImageSY(im) -1); - const int br = gdImageGetPixel(im, gdImageSX(im) - 1, gdImageSY(im) -1); - - if (tr == bl && tr == br) { - *color = tr; - return 3; - } else if (tl == bl && tl == br) { - *color = tl; - return 3; - } else if (tl == tr && tl == br) { - *color = tl; - return 3; - } else if (tl == tr && tl == bl) { - *color = tl; - return 3; - } else if (tl == tr || tl == bl || tl == br) { - *color = tl; - return 2; - } else if (tr == bl || tr == br) { - *color = tr; - return 2; - } else if (br == bl) { - *color = bl; - return 2; - } else { - register int r,b,g,a; - - r = (int)(0.5f + (gdImageRed(im, tl) + gdImageRed(im, tr) + gdImageRed(im, bl) + gdImageRed(im, br)) / 4); - g = (int)(0.5f + (gdImageGreen(im, tl) + gdImageGreen(im, tr) + gdImageGreen(im, bl) + gdImageGreen(im, br)) / 4); - b = (int)(0.5f + (gdImageBlue(im, tl) + gdImageBlue(im, tr) + gdImageBlue(im, bl) + gdImageBlue(im, br)) / 4); - a = (int)(0.5f + (gdImageAlpha(im, tl) + gdImageAlpha(im, tr) + gdImageAlpha(im, bl) + gdImageAlpha(im, br)) / 4); - *color = gdImageColorClosestAlpha(im, r, g, b, a); - return 0; - } -} - -static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold) -{ - const int dr = gdImageRed(im, col1) - gdImageRed(im, col2); - const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2); - const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2); - const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2); - const int dist = dr * dr + dg * dg + db * db + da * da; - - return (100.0 * dist / 195075) < threshold; -} - -/* - * To be implemented when we have more image formats. - * Buffer like gray8 gray16 or rgb8 will require some tweak - * and can be done in this function (called from the autocrop - * function. (Pierre) - */ -#if 0 -static int colors_equal (const int col1, const in col2) -{ - + const int tl = gdImageGetPixel(im, 0, 0); + const int tr = gdImageGetPixel(im, gdImageSX(im) - 1, 0); + const int bl = gdImageGetPixel(im, 0, gdImageSY(im) - 1); + const int br = gdImageGetPixel(im, gdImageSX(im) - 1, gdImageSY(im) - 1); + + if (tr == bl && tr == br) { + *color = tr; + return 3; + } else if (tl == bl && tl == br) { + *color = tl; + return 3; + } else if (tl == tr && tl == br) { + *color = tl; + return 3; + } else if (tl == tr && tl == bl) { + *color = tl; + return 3; + } else if (tl == tr || tl == bl || tl == br) { + *color = tl; + return 2; + } else if (tr == bl || tr == br) { + *color = tr; + return 2; + } else if (br == bl) { + *color = bl; + return 2; + } else { + register int r, b, g, a; + + r = (2 + gdImageRed(im, tl) + gdImageRed(im, tr) + gdImageRed(im, bl) + + gdImageRed(im, br)) / + 4; + g = (2 + gdImageGreen(im, tl) + gdImageGreen(im, tr) + gdImageGreen(im, bl) + + gdImageGreen(im, br)) / + 4; + b = (2 + gdImageBlue(im, tl) + gdImageBlue(im, tr) + gdImageBlue(im, bl) + + gdImageBlue(im, br)) / + 4; + a = (2 + gdImageAlpha(im, tl) + gdImageAlpha(im, tr) + gdImageAlpha(im, bl) + + gdImageAlpha(im, br)) / + 4; + *color = gdImageColorClosestAlpha(im, r, g, b, a); + return 0; + } } -#endif diff --git a/ext/gd/libgd/gd_draw.c b/ext/gd/libgd/gd_draw.c new file mode 100644 index 000000000000..444d53bff84e --- /dev/null +++ b/ext/gd/libgd/gd_draw.c @@ -0,0 +1,483 @@ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd_intern.h" + +/* 2.03: don't include zlib here or we can't build without PNG */ +#include "gd_color.h" +#include "gd_compositor.h" +#include "gd_draw_blend.h" +#include "gd_errors.h" +#include "gd_path.h" +#include "gd_path_dash.h" +#include "gd_path_matrix.h" +#include "gd_span_rle.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +/* Conversion helpers: legacy gdImage truecolor <-> premultiplied ARGB32 */ +static inline uint32_t gdcolor_to_premul(int gdcolor) +{ + return gdCompositePixelToArgb32(gdCompositePixelFromGd(gdcolor)); +} + +static inline int premul_to_gdcolor(uint32_t pm) +{ + return gdCompositePixelToGd(gdCompositePixelFromArgb32(pm)); +} + +BGD_DECLARE(void) +gdContextSetSourceRgba(gdContextPtr context, double r, double g, double b, double a) +{ + gdPaintPtr source = gdPaintCreateRgba(r, g, b, a); + gdContextSetSource(context, source); + gdPaintDestroy(source); +} + +BGD_DECLARE(void) +gdContextSetSourceRgb(gdContextPtr context, double r, double g, double b) +{ + gdPaintPtr source = gdPaintCreateRgba(r, g, b, 1.0); + gdContextSetSource(context, source); + gdPaintDestroy(source); +} + +GD_VECTOR2D_INTERNAL void gdContextSetSourceSurface(gdContextPtr context, gdSurfacePtr surface, + double x, double y) +{ + gdPaintSetSourceSurface(context, surface, x, y); +} + +BGD_DECLARE(void) +gdContextSetSourceImage(gdContextPtr context, gdImagePtr image, double x, double y) +{ + gdPathPatternPtr pattern; + gdPaintPtr paint; + gdPathMatrix matrix; + + if (!context || !image) + return; + pattern = gdPathPatternCreateForImage(image); + if (!pattern) + return; + gdPathMatrixInitTranslate(&matrix, x, y); + gdPathPatternSetMatrix(pattern, &matrix); + paint = gdPaintCreateFromPattern(pattern); + gdPathPatternDestroy(pattern); + if (!paint) + return; + gdContextSetSource(context, paint); + gdPaintDestroy(paint); +} + +BGD_DECLARE(void) +gdContextSetOperator(gdContextPtr context, gdCompositeOperator op) +{ + if (!context) + return; + if (!gdCompositeOperatorIsValid(op)) { + gd_error("gdContextSetOperator: invalid operator %d.\n", (int)op); + return; + } + context->state->op = op; +} + +BGD_DECLARE(void) +gdContextSetOpacity(gdContextPtr context, double opacity) +{ + if (!context || !isfinite(opacity)) + return; + context->state->opacity = CLAMP(opacity, 0.0, 1.0); +} + +BGD_DECLARE(void) +gdContextNewPath(gdContextPtr context) { gdPathClear(context->path); } + +BGD_DECLARE(void) gdContextAppendPath(gdContextPtr cr, gdPathPtr source) +{ + gdPathAppendPath(cr->path, source); +} + +GD_VECTOR2D_INTERNAL gdContextPtr gdContextCreate(gdSurfacePtr surface) +{ + gdContextPtr context = gdMalloc(sizeof(gdContext)); + if (!context) { + return NULL; + } + context->state = gdStateCreate(); + if (!context->state) { + goto failState; + } + context->path = gdPathCreate(); + if (!context->path) { + goto failPath; + } + context->rle = gdSpanRleCreate(); + if (!context->rle) { + goto failRle; + } + context->ref = 1; + context->surface = gdSurfaceAddRef(surface); + context->image = NULL; + context->clippath = NULL; + context->clip.x = 0.0; + context->clip.y = 0.0; + context->clip.w = surface->width; + context->clip.h = surface->height; + return context; +failRle: + gdFree(context->path); +failPath: + gdFree(context->state); +failState: + gdFree(context); + return NULL; +} + +BGD_DECLARE(gdContextPtr) +gdContextCreateForImage(gdImagePtr im) +{ + if (!im || !im->trueColor) { + return NULL; + } + + gdSurfacePtr scratch = gdSurfaceCreate(im->sx, im->sy, GD_SURFACE_ARGB32); + if (!scratch) { + return NULL; + } + + for (int y = 0; y < im->sy; y++) { + uint32_t *dst = (uint32_t *)(scratch->data + y * scratch->stride); + for (int x = 0; x < im->sx; x++) { + dst[x] = gdcolor_to_premul(im->tpixels[y][x]); + } + } + + gdContextPtr ctx = gdContextCreate(scratch); + if (!ctx) { + gdSurfaceDestroy(scratch); + return NULL; + } + gdSurfaceDestroy(scratch); + + ctx->image = im; + ctx->imageOwned = 0; + return ctx; +} + +BGD_DECLARE(void) +gdContextFlushImage(gdContextPtr ctx) +{ + if (!ctx || !ctx->image) { + return; + } + gdImagePtr im = ctx->image; + gdSurfacePtr scratch = ctx->surface; + + for (int y = 0; y < im->sy; y++) { + uint32_t *src = (uint32_t *)(scratch->data + y * scratch->stride); + for (int x = 0; x < im->sx; x++) { + im->tpixels[y][x] = premul_to_gdcolor(src[x]); + } + } +} + +BGD_DECLARE(gdImagePtr) +gdContextGetImage(gdContextPtr ctx) { return ctx ? ctx->image : NULL; } + +BGD_DECLARE(void) +gdContextStrokePreserve(gdContextPtr context) +{ + gdStatePtr state = context->state; + gdSpanRleClear(context->rle); + gdSpanRleRasterize(context->rle, context->path, &state->matrix, &context->clip, &state->stroke, + gdFillRuleNonZero); + if (!gdCompositeOperatorIsUnbounded(state->op)) + gdSpanRlePathClip(context->rle, state->clippath); + gdPathBlend(context, context->rle); +} + +BGD_DECLARE(void) +gdContextFillPreserve(gdContextPtr context) +{ + gdStatePtr state = context->state; + gdSpanRleClear(context->rle); + // gdPathDumpPathTransform(context->path, NULL); + gdSpanRleRasterize(context->rle, context->path, &state->matrix, &context->clip, NULL, + state->winding); + if (!gdCompositeOperatorIsUnbounded(state->op)) + gdSpanRlePathClip(context->rle, state->clippath); + gdPathBlend(context, context->rle); +} + +BGD_DECLARE(void) +gdContextFill(gdContextPtr context) +{ + gdContextFillPreserve(context); + gdContextNewPath(context); +} + +BGD_DECLARE(int) +gdContextClipPreserve(gdContextPtr context) +{ + unsigned int context_path_size; + gdPathPtr currentPath; + gdStatePtr state; + gdSpanRlePtr newclip; + + if (context == NULL) { + gd_error("gdContextClipPreserve: context must not be NULL"); + return 0; + } + currentPath = context->path; + state = context->state; + context_path_size = gdArrayNumElements(¤tPath->elements); + + if (context_path_size == 0) + return 1; + + gdSpanRleClear(context->rle); + gdSpanRleRasterize(context->rle, context->path, &state->matrix, &context->clip, NULL, + state->winding); + if (state->clippath) { + newclip = gdSpanHorizontalClip(state->clippath, context->rle); + } else { + newclip = gdSpanRleClone(context->rle); + } + if (!newclip) { + gd_error("gdContextClipPreserve: failed to allocate clip state"); + return 0; + } + gdSpanRleDestroy(state->clippath); + state->clippath = newclip; + return 1; +} + +BGD_DECLARE(void) +gdContextPaint(gdContextPtr context) +{ + gdSpanRlePtr rle; + gdStatePtr state = context->state; + if (state->clippath == NULL && context->clippath == NULL) { + gdPathPtr path = gdPathCreate(); + gdPathRectangle(path, context->clip.x, context->clip.y, context->clip.w, context->clip.h); + context->clippath = gdSpanRleCreate(); + gdSpanRleRasterize(context->clippath, path, &state->matrix, &context->clip, NULL, + gdFillRuleNonZero); + gdPathDestroy(path); + } + rle = state->clippath ? state->clippath : context->clippath; + gdPathBlend(context, rle); +} + +BGD_DECLARE(int) +gdContextClip(gdContextPtr context) +{ + if (!gdContextClipPreserve(context)) + return 0; + gdContextNewPath(context); + return 1; +} + +BGD_DECLARE(int) +gdContextSave(gdContextPtr context) +{ + gdStatePtr current; + gdStatePtr saved; + + if (context == NULL) { + gd_error("gdContextSave: context must not be NULL"); + return 0; + } + current = context->state; + saved = gdMalloc(sizeof(gdState)); + if (!saved) { + gd_error("gdContextSave: failed to allocate graphics state"); + return 0; + } + *saved = *current; + saved->source = gdPaintAddRef(current->source); + saved->clippath = gdSpanRleRetain(current->clippath); + saved->stroke.dash = gdPathDashClone(current->stroke.dash); + if (current->stroke.dash != NULL && saved->stroke.dash == NULL) { + gdSpanRleDestroy(saved->clippath); + gdPaintDestroy(saved->source); + gdFree(saved); + gd_error("gdContextSave: failed to clone dash state"); + return 0; + } + saved->next = current; + context->state = saved; + return 1; +} + +BGD_DECLARE(int) +gdContextRestore(gdContextPtr context) +{ + gdStatePtr restored; + + if (context == NULL) { + gd_error("gdContextRestore: context must not be NULL"); + return 0; + } + if (context->state->next == NULL) { + gd_error("gdContextRestore: no saved graphics state"); + return 0; + } + restored = context->state->next; + context->state->next = NULL; + gdStateDestroy(context->state); + context->state = restored; + return 1; +} + +BGD_DECLARE(void) +gdContextDestroy(gdContextPtr context) +{ + if (context == NULL) + return; + context->ref--; + if (context->ref == 0) { + if (context->image) { + gdContextFlushImage(context); + } + gdSurfaceDestroy(context->surface); + gdPathDestroy(context->path); + while (context->state) { + gdStatePtr next = context->state->next; + context->state->next = NULL; + gdStateDestroy(context->state); + context->state = next; + } + gdSpanRleDestroy(context->clippath); + gdSpanRleDestroy(context->rle); + gdFree(context); + } +} + +BGD_DECLARE(void) +gdContextMoveTo(gdContextPtr context, double x, double y) { gdPathMoveTo(context->path, x, y); } + +BGD_DECLARE(void) +gdContextRelMoveTo(gdContextPtr context, double dx, double dy) +{ + gdPathRelMoveTo(context->path, dx, dy); +} + +BGD_DECLARE(void) +gdContextLineTo(gdContextPtr context, double x, double y) { gdPathLineTo(context->path, x, y); } + +BGD_DECLARE(void) +gdContextRelLineTo(gdContextPtr context, double dx, double dy) +{ + gdPathRelLineTo(context->path, dx, dy); +} + +BGD_DECLARE(void) +gdContextSetLineWidth(gdContextPtr context, double width) { context->state->stroke.width = width; } + +BGD_DECLARE(void) +gdContextSetDash(gdContextPtr context, double offset, const double *data, int size) +{ + gdPathDashDestroy(context->state->stroke.dash); + context->state->stroke.dash = gdPathDashCreate(data, size, offset); +} + +BGD_DECLARE(void) +gdContextSetLineCap(gdContextPtr context, gdLineCap cap) { context->state->stroke.cap = cap; } + +BGD_DECLARE(void) +gdContextSetLineJoin(gdContextPtr context, gdLineJoin join) { context->state->stroke.join = join; } + +BGD_DECLARE(void) +gdContextCurveTo(gdContextPtr context, double x1, double y1, double x2, double y2, double x3, + double y3) +{ + gdPathCurveTo(context->path, x1, y1, x2, y2, x3, y3); +} + +BGD_DECLARE(void) +gdContextRelCurveTo(gdContextPtr context, double dx1, double dy1, double dx2, double dy2, + double dx3, double dy3) +{ + gdPathRelCurveTo(context->path, dx1, dy1, dx2, dy2, dx3, dy3); +} + +BGD_DECLARE(void) +gdContextQuadTo(gdContextPtr context, double x1, double y1, double x2, double y2) +{ + gdPathQuadTo(context->path, x1, y1, x2, y2); +} + +BGD_DECLARE(void) +gdContextRelQuadTo(gdContextPtr context, double dx1, double dy1, double dx2, double dy2) +{ + gdPathRelQuadTo(context->path, dx1, dy1, dx2, dy2); +} + +BGD_DECLARE(void) +gdContextArc(gdContextPtr context, double cx, double cy, double r, double a0, double a1) +{ + gdPathArc(context->path, cx, cy, r, a0, a1); +} + +BGD_DECLARE(void) +gdContextNegativeArc(gdContextPtr context, double cx, double cy, double r, double a0, double a1) +{ + gdPathNegativeArc(context->path, cx, cy, r, a0, a1); +} + +BGD_DECLARE(void) +gdContextRectangle(gdContextPtr context, double x, double y, double w, double h) +{ + gdPathRectangle(context->path, x, y, w, h); +} + +BGD_DECLARE(void) +gdContextClosePath(gdContextPtr context) +{ + if (!context) + return; + gdPathClose(context->path); +} + +BGD_DECLARE(void) +gdContextScale(gdContextPtr context, double x, double y) +{ + gdPathMatrixScale(&context->state->matrix, x, y); +} + +BGD_DECLARE(void) +gdContextTranslate(gdContextPtr context, double x, double y) +{ + gdPathMatrixTranslate(&context->state->matrix, x, y); +} + +BGD_DECLARE(void) +gdContextRotate(gdContextPtr context, double radians) +{ + gdPathMatrixRotate(&context->state->matrix, radians); +} + +BGD_DECLARE(void) +gdContextTransform(gdContextPtr context, const gdPathMatrixPtr matrix) +{ + gdPathMatrixMultiply(&context->state->matrix, matrix, &context->state->matrix); +} + +BGD_DECLARE(void) +gdContextSetFillRule(gdContextPtr context, gdFillRule winding) +{ + context->state->winding = winding; +} + +BGD_DECLARE(void) +gdContextStroke(gdContextPtr context) +{ + gdContextStrokePreserve(context); + gdContextNewPath(context); +} diff --git a/ext/gd/libgd/gd_draw_blend.c b/ext/gd/libgd/gd_draw_blend.c new file mode 100644 index 000000000000..48b35a228985 --- /dev/null +++ b/ext/gd/libgd/gd_draw_blend.c @@ -0,0 +1,788 @@ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_errors.h" +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "gd_array.h" +#include "gd_path_matrix.h" +#include "gd_span_rle.h" +#include "gd_surface.h" + +#include "gd_compositor.h" +#include "gd_fixed.h" +#include "gd_gradient.h" + +#define BILINEAR_INTERPOLATION_BITS 7 +#define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS) + +#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v))) +#define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b)) + +static inline int _fixed_to_bilinear_weight(gd_fixed_t x) +{ + return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & ((1 << BILINEAR_INTERPOLATION_BITS) - 1); +} + +static inline uint32_t fetch_pixel_general(gdSurfacePtr surface, int x, int y, int check_bounds) +{ + if (check_bounds && (x < 0 || x >= surface->width || y < 0 || y >= surface->height)) { + return 0; + } + + uint32_t *src = (uint32_t *)(surface->data); + return src[y * surface->stride / 4 + x]; +} + +static inline uint32_t bilinear_interpolation(uint32_t tl, uint32_t tr, uint32_t bl, uint32_t br, + int distx, int disty) +{ + uint64_t distxy, distxiy, distixy, distixiy; + uint64_t tl64, tr64, bl64, br64; + uint64_t f, r; + + if (tl == tr && tl == bl && tl == br) + return tl; + + distx <<= (8 - BILINEAR_INTERPOLATION_BITS); + disty <<= (8 - BILINEAR_INTERPOLATION_BITS); + + distxy = (uint64_t)distx * disty; + distxiy = (uint64_t)distx * (256 - disty); + distixy = (uint64_t)(256 - distx) * disty; + distixiy = (uint64_t)(256 - distx) * (256 - disty); + + /* Alpha and Blue */ + tl64 = tl & 0xff0000ff; + tr64 = tr & 0xff0000ff; + bl64 = bl & 0xff0000ff; + br64 = br & 0xff0000ff; + + f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; + r = f & 0x0000ff0000ff0000ull; + + /* Red and Green */ + tl64 = tl; + tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); + + tr64 = tr; + tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); + + bl64 = bl; + bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); + + br64 = br; + br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); + + f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; + r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); + + return (uint32_t)(r >> 16); +} + +static inline int _update_w_repeat(gdExtendMode repeat, int *c, int size) +{ + if (repeat == GD_EXTEND_NONE) { + if (*c < 0 || *c >= size) + return 0; + } else if (repeat == GD_EXTEND_REPEAT) { + while (*c >= size) + *c -= size; + while (*c < 0) + *c += size; + } else if (repeat == GD_EXTEND_PAD) { + *c = CLIP(*c, 0, size - 1); + } else /* REFLECT */ + { + *c = MOD(*c, size * 2); + if (*c >= size) + *c = size * 2 - *c - 1; + } + return 1; +} + +static inline uint32_t _surface_fetch_pixel_bilinear(gdSurfacePtr image, gd_fixed_t x, gd_fixed_t y, + gdExtendMode repeat_mode) +{ + int width = image->width; + int height = image->height; + int x1, y1, x2, y2; + uint32_t tl, tr, bl, br; + int32_t distx, disty; + + x1 = x - gd_fixed_1 / 2; + y1 = y - gd_fixed_1 / 2; + + distx = _fixed_to_bilinear_weight(x1); + disty = _fixed_to_bilinear_weight(y1); + x1 = gd_fixed_to_int(x1); + y1 = gd_fixed_to_int(y1); + x2 = x1 + 1; + y2 = y1 + 1; + if (repeat_mode != GD_EXTEND_NONE) { + _update_w_repeat(repeat_mode, &x1, width); + _update_w_repeat(repeat_mode, &y1, height); + _update_w_repeat(repeat_mode, &x2, width); + _update_w_repeat(repeat_mode, &y2, height); + + tl = fetch_pixel_general(image, x1, y1, 0); + bl = fetch_pixel_general(image, x1, y2, 0); + tr = fetch_pixel_general(image, x2, y1, 0); + br = fetch_pixel_general(image, x2, y2, 0); + } else { + tl = fetch_pixel_general(image, x1, y1, 1); + tr = fetch_pixel_general(image, x2, y1, 1); + bl = fetch_pixel_general(image, x1, y2, 1); + br = fetch_pixel_general(image, x2, y2, 1); + } + return bilinear_interpolation(tl, tr, bl, br, distx, disty); +} + +#define ALPHA(c) ((c) >> 24) +static void operator_argb_color_source(uint32_t *dest, int length, uint32_t color, uint32_t alpha) +{ + gdPremulPixelF src = gdCompositePixelFromArgb32(color); + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32(gdCompositePixel( + GD_OP_SOURCE, src, gdCompositePixelFromArgb32(dest[i]), alpha / 255.0f)); +} + +static void operator_argb_color_source_over(uint32_t *dest, int length, uint32_t color, + uint32_t const_alpha) +{ + gdPremulPixelF src = gdCompositePixelFromArgb32(color); + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32(gdCompositePixel( + GD_OP_OVER, src, gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void operator_argb_color_destination_in(uint32_t *dest, int length, uint32_t color, + uint32_t const_alpha) +{ + gdPremulPixelF src = gdCompositePixelFromArgb32(color); + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32(gdCompositePixel( + GD_OP_DEST_IN, src, gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void operator_argb_color_destination_out(uint32_t *dest, int length, uint32_t color, + uint32_t const_alpha) +{ + gdPremulPixelF src = gdCompositePixelFromArgb32(color); + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32(gdCompositePixel( + GD_OP_DEST_OUT, src, gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void operator_argb_color(gdCompositeOperator op, uint32_t *dest, int length, uint32_t color, + uint32_t alpha) +{ + gdPremulPixelF src = gdCompositePixelFromArgb32(color); + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32( + gdCompositePixel(op, src, gdCompositePixelFromArgb32(dest[i]), alpha / 255.0f)); +} + +#define spanBlendLoop(func) \ + while (count--) { \ + uint32_t *target = \ + (uint32_t *)(surface->data + currentSpan->y * surface->stride) + currentSpan->x; \ + func(target, currentSpan->len, color, currentSpan->coverage); \ + ++currentSpan; \ + }; + +static void argb32_blend_color(gdSurfacePtr surface, gdImageOp op, const gdSpanRlePtr rle, + uint32_t color) +{ + int count = rle->spans.size; + gdSpanPtr currentSpan = rle->spans.data; + switch (op) { + case gdImageOpsSrc: + spanBlendLoop(operator_argb_color_source); + break; + case gdImageOpsSrcOver: + spanBlendLoop(operator_argb_color_source_over); + break; + case gdImageOpsDstIn: + spanBlendLoop(operator_argb_color_destination_in); + break; + case gdImageOpsDstOut: + spanBlendLoop(operator_argb_color_destination_out); + break; + default: + while (count--) { + uint32_t *target = + (uint32_t *)(surface->data + currentSpan->y * surface->stride) + currentSpan->x; + operator_argb_color(op, target, currentSpan->len, color, currentSpan->coverage); + ++currentSpan; + } + break; + } +} + +static inline uint32_t premultiply_color(const gdColorPtr color, double opacity) +{ + const double a = color->a * opacity; + const uint32_t alpha = (uint8_t)floor(a * 255.0 + 0.5); + const uint32_t pr = (uint8_t)floor(color->r * a * 255.0 + 0.5); + const uint32_t pg = (uint8_t)floor(color->g * a * 255.0 + 0.5); + const uint32_t pb = (uint8_t)floor(color->b * a * 255.0 + 0.5); + + return (alpha << 24) | (pr << 16) | (pg << 8) | (pb); +} + +#define _getVarName(var) #var +void gdBlendColor(gdContextPtr context, const gdSpanRlePtr rle, const gdColorPtr color) +{ + if (color == NULL) + return; + + gdStatePtr state = context->state; + // replace once we have more than + switch (context->surface->type) { + case GD_SURFACE_ARGB32: { + uint32_t pm_color = premultiply_color(color, state->opacity); + argb32_blend_color(context->surface, state->op, rle, pm_color); + break; + } + case GD_SURFACE_XRGB32: + case GD_SURFACE_A8: + gd_error("gdDraw does not implement %s yet.\n", _getVarName(GD_SURFACE_XRGB32)); + break; + default: + gd_error("gdDraw: provided surface has an unknown type.\n"); + return; + } +} + +typedef struct { + gdPathMatrix matrix; + gdExtendMode extend; + uint8_t *data; + gdSurfacePtr surface; + int width; + int height; + int stride; + int alpha; +} _spans_pattern; + +// TODO: Once the rest is a tat bit faster, use func ptr for all but *_compose_source +// Macros are not an option, unreadable and painful to debug. +static void argb32_compose_source(uint32_t *dest, int length, const uint32_t *src, + uint32_t const_alpha) +{ + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32( + gdCompositePixel(GD_OP_SOURCE, gdCompositePixelFromArgb32(src[i]), + gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void argb32_compose_source_over(uint32_t *dest, int length, const uint32_t *src, + uint32_t const_alpha) +{ + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32( + gdCompositePixel(GD_OP_OVER, gdCompositePixelFromArgb32(src[i]), + gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void argb32_compose_dst_out(uint32_t *dest, int length, const uint32_t *src, + uint32_t const_alpha) +{ + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32( + gdCompositePixel(GD_OP_DEST_OUT, gdCompositePixelFromArgb32(src[i]), + gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void argb32_compose_dst_in(uint32_t *dest, int length, const uint32_t *src, + uint32_t const_alpha) +{ + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32( + gdCompositePixel(GD_OP_DEST_IN, gdCompositePixelFromArgb32(src[i]), + gdCompositePixelFromArgb32(dest[i]), const_alpha / 255.0f)); +} + +static void argb32_compose(gdCompositeOperator op, uint32_t *dest, int length, const uint32_t *src, + uint32_t const_alpha) +{ + for (int i = 0; i < length; i++) + dest[i] = gdCompositePixelToArgb32(gdCompositePixel(op, gdCompositePixelFromArgb32(src[i]), + gdCompositePixelFromArgb32(dest[i]), + const_alpha / 255.0f)); +} + +#define BUFFER_SIZE 1024 +static void render_spans_compose_source(const gdSurface *surface, const _spans_pattern *pattern, + uint32_t *buffer, const gdExtendMode extend, int fdx, + int fdy, int count, gdSpanPtr spans) +{ + while (count--) { + uint32_t *target = (uint32_t *)(surface->data + spans->y * surface->stride) + spans->x; + const double cx = spans->x + 0.5; + const double cy = spans->y + 0.5; + int x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + int y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + const int coverage = (spans->coverage * pattern->alpha + 127) / 255; + int length = spans->len; + while (length) { + int l = MIN(length, BUFFER_SIZE); + const uint32_t *end = buffer + l; + uint32_t *b = buffer; + while (b < end) { + *b = _surface_fetch_pixel_bilinear(pattern->surface, x, y, extend); + x += fdx; + y += fdy; + ++b; + } + argb32_compose_source(target, l, buffer, coverage); + target += l; + length -= l; + } + ++spans; + } +} + +static void render_spans_compose_source_over(const gdSurface *surface, + const _spans_pattern *pattern, uint32_t *buffer, + const gdExtendMode extend, int fdx, int fdy, int count, + gdSpanPtr spans) +{ + while (count--) { + uint32_t *target = (uint32_t *)(surface->data + spans->y * surface->stride) + spans->x; + const double cx = spans->x + 0.5; + const double cy = spans->y + 0.5; + int x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + int y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + const int coverage = (spans->coverage * pattern->alpha + 127) / 255; + int length = spans->len; + while (length) { + int l = MIN(length, BUFFER_SIZE); + const uint32_t *end = buffer + l; + uint32_t *b = buffer; + while (b < end) { + *b = _surface_fetch_pixel_bilinear(pattern->surface, x, y, extend); + x += fdx; + y += fdy; + ++b; + } + argb32_compose_source_over(target, l, buffer, coverage); + target += l; + length -= l; + } + ++spans; + } +} + +static void render_spans_compose_dst_in(const gdSurface *surface, const _spans_pattern *pattern, + uint32_t *buffer, const gdExtendMode extend, int fdx, + int fdy, int count, gdSpanPtr spans) +{ + while (count--) { + uint32_t *target = (uint32_t *)(surface->data + spans->y * surface->stride) + spans->x; + const double cx = spans->x + 0.5; + const double cy = spans->y + 0.5; + int x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + int y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + const int coverage = (spans->coverage * pattern->alpha + 127) / 255; + int length = spans->len; + while (length) { + int l = MIN(length, BUFFER_SIZE); + const uint32_t *end = buffer + l; + uint32_t *b = buffer; + while (b < end) { + *b = _surface_fetch_pixel_bilinear(pattern->surface, x, y, extend); + x += fdx; + y += fdy; + ++b; + } + argb32_compose_dst_in(target, l, buffer, coverage); + target += l; + length -= l; + } + ++spans; + } +} + +static void render_spans_compose_dst_out(const gdSurface *surface, const _spans_pattern *pattern, + uint32_t *buffer, const gdExtendMode extend, int fdx, + int fdy, int count, gdSpanPtr spans) +{ + while (count--) { + uint32_t *target = (uint32_t *)(surface->data + spans->y * surface->stride) + spans->x; + const double cx = spans->x + 0.5; + const double cy = spans->y + 0.5; + int x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + int y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + const int coverage = (spans->coverage * pattern->alpha + 127) / 255; + int length = spans->len; + while (length) { + int l = MIN(length, BUFFER_SIZE); + const uint32_t *end = buffer + l; + uint32_t *b = buffer; + while (b < end) { + *b = _surface_fetch_pixel_bilinear(pattern->surface, x, y, extend); + x += fdx; + y += fdy; + ++b; + } + argb32_compose_dst_out(target, l, buffer, coverage); + target += l; + length -= l; + } + ++spans; + } +} + +static void render_spans_compose(const gdSurface *surface, gdCompositeOperator op, + const _spans_pattern *pattern, uint32_t *buffer, + gdExtendMode extend, int fdx, int fdy, int count, gdSpanPtr spans) +{ + while (count--) { + uint32_t *target = (uint32_t *)(surface->data + spans->y * surface->stride) + spans->x; + const double cx = spans->x + 0.5; + const double cy = spans->y + 0.5; + int x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + int y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + int coverage = (spans->coverage * pattern->alpha + 127) / 255; + int length = spans->len; + while (length) { + int l = MIN(length, BUFFER_SIZE); + for (int i = 0; i < l; i++) { + buffer[i] = _surface_fetch_pixel_bilinear(pattern->surface, x, y, extend); + x += fdx; + y += fdy; + } + argb32_compose(op, target, l, buffer, coverage); + target += l; + length -= l; + } + ++spans; + } +} + +static void argb32_pattern_tiled_blend_transformed(gdSurfacePtr surface, gdImageOp op, + const gdSpanRlePtr rle, + const _spans_pattern *pattern) +{ + uint32_t buffer[BUFFER_SIZE]; + const gdExtendMode extend = pattern->extend; + int fdx = gd_double_to_fixed(pattern->matrix.m00); + int fdy = gd_double_to_fixed(pattern->matrix.m10); + int count = rle->spans.size; + gdSpanPtr spans = rle->spans.data; + switch (op) { + case gdImageOpsSrc: + render_spans_compose_source(surface, pattern, buffer, extend, fdx, fdy, count, spans); + break; + case gdImageOpsSrcOver: + render_spans_compose_source_over(surface, pattern, buffer, extend, fdx, fdy, count, spans); + break; + case gdImageOpsDstIn: + render_spans_compose_dst_in(surface, pattern, buffer, extend, fdx, fdy, count, spans); + break; + case gdImageOpsDstOut: + render_spans_compose_dst_out(surface, pattern, buffer, extend, fdx, fdy, count, spans); + break; + default: + render_spans_compose(surface, op, pattern, buffer, extend, fdx, fdy, count, spans); + break; + } +} + +#define spans_untransformed_blend_loop(composition) \ + while (count--) { \ + int x = spans->x; \ + int length = spans->len; \ + int sx = xoff + x; \ + int sy = yoff + spans->y; \ + if (sy >= 0 && sy < image_height && sx < image_width) { \ + if (sx < 0) { \ + x -= sx; \ + length += sx; \ + sx = 0; \ + } \ + if (sx + length > image_width) \ + length = image_width - sx; \ + if (length > 0) { \ + const int coverage = (spans->coverage * pattern->alpha + 127) / 255; \ + const uint32_t *src = \ + (const uint32_t *)(pattern->data + sy * pattern->stride) + sx; \ + uint32_t *dest = (uint32_t *)(surface->data + spans->y * surface->stride) + x; \ + composition(dest, length, src, coverage); \ + } \ + } \ + ++spans; \ + } + +static void argb32_pattern_blend_untransformed(gdSurfacePtr surface, gdImageOp op, + const gdSpanRlePtr rle, + const _spans_pattern *pattern) +{ + const int image_width = pattern->width; + const int image_height = pattern->height; + int xoff = (int)(pattern->matrix.m02); + int yoff = (int)(pattern->matrix.m12); + + int count = rle->spans.size; + gdSpanPtr spans = rle->spans.data; + + switch (op) { + case gdImageOpsSrc: + spans_untransformed_blend_loop(argb32_compose_source); + break; + case gdImageOpsSrcOver: + spans_untransformed_blend_loop(argb32_compose_source_over); + break; + case gdImageOpsDstIn: + spans_untransformed_blend_loop(argb32_compose_dst_in); + break; + case gdImageOpsDstOut: + spans_untransformed_blend_loop(argb32_compose_dst_out); + break; + default: + while (count--) { + int x = spans->x; + int length = spans->len; + int sx = xoff + x; + int sy = yoff + spans->y; + if (sy >= 0 && sy < image_height && sx < image_width) { + if (sx < 0) { + x -= sx; + length += sx; + sx = 0; + } + if (sx + length > image_width) + length = image_width - sx; + if (length > 0) { + int coverage = (spans->coverage * pattern->alpha + 127) / 255; + const uint32_t *src = + (const uint32_t *)(pattern->data + sy * pattern->stride) + sx; + uint32_t *dest = (uint32_t *)(surface->data + spans->y * surface->stride) + x; + argb32_compose(op, dest, length, src, coverage); + } + } + ++spans; + } + } +} + +void gdDrawBlendPattern(gdContextPtr context, const gdSpanRlePtr rle, + const gdPathPatternPtr pattern) +{ + if (pattern == NULL) + return; + + gdStatePtr state = context->state; + _spans_pattern pattern_impl; + pattern_impl.extend = pattern->extend; + pattern_impl.data = pattern->surface->data; + pattern_impl.surface = pattern->surface; + pattern_impl.width = pattern->surface->width; + pattern_impl.height = pattern->surface->height; + pattern_impl.stride = pattern->surface->stride; + pattern_impl.alpha = (int)(state->opacity * pattern->opacity * 255.0 + 0.5); + + pattern_impl.matrix = pattern->matrix; + gdPathMatrixMultiply(&pattern_impl.matrix, &pattern_impl.matrix, &state->matrix); + gdPathMatrixInvert(&pattern_impl.matrix); + + const gdPathMatrixPtr matrix = &pattern_impl.matrix; + int translating = + (matrix->m00 == 1.0 && matrix->m10 == 0.0 && matrix->m01 == 0.0 && matrix->m11 == 1.0); + if (translating) { + if (pattern->extend == GD_EXTEND_NONE) + argb32_pattern_blend_untransformed(context->surface, state->op, rle, &pattern_impl); + else + argb32_pattern_tiled_blend_transformed(context->surface, state->op, rle, &pattern_impl); + } else { + if (pattern->extend == GD_EXTEND_NONE) + // argb32_pattern_blend_untransformed(context->surface, state->op, rle, &pattern_impl); + argb32_pattern_tiled_blend_transformed(context->surface, state->op, rle, &pattern_impl); + else + argb32_pattern_tiled_blend_transformed(context->surface, state->op, rle, &pattern_impl); + } +} + +static unsigned int rle_coverage_at(const gdSpanRlePtr rle, int x, int y, int *cursor) +{ + if (!rle) + return 255; + while (*cursor < rle->spans.size) { + const gdSpanPtr s = &rle->spans.data[*cursor]; + if (s->y < y || (s->y == y && s->x + s->len <= x)) { + (*cursor)++; + continue; + } + if (s->y == y && x >= s->x && x < s->x + s->len) + return s->coverage; + break; + } + return 0; +} + +static gdPremulPixelF pattern_pixel_at(const _spans_pattern *pattern, int px, int py) +{ + double cx = px + 0.5; + double cy = py + 0.5; + gd_fixed_t x = gd_double_to_fixed(pattern->matrix.m01 * cy + pattern->matrix.m00 * cx + + pattern->matrix.m02); + gd_fixed_t y = gd_double_to_fixed(pattern->matrix.m11 * cy + pattern->matrix.m10 * cx + + pattern->matrix.m12); + return gdCompositePixelFromArgb32( + _surface_fetch_pixel_bilinear(pattern->surface, x, y, pattern->extend)); +} + +typedef struct { + const gdGradient *gradient; + gdPathMatrix device_to_pattern; + int valid; +} gdGradientSampler; + +static void gradient_sampler_init(gdGradientSampler *s, const gdGradient *g, const gdStatePtr state) +{ + s->gradient = g; + s->device_to_pattern = g->matrix; + gdPathMatrixMultiply(&s->device_to_pattern, &s->device_to_pattern, &state->matrix); + s->valid = gdPathMatrixInvert(&s->device_to_pattern); +} + +static gdPremulPixelF gradient_pixel_at(const gdGradientSampler *s, int x, int y) +{ + gdPremulPixelF z = {0, 0, 0, 0}; + return s->valid ? gdGradientSample(s->gradient, &s->device_to_pattern, x + 0.5, y + 0.5) : z; +} + +static void gdDrawBlendGradient(gdContextPtr context, const gdSpanRlePtr rle, + const gdGradient *gradient) +{ + gdGradientSampler sampler; + gdStatePtr state = context->state; + int count = rle->spans.size; + gdSpanPtr span = rle->spans.data; + gradient_sampler_init(&sampler, gradient, state); + while (count--) { + uint32_t *dst = + (uint32_t *)(context->surface->data + span->y * context->surface->stride) + span->x; + float coverage = (float)(span->coverage / 255.0 * state->opacity); + for (int i = 0; i < span->len; i++) { + gdPremulPixelF src = gradient_pixel_at(&sampler, span->x + i, span->y); + gdPremulPixelF old = gdCompositePixelFromArgb32(dst[i]); + dst[i] = gdCompositePixelToArgb32(gdCompositePixel(state->op, src, old, coverage)); + } + span++; + } +} + +static gdPremulPixelF lerp_clip(gdPremulPixelF dst, gdPremulPixelF result, float coverage) +{ + gdPremulPixelF p; + p.r = dst.r + (result.r - dst.r) * coverage; + p.g = dst.g + (result.g - dst.g) * coverage; + p.b = dst.b + (result.b - dst.b) * coverage; + p.a = dst.a + (result.a - dst.a) * coverage; + return p; +} + +static void blend_unbounded(gdContextPtr context, const gdSpanRlePtr shape) +{ + gdStatePtr state = context->state; + gdPaintPtr source = state->source; + gdSpanRlePtr clip_path = state->clippath; + gdPremulPixelF solid = {0, 0, 0, 0}; + _spans_pattern pattern; + gdGradientSampler gradient; + float paint_opacity = (float)state->opacity; + int shape_cursor = 0, clip_cursor = 0; + int x0 = MAX(0, (int)floor(context->clip.x)); + int y0 = MAX(0, (int)floor(context->clip.y)); + int x1 = MIN(context->surface->width, (int)ceil(context->clip.x + context->clip.w)); + int y1 = MIN(context->surface->height, (int)ceil(context->clip.y + context->clip.h)); + + if (source->type == gdPaintTypeColor) { + solid = gdCompositePixelFromArgb32(premultiply_color(source->color, 1.0)); + } else if (source->type == gdPaintTypePattern) { + gdPathPatternPtr p = source->pattern; + pattern.extend = p->extend; + pattern.surface = p->surface; + pattern.matrix = p->matrix; + gdPathMatrixMultiply(&pattern.matrix, &pattern.matrix, &state->matrix); + gdPathMatrixInvert(&pattern.matrix); + paint_opacity *= (float)p->opacity; + } else if (source->type == gdPaintTypeGradient) { + gradient_sampler_init(&gradient, source->gradient, state); + } else { + gd_error("Paint method not implemented or does not exist."); + return; + } + + for (int y = y0; y < y1; y++) { + uint32_t *row = (uint32_t *)(context->surface->data + y * context->surface->stride); + for (int x = x0; x < x1; x++) { + float mask = rle_coverage_at(shape, x, y, &shape_cursor) / 255.0f; + float clip = clip_path ? rle_coverage_at(clip_path, x, y, &clip_cursor) / 255.0f : 1.0f; + gdPremulPixelF src = + source->type == gdPaintTypeColor + ? solid + : (source->type == gdPaintTypePattern ? pattern_pixel_at(&pattern, x, y) + : gradient_pixel_at(&gradient, x, y)); + gdPremulPixelF dst = gdCompositePixelFromArgb32(row[x]); + gdPremulPixelF result; + if (clip == 0.0f) + continue; + result = gdCompositePixel(state->op, src, dst, mask * paint_opacity); + if (clip < 1.0f) + result = lerp_clip(dst, result, clip); + row[x] = gdCompositePixelToArgb32(result); + } + } +} + +void gdPathBlend(gdContextPtr context, const gdSpanRlePtr rle) +{ + if (rle == NULL) + return; + + if (gdCompositeOperatorIsUnbounded(context->state->op) && rle == context->rle) { + blend_unbounded(context, rle); + return; + } + if (rle->spans.size == 0 || context->state->opacity == 0.0) + return; + + gdPaintPtr source = context->state->source; + switch (source->type) { + case gdPaintTypeColor: + gdBlendColor(context, rle, source->color); + break; + case gdPaintTypePattern: + gdDrawBlendPattern(context, rle, source->pattern); + break; + case gdPaintTypeGradient: + gdDrawBlendGradient(context, rle, source->gradient); + break; + case gdPaintTypeSurface: + default: + gd_error("Paint method not implemented or does not exist."); + break; + } +} diff --git a/ext/gd/libgd/gd_draw_blend.h b/ext/gd/libgd/gd_draw_blend.h new file mode 100644 index 000000000000..720bcb054e28 --- /dev/null +++ b/ext/gd/libgd/gd_draw_blend.h @@ -0,0 +1,7 @@ +#ifndef GD_DRAW_BLEND_H +#define GD_DRAW_BLEND_H + +void gdBlendColor(gdContextPtr context, const gdSpanRlePtr rle, const gdColorPtr color); +void gdPathBlend(gdContextPtr context, const gdSpanRlePtr rle); + +#endif // GD_DRAW_BLEND_H diff --git a/ext/gd/libgd/gd_errors.h b/ext/gd/libgd/gd_errors.h index 8a28bf605197..fb8a470e0da1 100644 --- a/ext/gd/libgd/gd_errors.h +++ b/ext/gd/libgd/gd_errors.h @@ -2,9 +2,9 @@ #define GD_ERRORS_H #ifndef _WIN32 -# include +#include #else -# include "win32/syslog.h" +#include "win32/syslog.h" #endif /* diff --git a/ext/gd/libgd/gd_filename.c b/ext/gd/libgd/gd_filename.c new file mode 100644 index 000000000000..9de4dc470a08 --- /dev/null +++ b/ext/gd/libgd/gd_filename.c @@ -0,0 +1,278 @@ +/* Convenience functions to read or write images from or to disk, + * determining file type from the filename extension. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gd.h" +#include "gd_intern.h" + +typedef gdImagePtr(BGD_STDCALL *ReadFn)(FILE *in); +typedef void(BGD_STDCALL *WriteFn)(gdImagePtr im, FILE *out); +typedef gdImagePtr(BGD_STDCALL *LoadFn)(char *filename); + +#ifdef HAVE_LIBZ +static void BGD_STDCALL writegd2(gdImagePtr im, FILE *out) +{ + gdImageGd2(im, out, 0, GD2_FMT_COMPRESSED); +} /* writegd*/ +#endif + +#ifdef HAVE_LIBJPEG +static void BGD_STDCALL writejpeg(gdImagePtr im, FILE *out) +{ + gdImageJpeg(im, out, -1); +} /* writejpeg*/ +#endif + +static void BGD_STDCALL writewbmp(gdImagePtr im, FILE *out) +{ + int fg = gdImageColorClosest(im, 0, 0, 0); + + gdImageWBMP(im, fg, out); +} /* writejpeg*/ + +static void BGD_STDCALL writebmp(gdImagePtr im, FILE *out) +{ + gdImageBmp(im, out, GD_TRUE); +} /* writejpeg*/ + +static const struct FileType { + const char *ext; + ReadFn reader; + WriteFn writer; + LoadFn loader; +} Types[] = {{".gif", gdImageCreateFromGif, gdImageGif, NULL}, + {".gd", gdImageCreateFromGd, gdImageGd, NULL}, + {".wbmp", gdImageCreateFromWBMP, writewbmp, NULL}, + {".bmp", gdImageCreateFromBmp, writebmp, NULL}, + + {".xbm", gdImageCreateFromXbm, NULL, NULL}, + {".tga", gdImageCreateFromTga, NULL, NULL}, + +#ifdef HAVE_LIBAVIF + {".avif", gdImageCreateFromAvif, gdImageAvif, NULL}, +#endif + +#ifdef HAVE_LIBPNG + {".png", gdImageCreateFromPng, gdImagePng, NULL}, +#endif + + {".qoi", gdImageCreateFromQoi, gdImageQoi, NULL}, + +#ifdef HAVE_LIBJPEG + {".jpg", gdImageCreateFromJpeg, writejpeg, NULL}, + {".jpeg", gdImageCreateFromJpeg, writejpeg, NULL}, +#endif + +#ifdef HAVE_LIBHEIF + {".heic", gdImageCreateFromHeif, gdImageHeif, NULL}, + {".heix", gdImageCreateFromHeif, NULL, NULL}, +#endif + +#ifdef HAVE_LIBTIFF + {".tiff", gdImageCreateFromTiff, gdImageTiff, NULL}, + {".tif", gdImageCreateFromTiff, gdImageTiff, NULL}, +#endif + +#ifdef HAVE_LIBZ + {".gd2", gdImageCreateFromGd2, writegd2, NULL}, +#endif + +#ifdef HAVE_LIBWEBP + {".webp", gdImageCreateFromWebp, gdImageWebp, NULL}, +#endif + +#ifdef HAVE_LIBJXL + {".jxl", gdImageCreateFromJxl, gdImageJxl, NULL}, +#endif + +#ifdef HAVE_LIBXPM + {".xpm", NULL, NULL, gdImageCreateFromXpm}, +#endif + + {NULL, NULL, NULL, NULL}}; + +static const struct FileType *ftype(const char *filename) +{ + int n; + const char *ext; + + /* Find the file extension (i.e. the last period in the string. */ + ext = strrchr(filename, '.'); + if (!ext) + return NULL; + + for (n = 0; Types[n].ext; n++) { + if (gd_strcasecmp(ext, Types[n].ext) == 0) { + return &Types[n]; + } /* if */ + } /* for */ + + return NULL; +} /* ftype*/ + +/* + Function: gdSupportsFileType + + Tests if a given file type is supported by GD. + + Given the name of an image file (which does not have to exist), + returns 1 (i.e. TRUE) if can read a file + of that type. This is useful if you do not know which image types + were enabled at compile time. + + If _writing_ is true, the result will be true only if + can write a file of this type. + + Note that filename parsing is done exactly the same as is done by + and and is subject to the + same limitations. + + Assuming LibGD is compiled with support for these image types, the + following extensions are supported: + + - .gif + - .gd, .gd2 + - .wbmp + - .bmp + - .xbm + - .tga + - .png + - .qoi + - .jpg, .jpeg + - .heif, .heix + - .avif + - .tiff, .tif + - .webp + - .jxl + - .xpm + + Names are parsed case-insenstively. + + Parameters: + + filename - Filename with tested extension. + writing - Flag: true tests if writing works + + Returns: + + GD_TRUE (1) if the file type is supported, GD_FALSE (0) if not. + +*/ +BGD_DECLARE(int) +gdSupportsFileType(const char *filename, int writing) +{ + const struct FileType *entry = ftype(filename); + return !!entry && (!writing || !!entry->writer); +} /* gdSupportsFileType*/ + +/* + Function: gdImageCreateFromFile + + Read an image file of any supported. + + Given the path to a file, will open the + file, read its contents with the appropriate _gdImageCreateFrom*_ + function and return it. + + File type is determined by the filename extension, so having an + incorrect extension will probably not work. For example, renaming + PNG image "foo.png" to "foo.gif" and then attempting to load it + will fail even if GD supports both formats. See + for more details. + + NULL is returned on error. + + Parameters: + + filename - the input file name + + Returns: + + A pointer to the new image or NULL if an error occurred. + +*/ + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromFile(const char *filename) +{ + const struct FileType *entry = ftype(filename); + FILE *fh; + gdImagePtr result; + + if (!entry) + return NULL; + if (entry->loader) + return entry->loader((char *)filename); + if (!entry->reader) + return NULL; + + fh = fopen(filename, "rb"); + if (!fh) + return NULL; + + result = entry->reader(fh); + + fclose(fh); + + return result; +} /* gdImageCreateFromFile*/ + +/* + Function: gdImageFile + + Writes an image to a file in the format indicated by the filename. + + File type is determined by the extension of the file name. See + for an overview of the parsing. + + For file types that require extra arguments, + attempts to use sane defaults: + + - chunk size = 0, compression is enabled. + - quality = -1 (i.e. the reasonable default) + - foreground is the darkest available color + + Everything else is called with the two-argument function and so + will use the default values. + + has some rudimentary error detection and will return + GD_FALSE (0) if a detectable error occurred. However, the image + loaders do not normally return their error status so a result of + GD_TRUE (1) does **not** mean the file was saved successfully. + + Parameters: + + im - The image to save. + filename - The path to the file to which the image is saved. + + Returns: + + GD_FALSE (0) if an error was detected, GD_TRUE (1) if not. + +*/ + +BGD_DECLARE(int) +gdImageFile(gdImagePtr im, const char *filename) +{ + const struct FileType *entry = ftype(filename); + FILE *fh; + + if (!entry || !entry->writer) + return GD_FALSE; + + fh = fopen(filename, "wb"); + if (!fh) + return GD_FALSE; + + entry->writer(im, fh); + + fclose(fh); + + return GD_TRUE; +} /* gdImageFile*/ diff --git a/ext/gd/libgd/gd_filter.c b/ext/gd/libgd/gd_filter.c index d567898548d2..7fe9b6b8f5e8 100644 --- a/ext/gd/libgd/gd_filter.c +++ b/ext/gd/libgd/gd_filter.c @@ -1,623 +1,1056 @@ +/** + * File: Image Filters + */ + #include "gd.h" #include "gd_intern.h" +#include "gdhelpers.h" #ifdef _WIN32 -# include +#include #else -# include +#include #endif +#include #include #include -/* Filters function added on 2003/12 - * by Pierre-Alain Joye (pierre@php.net) - * - * Scatter filter added in libgd 2.1.0 - * by Kalle Sommer Nielsen (kalle@php.net) - **/ +#undef NDEBUG +/* Comment out this line to enable asserts. + * TODO: This logic really belongs in cmake and configure. + */ +#define NDEBUG 1 +#include + +typedef int(BGD_STDCALL *FuncPtr)(gdImagePtr, int, int); + +#define GET_PIXEL_FUNCTION(src) (src->trueColor ? gdImageGetTrueColorPixel : gdImageGetPixel) -/* Begin filters function */ -#define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel) +static int gdClampFloatToByte(float value) +{ + if (!isfinite(value)) { + return value > 0.0f ? 255 : 0; + } + if (value > 255.0f) { + return 255; + } + if (value < 0.0f) { + return 0; + } + return (int)value; +} #ifdef _WIN32 -# define GD_SCATTER_SEED() (unsigned int)(time(0) * GetCurrentProcessId()) +#define GD_SCATTER_SEED() (unsigned int)(time(0) * GetCurrentProcessId()) #else -# define GD_SCATTER_SEED() (unsigned int)(time(0) * getpid()) +#define GD_SCATTER_SEED() (unsigned int)(time(0) * getpid()) #endif -int gdImageScatter(gdImagePtr im, int sub, int plus) +/* + Function: gdImageScatter + */ +BGD_DECLARE(int) gdImageScatter(gdImagePtr im, int sub, int plus) { - gdScatter s; + gdScatter s; - s.sub = sub; - s.plus = plus; - s.num_colors = 0; - s.seed = GD_SCATTER_SEED(); - return gdImageScatterEx(im, &s); + s.sub = sub; + s.plus = plus; + s.num_colors = 0; + s.seed = GD_SCATTER_SEED(); + return gdImageScatterEx(im, &s); } -int gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors) +/* + Function: gdImageScatterColor + */ +BGD_DECLARE(int) +gdImageScatterColor(gdImagePtr im, int sub, int plus, int colors[], unsigned int num_colors) { - gdScatter s; - - s.sub = sub; - s.plus = plus; - s.colors = colors; - s.num_colors = num_colors; - s.seed = GD_SCATTER_SEED(); - return gdImageScatterEx(im, &s); + gdScatter s; + + s.sub = sub; + s.plus = plus; + s.colors = colors; + s.num_colors = num_colors; + s.seed = GD_SCATTER_SEED(); + return gdImageScatterEx(im, &s); } -int gdImageScatterEx(gdImagePtr im, gdScatterPtr scatter) +/* + Function: gdImageScatterEx + */ +BGD_DECLARE(int) gdImageScatterEx(gdImagePtr im, gdScatterPtr scatter) { - register int x, y; - int dest_x, dest_y; - int pxl, new_pxl; - unsigned int n; - int sub = scatter->sub, plus = scatter->plus; - - if (plus == 0 && sub == 0) { - return 1; - } - else if (sub >= plus) { - return 0; - } - - (void)srand(scatter->seed); - - if (scatter->num_colors) { - for (y = 0; y < im->sy; y++) { - for (x = 0; x < im->sx; x++) { - dest_x = (int)(x + ((rand() % (plus - sub)) + sub)); - dest_y = (int)(y + ((rand() % (plus - sub)) + sub)); - - if (!gdImageBoundsSafe(im, dest_x, dest_y)) { - continue; - } - - pxl = gdImageGetPixel(im, x, y); - new_pxl = gdImageGetPixel(im, dest_x, dest_y); - - for (n = 0; n < scatter->num_colors; n++) { - if (pxl == scatter->colors[n]) { - gdImageSetPixel(im, dest_x, dest_y, pxl); - gdImageSetPixel(im, x, y, new_pxl); - } - } - } - } - } - else { - for (y = 0; y < im->sy; y++) { - for (x = 0; x < im->sx; x++) { - dest_x = (int)(x + ((rand() % (plus - sub)) + sub)); - dest_y = (int)(y + ((rand() % (plus - sub)) + sub)); - - if (!gdImageBoundsSafe(im, dest_x, dest_y)) { - continue; - } - - pxl = gdImageGetPixel(im, x, y); - new_pxl = gdImageGetPixel(im, dest_x, dest_y); - - gdImageSetPixel(im, dest_x, dest_y, pxl); - gdImageSetPixel(im, x, y, new_pxl); - } - } - } - - return 1; + register int x, y; + int dest_x, dest_y; + int pxl, new_pxl; + unsigned int n; + int sub = scatter->sub, plus = scatter->plus; + + if (plus == 0 && sub == 0) { + return 1; + } else if (sub >= plus) { + return 0; + } + + (void)srand(scatter->seed); + + if (scatter->num_colors) { + for (y = 0; y < im->sy; y++) { + for (x = 0; x < im->sx; x++) { + dest_x = (int)(x + ((rand() % (plus - sub)) + sub)); + dest_y = (int)(y + ((rand() % (plus - sub)) + sub)); + + if (!gdImageBoundsSafe(im, dest_x, dest_y)) { + continue; + } + + pxl = gdImageGetPixel(im, x, y); + new_pxl = gdImageGetPixel(im, dest_x, dest_y); + + for (n = 0; n < scatter->num_colors; n++) { + if (pxl == scatter->colors[n]) { + gdImageSetPixel(im, dest_x, dest_y, pxl); + gdImageSetPixel(im, x, y, new_pxl); + } + } + } + } + } else { + for (y = 0; y < im->sy; y++) { + for (x = 0; x < im->sx; x++) { + dest_x = (int)(x + ((rand() % (plus - sub)) + sub)); + dest_y = (int)(y + ((rand() % (plus - sub)) + sub)); + + if (!gdImageBoundsSafe(im, dest_x, dest_y)) { + continue; + } + + pxl = gdImageGetPixel(im, x, y); + new_pxl = gdImageGetPixel(im, dest_x, dest_y); + + gdImageSetPixel(im, dest_x, dest_y, pxl); + gdImageSetPixel(im, x, y, new_pxl); + } + } + } + + return 1; } -int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode) +/* + Function: gdImagePixelate + */ +BGD_DECLARE(int) +gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode) { - int x, y; - - if (block_size <= 0) { - return 0; - } else if (block_size == 1) { - return 1; - } - switch (mode) { - case GD_PIXELATE_UPPERLEFT: - for (y = 0; y < im->sy; y += block_size) { - for (x = 0; x < im->sx; x += block_size) { - if (gdImageBoundsSafe(im, x, y)) { - int c = gdImageGetPixel(im, x, y); - gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c); - } - } - } - break; - case GD_PIXELATE_AVERAGE: - for (y = 0; y < im->sy; y += block_size) { - for (x = 0; x < im->sx; x += block_size) { - int a, r, g, b, c; - int total; - int cx, cy; - - a = r = g = b = c = total = 0; - /* sampling */ - for (cy = 0; cy < block_size; cy++) { - for (cx = 0; cx < block_size; cx++) { - if (!gdImageBoundsSafe(im, x + cx, y + cy)) { - continue; - } - c = gdImageGetPixel(im, x + cx, y + cy); - a += gdImageAlpha(im, c); - r += gdImageRed(im, c); - g += gdImageGreen(im, c); - b += gdImageBlue(im, c); - total++; - } - } - /* drawing */ - if (total > 0) { - c = gdImageColorResolveAlpha(im, r / total, g / total, b / total, a / total); - gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c); - } - } - } - break; - default: - return 0; - } - return 1; + int x, y; + + if (block_size <= 0) { + return 0; + } else if (block_size == 1) { + return 1; + } + switch (mode) { + case GD_PIXELATE_UPPERLEFT: + for (y = 0; y < im->sy; y += block_size) { + for (x = 0; x < im->sx; x += block_size) { + if (gdImageBoundsSafe(im, x, y)) { + int c = gdImageGetPixel(im, x, y); + gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c); + } + } + } + break; + case GD_PIXELATE_AVERAGE: + for (y = 0; y < im->sy; y += block_size) { + for (x = 0; x < im->sx; x += block_size) { + int a, r, g, b, c; + int total; + int cx, cy; + + a = r = g = b = c = total = 0; + /* sampling */ + for (cy = 0; cy < block_size; cy++) { + for (cx = 0; cx < block_size; cx++) { + if (!gdImageBoundsSafe(im, x + cx, y + cy)) { + continue; + } + c = gdImageGetPixel(im, x + cx, y + cy); + a += gdImageAlpha(im, c); + r += gdImageRed(im, c); + g += gdImageGreen(im, c); + b += gdImageBlue(im, c); + total++; + } + } + /* drawing */ + if (total > 0) { + c = gdImageColorResolveAlpha(im, r / total, g / total, b / total, a / total); + gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c); + } + } + } + break; + default: + return 0; + } + return 1; } -/* invert src image */ -int gdImageNegate(gdImagePtr src) +/** + * Function: gdImageNegate + * + * Invert an image + * + * Parameters: + * src - The image. + * + * Returns: + * Non-zero on success, zero on failure. + */ +BGD_DECLARE(int) gdImageNegate(gdImagePtr src) { - int x, y; - int r,g,b,a; - int new_pxl, pxl; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src==NULL) { - return 0; - } - - f = GET_PIXEL_FUNCTION(src); - - for (y=0; ysy; ++y) { - for (x=0; xsx; ++x) { - pxl = f (src, x, y); - r = gdImageRed(src, pxl); - g = gdImageGreen(src, pxl); - b = gdImageBlue(src, pxl); - a = gdImageAlpha(src, pxl); - - new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - return 1; + int x, y; + int r, g, b, a; + int new_pxl, pxl; + FuncPtr f; + + if (src == NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; ++y) { + for (x = 0; x < src->sx; ++x) { + pxl = f(src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + new_pxl = gdImageColorAllocateAlpha(src, 255 - r, 255 - g, 255 - b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, 255 - r, 255 - g, 255 - b, a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + return 1; } -/* Convert the image src to a grayscale image */ -int gdImageGrayScale(gdImagePtr src) +/** + * Function: gdImageGrayScale + * + * Convert an image to grayscale + * + * The red, green and blue components of each pixel are replaced by their + * weighted sum using the same coefficients as the REC.601 luma (Y') + * calculation. The alpha components are retained. + * + * For palette images the result may differ due to palette limitations. + * + * Parameters: + * src - The image. + * + * Returns: + * Non-zero on success, zero on failure. + */ +BGD_DECLARE(int) gdImageGrayScale(gdImagePtr src) { - int x, y; - int r,g,b,a; - int new_pxl, pxl; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - int alpha_blending; - - f = GET_PIXEL_FUNCTION(src); - - if (src==NULL) { - return 0; - } - - alpha_blending = src->alphaBlendingFlag; - gdImageAlphaBlending(src, gdEffectReplace); - - for (y=0; ysy; ++y) { - for (x=0; xsx; ++x) { - pxl = f (src, x, y); - r = gdImageRed(src, pxl); - g = gdImageGreen(src, pxl); - b = gdImageBlue(src, pxl); - a = gdImageAlpha(src, pxl); - r = g = b = (int) (.299 * r + .587 * g + .114 * b); - - new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - gdImageAlphaBlending(src, alpha_blending); - - return 1; + int x, y; + int r, g, b, a; + int new_pxl, pxl; + FuncPtr f; + int alpha_blending; + + if (src == NULL) { + return 0; + } + + alpha_blending = src->alphaBlendingFlag; + gdImageAlphaBlending(src, gdEffectReplace); + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; ++y) { + for (x = 0; x < src->sx; ++x) { + pxl = f(src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + r = g = b = (int)(.299 * r + .587 * g + .114 * b); + + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + gdImageAlphaBlending(src, alpha_blending); + + return 1; } -/* Set the brightness level for the image src */ -int gdImageBrightness(gdImagePtr src, int brightness) +/** + * Function: gdImageBrightness + * + * Change the brightness of an image + * + * Parameters: + * src - The image. + * brightness - The value to add to the color channels of all pixels. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) gdImageBrightness(gdImagePtr src, int brightness) { - int x, y; - int r,g,b,a; - int new_pxl, pxl; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - f = GET_PIXEL_FUNCTION(src); - - if (src==NULL || (brightness < -255 || brightness>255)) { - return 0; - } - - if (brightness==0) { - return 1; - } - - for (y=0; ysy; ++y) { - for (x=0; xsx; ++x) { - pxl = f (src, x, y); - - r = gdImageRed(src, pxl); - g = gdImageGreen(src, pxl); - b = gdImageBlue(src, pxl); - a = gdImageAlpha(src, pxl); - - r = r + brightness; - g = g + brightness; - b = b + brightness; - - r = (r > 255)? 255 : ((r < 0)? 0:r); - g = (g > 255)? 255 : ((g < 0)? 0:g); - b = (b > 255)? 255 : ((b < 0)? 0:b); - - new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - return 1; + int x, y; + int r, g, b, a; + int new_pxl, pxl; + FuncPtr f; + + if (src == NULL || (brightness < -255 || brightness > 255)) { + return 0; + } + + if (brightness == 0) { + return 1; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; ++y) { + for (x = 0; x < src->sx; ++x) { + pxl = f(src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + brightness; + g = g + brightness; + b = b + brightness; + + r = (r > 255) ? 255 : ((r < 0) ? 0 : r); + g = (g > 255) ? 255 : ((g < 0) ? 0 : g); + b = (b > 255) ? 255 : ((b < 0) ? 0 : b); + + new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + return 1; } - -int gdImageContrast(gdImagePtr src, double contrast) +/** + * Function: gdImageContrast + * + * Change the contrast of an image + * + * Parameters: + * src - The image. + * contrast - The contrast adjustment value. Negative values increase, postive + * values decrease the contrast. The larger the absolute value, the + * stronger the effect. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImageContrast(gdImagePtr src, double contrast) { - int x, y; - int r,g,b,a; - double rf,gf,bf; - int new_pxl, pxl; - typedef int (*FuncPtr)(gdImagePtr, int, int); - - FuncPtr f; - f = GET_PIXEL_FUNCTION(src); - - if (src==NULL) { - return 0; - } - - contrast = (double)(100.0-contrast)/100.0; - contrast = contrast*contrast; - - for (y=0; ysy; ++y) { - for (x=0; xsx; ++x) { - pxl = f(src, x, y); - - r = gdImageRed(src, pxl); - g = gdImageGreen(src, pxl); - b = gdImageBlue(src, pxl); - a = gdImageAlpha(src, pxl); - - rf = (double)r/255.0; - rf = rf-0.5; - rf = rf*contrast; - rf = rf+0.5; - rf = rf*255.0; - - bf = (double)b/255.0; - bf = bf-0.5; - bf = bf*contrast; - bf = bf+0.5; - bf = bf*255.0; - - gf = (double)g/255.0; - gf = gf-0.5; - gf = gf*contrast; - gf = gf+0.5; - gf = gf*255.0; - - rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf); - gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf); - bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf); - - new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - return 1; + int x, y; + int r, g, b, a; + double rf, gf, bf; + int new_pxl, pxl; + + FuncPtr f; + + if (src == NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + contrast = (double)(100.0 - contrast) / 100.0; + contrast = contrast * contrast; + + for (y = 0; y < src->sy; ++y) { + for (x = 0; x < src->sx; ++x) { + pxl = f(src, x, y); + + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + rf = (double)r / 255.0; + rf = rf - 0.5; + rf = rf * contrast; + rf = rf + 0.5; + rf = rf * 255.0; + + bf = (double)b / 255.0; + bf = bf - 0.5; + bf = bf * contrast; + bf = bf + 0.5; + bf = bf * 255.0; + + gf = (double)g / 255.0; + gf = gf - 0.5; + gf = gf * contrast; + gf = gf + 0.5; + gf = gf * 255.0; + + rf = (rf > 255.0) ? 255.0 : ((rf < 0.0) ? 0.0 : rf); + gf = (gf > 255.0) ? 255.0 : ((gf < 0.0) ? 0.0 : gf); + bf = (bf > 255.0) ? 255.0 : ((bf < 0.0) ? 0.0 : bf); + + new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + return 1; } - -int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha) +/** + * Function: gdImageColor + * + * Change channel values of an image + * + * Parameters: + * src - The image. + * red - The value to add to the red channel of all pixels. + * green - The value to add to the green channel of all pixels. + * blue - The value to add to the blue channel of all pixels. + * alpha - The value to add to the alpha channel of all pixels. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + */ +BGD_DECLARE(int) +gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha) { - int x, y; - int new_pxl, pxl; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src == NULL) { - return 0; - } - - f = GET_PIXEL_FUNCTION(src); - - for (y=0; ysy; ++y) { - for (x=0; xsx; ++x) { - int r,g,b,a; - - pxl = f(src, x, y); - r = gdImageRed(src, pxl); - g = gdImageGreen(src, pxl); - b = gdImageBlue(src, pxl); - a = gdImageAlpha(src, pxl); - - r = r + red; - g = g + green; - b = b + blue; - a = a + alpha; - - r = (r > 255)? 255 : ((r < 0)? 0 : r); - g = (g > 255)? 255 : ((g < 0)? 0 : g); - b = (b > 255)? 255 : ((b < 0)? 0 : b); - a = (a > 127)? 127 : ((a < 0)? 0 : a); - - new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - return 1; + int x, y; + int new_pxl, pxl; + FuncPtr f; + + if (src == NULL) { + return 0; + } + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; ++y) { + for (x = 0; x < src->sx; ++x) { + int r, g, b, a; + + pxl = f(src, x, y); + r = gdImageRed(src, pxl); + g = gdImageGreen(src, pxl); + b = gdImageBlue(src, pxl); + a = gdImageAlpha(src, pxl); + + r = r + red; + g = g + green; + b = b + blue; + a = a + alpha; + + r = (r > 255) ? 255 : ((r < 0) ? 0 : r); + g = (g > 255) ? 255 : ((g < 0) ? 0 : g); + b = (b > 255) ? 255 : ((b < 0) ? 0 : b); + a = (a > 127) ? 127 : ((a < 0) ? 0 : a); + + new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, r, g, b, a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + return 1; } -int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset) +/** + * Function: gdImageConvolution + * + * Apply a convolution matrix to an image + * + * Depending on the matrix a wide range of effects can be accomplished, e.g. + * blurring, sharpening, embossing and edge detection. + * + * Parameters: + * src - The image. + * filter - The 3x3 convolution matrix. + * filter_div - The value to divide the convoluted channel values by. + * offset - The value to add to the convoluted channel values. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + * - + * - + * - + * - + */ +BGD_DECLARE(int) +gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset) { - int x, y, i, j, new_a; - float new_r, new_g, new_b; - int new_pxl, pxl=0; - gdImagePtr srcback; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src==NULL) { - return 0; - } - - /* We need the orinal image with each safe neoghb. pixel */ - srcback = gdImageCreateTrueColor (src->sx, src->sy); - if (srcback==NULL) { - return 0; - } - - gdImageSaveAlpha(srcback, 1); - new_pxl = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127); - gdImageFill(srcback, 0, 0, new_pxl); - - gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); - - f = GET_PIXEL_FUNCTION(src); - - for ( y=0; ysy; y++) { - for(x=0; xsx; x++) { - new_r = new_g = new_b = 0; - pxl = f(srcback, x, y); - new_a = gdImageAlpha(srcback, pxl); - - for (j=0; j<3; j++) { - int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1); - for (i=0; i<3; i++) { - pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv); - new_r += (float)gdImageRed(srcback, pxl) * filter[j][i]; - new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i]; - new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i]; - } - } - - new_r = (new_r/filter_div)+offset; - new_g = (new_g/filter_div)+offset; - new_b = (new_b/filter_div)+offset; - - new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); - new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); - new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); - - new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - gdImageDestroy(srcback); - return 1; + int x, y, i, j, new_a; + float new_r, new_g, new_b; + int new_pxl, pxl = 0; + gdImagePtr srcback; + FuncPtr f; + + if (src == NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor(src->sx, src->sy); + if (srcback == NULL) { + return 0; + } + + gdImageSaveAlpha(srcback, 1); + new_pxl = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127); + gdImageFill(srcback, 0, 0, new_pxl); + + gdImageCopy(srcback, src, 0, 0, 0, 0, src->sx, src->sy); + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; y++) { + for (x = 0; x < src->sx; x++) { + int new_ri, new_gi, new_bi; + new_r = new_g = new_b = 0; + pxl = f(srcback, x, y); + new_a = gdImageAlpha(srcback, pxl); + + for (j = 0; j < 3; j++) { + int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1); + for (i = 0; i < 3; i++) { + pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv); + new_r += (float)gdImageRed(srcback, pxl) * filter[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i]; + } + } + + new_r = (new_r / filter_div) + offset; + new_g = (new_g / filter_div) + offset; + new_b = (new_b / filter_div) + offset; + + new_ri = gdClampFloatToByte(new_r); + new_gi = gdClampFloatToByte(new_g); + new_bi = gdClampFloatToByte(new_b); + + new_pxl = gdImageColorAllocateAlpha(src, new_ri, new_gi, new_bi, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, new_ri, new_gi, new_bi, new_a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + gdImageDestroy(srcback); + return 1; } -int gdImageSelectiveBlur( gdImagePtr src) +/* + Function: gdImageSelectiveBlur + */ +BGD_DECLARE(int) gdImageSelectiveBlur(gdImagePtr src) { - int x, y, i, j; - float new_r, new_g, new_b; - int new_pxl, cpxl, pxl, new_a=0; - float flt_r [3][3]; - float flt_g [3][3]; - float flt_b [3][3]; - float flt_r_sum, flt_g_sum, flt_b_sum; - - gdImagePtr srcback; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src==NULL) { - return 0; - } - - /* We need the orinal image with each safe neoghb. pixel */ - srcback = gdImageCreateTrueColor (src->sx, src->sy); - if (srcback==NULL) { - return 0; - } - gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy); - - f = GET_PIXEL_FUNCTION(src); - - for(y = 0; ysy; y++) { - for (x=0; xsx; x++) { - flt_r_sum = flt_g_sum = flt_b_sum = 0.0; - cpxl = f(src, x, y); - - for (j=0; j<3; j++) { - for (i=0; i<3; i++) { - if ((j == 1) && (i == 1)) { - flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5; - } else { - pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); - new_a = gdImageAlpha(srcback, pxl); - - new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl)); - - if (new_r < 0.0f) { - new_r = -new_r; - } - if (new_r != 0) { - flt_r[j][i] = 1.0f/new_r; - } else { - flt_r[j][i] = 1.0f; - } - - new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl)); - - if (new_g < 0.0f) { - new_g = -new_g; - } - if (new_g != 0) { - flt_g[j][i] = 1.0f/new_g; - } else { - flt_g[j][i] = 1.0f; - } - - new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl)); - - if (new_b < 0.0f) { - new_b = -new_b; - } - if (new_b != 0) { - flt_b[j][i] = 1.0f/new_b; - } else { - flt_b[j][i] = 1.0f; - } - } - - flt_r_sum += flt_r[j][i]; - flt_g_sum += flt_g[j][i]; - flt_b_sum += flt_b [j][i]; - } - } - - for (j=0; j<3; j++) { - for (i=0; i<3; i++) { - if (flt_r_sum != 0.0) { - flt_r[j][i] /= flt_r_sum; - } - if (flt_g_sum != 0.0) { - flt_g[j][i] /= flt_g_sum; - } - if (flt_b_sum != 0.0) { - flt_b [j][i] /= flt_b_sum; - } - } - } - - new_r = new_g = new_b = 0.0; - - for (j=0; j<3; j++) { - for (i=0; i<3; i++) { - pxl = f(src, x-(3>>1)+i, y-(3>>1)+j); - new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i]; - new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i]; - new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i]; - } - } - - new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); - new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); - new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); - new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); - if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); - } - gdImageSetPixel (src, x, y, new_pxl); - } - } - gdImageDestroy(srcback); - return 1; + int x, y, i, j; + float new_r, new_g, new_b; + int new_pxl, cpxl, pxl, new_a = 0; + float flt_r[3][3]; + float flt_g[3][3]; + float flt_b[3][3]; + float flt_r_sum, flt_g_sum, flt_b_sum; + + gdImagePtr srcback; + FuncPtr f; + + if (src == NULL) { + return 0; + } + + /* We need the orinal image with each safe neoghb. pixel */ + srcback = gdImageCreateTrueColor(src->sx, src->sy); + if (srcback == NULL) { + return 0; + } + gdImageCopy(srcback, src, 0, 0, 0, 0, src->sx, src->sy); + + f = GET_PIXEL_FUNCTION(src); + + for (y = 0; y < src->sy; y++) { + for (x = 0; x < src->sx; x++) { + flt_r_sum = flt_g_sum = flt_b_sum = 0.0; + cpxl = f(src, x, y); + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + if ((j == 1) && (i == 1)) { + flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5; + } else { + pxl = f(src, x - (3 >> 1) + i, y - (3 >> 1) + j); + new_a = gdImageAlpha(srcback, pxl); + + new_r = + ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed(srcback, pxl)); + + if (new_r < 0.0f) { + new_r = -new_r; + } + if (new_r != 0) { + flt_r[j][i] = 1.0f / new_r; + } else { + flt_r[j][i] = 1.0f; + } + + new_g = ((float)gdImageGreen(srcback, cpxl)) - + ((float)gdImageGreen(srcback, pxl)); + + if (new_g < 0.0f) { + new_g = -new_g; + } + if (new_g != 0) { + flt_g[j][i] = 1.0f / new_g; + } else { + flt_g[j][i] = 1.0f; + } + + new_b = ((float)gdImageBlue(srcback, cpxl)) - + ((float)gdImageBlue(srcback, pxl)); + + if (new_b < 0.0f) { + new_b = -new_b; + } + if (new_b != 0) { + flt_b[j][i] = 1.0f / new_b; + } else { + flt_b[j][i] = 1.0f; + } + } + + flt_r_sum += flt_r[j][i]; + flt_g_sum += flt_g[j][i]; + flt_b_sum += flt_b[j][i]; + } + } + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + if (flt_r_sum != 0.0) { + flt_r[j][i] /= flt_r_sum; + } + if (flt_g_sum != 0.0) { + flt_g[j][i] /= flt_g_sum; + } + if (flt_b_sum != 0.0) { + flt_b[j][i] /= flt_b_sum; + } + } + } + + new_r = new_g = new_b = 0.0; + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + pxl = f(src, x - (3 >> 1) + i, y - (3 >> 1) + j); + new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i]; + new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i]; + new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i]; + } + } + + new_r = (new_r > 255.0f) ? 255.0f : ((new_r < 0.0f) ? 0.0f : new_r); + new_g = (new_g > 255.0f) ? 255.0f : ((new_g < 0.0f) ? 0.0f : new_g); + new_b = (new_b > 255.0f) ? 255.0f : ((new_b < 0.0f) ? 0.0f : new_b); + new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + if (new_pxl == -1) { + new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + } + gdImageSetPixel(src, x, y, new_pxl); + } + } + gdImageDestroy(srcback); + return 1; } -int gdImageEdgeDetectQuick(gdImagePtr src) +/** + * Function: gdImageEdgeDetectQuick + * + * Edge detection of an image + * + * (see edge_detect_quick.jpg) + * + * Parameters: + * src - The image. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) gdImageEdgeDetectQuick(gdImagePtr src) { - float filter[3][3] = {{-1.0,0.0,-1.0}, - {0.0,4.0,0.0}, - {-1.0,0.0,-1.0}}; + float filter[3][3] = {{-1.0, 0.0, -1.0}, {0.0, 4.0, 0.0}, {-1.0, 0.0, -1.0}}; - return gdImageConvolution(src, filter, 1, 127); + return gdImageConvolution(src, filter, 1, 127); } -int gdImageGaussianBlur(gdImagePtr im) +/* + Function: gdImageGaussianBlur + + performs a Gaussian blur of radius 1 on the + image. The image is modified in place. + + *NOTE:* You will almost certain want to use + instead, as it allows you to change + your kernel size and sigma value. Future versions of this + function may fall back to calling it instead of + , causing subtle changes so be warned. + + Parameters: + im - The image to blur + + Returns: + GD_TRUE (1) on success, GD_FALSE (0) on failure. + +*/ + +BGD_DECLARE(int) gdImageGaussianBlur(gdImagePtr im) { - float filter[3][3] = {{1.0,2.0,1.0}, - {2.0,4.0,2.0}, - {1.0,2.0,1.0}}; + float filter[3][3] = {{1.0, 2.0, 1.0}, {2.0, 4.0, 2.0}, {1.0, 2.0, 1.0}}; - return gdImageConvolution(im, filter, 16, 0); + return gdImageConvolution(im, filter, 16, 0); } -int gdImageEmboss(gdImagePtr im) +/** + * Function: gdImageEmboss + * + * Emboss an image + * + * (see emboss.jpg) + * + * Parameters: + * im - The image. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImageEmboss(gdImagePtr im) { -/* - float filter[3][3] = {{1.0,1.0,1.0}, - {0.0,0.0,0.0}, - {-1.0,-1.0,-1.0}}; -*/ - float filter[3][3] = {{ 1.5, 0.0, 0.0}, - { 0.0, 0.0, 0.0}, - { 0.0, 0.0,-1.5}}; - - return gdImageConvolution(im, filter, 1, 127); + /* + float filter[3][3] = {{1.0,1.0,1.0}, + {0.0,0.0,0.0}, + {-1.0,-1.0,-1.0}}; + */ + float filter[3][3] = {{1.5, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, -1.5}}; + + return gdImageConvolution(im, filter, 1, 127); } -int gdImageMeanRemoval(gdImagePtr im) +/** + * Function: gdImageMeanRemoval + * + * Mean removal of an image + * + * (see mean_removal.jpg) + * + * Parameters: + * im - The image. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) gdImageMeanRemoval(gdImagePtr im) { - float filter[3][3] = {{-1.0,-1.0,-1.0}, - {-1.0,9.0,-1.0}, - {-1.0,-1.0,-1.0}}; + float filter[3][3] = {{-1.0, -1.0, -1.0}, {-1.0, 9.0, -1.0}, {-1.0, -1.0, -1.0}}; - return gdImageConvolution(im, filter, 1, 0); + return gdImageConvolution(im, filter, 1, 0); } -int gdImageSmooth(gdImagePtr im, float weight) +/** + * Function: gdImageSmooth + * + * Smooth an image + * + * (see smooth.jpg) + * + * Parameters: + * im - The image. + * weight - The strength of the smoothing. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + */ +BGD_DECLARE(int) gdImageSmooth(gdImagePtr im, float weight) { - float filter[3][3] = {{1.0,1.0,1.0}, - {1.0,0.0,1.0}, - {1.0,1.0,1.0}}; + float filter[3][3] = {{1.0, 1.0, 1.0}, {1.0, 0.0, 1.0}, {1.0, 1.0, 1.0}}; - filter[1][1] = weight; + filter[1][1] = weight; - return gdImageConvolution(im, filter, weight+8, 0); + return gdImageConvolution(im, filter, weight + 8, 0); } + +/* Return an array of coefficients for 'radius' and 'sigma' (sigma >= + * 0 means compute it). Result length is 2*radius+1. */ +static double *gaussian_coeffs(int radius, double sigmaArg) +{ + const double sigma = (sigmaArg <= 0.0) ? (2.0 / 3.0) * radius : sigmaArg; + const double s = 2.0 * sigma * sigma; + double *result; + double sum = 0; + int x, n, count; + + count = 2 * radius + 1; + + result = gdMalloc(sizeof(double) * count); + if (!result) { + return NULL; + } /* if */ + + for (x = -radius; x <= radius; x++) { + double coeff = exp(-(x * x) / s); + + sum += coeff; + result[x + radius] = coeff; + } /* for */ + + for (n = 0; n < count; n++) { + result[n] /= sum; + } /* for */ + + return result; +} /* gaussian_coeffs*/ + +static inline int reflect(int max, int x) +{ + assert(x > -max && x < 2 * max); + + if (x < 0) + return -x; + if (x >= max) + return max - (x - max) - 1; + return x; +} /* reflect*/ + +static inline void applyCoeffsLine(gdImagePtr src, gdImagePtr dst, int line, int linelen, + double *coeffs, int radius, gdAxis axis) +{ + int ndx; + + for (ndx = 0; ndx < linelen; ndx++) { + double r = 0, g = 0, b = 0, a = 0; + int cndx; + int *dest = (axis == HORIZONTAL) ? &dst->tpixels[line][ndx] : &dst->tpixels[ndx][line]; + + for (cndx = -radius; cndx <= radius; cndx++) { + const double coeff = coeffs[cndx + radius]; + const int rndx = reflect(linelen, ndx + cndx); + + const int srcpx = + (axis == HORIZONTAL) ? src->tpixels[line][rndx] : src->tpixels[rndx][line]; + + r += coeff * (double)gdTrueColorGetRed(srcpx); + g += coeff * (double)gdTrueColorGetGreen(srcpx); + b += coeff * (double)gdTrueColorGetBlue(srcpx); + a += coeff * (double)gdTrueColorGetAlpha(srcpx); + } /* for */ + + *dest = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF), uchar_clamp(b, 0xFF), + uchar_clamp(a, 0x7F)); + } /* for */ +} /* applyCoeffsLine*/ + +static void applyCoeffs(gdImagePtr src, gdImagePtr dst, double *coeffs, int radius, gdAxis axis) +{ + int line, numlines, linelen; + + if (axis == HORIZONTAL) { + numlines = src->sy; + linelen = src->sx; + } else { + numlines = src->sx; + linelen = src->sy; + } /* if .. else*/ + + for (line = 0; line < numlines; line++) { + applyCoeffsLine(src, dst, line, linelen, coeffs, radius, axis); + } /* for */ +} /* applyCoeffs*/ + +/* + Function: gdImageCopyGaussianBlurred + + Return a copy of the source image _src_ blurred according to the + parameters using the Gaussian Blur algorithm. + + _radius_ is a radius, not a diameter so a radius of 2 (for + example) will blur across a region 5 pixels across (2 to the + center, 1 for the center itself and another 2 to the other edge). + + _sigma_ represents the "fatness" of the curve (lower == fatter). + If _sigma_ is less than or equal to 0, + ignores it and instead computes an + "optimal" value. Be warned that future versions of this function + may compute sigma differently. + + The resulting image is always truecolor. + + More Details: + + A Gaussian Blur is generated by replacing each pixel's color + values with the average of the surrounding pixels' colors. This + region is a circle whose radius is given by argument _radius_. + Thus, a larger radius will yield a blurrier image. + + This average is not a simple mean of the values. Instead, values + are weighted using the Gaussian function (roughly a bell curve + centered around the destination pixel) giving it much more + influence on the result than its neighbours. Thus, a fatter curve + will give the center pixel more weight and make the image less + blurry; lower _sigma_ values will yield flatter curves. + + Currently, computes the default sigma + as + + (2/3)*radius + + Note, however that we reserve the right to change this if we find + a better ratio. If you absolutely need the current sigma value, + you should set it yourself. + + Parameters: + + src - the source image + radius - the blur radius (*not* diameter--range is 2*radius + 1) + sigma - the sigma value or a value <= 0.0 to use the computed default + + Returns: + + The new image or NULL if an error occurred. The result is always + truecolor. + + Example: + (start code) + + FILE *in; + gdImagePtr result, src; + + in = fopen("foo.png", "rb"); + src = gdImageCreateFromPng(in); + + result = gdImageCopyGaussianBlurred(im, src->sx / 10, -1.0); + + (end code) +*/ + +/* TODO: Look into turning this into a generic seperable filter + * function with Gaussian Blur being one special case. (At the + * moment, I can't find any other useful separable filter so for not, + * it's just blur.) */ +BGD_DECLARE(gdImagePtr) +gdImageCopyGaussianBlurred(gdImagePtr src, int radius, double sigma) +{ + gdImagePtr tmp = NULL, result = NULL; + double *coeffs; + int freeSrc = 0; + + if (radius < 1) { + return NULL; + } /* if */ + + /* Compute the coefficients. */ + coeffs = gaussian_coeffs(radius, sigma); + if (!coeffs) { + return NULL; + } /* if */ + + /* If the image is not truecolor, we first make a truecolor + * scratch copy. */ + if (!src->trueColor) { + int tcstat; + + src = gdImageClone(src); + if (!src) { + gdFree(coeffs); + return NULL; + } + + tcstat = gdImagePaletteToTrueColor(src); + if (!tcstat) { + gdImageDestroy(src); + gdFree(coeffs); + return NULL; + } /* if */ + + freeSrc = 1; + } /* if */ + + /* Apply the filter horizontally. */ + tmp = gdImageCreateTrueColor(src->sx, src->sy); + if (!tmp) { + if (freeSrc) { + gdImageDestroy(src); + } + gdFree(coeffs); + return NULL; + } + applyCoeffs(src, tmp, coeffs, radius, HORIZONTAL); + + /* Apply the filter vertically. */ + result = gdImageCreateTrueColor(src->sx, src->sy); + if (result) { + applyCoeffs(tmp, result, coeffs, radius, VERTICAL); + } /* if */ + + gdImageDestroy(tmp); + gdFree(coeffs); + + if (freeSrc) + gdImageDestroy(src); + + return result; +} /* gdImageCopyGaussianBlurred*/ /* End filters function */ diff --git a/ext/gd/libgd/gd_fixed.h b/ext/gd/libgd/gd_fixed.h new file mode 100644 index 000000000000..495e25859da3 --- /dev/null +++ b/ext/gd/libgd/gd_fixed.h @@ -0,0 +1,32 @@ +// +// Created by pierr on 7/21/2021. +// + +#ifndef GD_GD_FIXED_H +#define GD_GD_FIXED_H +/* Add *BSD and co for inttypes.h */ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "msinttypes/stdint.h" +#else +#include +#endif +/* only used here, let do a generic fixed point integers later if required by other + part of GD */ +typedef uint32_t gdFixed; +typedef int32_t gd_fixed_16_16; +typedef gd_fixed_16_16 gd_fixed_t; +#define gd_fixed_e ((gd_fixed_t)1) +#define gd_fixed_1 (gd_int_to_fixed(1)) +#define gd_fixed_1_minus_e (gd_fixed_1 - gd_fixed_e) +#define gd_fixed_minus_1 (pixman_int_to_fixed(-1)) +#define gd_fixed_to_int(f) ((int)((f) >> 16)) +#define gd_int_to_fixed(i) ((gd_fixed_t)(i) * (gd_fixed_t)65536) +#define gd_fixed_to_double(f) (double)((f) / (double)gd_fixed_1) +#define gd_double_to_fixed(d) ((gd_fixed_t)((d) * 65536.0)) +#define gd_fixed_frac(f) ((f) & gd_fixed_1_minus_e) +#define gd_fixed_floor(f) ((f) & ~gd_fixed_1_minus_e) +#define gd_fixed_ceil(f) gd_fixed_floor((f) + gd_fixed_1_minus_e) +#define gd_fixed_fraction(f) ((f) & gd_fixed_1_minus_e) +#define gd_fixed_mod_2(f) ((f) & (gd_fixed1 | gd_fixed_1_minus_e)) + +#endif // GD_GD_FIXED_H diff --git a/ext/gd/libgd/gd_gd.c b/ext/gd/libgd/gd_gd.c index d5fe16a9af16..da2a8449ce43 100644 --- a/ext/gd/libgd/gd_gd.c +++ b/ext/gd/libgd/gd_gd.c @@ -1,280 +1,402 @@ -#include +/** + * File: GD IO + * + * Read and write GD images. + * + * The GD image format is a proprietary image format of libgd. *It has to be* + * *regarded as being obsolete, and should only be used for development and* + * *testing purposes.* + * + * Structure of a GD image file: + * - file header + * - color header (either truecolor or palette) + * - image data + * + * All numbers are stored in big-endian format. Note that all GD output is done + * in the GD 2.x format (not to be confused with the GD2 format), but input may + * also be in the GD 1.x format. + * + * GD 1.x file header structure: + * width - 1 word + * height - 1 word + * + * GD 1.x color header (palette only): + * count - 1 byte (the number of used palette colors) + * transparent - 1 word (257 signals no transparency) + * palette - 256×3 bytes (RGB triplets) + * + * GD 2.x file header structure: + * signature - 1 word ("\xFF\xFE" for truecolor, "\xFF\xFF" for palette) + * width - 1 word + * height - 1 word + * + * GD 2.x truecolor image color header: + * truecolor - 1 byte (always "\001") + * transparent - 1 dword (ARGB color); "\377\377\377\377" means that no + * transparent color is set + * + * GD 2.x palette image color header: + * truecolor - 1 byte (always "\0") + * count - 1 word (the number of used palette colors) + * transparent - 1 dword (palette index); "\377\377\377\377" means that no + * transparent color is set + * palette - 256 dwords (RGBA colors) + * + * Image data: + * Sequential pixel data; row-major from top to bottom, left to right: + * - 1 byte per pixel for palette images + * - 1 dword (ARGB) per pixel for truecolor images + */ + +#include "gd.h" +#include "gd_errors.h" #include -#include +#include #include -#include "gd.h" +#include #define TRUE 1 #define FALSE 0 /* Exported functions: */ -extern void gdImageGd (gdImagePtr im, FILE * out); - +extern void gdImageGd(gdImagePtr im, FILE *out); /* Use this for commenting out debug-print statements. */ /* Just use the first '#define' to allow all the prints... */ /*#define GD2_DBG(s) (s) */ #define GD2_DBG(s) -/* */ -/* Shared code to read color tables from gd file. */ -/* */ -int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag) +/* + * Shared code to read color tables from gd file. + */ +int _gdGetColors(gdIOCtx *in, gdImagePtr im, int gd2xFlag) { - int i; - if (gd2xFlag) { - int trueColorFlag; - if (!gdGetByte(&trueColorFlag, in)) { - goto fail1; - } - /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12. - * Beginning in 2.0.12 truecolor is indicated by the initial 2-byte - * signature. - */ - if (trueColorFlag != im->trueColor) { - goto fail1; - } - /* This should have been a word all along */ - if (!im->trueColor) { - if (!gdGetWord(&im->colorsTotal, in)) { - goto fail1; - } - if (im->colorsTotal > gdMaxColors) { - goto fail1; - } - } - /* Int to accommodate truecolor single-color transparency */ - if (!gdGetInt(&im->transparent, in)) { - goto fail1; - } - } else { - if (!gdGetByte(&im->colorsTotal, in)) { - goto fail1; - } - if (!gdGetWord(&im->transparent, in)) { - goto fail1; - } - if (im->transparent == 257) { - im->transparent = (-1); - } - } - - GD2_DBG(printf("Palette had %d colours (T=%d)\n", im->colorsTotal, im->transparent)); - - if (im->trueColor) { - return TRUE; - } - - for (i = 0; i < gdMaxColors; i++) { - if (!gdGetByte(&im->red[i], in)) { - goto fail1; - } - if (!gdGetByte(&im->green[i], in)) { - goto fail1; - } - if (!gdGetByte(&im->blue[i], in)) { - goto fail1; - } - if (gd2xFlag) { - if (!gdGetByte(&im->alpha[i], in)) { - goto fail1; - } - } - } - - for (i = 0; i < im->colorsTotal; i++) { - im->open[i] = 0; - } - - return TRUE; + int i; + if (gd2xFlag) { + int trueColorFlag; + if (!gdGetByte(&trueColorFlag, in)) { + goto fail1; + } + /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12. + Beginning in 2.0.12 truecolor is indicated by the initial 2-byte + signature. */ + if (trueColorFlag != im->trueColor) { + goto fail1; + } + /* This should have been a word all along */ + if (!im->trueColor) { + if (!gdGetWord(&im->colorsTotal, in)) { + goto fail1; + } + if (im->colorsTotal > gdMaxColors) { + goto fail1; + } + } + /* Int to accommodate truecolor single-color transparency */ + if (!gdGetInt(&im->transparent, in)) { + goto fail1; + } + } else { + if (!gdGetByte(&im->colorsTotal, in)) { + goto fail1; + } + if (!gdGetWord(&im->transparent, in)) { + goto fail1; + } + } + /* Make sure transparent index is within bounds of the palette. */ + if (!(im->trueColor) && (im->transparent >= im->colorsTotal || im->transparent < 0)) { + im->transparent = (-1); + } + GD2_DBG(printf("Palette had %d colours (T=%d)\n", im->colorsTotal, im->transparent)); + if (im->trueColor) { + return TRUE; + } + for (i = 0; (i < gdMaxColors); i++) { + if (!gdGetByte(&im->red[i], in)) { + goto fail1; + } + if (!gdGetByte(&im->green[i], in)) { + goto fail1; + } + if (!gdGetByte(&im->blue[i], in)) { + goto fail1; + } + if (gd2xFlag) { + if (!gdGetByte(&im->alpha[i], in)) { + goto fail1; + } + } + } + + for (i = 0; (i < im->colorsTotal); i++) { + im->open[i] = 0; + } + + return TRUE; fail1: - return FALSE; + return FALSE; } /* */ /* Use the common basic header info to make the image object. */ /* */ -static gdImagePtr _gdCreateFromFile (gdIOCtx * in, int *sx, int *sy) +static gdImagePtr _gdCreateFromFile(gdIOCtx *in, int *sx, int *sy) { - gdImagePtr im; - int gd2xFlag = 0; - int trueColorFlag = 0; - - if (!gdGetWord(sx, in)) { - goto fail1; - } - if (*sx == 65535 || *sx == 65534) { - /* This is a gd 2.0 .gd file */ - gd2xFlag = 1; - /* 2.0.12: 65534 signals a truecolor .gd file. There is a slight redundancy here but we can live with it. */ - if (*sx == 65534) { - trueColorFlag = 1; - } - if (!gdGetWord(sx, in)) { - goto fail1; - } - } - if (!gdGetWord(sy, in)) { - goto fail1; - } - - GD2_DBG(printf("Image is %dx%d\n", *sx, *sy)); - - if (trueColorFlag) { - im = gdImageCreateTrueColor(*sx, *sy); - } else { - im = gdImageCreate(*sx, *sy); - } - if(!im) { - goto fail1; - } - if (!_gdGetColors(in, im, gd2xFlag)) { - goto fail2; - } - - return im; + gdImagePtr im; + int gd2xFlag = 0; + int trueColorFlag = 0; + + if (!gdGetWord(sx, in)) { + goto fail1; + } + if ((*sx == 65535) || (*sx == 65534)) { + /* This is a gd 2.0 .gd file */ + gd2xFlag = 1; + /* 2.0.12: 65534 signals a truecolor .gd file. There is a slight redundancy here but we can + * live with it. */ + if (*sx == 65534) { + trueColorFlag = 1; + } + if (!gdGetWord(sx, in)) { + goto fail1; + } + } + if (!gdGetWord(sy, in)) { + goto fail1; + } + + GD2_DBG(printf("Image is %dx%d\n", *sx, *sy)); + + if (trueColorFlag) { + im = gdImageCreateTrueColor(*sx, *sy); + } else { + im = gdImageCreate(*sx, *sy); + } + if (!im) { + goto fail1; + } + if (!_gdGetColors(in, im, gd2xFlag)) { + goto fail2; + } + + return im; fail2: - gdImageDestroy(im); + gdImageDestroy(im); fail1: - return 0; + return 0; } -gdImagePtr gdImageCreateFromGd (FILE * inFile) +/* + Function: gdImageCreateFromGd + + is called to load images from gd format + files. Invoke with an already opened pointer + to a file containing the desired image in the gd file format, + which is specific to gd and intended for very fast loading. (It is + not intended for compression; for compression, use PNG or JPEG.) + + returns a to the new image, or + NULL if unable to load the image (most often because the file is + corrupt or does not contain a gd format + image). does not close the file. You can + inspect the sx and sy members of the image to determine its + size. The image must eventually be destroyed using + . + + Variants: + + creates an image from GD data (i.e. the + contents of a GD file) already in memory. + + reads in an image using the functions in + a struct. + + Parameters: + + infile - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + + > gdImagePtr im; + > FILE *in; + > in = fopen("mygd.gd", "rb"); + > im = gdImageCreateFromGd(in); + > fclose(in); + > // ... Use the image ... + > gdImageDestroy(im); +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd(FILE *inFile) { - gdImagePtr im; - gdIOCtx *in; + gdImagePtr im; + gdIOCtx *in; - in = gdNewFileCtx(inFile); - im = gdImageCreateFromGdCtx(in); + in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromGdCtx(in); - in->gd_free(in); + in->gd_free(in); - return im; + return im; } -gdImagePtr gdImageCreateFromGdPtr (int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromGdCtx(in); - in->gd_free(in); +/* + Function: gdImageCreateFromGdPtr + + Parameters: - return im; + size - size of GD data in bytes. + data - GD data (i.e. contents of a GIF file). + + Reads in GD data from memory. See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGdPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromGdCtx(in); + in->gd_free(in); + + return im; } -gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in) +/* + Function: gdImageCreateFromGdCtx + + Reads in a GD image via a struct. See + . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGdCtx(gdIOCtxPtr in) { - int sx, sy; - int x, y; - gdImagePtr im; - - /* Read the header */ - im = _gdCreateFromFile(in, &sx, &sy); - - if (im == NULL) { - goto fail1; - } - - /* Then the data... */ - /* 2.0.12: support truecolor properly in .gd as well as in .gd2. Problem reported by Andreas Pfaller. */ - if (im->trueColor) { - for (y = 0; y < sy; y++) { - for (x = 0; x < sx; x++) { - int pix; - if (!gdGetInt(&pix, in)) { - goto fail2; - } - im->tpixels[y][x] = pix; - } - } - } else { - for (y = 0; y < sy; y++) { - for (x = 0; x < sx; x++) { - int ch; - ch = gdGetC(in); - if (ch == EOF) { - goto fail2; - } - /* ROW-MAJOR IN GD 1.3 */ - im->pixels[y][x] = ch; - } - } - } - - return im; + int sx, sy; + int x, y; + gdImagePtr im; + + /* Read the header */ + im = _gdCreateFromFile(in, &sx, &sy); + + if (im == NULL) { + goto fail1; + } + + /* Then the data... */ + /* 2.0.12: support truecolor properly in .gd as well as in .gd2. Problem reported by Andreas + * Pfaller. */ + if (im->trueColor) { + for (y = 0; (y < sy); y++) { + for (x = 0; (x < sx); x++) { + int pix; + if (!gdGetInt(&pix, in)) { + goto fail2; + } + im->tpixels[y][x] = pix; + } + } + } else { + for (y = 0; (y < sy); y++) { + for (x = 0; (x < sx); x++) { + int ch; + ch = gdGetC(in); + if (ch == EOF) { + goto fail2; + } + /* ROW-MAJOR IN GD 1.3 */ + im->pixels[y][x] = ch; + } + } + } + + return im; fail2: - gdImageDestroy (im); + gdImageDestroy(im); fail1: - return 0; + return 0; } -void _gdPutColors (gdImagePtr im, gdIOCtx * out) +void _gdPutColors(gdImagePtr im, gdIOCtx *out) { - int i; - - gdPutC(im->trueColor, out); - if (!im->trueColor) { - gdPutWord(im->colorsTotal, out); - } - gdPutInt(im->transparent, out); - if (!im->trueColor) { - for (i = 0; i < gdMaxColors; i++) { - gdPutC((unsigned char) im->red[i], out); - gdPutC((unsigned char) im->green[i], out); - gdPutC((unsigned char) im->blue[i], out); - gdPutC((unsigned char) im->alpha[i], out); - } - } + int i; + + gdPutC(im->trueColor, out); + if (!im->trueColor) { + gdPutWord(im->colorsTotal, out); + } + gdPutInt(im->transparent, out); + if (!im->trueColor) { + for (i = 0; (i < gdMaxColors); i++) { + gdPutC((unsigned char)im->red[i], out); + gdPutC((unsigned char)im->green[i], out); + gdPutC((unsigned char)im->blue[i], out); + gdPutC((unsigned char)im->alpha[i], out); + } + } } -static void _gdPutHeader (gdImagePtr im, gdIOCtx * out) +static void _gdPutHeader(gdImagePtr im, gdIOCtx *out) { - /* 65535 indicates this is a gd 2.x .gd file. - * 2.0.12: 65534 indicates truecolor. - */ - if (im->trueColor) { - gdPutWord(65534, out); - } else { - gdPutWord(65535, out); - } - gdPutWord(im->sx, out); - gdPutWord(im->sy, out); - - _gdPutColors(im, out); + /* 65535 indicates this is a gd 2.x .gd file. + * 2.0.12: 65534 indicates truecolor. + */ + if (im->trueColor) { + gdPutWord(65534, out); + } else { + gdPutWord(65535, out); + } + gdPutWord(im->sx, out); + gdPutWord(im->sy, out); + + _gdPutColors(im, out); } -static void _gdImageGd (gdImagePtr im, gdIOCtx * out) +static void _gdImageGd(gdImagePtr im, gdIOCtx *out) { - int x, y; - - _gdPutHeader(im, out); - - for (y = 0; y < im->sy; y++) { - for (x = 0; x < im->sx; x++) { - /* ROW-MAJOR IN GD 1.3 */ - if (im->trueColor) { - gdPutInt(im->tpixels[y][x], out); - } else { - gdPutC((unsigned char) im->pixels[y][x], out); - } - } - } + int x, y; + + _gdPutHeader(im, out); + + for (y = 0; (y < im->sy); y++) { + for (x = 0; (x < im->sx); x++) { + /* ROW-MAJOR IN GD 1.3 */ + if (im->trueColor) { + gdPutInt(im->tpixels[y][x], out); + } else { + gdPutC((unsigned char)im->pixels[y][x], out); + } + } + } } -void gdImageGd (gdImagePtr im, FILE * outFile) +/* + Function: gdImageGd + */ +BGD_DECLARE(void) gdImageGd(gdImagePtr im, FILE *outFile) { - gdIOCtx *out = gdNewFileCtx(outFile); - _gdImageGd(im, out); - out->gd_free(out); + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + _gdImageGd(im, out); + out->gd_free(out); } -void *gdImageGdPtr (gdImagePtr im, int *size) +/* + Function: gdImageGdPtr + */ +BGD_DECLARE(void *) gdImageGdPtr(gdImagePtr im, int *size) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - _gdImageGd(im, out); - rv = gdDPExtractData(out, size); - out->gd_free(out); - return rv; + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + _gdImageGd(im, out); + rv = gdDPExtractData(out, size); + out->gd_free(out); + return rv; } diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index 8e0307e5b120..24fc19c892ee 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -1,23 +1,80 @@ /* - * gd_gd2.c - * - * Implements the I/O and support for the GD2 format. - * - * Changing the definition of GD2_DBG (below) will cause copious messages - * to be displayed while it processes requests. - * - * Designed, Written & Copyright 1999, Philip Warner. - * + * gd_gd2.c + * + * Implements the I/O and support for the GD2 format. + * + * Changing the definition of GD2_DBG (below) will cause copious messages + * to be displayed while it processes requests. + * + * Designed, Written & Copyright 1999, Philip Warner. + * */ -#include -#include -#include -#include -#include +/** + * File: GD2 IO + * + * Read and write GD2 images. + * + * The GD2 image format is a proprietary image format of libgd. *It has to be* + * *regarded as being obsolete, and should only be used for development and* + * *testing purposes.* + * + * Structure of a GD2 image file: + * - file header + * - chunk headers (only for compressed data) + * - color header (either truecolor or palette) + * - chunks of image data (chunk-row-major, top to bottom, left to right) + * + * All numbers are stored in big-endian format. + * + * File header structure: + * signature - 4 bytes (always "gd2\0") + * version - 1 word (e.g. "\0\002") + * width - 1 word + * height - 1 word + * chunk_size - 1 word + * format - 1 word + * x_chunk_count - 1 word + * y_chunk_count - 1 word + * + * Recognized formats: + * 1 - raw palette image data + * 2 - compressed palette image data + * 3 - raw truecolor image data + * 4 - compressed truecolor image data + * + * Chunk header: + * offset - 1 dword + * size - 1 dword + * + * There are x_chunk_count * y_chunk_count chunk headers. + * + * Truecolor image color header: + * truecolor - 1 byte (always "\001") + * transparent - 1 dword (ARGB color); "\377\377\377\377" means that no + * transparent color is set + * + * Palette image color header: + * truecolor - 1 byte (always "\0") + * count - 1 word (the number of used palette colors) + * transparent - 1 dword (palette index); "\377\377\377\377" means that no + * transparent color is set + * palette - 256 dwords (RGBA colors) + * + * Chunk structure: + * Sequential pixel data of a rectangular area (chunk_size x chunk_size), + * row-major from top to bottom, left to right: + * - 1 byte per pixel for palette images + * - 1 dword (ARGB) per pixel for truecolor images + * + * Depending on format, the chunk may be ZLIB compressed. + */ #include "gd.h" #include "gd_errors.h" #include "gdhelpers.h" +#include +#include +#include #include @@ -28,824 +85,977 @@ * from im->trueColor, and the load routine doesn't need to tell * the end user the saved format. NOTE: adding 2 is assumed * to result in the correct format value for truecolor! -*/ + */ #define GD2_FMT_TRUECOLOR_RAW 3 #define GD2_FMT_TRUECOLOR_COMPRESSED 4 -#define gd2_compressed(fmt) (((fmt) == GD2_FMT_COMPRESSED) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED)) -#define gd2_truecolor(fmt) (((fmt) == GD2_FMT_TRUECOLOR_RAW) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED)) +#define gd2_compressed(fmt) \ + (((fmt) == GD2_FMT_COMPRESSED) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED)) +#define gd2_truecolor(fmt) \ + (((fmt) == GD2_FMT_TRUECOLOR_RAW) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED)) /* Use this for commenting out debug-print statements. */ /* Just use the first '#define' to allow all the prints... */ /* #define GD2_DBG(s) (s) */ #define GD2_DBG(s) -typedef struct -{ - int offset; - int size; +typedef struct { + int offset; + int size; } t_chunk_info; -extern int _gdGetColors(gdIOCtx * in, gdImagePtr im, int gd2xFlag); -extern void _gdPutColors(gdImagePtr im, gdIOCtx * out); +extern int _gdGetColors(gdIOCtx *in, gdImagePtr im, int gd2xFlag); +extern void _gdPutColors(gdImagePtr im, gdIOCtx *out); /* */ /* Read the extra info in the gd2 header. */ /* */ -static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** chunkIdx) +static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, + int *ncy, t_chunk_info **chunkIdx) { - int i; - int ch; - char id[5]; - t_chunk_info *cidx; - int sidx; - int nc; - - GD2_DBG(gd_error("Reading gd2 header info")); - - for (i = 0; i < 4; i++) { - ch = gdGetC(in); - if (ch == EOF) { - goto fail1; - } - id[i] = ch; - } - id[4] = 0; - - GD2_DBG(gd_error("Got file code: %s", id)); - - /* Equiv. of 'magick'. */ - if (strcmp(id, GD2_ID) != 0) { - GD2_DBG(gd_error("Not a valid gd2 file")); - goto fail1; - } - - /* Version */ - if (gdGetWord(vers, in) != 1) { - goto fail1; - } - GD2_DBG(gd_error("Version: %d", *vers)); - - if ((*vers != 1) && (*vers != 2)) { - GD2_DBG(gd_error("Bad version: %d", *vers)); - goto fail1; - } - - /* Image Size */ - if (!gdGetWord(sx, in)) { - GD2_DBG(gd_error("Could not get x-size")); - goto fail1; - } - if (!gdGetWord(sy, in)) { - GD2_DBG(gd_error("Could not get y-size")); - goto fail1; - } - GD2_DBG(gd_error("Image is %dx%d", *sx, *sy)); - - /* Chunk Size (pixels, not bytes!) */ - if (gdGetWord(cs, in) != 1) { - goto fail1; - } - GD2_DBG(gd_error("ChunkSize: %d", *cs)); - - if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) { - GD2_DBG(gd_error("Bad chunk size: %d", *cs)); - goto fail1; - } - - /* Data Format */ - if (gdGetWord(fmt, in) != 1) { - goto fail1; - } - GD2_DBG(gd_error("Format: %d", *fmt)); - - if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) { - GD2_DBG(gd_error("Bad data format: %d", *fmt)); - goto fail1; - } - - /* # of chunks wide */ - if (gdGetWord(ncx, in) != 1) { - goto fail1; - } - GD2_DBG(gd_error("%d Chunks Wide", *ncx)); - - /* # of chunks high */ - if (gdGetWord(ncy, in) != 1) { - goto fail1; - } - GD2_DBG(gd_error("%d Chunks vertically", *ncy)); - - if (gd2_compressed(*fmt)) { - if (overflow2(*ncx, *ncy)) { - GD2_DBG(printf ("Illegal chunk counts: %d * %d\n", *ncx, *ncy)); - goto fail1; - } - nc = (*ncx) * (*ncy); - GD2_DBG(gd_error("Reading %d chunk index entries", nc)); - if (overflow2(sizeof(t_chunk_info), nc)) { - goto fail1; - } - sidx = sizeof(t_chunk_info) * nc; - if (sidx <= 0) { - goto fail1; - } - cidx = gdCalloc(sidx, 1); - if (cidx == NULL) { - goto fail1; - } - - for (i = 0; i < nc; i++) { - if (gdGetInt(&cidx[i].offset, in) != 1) { - gdFree(cidx); - goto fail1; - } - if (gdGetInt(&cidx[i].size, in) != 1) { - gdFree(cidx); - goto fail1; - } - if (cidx[i].offset < 0 || cidx[i].size < 0) { - gdFree(cidx); - goto fail1; - } - } - *chunkIdx = cidx; - } - - GD2_DBG(gd_error("gd2 header complete")); - - return 1; - + int i; + int ch; + char id[5]; + t_chunk_info *cidx; + int sidx; + int nc; + + GD2_DBG(gd_error("Reading gd2 header info")); + + for (i = 0; i < 4; i++) { + ch = gdGetC(in); + if (ch == EOF) { + goto fail1; + }; + id[i] = ch; + }; + id[4] = 0; + + GD2_DBG(gd_error("Got file code: %s", id)); + + /* Equiv. of 'magick'. */ + if (strcmp(id, GD2_ID) != 0) { + GD2_DBG(gd_error("Not a valid gd2 file")); + goto fail1; + }; + + /* Version */ + if (gdGetWord(vers, in) != 1) { + goto fail1; + }; + GD2_DBG(gd_error("Version: %d", *vers)); + + if ((*vers != 1) && (*vers != 2)) { + GD2_DBG(gd_error("Bad version: %d", *vers)); + goto fail1; + }; + + /* Image Size */ + if (!gdGetWord(sx, in)) { + GD2_DBG(gd_error("Could not get x-size")); + goto fail1; + } + if (!gdGetWord(sy, in)) { + GD2_DBG(gd_error("Could not get y-size")); + goto fail1; + } + GD2_DBG(gd_error("Image is %dx%d", *sx, *sy)); + + /* Chunk Size (pixels, not bytes!) */ + if (gdGetWord(cs, in) != 1) { + goto fail1; + }; + GD2_DBG(gd_error("ChunkSize: %d", *cs)); + + if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) { + GD2_DBG(gd_error("Bad chunk size: %d", *cs)); + goto fail1; + }; + + /* Data Format */ + if (gdGetWord(fmt, in) != 1) { + goto fail1; + }; + GD2_DBG(gd_error("Format: %d", *fmt)); + + if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && + (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) { + GD2_DBG(gd_error("Bad data format: %d", *fmt)); + goto fail1; + }; + + /* # of chunks wide */ + if (gdGetWord(ncx, in) != 1) { + goto fail1; + }; + GD2_DBG(gd_error("%d Chunks Wide", *ncx)); + + /* # of chunks high */ + if (gdGetWord(ncy, in) != 1) { + goto fail1; + }; + GD2_DBG(gd_error("%d Chunks vertically", *ncy)); + + if (gd2_compressed(*fmt)) { + if (overflow2(*ncx, *ncy)) { + GD2_DBG(printf("Illegal chunk counts: %d * %d\n", *ncx, *ncy)); + goto fail1; + } + nc = (*ncx) * (*ncy); + GD2_DBG(gd_error("Reading %d chunk index entries", nc)); + if (overflow2(sizeof(t_chunk_info), nc)) { + goto fail1; + } + sidx = sizeof(t_chunk_info) * nc; + if (sidx <= 0) { + goto fail1; + } + + cidx = gdCalloc(sidx, 1); + if (cidx == NULL) { + goto fail1; + } + + for (i = 0; i < nc; i++) { + if (gdGetInt(&cidx[i].offset, in) != 1) { + goto fail2; + }; + if (gdGetInt(&cidx[i].size, in) != 1) { + goto fail2; + }; + if (cidx[i].offset < 0 || cidx[i].size < 0 || cidx[i].size == INT_MAX) + goto fail2; + }; + *chunkIdx = cidx; + }; + + GD2_DBG(gd_error("gd2 header complete")); + + return 1; +fail2: + gdFree(cidx); fail1: - return 0; + return 0; } -static gdImagePtr _gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** cidx) +static gdImagePtr _gd2CreateFromFile(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, + int *ncx, int *ncy, t_chunk_info **cidx) { - gdImagePtr im; - - if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) { - GD2_DBG(gd_error("Bad GD2 header")); - goto fail1; - } - - if (gd2_truecolor(*fmt)) { - im = gdImageCreateTrueColor(*sx, *sy); - } else { - im = gdImageCreate(*sx, *sy); - } - if (im == NULL) { - GD2_DBG(gd_error("Could not create gdImage")); - goto fail2; - } - - if (!_gdGetColors(in, im, (*vers) == 2)) { - GD2_DBG(gd_error("Could not read color palette")); - goto fail3; - } - GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); - - return im; + gdImagePtr im; + + if (_gd2GetHeader(in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) { + GD2_DBG(gd_error("Bad GD2 header")); + goto fail1; + } + + if (gd2_truecolor(*fmt)) { + im = gdImageCreateTrueColor(*sx, *sy); + } else { + im = gdImageCreate(*sx, *sy); + } + if (im == NULL) { + GD2_DBG(gd_error("Could not create gdImage")); + goto fail2; + } + + if (!_gdGetColors(in, im, (*vers) == 2)) { + GD2_DBG(gd_error("Could not read color palette")); + goto fail3; + } + GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); + + return im; fail3: - gdImageDestroy(im); + gdImageDestroy(im); fail2: - gdFree(*cidx); + gdFree(*cidx); fail1: - return 0; + return 0; } -static int _gd2ReadChunk (int offset, char *compBuf, int compSize, char *chunkBuf, uLongf * chunkLen, gdIOCtx * in) +static int _gd2ReadChunk(int offset, char *compBuf, int compSize, char *chunkBuf, uLongf *chunkLen, + gdIOCtx *in) { - int zerr; - - if (gdTell(in) != offset) { - GD2_DBG(gd_error("Positioning in file to %d", offset)); - gdSeek(in, offset); - } else { - GD2_DBG(gd_error("Already Positioned in file to %d", offset)); - } - - /* Read and uncompress an entire chunk. */ - GD2_DBG(gd_error("Reading file")); - if (gdGetBuf(compBuf, compSize, in) != compSize) { - return FALSE; - } - GD2_DBG(gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen)); - zerr = uncompress((unsigned char *) chunkBuf, chunkLen, (unsigned char *) compBuf, compSize); - if (zerr != Z_OK) { - GD2_DBG(gd_error("Error %d from uncompress", zerr)); - return FALSE; - } - GD2_DBG(gd_error("Got chunk")); - - return TRUE; + int zerr; + + if (gdTell(in) != offset) { + GD2_DBG(gd_error("Positioning in file to %d", offset)); + gdSeek(in, offset); + } else { + GD2_DBG(gd_error("Already Positioned in file to %d", offset)); + } + + /* Read and uncompress an entire chunk. */ + GD2_DBG(gd_error("Reading file")); + if (gdGetBuf(compBuf, compSize, in) != compSize) { + return FALSE; + } + GD2_DBG( + gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen)); + zerr = uncompress((unsigned char *)chunkBuf, chunkLen, (unsigned char *)compBuf, compSize); + if (zerr != Z_OK) { + GD2_DBG(gd_error("Error %d from uncompress", zerr)); + return FALSE; + } + GD2_DBG(gd_error("Got chunk")); + + return TRUE; } +/* + Function: gdImageCreateFromGd2 + + is called to load images from gd2 format + files. Invoke with an already opened + pointer to a file containing the desired image in the gd2 file + format, which is specific to gd2 and intended for fast loading of + parts of large images. (It is a compressed format, but generally + not as good as maximum compression of the entire image would be.) + + returns a to the new image, or + NULL if unable to load the image (most often because the file is + corrupt or does not contain a gd format + image). does not close the file. You can + inspect the sx and sy members of the image to determine its + size. The image must eventually be destroyed using + . + + + Variants: + + creates an image from GD data (i.e. the + contents of a GD2 file) already in memory. -gdImagePtr gdImageCreateFromGd2 (FILE * inFile) + reads in an image using the functions in + a struct. + + Parameters: + + infile - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + + > gdImagePtr im; + > FILE *in; + > in = fopen("mygd.gd2", "rb"); + > im = gdImageCreateFromGd2(in); + > fclose(in); + > // ... Use the image ... + > gdImageDestroy(im); +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2(FILE *inFile) { - gdIOCtx *in = gdNewFileCtx(inFile); - gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + gdImagePtr im; - im = gdImageCreateFromGd2Ctx(in); + if (in == NULL) + return NULL; + im = gdImageCreateFromGd2Ctx(in); - in->gd_free(in); + in->gd_free(in); - return im; + return im; } -gdImagePtr gdImageCreateFromGd2Ptr (int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromGd2Ctx(in); - in->gd_free(in); +/* + Function: gdImageCreateFromGd2Ptr + + Parameters: - return im; + size - size of GD2 data in bytes. + data - GD2 data (i.e. contents of a GIF file). + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ptr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromGd2Ctx(in); + in->gd_free(in); + + return im; } -gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in) +/* + Function: gdImageCreateFromGd2Ctx + + Reads in a GD2 image via a struct. See + . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx(gdIOCtxPtr in) { - int sx, sy; - int i; - int ncx, ncy, nc, cs, cx, cy; - int x, y, ylo, yhi, xlo, xhi; - int vers, fmt; - t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ - unsigned char *chunkBuf = NULL; /* So we can gdFree it with impunity. */ - int chunkNum = 0; - int chunkMax = 0; - uLongf chunkLen; - int chunkPos = 0; - int compMax = 0; - int bytesPerPixel; - char *compBuf = NULL; /* So we can gdFree it with impunity. */ - - gdImagePtr im; - - /* Get the header */ - if (!(im = _gd2CreateFromFile(in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx))) { - return 0; - } - - bytesPerPixel = im->trueColor ? 4 : 1; - nc = ncx * ncy; - - if (gd2_compressed(fmt)) { - /* Find the maximum compressed chunk size. */ - compMax = 0; - for (i = 0; (i < nc); i++) { - if (chunkIdx[i].size > compMax) { - compMax = chunkIdx[i].size; - } - } - compMax++; - - /* Allocate buffers */ - chunkMax = cs * bytesPerPixel * cs; - if (chunkMax <= 0) { - return 0; - } - chunkBuf = gdCalloc(chunkMax, 1); - compBuf = gdCalloc(compMax, 1); - - GD2_DBG(gd_error("Largest compressed chunk is %d bytes", compMax)); - } - - /* Read the data... */ - for (cy = 0; (cy < ncy); cy++) { - for (cx = 0; (cx < ncx); cx++) { - ylo = cy * cs; - yhi = ylo + cs; - if (yhi > im->sy) { - yhi = im->sy; - } - - GD2_DBG(gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, yhi)); - - if (gd2_compressed(fmt)) { - chunkLen = chunkMax; - - if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *) chunkBuf, &chunkLen, in)) { - GD2_DBG(gd_error("Error reading comproessed chunk")); - goto fail2; - } - - chunkPos = 0; - } - - for (y = ylo; (y < yhi); y++) { - xlo = cx * cs; - xhi = xlo + cs; - if (xhi > im->sx) { - xhi = im->sx; - } - - if (!gd2_compressed(fmt)) { - for (x = xlo; x < xhi; x++) { - if (im->trueColor) { - if (!gdGetInt(&im->tpixels[y][x], in)) { - gd_error("gd2: EOF while reading\n"); - gdImageDestroy(im); - return NULL; - } - } else { - int ch; - if (!gdGetByte(&ch, in)) { - gd_error("gd2: EOF while reading\n"); - gdImageDestroy(im); - return NULL; - } - im->pixels[y][x] = ch; - } - } - } else { - for (x = xlo; x < xhi; x++) { - if (im->trueColor) { - /* 2.0.1: work around a gcc bug by being verbose. TBB */ - int a = chunkBuf[chunkPos++] << 24; - int r = chunkBuf[chunkPos++] << 16; - int g = chunkBuf[chunkPos++] << 8; - int b = chunkBuf[chunkPos++]; - im->tpixels[y][x] = a + r + g + b; - } else { - im->pixels[y][x] = chunkBuf[chunkPos++]; - } - } - } - } - chunkNum++; - } - } - - GD2_DBG(gd_error("Freeing memory")); - - if (chunkBuf) { - gdFree(chunkBuf); - } - if (compBuf) { - gdFree(compBuf); - } - if (chunkIdx) { - gdFree(chunkIdx); - } - - GD2_DBG(gd_error("Done")); - - return im; + int sx, sy; + int i; + int ncx, ncy, nc, cs, cx, cy; + int x, y, ylo, yhi, xlo, xhi; + int vers, fmt; + t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ + unsigned char *chunkBuf = NULL; /* So we can gdFree it with impunity. */ + int chunkNum = 0; + int chunkMax = 0; + uLongf chunkLen; + int chunkPos = 0; + int compMax = 0; + int bytesPerPixel; + char *compBuf = NULL; /* So we can gdFree it with impunity. */ + + gdImagePtr im; + + /* Get the header */ + if (!(im = _gd2CreateFromFile(in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx))) { + return 0; + } + + bytesPerPixel = im->trueColor ? 4 : 1; + if (overflow2(ncx, ncy)) + goto fail; + nc = ncx * ncy; + + if (overflow2(ncy, cs) || overflow2(ncx, cs) || overflow2(bytesPerPixel, cs)) + goto fail; + + if (gd2_compressed(fmt)) { + /* Find the maximum compressed chunk size. */ + compMax = 0; + for (i = 0; (i < nc); i++) { + if (chunkIdx[i].size > compMax) { + compMax = chunkIdx[i].size; + } + } + compMax++; + + /* Allocate buffers */ + chunkMax = cs * bytesPerPixel * cs; + chunkBuf = gdCalloc(chunkMax, 1); + if (!chunkBuf) { + goto fail; + } + compBuf = gdCalloc(compMax, 1); + if (!compBuf) { + goto fail; + } + + GD2_DBG(printf("Largest compressed chunk is %d bytes\n", compMax)); + }; + + /* Read the data... */ + for (cy = 0; (cy < ncy); cy++) { + for (cx = 0; (cx < ncx); cx++) { + ylo = cy * cs; + yhi = ylo + cs; + if (yhi > im->sy) { + yhi = im->sy; + } + + GD2_DBG(gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, + yhi)); + + if (gd2_compressed(fmt)) { + chunkLen = chunkMax; + + if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, + (char *)chunkBuf, &chunkLen, in)) { + GD2_DBG(gd_error("Error reading comproessed chunk")); + goto fail; + } + + chunkPos = 0; + } + + for (y = ylo; (y < yhi); y++) { + xlo = cx * cs; + xhi = xlo + cs; + if (xhi > im->sx) { + xhi = im->sx; + } + + if (!gd2_compressed(fmt)) { + for (x = xlo; x < xhi; x++) { + if (im->trueColor) { + if (!gdGetInt(&im->tpixels[y][x], in)) { + gd_error("gd2: EOF while reading\n"); + goto fail; + } + } else { + int ch; + if (!gdGetByte(&ch, in)) { + gd_error("gd2: EOF while reading\n"); + goto fail; + } + im->pixels[y][x] = ch; + } + } + } else { + for (x = xlo; x < xhi; x++) { + if (im->trueColor) { + /* 2.0.1: work around a gcc bug by being verbose. TBB */ + int a = chunkBuf[chunkPos++] << 24; + int r = chunkBuf[chunkPos++] << 16; + int g = chunkBuf[chunkPos++] << 8; + int b = chunkBuf[chunkPos++]; + im->tpixels[y][x] = a + r + g + b; + } else { + im->pixels[y][x] = chunkBuf[chunkPos++]; + } + } + } + } + chunkNum++; + } + } + + GD2_DBG(gd_error("Freeing memory")); + + if (chunkBuf) { + gdFree(chunkBuf); + } + if (compBuf) { + gdFree(compBuf); + } + if (chunkIdx) { + gdFree(chunkIdx); + } + + GD2_DBG(gd_error("Done")); + + return im; -fail2: - gdImageDestroy(im); - if (chunkBuf) { - gdFree(chunkBuf); - } - if (compBuf) { - gdFree(compBuf); - } - if (chunkIdx) { - gdFree(chunkIdx); - } - - return 0; +fail: + gdImageDestroy(im); + if (chunkBuf) { + gdFree(chunkBuf); + } + if (compBuf) { + gdFree(compBuf); + } + if (chunkIdx) { + gdFree(chunkIdx); + } + + return 0; } -gdImagePtr gdImageCreateFromGd2PartPtr (int size, void *data, int srcx, int srcy, int w, int h) +/* + Function: gdImageCreateFromGd2Part + + is called to load parts of images from + gd2 format files. Invoked in the same way as , + but with extra parameters indicating the source (x, y) and + width/height of the desired image. + returns a to the new image, or NULL if unable to load + the image. The image must eventually be destroyed using + . + + Variants: + + creates an image from GD2 data + (i.e. the contents of a GD2 file) already in memory. + + reads in an image using the functions in + a struct. + + Parameters: + + infile - The input FILE pointer + srcx, srcy - The source X and Y coordinates + w, h - The resulting image's width and height + + Returns: + + A pointer to the new image or NULL if an error occurred. + +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Part(FILE *inFile, int srcx, int srcy, int w, int h) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromGd2PartCtx(in, srcx, srcy, w, h); - in->gd_free(in); + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromGd2PartCtx(in, srcx, srcy, w, h); + + in->gd_free(in); - return im; + return im; } -gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h) -{ - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx(inFile); +/* + Function: gdImageCreateFromGd2PartPtr - im = gdImageCreateFromGd2PartCtx(in, srcx, srcy, w, h); + Parameters: - in->gd_free(in); + size - size of GD data in bytes. + data - GD data (i.e. contents of a GIF file). + srcx, srcy - The source X and Y coordinates + w, h - The resulting image's width and height - return im; + Reads in part of a GD2 image file stored from memory. See + . +*/ +BGD_DECLARE(gdImagePtr) +gdImageCreateFromGd2PartPtr(int size, void *data, int srcx, int srcy, int w, int h) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromGd2PartCtx(in, srcx, srcy, w, h); + in->gd_free(in); + return im; } -gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h) +/* + Function: gdImageCreateFromGd2PartCtx + + Parameters: + + in - The data source. + srcx, srcy - The source X and Y coordinates + w, h - The resulting image's width and height + + Reads in part of a GD2 data image file via a struct. See + . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2PartCtx(gdIOCtx *in, int srcx, int srcy, int w, int h) { - int scx, scy, ecx, ecy, fsx, fsy; - int nc, ncx, ncy, cs, cx, cy; - int x, y, ylo, yhi, xlo, xhi; - int dstart, dpos; - int i; - /* 2.0.12: unsigned is correct; fixes problems with color munging. Thanks to Steven Brown. */ - unsigned int ch; - int vers, fmt; - t_chunk_info *chunkIdx = NULL; - unsigned char *chunkBuf = NULL; - int chunkNum; - int chunkMax = 0; - uLongf chunkLen; - int chunkPos = 0; - int compMax; - char *compBuf = NULL; - - gdImagePtr im; - - if (w<1 || h <1) { - return 0; - } - - /* The next few lines are basically copied from gd2CreateFromFile - * we change the file size, so don't want to use the code directly. - * but we do need to know the file size. - */ - if (_gd2GetHeader(in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1) { - goto fail1; - } - - GD2_DBG(gd_error("File size is %dx%d", fsx, fsy)); - - /* This is the difference - make a file based on size of chunks. */ - if (gd2_truecolor(fmt)) { - im = gdImageCreateTrueColor(w, h); - } else { - im = gdImageCreate(w, h); - } - if (im == NULL) { - goto fail1; - } - - if (!_gdGetColors(in, im, vers == 2)) { - goto fail2; - } - GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); - - /* Process the header info */ - nc = ncx * ncy; - - if (gd2_compressed(fmt)) { - /* Find the maximum compressed chunk size. */ - compMax = 0; - for (i = 0; (i < nc); i++) { - if (chunkIdx[i].size > compMax) { - compMax = chunkIdx[i].size; - } - } - compMax++; - - if (im->trueColor) { - chunkMax = cs * cs * 4; - } else { - chunkMax = cs * cs; - } - if (chunkMax <= 0) { - goto fail2; - } - - chunkBuf = gdCalloc(chunkMax, 1); - compBuf = gdCalloc(compMax, 1); - } - - /* Work out start/end chunks */ - scx = srcx / cs; - scy = srcy / cs; - if (scx < 0) { - scx = 0; - } - if (scy < 0) { - scy = 0; - } - - ecx = (srcx + w) / cs; - ecy = (srcy + h) / cs; - if (ecx >= ncx) { - ecx = ncx - 1; - } - if (ecy >= ncy) { - ecy = ncy - 1; - } - - /* Remember file position of image data. */ - dstart = gdTell(in); - GD2_DBG(gd_error("Data starts at %d", dstart)); - - /* Loop through the chunks. */ - for (cy = scy; (cy <= ecy); cy++) { - ylo = cy * cs; - yhi = ylo + cs; - if (yhi > fsy) { - yhi = fsy; - } - - for (cx = scx; cx <= ecx; cx++) { - - xlo = cx * cs; - xhi = xlo + cs; - if (xhi > fsx) { - xhi = fsx; - } - - GD2_DBG(gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi)); - - if (!gd2_compressed(fmt)) { - GD2_DBG(gd_error("Using raw format data")); - if (im->trueColor) { - dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart; - } else { - dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart; - } - - /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */ - if (!gdSeek(in, dpos)) { - gd_error_ex(E_WARNING, "Error from seek: %d", errno); - goto fail2; - } - GD2_DBG(gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart)); - } else { - chunkNum = cx + cy * ncx; - - chunkLen = chunkMax; - if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *)chunkBuf, &chunkLen, in)) { - gd_error("Error reading comproessed chunk"); - goto fail2; - } - chunkPos = 0; - GD2_DBG(gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum)); - } - - GD2_DBG(gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi)); - - for (y = ylo; (y < yhi); y++) { - for (x = xlo; x < xhi; x++) { - if (!gd2_compressed(fmt)) { - if (im->trueColor) { - if (!gdGetInt((int *)&ch, in)) { - ch = 0; - } - } else { - ch = gdGetC(in); - if ((int)ch == EOF) { - ch = 0; - } - } - } else { - if (im->trueColor) { - ch = chunkBuf[chunkPos++]; - ch = (ch << 8) + chunkBuf[chunkPos++]; - ch = (ch << 8) + chunkBuf[chunkPos++]; - ch = (ch << 8) + chunkBuf[chunkPos++]; - } else { - ch = chunkBuf[chunkPos++]; - } - } - - /* Only use a point that is in the image. */ - if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)) { - if (im->trueColor) { - im->tpixels[y - srcy][x - srcx] = ch; - } else { - im->pixels[y - srcy][x - srcx] = ch; - } - } - } - } - } - } - - if (chunkBuf) { - gdFree(chunkBuf); - } - if (compBuf) { - gdFree(compBuf); - } - if (chunkIdx) { - gdFree(chunkIdx); - } - - return im; + int scx, scy, ecx, ecy, fsx, fsy; + int nc, ncx, ncy, cs, cx, cy; + int x, y, ylo, yhi, xlo, xhi; + int dstart, dpos; + int i; + /* 2.0.12: unsigned is correct; fixes problems with color munging. Thanks to Steven Brown. */ + unsigned int ch; + int vers, fmt; + t_chunk_info *chunkIdx = NULL; + unsigned char *chunkBuf = NULL; + int chunkNum; + int chunkMax = 0; + uLongf chunkLen; + int chunkPos = 0; + int compMax; + char *compBuf = NULL; + + gdImagePtr im; + if (w < 1 || h < 1) { + return 0; + } + + /* The next few lines are basically copied from gd2CreateFromFile + * we change the file size, so don't want to use the code directly. + * but we do need to know the file size. + */ + if (_gd2GetHeader(in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1) { + goto fail1; + } + + GD2_DBG(gd_error("File size is %dx%d", fsx, fsy)); + + /* This is the difference - make a file based on size of chunks. */ + if (gd2_truecolor(fmt)) { + im = gdImageCreateTrueColor(w, h); + } else { + im = gdImageCreate(w, h); + } + if (im == NULL) { + goto fail1; + } + + if (!_gdGetColors(in, im, vers == 2)) { + goto fail2; + } + GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); + + /* Process the header info */ + nc = ncx * ncy; + + if (gd2_compressed(fmt)) { + /* Find the maximum compressed chunk size. */ + compMax = 0; + for (i = 0; (i < nc); i++) { + if (chunkIdx[i].size > compMax) { + compMax = chunkIdx[i].size; + } + } + compMax++; + + if (im->trueColor) { + chunkMax = cs * cs * 4; + } else { + chunkMax = cs * cs; + } + if (chunkMax <= 0) { + goto fail2; + } + + chunkBuf = gdCalloc(chunkMax, 1); + if (!chunkBuf) { + goto fail2; + } + compBuf = gdCalloc(compMax, 1); + if (!compBuf) { + goto fail2; + } + } + + /* Work out start/end chunks */ + scx = srcx / cs; + scy = srcy / cs; + if (scx < 0) { + scx = 0; + } + if (scy < 0) { + scy = 0; + } + + ecx = (srcx + w) / cs; + ecy = (srcy + h) / cs; + if (ecx >= ncx) { + ecx = ncx - 1; + } + if (ecy >= ncy) { + ecy = ncy - 1; + } + + /* Remember file position of image data. */ + dstart = gdTell(in); + GD2_DBG(gd_error("Data starts at %d", dstart)); + + /* Loop through the chunks. */ + for (cy = scy; (cy <= ecy); cy++) { + ylo = cy * cs; + yhi = ylo + cs; + if (yhi > fsy) { + yhi = fsy; + } + + for (cx = scx; (cx <= ecx); cx++) { + + xlo = cx * cs; + xhi = xlo + cs; + if (xhi > fsx) { + xhi = fsx; + } + + GD2_DBG(gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi)); + + if (!gd2_compressed(fmt)) { + GD2_DBG(gd_error("Using raw format data")); + if (im->trueColor) { + dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart; + } else { + dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart; + } + + /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */ + if (!gdSeek(in, dpos)) { + gd_error_ex(E_WARNING, "Error from seek: %d", errno); + goto fail2; + } + GD2_DBG(gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart)); + } else { + chunkNum = cx + cy * ncx; + + chunkLen = chunkMax; + if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, + (char *)chunkBuf, &chunkLen, in)) { + gd_error("Error reading comproessed chunk"); + goto fail2; + } + chunkPos = 0; + GD2_DBG(gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum)); + } + + GD2_DBG(gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi)); + for (y = ylo; (y < yhi); y++) { + for (x = xlo; x < xhi; x++) { + if (!gd2_compressed(fmt)) { + if (im->trueColor) { + if (!gdGetInt((int *)&ch, in)) { + ch = 0; + } + } else { + ch = gdGetC(in); + if ((int)ch == EOF) { + ch = 0; + } + } + } else { + if (im->trueColor) { + ch = chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + } else { + ch = chunkBuf[chunkPos++]; + } + } + + /* Only use a point that is in the image. */ + if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && + (y < (srcy + h)) && (y < fsy) && (y >= 0)) { + if (im->trueColor) { + im->tpixels[y - srcy][x - srcx] = ch; + } else { + im->pixels[y - srcy][x - srcx] = ch; + } + } + } + } + } + } + + if (chunkBuf) { + gdFree(chunkBuf); + } + if (compBuf) { + gdFree(compBuf); + } + if (chunkIdx) { + gdFree(chunkIdx); + } + return im; fail2: - gdImageDestroy(im); + gdImageDestroy(im); fail1: - if (chunkBuf) { - gdFree(chunkBuf); - } - if (compBuf) { - gdFree(compBuf); - } - if (chunkIdx) { - gdFree(chunkIdx); - } - - return 0; + if (chunkBuf) { + gdFree(chunkBuf); + } + if (compBuf) { + gdFree(compBuf); + } + if (chunkIdx) { + gdFree(chunkIdx); + } + return 0; } -static void _gd2PutHeader (gdImagePtr im, gdIOCtx * out, int cs, int fmt, int cx, int cy) +static void _gd2PutHeader(gdImagePtr im, gdIOCtx *out, int cs, int fmt, int cx, int cy) { - int i; - - /* Send the gd2 id, to verify file format. */ - for (i = 0; i < 4; i++) { - gdPutC((unsigned char) (GD2_ID[i]), out); - } - - /* We put the version info first, so future versions can easily change header info. */ - - gdPutWord(GD2_VERS, out); - gdPutWord(im->sx, out); - gdPutWord(im->sy, out); - gdPutWord(cs, out); - gdPutWord(fmt, out); - gdPutWord(cx, out); - gdPutWord(cy, out); + int i; + + /* Send the gd2 id, to verify file format. */ + for (i = 0; i < 4; i++) { + gdPutC((unsigned char)(GD2_ID[i]), out); + } + + /* We put the version info first, so future versions can easily change header info. */ + + gdPutWord(GD2_VERS, out); + gdPutWord(im->sx, out); + gdPutWord(im->sy, out); + gdPutWord(cs, out); + gdPutWord(fmt, out); + gdPutWord(cx, out); + gdPutWord(cy, out); } -static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) +/* returns 0 on success, 1 on failure */ +static int _gdImageGd2(gdImagePtr im, gdIOCtx *out, int cs, int fmt) { - int ncx, ncy, cx, cy; - int x, y, ylo, yhi, xlo, xhi; - int chunkLen; - int chunkNum = 0; - char *chunkData = NULL; /* So we can gdFree it with impunity. */ - char *compData = NULL; /* So we can gdFree it with impunity. */ - uLongf compLen; - int idxPos = 0; - int idxSize; - t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ - int posSave; - int bytesPerPixel = im->trueColor ? 4 : 1; - int compMax = 0; - - /* Force fmt to a valid value since we don't return anything. */ - if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { - fmt = GD2_FMT_COMPRESSED; - } - if (im->trueColor) { - fmt += 2; - } - /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems - * a little silly to expect performance improvements on a 64x64 bit scale, and - * 4096 because we buffer one chunk, and a 16MB buffer seems a little large - it may be - * OK for one user, but for another to read it, they require the buffer. - */ - if (cs == 0) { - cs = GD2_CHUNKSIZE; - } else if (cs < GD2_CHUNKSIZE_MIN) { - cs = GD2_CHUNKSIZE_MIN; - } else if (cs > GD2_CHUNKSIZE_MAX) { - cs = GD2_CHUNKSIZE_MAX; - } - - /* Work out number of chunks. */ - ncx = (im->sx + cs - 1) / cs; - ncy = (im->sy + cs - 1) / cs; - - /* Write the standard header. */ - _gd2PutHeader (im, out, cs, fmt, ncx, ncy); - - if (gd2_compressed(fmt)) { - /* Work out size of buffer for compressed data, If CHUNKSIZE is large, - * then these will be large! - */ - - /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 - * - we'll use 1.02 to be paranoid. - */ - compMax = (int)(cs * bytesPerPixel * cs * 1.02f) + 12; - - /* Allocate the buffers. */ - chunkData = safe_emalloc(cs * bytesPerPixel, cs, 0); - memset(chunkData, 0, cs * bytesPerPixel * cs); - if (compMax <= 0) { - goto fail; - } - compData = gdCalloc(compMax, 1); - - /* Save the file position of chunk index, and allocate enough space for - * each chunk_info block . - */ - idxPos = gdTell(out); - idxSize = ncx * ncy * sizeof(t_chunk_info); - GD2_DBG(gd_error("Index size is %d", idxSize)); - gdSeek(out, idxPos + idxSize); - - chunkIdx = safe_emalloc(idxSize, sizeof(t_chunk_info), 0); - memset(chunkIdx, 0, idxSize * sizeof(t_chunk_info)); - } - - _gdPutColors (im, out); - - GD2_DBG(gd_error("Size: %dx%d", im->sx, im->sy)); - GD2_DBG(gd_error("Chunks: %dx%d", ncx, ncy)); - - for (cy = 0; (cy < ncy); cy++) { - for (cx = 0; (cx < ncx); cx++) { - ylo = cy * cs; - yhi = ylo + cs; - if (yhi > im->sy) { - yhi = im->sy; - } - - GD2_DBG(gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi)); - chunkLen = 0; - for (y = ylo; (y < yhi); y++) { - GD2_DBG(gd_error("y=%d: ",y)); - xlo = cx * cs; - xhi = xlo + cs; - if (xhi > im->sx) { - xhi = im->sx; - } - - if (gd2_compressed(fmt)) { - for (x = xlo; x < xhi; x++) { - GD2_DBG(gd_error("%d...",x)); - if (im->trueColor) { - int p = im->tpixels[y][x]; - chunkData[chunkLen++] = gdTrueColorGetAlpha(p); - chunkData[chunkLen++] = gdTrueColorGetRed(p); - chunkData[chunkLen++] = gdTrueColorGetGreen(p); - chunkData[chunkLen++] = gdTrueColorGetBlue(p); - } else { - chunkData[chunkLen++] = im->pixels[y][x]; - } - } - } else { - for (x = xlo; x < xhi; x++) { - GD2_DBG(gd_error("%d, ",x)); - - if (im->trueColor) { - gdPutInt(im->tpixels[y][x], out); - } else { - gdPutC((unsigned char) im->pixels[y][x], out); - } - } - } - GD2_DBG(gd_error("y=%d done.",y)); - } - - if (gd2_compressed(fmt)) { - compLen = compMax; - if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) { - gd_error("Error from compressing"); - } else { - chunkIdx[chunkNum].offset = gdTell(out); - chunkIdx[chunkNum++].size = compLen; - GD2_DBG(gd_error("Chunk %d size %d offset %d", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); - - if (gdPutBuf (compData, compLen, out) <= 0) { - /* Any alternate suggestions for handling this? */ - gd_error_ex(E_WARNING, "Error %d on write", errno); - } - } - } - } - } - - if (gd2_compressed(fmt)) { - /* Save the position, write the index, restore position (paranoia). */ - GD2_DBG(gd_error("Seeking %d to write index", idxPos)); - posSave = gdTell(out); - gdSeek(out, idxPos); - GD2_DBG(gd_error("Writing index")); - for (x = 0; x < chunkNum; x++) { - GD2_DBG(gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset)); - gdPutInt(chunkIdx[x].offset, out); - gdPutInt(chunkIdx[x].size, out); - } - gdSeek(out, posSave); - } + int ret = 0; + int ncx, ncy, cx, cy; + int x, y, ylo, yhi, xlo, xhi; + int chunkLen; + int chunkNum = 0; + char *chunkData = NULL; /* So we can gdFree it with impunity. */ + char *compData = NULL; /* So we can gdFree it with impunity. */ + uLongf compLen; + int idxPos = 0; + int idxSize; + t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ + int posSave; + int bytesPerPixel = im->trueColor ? 4 : 1; + int compMax = 0; + + /* Force fmt to a valid value since we don't return anything. */ + if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { + fmt = GD2_FMT_COMPRESSED; + } + if (im->trueColor) { + fmt += 2; + } + /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems + * a little silly to expect performance improvements on a 64x64 bit scale, and + * 4096 because we buffer one chunk, and a 16MB buffer seems a little large - it may be + * OK for one user, but for another to read it, they require the buffer. + */ + if (cs == 0) { + cs = GD2_CHUNKSIZE; + } else if (cs < GD2_CHUNKSIZE_MIN) { + cs = GD2_CHUNKSIZE_MIN; + } else if (cs > GD2_CHUNKSIZE_MAX) { + cs = GD2_CHUNKSIZE_MAX; + } + + /* Work out number of chunks. */ + ncx = (im->sx + cs - 1) / cs; + ncy = (im->sy + cs - 1) / cs; + + /* Write the standard header. */ + _gd2PutHeader(im, out, cs, fmt, ncx, ncy); + + if (gd2_compressed(fmt)) { + /* Work out size of buffer for compressed data, If CHUNKSIZE is large, + * then these will be large! + * The zlib notes say output buffer size should be (input size) * 1.01 * 12 + * - we'll use 1.02 to be paranoid. + */ + compMax = (int)(cs * bytesPerPixel * cs * 1.02f) + 12; + + chunkData = gdCalloc(cs * bytesPerPixel * cs, 1); + if (!chunkData) { + ret = 1; + goto fail; + } + compData = gdCalloc(compMax, 1); + if (!compData) { + ret = 1; + goto fail; + } + + /* Save the file position of chunk index, and allocate enough space for + * each chunk_info block . + */ + idxPos = gdTell(out); + idxSize = ncx * ncy * sizeof(t_chunk_info); + GD2_DBG(gd_error("Index size is %d", idxSize)); + gdSeek(out, idxPos + idxSize); + + chunkIdx = gdCalloc(idxSize * sizeof(t_chunk_info), 1); + if (!chunkIdx) { + ret = 1; + goto fail; + } + } + + _gdPutColors(im, out); + + GD2_DBG(gd_error("Size: %dx%d", im->sx, im->sy)); + GD2_DBG(gd_error("Chunks: %dx%d", ncx, ncy)); + + for (cy = 0; (cy < ncy); cy++) { + for (cx = 0; (cx < ncx); cx++) { + ylo = cy * cs; + yhi = ylo + cs; + if (yhi > im->sy) { + yhi = im->sy; + } + + GD2_DBG(gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi)); + chunkLen = 0; + for (y = ylo; (y < yhi); y++) { + xlo = cx * cs; + xhi = xlo + cs; + if (xhi > im->sx) { + xhi = im->sx; + } + + if (gd2_compressed(fmt)) { + for (x = xlo; x < xhi; x++) { + if (im->trueColor) { + int p = im->tpixels[y][x]; + chunkData[chunkLen++] = gdTrueColorGetAlpha(p); + chunkData[chunkLen++] = gdTrueColorGetRed(p); + chunkData[chunkLen++] = gdTrueColorGetGreen(p); + chunkData[chunkLen++] = gdTrueColorGetBlue(p); + } else { + chunkData[chunkLen++] = im->pixels[y][x]; + } + } + } else { + for (x = xlo; x < xhi; x++) { + if (im->trueColor) { + gdPutInt(im->tpixels[y][x], out); + } else { + gdPutC((unsigned char)im->pixels[y][x], out); + } + } + } + } + if (gd2_compressed(fmt)) { + compLen = compMax; + if (compress((unsigned char *)&compData[0], &compLen, + (unsigned char *)&chunkData[0], chunkLen) != Z_OK) { + gd_error("Error from compressing"); + } else { + chunkIdx[chunkNum].offset = gdTell(out); + chunkIdx[chunkNum++].size = compLen; + GD2_DBG(gd_error("Chunk %d size %d offset %d", chunkNum, + chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); + + if (gdPutBuf(compData, compLen, out) <= 0) { + /* Any alternate suggestions for handling this? */ + gd_error_ex(E_WARNING, "Error %d on write", errno); + } + } + } + } + } + if (gd2_compressed(fmt)) { + /* Save the position, write the index, restore position (paranoia). */ + GD2_DBG(gd_error("Seeking %d to write index", idxPos)); + posSave = gdTell(out); + gdSeek(out, idxPos); + GD2_DBG(gd_error("Writing index")); + for (x = 0; x < chunkNum; x++) { + GD2_DBG( + gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset)); + gdPutInt(chunkIdx[x].offset, out); + gdPutInt(chunkIdx[x].size, out); + } + gdSeek(out, posSave); + } fail: - GD2_DBG(gd_error("Freeing memory")); - if (chunkData) { - gdFree(chunkData); - } - if (compData) { - gdFree(compData); - } - if (chunkIdx) { - gdFree(chunkIdx); - } - GD2_DBG(gd_error("Done")); + GD2_DBG(gd_error("Freeing memory")); + if (chunkData) { + gdFree(chunkData); + } + if (compData) { + gdFree(compData); + } + if (chunkIdx) { + gdFree(chunkIdx); + } + GD2_DBG(gd_error("Done")); + + return ret; } -void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt) +/* + Function: gdImageGd2 +*/ +BGD_DECLARE(void) gdImageGd2(gdImagePtr im, FILE *outFile, int cs, int fmt) { - gdIOCtx *out = gdNewFileCtx(outFile); - - _gdImageGd2(im, out, cs, fmt); - - out->gd_free(out); + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + _gdImageGd2(im, out, cs, fmt); + out->gd_free(out); } -void *gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size) +/* + Function: gdImageGd2Ptr +*/ +BGD_DECLARE(void *) gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - - _gdImageGd2(im, out, cs, fmt); - rv = gdDPExtractData(out, size); - out->gd_free(out); - - return rv; + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + + if (_gdImageGd2(im, out, cs, fmt)) { + rv = NULL; + } else { + rv = gdDPExtractData(out, size); + } + + out->gd_free(out); + return rv; } diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index 0204c4158db4..5a19a8a3abd1 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -1,9 +1,15 @@ -#include -#include -#include -#include +/** + * File: GIF Input + * + * Read GIF images. + */ #include "gd.h" #include "gd_errors.h" +#include "gdhelpers.h" +#include +#include +#include +#include #include "php.h" @@ -14,13 +20,13 @@ static int verbose_set = 0; static int verbose; -#define VERBOSE (verbose_set?verbose:set_verbose()) +#define VERBOSE (verbose_set ? verbose : set_verbose()) static int set_verbose(void) { - verbose = !!getenv("GIF_VERBOSE"); - verbose_set = 1; - return(verbose); + verbose = !!getenv("GIF_VERBOSE"); + verbose_set = 1; + return (verbose); } #else @@ -29,25 +35,25 @@ static int set_verbose(void) #endif +#define MAXCOLORMAPSIZE 256 -#define MAXCOLORMAPSIZE 256 +#define TRUE 1 +#define FALSE 0 -#define TRUE 1 -#define FALSE 0 +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 -#define CM_RED 0 -#define CM_GREEN 1 -#define CM_BLUE 2 +#define MAX_LWZ_BITS 12 -#define MAX_LWZ_BITS 12 +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 -#define INTERLACE 0x40 -#define LOCALCOLORMAP 0x80 -#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) -#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0) +#define ReadOK(file, buffer, len) (gdGetBuf(buffer, len, file) == len) -#define LM_to_uint(a,b) (((b)<<8)|(a)) +#define LM_to_uint(a, b) (((b) << 8) | (a)) /* We may eventually want to use this information, but def it out for now */ #if 0 @@ -71,581 +77,1469 @@ static struct { } Gif89 = { -1, -1, -1, 0 }; #endif -#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) +#define STACK_SIZE ((1 << (MAX_LWZ_BITS)) * 2) #define CSD_BUF_SIZE 280 typedef struct { - unsigned char buf[CSD_BUF_SIZE]; - int curbit, lastbit, done, last_byte; + unsigned char buf[CSD_BUF_SIZE]; + int curbit; + int lastbit; + int done; + int last_byte; } CODE_STATIC_DATA; typedef struct { - int fresh; - int code_size, set_code_size; - int max_code, max_code_size; - int firstcode, oldcode; - int clear_code, end_code; - int table[2][(1<< MAX_LWZ_BITS)]; - int stack[STACK_SIZE], *sp; - CODE_STATIC_DATA scd; + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1 << MAX_LWZ_BITS)]; + int stack[STACK_SIZE], *sp; + CODE_STATIC_DATA scd; } LZW_STATIC_DATA; -static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); -static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP); -static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP); -static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP); -static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP); +static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]); +static int DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP); +static int GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP); +static int GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, + int *ZeroDataBlockP); +static int LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, + int *ZeroDataBlockP); + +static int ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], + int colorCount, int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */ + +typedef struct { + int transparent; + int delay; + int disposal; +} GifGraphicControl; + +typedef struct gdGifReadStruct { + gdIOCtxPtr in; + int ownsCtx; + int done; + int error; + int pendingSeparator; + int frameIndex; + int screenWidth; + int screenHeight; + int backgroundIndex; + int haveGlobalColormap; + int globalColorCount; + int loopCount; + unsigned char globalColorMap[3][MAXCOLORMAPSIZE]; + unsigned char localColorMap[3][MAXCOLORMAPSIZE]; + GifGraphicControl gce; + gdImagePtr rawFrame; + gdImagePtr canvas; + gdImagePtr previousCanvas; + gdGifFrameInfo lastInfo; +} gdGifRead; + +static void GifResetGraphicControl(GifGraphicControl *gce); +static void GifTrimColorTable(gdImagePtr im); +static int GifReadHeader(gdGifRead *gif); +static int GifPrimeFirstImage(gdGifRead *gif); +static int GifSkipSubBlocks(gdIOCtxPtr in, int *ZeroDataBlockP); +static int GifReadApplicationExtension(gdGifRead *gif, int *ZeroDataBlockP); +static int GifReadExtension(gdGifRead *gif, int label, int *ZeroDataBlockP); +static void GifFillFrameInfo(gdGifRead *gif, gdGifFrameInfo *info); +static int GifFrameToColor(gdImagePtr frame, int color); +static int GifBackgroundColor(gdGifRead *gif, int transparentIndex); +static int GifEnsureCanvas(gdGifRead *gif, int transparentIndex); +static gdImagePtr GifCloneImage(gdImagePtr src); +static void GifApplyPreviousDisposal(gdGifRead *gif); +static int GifCompositeFrame(gdGifRead *gif); +static int GifProbeIsAnimated(gdIOCtxPtr in); + +static void GifResetGraphicControl(GifGraphicControl *gce) +{ + gce->transparent = -1; + gce->delay = 0; + gce->disposal = gdDisposalUnknown; +} + +static void GifTrimColorTable(gdImagePtr im) +{ + int i; + + for (i = im->colorsTotal - 1; i >= 0; i--) { + if (im->open[i]) { + im->colorsTotal--; + } else { + break; + } + } +} -static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */ +static int GifReadHeader(gdGifRead *gif) +{ + unsigned char buf[16]; + int bitPixel; + + memset(gif->globalColorMap, 0, 3 * MAXCOLORMAPSIZE); + memset(gif->localColorMap, 0, 3 * MAXCOLORMAPSIZE); + GifResetGraphicControl(&gif->gce); + gif->loopCount = 1; + + if (!ReadOK(gif->in, buf, 6)) { + return 0; + } + if (strncmp((char *)buf, "GIF", 3) != 0) { + return 0; + } + if (memcmp((char *)buf + 3, "87a", 3) != 0 && memcmp((char *)buf + 3, "89a", 3) != 0) { + return 0; + } + if (!ReadOK(gif->in, buf, 7)) { + return 0; + } + + gif->screenWidth = LM_to_uint(buf[0], buf[1]); + gif->screenHeight = LM_to_uint(buf[2], buf[3]); + if (gif->screenWidth <= 0 || gif->screenHeight <= 0) { + return 0; + } + + gif->backgroundIndex = buf[5]; + bitPixel = 2 << (buf[4] & 0x07); + gif->globalColorCount = bitPixel; + gif->haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); + if (gif->haveGlobalColormap) { + if (ReadColorMap(gif->in, bitPixel, gif->globalColorMap)) { + return 0; + } + } + + return 1; +} -gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */ +static int GifSkipSubBlocks(gdIOCtxPtr in, int *ZeroDataBlockP) { - gdIOCtx *in = gdNewSSCtx(inSource, NULL); - gdImagePtr im; + unsigned char buf[256]; + int count; - im = gdImageCreateFromGifCtx(in); + do { + count = GetDataBlock(in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + } while (count > 0); + + return 1; +} - in->gd_free(in); +static int GifReadApplicationExtension(gdGifRead *gif, int *ZeroDataBlockP) +{ + unsigned char buf[256]; + int count; + + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + + if (count == 11 && memcmp(buf, "NETSCAPE2.0", 11) == 0) { + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + if (count >= 3 && buf[0] == 1) { + gif->loopCount = LM_to_uint(buf[1], buf[2]); + } + while (count > 0) { + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + } + return 1; + } + + while (count > 0) { + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + } + return 1; +} - return im; +static int GifReadExtension(gdGifRead *gif, int label, int *ZeroDataBlockP) +{ + unsigned char buf[256]; + int count; + + if (label == 0xf9) { + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + if (count >= 4) { + gif->gce.disposal = (buf[0] >> 2) & 0x7; + if (gif->gce.disposal == 4) { + gif->gce.disposal = gdDisposalRestorePrevious; + } + gif->gce.delay = LM_to_uint(buf[1], buf[2]); + gif->gce.transparent = (buf[0] & 0x1) ? buf[3] : -1; + } + while (count > 0) { + count = GetDataBlock(gif->in, buf, ZeroDataBlockP); + if (count < 0) { + return 0; + } + } + return 1; + } + + if (label == 0xff) { + return GifReadApplicationExtension(gif, ZeroDataBlockP); + } + + return GifSkipSubBlocks(gif->in, ZeroDataBlockP); } -/* }}} */ -gdImagePtr gdImageCreateFromGif(FILE *fdFile) /* {{{ */ +static int GifPrimeFirstImage(gdGifRead *gif) { - gdIOCtx *fd = gdNewFileCtx(fdFile); - gdImagePtr im = 0; + unsigned char c; + int ZeroDataBlock = FALSE; + + for (;;) { + if (!ReadOK(gif->in, &c, 1)) { + return 0; + } + if (c == ';') { + gif->done = 1; + return 1; + } + if (c == ',') { + gif->pendingSeparator = 1; + return 1; + } + if (c == '!') { + if (!ReadOK(gif->in, &c, 1) || !GifReadExtension(gif, c, &ZeroDataBlock)) { + return 0; + } + continue; + } + } +} - im = gdImageCreateFromGifCtx(fd); +static void GifFillFrameInfo(gdGifRead *gif, gdGifFrameInfo *info) +{ + if (info != NULL) { + *info = gif->lastInfo; + } +} - fd->gd_free(fd); +static int GifFrameToColor(gdImagePtr frame, int color) +{ + return gdTrueColorAlpha(frame->red[color], frame->green[color], frame->blue[color], + frame->alpha[color]); +} - return im; +static int GifBackgroundColor(gdGifRead *gif, int transparentIndex) +{ + int bg = gif->backgroundIndex; + + if (bg == transparentIndex) { + return gdTrueColorAlpha(0, 0, 0, gdAlphaTransparent); + } + if (gif->haveGlobalColormap && bg >= 0 && bg < MAXCOLORMAPSIZE) { + return gdTrueColorAlpha(gif->globalColorMap[CM_RED][bg], gif->globalColorMap[CM_GREEN][bg], + gif->globalColorMap[CM_BLUE][bg], gdAlphaOpaque); + } + return gdTrueColorAlpha(0, 0, 0, gdAlphaTransparent); +} + +static int GifEnsureCanvas(gdGifRead *gif, int transparentIndex) +{ + int x, y, bg; + + if (gif->canvas != NULL) { + return 1; + } + + gif->canvas = gdImageCreateTrueColor(gif->screenWidth, gif->screenHeight); + if (gif->canvas == NULL) { + return 0; + } + gdImageAlphaBlending(gif->canvas, 0); + gdImageSaveAlpha(gif->canvas, 1); + + bg = GifBackgroundColor(gif, transparentIndex); + for (y = 0; y < gif->screenHeight; y++) { + for (x = 0; x < gif->screenWidth; x++) { + gdImageSetPixel(gif->canvas, x, y, bg); + } + } + + return 1; +} + +static gdImagePtr GifCloneImage(gdImagePtr src) +{ + gdImagePtr dst; + int x, y; + + if (src == NULL) { + return NULL; + } + + dst = + src->trueColor ? gdImageCreateTrueColor(src->sx, src->sy) : gdImageCreate(src->sx, src->sy); + if (dst == NULL) { + return NULL; + } + + if (src->trueColor) { + gdImageAlphaBlending(dst, 0); + gdImageSaveAlpha(dst, src->saveAlphaFlag); + for (y = 0; y < src->sy; y++) { + for (x = 0; x < src->sx; x++) { + gdImageSetPixel(dst, x, y, gdImageGetPixel(src, x, y)); + } + } + } else { + for (x = 0; x < gdMaxColors; x++) { + dst->red[x] = src->red[x]; + dst->green[x] = src->green[x]; + dst->blue[x] = src->blue[x]; + dst->alpha[x] = src->alpha[x]; + dst->open[x] = src->open[x]; + } + dst->colorsTotal = src->colorsTotal; + dst->transparent = src->transparent; + for (y = 0; y < src->sy; y++) { + for (x = 0; x < src->sx; x++) { + gdImageSetPixel(dst, x, y, gdImageGetPixel(src, x, y)); + } + } + } + + return dst; +} + +static void GifApplyPreviousDisposal(gdGifRead *gif) +{ + gdGifFrameInfo *info = &gif->lastInfo; + int x, y, bg; + + if (gif->canvas == NULL || gif->frameIndex <= 0) { + return; + } + + if (info->disposal == gdDisposalRestoreBackground) { + bg = GifBackgroundColor(gif, info->transparentIndex); + for (y = info->y; y < info->y + info->height; y++) { + for (x = info->x; x < info->x + info->width; x++) { + gdImageSetPixel(gif->canvas, x, y, bg); + } + } + } else if (info->disposal == gdDisposalRestorePrevious && gif->previousCanvas != NULL) { + for (y = info->y; y < info->y + info->height; y++) { + for (x = info->x; x < info->x + info->width; x++) { + gdImageSetPixel(gif->canvas, x, y, gdImageGetPixel(gif->previousCanvas, x, y)); + } + } + } + + if (gif->previousCanvas != NULL) { + gdImageDestroy(gif->previousCanvas); + gif->previousCanvas = NULL; + } +} + +static int GifCompositeFrame(gdGifRead *gif) +{ + gdGifFrameInfo *info = &gif->lastInfo; + int x, y, c; + + if (!GifEnsureCanvas(gif, info->transparentIndex)) { + return 0; + } + + if (info->disposal == gdDisposalRestorePrevious) { + gif->previousCanvas = GifCloneImage(gif->canvas); + if (gif->previousCanvas == NULL) { + return 0; + } + } + + for (y = 0; y < info->height; y++) { + for (x = 0; x < info->width; x++) { + c = gdImageGetPixel(gif->rawFrame, x, y); + if (c == info->transparentIndex) { + continue; + } + gdImageSetPixel(gif->canvas, info->x + x, info->y + y, + GifFrameToColor(gif->rawFrame, c)); + } + } + + return 1; +} + +static int GifProbeIsAnimated(gdIOCtxPtr in) +{ + unsigned char buf[16], c; + int bitPixel, frameCount = 0, zero = 0; + + if (in == NULL || !ReadOK(in, buf, 6)) { + return -1; + } + if (strncmp((char *)buf, "GIF", 3) != 0 || + (memcmp((char *)buf + 3, "87a", 3) != 0 && memcmp((char *)buf + 3, "89a", 3) != 0)) { + return -1; + } + if (!ReadOK(in, buf, 7)) { + return -1; + } + if (LM_to_uint(buf[0], buf[1]) <= 0 || LM_to_uint(buf[2], buf[3]) <= 0) { + return -1; + } + bitPixel = 2 << (buf[4] & 0x07); + if (BitSet(buf[4], LOCALCOLORMAP)) { + while (bitPixel-- > 0) { + if (!ReadOK(in, buf, 3)) { + return -1; + } + } + } + + for (;;) { + if (!ReadOK(in, &c, 1)) { + return -1; + } + if (c == ';') { + return frameCount > 1 ? 1 : 0; + } + if (c == '!') { + if (!ReadOK(in, &c, 1) || !GifSkipSubBlocks(in, &zero)) { + return -1; + } + continue; + } + if (c == ',') { + int localColorCount; + if (!ReadOK(in, buf, 9)) { + return -1; + } + localColorCount = BitSet(buf[8], LOCALCOLORMAP) ? (2 << (buf[8] & 0x07)) : 0; + while (localColorCount-- > 0) { + if (!ReadOK(in, buf, 3)) { + return -1; + } + } + if (!ReadOK(in, &c, 1) || !GifSkipSubBlocks(in, &zero)) { + return -1; + } + frameCount++; + if (frameCount > 1) { + return 1; + } + continue; + } + return -1; + } +} + +BGD_DECLARE(int) gdGifIsAnimated(FILE *fdFile) +{ + gdIOCtx *fd; + int result, pos; + + if (fdFile == NULL) { + return -1; + } + fd = gdNewFileCtx(fdFile); + if (fd == NULL) { + return -1; + } + pos = (int)gdTell(fd); + if (pos < 0) { + fd->gd_free(fd); + return -1; + } + result = GifProbeIsAnimated(fd); + if (!gdSeek(fd, pos)) { + result = -1; + } + fd->gd_free(fd); + return result; +} + +BGD_DECLARE(int) gdGifIsAnimatedCtx(gdIOCtxPtr in) +{ + int result, pos; + + if (in == NULL || in->tell == NULL || in->seek == NULL) { + return -1; + } + pos = (int)gdTell(in); + if (pos < 0) { + return -1; + } + result = GifProbeIsAnimated(in); + if (!gdSeek(in, pos)) { + return -1; + } + return result; +} + +BGD_DECLARE(int) gdGifIsAnimatedPtr(int size, void *data) +{ + gdIOCtx *in; + int result; + + if (size <= 0 || data == NULL) { + return -1; + } + in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) { + return -1; + } + result = GifProbeIsAnimated(in); + in->gd_free(in); + return result; +} + +BGD_DECLARE(gdGifReadPtr) gdGifReadOpen(FILE *fdFile) +{ + gdIOCtx *fd; + gdGifReadPtr gif; + + if (fdFile == NULL) { + return NULL; + } + fd = gdNewFileCtx(fdFile); + if (fd == NULL) { + return NULL; + } + gif = gdGifReadOpenCtx(fd); + if (gif == NULL) { + fd->gd_free(fd); + return NULL; + } + gif->ownsCtx = 1; + return gif; +} + +BGD_DECLARE(gdGifReadPtr) gdGifReadOpenPtr(int size, void *data) +{ + gdIOCtx *in; + gdGifReadPtr gif; + + if (size <= 0 || data == NULL) { + return NULL; + } + in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) { + return NULL; + } + gif = gdGifReadOpenCtx(in); + if (gif == NULL) { + in->gd_free(in); + return NULL; + } + gif->ownsCtx = 1; + return gif; +} + +BGD_DECLARE(gdGifReadPtr) gdGifReadOpenCtx(gdIOCtxPtr in) +{ + gdGifReadPtr gif; + + if (in == NULL) { + return NULL; + } + + gif = (gdGifReadPtr)gdCalloc(1, sizeof(gdGifRead)); + if (gif == NULL) { + return NULL; + } + gif->in = in; + gif->ownsCtx = 0; + GifResetGraphicControl(&gif->gce); + if (!GifReadHeader(gif) || !GifPrimeFirstImage(gif)) { + gdFree(gif); + return NULL; + } + + return gif; } -/* }}} */ -gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */ +BGD_DECLARE(void) gdGifReadClose(gdGifReadPtr gif) { - int BitPixel; + if (gif == NULL) { + return; + } + if (gif->rawFrame != NULL) { + gdImageDestroy(gif->rawFrame); + } + if (gif->canvas != NULL) { + gdImageDestroy(gif->canvas); + } + if (gif->previousCanvas != NULL) { + gdImageDestroy(gif->previousCanvas); + } + if (gif->ownsCtx && gif->in != NULL) { + gif->in->gd_free(gif->in); + } + gdFree(gif); +} + +BGD_DECLARE(int) gdGifReadGetInfo(gdGifReadPtr gif, gdGifInfo *info) +{ + if (gif == NULL || info == NULL) { + return 0; + } + info->width = gif->screenWidth; + info->height = gif->screenHeight; + info->backgroundIndex = gif->backgroundIndex; + info->globalColorTable = gif->haveGlobalColormap; + info->loopCount = gif->loopCount; + return 1; +} + +BGD_DECLARE(int) +gdGifReadNextFrame(gdGifReadPtr gif, gdGifFrameInfo *info, gdImagePtr *frame) +{ + unsigned char buf[16], c; + int ZeroDataBlock = FALSE; + + if (frame != NULL) { + *frame = NULL; + } + if (gif == NULL || gif->error) { + return -1; + } + if (gif->done) { + return 0; + } + + for (;;) { + int top, left, width, height; + int useGlobalColormap, bitPixel, interlace, hasLocal; + + if (gif->pendingSeparator) { + c = ','; + gif->pendingSeparator = 0; + } else if (!ReadOK(gif->in, &c, 1)) { + gif->error = 1; + return -1; + } + if (c == ';') { + gif->done = 1; + return 0; + } + if (c == '!') { + if (!ReadOK(gif->in, &c, 1) || !GifReadExtension(gif, c, &ZeroDataBlock)) { + gif->error = 1; + return -1; + } + continue; + } + if (c != ',') { + continue; + } + + if (!ReadOK(gif->in, buf, 9)) { + gif->error = 1; + return -1; + } + + hasLocal = BitSet(buf[8], LOCALCOLORMAP); + useGlobalColormap = !hasLocal; + bitPixel = 1 << ((buf[8] & 0x07) + 1); + left = LM_to_uint(buf[0], buf[1]); + top = LM_to_uint(buf[2], buf[3]); + width = LM_to_uint(buf[4], buf[5]); + height = LM_to_uint(buf[6], buf[7]); + interlace = BitSet(buf[8], INTERLACE); + + if (width <= 0 || height <= 0 || ((left + width) > gif->screenWidth) || + ((top + height) > gif->screenHeight)) { + gif->error = 1; + return -1; + } + if (useGlobalColormap && !gif->haveGlobalColormap) { + gif->globalColorMap[CM_RED][1] = 0xff; + gif->globalColorMap[CM_GREEN][1] = 0xff; + gif->globalColorMap[CM_BLUE][1] = 0xff; + } + + if (gif->rawFrame != NULL) { + gdImageDestroy(gif->rawFrame); + gif->rawFrame = NULL; + } + gif->rawFrame = gdImageCreate(width, height); + if (gif->rawFrame == NULL) { + gif->error = 1; + return -1; + } + gif->rawFrame->interlace = interlace; + + if (hasLocal) { + if (ReadColorMap(gif->in, bitPixel, gif->localColorMap) || + !ReadImage(gif->rawFrame, gif->in, width, height, gif->localColorMap, bitPixel, + interlace, &ZeroDataBlock)) { + gif->error = 1; + return -1; + } + } else { + if (!ReadImage(gif->rawFrame, gif->in, width, height, gif->globalColorMap, + gif->globalColorCount, interlace, &ZeroDataBlock)) { + gif->error = 1; + return -1; + } + } + + if (gif->gce.transparent != -1) { + gdImageColorTransparent(gif->rawFrame, gif->gce.transparent); + } + GifTrimColorTable(gif->rawFrame); + if (!gif->rawFrame->colorsTotal) { + gif->error = 1; + return -1; + } + + gif->lastInfo.frameIndex = gif->frameIndex; + gif->lastInfo.x = left; + gif->lastInfo.y = top; + gif->lastInfo.width = width; + gif->lastInfo.height = height; + gif->lastInfo.delay = gif->gce.delay; + gif->lastInfo.disposal = gif->gce.disposal; + gif->lastInfo.transparentIndex = gif->gce.transparent; + gif->lastInfo.localColorTable = hasLocal; + gif->lastInfo.interlace = interlace; + gif->frameIndex++; + GifFillFrameInfo(gif, info); + if (frame != NULL) { + *frame = gif->rawFrame; + } + GifResetGraphicControl(&gif->gce); + return 1; + } +} + +BGD_DECLARE(int) +gdGifReadNextImage(gdGifReadPtr gif, gdGifFrameInfo *info, gdImagePtr *image) +{ + int result; + + if (image != NULL) { + *image = NULL; + } + if (gif == NULL) { + return -1; + } + + GifApplyPreviousDisposal(gif); + result = gdGifReadNextFrame(gif, info, NULL); + if (result <= 0) { + return result; + } + if (!GifCompositeFrame(gif)) { + gif->error = 1; + return -1; + } + if (image != NULL) { + *image = gif->canvas; + } + return 1; +} + +BGD_DECLARE(gdImagePtr) gdGifReadCloneImage(gdGifReadPtr gif) +{ + if (gif == NULL) { + return NULL; + } + return GifCloneImage(gif->canvas); +} + +/* + Function: gdImageCreateFromGif + + is called to load images from GIF format + files. Invoke with an already opened + pointer to a file containing the desired + image. + + returns a to the new image, or + NULL if unable to load the image (most often because the file is + corrupt or does not contain a GIF image). + does not close the file. You can inspect the sx and sy members of + the image to determine its size. The image must eventually be + destroyed using . + + Variants: + + creates an image from GIF data (i.e. the + contents of a GIF file) already in memory. + + reads in an image using the functions in + a struct. + + Parameters: + + infile - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + + > gdImagePtr im; + > ... inside a function ... + > FILE *in; + > in = fopen("mygif.gif", "rb"); + > im = gdImageCreateFromGif(in); + > fclose(in); + > // ... Use the image ... + > gdImageDestroy(im); + +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGif(FILE *fdFile) +{ + gdIOCtx *fd = gdNewFileCtx(fdFile); + gdImagePtr im; + + if (fd == NULL) + return NULL; + im = gdImageCreateFromGifCtx(fd); + + fd->gd_free(fd); + + return im; +} + +/* + Function: gdImageCreateFromGifPtr + + Parameters: + + size - size of GIF data in bytes. + data - GIF data (i.e. contents of a GIF file). + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGifPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return 0; + } + im = gdImageCreateFromGifCtx(in); + in->gd_free(in); + return im; +} + +/* + Function: gdImageCreateFromGifCtx + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd) +{ + int BitPixel; #if 0 int ColorResolution; int Background; int AspectRatio; #endif - int Transparent = (-1); - unsigned char buf[16]; - unsigned char c; - unsigned char ColorMap[3][MAXCOLORMAPSIZE]; - unsigned char localColorMap[3][MAXCOLORMAPSIZE]; - int imw, imh, screen_width, screen_height; - int useGlobalColormap; - int bitPixel; - int i; - /*1.4//int imageCount = 0; */ - - int ZeroDataBlock = FALSE; - int haveGlobalColormap; - gdImagePtr im = 0; - - memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE); - memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE); - - /*1.4//imageNumber = 1; */ - if (! ReadOK(fd,buf,6)) { - return 0; - } - if (strncmp((char *)buf,"GIF",3) != 0) { - return 0; - } - - if (memcmp((char *)buf+3, "87a", 3) == 0) { - /* GIF87a */ - } else if (memcmp((char *)buf+3, "89a", 3) == 0) { - /* GIF89a */ - } else { - return 0; - } - - if (! ReadOK(fd,buf,7)) { - return 0; - } - - BitPixel = 2<<(buf[4]&0x07); + int Transparent = (-1); + unsigned char buf[16]; + unsigned char c; + unsigned char ColorMap[3][MAXCOLORMAPSIZE]; + unsigned char localColorMap[3][MAXCOLORMAPSIZE]; + int imw, imh, screen_width, screen_height; + int useGlobalColormap; + int bitPixel, i; + /*1.4//int imageCount = 0; */ + /* 2.0.28: threadsafe storage */ + int ZeroDataBlock = FALSE; + int haveGlobalColormap; + + gdImagePtr im = 0; + + memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE); + memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE); + + if (!ReadOK(fd, buf, 6)) { + return 0; + } + + if (strncmp((char *)buf, "GIF", 3) != 0) { + return 0; + } + + if (memcmp((char *)buf + 3, "87a", 3) == 0) { + /* GIF87a */ + } else if (memcmp((char *)buf + 3, "89a", 3) == 0) { + /* GIF89a */ + } else { + return 0; + } + + if (!ReadOK(fd, buf, 7)) { + return 0; + } + + BitPixel = 2 << (buf[4] & 0x07); #if 0 ColorResolution = (int) (((buf[4]&0x70)>>3)+1); Background = buf[5]; AspectRatio = buf[6]; #endif - screen_width = imw = LM_to_uint(buf[0],buf[1]); - screen_height = imh = LM_to_uint(buf[2],buf[3]); - - haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */ - if (haveGlobalColormap) { - if (ReadColorMap(fd, BitPixel, ColorMap)) { - return 0; - } - } - - for (;;) { - int top, left; - int width, height; - - if (! ReadOK(fd,&c,1)) { - return 0; - } - if (c == ';') { /* GIF terminator */ - goto terminated; - } - - if (c == '!') { /* Extension */ - if (! ReadOK(fd,&c,1)) { - return 0; - } - DoExtension(fd, c, &Transparent, &ZeroDataBlock); - continue; - } - - if (c != ',') { /* Not a valid start character */ - continue; - } - - /*1.4//++imageCount; */ - - if (! ReadOK(fd,buf,9)) { - return 0; - } - - useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); - - bitPixel = 1<<((buf[8]&0x07)+1); - left = LM_to_uint(buf[0], buf[1]); - top = LM_to_uint(buf[2], buf[3]); - width = LM_to_uint(buf[4], buf[5]); - height = LM_to_uint(buf[6], buf[7]); - - if (left + width > screen_width || top + height > screen_height) { - if (VERBOSE) { - printf("Frame is not confined to screen dimension.\n"); - } - return 0; - } - - if (!(im = gdImageCreate(width, height))) { - return 0; - } - im->interlace = BitSet(buf[8], INTERLACE); - if (!useGlobalColormap) { - if (ReadColorMap(fd, bitPixel, localColorMap)) { - gdImageDestroy(im); - return 0; - } - ReadImage(im, fd, width, height, localColorMap, - BitSet(buf[8], INTERLACE), &ZeroDataBlock); - } else { - if (!haveGlobalColormap) { - // Still a valid gif, apply simple default palette as per spec - ColorMap[CM_RED][1] = 0xff; - ColorMap[CM_GREEN][1] = 0xff; - ColorMap[CM_BLUE][1] = 0xff; - } - ReadImage(im, fd, width, height, - ColorMap, - BitSet(buf[8], INTERLACE), &ZeroDataBlock); - } - if (Transparent != (-1)) { - gdImageColorTransparent(im, Transparent); - } - goto terminated; - } + screen_width = imw = LM_to_uint(buf[0], buf[1]); + screen_height = imh = LM_to_uint(buf[2], buf[3]); + + haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */ + if (haveGlobalColormap) { + if (ReadColorMap(fd, BitPixel, ColorMap)) { + return 0; + } + } + + for (;;) { + int top, left; + int width, height; + + if (!ReadOK(fd, &c, 1)) { + return 0; + } + + if (c == ';') { /* GIF terminator */ + goto terminated; + } + + if (c == '!') { /* Extension */ + if (!ReadOK(fd, &c, 1)) { + return 0; + } + + DoExtension(fd, c, &Transparent, &ZeroDataBlock); + continue; + } + + if (c != ',') { /* Not a valid start character */ + continue; + } + + /*1.4//++imageCount; */ + + if (!ReadOK(fd, buf, 9)) { + return 0; + } + + useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP); + + bitPixel = 1 << ((buf[8] & 0x07) + 1); + left = LM_to_uint(buf[0], buf[1]); + top = LM_to_uint(buf[2], buf[3]); + width = LM_to_uint(buf[4], buf[5]); + height = LM_to_uint(buf[6], buf[7]); + + if (((left + width) > screen_width) || ((top + height) > screen_height)) { + if (VERBOSE) { + printf("Frame is not confined to screen dimension.\n"); + } + return 0; + } + + if (!(im = gdImageCreate(width, height))) { + return 0; + } + + im->interlace = BitSet(buf[8], INTERLACE); + if (!useGlobalColormap) { + if (ReadColorMap(fd, bitPixel, localColorMap)) { + gdImageDestroy(im); + return 0; + } + + /* Legacy gdImageCreateFromGif* is intentionally tolerant of + * out-of-palette LZW results and maps them to color 0. The newer + * iterator API passes the actual color table size and rejects those + * malformed frames instead. + */ + if (!ReadImage(im, fd, width, height, localColorMap, 0, BitSet(buf[8], INTERLACE), + &ZeroDataBlock)) { + gdImageDestroy(im); + return 0; + } + } else { + if (!haveGlobalColormap) { + // Still a valid gif, apply simple default palette as per spec + ColorMap[CM_RED][1] = 0xff; + ColorMap[CM_GREEN][1] = 0xff; + ColorMap[CM_BLUE][1] = 0xff; + } + + /* Keep legacy tolerance here as above; strict validation is used by + * the animated GIF iterator. + */ + if (!ReadImage(im, fd, width, height, ColorMap, 0, BitSet(buf[8], INTERLACE), + &ZeroDataBlock)) { + gdImageDestroy(im); + return 0; + } + } + + if (Transparent != (-1)) { + gdImageColorTransparent(im, Transparent); + } + + goto terminated; + } terminated: - /* Terminator before any image was declared! */ - if (!im) { - return 0; - } - /* Check for open colors at the end, so - we can reduce colorsTotal and ultimately - BitsPerPixel */ - for (i=((im->colorsTotal-1)); (i>=0); i--) { - if (im->open[i]) { - im->colorsTotal--; - } else { - break; - } - } - if (!im->colorsTotal) { - gdImageDestroy(im); - return 0; - } - return im; + /* Terminator before any image was declared! */ + if (!im) { + return 0; + } + + /* Check for open colors at the end, so + * we can reduce colorsTotal and ultimately + * BitsPerPixel */ + for (i = im->colorsTotal - 1; i >= 0; i--) { + if (im->open[i]) { + im->colorsTotal--; + } else { + break; + } + } + + if (!im->colorsTotal) { + gdImageDestroy(im); + return 0; + } + + return im; } -/* }}} */ -static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) /* {{{ */ +static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) { - int i; - unsigned char rgb[3]; + int i; + unsigned char rgb[3]; + for (i = 0; i < number; ++i) { + if (!ReadOK(fd, rgb, sizeof(rgb))) { + return TRUE; + } - for (i = 0; i < number; ++i) { - if (! ReadOK(fd, rgb, sizeof(rgb))) { - return TRUE; - } - buffer[CM_RED][i] = rgb[0] ; - buffer[CM_GREEN][i] = rgb[1] ; - buffer[CM_BLUE][i] = rgb[2] ; - } + buffer[CM_RED][i] = rgb[0]; + buffer[CM_GREEN][i] = rgb[1]; + buffer[CM_BLUE][i] = rgb[2]; + } - - return FALSE; + return FALSE; } -/* }}} */ -static int -DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP) +static int DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP) { - unsigned char buf[256]; + unsigned char buf[256]; - switch (label) { - case 0xf9: /* Graphic Control Extension */ - memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ - (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP); + switch (label) { + case 0xf9: /* Graphic Control Extension */ + memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ + (void)GetDataBlock(fd, (unsigned char *)buf, ZeroDataBlockP); #if 0 Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint(buf[1],buf[2]); #endif - if ((buf[0] & 0x1) != 0) - *Transparent = buf[3]; + if ((buf[0] & 0x1) != 0) { + *Transparent = buf[3]; + } - while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0); - return FALSE; - default: - break; - } - while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0) - ; + while (GetDataBlock(fd, (unsigned char *)buf, ZeroDataBlockP) > 0) + ; + return FALSE; - return FALSE; + default: + break; + } + + while (GetDataBlock(fd, (unsigned char *)buf, ZeroDataBlockP) > 0) + ; + + return FALSE; } -/* }}} */ -static int -GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) +static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) { - unsigned char count; + unsigned char count; - if (! ReadOK(fd,&count,1)) { - return -1; - } + if (!ReadOK(fd, &count, 1)) { + return -1; + } - *ZeroDataBlockP = count == 0; + *ZeroDataBlockP = count == 0; - if ((count != 0) && (! ReadOK(fd, buf, count))) { - return -1; - } + if ((count != 0) && (!ReadOK(fd, buf, count))) { + return -1; + } - return count; + return count; } -/* }}} */ -static int -GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) -{ - int rv; - int i; - - rv = GetDataBlock_(fd,buf, ZeroDataBlockP); - if (VERBOSE) { - char *tmp = NULL; - if (rv > 0) { - tmp = safe_emalloc(3 * rv, sizeof(char), 1); - for (i=0;i 0) { + printf(":"); + for (i = 0; i < rv; i++) { + printf(" %02x", buf[i]); + } + } + printf("]\n"); + } + + return rv; } -/* }}} */ -static int -GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) +static int GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, + int *ZeroDataBlockP) { - int i, j, ret; - int count; - - if (flag) { - scd->curbit = 0; - scd->lastbit = 0; - scd->last_byte = 2; - scd->done = FALSE; - return 0; - } - - if ( (scd->curbit + code_size) >= scd->lastbit) { - if (scd->done) { - if (scd->curbit >= scd->lastbit) { - /* Oh well */ - } - return -1; - } - scd->buf[0] = scd->buf[scd->last_byte-2]; - scd->buf[1] = scd->buf[scd->last_byte-1]; + int i, j, ret; + int count; + + if (flag) { + scd->curbit = 0; + scd->lastbit = 0; + scd->last_byte = 2; + scd->done = FALSE; + return 0; + } + + if ((scd->curbit + code_size) >= scd->lastbit) { + if (scd->done) { + if (scd->curbit >= scd->lastbit) { + /* Oh well */ + } + return -1; + } + + scd->buf[0] = scd->buf[scd->last_byte - 2]; + scd->buf[1] = scd->buf[scd->last_byte - 1]; + scd->last_byte = 2; + scd->curbit = (scd->curbit - scd->lastbit) + 16; + scd->lastbit = 16; + + do { + if (scd->last_byte > (CSD_BUF_SIZE - 255)) { + return -1; + } + + if ((count = GetDataBlock(fd, &scd->buf[scd->last_byte], ZeroDataBlockP)) <= 0) { + scd->done = TRUE; + break; + } + + scd->last_byte += count; + scd->lastbit += count * 8; + } while ((scd->curbit + code_size) > scd->lastbit); + } + + if ((scd->curbit + code_size) > scd->lastbit) { + return -1; + } + + if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) { + ret = -1; + } else { + ret = 0; + for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) { + ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j; + } + } + + scd->curbit += code_size; + + return ret; +} - if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0) - scd->done = TRUE; +static int GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) +{ + int rv; - scd->last_byte = 2 + count; - scd->curbit = (scd->curbit - scd->lastbit) + 16; - scd->lastbit = (2+count)*8 ; - } + rv = GetCode_(fd, scd, code_size, flag, ZeroDataBlockP); - if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) { - ret = -1; - } else { - ret = 0; - for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) { - ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j; - } - } + if (VERBOSE) { + printf("[GetCode(,%d,%d) returning %d]\n", code_size, flag, rv); + } - scd->curbit += code_size; - return ret; + return rv; } -static int -GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) +static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, + int *ZeroDataBlockP) { - int rv; - - rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP); - if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv); - return(rv); + int code, incode, i; + + if (flag) { + sd->set_code_size = input_code_size; + sd->code_size = sd->set_code_size + 1; + sd->clear_code = 1 << sd->set_code_size; + sd->end_code = sd->clear_code + 1; + sd->max_code_size = 2 * sd->clear_code; + sd->max_code = sd->clear_code + 2; + + GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP); + + sd->fresh = TRUE; + + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; + } + + for (; i < (1 << MAX_LWZ_BITS); ++i) { + sd->table[0][i] = sd->table[1][0] = 0; + } + + sd->sp = sd->stack; + + return 0; + + } else if (sd->fresh) { + sd->fresh = FALSE; + + do { + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + } while (sd->firstcode == sd->clear_code); + + return sd->firstcode; + } + + if (sd->sp > sd->stack) { + return *--sd->sp; + } + + while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { + if (code == sd->clear_code) { + for (i = 0; i < sd->clear_code; ++i) { + sd->table[0][i] = 0; + sd->table[1][i] = i; + } + + for (; i < (1 << MAX_LWZ_BITS); ++i) { + sd->table[0][i] = sd->table[1][i] = 0; + } + + sd->code_size = sd->set_code_size + 1; + sd->max_code_size = 2 * sd->clear_code; + sd->max_code = sd->clear_code + 2; + sd->sp = sd->stack; + sd->firstcode = sd->oldcode = + GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); + + return sd->firstcode; + } else if (code == sd->end_code) { + int count; + unsigned char buf[260]; + + if (*ZeroDataBlockP) { + return -2; + } + + while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0) + ; + + if (count != 0) { + return -2; + } + } + + incode = code; + + if (sd->sp == (sd->stack + STACK_SIZE)) { + /* Bad compressed data stream */ + return -1; + } + + if (code >= sd->max_code) { + *sd->sp++ = sd->firstcode; + code = sd->oldcode; + } + + while (code >= sd->clear_code) { + if (sd->sp == (sd->stack + STACK_SIZE)) { + /* Bad compressed data stream */ + return -1; + } + if (code >= (1 << MAX_LWZ_BITS)) { + /* Corrupted code */ + return -1; + } + + *sd->sp++ = sd->table[1][code]; + + if (code == sd->table[0][code]) { + /* Oh well */ + } + + code = sd->table[0][code]; + } + if (code >= (1 << MAX_LWZ_BITS)) { + /* Corrupted code */ + return -1; + } + + *sd->sp++ = sd->firstcode = sd->table[1][code]; + + if ((code = sd->max_code) < (1 << MAX_LWZ_BITS)) { + sd->table[0][code] = sd->oldcode; + sd->table[1][code] = sd->firstcode; + ++sd->max_code; + + if ((sd->max_code >= sd->max_code_size) && (sd->max_code_size < (1 << MAX_LWZ_BITS))) { + sd->max_code_size *= 2; + ++sd->code_size; + } + } + + sd->oldcode = incode; + + if (sd->sp > sd->stack) { + return *--sd->sp; + } + } + + return code; } -/* }}} */ -static int -LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) -{ - int code, incode, i; - - if (flag) { - sd->set_code_size = input_code_size; - sd->code_size = sd->set_code_size+1; - sd->clear_code = 1 << sd->set_code_size ; - sd->end_code = sd->clear_code + 1; - sd->max_code_size = 2*sd->clear_code; - sd->max_code = sd->clear_code+2; - - GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP); - - sd->fresh = TRUE; - - for (i = 0; i < sd->clear_code; ++i) { - sd->table[0][i] = 0; - sd->table[1][i] = i; - } - for (; i < (1<table[0][i] = sd->table[1][0] = 0; - - sd->sp = sd->stack; - - return 0; - } else if (sd->fresh) { - sd->fresh = FALSE; - do { - sd->firstcode = sd->oldcode = - GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); - } while (sd->firstcode == sd->clear_code); - return sd->firstcode; - } - - if (sd->sp > sd->stack) - return *--sd->sp; - - while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { - if (code == sd->clear_code) { - for (i = 0; i < sd->clear_code; ++i) { - sd->table[0][i] = 0; - sd->table[1][i] = i; - } - for (; i < (1<table[0][i] = sd->table[1][i] = 0; - sd->code_size = sd->set_code_size+1; - sd->max_code_size = 2*sd->clear_code; - sd->max_code = sd->clear_code+2; - sd->sp = sd->stack; - sd->firstcode = sd->oldcode = - GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); - return sd->firstcode; - } else if (code == sd->end_code) { - int count; - unsigned char buf[260]; - - if (*ZeroDataBlockP) - return -2; - - while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0) - ; - - if (count != 0) - return -2; - } - - incode = code; - - if (sd->sp == (sd->stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - - if (code >= sd->max_code) { - *sd->sp++ = sd->firstcode; - code = sd->oldcode; - } - - while (code >= sd->clear_code) { - if (sd->sp == (sd->stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - *sd->sp++ = sd->table[1][code]; - if (code == sd->table[0][code]) { - /* Oh well */ - } - code = sd->table[0][code]; - } - - *sd->sp++ = sd->firstcode = sd->table[1][code]; - - if ((code = sd->max_code) <(1<table[0][code] = sd->oldcode; - sd->table[1][code] = sd->firstcode; - ++sd->max_code; - if ((sd->max_code >= sd->max_code_size) && - (sd->max_code_size < (1<max_code_size *= 2; - ++sd->code_size; - } - } - - sd->oldcode = incode; - - if (sd->sp > sd->stack) - return *--sd->sp; - } - return code; -} -/* }}} */ - -static int -LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) +static int LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, + int *ZeroDataBlockP) { - int rv; + int rv; + + rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP); - rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP); - if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); - return(rv); + if (VERBOSE) { + printf("[LWZReadByte(,%d,%d) returning %d]\n", flag, input_code_size, rv); + } + + return rv; } -/* }}} */ -static void -ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */ -{ - unsigned char c; - int v; - int xpos = 0, ypos = 0, pass = 0; - int i; - LZW_STATIC_DATA sd; - - - /* - ** Initialize the Compression routines - */ - if (! ReadOK(fd,&c,1)) { - return; - } - - if (c > MAX_LWZ_BITS) { - return; - } - - /* Stash the color map into the image */ - for (i=0; (ired[i] = cmap[CM_RED][i]; - im->green[i] = cmap[CM_GREEN][i]; - im->blue[i] = cmap[CM_BLUE][i]; - im->open[i] = 1; - } - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; - if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) { - return; - } - - /* - ** If this is an "uninteresting picture" ignore it. - ** REMOVED For 1.4 - */ - /*if (ignore) { */ - /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */ - /* ; */ - /* return; */ - /*} */ - - while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0) { - if (v >= gdMaxColors) { - v = 0; - } - /* This how we recognize which colors are actually used. */ - if (im->open[v]) { - im->open[v] = 0; - } - gdImageSetPixel(im, xpos, ypos, v); - ++xpos; - if (xpos == len) { - xpos = 0; - if (interlace) { - switch (pass) { - case 0: - case 1: - ypos += 8; break; - case 2: - ypos += 4; break; - case 3: - ypos += 2; break; - } - - if (ypos >= height) { - ++pass; - switch (pass) { - case 1: - ypos = 4; break; - case 2: - ypos = 2; break; - case 3: - ypos = 1; break; - default: - goto fini; - } - } - } else { - ++ypos; - } - } - if (ypos >= height) - break; - } +static int ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], + int colorCount, int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */ +{ + unsigned char c; + int xpos = 0, ypos = 0, pass = 0; + int v, i; + LZW_STATIC_DATA sd; + + /* Initialize the Compression routines */ + if (!ReadOK(fd, &c, 1)) { + return 0; + } + + if (c > MAX_LWZ_BITS) { + return 0; + } + + /* Stash the color map into the image */ + for (i = 0; (i < gdMaxColors); i++) { + im->red[i] = cmap[CM_RED][i]; + im->green[i] = cmap[CM_GREEN][i]; + im->blue[i] = cmap[CM_BLUE][i]; + im->open[i] = 1; + } + + /* Many (perhaps most) of these colors will remain marked open. */ + im->colorsTotal = gdMaxColors; + if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) { + return 0; + } + + /* + ** If this is an "uninteresting picture" ignore it. + ** REMOVED For 1.4 + */ + /*if (ignore) { */ + /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */ + /* ; */ + /* return; */ + /*} */ + + while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0) { + if (colorCount > 0 && v >= colorCount) { + return 0; + } + if (v >= gdMaxColors) { + v = 0; + } + + /* This how we recognize which colors are actually used. */ + if (im->open[v]) { + im->open[v] = 0; + } + + gdImageSetPixel(im, xpos, ypos, v); + + ++xpos; + if (xpos == len) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } else { + ++ypos; + } + } + + if (ypos >= height) { + break; + } + } fini: - if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) { - /* Ignore extra */ - } + if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >= 0) { + /* Ignore extra */ + } + return 1; } /* }}} */ diff --git a/ext/gd/libgd/gd_gif_out.c b/ext/gd/libgd/gd_gif_out.c index e721992b48cb..8f284ca23a6b 100644 --- a/ext/gd/libgd/gd_gif_out.c +++ b/ext/gd/libgd/gd_gif_out.c @@ -1,8 +1,15 @@ -#include +/** + * File: GIF Output + * + * Write GIF images. + */ + +#include "gd.h" +#include "gdhelpers.h" #include -#include +#include #include -#include "gd.h" +#include /* Code drawn from ppmtogif.c, from the pbmplus package ** @@ -25,16 +32,14 @@ ** CompuServe Incorporated. */ -/* - * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 - */ -typedef int code_int; +/* a code_int must be able to hold 2**GIFBITS values of type int, and also -1 */ +typedef int code_int; #ifdef SIGNED_COMPARE_SLOW typedef unsigned long int count_int; typedef unsigned short int count_short; -#else /*SIGNED_COMPARE_SLOW*/ -typedef long int count_int; +#else /*SIGNED_COMPARE_SLOW*/ +typedef long int count_int; #endif /*SIGNED_COMPARE_SLOW*/ /* 2.0.28: threadsafe */ @@ -44,139 +49,934 @@ typedef long int count_int; /* should NEVER generate this code */ #define maxmaxcode ((code_int)1 << GIFBITS) -#define HSIZE 5003 /* 80% occupancy */ -#define hsize HSIZE /* Apparently invariant, left over from - compress */ +#define HSIZE 5003 /* 80% occupancy */ +#define hsize HSIZE /* Apparently invariant, left over from compress */ typedef struct { - int Width, Height; - int curx, cury; - long CountDown; - int Pass; - int Interlace; - int n_bits; /* number of bits/code */ - code_int maxcode; /* maximum code, given n_bits */ - count_int htab [HSIZE]; - unsigned short codetab [HSIZE]; - code_int free_ent; /* first unused entry */ - /* - * block compression parameters -- after all codes are used up, - * and compression rate changes, start over. - */ - int clear_flg; - int offset; - long int in_count; /* length of input */ - long int out_count; /* # of codes output (for debugging) */ - - int g_init_bits; - gdIOCtx * g_outfile; - - int ClearCode; - int EOFCode; - unsigned long cur_accum; - int cur_bits; - /* - * Number of characters so far in this 'packet' - */ - int a_count; - /* - * Define the storage for the packet accumulator - */ - char accum[ 256 ]; + int Width, Height; + int curx, cury; + long CountDown; + int Pass; + int Interlace; + int n_bits; + code_int maxcode; + count_int htab[HSIZE]; + unsigned short codetab[HSIZE]; + /* first unused entry */ + code_int free_ent; + /* block compression parameters -- after all codes are used up, + * and compression rate changes, start over. */ + int clear_flg; + int offset; + long int in_count; + /* # of codes output (for debugging) */ + long int out_count; + int g_init_bits; + gdIOCtx *g_outfile; + int ClearCode; + int EOFCode; + unsigned long cur_accum; + int cur_bits; + int a_count; + char accum[256]; } GifCtx; static int gifPutWord(int w, gdIOCtx *out); static int colorstobpp(int colors); -static void BumpPixel (GifCtx *ctx); -static int GIFNextPixel (gdImagePtr im, GifCtx *ctx); -static void GIFEncode (gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im); -static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx); -static void output (code_int code, GifCtx *ctx); -static void cl_block (GifCtx *ctx); -static void cl_hash (register count_int chsize, GifCtx *ctx); -static void char_init (GifCtx *ctx); -static void char_out (int c, GifCtx *ctx); -static void flush_char (GifCtx *ctx); +static void BumpPixel(GifCtx *ctx); +static int GIFNextPixel(gdImagePtr im, GifCtx *ctx); +static void GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, + int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, + gdImagePtr im); +static void GIFAnimEncode(gdIOCtxPtr fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, + int GInterlace, int Transparent, int Delay, int Disposal, + int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im); +static void compress(int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx); +static void output(code_int code, GifCtx *ctx); +static void cl_block(GifCtx *ctx); +static void cl_hash(register count_int chsize, GifCtx *ctx); +static void char_init(GifCtx *ctx); +static void char_out(int c, GifCtx *ctx); +static void flush_char(GifCtx *ctx); static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out); +static int _gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out, int LocalCM, int LeftOfs, + int TopOfs, int Delay, int Disposal, gdImagePtr previm); + +/* + Function: gdImageGifPtr + + Identical to except that it returns a pointer to a + memory area with the GIF data. This memory must be freed by the + caller when it is no longer needed. + + The caller *must* invoke , not _free()_. This is because + it is not guaranteed that libgd will use the same implementation + of malloc, free, etc. as your proggram. + + The 'size' parameter receives the total size of the block of + memory. + + Parameters: + + im - The image to write + size - Output: the size of the resulting image. + + Returns: + + A pointer to the GIF data or NULL if an error occurred. + +*/ +BGD_DECLARE(void *) gdImageGifPtr(gdImagePtr im, int *size) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageGifCtx(im, out)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; +} + +/* + Function: gdImageGif + + outputs the specified image to the specified file in + GIF format. The file must be open for binary writing. (Under MSDOS + and all versions of Windows, it is important to use "wb" as + opposed to simply "w" as the mode when opening the file; under + Unix there is no penalty for doing so). does not close + the file; your code must do so. + + GIF does not support true color; GIF images can contain a maximum + of 256 colors. If the image to be written is a truecolor image, + such as those created with gdImageCreateTrueColor or loaded from a + JPEG or a truecolor PNG image file, a palette-based temporary + image will automatically be created internally using the + function. The original image + pixels are not modified. This conversion produces high quality + palettes but does require some CPU time. If you are regularly + converting truecolor to palette in this way, you should consider + creating your image as a palette-based image in the first place. + + Variants: + + outputs the image via a struct. + + stores the image in a large array of bytes. + + Parameters: + + im - The image to write + outFile - The FILE pointer to write the image to. + + Returns: + + Nothing + + Example: + + > gdImagePtr im; + > int black, white; + > FILE *out; + > // Create the image + > im = gdImageCreate(100, 100); + > // Allocate background + > white = gdImageColorAllocate(im, 255, 255, 255); + > // Allocate drawing color + > black = gdImageColorAllocate(im, 0, 0, 0); + > // Draw rectangle + > gdImageRectangle(im, 0, 0, 99, 99, black); + > // Open output file in binary mode + > out = fopen("rect.gif", "wb"); + > // Write GIF + > gdImageGif(im, out); + > // Close file + > fclose(out); + > // Destroy image + > gdImageDestroy(im); + +*/ +BGD_DECLARE(void) gdImageGif(gdImagePtr im, FILE *outFile) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageGifCtx(im, out); + out->gd_free(out); +} + +/* + Function: gdImageGifCtx + + Writes a GIF image via a . See . + + Parameters: + + im - The image to write + out - The struct used to do the writing. + + Returns: + + Nothing. + +*/ +BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) { _gdImageGifCtx(im, out); } + +/* returns 0 on success, 1 on failure */ +static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) +{ + gdImagePtr pim = 0, tim = im; + int interlace, BitsPerPixel; + interlace = im->interlace; + + if (im->trueColor) { + /* Expensive, but the only way that produces an + acceptable result: mix down to a palette + based temporary image. */ + pim = gdImageCreatePaletteFromTrueColor(im, 1, 256); + if (!pim) { + return 1; + } + tim = pim; + } + + BitsPerPixel = colorstobpp(tim->colorsTotal); + + /* All set, let's do it. */ + GIFEncode(out, tim->sx, tim->sy, interlace, 0, tim->transparent, BitsPerPixel, tim->red, + tim->green, tim->blue, tim); + + if (pim) { + /* Destroy palette based temporary image. */ + gdImageDestroy(pim); + } + + return 0; +} + +/* + Function: gdImageGifAnimBeginPtr + + Like except that it outputs to a memory + buffer. See . + + The returned memory must be freed by the caller when it is no + longer needed. **The caller must invoke (), not free()**, + unless the caller is absolutely certain that the same + implementations of malloc, free, etc. are used both at library + build time and at application build time (but don't; it could + always change). + + The 'size' parameter receives the total size of the block of + memory. + + Parameters: + + im - The reference image + size - Output: the size in bytes of the result. + GlobalCM - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default + Loops - Loop count; 0 -> infinite, -1 means no loop + + Returns: + + A pointer to the resulting data (the contents of the start of the + GIF) or NULL if an error occurred. + +*/ + +BGD_DECLARE(void *) +gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM, int Loops) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops); + rv = gdDPExtractData(out, size); + out->gd_free(out); + return rv; +} + +/* + Function: gdImageGifAnimBegin + + This function must be called as the first function when creating a + GIF animation. It writes the correct GIF file headers to selected + file output, and prepares for frames to be added for the + animation. The image argument is not used to produce an image + frame to the file, it is only used to establish the GIF animation + frame size, interlacing options and the color + palette. is used to add the first and + subsequent frames to the animation, and the animation must be + terminated by writing a semicolon character (;) to it or by using + gdImageGifAnimEnd to do that. + + The GlobalCM flag indicates if a global color map (or palette) is + used in the GIF89A header. A nonzero value specifies that a global + color map should be used to reduce the size of the animation. Of + course, if the color maps of individual frames differ greatly, a + global color map may not be a good idea. GlobalCM=1 means write + global color map, GlobalCM=0 means do not, and GlobalCM=-1 means + to do the default, which currently is to use a global color map. + + If Loops is 0 or greater, the Netscape 2.0 extension for animation + loop count is written. 0 means infinite loop count. -1 means that + the extension is not added which results in no looping. -1 is the + default. + + Variants: + + outputs the image via a struct. + + stores the image in a large array of bytes. + + Parameters: + + im - The reference image + outfile - The output FILE*. + GlobalCM - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default + Loops - Loop count; 0 -> infinite, -1 means no loop + + Returns: + + Nothing. + + Example: + + See . + +*/ + +BGD_DECLARE(void) +gdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops); + out->gd_free(out); +} + +/* + Function: gdImageGifAnimBeginCtx + + Like except that it outputs to . + See . -void * gdImageGifPtr (gdImagePtr im, int *size) + Parameters: + + im - The reference image + out - Pointer to the output . + GlobalCM - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default + Loops - Loop count; 0 -> infinite, -1 means no loop + + Returns: + + Nothing. + +*/ +BGD_DECLARE(void) +gdImageGifAnimBeginCtx(gdImagePtr im, gdIOCtxPtr out, int GlobalCM, int Loops) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - if (!_gdImageGifCtx(im, out)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } - out->gd_free (out); - return rv; + int B; + int RWidth, RHeight; + int Resolution; + int ColorMapSize; + int BitsPerPixel; + int Background = 0; + int i; + + /* Default is to use global color map */ + if (GlobalCM < 0) { + GlobalCM = 1; + } + + BitsPerPixel = colorstobpp(im->colorsTotal); + ColorMapSize = 1 << BitsPerPixel; + + RWidth = im->sx; + RHeight = im->sy; + + Resolution = BitsPerPixel; + + /* Write the Magic header */ + gdPutBuf("GIF89a", 6, out); + + /* Write out the screen width and height */ + gifPutWord(RWidth, out); + gifPutWord(RHeight, out); + + /* Indicate that there is a global colour map */ + B = GlobalCM ? 0x80 : 0; + + /* OR in the resolution */ + B |= (Resolution - 1) << 4; + + /* OR in the Bits per Pixel */ + B |= (BitsPerPixel - 1); + + /* Write it out */ + gdPutC(B, out); + + /* Write out the Background colour */ + gdPutC(Background, out); + + /* Byte of 0's (future expansion) */ + gdPutC(0, out); + + /* Write out the Global Colour Map */ + if (GlobalCM) { + for (i = 0; i < ColorMapSize; ++i) { + gdPutC(im->red[i], out); + gdPutC(im->green[i], out); + gdPutC(im->blue[i], out); + } + } + + if (Loops >= 0) { + gdPutBuf("!\377\13NETSCAPE2.0\3\1", 16, out); + gifPutWord(Loops, out); + gdPutC(0, out); + } } -void gdImageGif (gdImagePtr im, FILE * outFile) +/* + Function: gdImageGifAnimAddPtr + + Like (which contains more information) except + that it stores the data to write into memory and returns a pointer + to it. + + This memory must be freed by the caller when it is no longer + needed. **The caller must invoke (), not free(),** unless + the caller is absolutely certain that the same implementations of + malloc, free, etc. are used both at library build time and at + application build time (but don't; it could always change). + + The 'size' parameter receives the total size of the block of + memory. + + Parameters: + + im - The image to add. + size - Output: the size of the resulting buffer. + LocalCM - Flag. If 1, use a local color map for this frame. + LeftOfs - Left offset of image in frame. + TopOfs - Top offset of image in frame. + Delay - Delay before next frame (in 1/100 seconds) + Disposal - MODE: How to treat this frame when the next one loads. + previm - NULL or a pointer to the previous image written. + + Returns: + + Pointer to the resulting data or NULL if an error occurred. + +*/ +BGD_DECLARE(void *) +gdImageGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm) { - gdIOCtx *out = gdNewFileCtx (outFile); - gdImageGifCtx (im, out); - out->gd_free (out); + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; } -void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) +/* + Function: gdImageGifAnimAdd + + This function writes GIF animation frames to GIF animation, which + was initialized with . With _LeftOfs_ and + _TopOfs_ you can place this frame in different offset than (0,0) + inside the image screen as defined in . Delay + between the previous frame and this frame is in 1/100s + units. _Disposal_ is usually , meaning that the + pixels changed by this frame should remain on the display when the + next frame begins to render, but can also be + (not recommended), (restores the + first allocated color of the global palette), or + (restores the appearance of the + affected area before the frame was rendered). Only + is a sensible choice for the first frame. If + _previm_ is passed, the built-in GIF optimizer will always use + regardless of the Disposal parameter. + + Setting the _LocalCM_ flag to 1 adds a local palette for this + image to the animation. Otherwise the global palette is assumed + and the user must make sure the palettes match. Use + to do that. + + Automatic optimization is activated by giving the previous image + as a parameter. This function then compares the images and only + writes the changed pixels to the new frame in animation. The + _Disposal_ parameter for optimized animations must be set to 1, + also for the first frame. _LeftOfs_ and _TopOfs_ parameters are + ignored for optimized frames. To achieve good optimization, it is + usually best to use a single global color map. To allow + to compress unchanged pixels via the use of a + transparent color, the image must include a transparent color. + + + Variants: + + outputs its data via a struct. + + outputs its data to a memory buffer which + it returns. + + Parameters: + + im - The image to add. + outfile - The output FILE* being written. + LocalCM - Flag. If 1, use a local color map for this frame. + LeftOfs - Left offset of image in frame. + TopOfs - Top offset of image in frame. + Delay - Delay before next frame (in 1/100 seconds) + Disposal - MODE: How to treat this frame when the next one loads. + previm - NULL or a pointer to the previous image written. + + Returns: + + Nothing. + + Example: + (start code) + +{ + gdImagePtr im, im2, im3; + int black, white, trans; + FILE *out; + + im = gdImageCreate(100, 100); // Create the image + white = gdImageColorAllocate(im, 255, 255, 255); // Allocate background + black = gdImageColorAllocate(im, 0, 0, 0); // Allocate drawing color + trans = gdImageColorAllocate(im, 1, 1, 1); // trans clr for compression + gdImageRectangle(im, 0, 0, 10, 10, black); // Draw rectangle + + out = fopen("anim.gif", "wb");// Open output file in binary mode + gdImageGifAnimBegin(im, out, 1, 3);// Write GIF hdr, global clr map,loops + // Write the first frame. No local color map. Delay = 1s + gdImageGifAnimAdd(im, out, 0, 0, 0, 100, 1, NULL); + + // construct the second frame + im2 = gdImageCreate(100, 100); + (void)gdImageColorAllocate(im2, 255, 255, 255); // White background + gdImagePaletteCopy (im2, im); // Make sure the palette is identical + gdImageRectangle(im2, 0, 0, 15, 15, black); // Draw something + // Allow animation compression with transparent pixels + gdImageColorTransparent (im2, trans); + gdImageGifAnimAdd(im2, out, 0, 0, 0, 100, 1, im); // Add second frame + + // construct the third frame + im3 = gdImageCreate(100, 100); + (void)gdImageColorAllocate(im3, 255, 255, 255); // white background + gdImagePaletteCopy (im3, im); // Make sure the palette is identical + gdImageRectangle(im3, 0, 0, 15, 20, black); // Draw something + // Allow animation compression with transparent pixels + gdImageColorTransparent (im3, trans); + // Add the third frame, compressing against the second one + gdImageGifAnimAdd(im3, out, 0, 0, 0, 100, 1, im2); + gdImageGifAnimEnd(out); // End marker, same as putc(';', out); + fclose(out); // Close file + + // Destroy images + gdImageDestroy(im); + gdImageDestroy(im2); + gdImageDestroy(im3); + } + + (end code) +*/ + +BGD_DECLARE(void) +gdImageGifAnimAdd(gdImagePtr im, FILE *outFile, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm) { - _gdImageGifCtx(im, out); + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm); + out->gd_free(out); +} + +static int comparewithmap(gdImagePtr im1, gdImagePtr im2, int c1, int c2, int *colorMap) +{ + if (!colorMap) { + return c1 == c2; + } + + if (-2 != colorMap[c1]) { + return colorMap[c1] == c2; + } + + return (colorMap[c1] = gdImageColorExactAlpha(im2, im1->red[c1], im1->green[c1], im1->blue[c1], + im1->alpha[c1])) == c2; +} + +/* + Function: gdImageGifAnimAddCtx + + Adds an animation frame via a . See gdImageGifAnimAdd>. + + Parameters: + + im - The image to add. + out - The output . + LocalCM - Flag. If 1, use a local color map for this frame. + LeftOfs - Left offset of image in frame. + TopOfs - Top offset of image in frame. + Delay - Delay before next frame (in 1/100 seconds) + Disposal - MODE: How to treat this frame when the next one loads. + previm - NULL or a pointer to the previous image written. + + Returns: + + Nothing. + +*/ +BGD_DECLARE(void) +gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out, int LocalCM, int LeftOfs, int TopOfs, int Delay, + int Disposal, gdImagePtr previm) +{ + _gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm); } /* returns 0 on success, 1 on failure */ -static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) +static int _gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out, int LocalCM, int LeftOfs, + int TopOfs, int Delay, int Disposal, gdImagePtr previm) { - gdImagePtr pim = 0, tim = im; - int interlace, BitsPerPixel; - interlace = im->interlace; - if (im->trueColor) { - /* Expensive, but the only way that produces an - acceptable result: mix down to a palette - based temporary image. */ - pim = gdImageCreatePaletteFromTrueColor(im, 1, 256); - if (!pim) { - return 1; - } - tim = pim; - } - BitsPerPixel = colorstobpp(tim->colorsTotal); - /* All set, let's do it. */ - GIFEncode( - out, tim->sx, tim->sy, interlace, 0, tim->transparent, BitsPerPixel, - tim->red, tim->green, tim->blue, tim); - if (pim) { - /* Destroy palette based temporary image. */ - gdImageDestroy( pim); - } + gdImagePtr pim = NULL, tim = im; + int interlace, transparent, BitsPerPixel; + interlace = im->interlace; + transparent = im->transparent; + + /* Default is no local color map */ + if (LocalCM < 0) { + LocalCM = 0; + } + + if (im->trueColor) { + /* Expensive, but the only way that produces an + acceptable result: mix down to a palette + based temporary image. */ + pim = gdImageCreatePaletteFromTrueColor(im, 1, 256); + if (!pim) { + return 1; + } + tim = pim; + } + + if (previm) { + /* create optimized animation. Compare this image to + the previous image and crop the temporary copy of + current image to include only changed rectangular + area. Also replace unchanged pixels inside this + area with transparent color. Transparent color + needs to be already allocated! + Preconditions: + TopOfs, LeftOfs are assumed 0 + + Images should be of same size. If not, a temporary + copy is made with the same size as previous image. + + */ + gdImagePtr prev_pim = 0, prev_tim = previm; + int x, y; + int no_changes = 0; + int min_x = 0; + int min_y = tim->sy; + int max_x = 0; + int max_y = 0; + int colorMap[256]; + + if (previm->trueColor) { + prev_pim = gdImageCreatePaletteFromTrueColor(previm, 1, 256); + if (!prev_pim) { + goto fail_end; + } + prev_tim = prev_pim; + } + + for (x = 0; x < 256; ++x) { + colorMap[x] = -2; + } + + /* First find bounding box of changed areas. */ + /* first find the top changed row */ + for (y = 0; y < tim->sy; ++y) { + for (x = 0; x < tim->sx; ++x) { + if (!comparewithmap(prev_tim, tim, prev_tim->pixels[y][x], tim->pixels[y][x], + colorMap)) { + min_y = max_y = y; + min_x = max_x = x; + goto break_top; + } + } + } + + break_top: + if (tim->sy == min_y) { + /* No changes in this frame. Encode a 1x1 transparent placeholder. + */ + no_changes = 1; + transparent = 0; + min_x = min_y = 0; + max_x = max_y = 0; + } else { + /* Then the bottom row */ + for (y = tim->sy - 1; y > min_y; --y) { + for (x = 0; x < tim->sx; ++x) { + if (!gdImageBoundsSafe(prev_tim, x, y)) + continue; + if (!comparewithmap(prev_tim, tim, prev_tim->pixels[y][x], tim->pixels[y][x], + colorMap)) { + max_y = y; + if (x < min_x) { + min_x = x; + } + if (x > max_x) { + max_x = x; + } + goto break_bot; + } + } + } + + break_bot: + /* left side */ + for (x = 0; x < min_x; ++x) { + for (y = min_y; y <= max_y; ++y) { + if (!gdImageBoundsSafe(prev_tim, x, y)) + continue; + if (!comparewithmap(prev_tim, tim, prev_tim->pixels[y][x], tim->pixels[y][x], + colorMap)) { + min_x = x; + goto break_left; + } + } + } + + break_left: + /* right side */ + for (x = tim->sx - 1; x > max_x; --x) { + for (y = min_y; y <= max_y; ++y) { + if (!gdImageBoundsSafe(prev_tim, x, y)) + continue; + if (!comparewithmap(prev_tim, tim, prev_tim->pixels[y][x], tim->pixels[y][x], + colorMap)) { + max_x = x; + goto break_right; + } + } + } + + break_right:; + } + + LeftOfs = min_x; + TopOfs = min_y; + Disposal = 1; + + /* Make a copy of the image with the new offsets. + But only if necessary. */ + if (min_x != 0 || max_x != tim->sx - 1 || min_y != 0 || max_y != tim->sy - 1 || + transparent >= 0) { + + gdImagePtr pim2 = gdImageCreate(max_x - min_x + 1, max_y - min_y + 1); + + if (!pim2) { + if (prev_pim) { + gdImageDestroy(prev_pim); + } + goto fail_end; + } + + gdImagePaletteCopy(pim2, LocalCM ? tim : prev_tim); + gdImageCopy(pim2, tim, 0, 0, min_x, min_y, max_x - min_x + 1, max_y - min_y + 1); + + if (pim) { + gdImageDestroy(pim); + } + + tim = pim = pim2; + } + + /* now let's compare pixels for transparent + optimization. But only if transparent is set. */ + if (transparent >= 0) { + for (y = 0; y < tim->sy; ++y) { + for (x = 0; x < tim->sx; ++x) { + if (no_changes || + comparewithmap(prev_tim, tim, prev_tim->pixels[min_y + y][min_x + x], + tim->pixels[y][x], 0)) { + gdImageSetPixel(tim, x, y, transparent); + break; + } + } + } + } + if (prev_pim) { + gdImageDestroy(prev_pim); + } + } + + BitsPerPixel = colorstobpp(tim->colorsTotal); + + /* All set, let's do it. */ + GIFAnimEncode(out, tim->sx, tim->sy, LeftOfs, TopOfs, interlace, transparent, Delay, Disposal, + BitsPerPixel, LocalCM ? tim->red : 0, tim->green, tim->blue, tim); + if (pim) { + /* Destroy palette based temporary image. */ + gdImageDestroy(pim); + } return 0; + +fail_end: + if (pim) { + /* Destroy palette based temporary image. */ + gdImageDestroy(pim); + } + return 1; } -static int -colorstobpp(int colors) +/* + Function: gdImageGifAnimEnd + + Terminates the GIF file properly. + + (Previous versions of this function's documentation suggested just + manually writing a semicolon (';') instead since that is all this + function does. While that has no longer changed, we now suggest + that you do not do this and instead always call + (or equivalent) since later versions could + possibly do more or different things.) + + Variants: + + outputs its data via a struct. + + outputs its data to a memory buffer which + it returns. + + Parameters: + + outfile - the destination FILE*. + + Returns: + + Nothing. + +*/ + +BGD_DECLARE(void) gdImageGifAnimEnd(FILE *outFile) +{ +#if 1 + putc(';', outFile); +#else + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageGifAnimEndCtx(out); + out->gd_free(out); +#endif +} + +/* + Function: gdImageGifAnimEndPtr + + Like (which contains more information) except + that it stores the data to write into memory and returns a pointer + to it. + + This memory must be freed by the caller when it is no longer + needed. **The caller must invoke (), not free(),** unless + the caller is absolutely certain that the same implementations of + malloc, free, etc. are used both at library build time and at + application build time (but don't; it could always change). + + The 'size' parameter receives the total size of the block of + memory. + + Parameters: + + size - Output: the size of the resulting buffer. + + Returns: + + Pointer to the resulting data or NULL if an error occurred. + +*/ + +BGD_DECLARE(void *) gdImageGifAnimEndPtr(int *size) +{ + char *rv = (char *)gdMalloc(1); + if (!rv) { + return 0; + } + *rv = ';'; + *size = 1; + return (void *)rv; +} + +/* + Function: gdImageGifAnimEndCtx + + Like , but writes its data via a . + + Parameters: + + out - the destination . + + Returns: + + Nothing. + +*/ + +BGD_DECLARE(void) gdImageGifAnimEndCtx(gdIOCtx *out) +{ + /* + * Write the GIF file terminator + */ + gdPutC(';', out); +} + +static int colorstobpp(int colors) { int bpp = 0; - if ( colors <= 2 ) + if (colors <= 2) bpp = 1; - else if ( colors <= 4 ) + else if (colors <= 4) bpp = 2; - else if ( colors <= 8 ) + else if (colors <= 8) bpp = 3; - else if ( colors <= 16 ) + else if (colors <= 16) bpp = 4; - else if ( colors <= 32 ) + else if (colors <= 32) bpp = 5; - else if ( colors <= 64 ) + else if (colors <= 64) bpp = 6; - else if ( colors <= 128 ) + else if (colors <= 128) bpp = 7; - else if ( colors <= 256 ) + else if (colors <= 256) bpp = 8; + return bpp; - } +} /***************************************************************************** * @@ -189,236 +989,289 @@ colorstobpp(int colors) #define TRUE 1 #define FALSE 0 -/* - * Bump the 'curx' and 'cury' to point to the next pixel - */ -static void -BumpPixel(GifCtx *ctx) + +/* Bump the 'curx' and 'cury' to point to the next pixel */ +static void BumpPixel(GifCtx *ctx) { - /* - * Bump the current X position - */ - ++(ctx->curx); - - /* - * If we are at the end of a scan line, set curx back to the beginning - * If we are interlaced, bump the cury to the appropriate spot, - * otherwise, just increment it. - */ - if( ctx->curx == ctx->Width ) { - ctx->curx = 0; - - if( !ctx->Interlace ) - ++(ctx->cury); - else { - switch( ctx->Pass ) { - - case 0: - ctx->cury += 8; - if( ctx->cury >= ctx->Height ) { - ++(ctx->Pass); - ctx->cury = 4; - } - break; - - case 1: - ctx->cury += 8; - if( ctx->cury >= ctx->Height ) { - ++(ctx->Pass); - ctx->cury = 2; - } - break; - - case 2: - ctx->cury += 4; - if( ctx->cury >= ctx->Height ) { - ++(ctx->Pass); - ctx->cury = 1; - } - break; - - case 3: - ctx->cury += 2; - break; - } + /* Bump the current X position */ + ++(ctx->curx); + + /* If we are at the end of a scan line, set curx back to the beginning + * If we are interlaced, bump the cury to the appropriate spot, + * otherwise, just increment it. */ + if (ctx->curx == ctx->Width) { + ctx->curx = 0; + + if (!ctx->Interlace) { + ++(ctx->cury); + } else { + switch (ctx->Pass) { + + case 0: + ctx->cury += 8; + if (ctx->cury >= ctx->Height) { + ++(ctx->Pass); + ctx->cury = 4; } + break; + + case 1: + ctx->cury += 8; + if (ctx->cury >= ctx->Height) { + ++(ctx->Pass); + ctx->cury = 2; + } + break; + + case 2: + ctx->cury += 4; + if (ctx->cury >= ctx->Height) { + ++(ctx->Pass); + ctx->cury = 1; + } + break; + + case 3: + ctx->cury += 2; + break; + } } + } } -/* - * Return the next pixel from the image - */ -static int -GIFNextPixel(gdImagePtr im, GifCtx *ctx) +/* Return the next pixel from the image */ +static int GIFNextPixel(gdImagePtr im, GifCtx *ctx) { - int r; + int r; - if( ctx->CountDown == 0 ) - return EOF; + if (ctx->CountDown == 0) { + return EOF; + } - --(ctx->CountDown); + --(ctx->CountDown); - r = gdImageGetPixel(im, ctx->curx, ctx->cury); + r = gdImageGetPixel(im, ctx->curx, ctx->cury); - BumpPixel(ctx); + BumpPixel(ctx); - return r; + return r; } /* public */ -static void -GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im) +static void GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, + int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, + gdImagePtr im) +{ + int B; + int RWidth, RHeight; + int LeftOfs, TopOfs; + int Resolution; + int ColorMapSize; + int InitCodeSize; + int i; + GifCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.Interlace = GInterlace; + ctx.in_count = 1; + + ColorMapSize = 1 << BitsPerPixel; + + RWidth = ctx.Width = GWidth; + RHeight = ctx.Height = GHeight; + LeftOfs = TopOfs = 0; + + Resolution = BitsPerPixel; + + /* Calculate number of bits we are expecting */ + ctx.CountDown = (long)ctx.Width * (long)ctx.Height; + + /* Indicate which pass we are on (if interlace) */ + ctx.Pass = 0; + + /* The initial code size */ + if (BitsPerPixel <= 1) { + InitCodeSize = 2; + } else { + InitCodeSize = BitsPerPixel; + } + + /* Set up the current x and y position */ + ctx.curx = ctx.cury = 0; + + /* Write the Magic header */ + gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp); + + /* Write out the screen width and height */ + gifPutWord(RWidth, fp); + gifPutWord(RHeight, fp); + + /* Indicate that there is a global colour map */ + /* Yes, there is a color map */ + B = 0x80; + + /* OR in the resolution */ + B |= (Resolution - 1) << 4; + + /* OR in the Bits per Pixel */ + B |= (BitsPerPixel - 1); + + /* Write it out */ + gdPutC(B, fp); + + /* Write out the Background colour */ + gdPutC(Background, fp); + + /* Byte of 0's (future expansion) */ + gdPutC(0, fp); + + /* Write out the Global Colour Map */ + for (i = 0; i < ColorMapSize; ++i) { + gdPutC(Red[i], fp); + gdPutC(Green[i], fp); + gdPutC(Blue[i], fp); + } + + /* Write out extension for transparent colour index, if necessary. */ + if (Transparent >= 0) { + gdPutC('!', fp); + gdPutC(0xf9, fp); + gdPutC(4, fp); + gdPutC(1, fp); + gdPutC(0, fp); + gdPutC(0, fp); + gdPutC((unsigned char)Transparent, fp); + gdPutC(0, fp); + } + + /* Write an Image separator */ + gdPutC(',', fp); + + /* Write the Image header */ + gifPutWord(LeftOfs, fp); + gifPutWord(TopOfs, fp); + gifPutWord(ctx.Width, fp); + gifPutWord(ctx.Height, fp); + + /* Write out whether or not the image is interlaced */ + if (ctx.Interlace) { + gdPutC(0x40, fp); + } else { + gdPutC(0x00, fp); + } + + /* Write out the initial code size */ + gdPutC(InitCodeSize, fp); + + /* Go and actually compress the data */ + compress(InitCodeSize + 1, fp, im, &ctx); + + /* Write out a Zero-length packet (to end the series) */ + gdPutC(0, fp); + + /* Write the GIF file terminator */ + gdPutC(';', fp); +} + +static void GIFAnimEncode(gdIOCtxPtr fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, + int GInterlace, int Transparent, int Delay, int Disposal, + int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im) { - int B; - int RWidth, RHeight; - int LeftOfs, TopOfs; - int Resolution; - int ColorMapSize; - int InitCodeSize; - int i; - GifCtx ctx; - - memset(&ctx, 0, sizeof(ctx)); - ctx.Interlace = GInterlace; - ctx.in_count = 1; - - ColorMapSize = 1 << BitsPerPixel; - - RWidth = ctx.Width = GWidth; - RHeight = ctx.Height = GHeight; - LeftOfs = TopOfs = 0; - - Resolution = BitsPerPixel; - - /* - * Calculate number of bits we are expecting - */ - ctx.CountDown = (long)ctx.Width * (long)ctx.Height; - - /* - * Indicate which pass we are on (if interlace) - */ - ctx.Pass = 0; - - /* - * The initial code size - */ - if( BitsPerPixel <= 1 ) - InitCodeSize = 2; - else - InitCodeSize = BitsPerPixel; - - /* - * Set up the current x and y position - */ - ctx.curx = ctx.cury = 0; - - /* - * Write the Magic header - */ - gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp ); - - /* - * Write out the screen width and height - */ - gifPutWord( RWidth, fp ); - gifPutWord( RHeight, fp ); - - /* - * Indicate that there is a global colour map - */ - B = 0x80; /* Yes, there is a color map */ - - /* - * OR in the resolution - */ - B |= (Resolution - 1) << 4; - - /* - * OR in the Bits per Pixel - */ - B |= (BitsPerPixel - 1); - - /* - * Write it out - */ - gdPutC( B, fp ); - - /* - * Write out the Background colour - */ - gdPutC( Background, fp ); - - /* - * Byte of 0's (future expansion) - */ - gdPutC( 0, fp ); - - /* - * Write out the Global Colour Map - */ - for( i=0; i= 0 ? 1 : 0) | (Disposal << 2), fp); + gdPutC((unsigned char)(Delay & 255), fp); + gdPutC((unsigned char)((Delay >> 8) & 255), fp); + gdPutC((unsigned char)Transparent, fp); + gdPutC(0, fp); + + /* Write an Image separator */ + gdPutC(',', fp); + + /* Write out the Image header */ + gifPutWord(LeftOfs, fp); + gifPutWord(TopOfs, fp); + gifPutWord(ctx.Width, fp); + gifPutWord(ctx.Height, fp); + + /* Indicate that there is a local colour map */ + B = (Red && Green && Blue) ? 0x80 : 0; + + /* OR in the interlacing */ + B |= ctx.Interlace ? 0x40 : 0; + + /* OR in the Bits per Pixel */ + B |= (Red && Green && Blue) ? (BitsPerPixel - 1) : 0; + + /* Write it out */ + gdPutC(B, fp); + + /* Write out the Local Colour Map */ + if (Red && Green && Blue) { + for (i = 0; i < ColorMapSize; ++i) { + gdPutC(Red[i], fp); + gdPutC(Green[i], fp); + gdPutC(Blue[i], fp); } + } + + /* Write out the initial code size */ + gdPutC(InitCodeSize, fp); - /* - * Write out extension for transparent colour index, if necessary. - */ - if ( Transparent >= 0 ) { - gdPutC( '!', fp ); - gdPutC( 0xf9, fp ); - gdPutC( 4, fp ); - gdPutC( 1, fp ); - gdPutC( 0, fp ); - gdPutC( 0, fp ); - gdPutC( (unsigned char) Transparent, fp ); - gdPutC( 0, fp ); - } - - /* - * Write an Image separator - */ - gdPutC( ',', fp ); - - /* - * Write the Image header - */ - - gifPutWord( LeftOfs, fp ); - gifPutWord( TopOfs, fp ); - gifPutWord( ctx.Width, fp ); - gifPutWord( ctx.Height, fp ); - - /* - * Write out whether or not the image is interlaced - */ - if( ctx.Interlace ) - gdPutC( 0x40, fp ); - else - gdPutC( 0x00, fp ); - - /* - * Write out the initial code size - */ - gdPutC( InitCodeSize, fp ); - - /* - * Go and actually compress the data - */ - compress( InitCodeSize+1, fp, im, &ctx ); - - /* - * Write out a Zero-length packet (to end the series) - */ - gdPutC( 0, fp ); - - /* - * Write the GIF file terminator - */ - gdPutC( ';', fp ); + /* Go and actually compress the data */ + compress(InitCodeSize + 1, fp, im, &ctx); + + /* Write out a Zero-length packet (to end the series) */ + gdPutC(0, fp); } /*************************************************************************** @@ -430,16 +1283,14 @@ GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background * ***************************************************************************/ -/* - * General DEFINEs - */ +/* General DEFINEs */ -#define GIFBITS 12 +#define GIFBITS 12 #ifdef NO_UCHAR - typedef char char_type; -#else /*NO_UCHAR*/ - typedef unsigned char char_type; +typedef char char_type; +#else /*NO_UCHAR*/ +typedef unsigned char char_type; #endif /*NO_UCHAR*/ /* @@ -460,15 +1311,14 @@ GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background #define ARGVAL() (*++(*argv) || (--argc && *++argv)) -#ifdef COMPATIBLE /* But wrong! */ -# define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1) +#ifdef COMPATIBLE /* But wrong! */ +#define MAXCODE(n_bits) ((code_int)1 << (n_bits) - 1) #else /*COMPATIBLE*/ -# define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1) +#define MAXCODE(n_bits) (((code_int)1 << (n_bits)) - 1) #endif /*COMPATIBLE*/ -#define HashTabOf(i) ctx->htab[i] -#define CodeTabOf(i) ctx->codetab[i] - +#define HashTabOf(i) ctx->htab[i] +#define CodeTabOf(i) ctx->codetab[i] /* * To save much memory, we overlay the table used by compress() with those @@ -480,8 +1330,8 @@ GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background */ #define tab_prefixof(i) CodeTabOf(i) -#define tab_suffixof(i) ((char_type*)(htab))[i] -#define de_stack ((char_type*)&tab_suffixof((code_int)1<g_init_bits = init_bits; ctx->g_outfile = outfile; - /* - * Set up the necessary values - */ + /* Set up the necessary values */ ctx->offset = 0; ctx->out_count = 0; ctx->clear_flg = 0; @@ -535,67 +1380,77 @@ compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx) char_init(ctx); - ent = GIFNextPixel( im, ctx ); + ent = GIFNextPixel(im, ctx); hshift = 0; - for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L ) + for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L) { ++hshift; - hshift = 8 - hshift; /* set hash code range bound */ + } + hshift = 8 - hshift; /* set hash code range bound */ hsize_reg = hsize; - cl_hash( (count_int) hsize_reg, ctx ); /* clear hash table */ + cl_hash((count_int)hsize_reg, ctx); /* clear hash table */ - output( (code_int)ctx->ClearCode, ctx ); + output((code_int)ctx->ClearCode, ctx); #ifdef SIGNED_COMPARE_SLOW - while ( (c = GIFNextPixel( im, ctx )) != (unsigned) EOF ) { -#else /*SIGNED_COMPARE_SLOW*/ - while ( (c = GIFNextPixel( im, ctx )) != EOF ) { /* } */ + while ((c = GIFNextPixel(im, ctx)) != (unsigned)EOF) { +#else /*SIGNED_COMPARE_SLOW*/ + while ((c = GIFNextPixel(im, ctx)) != EOF) { #endif /*SIGNED_COMPARE_SLOW*/ ++(ctx->in_count); - fcode = (long) (((long) c << maxbits) + ent); - i = (((code_int)c << hshift) ^ ent); /* xor hashing */ + fcode = (long)(((long)c << maxbits) + ent); + i = (((code_int)c << hshift) ^ ent); /* xor hashing */ - if ( HashTabOf (i) == fcode ) { - ent = CodeTabOf (i); + if (HashTabOf(i) == fcode) { + ent = CodeTabOf(i); continue; - } else if ( (long)HashTabOf (i) < 0 ) /* empty slot */ + } else if ((long)HashTabOf(i) < 0) { /* empty slot */ goto nomatch; - disp = hsize_reg - i; /* secondary hash (after G. Knott) */ - if ( i == 0 ) + } + + disp = hsize_reg - i; /* secondary hash (after G. Knott) */ + + if (i == 0) { disp = 1; -probe: - if ( (i -= disp) < 0 ) + } + + probe: + if ((i -= disp) < 0) { i += hsize_reg; + } - if ( HashTabOf (i) == fcode ) { - ent = CodeTabOf (i); + if (HashTabOf(i) == fcode) { + ent = CodeTabOf(i); continue; } - if ( (long)HashTabOf (i) > 0 ) + + if ((long)HashTabOf(i) > 0) { goto probe; -nomatch: - output ( (code_int) ent, ctx ); + } + + nomatch: + output((code_int)ent, ctx); ++(ctx->out_count); ent = c; #ifdef SIGNED_COMPARE_SLOW - if ( (unsigned) ctx->free_ent < (unsigned) maxmaxcode) { -#else /*SIGNED_COMPARE_SLOW*/ - if ( ctx->free_ent < maxmaxcode ) { /* } */ -#endif /*SIGNED_COMPARE_SLOW*/ - CodeTabOf (i) = ctx->free_ent++; /* code -> hashtable */ - HashTabOf (i) = fcode; - } else - cl_block(ctx); + if ((unsigned)ctx->free_ent < (unsigned)maxmaxcode) { +#else /*SIGNED_COMPARE_SLOW*/ + if (ctx->free_ent < maxmaxcode) { /* } */ +#endif /*SIGNED_COMPARE_SLOW*/ + CodeTabOf(i) = ctx->free_ent++; /* code -> hashtable */ + HashTabOf(i) = fcode; + } else { + cl_block(ctx); + } } - /* - * Put out the final code. - */ - output( (code_int)ent, ctx ); + + /* Put out the final code. */ + output((code_int)ent, ctx); ++(ctx->out_count); - output( (code_int) ctx->EOFCode, ctx ); + output((code_int)ctx->EOFCode, ctx); } /***************************************************************** @@ -615,11 +1470,9 @@ compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx) * code in turn. When the buffer fills up empty it and start over. */ -static const unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, - 0x001F, 0x003F, 0x007F, 0x00FF, - 0x01FF, 0x03FF, 0x07FF, 0x0FFF, - 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; - +static const unsigned long masks[] = {0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, + 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, + 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF}; /* Arbitrary value to mark output is done. When we see EOFCode, then we don't * expect to see any more data. If we do (e.g. corrupt image inputs), cur_bits @@ -627,25 +1480,22 @@ static const unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, */ #define CUR_BITS_FINISHED -1000 - -static void -output(code_int code, GifCtx *ctx) +static void output(code_int code, GifCtx *ctx) { - if (ctx->cur_bits == CUR_BITS_FINISHED) { - return; - } + if (ctx->cur_bits == CUR_BITS_FINISHED) + return; + ctx->cur_accum &= masks[ctx->cur_bits]; - ctx->cur_accum &= masks[ ctx->cur_bits ]; - - if( ctx->cur_bits > 0 ) + if (ctx->cur_bits > 0) { ctx->cur_accum |= ((long)code << ctx->cur_bits); - else + } else { ctx->cur_accum = code; + } ctx->cur_bits += ctx->n_bits; - while( ctx->cur_bits >= 8 ) { - char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx ); + while (ctx->cur_bits >= 8) { + char_out((unsigned int)(ctx->cur_accum & 0xff), ctx); ctx->cur_accum >>= 8; ctx->cur_bits -= 8; } @@ -654,35 +1504,29 @@ output(code_int code, GifCtx *ctx) * If the next entry is going to be too big for the code size, * then increase it, if possible. */ - if ( ctx->free_ent > ctx->maxcode || ctx->clear_flg ) { - - if( ctx->clear_flg ) { - - ctx->maxcode = MAXCODE (ctx->n_bits = ctx->g_init_bits); - ctx->clear_flg = 0; - + if (ctx->free_ent > ctx->maxcode || ctx->clear_flg) { + if (ctx->clear_flg) { + ctx->maxcode = MAXCODE(ctx->n_bits = ctx->g_init_bits); + ctx->clear_flg = 0; + } else { + ++(ctx->n_bits); + if (ctx->n_bits == maxbits) { + ctx->maxcode = maxmaxcode; } else { - - ++(ctx->n_bits); - if ( ctx->n_bits == maxbits ) - ctx->maxcode = maxmaxcode; - else - ctx->maxcode = MAXCODE(ctx->n_bits); + ctx->maxcode = MAXCODE(ctx->n_bits); } } + } - if( code == ctx->EOFCode ) { - /* - * At EOF, write the rest of the buffer. - */ - while( ctx->cur_bits > 0 ) { - char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx); - ctx->cur_accum >>= 8; - ctx->cur_bits -= 8; + if (code == ctx->EOFCode) { + /* At EOF, write the rest of the buffer. */ + while (ctx->cur_bits > 0) { + char_out((unsigned int)(ctx->cur_accum & 0xff), ctx); + ctx->cur_accum >>= 8; + ctx->cur_bits -= 8; } - - /* Flag that it's done to prevent re-entry. */ - ctx->cur_bits = CUR_BITS_FINISHED; + /* Flag that it's done to prevent re-entry. */ + ctx->cur_bits = CUR_BITS_FINISHED; flush_char(ctx); } @@ -691,50 +1535,45 @@ output(code_int code, GifCtx *ctx) /* * Clear out the hash table */ -static void -cl_block (GifCtx *ctx) /* table clear for block compress */ +static void cl_block(GifCtx *ctx) /* table clear for block compress */ { + cl_hash((count_int)hsize, ctx); + ctx->free_ent = ctx->ClearCode + 2; + ctx->clear_flg = 1; - cl_hash ( (count_int) hsize, ctx ); - ctx->free_ent = ctx->ClearCode + 2; - ctx->clear_flg = 1; - - output( (code_int)ctx->ClearCode, ctx); + output((code_int)ctx->ClearCode, ctx); } -static void -cl_hash(register count_int chsize, GifCtx *ctx) /* reset code table */ - +static void cl_hash(register count_int chsize, GifCtx *ctx) /* reset code table */ { - - register count_int *htab_p = ctx->htab+chsize; - - register long i; - register long m1 = -1; - - i = chsize - 16; - do { /* might use Sys V memset(3) here */ - *(htab_p-16) = m1; - *(htab_p-15) = m1; - *(htab_p-14) = m1; - *(htab_p-13) = m1; - *(htab_p-12) = m1; - *(htab_p-11) = m1; - *(htab_p-10) = m1; - *(htab_p-9) = m1; - *(htab_p-8) = m1; - *(htab_p-7) = m1; - *(htab_p-6) = m1; - *(htab_p-5) = m1; - *(htab_p-4) = m1; - *(htab_p-3) = m1; - *(htab_p-2) = m1; - *(htab_p-1) = m1; - htab_p -= 16; - } while ((i -= 16) >= 0); - - for ( i += 16; i > 0; --i ) - *--htab_p = m1; + register count_int *htab_p = ctx->htab + chsize; + register long i; + register long m1 = -1; + + i = chsize - 16; + do { /* might use Sys V memset(3) here */ + *(htab_p - 16) = m1; + *(htab_p - 15) = m1; + *(htab_p - 14) = m1; + *(htab_p - 13) = m1; + *(htab_p - 12) = m1; + *(htab_p - 11) = m1; + *(htab_p - 10) = m1; + *(htab_p - 9) = m1; + *(htab_p - 8) = m1; + *(htab_p - 7) = m1; + *(htab_p - 6) = m1; + *(htab_p - 5) = m1; + *(htab_p - 4) = m1; + *(htab_p - 3) = m1; + *(htab_p - 2) = m1; + *(htab_p - 1) = m1; + htab_p -= 16; + } while ((i -= 16) >= 0); + + for (i += 16; i > 0; --i) { + *--htab_p = m1; + } } /****************************************************************************** @@ -746,43 +1585,36 @@ cl_hash(register count_int chsize, GifCtx *ctx) /* reset code table */ /* * Set up the 'byte output' routine */ -static void -char_init(GifCtx *ctx) -{ - ctx->a_count = 0; -} +static void char_init(GifCtx *ctx) { ctx->a_count = 0; } /* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ -static void -char_out(int c, GifCtx *ctx) +static void char_out(int c, GifCtx *ctx) { - ctx->accum[ ctx->a_count++ ] = c; - if( ctx->a_count >= 254 ) - flush_char(ctx); + ctx->accum[ctx->a_count++] = c; + if (ctx->a_count >= 254) { + flush_char(ctx); + } } /* * Flush the packet to disk, and reset the accumulator */ -static void -flush_char(GifCtx *ctx) +static void flush_char(GifCtx *ctx) { - if( ctx->a_count > 0 ) { - gdPutC( ctx->a_count, ctx->g_outfile ); - gdPutBuf( ctx->accum, ctx->a_count, ctx->g_outfile ); - ctx->a_count = 0; - } + if (ctx->a_count > 0) { + gdPutC(ctx->a_count, ctx->g_outfile); + gdPutBuf(ctx->accum, ctx->a_count, ctx->g_outfile); + ctx->a_count = 0; + } } static int gifPutWord(int w, gdIOCtx *out) { - /* Byte order is little-endian */ - gdPutC(w & 0xFF, out); - gdPutC((w >> 8) & 0xFF, out); - return 0; + /* Byte order is little-endian */ + gdPutC(w & 0xFF, out); + gdPutC((w >> 8) & 0xFF, out); + return 0; } - - diff --git a/ext/gd/libgd/gd_gradient.c b/ext/gd/libgd/gd_gradient.c new file mode 100644 index 000000000000..e1281f3e10e8 --- /dev/null +++ b/ext/gd/libgd/gd_gradient.c @@ -0,0 +1,318 @@ +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_gradient.h" +#include "gd_path_matrix.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +static int finite_matrix(const gdPathMatrix *m) +{ + return m && isfinite(m->m00) && isfinite(m->m10) && isfinite(m->m01) && isfinite(m->m11) && + isfinite(m->m02) && isfinite(m->m12); +} + +static int valid_extend(gdExtendMode e) { return e >= GD_EXTEND_NONE && e <= GD_EXTEND_PAD; } + +static gdPaintPtr create_gradient(gdGradientKind kind) +{ + gdPaintPtr paint = gdMalloc(sizeof(*paint)); + gdGradient *g; + if (!paint) + return NULL; + g = gdCalloc(1, sizeof(*g)); + if (!g) { + gdFree(paint); + return NULL; + } + g->kind = kind; + g->extend = GD_EXTEND_PAD; + gdPathMatrixInitIdentity(&g->matrix); + gdPathMatrixInitIdentity(&g->inverse); + paint->ref = 1; + paint->type = gdPaintTypeGradient; + paint->gradient = g; + return paint; +} + +BGD_DECLARE(gdPaintPtr) gdPaintCreateLinear(double x0, double y0, double x1, double y1) +{ + gdPaintPtr p; + gdGradient *g; + double dx, dy, ls, s; + if (!isfinite(x0) || !isfinite(y0) || !isfinite(x1) || !isfinite(y1)) + return NULL; + p = create_gradient(GD_GRADIENT_LINEAR); + if (!p) + return NULL; + g = p->gradient; + dx = x1 - x0; + dy = y1 - y0; + ls = dx * dx + dy * dy; + s = fmax(fmax(fabs(x0), fabs(y0)), fmax(fabs(x1), fabs(y1))); + g->geometry.linear.x0 = x0; + g->geometry.linear.y0 = y0; + g->geometry.linear.dx = dx; + g->geometry.linear.dy = dy; + g->geometry.linear.scale = s; + g->geometry.linear.inverse_length_squared = + (isfinite(ls) && ls > 64.0 * DBL_EPSILON * fmax(1.0, s * s)) ? 1.0 / ls : 0.0; + return p; +} + +BGD_DECLARE(gdPaintPtr) +gdPaintCreateRadial(double x0, double y0, double r0, double x1, double y1, double r1) +{ + gdPaintPtr p; + gdGradient *g; + double s; + if (!isfinite(x0) || !isfinite(y0) || !isfinite(r0) || !isfinite(x1) || !isfinite(y1) || + !isfinite(r1) || r0 < 0 || r1 < 0) + return NULL; + p = create_gradient(GD_GRADIENT_RADIAL); + if (!p) + return NULL; + g = p->gradient; + g->geometry.radial.x0 = x0; + g->geometry.radial.y0 = y0; + g->geometry.radial.r0 = r0; + g->geometry.radial.x1 = x1; + g->geometry.radial.y1 = y1; + g->geometry.radial.r1 = r1; + g->geometry.radial.cdx = x1 - x0; + g->geometry.radial.cdy = y1 - y0; + g->geometry.radial.dr = r1 - r0; + g->geometry.radial.quadratic_a = g->geometry.radial.cdx * g->geometry.radial.cdx + + g->geometry.radial.cdy * g->geometry.radial.cdy - + g->geometry.radial.dr * g->geometry.radial.dr; + s = fmax(fmax(fabs(x0), fabs(y0)), fmax(fabs(x1), fabs(y1))); + s = fmax(s, fmax(r0, r1)); + g->geometry.radial.scale = s; + return p; +} + +void gdGradientDestroy(gdGradient *g) +{ + if (g) { + gdFree(g->stops); + gdFree(g); + } +} + +static gdPremulPixelF ramp_at(const gdColorStop *s, size_t n, double t) +{ + size_t i, last; + gdPremulPixelF z = {0, 0, 0, 0}, a, b, out; + double u; + if (!n) + return z; + if (n == 1) + return s[0].color; + if (t < s[0].offset) + return s[0].color; + if (t >= s[n - 1].offset) + return s[n - 1].color; + for (i = 0; i < n && s[i].offset < t; i++) { + } + if (s[i].offset == t) { + while (i + 1 < n && s[i + 1].offset == t) + i++; + return s[i].color; + } + last = i; + a = s[i - 1].color; + b = s[last].color; + u = (t - s[i - 1].offset) / (s[last].offset - s[i - 1].offset); + out.r = (float)(a.r + (b.r - a.r) * u); + out.g = (float)(a.g + (b.g - a.g) * u); + out.b = (float)(a.b + (b.b - a.b) * u); + out.a = (float)(a.a + (b.a - a.a) * u); + return out; +} + +BGD_DECLARE(int) +gdPaintAddColorStopRgba(gdPaintPtr p, double off, double r, double g, double b, double a) +{ + gdGradient *gradient; + gdColorStop *candidate; + gdPremulPixelF lut[GD_GRADIENT_LUT_SIZE]; + size_t n, i, j; + if (!p || p->type != gdPaintTypeGradient || !isfinite(off) || !isfinite(r) || !isfinite(g) || + !isfinite(b) || !isfinite(a) || off < 0 || off > 1 || r < 0 || r > 1 || g < 0 || g > 1 || + b < 0 || b > 1 || a < 0 || a > 1) + return 0; + gradient = p->gradient; + n = gradient->stop_count + 1; + candidate = gdMalloc(n * sizeof(*candidate)); + if (!candidate) + return 0; + if (gradient->stop_count) + memcpy(candidate, gradient->stops, gradient->stop_count * sizeof(*candidate)); + candidate[n - 1].offset = off; + candidate[n - 1].sequence = gradient->next_sequence; + candidate[n - 1].color.r = (float)(r * a); + candidate[n - 1].color.g = (float)(g * a); + candidate[n - 1].color.b = (float)(b * a); + candidate[n - 1].color.a = (float)a; + for (i = 1; i < n; i++) { + gdColorStop v = candidate[i]; + j = i; + while (j && + (candidate[j - 1].offset > v.offset || + (candidate[j - 1].offset == v.offset && candidate[j - 1].sequence > v.sequence))) { + candidate[j] = candidate[j - 1]; + j--; + } + candidate[j] = v; + } + for (i = 0; i < GD_GRADIENT_LUT_SIZE; i++) + lut[i] = ramp_at(candidate, n, i / (double)(GD_GRADIENT_LUT_SIZE - 1)); + gdFree(gradient->stops); + gradient->stops = candidate; + gradient->stop_count = n; + gradient->stop_capacity = n; + gradient->next_sequence++; + memcpy(gradient->lut, lut, sizeof(lut)); + return 1; +} + +BGD_DECLARE(int) gdPaintAddColorStopRgb(gdPaintPtr p, double o, double r, double g, double b) +{ + return gdPaintAddColorStopRgba(p, o, r, g, b, 1.0); +} + +BGD_DECLARE(int) gdPaintSetExtend(gdPaintPtr p, gdExtendMode e) +{ + if (!p || !valid_extend(e)) + return 0; + if (p->type == gdPaintTypeGradient) { + p->gradient->extend = e; + return 1; + } + if (p->type == gdPaintTypePattern) { + p->pattern->extend = e; + return 1; + } + return 0; +} + +BGD_DECLARE(int) gdPaintSetMatrix(gdPaintPtr p, const gdPathMatrixPtr m) +{ + gdPathMatrix inv; + if (!p || !finite_matrix(m)) + return 0; + inv = *m; + if (!gdPathMatrixInvert(&inv)) + return 0; + if (p->type == gdPaintTypeGradient) { + p->gradient->matrix = *m; + p->gradient->inverse = inv; + return 1; + } + if (p->type == gdPaintTypePattern) { + p->pattern->matrix = *m; + return 1; + } + return 0; +} + +int gdExtendFold(double raw, gdExtendMode mode, double *f) +{ + double m; + if (!f || !isfinite(raw) || !valid_extend(mode)) + return 0; + if (raw == 0.0) + raw = 0.0; + switch (mode) { + case GD_EXTEND_NONE: + if (raw < 0 || raw > 1) + return 0; + *f = raw; + return 1; + case GD_EXTEND_PAD: + *f = raw < 0 ? 0 : (raw > 1 ? 1 : raw); + return 1; + case GD_EXTEND_REPEAT: + *f = raw - floor(raw); + return 1; + case GD_EXTEND_REFLECT: + m = fmod(raw, 2.0); + if (m < 0) + m += 2; + *f = m <= 1 ? m : 2 - m; + return 1; + default: + return 0; + } +} + +static int radial_t(const gdGradient *g, double x, double y, double *out) +{ + const double cx = g->geometry.radial.cdx, cy = g->geometry.radial.cdy, + dr = g->geometry.radial.dr; + double px = x - g->geometry.radial.x0, py = y - g->geometry.radial.y0, + r0 = g->geometry.radial.r0; + double A = g->geometry.radial.quadratic_a, B = px * cx + py * cy + r0 * dr, + C = px * px + py * py - r0 * r0; + double scale = fmax(1.0, g->geometry.radial.scale + fabs(px) + fabs(py)); + double coord_tol = 64 * DBL_EPSILON * scale; + double tol = coord_tol * scale, roots[2], disc; + int n = 0, valid = 0; + if (fabs(cx) <= coord_tol && fabs(cy) <= coord_tol && fabs(dr) <= coord_tol) + return 0; + if (fabs(A) <= tol) { + if (fabs(B) <= tol) + return 0; + roots[n++] = C / (2 * B); + } else { + disc = B * B - A * C; + if (disc < 0) { + if (disc >= -tol * scale * scale) + disc = 0; + else + return 0; + } + disc = sqrt(disc); + roots[n++] = (B + disc) / A; + roots[n++] = (B - disc) / A; + } + for (int i = 0; i < n; i++) + if (isfinite(roots[i]) && r0 + roots[i] * dr >= -coord_tol && + (g->extend != GD_EXTEND_NONE || (roots[i] >= 0 && roots[i] <= 1))) { + if (!valid || roots[i] > *out) + *out = roots[i]; + valid = 1; + } + return valid; +} + +gdPremulPixelF gdGradientSample(const gdGradient *g, const gdPathMatrix *m, double x, double y) +{ + gdPremulPixelF z = {0, 0, 0, 0}; + double px, py, t, f; + long i; + if (!g || !m || !g->stop_count) + return z; + px = m->m01 * y + m->m00 * x + m->m02; + py = m->m11 * y + m->m10 * x + m->m12; + if (g->kind == GD_GRADIENT_LINEAR) { + if (g->geometry.linear.inverse_length_squared == 0) + return z; + t = ((px - g->geometry.linear.x0) * g->geometry.linear.dx + + (py - g->geometry.linear.y0) * g->geometry.linear.dy) * + g->geometry.linear.inverse_length_squared; + } else if (!radial_t(g, px, py, &t)) + return z; + if (!gdExtendFold(t, g->extend, &f)) + return z; + i = (long)floor(f * (GD_GRADIENT_LUT_SIZE - 1) + 0.5); + if (i < 0) + i = 0; + if (i >= GD_GRADIENT_LUT_SIZE) + i = GD_GRADIENT_LUT_SIZE - 1; + return g->lut[i]; +} diff --git a/ext/gd/libgd/gd_gradient.h b/ext/gd/libgd/gd_gradient.h new file mode 100644 index 000000000000..308654232f68 --- /dev/null +++ b/ext/gd/libgd/gd_gradient.h @@ -0,0 +1,43 @@ +#ifndef GD_GRADIENT_H +#define GD_GRADIENT_H + +#include "gd_compositor.h" +#include "gd_vector2d_private.h" +#include +#include + +#define GD_GRADIENT_LUT_SIZE 1024 + +typedef enum { GD_GRADIENT_LINEAR, GD_GRADIENT_RADIAL } gdGradientKind; + +typedef struct { + double offset; + gdPremulPixelF color; + uint64_t sequence; +} gdColorStop; + +struct gdGradientStruct { + gdGradientKind kind; + gdExtendMode extend; + gdPathMatrix matrix; + gdPathMatrix inverse; + gdColorStop *stops; + size_t stop_count, stop_capacity; + uint64_t next_sequence; + gdPremulPixelF lut[GD_GRADIENT_LUT_SIZE]; + union { + struct { + double x0, y0, dx, dy, inverse_length_squared, scale; + } linear; + struct { + double x0, y0, r0, x1, y1, r1, cdx, cdy, dr, quadratic_a, scale; + } radial; + } geometry; +}; + +void gdGradientDestroy(gdGradient *gradient); +int gdExtendFold(double raw, gdExtendMode mode, double *folded); +gdPremulPixelF gdGradientSample(const gdGradient *gradient, const gdPathMatrix *device_to_pattern, + double device_x, double device_y); + +#endif diff --git a/ext/gd/libgd/gd_heif.c b/ext/gd/libgd/gd_heif.c new file mode 100644 index 000000000000..c8b6057d00bc --- /dev/null +++ b/ext/gd/libgd/gd_heif.c @@ -0,0 +1,621 @@ +/** + * File: HEIF IO + * + * Read and write HEIF images. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "gd.h" +#include "gd_errors.h" +#include "gdhelpers.h" +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBHEIF +#include + +#define GD_HEIF_ALLOC_STEP (4 * 1024) +#define GD_HEIF_HEADER 12 + +typedef enum gd_heif_brand { + GD_HEIF_BRAND_AVIF = 1, + GD_HEIF_BRAND_MIF1 = 2, + GD_HEIF_BRAND_HEIC = 4, + GD_HEIF_BRAND_HEIX = 8, +} gd_heif_brand; + +/* + Function: gdImageCreateFromHeif + + is called to load truecolor images from + HEIF format files. Invoke with an + already opened pointer to a file containing the desired + image. returns a to the new + truecolor image, or NULL if unable to load the image (most often + because the file is corrupt or does not contain a HEIF + image). does not close the file. + + You can inspect the sx and sy members of the image to determine + its size. The image must eventually be destroyed using + . + + *The returned image is always a truecolor image.* + + Parameters: + + infile - The input FILE pointer. + + Returns: + + A pointer to the new *truecolor* image. This will need to be + destroyed with once it is no longer needed. + + On error, returns NULL. +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeif(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + + if (!in) + return NULL; + im = gdImageCreateFromHeifCtx(in); + in->gd_free(in); + + return im; +} + +/* + Function: gdImageCreateFromHeifPtr + + See . + + Parameters: + + size - size of HEIF data in bytes. + data - pointer to HEIF data. +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + + if (!in) + return NULL; + im = gdImageCreateFromHeifCtx(in); + in->gd_free(in); + + return im; +} + +static int _gdHeifCheckBrand(unsigned char *magic, gd_heif_brand expected_brand) +{ + if (memcmp(magic + 4, "ftyp", 4) != 0) + return GD_FALSE; + if (memcmp(magic + 8, "avif", 4) == 0 && expected_brand & GD_HEIF_BRAND_AVIF) + return GD_TRUE; + if (memcmp(magic + 8, "heic", 4) == 0 && expected_brand & GD_HEIF_BRAND_HEIC) + return GD_TRUE; + if (memcmp(magic + 8, "heix", 4) == 0 && expected_brand & GD_HEIF_BRAND_HEIX) + return GD_TRUE; + if (memcmp(magic + 8, "mif1", 4) == 0 && expected_brand & GD_HEIF_BRAND_MIF1) + return GD_TRUE; + + return GD_FALSE; +} + +static gdImagePtr _gdImageCreateFromHeifCtx(gdIOCtx *infile, gd_heif_brand expected_brand) +{ + struct heif_context *heif_ctx; + struct heif_decoding_options *heif_dec_opts; + struct heif_image_handle *heif_imhandle; + struct heif_image *heif_im; + struct heif_error err; + int width, height; + uint8_t *filedata = NULL; + uint8_t *rgba = NULL; + unsigned char *read, *temp, magic[GD_HEIF_HEADER]; + int magic_len; + size_t size = 0, n = GD_HEIF_ALLOC_STEP; + gdImagePtr im; + int x, y; + uint8_t *p, *row_start; + int stride; + + magic_len = gdGetBuf(magic, GD_HEIF_HEADER, infile); + if (magic_len != GD_HEIF_HEADER || !_gdHeifCheckBrand(magic, expected_brand)) { + gd_error("gd-heif incorrect type of file\n"); + return NULL; + } + gdSeek(infile, 0); + + while (n == GD_HEIF_ALLOC_STEP) { + temp = gdRealloc(filedata, size + GD_HEIF_ALLOC_STEP); + if (temp) { + filedata = temp; + read = temp + size; + } else { + gdFree(filedata); + gd_error("gd-heif decode realloc failed\n"); + return NULL; + } + + n = gdGetBuf(read, GD_HEIF_ALLOC_STEP, infile); + if (n > 0) { + size += n; + } + } + + heif_ctx = heif_context_alloc(); + if (heif_ctx == NULL) { + gd_error("gd-heif could not allocate context\n"); + gdFree(filedata); + return NULL; + } + err = heif_context_read_from_memory_without_copy(heif_ctx, filedata, size, NULL); + if (err.code != heif_error_Ok) { + gd_error("gd-heif context creation failed\n"); + gdFree(filedata); + heif_context_free(heif_ctx); + return NULL; + } + + heif_imhandle = NULL; + err = heif_context_get_primary_image_handle(heif_ctx, &heif_imhandle); + if (err.code != heif_error_Ok) { + gd_error("gd-heif cannot retreive handle\n"); + gdFree(filedata); + heif_context_free(heif_ctx); + return NULL; + } + + heif_im = NULL; + heif_dec_opts = heif_decoding_options_alloc(); + if (heif_dec_opts == NULL) { + gd_error("gd-heif could not allocate decode options\n"); + gdFree(filedata); + heif_image_handle_release(heif_imhandle); + heif_context_free(heif_ctx); + return NULL; + } + + heif_dec_opts->convert_hdr_to_8bit = GD_TRUE; + heif_dec_opts->ignore_transformations = GD_TRUE; + err = heif_decode_image(heif_imhandle, &heif_im, heif_colorspace_RGB, + heif_chroma_interleaved_RGBA, heif_dec_opts); + heif_decoding_options_free(heif_dec_opts); + if (err.code != heif_error_Ok) { + gd_error("gd-heif decoding failed\n"); + gdFree(filedata); + heif_image_handle_release(heif_imhandle); + heif_context_free(heif_ctx); + return NULL; + } + + width = heif_image_get_width(heif_im, heif_channel_interleaved); + height = heif_image_get_height(heif_im, heif_channel_interleaved); + + im = gdImageCreateTrueColor(width, height); + if (!im) { + gdFree(filedata); + heif_image_release(heif_im); + heif_image_handle_release(heif_imhandle); + heif_context_free(heif_ctx); + return NULL; + } + rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, &stride); + if (!rgba) { + gd_error("gd-heif cannot get image plane\n"); + gdFree(filedata); + heif_image_release(heif_im); + heif_image_handle_release(heif_imhandle); + heif_context_free(heif_ctx); + gdImageDestroy(im); + return NULL; + } + row_start = rgba; + for (y = 0, p = rgba; y < height; y++) { + p = row_start; + for (x = 0; x < width; x++) { + uint8_t r = *(p++); + uint8_t g = *(p++); + uint8_t b = *(p++); + uint8_t a = gdAlphaMax - (*(p++) >> 1); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a); + } + row_start += stride; + } + gdFree(filedata); + heif_image_release(heif_im); + heif_image_handle_release(heif_imhandle); + heif_context_free(heif_ctx); + + return im; +} + +/* + Function: gdImageCreateFromHeifCtx + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifCtx(gdIOCtx *infile) +{ + return _gdImageCreateFromHeifCtx(infile, GD_HEIF_BRAND_AVIF | GD_HEIF_BRAND_MIF1 | + GD_HEIF_BRAND_HEIC | GD_HEIF_BRAND_HEIX); +} + +static struct heif_error _gdImageWriteHeif(struct heif_context *heif_ctx, const void *data, + size_t size, void *userdata) +{ + ARG_NOT_USED(heif_ctx); + gdIOCtx *outfile; + struct heif_error err; + int bytes_written; + + outfile = (gdIOCtx *)userdata; + if (outfile == NULL || data == NULL || size > INT_MAX) { + err.code = heif_error_Encoding_error; + err.subcode = heif_suberror_Cannot_write_output_data; + err.message = "gd-heif write callback received invalid arguments"; + return err; + } + + bytes_written = gdPutBuf(data, (int)size, outfile); + if (bytes_written != (int)size) { + err.code = heif_error_Encoding_error; + err.subcode = heif_suberror_Cannot_write_output_data; + err.message = "gd-heif failed to write output data"; + return err; + } + + err.code = heif_error_Ok; + err.subcode = heif_suberror_Unspecified; + err.message = ""; + + return err; +} + +/* returns GD_TRUE on success, GD_FALSE on failure */ +static int _gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifCodec codec, + gdHeifChroma chroma) +{ + struct heif_context *heif_ctx; + struct heif_encoder *heif_enc; + struct heif_image *heif_im; + struct heif_writer heif_wr; + struct heif_error err; + uint8_t *rgba; + int x, y; + uint8_t *p; + uint8_t *row_start; + int stride; + if (im == NULL) { + return GD_FALSE; + } + + if (codec != GD_HEIF_CODEC_HEVC && codec != GD_HEIF_CODEC_AV1) { + gd_error("Unsupported format by heif"); + return GD_FALSE; + } + + if (!gdImageTrueColor(im)) { + gd_error("Palette image not supported by heif\n"); + return GD_FALSE; + } + + if (overflow2(gdImageSX(im), 4)) { + return GD_FALSE; + } + + if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) { + return GD_FALSE; + } + + heif_ctx = heif_context_alloc(); + if (heif_ctx == NULL) { + gd_error("gd-heif could not allocate context\n"); + return GD_FALSE; + } + err = heif_context_get_encoder_for_format(heif_ctx, (enum heif_compression_format)codec, + &heif_enc); + if (err.code != heif_error_Ok) { + gd_error("gd-heif encoder acquisition failed (missing codec support?: " + "code: %d, subcode: %d, message: %s)\n", + err.code, err.subcode, err.message); + heif_context_free(heif_ctx); + return GD_FALSE; + } + + if (quality == 200) { + err = heif_encoder_set_lossless(heif_enc, GD_TRUE); + } else if (quality == -1) { + err = heif_encoder_set_lossy_quality(heif_enc, 80); + } else { + err = heif_encoder_set_lossy_quality(heif_enc, quality); + } + if (err.code != heif_error_Ok) { + gd_error("gd-heif invalid quality number\n"); + heif_encoder_release(heif_enc); + heif_context_free(heif_ctx); + return GD_FALSE; + } + + if (heif_get_version_number_major() >= 1 && heif_get_version_number_minor() >= 9) { + err = heif_encoder_set_parameter_string(heif_enc, "chroma", chroma); + if (err.code != heif_error_Ok) { + gd_error("gd-heif invalid chroma subsampling parameter\n"); + heif_encoder_release(heif_enc); + heif_context_free(heif_ctx); + return GD_FALSE; + } + } + + err = heif_image_create(gdImageSX(im), gdImageSY(im), heif_colorspace_RGB, + heif_chroma_interleaved_RGBA, &heif_im); + if (err.code != heif_error_Ok) { + gd_error("gd-heif image creation failed"); + heif_encoder_release(heif_enc); + heif_context_free(heif_ctx); + return GD_FALSE; + } + + err = heif_image_add_plane(heif_im, heif_channel_interleaved, gdImageSX(im), gdImageSY(im), 32); + if (err.code != heif_error_Ok) { + gd_error("gd-heif cannot add image plane\n"); + heif_image_release(heif_im); + heif_encoder_release(heif_enc); + heif_context_free(heif_ctx); + return GD_FALSE; + } + + rgba = (uint8_t *)heif_image_get_plane_readonly(heif_im, heif_channel_interleaved, &stride); + if (!rgba) { + gd_error("gd-heif cannot get image plane\n"); + heif_image_release(heif_im); + heif_encoder_release(heif_enc); + heif_context_free(heif_ctx); + return GD_FALSE; + } + row_start = rgba; + for (y = 0; y < gdImageSY(im); y++) { + p = row_start; + for (x = 0; x < gdImageSX(im); x++) { + int c; + char a; + c = im->tpixels[y][x]; + a = gdTrueColorGetAlpha(c); + if (a == 127) { + a = 0; + } else { + a = 255 - ((a << 1) + (a >> 6)); + } + *(p++) = gdTrueColorGetRed(c); + *(p++) = gdTrueColorGetGreen(c); + *(p++) = gdTrueColorGetBlue(c); + *(p++) = a; + } + row_start += stride; + } + err = heif_context_encode_image(heif_ctx, heif_im, heif_enc, NULL, NULL); + heif_encoder_release(heif_enc); + if (err.code != heif_error_Ok) { + gd_error("gd-heif encoding failed\n"); + heif_image_release(heif_im); + heif_context_free(heif_ctx); + return GD_FALSE; + } + heif_wr.write = _gdImageWriteHeif; + heif_wr.writer_api_version = 1; + err = heif_context_write(heif_ctx, &heif_wr, (void *)outfile); + + heif_image_release(heif_im); + heif_context_free(heif_ctx); + if (err.code != heif_error_Ok) { + gd_error("gd-heif write failed (code: %d, subcode: %d, message: %s)\n", err.code, + err.subcode, err.message); + return GD_FALSE; + } + + return GD_TRUE; +} + +/* + Function: gdImageHeifCtx + + Write the image as HEIF data via a . See + for more details. + + Parameters: + + im - The image to write. + outfile - The output sink. + quality - Image quality. + codec - The output coding format. + chroma - The output chroma subsampling format. + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) +gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + _gdImageHeifCtx(im, outfile, quality, codec, chroma); +} + +/* + Function: gdImageHeifEx + + outputs the specified image to the specified file in + HEIF format. The file must be open for writing. Under MSDOS and + all versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + If _quality_ is -1, a reasonable quality value (which should yield a + good general quality / size tradeoff for most situations) is used. Otherwise + _quality_ should be a value in the range 0-100, higher quality values + usually implying both higher quality and larger image sizes or 200, for + lossless codec. + + For _codec_, the default and most widely supported option is + GD_HEIF_CODEC_HEVC. GD_HEIF_CODEC_AV1 is a newer codec that may not be + supported by all decoders but can offer better compression efficiency. + They must be installed on the system and enabled at compile time to be used. + + Variants: + + stores the image using a struct. + + stores the image to RAM. + + Parameters: + + im - The image to save. + outFile - The FILE pointer to write to. + quality - Codec quality (0-100). + codec - The output coding format. + chroma - The output chroma subsampling format. + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) +gdImageHeifEx(gdImagePtr im, FILE *outFile, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageHeifCtx(im, out, quality, codec, chroma); + out->gd_free(out); +} + +/* + Function: gdImageHeif + + Variant of which uses the default quality (-1), the + default codec (GD_HEIF_Codec_HEVC) and the default chroma + subsampling (GD_HEIF_CHROMA_444). + + Parameters: + + im - The image to save + outFile - The FILE pointer to write to. + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) gdImageHeif(gdImagePtr im, FILE *outFile) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageHeifCtx(im, out, -1, GD_HEIF_CODEC_HEVC, GD_HEIF_CHROMA_444); + out->gd_free(out); +} + +/* + Function: gdImageHeifPtr + + See . +*/ +BGD_DECLARE(void *) gdImageHeifPtr(gdImagePtr im, int *size) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageHeifCtx(im, out, -1, GD_HEIF_CODEC_HEVC, GD_HEIF_CHROMA_444)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + + return rv; +} + +/* + Function: gdImageHeifPtrEx + + See . +*/ +BGD_DECLARE(void *) +gdImageHeifPtrEx(gdImagePtr im, int *size, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageHeifCtx(im, out, quality, codec, chroma)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; +} + +#else /* HAVE_LIBHEIF */ + +static void _noHeifError(void) { gd_error("HEIF image support has been disabled\n"); } + +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeif(FILE *inFile) +{ + _noHeifError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifPtr(int size, void *data) +{ + _noHeifError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromHeifCtx(gdIOCtx *infile) +{ + _noHeifError(); + return NULL; +} + +BGD_DECLARE(void) +gdImageHeifCtx(gdImagePtr im, gdIOCtx *outfile, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + _noHeifError(); +} + +BGD_DECLARE(void) +gdImageHeifEx(gdImagePtr im, FILE *outFile, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + _noHeifError(); +} + +BGD_DECLARE(void) gdImageHeif(gdImagePtr im, FILE *outFile) { _noHeifError(); } + +BGD_DECLARE(void *) gdImageHeifPtr(gdImagePtr im, int *size) +{ + _noHeifError(); + return NULL; +} + +BGD_DECLARE(void *) +gdImageHeifPtrEx(gdImagePtr im, int *size, int quality, gdHeifCodec codec, gdHeifChroma chroma) +{ + _noHeifError(); + return NULL; +} + +#endif /* HAVE_LIBHEIF */ diff --git a/ext/gd/libgd/gd_intern.h b/ext/gd/libgd/gd_intern.h index c7098d21b837..2a4b874c5ac3 100644 --- a/ext/gd/libgd/gd_intern.h +++ b/ext/gd/libgd/gd_intern.h @@ -1,20 +1,195 @@ +/* Internal header for random common utility functions. */ + #ifndef GD_INTERN_H #define GD_INTERN_H + +#include "gd.h" +#include +#ifdef _MSC_VER +#ifndef SSIZE_MAX +#ifdef _WIN64 +#define SSIZE_MAX _I64_MAX +#else +#define SSIZE_MAX INT_MAX +#endif +#endif +#endif +#if defined(_MSC_VER) +#define UNUSED_PARAM(x) x +#elif defined(__GNUC__) || defined(__clang__) +#define UNUSED_PARAM(x) x __attribute__((unused)) +#else +#define UNUSED_PARAM(x) x +#endif #ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif -#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c))) +#define MIN3(a, b, c) ((a) < (b) ? (MIN(a, c)) : (MIN(b, c))) #ifndef MAX -#define MAX(a,b) ((a)<(b)?(b):(a)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#endif +#define MAX3(a, b, c) ((a) < (b) ? (MAX(b, c)) : (MAX(a, c))) +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +#ifdef _MSC_VER +#define gd_strcasecmp _stricmp +#else +#define gd_strcasecmp strcasecmp #endif -#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c))) -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +typedef enum { + HORIZONTAL, + VERTICAL, +} gdAxis; + +/* Convert a double to an unsigned char, rounding to the nearest + * integer and clamping the result between 0 and max. The absolute + * value of clr must be less than the maximum value of an unsigned + * short. */ +static inline unsigned char uchar_clamp(double clr, unsigned char max) +{ + unsigned short result; + + // assert(fabs(clr) <= SHRT_MAX); + + /* Casting a negative float to an unsigned short is undefined. + * However, casting a float to a signed truncates toward zero and + * casting a negative signed value to an unsigned of the same size + * results in a bit-identical value (assuming twos-complement + * arithmetic). This is what we want: all legal negative values + * for clr will be greater than 255. */ + + /* Convert and clamp. */ + result = (unsigned short)(short)(clr + 0.5); + if (result > max) { + result = (clr < 0) ? 0 : max; + } /* if */ + + return result; +} /* uchar_clamp*/ /* Internal prototypes: */ +/* gd_jpeg.c */ +void *gdImageJpegPtrWithMetadataNoSubsampling(gdImagePtr im, int *size, int quality, + const gdImageMetadata *metadata); + /* gd_rotate.c */ gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent); gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent); gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent); -#endif +/** + * Clip a copy operation to the destination image bounds. + * Adjusts srcX/srcY to match any clipping applied to dstX/dstY. + * Returns 0 if the operation is entirely outside dst (nothing to do), + * 1 if there is work to do. + */ +static inline int gdImageClipCopy(gdImagePtr dst, int *dstX, int *dstY, int *srcX, int *srcY, + int *w, int *h) +{ + int x1, y1, x2, y2; + + /* overflow-safe dst rect: [dstX, dstY] to [dstX+w, dstY+h] */ + x1 = *dstX; + y1 = *dstY; + + /* check w/h are positive */ + if (*w <= 0 || *h <= 0) { + return 0; + } + + /* overflow check for dstX+w and dstY+h */ + if (*dstX > 0 && *w > INT_MAX - *dstX) { + x2 = INT_MAX; + } else { + x2 = *dstX + *w; + } + if (*dstY > 0 && *h > INT_MAX - *dstY) { + y2 = INT_MAX; + } else { + y2 = *dstY + *h; + } + + /* entirely outside dst? */ + if (x1 >= gdImageSX(dst) || y1 >= gdImageSY(dst) || x2 <= 0 || y2 <= 0) { + return 0; + } + + /* clip left */ + if (x1 < 0) { + *srcX -= x1; /* advance srcX by the same amount */ + *w += x1; /* reduce width */ + *dstX = 0; + } + + /* clip top */ + if (y1 < 0) { + *srcY -= y1; + *h += y1; + *dstY = 0; + } + + /* clip right */ + if (*dstX + *w > gdImageSX(dst)) { + *w = gdImageSX(dst) - *dstX; + } + + /* clip bottom */ + if (*dstY + *h > gdImageSY(dst)) { + *h = gdImageSY(dst) - *dstY; + } + + /* sanity: clipping may have reduced w/h to zero */ + if (*w <= 0 || *h <= 0) { + return 0; + } + + return 1; +} +static inline int gdImageClipCopyResized(gdImagePtr dst, int *dstX, int *dstY, int *dstW, int *dstH, + int *srcX, int *srcY, int *srcW, int *srcH) +{ + int orig_dstW = *dstW; + int orig_dstH = *dstH; + + if (*dstW <= 0 || *dstH <= 0 || *srcW <= 0 || *srcH <= 0) { + return 0; + } + if (*dstX >= gdImageSX(dst) || *dstY >= gdImageSY(dst) || *dstX + *dstW <= 0 || + *dstY + *dstH <= 0) { + return 0; + } + + /* clip left — adjust srcX proportionally */ + if (*dstX < 0) { + *srcX += (-*dstX) * *srcW / orig_dstW; + *srcW -= (-*dstX) * *srcW / orig_dstW; + *dstW += *dstX; + *dstX = 0; + } + /* clip top */ + if (*dstY < 0) { + *srcY += (-*dstY) * *srcH / orig_dstH; + *srcH -= (-*dstY) * *srcH / orig_dstH; + *dstH += *dstY; + *dstY = 0; + } + /* clip right */ + if (*dstX + *dstW > gdImageSX(dst)) { + int clip = *dstX + *dstW - gdImageSX(dst); + *srcW -= clip * *srcW / orig_dstW; + *dstW = gdImageSX(dst) - *dstX; + } + /* clip bottom */ + if (*dstY + *dstH > gdImageSY(dst)) { + int clip = *dstY + *dstH - gdImageSY(dst); + *srcH -= clip * *srcH / orig_dstH; + *dstH = gdImageSY(dst) - *dstY; + } + + if (*dstW <= 0 || *dstH <= 0) + return 0; + return 1; +} +#endif /* GD_INTERN_H */ diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index f8ba9087910f..cdc62f09b520 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -18,75 +18,77 @@ */ /* - Summary: + Summary: - - Horizontal filter contributions are calculated on the fly, - as each column is mapped from src to dst image. This lets - us omit having to allocate a temporary full horizontal stretch - of the src image. + - Horizontal filter contributions are calculated on the fly, + as each column is mapped from src to dst image. This lets + us omit having to allocate a temporary full horizontal stretch + of the src image. - - If none of the src pixels within a sampling region differ, - then the output pixel is forced to equal (any of) the source pixel. - This ensures that filters do not corrupt areas of constant color. - - - Filter weight contribution results, after summing, are - rounded to the nearest pixel color value instead of - being casted to ILubyte (usually an int or char). Otherwise, - artifacting occurs. + - If none of the src pixels within a sampling region differ, + then the output pixel is forced to equal (any of) the source pixel. + This ensures that filters do not corrupt areas of constant color. + - Filter weight contribution results, after summing, are + rounded to the nearest pixel color value instead of + being casted to ILubyte (usually an int or char). Otherwise, + artifacting occurs. */ /* - Additional functions are available for simple rotation or up/downscaling. - downscaling using the fixed point implementations are usually much faster - than the existing gdImageCopyResampled while having a similar or better - quality. - - For image rotations, the optimized versions have a lazy antialiasing for - the edges of the images. For a much better antialiased result, the affine - function is recommended. + Additional functions are available for simple rotation or up/downscaling. + downscaling using the fixed point implementations are usually much faster + than the existing gdImageCopyResampled while having a similar or better + quality. + + For image rotations, the optimized versions have a lazy antialiasing for + the edges of the images. For a much better antialiased result, the affine + function is recommended. */ /* TODO: - Optimize pixel accesses and loops once we have continuous buffer - - Add scale support for a portion only of an image (equivalent of copyresized/resampled) + - Add scale support for a portion only of an image (equivalent of +copyresized/resampled) */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include #include #include #include -#include + +#undef NDEBUG +/* Comment out this line to enable asserts. + * TODO: This logic really belongs in cmake and configure. + */ +/* #define NDEBUG 1 */ +#include #include "gd.h" -#include "gdhelpers.h" #include "gd_intern.h" +#include "gdhelpers.h" -static gdImagePtr gdImageScaleBilinear(gdImagePtr im, - const unsigned int new_width, +static gdImagePtr gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, const unsigned int new_height); -static gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, - const unsigned int width, +static gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, const unsigned int height); -static gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, - const unsigned int width, const unsigned int height); -static gdImagePtr gdImageScaleTwoPass(const gdImagePtr pOrigImage, - const unsigned int uOrigWidth, - const unsigned int uOrigHeight, - const unsigned int uNewWidth, - const unsigned int uNewHeight); -static gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, - const float degrees, +static gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, + const unsigned int height); +static gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor); -static gdImagePtr gdImageRotateGeneric(gdImagePtr src, - const float degrees, - const int bgColor); +static gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor); -/* only used here, let do a generic fixed point integers later if required by other - part of GD */ +#ifdef FUNCTION_NOT_USED_YET +/* only used by the inactive edge helper below */ typedef long gdFixed; /* Integer to fixed point */ -#define gd_itofx(x) (long)((unsigned long)(x) << 8) +#define gd_itofx(x) ((x) << 8) /* Float to fixed point */ #define gd_ftofx(x) (long)((x) * 256) @@ -98,255 +100,174 @@ typedef long gdFixed; #define gd_fxtoi(x) ((x) >> 8) /* Fixed point to float */ -# define gd_fxtof(x) ((float)(x) / 256) +#define gd_fxtof(x) ((float)(x) / 256) /* Fixed point to double */ #define gd_fxtod(x) ((double)(x) / 256) /* Multiply a fixed by a fixed */ -#define gd_mulfx(x,y) (((x) * (y)) >> 8) +#define gd_mulfx(x, y) (((x) * (y)) >> 8) /* Divide a fixed by a fixed */ -#define gd_divfx(x,y) ((long)((unsigned long)(x) << 8) / (y)) +#define gd_divfx(x, y) (((x) << 8) / (y)) +#endif -typedef struct -{ - double *Weights; /* Normalized weights of neighboring pixels */ - int Left,Right; /* Bounds of source pixels window */ +typedef struct _FilterInfo { + double (*function)(const double, const double), support; +} FilterInfo; + +typedef struct { + double *Weights; /* Normalized weights of neighboring pixels */ + int Left, Right; /* Bounds of source pixels window */ } ContributionType; /* Contirbution information for a single pixel */ -typedef struct -{ - ContributionType *ContribRow; /* Row (or column) of contribution weights */ - unsigned int WindowSize, /* Filter window size (of affecting source pixels) */ - LineLength; /* Length of line (no. or rows / cols) */ +typedef struct { + ContributionType *ContribRow; /* Row (or column) of contribution weights */ + unsigned int WindowSize, /* Filter window size (of affecting source pixels) */ + LineLength; /* Length of line (no. or rows / cols) */ } LineContribType; -/* Each core filter has its own radius */ -#define DEFAULT_FILTER_LINEAR 1.0f -#define DEFAULT_FILTER_BICUBIC 3.0f -#define DEFAULT_FILTER_BOX 0.5f -#define DEFAULT_FILTER_GENERALIZED_CUBIC 0.5f -#define DEFAULT_FILTER_RADIUS 1.0f -#define DEFAULT_LANCZOS8_RADIUS 8.0f -#define DEFAULT_LANCZOS3_RADIUS 3.0f -#define DEFAULT_HERMITE_RADIUS 1.0f -#define DEFAULT_BOX_RADIUS 0.5f -#define DEFAULT_TRIANGLE_RADIUS 1.0f -#define DEFAULT_BELL_RADIUS 1.5f -#define DEFAULT_CUBICSPLINE_RADIUS 2.0f -#define DEFAULT_MITCHELL_RADIUS 2.0f -#define DEFAULT_COSINE_RADIUS 1.0f -#define DEFAULT_CATMULLROM_RADIUS 2.0f -#define DEFAULT_QUADRATIC_RADIUS 1.5f -#define DEFAULT_QUADRATICBSPLINE_RADIUS 1.5f -#define DEFAULT_CUBICCONVOLUTION_RADIUS 3.0f -#define DEFAULT_GAUSSIAN_RADIUS 1.0f -#define DEFAULT_HANNING_RADIUS 1.0f -#define DEFAULT_HAMMING_RADIUS 1.0f -#define DEFAULT_SINC_RADIUS 1.0f -#define DEFAULT_WELSH_RADIUS 1.0f - -enum GD_RESIZE_FILTER_TYPE{ - FILTER_DEFAULT = 0, - FILTER_BELL, - FILTER_BESSEL, - FILTER_BLACKMAN, - FILTER_BOX, - FILTER_BSPLINE, - FILTER_CATMULLROM, - FILTER_COSINE, - FILTER_CUBICCONVOLUTION, - FILTER_CUBICSPLINE, - FILTER_HERMITE, - FILTER_LANCZOS3, - FILTER_LANCZOS8, - FILTER_MITCHELL, - FILTER_QUADRATIC, - FILTER_QUADRATICBSPLINE, - FILTER_TRIANGLE, - FILTER_GAUSSIAN, - FILTER_HANNING, - FILTER_HAMMING, - FILTER_SINC, - FILTER_WELSH, - - FILTER_CALLBACK = 999 -}; - -typedef enum GD_RESIZE_FILTER_TYPE gdResizeFilterType; - static double KernelBessel_J1(const double x) { - double p, q; - - register long i; - - static const double - Pone[] = - { - 0.581199354001606143928050809e+21, - -0.6672106568924916298020941484e+20, - 0.2316433580634002297931815435e+19, - -0.3588817569910106050743641413e+17, - 0.2908795263834775409737601689e+15, - -0.1322983480332126453125473247e+13, - 0.3413234182301700539091292655e+10, - -0.4695753530642995859767162166e+7, - 0.270112271089232341485679099e+4 - }, - Qone[] = - { - 0.11623987080032122878585294e+22, - 0.1185770712190320999837113348e+20, - 0.6092061398917521746105196863e+17, - 0.2081661221307607351240184229e+15, - 0.5243710262167649715406728642e+12, - 0.1013863514358673989967045588e+10, - 0.1501793594998585505921097578e+7, - 0.1606931573481487801970916749e+4, - 0.1e+1 - }; - - p = Pone[8]; - q = Qone[8]; - for (i=7; i >= 0; i--) - { - p = p*x*x+Pone[i]; - q = q*x*x+Qone[i]; - } - return (double)(p/q); + double p, q; + + register long i; + + static const double Pone[] = {0.581199354001606143928050809e+21, + -0.6672106568924916298020941484e+20, + 0.2316433580634002297931815435e+19, + -0.3588817569910106050743641413e+17, + 0.2908795263834775409737601689e+15, + -0.1322983480332126453125473247e+13, + 0.3413234182301700539091292655e+10, + -0.4695753530642995859767162166e+7, + 0.270112271089232341485679099e+4}, + Qone[] = {0.11623987080032122878585294e+22, + 0.1185770712190320999837113348e+20, + 0.6092061398917521746105196863e+17, + 0.2081661221307607351240184229e+15, + 0.5243710262167649715406728642e+12, + 0.1013863514358673989967045588e+10, + 0.1501793594998585505921097578e+7, + 0.1606931573481487801970916749e+4, + 0.1e+1}; + + p = Pone[8]; + q = Qone[8]; + for (i = 7; i >= 0; i--) { + p = p * x * x + Pone[i]; + q = q * x * x + Qone[i]; + } + return (double)(p / q); } static double KernelBessel_P1(const double x) { - double p, q; - - register long i; - - static const double - Pone[] = - { - 0.352246649133679798341724373e+5, - 0.62758845247161281269005675e+5, - 0.313539631109159574238669888e+5, - 0.49854832060594338434500455e+4, - 0.2111529182853962382105718e+3, - 0.12571716929145341558495e+1 - }, - Qone[] = - { - 0.352246649133679798068390431e+5, - 0.626943469593560511888833731e+5, - 0.312404063819041039923015703e+5, - 0.4930396490181088979386097e+4, - 0.2030775189134759322293574e+3, - 0.1e+1 - }; - - p = Pone[5]; - q = Qone[5]; - for (i=4; i >= 0; i--) - { - p = p*(8.0/x)*(8.0/x)+Pone[i]; - q = q*(8.0/x)*(8.0/x)+Qone[i]; - } - return (double)(p/q); + double p, q; + + register long i; + + static const double Pone[] = {0.352246649133679798341724373e+5, 0.62758845247161281269005675e+5, + 0.313539631109159574238669888e+5, 0.49854832060594338434500455e+4, + 0.2111529182853962382105718e+3, 0.12571716929145341558495e+1}, + Qone[] = { + 0.352246649133679798068390431e+5, 0.626943469593560511888833731e+5, + 0.312404063819041039923015703e+5, 0.4930396490181088979386097e+4, + 0.2030775189134759322293574e+3, 0.1e+1}; + + p = Pone[5]; + q = Qone[5]; + for (i = 4; i >= 0; i--) { + p = p * (8.0 / x) * (8.0 / x) + Pone[i]; + q = q * (8.0 / x) * (8.0 / x) + Qone[i]; + } + return (double)(p / q); } static double KernelBessel_Q1(const double x) { - double p, q; - - register long i; - - static const double - Pone[] = - { - 0.3511751914303552822533318e+3, - 0.7210391804904475039280863e+3, - 0.4259873011654442389886993e+3, - 0.831898957673850827325226e+2, - 0.45681716295512267064405e+1, - 0.3532840052740123642735e-1 - }, - Qone[] = - { - 0.74917374171809127714519505e+4, - 0.154141773392650970499848051e+5, - 0.91522317015169922705904727e+4, - 0.18111867005523513506724158e+4, - 0.1038187585462133728776636e+3, - 0.1e+1 - }; - - p = Pone[5]; - q = Qone[5]; - for (i=4; i >= 0; i--) - { - p = p*(8.0/x)*(8.0/x)+Pone[i]; - q = q*(8.0/x)*(8.0/x)+Qone[i]; - } - return (double)(p/q); + double p, q; + + register long i; + + static const double Pone[] = {0.3511751914303552822533318e+3, 0.7210391804904475039280863e+3, + 0.4259873011654442389886993e+3, 0.831898957673850827325226e+2, + 0.45681716295512267064405e+1, 0.3532840052740123642735e-1}, + Qone[] = {0.74917374171809127714519505e+4, 0.154141773392650970499848051e+5, + 0.91522317015169922705904727e+4, 0.18111867005523513506724158e+4, + 0.1038187585462133728776636e+3, 0.1e+1}; + + p = Pone[5]; + q = Qone[5]; + for (i = 4; i >= 0; i--) { + p = p * (8.0 / x) * (8.0 / x) + Pone[i]; + q = q * (8.0 / x) * (8.0 / x) + Qone[i]; + } + return (double)(p / q); } static double KernelBessel_Order1(double x) { - double p, q; - - if (x == 0.0) - return (0.0f); - p = x; - if (x < 0.0) - x=(-x); - if (x < 8.0) - return (p*KernelBessel_J1(x)); - q = (double)sqrt(2.0f/(M_PI*x))*(double)(KernelBessel_P1(x)*(1.0f/sqrt(2.0f)*(sin(x)-cos(x)))-8.0f/x*KernelBessel_Q1(x)* - (-1.0f/sqrt(2.0f)*(sin(x)+cos(x)))); - if (p < 0.0f) - q = (-q); - return (q); + double p, q; + + if (x == 0.0) + return (0.0f); + p = x; + if (x < 0.0) + x = (-x); + if (x < 8.0) + return (p * KernelBessel_J1(x)); + q = (double)sqrt(2.0f / (M_PI * x)) * + (double)(KernelBessel_P1(x) * (1.0f / sqrt(2.0f) * (sin(x) - cos(x))) - + 8.0f / x * KernelBessel_Q1(x) * (-1.0f / sqrt(2.0f) * (sin(x) + cos(x)))); + if (p < 0.0f) + q = (-q); + return (q); } -static double filter_bessel(const double x) +static double filter_sinc(const double x, const double support) { - if (x == 0.0f) - return (double)(M_PI/4.0f); - return (KernelBessel_Order1((double)M_PI*x)/(2.0f*x)); + ARG_NOT_USED(support); + /* X-scaled Sinc(x) function. */ + if (x == 0.0) + return (1.0); + return (sin(M_PI * (double)x) / (M_PI * (double)x)); } +static double filter_bessel(const double x, const double support) +{ + ARG_NOT_USED(support); + if (x == 0.0f) + return (double)(M_PI / 4.0f); + return (KernelBessel_Order1((double)M_PI * x) / (2.0f * x)); +} -static double filter_blackman(const double x) +static double filter_blackman(const double x, const double support) { - return (0.42f+0.5f*(double)cos(M_PI*x)+0.08f*(double)cos(2.0f*M_PI*x)); + ARG_NOT_USED(support); + return (0.42f + 0.5f * (double)cos(M_PI * x) + 0.08f * (double)cos(2.0f * M_PI * x)); } -double filter_linear(const double x) { - double ax = fabs(x); - if (ax < 1.0f) { - return (1.0f - ax); - } - return 0.0f; +static double filter_linear(const double x, const double support) +{ + ARG_NOT_USED(support); + double ax = fabs(x); + if (ax < 1.0f) { + return (1.0f - ax); + } + return 0.0f; } -/** - * Bicubic interpolation kernel (a=-1): - \verbatim - / - | 1-2|t|**2+|t|**3 , if |t| < 1 - h(t) = | 4-8|t|+5|t|**2-|t|**3 , if 1<=|t|<2 - | 0 , otherwise - \ - \endverbatim - * ***bd*** 2.2004 - */ -static double filter_bicubic(const double t) +static double filter_blackman_bessel(const double x, const double support) { - const double abs_t = (double)fabs(t); - const double abs_t_sq = abs_t * abs_t; - if (abs_t<1) return 1-2*abs_t_sq+abs_t_sq*abs_t; - if (abs_t<2) return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t; - return 0; + ARG_NOT_USED(support); + return (filter_blackman(x / support, support) * filter_bessel(x, support)); +} + +static double filter_blackman_sinc(const double x, const double support) +{ + ARG_NOT_USED(support); + return (filter_blackman(x / support, support) * filter_sinc(x, support)); } /** @@ -360,386 +281,460 @@ static double filter_bicubic(const double t) \endverbatim * Often used values for a are -1 and -1/2. */ -static double filter_generalized_cubic(const double t) -{ - const double a = -DEFAULT_FILTER_GENERALIZED_CUBIC; - double abs_t = (double)fabs(t); - double abs_t_sq = abs_t * abs_t; - if (abs_t < 1) return (a + 2) * abs_t_sq * abs_t - (a + 3) * abs_t_sq + 1; - if (abs_t < 2) return a * abs_t_sq * abs_t - 5 * a * abs_t_sq + 8 * a * abs_t - 4 * a; - return 0; +static double filter_generalized_cubic(const double t, const double support) +{ + const double a = -support; + double abs_t = (double)fabs(t); + double abs_t_sq = abs_t * abs_t; + if (abs_t < 1) + return (a + 2) * abs_t_sq * abs_t - (a + 3) * abs_t_sq + 1; + if (abs_t < 2) + return a * abs_t_sq * abs_t - 5 * a * abs_t_sq + 8 * a * abs_t - 4 * a; + return 0; } -#ifdef FUNCTION_NOT_USED_YET /* CubicSpline filter, default radius 2 */ -static double filter_cubic_spline(const double x1) +static double filter_cubic_spline(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); + const double x = x1 < 0.0 ? -x1 : x1; - if (x < 1.0 ) { - const double x2 = x*x; + if (x < 1.0) { + const double x2 = x * x; - return (0.5 * x2 * x - x2 + 2.0 / 3.0); - } - if (x < 2.0) { - return (pow(2.0 - x, 3.0)/6.0); - } - return 0; + return (0.5 * x2 * x - x2 + 2.0 / 3.0); + } + if (x < 2.0) { + return (pow(2.0 - x, 3.0) / 6.0); + } + return 0; } -#endif #ifdef FUNCTION_NOT_USED_YET /* CubicConvolution filter, default radius 3 */ -static double filter_cubic_convolution(const double x1) +static double filter_cubic_convolution(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; - const double x2 = x1 * x1; - const double x2_x = x2 * x; - - if (x <= 1.0) return ((4.0 / 3.0)* x2_x - (7.0 / 3.0) * x2 + 1.0); - if (x <= 2.0) return (- (7.0 / 12.0) * x2_x + 3 * x2 - (59.0 / 12.0) * x + 2.5); - if (x <= 3.0) return ( (1.0/12.0) * x2_x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5); - return 0; + const double x = x1 < 0.0 ? -x1 : x1; + const double x2 = x1 * x1; + const double x2_x = x2 * x; + ARG_NOT_USED(support); + if (x <= 1.0) + return ((4.0 / 3.0) * x2_x - (7.0 / 3.0) * x2 + 1.0); + if (x <= 2.0) + return (-(7.0 / 12.0) * x2_x + 3 * x2 - (59.0 / 12.0) * x + 2.5); + if (x <= 3.0) + return ((1.0 / 12.0) * x2_x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5); + return 0; } #endif -static double filter_box(double x) { - if (x < - DEFAULT_FILTER_BOX) - return 0.0f; - if (x < DEFAULT_FILTER_BOX) - return 1.0f; - return 0.0f; -} - -static double filter_catmullrom(const double x) -{ - if (x < -2.0) - return(0.0f); - if (x < -1.0) - return(0.5f*(4.0f+x*(8.0f+x*(5.0f+x)))); - if (x < 0.0) - return(0.5f*(2.0f+x*x*(-5.0f-3.0f*x))); - if (x < 1.0) - return(0.5f*(2.0f+x*x*(-5.0f+3.0f*x))); - if (x < 2.0) - return(0.5f*(4.0f+x*(-8.0f+x*(5.0f-x)))); - return(0.0f); +static double filter_box(double x, const double support) +{ + if (x < -support) + return 0.0f; + if (x < support) + return 1.0f; + return 0.0f; } -#ifdef FUNCTION_NOT_USED_YET -static double filter_filter(double t) +static double filter_catmullrom(const double x, const double support) { - /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */ - if(t < 0.0) t = -t; - if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0); - return(0.0); + ARG_NOT_USED(support); + if (x < -2.0) + return (0.0f); + if (x < -1.0) + return (0.5f * (4.0f + x * (8.0f + x * (5.0f + x)))); + if (x < 0.0) + return (0.5f * (2.0f + x * x * (-5.0f - 3.0f * x))); + if (x < 1.0) + return (0.5f * (2.0f + x * x * (-5.0f + 3.0f * x))); + if (x < 2.0) + return (0.5f * (4.0f + x * (-8.0f + x * (5.0f - x)))); + return (0.0f); } -#endif -#ifdef FUNCTION_NOT_USED_YET /* Lanczos8 filter, default radius 8 */ -static double filter_lanczos8(const double x1) +static double filter_lanczos8(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; -#define R DEFAULT_LANCZOS8_RADIUS + const double x = x1 < 0.0 ? -x1 : x1; - if ( x == 0.0) return 1; + if (x == 0.0) + return 1; - if ( x < R) { - return R * sin(x*M_PI) * sin(x * M_PI/ R) / (x * M_PI * x * M_PI); - } - return 0.0; -#undef R + if (x < support) { + return support * sin(x * M_PI) * sin(x * M_PI / support) / (x * M_PI * x * M_PI); + } + return 0.0; } -#endif -#ifdef FUNCTION_NOT_USED_YET -/* Lanczos3 filter, default radius 3 */ -static double filter_lanczos3(const double x1) +static double filter_lanczos3(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; -#define R DEFAULT_LANCZOS3_RADIUS - - if ( x == 0.0) return 1; - - if ( x < R) - { - return R * sin(x*M_PI) * sin(x * M_PI / R) / (x * M_PI * x * M_PI); - } - return 0.0; -#undef R + if (x1 < -3.0) + return (0.0); + if (x1 < 0.0) + return (filter_sinc(-x1, support) * filter_sinc(-x1 / 3.0, support)); + if (x1 < 3.0) + return (filter_sinc(x1, support) * filter_sinc(x1 / 3.0, support)); + return (0.0); } -#endif /* Hermite filter, default radius 1 */ -static double filter_hermite(const double x1) +static double filter_hermite(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; + const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); - if (x < 1.0) return ((2.0 * x - 3) * x * x + 1.0 ); + if (x < 1.0) + return ((2.0 * x - 3) * x * x + 1.0); - return 0.0; + return 0.0; } /* Trangle filter, default radius 1 */ -static double filter_triangle(const double x1) +static double filter_triangle(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; - if (x < 1.0) return (1.0 - x); - return 0.0; + const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); + + if (x < 1.0) + return (1.0 - x); + return 0.0; } /* Bell filter, default radius 1.5 */ -static double filter_bell(const double x1) +static double filter_bell(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; - - if (x < 0.5) return (0.75 - x*x); - if (x < 1.5) return (0.5 * pow(x - 1.5, 2.0)); - return 0.0; + const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); + + if (x < 0.5) + return (0.75 - x * x); + if (x < 1.5) + return (0.5 * pow(x - 1.5, 2.0)); + return 0.0; } /* Mitchell filter, default radius 2.0 */ -static double filter_mitchell(const double x) +static double filter_mitchell(const double x, const double support) { -#define KM_B (1.0f/3.0f) -#define KM_C (1.0f/3.0f) -#define KM_P0 (( 6.0f - 2.0f * KM_B ) / 6.0f) + ARG_NOT_USED(support); +#define KM_B (1.0f / 3.0f) +#define KM_C (1.0f / 3.0f) +#define KM_P0 ((6.0f - 2.0f * KM_B) / 6.0f) #define KM_P2 ((-18.0f + 12.0f * KM_B + 6.0f * KM_C) / 6.0f) -#define KM_P3 (( 12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f) -#define KM_Q0 (( 8.0f * KM_B + 24.0f * KM_C) / 6.0f) +#define KM_P3 ((12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f) +#define KM_Q0 ((8.0f * KM_B + 24.0f * KM_C) / 6.0f) #define KM_Q1 ((-12.0f * KM_B - 48.0f * KM_C) / 6.0f) -#define KM_Q2 (( 6.0f * KM_B + 30.0f * KM_C) / 6.0f) -#define KM_Q3 (( -1.0f * KM_B - 6.0f * KM_C) / 6.0f) - - if (x < -2.0) - return(0.0f); - if (x < -1.0) - return(KM_Q0-x*(KM_Q1-x*(KM_Q2-x*KM_Q3))); - if (x < 0.0f) - return(KM_P0+x*x*(KM_P2-x*KM_P3)); - if (x < 1.0f) - return(KM_P0+x*x*(KM_P2+x*KM_P3)); - if (x < 2.0f) - return(KM_Q0+x*(KM_Q1+x*(KM_Q2+x*KM_Q3))); - return(0.0f); +#define KM_Q2 ((6.0f * KM_B + 30.0f * KM_C) / 6.0f) +#define KM_Q3 ((-1.0f * KM_B - 6.0f * KM_C) / 6.0f) + + if (x < -2.0) + return (0.0f); + if (x < -1.0) + return (KM_Q0 - x * (KM_Q1 - x * (KM_Q2 - x * KM_Q3))); + if (x < 0.0f) + return (KM_P0 + x * x * (KM_P2 - x * KM_P3)); + if (x < 1.0f) + return (KM_P0 + x * x * (KM_P2 + x * KM_P3)); + if (x < 2.0f) + return (KM_Q0 + x * (KM_Q1 + x * (KM_Q2 + x * KM_Q3))); + + return (0.0f); } - - -#ifdef FUNCTION_NOT_USED_YET /* Cosine filter, default radius 1 */ -static double filter_cosine(const double x) +static double filter_cosine(const double x, const double support) { - if ((x >= -1.0) && (x <= 1.0)) return ((cos(x * M_PI) + 1.0)/2.0); + ARG_NOT_USED(support); + if ((x >= -1.0) && (x <= 1.0)) + return ((cos(x * M_PI) + 1.0) / 2.0); - return 0; + return 0; } -#endif /* Quadratic filter, default radius 1.5 */ -static double filter_quadratic(const double x1) +static double filter_quadratic(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; - - if (x <= 0.5) return (- 2.0 * x * x + 1); - if (x <= 1.5) return (x * x - 2.5* x + 1.5); - return 0.0; + const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); + if (x <= 0.5) + return (-2.0 * x * x + 1); + if (x <= 1.5) + return (x * x - 2.5 * x + 1.5); + return 0.0; } -static double filter_bspline(const double x) +static double filter_bspline(const double x, const double support) { - if (x>2.0f) { - return 0.0f; - } else { - double a, b, c, d; - /* Was calculated anyway cause the "if((x-1.0f) < 0)" */ - const double xm1 = x - 1.0f; - const double xp1 = x + 1.0f; - const double xp2 = x + 2.0f; - - if ((xp2) <= 0.0f) a = 0.0f; else a = xp2*xp2*xp2; - if ((xp1) <= 0.0f) b = 0.0f; else b = xp1*xp1*xp1; - if (x <= 0) c = 0.0f; else c = x*x*x; - if ((xm1) <= 0.0f) d = 0.0f; else d = xm1*xm1*xm1; - - return (0.16666666666666666667f * (a - (4.0f * b) + (6.0f * c) - (4.0f * d))); - } + ARG_NOT_USED(support); + if (x > 2.0f) { + return 0.0f; + } else { + double a, b, c, d; + /* Was calculated anyway cause the "if((x-1.0f) < 0)" */ + const double xm1 = x - 1.0f; + const double xp1 = x + 1.0f; + const double xp2 = x + 2.0f; + + if ((xp2) <= 0.0f) + a = 0.0f; + else + a = xp2 * xp2 * xp2; + if ((xp1) <= 0.0f) + b = 0.0f; + else + b = xp1 * xp1 * xp1; + if (x <= 0) + c = 0.0f; + else + c = x * x * x; + if ((xm1) <= 0.0f) + d = 0.0f; + else + d = xm1 * xm1 * xm1; + + return (0.16666666666666666667f * (a - (4.0f * b) + (6.0f * c) - (4.0f * d))); + } } -#ifdef FUNCTION_NOT_USED_YET /* QuadraticBSpline filter, default radius 1.5 */ -static double filter_quadratic_bspline(const double x1) +static double filter_quadratic_bspline(const double x1, const double support) { - const double x = x1 < 0.0 ? -x1 : x1; - - if (x <= 0.5) return (- x * x + 0.75); - if (x <= 1.5) return (0.5 * x * x - 1.5 * x + 1.125); - return 0.0; + const double x = x1 < 0.0 ? -x1 : x1; + ARG_NOT_USED(support); + if (x <= 0.5) + return (-x * x + 0.75); + if (x <= 1.5) + return (0.5 * x * x - 1.5 * x + 1.125); + return 0.0; } -#endif -static double filter_gaussian(const double x) +static double filter_gaussian(const double x, const double support) { - /* return(exp((double) (-2.0 * x * x)) * sqrt(2.0 / M_PI)); */ - return (double)(exp(-2.0f * x * x) * 0.79788456080287f); + ARG_NOT_USED(support); + /* return(exp((double) (-2.0 * x * x)) * sqrt(2.0 / M_PI)); */ + return (double)(exp(-2.0f * x * x) * 0.79788456080287f); } -static double filter_hanning(const double x) +static double filter_hanning(const double x, const double support) { - /* A Cosine windowing function */ - return(0.5 + 0.5 * cos(M_PI * x)); + ARG_NOT_USED(support); + /* A Cosine windowing function */ + return (0.5 + 0.5 * cos(M_PI * x)); } -static double filter_hamming(const double x) -{ - /* should be - (0.54+0.46*cos(M_PI*(double) x)); - but this approximation is sufficient */ - if (x < -1.0f) - return 0.0f; - if (x < 0.0f) - return 0.92f*(-2.0f*x-3.0f)*x*x+1.0f; - if (x < 1.0f) - return 0.92f*(2.0f*x-3.0f)*x*x+1.0f; - return 0.0f; +static double filter_hamming(const double x, const double support) +{ + ARG_NOT_USED(support); + /* should be + (0.54+0.46*cos(M_PI*(double) x)); + but this approximation is sufficient */ + if (x < -1.0f) + return 0.0f; + if (x < 0.0f) + return 0.92f * (-2.0f * x - 3.0f) * x * x + 1.0f; + if (x < 1.0f) + return 0.92f * (2.0f * x - 3.0f) * x * x + 1.0f; + return 0.0f; } -static double filter_power(const double x) +static double filter_power(const double x, const double support) { - const double a = 2.0f; - if (fabs(x)>1) return 0.0f; - return (1.0f - (double)fabs(pow(x,a))); + ARG_NOT_USED(support); + const double a = 2.0f; + if (fabs(x) > 1) + return 0.0f; + return (1.0f - (double)fabs(pow(x, a))); } -static double filter_sinc(const double x) +static double filter_welsh(const double x, const double support) { - /* X-scaled Sinc(x) function. */ - if (x == 0.0) return(1.0); - return (sin(M_PI * (double) x) / (M_PI * (double) x)); + ARG_NOT_USED(support); + /* Welsh parabolic windowing filter */ + if (x < 1.0) + return (1 - x * x); + return (0.0); } +#if defined(_MSC_VER) && !defined(inline) +#define inline __inline +#endif + +/* keep it for future usage for affine copy over an existing image, targetting + * fix for 2.2.2 */ #ifdef FUNCTION_NOT_USED_YET -static double filter_welsh(const double x) +/* Copied from upstream's libgd */ +static inline int _color_blend(const int dst, const int src) { - /* Welsh parabolic windowing filter */ - if (x < 1.0) - return(1 - x*x); - return(0.0); + const int src_alpha = gdTrueColorGetAlpha(src); + + if (src_alpha == gdAlphaOpaque) { + return src; + } else { + const int dst_alpha = gdTrueColorGetAlpha(dst); + + if (src_alpha == gdAlphaTransparent) + return dst; + if (dst_alpha == gdAlphaTransparent) { + return src; + } else { + register int alpha, red, green, blue; + const int src_weight = gdAlphaTransparent - src_alpha; + const int dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax; + const int tot_weight = src_weight + dst_weight; + + alpha = src_alpha * dst_alpha / gdAlphaMax; + + red = (gdTrueColorGetRed(src) * src_weight + gdTrueColorGetRed(dst) * dst_weight) / + tot_weight; + green = + (gdTrueColorGetGreen(src) * src_weight + gdTrueColorGetGreen(dst) * dst_weight) / + tot_weight; + blue = (gdTrueColorGetBlue(src) * src_weight + gdTrueColorGetBlue(dst) * dst_weight) / + tot_weight; + + return ((alpha << 24) + (red << 16) + (green << 8) + blue); + } + } +} + +static inline int _setEdgePixel(const gdImagePtr src, unsigned int x, unsigned int y, + gdFixed coverage, const int bgColor) +{ + const gdFixed f_127 = gd_itofx(127); + register int c = src->tpixels[y][x]; + c = c | (((int)(gd_fxtof(gd_mulfx(coverage, f_127)) + 50.5f)) << 24); + return _color_blend(bgColor, c); } #endif +static inline int getPixelOverflowTC(gdImagePtr im, const int x, const int y, + const int bgColor /* 31bit ARGB TC */) +{ + if (gdImageBoundsSafe(im, x, y)) { + const int c = im->tpixels[y][x]; + if (c == im->transparent) { + return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor; + } + return c; /* 31bit ARGB TC */ + } else { + return bgColor; /* 31bit ARGB TC */ + } +} -/* keep it for future usage for affine copy over an existing image, targetting fix for 2.2.2 */ -#if 0 -/* Copied from upstream's libgd */ -static inline int _color_blend (const int dst, const int src) +static inline int getPixelOverflowTCClipped(gdImagePtr im, const int x, const int y, + const int bgColor, const gdRectPtr clip) { - const int src_alpha = gdTrueColorGetAlpha(src); + if (clip != NULL && + (x < clip->x || y < clip->y || x >= clip->x + clip->width || y >= clip->y + clip->height)) { + return bgColor; + } + return getPixelOverflowTC(im, x, y, bgColor); +} + +#define colorIndex2RGBA(c) \ + gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(c)]) +#define colorIndex2RGBcustomA(c, a) \ + gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(a)]) +static inline int getPixelOverflowPalette(gdImagePtr im, const int x, const int y, + const int bgColor /* 31bit ARGB TC */) +{ + if (gdImageBoundsSafe(im, x, y)) { + const int c = im->pixels[y][x]; + if (c == im->transparent) { + return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor; + } + return colorIndex2RGBA(c); + } else { + return bgColor; /* 31bit ARGB TC */ + } +} - if( src_alpha == gdAlphaOpaque ) { - return src; - } else { - const int dst_alpha = gdTrueColorGetAlpha(dst); - - if( src_alpha == gdAlphaTransparent ) return dst; - if( dst_alpha == gdAlphaTransparent ) { - return src; - } else { - register int alpha, red, green, blue; - const int src_weight = gdAlphaTransparent - src_alpha; - const int dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax; - const int tot_weight = src_weight + dst_weight; - - alpha = src_alpha * dst_alpha / gdAlphaMax; - - red = (gdTrueColorGetRed(src) * src_weight - + gdTrueColorGetRed(dst) * dst_weight) / tot_weight; - green = (gdTrueColorGetGreen(src) * src_weight - + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight; - blue = (gdTrueColorGetBlue(src) * src_weight - + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight; - - return ((alpha << 24) + (red << 16) + (green << 8) + blue); - } - } +static inline int getPixelOverflowPaletteClipped(gdImagePtr im, const int x, const int y, + const int bgColor, const gdRectPtr clip) +{ + if (clip != NULL && + (x < clip->x || y < clip->y || x >= clip->x + clip->width || y >= clip->y + clip->height)) { + return bgColor; + } + return getPixelOverflowPalette(im, x, y, bgColor); } -#endif -static inline int getPixelOverflowTC(gdImagePtr im, const int x, const int y, const int bgColor) -{ - if (gdImageBoundsSafe(im, x, y)) { - const int c = im->tpixels[y][x]; - if (c == im->transparent) { - return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor; - } - return c; - } else { - return bgColor; - } +static inline int gdClampInt(const int value, const int min, const int max) +{ + return value < min ? min : (value > max ? max : value); } -#define colorIndex2RGBA(c) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(c)]) -#define colorIndex2RGBcustomA(c, a) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(a)]) -static inline int getPixelOverflowPalette(gdImagePtr im, const int x, const int y, const int bgColor) -{ - if (gdImageBoundsSafe(im, x, y)) { - const int c = im->pixels[y][x]; - if (c == im->transparent) { - return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor; - } - return colorIndex2RGBA(c); - } else { - return bgColor; - } +static inline interpolation_method gdImageGetEffectiveInterpolation(const gdImagePtr im) +{ + switch (im->interpolation_id) { + case GD_DEFAULT: + case GD_BILINEAR_FIXED: + case GD_LINEAR: + return filter_linear; + + case GD_BICUBIC: + case GD_BICUBIC_FIXED: + return filter_cubic_spline; + + default: + return im->interpolation; + } } -static int getPixelInterpolateWeight(gdImagePtr im, const double x, const double y, const int bgColor) -{ - /* Closest pixel <= (xf,yf) */ - int sx = (int)(x); - int sy = (int)(y); - const double xf = x - (double)sx; - const double yf = y - (double)sy; - const double nxf = (double) 1.0 - xf; - const double nyf = (double) 1.0 - yf; - const double m1 = xf * yf; - const double m2 = nxf * yf; - const double m3 = xf * nyf; - const double m4 = nxf * nyf; - - /* get color values of neighbouring pixels */ - const int c1 = im->trueColor == 1 ? getPixelOverflowTC(im, sx, sy, bgColor) : getPixelOverflowPalette(im, sx, sy, bgColor); - const int c2 = im->trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy, bgColor) : getPixelOverflowPalette(im, sx - 1, sy, bgColor); - const int c3 = im->trueColor == 1 ? getPixelOverflowTC(im, sx, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor); - const int c4 = im->trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor); - int r, g, b, a; - - if (x < 0) sx--; - if (y < 0) sy--; - - /* component-wise summing-up of color values */ - if (im->trueColor) { - r = (int)(m1*gdTrueColorGetRed(c1) + m2*gdTrueColorGetRed(c2) + m3*gdTrueColorGetRed(c3) + m4*gdTrueColorGetRed(c4)); - g = (int)(m1*gdTrueColorGetGreen(c1) + m2*gdTrueColorGetGreen(c2) + m3*gdTrueColorGetGreen(c3) + m4*gdTrueColorGetGreen(c4)); - b = (int)(m1*gdTrueColorGetBlue(c1) + m2*gdTrueColorGetBlue(c2) + m3*gdTrueColorGetBlue(c3) + m4*gdTrueColorGetBlue(c4)); - a = (int)(m1*gdTrueColorGetAlpha(c1) + m2*gdTrueColorGetAlpha(c2) + m3*gdTrueColorGetAlpha(c3) + m4*gdTrueColorGetAlpha(c4)); - } else { - r = (int)(m1*im->red[(c1)] + m2*im->red[(c2)] + m3*im->red[(c3)] + m4*im->red[(c4)]); - g = (int)(m1*im->green[(c1)] + m2*im->green[(c2)] + m3*im->green[(c3)] + m4*im->green[(c4)]); - b = (int)(m1*im->blue[(c1)] + m2*im->blue[(c2)] + m3*im->blue[(c3)] + m4*im->blue[(c4)]); - a = (int)(m1*im->alpha[(c1)] + m2*im->alpha[(c2)] + m3*im->alpha[(c3)] + m4*im->alpha[(c4)]); - } - - r = CLAMP(r, 0, 255); - g = CLAMP(g, 0, 255); - b = CLAMP(b, 0, 255); - a = CLAMP(a, 0, gdAlphaMax); - return gdTrueColorAlpha(r, g, b, a); +static int getPixelInterpolateWeightClipped(gdImagePtr im, const double x, const double y, + const int bgColor, const gdRectPtr clip) +{ + /* Closest pixel <= (xf,yf) */ + int sx = (int)(x); + int sy = (int)(y); + const double xf = x - (double)sx; + const double yf = y - (double)sy; + const double nxf = (double)1.0 - xf; + const double nyf = (double)1.0 - yf; + const double m1 = xf * yf; + const double m2 = nxf * yf; + const double m3 = xf * nyf; + const double m4 = nxf * nyf; + + /* get color values of neighbouring pixels */ + const int c1 = im->trueColor == 1 ? getPixelOverflowTCClipped(im, sx, sy, bgColor, clip) + : getPixelOverflowPaletteClipped(im, sx, sy, bgColor, clip); + const int c2 = im->trueColor == 1 + ? getPixelOverflowTCClipped(im, sx - 1, sy, bgColor, clip) + : getPixelOverflowPaletteClipped(im, sx - 1, sy, bgColor, clip); + const int c3 = im->trueColor == 1 + ? getPixelOverflowTCClipped(im, sx, sy - 1, bgColor, clip) + : getPixelOverflowPaletteClipped(im, sx, sy - 1, bgColor, clip); + const int c4 = im->trueColor == 1 + ? getPixelOverflowTCClipped(im, sx - 1, sy - 1, bgColor, clip) + : getPixelOverflowPaletteClipped(im, sx, sy - 1, bgColor, clip); + int r, g, b, a; + + if (x < 0) + sx--; + if (y < 0) + sy--; + + /* component-wise summing-up of color values */ + r = (int)(m1 * gdTrueColorGetRed(c1) + m2 * gdTrueColorGetRed(c2) + m3 * gdTrueColorGetRed(c3) + + m4 * gdTrueColorGetRed(c4)); + g = (int)(m1 * gdTrueColorGetGreen(c1) + m2 * gdTrueColorGetGreen(c2) + + m3 * gdTrueColorGetGreen(c3) + m4 * gdTrueColorGetGreen(c4)); + b = (int)(m1 * gdTrueColorGetBlue(c1) + m2 * gdTrueColorGetBlue(c2) + + m3 * gdTrueColorGetBlue(c3) + m4 * gdTrueColorGetBlue(c4)); + a = (int)(m1 * gdTrueColorGetAlpha(c1) + m2 * gdTrueColorGetAlpha(c2) + + m3 * gdTrueColorGetAlpha(c3) + m4 * gdTrueColorGetAlpha(c4)); + + r = CLAMP(r, 0, 255); + g = CLAMP(g, 0, 255); + b = CLAMP(b, 0, 255); + a = CLAMP(a, 0, gdAlphaMax); + return gdTrueColorAlpha(r, g, b, a); } /** - * Function: getPixelInterpolated + * InternalFunction: getPixelInterpolated * Returns the interpolated color value using the default interpolation * method. The returned color is always in the ARGB format (truecolor). * @@ -750,873 +745,733 @@ static int getPixelInterpolateWeight(gdImagePtr im, const double x, const double * method - Interpolation method * * Returns: - * GD_TRUE if the affine is rectilinear or GD_FALSE + * the interpolated color or -1 on error * * See also: * */ -int getPixelInterpolated(gdImagePtr im, const double x, const double y, const int bgColor) -{ - const int xi=(int)(x); - const int yi=(int)(y); - int yii; - int i; - double kernel, kernel_cache_y; - double kernel_x[12], kernel_y[4]; - double new_r = 0.0f, new_g = 0.0f, new_b = 0.0f, new_a = 0.0f; - - /* These methods use special implementations */ - if (im->interpolation_id == GD_NEAREST_NEIGHBOUR) { - return -1; - } - - if (im->interpolation_id == GD_WEIGHTED4) { - return getPixelInterpolateWeight(im, x, y, bgColor); - } - - if (im->interpolation_id == GD_NEAREST_NEIGHBOUR) { - if (im->trueColor == 1) { - return getPixelOverflowTC(im, xi, yi, bgColor); - } else { - return getPixelOverflowPalette(im, xi, yi, bgColor); - } - } - if (im->interpolation) { - for (i=0; i<4; i++) { - kernel_x[i] = (double) im->interpolation((double)(xi+i-1-x)); - kernel_y[i] = (double) im->interpolation((double)(yi+i-1-y)); - } - } else { - return -1; - } - - /* - * TODO: use the known fast rgba multiplication implementation once - * the new formats are in place - */ - for (yii = yi-1; yii < yi+3; yii++) { - int xii; - kernel_cache_y = kernel_y[yii-(yi-1)]; - if (im->trueColor) { - for (xii=xi-1; xiiinterpolation_id == GD_NEAREST_NEIGHBOUR) { + const int sx = gdClampInt((int)floor(x + 0.5), 0, gdImageSX(im) - 1); + const int sy = gdClampInt((int)floor(y + 0.5), 0, gdImageSY(im) - 1); + + return im->trueColor == 1 ? getPixelOverflowTCClipped(im, sx, sy, bgColor, clip) + : getPixelOverflowPaletteClipped(im, sx, sy, bgColor, clip); + } + + if (im->interpolation_id == GD_WEIGHTED4) { + return getPixelInterpolateWeightClipped(im, x, y, bgColor, clip); + } -static inline LineContribType * _gdContributionsAlloc(unsigned int line_length, unsigned int windows_size) -{ - unsigned int u = 0; - LineContribType *res; - size_t weights_size; - - if (overflow2(windows_size, sizeof(double))) { - return NULL; - } else { - weights_size = windows_size * sizeof(double); - } - res = (LineContribType *) gdMalloc(sizeof(LineContribType)); - if (!res) { - return NULL; - } - res->WindowSize = windows_size; - res->LineLength = line_length; - if (overflow2(line_length, sizeof(ContributionType))) { - gdFree(res); - return NULL; - } - res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType)); - if (res->ContribRow == NULL) { - gdFree(res); - return NULL; - } - for (u = 0 ; u < line_length ; u++) { - res->ContribRow[u].Weights = (double *) gdMalloc(weights_size); - if (res->ContribRow[u].Weights == NULL) { - unsigned int i; - for (i=0;iContribRow[i].Weights); - } - gdFree(res->ContribRow); - gdFree(res); - return NULL; - } - } - return res; + if (interpolation) { + for (i = 0; i < 4; i++) { + kernel_x[i] = (double)interpolation((double)(xi + i - 1 - x), 1.0); + kernel_y[i] = (double)interpolation((double)(yi + i - 1 - y), 1.0); + } + } else { + return -1; + } + + /* + * TODO: use the known fast rgba multiplication implementation once + * the new formats are in place + */ + for (yii = yi - 1; yii < yi + 3; yii++) { + int xii; + kernel_cache_y = kernel_y[yii - (yi - 1)]; + if (im->trueColor) { + for (xii = xi - 1; xii < xi + 3; xii++) { + const int rgbs = getPixelOverflowTCClipped(im, xii, yii, bgColor, clip); + + kernel = kernel_cache_y * kernel_x[xii - (xi - 1)]; + new_r += kernel * gdTrueColorGetRed(rgbs); + new_g += kernel * gdTrueColorGetGreen(rgbs); + new_b += kernel * gdTrueColorGetBlue(rgbs); + new_a += kernel * gdTrueColorGetAlpha(rgbs); + } + } else { + for (xii = xi - 1; xii < xi + 3; xii++) { + const int rgbs = getPixelOverflowPaletteClipped(im, xii, yii, bgColor, clip); + + kernel = kernel_cache_y * kernel_x[xii - (xi - 1)]; + new_r += kernel * gdTrueColorGetRed(rgbs); + new_g += kernel * gdTrueColorGetGreen(rgbs); + new_b += kernel * gdTrueColorGetBlue(rgbs); + new_a += kernel * gdTrueColorGetAlpha(rgbs); + } + } + } + + new_r = CLAMP(new_r, 0, 255); + new_g = CLAMP(new_g, 0, 255); + new_b = CLAMP(new_b, 0, 255); + new_a = CLAMP(new_a, 0, gdAlphaMax); + + return gdTrueColorAlpha((int)(new_r + 0.5), (int)(new_g + 0.5), (int)(new_b + 0.5), + (int)(new_a + 0.5)); } -static inline void _gdContributionsFree(LineContribType * p) +static int getPixelInterpolated(gdImagePtr im, const double x, const double y, const int bgColor) { - unsigned int u; - for (u = 0; u < p->LineLength; u++) { - gdFree(p->ContribRow[u].Weights); - } - gdFree(p->ContribRow); - gdFree(p); + return getPixelInterpolatedClipped(im, x, y, bgColor, NULL); } -static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const interpolation_method pFilter) -{ - double width_d; - double scale_f_d = 1.0; - const double filter_width_d = DEFAULT_BOX_RADIUS; - int windows_size; - unsigned int u; - LineContribType *res; - - if (scale_d < 1.0) { - width_d = filter_width_d / scale_d; - scale_f_d = scale_d; - } else { - width_d= filter_width_d; - } - - windows_size = 2 * (int)ceil(width_d) + 1; - res = _gdContributionsAlloc(line_size, windows_size); - if (res == NULL) { - return NULL; - } - for (u = 0; u < line_size; u++) { - const double dCenter = (double)u / scale_d; - /* get the significant edge points affecting the pixel */ - register int iLeft = MAX(0, (int)floor (dCenter - width_d)); - int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1); - double dTotalWeight = 0.0; - int iSrc; - - /* Cut edge points to fit in filter window in case of spill-off */ - if (iRight - iLeft + 1 > windows_size) { - if (iLeft < ((int)src_size - 1 / 2)) { - iLeft++; - } else { - iRight--; - } - } - - res->ContribRow[u].Left = iLeft; - res->ContribRow[u].Right = iRight; - - for (iSrc = iLeft; iSrc <= iRight; iSrc++) { - dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc))); - } - - if (dTotalWeight < 0.0) { - _gdContributionsFree(res); - return NULL; - } - - if (dTotalWeight > 0.0) { - for (iSrc = iLeft; iSrc <= iRight; iSrc++) { - res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight; - } - } - } - return res; +static inline LineContribType *_gdContributionsAlloc(unsigned int line_length, + unsigned int windows_size) +{ + unsigned int u = 0; + LineContribType *res; + size_t weights_size; + + if (overflow2(windows_size, sizeof(double))) { + return NULL; + } else { + weights_size = windows_size * sizeof(double); + } + res = (LineContribType *)gdMalloc(sizeof(LineContribType)); + if (!res) { + return NULL; + } + res->WindowSize = windows_size; + res->LineLength = line_length; + if (overflow2(line_length, sizeof(ContributionType))) { + gdFree(res); + return NULL; + } + res->ContribRow = (ContributionType *)gdMalloc(line_length * sizeof(ContributionType)); + if (res->ContribRow == NULL) { + gdFree(res); + return NULL; + } + for (u = 0; u < line_length; u++) { + res->ContribRow[u].Weights = (double *)gdMalloc(weights_size); + if (res->ContribRow[u].Weights == NULL) { + unsigned int i; + + for (i = 0; i < u; i++) { + gdFree(res->ContribRow[i].Weights); + } + gdFree(res->ContribRow); + gdFree(res); + return NULL; + } + } + return res; } -/* Convert a double to an unsigned char, rounding to the nearest - * integer and clamping the result between 0 and max. The absolute - * value of clr must be less than the maximum value of an unsigned - * short. */ -static inline unsigned char -uchar_clamp(double clr, unsigned char max) { - unsigned short result; - - //assert(fabs(clr) <= SHRT_MAX); - - /* Casting a negative float to an unsigned short is undefined. - * However, casting a float to a signed truncates toward zero and - * casting a negative signed value to an unsigned of the same size - * results in a bit-identical value (assuming twos-complement - * arithmetic). This is what we want: all legal negative values - * for clr will be greater than 255. */ - - /* Convert and clamp. */ - result = (unsigned short)(short)(clr + 0.5); - if (result > max) { - result = (clr < 0) ? 0 : max; - }/* if */ - - return result; -}/* uchar_clamp*/ - -static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImagePtr dst, unsigned int dst_width, unsigned int row, LineContribType *contrib) -{ - int *p_src_row = pSrc->tpixels[row]; - int *p_dst_row = dst->tpixels[row]; - unsigned int x; - - for (x = 0; x < dst_width; x++) { - double r = 0, g = 0, b = 0, a = 0; - const int left = contrib->ContribRow[x].Left; - const int right = contrib->ContribRow[x].Right; - int i; - - /* Accumulate each channel */ - for (i = left; i <= right; i++) { - const int left_channel = i - left; - r += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetRed(p_src_row[i])); - g += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetGreen(p_src_row[i])); - b += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetBlue(p_src_row[i])); - a += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetAlpha(p_src_row[i])); - } - p_dst_row[x] = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF), - uchar_clamp(b, 0xFF), - uchar_clamp(a, 0x7F)); /* alpha is 0..127 */ +static inline void _gdContributionsFree(LineContribType *p) +{ + unsigned int u; + for (u = 0; u < p->LineLength; u++) { + gdFree(p->ContribRow[u].Weights); } + gdFree(p->ContribRow); + gdFree(p); } -static inline int _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height) -{ - unsigned int u; - LineContribType * contrib; - - /* same width, just copy it */ - if (dst_width == src_width) { - unsigned int y; - for (y = 0; y < src_height - 1; ++y) { - memcpy(pDst->tpixels[y], pSrc->tpixels[y], src_width); - } - } - - contrib = _gdContributionsCalc(dst_width, src_width, (double)dst_width / (double)src_width, pSrc->interpolation); - if (contrib == NULL) { - return 0; - } - /* Scale each row */ - for (u = 0; u < dst_height; u++) { - _gdScaleRow(pSrc, src_width, pDst, dst_width, u, contrib); - } - _gdContributionsFree (contrib); - return 1; -} +static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, + double scale_d, const double support, + const interpolation_method pFilter) +{ + double width_d; + double scale_f_d = 1.0; + const double filter_width_d = support; + int windows_size; + unsigned int u; + LineContribType *res; + + if (scale_d < 1.0) { + width_d = filter_width_d / scale_d; + scale_f_d = scale_d; + } else { + width_d = filter_width_d; + } -static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImagePtr pRes, unsigned int dst_width, unsigned int dst_height, unsigned int uCol, LineContribType *contrib) -{ - unsigned int y; - for (y = 0; y < dst_height; y++) { - double r = 0, g = 0, b = 0, a = 0; - const int iLeft = contrib->ContribRow[y].Left; - const int iRight = contrib->ContribRow[y].Right; - int i; - - /* Accumulate each channel */ - for (i = iLeft; i <= iRight; i++) { - const int pCurSrc = pSrc->tpixels[i][uCol]; - const int i_iLeft = i - iLeft; - r += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetRed(pCurSrc)); - g += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetGreen(pCurSrc)); - b += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetBlue(pCurSrc)); - a += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetAlpha(pCurSrc)); - } - pRes->tpixels[y][uCol] = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF), - uchar_clamp(b, 0xFF), - uchar_clamp(a, 0x7F)); /* alpha is 0..127 */ - } + windows_size = 2 * (int)ceil(width_d) + 1; + res = _gdContributionsAlloc(line_size, windows_size); + if (res == NULL) { + return NULL; + } + for (u = 0; u < line_size; u++) { + const double dCenter = (double)u / scale_d; + /* get the significant edge points affecting the pixel */ + register int iLeft = MAX(0, (int)floor(dCenter - width_d)); + int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1); + double dTotalWeight = 0.0; + int iSrc; + + /* Cut edge points to fit in filter window in case of spill-off */ + if (iRight - iLeft + 1 > windows_size) { + if (iLeft < ((int)src_size - 1 / 2)) { + iLeft++; + } else { + iRight--; + } + } + + res->ContribRow[u].Left = iLeft; + res->ContribRow[u].Right = iRight; + + for (iSrc = iLeft; iSrc <= iRight; iSrc++) { + dTotalWeight += + (res->ContribRow[u].Weights[iSrc - iLeft] = + scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc), support)); + } + + if (dTotalWeight < 0.0) { + _gdContributionsFree(res); + return NULL; + } + + if (dTotalWeight > 0.0) { + for (iSrc = iLeft; iSrc <= iRight; iSrc++) { + res->ContribRow[u].Weights[iSrc - iLeft] /= dTotalWeight; + } + } + } + return res; } -static inline int _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_width, const unsigned int src_height, const gdImagePtr pDst, const unsigned int dst_width, const unsigned int dst_height) -{ - unsigned int u; - LineContribType * contrib; - - /* same height, copy it */ - if (src_height == dst_height) { - unsigned int y; - for (y = 0; y < src_height - 1; ++y) { - memcpy(pDst->tpixels[y], pSrc->tpixels[y], src_width); - } - } - - contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation); - if (contrib == NULL) { - return 0; - } - /* scale each column */ - for (u = 0; u < dst_width; u++) { - _gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib); - } - _gdContributionsFree(contrib); - return 1; -} +static inline void _gdScaleOneAxis(gdImagePtr pSrc, gdImagePtr dst, unsigned int dst_len, + unsigned int row, LineContribType *contrib, gdAxis axis) +{ + unsigned int ndx; + + for (ndx = 0; ndx < dst_len; ndx++) { + double r = 0, g = 0, b = 0, a = 0; + const int left = contrib->ContribRow[ndx].Left; + const int right = contrib->ContribRow[ndx].Right; + int *dest = (axis == HORIZONTAL) ? &dst->tpixels[row][ndx] : &dst->tpixels[ndx][row]; + + int i; + + /* Accumulate each channel */ + for (i = left; i <= right; i++) { + const int left_channel = i - left; + const int srcpx = (axis == HORIZONTAL) ? pSrc->tpixels[row][i] : pSrc->tpixels[i][row]; + + r += + contrib->ContribRow[ndx].Weights[left_channel] * (double)(gdTrueColorGetRed(srcpx)); + g += contrib->ContribRow[ndx].Weights[left_channel] * + (double)(gdTrueColorGetGreen(srcpx)); + b += contrib->ContribRow[ndx].Weights[left_channel] * + (double)(gdTrueColorGetBlue(srcpx)); + a += contrib->ContribRow[ndx].Weights[left_channel] * + (double)(gdTrueColorGetAlpha(srcpx)); + } /* for */ + + *dest = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF), uchar_clamp(b, 0xFF), + uchar_clamp(a, 0x7F)); /* alpha is 0..127 */ + } /* for */ +} /* _gdScaleOneAxis*/ + +static inline int _gdScalePass(const gdImagePtr pSrc, const unsigned int src_len, + const gdImagePtr pDst, const unsigned int dst_len, + const unsigned int num_lines, const gdAxis axis, + const FilterInfo *filter) +{ + unsigned int line_ndx; + LineContribType *contrib; + + /* Same dim, just copy it. */ + assert(dst_len != src_len); // TODO: caller should handle this. + + contrib = _gdContributionsCalc(dst_len, src_len, (double)dst_len / (double)src_len, + filter->support, filter->function); + if (contrib == NULL) { + return 0; + } + + /* Scale each line */ + for (line_ndx = 0; line_ndx < num_lines; line_ndx++) { + _gdScaleOneAxis(pSrc, pDst, dst_len, line_ndx, contrib, axis); + } + _gdContributionsFree(contrib); + return 1; +} /* _gdScalePass*/ + +static const FilterInfo filters[GD_METHOD_COUNT + 1] = { + {filter_box, 0.0}, + {filter_bell, 1.5}, + {filter_bessel, 0.0}, + {NULL, 0.0}, /* NA bilenear/bilinear fixed */ + {NULL, 0.0}, /* NA bicubic */ + {NULL, 0.0}, /* NA bicubic fixed */ + {filter_blackman, 1.0}, + {filter_box, 0.5}, + {filter_bspline, 1.5}, + {filter_catmullrom, 2.0}, + {filter_gaussian, 1.25}, + {filter_generalized_cubic, 0.5}, + {filter_hermite, 1.0}, + {filter_hamming, 1.0}, + {filter_hanning, 1.0}, + {filter_mitchell, 2.0}, + {NULL, 0.0}, /* NA Nearest */ + {filter_power, 0.0}, + {filter_quadratic, 1.5}, + {filter_sinc, 1.0}, + {filter_triangle, 1.0}, + {NULL, 1.0}, /* NA weighted4 */ + {filter_linear, 1.0}, + {filter_lanczos3, 3.0}, + {filter_lanczos8, 8.0}, + {filter_blackman_bessel, 3.2383}, + {filter_blackman_sinc, 4.0}, + {filter_quadratic_bspline, 1.5}, + {filter_cubic_spline, 0.0}, + {filter_cosine, 0.0}, + {filter_welsh, 0.0}, +}; -static gdImagePtr -gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const unsigned int new_width, const unsigned int new_height) -{ - gdImagePtr tmp_im; - gdImagePtr dst; - int scale_pass_res; - - /* Convert to truecolor if it isn't; this code requires it. */ - if (!src->trueColor) { - gdImagePaletteToTrueColor(src); - } - - tmp_im = gdImageCreateTrueColor(new_width, src_height); - if (tmp_im == NULL) { - return NULL; - } - gdImageSetInterpolationMethod(tmp_im, src->interpolation_id); - scale_pass_res = _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height); - if (scale_pass_res != 1) { - gdImageDestroy(tmp_im); - return NULL; - } - - dst = gdImageCreateTrueColor(new_width, new_height); - if (dst == NULL) { - gdImageDestroy(tmp_im); - return NULL; - } - gdImageSetInterpolationMethod(dst, src->interpolation_id); - scale_pass_res = _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height); - if (scale_pass_res != 1) { - gdImageDestroy(dst); - gdImageDestroy(tmp_im); - return NULL; - } - gdImageDestroy(tmp_im); - - return dst; +static const FilterInfo *_get_filterinfo_for_id(gdInterpolationMethod id) +{ + + if (id >= GD_METHOD_COUNT) { + id = GD_DEFAULT; + } + return &filters[id]; } +static gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int new_width, + const unsigned int new_height) +{ + const unsigned int src_width = src->sx; + const unsigned int src_height = src->sy; + gdImagePtr tmp_im = NULL; + gdImagePtr dst = NULL; + int scale_pass_res; + const FilterInfo *filter = _get_filterinfo_for_id(src->interpolation_id); + + /* First, handle the trivial case. */ + if (src_width == new_width && src_height == new_height) { + return gdImageClone(src); + } + + /* Convert to truecolor if it isn't; this code requires it. */ + if (!src->trueColor) { + gdImagePaletteToTrueColor(src); + } + + /* Scale horizontally unless sizes are the same. */ + if (src_width == new_width) { + tmp_im = src; + } else { + tmp_im = gdImageCreateTrueColor(new_width, src_height); + if (tmp_im == NULL) { + return NULL; + } + gdImageSetInterpolationMethod(tmp_im, src->interpolation_id); + + scale_pass_res = + _gdScalePass(src, src_width, tmp_im, new_width, src_height, HORIZONTAL, filter); + if (scale_pass_res != 1) { + gdImageDestroy(tmp_im); + return NULL; + } + } + + /* If vertical sizes match, we're done. */ + if (src_height == new_height) { + assert(tmp_im != src); + return tmp_im; + } + + /* Otherwise, we need to scale vertically. */ + dst = gdImageCreateTrueColor(new_width, new_height); + if (dst != NULL) { + gdImageSetInterpolationMethod(dst, src->interpolation_id); + scale_pass_res = + _gdScalePass(tmp_im, src_height, dst, new_height, new_width, VERTICAL, filter); + if (scale_pass_res != 1) { + gdImageDestroy(dst); + if (src != tmp_im) { + gdImageDestroy(tmp_im); + } + return NULL; + } + } + + if (src != tmp_im) { + gdImageDestroy(tmp_im); + } + + return dst; +} /* gdImageScaleTwoPass*/ + /* - BilinearFixed, BicubicFixed and nearest implementations are rewamped versions of the implementation in CBitmapEx - http://www.codeproject.com/Articles/29121/CBitmapEx-Free-C-Bitmap-Manipulation-Class - Integer only implementation, good to have for common usages like pre scale very large - images before using another interpolation methods for the last step. + Bilinear, bicubic and nearest implementations are + rewamped versions of the implementation in CBitmapEx + + http://www.codeproject.com/Articles/29121/CBitmapEx-Free-C-Bitmap-Manipulation-Class + + The GD_BILINEAR_FIXED and GD_BICUBIC_FIXED public names are kept for + compatibility, but these implementations use floating point arithmetic. */ -static gdImagePtr -gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, const unsigned int height) -{ - const unsigned long new_width = MAX(1, width); - const unsigned long new_height = MAX(1, height); - const float dx = (float)im->sx / (float)new_width; - const float dy = (float)im->sy / (float)new_height; - const gdFixed f_dx = gd_ftofx(dx); - const gdFixed f_dy = gd_ftofx(dy); - - gdImagePtr dst_img; - unsigned long dst_offset_x; - unsigned long dst_offset_y = 0; - unsigned int i; - - dst_img = gdImageCreateTrueColor(new_width, new_height); - - if (dst_img == NULL) { - return NULL; - } - - for (i=0; itrueColor) { - for (j=0; jtpixels[dst_offset_y][dst_offset_x++] = im->tpixels[m][n]; - } - } else { - for (j=0; jtpixels[dst_offset_y][dst_offset_x++] = colorIndex2RGBA(im->pixels[m][n]); - } - } - dst_offset_y++; - } - return dst_img; +static gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, + const unsigned int height) +{ + const unsigned long new_width = MAX(1, width); + const unsigned long new_height = MAX(1, height); + const double dx = (double)im->sx / (double)new_width; + const double dy = (double)im->sy / (double)new_height; + + gdImagePtr dst_img; + unsigned long dst_offset_x; + unsigned long dst_offset_y = 0; + unsigned int i; + + dst_img = gdImageCreateTrueColor(new_width, new_height); + + if (dst_img == NULL) { + return NULL; + } + + for (i = 0; i < new_height; i++) { + unsigned int j; + dst_offset_x = 0; + if (im->trueColor) { + for (j = 0; j < new_width; j++) { + const long m = gdClampInt((int)((double)i * dy), 0, gdImageSY(im) - 1); + const long n = gdClampInt((int)((double)j * dx), 0, gdImageSX(im) - 1); + + dst_img->tpixels[dst_offset_y][dst_offset_x++] = im->tpixels[m][n]; + } + } else { + for (j = 0; j < new_width; j++) { + const long m = gdClampInt((int)((double)i * dy), 0, gdImageSY(im) - 1); + const long n = gdClampInt((int)((double)j * dx), 0, gdImageSX(im) - 1); + + dst_img->tpixels[dst_offset_y][dst_offset_x++] = colorIndex2RGBA(im->pixels[m][n]); + } + } + dst_offset_y++; + } + return dst_img; } -static gdImagePtr gdImageScaleBilinearPalette(gdImagePtr im, const unsigned int new_width, const unsigned int new_height) -{ - long _width = MAX(1, new_width); - long _height = MAX(1, new_height); - float dx = (float)gdImageSX(im) / (float)_width; - float dy = (float)gdImageSY(im) / (float)_height; - gdFixed f_dx = gd_ftofx(dx); - gdFixed f_dy = gd_ftofx(dy); - gdFixed f_1 = gd_itofx(1); - - int dst_offset_h; - int dst_offset_v = 0; - long i; - gdImagePtr new_img; - const int transparent = im->transparent; - - new_img = gdImageCreateTrueColor(new_width, new_height); - if (new_img == NULL) { - return NULL; - } - - if (transparent < 0) { - /* uninitialized */ - new_img->transparent = -1; - } else { - new_img->transparent = gdTrueColorAlpha(im->red[transparent], im->green[transparent], im->blue[transparent], im->alpha[transparent]); - } - - for (i=0; i < _height; i++) { - long j; - const gdFixed f_i = gd_itofx(i); - const gdFixed f_a = gd_mulfx(f_i, f_dy); - register long m = gd_fxtoi(f_a); - - dst_offset_h = 0; - - for (j=0; j < _width; j++) { - /* Update bitmap */ - gdFixed f_j = gd_itofx(j); - gdFixed f_b = gd_mulfx(f_j, f_dx); - - const long n = gd_fxtoi(f_b); - gdFixed f_f = f_a - gd_itofx(m); - gdFixed f_g = f_b - gd_itofx(n); - - const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g); - const gdFixed f_w2 = gd_mulfx(f_1-f_f, f_g); - const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g); - const gdFixed f_w4 = gd_mulfx(f_f, f_g); - unsigned int pixel1; - unsigned int pixel2; - unsigned int pixel3; - unsigned int pixel4; - register gdFixed f_r1, f_r2, f_r3, f_r4, - f_g1, f_g2, f_g3, f_g4, - f_b1, f_b2, f_b3, f_b4, - f_a1, f_a2, f_a3, f_a4; - - /* 0 for bgColor; (n,m) is supposed to be valid anyway */ - pixel1 = getPixelOverflowPalette(im, n, m, 0); - pixel2 = getPixelOverflowPalette(im, n + 1, m, pixel1); - pixel3 = getPixelOverflowPalette(im, n, m + 1, pixel1); - pixel4 = getPixelOverflowPalette(im, n + 1, m + 1, pixel1); - - f_r1 = gd_itofx(gdTrueColorGetRed(pixel1)); - f_r2 = gd_itofx(gdTrueColorGetRed(pixel2)); - f_r3 = gd_itofx(gdTrueColorGetRed(pixel3)); - f_r4 = gd_itofx(gdTrueColorGetRed(pixel4)); - f_g1 = gd_itofx(gdTrueColorGetGreen(pixel1)); - f_g2 = gd_itofx(gdTrueColorGetGreen(pixel2)); - f_g3 = gd_itofx(gdTrueColorGetGreen(pixel3)); - f_g4 = gd_itofx(gdTrueColorGetGreen(pixel4)); - f_b1 = gd_itofx(gdTrueColorGetBlue(pixel1)); - f_b2 = gd_itofx(gdTrueColorGetBlue(pixel2)); - f_b3 = gd_itofx(gdTrueColorGetBlue(pixel3)); - f_b4 = gd_itofx(gdTrueColorGetBlue(pixel4)); - f_a1 = gd_itofx(gdTrueColorGetAlpha(pixel1)); - f_a2 = gd_itofx(gdTrueColorGetAlpha(pixel2)); - f_a3 = gd_itofx(gdTrueColorGetAlpha(pixel3)); - f_a4 = gd_itofx(gdTrueColorGetAlpha(pixel4)); - - { - const unsigned char red = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_r1) + gd_mulfx(f_w2, f_r2) + gd_mulfx(f_w3, f_r3) + gd_mulfx(f_w4, f_r4)); - const unsigned char green = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_g1) + gd_mulfx(f_w2, f_g2) + gd_mulfx(f_w3, f_g3) + gd_mulfx(f_w4, f_g4)); - const unsigned char blue = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_b1) + gd_mulfx(f_w2, f_b2) + gd_mulfx(f_w3, f_b3) + gd_mulfx(f_w4, f_b4)); - const unsigned char alpha = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_a1) + gd_mulfx(f_w2, f_a2) + gd_mulfx(f_w3, f_a3) + gd_mulfx(f_w4, f_a4)); - - new_img->tpixels[dst_offset_v][dst_offset_h] = gdTrueColorAlpha(red, green, blue, alpha); - } - - dst_offset_h++; - } - - dst_offset_v++; - } - return new_img; +static gdImagePtr gdImageScaleBilinearPalette(gdImagePtr im, const unsigned int new_width, + const unsigned int new_height) +{ + long _width = MAX(1, new_width); + long _height = MAX(1, new_height); + double dx = (double)gdImageSX(im) / (double)_width; + double dy = (double)gdImageSY(im) / (double)_height; + + int dst_offset_h; + int dst_offset_v = 0; + long i; + gdImagePtr new_img; + const int transparent = im->transparent; + + new_img = gdImageCreateTrueColor(new_width, new_height); + if (new_img == NULL) { + return NULL; + } + + if (transparent < 0) { + /* uninitialized */ + new_img->transparent = -1; + } else { + new_img->transparent = gdTrueColorAlpha(im->red[transparent], im->green[transparent], + im->blue[transparent], im->alpha[transparent]); + } + + for (i = 0; i < _height; i++) { + long j; + const double src_y = (double)i * dy; + register long m = gdClampInt((int)src_y, 0, gdImageSY(im) - 1); + + dst_offset_h = 0; + + for (j = 0; j < _width; j++) { + /* Update bitmap */ + const double src_x = (double)j * dx; + const long n = gdClampInt((int)src_x, 0, gdImageSX(im) - 1); + const double f_f = src_y - (double)m; + const double f_g = src_x - (double)n; + + const double f_w1 = (1.0 - f_f) * (1.0 - f_g); + const double f_w2 = (1.0 - f_f) * f_g; + const double f_w3 = f_f * (1.0 - f_g); + const double f_w4 = f_f * f_g; + unsigned int pixel1; + unsigned int pixel2; + unsigned int pixel3; + unsigned int pixel4; + + /* 0 for bgColor; (n,m) is supposed to be valid anyway */ + pixel1 = getPixelOverflowPalette(im, n, m, 0); + pixel2 = getPixelOverflowPalette(im, n + 1, m, pixel1); + pixel3 = getPixelOverflowPalette(im, n, m + 1, pixel1); + pixel4 = getPixelOverflowPalette(im, n + 1, m + 1, pixel1); + + { + const unsigned char red = uchar_clamp( + f_w1 * gdTrueColorGetRed(pixel1) + f_w2 * gdTrueColorGetRed(pixel2) + + f_w3 * gdTrueColorGetRed(pixel3) + f_w4 * gdTrueColorGetRed(pixel4), + 0xFF); + const unsigned char green = uchar_clamp( + f_w1 * gdTrueColorGetGreen(pixel1) + f_w2 * gdTrueColorGetGreen(pixel2) + + f_w3 * gdTrueColorGetGreen(pixel3) + f_w4 * gdTrueColorGetGreen(pixel4), + 0xFF); + const unsigned char blue = uchar_clamp( + f_w1 * gdTrueColorGetBlue(pixel1) + f_w2 * gdTrueColorGetBlue(pixel2) + + f_w3 * gdTrueColorGetBlue(pixel3) + f_w4 * gdTrueColorGetBlue(pixel4), + 0xFF); + const unsigned char alpha = uchar_clamp( + f_w1 * gdTrueColorGetAlpha(pixel1) + f_w2 * gdTrueColorGetAlpha(pixel2) + + f_w3 * gdTrueColorGetAlpha(pixel3) + f_w4 * gdTrueColorGetAlpha(pixel4), + 0x7F); + + new_img->tpixels[dst_offset_v][dst_offset_h] = + gdTrueColorAlpha(red, green, blue, alpha); + } + + dst_offset_h++; + } + + dst_offset_v++; + } + return new_img; } -static gdImagePtr gdImageScaleBilinearTC(gdImagePtr im, const unsigned int new_width, const unsigned int new_height) -{ - long dst_w = MAX(1, new_width); - long dst_h = MAX(1, new_height); - float dx = (float)gdImageSX(im) / (float)dst_w; - float dy = (float)gdImageSY(im) / (float)dst_h; - gdFixed f_dx = gd_ftofx(dx); - gdFixed f_dy = gd_ftofx(dy); - gdFixed f_1 = gd_itofx(1); - - int dst_offset_h; - int dst_offset_v = 0; - long i; - gdImagePtr new_img; - - new_img = gdImageCreateTrueColor(new_width, new_height); - if (!new_img){ - return NULL; - } - - for (i=0; i < dst_h; i++) { - long j; - dst_offset_h = 0; - for (j=0; j < dst_w; j++) { - /* Update bitmap */ - gdFixed f_i = gd_itofx(i); - gdFixed f_j = gd_itofx(j); - gdFixed f_a = gd_mulfx(f_i, f_dy); - gdFixed f_b = gd_mulfx(f_j, f_dx); - const long m = gd_fxtoi(f_a); - const long n = gd_fxtoi(f_b); - gdFixed f_f = f_a - gd_itofx(m); - gdFixed f_g = f_b - gd_itofx(n); - - const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g); - const gdFixed f_w2 = gd_mulfx(f_1-f_f, f_g); - const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g); - const gdFixed f_w4 = gd_mulfx(f_f, f_g); - unsigned int pixel1; - unsigned int pixel2; - unsigned int pixel3; - unsigned int pixel4; - register gdFixed f_r1, f_r2, f_r3, f_r4, - f_g1, f_g2, f_g3, f_g4, - f_b1, f_b2, f_b3, f_b4, - f_a1, f_a2, f_a3, f_a4; - /* 0 for bgColor; (n,m) is supposed to be valid anyway */ - pixel1 = getPixelOverflowTC(im, n, m, 0); - pixel2 = getPixelOverflowTC(im, n + 1, m, pixel1); - pixel3 = getPixelOverflowTC(im, n, m + 1, pixel1); - pixel4 = getPixelOverflowTC(im, n + 1, m + 1, pixel1); - - f_r1 = gd_itofx(gdTrueColorGetRed(pixel1)); - f_r2 = gd_itofx(gdTrueColorGetRed(pixel2)); - f_r3 = gd_itofx(gdTrueColorGetRed(pixel3)); - f_r4 = gd_itofx(gdTrueColorGetRed(pixel4)); - f_g1 = gd_itofx(gdTrueColorGetGreen(pixel1)); - f_g2 = gd_itofx(gdTrueColorGetGreen(pixel2)); - f_g3 = gd_itofx(gdTrueColorGetGreen(pixel3)); - f_g4 = gd_itofx(gdTrueColorGetGreen(pixel4)); - f_b1 = gd_itofx(gdTrueColorGetBlue(pixel1)); - f_b2 = gd_itofx(gdTrueColorGetBlue(pixel2)); - f_b3 = gd_itofx(gdTrueColorGetBlue(pixel3)); - f_b4 = gd_itofx(gdTrueColorGetBlue(pixel4)); - f_a1 = gd_itofx(gdTrueColorGetAlpha(pixel1)); - f_a2 = gd_itofx(gdTrueColorGetAlpha(pixel2)); - f_a3 = gd_itofx(gdTrueColorGetAlpha(pixel3)); - f_a4 = gd_itofx(gdTrueColorGetAlpha(pixel4)); - { - const unsigned char red = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_r1) + gd_mulfx(f_w2, f_r2) + gd_mulfx(f_w3, f_r3) + gd_mulfx(f_w4, f_r4)); - const unsigned char green = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_g1) + gd_mulfx(f_w2, f_g2) + gd_mulfx(f_w3, f_g3) + gd_mulfx(f_w4, f_g4)); - const unsigned char blue = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_b1) + gd_mulfx(f_w2, f_b2) + gd_mulfx(f_w3, f_b3) + gd_mulfx(f_w4, f_b4)); - const unsigned char alpha = (unsigned char) gd_fxtoi(gd_mulfx(f_w1, f_a1) + gd_mulfx(f_w2, f_a2) + gd_mulfx(f_w3, f_a3) + gd_mulfx(f_w4, f_a4)); - - new_img->tpixels[dst_offset_v][dst_offset_h] = gdTrueColorAlpha(red, green, blue, alpha); - } - - dst_offset_h++; - } - - dst_offset_v++; - } - return new_img; +static gdImagePtr gdImageScaleBilinearTC(gdImagePtr im, const unsigned int new_width, + const unsigned int new_height) +{ + long dst_w = MAX(1, new_width); + long dst_h = MAX(1, new_height); + double dx = (double)gdImageSX(im) / (double)dst_w; + double dy = (double)gdImageSY(im) / (double)dst_h; + + int dst_offset_h; + int dst_offset_v = 0; + long i; + gdImagePtr new_img; + + new_img = gdImageCreateTrueColor(new_width, new_height); + if (!new_img) { + return NULL; + } + + for (i = 0; i < dst_h; i++) { + long j; + dst_offset_h = 0; + for (j = 0; j < dst_w; j++) { + /* Update bitmap */ + const double src_y = (double)i * dy; + const double src_x = (double)j * dx; + const long m = gdClampInt((int)src_y, 0, gdImageSY(im) - 1); + const long n = gdClampInt((int)src_x, 0, gdImageSX(im) - 1); + const double f_f = src_y - (double)m; + const double f_g = src_x - (double)n; + + const double f_w1 = (1.0 - f_f) * (1.0 - f_g); + const double f_w2 = (1.0 - f_f) * f_g; + const double f_w3 = f_f * (1.0 - f_g); + const double f_w4 = f_f * f_g; + unsigned int pixel1; + unsigned int pixel2; + unsigned int pixel3; + unsigned int pixel4; + /* 0 for bgColor; (n,m) is supposed to be valid anyway */ + pixel1 = getPixelOverflowTC(im, n, m, 0); + pixel2 = getPixelOverflowTC(im, n + 1, m, pixel1); + pixel3 = getPixelOverflowTC(im, n, m + 1, pixel1); + pixel4 = getPixelOverflowTC(im, n + 1, m + 1, pixel1); + + { + const unsigned char red = uchar_clamp( + f_w1 * gdTrueColorGetRed(pixel1) + f_w2 * gdTrueColorGetRed(pixel2) + + f_w3 * gdTrueColorGetRed(pixel3) + f_w4 * gdTrueColorGetRed(pixel4), + 0xFF); + const unsigned char green = uchar_clamp( + f_w1 * gdTrueColorGetGreen(pixel1) + f_w2 * gdTrueColorGetGreen(pixel2) + + f_w3 * gdTrueColorGetGreen(pixel3) + f_w4 * gdTrueColorGetGreen(pixel4), + 0xFF); + const unsigned char blue = uchar_clamp( + f_w1 * gdTrueColorGetBlue(pixel1) + f_w2 * gdTrueColorGetBlue(pixel2) + + f_w3 * gdTrueColorGetBlue(pixel3) + f_w4 * gdTrueColorGetBlue(pixel4), + 0xFF); + const unsigned char alpha = uchar_clamp( + f_w1 * gdTrueColorGetAlpha(pixel1) + f_w2 * gdTrueColorGetAlpha(pixel2) + + f_w3 * gdTrueColorGetAlpha(pixel3) + f_w4 * gdTrueColorGetAlpha(pixel4), + 0x7F); + + new_img->tpixels[dst_offset_v][dst_offset_h] = + gdTrueColorAlpha(red, green, blue, alpha); + } + + dst_offset_h++; + } + + dst_offset_v++; + } + return new_img; } -static gdImagePtr -gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, const unsigned int new_height) +static gdImagePtr gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, + const unsigned int new_height) { - if (im->trueColor) { - return gdImageScaleBilinearTC(im, new_width, new_height); - } else { - return gdImageScaleBilinearPalette(im, new_width, new_height); - } + if (im->trueColor) { + return gdImageScaleBilinearTC(im, new_width, new_height); + } else { + return gdImageScaleBilinearPalette(im, new_width, new_height); + } } -static gdImagePtr -gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, const unsigned int height) -{ - const long new_width = MAX(1, width); - const long new_height = MAX(1, height); - const int src_w = gdImageSX(src); - const int src_h = gdImageSY(src); - const gdFixed f_dx = gd_ftofx((float)src_w / (float)new_width); - const gdFixed f_dy = gd_ftofx((float)src_h / (float)new_height); - const gdFixed f_1 = gd_itofx(1); - const gdFixed f_2 = gd_itofx(2); - const gdFixed f_4 = gd_itofx(4); - const gdFixed f_6 = gd_itofx(6); - const gdFixed f_gamma = gd_ftofx(1.04f); - gdImagePtr dst; - - unsigned int dst_offset_x; - unsigned int dst_offset_y = 0; - long i; - - /* impact perf a bit, but not that much. Implementation for palette - images can be done at a later point. - */ - if (src->trueColor == 0) { - gdImagePaletteToTrueColor(src); - } - - dst = gdImageCreateTrueColor(new_width, new_height); - if (!dst) { - return NULL; - } - - dst->saveAlphaFlag = 1; - - for (i=0; i < new_height; i++) { - long j; - dst_offset_x = 0; - - for (j=0; j < new_width; j++) { - const gdFixed f_a = gd_mulfx(gd_itofx(i), f_dy); - const gdFixed f_b = gd_mulfx(gd_itofx(j), f_dx); - const long m = gd_fxtoi(f_a); - const long n = gd_fxtoi(f_b); - const gdFixed f_f = f_a - gd_itofx(m); - const gdFixed f_g = f_b - gd_itofx(n); - unsigned int src_offset_x[16], src_offset_y[16]; - long k; - register gdFixed f_red = 0, f_green = 0, f_blue = 0, f_alpha = 0; - unsigned char red, green, blue, alpha = 0; - int *dst_row = dst->tpixels[dst_offset_y]; - - if ((m < 1) || (n < 1)) { - src_offset_x[0] = n; - src_offset_y[0] = m; - } else { - src_offset_x[0] = n - 1; - src_offset_y[0] = m; - } - - src_offset_x[1] = n; - src_offset_y[1] = m; - - if ((m < 1) || (n >= src_w - 1)) { - src_offset_x[2] = n; - src_offset_y[2] = m; - } else { - src_offset_x[2] = n + 1; - src_offset_y[2] = m; - } - - if ((m < 1) || (n >= src_w - 2)) { - src_offset_x[3] = n; - src_offset_y[3] = m; - } else { - src_offset_x[3] = n + 1 + 1; - src_offset_y[3] = m; - } - - if (n < 1) { - src_offset_x[4] = n; - src_offset_y[4] = m; - } else { - src_offset_x[4] = n - 1; - src_offset_y[4] = m; - } - - src_offset_x[5] = n; - src_offset_y[5] = m; - if (n >= src_w-1) { - src_offset_x[6] = n; - src_offset_y[6] = m; - } else { - src_offset_x[6] = n + 1; - src_offset_y[6] = m; - } - - if (n >= src_w - 2) { - src_offset_x[7] = n; - src_offset_y[7] = m; - } else { - src_offset_x[7] = n + 1 + 1; - src_offset_y[7] = m; - } - - if ((m >= src_h - 1) || (n < 1)) { - src_offset_x[8] = n; - src_offset_y[8] = m; - } else { - src_offset_x[8] = n - 1; - src_offset_y[8] = m; - } - - src_offset_x[9] = n; - src_offset_y[9] = m; - - if ((m >= src_h-1) || (n >= src_w-1)) { - src_offset_x[10] = n; - src_offset_y[10] = m; - } else { - src_offset_x[10] = n + 1; - src_offset_y[10] = m; - } - - if ((m >= src_h - 1) || (n >= src_w - 2)) { - src_offset_x[11] = n; - src_offset_y[11] = m; - } else { - src_offset_x[11] = n + 1 + 1; - src_offset_y[11] = m; - } - - if ((m >= src_h - 2) || (n < 1)) { - src_offset_x[12] = n; - src_offset_y[12] = m; - } else { - src_offset_x[12] = n - 1; - src_offset_y[12] = m; - } - - src_offset_x[13] = n; - src_offset_y[13] = m; - - if ((m >= src_h - 2) || (n >= src_w - 1)) { - src_offset_x[14] = n; - src_offset_y[14] = m; - } else { - src_offset_x[14] = n + 1; - src_offset_y[14] = m; - } - - if ((m >= src_h - 2) || (n >= src_w - 2)) { - src_offset_x[15] = n; - src_offset_y[15] = m; - } else { - src_offset_x[15] = n + 1 + 1; - src_offset_y[15] = m; - } - - for (k = -1; k < 3; k++) { - const gdFixed f = gd_itofx(k)-f_f; - const gdFixed f_fm1 = f - f_1; - const gdFixed f_fp1 = f + f_1; - const gdFixed f_fp2 = f + f_2; - register gdFixed f_a = 0, f_b = 0, f_d = 0, f_c = 0; - register gdFixed f_RY; - int l; - - if (f_fp2 > 0) f_a = gd_mulfx(f_fp2, gd_mulfx(f_fp2,f_fp2)); - if (f_fp1 > 0) f_b = gd_mulfx(f_fp1, gd_mulfx(f_fp1,f_fp1)); - if (f > 0) f_c = gd_mulfx(f, gd_mulfx(f,f)); - if (f_fm1 > 0) f_d = gd_mulfx(f_fm1, gd_mulfx(f_fm1,f_fm1)); - - f_RY = gd_divfx((f_a - gd_mulfx(f_4,f_b) + gd_mulfx(f_6,f_c) - gd_mulfx(f_4,f_d)),f_6); - - for (l = -1; l < 3; l++) { - const gdFixed f = gd_itofx(l) - f_g; - const gdFixed f_fm1 = f - f_1; - const gdFixed f_fp1 = f + f_1; - const gdFixed f_fp2 = f + f_2; - register gdFixed f_a = 0, f_b = 0, f_c = 0, f_d = 0; - register gdFixed f_RX, f_R, f_rs, f_gs, f_bs, f_ba; - register int c; - const int _k = ((k+1)*4) + (l+1); - - if (f_fp2 > 0) f_a = gd_mulfx(f_fp2,gd_mulfx(f_fp2,f_fp2)); - - if (f_fp1 > 0) f_b = gd_mulfx(f_fp1,gd_mulfx(f_fp1,f_fp1)); - - if (f > 0) f_c = gd_mulfx(f,gd_mulfx(f,f)); - - if (f_fm1 > 0) f_d = gd_mulfx(f_fm1,gd_mulfx(f_fm1,f_fm1)); - - f_RX = gd_divfx((f_a-gd_mulfx(f_4,f_b)+gd_mulfx(f_6,f_c)-gd_mulfx(f_4,f_d)),f_6); - f_R = gd_mulfx(f_RY,f_RX); - - c = src->tpixels[*(src_offset_y + _k)][*(src_offset_x + _k)]; - f_rs = gd_itofx(gdTrueColorGetRed(c)); - f_gs = gd_itofx(gdTrueColorGetGreen(c)); - f_bs = gd_itofx(gdTrueColorGetBlue(c)); - f_ba = gd_itofx(gdTrueColorGetAlpha(c)); - - f_red += gd_mulfx(f_rs,f_R); - f_green += gd_mulfx(f_gs,f_R); - f_blue += gd_mulfx(f_bs,f_R); - f_alpha += gd_mulfx(f_ba,f_R); - } - } - - red = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_red, f_gamma)), 0, 255); - green = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_green, f_gamma)), 0, 255); - blue = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_blue, f_gamma)), 0, 255); - alpha = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_alpha, f_gamma)), 0, 127); - - *(dst_row + dst_offset_x) = gdTrueColorAlpha(red, green, blue, alpha); - - dst_offset_x++; - } - dst_offset_y++; - } - return dst; +static gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, + const unsigned int height) +{ + const long new_width = MAX(1, width); + const long new_height = MAX(1, height); + const int src_w = gdImageSX(src); + const int src_h = gdImageSY(src); + const double dx = (double)src_w / (double)new_width; + const double dy = (double)src_h / (double)new_height; + const double gamma = 1.04; + gdImagePtr dst; + + unsigned int dst_offset_x; + unsigned int dst_offset_y = 0; + long i; + + /* impact perf a bit, but not that much. Implementation for palette + images can be done at a later point. + */ + if (src->trueColor == 0) { + gdImagePaletteToTrueColor(src); + } + + dst = gdImageCreateTrueColor(new_width, new_height); + if (!dst) { + return NULL; + } + + dst->saveAlphaFlag = 1; + + for (i = 0; i < new_height; i++) { + long j; + const double src_y = (double)i * dy; + const long m = gdClampInt((int)src_y, 0, src_h - 1); + const double f_f = src_y - (double)m; + dst_offset_x = 0; + + for (j = 0; j < new_width; j++) { + const double src_x = (double)j * dx; + const long n = gdClampInt((int)src_x, 0, src_w - 1); + const double f_g = src_x - (double)n; + long k; + double red_acc = 0.0, green_acc = 0.0, blue_acc = 0.0, alpha_acc = 0.0; + unsigned char red, green, blue, alpha = 0; + int *dst_row = dst->tpixels[dst_offset_y]; + + for (k = -1; k < 3; k++) { + int l; + const int src_y_sample = gdClampInt((int)m + (int)k, 0, src_h - 1); + const double weight_y = filter_cubic_spline((double)k - f_f, 0.0); + + for (l = -1; l < 3; l++) { + const int src_x_sample = gdClampInt((int)n + (int)l, 0, src_w - 1); + const double weight = weight_y * filter_cubic_spline((double)l - f_g, 0.0); + const int c = src->tpixels[src_y_sample][src_x_sample]; + + red_acc += weight * (double)gdTrueColorGetRed(c); + green_acc += weight * (double)gdTrueColorGetGreen(c); + blue_acc += weight * (double)gdTrueColorGetBlue(c); + alpha_acc += weight * (double)gdTrueColorGetAlpha(c); + } + } + + red = uchar_clamp(red_acc * gamma, 0xFF); + green = uchar_clamp(green_acc * gamma, 0xFF); + blue = uchar_clamp(blue_acc * gamma, 0xFF); + alpha = uchar_clamp(alpha_acc * gamma, 0x7F); + + *(dst_row + dst_offset_x) = gdTrueColorAlpha(red, green, blue, alpha); + + dst_offset_x++; + } + dst_offset_y++; + } + return dst; } -gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height) -{ - gdImagePtr im_scaled = NULL; - - if (src == NULL || src->interpolation_id < 0 || src->interpolation_id > GD_METHOD_COUNT) { - return NULL; - } - - if (new_width == 0 || new_height == 0) { - return NULL; - } - - if (new_width == gdImageSX(src) && new_height == gdImageSY(src)) { - return gdImageClone(src); - } - switch (src->interpolation_id) { - /*Special cases, optimized implementations */ - case GD_NEAREST_NEIGHBOUR: - im_scaled = gdImageScaleNearestNeighbour(src, new_width, new_height); - break; - - case GD_BILINEAR_FIXED: - case GD_LINEAR: - im_scaled = gdImageScaleBilinear(src, new_width, new_height); - break; - - case GD_BICUBIC_FIXED: - case GD_BICUBIC: - im_scaled = gdImageScaleBicubicFixed(src, new_width, new_height); - break; - - /* generic */ - default: - if (src->interpolation == NULL) { - return NULL; - } - im_scaled = gdImageScaleTwoPass(src, src->sx, src->sy, new_width, new_height); - break; - } - return im_scaled; +/** + * Function: gdImageScale + * + * Scale an image + * + * Creates a new image, scaled to the requested size using the current + * . + * + * Note that GD_WEIGHTED4 is not yet supported by this function. + * + * Parameters: + * src - The source image. + * new_width - The new width. + * new_height - The new height. + * + * Returns: + * The scaled image on success, NULL on failure. + * + * See also: + * - + * - + */ +BGD_DECLARE(gdImagePtr) +gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height) +{ + gdImagePtr im_scaled = NULL; + + if (src == NULL || (uintmax_t)src->interpolation_id >= GD_METHOD_COUNT) { + return NULL; + } + + if (new_width == 0 || new_height == 0) { + return NULL; + } + if ((int)new_width == gdImageSX(src) && (int)new_height == gdImageSY(src)) { + return gdImageClone(src); + } + switch (src->interpolation_id) { + /*Special cases, optimized implementations */ + case GD_NEAREST_NEIGHBOUR: + im_scaled = gdImageScaleNearestNeighbour(src, new_width, new_height); + break; + + case GD_BILINEAR_FIXED: + case GD_LINEAR: + im_scaled = gdImageScaleBilinear(src, new_width, new_height); + break; + + case GD_BICUBIC_FIXED: + case GD_BICUBIC: + im_scaled = gdImageScaleBicubicFixed(src, new_width, new_height); + break; + + /* generic */ + default: + if (src->interpolation == NULL) { + return NULL; + } + im_scaled = gdImageScaleTwoPass(src, new_width, new_height); + break; + } + + return im_scaled; } static int gdRotatedImageSize(gdImagePtr src, const float angle, gdRectPtr bbox) @@ -1636,207 +1491,223 @@ static int gdRotatedImageSize(gdImagePtr src, const float angle, gdRectPtr bbox) return GD_TRUE; } -static gdImagePtr -gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor) -{ - float _angle = ((float) (-degrees / 180.0f) * (float)M_PI); - const int src_w = gdImageSX(src); - const int src_h = gdImageSY(src); - const gdFixed f_0_5 = gd_ftofx(0.5f); - const gdFixed f_H = gd_itofx(src_h/2); - const gdFixed f_W = gd_itofx(src_w/2); - const gdFixed f_cos = gd_ftofx(cos(-_angle)); - const gdFixed f_sin = gd_ftofx(sin(-_angle)); - - unsigned int dst_offset_x; - unsigned int dst_offset_y = 0; - unsigned int i; - gdImagePtr dst; - gdRect bbox; - int new_height, new_width; +static gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, + const int bgColor) +{ + double _angle = ((double)(-degrees) / 180.0) * M_PI; + const int src_w = gdImageSX(src); + const int src_h = gdImageSY(src); + const double H = (double)(src_h / 2); + const double W = (double)(src_w / 2); + const double cos_angle = cos(-_angle); + const double sin_angle = sin(-_angle); + + unsigned int dst_offset_x; + unsigned int dst_offset_y = 0; + unsigned int i; + gdImagePtr dst; + gdRect bbox; + unsigned int new_height, new_width; gdRotatedImageSize(src, degrees, &bbox); new_width = bbox.width; new_height = bbox.height; - dst = gdImageCreateTrueColor(new_width, new_height); - if (!dst) { - return NULL; - } - dst->saveAlphaFlag = 1; - for (i = 0; i < new_height; i++) { - unsigned int j; - dst_offset_x = 0; - for (j = 0; j < new_width; j++) { - gdFixed f_i = gd_itofx((int)i - (int)new_height/2); - gdFixed f_j = gd_itofx((int)j - (int)new_width/2); - gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H; - gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W; - long m = gd_fxtoi(f_m); - long n = gd_fxtoi(f_n); - - if ((m > 0) && (m < src_h-1) && (n > 0) && (n < src_w-1)) { - if (dst_offset_y < new_height) { - dst->tpixels[dst_offset_y][dst_offset_x++] = src->tpixels[m][n]; - } - } else { - if (dst_offset_y < new_height) { - dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor; - } - } - } - dst_offset_y++; - } - return dst; + dst = gdImageCreateTrueColor(new_width, new_height); + if (!dst) { + return NULL; + } + dst->saveAlphaFlag = 1; + for (i = 0; i < new_height; i++) { + unsigned int j; + dst_offset_x = 0; + for (j = 0; j < new_width; j++) { + const double dst_y = (double)((int)i - (int)new_height / 2); + const double dst_x = (double)((int)j - (int)new_width / 2); + const double src_y = dst_x * sin_angle + dst_y * cos_angle + H; + const double src_x = dst_x * cos_angle - dst_y * sin_angle + W; + long m = (long)floor(src_y + 0.5); + long n = (long)floor(src_x + 0.5); + + if ((m > 0) && (m < src_h - 1) && (n > 0) && (n < src_w - 1)) { + if (dst_offset_y < new_height) { + dst->tpixels[dst_offset_y][dst_offset_x++] = src->tpixels[m][n]; + } + } else { + if (dst_offset_y < new_height) { + dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor; + } + } + } + dst_offset_y++; + } + return dst; } -static gdImagePtr -gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor) -{ - float _angle = ((float) (-degrees / 180.0f) * (float)M_PI); - const int src_w = gdImageSX(src); - const int src_h = gdImageSY(src); - const gdFixed f_0_5 = gd_ftofx(0.5f); - const gdFixed f_H = gd_itofx(src_h/2); - const gdFixed f_W = gd_itofx(src_w/2); - const gdFixed f_cos = gd_ftofx(cos(-_angle)); - const gdFixed f_sin = gd_ftofx(sin(-_angle)); - - unsigned int dst_offset_x; - unsigned int dst_offset_y = 0; - unsigned int i; - gdImagePtr dst; - int new_width, new_height; - gdRect bbox; - - if (bgColor < 0) { - return NULL; - } - - if (src->interpolation == NULL) { - gdImageSetInterpolationMethod(src, GD_DEFAULT); - } +static gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor) +{ + double _angle = ((double)(-degrees) / 180.0) * M_PI; + const int src_w = gdImageSX(src); + const int src_h = gdImageSY(src); + const double H = (double)(src_h / 2); + const double W = (double)(src_w / 2); + const double cos_angle = cos(-_angle); + const double sin_angle = sin(-_angle); + + unsigned int dst_offset_x; + unsigned int dst_offset_y = 0; + unsigned int i; + gdImagePtr dst; + unsigned int new_width, new_height; + gdRect bbox; + + if (bgColor < 0) { + return NULL; + } gdRotatedImageSize(src, degrees, &bbox); new_width = bbox.width; new_height = bbox.height; - dst = gdImageCreateTrueColor(new_width, new_height); - if (!dst) { - return NULL; - } - dst->saveAlphaFlag = 1; - - for (i = 0; i < new_height; i++) { - unsigned int j; - dst_offset_x = 0; - for (j = 0; j < new_width; j++) { - gdFixed f_i = gd_itofx((int)i - (int)new_height/ 2); - gdFixed f_j = gd_itofx((int)j - (int)new_width / 2); - gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H; - gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W; - long m = gd_fxtoi(f_m); - long n = gd_fxtoi(f_n); - - if (m < -1 || n < -1 || m >= src_h || n >= src_w ) { - dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor; - } else { - dst->tpixels[dst_offset_y][dst_offset_x++] = getPixelInterpolated(src, gd_fxtod(f_n), gd_fxtod(f_m), bgColor); - } - } - dst_offset_y++; - } - return dst; -} - -gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor) -{ - /* round to two decimals and keep the 100x multiplication to use it in the common square angles - case later. Keep the two decimal precisions so smaller rotation steps can be done, useful for - slow animations. */ - const int angle_rounded = fmod((int) floorf(angle * 100), 360 * 100); - - if (bgcolor < 0) { - return NULL; - } - - /* impact perf a bit, but not that much. Implementation for palette - images can be done at a later point. - */ - if (src->trueColor == 0) { - if (bgcolor < gdMaxColors) { - bgcolor = gdTrueColorAlpha(src->red[bgcolor], src->green[bgcolor], src->blue[bgcolor], src->alpha[bgcolor]); - } - gdImagePaletteToTrueColor(src); - } - - /* no interpolation needed here */ - switch (angle_rounded) { - case 0: { - gdImagePtr dst = gdImageCreateTrueColor(src->sx, src->sy); - if (dst == NULL) { - return NULL; - } - dst->transparent = src->transparent; - dst->saveAlphaFlag = 1; - dst->alphaBlendingFlag = gdEffectReplace; - - gdImageCopy(dst, src, 0,0,0,0,src->sx,src->sy); - return dst; - } - case -27000: - case 9000: - return gdImageRotate90(src, 0); - case -18000: - case 18000: - return gdImageRotate180(src, 0); - case -9000: - case 27000: - return gdImageRotate270(src, 0); - } - - if (src == NULL || src->interpolation_id < 1 || src->interpolation_id > GD_METHOD_COUNT) { - return NULL; - } - - switch (src->interpolation_id) { - case GD_NEAREST_NEIGHBOUR: - return gdImageRotateNearestNeighbour(src, angle, bgcolor); - break; - - case GD_BILINEAR_FIXED: - case GD_BICUBIC_FIXED: - default: - return gdImageRotateGeneric(src, angle, bgcolor); - } - return NULL; + dst = gdImageCreateTrueColor(new_width, new_height); + if (!dst) { + return NULL; + } + dst->saveAlphaFlag = 1; + + for (i = 0; i < new_height; i++) { + unsigned int j; + dst_offset_x = 0; + for (j = 0; j < new_width; j++) { + const double dst_y = (double)((int)i - (int)new_height / 2); + const double dst_x = (double)((int)j - (int)new_width / 2); + const double src_y = dst_x * sin_angle + dst_y * cos_angle + H; + const double src_x = dst_x * cos_angle - dst_y * sin_angle + W; + long m = (long)floor(src_y); + long n = (long)floor(src_x); + + if (m < -1 || n < -1 || m >= src_h || n >= src_w) { + dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor; + } else { + dst->tpixels[dst_offset_y][dst_offset_x++] = + getPixelInterpolated(src, src_x, src_y, bgColor); + } + } + dst_offset_y++; + } + return dst; } /** - * Title: Affine transformation - **/ + * Function: gdImageRotateInterpolated + * + * Rotate an image + * + * Creates a new image, counter-clockwise rotated by the requested angle + * using the current . Non-square angles will add a + * border with bgcolor. + * + * Parameters: + * src - The source image. + * angle - The angle in degrees. + * bgcolor - The color to fill the added background with. + * + * Returns: + * The rotated image on success, NULL on failure. + * + * See also: + * - + */ +BGD_DECLARE(gdImagePtr) +gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor) +{ + /* round to two decimals and keep the 100x multiplication to use it in the + common square angles case later. Keep the two decimal precisions so + smaller rotation steps can be done, useful for slow animations, f.e. */ + const int angle_rounded = fmod((int)floorf(angle * 100), 360 * 100); + gdImagePtr src_tc = src; + int src_cloned = 0; + if (src == NULL || bgcolor < 0) { + return NULL; + } -/** - * Group: Transform - **/ + if (!gdImageTrueColor(src)) { + if (bgcolor < gdMaxColors) { + bgcolor = gdTrueColorAlpha(src->red[bgcolor], src->green[bgcolor], src->blue[bgcolor], + src->alpha[bgcolor]); + } + src_tc = gdImageClone(src); + gdImagePaletteToTrueColor(src_tc); + src_cloned = 1; + } - static void gdImageClipRectangle(gdImagePtr im, gdRectPtr r) -{ - int c1x, c1y, c2x, c2y; - int x1,y1; + /* 0 && 90 degrees multiple rotation, 0 rotation simply clones the return + image and convert it to truecolor, as we must return truecolor image. */ + switch (angle_rounded) { + case 0: + return src_cloned ? src_tc : gdImageClone(src); + + case -27000: + case 9000: + if (src_cloned) + gdImageDestroy(src_tc); + return gdImageRotate90(src, 0); + + case -18000: + case 18000: + if (src_cloned) + gdImageDestroy(src_tc); + return gdImageRotate180(src, 0); + + case -9000: + case 27000: + if (src_cloned) + gdImageDestroy(src_tc); + return gdImageRotate270(src, 0); + } + + if (src->interpolation_id < 1 || src->interpolation_id > GD_METHOD_COUNT) { + if (src_cloned) + gdImageDestroy(src_tc); + return NULL; + } + + switch (src->interpolation_id) { + case GD_NEAREST_NEIGHBOUR: { + gdImagePtr res = gdImageRotateNearestNeighbour(src_tc, angle, bgcolor); + if (src_cloned) + gdImageDestroy(src_tc); + return res; + } - gdImageGetClip(im, &c1x, &c1y, &c2x, &c2y); - x1 = r->x + r->width - 1; - y1 = r->y + r->height - 1; - r->x = CLAMP(r->x, c1x, c2x); - r->y = CLAMP(r->y, c1y, c2y); - r->width = CLAMP(x1, c1x, c2x) - r->x + 1; - r->height = CLAMP(y1, c1y, c2y) - r->y + 1; + case GD_BILINEAR_FIXED: + case GD_BICUBIC_FIXED: + default: { + gdImagePtr res = gdImageRotateGeneric(src_tc, angle, bgcolor); + if (src_cloned) + gdImageDestroy(src_tc); + return res; + } + } + return NULL; } -void gdDumpRect(const char *msg, gdRectPtr r) +/** + * Group: Affine Transformation + **/ + +static void gdImageClipRectangle(gdImagePtr im, gdRectPtr r) { - printf("%s (%i, %i) (%i, %i)\n", msg, r->x, r->y, r->width, r->height); + int c1x, c1y, c2x, c2y; + int x1, y1; + + gdImageGetClip(im, &c1x, &c1y, &c2x, &c2y); + x1 = r->x + r->width - 1; + y1 = r->y + r->height - 1; + r->x = CLAMP(r->x, c1x, c2x); + r->y = CLAMP(r->y, c1y, c2y); + r->width = CLAMP(x1, c1x, c2x) - r->x + 1; + r->height = CLAMP(y1, c1y, c2y) - r->y + 1; } /** @@ -1855,55 +1726,135 @@ void gdDumpRect(const char *msg, gdRectPtr r) * Returns: * GD_TRUE if the affine is rectilinear or GD_FALSE */ -int gdTransformAffineGetImage(gdImagePtr *dst, - const gdImagePtr src, - gdRectPtr src_area, - const double affine[6]) -{ - int res; - double m[6]; - gdRect bbox; - gdRect area_full; - - if (src_area == NULL) { - area_full.x = 0; - area_full.y = 0; - area_full.width = gdImageSX(src); - area_full.height = gdImageSY(src); - src_area = &area_full; - } - - gdTransformAffineBoundingBox(src_area, affine, &bbox); - - *dst = gdImageCreateTrueColor(bbox.width, bbox.height); - if (*dst == NULL) { - return GD_FALSE; - } - (*dst)->saveAlphaFlag = 1; - - if (!src->trueColor) { - gdImagePaletteToTrueColor(src); - } - - /* Translate to dst origin (0,0) */ - gdAffineTranslate(m, -bbox.x, -bbox.y); - gdAffineConcat(m, affine, m); - - gdImageAlphaBlending(*dst, 0); - - res = gdTransformAffineCopy(*dst, - 0,0, - src, - src_area, - m); - - if (res != GD_TRUE) { - gdImageDestroy(*dst); - dst = NULL; - return GD_FALSE; - } else { - return GD_TRUE; - } +BGD_DECLARE(int) +gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, + const double affine[6]) +{ + int res; + double m[6]; + gdRect bbox; + gdRect area_full; + + if (src_area == NULL) { + area_full.x = 0; + area_full.y = 0; + area_full.width = gdImageSX(src); + area_full.height = gdImageSY(src); + src_area = &area_full; + } + + if (gdTransformAffineBoundingBox(src_area, affine, &bbox) != GD_TRUE) { + *dst = NULL; + return GD_FALSE; + } + + *dst = gdImageCreateTrueColor(bbox.width, bbox.height); + if (*dst == NULL) { + return GD_FALSE; + } + (*dst)->saveAlphaFlag = 1; + gdImageAlphaBlending(*dst, 0); + /* The API has no background-color parameter, so uncovered output starts + * transparent. */ + gdImageFilledRectangle(*dst, 0, 0, bbox.width - 1, bbox.height - 1, + gdTrueColorAlpha(0, 0, 0, gdAlphaTransparent)); + + if (!src->trueColor) { + gdImagePaletteToTrueColor(src); + } + + /* Translate to dst origin (0,0) */ + gdAffineTranslate(m, -bbox.x, -bbox.y); + gdAffineConcat(m, affine, m); + + res = gdTransformAffineCopy(*dst, 0, 0, src, src_area, m); + + if (res != GD_TRUE) { + gdImageDestroy(*dst); + *dst = NULL; + return GD_FALSE; + } else { + return GD_TRUE; + } +} + +/** Function: getPixelRgbInterpolated + * get the index of the image's colors + * + * Parameters: + * im - Image to draw the transformed image + * tcolor - TrueColor + * + * Return: + * index of colors + */ +static int getPixelRgbInterpolated(gdImagePtr im, const int tcolor) +{ + unsigned char r, g, b, a; + int ct; + int i; + + b = (unsigned char)(tcolor); + g = (unsigned char)(tcolor >> 8); + r = (unsigned char)(tcolor >> 16); + a = (unsigned char)(tcolor >> 24); + + for (i = 0; i < im->colorsTotal; i++) { + if (im->red[i] == r && im->green[i] == g && im->blue[i] == b && im->alpha[i] == a) { + return i; + } + } + + ct = im->colorsTotal; + if (ct == gdMaxColors) { + return -1; + } + + im->colorsTotal++; + im->red[ct] = r; + im->green[ct] = g; + im->blue[ct] = b; + im->alpha[ct] = a; + im->open[ct] = 0; + + return ct; +} + +#define GD_AFFINE_KERNEL_SUPPORT 2.0 + +typedef struct { + gdImagePtr src; + gdRectPtr clip; + int bgColor; +} gdAffineSampleContext; + +static inline int gdAffineSampleIntersectsRegion(const double x, const double y, + const gdRectPtr region) +{ + const double left = (double)region->x - GD_AFFINE_KERNEL_SUPPORT; + const double top = (double)region->y - GD_AFFINE_KERNEL_SUPPORT; + const double right = (double)(region->x + region->width - 1) + GD_AFFINE_KERNEL_SUPPORT; + const double bottom = (double)(region->y + region->height - 1) + GD_AFFINE_KERNEL_SUPPORT; + + return x >= left && x <= right && y >= top && y <= bottom; +} + +static inline int gdAffineSample(const gdAffineSampleContext *ctx, const double x, const double y, + int *color) +{ + int c; + + if (!gdAffineSampleIntersectsRegion(x, y, ctx->clip)) { + return GD_FALSE; + } + + c = getPixelInterpolatedClipped(ctx->src, x, y, ctx->bgColor, ctx->clip); + if (gdTrueColorGetAlpha(c) == gdAlphaTransparent) { + return GD_FALSE; + } + + *color = c; + return GD_TRUE; } /** @@ -1921,116 +1872,120 @@ int gdTransformAffineGetImage(gdImagePtr *dst, * Returns: * GD_TRUE on success or GD_FALSE on failure */ -int gdTransformAffineCopy(gdImagePtr dst, - int dst_x, int dst_y, - const gdImagePtr src, - gdRectPtr src_region, - const double affine[6]) -{ - int c1x,c1y,c2x,c2y; - int backclip = 0; - int backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2; - register int x, y, src_offset_x, src_offset_y; - double inv[6]; - gdPointF pt, src_pt; - gdRect bbox; - int end_x, end_y; - gdInterpolationMethod interpolation_id_bak = src->interpolation_id; - - /* These methods use special implementations */ - if (src->interpolation_id == GD_BILINEAR_FIXED || src->interpolation_id == GD_BICUBIC_FIXED || src->interpolation_id == GD_NEAREST_NEIGHBOUR) { - interpolation_id_bak = src->interpolation_id; - - gdImageSetInterpolationMethod(src, GD_BICUBIC); - } - - - gdImageClipRectangle(src, src_region); - - if (src_region->x > 0 || src_region->y > 0 - || src_region->width < gdImageSX(src) - || src_region->height < gdImageSY(src)) { - backclip = 1; - - gdImageGetClip(src, &backup_clipx1, &backup_clipy1, - &backup_clipx2, &backup_clipy2); - - gdImageSetClip(src, src_region->x, src_region->y, - src_region->x + src_region->width - 1, - src_region->y + src_region->height - 1); - } - - if (!gdTransformAffineBoundingBox(src_region, affine, &bbox)) { - if (backclip) { - gdImageSetClip(src, backup_clipx1, backup_clipy1, - backup_clipx2, backup_clipy2); - } - gdImageSetInterpolationMethod(src, interpolation_id_bak); - return GD_FALSE; - } - - gdImageGetClip(dst, &c1x, &c1y, &c2x, &c2y); - - end_x = bbox.width + abs(bbox.x); - end_y = bbox.height + abs(bbox.y); - - /* Get inverse affine to let us work with destination -> source */ - if (gdAffineInvert(inv, affine) == GD_FALSE) { - gdImageSetInterpolationMethod(src, interpolation_id_bak); - return GD_FALSE; - } - - src_offset_x = src_region->x; - src_offset_y = src_region->y; - - if (dst->alphaBlendingFlag) { - for (y = bbox.y; y <= end_y; y++) { - pt.y = y + 0.5; - for (x = 0; x <= end_x; x++) { - pt.x = x + 0.5; - gdAffineApplyToPointF(&src_pt, &pt, inv); - gdImageSetPixel(dst, dst_x + x, dst_y + y, getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, 0)); - } - } - } else { - for (y = 0; y <= end_y; y++) { - unsigned char *dst_p = NULL; - int *tdst_p = NULL; - - pt.y = y + 0.5 + bbox.y; - if ((dst_y + y) < 0 || ((dst_y + y) > gdImageSY(dst) -1)) { - continue; - } - if (dst->trueColor) { - tdst_p = dst->tpixels[dst_y + y] + dst_x; - } else { - dst_p = dst->pixels[dst_y + y] + dst_x; - } - - for (x = 0; x <= end_x; x++) { - pt.x = x + 0.5 + bbox.x; - gdAffineApplyToPointF(&src_pt, &pt, inv); - - if ((dst_x + x) < 0 || (dst_x + x) > (gdImageSX(dst) - 1)) { - break; - } - if (dst->trueColor) { - *(tdst_p++) = getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, -1); - } else { - *(dst_p++) = getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, -1); - } - } - } - } - - /* Restore clip if required */ - if (backclip) { - gdImageSetClip(src, backup_clipx1, backup_clipy1, - backup_clipx2, backup_clipy2); - } - - gdImageSetInterpolationMethod(src, interpolation_id_bak); - return GD_TRUE; +BGD_DECLARE(int) +gdTransformAffineCopy(gdImagePtr dst, int dst_x, int dst_y, const gdImagePtr src, + gdRectPtr src_region, const double affine[6]) +{ + int backclip = 0; + int backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2; + register int x, y, src_offset_x, src_offset_y; + double inv[6]; + gdPointF pt, src_pt; + gdRect bbox; + int end_x, end_y; + const int transparent = gdTrueColorAlpha(0, 0, 0, gdAlphaTransparent); + gdAffineSampleContext sample_ctx; + + gdImageClipRectangle(src, src_region); + + if (src_region->x > 0 || src_region->y > 0 || src_region->width < gdImageSX(src) || + src_region->height < gdImageSY(src)) { + backclip = 1; + + gdImageGetClip(src, &backup_clipx1, &backup_clipy1, &backup_clipx2, &backup_clipy2); + + gdImageSetClip(src, src_region->x, src_region->y, src_region->x + src_region->width - 1, + src_region->y + src_region->height - 1); + } + + if (!gdTransformAffineBoundingBox(src_region, affine, &bbox)) { + if (backclip) { + gdImageSetClip(src, backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2); + } + return GD_FALSE; + } + + end_x = bbox.width + abs(bbox.x); + end_y = bbox.height + abs(bbox.y); + + /* Get inverse affine to let us work with destination -> source */ + if (gdAffineInvert(inv, affine) == GD_FALSE) { + if (backclip) { + gdImageSetClip(src, backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2); + } + return GD_FALSE; + } + + src_offset_x = src_region->x; + src_offset_y = src_region->y; + sample_ctx.src = src; + sample_ctx.clip = src_region; + sample_ctx.bgColor = transparent; + + if (dst->alphaBlendingFlag) { + for (y = bbox.y; y <= end_y; y++) { + pt.y = y + 0.5; + for (x = bbox.x; x <= end_x; x++) { + pt.x = x + 0.5; + int c; + gdAffineApplyToPointF(&src_pt, &pt, inv); + const double sample_x = src_offset_x + src_pt.x; + const double sample_y = src_offset_y + src_pt.y; + if (!gdAffineSample(&sample_ctx, sample_x, sample_y, &c)) { + continue; + } + gdImageSetPixel(dst, dst_x + x, dst_y + y, c); + } + } + } else { + for (y = bbox.y; y <= end_y; y++) { + unsigned char *dst_p = NULL; + int *tdst_p = NULL; + + pt.y = y + 0.5; + if ((dst_y + y) < 0 || ((dst_y + y) > gdImageSY(dst) - 1)) { + continue; + } + if (dst->trueColor) { + tdst_p = dst->tpixels[dst_y + y]; + } else { + dst_p = dst->pixels[dst_y + y]; + } + + for (x = bbox.x; x <= end_x; x++) { + pt.x = x + 0.5; + gdAffineApplyToPointF(&src_pt, &pt, inv); + + if ((dst_x + x) < 0 || (dst_x + x) > (gdImageSX(dst) - 1)) { + break; + } + { + const double sample_x = src_offset_x + src_pt.x; + const double sample_y = src_offset_y + src_pt.y; + int c; + + if (!gdAffineSample(&sample_ctx, sample_x, sample_y, &c)) { + continue; + } + if (dst->trueColor) { + *(tdst_p + dst_x + x) = c; + } else { + const int pc = getPixelRgbInterpolated(dst, c); + if (pc >= 0) { + *(dst_p + dst_x + x) = pc; + } + } + } + } + } + } + + /* Restore clip if required */ + if (backclip) { + gdImageSetClip(src, backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2); + } + + return GD_TRUE; } /** @@ -2046,126 +2001,195 @@ int gdTransformAffineCopy(gdImagePtr dst, * Returns: * GD_TRUE if the affine is rectilinear or GD_FALSE */ -int gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox) -{ - gdPointF extent[4], min, max, point; - int i; - - extent[0].x=0.0; - extent[0].y=0.0; - extent[1].x=(double) src->width; - extent[1].y=0.0; - extent[2].x=(double) src->width; - extent[2].y=(double) src->height; - extent[3].x=0.0; - extent[3].y=(double) src->height; - - for (i=0; i < 4; i++) { - point=extent[i]; - if (gdAffineApplyToPointF(&extent[i], &point, affine) != GD_TRUE) { - return GD_FALSE; - } - } - min=extent[0]; - max=extent[0]; - - for (i=1; i < 4; i++) { - if (min.x > extent[i].x) - min.x=extent[i].x; - if (min.y > extent[i].y) - min.y=extent[i].y; - if (max.x < extent[i].x) - max.x=extent[i].x; - if (max.y < extent[i].y) - max.y=extent[i].y; - } - bbox->x = (int) min.x; - bbox->y = (int) min.y; - bbox->width = (int) floor(max.x - min.x) - 1; - bbox->height = (int) floor(max.y - min.y); - return GD_TRUE; +BGD_DECLARE(int) +gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox) +{ + gdPointF extent[4], min, max, point; + double bbox_x_d, bbox_y_d, bbox_width_d, bbox_height_d; + int bbox_x, bbox_y, bbox_width, bbox_height; + int i; + + extent[0].x = 0.0; + extent[0].y = 0.0; + extent[1].x = (double)src->width; + extent[1].y = 0.0; + extent[2].x = (double)src->width; + extent[2].y = (double)src->height; + extent[3].x = 0.0; + extent[3].y = (double)src->height; + + for (i = 0; i < 4; i++) { + point = extent[i]; + if (gdAffineApplyToPointF(&extent[i], &point, affine) != GD_TRUE) { + return GD_FALSE; + } + } + min = extent[0]; + max = extent[0]; + + for (i = 1; i < 4; i++) { + if (min.x > extent[i].x) + min.x = extent[i].x; + if (min.y > extent[i].y) + min.y = extent[i].y; + if (max.x < extent[i].x) + max.x = extent[i].x; + if (max.y < extent[i].y) + max.y = extent[i].y; + } + bbox_x_d = floor(min.x); + bbox_y_d = floor(min.y); + bbox_width_d = ceil(max.x) - bbox_x_d; + bbox_height_d = ceil(max.y) - bbox_y_d; + if (!isfinite(bbox_x_d) || !isfinite(bbox_y_d) || !isfinite(bbox_width_d) || + !isfinite(bbox_height_d) || bbox_x_d < INT_MIN || bbox_x_d > INT_MAX || + bbox_y_d < INT_MIN || bbox_y_d > INT_MAX || bbox_width_d < 0.0 || bbox_width_d > INT_MAX || + bbox_height_d < 0.0 || bbox_height_d > INT_MAX) { + return GD_FALSE; + } + bbox_x = (int)bbox_x_d; + bbox_y = (int)bbox_y_d; + bbox_width = (int)bbox_width_d; + bbox_height = (int)bbox_height_d; + if ((bbox_x < 0 && bbox_width > INT_MAX + bbox_x) || + (bbox_x > 0 && bbox_width > INT_MAX - bbox_x) || + (bbox_y < 0 && bbox_height > INT_MAX + bbox_y) || + (bbox_y > 0 && bbox_height > INT_MAX - bbox_y)) { + return GD_FALSE; + } + bbox->x = bbox_x; + bbox->y = bbox_y; + bbox->width = bbox_width; + bbox->height = bbox_height; + + return GD_TRUE; } -int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id) -{ - if (im == NULL || id < 0 || id > GD_METHOD_COUNT) { - return 0; - } - - switch (id) { - case GD_NEAREST_NEIGHBOUR: - case GD_WEIGHTED4: - im->interpolation = NULL; - break; - - /* generic versions*/ - /* GD_BILINEAR_FIXED and GD_BICUBIC_FIXED are kept for BC reasons */ - case GD_BILINEAR_FIXED: - case GD_LINEAR: - im->interpolation = filter_linear; - break; - case GD_BELL: - im->interpolation = filter_bell; - break; - case GD_BESSEL: - im->interpolation = filter_bessel; - break; - case GD_BICUBIC_FIXED: - case GD_BICUBIC: - im->interpolation = filter_bicubic; - break; - case GD_BLACKMAN: - im->interpolation = filter_blackman; - break; - case GD_BOX: - im->interpolation = filter_box; - break; - case GD_BSPLINE: - im->interpolation = filter_bspline; - break; - case GD_CATMULLROM: - im->interpolation = filter_catmullrom; - break; - case GD_GAUSSIAN: - im->interpolation = filter_gaussian; - break; - case GD_GENERALIZED_CUBIC: - im->interpolation = filter_generalized_cubic; - break; - case GD_HERMITE: - im->interpolation = filter_hermite; - break; - case GD_HAMMING: - im->interpolation = filter_hamming; - break; - case GD_HANNING: - im->interpolation = filter_hanning; - break; - case GD_MITCHELL: - im->interpolation = filter_mitchell; - break; - case GD_POWER: - im->interpolation = filter_power; - break; - case GD_QUADRATIC: - im->interpolation = filter_quadratic; - break; - case GD_SINC: - im->interpolation = filter_sinc; - break; - case GD_TRIANGLE: - im->interpolation = filter_triangle; - break; - case GD_DEFAULT: - id = GD_LINEAR; - im->interpolation = filter_linear; - break; - - default: - return 0; - } - im->interpolation_id = id; - return 1; +/** + * Group: Interpolation Method + */ + +/** + * Function: gdImageSetInterpolationMethod + * + * Set the interpolation method for subsequent operations + * + * Parameters: + * im - The image. + * id - The interpolation method. + * + * Returns: + * Non-zero on success, zero on failure. + * + * See also: + * - + * - + */ +BGD_DECLARE(int) +gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id) +{ + if (im == NULL || (uintmax_t)id > GD_METHOD_COUNT) { + return 0; + } + + switch (id) { + case GD_NEAREST_NEIGHBOUR: + case GD_WEIGHTED4: + im->interpolation = NULL; + break; + + /* generic versions*/ + /* GD_BILINEAR_FIXED and GD_BICUBIC_FIXED are kept for BC reasons */ + case GD_BILINEAR_FIXED: + case GD_LINEAR: + im->interpolation = filter_linear; + break; + case GD_BELL: + im->interpolation = filter_bell; + break; + case GD_BESSEL: + im->interpolation = filter_bessel; + break; + case GD_BICUBIC_FIXED: + case GD_BICUBIC: + /* no interpolation as gdImageScale calls a dedicated function */ + im->interpolation = NULL; + break; + case GD_BLACKMAN: + im->interpolation = filter_blackman; + break; + case GD_BOX: + im->interpolation = filter_box; + break; + case GD_BSPLINE: + im->interpolation = filter_bspline; + break; + case GD_CATMULLROM: + im->interpolation = filter_catmullrom; + break; + case GD_GAUSSIAN: + im->interpolation = filter_gaussian; + break; + case GD_GENERALIZED_CUBIC: + im->interpolation = filter_generalized_cubic; + break; + case GD_HERMITE: + im->interpolation = filter_hermite; + break; + case GD_HAMMING: + im->interpolation = filter_hamming; + break; + case GD_HANNING: + im->interpolation = filter_hanning; + break; + case GD_MITCHELL: + im->interpolation = filter_mitchell; + break; + case GD_POWER: + im->interpolation = filter_power; + break; + case GD_QUADRATIC: + im->interpolation = filter_quadratic; + break; + case GD_SINC: + im->interpolation = filter_sinc; + break; + case GD_TRIANGLE: + im->interpolation = filter_triangle; + break; + case GD_LANCZOS3: + im->interpolation = filter_lanczos3; + break; + case GD_LANCZOS8: + im->interpolation = filter_lanczos8; + break; + case GD_BLACKMAN_BESSEL: + im->interpolation = filter_blackman_bessel; + break; + case GD_BLACKMAN_SINC: + im->interpolation = filter_blackman_sinc; + break; + case GD_QUADRATIC_BSPLINE: + im->interpolation = filter_quadratic_bspline; + break; + case GD_CUBIC_SPLINE: + im->interpolation = filter_cubic_spline; + break; + case GD_COSINE: + im->interpolation = filter_cosine; + break; + case GD_WELSH: + im->interpolation = filter_welsh; + break; + case GD_DEFAULT: + id = GD_LINEAR; + im->interpolation = filter_linear; + break; + default: + return 0; + } + im->interpolation_id = id; + return 1; } /** @@ -2186,11 +2210,9 @@ int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id) * - * - */ -gdInterpolationMethod gdImageGetInterpolationMethod(gdImagePtr im) -{ - return im->interpolation_id; -} +BGD_DECLARE(gdInterpolationMethod) +gdImageGetInterpolationMethod(gdImagePtr im) { return im->interpolation_id; } #ifdef _MSC_VER -# pragma optimize("", on) +#pragma optimize("", on) #endif diff --git a/ext/gd/libgd/gd_io.c b/ext/gd/libgd/gd_io.c index 1ca822fc9b63..b443ae8856eb 100644 --- a/ext/gd/libgd/gd_io.c +++ b/ext/gd/libgd/gd_io.c @@ -1,205 +1,201 @@ /* - * io.c - * - * Implements the simple I/O 'helper' routines. - * - * Not really essential, but these routines were used extensively in GD, - * so they were moved here. They also make IOCtx calls look better... - * - * Written (or, at least, moved) 1999, Philip Warner. - * + * io.c + * + * Implements the simple I/O 'helper' routines. + * + * Not really essential, but these routines were used extensively in GD, + * so they were moved here. They also make IOCtx calls look better... + * + * Written (or, at least, moved) 1999, Philip Warner. */ +#include "gd.h" #include -#include +#include #include -#include "gd.h" +#include /* Use this for commenting out debug-print statements. */ /* Just use the first '#define' to allow all the prints... */ /*#define IO_DBG(s) (s) */ #define IO_DBG(s) +#define GD_IO_EOF_CHK(r) \ + if (r == EOF) { \ + return 0; \ + } -#define GD_IO_EOF_CHK(r) \ - if (r == EOF) { \ - return 0; \ - } \ +void gdPutC(const unsigned char c, gdIOCtx *ctx) { (ctx->putC)(ctx, c); } -/* - * Write out a word to the I/O context pointer - */ -void Putword (int w, gdIOCtx * ctx) +void gdPutWord(int w, gdIOCtx *ctx) { - unsigned char buf[2]; - - buf[0] = w & 0xff; - buf[1] = (w / 256) & 0xff; - (ctx->putBuf) (ctx, (char *) buf, 2); + IO_DBG(printf("Putting word...\n")); + (ctx->putC)(ctx, (unsigned char)(w >> 8)); + (ctx->putC)(ctx, (unsigned char)(w & 0xFF)); + IO_DBG(printf("put.\n")); } -void Putchar (int c, gdIOCtx * ctx) +void gdPutInt(int w, gdIOCtx *ctx) { - (ctx->putC) (ctx, c & 0xff); + IO_DBG(printf("Putting int...\n")); + (ctx->putC)(ctx, (unsigned char)(w >> 24)); + (ctx->putC)(ctx, (unsigned char)((w >> 16) & 0xFF)); + (ctx->putC)(ctx, (unsigned char)((w >> 8) & 0xFF)); + (ctx->putC)(ctx, (unsigned char)(w & 0xFF)); + IO_DBG(printf("put.\n")); } -void gdPutC (const unsigned char c, gdIOCtx * ctx) -{ - (ctx->putC) (ctx, c); -} +int gdGetC(gdIOCtx *ctx) { return ((ctx->getC)(ctx)); } -void gdPutWord (int w, gdIOCtx * ctx) +int gdGetByte(int *result, gdIOCtx *ctx) { - IO_DBG (gd_error("Putting word...")); - (ctx->putC) (ctx, (unsigned char) (w >> 8)); - (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (gd_error("put.")); -} + int r; -void gdPutInt (int w, gdIOCtx * ctx) -{ - IO_DBG (gd_error("Putting int...")); - (ctx->putC) (ctx, (unsigned char) (w >> 24)); - (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF)); - (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF)); - (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (gd_error("put.")); -} + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } -int gdGetC (gdIOCtx * ctx) -{ - return ((ctx->getC) (ctx)); -} + *result = r; -int gdGetByte (int *result, gdIOCtx * ctx) -{ - int r; - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result = r; - return 1; + return 1; } -int gdGetWord (int *result, gdIOCtx * ctx) +int gdGetWord(int *result, gdIOCtx *ctx) { - int r; - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result = r << 8; - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result += r; - return 1; -} + int r; + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + *result = r << 8; + + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + *result += r; + + return 1; +} int gdGetWordLSB(signed short int *result, gdIOCtx *ctx) { - int high = 0, low = 0; - low = (ctx->getC) (ctx); - if (low == EOF) { - return 0; - } - - high = (ctx->getC) (ctx); - if (high == EOF) { - return 0; - } - - if (result) { - *result = (high << 8) | low; - } - - return 1; + int high = 0, low = 0; + low = (ctx->getC)(ctx); + if (low == EOF) { + return 0; + } + + high = (ctx->getC)(ctx); + if (high == EOF) { + return 0; + } + + if (result) { + *result = (high << 8) | low; + } + + return 1; } -int gdGetInt (int *result, gdIOCtx * ctx) +int gdGetInt(int *result, gdIOCtx *ctx) { - unsigned int r; - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result = r << 24; - - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result += r << 16; - - r = (ctx->getC) (ctx); - if (r == EOF) { - return 0; - } - *result += r << 8; - - r = (ctx->getC) (ctx); - GD_IO_EOF_CHK(r); - *result += r; - - return 1; + int r; + uint32_t value; + + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + value = (uint32_t)r << 24; + + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + value |= (uint32_t)r << 16; + + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + value |= (uint32_t)r << 8; + + r = (ctx->getC)(ctx); + if (r == EOF) { + return 0; + } + + value |= (uint32_t)r; + *result = (int32_t)value; + + return 1; } int gdGetIntLSB(signed int *result, gdIOCtx *ctx) { - unsigned int c; - unsigned int r = 0; - - c = (ctx->getC) (ctx); - if (c == EOF) { - return 0; - } - r |= (c << 24); - r >>= 8; - - c = (ctx->getC) (ctx); - if (c == EOF) { - return 0; - } - r |= (c << 24); - r >>= 8; - - c = (ctx->getC) (ctx); - if (c == EOF) { - return 0; - } - r |= (c << 24); - r >>= 8; - - c = (ctx->getC) (ctx); - if (c == EOF) { - return 0; - } - r |= (c << 24); - - if (result) { - *result = (signed int)r; - } - - return 1; + int c; + uint32_t r; + + c = (ctx->getC)(ctx); + if (c == EOF) { + return 0; + } + r = (uint32_t)c; + + c = (ctx->getC)(ctx); + if (c == EOF) { + return 0; + } + r |= (uint32_t)c << 8; + + c = (ctx->getC)(ctx); + if (c == EOF) { + return 0; + } + r |= (uint32_t)c << 16; + + c = (ctx->getC)(ctx); + if (c == EOF) { + return 0; + } + r |= (uint32_t)c << 24; + + if (result) { + *result = (int32_t)r; + } + + return 1; } -int gdPutBuf (const void *buf, int size, gdIOCtx * ctx) +int gdPutBuf(const void *buf, int size, gdIOCtx *ctx) { - IO_DBG (gd_error("Putting buf...")); - return (ctx->putBuf) (ctx, buf, size); - IO_DBG (gd_error("put.")); + IO_DBG(printf("Putting buf...\n")); + return (ctx->putBuf)(ctx, buf, size); + IO_DBG(printf("put.\n")); } -int gdGetBuf (void *buf, int size, gdIOCtx * ctx) -{ - return (ctx->getBuf) (ctx, buf, size); -} +int gdGetBuf(void *buf, int size, gdIOCtx *ctx) { return (ctx->getBuf)(ctx, buf, size); } -int gdSeek (gdIOCtx * ctx, const int pos) +int gdSeek(gdIOCtx *ctx, const int pos) { - IO_DBG (gd_error("Seeking...")); - return ((ctx->seek) (ctx, pos)); - IO_DBG (gd_error("Done.")); + IO_DBG(printf("Seeking...\n")); + return ((ctx->seek)(ctx, pos)); + IO_DBG(printf("Done.\n")); } -long gdTell (gdIOCtx * ctx) +long gdTell(gdIOCtx *ctx) { - IO_DBG (gd_error("Telling...")); - return ((ctx->tell) (ctx)); - IO_DBG (gd_error ("told.")); + IO_DBG(printf("Telling...\n")); + return ((ctx->tell)(ctx)); + IO_DBG(printf("told.\n")); } diff --git a/ext/gd/libgd/gd_io.h b/ext/gd/libgd/gd_io.h index 00f3a88ed620..7a11748de5dc 100644 --- a/ext/gd/libgd/gd_io.h +++ b/ext/gd/libgd/gd_io.h @@ -8,32 +8,32 @@ #endif typedef struct gdIOCtx { - int (*getC)(struct gdIOCtx*); - int (*getBuf)(struct gdIOCtx*, void*, int); + int (*getC)(struct gdIOCtx *); + int (*getBuf)(struct gdIOCtx *, void *, int); - void (*putC)(struct gdIOCtx*, int); - int (*putBuf)(struct gdIOCtx*, const void*, int); + void (*putC)(struct gdIOCtx *, int); + int (*putBuf)(struct gdIOCtx *, const void *, int); - int (*seek)(struct gdIOCtx*, const int); - long (*tell)(struct gdIOCtx*); + int (*seek)(struct gdIOCtx *, const int); + long (*tell)(struct gdIOCtx *); - void (*gd_free)(struct gdIOCtx*); + void (*gd_free)(struct gdIOCtx *); - void *data; + void *data; } gdIOCtx; -typedef struct gdIOCtx *gdIOCtxPtr; +typedef struct gdIOCtx *gdIOCtxPtr; void Putword(int w, gdIOCtx *ctx); void Putchar(int c, gdIOCtx *ctx); void gdPutC(const unsigned char c, gdIOCtx *ctx); -int gdPutBuf(const void *, int, gdIOCtx*); +int gdPutBuf(const void *, int, gdIOCtx *); void gdPutWord(int w, gdIOCtx *ctx); void gdPutInt(int w, gdIOCtx *ctx); int gdGetC(gdIOCtx *ctx); -int gdGetBuf(void *, int, gdIOCtx*); +int gdGetBuf(void *, int, gdIOCtx *); int gdGetByte(int *result, gdIOCtx *ctx); int gdGetWord(int *result, gdIOCtx *ctx); int gdGetWordLSB(signed short int *result, gdIOCtx *ctx); diff --git a/ext/gd/libgd/gd_io_dp.c b/ext/gd/libgd/gd_io_dp.c index 81b988157fb2..45699e0f7a3b 100644 --- a/ext/gd/libgd/gd_io_dp.c +++ b/ext/gd/libgd/gd_io_dp.c @@ -1,363 +1,426 @@ /* - * io_dp.c - * - * Implements the dynamic pointer interface. - * - * Based on GD.pm code by Lincoln Stein for interfacing to libgd. - * Added support for reading as well as support for 'tell' and 'seek'. - * - * As will all I/O modules, most functions are for local use only (called - * via function pointers in the I/O context). - * - * gdDPExtractData is the exception to this: it will return the pointer to - * the internal data, and reset the internal storage. - * - * Written/Modified 1999, Philip Warner. - * + * io_dp.c + * + * Implements the dynamic pointer interface. + * + * Based on GD.pm code by Lincoln Stein for interfacing to libgd. + * Added support for reading as well as support for 'tell' and 'seek'. + * + * As with all I/O modules, most functions are for local use only (called + * via function pointers in the I/O context). + * + * gdDPExtractData is the exception to this: it will return the pointer to + * the internal data, and reset the internal storage. + * + * Written/Modified 1999, Philip Warner. */ -#include -#include -#include #include "gd.h" #include "gdhelpers.h" +#include +#include +#include #define TRUE 1 #define FALSE 0 /* this is used for creating images in main memory */ -typedef struct dpStruct -{ - void *data; - int logicalSize; - int realSize; - int dataGood; - int pos; - int freeOK; +typedef struct dpStruct { + void *data; + int logicalSize; + int realSize; + int dataGood; + int pos; + int freeOK; } dynamicPtr; -typedef struct dpIOCtx -{ - gdIOCtx ctx; - dynamicPtr *dp; +typedef struct dpIOCtx { + gdIOCtx ctx; + dynamicPtr *dp; } dpIOCtx; typedef struct dpIOCtx *dpIOCtxPtr; /* these functions operate on in-memory dynamic pointers */ -static int allocDynamic (dynamicPtr * dp, int initialSize, void *data); -static int appendDynamic (dynamicPtr * dp, const void *src, int size); -static int gdReallocDynamic (dynamicPtr * dp, int required); -static int trimDynamic (dynamicPtr * dp); -static void gdFreeDynamicCtx (struct gdIOCtx *ctx); -static dynamicPtr *newDynamic (int initialSize, void *data, int freeOKFlag); +static int allocDynamic(dynamicPtr *dp, int initialSize, void *data); +static int appendDynamic(dynamicPtr *dp, const void *src, int size); +static int gdReallocDynamic(dynamicPtr *dp, int required); +static int trimDynamic(dynamicPtr *dp); +static void gdFreeDynamicCtx(gdIOCtxPtr ctx); +static dynamicPtr *newDynamic(int initialSize, void *data, int freeOKFlag); -static int dynamicPutbuf (struct gdIOCtx *, const void *, int); -static void dynamicPutchar (struct gdIOCtx *, int a); +static int dynamicPutbuf(gdIOCtxPtr, const void *, int); +static void dynamicPutchar(gdIOCtxPtr, int a); -static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len); -static int dynamicGetchar (gdIOCtxPtr ctx); +static int dynamicGetbuf(gdIOCtxPtr ctx, void *buf, int len); +static int dynamicGetchar(gdIOCtxPtr ctx); -static int dynamicSeek (struct gdIOCtx *, const int); -static long dynamicTell (struct gdIOCtx *); +static int dynamicSeek(gdIOCtxPtr, const int); +static long dynamicTell(gdIOCtxPtr); -/* return data as a dynamic pointer */ -gdIOCtx * gdNewDynamicCtx (int initialSize, void *data) +/* + Function: gdNewDynamicCtx + + Return data as a dynamic pointer. +*/ +BGD_DECLARE(gdIOCtx *) gdNewDynamicCtx(int initialSize, void *data) { - return gdNewDynamicCtxEx(initialSize, data, 1); + /* 2.0.23: Phil Moore: 'return' keyword was missing! */ + return gdNewDynamicCtxEx(initialSize, data, 1); } -gdIOCtx * gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag) +/* + Function: gdNewDynamicCtxEx +*/ +BGD_DECLARE(gdIOCtx *) +gdNewDynamicCtxEx(int initialSize, void *data, int freeOKFlag) { - dpIOCtx *ctx; - dynamicPtr *dp; + dpIOCtx *ctx; + dynamicPtr *dp; - ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx)); + ctx = (dpIOCtx *)gdMalloc(sizeof(dpIOCtx)); + if (ctx == NULL) { + return NULL; + } - dp = newDynamic(initialSize, data, freeOKFlag); + dp = newDynamic(initialSize, data, freeOKFlag); + if (!dp) { + gdFree(ctx); + return NULL; + }; - ctx->dp = dp; + ctx->dp = dp; - ctx->ctx.getC = dynamicGetchar; - ctx->ctx.putC = dynamicPutchar; + ctx->ctx.getC = dynamicGetchar; + ctx->ctx.putC = dynamicPutchar; - ctx->ctx.getBuf = dynamicGetbuf; - ctx->ctx.putBuf = dynamicPutbuf; + ctx->ctx.getBuf = dynamicGetbuf; + ctx->ctx.putBuf = dynamicPutbuf; - ctx->ctx.seek = dynamicSeek; - ctx->ctx.tell = dynamicTell; + ctx->ctx.seek = dynamicSeek; + ctx->ctx.tell = dynamicTell; - ctx->ctx.gd_free = gdFreeDynamicCtx; + ctx->ctx.gd_free = gdFreeDynamicCtx; - return (gdIOCtx *) ctx; + return (gdIOCtx *)ctx; } -void * gdDPExtractData (struct gdIOCtx *ctx, int *size) +/* + Function: gdDPExtractData +*/ +BGD_DECLARE(void *) gdDPExtractData(gdIOCtxPtr ctx, int *size) { - dynamicPtr *dp; - dpIOCtx *dctx; - void *data; - - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; - - /* clean up the data block and return it */ - if (dp->dataGood) { - trimDynamic (dp); - *size = dp->logicalSize; - data = dp->data; - } else { - *size = 0; - data = NULL; - if (dp->data != NULL && dp->freeOK) { - gdFree(dp->data); - } - } - - dp->data = NULL; - dp->realSize = 0; - dp->logicalSize = 0; - - return data; + dynamicPtr *dp; + dpIOCtx *dctx; + void *data; + + dctx = (dpIOCtx *)ctx; + dp = dctx->dp; + + /* clean up the data block and return it */ + if (dp->dataGood) { + trimDynamic(dp); + *size = dp->logicalSize; + data = dp->data; + } else { + *size = 0; + data = NULL; + /* 2.0.21: never free memory we don't own */ + if ((dp->data != NULL) && (dp->freeOK)) { + gdFree(dp->data); + } + } + + dp->data = NULL; + dp->realSize = 0; + dp->logicalSize = 0; + + return data; } -static void gdFreeDynamicCtx (struct gdIOCtx *ctx) +static void gdFreeDynamicCtx(gdIOCtxPtr ctx) { - dynamicPtr *dp; - dpIOCtx *dctx; + dynamicPtr *dp; + dpIOCtx *dctx; - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; + dctx = (dpIOCtx *)ctx; + dp = dctx->dp; - gdFree(ctx); + gdFree(ctx); - dp->realSize = 0; - dp->logicalSize = 0; + /* clean up the data block and return it */ + /* 2.0.21: never free memory we don't own */ + if ((dp->data != NULL) && (dp->freeOK)) { + gdFree(dp->data); + dp->data = NULL; + } - gdFree(dp); + dp->realSize = 0; + dp->logicalSize = 0; + + gdFree(dp); } -static long dynamicTell (struct gdIOCtx *ctx) +static long dynamicTell(gdIOCtxPtr ctx) { - dpIOCtx *dctx; - - dctx = (dpIOCtx *) ctx; + dpIOCtx *dctx; - return (dctx->dp->pos); + dctx = (dpIOCtx *)ctx; + return (dctx->dp->pos); } -static int dynamicSeek (struct gdIOCtx *ctx, const int pos) +static int dynamicSeek(gdIOCtxPtr ctx, const int pos) { - int bytesNeeded; - dynamicPtr *dp; - dpIOCtx *dctx; - - if (pos < 0) { - return FALSE; - } - dctx = (dpIOCtx *) ctx; - dp = dctx->dp; - - if (!dp->dataGood) { - return FALSE; - } - - bytesNeeded = pos; - if (bytesNeeded > dp->realSize) { - /* 2.0.21 */ - if (!dp->freeOK) { - return FALSE; - } - gdReallocDynamic (dp, dp->realSize * 2); - } - - /* if we get here, we can be sure that we have enough bytes to copy safely */ - - /* Extend the logical size if we seek beyond EOF. */ - if (pos > dp->logicalSize) { - dp->logicalSize = pos; - } - - dp->pos = pos; - - return TRUE; + int bytesNeeded; + dynamicPtr *dp; + dpIOCtx *dctx; + + if (pos < 0) { + return FALSE; + } + dctx = (dpIOCtx *)ctx; + dp = dctx->dp; + + if (!dp->dataGood) { + return FALSE; + } + + bytesNeeded = pos; + if (bytesNeeded > dp->realSize) { + /* 2.0.21 */ + if (!dp->freeOK) { + return FALSE; + } + + if (overflow2(dp->realSize, 2)) { + return FALSE; + } + + if (!gdReallocDynamic(dp, dp->realSize * 2)) { + dp->dataGood = FALSE; + return FALSE; + } + } + + /* if we get here, we can be sure that we have enough bytes + * to copy safely */ + + /* Extend the logical size if we seek beyond EOF. */ + if (pos > dp->logicalSize) { + dp->logicalSize = pos; + }; + + dp->pos = pos; + + return TRUE; } /* return data as a dynamic pointer */ -static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag) +static dynamicPtr *newDynamic(int initialSize, void *data, int freeOKFlag) { - dynamicPtr *dp; - dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr)); + dynamicPtr *dp; - allocDynamic (dp, initialSize, data); + dp = (dynamicPtr *)gdMalloc(sizeof(dynamicPtr)); + if (dp == NULL) { + return NULL; + } + + if (!allocDynamic(dp, initialSize, data)) { + gdFree(dp); + return NULL; + } - dp->pos = 0; - dp->freeOK = freeOKFlag; + dp->pos = 0; + dp->freeOK = freeOKFlag; - return dp; + return dp; } -static int -dynamicPutbuf (struct gdIOCtx *ctx, const void *buf, int size) +static int dynamicPutbuf(gdIOCtxPtr ctx, const void *buf, int size) { - dpIOCtx *dctx; - dctx = (dpIOCtx *) ctx; + dpIOCtx *dctx; + dctx = (dpIOCtx *)ctx; - appendDynamic (dctx->dp, buf, size); + appendDynamic(dctx->dp, buf, size); - if (dctx->dp->dataGood) - { - return size; - } - else - { - return -1; + if (dctx->dp->dataGood) { + return size; + } else { + return -1; }; - } -static void dynamicPutchar (struct gdIOCtx *ctx, int a) +static void dynamicPutchar(gdIOCtxPtr ctx, int a) { - unsigned char b; - dpIOCtxPtr dctx; + unsigned char b; + dpIOCtxPtr dctx; - b = a; - dctx = (dpIOCtxPtr) ctx; + b = a; + dctx = (dpIOCtxPtr)ctx; - appendDynamic(dctx->dp, &b, 1); + appendDynamic(dctx->dp, &b, 1); } -static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len) +/* returns the number of bytes actually read; 0 on EOF and error */ +static int dynamicGetbuf(gdIOCtxPtr ctx, void *buf, int len) { - int rlen, remain; - dpIOCtxPtr dctx; - dynamicPtr *dp; - - dctx = (dpIOCtxPtr) ctx; - dp = dctx->dp; - - remain = dp->logicalSize - dp->pos; - if (remain >= len) { - rlen = len; - } else { - if (remain <= 0) { - return EOF; - } - rlen = remain; - } - - memcpy(buf, (void *) ((char *) dp->data + dp->pos), rlen); - dp->pos += rlen; - - return rlen; + int rlen, remain; + dpIOCtxPtr dctx; + dynamicPtr *dp; + + dctx = (dpIOCtxPtr)ctx; + dp = dctx->dp; + + if (dp->pos < 0 || dp->pos >= dp->realSize) { + return 0; + } + + remain = dp->logicalSize - dp->pos; + if (remain >= len) { + rlen = len; + } else { + if (remain <= 0) { + return 0; + } + + rlen = remain; + } + + if (dp->pos + rlen > dp->realSize) { + rlen = dp->realSize - dp->pos; + } + + if (rlen < 0) { + return 0; + } + + memcpy(buf, (void *)((char *)dp->data + dp->pos), rlen); + dp->pos += rlen; + + return rlen; } -static int dynamicGetchar (gdIOCtxPtr ctx) +static int dynamicGetchar(gdIOCtxPtr ctx) { - unsigned char b; - int rv; - - rv = dynamicGetbuf (ctx, &b, 1); - if (rv != 1) { - return EOF; - } else { - return b; /* (b & 0xff); */ - } + unsigned char b; + int rv; + + rv = dynamicGetbuf(ctx, &b, 1); + + if (rv != 1) { + return EOF; + } else { + return b; /* (b & 0xff); */ + } } /* ********************************************************************* - * InitDynamic - Return a dynamically resizable void* - * - * ********************************************************************* - */ -static int -allocDynamic (dynamicPtr * dp, int initialSize, void *data) + **********************************************************************/ +static int allocDynamic(dynamicPtr *dp, int initialSize, void *data) { + if (data == NULL) { + dp->logicalSize = 0; + dp->dataGood = FALSE; + dp->data = gdMalloc(initialSize); + } else { + dp->logicalSize = initialSize; + dp->dataGood = TRUE; + dp->data = data; + } - if (data == NULL) { - dp->logicalSize = 0; - dp->dataGood = FALSE; - dp->data = gdMalloc(initialSize); - } else { - dp->logicalSize = initialSize; - dp->dataGood = TRUE; - dp->data = data; - } - - dp->realSize = initialSize; - dp->dataGood = TRUE; - dp->pos = 0; - - return TRUE; + if (dp->data != NULL) { + dp->realSize = initialSize; + dp->dataGood = TRUE; + dp->pos = 0; + return TRUE; + } else { + dp->realSize = 0; + return FALSE; + } } /* append bytes to the end of a dynamic pointer */ -static int appendDynamic (dynamicPtr * dp, const void *src, int size) +static int appendDynamic(dynamicPtr *dp, const void *src, int size) { - int bytesNeeded; - char *tmp; + int bytesNeeded; + char *tmp; + + if (!dp->dataGood) { + return FALSE; + } + + /* bytesNeeded = dp->logicalSize + size; */ + bytesNeeded = dp->pos + size; - if (!dp->dataGood) { - return FALSE; - } + if (bytesNeeded > dp->realSize) { + /* 2.0.21 */ + if (!dp->freeOK) { + return FALSE; + } - /* bytesNeeded = dp->logicalSize + size; */ - bytesNeeded = dp->pos + size; + if (overflow2(dp->realSize, 2)) { + return FALSE; + } - if (bytesNeeded > dp->realSize) { - /* 2.0.21 */ - if (!dp->freeOK) { - return FALSE; - } - gdReallocDynamic(dp, bytesNeeded * 2); - } + if (!gdReallocDynamic(dp, bytesNeeded * 2)) { + dp->dataGood = FALSE; + return FALSE; + } + } + + /* if we get here, we can be sure that we have enough bytes + * to copy safely */ - /* if we get here, we can be sure that we have enough bytes to copy safely */ - /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */ + /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */ - tmp = (char *) dp->data; - memcpy((void *) (tmp + (dp->pos)), src, size); - dp->pos += size; + tmp = (char *)dp->data; + memcpy((void *)(tmp + (dp->pos)), src, size); + dp->pos += size; - if (dp->pos > dp->logicalSize) { - dp->logicalSize = dp->pos; - } + if (dp->pos > dp->logicalSize) { + dp->logicalSize = dp->pos; + }; - return TRUE; + return TRUE; } /* grow (or shrink) dynamic pointer */ -static int gdReallocDynamic (dynamicPtr * dp, int required) +static int gdReallocDynamic(dynamicPtr *dp, int required) { - void *newPtr; - - /* First try gdRealloc(). If that doesn't work, make a new memory block and copy. */ - if ((newPtr = gdRealloc(dp->data, required))) { - dp->realSize = required; - dp->data = newPtr; - return TRUE; - } - - /* create a new pointer */ - newPtr = gdMalloc(required); + void *newPtr; + + /* First try gdRealloc(). If that doesn't work, make a new + * memory block and copy. */ + if ((newPtr = gdRealloc(dp->data, required))) { + dp->realSize = required; + dp->data = newPtr; + return TRUE; + } - /* copy the old data into it */ - memcpy(newPtr, dp->data, dp->logicalSize); - gdFree(dp->data); - dp->data = newPtr; + /* create a new pointer */ + newPtr = gdMalloc(required); + if (!newPtr) { + dp->dataGood = FALSE; + return FALSE; + } - dp->realSize = required; + /* copy the old data into it */ + memcpy(newPtr, dp->data, dp->logicalSize); + gdFree(dp->data); + dp->data = newPtr; - return TRUE; + dp->realSize = required; + return TRUE; } /* trim pointer so that its real and logical sizes match */ -static int trimDynamic (dynamicPtr * dp) +static int trimDynamic(dynamicPtr *dp) { - /* 2.0.21: we don't reallocate memory we don't own */ - if (!dp->freeOK) { - return FALSE; - } - return gdReallocDynamic(dp, dp->logicalSize); + /* 2.0.21: we don't reallocate memory we don't own */ + if (!dp->freeOK) { + return TRUE; + } + + return gdReallocDynamic(dp, dp->logicalSize); } diff --git a/ext/gd/libgd/gd_io_file.c b/ext/gd/libgd/gd_io_file.c index 8318a45969a2..4728f596e4f9 100644 --- a/ext/gd/libgd/gd_io_file.c +++ b/ext/gd/libgd/gd_io_file.c @@ -1,128 +1,128 @@ - /* - * io_file.c - * - * Implements the file interface. - * - * As will all I/O modules, most functions are for local use only (called - * via function pointers in the I/O context). - * - * Most functions are just 'wrappers' for standard file functions. - * - * Written/Modified 1999, Philip Warner. - * + * io_file.c + * + * Implements the file interface. + * + * As will all I/O modules, most functions are for local use only (called + * via function pointers in the I/O context). + * + * Most functions are just 'wrappers' for standard file functions. + * + * Written/Modified 1999, Philip Warner. + * */ /* For platforms with incomplete ANSI defines. Fortunately, - SEEK_SET is defined to be zero by the standard. */ + * SEEK_SET is defined to be zero by the standard. */ #ifndef SEEK_SET #define SEEK_SET 0 #endif /* SEEK_SET */ -#include -#include -#include #include "gd.h" #include "gdhelpers.h" +#include +#include +#include /* this is used for creating images in main memory */ -typedef struct fileIOCtx -{ - gdIOCtx ctx; - FILE *f; +typedef struct fileIOCtx { + gdIOCtx ctx; + FILE *f; } fileIOCtx; -gdIOCtx *newFileCtx (FILE * f); +gdIOCtxPtr newFileCtx(FILE *f); -static int fileGetbuf (gdIOCtx *, void *, int); -static int filePutbuf (gdIOCtx *, const void *, int); -static void filePutchar (gdIOCtx *, int); -static int fileGetchar (gdIOCtx * ctx); +static int fileGetbuf(gdIOCtxPtr, void *, int); +static int filePutbuf(gdIOCtxPtr, const void *, int); +static void filePutchar(gdIOCtxPtr, int); +static int fileGetchar(gdIOCtxPtr ctx); -static int fileSeek (struct gdIOCtx *, const int); -static long fileTell (struct gdIOCtx *); -static void gdFreeFileCtx (gdIOCtx * ctx); +static int fileSeek(gdIOCtxPtr, const int); +static long fileTell(gdIOCtxPtr); +static void gdFreeFileCtx(gdIOCtxPtr ctx); -/* return data as a dynamic pointer */ -gdIOCtx * gdNewFileCtx (FILE * f) -{ - fileIOCtx *ctx; +/* + Function: gdNewFileCtx - ctx = (fileIOCtx *) gdMalloc(sizeof (fileIOCtx)); + Return data as a dynamic pointer. +*/ +BGD_DECLARE(gdIOCtxPtr) gdNewFileCtx(FILE *f) +{ + fileIOCtx *ctx; - ctx->f = f; + if (f == NULL) + return NULL; + ctx = (fileIOCtx *)gdMalloc(sizeof(fileIOCtx)); + if (ctx == NULL) { + return NULL; + } - ctx->ctx.getC = fileGetchar; - ctx->ctx.putC = filePutchar; + ctx->f = f; - ctx->ctx.getBuf = fileGetbuf; - ctx->ctx.putBuf = filePutbuf; + ctx->ctx.getC = fileGetchar; + ctx->ctx.putC = filePutchar; - ctx->ctx.tell = fileTell; - ctx->ctx.seek = fileSeek; + ctx->ctx.getBuf = fileGetbuf; + ctx->ctx.putBuf = filePutbuf; - ctx->ctx.gd_free = gdFreeFileCtx; + ctx->ctx.tell = fileTell; + ctx->ctx.seek = fileSeek; - return (gdIOCtx *) ctx; -} + ctx->ctx.gd_free = gdFreeFileCtx; -static void gdFreeFileCtx (gdIOCtx * ctx) -{ - gdFree(ctx); + return (gdIOCtxPtr)ctx; } +static void gdFreeFileCtx(gdIOCtxPtr ctx) { gdFree(ctx); } -static int filePutbuf (gdIOCtx * ctx, const void *buf, int size) +static int filePutbuf(gdIOCtxPtr ctx, const void *buf, int size) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; - - return fwrite(buf, 1, size, fctx->f); + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; + return fwrite(buf, 1, size, fctx->f); } -static int fileGetbuf (gdIOCtx * ctx, void *buf, int size) +static int fileGetbuf(gdIOCtxPtr ctx, void *buf, int size) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; - return fread(buf, 1, size, fctx->f); + return (fread(buf, 1, size, fctx->f)); } -static void filePutchar (gdIOCtx * ctx, int a) +static void filePutchar(gdIOCtxPtr ctx, int a) { - unsigned char b; - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + unsigned char b; + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; - b = a; + b = a; - putc (b, fctx->f); + putc(b, fctx->f); } -static int fileGetchar (gdIOCtx * ctx) +static int fileGetchar(gdIOCtxPtr ctx) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; - return getc (fctx->f); + return getc(fctx->f); } - -static int fileSeek (struct gdIOCtx *ctx, const int pos) +static int fileSeek(gdIOCtxPtr ctx, const int pos) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; - - return (fseek (fctx->f, pos, SEEK_SET) == 0); + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; + return (fseek(fctx->f, pos, SEEK_SET) == 0); } -static long fileTell (struct gdIOCtx *ctx) +static long fileTell(gdIOCtxPtr ctx) { - fileIOCtx *fctx; - fctx = (fileIOCtx *) ctx; + fileIOCtx *fctx; + fctx = (fileIOCtx *)ctx; - return ftell (fctx->f); + return ftell(fctx->f); } diff --git a/ext/gd/libgd/gd_io_ss.c b/ext/gd/libgd/gd_io_ss.c index 0275cdc40330..24c957a3e613 100644 --- a/ext/gd/libgd/gd_io_ss.c +++ b/ext/gd/libgd/gd_io_ss.c @@ -1,138 +1,139 @@ /* - * io_ss.c - * - * Implements the Source/Sink interface. - * - * As will all I/O modules, most functions are for local use only (called - * via function pointers in the I/O context). - * - * The Source/Sink model is the primary 'user' interface for alternate data - * sources; the IOCtx interface is intended (at least in version 1.5) to be - * used internally until it settles down a bit. - * - * This module just layers the Source/Sink interface on top of the IOCtx; no - * support is provided for tell/seek, so GD2 writing is not possible, and - * retrieving parts of GD2 files is also not possible. - * - * A new SS context does not need to be created with both a Source and a Sink. - * - * Written/Modified 1999, Philip Warner. - * + * io_ss.c + * + * Implements the Source/Sink interface. + * + * As will all I/O modules, most functions are for local use only (called + * via function pointers in the I/O context). + * + * The Source/Sink model is the primary 'user' interface for alternate data + * sources; the IOCtx interface is intended (at least in version 1.5) to be + * used internally until it settles down a bit. + * + * This module just layers the Source/Sink interface on top of the IOCtx; no + * support is provided for tell/seek, so GD2 writing is not possible, and + * retrieving parts of GD2 files is also not possible. + * + * A new SS context does not need to be created with both a Source and a Sink. + * + * Written/Modified 1999, Philip Warner. + * */ -#include -#include -#include #include "gd.h" #include "gdhelpers.h" +#include +#include +#include /* this is used for creating images in main memory */ -typedef struct ssIOCtx -{ - gdIOCtx ctx; - gdSourcePtr src; - gdSinkPtr snk; +typedef struct ssIOCtx { + gdIOCtx ctx; + gdSourcePtr src; + gdSinkPtr snk; } ssIOCtx; typedef struct ssIOCtx *ssIOCtxPtr; -gdIOCtx *gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk); +static int sourceGetbuf(gdIOCtx *, void *, int); +static int sourceGetchar(gdIOCtx *ctx); +static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size); +static void sinkPutchar(gdIOCtx *ctx, int a); +static void gdFreeSsCtx(gdIOCtx *ctx); -static int sourceGetbuf (gdIOCtx *, void *, int); -static int sourceGetchar (gdIOCtx * ctx); -static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size); -static void sinkPutchar (gdIOCtx * ctx, int a); -static void gdFreeSsCtx (gdIOCtx * ctx); +/* + Function: gdNewSSCtx -/* return data as a dynamic pointer */ -gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) + Return data as a dynamic pointer. +*/ +BGD_DECLARE(gdIOCtx *) gdNewSSCtx(gdSourcePtr src, gdSinkPtr snk) { - ssIOCtxPtr ctx; - - ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx)); + ssIOCtxPtr ctx; - ctx->src = src; - ctx->snk = snk; + ctx = (ssIOCtxPtr)gdMalloc(sizeof(ssIOCtx)); + if (ctx == NULL) { + return NULL; + } - ctx->ctx.getC = sourceGetchar; - ctx->ctx.getBuf = sourceGetbuf; + ctx->src = src; + ctx->snk = snk; - ctx->ctx.putC = sinkPutchar; - ctx->ctx.putBuf = sinkPutbuf; + ctx->ctx.getC = sourceGetchar; + ctx->ctx.getBuf = sourceGetbuf; - ctx->ctx.tell = NULL; - ctx->ctx.seek = NULL; + ctx->ctx.putC = sinkPutchar; + ctx->ctx.putBuf = sinkPutbuf; - ctx->ctx.gd_free = gdFreeSsCtx; + ctx->ctx.tell = NULL; + ctx->ctx.seek = NULL; - return (gdIOCtx *) ctx; -} + ctx->ctx.gd_free = gdFreeSsCtx; -static void gdFreeSsCtx (gdIOCtx * ctx) -{ - gdFree(ctx); + return (gdIOCtx *)ctx; } +static void gdFreeSsCtx(gdIOCtx *ctx) { gdFree(ctx); } -static int sourceGetbuf (gdIOCtx * ctx, void *buf, int size) +static int sourceGetbuf(gdIOCtx *ctx, void *buf, int size) { - ssIOCtx *lctx; - int res; + ssIOCtx *lctx; + int res; - lctx = (ssIOCtx *) ctx; + lctx = (ssIOCtx *)ctx; - res = ((lctx->src->source) (lctx->src->context, buf, size)); + res = ((lctx->src->source)(lctx->src->context, buf, size)); - /* - * Translate the return values from the Source object: - * 0 is EOF, -1 is error - */ + /* + * Translate the return values from the Source object: + * 0 is EOF, -1 is error + */ - if (res == 0) { - return EOF; - } else if (res < 0) { - return 0; - } else { - return res; - } + if (res == 0) { + return 0; + } else if (res < 0) { + return 0; + } else { + return res; + } } -static int sourceGetchar (gdIOCtx * ctx) +static int sourceGetchar(gdIOCtx *ctx) { - int res; - unsigned char buf; + int res; + unsigned char buf; - res = sourceGetbuf (ctx, &buf, 1); + res = sourceGetbuf(ctx, &buf, 1); - if (res == 1) { - return buf; - } else { - return EOF; - } + if (res == 1) { + return buf; + } else { + return EOF; + } } -static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size) +static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size) { - ssIOCtxPtr lctx; - int res; + ssIOCtxPtr lctx; + int res; - lctx = (ssIOCtx *) ctx; + lctx = (ssIOCtx *)ctx; - res = (lctx->snk->sink) (lctx->snk->context, buf, size); + res = (lctx->snk->sink)(lctx->snk->context, buf, size); - if (res <= 0) { - return 0; - } else { - return res; - } + if (res <= 0) { + return 0; + } else { + return res; + } } -static void sinkPutchar (gdIOCtx * ctx, int a) +static void sinkPutchar(gdIOCtx *ctx, int a) { - unsigned char b; + unsigned char b; + + b = a; - b = a; - sinkPutbuf (ctx, &b, 1); + sinkPutbuf(ctx, &b, 1); } diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index c15a97c7b592..fde1102f4157 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -1,6 +1,6 @@ /* * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the - * gd graphics library (http://www.boutell.com/gd/). + * gd graphics library (https://libgd.github.io). * * This software is based in part on the work of the Independent JPEG * Group. For more information on the IJG JPEG software (and JPEG @@ -21,120 +21,134 @@ * Christian Aberger */ -#include -#include -#include +/** + * File: JPEG IO + * + * Read and write JPEG images. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include +#include #include #include "gd.h" #include "gd_errors.h" +#include "gd_intern.h" /* TBB: move this up so include files are not brought in */ /* JCE: arrange HAVE_LIBJPEG so that it can be set in gd.h */ #ifdef HAVE_LIBJPEG #include "gdhelpers.h" -#undef HAVE_STDLIB_H + +#if defined(_WIN32) && defined(__MINGW32__) +#define HAVE_BOOLEAN +#endif /* 1.8.1: remove dependency on jinclude.h */ -#include "jpeglib.h" #include "jerror.h" +#include "jpeglib.h" static const char *const GD_JPEG_VERSION = "1.0"; -typedef struct _jmpbuf_wrapper -{ - jmp_buf jmpbuf; - int ignore_warning; +typedef struct _jmpbuf_wrapper { + jmp_buf jmpbuf; + int ignore_warning; } jmpbuf_wrapper; -static void php_jpeg_emit_message(j_common_ptr jpeg_info, int level) +static void jpeg_emit_message(j_common_ptr jpeg_info, int level) { - char message[JMSG_LENGTH_MAX]; - jmpbuf_wrapper *jmpbufw; - int ignore_warning = 0; - - jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data; - - if (jmpbufw != 0) { - ignore_warning = jmpbufw->ignore_warning; - } - - (jpeg_info->err->format_message)(jpeg_info,message); - - /* It is a warning message */ - if (level < 0) { - /* display only the 1st warning, as would do a default libjpeg - * unless strace_level >= 3 - */ - if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) { - if (!ignore_warning) { - gd_error("gd-jpeg, libjpeg: recoverable error: %s\n", message); - } - } - - jpeg_info->err->num_warnings++; - } else { - /* strace msg, Show it if trace_level >= level. */ - if (jpeg_info->err->trace_level >= level) { - if (!ignore_warning) { - gd_error("gd-jpeg, libjpeg: strace message: %s\n", message); - } - } - } + char message[JMSG_LENGTH_MAX]; + jmpbuf_wrapper *jmpbufw; + int ignore_warning = 0; + + jmpbufw = (jmpbuf_wrapper *)jpeg_info->client_data; + + if (jmpbufw != 0) { + ignore_warning = jmpbufw->ignore_warning; + } + + (jpeg_info->err->format_message)(jpeg_info, message); + + /* It is a warning message */ + if (level < 0) { + /* display only the 1st warning, as would do a default libjpeg + * unless strace_level >= 3 + */ + if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) { + if (!ignore_warning) { + gd_error("gd-jpeg, libjpeg: recoverable error: %s\n", message); + } + } + + jpeg_info->err->num_warnings++; + } else { + /* strace msg, Show it if trace_level >= level. */ + if (jpeg_info->err->trace_level >= level) { + if (!ignore_warning) { + gd_error("gd-jpeg, libjpeg: strace message: %s\n", message); + } + } + } } - /* Called by the IJG JPEG library upon encountering a fatal error */ -static void fatal_jpeg_error (j_common_ptr cinfo) +static void fatal_jpeg_error(j_common_ptr cinfo) { - jmpbuf_wrapper *jmpbufw; - char buffer[JMSG_LENGTH_MAX]; + jmpbuf_wrapper *jmpbufw; + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - gd_error_ex(GD_WARNING, "gd-jpeg: JPEG library reports unrecoverable error: %s", buffer); + (*cinfo->err->format_message)(cinfo, buffer); + gd_error_ex(GD_WARNING, "gd-jpeg: JPEG library reports unrecoverable error: %s", buffer); - jmpbufw = (jmpbuf_wrapper *) cinfo->client_data; - jpeg_destroy (cinfo); + jmpbufw = (jmpbuf_wrapper *)cinfo->client_data; + jpeg_destroy(cinfo); - if (jmpbufw != 0) { - longjmp (jmpbufw->jmpbuf, 1); - gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating"); - } else { - gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating"); - } + if (jmpbufw != 0) { + longjmp(jmpbufw->jmpbuf, 1); + gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp " + "returned control; terminating\n"); + } else { + gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf " + "unrecoverable; terminating\n"); + } - exit (99); + exit(99); } -const char * gdJpegGetVersionString() +BGD_DECLARE(const char *) gdJpegGetVersionString() { - switch(JPEG_LIB_VERSION) { - case 62: - return "6b"; - break; - - case 70: - return "7"; - break; - - case 80: - return "8"; - break; - - case 90: - return "9 compatible"; - break; - - case 100: - return "10 compatible"; - break; - - default: - return "unknown"; - } + switch (JPEG_LIB_VERSION) { + case 62: + return "6b"; + break; + + case 70: + return "7"; + break; + + case 80: + return "8"; + break; + + case 90: + return "9 compatible"; + break; + + case 100: + return "10 compatible"; + break; + + default: + return "unknown"; + } } -static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality); +static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality, + const gdImageMetadata *metadata, int force_no_subsampling); /* * Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality @@ -145,436 +159,1097 @@ static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality); * library documentation for more details. */ -void gdImageJpeg (gdImagePtr im, FILE * outFile, int quality) +/* + Function: gdImageJpeg + + outputs the specified image to the specified file in + JPEG format. The file must be open for writing. Under MSDOS and + all versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + If _quality_ is negative, the default IJG JPEG quality value (which + should yield a good general quality / size tradeoff for most + situations) is used. Otherwise, for practical purposes, _quality_ + should be a value in the range 0-95, higher quality values usually + implying both higher quality and larger image sizes. + + If you have set image interlacing using , this + function will interpret that to mean you wish to output a + progressive JPEG. Some programs (e.g., Web browsers) can display + progressive JPEGs incrementally; this can be useful when browsing + over a relatively slow communications link, for + example. Progressive JPEGs can also be slightly smaller than + sequential (non-progressive) JPEGs. + + Variants: + + stores the image using a struct. + + stores the image to RAM. + + Parameters: + + im - The image to save + outFile - The FILE pointer to write to. + quality - Compression quality (0-95, 0 means use the default). + + Returns: + + Nothing. + + Example: + (start code) + + gdImagePtr im; + int black, white; + FILE *out; + // Create the image + im = gdImageCreate(100, 100); + // Allocate background + white = gdImageColorAllocate(im, 255, 255, 255); + // Allocate drawing color + black = gdImageColorAllocate(im, 0, 0, 0); + // Draw rectangle + gdImageRectangle(im, 0, 0, 99, 99, black); + // Open output file in binary mode + out = fopen("rect.jpg", "wb"); + // Write JPEG using default quality + gdImageJpeg(im, out, -1); + // Close file + fclose(out); + // Destroy image + gdImageDestroy(im); + + (end code) +*/ + +BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *outFile, int quality) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageJpegCtx(im, out, quality); + out->gd_free(out); +} + +/* + Function: gdImageJpegPtr + + Identical to except that it returns a pointer to a + memory area with the JPEG data. This memory must be freed by the + caller when it is no longer needed. + + The caller *must* invoke , not free(). This is because it + is not guaranteed that libgd will use the same implementation of + malloc, free, etc. as your proggram. + + The 'size' parameter receives the total size of the block of + memory. + + Parameters: + + im - The image to write + size - Output: the size of the resulting image. + quality - Compression quality. + + Returns: + + A pointer to the JPEG data or NULL if an error occurred. + +*/ +BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality) { - gdIOCtx *out = gdNewFileCtx (outFile); - gdImageJpegCtx (im, out, quality); - out->gd_free (out); + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageJpegCtx(im, out, quality, NULL, 0)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; } -void *gdImageJpegPtr (gdImagePtr im, int *size, int quality) +BGD_DECLARE(void *) +gdImageJpegPtrWithMetadata(gdImagePtr im, int *size, int quality, const gdImageMetadata *metadata) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - if (!_gdImageJpegCtx(im, out, quality)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } - out->gd_free (out); + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageJpegCtx(im, out, quality, metadata, 0)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; +} - return rv; +void *gdImageJpegPtrWithMetadataNoSubsampling(gdImagePtr im, int *size, int quality, + const gdImageMetadata *metadata) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageJpegCtx(im, out, quality, metadata, 1)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; } -void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile); +static void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile); + +/* + Function: gdImageJpegCtx + + Write the image as JPEG data via a . See + for more details. + + Parameters: + + im - The image to write. + outfile - The output sink. + quality - Image quality. + +*/ +BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) +{ + _gdImageJpegCtx(im, outfile, quality, NULL, 0); +} -void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) +BGD_DECLARE(void) +gdImageJpegCtxWithMetadata(gdImagePtr im, gdIOCtx *outfile, int quality, + const gdImageMetadata *metadata) { - _gdImageJpegCtx(im, outfile, quality); + _gdImageJpegCtx(im, outfile, quality, metadata, 0); } /* returns 0 on success, 1 on failure */ -static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) -{ - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - int i, j, jidx; - /* volatile so we can gdFree it on return from longjmp */ - volatile JSAMPROW row = 0; - JSAMPROW rowptr[1]; - jmpbuf_wrapper jmpbufw; - JDIMENSION nlines; - char comment[255]; - - memset (&cinfo, 0, sizeof (cinfo)); - memset (&jerr, 0, sizeof (jerr)); - - cinfo.err = jpeg_std_error (&jerr); - cinfo.client_data = &jmpbufw; - if (setjmp (jmpbufw.jmpbuf) != 0) { - /* we're here courtesy of longjmp */ - if (row) { - gdFree (row); - } - return 1; - } +static int gdJpegWriteAppMarker(j_compress_ptr cinfo, int marker, const unsigned char *data, + size_t size) +{ + if (data == NULL && size != 0) { + return 1; + } + if (size > 65533) { + return 1; + } + jpeg_write_marker(cinfo, marker, data, (unsigned int)size); + return 0; +} - cinfo.err->error_exit = fatal_jpeg_error; +static int gdJpegWriteIccProfile(j_compress_ptr cinfo, const unsigned char *data, size_t size) +{ + static const unsigned char icc_signature[] = "ICC_PROFILE"; + unsigned char *segment; + size_t offset = 0; + size_t max_payload = 65533 - 14; + int segment_count; + int segment_index; + + if (data == NULL && size != 0) { + return 1; + } + if (size == 0) { + return 0; + } + if (size > max_payload * 255) { + return 1; + } + + segment_count = (int)((size + max_payload - 1) / max_payload); + segment = (unsigned char *)gdMalloc(65533); + if (segment == NULL) { + return 1; + } + memcpy(segment, icc_signature, 12); + + for (segment_index = 1; segment_index <= segment_count; segment_index++) { + size_t chunk_size = size - offset; + if (chunk_size > max_payload) { + chunk_size = max_payload; + } + segment[12] = (unsigned char)segment_index; + segment[13] = (unsigned char)segment_count; + memcpy(segment + 14, data + offset, chunk_size); + jpeg_write_marker(cinfo, JPEG_APP0 + 2, segment, (unsigned int)(chunk_size + 14)); + offset += chunk_size; + } + + gdFree(segment); + return 0; +} - jpeg_create_compress (&cinfo); +static int gdJpegWriteMetadata(j_compress_ptr cinfo, const gdImageMetadata *metadata) +{ + const unsigned char *data; + size_t size; + + if (metadata == NULL) { + return 0; + } + + data = gdImageMetadataGetProfile(metadata, "exif", &size); + if (data != NULL && gdJpegWriteAppMarker(cinfo, JPEG_APP0 + 1, data, size)) { + return 1; + } + data = gdImageMetadataGetProfile(metadata, "xmp", &size); + if (data != NULL && gdJpegWriteAppMarker(cinfo, JPEG_APP0 + 1, data, size)) { + return 1; + } + data = gdImageMetadataGetProfile(metadata, "icc", &size); + if (data != NULL && gdJpegWriteIccProfile(cinfo, data, size)) { + return 1; + } + data = gdImageMetadataGetProfile(metadata, "iptc", &size); + if (data != NULL && gdJpegWriteAppMarker(cinfo, JPEG_APP0 + 13, data, size)) { + return 1; + } + + return 0; +} - cinfo.image_width = im->sx; - cinfo.image_height = im->sy; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - jpeg_set_defaults (&cinfo); +static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality, + const gdImageMetadata *metadata, int force_no_subsampling) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + int i, j, jidx; + /* volatile so we can gdFree it on return from longjmp */ + volatile JSAMPROW row = 0; + JSAMPROW rowptr[1]; + jmpbuf_wrapper jmpbufw; + JDIMENSION nlines; + char comment[255]; + +#ifdef JPEG_DEBUG + gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); + gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", + JPEG_LIB_VERSION, BITS_IN_JSAMPLE); + if (!im->trueColor) { + for (i = 0; i < im->colorsTotal; i++) { + if (!im->open[i]) { + gd_error_ex(GD_DEBUG, "gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, + im->red[i], im->green[i], im->blue[i]); + } + } + } +#endif /* JPEG_DEBUG */ + + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); + + cinfo.err = jpeg_std_error(&jerr); + cinfo.client_data = &jmpbufw; + + if (setjmp(jmpbufw.jmpbuf) != 0) { + /* we're here courtesy of longjmp */ + if (row) { + gdFree(row); + } + return 1; + } + + cinfo.err->emit_message = jpeg_emit_message; + cinfo.err->error_exit = fatal_jpeg_error; + + jpeg_create_compress(&cinfo); + + cinfo.image_width = im->sx; + cinfo.image_height = im->sy; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + + cinfo.density_unit = 1; + cinfo.X_density = im->res_x; + cinfo.Y_density = im->res_y; + + if (quality >= 0) { + jpeg_set_quality(&cinfo, quality, TRUE); + } + if (force_no_subsampling || quality >= 90) { + for (i = 0; i < cinfo.num_components; i++) { + cinfo.comp_info[i].h_samp_factor = 1; + cinfo.comp_info[i].v_samp_factor = 1; + } + } + + /* If user requests interlace, translate that to progressive JPEG */ + if (gdImageGetInterlaced(im)) { +#ifdef JPEG_DEBUG + gd_error_ex(GD_DEBUG, "gd-jpeg: interlace set, outputting progressive JPEG image\n"); +#endif + jpeg_simple_progression(&cinfo); + } - cinfo.density_unit = 1; - cinfo.X_density = im->res_x; - cinfo.Y_density = im->res_y; + jpeg_gdIOCtx_dest(&cinfo, outfile); - if (quality >= 0) { - jpeg_set_quality (&cinfo, quality, TRUE); - } + row = (JSAMPROW)gdCalloc(1, cinfo.image_width * cinfo.input_components * sizeof(JSAMPLE)); + if (row == 0) { + gd_error("gd-jpeg: error: unable to allocate JPEG row structure: " + "gdCalloc returns NULL\n"); + jpeg_destroy_compress(&cinfo); + return 1; + } - /* If user requests interlace, translate that to progressive JPEG */ - if (gdImageGetInterlaced (im)) { - jpeg_simple_progression (&cinfo); - } + rowptr[0] = row; - jpeg_gdIOCtx_dest (&cinfo, outfile); + jpeg_start_compress(&cinfo, TRUE); - row = (JSAMPROW) safe_emalloc(cinfo.image_width * cinfo.input_components, sizeof(JSAMPLE), 0); - memset(row, 0, cinfo.image_width * cinfo.input_components * sizeof(JSAMPLE)); - rowptr[0] = row; + if (gdJpegWriteMetadata(&cinfo, metadata)) { + gd_error("gd-jpeg: error: unable to write metadata\n"); + goto error; + } - jpeg_start_compress (&cinfo, TRUE); + sprintf(comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),", GD_JPEG_VERSION, + JPEG_LIB_VERSION); - if (quality >= 0) { - snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), quality = %d\n", GD_JPEG_VERSION, JPEG_LIB_VERSION, quality); - } else { - snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), default quality\n", GD_JPEG_VERSION, JPEG_LIB_VERSION); - } - jpeg_write_marker (&cinfo, JPEG_COM, (unsigned char *) comment, (unsigned int) strlen (comment)); - if (im->trueColor) { + if (quality >= 0) { + sprintf(comment + strlen(comment), " quality = %d\n", quality); + } else { + strcat(comment + strlen(comment), " default quality\n"); + } + + jpeg_write_marker(&cinfo, JPEG_COM, (unsigned char *)comment, (unsigned int)strlen(comment)); + if (im->trueColor) { #if BITS_IN_JSAMPLE == 12 - gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry"); - goto error; + gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit\n" + "precision. This is mostly useless, because JPEGs on the web are\n" + "8-bit and such versions of the jpeg library won't read or write\n" + "them. GD doesn't support these unusual images. Edit your\n" + "jmorecfg.h file to specify the correct precision and completely\n" + "'make clean' and 'make install' libjpeg again. Sorry.\n"); + goto error; #endif /* BITS_IN_JSAMPLE == 12 */ - - for (i = 0; i < im->sy; i++) { - for (jidx = 0, j = 0; j < im->sx; j++) { - int val = im->tpixels[i][j]; - - row[jidx++] = gdTrueColorGetRed (val); - row[jidx++] = gdTrueColorGetGreen (val); - row[jidx++] = gdTrueColorGetBlue (val); - } - - nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); - if (nlines != 1) { - gd_error_ex(GD_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); - } - } - } else { - for (i = 0; i < im->sy; i++) { - for (jidx = 0, j = 0; j < im->sx; j++) { - int idx = im->pixels[i][j]; - - /* NB: Although gd RGB values are ints, their max value is - * 255 (see the documentation for gdImageColorAllocate()) - * -- perfect for 8-bit JPEG encoding (which is the norm) - */ + for (i = 0; i < im->sy; i++) { + for (jidx = 0, j = 0; j < im->sx; j++) { + int val = im->tpixels[i][j]; + row[jidx++] = gdTrueColorGetRed(val); + row[jidx++] = gdTrueColorGetGreen(val); + row[jidx++] = gdTrueColorGetBlue(val); + } + + nlines = jpeg_write_scanlines(&cinfo, rowptr, 1); + + if (nlines != 1) { + gd_error("gd_jpeg: warning: jpeg_write_scanlines returns %u -- " + "expected 1\n", + nlines); + } + } + } else { + for (i = 0; i < im->sy; i++) { + for (jidx = 0, j = 0; j < im->sx; j++) { + int idx = im->pixels[i][j]; + + /* + * NB: Although gd RGB values are ints, their max value is + * 255 (see the documentation for gdImageColorAllocate()) + * -- perfect for 8-bit JPEG encoding (which is the norm) + */ #if BITS_IN_JSAMPLE == 8 - row[jidx++] = im->red[idx]; - row[jidx++] = im->green[idx]; - row[jidx++] = im->blue[idx]; + row[jidx++] = im->red[idx]; + row[jidx++] = im->green[idx]; + row[jidx++] = im->blue[idx]; #elif BITS_IN_JSAMPLE == 12 - row[jidx++] = im->red[idx] << 4; - row[jidx++] = im->green[idx] << 4; - row[jidx++] = im->blue[idx] << 4; + row[jidx++] = im->red[idx] << 4; + row[jidx++] = im->green[idx] << 4; + row[jidx++] = im->blue[idx] << 4; #else #error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12 #endif - } - - nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); - if (nlines != 1) { - gd_error_ex(GD_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); - } - } - } + } + + nlines = jpeg_write_scanlines(&cinfo, rowptr, 1); + if (nlines != 1) { + gd_error("gd_jpeg: warning: jpeg_write_scanlines" + " returns %u -- expected 1\n", + nlines); + } + } + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + gdFree(row); + return 0; - jpeg_finish_compress (&cinfo); - jpeg_destroy_compress (&cinfo); - gdFree (row); - return 0; +error: + jpeg_destroy_compress(&cinfo); + if (row) { + gdFree(row); + } + return 1; } -gdImagePtr gdImageCreateFromJpeg (FILE * inFile) +/* + Function: gdImageCreateFromJpeg + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile) { - return gdImageCreateFromJpegEx(inFile, 1); + return gdImageCreateFromJpegEx(inFile, 1); } -gdImagePtr gdImageCreateFromJpegEx (FILE * inFile, int ignore_warning) -{ - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx(inFile); - im = gdImageCreateFromJpegCtxEx(in, ignore_warning); - in->gd_free (in); +/* + Function: gdImageCreateFromJpegEx - return im; -} + is called to load truecolor images from + JPEG format files. Invoke with an + already opened pointer to a file containing the desired + image. returns a to the new + truecolor image, or NULL if unable to load the image (most often + because the file is corrupt or does not contain a JPEG + image). does not close the file. + + You can inspect the sx and sy members of the image to determine + its size. The image must eventually be destroyed using + . -gdImagePtr gdImageCreateFromJpegPtr (int size, void *data) + *The returned image is always a truecolor image.* + + Variants: + + creates an image from JPEG data + already in memory. + + reads its data via the function + pointers in a structure. + + , and + are equivalent to calling their + _Ex_-named counterparts with an ignore_warning set to 1 + (i.e. TRUE). + + Parameters: + + infile - The input FILE pointer. + ignore_warning - Flag. If true, ignores recoverable warnings. + + Returns: + + A pointer to the new *truecolor* image. This will need to be + destroyed with once it is no longer needed. + + On error, returns NULL. + + Example: + (start code) + + gdImagePtr im; + FILE *in; + in = fopen("myjpeg.jpg", "rb"); + im = gdImageCreateFromJpegEx(in, GD_TRUE); + fclose(in); + // ... Use the image ... + gdImageDestroy(im); + + (end code) +*/ +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegEx(FILE *inFile, int ignore_warning) { - return gdImageCreateFromJpegPtrEx(size, data, 1); + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromJpegCtxEx(in, ignore_warning); + in->gd_free(in); + return im; } -gdImagePtr gdImageCreateFromJpegPtrEx (int size, void *data, int ignore_warning) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromJpegCtxEx(in, ignore_warning); - in->gd_free(in); +/* + Function: gdImageCreateFromJpegPtr + + Parameters: - return im; + size - size of JPEG data in bytes. + data - pointer to JPEG data. + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data) +{ + return gdImageCreateFromJpegPtrEx(size, data, 1); } -void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile); +/* + Function: gdImageCreateFromJpegPtrEx -static int CMYKToRGB(int c, int m, int y, int k, int inverted); + Parameters: + size - size of JPEG data in bytes. + data - pointer to JPEG data. + ignore_warning - if true, ignore recoverable warnings -/* - * Create a gd-format image from the JPEG-format INFILE. Returns the - * image, or NULL upon error. - */ -gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile) -{ - return gdImageCreateFromJpegCtxEx(infile, 1); -} - -gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - jmpbuf_wrapper jmpbufw; - /* volatile so we can gdFree them after longjmp */ - volatile JSAMPROW row = 0; - volatile gdImagePtr im = 0; - JSAMPROW rowptr[1]; - unsigned int i, j; - int retval; - JDIMENSION nrows; - int channels = 3; - int inverted = 0; - - memset (&cinfo, 0, sizeof (cinfo)); - memset (&jerr, 0, sizeof (jerr)); - - jmpbufw.ignore_warning = ignore_warning; - - cinfo.err = jpeg_std_error (&jerr); - cinfo.client_data = &jmpbufw; - cinfo.err->emit_message = php_jpeg_emit_message; - - if (setjmp (jmpbufw.jmpbuf) != 0) { - /* we're here courtesy of longjmp */ - if (row) { - gdFree (row); - } - if (im) { - gdImageDestroy (im); - } - return 0; - } + See . +*/ +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return 0; + } + im = gdImageCreateFromJpegCtxEx(in, ignore_warning); + in->gd_free(in); + return im; +} - cinfo.err->error_exit = fatal_jpeg_error; +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrWithMetadata(int size, void *data, gdImageMetadata *metadata) +{ + return gdImageCreateFromJpegPtrExWithMetadata(size, data, 1, metadata); +} - jpeg_create_decompress (&cinfo); +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrExWithMetadata(int size, void *data, int ignore_warning, + gdImageMetadata *metadata) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return 0; + } + im = gdImageCreateFromJpegCtxExWithMetadata(in, ignore_warning, metadata); + in->gd_free(in); + return im; +} - jpeg_gdIOCtx_src (&cinfo, infile); +static void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile); - /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK files with inverted components. */ - jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); +static int CMYKToRGB(int c, int m, int y, int k, int inverted); - retval = jpeg_read_header (&cinfo, TRUE); - if (retval != JPEG_HEADER_OK) { - gd_error_ex(GD_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); - } +static int gdJpegMarkerStartsWith(jpeg_saved_marker_ptr marker, const unsigned char *prefix, + size_t prefix_size) +{ + return marker->data_length >= prefix_size && memcmp(marker->data, prefix, prefix_size) == 0; +} - if (cinfo.image_height > INT_MAX) { - gd_error_ex(GD_WARNING, "gd-jpeg: warning: JPEG image height (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_height, INT_MAX); - } +static int gdJpegCollectIccProfile(j_decompress_ptr cinfo, gdImageMetadata *metadata) +{ + static const unsigned char icc_signature[] = "ICC_PROFILE"; + jpeg_saved_marker_ptr marker; + jpeg_saved_marker_ptr segments[256]; + unsigned int segment_sizes[256]; + unsigned int segment_count = 0; + unsigned int i; + size_t total_size = 0; + size_t offset = 0; + unsigned char *icc; + int status; + + memset(segments, 0, sizeof(segments)); + memset(segment_sizes, 0, sizeof(segment_sizes)); + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + unsigned int sequence; + unsigned int count; + + if (marker->marker != JPEG_APP0 + 2 || !gdJpegMarkerStartsWith(marker, icc_signature, 12) || + marker->data_length < 14) { + continue; + } + + sequence = marker->data[12]; + count = marker->data[13]; + if (sequence == 0 || count == 0 || sequence > count) { + return GD_META_ERR_PARSE; + } + if (segment_count == 0) { + segment_count = count; + } else if (segment_count != count) { + return GD_META_ERR_PARSE; + } + if (segments[sequence] != NULL) { + return GD_META_ERR_PARSE; + } + segments[sequence] = marker; + segment_sizes[sequence] = marker->data_length - 14; + if ((size_t)-1 - total_size < segment_sizes[sequence]) { + return GD_META_ERR_LIMIT; + } + total_size += segment_sizes[sequence]; + } + + if (segment_count == 0) { + return GD_META_OK; + } + + for (i = 1; i <= segment_count; i++) { + if (segments[i] == NULL) { + return GD_META_ERR_PARSE; + } + } + + icc = (unsigned char *)gdMalloc(total_size); + if (icc == NULL && total_size != 0) { + return GD_META_ERR_NOMEM; + } + + for (i = 1; i <= segment_count; i++) { + if (segment_sizes[i] != 0) { + // codechecker_false_positive [all] suppress all checker results + memcpy(icc + offset, segments[i]->data + 14, segment_sizes[i]); + } + offset += segment_sizes[i]; + } + + status = gdImageMetadataSetProfile(metadata, "icc", icc, total_size); + if (icc != NULL) { + gdFree(icc); + } + return status; +} - if (cinfo.image_width > INT_MAX) { - gd_error_ex(GD_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX); - } +static int gdJpegCollectMetadata(j_decompress_ptr cinfo, gdImageMetadata *metadata) +{ + static const unsigned char exif_signature[] = {'E', 'x', 'i', 'f', '\0', '\0'}; + static const unsigned char xmp_signature[] = "http://ns.adobe.com/xap/1.0/"; + static const unsigned char iptc_signature[] = "Photoshop 3.0"; + jpeg_saved_marker_ptr marker; + int status; + + if (metadata == NULL) { + return GD_META_OK; + } + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker->marker == JPEG_APP0 + 1 && + gdJpegMarkerStartsWith(marker, exif_signature, sizeof(exif_signature))) { + status = gdImageMetadataSetProfile(metadata, "exif", marker->data, marker->data_length); + if (status != GD_META_OK) { + return status; + } + } else if (marker->marker == JPEG_APP0 + 1 && + gdJpegMarkerStartsWith(marker, xmp_signature, sizeof(xmp_signature))) { + status = gdImageMetadataSetProfile(metadata, "xmp", marker->data, marker->data_length); + if (status != GD_META_OK) { + return status; + } + } else if (marker->marker == JPEG_APP0 + 13 && + gdJpegMarkerStartsWith(marker, iptc_signature, sizeof(iptc_signature))) { + status = gdImageMetadataSetProfile(metadata, "iptc", marker->data, marker->data_length); + if (status != GD_META_OK) { + return status; + } + } + } + + return gdJpegCollectIccProfile(cinfo, metadata); +} - im = gdImageCreateTrueColor ((int) cinfo.image_width, (int) cinfo.image_height); - if (im == 0) { - gd_error("gd-jpeg error: cannot allocate gdImage struct"); - goto error; - } +/* + Function: gdImageCreateFromJpegCtx - /* check if the resolution is specified */ - switch (cinfo.density_unit) { - case 1: - im->res_x = cinfo.X_density; - im->res_y = cinfo.Y_density; - break; - case 2: - im->res_x = DPCM2DPI(cinfo.X_density); - im->res_y = DPCM2DPI(cinfo.Y_density); - break; - } + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile) +{ + return gdImageCreateFromJpegCtxEx(infile, 1); +} - /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for - * thumbnails but there's no support for fussy adjustment of the - * assumed properties of inks and paper. */ - if ((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) { - cinfo.out_color_space = JCS_CMYK; - } else { - cinfo.out_color_space = JCS_RGB; - } +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxWithMetadata(gdIOCtx *infile, gdImageMetadata *metadata) +{ + return gdImageCreateFromJpegCtxExWithMetadata(infile, 1, metadata); +} - if (jpeg_start_decompress (&cinfo) != TRUE) { - gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source"); - } +/* + Function: gdImageCreateFromJpegCtxEx - /* REMOVED by TBB 2/12/01. This field of the structure is - * documented as private, and sure enough it's gone in the - * latest libjpeg, replaced by something else. Unfortunately - * there is still no right way to find out if the file was - * progressive or not; just declare your intent before you - * write one by calling gdImageInterlace(im, 1) yourself. - * After all, we're not really supposed to rework JPEGs and - * write them out again anyway. Lossy compression, remember? - */ -#if 0 - gdImageInterlace (im, cinfo.progressive_mode != 0); -#endif + See . +*/ +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning) +{ + return gdImageCreateFromJpegCtxExWithMetadata(infile, ignore_warning, NULL); +} - if (cinfo.out_color_space == JCS_RGB) { - if (cinfo.output_components != 3) { - gd_error_ex(GD_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3 for RGB)", cinfo.output_components); - goto error; - } - channels = 3; - } else if (cinfo.out_color_space == JCS_CMYK) { - jpeg_saved_marker_ptr marker; - if (cinfo.output_components != 4) { - gd_error_ex(GD_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 4 for CMYK)", cinfo.output_components); - goto error; - } - channels = 4; - marker = cinfo.marker_list; - while (marker) { - if ((marker->marker == (JPEG_APP0 + 14)) && (marker->data_length >= 12) && (!strncmp((const char *) marker->data, "Adobe", 5))) { - inverted = 1; - break; - } - marker = marker->next; - } - } else { - gd_error_ex(GD_WARNING, "gd-jpeg: error: unexpected colorspace."); - goto error; - } +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxExWithMetadata(gdIOCtx *infile, int ignore_warning, + gdImageMetadata *metadata) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + jmpbuf_wrapper jmpbufw; + /* volatile so we can gdFree them after longjmp */ + volatile JSAMPROW row = 0; + volatile gdImagePtr im = 0; + JSAMPROW rowptr[1]; + JDIMENSION i, j; + int retval; + JDIMENSION nrows; + int channels = 3; + int inverted = 0; + +#ifdef JPEG_DEBUG + gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); + gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", + JPEG_LIB_VERSION, BITS_IN_JSAMPLE); + gd_error_ex(GD_DEBUG, "sizeof: %d\n", sizeof(struct jpeg_decompress_struct)); +#endif + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); + + jmpbufw.ignore_warning = ignore_warning; + + cinfo.err = jpeg_std_error(&jerr); + cinfo.client_data = &jmpbufw; + + cinfo.err->emit_message = jpeg_emit_message; + + if (setjmp(jmpbufw.jmpbuf) != 0) { + /* we're here courtesy of longjmp */ + if (row) { + gdFree(row); + } + if (im) { + gdImageDestroy(im); + } + return 0; + } + + cinfo.err->error_exit = fatal_jpeg_error; + + jpeg_create_decompress(&cinfo); + + jpeg_gdIOCtx_src(&cinfo, infile); + + /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK + * files with inverted components. + */ + jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); + if (metadata != NULL) { + jpeg_save_markers(&cinfo, JPEG_APP0 + 1, 0xFFFF); + jpeg_save_markers(&cinfo, JPEG_APP0 + 2, 0xFFFF); + jpeg_save_markers(&cinfo, JPEG_APP0 + 13, 0xFFFF); + } + + retval = jpeg_read_header(&cinfo, TRUE); + if (retval != JPEG_HEADER_OK) { + gd_error("gd-jpeg: warning: jpeg_read_header returns" + " %d, expected %d\n", + retval, JPEG_HEADER_OK); + } + + retval = gdJpegCollectMetadata(&cinfo, metadata); + if (retval != GD_META_OK) { + gd_error("gd-jpeg: error: unable to read metadata\n"); + goto error; + } + + if (cinfo.image_height > INT_MAX) { + gd_error("gd-jpeg: warning: JPEG image height (%u) is" + " greater than INT_MAX (%d) (and thus greater than" + " gd can handle)", + cinfo.image_height, INT_MAX); + } + + if (cinfo.image_width > INT_MAX) { + gd_error("gd-jpeg: warning: JPEG image width (%u) is" + " greater than INT_MAX (%d) (and thus greater than" + " gd can handle)\n", + cinfo.image_width, INT_MAX); + } + + im = gdImageCreateTrueColor((int)cinfo.image_width, (int)cinfo.image_height); + if (im == 0) { + gd_error("gd-jpeg error: cannot allocate gdImage struct\n"); + goto error; + } + + /* check if the resolution is specified */ + switch (cinfo.density_unit) { + case 1: + im->res_x = cinfo.X_density; + im->res_y = cinfo.Y_density; + break; + case 2: + im->res_x = DPCM2DPI(cinfo.X_density); + im->res_y = DPCM2DPI(cinfo.Y_density); + break; + } + + /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for + * thumbnails but there's no support for fussy adjustment of the + * assumed properties of inks and paper. + */ + if ((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) { + cinfo.out_color_space = JCS_CMYK; + } else { + cinfo.out_color_space = JCS_RGB; + } + + if (jpeg_start_decompress(&cinfo) != TRUE) { + gd_error("gd-jpeg: warning: jpeg_start_decompress" + " reports suspended data source\n"); + } + +#ifdef JPEG_DEBUG + gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG image information:"); + if (cinfo.saw_JFIF_marker) { + gd_error_ex(GD_DEBUG, " JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, + (int)cinfo.JFIF_minor_version); + } else if (cinfo.saw_Adobe_marker) { + gd_error_ex(GD_DEBUG, " Adobe format"); + } else { + gd_error_ex(GD_DEBUG, " UNKNOWN format"); + } + + gd_error_ex(GD_DEBUG, " %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width, + cinfo.image_height, cinfo.output_width, cinfo.output_height, cinfo.data_precision); + gd_error_ex(GD_DEBUG, " %s", (cinfo.progressive_mode ? "progressive" : "baseline")); + gd_error_ex(GD_DEBUG, " image, %d quantized colors, ", cinfo.actual_number_of_colors); + + switch (cinfo.jpeg_color_space) { + case JCS_GRAYSCALE: + gd_error_ex(GD_DEBUG, "grayscale"); + break; + + case JCS_RGB: + gd_error_ex(GD_DEBUG, "RGB"); + break; + + case JCS_YCbCr: + gd_error_ex(GD_DEBUG, "YCbCr (a.k.a. YUV)"); + break; + + case JCS_CMYK: + gd_error_ex(GD_DEBUG, "CMYK"); + break; + + case JCS_YCCK: + gd_error_ex(GD_DEBUG, "YCbCrK"); + break; + + default: + gd_error_ex(GD_DEBUG, "UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space); + break; + } + + gd_error_ex(GD_DEBUG, " colorspace\n"); + fflush(stdout); +#endif /* JPEG_DEBUG */ + + /* REMOVED by TBB 2/12/01. This field of the structure is + * documented as private, and sure enough it's gone in the + * latest libjpeg, replaced by something else. Unfortunately + * there is still no right way to find out if the file was + * progressive or not; just declare your intent before you + * write one by calling gdImageInterlace(im, 1) yourself. + * After all, we're not really supposed to rework JPEGs and + * write them out again anyway. Lossy compression, remember? */ +#if 0 + gdImageInterlace (im, cinfo.progressive_mode != 0); +#endif + if (cinfo.out_color_space == JCS_RGB) { + if (cinfo.output_components != 3) { + gd_error("gd-jpeg: error: JPEG color quantization" + " request resulted in output_components == %d" + " (expected 3 for RGB)\n", + cinfo.output_components); + goto error; + } + channels = 3; + } else if (cinfo.out_color_space == JCS_CMYK) { + jpeg_saved_marker_ptr marker; + if (cinfo.output_components != 4) { + gd_error("gd-jpeg: error: JPEG color quantization" + " request resulted in output_components == %d" + " (expected 4 for CMYK)\n", + cinfo.output_components); + goto error; + } + channels = 4; + + marker = cinfo.marker_list; + while (marker) { + if ((marker->marker == (JPEG_APP0 + 14)) && (marker->data_length >= 12) && + (!strncmp((const char *)marker->data, "Adobe", 5))) { + inverted = 1; + break; + } + marker = marker->next; + } + } else { + gd_error("gd-jpeg: error: unexpected colorspace\n"); + goto error; + } #if BITS_IN_JSAMPLE == 12 - gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry."); - goto error; + gd_error_ex(GD_ERROR, "gd-jpeg: error: jpeg library was compiled for 12-bit\n" + "precision. This is mostly useless, because JPEGs on the web are\n" + "8-bit and such versions of the jpeg library won't read or write\n" + "them. GD doesn't support these unusual images. Edit your\n" + "jmorecfg.h file to specify the correct precision and completely\n" + "'make clean' and 'make install' libjpeg again. Sorry.\n"); + goto error; #endif /* BITS_IN_JSAMPLE == 12 */ - row = safe_emalloc(cinfo.output_width * channels, sizeof(JSAMPLE), 0); - memset(row, 0, cinfo.output_width * channels * sizeof(JSAMPLE)); - rowptr[0] = row; - - if (cinfo.out_color_space == JCS_CMYK) { - for (i = 0; i < cinfo.output_height; i++) { - register JSAMPROW currow = row; - register int *tpix = im->tpixels[i]; - nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); - if (nrows != 1) { - gd_error_ex(GD_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); - goto error; - } - for (j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { - *tpix = CMYKToRGB (currow[0], currow[1], currow[2], currow[3], inverted); - } - } - } else { - for (i = 0; i < cinfo.output_height; i++) { - register JSAMPROW currow = row; - register int *tpix = im->tpixels[i]; - nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); - if (nrows != 1) { - gd_error_ex(GD_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); - goto error; - } - for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { - *tpix = gdTrueColor (currow[0], currow[1], currow[2]); - } - } - } + row = gdCalloc(cinfo.output_width * channels, sizeof(JSAMPLE)); + if (row == 0) { + gd_error("gd-jpeg: error: unable to allocate row for" + " JPEG scanline: gdCalloc returns NULL\n"); + goto error; + } + rowptr[0] = row; + if (cinfo.out_color_space == JCS_CMYK) { + for (i = 0; i < cinfo.output_height; i++) { + register JSAMPROW currow = row; + register int *tpix = im->tpixels[i]; + nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); + if (nrows != 1) { + gd_error("gd-jpeg: error: jpeg_read_scanlines" + " returns %u, expected 1\n", + nrows); + goto error; + } + for (j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { + *tpix = CMYKToRGB(currow[0], currow[1], currow[2], currow[3], inverted); + } + } + } else { + for (i = 0; i < cinfo.output_height; i++) { + register JSAMPROW currow = row; + register int *tpix = im->tpixels[i]; + nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); + if (nrows != 1) { + gd_error("gd-jpeg: error: jpeg_read_scanlines" + " returns %u, expected 1\n", + nrows); + goto error; + } + for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { + *tpix = gdTrueColor(currow[0], currow[1], currow[2]); + } + } + } + + if (jpeg_finish_decompress(&cinfo) != TRUE) { + gd_error("gd-jpeg: warning: jpeg_finish_decompress" + " reports suspended data source\n"); + } + /* TBB 2.0.29: we should do our best to read whatever we can read, and a + * warning is a warning. A fatal error on warnings doesn't make sense. */ +#if 0 + /* This was originally added by Truxton Fulton */ + if (cinfo.err->num_warnings > 0) + goto error; +#endif - if (jpeg_finish_decompress (&cinfo) != TRUE) { - gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); - } - if (!ignore_warning) { - if (cinfo.err->num_warnings > 0) { - goto error; - } - } + jpeg_destroy_decompress(&cinfo); + gdFree(row); + return im; - jpeg_destroy_decompress (&cinfo); - gdFree (row); +error: + jpeg_destroy_decompress(&cinfo); - return im; + if (row) { + gdFree(row); + } + if (im) { + gdImageDestroy(im); + } -error: - jpeg_destroy_decompress (&cinfo); - if (row) { - gdFree (row); - } - if (im) { - gdImageDestroy (im); - } - return 0; + return 0; } /* A very basic conversion approach, TBB */ + static int CMYKToRGB(int c, int m, int y, int k, int inverted) { + if (inverted) { + c = 255 - c; + m = 255 - m; + y = 255 - y; + k = 255 - k; + } + + return gdTrueColor((255 - c) * (255 - k) / 255, (255 - m) * (255 - k) / 255, + (255 - y) * (255 - k) / 255); +#if 0 if (inverted) { c = 255 - c; m = 255 - m; y = 255 - y; k = 255 - k; } - return gdTrueColor((255 - c) * (255 - k) / 255, (255 - m) * (255 - k) / 255, (255 - y) * (255 - k) / 255); + c = c * (255 - k) / 255 + k; + if (c > 255) { + c = 255; + } + if (c < 0) { + c = 0; + } + m = m * (255 - k) / 255 + k; + if (m > 255) { + m = 255; + } + if (m < 0) { + m = 0; + } + y = y * (255 - k) / 255 + k; + if (y > 255) { + y = 255; + } + if (y < 0) { + y = 0; + } + c = 255 - c; + m = 255 - m; + y = 255 - y; + return gdTrueColor (c, m, y); +#endif } /* * gdIOCtx JPEG data sources and sinks, T. Boutell * almost a simple global replace from T. Lane's stdio versions. - * */ /* Expanded data source object for gdIOCtx input */ - -typedef struct -{ - struct jpeg_source_mgr pub; /* public fields */ - - gdIOCtx *infile; /* source stream */ - unsigned char *buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + gdIOCtx *infile; /* source stream */ + unsigned char *buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ } my_source_mgr; typedef my_source_mgr *my_src_ptr; -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ /* * Initialize source --- called by jpeg_read_header * before any data is actually read. */ -void init_source (j_decompress_ptr cinfo) +static void init_source(j_decompress_ptr cinfo) { - my_src_ptr src = (my_src_ptr) cinfo->src; + my_src_ptr src = (my_src_ptr)cinfo->src; - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; } - /* * Fill the input buffer --- called whenever buffer is emptied. * @@ -610,48 +1285,46 @@ void init_source (j_decompress_ptr cinfo) #define END_JPEG_SEQUENCE "\r\n[*]--:END JPEG:--[*]\r\n" -boolean fill_input_buffer (j_decompress_ptr cinfo) +static boolean fill_input_buffer(j_decompress_ptr cinfo) { - my_src_ptr src = (my_src_ptr) cinfo->src; - /* 2.0.12: signed size. Thanks to Geert Jansen */ - ssize_t nbytes = 0; - - /* ssize_t got; */ - /* char *s; */ - memset(src->buffer, 0, INPUT_BUF_SIZE); - - while (nbytes < INPUT_BUF_SIZE) { - int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile); - - if (got == EOF || got == 0) { - /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */ - if (!nbytes) { - nbytes = -1; - } - break; - } - nbytes += got; - } - - if (nbytes <= 0) { - if (src->start_of_file) { /* Treat empty input file as fatal error */ - ERREXIT (cinfo, JERR_INPUT_EMPTY); - } - WARNMS (cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (unsigned char) 0xFF; - src->buffer[1] = (unsigned char) JPEG_EOI; - nbytes = 2; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; + my_src_ptr src = (my_src_ptr)cinfo->src; + /* 2.0.12: signed size. Thanks to Geert Jansen */ + ssize_t nbytes = 0; + memset(src->buffer, 0, INPUT_BUF_SIZE); + + while (nbytes < INPUT_BUF_SIZE) { + int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile); + + if ((got == EOF) || (got == 0)) { + /* EOF or error. If we got any data, don't worry about it. + * If we didn't, then this is unexpected. */ + if (!nbytes) { + nbytes = -1; + } + break; + } + nbytes += got; + } + + if (nbytes <= 0) { + if (src->start_of_file) { + /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + } + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (unsigned char)0xFF; + src->buffer[1] = (unsigned char)JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; } - /* * Skip data --- used to skip over a potentially large amount of * uninteresting data (such as an APPn marker). @@ -664,27 +1337,26 @@ boolean fill_input_buffer (j_decompress_ptr cinfo) * buffer is the application writer's problem. */ -void skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* Just a dumb implementation for now. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) { - while (num_bytes > (long) src->pub.bytes_in_buffer) { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) fill_input_buffer (cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } +static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr)cinfo->src; + + /* Just a dumb implementation for now. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long)src->pub.bytes_in_buffer) { + num_bytes -= (long)src->pub.bytes_in_buffer; + (void)fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t)num_bytes; + src->pub.bytes_in_buffer -= (size_t)num_bytes; + } } - /* * An additional method that can be provided by data source modules is the * resync_to_restart method for error recovery in the presence of RST markers. @@ -693,7 +1365,6 @@ void skip_input_data (j_decompress_ptr cinfo, long num_bytes) * is possible. */ - /* * Terminate source --- called by jpeg_finish_decompress * after all data has been read. Often a no-op. @@ -702,15 +1373,7 @@ void skip_input_data (j_decompress_ptr cinfo, long num_bytes) * application must deal with any cleanup that should happen even * for error exit. */ - -void term_source (j_decompress_ptr cinfo) -{ -#if 0 - * never used */ - my_src_ptr src = (my_src_ptr) cinfo->src; -#endif -} - +static void term_source(j_decompress_ptr cinfo) { (void)cinfo; } /* * Prepare for input from a gdIOCtx stream. @@ -718,66 +1381,66 @@ void term_source (j_decompress_ptr cinfo) * for closing it after finishing decompression. */ -void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile) +static void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile) { - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof (unsigned char)); - - } - - src = (my_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->infile = infile; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { + /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr)); + src = (my_src_ptr)cinfo->src; + src->buffer = (unsigned char *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof(unsigned char)); + } + + src = (my_src_ptr)cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ } /* Expanded data destination object for stdio output */ - -typedef struct -{ - struct jpeg_destination_mgr pub; /* public fields */ - gdIOCtx *outfile; /* target stream */ - unsigned char *buffer; /* start of buffer */ +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + gdIOCtx *outfile; /* target stream */ + unsigned char *buffer; /* start of buffer */ } my_destination_mgr; typedef my_destination_mgr *my_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ /* * Initialize destination --- called by jpeg_start_compress * before any data is actually written. */ -void init_destination (j_compress_ptr cinfo) +static void init_destination(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + my_dest_ptr dest = (my_dest_ptr)cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof (unsigned char)); + /* Allocate the output buffer --- it will be released when done with image + */ + dest->buffer = (unsigned char *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(unsigned char)); - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } - /* * Empty the output buffer --- called whenever buffer fills up. * @@ -801,21 +1464,20 @@ void init_destination (j_compress_ptr cinfo) * write it out when emptying the buffer externally. */ -boolean empty_output_buffer (j_compress_ptr cinfo) +static boolean empty_output_buffer(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + my_dest_ptr dest = (my_dest_ptr)cinfo->dest; - if (gdPutBuf (dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t) OUTPUT_BUF_SIZE) { - ERREXIT (cinfo, JERR_FILE_WRITE); - } + if (gdPutBuf(dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t)OUTPUT_BUF_SIZE) { + ERREXIT(cinfo, JERR_FILE_WRITE); + } - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - return TRUE; + return TRUE; } - /* * Terminate destination --- called by jpeg_finish_compress * after all data has been written. Usually needs to flush buffer. @@ -825,43 +1487,200 @@ boolean empty_output_buffer (j_compress_ptr cinfo) * for error exit. */ -void term_destination (j_compress_ptr cinfo) +static void term_destination(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - - /* Write any data remaining in the buffer */ - if (datacount > 0 && ((size_t)gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)) { - ERREXIT (cinfo, JERR_FILE_WRITE); - } + my_dest_ptr dest = (my_dest_ptr)cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if ((size_t)gdPutBuf(dest->buffer, datacount, dest->outfile) != datacount) { + ERREXIT(cinfo, JERR_FILE_WRITE); + } + } } - /* * Prepare for output to a stdio stream. * The caller must have already opened the stream, and is responsible * for closing it after finishing compression. */ -void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile) +static void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile) { - my_dest_ptr dest; + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { + /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_destination_mgr)); + } + + dest = (my_dest_ptr)cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} - /* The destination object is made permanent so that multiple JPEG images - * can be written to the same file without re-executing jpeg_stdio_dest. - * This makes it dangerous to use this manager and a different destination - * manager serially with the same JPEG object, because their private object - * sizes may be different. Caveat programmer. - */ - if (cinfo->dest == NULL) { /* first time for this JPEG object? */ - cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_destination_mgr)); - } +#else /* !HAVE_LIBJPEG */ + +static void _noJpegError(void) { gd_error("JPEG image support has been disabled\n"); } + +BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *outFile, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + ARG_NOT_USED(quality); + _noJpegError(); +} + +BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(quality); + _noJpegError(); + return NULL; +} - dest = (my_dest_ptr) cinfo->dest; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->outfile = outfile; +BGD_DECLARE(void *) +gdImageJpegPtrWithMetadata(gdImagePtr im, int *size, int quality, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(quality); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; +} + +void *gdImageJpegPtrWithMetadataNoSubsampling(gdImagePtr im, int *size, int quality, + const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(quality); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(quality); + _noJpegError(); +} + +BGD_DECLARE(void) +gdImageJpegCtxWithMetadata(gdImagePtr im, gdIOCtx *outfile, int quality, + const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(quality); + ARG_NOT_USED(metadata); + _noJpegError(); +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegEx(FILE *inFile, int ignore_warning) +{ + ARG_NOT_USED(inFile); + ARG_NOT_USED(ignore_warning); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + ARG_NOT_USED(ignore_warning); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrWithMetadata(int size, void *data, gdImageMetadata *metadata) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegPtrExWithMetadata(int size, void *data, int ignore_warning, + gdImageMetadata *metadata) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + ARG_NOT_USED(ignore_warning); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile) +{ + ARG_NOT_USED(infile); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning) +{ + ARG_NOT_USED(infile); + ARG_NOT_USED(ignore_warning); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxWithMetadata(gdIOCtx *infile, gdImageMetadata *metadata) +{ + ARG_NOT_USED(infile); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromJpegCtxExWithMetadata(gdIOCtx *infile, int ignore_warning, + gdImageMetadata *metadata) +{ + ARG_NOT_USED(infile); + ARG_NOT_USED(ignore_warning); + ARG_NOT_USED(metadata); + _noJpegError(); + return NULL; } #endif /* HAVE_LIBJPEG */ diff --git a/ext/gd/libgd/gd_jxl.c b/ext/gd/libgd/gd_jxl.c new file mode 100644 index 000000000000..77e0c576cbc5 --- /dev/null +++ b/ext/gd/libgd/gd_jxl.c @@ -0,0 +1,1507 @@ +/** + * File: JPEG XL IO + * + * Read and write JPEG XL images. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "gd.h" +#include "gd_errors.h" +#include "gd_intern.h" +#include "gdhelpers.h" +#include +#include +#include +#include + +#ifdef HAVE_LIBJXL +#include +#include +#include +#include + +#define GD_JXL_ALLOC_STEP (4 * 1024) + +/* ---- Internal helpers ---- */ + +/* Slurp gdIOCtx into dynamic buffer (pattern from gd_webp.c) */ +static uint8_t *JxlReadCtxData(gdIOCtx *infile, size_t *size) +{ + uint8_t *filedata = NULL, *temp, *read; + ssize_t n; + + *size = 0; + do { + temp = gdRealloc(filedata, *size + GD_JXL_ALLOC_STEP); + if (temp == NULL) { + gdFree(filedata); + gd_error("JXL decode: realloc failed"); + return NULL; + } + filedata = temp; + read = temp + *size; + n = gdGetBuf(read, GD_JXL_ALLOC_STEP, infile); + if (n > 0 && n != EOF) { + *size += n; + } + } while (n > 0 && n != EOF); + + if (*size == 0) { + gdFree(filedata); + return NULL; + } + + return filedata; +} + +/* JXL alpha (0-255) -> gd alpha (0-127, 0=opaque) */ +static int JxlAlphaJxlToGd(uint8_t jxl_alpha) +{ + if (jxl_alpha == 0) { + return gdAlphaTransparent; + } + return gdAlphaMax - (jxl_alpha >> 1); +} + +/* gd alpha (0-127) -> JXL alpha (0-255) */ +static uint8_t JxlAlphaGdToJxl(int gd_alpha) +{ + if (gd_alpha == gdAlphaTransparent) { + return 0; + } + return (uint8_t)((gdAlphaMax - gd_alpha) << 1); +} + +static int JxlImageHasAlpha(gdImagePtr im) +{ + int x, y; + + if (im == NULL) { + return 0; + } + + for (y = 0; y < gdImageSY(im); y++) { + for (x = 0; x < gdImageSX(im); x++) { + if (gdTrueColorGetAlpha(im->tpixels[y][x]) != gdAlphaOpaque) { + return 1; + } + } + } + + return 0; +} + +static int JxlDurationToMs(uint32_t duration, const JxlAnimationHeader *animation) +{ + if (animation == NULL || animation->tps_numerator == 0) { + return 0; + } + + return (int)((uint64_t)duration * 1000 * animation->tps_denominator / animation->tps_numerator); +} + +/* Build gdImagePtr from RGBA u8 buffer */ +static gdImagePtr JxlImageFromRGBA(const uint8_t *rgba, int width, int height, int has_alpha) +{ + gdImagePtr im; + const uint8_t *p; + int x, y; + + if (rgba == NULL || width <= 0 || height <= 0) { + return NULL; + } + im = gdImageCreateTrueColor(width, height); + if (im == NULL) { + return NULL; + } + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, has_alpha); + for (y = 0, p = rgba; y < height; y++) { + for (x = 0; x < width; x++) { + uint8_t r = *(p++); + uint8_t g = *(p++); + uint8_t b = *(p++); + uint8_t a = *(p++); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, JxlAlphaJxlToGd(a)); + } + } + return im; +} + +/* Extract RGBA u8 buffer from gdImagePtr */ +static int JxlImageToRGBA(gdImagePtr im, uint8_t **rgba, int *has_alpha) +{ + uint8_t *p; + int x, y; + int w, h; + + *rgba = NULL; + *has_alpha = 0; + + if (im == NULL) { + return 0; + } + + /* Convert palette to truecolor if needed */ + if (!gdImageTrueColor(im)) { + gdImagePaletteToTrueColor(im); + } + + w = gdImageSX(im); + h = gdImageSY(im); + + /* Check for alpha presence */ + if (gdImageGetTransparent(im) != -1 || JxlImageHasAlpha(im)) { + *has_alpha = 1; + } + + /* Overflow checks */ + if (overflow2(w, 4)) { + return 0; + } + if (overflow2(w * 4, h)) { + return 0; + } + + *rgba = (uint8_t *)gdMalloc((size_t)w * 4 * (size_t)h); + if (*rgba == NULL) { + return 0; + } + + p = *rgba; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + int c = im->tpixels[y][x]; + *(p++) = gdTrueColorGetRed(c); + *(p++) = gdTrueColorGetGreen(c); + *(p++) = gdTrueColorGetBlue(c); + *(p++) = JxlAlphaGdToJxl(gdTrueColorGetAlpha(c)); + } + } + return 1; +} + +static uint8_t *JxlRGBFromRGBA(const uint8_t *rgba, int width, int height) +{ + uint8_t *rgb, *dst; + const uint8_t *src; + int x, y; + + if (overflow2(width, 3) || overflow2(width * 3, height)) { + return NULL; + } + + rgb = (uint8_t *)gdMalloc((size_t)width * 3 * (size_t)height); + if (rgb == NULL) { + return NULL; + } + + src = rgba; + dst = rgb; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src++; + } + } + + return rgb; +} + +/* ---- Still-image decode ---- */ + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxl(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (!in) { + return 0; + } + im = gdImageCreateFromJxlCtx(in); + in->gd_free(in); + return im; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return 0; + } + im = gdImageCreateFromJxlCtx(in); + in->gd_free(in); + return im; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlCtx(gdIOCtxPtr inCtx) +{ + size_t buf_len = 0; + uint8_t *buf = NULL; + JxlDecoder *dec = NULL; + JxlBasicInfo info = {0}; + uint8_t *pixels = NULL; + gdImagePtr im = NULL; + int has_alpha = 0; + int have_basic_info = 0; + + if (inCtx == NULL) { + return NULL; + } + + buf = JxlReadCtxData(inCtx, &buf_len); + if (buf == NULL) { + return NULL; + } + + dec = JxlDecoderCreate(NULL); + if (dec == NULL) { + gd_error("gdImageCreateFromJxl: JxlDecoderCreate failed"); + gdFree(buf); + return NULL; + } + + JxlDecoderSubscribeEvents(dec, + JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE); + + /* Attach CMS for color space conversion to sRGB */ + JxlDecoderSetCms(dec, *JxlGetDefaultCms()); + + /* Set desired output color profile (sRGB) */ + JxlColorEncoding srgb_enc; + JxlColorEncodingSetToSRGB(&srgb_enc, JXL_FALSE); + JxlDecoderSetPreferredColorProfile(dec, &srgb_enc); + + JxlDecoderSetInput(dec, buf, buf_len); + JxlDecoderCloseInput(dec); + + for (;;) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec); + + if (status == JXL_DEC_BASIC_INFO) { + status = JxlDecoderGetBasicInfo(dec, &info); + if (status != JXL_DEC_SUCCESS) { + gd_error("gdImageCreateFromJxl: failed to get basic info"); + goto decode_fail; + } + have_basic_info = 1; + has_alpha = (info.alpha_bits > 0); + } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { + JxlPixelFormat fmt = {.num_channels = 4, /* RGBA */ + .data_type = JXL_TYPE_UINT8, + .endianness = JXL_NATIVE_ENDIAN, + .align = 0}; + size_t pixels_size; + + if (!have_basic_info) { + gd_error("gdImageCreateFromJxl: missing basic info"); + goto decode_fail; + } + if (overflow2((int)info.xsize, (int)info.ysize) || + overflow2((int)info.xsize * (int)info.ysize, 4)) { + gd_error("gdImageCreateFromJxl: image dimensions overflow"); + goto decode_fail; + } + + pixels_size = (size_t)info.xsize * (size_t)info.ysize * 4; + pixels = (uint8_t *)gdMalloc(pixels_size); + if (pixels == NULL) { + gd_error("gdImageCreateFromJxl: pixel buffer allocation failed"); + goto decode_fail; + } + + if (JxlDecoderSetImageOutBuffer(dec, &fmt, pixels, pixels_size) != JXL_DEC_SUCCESS) { + gd_error("gdImageCreateFromJxl: failed to set output buffer"); + goto decode_fail; + } + } else if (status == JXL_DEC_FULL_IMAGE) { + if (!have_basic_info || pixels == NULL) { + gd_error("gdImageCreateFromJxl: incomplete decoded image"); + goto decode_fail; + } + break; /* pixels buffer is populated */ + } else if (status == JXL_DEC_SUCCESS || status == JXL_DEC_ERROR) { + gd_error("gdImageCreateFromJxl: decoder error"); + goto decode_fail; + } + } + + /* Build gdImagePtr from RGBA buffer */ + im = JxlImageFromRGBA(pixels, (int)info.xsize, (int)info.ysize, has_alpha); + if (!im) { + gd_error("gdImageCreateFromJxl: JxlImageFromRGBA failed"); + goto decode_fail; + } + + /* Success path - pixels consumed by im */ + gdFree(pixels); + pixels = NULL; + gdFree(buf); + buf = NULL; + JxlDecoderDestroy(dec); + return im; + +decode_fail: + if (pixels) + gdFree(pixels); + if (buf) + gdFree(buf); + if (dec) + JxlDecoderDestroy(dec); + return NULL; +} + +/* ---- Still-image encode ---- */ + +static int _gdImageJxlCtxEx(gdImagePtr im, gdIOCtx *outfile, int lossless, float distance, + int effort) +{ + JxlEncoder *enc = NULL; + JxlEncoderFrameSettings *frame_opts = NULL; + uint8_t *pixels = NULL; + int has_alpha = 0; + uint8_t outbuf[65536]; + int w, h; + int ret = 1; + + if (im == NULL) { + return 1; + } + + w = gdImageSX(im); + h = gdImageSY(im); + + /* Extract RGBA pixels */ + if (!JxlImageToRGBA(im, &pixels, &has_alpha)) { + gd_error("gdImageJxl: pixel extraction failed"); + return 1; + } + + enc = JxlEncoderCreate(NULL); + if (enc == NULL) { + gd_error("gdImageJxl: JxlEncoderCreate failed"); + gdFree(pixels); + return 1; + } + + /* Set basic info */ + JxlBasicInfo info; + JxlEncoderInitBasicInfo(&info); + info.xsize = w; + info.ysize = h; + info.bits_per_sample = 8; + info.exponent_bits_per_sample = 0; + info.num_color_channels = 3; + info.num_extra_channels = has_alpha ? 1 : 0; + info.alpha_bits = has_alpha ? 8 : 0; + info.alpha_exponent_bits = 0; + info.alpha_premultiplied = JXL_FALSE; + info.uses_original_profile = lossless ? JXL_TRUE : JXL_FALSE; + + if (JxlEncoderSetBasicInfo(enc, &info) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderSetBasicInfo failed"); + goto encode_fail; + } + + /* Set color encoding (sRGB) */ + JxlColorEncoding srgb_enc; + JxlColorEncodingSetToSRGB(&srgb_enc, JXL_FALSE); + if (JxlEncoderSetColorEncoding(enc, &srgb_enc) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderSetColorEncoding failed"); + goto encode_fail; + } + + /* Configure frame options */ + frame_opts = JxlEncoderFrameSettingsCreate(enc, NULL); + if (frame_opts == NULL) { + gd_error("gdImageJxl: JxlEncoderFrameSettingsCreate failed"); + goto encode_fail; + } + + if (lossless) { + if (JxlEncoderSetFrameLossless(frame_opts, JXL_TRUE) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderSetFrameLossless failed"); + goto encode_fail; + } + } else { + if (JxlEncoderSetFrameDistance(frame_opts, distance) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderSetFrameDistance failed"); + goto encode_fail; + } + } + + if (JxlEncoderFrameSettingsSetOption(frame_opts, JXL_ENC_FRAME_SETTING_EFFORT, effort) != + JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderFrameSettingsSetOption effort failed"); + goto encode_fail; + } + + /* Add image frame */ + uint8_t *frame_pixels = pixels; + size_t frame_pixels_size = (size_t)w * (size_t)h * 4; + JxlPixelFormat fmt = {.num_channels = has_alpha ? 4u : 3u, + .data_type = JXL_TYPE_UINT8, + .endianness = JXL_NATIVE_ENDIAN, + .align = 0}; + + if (!has_alpha) { + frame_pixels = JxlRGBFromRGBA(pixels, w, h); + if (frame_pixels == NULL) { + gd_error("gdImageJxl: RGB buffer allocation failed"); + goto encode_fail; + } + frame_pixels_size = (size_t)w * (size_t)h * 3; + } + + if (JxlEncoderAddImageFrame(frame_opts, &fmt, frame_pixels, frame_pixels_size) != + JXL_ENC_SUCCESS) { + gd_error("gdImageJxl: JxlEncoderAddImageFrame failed"); + if (frame_pixels != pixels) + gdFree(frame_pixels); + goto encode_fail; + } + if (frame_pixels != pixels) + gdFree(frame_pixels); + + JxlEncoderCloseInput(enc); + for (;;) { + uint8_t *next_out = outbuf; + size_t avail = sizeof(outbuf); + JxlEncoderStatus st = JxlEncoderProcessOutput(enc, &next_out, &avail); + + size_t written = sizeof(outbuf) - avail; + if (written > 0) { + if (gdPutBuf(outbuf, (int)written, outfile) != (int)written) { + gd_error("gdImageJxl: write error"); + goto encode_fail; + } + } + + if (st == JXL_ENC_SUCCESS) { + ret = 0; + break; + } + if (st != JXL_ENC_NEED_MORE_OUTPUT) { + gd_error("gdImageJxl: encoder error"); + goto encode_fail; + } + } + +encode_fail: + // frame_opts is owned by enc, so no separate destroy needed + if (enc) + JxlEncoderDestroy(enc); + if (pixels) + gdFree(pixels); + return ret; +} + +BGD_DECLARE(void) gdImageJxl(gdImagePtr im, FILE *outFile) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageJxlCtxEx(im, out, 0, 1.0f, 7); + out->gd_free(out); +} + +BGD_DECLARE(void) +gdImageJxlEx(gdImagePtr im, FILE *outFile, int lossless, float distance, int effort) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageJxlCtxEx(im, out, lossless, distance, effort); + out->gd_free(out); +} + +BGD_DECLARE(void *) gdImageJxlPtr(gdImagePtr im, int *size) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageJxlCtxEx(im, out, 0, 1.0f, 7)) { + rv = NULL; + } else { + rv = gdDPExtractData(out, size); + } + out->gd_free(out); + return rv; +} + +BGD_DECLARE(void *) +gdImageJxlPtrEx(gdImagePtr im, int *size, int lossless, float distance, int effort) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageJxlCtxEx(im, out, lossless, distance, effort)) { + rv = NULL; + } else { + rv = gdDPExtractData(out, size); + } + out->gd_free(out); + return rv; +} + +BGD_DECLARE(void) gdImageJxlCtx(gdImagePtr im, gdIOCtxPtr outfile) +{ + _gdImageJxlCtxEx(im, outfile, 0, 1.0f, 7); +} + +BGD_DECLARE(void) +gdImageJxlCtxEx(gdImagePtr im, gdIOCtxPtr outfile, int lossless, float distance, int effort) +{ + _gdImageJxlCtxEx(im, outfile, lossless, distance, effort); +} + +/* ---- Animation structures ---- */ + +typedef struct gdJxlAnim { + JxlEncoder *enc; + JxlEncoderFrameSettings *frame_opts; + gdIOCtxPtr ctx; + uint32_t width; + uint32_t height; + int has_alpha; + int ownsCtx; + int memoryWriter; + int finalized; + int timestamp; +} gdJxlAnim; + +typedef struct gdJxlAnimReader { + JxlDecoder *dec; + uint8_t *buf; + size_t buf_len; + JxlBasicInfo info; + int coalesced; + int done; + int last_frame_seen; +} gdJxlAnimReader; + +/* ---- Animation write ---- */ + +static int JxlAnimDrainEncoder(gdJxlAnim *anim) +{ + uint8_t outbuf[65536]; + for (;;) { + uint8_t *next_out = outbuf; + size_t avail = sizeof(outbuf); + JxlEncoderStatus st = JxlEncoderProcessOutput(anim->enc, &next_out, &avail); + + size_t written = sizeof(outbuf) - avail; + if (written > 0) { + if (gdPutBuf(outbuf, (int)written, anim->ctx) != (int)written) { + gd_error("gdImageJxlAnim: write error"); + return 0; + } + } + + if (st == JXL_ENC_SUCCESS) { + return 1; + } + if (st != JXL_ENC_NEED_MORE_OUTPUT) { + gd_error("gdImageJxlAnim: encoder error"); + return 0; + } + } +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBegin(FILE *outFile, int width, int height, int lossless, float distance, int effort) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return NULL; + } + gdJxlAnimPtr anim = gdImageJxlAnimBeginCtx(out, width, height, lossless, distance, effort); + if (anim) { + anim->ownsCtx = 1; + } else { + out->gd_free(out); + } + return anim; +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginCtx(gdIOCtxPtr outCtx, int width, int height, int lossless, float distance, + int effort) +{ + gdJxlAnimPtr anim; + JxlBasicInfo info; + + if (outCtx == NULL || width <= 0 || height <= 0) { + return NULL; + } + + anim = (gdJxlAnimPtr)gdCalloc(1, sizeof(struct gdJxlAnim)); + if (anim == NULL) { + return NULL; + } + + anim->enc = JxlEncoderCreate(NULL); + if (anim->enc == NULL) { + gd_error("gdImageJxlAnimBegin: JxlEncoderCreate failed"); + gdFree(anim); + return NULL; + } + + anim->ctx = outCtx; + anim->width = width; + anim->height = height; + anim->ownsCtx = 0; + anim->memoryWriter = 0; + anim->finalized = 0; + anim->timestamp = 0; + + /* Set basic info for animation */ + JxlEncoderInitBasicInfo(&info); + info.xsize = width; + info.ysize = height; + info.bits_per_sample = 8; + info.exponent_bits_per_sample = 0; + info.num_color_channels = 3; + info.num_extra_channels = 1; + info.alpha_bits = 8; + info.alpha_exponent_bits = 0; + info.alpha_premultiplied = JXL_FALSE; + info.uses_original_profile = lossless ? JXL_TRUE : JXL_FALSE; + info.have_animation = JXL_TRUE; + info.animation.tps_numerator = 1000; /* ms == ticks */ + info.animation.tps_denominator = 1; + info.animation.num_loops = 0; /* loop forever */ + + if (JxlEncoderSetBasicInfo(anim->enc, &info) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimBegin: JxlEncoderSetBasicInfo failed"); + JxlEncoderDestroy(anim->enc); + gdFree(anim); + return NULL; + } + + /* Set color encoding (sRGB) */ + JxlColorEncoding srgb_enc; + JxlColorEncodingSetToSRGB(&srgb_enc, JXL_FALSE); + if (JxlEncoderSetColorEncoding(anim->enc, &srgb_enc) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimBegin: JxlEncoderSetColorEncoding failed"); + JxlEncoderDestroy(anim->enc); + gdFree(anim); + return NULL; + } + + /* Create frame settings once, reuse for all frames */ + anim->frame_opts = JxlEncoderFrameSettingsCreate(anim->enc, NULL); + if (anim->frame_opts == NULL) { + gd_error("gdImageJxlAnimBegin: JxlEncoderFrameSettingsCreate failed"); + JxlEncoderDestroy(anim->enc); + gdFree(anim); + return NULL; + } + + if (lossless) { + if (JxlEncoderSetFrameLossless(anim->frame_opts, JXL_TRUE) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimBegin: JxlEncoderSetFrameLossless failed"); + goto anim_begin_fail; + } + } else { + if (JxlEncoderSetFrameDistance(anim->frame_opts, distance) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimBegin: JxlEncoderSetFrameDistance failed"); + goto anim_begin_fail; + } + } + + if (JxlEncoderFrameSettingsSetOption(anim->frame_opts, JXL_ENC_FRAME_SETTING_EFFORT, effort) != + JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimBegin: JxlEncoderFrameSettingsSetOption effort " + "failed"); + goto anim_begin_fail; + } + + return anim; + +anim_begin_fail: + // anim->frame_opts is owned by anim->enc, so no separate destroy needed + if (anim->enc) + JxlEncoderDestroy(anim->enc); + gdFree(anim); + return NULL; +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginPtr(int width, int height, int lossless, float distance, int effort) +{ + gdIOCtx *out; + gdJxlAnimPtr anim; + + out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + + anim = gdImageJxlAnimBeginCtx(out, width, height, lossless, distance, effort); + if (anim == NULL) { + out->gd_free(out); + return NULL; + } + + anim->ownsCtx = 1; + anim->memoryWriter = 1; + return anim; +} + +BGD_DECLARE(int) +gdImageJxlAnimAddFrame(gdJxlAnimPtr anim, gdImagePtr im, int delay_ms) +{ + JxlFrameHeader fhdr; + JxlPixelFormat fmt; + uint8_t *pixels = NULL; + int has_alpha = 0; + int w, h; + + if (anim == NULL || im == NULL || delay_ms < 0 || anim->finalized) { + return 0; + } + + if (!gdImageTrueColor(im)) { + gd_error("Palette image not supported by JXL animation"); + return 0; + } + + w = gdImageSX(im); + h = gdImageSY(im); + + if (w != (int)anim->width || h != (int)anim->height) { + gd_error("gdImageJxlAnimAddFrame: frame size must match canvas size"); + return 0; + } + + if (!JxlImageToRGBA(im, &pixels, &has_alpha)) { + gd_error("gdImageJxlAnimAddFrame: pixel extraction failed"); + return 0; + } + + /* Update alpha info for this frame if needed */ + if (has_alpha && anim->has_alpha == 0) { + anim->has_alpha = 1; + } + + /* Set frame header - duration only, REPLACE blend, full canvas */ + JxlEncoderInitFrameHeader(&fhdr); + fhdr.duration = (uint32_t)delay_ms; /* ticks == ms */ + + if (JxlEncoderSetFrameHeader(anim->frame_opts, &fhdr) != JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimAddFrame: JxlEncoderSetFrameHeader failed"); + gdFree(pixels); + return 0; + } + + fmt.num_channels = 4; + fmt.data_type = JXL_TYPE_UINT8; + fmt.endianness = JXL_NATIVE_ENDIAN; + fmt.align = 0; + + if (JxlEncoderAddImageFrame(anim->frame_opts, &fmt, pixels, (size_t)w * (size_t)h * 4) != + JXL_ENC_SUCCESS) { + gd_error("gdImageJxlAnimAddFrame: JxlEncoderAddImageFrame failed"); + gdFree(pixels); + return 0; + } + + gdFree(pixels); + pixels = NULL; + + anim->timestamp += delay_ms; + return 1; +} + +BGD_DECLARE(int) gdImageJxlAnimEnd(gdJxlAnimPtr anim) +{ + int ret = 0; + + if (anim == NULL) { + return 0; + } + + if (!anim->finalized) { + JxlEncoderCloseInput(anim->enc); + + if (!JxlAnimDrainEncoder(anim)) { + goto anim_end_cleanup; + } + + anim->finalized = 1; + } + + ret = 1; + +anim_end_cleanup: + // anim->frame_opts is owned by anim->enc, so no separate destroy needed + if (anim->enc) + JxlEncoderDestroy(anim->enc); + if (anim->ownsCtx && anim->ctx) + anim->ctx->gd_free(anim->ctx); + gdFree(anim); + return ret; +} + +BGD_DECLARE(void *) gdImageJxlAnimEndPtr(gdJxlAnimPtr anim, int *size) +{ + void *rv = NULL; + + if (size != NULL) { + *size = 0; + } + if (anim == NULL || !anim->memoryWriter) { + if (anim != NULL) { + gdImageJxlAnimEnd(anim); + } + return NULL; + } + + if (!anim->finalized) { + JxlEncoderCloseInput(anim->enc); + + if (!JxlAnimDrainEncoder(anim)) { + goto anim_end_ptr_cleanup; + } + + anim->finalized = 1; + } + + rv = gdDPExtractData(anim->ctx, size); + +anim_end_ptr_cleanup: + if (anim->enc) + JxlEncoderDestroy(anim->enc); + if (anim->ctx) + anim->ctx->gd_free(anim->ctx); + gdFree(anim); + return rv; +} + +/* ---- Animation read (coalesced & raw) ---- */ + +static gdJxlAnimReaderPtr _gdImageJxlAnimReaderCreateCtx(gdIOCtxPtr inCtx, int coalesced) +{ + size_t buf_len = 0; + uint8_t *buf = NULL; + JxlDecoder *dec = NULL; + gdJxlAnimReaderPtr reader = NULL; + + if (inCtx == NULL) { + return NULL; + } + + buf = JxlReadCtxData(inCtx, &buf_len); + if (buf == NULL) { + return NULL; + } + + dec = JxlDecoderCreate(NULL); + if (dec == NULL) { + gd_error("gdImageJxlAnimReaderCreate: JxlDecoderCreate failed"); + gdFree(buf); + return NULL; + } + + reader = (gdJxlAnimReaderPtr)gdCalloc(1, sizeof(struct gdJxlAnimReader)); + if (reader == NULL) { + JxlDecoderDestroy(dec); + gdFree(buf); + return NULL; + } + + if (coalesced) { + JxlDecoderSubscribeEvents(dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME | + JXL_DEC_FULL_IMAGE); + JxlDecoderSetCoalescing(dec, JXL_TRUE); + } else { + JxlDecoderSubscribeEvents(dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME | + JXL_DEC_FULL_IMAGE); + JxlDecoderSetCoalescing(dec, JXL_FALSE); + } + + /* Attach CMS for color space conversion to sRGB */ + JxlDecoderSetCms(dec, *JxlGetDefaultCms()); + + /* Set desired output color profile (sRGB) */ + JxlColorEncoding srgb_enc; + JxlColorEncodingSetToSRGB(&srgb_enc, JXL_FALSE); + JxlDecoderSetPreferredColorProfile(dec, &srgb_enc); + + JxlDecoderSetInput(dec, buf, buf_len); + JxlDecoderCloseInput(dec); + + /* Process until BASIC_INFO to get dimensions */ + for (;;) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec); + if (status == JXL_DEC_BASIC_INFO) { + if (JxlDecoderGetBasicInfo(dec, &reader->info) != JXL_DEC_SUCCESS) { + gd_error("gdImageJxlAnimReaderCreate: failed to get basic info"); + JxlDecoderDestroy(dec); + gdFree(buf); + gdFree(reader); + return NULL; + } + break; + } + if (status == JXL_DEC_ERROR || status == JXL_DEC_SUCCESS) { + gd_error("gdImageJxlAnimReaderCreate: failed to get basic info"); + JxlDecoderDestroy(dec); + gdFree(buf); + gdFree(reader); + return NULL; + } + } + + reader->dec = dec; + reader->buf = buf; + reader->buf_len = buf_len; + reader->coalesced = coalesced; + reader->done = 0; + reader->last_frame_seen = 0; + + return reader; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreate(FILE *inFile) +{ + gdIOCtx *in = gdNewFileCtx(inFile); + if (!in) { + return NULL; + } + gdJxlAnimReaderPtr reader = _gdImageJxlAnimReaderCreateCtx(in, JXL_TRUE); + in->gd_free(in); + return reader; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreatePtr(int size, void *data) +{ + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return NULL; + } + gdJxlAnimReaderPtr reader = _gdImageJxlAnimReaderCreateCtx(in, JXL_TRUE); + in->gd_free(in); + return reader; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateCtx(gdIOCtxPtr inCtx) +{ + return _gdImageJxlAnimReaderCreateCtx(inCtx, JXL_TRUE); +} + +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateRaw(FILE *inFile) +{ + gdIOCtx *in = gdNewFileCtx(inFile); + if (!in) { + return NULL; + } + gdJxlAnimReaderPtr reader = _gdImageJxlAnimReaderCreateCtx(in, JXL_FALSE); + in->gd_free(in); + return reader; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateRawPtr(int size, void *data) +{ + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return NULL; + } + gdJxlAnimReaderPtr reader = _gdImageJxlAnimReaderCreateCtx(in, JXL_FALSE); + in->gd_free(in); + return reader; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateRawCtx(gdIOCtxPtr inCtx) +{ + return _gdImageJxlAnimReaderCreateCtx(inCtx, JXL_FALSE); +} + +/* Helper: build gdImagePtr from current decoder state */ +static gdImagePtr JxlAnimReaderGetCurrentFrame(gdJxlAnimReaderPtr reader, int *delay_ms) +{ + JxlDecoder *dec = reader->dec; + JxlBasicInfo info = reader->info; + uint8_t *pixels = NULL; + gdImagePtr im = NULL; + int have_frame_header = 0; + + if (reader->done) { + return NULL; + } + + for (;;) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec); + + if (status == JXL_DEC_FRAME) { + JxlFrameHeader fhdr = {0}; + status = JxlDecoderGetFrameHeader(dec, &fhdr); + if (status != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to get frame header"); + if (pixels) + gdFree(pixels); + return NULL; + } + have_frame_header = 1; + reader->last_frame_seen = fhdr.is_last == JXL_TRUE; + if (delay_ms) { + *delay_ms = JxlDurationToMs(fhdr.duration, &info.animation); + } + } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { + JxlPixelFormat fmt = {.num_channels = 4, + .data_type = JXL_TYPE_UINT8, + .endianness = JXL_NATIVE_ENDIAN, + .align = 0}; + size_t pixels_size; + int w, h; + + if (reader->coalesced) { + w = (int)info.xsize; + h = (int)info.ysize; + } else { + /* For non-coalesced, we need to query the frame size */ + size_t buf_size; + if (!have_frame_header) { + gd_error("gdJxlReadNextFrame: missing frame header"); + return NULL; + } + if (JxlDecoderImageOutBufferSize(dec, &fmt, &buf_size) != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to get buffer size"); + return NULL; + } + w = (int)sqrt(buf_size / 4); /* approximation - we'll get actual size from fmt */ + h = (int)(buf_size / 4 / w); + /* Actually better: we know the frame size from layer_info but + * for simplicity with coalesced=false we allocate based on + * the buffer size reported */ + } + + if (overflow2(w, h) || overflow2(w * h, 4)) { + gd_error("gdJxlReadNextFrame: frame dimensions overflow"); + return NULL; + } + + pixels_size = (size_t)w * (size_t)h * 4; + pixels = (uint8_t *)gdMalloc(pixels_size); + if (pixels == NULL) { + gd_error("gdJxlReadNextFrame: pixel buffer allocation failed"); + return NULL; + } + + if (JxlDecoderSetImageOutBuffer(dec, &fmt, pixels, pixels_size) != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to set output buffer"); + gdFree(pixels); + return NULL; + } + } else if (status == JXL_DEC_FULL_IMAGE) { + int has_alpha = (info.alpha_bits > 0); + int w, h; + + if (reader->coalesced) { + w = (int)info.xsize; + h = (int)info.ysize; + } else { + /* For non-coalesced, we don't know exact dimensions here. + * We'll reconstruct from the buffer. This is a simplification. + */ + w = (int)info.xsize; + h = (int)info.ysize; + } + + im = JxlImageFromRGBA(pixels, w, h, has_alpha); + if (pixels) + gdFree(pixels); + if (reader->last_frame_seen) + reader->done = 1; + return im; + } else if (status == JXL_DEC_SUCCESS) { + reader->done = 1; + if (pixels) + gdFree(pixels); + return NULL; + } else if (status == JXL_DEC_ERROR) { + gd_error("gdJxlReadNextFrame: decoder error"); + if (pixels) + gdFree(pixels); + return NULL; + } + } +} + +BGD_DECLARE(gdImagePtr) +gdJxlReadNextImage(gdJxlAnimReaderPtr reader, int *delay_ms) +{ + if (reader == NULL || reader->coalesced == 0) { + return NULL; + } + return JxlAnimReaderGetCurrentFrame(reader, delay_ms); +} + +/* For non-coalesced reader, we need to extract frame info */ +static void JxlFrameHeaderToInfo(const JxlFrameHeader *fhdr, const JxlBasicInfo *info, + gdJxlFrameInfo *out) +{ + out->delay_ms = JxlDurationToMs(fhdr->duration, &info->animation); + out->x_offset = (int)fhdr->layer_info.crop_x0; + out->y_offset = (int)fhdr->layer_info.crop_y0; + out->width = (int)fhdr->layer_info.xsize; + out->height = (int)fhdr->layer_info.ysize; + out->blend_mode = (int)fhdr->layer_info.blend_info.blendmode; + out->is_last = (int)fhdr->is_last; +} + +static gdImagePtr JxlAnimReaderGetCurrentRawFrame(gdJxlAnimReaderPtr reader, gdJxlFrameInfo *info) +{ + JxlDecoder *dec = reader->dec; + JxlBasicInfo basic = reader->info; + JxlFrameHeader fhdr = {0}; + uint8_t *pixels = NULL; + gdImagePtr im = NULL; + int has_alpha = 0; + int have_frame_header = 0; + int w = 0, h = 0; + + if (reader->done) { + return NULL; + } + + for (;;) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec); + + if (status == JXL_DEC_FRAME) { + status = JxlDecoderGetFrameHeader(dec, &fhdr); + if (status != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to get frame header"); + return NULL; + } + have_frame_header = 1; + reader->last_frame_seen = fhdr.is_last == JXL_TRUE; + JxlFrameHeaderToInfo(&fhdr, &basic, info); + has_alpha = (basic.alpha_bits > 0); + } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { + JxlPixelFormat fmt = {.num_channels = 4, + .data_type = JXL_TYPE_UINT8, + .endianness = JXL_NATIVE_ENDIAN, + .align = 0}; + size_t pixels_size; + + /* Query the exact buffer size for this frame */ + if (!have_frame_header) { + gd_error("gdJxlReadNextFrame: missing frame header"); + return NULL; + } + if (JxlDecoderImageOutBufferSize(dec, &fmt, &pixels_size) != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to get buffer size"); + return NULL; + } + w = (int)fhdr.layer_info.xsize; + h = (int)fhdr.layer_info.ysize; + + if (overflow2(w, h) || overflow2(w * h, 4)) { + gd_error("gdJxlReadNextFrame: frame dimensions overflow"); + return NULL; + } + + /* Verify pixels_size matches expected */ + if (pixels_size != (size_t)w * (size_t)h * 4) { + gd_error("gdJxlReadNextFrame: unexpected buffer size"); + return NULL; + } + + pixels = (uint8_t *)gdMalloc(pixels_size); + if (pixels == NULL) { + gd_error("gdJxlReadNextFrame: pixel buffer allocation failed"); + return NULL; + } + + if (JxlDecoderSetImageOutBuffer(dec, &fmt, pixels, pixels_size) != JXL_DEC_SUCCESS) { + gd_error("gdJxlReadNextFrame: failed to set output buffer"); + gdFree(pixels); + return NULL; + } + } else if (status == JXL_DEC_FULL_IMAGE) { + if (pixels == NULL) { + gd_error("gdJxlReadNextFrame: incomplete decoded frame"); + return NULL; + } + w = info->width; + h = info->height; + im = JxlImageFromRGBA(pixels, w, h, has_alpha); + if (pixels) + gdFree(pixels); + if (reader->last_frame_seen) + reader->done = 1; + return im; + } else if (status == JXL_DEC_SUCCESS) { + reader->done = 1; + if (pixels) + gdFree(pixels); + return NULL; + } else if (status == JXL_DEC_ERROR) { + gd_error("gdJxlReadNextFrame: decoder error"); + if (pixels) + gdFree(pixels); + return NULL; + } + } +} + +BGD_DECLARE(gdImagePtr) +gdJxlReadNextFrame(gdJxlAnimReaderPtr reader, gdJxlFrameInfo *info) +{ + if (reader == NULL || reader->coalesced != 0 || info == NULL) { + return NULL; + } + return JxlAnimReaderGetCurrentRawFrame(reader, info); +} + +BGD_DECLARE(void) gdImageJxlAnimReaderDestroy(gdJxlAnimReaderPtr reader) +{ + if (reader == NULL) { + return; + } + if (reader->dec) + JxlDecoderDestroy(reader->dec); + if (reader->buf) + gdFree(reader->buf); + gdFree(reader); +} + +#else /* !HAVE_LIBJXL */ + +static void _noJxlError(void) { gd_error("JXL image support has been disabled\n"); } + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxl(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromJxlCtx(gdIOCtx *infile) +{ + ARG_NOT_USED(infile); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(void) gdImageJxl(gdImagePtr im, FILE *outFile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + _noJxlError(); +} + +BGD_DECLARE(void) +gdImageJxlEx(gdImagePtr im, FILE *outFile, int lossless, float distance, int effort) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); +} + +BGD_DECLARE(void *) gdImageJxlPtr(gdImagePtr im, int *size) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(void *) +gdImageJxlPtrEx(gdImagePtr im, int *size, int lossless, float distance, int effort) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(void) gdImageJxlCtx(gdImagePtr im, gdIOCtxPtr outfile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + _noJxlError(); +} + +BGD_DECLARE(void) +gdImageJxlCtxEx(gdImagePtr im, gdIOCtxPtr outfile, int lossless, float distance, int effort) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); +} + +/* Animation stubs */ +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreate(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreatePtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateCtx(gdIOCtxPtr inCtx) +{ + ARG_NOT_USED(inCtx); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdJxlReadNextImage(gdJxlAnimReaderPtr reader, int *delay_ms) +{ + ARG_NOT_USED(reader); + ARG_NOT_USED(delay_ms); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) gdImageJxlAnimReaderCreateRaw(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateRawPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimReaderPtr) +gdImageJxlAnimReaderCreateRawCtx(gdIOCtxPtr inCtx) +{ + ARG_NOT_USED(inCtx); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdJxlReadNextFrame(gdJxlAnimReaderPtr reader, gdJxlFrameInfo *info) +{ + ARG_NOT_USED(reader); + ARG_NOT_USED(info); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(void) gdImageJxlAnimReaderDestroy(gdJxlAnimReaderPtr reader) +{ + ARG_NOT_USED(reader); + _noJxlError(); +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBegin(FILE *outFile, int width, int height, int lossless, float distance, int effort) +{ + ARG_NOT_USED(outFile); + ARG_NOT_USED(width); + ARG_NOT_USED(height); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginCtx(gdIOCtxPtr outCtx, int width, int height, int lossless, float distance, + int effort) +{ + ARG_NOT_USED(outCtx); + ARG_NOT_USED(width); + ARG_NOT_USED(height); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(gdJxlAnimPtr) +gdImageJxlAnimBeginPtr(int width, int height, int lossless, float distance, int effort) +{ + ARG_NOT_USED(width); + ARG_NOT_USED(height); + ARG_NOT_USED(lossless); + ARG_NOT_USED(distance); + ARG_NOT_USED(effort); + _noJxlError(); + return NULL; +} + +BGD_DECLARE(int) +gdImageJxlAnimAddFrame(gdJxlAnimPtr anim, gdImagePtr im, int delay_ms) +{ + ARG_NOT_USED(anim); + ARG_NOT_USED(im); + ARG_NOT_USED(delay_ms); + _noJxlError(); + return 0; +} + +BGD_DECLARE(int) gdImageJxlAnimEnd(gdJxlAnimPtr anim) +{ + ARG_NOT_USED(anim); + _noJxlError(); + return 0; +} + +BGD_DECLARE(void *) gdImageJxlAnimEndPtr(gdJxlAnimPtr anim, int *size) +{ + ARG_NOT_USED(anim); + if (size != NULL) { + *size = 0; + } + _noJxlError(); + return NULL; +} + +#endif /* HAVE_LIBJXL */ diff --git a/ext/gd/libgd/gd_matrix.c b/ext/gd/libgd/gd_matrix.c index ec4067483358..d79f9e69314b 100644 --- a/ext/gd/libgd/gd_matrix.c +++ b/ext/gd/libgd/gd_matrix.c @@ -2,12 +2,33 @@ #include #ifndef M_PI -# define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif /** * Title: Matrix * Group: Affine Matrix + * + * Matrix functions to initialize, transform and various other operations + * on these matrices. + * They can be used with gdTransformAffineCopy and are also used in various + * transformations functions in GD. + * + * matrix are create using a 6 elements double array: + * (start code) + * matrix[0] == xx + * matrix[1] == yx + * matrix[2] == xy + * matrix[3] == xy + * matrix[4] == x0 + * matrix[5] == y0 + * (end code) + * where the transformation of a given point (x,y) is given by: + * + * (start code) + * x_new = xx * x + xy * y + x0; + * y_new = yx * x + yy * y + y0; + * (end code) */ /** @@ -24,14 +45,14 @@ * Returns: * GD_TRUE if the affine is rectilinear or GD_FALSE */ -int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, - const double affine[6]) +BGD_DECLARE(int) +gdAffineApplyToPointF(gdPointFPtr dst, const gdPointFPtr src, const double affine[6]) { - double x = src->x; - double y = src->y; - dst->x = x * affine[0] + y * affine[2] + affine[4]; - dst->y = x * affine[1] + y * affine[3] + affine[5]; - return GD_TRUE; + double x = src->x; + double y = src->y; + dst->x = x * affine[0] + y * affine[2] + affine[4]; + dst->y = x * affine[1] + y * affine[3] + affine[5]; + return GD_TRUE; } /** @@ -55,22 +76,25 @@ int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, * Returns: * GD_TRUE on success or GD_FALSE on failure */ -int gdAffineInvert (double dst[6], const double src[6]) +BGD_DECLARE(int) gdAffineInvert(double dst[6], const double src[6]) { - double r_det = (src[0] * src[3] - src[1] * src[2]); + double r_det = (src[0] * src[3] - src[1] * src[2]); - if (r_det <= 0.0) { - return GD_FALSE; - } + if (!isfinite(r_det)) { + return GD_FALSE; + } + if (r_det == 0) { + return GD_FALSE; + } - r_det = 1.0 / r_det; - dst[0] = src[3] * r_det; - dst[1] = -src[1] * r_det; - dst[2] = -src[2] * r_det; - dst[3] = src[0] * r_det; - dst[4] = -src[4] * dst[0] - src[5] * dst[2]; - dst[5] = -src[4] * dst[1] - src[5] * dst[3]; - return GD_TRUE; + r_det = 1.0 / r_det; + dst[0] = src[3] * r_det; + dst[1] = -src[1] * r_det; + dst[2] = -src[2] * r_det; + dst[3] = src[0] * r_det; + dst[4] = -src[4] * dst[0] - src[5] * dst[2]; + dst[5] = -src[4] * dst[1] - src[5] * dst[3]; + return GD_TRUE; } /** @@ -88,17 +112,18 @@ int gdAffineInvert (double dst[6], const double src[6]) * flip_v - Whether or not to flip vertically * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineFlip (double dst[6], const double src[6], const int flip_h, const int flip_v) +BGD_DECLARE(int) +gdAffineFlip(double dst[6], const double src[6], const int flip_h, const int flip_v) { - dst[0] = flip_h ? - src[0] : src[0]; - dst[1] = flip_h ? - src[1] : src[1]; - dst[2] = flip_v ? - src[2] : src[2]; - dst[3] = flip_v ? - src[3] : src[3]; - dst[4] = flip_h ? - src[4] : src[4]; - dst[5] = flip_v ? - src[5] : src[5]; - return GD_TRUE; + dst[0] = flip_h ? -src[0] : src[0]; + dst[1] = flip_h ? -src[1] : src[1]; + dst[2] = flip_v ? -src[2] : src[2]; + dst[3] = flip_v ? -src[3] : src[3]; + dst[4] = flip_h ? -src[4] : src[4]; + dst[5] = flip_v ? -src[5] : src[5]; + return GD_TRUE; } /** @@ -116,25 +141,26 @@ int gdAffineFlip (double dst[6], const double src[6], const int flip_h, const in * m2 - Second affine matrix * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineConcat (double dst[6], const double m1[6], const double m2[6]) +BGD_DECLARE(int) +gdAffineConcat(double dst[6], const double m1[6], const double m2[6]) { - double dst0, dst1, dst2, dst3, dst4, dst5; + double dst0, dst1, dst2, dst3, dst4, dst5; - dst0 = m1[0] * m2[0] + m1[1] * m2[2]; - dst1 = m1[0] * m2[1] + m1[1] * m2[3]; - dst2 = m1[2] * m2[0] + m1[3] * m2[2]; - dst3 = m1[2] * m2[1] + m1[3] * m2[3]; - dst4 = m1[4] * m2[0] + m1[5] * m2[2] + m2[4]; - dst5 = m1[4] * m2[1] + m1[5] * m2[3] + m2[5]; - dst[0] = dst0; - dst[1] = dst1; - dst[2] = dst2; - dst[3] = dst3; - dst[4] = dst4; - dst[5] = dst5; - return GD_TRUE; + dst0 = m1[0] * m2[0] + m1[1] * m2[2]; + dst1 = m1[0] * m2[1] + m1[1] * m2[3]; + dst2 = m1[2] * m2[0] + m1[3] * m2[2]; + dst3 = m1[2] * m2[1] + m1[3] * m2[3]; + dst4 = m1[4] * m2[0] + m1[5] * m2[2] + m2[4]; + dst5 = m1[4] * m2[1] + m1[5] * m2[3] + m2[5]; + dst[0] = dst0; + dst[1] = dst1; + dst[2] = dst2; + dst[3] = dst3; + dst[4] = dst4; + dst[5] = dst5; + return GD_TRUE; } /** @@ -145,17 +171,17 @@ int gdAffineConcat (double dst[6], const double m1[6], const double m2[6]) * dst - Where to store the resulting affine transform * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineIdentity (double dst[6]) +BGD_DECLARE(int) gdAffineIdentity(double dst[6]) { - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 1; - dst[4] = 0; - dst[5] = 0; - return GD_TRUE; + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 1; + dst[4] = 0; + dst[5] = 0; + return GD_TRUE; } /** @@ -167,17 +193,18 @@ int gdAffineIdentity (double dst[6]) * scale_y - Y scale factor * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineScale (double dst[6], const double scale_x, const double scale_y) +BGD_DECLARE(int) +gdAffineScale(double dst[6], const double scale_x, const double scale_y) { - dst[0] = scale_x; - dst[1] = 0; - dst[2] = 0; - dst[3] = scale_y; - dst[4] = 0; - dst[5] = 0; - return GD_TRUE; + dst[0] = scale_x; + dst[1] = 0; + dst[2] = 0; + dst[3] = scale_y; + dst[4] = 0; + dst[5] = 0; + return GD_TRUE; } /** @@ -192,20 +219,20 @@ int gdAffineScale (double dst[6], const double scale_x, const double scale_y) * angle - Rotation angle in degrees * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineRotate (double dst[6], const double angle) +BGD_DECLARE(int) gdAffineRotate(double dst[6], const double angle) { - const double sin_t = sin (angle * M_PI / 180.0); - const double cos_t = cos (angle * M_PI / 180.0); + const double sin_t = sin(angle * M_PI / 180.0); + const double cos_t = cos(angle * M_PI / 180.0); - dst[0] = cos_t; - dst[1] = sin_t; - dst[2] = -sin_t; - dst[3] = cos_t; - dst[4] = 0; - dst[5] = 0; - return GD_TRUE; + dst[0] = cos_t; + dst[1] = sin_t; + dst[2] = -sin_t; + dst[3] = cos_t; + dst[4] = 0; + dst[5] = 0; + return GD_TRUE; } /** @@ -217,17 +244,17 @@ int gdAffineRotate (double dst[6], const double angle) * angle - Shear angle in degrees * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineShearHorizontal(double dst[6], const double angle) +BGD_DECLARE(int) gdAffineShearHorizontal(double dst[6], const double angle) { - dst[0] = 1; - dst[1] = 0; - dst[2] = tan(angle * M_PI / 180.0); - dst[3] = 1; - dst[4] = 0; - dst[5] = 0; - return GD_TRUE; + dst[0] = 1; + dst[1] = 0; + dst[2] = tan(angle * M_PI / 180.0); + dst[3] = 1; + dst[4] = 0; + dst[5] = 0; + return GD_TRUE; } /** @@ -239,17 +266,17 @@ int gdAffineShearHorizontal(double dst[6], const double angle) * angle - Shear angle in degrees * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineShearVertical(double dst[6], const double angle) +BGD_DECLARE(int) gdAffineShearVertical(double dst[6], const double angle) { - dst[0] = 1; - dst[1] = tan(angle * M_PI / 180.0); - dst[2] = 0; - dst[3] = 1; - dst[4] = 0; - dst[5] = 0; - return GD_TRUE; + dst[0] = 1; + dst[1] = tan(angle * M_PI / 180.0); + dst[2] = 0; + dst[3] = 1; + dst[4] = 0; + dst[5] = 0; + return GD_TRUE; } /** @@ -262,16 +289,17 @@ int gdAffineShearVertical(double dst[6], const double angle) * offset_y - Vertical translation amount * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineTranslate (double dst[6], const double offset_x, const double offset_y) +BGD_DECLARE(int) +gdAffineTranslate(double dst[6], const double offset_x, const double offset_y) { - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 1; - dst[4] = offset_x; - dst[5] = offset_y; + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 1; + dst[4] = offset_x; + dst[5] = offset_y; return GD_TRUE; } @@ -284,11 +312,11 @@ int gdAffineTranslate (double dst[6], const double offset_x, const double offset * composed of scaling, rotation, shearing, and translation, returns * the amount of scaling. * - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE **/ -double gdAffineExpansion (const double src[6]) +BGD_DECLARE(double) gdAffineExpansion(const double src[6]) { - return sqrt (fabs (src[0] * src[3] - src[1] * src[2])); + return sqrt(fabs(src[0] * src[3] - src[1] * src[2])); } /** @@ -302,10 +330,10 @@ double gdAffineExpansion (const double src[6]) * Returns: * GD_TRUE if the affine is rectilinear or GD_FALSE */ -int gdAffineRectilinear (const double m[6]) +BGD_DECLARE(int) gdAffineRectilinear(const double m[6]) { - return ((fabs (m[1]) < GD_EPSILON && fabs (m[2]) < GD_EPSILON) || - (fabs (m[0]) < GD_EPSILON && fabs (m[3]) < GD_EPSILON)); + return ((fabs(m[1]) < GD_EPSILON && fabs(m[2]) < GD_EPSILON) || + (fabs(m[0]) < GD_EPSILON && fabs(m[3]) < GD_EPSILON)); } /** @@ -318,14 +346,11 @@ int gdAffineRectilinear (const double m[6]) * m2 - The first affine transformation * * Returns: - * GD_SUCCESS on success or GD_FAILURE + * GD_TRUE on success or GD_FALSE */ -int gdAffineEqual (const double m1[6], const double m2[6]) +BGD_DECLARE(int) gdAffineEqual(const double m1[6], const double m2[6]) { - return (fabs (m1[0] - m2[0]) < GD_EPSILON && - fabs (m1[1] - m2[1]) < GD_EPSILON && - fabs (m1[2] - m2[2]) < GD_EPSILON && - fabs (m1[3] - m2[3]) < GD_EPSILON && - fabs (m1[4] - m2[4]) < GD_EPSILON && - fabs (m1[5] - m2[5]) < GD_EPSILON); + return (fabs(m1[0] - m2[0]) < GD_EPSILON && fabs(m1[1] - m2[1]) < GD_EPSILON && + fabs(m1[2] - m2[2]) < GD_EPSILON && fabs(m1[3] - m2[3]) < GD_EPSILON && + fabs(m1[4] - m2[4]) < GD_EPSILON && fabs(m1[5] - m2[5]) < GD_EPSILON); } diff --git a/ext/gd/libgd/gd_metadata.c b/ext/gd/libgd/gd_metadata.c new file mode 100644 index 000000000000..d5876fb0fbd9 --- /dev/null +++ b/ext/gd/libgd/gd_metadata.c @@ -0,0 +1,324 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "gd.h" +#include "gdhelpers.h" + +typedef struct gdImageMetadataProfile { + char *key; + unsigned char *data; + size_t size; + struct gdImageMetadataProfile *next; +} gdImageMetadataProfile; + +struct gdImageMetadata { + gdImageMetadataProfile *profiles; + size_t profile_count; + size_t total_size; + size_t max_profile_size; + size_t max_total_size; +}; + +static int gdMetadataKeyIsValid(const char *key) { return key != NULL && key[0] != '\0'; } + +static char *gdMetadataStrdup(const char *src) +{ + size_t len; + char *dst; + + len = strlen(src); + dst = (char *)gdMalloc(len + 1); + if (dst == NULL) { + return NULL; + } + memcpy(dst, src, len + 1); + return dst; +} + +static gdImageMetadataProfile *gdMetadataFindProfile(const gdImageMetadata *metadata, + const char *key) +{ + gdImageMetadataProfile *profile; + + if (metadata == NULL || !gdMetadataKeyIsValid(key)) { + return NULL; + } + + profile = metadata->profiles; + while (profile != NULL) { + if (strcmp(profile->key, key) == 0) { + return profile; + } + profile = profile->next; + } + + return NULL; +} + +static void gdMetadataFreeProfile(gdImageMetadataProfile *profile) +{ + if (profile == NULL) { + return; + } + if (profile->key != NULL) { + gdFree(profile->key); + } + if (profile->data != NULL) { + gdFree(profile->data); + } + gdFree(profile); +} + +BGD_DECLARE(gdImageMetadata *) gdImageMetadataCreate(void) +{ + gdImageMetadata *metadata; + + metadata = (gdImageMetadata *)gdCalloc(1, sizeof(gdImageMetadata)); + if (metadata == NULL) { + return NULL; + } + + metadata->max_profile_size = GD_METADATA_DEFAULT_MAX_PROFILE_SIZE; + metadata->max_total_size = GD_METADATA_DEFAULT_MAX_TOTAL_SIZE; + + return metadata; +} + +BGD_DECLARE(void) gdImageMetadataFree(gdImageMetadata *metadata) +{ + if (metadata == NULL) { + return; + } + + gdImageMetadataReset(metadata); + gdFree(metadata); +} + +BGD_DECLARE(void) gdImageMetadataReset(gdImageMetadata *metadata) +{ + gdImageMetadataProfile *profile; + + if (metadata == NULL) { + return; + } + + profile = metadata->profiles; + while (profile != NULL) { + gdImageMetadataProfile *next = profile->next; + gdMetadataFreeProfile(profile); + profile = next; + } + + metadata->profiles = NULL; + metadata->profile_count = 0; + metadata->total_size = 0; +} + +BGD_DECLARE(int) +gdImageMetadataSetLimits(gdImageMetadata *metadata, size_t max_profile_size, size_t max_total_size) +{ + if (metadata == NULL) { + return GD_META_ERR_INVALID; + } + + if (max_profile_size != 0 || max_total_size != 0) { + gdImageMetadataProfile *profile; + + if (max_total_size != 0 && metadata->total_size > max_total_size) { + return GD_META_ERR_LIMIT; + } + + profile = metadata->profiles; + while (profile != NULL) { + if (max_profile_size != 0 && profile->size > max_profile_size) { + return GD_META_ERR_LIMIT; + } + profile = profile->next; + } + } + + metadata->max_profile_size = max_profile_size; + metadata->max_total_size = max_total_size; + return GD_META_OK; +} + +BGD_DECLARE(void) +gdImageMetadataGetLimits(const gdImageMetadata *metadata, size_t *max_profile_size, + size_t *max_total_size) +{ + if (max_profile_size != NULL) { + *max_profile_size = metadata != NULL ? metadata->max_profile_size : 0; + } + if (max_total_size != NULL) { + *max_total_size = metadata != NULL ? metadata->max_total_size : 0; + } +} + +BGD_DECLARE(int) +gdImageMetadataSetProfile(gdImageMetadata *metadata, const char *key, const unsigned char *data, + size_t size) +{ + gdImageMetadataProfile *profile; + unsigned char *new_data = NULL; + size_t old_size = 0; + size_t new_total; + + if (metadata == NULL || !gdMetadataKeyIsValid(key) || (data == NULL && size != 0)) { + return GD_META_ERR_INVALID; + } + + if (metadata->max_profile_size != 0 && size > metadata->max_profile_size) { + return GD_META_ERR_LIMIT; + } + + profile = gdMetadataFindProfile(metadata, key); + if (profile != NULL) { + old_size = profile->size; + } + + if ((size_t)-1 - (metadata->total_size - old_size) < size) { + return GD_META_ERR_LIMIT; + } + new_total = metadata->total_size - old_size + size; + if (metadata->max_total_size != 0 && new_total > metadata->max_total_size) { + return GD_META_ERR_LIMIT; + } + + if (size != 0) { + new_data = (unsigned char *)gdMalloc(size); + if (new_data == NULL) { + return GD_META_ERR_NOMEM; + } + memcpy(new_data, data, size); + } + + if (profile == NULL) { + profile = (gdImageMetadataProfile *)gdCalloc(1, sizeof(gdImageMetadataProfile)); + if (profile == NULL) { + if (new_data != NULL) { + gdFree(new_data); + } + return GD_META_ERR_NOMEM; + } + profile->key = gdMetadataStrdup(key); + if (profile->key == NULL) { + if (new_data != NULL) { + gdFree(new_data); + } + gdFree(profile); + return GD_META_ERR_NOMEM; + } + profile->next = metadata->profiles; + metadata->profiles = profile; + metadata->profile_count++; + } else if (profile->data != NULL) { + gdFree(profile->data); + } + + profile->data = new_data; + profile->size = size; + metadata->total_size = new_total; + + return GD_META_OK; +} + +BGD_DECLARE(const unsigned char *) +gdImageMetadataGetProfile(const gdImageMetadata *metadata, const char *key, size_t *size) +{ + gdImageMetadataProfile *profile; + + if (size != NULL) { + *size = 0; + } + + profile = gdMetadataFindProfile(metadata, key); + if (profile == NULL) { + return NULL; + } + + if (size != NULL) { + *size = profile->size; + } + return profile->data; +} + +BGD_DECLARE(int) +gdImageMetadataRemoveProfile(gdImageMetadata *metadata, const char *key) +{ + gdImageMetadataProfile *profile; + gdImageMetadataProfile *previous = NULL; + + if (metadata == NULL || !gdMetadataKeyIsValid(key)) { + return GD_META_ERR_INVALID; + } + + profile = metadata->profiles; + while (profile != NULL) { + if (strcmp(profile->key, key) == 0) { + if (previous == NULL) { + metadata->profiles = profile->next; + } else { + previous->next = profile->next; + } + metadata->profile_count--; + metadata->total_size -= profile->size; + gdMetadataFreeProfile(profile); + return GD_META_OK; + } + previous = profile; + profile = profile->next; + } + + return GD_META_OK; +} + +BGD_DECLARE(size_t) +gdImageMetadataGetProfileCount(const gdImageMetadata *metadata) +{ + return metadata != NULL ? metadata->profile_count : 0; +} + +BGD_DECLARE(int) +gdImageMetadataGetProfileAt(const gdImageMetadata *metadata, size_t index, const char **key, + const unsigned char **data, size_t *size) +{ + gdImageMetadataProfile *profile; + size_t i = 0; + + if (key != NULL) { + *key = NULL; + } + if (data != NULL) { + *data = NULL; + } + if (size != NULL) { + *size = 0; + } + + if (metadata == NULL) { + return GD_META_ERR_INVALID; + } + + profile = metadata->profiles; + while (profile != NULL) { + if (i == index) { + if (key != NULL) { + *key = profile->key; + } + if (data != NULL) { + *data = profile->data; + } + if (size != NULL) { + *size = profile->size; + } + return GD_META_OK; + } + i++; + profile = profile->next; + } + + return GD_META_ERR_INVALID; +} diff --git a/ext/gd/libgd/gd_nnquant.c b/ext/gd/libgd/gd_nnquant.c new file mode 100644 index 000000000000..e4f83fa5d8bb --- /dev/null +++ b/ext/gd/libgd/gd_nnquant.c @@ -0,0 +1,633 @@ +/* NeuQuant Neural-Net Quantization Algorithm + * ------------------------------------------ + * + * Copyright (c) 1994 Anthony Dekker + * + * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. + * See "Kohonen neural networks for optimal colour quantization" + * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. + * for a discussion of the algorithm. + * See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML + * + * Any party obtaining a copy of these files from the author, directly or + * indirectly, is granted, free of charge, a full and unrestricted irrevocable, + * world-wide, paid up, royalty-free, nonexclusive right and license to deal + * in this software and documentation files (the "Software"), including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons who + * receive copies from any such party to do so, with the only requirement being + * that this copyright notice remain intact. + * + * + * Modified to process 32bit RGBA images. + * Stuart Coyle 2004-2007 + * From: http://pngnq.sourceforge.net/ + * + * Ported to libgd by Pierre A. Joye + * (and make it thread safety by droping static and global variables) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "gd.h" +#include "gd_errors.h" +#include "gdhelpers.h" +#include +#include +#include + +#include "gd_nnquant.h" + +/* Network Definitions + ------------------- */ + +#define maxnetpos (MAXNETSIZE - 1) +#define netbiasshift 4 /* bias for colour values */ +#define ncycles 100 /* no. of learning cycles */ + +/* defs for freq and bias */ +#define intbiasshift 16 /* bias for fractions */ +#define intbias (((int)1) << intbiasshift) +#define gammashift 10 /* gamma = 1024 */ +#define gamma (((int)1) << gammashift) +#define betashift 10 +#define beta (intbias >> betashift) /* beta = 1/1024 */ +#define betagamma (intbias << (gammashift - betashift)) + +/* defs for decreasing radius factor */ +#define initrad (MAXNETSIZE >> 3) /* for 256 cols, radius starts */ +#define radiusbiasshift 6 /* at 32.0 biased by 6 bits */ +#define radiusbias (((int)1) << radiusbiasshift) +#define initradius (initrad * radiusbias) /* and decreases by a */ +#define radiusdec 30 /* factor of 1/30 each cycle */ + +/* defs for decreasing alpha factor */ +#define alphabiasshift 10 /* alpha starts at 1.0 */ +#define initalpha (((int)1) << alphabiasshift) + +/* radbias and alpharadbias used for radpower calculation */ +#define radbiasshift 8 +#define radbias (((int)1) << radbiasshift) +#define alpharadbshift (alphabiasshift + radbiasshift) +#define alpharadbias (((int)1) << alpharadbshift) + +#define ALPHA 0 +#define RED 1 +#define BLUE 2 +#define GREEN 3 + +typedef int nq_pixel[5]; + +typedef struct { + /* biased by 10 bits */ + int alphadec; + + /* lengthcount = H*W*3 */ + int lengthcount; + + /* sampling factor 1..30 */ + int samplefac; + + /* Number of colours to use. Made a global instead of #define */ + int netsize; + + /* for network lookup - really 256 */ + int netindex[256]; + + /* ABGRc */ + /* the network itself */ + nq_pixel network[MAXNETSIZE]; + + /* bias and freq arrays for learning */ + int bias[MAXNETSIZE]; + int freq[MAXNETSIZE]; + + /* radpower for precomputation */ + int radpower[initrad]; + + /* the input image itself */ + unsigned char *thepicture; +} nn_quant; + +/* Initialise network in range (0,0,0,0) to (255,255,255,255) and set parameters + ----------------------------------------------------------------------- */ +static void initnet(nn_quant *nnq, unsigned char *thepic, int len, int sample, int colours) +{ + register int i; + register int *p; + + /* Clear out network from previous runs */ + /* thanks to Chen Bin for this fix */ + memset((void *)nnq->network, 0, sizeof(nq_pixel) * MAXNETSIZE); + + nnq->thepicture = thepic; + nnq->lengthcount = len; + nnq->samplefac = sample; + nnq->netsize = colours; + + for (i = 0; i < nnq->netsize; i++) { + p = nnq->network[i]; + p[0] = p[1] = p[2] = p[3] = (i << (netbiasshift + 8)) / nnq->netsize; + nnq->freq[i] = intbias / nnq->netsize; /* 1/netsize */ + nnq->bias[i] = 0; + } +} + +/* -------------------------- */ + +/* Unbias network to give byte values 0..255 and record + * position i to prepare for sort + */ +/* -------------------------- */ + +static void unbiasnet(nn_quant *nnq) +{ + int i, j, temp; + + for (i = 0; i < nnq->netsize; i++) { + for (j = 0; j < 4; j++) { + /* OLD CODE: network[i][j] >>= netbiasshift; */ + /* Fix based on bug report by Juergen Weigert jw@suse.de */ + temp = (nnq->network[i][j] + (1 << (netbiasshift - 1))) >> netbiasshift; + if (temp > 255) + temp = 255; + nnq->network[i][j] = temp; + } + nnq->network[i][4] = i; /* record colour no */ + } +} + +/* Output colormap to unsigned char ptr in RGBA format */ +static void getcolormap(nn_quant *nnq, unsigned char *map) +{ + int i, j; + for (j = 0; j < nnq->netsize; j++) { + for (i = 3; i >= 0; i--) { + *map = nnq->network[j][i]; + map++; + } + } +} + +/* Insertion sort of network and building of netindex[0..255] (to do after + unbias) + ------------------------------------------------------------------------------- + */ +static void inxbuild(nn_quant *nnq) +{ + register int i, j, smallpos, smallval; + register int *p, *q; + int previouscol, startpos; + + previouscol = 0; + startpos = 0; + for (i = 0; i < nnq->netsize; i++) { + p = nnq->network[i]; + smallpos = i; + smallval = p[2]; /* index on g */ + /* find smallest in i..netsize-1 */ + for (j = i + 1; j < nnq->netsize; j++) { + q = nnq->network[j]; + if (q[2] < smallval) { /* index on g */ + smallpos = j; + smallval = q[2]; /* index on g */ + } + } + q = nnq->network[smallpos]; + /* swap p (i) and q (smallpos) entries */ + if (i != smallpos) { + j = q[0]; + q[0] = p[0]; + p[0] = j; + j = q[1]; + q[1] = p[1]; + p[1] = j; + j = q[2]; + q[2] = p[2]; + p[2] = j; + j = q[3]; + q[3] = p[3]; + p[3] = j; + j = q[4]; + q[4] = p[4]; + p[4] = j; + } + /* smallval entry is now in position i */ + if (smallval != previouscol) { + nnq->netindex[previouscol] = (startpos + i) >> 1; + for (j = previouscol + 1; j < smallval; j++) + nnq->netindex[j] = i; + previouscol = smallval; + startpos = i; + } + } + nnq->netindex[previouscol] = (startpos + maxnetpos) >> 1; + for (j = previouscol + 1; j < 256; j++) + nnq->netindex[j] = maxnetpos; /* really 256 */ +} + +/* Search for ABGR values 0..255 (after net is unbiased) and return colour index + ---------------------------------------------------------------------------- + */ +static unsigned int inxsearch(nn_quant *nnq, int al, int b, int g, int r) +{ + register int i, j, dist, a, bestd; + register int *p; + unsigned int best; + + bestd = 1000; /* biggest possible dist is 256*3 */ + best = 0; + i = nnq->netindex[g]; /* index on g */ + j = i - 1; /* start at netindex[g] and work outwards */ + + while ((i < nnq->netsize) || (j >= 0)) { + if (i < nnq->netsize) { + p = nnq->network[i]; + dist = p[2] - g; /* inx key */ + if (dist >= bestd) + i = nnq->netsize; /* stop iter */ + else { + i++; + if (dist < 0) + dist = -dist; + a = p[1] - b; + if (a < 0) + a = -a; + dist += a; + if (dist < bestd) { + a = p[3] - r; + if (a < 0) + a = -a; + dist += a; + } + if (dist < bestd) { + a = p[0] - al; + if (a < 0) + a = -a; + dist += a; + } + if (dist < bestd) { + bestd = dist; + best = p[4]; + } + } + } + + if (j >= 0) { + p = nnq->network[j]; + dist = g - p[2]; /* inx key - reverse dif */ + if (dist >= bestd) + j = -1; /* stop iter */ + else { + j--; + if (dist < 0) + dist = -dist; + a = p[1] - b; + if (a < 0) + a = -a; + dist += a; + if (dist < bestd) { + a = p[3] - r; + if (a < 0) + a = -a; + dist += a; + } + if (dist < bestd) { + a = p[0] - al; + if (a < 0) + a = -a; + dist += a; + } + if (dist < bestd) { + bestd = dist; + best = p[4]; + } + } + } + } + + return (best); +} + +/* Search for biased ABGR values + ---------------------------- */ +static int contest(nn_quant *nnq, int al, int b, int g, int r) +{ + /* finds closest neuron (min dist) and updates freq */ + /* finds best neuron (min dist-bias) and returns position */ + /* for frequently chosen neurons, freq[i] is high and bias[i] is negative */ + /* bias[i] = gamma*((1/netsize)-freq[i]) */ + + register int i, dist, a, biasdist, betafreq; + unsigned int bestpos, bestbiaspos; + double bestd, bestbiasd; + register int *p, *f, *n; + + bestd = INT_MAX; + bestbiasd = bestd; + bestpos = 0; + bestbiaspos = bestpos; + p = nnq->bias; + f = nnq->freq; + + for (i = 0; i < nnq->netsize; i++) { + n = nnq->network[i]; + dist = n[0] - al; + if (dist < 0) + dist = -dist; + a = n[1] - b; + if (a < 0) + a = -a; + dist += a; + a = n[2] - g; + if (a < 0) + a = -a; + dist += a; + a = n[3] - r; + if (a < 0) + a = -a; + dist += a; + if (dist < bestd) { + bestd = dist; + bestpos = i; + } + biasdist = dist - ((*p) >> (intbiasshift - netbiasshift)); + if (biasdist < bestbiasd) { + bestbiasd = biasdist; + bestbiaspos = i; + } + betafreq = (*f >> betashift); + *f++ -= betafreq; + *p++ += (betafreq << gammashift); + } + nnq->freq[bestpos] += beta; + nnq->bias[bestpos] -= betagamma; + return (bestbiaspos); +} + +/* Move neuron i towards biased (a,b,g,r) by factor alpha + ---------------------------------------------------- */ + +static void altersingle(nn_quant *nnq, int alpha, int i, int al, int b, int g, int r) +{ + register int *n; + + n = nnq->network[i]; /* alter hit neuron */ + *n -= (alpha * (*n - al)) / initalpha; + n++; + *n -= (alpha * (*n - b)) / initalpha; + n++; + *n -= (alpha * (*n - g)) / initalpha; + n++; + *n -= (alpha * (*n - r)) / initalpha; +} + +/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in + radpower[|i-j|] + --------------------------------------------------------------------------------- + */ + +static void alterneigh(nn_quant *nnq, int rad, int i, int al, int b, int g, int r) +{ + register int j, k, lo, hi, a; + register int *p, *q; + + lo = i - rad; + if (lo < -1) + lo = -1; + hi = i + rad; + if (hi > nnq->netsize) + hi = nnq->netsize; + + j = i + 1; + k = i - 1; + q = nnq->radpower; + while ((j < hi) || (k > lo)) { + a = (*(++q)); + if (j < hi) { + p = nnq->network[j]; + *p -= (a * (*p - al)) / alpharadbias; + p++; + *p -= (a * (*p - b)) / alpharadbias; + p++; + *p -= (a * (*p - g)) / alpharadbias; + p++; + *p -= (a * (*p - r)) / alpharadbias; + j++; + } + if (k > lo) { + p = nnq->network[k]; + *p -= (a * (*p - al)) / alpharadbias; + p++; + *p -= (a * (*p - b)) / alpharadbias; + p++; + *p -= (a * (*p - g)) / alpharadbias; + p++; + *p -= (a * (*p - r)) / alpharadbias; + k--; + } + } +} + +/* Main Learning Loop + ------------------ */ + +static void learn(nn_quant *nnq, int verbose) /* Stu: N.B. added parameter so that main() could + control verbosity. */ +{ + register int i, j, al, b, g, r; + int radius, rad, alpha, step, delta, samplepixels; + register unsigned char *p; + unsigned char *lim; + + nnq->alphadec = 30 + ((nnq->samplefac - 1) / 3); + p = nnq->thepicture; + lim = nnq->thepicture + nnq->lengthcount; + samplepixels = nnq->lengthcount / (4 * nnq->samplefac); + /* here's a problem with small images: samplepixels < ncycles => delta = 0 + */ + delta = samplepixels / ncycles; + /* kludge to fix */ + if (delta == 0) + delta = 1; + alpha = initalpha; + radius = initradius; + + rad = radius >> radiusbiasshift; + + for (i = 0; i < rad; i++) + nnq->radpower[i] = alpha * (((rad * rad - i * i) * radbias) / (rad * rad)); + + if (verbose) + gd_error_ex(GD_NOTICE, "beginning 1D learning: initial radius=%d\n", rad); + + if ((nnq->lengthcount % prime1) != 0) + step = 4 * prime1; + else { + if ((nnq->lengthcount % prime2) != 0) + step = 4 * prime2; + else { + if ((nnq->lengthcount % prime3) != 0) + step = 4 * prime3; + else + step = 4 * prime4; + } + } + + i = 0; + while (i < samplepixels) { + al = p[ALPHA] << netbiasshift; + b = p[BLUE] << netbiasshift; + g = p[GREEN] << netbiasshift; + r = p[RED] << netbiasshift; + j = contest(nnq, al, b, g, r); + + altersingle(nnq, alpha, j, al, b, g, r); + if (rad) + alterneigh(nnq, rad, j, al, b, g, r); /* alter neighbours */ + + p += step; + while (p >= lim) + p -= nnq->lengthcount; + + i++; + if (i % delta == 0) { /* FPE here if delta=0*/ + alpha -= alpha / nnq->alphadec; + radius -= radius / radiusdec; + rad = radius >> radiusbiasshift; + if (rad <= 1) + rad = 0; + for (j = 0; j < rad; j++) + nnq->radpower[j] = alpha * (((rad * rad - j * j) * radbias) / (rad * rad)); + } + } + if (verbose) + gd_error_ex(GD_NOTICE, "finished 1D learning: final alpha=%f !\n", + ((float)alpha) / initalpha); +} + +/** + * Function: gdImageNeuQuant + * + * Creates a new palette image from a truecolor image + * + * This is the same as calling with the + * quantization method . + * + * Parameters: + * im - The image. + * max_color - The number of desired palette entries. + * sample_factor - The quantization precision between 1 (highest quality) and + * 10 (fastest). + * + * Returns: + * A newly create palette image; NULL on failure. + */ +BGD_DECLARE(gdImagePtr) +gdImageNeuQuant(gdImagePtr im, const int max_color, int sample_factor) +{ + const int newcolors = max_color; + const int verbose = 1; + + int i, x; + + unsigned char map[MAXNETSIZE][4] = {{0}}; + unsigned char *d; + + nn_quant *nnq = NULL; + + int row; + unsigned char *rgba = NULL; + gdImagePtr dst = NULL; + + if (newcolors <= 0 || newcolors > MAXNETSIZE) { + gd_error("neuquant: max_color must be between 1 and %d\n", MAXNETSIZE); + goto done; + } + + /* Default it to 3 */ + if (sample_factor < 1) { + sample_factor = 3; + } + /* Start neuquant */ + /* Pierre: + * This implementation works with aligned contiguous buffer only + * Upcoming new buffers are contiguous and will be much faster. + * let don't bloat this code to support our good "old" 31bit format. + * It also lets us convert palette image, if one likes to reduce + * a palette + */ + if (overflow2(gdImageSX(im), gdImageSY(im)) || overflow2(gdImageSX(im) * gdImageSY(im), 4)) { + goto done; + } + rgba = (unsigned char *)gdMalloc(gdImageSX(im) * gdImageSY(im) * 4); + if (!rgba) { + goto done; + } + + d = rgba; + for (row = 0; row < gdImageSY(im); row++) { + int *p = im->tpixels[row]; + register int c; + + for (i = 0; i < gdImageSX(im); i++) { + c = *p; + *d++ = gdImageAlpha(im, c); + *d++ = gdImageRed(im, c); + *d++ = gdImageBlue(im, c); + *d++ = gdImageGreen(im, c); + p++; + } + } + + nnq = (nn_quant *)gdMalloc(sizeof(nn_quant)); + if (!nnq) { + goto done; + } + + initnet(nnq, rgba, gdImageSY(im) * gdImageSX(im) * 4, sample_factor, newcolors); + + learn(nnq, verbose); + unbiasnet(nnq); + getcolormap(nnq, (unsigned char *)map); + inxbuild(nnq); + + dst = gdImageCreate(gdImageSX(im), gdImageSY(im)); + if (!dst) { + goto done; + } + + for (x = 0; x < newcolors; ++x) { + dst->red[x] = map[x][0]; + dst->green[x] = map[x][1]; + dst->blue[x] = map[x][2]; + dst->alpha[x] = map[x][3]; + dst->open[x] = 0; + dst->colorsTotal++; + } + + /* Do each image row */ + for (row = 0; row < gdImageSY(im); ++row) { + int offset; + unsigned char *p = dst->pixels[row]; + + /* Assign the new colors */ + offset = row * gdImageSX(im) * 4; + for (i = 0; i < gdImageSX(im); i++) { + p[i] = inxsearch(nnq, rgba[i * 4 + offset + ALPHA], rgba[i * 4 + offset + BLUE], + rgba[i * 4 + offset + GREEN], rgba[i * 4 + offset + RED]); + } + } + +done: + if (rgba) { + gdFree(rgba); + } + + if (nnq) { + gdFree(nnq); + } + return dst; +} diff --git a/ext/gd/libgd/gd_nnquant.h b/ext/gd/libgd/gd_nnquant.h new file mode 100644 index 000000000000..0b7a17889609 --- /dev/null +++ b/ext/gd/libgd/gd_nnquant.h @@ -0,0 +1,15 @@ +/* maximum number of colours that can be used. + actual number is now passed to initcolors */ +#define MAXNETSIZE 256 + +/* For 256 colours, fixed arrays need 8kb, plus space for the image + ---------------------------------------------------------------- */ + +/* four primes near 500 - assume no image has a length so large */ +/* that it is divisible by all four primes */ +#define prime1 499 +#define prime2 491 +#define prime3 487 +#define prime4 503 + +#define minpicturebytes (4 * prime4) /* minimum size for input image */ diff --git a/ext/gd/libgd/gd_path.c b/ext/gd/libgd/gd_path.c new file mode 100644 index 000000000000..85fe5fe775ad --- /dev/null +++ b/ext/gd/libgd/gd_path.c @@ -0,0 +1,726 @@ + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "gd_compositor.h" +#include "gd_gradient.h" +#include "gd_path.h" +#include "gd_path_arc.h" +#include "gd_path_dash.h" +#include "gd_path_matrix.h" +#include "gd_span_rle.h" + +static gdSurfacePtr gdSurfaceSnapshotImage(gdImagePtr image) +{ + gdSurfacePtr surface; + int x, y; + + if (!image) + return NULL; + surface = gdSurfaceCreate(image->sx, image->sy, GD_SURFACE_ARGB32); + if (!surface) + return NULL; + for (y = 0; y < image->sy; y++) { + uint32_t *row = (uint32_t *)(surface->data + y * surface->stride); + for (x = 0; x < image->sx; x++) { + int pixel = gdImageGetTrueColorPixel(image, x, y); + row[x] = gdCompositePixelToArgb32(gdCompositePixelFromGd(pixel)); + } + } + return surface; +} + +gdPaintPtr gdPaintAddRef(gdPaintPtr paint) +{ + if (paint == NULL) + return NULL; + + ++paint->ref; + return paint; +} + +BGD_DECLARE(void) gdPaintDestroy(gdPaintPtr paint) +{ + if (paint == NULL) + return; + paint->ref--; + + if (paint->ref == 0) { + switch (paint->type) { + case gdPaintTypeColor: + gdFree(paint->color); + break; + case gdPaintTypeGradient: + gdGradientDestroy(paint->gradient); + break; + case gdPaintTypeSurface: + // Not implemented + break; + case gdPaintTypePattern: + gdPathPatternDestroy(paint->pattern); + break; + default: { + } + } + gdFree(paint); + } +} + +void gdColorInitRgba(gdColorPtr color, double r, double g, double b, double a) +{ + color->r = CLAMP(r, 0.0, 1.0); + color->g = CLAMP(g, 0.0, 1.0); + color->b = CLAMP(b, 0.0, 1.0); + color->a = CLAMP(a, 0.0, 1.0); +} + +gdPathPatternPtr gdPaintGetPattern(const gdPaintPtr paint) +{ + return paint->type == gdPaintTypePattern ? paint->pattern : NULL; +} + +GD_VECTOR2D_INTERNAL gdPathPatternPtr gdPathPatternCreate(gdSurfacePtr surface) +{ + if (!surface) + return NULL; + gdPathPatternPtr pattern = gdMalloc(sizeof(gdPathPattern)); + if (!pattern) + return NULL; + pattern->ref = 1; + pattern->extend = GD_EXTEND_NONE; + pattern->surface = surface; + gdSurfaceAddRef(surface); + pattern->opacity = 1.0; + gdPathMatrixInitIdentity(&pattern->matrix); + return pattern; +} + +BGD_DECLARE(gdPathPatternPtr) gdPathPatternCreateForImage(gdImagePtr image) +{ + gdSurfacePtr snapshot = gdSurfaceSnapshotImage(image); + gdPathPatternPtr pattern; + + if (!snapshot) + return NULL; + pattern = gdPathPatternCreate(snapshot); + gdSurfaceDestroy(snapshot); + return pattern; +} + +BGD_DECLARE(void) gdPathPatternDestroy(gdPathPatternPtr pattern) +{ + if (pattern == NULL) + return; + + if (--pattern->ref == 0) { + gdSurfaceDestroy(pattern->surface); + gdFree(pattern); + } +} + +void gdPathPatternAddRef(gdPathPatternPtr pattern) +{ + if (pattern == NULL) + return; + pattern->ref++; +} + +BGD_DECLARE(gdPaintPtr) gdPaintCreateFromPattern(gdPathPatternPtr pattern) +{ + gdPaintPtr paint = gdMalloc(sizeof(gdPaint)); + if (!paint) + return NULL; + paint->ref = 1; + paint->type = gdPaintTypePattern; + paint->pattern = pattern; + gdPathPatternAddRef(pattern); + return paint; +} + +gdPaintPtr gdPaintCreateForSurface(gdSurfacePtr surface) +{ + gdPathPatternPtr pattern = gdPathPatternCreate(surface); + gdPaintPtr paint = gdPaintCreateFromPattern(pattern); + gdPathPatternDestroy(pattern); + return paint; +} + +BGD_DECLARE(void) gdPathPatternSetExtend(gdPathPatternPtr pattern, gdExtendMode extend) +{ + pattern->extend = extend; +} + +BGD_DECLARE(void) gdPathPatternSetMatrix(gdPathPatternPtr pattern, gdPathMatrixPtr matrix) +{ + memcpy(&pattern->matrix, matrix, sizeof(gdPathMatrix)); +} + +BGD_DECLARE(void) gdPathPatternSetOpacity(gdPathPatternPtr pattern, double opacity) +{ + if (!pattern || !isfinite(opacity)) + return; + pattern->opacity = CLAMP(opacity, 0.0, 1.0); +} + +void gdPaintSetSourceSurface(gdContextPtr context, gdSurfacePtr surface, double x, double y) +{ + gdPathMatrix matrix; + gdPaintPtr paint; + gdPathPatternPtr pattern = gdPathPatternCreate(surface); + gdPathPatternSetExtend(pattern, GD_EXTEND_NONE); + gdPathMatrixMultiply(&matrix, &matrix, &context->state->matrix); + gdPathMatrixInitTranslate(&matrix, x, y); + gdPathPatternSetMatrix(pattern, &matrix); + paint = gdPaintCreateFromPattern(pattern); + gdContextSetSource(context, paint); +} + +gdPaintPtr gdPaintCreateRgba(double r, double g, double b, double a) +{ + gdPaintPtr paint = gdMalloc(sizeof(gdPaint)); + if (!paint) { + return NULL; + } + paint->color = gdMalloc(sizeof(gdColor)); + if (!paint->color) { + gdFree(paint); + return NULL; + } + + paint->ref = 1; + paint->type = gdPaintTypeColor; + gdColorInitRgba(paint->color, r, g, b, a); + return paint; +} + +gdPaintPtr gdPaintCreateRgb(double r, double g, double b) +{ + return gdPaintCreateRgba(r, g, b, 1.0); +} + +BGD_DECLARE(void) gdContextSetSource(gdContextPtr context, gdPaintPtr source) +{ + source = gdPaintAddRef(source); + gdPaintDestroy(context->state->source); + context->state->source = source; +} + +void gdContextSetSourceColorRgb(gdContextPtr context, double r, double g, double b) +{ + gdContextSetSourceRgba(context, r, g, b, 1.0); +} + +gdStatePtr gdStateCreate() +{ + gdStatePtr state = gdMalloc(sizeof(gdState)); + if (!state) { + return NULL; + } + // state->font = NULL; + state->source = gdPaintCreateRgba(0, 0, 0, 1.0); + if (!state->source) { + gdFree(state); + return NULL; + } + gdPathMatrixInitIdentity(&state->matrix); + state->winding = gdFillRuleNonZero; + state->stroke.width = 1.0; + state->stroke.miterlimit = 4.0; + state->stroke.cap = gdLineCapButt; + state->stroke.join = gdLineJoinMiter; + state->stroke.dash = NULL; + state->op = GD_OP_OVER; + // state->fontsize = 12.0; + state->opacity = 1.0; + state->clippath = NULL; + state->next = NULL; + return state; +} + +void gdStateDestroy(gdStatePtr state) +{ + // state->font + gdSpanRleDestroy(state->clippath); + gdPaintDestroy(state->source); + gdPathDashDestroy(state->stroke.dash); + gdFree(state); +} + +BGD_DECLARE(gdPathPtr) gdPathCreate() +{ + gdPathPtr path = gdMalloc(sizeof(gdPath)); + if (!path) + return NULL; + path->ref = 1; + path->contours = 0; + path->start.x = 0.0; + path->start.y = 0.0; + gdArrayInit(&path->elements, sizeof(gdPathOps)); + gdArrayInit(&path->points, sizeof(gdPointF)); + return path; +} + +BGD_DECLARE(gdPathPtr) gdPathDuplicate(const gdPathPtr path) +{ + unsigned int num_elements; + unsigned int num_points; + gdPathPtr result; + + if (!path) + return NULL; + result = gdPathCreate(); + if (!result) + return NULL; + + num_elements = gdArrayNumElements(&path->elements); + num_points = gdArrayNumElements(&path->points); + if ((num_elements && !gdArrayAppendMultiple(&result->elements, gdArrayGetData(&path->elements), + num_elements)) || + (num_points && + !gdArrayAppendMultiple(&result->points, gdArrayGetData(&path->points), num_points))) { + gdPathDestroy(result); + return NULL; + } + + result->contours = path->contours; + result->start = path->start; + + return result; +} + +BGD_DECLARE(void) gdPathAppendPath(gdPathPtr path, const gdPathPtr source) +{ + gdArrayAppendMultiple(&path->elements, gdArrayGetData(&source->elements), + gdArrayNumElements(&source->elements)); + gdArrayAppendMultiple(&path->points, gdArrayGetData(&source->points), + gdArrayNumElements(&source->points)); + + path->contours += source->contours; + path->start = source->start; +} + +BGD_DECLARE(void) gdPathTransform(gdPathPtr path, const gdPathMatrixPtr matrix) +{ + gdPointFPtr p; + unsigned int numElements = gdArrayNumElements(&path->points); + unsigned int i; + + // memset(p, 0, sizeof(gdPointF) * 3); + for (i = 0; i < numElements; i++) { + p = (gdPointFPtr)gdArrayIndex(&path->points, i); + gdPathMatrixMapPoint(matrix, p, p); + } +} + +static inline void _path_get_current_point(const gdPathPtr path, double *x, double *y) +{ + unsigned int numElems = gdArrayNumElements(&path->points); + if (x) + *x = 0.0; + if (y) + *y = 0.0; + if (numElems < 1) + return; + gdPointFPtr point = gdArrayIndex(&path->points, numElems - 1); + if (x) { + *x = point->x; + } + if (y) { + *y = point->y; + } +} + +typedef struct { + double x1; + double y1; + double x2; + double y2; + double x3; + double y3; + double x4; + double y4; +} cubic_points; + +static inline void split(const cubic_points *b, cubic_points *first, cubic_points *second) +{ + double c = (b->x2 + b->x3) * 0.5; + first->x2 = (b->x1 + b->x2) * 0.5; + second->x3 = (b->x3 + b->x4) * 0.5; + first->x1 = b->x1; + second->x4 = b->x4; + first->x3 = (first->x2 + c) * 0.5; + second->x2 = (second->x3 + c) * 0.5; + first->x4 = second->x1 = (first->x3 + second->x2) * 0.5; + + c = (b->y2 + b->y3) * 0.5; + first->y2 = (b->y1 + b->y2) * 0.5; + second->y3 = (b->y3 + b->y4) * 0.5; + first->y1 = b->y1; + second->y4 = b->y4; + first->y3 = (first->y2 + c) * 0.5; + second->y2 = (second->y3 + c) * 0.5; + first->y4 = second->y1 = (first->y3 + second->y2) * 0.5; +} + +/* See http://agg.sourceforge.net/antigrain.com/research/adaptive_bezier/index.html */ +static void _cubic_flatten(gdPathPtr path, const gdPointFPtr p0, const gdPointFPtr p1, + const gdPointFPtr p2, const gdPointFPtr p3) +{ + cubic_points beziers[32]; + beziers[0].x1 = p0->x; + beziers[0].y1 = p0->y; + beziers[0].x2 = p1->x; + beziers[0].y2 = p1->y; + beziers[0].x3 = p2->x; + beziers[0].y3 = p2->y; + beziers[0].x4 = p3->x; + beziers[0].y4 = p3->y; + + /* tolerance for the distance t to the line + 0.1 is a common accepted value + */ + const double tolerance = 0.1; + + cubic_points *b = beziers; + while (b >= beziers) { + double y4y1 = b->y4 - b->y1; + double x4x1 = b->x4 - b->x1; + double l = fabs(x4x1) + fabs(y4y1); + double d; + if (l > 1.0) { + d = fabs((x4x1) * (b->y1 - b->y2) - (y4y1) * (b->x1 - b->x2)) + + fabs((x4x1) * (b->y1 - b->y3) - (y4y1) * (b->x1 - b->x3)); + } else { + d = fabs(b->x1 - b->x2) + fabs(b->y1 - b->y2) + fabs(b->x1 - b->x3) + + fabs(b->y1 - b->y3); + l = 1.0; + } + + if (d < tolerance * l || b == beziers + 31) { + gdPathLineTo(path, b->x4, b->y4); + --b; + } else { + split(b, b + 1, b); + ++b; + } + } +} + +gdPathPtr gdPathDuplicateFlattened(const gdPathPtr path) +{ + gdPathPtr result = gdPathCreate(); + + gdArrayReallocBy(&result->elements, gdArrayNumElements(&path->elements)); + gdArrayReallocBy(&result->points, gdArrayNumElements(&path->points)); + + gdPointFPtr points = gdArrayGetData(&path->points); + for (unsigned int i = 0; i < gdArrayNumElements(&path->elements); i++) { + const gdPathOpsPtr cur_elem = gdArrayIndex(&path->elements, i); + switch (*cur_elem) { + case gdPathOpsMoveTo: + gdPathMoveTo(result, points[0].x, points[0].y); + points += 1; + break; + case gdPathOpsLineTo: + case gdPathOpsClose: + gdPathLineTo(result, points[0].x, points[0].y); + points += 1; + break; + case gdPathOpsCubicTo: { + gdPointF p0; + _path_get_current_point(result, &p0.x, &p0.y); + _cubic_flatten(result, &p0, points, points + 1, points + 2); + points += 3; + break; + } + default: + // Only to silent compiler + break; + } + } + return result; +} + +gdPathPtr gdPathAddRef(gdPathPtr path) +{ + if (path == NULL) + return NULL; + path->ref++; + return path; +} + +BGD_DECLARE(void) gdPathDestroy(gdPathPtr path) +{ + if (path == NULL) + return; + path->ref--; + if (path->ref == 0) { + gdArrayDestroy(&path->elements); + gdArrayDestroy(&path->points); + gdFree(path); + } +} + +void gdPathClear(gdPathPtr path) +{ + gdArrayTruncate(&path->elements, 0); + gdArrayTruncate(&path->points, 0); + path->contours = 0; + path->start.x = 0.0; + path->start.y = 0.0; +} + +/* dump a path, could be nicer but good enough for now +Not exported, only for debugging purposes here */ +void gdPathDumpPathTransform(const gdPathPtr path, const gdPathMatrixPtr matrix) +{ + // GD_FT_Outline* outline = gd_ft_outline_create(path->points.size, path->contours); + gdPointF p[3]; + unsigned int numElements = gdArrayNumElements(&path->elements); + unsigned int pointsIndex = 0; + unsigned int i; + + memset(p, 0, sizeof(gdPointF) * 3); + printf("NEWOUTLINE CONVERT\n"); + for (i = 0; i < numElements; i++) { + gdPathOpsPtr element = (gdPathOpsPtr)gdArrayIndex(&path->elements, i); + gdPointFPtr point = gdArrayIndex(&path->points, pointsIndex); + printf("-------\n"); + switch (*element) { + case gdPathOpsMoveTo: + if (matrix) + gdPathMatrixMapPoint(matrix, point, &p[0]); + printf("MoveTo(%f, %f)", point->x, point->y); + printf("(%f, %f)", p[0].x, p[0].y); + pointsIndex += 1; + break; + case gdPathOpsLineTo: + if (matrix) + gdPathMatrixMapPoint(matrix, point, &p[0]); + printf("LineTo(%f, %f)", point->x, point->y); + printf("(%f, %f)", p[0].x, p[0].y); + pointsIndex += 1; + break; + case gdPathOpsCubicTo: + printf("CubicTo(%f, %f)", point->x, point->y); + if (matrix) + gdPathMatrixMapPoint(matrix, point, &p[0]); + printf("(%f, %f)", p[0].x, p[0].y); + + point = gdArrayIndex(&path->points, pointsIndex + 1); + if (matrix) + gdPathMatrixMapPoint(matrix, point, &p[1]); + printf("(%f, %f)", p[1].x, p[1].y); + + point = gdArrayIndex(&path->points, pointsIndex + 2); + if (matrix) + gdPathMatrixMapPoint(matrix, point, &p[2]); + printf("(%f, %f)", p[2].x, p[2].y); + pointsIndex += 3; + break; + case gdPathOpsClose: + printf("Outline close"); + pointsIndex += 1; + break; + default: + break; + } + printf("\n-------\n"); + } +} + +static inline void _relativeTo(const gdPathPtr path, double *x, double *y) +{ + double _x = -1, _y = -1; + _path_get_current_point(path, &_x, &_y); + *x += _x; + *y += _y; +} + +BGD_DECLARE(void) gdPathMoveTo(gdPathPtr path, double x, double y) +{ + const gdPathOps op = gdPathOpsMoveTo; + gdPointF point; + + gdArrayAppend(&path->elements, &op); + path->contours += 1; + + point.x = x; + point.y = y; + gdArrayAppend(&path->points, &point); + path->start.x = x; + path->start.y = y; +} + +BGD_DECLARE(void) gdPathRelMoveTo(gdPathPtr path, double dx, double dy) +{ + _relativeTo(path, &dx, &dy); + gdPathMoveTo(path, dx, dy); +} + +BGD_DECLARE(void) gdPathLineTo(gdPathPtr path, double x, double y) +{ + const gdPathOps op = gdPathOpsLineTo; + gdPointF point; + + gdArrayAppend(&path->elements, &op); + + point.x = x; + point.y = y; + gdArrayAppend(&path->points, &point); +} +BGD_DECLARE(void) gdPathRelLineTo(gdPathPtr path, double dx, double dy) +{ + _relativeTo(path, &dx, &dy); + gdPathLineTo(path, dx, dy); +} + +BGD_DECLARE(void) +gdPathCurveTo(gdPathPtr path, double x1, double y1, double x2, double y2, double x3, double y3) +{ + const gdPathOps op = gdPathOpsCubicTo; + gdPointF points[3]; + + gdArrayAppend(&path->elements, &op); + points[0].x = x1; + points[0].y = y1; + points[1].x = x2; + points[1].y = y2; + points[2].x = x3; + points[2].y = y3; + gdArrayAppend(&path->points, &points[0]); + gdArrayAppend(&path->points, &points[1]); + gdArrayAppend(&path->points, &points[2]); +} + +BGD_DECLARE(void) +gdPathRelCurveTo(gdPathPtr path, double dx1, double dy1, double dx2, double dy2, double dx3, + double dy3) +{ + _relativeTo(path, &dx1, &dy1); + _relativeTo(path, &dx2, &dy2); + _relativeTo(path, &dx3, &dy3); + gdPathCurveTo(path, dx1, dy1, dx2, dy2, dx3, dy3); +} + +BGD_DECLARE(void) gdPathQuadTo(gdPathPtr path, double x1, double y1, double x2, double y2) +{ + const gdPathOps op = gdPathOpsQuadTo; + gdPointF points[2] = {{x1, y1}, {x2, y2}}; + + gdArrayAppend(&path->elements, &op); + gdArrayAppend(&path->points, &points[0]); + gdArrayAppend(&path->points, &points[1]); +} + +BGD_DECLARE(void) gdPathRelQuadTo(gdPathPtr path, double dx1, double dy1, double dx2, double dy2) +{ + _relativeTo(path, &dx1, &dy1); + _relativeTo(path, &dx2, &dy2); + gdPathQuadTo(path, dx1, dy1, dx2, dy2); +} + +/* +Based on http://www.whizkidtech.redprince.net/bezier/circle/kappa/ +*/ +static void _gdPathArc(gdPathPtr path, double cx, double cy, double radius, double angle1, + double angle2, int ccw) +{ + if (ccw) + _gd_arc_path_negative(path, cx, cy, radius, angle1, angle2); + else + _gd_arc_path(path, cx, cy, radius, angle1, angle2); +} + +BGD_DECLARE(void) +gdPathArc(gdPathPtr path, double cx, double cy, double radius, double angle1, double angle2) +{ + _gdPathArc(path, cx, cy, radius, angle1, angle2, 0); +} + +BGD_DECLARE(void) +gdPathNegativeArc(gdPathPtr path, double cx, double cy, double radius, double angle1, double angle2) +{ + _gdPathArc(path, cx, cy, radius, angle1, angle2, 1); +} + +BGD_DECLARE(void) +gdPathArcTo(gdPathPtr path, double x1, double y1, double x2, double y2, double radius) +{ + double x0, y0; + _path_get_current_point(path, &x0, &y0); + if ((x0 == x1 && y0 == y1) || (x1 == x2 && y1 == y2) || radius <= 0.0) { + gdPathLineTo(path, x1, y1); + return; + } + + double dir = (x2 - x1) * (y0 - y1) + (y2 - y1) * (x1 - x0); + if (dir == 0.0) { + gdPathLineTo(path, x1, y1); + return; + } + + double a2 = (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1); + double b2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + double c2 = (x0 - x2) * (x0 - x2) + (y0 - y2) * (y0 - y2); + + double cosx = (a2 + b2 - c2) / (2 * sqrt(a2 * b2)); + double sinx = sqrt(1 - cosx * cosx); + double d = radius / ((1 - cosx) / sinx); + + double anx = (x1 - x0) / sqrt(a2); + double any = (y1 - y0) / sqrt(a2); + double bnx = (x1 - x2) / sqrt(b2); + double bny = (y1 - y2) / sqrt(b2); + + double x3 = x1 - anx * d; + double y3 = y1 - any * d; + double x4 = x1 - bnx * d; + double y4 = y1 - bny * d; + + int ccw = dir < 0.0; + double cx = x3 + any * radius * (ccw ? 1 : -1); + double cy = y3 - anx * radius * (ccw ? 1 : -1); + double a0 = atan2(y3 - cy, x3 - cx); + double a1 = atan2(y4 - cy, x4 - cx); + + gdPathLineTo(path, x3, y3); + _gdPathArc(path, cx, cy, radius, a0, a1, ccw); +} + +BGD_DECLARE(void) gdPathRectangle(gdPathPtr path, double x, double y, double w, double h) +{ + gdPathMoveTo(path, x, y); + gdPathLineTo(path, x + w, y); + gdPathLineTo(path, x + w, y + h); + gdPathLineTo(path, x, y + h); + gdPathLineTo(path, x, y); + gdPathClose(path); +} + +BGD_DECLARE(void) gdPathClose(gdPathPtr path) +{ + const int numElements = gdArrayNumElements(&path->elements); + const gdPathOps OpClose = gdPathOpsClose; + if (numElements == 0) + return; + const gdPathOpsPtr lastOpPtr = gdArrayIndex(&path->elements, (unsigned int)numElements - 1); + if (*lastOpPtr == gdPathOpsClose) + return; + + gdPointF point; + point.x = path->start.x; + point.y = path->start.y; + gdArrayAppend(&path->elements, &OpClose); + gdArrayAppend(&path->points, &point); +} + +void gdPathBlend(gdContextPtr context, const gdSpanRlePtr rle); diff --git a/ext/gd/libgd/gd_path.h b/ext/gd/libgd/gd_path.h new file mode 100644 index 000000000000..e84f84e8e30b --- /dev/null +++ b/ext/gd/libgd/gd_path.h @@ -0,0 +1,43 @@ +#ifndef GD_PATH_H +#define GD_PATH_H + +#include "gd_vector2d_private.h" + +#include + +gdPathPtr gdPathAddRef(gdPathPtr path); + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#ifndef M_PI2 +#define M_PI2 M_PI * 2 +#endif + +#define EPSILON_DOUBLE 0.000000000001f +#define MAX_FULL_CIRCLES 65536 +#define PATH_KAPPA 0.5522847498 +#define DEFAULT_TOLERANCE 0.1 +static inline int _doubleEqualsEpsilon(double p1, double p2) +{ + return (fabs(p1 - p2) < EPSILON_DOUBLE); +} + +static inline int _doubleIsZero(double f) { return (fabs(f) <= EPSILON_DOUBLE); } + +#define ARRAY_LENGTH(__array) ((int)(sizeof(__array) / sizeof(__array[0]))) + +gdPaintPtr gdPaintCreateRgba(double r, double g, double b, double a); +gdPaintPtr gdPaintAddRef(gdPaintPtr paint); + +gdStatePtr gdStateCreate(); +void gdStateDestroy(gdStatePtr state); + +gdPathPtr gdPathDuplicateFlattened(const gdPathPtr path); +void gdPathClear(gdPathPtr path); + +gdPaintPtr gdPaintCreateForSurface(gdSurfacePtr surface); +gdPathPatternPtr gdPaintGetPattern(const gdPaintPtr paint); +void gdPaintSetSourceSurface(gdContextPtr context, gdSurfacePtr surface, double x, double y); +void gdPathDumpPathTransform(const gdPathPtr path, const gdPathMatrixPtr matrix); +#endif // GD_PATH_H diff --git a/ext/gd/libgd/gd_path_arc.c b/ext/gd/libgd/gd_path_arc.c new file mode 100644 index 000000000000..6b635168fbb1 --- /dev/null +++ b/ext/gd/libgd/gd_path_arc.c @@ -0,0 +1,250 @@ + +/* This is a port of Carl's amazing work on this. The license chosen + * here is the MPL 1.1, applying to this file only. + * + * Copyright © 2004 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Kristian Høgsberg + * Carl Worth + */ + +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_errors.h" +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "gd_array.h" +#include "gd_path.h" +#include "gd_path_arc.h" +#include "gd_path_matrix.h" +#include "gd_span_rle.h" +#include "gd_surface.h" + +/* Spline deviation from the circle in radius would be given by: + + error = sqrt (x**2 + y**2) - 1 + + A simpler error function to work with is: + + e = x**2 + y**2 - 1 + + From "Good approximation of circles by curvature-continuous Bezier + curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric + Design 8 (1990) 22-41, we learn: + + abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4) + + and + abs (error) =~ 1/2 * e + + Of course, this error value applies only for the particular spline + approximation that is used in _gd_arc_segment. + + Detailed explanation https://itc.ktu.lt/index.php/ITC/article/view/11812 +*/ +static double _arc_error_normalized(double angle) +{ + return 2.0 / 27.0 * pow(sin(angle / 4), 6) / pow(cos(angle / 4), 2); +} + +static double _arc_max_angle_for_tolerance_normalized(double tolerance) +{ + double angle, error; + int i; + + /* Use table lookup to reduce search time in most cases. */ + struct { + double angle; + double error; + } table[] = { + {M_PI / 1.0, 0.0185185185185185036127}, {M_PI / 2.0, 0.000272567143730179811158}, + {M_PI / 3.0, 2.38647043651461047433e-05}, {M_PI / 4.0, 4.2455377443222443279e-06}, + {M_PI / 5.0, 1.11281001494389081528e-06}, {M_PI / 6.0, 3.72662000942734705475e-07}, + {M_PI / 7.0, 1.47783685574284411325e-07}, {M_PI / 8.0, 6.63240432022601149057e-08}, + {M_PI / 9.0, 3.2715520137536980553e-08}, {M_PI / 10.0, 1.73863223499021216974e-08}, + {M_PI / 11.0, 9.81410988043554039085e-09}, + }; + int table_size = ARRAY_LENGTH(table); + + for (i = 0; i < table_size; i++) + if (table[i].error < tolerance) + return table[i].angle; + + ++i; + do { + angle = M_PI / i++; + error = _arc_error_normalized(angle); + } while (error > tolerance); + + return angle; +} + +static int _arc_segments_needed(double angle, double radius, double tolerance) +{ + double major_axis, max_angle; + + major_axis = radius; + max_angle = _arc_max_angle_for_tolerance_normalized(tolerance / major_axis); + + return ceil(fabs(angle) / max_angle); +} + +/* We want to draw a single spline approximating a circular arc radius + R from angle A to angle B. Since we want a symmetric spline that + matches the endpoints of the arc in position and slope, we know + that the spline control points must be: + + (R * cos(A), R * sin(A)) + (R * cos(A) - h * sin(A), R * sin(A) + h * cos (A)) + (R * cos(B) + h * sin(B), R * sin(B) - h * cos (B)) + (R * cos(B), R * sin(B)) + + for some value of h. + + "Approximation of circular arcs by cubic polynomials", Michael + Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides + various values of h along with error analysis for each. + + From that paper, a very practical value of h is: + + h = 4/3 * R * tan(angle/4) + + This value does not give the spline with minimal error, but it does + provide a very good approximation, (6th-order convergence), and the + error expression is quite simple, (see the comment for + _arc_error_normalized). +*/ +static void _gd_arc_segment(gdPathPtr path, double xc, double yc, double radius, double angle_A, + double angle_B) +{ + double r_sin_A, r_cos_A; + double r_sin_B, r_cos_B; + double h; + + r_sin_A = radius * sin(angle_A); + r_cos_A = radius * cos(angle_A); + r_sin_B = radius * sin(angle_B); + r_cos_B = radius * cos(angle_B); + + h = 4.0 / 3.0 * tan((angle_B - angle_A) / 4.0); + + gdPathCurveTo(path, xc + r_cos_A - h * r_sin_A, yc + r_sin_A + h * r_cos_A, + xc + r_cos_B + h * r_sin_B, yc + r_sin_B - h * r_cos_B, xc + r_cos_B, + yc + r_sin_B); +} + +static void _gd_arc_in_direction(gdPathPtr path, double xc, double yc, double radius, + double angle_min, double angle_max, arcDirectionType dir) +{ + if (!path) + return; + + if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { + angle_max = fmod(angle_max - angle_min, 2 * M_PI); + angle_min = fmod(angle_min, 2 * M_PI); + angle_max += angle_min + 2 * M_PI * MAX_FULL_CIRCLES; + } + + /* Recurse if drawing arc larger than pi */ + if (angle_max - angle_min > M_PI) { + double angle_mid = angle_min + (angle_max - angle_min) / 2.0; + if (dir == ARC_CW) { + _gd_arc_in_direction(path, xc, yc, radius, angle_min, angle_mid, dir); + + _gd_arc_in_direction(path, xc, yc, radius, angle_mid, angle_max, dir); + } else { + _gd_arc_in_direction(path, xc, yc, radius, angle_mid, angle_max, dir); + + _gd_arc_in_direction(path, xc, yc, radius, angle_min, angle_mid, dir); + } + } else if (angle_max != angle_min) { + int i, segments; + double step; + segments = _arc_segments_needed(angle_max - angle_min, radius, DEFAULT_TOLERANCE); + step = (angle_max - angle_min) / segments; + segments -= 1; + + if (dir == ARC_CCW) { + double t; + + t = angle_min; + angle_min = angle_max; + angle_max = t; + + step = -step; + } + gdPathMoveTo(path, xc + radius * cos(angle_min), yc + radius * sin(angle_min)); + + for (i = 0; i < segments; i++, angle_min += step) { + _gd_arc_segment(path, xc, yc, radius, angle_min, angle_min + step); + } + + _gd_arc_segment(path, xc, yc, radius, angle_min, angle_max); + } else { + gdPathLineTo(path, xc + radius * cos(angle_min), yc + radius * sin(angle_min)); + } +} + +void _gd_arc_path(gdPathPtr path, double xc, double yc, double radius, double angle_min, + double angle_max) +{ + if (angle_min > M_PI2) { + angle_min = fmod(angle_min, M_PI2); + } + + if (angle_max > M_PI2) { + printf(" fmod max -"); + angle_max = fmod(angle_max, M_PI2); + } + + if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { + angle_max = fmod(angle_max - angle_min, 2 * M_PI); + angle_min = fmod(angle_min, 2 * M_PI); + angle_max += angle_min + 2 * M_PI * MAX_FULL_CIRCLES; + } + _gd_arc_in_direction(path, xc, yc, radius, angle_min, angle_max, ARC_CW); +} + +void _gd_arc_path_negative(gdPathPtr path, double xc, double yc, double radius, double angle1, + double angle2) +{ + _gd_arc_in_direction(path, xc, yc, radius, angle2, angle1, ARC_CCW); +} diff --git a/ext/gd/libgd/gd_path_arc.h b/ext/gd/libgd/gd_path_arc.h new file mode 100644 index 000000000000..2e6a6e010c74 --- /dev/null +++ b/ext/gd/libgd/gd_path_arc.h @@ -0,0 +1,13 @@ +#ifndef GD_PATH_ARC_H +#define GD_PATH_ARC_H + +#include "gd_vector2d.h" + +void _gd_arc_path(gdPathPtr path, double xc, double yc, double radius, double angle1, + double angle2); + +void _gd_arc_path_negative(gdPathPtr path, double xc, double yc, double radius, double angle1, + double angle2); + +typedef enum arcDirectionTypeStruct { ARC_CW, ARC_CCW } arcDirectionType; +#endif // GD_PATH_ARC_H diff --git a/ext/gd/libgd/gd_path_dash.c b/ext/gd/libgd/gd_path_dash.c new file mode 100644 index 000000000000..a661de894e10 --- /dev/null +++ b/ext/gd/libgd/gd_path_dash.c @@ -0,0 +1,124 @@ +#include +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_errors.h" +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "gd_array.h" +#include "gd_path.h" +#include "gd_path_dash.h" +#include "gd_path_matrix.h" + +gdPathDashPtr gdPathDashCreate(const double *data, int size, double offset) +{ + if (data == NULL || size == 0) + return NULL; + + gdPathDashPtr dash = gdMalloc(sizeof(gdPathDash)); + if (!dash) { + return NULL; + } + dash->offset = offset; + dash->data = gdMalloc((size_t)size * sizeof(double)); + if (!dash->data) { + gdFree(dash); + return NULL; + } + dash->size = size; + memcpy(dash->data, data, (size_t)size * sizeof(double)); + return dash; +} + +void gdPathDashDestroy(gdPathDashPtr dash) +{ + if (dash == NULL) + return; + gdFree(dash->data); + gdFree(dash); +} + +gdPathDashPtr gdPathDashClone(const gdPathDashPtr dash) +{ + if (dash == NULL) + return NULL; + + return gdPathDashCreate(dash->data, dash->size, dash->offset); +} + +gdPathPtr gdPathApplyDash(const gdPathDashPtr dash, const gdPathPtr path) +{ + gdPathPtr flat = gdPathDuplicateFlattened(path); + gdPathPtr result = gdPathCreate(); + + gdArrayReallocBy(&result->elements, gdArrayNumElements(&flat->elements)); + gdArrayReallocBy(&result->points, gdArrayNumElements(&flat->points)); + + int toggle = 1; + int offset = 0; + double phase = dash->offset; + while (phase >= dash->data[offset]) { + toggle = !toggle; + phase -= dash->data[offset]; + if (++offset == dash->size) + offset = 0; + } + + gdPathOpsPtr elements = (gdPathOpsPtr)gdArrayGetData(&flat->elements); + gdPathOpsPtr end = elements + gdArrayNumElements(&flat->elements); + gdPointFPtr points = (gdPointFPtr)gdArrayGetData(&flat->points); + + while (elements < end) { + int itoggle = toggle; + int ioffset = offset; + double iphase = phase; + + double x0 = points->x; + double y0 = points->y; + + if (itoggle) + gdPathMoveTo(result, x0, y0); + ++elements; + ++points; + while (elements < end && *elements == gdPathOpsLineTo) { + double dx = points->x - x0; + double dy = points->y - y0; + double dist0 = sqrt(dx * dx + dy * dy); + double dist1 = 0; + while (dist0 - dist1 > dash->data[ioffset] - iphase) { + dist1 += dash->data[ioffset] - iphase; + double a = dist1 / dist0; + double x = x0 + a * dx; + double y = y0 + a * dy; + + if (itoggle) + gdPathLineTo(result, x, y); + else { + gdPathMoveTo(result, x, y); + } + + itoggle = !itoggle; + iphase = 0; + if (++ioffset == dash->size) + ioffset = 0; + } + + iphase += dist0 - dist1; + + x0 = points->x; + y0 = points->y; + + if (itoggle) + gdPathLineTo(result, x0, y0); + + ++elements; + ++points; + } + } + + gdPathDestroy(flat); + return result; +} diff --git a/ext/gd/libgd/gd_path_dash.h b/ext/gd/libgd/gd_path_dash.h new file mode 100644 index 000000000000..07d6c7126250 --- /dev/null +++ b/ext/gd/libgd/gd_path_dash.h @@ -0,0 +1,30 @@ +#ifndef GD_PATH_DASH_H +#define GD_PATH_DASH_H + +#include "gd_vector2d_private.h" + +#define _dash_init(dash) \ + do { \ + dash.data = NULL; \ + dash.size = 0; \ + dash.capacity = 0; \ + } while (0) + +#define _dash_allocate(dash, count) \ + do { \ + if (dash.size + count > dash.capacity) { \ + int capacity = dash.size + count; \ + int newcapacity = dash.capacity == 0 ? 8 : dash.capacity; \ + while (newcapacity < capacity) { \ + newcapacity *= 2; \ + } \ + dash.data = gdRealloc(dash.data, (size_t)newcapacity * sizeof(dash.data[0])); \ + dash.capacity = newcapacity; \ + } \ + } while (0) + +gdPathDashPtr gdPathDashCreate(const double *data, int size, double offset); +gdPathDashPtr gdPathDashClone(const gdPathDashPtr dash); +void gdPathDashDestroy(gdPathDashPtr dash); +gdPathPtr gdPathApplyDash(const gdPathDashPtr dash, const gdPathPtr path); +#endif // GD_PATH_DASH_H diff --git a/ext/gd/libgd/gd_path_matrix.c b/ext/gd/libgd/gd_path_matrix.c new file mode 100644 index 000000000000..ff932254badf --- /dev/null +++ b/ext/gd/libgd/gd_path_matrix.c @@ -0,0 +1,222 @@ +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd_path_matrix.h" +#include "gd_vector2d_private.h" + +BGD_DECLARE(void) +gdPathMatrixInit(gdPathMatrixPtr matrix, double m00, double m10, double m01, double m11, double m02, + double m12) +{ + matrix->m00 = m00; + matrix->m10 = m10; + matrix->m01 = m01; + matrix->m11 = m11; + matrix->m02 = m02; + matrix->m12 = m12; +} + +BGD_DECLARE(void) gdPathMatrixInitIdentity(gdPathMatrixPtr matrix) +{ + matrix->m00 = 1.0; + matrix->m10 = 0.0; + matrix->m01 = 0.0; + matrix->m11 = 1.0; + matrix->m02 = 0.0; + matrix->m12 = 0.0; +} + +BGD_DECLARE(void) gdPathMatrixInitTranslate(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrixInit(matrix, 1.0, 0.0, 0.0, 1.0, x, y); +} + +BGD_DECLARE(void) gdPathMatrixInitScale(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrixInit(matrix, x, 0.0, 0.0, y, 0.0, 0.0); +} + +BGD_DECLARE(void) gdPathMatrixInitShear(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrixInit(matrix, 1.0, tan(y), tan(x), 1.0, 0.0, 0.0); +} + +BGD_DECLARE(void) gdPathMatrixInitRotate(gdPathMatrixPtr matrix, double radians) +{ + double c = cos(radians); + double s = sin(radians); + + gdPathMatrixInit(matrix, c, s, -s, c, 0.0, 0.0); +} + +BGD_DECLARE(void) +gdPathMatrixInitRotateTranslate(gdPathMatrixPtr matrix, double radians, double x, double y) +{ + double c = cos(radians); + double s = sin(radians); + + double cx = x * (1 - c) + y * s; + double cy = y * (1 - c) - x * s; + + gdPathMatrixInit(matrix, c, s, -s, c, cx, cy); +} + +BGD_DECLARE(void) gdPathMatrixTranslate(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrix m; + gdPathMatrixInitTranslate(&m, x, y); + gdPathMatrixMultiply(matrix, &m, matrix); +} + +BGD_DECLARE(void) gdPathMatrixScale(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrix m; + gdPathMatrixInitScale(&m, x, y); + gdPathMatrixMultiply(matrix, &m, matrix); +} + +BGD_DECLARE(void) gdPathMatrixShear(gdPathMatrixPtr matrix, double x, double y) +{ + gdPathMatrix m; + gdPathMatrixInitShear(&m, x, y); + gdPathMatrixMultiply(matrix, &m, matrix); +} + +BGD_DECLARE(void) gdPathMatrixRotate(gdPathMatrixPtr matrix, double radians) +{ + gdPathMatrix m; + gdPathMatrixInitRotate(&m, radians); + gdPathMatrixMultiply(matrix, &m, matrix); +} + +BGD_DECLARE(void) +gdPathMatrixRotateTranslate(gdPathMatrixPtr matrix, double radians, double x, double y) +{ + gdPathMatrix m; + gdPathMatrixInitRotateTranslate(&m, radians, x, y); + gdPathMatrixMultiply(matrix, &m, matrix); +} + +BGD_DECLARE(void) +gdPathMatrixMultiply(gdPathMatrixPtr matrix, const gdPathMatrixPtr a, const gdPathMatrixPtr b) +{ + double m00 = a->m00 * b->m00 + a->m10 * b->m01; + double m10 = a->m00 * b->m10 + a->m10 * b->m11; + double m01 = a->m01 * b->m00 + a->m11 * b->m01; + double m11 = a->m01 * b->m10 + a->m11 * b->m11; + double m02 = a->m02 * b->m00 + a->m12 * b->m01 + b->m02; + double m12 = a->m02 * b->m10 + a->m12 * b->m11 + b->m12; + + gdPathMatrixInit(matrix, m00, m10, m01, m11, m02, m12); +} + +BGD_DECLARE(int) gdPathMatrixInvert(gdPathMatrixPtr matrix) +{ + double det = (matrix->m00 * matrix->m11 - matrix->m10 * matrix->m01); + if (det == 0.0) + return 0; + + double inv_det = 1.0 / det; + double m00 = matrix->m00 * inv_det; + double m10 = matrix->m10 * inv_det; + double m01 = matrix->m01 * inv_det; + double m11 = matrix->m11 * inv_det; + double m02 = (matrix->m01 * matrix->m12 - matrix->m11 * matrix->m02) * inv_det; + double m12 = (matrix->m10 * matrix->m02 - matrix->m00 * matrix->m12) * inv_det; + + gdPathMatrixInit(matrix, m11, -m10, -m01, m00, m02, m12); + return 1; +} + +BGD_DECLARE(void) +gdPathMatrixMap(const gdPathMatrixPtr matrix, double x, double y, double *result_x, + double *result_y) +{ + *result_x = x * matrix->m00 + y * matrix->m01 + matrix->m02; + *result_y = x * matrix->m10 + y * matrix->m11 + matrix->m12; +} + +BGD_DECLARE(void) +gdPathMatrixMapPoint(const gdPathMatrixPtr matrix, const gdPointFPtr src, gdPointFPtr dst) +{ + gdPathMatrixMap(matrix, src->x, src->y, &dst->x, &dst->y); +} + +BGD_DECLARE(void) +gdPathMatrixMapRect(const gdPathMatrixPtr matrix, const gdRectFPtr src, gdRectFPtr dst) +{ + gdPointF p[4]; + p[0].x = src->x; + p[0].y = src->y; + p[1].x = src->x + src->w; + p[1].y = src->y; + p[2].x = src->x + src->w; + p[2].y = src->y + src->h; + p[3].x = src->x; + p[3].y = src->y + src->h; + + gdPathMatrixMapPoint(matrix, &p[0], &p[0]); + gdPathMatrixMapPoint(matrix, &p[1], &p[1]); + gdPathMatrixMapPoint(matrix, &p[2], &p[2]); + gdPathMatrixMapPoint(matrix, &p[3], &p[3]); + + double l = p[0].x; + double t = p[0].y; + double r = p[0].x; + double b = p[0].y; + + for (int i = 1; i < 4; i++) { + if (p[i].x < l) + l = p[i].x; + if (p[i].x > r) + r = p[i].x; + if (p[i].y < t) + t = p[i].y; + if (p[i].y > b) + b = p[i].y; + } + + dst->x = l; + dst->y = t; + dst->w = r - l; + dst->h = b - t; +} + +void _matrix_get_affine(const gdPathMatrixPtr matrix, double *m00, double *m10, double *m01, + double *m11, double *m02, double *m12) +{ + *m00 = matrix->m00; + *m10 = matrix->m10; + + *m01 = matrix->m01; + *m11 = matrix->m11; + + if (m02) + *m02 = matrix->m02; + if (m12) + *m12 = matrix->m12; +} + +double _gd_matrix_transformed_circle_major_axis(const gdPathMatrixPtr matrix, double radius) +{ + double a, b, c, d, f, g, h, i, j; + + _matrix_get_affine(matrix, &a, &b, &c, &d, NULL, NULL); + + i = a * a + b * b; + j = c * c + d * d; + + f = 0.5 * (i + j); + g = 0.5 * (i - j); + h = a * c + b * d; + + return radius * sqrt(f + hypot(g, h)); + + /* + * we don't need the minor axis length, which is + * double min = radius * sqrt (f - sqrt (g*g+h*h)); + */ +} diff --git a/ext/gd/libgd/gd_path_matrix.h b/ext/gd/libgd/gd_path_matrix.h new file mode 100644 index 000000000000..c7049240bd8c --- /dev/null +++ b/ext/gd/libgd/gd_path_matrix.h @@ -0,0 +1,10 @@ +#ifndef GD_PATH_MATRIX_H +#define GD_PATH_MATRIX_H + +#include "gd_vector2d.h" + +/* Largest semiaxis after transforming a circle: radius times the largest + * singular value of the matrix's linear component. Translation is ignored. */ +double _gd_matrix_transformed_circle_major_axis(const gdPathMatrixPtr matrix, double radius); + +#endif /* GD_PATH_MATRIX_H */ diff --git a/ext/gd/libgd/gd_path_outline.h b/ext/gd/libgd/gd_path_outline.h new file mode 100644 index 000000000000..c22ba127498c --- /dev/null +++ b/ext/gd/libgd/gd_path_outline.h @@ -0,0 +1,19 @@ +#ifndef GD_PATH_OUTLINE_H +#define GD_PATH_OUTLINE_H + +#include "ftraster/gd_ft_raster.h" +#include "gd_vector2d_private.h" + +/* Internal gdPath <-> FreeType outline bridge. */ +GD_FT_Outline *gd_ft_outline_create(int points, int contours); +void gd_ft_outline_close(GD_FT_Outline *outline); +void gd_ft_outline_end(GD_FT_Outline *outline); +void gd_ft_outline_move_to(GD_FT_Outline *outline, double x, double y); +void gd_ft_outline_line_to(GD_FT_Outline *outline, double x, double y); +void gd_ft_outline_cubic_to(GD_FT_Outline *outline, double x1, double y1, double x2, double y2, + double x3, double y3); +void gd_ft_outline_conic_to(GD_FT_Outline *outline, double x1, double y1, double x2, double y2); +GD_FT_Outline *gd_ft_outline_convert(const gdPathPtr path, const gdPathMatrixPtr matrix); +void gd_ft_outline_destroy(GD_FT_Outline *outline); + +#endif diff --git a/ext/gd/libgd/gd_path_stroke.c b/ext/gd/libgd/gd_path_stroke.c new file mode 100644 index 000000000000..f3c74ae12228 --- /dev/null +++ b/ext/gd/libgd/gd_path_stroke.c @@ -0,0 +1,185 @@ +#include "ftraster/gd_ft_raster.h" +#include "ftraster/gd_ft_stroker.h" +#include "gd_path.h" +#include "gd_path_matrix.h" +#include "gd_path_outline.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" +#include + +static gdPathPtr ft_outline_to_gdpath(const GD_FT_Outline *outline) +{ + if (!outline || outline->n_points == 0) + return NULL; + + gdPathPtr path = gdPathCreate(); + if (!path) + return NULL; + + int first = 0; + for (int contour = 0; contour < outline->n_contours; contour++) { + int last = outline->contours[contour]; + int point = first; + GD_FT_Vector start; + + if (last < first) + goto invalid_outline; + + char first_tag = GD_FT_CURVE_TAG(outline->tags[first]); + char last_tag = GD_FT_CURVE_TAG(outline->tags[last]); + + if (first_tag == GD_FT_CURVE_TAG_ON) { + start = outline->points[point++]; + } else if (first_tag == GD_FT_CURVE_TAG_CONIC) { + if (last_tag == GD_FT_CURVE_TAG_ON) { + start = outline->points[last--]; + } else if (last_tag == GD_FT_CURVE_TAG_CONIC) { + start.x = (outline->points[first].x + outline->points[last].x) / 2; + start.y = (outline->points[first].y + outline->points[last].y) / 2; + } else { + goto invalid_outline; + } + } else { + goto invalid_outline; + } + + gdPathMoveTo(path, start.x / 64.0, start.y / 64.0); + + while (point <= last) { + char tag = GD_FT_CURVE_TAG(outline->tags[point]); + GD_FT_Vector current = outline->points[point++]; + + if (tag == GD_FT_CURVE_TAG_ON) { + gdPathLineTo(path, current.x / 64.0, current.y / 64.0); + continue; + } + + if (tag == GD_FT_CURVE_TAG_CONIC) { + GD_FT_Vector control = current; + for (;;) { + if (point > last) { + gdPathQuadTo(path, control.x / 64.0, control.y / 64.0, start.x / 64.0, + start.y / 64.0); + break; + } + + tag = GD_FT_CURVE_TAG(outline->tags[point]); + current = outline->points[point++]; + if (tag == GD_FT_CURVE_TAG_ON) { + gdPathQuadTo(path, control.x / 64.0, control.y / 64.0, current.x / 64.0, + current.y / 64.0); + break; + } + if (tag != GD_FT_CURVE_TAG_CONIC) + goto invalid_outline; + + GD_FT_Vector middle = {(control.x + current.x) / 2, + (control.y + current.y) / 2}; + gdPathQuadTo(path, control.x / 64.0, control.y / 64.0, middle.x / 64.0, + middle.y / 64.0); + control = current; + } + continue; + } + + if (tag != GD_FT_CURVE_TAG_CUBIC || point > last || + GD_FT_CURVE_TAG(outline->tags[point]) != GD_FT_CURVE_TAG_CUBIC) + goto invalid_outline; + + GD_FT_Vector control1 = current; + GD_FT_Vector control2 = outline->points[point++]; + GD_FT_Vector end = start; + if (point <= last) { + if (GD_FT_CURVE_TAG(outline->tags[point]) != GD_FT_CURVE_TAG_ON) + goto invalid_outline; + end = outline->points[point++]; + } + gdPathCurveTo(path, control1.x / 64.0, control1.y / 64.0, control2.x / 64.0, + control2.y / 64.0, end.x / 64.0, end.y / 64.0); + } + + gdPathClose(path); + first = outline->contours[contour] + 1; + } + + return path; + +invalid_outline: + gdPathDestroy(path); + return NULL; +} + +GD_VECTOR2D_INTERNAL gdPathPtr gdPathStrokeToPath(const gdPathPtr path, const gdStrokePtr stroke, + const gdPathMatrixPtr matrix) +{ + if (!path || !stroke || stroke->width <= 0) + return NULL; + + GD_FT_Outline *outline = gd_ft_outline_convert(path, matrix); + if (!outline) + return NULL; + + GD_FT_Stroker stroker; + GD_FT_Stroker_New(&stroker); + + double radius = stroke->width / 2.0; + GD_FT_Fixed ftWidth = (GD_FT_Fixed)(radius * 64); + GD_FT_Fixed ftMiterLimit = (GD_FT_Fixed)(stroke->miterlimit * 65536); + + GD_FT_Stroker_LineCap ftCap; + switch (stroke->cap) { + case gdLineCapSquare: + ftCap = GD_FT_STROKER_LINECAP_SQUARE; + break; + case gdLineCapRound: + ftCap = GD_FT_STROKER_LINECAP_ROUND; + break; + case gdLineCapButt: + default: + ftCap = GD_FT_STROKER_LINECAP_BUTT; + break; + } + + GD_FT_Stroker_LineJoin ftJoin; + switch (stroke->join) { + case gdLineJoinBevel: + ftJoin = GD_FT_STROKER_LINEJOIN_BEVEL; + break; + case gdLineJoinRound: + ftJoin = GD_FT_STROKER_LINEJOIN_ROUND; + break; + case gdLineJoinMiter: + default: + ftJoin = GD_FT_STROKER_LINEJOIN_MITER_FIXED; + break; + } + + GD_FT_Stroker_Set(stroker, ftWidth, ftCap, ftJoin, ftMiterLimit); + + GD_FT_Stroker_ParseOutline(stroker, outline); + + GD_FT_UInt points, contours; + GD_FT_Stroker_GetCounts(stroker, &points, &contours); + + GD_FT_Outline *strokeOutline = gd_ft_outline_create((int)points, (int)contours); + if (!strokeOutline) { + GD_FT_Stroker_Done(stroker); + gd_ft_outline_destroy(outline); + return NULL; + } + + // Use combined export (both borders + caps) - works for both open and closed paths + GD_FT_Stroker_Export(stroker, strokeOutline); + GD_FT_Stroker_Done(stroker); + + gdPathPtr strokePath = ft_outline_to_gdpath(strokeOutline); + + gd_ft_outline_destroy(outline); + gd_ft_outline_destroy(strokeOutline); + + if (!strokePath) { + return NULL; + } + + return strokePath; +} diff --git a/ext/gd/libgd/gd_perceptual_diff.c b/ext/gd/libgd/gd_perceptual_diff.c new file mode 100644 index 000000000000..f4b68babd190 --- /dev/null +++ b/ext/gd/libgd/gd_perceptual_diff.c @@ -0,0 +1,149 @@ +#include "gd.h" + +#include +#include +#include + +#define GD_PERCEPTUAL_MAX_DELTA 35215.0 + +static uint8_t gd_alpha_to_opacity(int alpha) +{ + return (uint8_t)(((127 - alpha) * 255 + 63) / 127); +} + +static uint8_t blend(uint8_t color, uint8_t alpha, uint8_t background) +{ + return (uint8_t)((color * alpha + background * (255 - alpha) + 127) / 255); +} + +static double pixel_diff_yiq(uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2) +{ + double dr = r1 - r2; + double dg = g1 - g2; + double db = b1 - b2; + double y = dr * 0.29889531 + dg * 0.58662247 + db * 0.11448223; + double i = dr * 0.59597799 - dg * 0.27417610 - db * 0.32180189; + double q = dr * 0.21147017 - dg * 0.52261711 + db * 0.31114694; + + return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q; +} + +BGD_DECLARE(int) gdImagePerceptualDiff(gdImagePtr image1, gdImagePtr image2, double threshold, + const gdImagePerceptualDiffOptions *options, gdImagePtr *diff_image, + gdImagePerceptualDiffResult *result) +{ + gdImageDiffMode mode = GD_IMAGE_DIFF_OVERLAY; + int highlight_color = gdTrueColorAlpha(255, 0, 0, 0); + gdImagePtr diff = NULL; + double maximum_delta = 0.0; + double max_yiq_delta; + int alpha_threshold; + int x, y; + + if (diff_image != NULL) { + *diff_image = NULL; + } + if (result != NULL) { + result->pixels_changed = 0; + result->maximum_delta = 0.0; + } + + if (image1 == NULL || image2 == NULL || result == NULL || + !(threshold >= 0.0 && threshold <= 1.0) || image1->sx != image2->sx || + image1->sy != image2->sy) { + return 0; + } + + if (options != NULL) { + mode = options->mode; + highlight_color = options->highlight_color; + } + if (mode < GD_IMAGE_DIFF_NONE || mode > GD_IMAGE_DIFF_MASK) { + return 0; + } + + if (mode != GD_IMAGE_DIFF_NONE && diff_image != NULL) { + diff = gdImageCreateTrueColor(image1->sx, image1->sy); + if (diff == NULL) { + return 0; + } + gdImageAlphaBlending(diff, 0); + gdImageSaveAlpha(diff, 1); + } + + max_yiq_delta = GD_PERCEPTUAL_MAX_DELTA * threshold * threshold; + alpha_threshold = (int)(threshold * 127); + + for (y = 0; y < image1->sy; y++) { + for (x = 0; x < image1->sx; x++) { + int p1 = gdImageGetTrueColorPixel(image1, x, y); + int p2 = gdImageGetTrueColorPixel(image2, x, y); + double delta = 0.0; + int is_diff = 0; + + if (p1 != p2) { + uint8_t r1 = gdTrueColorGetRed(p1); + uint8_t g1 = gdTrueColorGetGreen(p1); + uint8_t b1 = gdTrueColorGetBlue(p1); + int ga1 = gdTrueColorGetAlpha(p1); + uint8_t r2 = gdTrueColorGetRed(p2); + uint8_t g2 = gdTrueColorGetGreen(p2); + uint8_t b2 = gdTrueColorGetBlue(p2); + int ga2 = gdTrueColorGetAlpha(p2); + int alpha_delta = abs(ga1 - ga2); + + delta = (double)alpha_delta / 127.0; + if (alpha_delta > alpha_threshold) { + is_diff = 1; + } else { + uint8_t a1 = gd_alpha_to_opacity(ga1); + uint8_t a2 = gd_alpha_to_opacity(ga2); + double yiq_delta = 0.0; + + if (a1 == 0 && a2 == 0) { + delta = 0.0; + } else if (a1 > 250 && a2 > 250) { + yiq_delta = pixel_diff_yiq(r1, g1, b1, r2, g2, b2); + } else { + double delta_white = pixel_diff_yiq(blend(r1, a1, 255), blend(g1, a1, 255), + blend(b1, a1, 255), blend(r2, a2, 255), + blend(g2, a2, 255), blend(b2, a2, 255)); + double delta_black = + pixel_diff_yiq(blend(r1, a1, 0), blend(g1, a1, 0), blend(b1, a1, 0), + blend(r2, a2, 0), blend(g2, a2, 0), blend(b2, a2, 0)); + yiq_delta = delta_white < delta_black ? delta_white : delta_black; + } + if (yiq_delta > 0.0) { + double color_delta = sqrt(yiq_delta / GD_PERCEPTUAL_MAX_DELTA); + if (color_delta > delta) { + delta = color_delta; + } + is_diff = yiq_delta > max_yiq_delta; + } + } + } + + if (delta > maximum_delta) { + maximum_delta = delta; + } + if (is_diff) { + result->pixels_changed++; + if (diff != NULL) { + gdImageSetPixel(diff, x, y, highlight_color); + } + } else if (diff != NULL && mode == GD_IMAGE_DIFF_OVERLAY) { + gdImageSetPixel(diff, x, y, + gdTrueColorAlpha(gdTrueColorGetRed(p1), gdTrueColorGetGreen(p1), + gdTrueColorGetBlue(p1), 102)); + } else if (diff != NULL) { + gdImageSetPixel(diff, x, y, gdTrueColorAlpha(0, 0, 0, 127)); + } + } + } + + result->maximum_delta = maximum_delta; + if (diff_image != NULL) { + *diff_image = diff; + } + return 1; +} diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index 655eee77b906..a07c1ca143c8 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -1,783 +1,1822 @@ -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "gd.h" #include "gd_errors.h" +#include "gd_intern.h" +#include +#include +#include +#include +#include /* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */ #ifdef HAVE_LIBPNG -#include "png.h" /* includes zlib.h and setjmp.h */ #include "gdhelpers.h" +#include "png.h" /* includes zlib.h and setjmp.h */ +#include "zlib.h" #define TRUE 1 #define FALSE 0 -/*--------------------------------------------------------------------------- +static const unsigned char gdPngSignature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - gd_png.c Copyright 1999 Greg Roelofs and Thomas Boutell +BGD_DECLARE(const char *) gdPngGetVersionString(void) { return PNG_LIBPNG_VER_STRING; } - The routines in this file, gdImagePng*() and gdImageCreateFromPng*(), - are drop-in replacements for gdImageGif*() and gdImageCreateFromGif*(), - except that these functions are noisier in the case of errors (comment - out all fprintf() statements to disable that). +static unsigned int gdPngGetUint32(const unsigned char *data) +{ + return ((unsigned int)data[0] << 24) | ((unsigned int)data[1] << 16) | + ((unsigned int)data[2] << 8) | (unsigned int)data[3]; +} - GD 2.0 supports RGBA truecolor and will read and write truecolor PNGs. - GD 2.0 supports 8 bits of color resolution per channel and - 7 bits of alpha channel resolution. Images with more than 8 bits - per channel are reduced to 8 bits. Images with an alpha channel are - only able to resolve down to '1/128th opaque' instead of '1/256th', - and this conversion is also automatic. I very much doubt you can see it. - Both tRNS and true alpha are supported. +static void gdPngPutUint32(unsigned char *data, size_t value) +{ + data[0] = (unsigned char)((value >> 24) & 0xff); + data[1] = (unsigned char)((value >> 16) & 0xff); + data[2] = (unsigned char)((value >> 8) & 0xff); + data[3] = (unsigned char)(value & 0xff); +} - Gamma is ignored, and there is no support for text annotations. +static int gdPngChunkIs(const unsigned char *type, const char *name) +{ + return memcmp(type, name, 4) == 0; +} - Last updated: 9 February 2001 +static int gdPngIsXmpItxt(const unsigned char *data, size_t size) +{ + static const char keyword[] = "XML:com.adobe.xmp"; + size_t keyword_size = sizeof(keyword) - 1; - ---------------------------------------------------------------------------*/ + return size > keyword_size && memcmp(data, keyword, keyword_size) == 0 && + data[keyword_size] == 0; +} -const char * gdPngGetVersionString() +static int gdPngIsRawProfile(const unsigned char *data, size_t size, const char *profile_type) { - return PNG_LIBPNG_VER_STRING; + static const char prefix[] = "Raw profile type "; + size_t prefix_size = sizeof(prefix) - 1; + size_t profile_type_size; + + if (data == NULL) { + return FALSE; + } + + profile_type_size = strlen(profile_type); + return size > prefix_size + profile_type_size && memcmp(data, prefix, prefix_size) == 0 && + memcmp(data + prefix_size, profile_type, profile_type_size) == 0 && + data[prefix_size + profile_type_size] == 0; } -#ifdef PNG_SETJMP_SUPPORTED -typedef struct _jmpbuf_wrapper +static int gdPngSetTextProfile(gdImageMetadata *metadata, const unsigned char *data, size_t size) { - jmp_buf jmpbuf; -} jmpbuf_wrapper; + const unsigned char *nul; + size_t keyword_size; + char *key; + int status; + + nul = (const unsigned char *)memchr(data, 0, size); + if (nul == NULL || nul == data) { + return GD_META_OK; + } + + keyword_size = (size_t)(nul - data); + key = (char *)gdMalloc(sizeof("png:text:") + keyword_size); + if (key == NULL) { + return GD_META_ERR_NOMEM; + } + memcpy(key, "png:text:", sizeof("png:text:") - 1); + memcpy(key + sizeof("png:text:") - 1, data, keyword_size); + key[sizeof("png:text:") - 1 + keyword_size] = '\0'; -static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) + status = gdImageMetadataSetProfile(metadata, key, data, size); + gdFree(key); + return status; +} + +static int gdPngReadMetadataFromMemory(const unsigned char *png, size_t png_size, + gdImageMetadata *metadata) { - jmpbuf_wrapper *jmpbuf_ptr; + size_t pos = 8; - /* This function, aside from the extra step of retrieving the "error - * pointer" (below) and the fact that it exists within the application - * rather than within libpng, is essentially identical to libpng's - * default error handler. The second point is critical: since both - * setjmp() and longjmp() are called from the same code, they are - * guaranteed to have compatible notions of how big a jmp_buf is, - * regardless of whether _BSD_SOURCE or anything else has (or has not) - * been defined. - */ + if (metadata == NULL) { + return GD_META_OK; + } + if (png == NULL || png_size < 8 || memcmp(png, gdPngSignature, 8) != 0) { + return GD_META_ERR_FORMAT; + } - gd_error_ex(GD_WARNING, "gd-png: fatal libpng error: %s", msg); + while (pos + 12 <= png_size) { + unsigned int chunk_size = gdPngGetUint32(png + pos); + const unsigned char *type = png + pos + 4; + const unsigned char *chunk_data = png + pos + 8; + int status = GD_META_OK; + + if ((size_t)chunk_size > png_size - pos - 12) { + return GD_META_ERR_PARSE; + } + + if (gdPngChunkIs(type, "eXIf")) { + status = gdImageMetadataSetProfile(metadata, "exif", chunk_data, chunk_size); + } else if (gdPngChunkIs(type, "zTXt") && + gdPngIsRawProfile(chunk_data, chunk_size, "exif")) { + status = gdImageMetadataSetProfile(metadata, "exif", chunk_data, chunk_size); + } else if (gdPngChunkIs(type, "iCCP")) { + status = gdImageMetadataSetProfile(metadata, "icc", chunk_data, chunk_size); + } else if (gdPngChunkIs(type, "iTXt") && gdPngIsXmpItxt(chunk_data, chunk_size)) { + status = gdImageMetadataSetProfile(metadata, "xmp", chunk_data, chunk_size); + } else if (gdPngChunkIs(type, "zTXt") && gdPngIsRawProfile(chunk_data, chunk_size, "xmp")) { + status = gdImageMetadataSetProfile(metadata, "xmp", chunk_data, chunk_size); + } else if (gdPngChunkIs(type, "tEXt")) { + status = gdPngSetTextProfile(metadata, chunk_data, chunk_size); + } + if (status != GD_META_OK) { + return status; + } + + pos += (size_t)chunk_size + 12; + if (gdPngChunkIs(type, "IEND")) { + return GD_META_OK; + } + } - jmpbuf_ptr = png_get_error_ptr (png_ptr); - if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ - gd_error_ex(GD_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating."); - } + return GD_META_ERR_PARSE; +} + +static int gdPngAppendChunk(unsigned char *out, size_t *out_pos, const char *type, + const unsigned char *data, size_t size) +{ + uLong crc; + + if (data == NULL || size > UINT32_MAX) { + return GD_META_ERR_INVALID; + } - longjmp (jmpbuf_ptr->jmpbuf, 1); + gdPngPutUint32(out + *out_pos, size); + memcpy(out + *out_pos + 4, type, 4); + if (size != 0) { + memcpy(out + *out_pos + 8, data, size); + } + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, out + *out_pos + 4, (uInt)(size + 4)); + gdPngPutUint32(out + *out_pos + 8 + size, crc); + *out_pos += size + 12; + return GD_META_OK; } -static void gdPngWarningHandler (png_structp png_ptr, png_const_charp msg) +static int gdPngMetadataChunkSize(size_t *total, const unsigned char *data, size_t size) { - gd_error_ex(GD_WARNING, "gd-png: libpng warning: %s", msg); + if (data == NULL) { + return GD_META_OK; + } + if (size > UINT32_MAX || (size_t)-1 - *total < size + 12) { + return GD_META_ERR_LIMIT; + } + *total += size + 12; + return GD_META_OK; +} + +static int gdPngShouldSkipChunk(const unsigned char *type, const unsigned char *data, size_t size, + const gdImageMetadata *metadata) +{ + return (gdImageMetadataGetProfile(metadata, "exif", NULL) != NULL && + (gdPngChunkIs(type, "eXIf") || + (gdPngChunkIs(type, "zTXt") && gdPngIsRawProfile(data, size, "exif")))) || + (gdImageMetadataGetProfile(metadata, "icc", NULL) != NULL && + gdPngChunkIs(type, "iCCP")) || + (gdImageMetadataGetProfile(metadata, "xmp", NULL) != NULL && + ((gdPngChunkIs(type, "iTXt") && gdPngIsXmpItxt(data, size)) || + (gdPngChunkIs(type, "zTXt") && gdPngIsRawProfile(data, size, "xmp")))); +} + +static void *gdPngReadCtxToMemory(gdIOCtx *infile, int *size) +{ + enum { GD_PNG_ALLOC_STEP = 8192 }; + unsigned char *data = NULL; + int logical_size = 0; + int real_size = 0; + + if (size != NULL) { + *size = 0; + } + if (infile == NULL || size == NULL) { + return NULL; + } + + for (;;) { + int n; + + if (real_size - logical_size < GD_PNG_ALLOC_STEP) { + unsigned char *temp; + int new_size; + + if (real_size > INT_MAX - GD_PNG_ALLOC_STEP) { + gdFree(data); + return NULL; + } + new_size = real_size + GD_PNG_ALLOC_STEP; + temp = (unsigned char *)gdRealloc(data, new_size); + if (temp == NULL) { + gdFree(data); + return NULL; + } + data = temp; + real_size = new_size; + } + + n = gdGetBuf(data + logical_size, GD_PNG_ALLOC_STEP, infile); + if (n <= 0) { + break; + } + logical_size += n; + } + + *size = logical_size; + return data; +} + +/*--------------------------------------------------------------------------- + + gd_png.c Copyright 1999 Greg Roelofs and Thomas Boutell + + The routines in this file, gdImagePng*() and gdImageCreateFromPng*(), + are drop-in replacements for gdImageGif*() and gdImageCreateFromGif*(), + except that these functions are noisier in the case of errors (comment + out all fprintf() statements to disable that). + + GD 2.0 supports RGBA truecolor and will read and write truecolor PNGs. + GD 2.0 supports 8 bits of color resolution per channel and + 7 bits of alpha channel resolution. Images with more than 8 bits + per channel are reduced to 8 bits. Images with an alpha channel are + only able to resolve down to '1/128th opaque' instead of '1/256th', + and this conversion is also automatic. I very much doubt you can see it. + Both tRNS and true alpha are supported. + + Gamma is ignored, and there is no support for text annotations. + + Last updated: 9 February 2001 + + ---------------------------------------------------------------------------*/ + +/** + * File: PNG IO + * + * Read and write PNG images. + */ + +#ifdef PNG_SETJMP_SUPPORTED +typedef struct _jmpbuf_wrapper { + jmp_buf jmpbuf; +} jmpbuf_wrapper; + +static void gdPngErrorHandler(png_structp png_ptr, png_const_charp msg) +{ + jmpbuf_wrapper *jmpbuf_ptr; + + /* This function, aside from the extra step of retrieving the "error + * pointer" (below) and the fact that it exists within the application + * rather than within libpng, is essentially identical to libpng's + * default error handler. The second point is critical: since both + * setjmp() and longjmp() are called from the same code, they are + * guaranteed to have compatible notions of how big a jmp_buf is, + * regardless of whether _BSD_SOURCE or anything else has (or has not) + * been defined. */ + + gd_error_ex(GD_WARNING, "gd-png: fatal libpng error: %s\n", msg); + + jmpbuf_ptr = png_get_error_ptr(png_ptr); + if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ + gd_error_ex(GD_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf " + "unrecoverable; terminating.\n"); + exit(99); + } + + longjmp(jmpbuf_ptr->jmpbuf, 1); +} + +static void gdPngWarningHandler(UNUSED_PARAM(png_structp png_ptr), png_const_charp msg) +{ + gd_error_ex(GD_WARNING, "gd-png: libpng warning: %s", msg); } #endif -static void gdPngReadData (png_structp png_ptr, png_bytep data, png_size_t length) +static void gdPngReadData(png_structp png_ptr, png_bytep data, png_size_t length) { - int check; - check = gdGetBuf(data, length, (gdIOCtx *) png_get_io_ptr(png_ptr)); - if (check != length) { - png_error(png_ptr, "Read Error: truncated data"); - } + int check; + check = gdGetBuf(data, length, (gdIOCtx *)png_get_io_ptr(png_ptr)); + if (check != (int)length) { + png_error(png_ptr, "Read Error: truncated data"); + } } -static void gdPngWriteData (png_structp png_ptr, png_bytep data, png_size_t length) +static void gdPngWriteData(png_structp png_ptr, png_bytep data, png_size_t length) +{ + gdPutBuf(data, length, (gdIOCtx *)png_get_io_ptr(png_ptr)); +} + +static void gdPngFlushData(png_structp png_ptr) { (void)png_ptr; } + +/* + Function: gdImageCreateFromPng + + is called to load images from PNG format + files. Invoke with an already opened + pointer to a FILE containing the desired + image. returns a to the new + image, or NULL if unable to load the image (most often because the + file is corrupt or does not contain a PNG + image). does not close the file. You can + inspect the sx and sy members of the image to determine its + size. The image must eventually be destroyed using + gdImageDestroy(). + + If the PNG image being loaded is a truecolor image, the resulting + gdImagePtr will refer to a truecolor image. If the PNG image being + loaded is a palette or grayscale image, the resulting gdImagePtr + will refer to a palette image. gd retains only 8 bits of + resolution for each of the red, green and blue channels, and only + 7 bits of resolution for the alpha channel. The former restriction + affects only a handful of very rare 48-bit color and 16-bit + grayscale PNG images. The second restriction affects all + semitransparent PNG images, but the difference is essentially + invisible to the eye. 7 bits of alpha channel resolution is, in + practice, quite a lot. + + Variants: + + creates an image from PNG data (i.e. the + contents of a PNG file) already in memory. + + reads in an image using the functions in + a struct. + + is similar to + but uses the old interface. + It is *obsolete*. + + Parameters: + + infile - The input FILE pointer. + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + (start code) + + gdImagePtr im; + ... inside a function ... + FILE *in; + in = fopen("mypng.png", "rb"); + im = gdImageCreateFromPng(in); + fclose(in); + // ... Use the image ... + gdImageDestroy(im); + + (end code) + */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPng(FILE *inFile) { - gdPutBuf (data, length, (gdIOCtx *) png_get_io_ptr(png_ptr)); + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromPngCtx(in); + in->gd_free(in); + return im; } -static void gdPngFlushData (png_structp png_ptr) +/* + Function: gdImageCreateFromPngPtr + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngPtr(int size, void *data) { + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromPngCtx(in); + in->gd_free(in); + return im; } -gdImagePtr gdImageCreateFromPng (FILE * inFile) +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngPtrWithMetadata(int size, void *data, gdImageMetadata *metadata) { - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx(inFile); - im = gdImageCreateFromPngCtx(in); - in->gd_free(in); + gdImagePtr im; + gdIOCtx *in; + + if (metadata != NULL) { + int status = gdPngReadMetadataFromMemory((const unsigned char *)data, size, metadata); + if (status != GD_META_OK) { + return NULL; + } + } - return im; + in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromPngCtx(in); + in->gd_free(in); + return im; } -gdImagePtr gdImageCreateFromPngPtr (int size, void *data) +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngCtxWithMetadata(gdIOCtx *infile, gdImageMetadata *metadata) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromPngCtx(in); - in->gd_free(in); - return im; + void *data; + int size; + gdImagePtr im; + + data = gdPngReadCtxToMemory(infile, &size); + if (data == NULL) { + return NULL; + } + + im = gdImageCreateFromPngPtrWithMetadata(size, data, metadata); + gdFree(data); + return im; } -/* This routine is based in part on the Chapter 13 demo code in "PNG: The - * Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html). +/* This routine is based in part on the Chapter 13 demo code in + * "PNG: The Definitive Guide" (http://www.libpng.org/pub/png/book/). */ -gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) + +/* + Function: gdImageCreateFromPngCtx + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx(gdIOCtx *infile) { - png_byte sig[8]; + png_byte sig[8]; #ifdef PNG_SETJMP_SUPPORTED - jmpbuf_wrapper jbw; + jmpbuf_wrapper jbw; #endif - png_structp png_ptr; - png_infop info_ptr; - png_uint_32 width, height, rowbytes, w, h, res_x, res_y; - int bit_depth, color_type, interlace_type, unit_type; - int num_palette, num_trans; - png_colorp palette; - png_color_16p trans_gray_rgb; - png_color_16p trans_color_rgb; - png_bytep trans; - volatile png_bytep image_data = NULL; - volatile png_bytepp row_pointers = NULL; - gdImagePtr im = NULL; - int i, j, *open = NULL; - volatile int transparent = -1; - volatile int palette_allocated = FALSE; - - - /* Make sure the signature can't match by dumb luck -- TBB */ - /* GRR: isn't sizeof(infile) equal to the size of the pointer? */ - memset (sig, 0, sizeof(sig)); - - /* first do a quick check that the file really is a PNG image; could - * have used slightly more general png_sig_cmp() function instead - */ - if (gdGetBuf(sig, 8, infile) < 8) { - return NULL; - } - - if (png_sig_cmp(sig, 0, 8) != 0) { /* bad signature */ - return NULL; - } + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height, rowbytes, w, h, res_x, res_y; + int bit_depth, color_type, interlace_type, unit_type; + int num_palette = 0, num_trans; + png_colorp palette; + png_color_16p trans_gray_rgb; + png_color_16p trans_color_rgb; + png_bytep trans; + png_bytep image_data = NULL; + png_bytepp row_pointers = NULL; + gdImagePtr im = NULL; + int i, j, *open = NULL; + volatile int transparent = -1; + volatile int palette_allocated = FALSE; + + /* Make sure the signature can't match by dumb luck -- TBB */ + /* GRR: isn't sizeof(infile) equal to the size of the pointer? */ + memset(sig, 0, sizeof(sig)); + + /* first do a quick check that the file really is a PNG image; could + * have used slightly more general png_sig_cmp() function instead */ + if (gdGetBuf(sig, 8, infile) < 8) { + return NULL; + } + + if (png_sig_cmp(sig, 0, 8) != 0) { /* bad signature */ + return NULL; /* bad signature */ + } #ifdef PNG_SETJMP_SUPPORTED - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbw, gdPngErrorHandler, gdPngWarningHandler); + png_ptr = + png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbw, gdPngErrorHandler, gdPngWarningHandler); #else - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif - if (png_ptr == NULL) { - gd_error("gd-png error: cannot allocate libpng main struct"); - return NULL; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - gd_error("gd-png error: cannot allocate libpng info struct"); - png_destroy_read_struct (&png_ptr, NULL, NULL); - - return NULL; - } - - /* we could create a second info struct here (end_info), but it's only - * useful if we want to keep pre- and post-IDAT chunk info separated - * (mainly for PNG-aware image editors and converters) - */ - - /* setjmp() must be called in every non-callback function that calls a - * PNG-reading libpng function - */ + if (png_ptr == NULL) { + gd_error("gd-png error: cannot allocate libpng main struct\n"); + return NULL; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + gd_error("gd-png error: cannot allocate libpng info struct\n"); + png_destroy_read_struct(&png_ptr, NULL, NULL); + + return NULL; + } + + /* we could create a second info struct here (end_info), but it's only + * useful if we want to keep pre- and post-IDAT chunk info separated + * (mainly for PNG-aware image editors and converters) + */ + + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function. We must reset it everytime we get a + * new allocation that we save in a stack variable. + */ #ifdef PNG_SETJMP_SUPPORTED - if (setjmp(jbw.jmpbuf)) { - gd_error("gd-png error: setjmp returns error condition"); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + if (setjmp(jbw.jmpbuf)) { + gd_error("gd-png error: setjmp returns error condition 1\n"); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return NULL; - } + return NULL; + } #endif - png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ - - png_set_read_fn(png_ptr, (void *) infile, gdPngReadData); - png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ - - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); - if ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA) - || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - im = gdImageCreateTrueColor((int) width, (int) height); - } else { - im = gdImageCreate((int) width, (int) height); - } - if (im == NULL) { - gd_error("gd-png error: cannot allocate gdImage struct"); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - - return NULL; - } - - if (bit_depth == 16) { - png_set_strip_16(png_ptr); - } else if (bit_depth < 8) { - png_set_packing (png_ptr); /* expand to 1 byte per pixel */ - } - - /* setjmp() must be called in every non-callback function that calls a - * PNG-reading libpng function - */ + png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ + + png_set_read_fn(png_ptr, (void *)infile, gdPngReadData); + png_set_user_limits(png_ptr, 0x7fffffffL, 0x7fffffffL); + png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, + NULL); + if ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA) || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + im = gdImageCreateTrueColor((int)width, (int)height); + } else { + im = gdImageCreate((int)width, (int)height); + } + if (im == NULL) { + gd_error("gd-png error: cannot allocate gdImage struct\n"); + goto error; + } + + if (bit_depth == 16) { + png_set_strip_16(png_ptr); + } else if (bit_depth < 8) { + png_set_packing(png_ptr); /* expand to 1 byte per pixel */ + } + + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function. We must reset it everytime we get a + * new allocation that we save in a stack variable. + */ #ifdef PNG_SETJMP_SUPPORTED - if (setjmp(jbw.jmpbuf)) { - gd_error("gd-png error: setjmp returns error condition"); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - gdFree(image_data); - gdFree(row_pointers); - if (im) { - gdImageDestroy(im); - } - return NULL; - } + if (setjmp(jbw.jmpbuf)) { + gd_error("gd-png error: setjmp returns error condition 2\n"); + goto error; + } #endif #ifdef PNG_pHYs_SUPPORTED - /* check if the resolution is specified */ - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) { - if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) { - switch (unit_type) { - case PNG_RESOLUTION_METER: - im->res_x = DPM2DPI(res_x); - im->res_y = DPM2DPI(res_y); - break; - } - } - } + /* check if the resolution is specified */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) { + if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) { + switch (unit_type) { + case PNG_RESOLUTION_METER: + im->res_x = DPM2DPI(res_x); + im->res_y = DPM2DPI(res_y); + break; + } + } + } #endif - switch (color_type) { - case PNG_COLOR_TYPE_PALETTE: - png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); + switch (color_type) { + case PNG_COLOR_TYPE_PALETTE: + png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); #ifdef DEBUG - gd_error("gd-png color_type is palette, colors: %d", num_palette); + gd_error("gd-png color_type is palette, colors: %d\n", num_palette); #endif /* DEBUG */ - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { - /* gd 2.0: we support this rather thoroughly now. Grab the - * first fully transparent entry, if any, as the value of - * the simple-transparency index, mostly for backwards - * binary compatibility. The alpha channel is where it's - * really at these days. - */ - int firstZero = 1; - png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); - for (i = 0; i < num_trans; ++i) { - im->alpha[i] = gdAlphaMax - (trans[i] >> 1); - if ((trans[i] == 0) && (firstZero)) { - transparent = i; - firstZero = 0; - } - } - } - break; - case PNG_COLOR_TYPE_GRAY: - /* create a fake palette and check for single-shade transparency */ - if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) { - gd_error("gd-png error: cannot allocate gray palette"); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - - return NULL; - } - palette_allocated = TRUE; - if (bit_depth < 8) { - num_palette = 1 << bit_depth; - for (i = 0; i < 256; ++i) { - j = (255 * i) / (num_palette - 1); - palette[i].red = palette[i].green = palette[i].blue = j; - } - } else { - num_palette = 256; - for (i = 0; i < 256; ++i) { - palette[i].red = palette[i].green = palette[i].blue = i; - } - } - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb); - if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ - transparent = trans_gray_rgb->gray >> 8; - } else { - transparent = trans_gray_rgb->gray; - } - /* Note slight error in 16-bit case: up to 256 16-bit shades - * may get mapped to a single 8-bit shade, and only one of them - * is supposed to be transparent. IOW, both opaque pixels and - * transparent pixels will be mapped into the transparent entry. - * There is no particularly good way around this in the case - * that all 256 8-bit shades are used, but one could write some - * custom 16-bit code to handle the case where there are gdFree - * palette entries. This error will be extremely rare in - * general, though. (Quite possibly there is only one such - * image in existence.) - */ - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - png_set_gray_to_rgb(png_ptr); - ZEND_FALLTHROUGH; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - /* gd 2.0: we now support truecolor. See the comment above - * for a rare situation in which the transparent pixel may not - * work properly with 16-bit channels. - */ - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_color_rgb); - if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ - transparent = gdTrueColor(trans_color_rgb->red >> 8, - trans_color_rgb->green >> 8, - trans_color_rgb->blue >> 8); - } else { - transparent = gdTrueColor(trans_color_rgb->red, - trans_color_rgb->green, - trans_color_rgb->blue); - } - } - break; - } + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + /* gd 2.0: we support this rather thoroughly now. Grab the + * first fully transparent entry, if any, as the value of + * the simple-transparency index, mostly for backwards + * binary compatibility. The alpha channel is where it's + * really at these days. + */ + int firstZero = 1; + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); + for (i = 0; i < num_trans; ++i) { + im->alpha[i] = gdAlphaMax - (trans[i] >> 1); + if ((trans[i] == 0) && (firstZero)) { + /* 2.0.5: long-forgotten patch from Wez Furlong */ + transparent = i; + firstZero = 0; + } + } + } + break; + + case PNG_COLOR_TYPE_GRAY: + /* create a fake palette and check for single-shade transparency */ + if ((palette = (png_colorp)gdMalloc(256 * sizeof(png_color))) == NULL) { + gd_error("gd-png error: cannot allocate gray palette\n"); + goto error; + } + palette_allocated = TRUE; + if (bit_depth < 8) { + num_palette = 1 << bit_depth; + for (i = 0; i < 256; ++i) { + j = (255 * i) / (num_palette - 1); + palette[i].red = palette[i].green = palette[i].blue = j; + } + } else { + num_palette = 256; + for (i = 0; i < 256; ++i) { + palette[i].red = palette[i].green = palette[i].blue = i; + } + } + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb); + if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ + transparent = trans_gray_rgb->gray >> 8; + } else { + transparent = trans_gray_rgb->gray; + } + /* Note slight error in 16-bit case: up to 256 16-bit shades + * may get mapped to a single 8-bit shade, and only one of them + * is supposed to be transparent. IOW, both opaque pixels and + * transparent pixels will be mapped into the transparent entry. + * There is no particularly good way around this in the case + * that all 256 8-bit shades are used, but one could write some + * custom 16-bit code to handle the case where there are gdFree + * palette entries. This error will be extremely rare in + * general, though. (Quite possibly there is only one such + * image in existence.) */ + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_set_gray_to_rgb(png_ptr); + // fall through + // Keep above comment, gcc recognizes it and silent its warning about + // fall through case here + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + /* gd 2.0: we now support truecolor. See the comment above + for a rare situation in which the transparent pixel may not + work properly with 16-bit channels. */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_color_rgb); + if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ + transparent = gdTrueColor(trans_color_rgb->red >> 8, trans_color_rgb->green >> 8, + trans_color_rgb->blue >> 8); + } else { + transparent = gdTrueColor(trans_color_rgb->red, trans_color_rgb->green, + trans_color_rgb->blue); + } + } + break; + default: + gd_error("gd-png color_type is unknown: %d\n", color_type); + goto error; + } - /* enable the interlace transform if supported */ + /* enable the interlace transform if supported */ #ifdef PNG_READ_INTERLACING_SUPPORTED - (void)png_set_interlace_handling(png_ptr); + (void)png_set_interlace_handling(png_ptr); #endif - png_read_update_info(png_ptr, info_ptr); - - /* allocate space for the PNG image data */ - rowbytes = png_get_rowbytes(png_ptr, info_ptr); - image_data = (png_bytep) safe_emalloc(rowbytes, height, 0); - - row_pointers = (png_bytepp) safe_emalloc(height, sizeof(png_bytep), 0); - - /* set the individual row_pointers to point at the correct offsets */ - for (h = 0; h < height; ++h) { - row_pointers[h] = image_data + h * rowbytes; - } - - png_read_image(png_ptr, row_pointers); /* read whole image... */ - png_read_end(png_ptr, NULL); /* ...done! */ - - if (!im->trueColor) { - im->colorsTotal = num_palette; - /* load the palette and mark all entries "open" (unused) for now */ - open = im->open; - for (i = 0; i < num_palette; ++i) { - im->red[i] = palette[i].red; - im->green[i] = palette[i].green; - im->blue[i] = palette[i].blue; - open[i] = 1; - } - for (i = num_palette; i < gdMaxColors; ++i) { - open[i] = 1; - } - } - - /* 2.0.12: Slaven Rezic: palette images are not the only images - * with a simple transparent color setting. - */ - im->transparent = transparent; - im->interlace = (interlace_type == PNG_INTERLACE_ADAM7); - - /* can't nuke structs until done with palette */ - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - switch (color_type) { - case PNG_COLOR_TYPE_RGB: - for (h = 0; h < height; h++) { - int boffset = 0; - for (w = 0; w < width; w++) { - register png_byte r = row_pointers[h][boffset++]; - register png_byte g = row_pointers[h][boffset++]; - register png_byte b = row_pointers[h][boffset++]; - im->tpixels[h][w] = gdTrueColor (r, g, b); - } - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - case PNG_COLOR_TYPE_RGB_ALPHA: - for (h = 0; h < height; h++) { - int boffset = 0; - for (w = 0; w < width; w++) { - register png_byte r = row_pointers[h][boffset++]; - register png_byte g = row_pointers[h][boffset++]; - register png_byte b = row_pointers[h][boffset++]; - - /* gd has only 7 bits of alpha channel resolution, and - * 127 is transparent, 0 opaque. A moment of convenience, - * a lifetime of compatibility. - */ - - register png_byte a = gdAlphaMax - (row_pointers[h][boffset++] >> 1); - im->tpixels[h][w] = gdTrueColorAlpha(r, g, b, a); - } - } - break; - - default: - /* Palette image, or something coerced to be one */ - for (h = 0; h < height; ++h) { - for (w = 0; w < width; ++w) { - register png_byte idx = row_pointers[h][w]; - im->pixels[h][w] = idx; - open[idx] = 0; - } - } - } + png_read_update_info(png_ptr, info_ptr); + + /* allocate space for the PNG image data */ + rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (overflow2(rowbytes, height)) + goto error; + image_data = (png_bytep)gdMalloc(rowbytes * height); + if (!image_data) { + gd_error("gd-png error: cannot allocate image data\n"); + goto error; + } + if (overflow2(height, sizeof(png_bytep))) + goto error; + + row_pointers = (png_bytepp)gdMalloc(height * sizeof(png_bytep)); + if (!row_pointers) { + gd_error("gd-png error: cannot allocate row pointers\n"); + goto error; + } + + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function. We must reset it everytime we get a + * new allocation that we save in a stack variable. + */ +#ifdef PNG_SETJMP_SUPPORTED + if (setjmp(jbw.jmpbuf)) { + gd_error("gd-png error: setjmp returns error condition 3\n"); + goto error; + } +#endif + + /* set the individual row_pointers to point at the correct offsets */ + for (h = 0; h < height; ++h) { + row_pointers[h] = image_data + h * rowbytes; + } + + png_read_image(png_ptr, row_pointers); /* read whole image... */ + png_read_end(png_ptr, NULL); /* ...done! */ + + if (!im->trueColor) { + im->colorsTotal = num_palette; + /* load the palette and mark all entries "open" (unused) for now */ + open = im->open; + for (i = 0; i < num_palette; ++i) { + im->red[i] = palette[i].red; + im->green[i] = palette[i].green; + im->blue[i] = palette[i].blue; + open[i] = 1; + } + for (i = num_palette; i < gdMaxColors; ++i) { + open[i] = 1; + } + } + /* 2.0.12: Slaven Rezic: palette images are not the only images + with a simple transparent color setting */ + im->transparent = transparent; + im->interlace = (interlace_type == PNG_INTERLACE_ADAM7); + + /* can't nuke structs until done with palette */ + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + switch (color_type) { + case PNG_COLOR_TYPE_RGB: + for (h = 0; h < height; h++) { + int boffset = 0; + for (w = 0; w < width; w++) { + register png_byte r = row_pointers[h][boffset++]; + register png_byte g = row_pointers[h][boffset++]; + register png_byte b = row_pointers[h][boffset++]; + im->tpixels[h][w] = gdTrueColor(r, g, b); + } + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + case PNG_COLOR_TYPE_RGB_ALPHA: + for (h = 0; h < height; h++) { + int boffset = 0; + for (w = 0; w < width; w++) { + register png_byte r = row_pointers[h][boffset++]; + register png_byte g = row_pointers[h][boffset++]; + register png_byte b = row_pointers[h][boffset++]; + + /* gd has only 7 bits of alpha channel resolution, and + * 127 is transparent, 0 opaque. A moment of convenience, + * a lifetime of compatibility. + */ + + register png_byte a = gdAlphaMax - (row_pointers[h][boffset++] >> 1); + im->tpixels[h][w] = gdTrueColorAlpha(r, g, b, a); + } + } + break; + default: + if (!im->trueColor) { + /* Palette image, or something coerced to be one */ + for (h = 0; h < height; ++h) { + for (w = 0; w < width; ++w) { + register png_byte idx = row_pointers[h][w]; + im->pixels[h][w] = idx; + open[idx] = 0; + } + } + } + } #ifdef DEBUG - if (!im->trueColor) { - for (i = num_palette; i < gdMaxColors; ++i) { - if (!open[i]) { - gd_error("gd-png warning: image data references out-of-range color index (%d)", i); - } - } - } + if (!im->trueColor) { + for (i = num_palette; i < gdMaxColors; ++i) { + if (!open[i]) { + fprintf(stderr, + "gd-png warning: image data references out-of-range" + " color index (%d)\n", + i); + } + } + } #endif - if (palette_allocated) { - gdFree(palette); - } - gdFree(image_data); - gdFree(row_pointers); +done: + if (palette_allocated) { + gdFree(palette); + } + if (image_data) + gdFree(image_data); + if (row_pointers) + gdFree(row_pointers); + + return im; + +error: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + if (im) { + gdImageDestroy(im); + im = NULL; + } + goto done; +} + +/* + Function: gdImagePngEx + + outputs the specified image to the specified file in + PNG format. The file must be open for writing. Under MSDOS and all + versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + In addition, allows the level of compression to be + specified. A compression level of 0 means "no compression." A + compression level of 1 means "compressed, but as quickly as + possible." A compression level of 9 means "compressed as much as + possible to produce the smallest possible file." A compression level + of -1 will use the default compression level at the time zlib was + compiled on your system. + + Variants: + + is equivalent to calling with + compression of -1. + + and write via a + instead of a file handle. + + and store the image file to + memory. + + Parameters: + + im - the image to write + outFile - the output FILE* object. + level - compression level: 0 -> none, 1-9 -> level, -1 -> default + + Returns: + + Nothing. + + Example: + (start code) + + gdImagePtr im; + int black, white; + FILE *out; + + im = gdImageCreate(100, 100); // Create the image + white = gdImageColorAllocate(im, 255, 255, 255); // Alloc background + black = gdImageColorAllocate(im, 0, 0, 0); // Allocate drawing color + gdImageRectangle(im, 0, 0, 99, 99, black); // Draw rectangle + out = fopen("rect.png", "wb"); // Open output file (binary) + gdImagePngEx(im, out, 9); // Write PNG, max compression + fclose(out); // Close file + gdImageDestroy(im); // Destroy image + + (end code) +*/ +BGD_DECLARE(void) gdImagePngEx(gdImagePtr im, FILE *outFile, int level) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImagePngCtxEx(im, out, level); + out->gd_free(out); +} + +/* + Function: gdImagePng + + Equivalent to calling with compression of -1. + + Parameters: + + im - the image to save. + outFile - the output FILE*. + + Returns: - return im; + Nothing. +*/ +BGD_DECLARE(void) gdImagePng(gdImagePtr im, FILE *outFile) { gdImagePngEx(im, outFile, -1); } + +static int _gdImagePngCtxWithOptions(gdImagePtr im, gdIOCtx *outfile, + const gdPngWriteOptions *options); + +BGD_DECLARE(void) gdPngWriteOptionsInit(gdPngWriteOptions *options) +{ + if (options == NULL) + return; + memset(options, 0, sizeof(*options)); + options->struct_size = sizeof(*options); + options->compression_level = -1; + options->filters = GD_PNG_FILTER_AUTO; + options->compression_strategy = GD_PNG_COMPRESSION_STRATEGY_DEFAULT; } -void gdImagePngEx (gdImagePtr im, FILE * outFile, int level, int basefilter) +static int gdPngWriteOptionsValid(const gdPngWriteOptions *options) { - gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, level, basefilter); - out->gd_free(out); + if (options->struct_size < sizeof(*options)) { + gd_error("gd-png error: invalid options structure size\n"); + return FALSE; + } + if (options->compression_level < -1 || options->compression_level > 9) { + gd_error("gd-png error: compression level must be -1 through 9\n"); + return FALSE; + } + if ((options->filters & ~GD_PNG_FILTER_ALL) != 0) { + gd_error("gd-png error: invalid filter mask\n"); + return FALSE; + } + if (options->compression_strategy < GD_PNG_COMPRESSION_STRATEGY_DEFAULT || + options->compression_strategy > GD_PNG_COMPRESSION_STRATEGY_FIXED) { + gd_error("gd-png error: invalid compression strategy\n"); + return FALSE; + } + return TRUE; } -void gdImagePng (gdImagePtr im, FILE * outFile) +BGD_DECLARE(int) +gdImagePngWithOptions(gdImagePtr im, FILE *outFile, const gdPngWriteOptions *options) { - gdIOCtx *out = gdNewFileCtx(outFile); - gdImagePngCtxEx(im, out, -1, -1); - out->gd_free(out); + gdIOCtx *out; + int status; + if (im == NULL || outFile == NULL) + return 1; + out = gdNewFileCtx(outFile); + if (out == NULL) + return 1; + status = gdImagePngCtxWithOptions(im, out, options); + out->gd_free(out); + return status; } -void * gdImagePngPtr (gdImagePtr im, int *size) +/* + Function: gdImagePngPtr + + Equivalent to calling with compression of -1. + + See for more information. + + Parameters: + + im - the image to save. + size - Output: size in bytes of the result. + + Returns: + + A pointer to memory containing the image data or NULL on error. + +*/ +BGD_DECLARE(void *) gdImagePngPtr(gdImagePtr im, int *size) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, -1, -1); - rv = gdDPExtractData(out, size); - out->gd_free(out); + return gdImagePngPtrEx(im, size, -1); +} + +/* + Function: gdImagePngPtrEx + + Identical to except that it returns a pointer to a + memory area with the PNG data. This memory must be freed by the + caller when it is no longer needed. **The caller must invoke + gdFree(), not free()** + + The 'size' parameter receives the total size of the block of + memory. + + See for more information. + + Parameters: + + im - the image to save. + size - Output: size in bytes of the result. + level - compression level: 0 -> none, 1-9 -> level, -1 -> default + + Returns: - return rv; + A pointer to memory containing the image data or NULL on error. + +*/ +BGD_DECLARE(void *) gdImagePngPtrEx(gdImagePtr im, int *size, int level) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + gdPngWriteOptions options; + if (out == NULL) + return NULL; + gdPngWriteOptionsInit(&options); + options.compression_level = level; + if (!_gdImagePngCtxWithOptions(im, out, &options)) + rv = gdDPExtractData(out, size); + else + rv = NULL; + out->gd_free(out); + return rv; } -void * gdImagePngPtrEx (gdImagePtr im, int *size, int level, int basefilter) +BGD_DECLARE(void *) +gdImagePngPtrWithOptions(gdImagePtr im, int *size, const gdPngWriteOptions *options) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImagePngCtxEx(im, out, level, basefilter); - rv = gdDPExtractData(out, size); - out->gd_free(out); - return rv; + gdPngWriteOptions defaults; + gdIOCtx *out; + void *rv = NULL; + if (size != NULL) + *size = 0; + if (im == NULL || size == NULL) + return NULL; + if (options == NULL) { + gdPngWriteOptionsInit(&defaults); + options = &defaults; + } + if (!gdPngWriteOptionsValid(options)) + return NULL; + out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImagePngCtxWithOptions(im, out, options)) + rv = gdDPExtractData(out, size); + out->gd_free(out); + if (rv != NULL && options->metadata != NULL && + gdImageMetadataInjectPng(&rv, size, options->metadata) != GD_META_OK) { + gdFree(rv); + *size = 0; + return NULL; + } + return rv; } -void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) +BGD_DECLARE(void *) +gdImagePngPtrWithMetadata(gdImagePtr im, int *size, const gdImageMetadata *metadata) { - gdImagePngCtxEx(im, outfile, -1, -1); + return gdImagePngPtrExWithMetadata(im, size, -1, metadata); +} + +BGD_DECLARE(void *) +gdImagePngPtrExWithMetadata(gdImagePtr im, int *size, int level, const gdImageMetadata *metadata) +{ + void *rv = gdImagePngPtrEx(im, size, level); + if (rv == NULL) + return NULL; + if (gdImageMetadataInjectPng(&rv, size, metadata) != GD_META_OK) { + gdFree(rv); + if (size != NULL) + *size = 0; + return NULL; + } + return rv; +} + +BGD_DECLARE(int) +gdImageMetadataInjectPng(void **data, int *size, const gdImageMetadata *metadata) +{ + const unsigned char *png; + unsigned char *out; + const unsigned char *profile; + size_t profile_size; + size_t png_size; + size_t pos; + size_t out_pos; + size_t out_size; + size_t extra_size = 0; + size_t i; + int wrote_after_ihdr = FALSE; + + if (data == NULL || size == NULL || *data == NULL || *size < 0) { + return GD_META_ERR_INVALID; + } + if (metadata == NULL) { + return GD_META_OK; + } + + png = (const unsigned char *)*data; + png_size = (size_t)*size; + if (png_size < 8 || memcmp(png, gdPngSignature, 8) != 0) { + return GD_META_ERR_FORMAT; + } + + profile = gdImageMetadataGetProfile(metadata, "exif", &profile_size); + if (gdPngMetadataChunkSize(&extra_size, profile, profile_size) != GD_META_OK) { + return GD_META_ERR_LIMIT; + } + profile = gdImageMetadataGetProfile(metadata, "icc", &profile_size); + if (gdPngMetadataChunkSize(&extra_size, profile, profile_size) != GD_META_OK) { + return GD_META_ERR_LIMIT; + } + profile = gdImageMetadataGetProfile(metadata, "xmp", &profile_size); + if (gdPngMetadataChunkSize(&extra_size, profile, profile_size) != GD_META_OK) { + return GD_META_ERR_LIMIT; + } + for (i = 0; i < gdImageMetadataGetProfileCount(metadata); i++) { + const char *key = NULL; + const unsigned char *text_data = NULL; + size_t text_size = 0; + if (gdImageMetadataGetProfileAt(metadata, i, &key, &text_data, &text_size) == GD_META_OK && + key != NULL && strncmp(key, "png:text:", 9) == 0) { + if (gdPngMetadataChunkSize(&extra_size, text_data, text_size) != GD_META_OK) { + return GD_META_ERR_LIMIT; + } + } + } + + if ((size_t)-1 - png_size < extra_size || png_size + extra_size > INT_MAX) { + return GD_META_ERR_LIMIT; + } + out_size = png_size + extra_size; + out = (unsigned char *)gdMalloc(out_size); + if (out == NULL) { + return GD_META_ERR_NOMEM; + } + + memcpy(out, png, 8); + pos = 8; + out_pos = 8; + while (pos + 12 <= png_size) { + unsigned int chunk_size = gdPngGetUint32(png + pos); + const unsigned char *type = png + pos + 4; + const unsigned char *chunk_data = png + pos + 8; + size_t chunk_total; + + if ((size_t)chunk_size > png_size - pos - 12) { + gdFree(out); + return GD_META_ERR_PARSE; + } + chunk_total = (size_t)chunk_size + 12; + + if (!gdPngShouldSkipChunk(type, chunk_data, chunk_size, metadata)) { + memcpy(out + out_pos, png + pos, chunk_total); + out_pos += chunk_total; + } + pos += chunk_total; + + if (gdPngChunkIs(type, "IHDR") && !wrote_after_ihdr) { + int status; + profile = gdImageMetadataGetProfile(metadata, "exif", &profile_size); + if (profile != NULL && + (status = gdPngAppendChunk( + out, &out_pos, + gdPngIsRawProfile(profile, profile_size, "exif") ? "zTXt" : "eXIf", profile, + profile_size)) != GD_META_OK) { + gdFree(out); + return status; + } + profile = gdImageMetadataGetProfile(metadata, "icc", &profile_size); + if (profile != NULL && (status = gdPngAppendChunk(out, &out_pos, "iCCP", profile, + profile_size)) != GD_META_OK) { + gdFree(out); + return status; + } + profile = gdImageMetadataGetProfile(metadata, "xmp", &profile_size); + if (profile != NULL && + (status = gdPngAppendChunk(out, &out_pos, + gdPngIsRawProfile(profile, profile_size, "xmp") ? "zTXt" + : "iTXt", + profile, profile_size)) != GD_META_OK) { + gdFree(out); + return status; + } + for (i = 0; i < gdImageMetadataGetProfileCount(metadata); i++) { + const char *key = NULL; + const unsigned char *text_data = NULL; + size_t text_size = 0; + if (gdImageMetadataGetProfileAt(metadata, i, &key, &text_data, &text_size) == + GD_META_OK && + key != NULL && strncmp(key, "png:text:", 9) == 0) { + status = gdPngAppendChunk(out, &out_pos, "tEXt", text_data, text_size); + if (status != GD_META_OK) { + gdFree(out); + return status; + } + } + } + wrote_after_ihdr = TRUE; + } + + if (gdPngChunkIs(type, "IEND")) { + gdFree(*data); + *data = out; + *size = (int)out_pos; + return GD_META_OK; + } + } + + gdFree(out); + return GD_META_ERR_PARSE; +} + +/* + Function: gdImagePngCtx + + Equivalent to calling with compression of -1. + See for more information. + + Parameters: + + im - the image to save. + outfile - the to write to. + + Returns: + + Nothing. + +*/ +BGD_DECLARE(void) gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile) +{ + /* 2.0.13: 'return' here was an error, thanks to Kevin Smith */ + gdImagePngCtxEx(im, outfile, -1); +} + +BGD_DECLARE(void) +gdImagePngCtxWithMetadata(gdImagePtr im, gdIOCtx *outfile, const gdImageMetadata *metadata) +{ + gdImagePngCtxExWithMetadata(im, outfile, -1, metadata); +} + +/* + Function: gdImagePngCtxEx + + Outputs the given image as PNG data, but using a instead + of a file. See . + + Parameters: + + im - the image to save. + outfile - the to write to. + level - compression level: 0 -> none, 1-9 -> level, -1 -> default + + Returns: + + Nothing. + +*/ +BGD_DECLARE(void) gdImagePngCtxEx(gdImagePtr im, gdIOCtx *outfile, int level) +{ + gdPngWriteOptions options; + gdPngWriteOptionsInit(&options); + options.compression_level = level; + (void)_gdImagePngCtxWithOptions(im, outfile, &options); +} + +BGD_DECLARE(void) +gdImagePngCtxExWithMetadata(gdImagePtr im, gdIOCtx *outfile, int level, + const gdImageMetadata *metadata) +{ + void *data; + int size = 0; + data = gdImagePngPtrExWithMetadata(im, &size, level, metadata); + if (data == NULL) + return; + gdPutBuf(data, size, outfile); + gdFree(data); +} + +BGD_DECLARE(int) +gdImagePngCtxWithOptions(gdImagePtr im, gdIOCtx *outfile, const gdPngWriteOptions *options) +{ + gdPngWriteOptions defaults; + void *data; + int size = 0; + + if (im == NULL || outfile == NULL) + return 1; + if (options == NULL) { + gdPngWriteOptionsInit(&defaults); + options = &defaults; + } + if (!gdPngWriteOptionsValid(options)) + return 1; + if (options->metadata == NULL) + return _gdImagePngCtxWithOptions(im, outfile, options); + data = gdImagePngPtrWithOptions(im, &size, options); + if (data == NULL) + return 1; + if (gdPutBuf(data, size, outfile) != size) { + gdFree(data); + return 1; + } + gdFree(data); + return 0; } /* This routine is based in part on code from Dale Lutz (Safe Software Inc.) * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" - * (http://www.cdrom.com/pub/png/pngbook.html). + * (http://www.libpng.org/pub/png/book/). */ -void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilter) -{ - int i, j, bit_depth = 0, interlace_type; - int width = im->sx; - int height = im->sy; - int colors = im->colorsTotal; - int *open = im->open; - int mapping[gdMaxColors]; /* mapping[gd_index] == png_index */ - png_byte trans_values[256]; - png_color_16 trans_rgb_value; - png_color palette[gdMaxColors]; - png_structp png_ptr; - png_infop info_ptr; - volatile int transparent = im->transparent; - volatile int remap = FALSE; +/* returns 0 on success, 1 on failure */ +static int _gdImagePngCtxWithOptions(gdImagePtr im, gdIOCtx *outfile, + const gdPngWriteOptions *options) +{ + int i, j, bit_depth = 0, interlace_type; + int width = im->sx; + int height = im->sy; + int colors = im->colorsTotal; + int *open = im->open; + int mapping[gdMaxColors]; /* mapping[gd_index] == png_index */ + png_byte trans_values[256]; + png_color_16 trans_rgb_value; + png_color palette[gdMaxColors]; + png_structp png_ptr; + png_infop info_ptr; + png_bytep *row_pointers = NULL; + volatile int transparent = im->transparent; + volatile int remap = FALSE; #ifdef PNG_SETJMP_SUPPORTED - jmpbuf_wrapper jbw; + jmpbuf_wrapper jbw; +#endif + int ret = 0; + + /* width or height of value 0 is invalid in IHDR; + see http://www.w3.org/TR/PNG-Chunks.html */ + if (width == 0 || height == 0) + return 1; - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &jbw, gdPngErrorHandler, gdPngWarningHandler); +#ifdef PNG_SETJMP_SUPPORTED + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &jbw, gdPngErrorHandler, + gdPngWarningHandler); #else - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif - if (png_ptr == NULL) { - gd_error("gd-png error: cannot allocate libpng main struct"); - return; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - gd_error("gd-png error: cannot allocate libpng info struct"); - png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + if (png_ptr == NULL) { + gd_error("gd-png error: cannot allocate libpng main struct\n"); + return 1; + } - return; + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + gd_error("gd-png error: cannot allocate libpng info struct\n"); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return 1; } #ifdef PNG_SETJMP_SUPPORTED - if (setjmp(jbw.jmpbuf)) { - gd_error("gd-png error: setjmp returns error condition"); - png_destroy_write_struct (&png_ptr, &info_ptr); - - return; - } -#endif + if (setjmp(jbw.jmpbuf)) { + gd_error("gd-png error: setjmp returns error condition\n"); + png_destroy_write_struct(&png_ptr, &info_ptr); - png_set_write_fn(png_ptr, (void *) outfile, gdPngWriteData, gdPngFlushData); + if (row_pointers) { + for (i = 0; i < height; ++i) + gdFree(row_pointers[i]); + gdFree(row_pointers); + } - /* This is best for palette images, and libpng defaults to it for - * palette images anyway, so we don't need to do it explicitly. - * What to ideally do for truecolor images depends, alas, on the image. - * gd is intentionally imperfect and doesn't spend a lot of time - * fussing with such things. - */ - - /* png_set_filter(png_ptr, 0, PNG_FILTER_NONE); */ + return 1; + } +#endif - /* 2.0.12: this is finally a parameter */ - if (level != -1 && (level < 0 || level > 9)) { - gd_error("gd-png error: compression level must be 0 through 9"); - return; - } - png_set_compression_level(png_ptr, level); - if (basefilter >= 0) { - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter); - } + png_set_write_fn(png_ptr, (void *)outfile, gdPngWriteData, gdPngFlushData); + + png_set_user_limits(png_ptr, 0x7fffffffL, 0x7fffffffL); + + /* This is best for palette images, and libpng defaults to it for + palette images anyway, so we don't need to do it explicitly. + What to ideally do for truecolor images depends, alas, on the image. + gd is intentionally imperfect and doesn't spend a lot of time + fussing with such things. */ + + /* 2.0.12: this is finally a parameter */ + png_set_compression_level(png_ptr, options->compression_level); + if (options->filters != GD_PNG_FILTER_AUTO) { + int filters = 0; + if (options->filters & GD_PNG_FILTER_NONE) + filters |= PNG_FILTER_NONE; + if (options->filters & GD_PNG_FILTER_SUB) + filters |= PNG_FILTER_SUB; + if (options->filters & GD_PNG_FILTER_UP) + filters |= PNG_FILTER_UP; + if (options->filters & GD_PNG_FILTER_AVERAGE) + filters |= PNG_FILTER_AVG; + if (options->filters & GD_PNG_FILTER_PAETH) + filters |= PNG_FILTER_PAETH; + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); + } + if (options->compression_strategy != GD_PNG_COMPRESSION_STRATEGY_DEFAULT) { + int strategy = Z_DEFAULT_STRATEGY; + switch (options->compression_strategy) { + case GD_PNG_COMPRESSION_STRATEGY_FILTERED: + strategy = Z_FILTERED; + break; + case GD_PNG_COMPRESSION_STRATEGY_HUFFMAN_ONLY: + strategy = Z_HUFFMAN_ONLY; + break; + case GD_PNG_COMPRESSION_STRATEGY_RLE: + strategy = Z_RLE; + break; + case GD_PNG_COMPRESSION_STRATEGY_FIXED: + strategy = Z_FIXED; + break; + } + png_set_compression_strategy(png_ptr, strategy); + } #ifdef PNG_pHYs_SUPPORTED - /* 2.1.0: specify the resolution */ - png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y), - PNG_RESOLUTION_METER); + /* 2.1.0: specify the resolution */ + png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y), PNG_RESOLUTION_METER); #endif - /* can set this to a smaller value without compromising compression if all - * image data is 16K or less; will save some decoder memory [min == 8] - */ - - /* png_set_compression_window_bits(png_ptr, 15); */ + /* can set this to a smaller value without compromising compression if all + * image data is 16K or less; will save some decoder memory [min == 8] */ + /* png_set_compression_window_bits(png_ptr, 15); */ - if (!im->trueColor) { - if (transparent >= im->colorsTotal || (transparent >= 0 && open[transparent])) { - transparent = -1; - } - - for (i = 0; i < gdMaxColors; ++i) { - mapping[i] = -1; - } - - /* count actual number of colors used (colorsTotal == high-water mark) */ - colors = 0; - for (i = 0; i < im->colorsTotal; ++i) { - if (!open[i]) { - mapping[i] = colors; - ++colors; - } - } - if (colors == 0) { - gd_error("gd-png error: no colors in palette"); - goto bail; - } - if (colors < im->colorsTotal) { - remap = TRUE; - } - if (colors <= 2) { - bit_depth = 1; - } else if (colors <= 4) { - bit_depth = 2; - } else if (colors <= 16) { - bit_depth = 4; - } else { - bit_depth = 8; - } - } - - interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; - - if (im->trueColor) { - if (im->saveAlphaFlag) { - png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } else { - png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } - } else { - png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_PALETTE, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } - - if (im->trueColor && !im->saveAlphaFlag && (transparent >= 0)) { - /* 2.0.9: fixed by Thomas Winzig */ - trans_rgb_value.red = gdTrueColorGetRed (im->transparent); - trans_rgb_value.green = gdTrueColorGetGreen (im->transparent); - trans_rgb_value.blue = gdTrueColorGetBlue (im->transparent); - png_set_tRNS(png_ptr, info_ptr, 0, 0, &trans_rgb_value); - } - - if (!im->trueColor) { - /* Oy veh. Remap the PNG palette to put the entries with interesting alpha channel - * values first. This minimizes the size of the tRNS chunk and thus the size - * of the PNG file as a whole. - */ - - int tc = 0; - int i; - int j; - int k; - - for (i = 0; (i < im->colorsTotal); i++) { - if ((!im->open[i]) && (im->alpha[i] != gdAlphaOpaque)) { - tc++; - } - } - if (tc) { + if (!im->trueColor) { + if (transparent >= im->colorsTotal || (transparent >= 0 && open[transparent])) + transparent = -1; + } + if (!im->trueColor) { + for (i = 0; i < gdMaxColors; ++i) + mapping[i] = -1; + } + if (!im->trueColor) { + /* count actual number of colors used (colorsTotal == high-water mark) + */ + colors = 0; + for (i = 0; i < im->colorsTotal; ++i) { + if (!open[i]) { + mapping[i] = colors; + ++colors; + } + } + if (colors == 0) { + gd_error("gd-png error: no colors in palette\n"); + ret = 1; + goto bail; + } + if (colors < im->colorsTotal) { + remap = TRUE; + } + if (colors <= 2) + bit_depth = 1; + else if (colors <= 4) + bit_depth = 2; + else if (colors <= 16) + bit_depth = 4; + else + bit_depth = 8; + } + interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; + + if (im->trueColor) { + if (im->saveAlphaFlag) { + png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, + interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } else { + png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, interlace_type, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + } else { + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_PALETTE, + interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + if (im->trueColor && (!im->saveAlphaFlag) && (transparent >= 0)) { + /* 2.0.9: fixed by Thomas Winzig */ + trans_rgb_value.red = gdTrueColorGetRed(im->transparent); + trans_rgb_value.green = gdTrueColorGetGreen(im->transparent); + trans_rgb_value.blue = gdTrueColorGetBlue(im->transparent); + png_set_tRNS(png_ptr, info_ptr, 0, 0, &trans_rgb_value); + } + if (!im->trueColor) { + /* Oy veh. Remap the PNG palette to put the + entries with interesting alpha channel + values first. This minimizes the size + of the tRNS chunk and thus the size + of the PNG file as a whole. */ + int tc = 0; + int i; + int j; + int k; + for (i = 0; (i < im->colorsTotal); i++) { + if ((!im->open[i]) && (im->alpha[i] != gdAlphaOpaque)) { + tc++; + } + } + if (tc) { #if 0 for (i = 0; (i < im->colorsTotal); i++) { - trans_values[i] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); + trans_values[i] = 255 - + ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); } png_set_tRNS (png_ptr, info_ptr, trans_values, 256, NULL); #endif - if (!remap) { - remap = TRUE; - } + if (!remap) { + remap = TRUE; + } + /* (Semi-)transparent indexes come up from the bottom + of the list of real colors; opaque + indexes come down from the top */ + j = 0; + k = colors - 1; + for (i = 0; (i < im->colorsTotal); i++) { + if (!im->open[i]) { + if (im->alpha[i] != gdAlphaOpaque) { + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ + trans_values[j] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); + mapping[i] = j++; + } else { + mapping[i] = k--; + } + } + } + png_set_tRNS(png_ptr, info_ptr, trans_values, tc, NULL); + } + } - /* (Semi-)transparent indexes come up from the bottom of the list of real colors; opaque - * indexes come down from the top - */ - j = 0; - k = colors - 1; - - for (i = 0; i < im->colorsTotal; i++) { - if (!im->open[i]) { - if (im->alpha[i] != gdAlphaOpaque) { - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ - trans_values[j] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); - mapping[i] = j++; - } else { - mapping[i] = k--; - } - } - } - png_set_tRNS(png_ptr, info_ptr, trans_values, tc, NULL); - } - } - - /* convert palette to libpng layout */ - if (!im->trueColor) { - if (remap) { - for (i = 0; i < im->colorsTotal; ++i) { - if (mapping[i] < 0) { - continue; - } - - palette[mapping[i]].red = im->red[i]; - palette[mapping[i]].green = im->green[i]; - palette[mapping[i]].blue = im->blue[i]; - } - } else { - for (i = 0; i < colors; ++i) { - palette[i].red = im->red[i]; - palette[i].green = im->green[i]; - palette[i].blue = im->blue[i]; - } - } - png_set_PLTE(png_ptr, info_ptr, palette, colors); - } - - /* write out the PNG header info (everything up to first IDAT) */ - png_write_info(png_ptr, info_ptr); - - /* make sure < 8-bit images are packed into pixels as tightly as possible */ - png_set_packing(png_ptr); - - /* This code allocates a set of row buffers and copies the gd image data - * into them only in the case that remapping is necessary; in gd 1.3 and - * later, the im->pixels array is laid out identically to libpng's row - * pointers and can be passed to png_write_image() function directly. - * The remapping case could be accomplished with less memory for non- - * interlaced images, but interlacing causes some serious complications. - */ - - if (im->trueColor) { - /* performance optimizations by Phong Tran */ - int channels = im->saveAlphaFlag ? 4 : 3; - /* Our little 7-bit alpha channel trick costs us a bit here. */ - png_bytep *row_pointers; - unsigned char* pOutputRow; - int **ptpixels = im->tpixels; - int *pThisRow; - unsigned char a; - int thisPixel; - png_bytep *prow_pointers; - int saveAlphaFlag = im->saveAlphaFlag; - - row_pointers = safe_emalloc(sizeof(png_bytep), height, 0); - prow_pointers = row_pointers; - for (j = 0; j < height; ++j) { - *prow_pointers = (png_bytep) safe_emalloc(width, channels, 0); - pOutputRow = *prow_pointers++; - pThisRow = *ptpixels++; - for (i = 0; i < width; ++i) { - thisPixel = *pThisRow++; - *pOutputRow++ = gdTrueColorGetRed(thisPixel); - *pOutputRow++ = gdTrueColorGetGreen(thisPixel); - *pOutputRow++ = gdTrueColorGetBlue(thisPixel); - if (saveAlphaFlag) { - /* convert the 7-bit alpha channel to an 8-bit alpha channel. - * We do a little bit-flipping magic, repeating the MSB - * as the LSB, to ensure that 0 maps to 0 and - * 127 maps to 255. We also have to invert to match - * PNG's convention in which 255 is opaque. - */ - a = gdTrueColorGetAlpha(thisPixel); - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ - *pOutputRow++ = 255 - ((a << 1) + (a >> 6)); - } - } - } - - png_write_image(png_ptr, row_pointers); - png_write_end(png_ptr, info_ptr); - - for (j = 0; j < height; ++j) { - gdFree(row_pointers[j]); - } - - gdFree(row_pointers); - } else { - if (remap) { - png_bytep *row_pointers; - row_pointers = safe_emalloc(height, sizeof(png_bytep), 0); - for (j = 0; j < height; ++j) { - row_pointers[j] = (png_bytep) gdMalloc(width); - for (i = 0; i < width; ++i) { - row_pointers[j][i] = mapping[im->pixels[j][i]]; - } - } + /* convert palette to libpng layout */ + if (!im->trueColor) { + if (remap) + for (i = 0; i < im->colorsTotal; ++i) { + if (mapping[i] < 0) + continue; + palette[mapping[i]].red = im->red[i]; + palette[mapping[i]].green = im->green[i]; + palette[mapping[i]].blue = im->blue[i]; + } + else + for (i = 0; i < colors; ++i) { + palette[i].red = im->red[i]; + palette[i].green = im->green[i]; + palette[i].blue = im->blue[i]; + } + png_set_PLTE(png_ptr, info_ptr, palette, colors); + } + + /* write out the PNG header info (everything up to first IDAT) */ + png_write_info(png_ptr, info_ptr); + + /* make sure < 8-bit images are packed into pixels as tightly as possible */ + png_set_packing(png_ptr); + + /* This code allocates a set of row buffers and copies the gd image data + * into them only in the case that remapping is necessary; in gd 1.3 and + * later, the im->pixels array is laid out identically to libpng's row + * pointers and can be passed to png_write_image() function directly. + * The remapping case could be accomplished with less memory for non- + * interlaced images, but interlacing causes some serious complications. */ + if (im->trueColor) { + /* performance optimizations by Phong Tran */ + int channels = im->saveAlphaFlag ? 4 : 3; + /* Our little 7-bit alpha channel trick costs us a bit here. */ + unsigned char *pOutputRow; + int **ptpixels = im->tpixels; + int *pThisRow; + unsigned char a; + int thisPixel; + png_bytep *prow_pointers; + int saveAlphaFlag = im->saveAlphaFlag; + if (overflow2(sizeof(png_bytep), height)) { + ret = 1; + goto bail; + } + /* Need to use calloc so we can clean it up sanely in the error handler. + */ + row_pointers = gdCalloc(height, sizeof(png_bytep)); + if (row_pointers == NULL) { + gd_error("gd-png error: unable to allocate row_pointers\n"); + ret = 1; + goto bail; + } + prow_pointers = row_pointers; + for (j = 0; j < height; ++j) { + if (overflow2(width, channels) || + ((*prow_pointers = (png_bytep)gdMalloc(width * channels)) == NULL)) { + gd_error("gd-png error: unable to allocate rows\n"); + for (i = 0; i < j; ++i) + gdFree(row_pointers[i]); + /* 2.0.29: memory leak TBB */ + gdFree(row_pointers); + ret = 1; + goto bail; + } + pOutputRow = *prow_pointers++; + pThisRow = *ptpixels++; + for (i = 0; i < width; ++i) { + thisPixel = *pThisRow++; + *pOutputRow++ = gdTrueColorGetRed(thisPixel); + *pOutputRow++ = gdTrueColorGetGreen(thisPixel); + *pOutputRow++ = gdTrueColorGetBlue(thisPixel); + + if (saveAlphaFlag) { + /* convert the 7-bit alpha channel to an 8-bit alpha + channel. We do a little bit-flipping magic, repeating the + MSB as the LSB, to ensure that 0 maps to 0 and 127 maps + to 255. We also have to invert to match PNG's convention + in which 255 is opaque. */ + a = gdTrueColorGetAlpha(thisPixel); + /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ + *pOutputRow++ = 255 - ((a << 1) + (a >> 6)); + } + } + } + + png_write_image(png_ptr, row_pointers); + png_write_end(png_ptr, info_ptr); + + for (j = 0; j < height; ++j) + gdFree(row_pointers[j]); + gdFree(row_pointers); + } else { + if (remap) { + png_bytep *row_pointers; + if (overflow2(sizeof(png_bytep), height)) { + ret = 1; + goto bail; + } + row_pointers = gdMalloc(sizeof(png_bytep) * height); + if (row_pointers == NULL) { + gd_error("gd-png error: unable to allocate row_pointers\n"); + ret = 1; + goto bail; + } + for (j = 0; j < height; ++j) { + if ((row_pointers[j] = (png_bytep)gdMalloc(width)) == NULL) { + gd_error("gd-png error: unable to allocate rows\n"); + for (i = 0; i < j; ++i) + gdFree(row_pointers[i]); + /* TBB: memory leak */ + gdFree(row_pointers); + ret = 1; + goto bail; + } + for (i = 0; i < width; ++i) + row_pointers[j][i] = mapping[im->pixels[j][i]]; + } + + png_write_image(png_ptr, row_pointers); + + for (j = 0; j < height; ++j) + gdFree(row_pointers[j]); + gdFree(row_pointers); + + png_write_end(png_ptr, info_ptr); + } else { + png_write_image(png_ptr, im->pixels); + png_write_end(png_ptr, info_ptr); + } + } + /* 1.6.3: maybe we should give that memory BACK! TBB */ +bail: + png_destroy_write_struct(&png_ptr, &info_ptr); + return ret; +} - png_write_image(png_ptr, row_pointers); - png_write_end(png_ptr, info_ptr); +#else /* !HAVE_LIBPNG */ - for (j = 0; j < height; ++j) { - gdFree(row_pointers[j]); - } +static void _noPngError(void) { gd_error("PNG image support has been disabled\n"); } + +BGD_DECLARE(void) gdPngWriteOptionsInit(gdPngWriteOptions *options) +{ + if (options == NULL) + return; + memset(options, 0, sizeof(*options)); + options->struct_size = sizeof(*options); + options->compression_level = -1; +} + +BGD_DECLARE(int) +gdImagePngWithOptions(gdImagePtr im, FILE *outFile, const gdPngWriteOptions *options) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + ARG_NOT_USED(options); + _noPngError(); + return 1; +} - gdFree(row_pointers); - } else { - png_write_image(png_ptr, im->pixels); - png_write_end(png_ptr, info_ptr); - } - } - /* 1.6.3: maybe we should give that memory BACK! TBB */ - bail: - png_destroy_write_struct(&png_ptr, &info_ptr); +BGD_DECLARE(int) +gdImagePngCtxWithOptions(gdImagePtr im, gdIOCtx *outfile, const gdPngWriteOptions *options) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(options); + _noPngError(); + return 1; +} + +BGD_DECLARE(void *) +gdImagePngPtrWithOptions(gdImagePtr im, int *size, const gdPngWriteOptions *options) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(options); + if (size != NULL) + *size = 0; + _noPngError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromPng(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noPngError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngPtrWithMetadata(int size, void *data, gdImageMetadata *metadata) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + ARG_NOT_USED(metadata); + return NULL; +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromPngCtxWithMetadata(gdIOCtx *infile, gdImageMetadata *metadata) +{ + ARG_NOT_USED(infile); + ARG_NOT_USED(metadata); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx(gdIOCtx *infile) +{ + ARG_NOT_USED(infile); + return NULL; +} + +BGD_DECLARE(void) gdImagePngEx(gdImagePtr im, FILE *outFile, int level) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + ARG_NOT_USED(level); + _noPngError(); +} + +BGD_DECLARE(void) gdImagePng(gdImagePtr im, FILE *outFile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + _noPngError(); +} + +BGD_DECLARE(void *) gdImagePngPtr(gdImagePtr im, int *size) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + return NULL; +} + +BGD_DECLARE(void *) gdImagePngPtrEx(gdImagePtr im, int *size, int level) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(level); + return NULL; +} + +BGD_DECLARE(void *) +gdImagePngPtrWithMetadata(gdImagePtr im, int *size, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(metadata); + return NULL; +} + +BGD_DECLARE(void *) +gdImagePngPtrExWithMetadata(gdImagePtr im, int *size, int level, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(level); + ARG_NOT_USED(metadata); + return NULL; +} + +BGD_DECLARE(int) +gdImageMetadataInjectPng(void **data, int *size, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(data); + ARG_NOT_USED(size); + ARG_NOT_USED(metadata); + return GD_META_ERR_UNSUPPORTED; +} + +BGD_DECLARE(void) gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + _noPngError(); +} + +BGD_DECLARE(void) +gdImagePngCtxWithMetadata(gdImagePtr im, gdIOCtx *outfile, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(metadata); + _noPngError(); +} + +BGD_DECLARE(void) gdImagePngCtxEx(gdImagePtr im, gdIOCtx *outfile, int level) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(level); + _noPngError(); +} + +BGD_DECLARE(void) +gdImagePngCtxExWithMetadata(gdImagePtr im, gdIOCtx *outfile, int level, + const gdImageMetadata *metadata) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(level); + ARG_NOT_USED(metadata); + _noPngError(); } #endif /* HAVE_LIBPNG */ diff --git a/ext/gd/libgd/gd_qoi.c b/ext/gd/libgd/gd_qoi.c new file mode 100644 index 000000000000..e3a155bb1c2d --- /dev/null +++ b/ext/gd/libgd/gd_qoi.c @@ -0,0 +1,372 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "gd.h" +#include "gd_errors.h" +#include "gdhelpers.h" + +#define QOI_IMPLEMENTATION +#include "gd_qoi.h" + +#define GD_QOI_ALLOC_STEP 8192 + +static unsigned char alpha7BitTo8Bit(int alpha7Bit) +{ + return (unsigned char)(alpha7Bit == gdAlphaTransparent + ? 0 + : 255 - ((alpha7Bit << 1) + (alpha7Bit >> 6))); +} + +static int alpha8BitTo7Bit(unsigned char alpha8Bit) { return gdAlphaMax - (alpha8Bit >> 1); } + +static void *gdQoiReadCtxToMemory(gdIOCtx *infile, int *size) +{ + unsigned char *data = NULL; + int logical_size = 0; + int real_size = 0; + + if (size != NULL) { + *size = 0; + } + if (infile == NULL || size == NULL) { + return NULL; + } + + for (;;) { + int n; + + if (real_size - logical_size < GD_QOI_ALLOC_STEP) { + unsigned char *temp; + int new_size; + + if (real_size > INT_MAX - GD_QOI_ALLOC_STEP) { + gdFree(data); + return NULL; + } + new_size = real_size + GD_QOI_ALLOC_STEP; + temp = (unsigned char *)gdRealloc(data, new_size); + if (temp == NULL) { + gdFree(data); + return NULL; + } + data = temp; + real_size = new_size; + } + + n = gdGetBuf(data + logical_size, GD_QOI_ALLOC_STEP, infile); + if (n <= 0) { + break; + } + logical_size += n; + } + + *size = logical_size; + return data; +} + +static gdImagePtr gdImageCreateFromQoiBytes(const void *data, int size) +{ + qoi_desc desc; + unsigned char *pixels; + gdImagePtr im = NULL; + unsigned int x, y; + unsigned char *p; + + if (data == NULL || size <= 0) { + return NULL; + } + + memset(&desc, 0, sizeof(desc)); + pixels = (unsigned char *)gdQoiDecode(data, size, &desc, 4); + if (pixels == NULL) { + return NULL; + } + + if (desc.width == 0 || desc.height == 0 || desc.width > INT_MAX || desc.height > INT_MAX) { + gdFree(pixels); + return NULL; + } + + im = gdImageCreateTrueColor((int)desc.width, (int)desc.height); + if (im == NULL) { + gdFree(pixels); + return NULL; + } + im->saveAlphaFlag = 1; + im->alphaBlendingFlag = 0; + + p = pixels; + for (y = 0; y < desc.height; y++) { + for (x = 0; x < desc.width; x++) { + unsigned char r = *(p++); + unsigned char g = *(p++); + unsigned char b = *(p++); + unsigned char a = *(p++); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, alpha8BitTo7Bit(a)); + } + } + + gdFree(pixels); + return im; +} + +static unsigned char *gdImageToQoiPixels(gdImagePtr im) +{ + unsigned char *pixels, *p; + int x, y; + + if (im == NULL || gdImageSX(im) <= 0 || gdImageSY(im) <= 0) { + return NULL; + } + if (overflow2(gdImageSX(im), gdImageSY(im)) || overflow2(gdImageSX(im) * gdImageSY(im), 4)) { + return NULL; + } + + pixels = (unsigned char *)gdMalloc((size_t)gdImageSX(im) * gdImageSY(im) * 4); + if (pixels == NULL) { + return NULL; + } + + p = pixels; + if (im->trueColor) { + for (y = 0; y < gdImageSY(im); y++) { + for (x = 0; x < gdImageSX(im); x++) { + int c = im->tpixels[y][x]; + *(p++) = gdTrueColorGetRed(c); + *(p++) = gdTrueColorGetGreen(c); + *(p++) = gdTrueColorGetBlue(c); + *(p++) = alpha7BitTo8Bit(gdTrueColorGetAlpha(c)); + } + } + } else { + for (y = 0; y < gdImageSY(im); y++) { + for (x = 0; x < gdImageSX(im); x++) { + int c = im->pixels[y][x]; + *(p++) = (unsigned char)im->red[c]; + *(p++) = (unsigned char)im->green[c]; + *(p++) = (unsigned char)im->blue[c]; + *(p++) = alpha7BitTo8Bit(im->alpha[c]); + } + } + } + + return pixels; +} + +static int gdQoiNormalizeColorspace(int colorspace) +{ + return colorspace == GD_QOI_LINEAR ? QOI_LINEAR : QOI_SRGB; +} + +static int _gdImageQoiCtx(gdImagePtr im, gdIOCtx *outfile, int colorspace) +{ + qoi_desc desc; + unsigned char *pixels; + void *encoded; + int encoded_size = 0; + int result = 0; + + if (outfile == NULL) { + return 0; + } + + pixels = gdImageToQoiPixels(im); + if (pixels == NULL) { + return 0; + } + + desc.width = (unsigned int)gdImageSX(im); + desc.height = (unsigned int)gdImageSY(im); + desc.channels = 4; + desc.colorspace = (unsigned char)gdQoiNormalizeColorspace(colorspace); + + encoded = gdQoiEncode(pixels, &desc, &encoded_size); + gdFree(pixels); + if (encoded == NULL || encoded_size <= 0) { + gdFree(encoded); + return 0; + } + + if (gdPutBuf(encoded, encoded_size, outfile) == encoded_size) { + result = 1; + } else { + gd_error("gd-qoi write error\n"); + } + + gdFree(encoded); + return result; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoi(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) { + return NULL; + } + im = gdImageCreateFromQoiCtx(in); + in->gd_free(in); + return im; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiPtr(int size, void *data) +{ + return gdImageCreateFromQoiPtrWithMetadata(size, data, NULL); +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromQoiPtrWithMetadata(int size, void *data, gdImageMetadata *metadata) +{ + ARG_NOT_USED(metadata); + return gdImageCreateFromQoiBytes(data, size); +} + +BGD_DECLARE(gdImagePtr) +gdImageCreateFromQoiCtxWithMetadata(gdIOCtx *infile, gdImageMetadata *metadata) +{ + void *data; + int size = 0; + gdImagePtr im; + + ARG_NOT_USED(metadata); + data = gdQoiReadCtxToMemory(infile, &size); + if (data == NULL) { + return NULL; + } + im = gdImageCreateFromQoiBytes(data, size); + gdFree(data); + return im; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiCtx(gdIOCtx *infile) +{ + return gdImageCreateFromQoiCtxWithMetadata(infile, NULL); +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromQoiSource(gdSourcePtr inSource) +{ + gdImagePtr im; + gdIOCtx *in; + if (inSource == NULL) { + return NULL; + } + in = gdNewSSCtx(inSource, NULL); + if (in == NULL) { + return NULL; + } + im = gdImageCreateFromQoiCtx(in); + in->gd_free(in); + return im; +} + +BGD_DECLARE(void) gdImageQoiEx(gdImagePtr im, FILE *outFile, int colorspace) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + gdImageQoiCtxEx(im, out, colorspace); + out->gd_free(out); +} + +BGD_DECLARE(void) gdImageQoi(gdImagePtr im, FILE *outFile) +{ + gdImageQoiEx(im, outFile, GD_QOI_SRGB); +} + +BGD_DECLARE(void *) gdImageQoiPtr(gdImagePtr im, int *size) +{ + return gdImageQoiPtrEx(im, size, GD_QOI_SRGB); +} + +BGD_DECLARE(void *) gdImageQoiPtrEx(gdImagePtr im, int *size, int colorspace) +{ + gdIOCtx *out; + void *rv = NULL; + + if (size != NULL) { + *size = 0; + } + if (size == NULL) { + return NULL; + } + + out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageQoiCtx(im, out, colorspace)) { + rv = gdDPExtractData(out, size); + } + out->gd_free(out); + return rv; +} + +BGD_DECLARE(void *) +gdImageQoiPtrWithMetadata(gdImagePtr im, int *size, const gdImageMetadata *metadata) +{ + return gdImageQoiPtrExWithMetadata(im, size, GD_QOI_SRGB, metadata); +} + +BGD_DECLARE(void *) +gdImageQoiPtrExWithMetadata(gdImagePtr im, int *size, int colorspace, + const gdImageMetadata *metadata) +{ + ARG_NOT_USED(metadata); + return gdImageQoiPtrEx(im, size, colorspace); +} + +BGD_DECLARE(int) +gdImageMetadataInjectQoi(void **data, int *size, const gdImageMetadata *metadata) +{ + ARG_NOT_USED(data); + ARG_NOT_USED(size); + ARG_NOT_USED(metadata); + return GD_META_OK; +} + +BGD_DECLARE(void) gdImageQoiCtx(gdImagePtr im, gdIOCtx *outfile) +{ + gdImageQoiCtxEx(im, outfile, GD_QOI_SRGB); +} + +BGD_DECLARE(void) +gdImageQoiCtxWithMetadata(gdImagePtr im, gdIOCtx *outfile, const gdImageMetadata *metadata) +{ + gdImageQoiCtxExWithMetadata(im, outfile, GD_QOI_SRGB, metadata); +} + +BGD_DECLARE(void) +gdImageQoiCtxEx(gdImagePtr im, gdIOCtx *outfile, int colorspace) +{ + _gdImageQoiCtx(im, outfile, colorspace); +} + +BGD_DECLARE(void) +gdImageQoiCtxExWithMetadata(gdImagePtr im, gdIOCtx *outfile, int colorspace, + const gdImageMetadata *metadata) +{ + ARG_NOT_USED(metadata); + _gdImageQoiCtx(im, outfile, colorspace); +} + +BGD_DECLARE(void) gdImageQoiToSink(gdImagePtr im, gdSinkPtr outSink) +{ + gdIOCtx *out; + if (outSink == NULL) { + return; + } + out = gdNewSSCtx(NULL, outSink); + if (out == NULL) { + return; + } + gdImageQoiCtx(im, out); + out->gd_free(out); +} diff --git a/ext/gd/libgd/gd_qoi.h b/ext/gd/libgd/gd_qoi.h new file mode 100644 index 000000000000..7cb2d4360a97 --- /dev/null +++ b/ext/gd/libgd/gd_qoi.h @@ -0,0 +1,629 @@ +/* + +Copyright (c) 2021, Dominic Szablewski - https://phoboslab.org +SPDX-License-Identifier: MIT + +This copy is vendored for libgd's QOI codec. The upstream MIT license is +also included in docs/QOI-LICENSE. + + +QOI - The "Quite OK Image" format for fast, lossless image compression + +-- About + +QOI encodes and decodes images in a lossless format. Compared to stb_image and +stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and +20% better compression. + + +-- Synopsis + +// Define `QOI_IMPLEMENTATION` in *one* C/C++ file before including this +// library to create the implementation. + +#define QOI_IMPLEMENTATION +#include "qoi.h" + +// Encode and store an RGBA buffer to the file system. The qoi_desc describes +// the input pixel data. +qoi_write("image_new.qoi", rgba_pixels, &(qoi_desc){ + .width = 1920, + .height = 1080, + .channels = 4, + .colorspace = QOI_SRGB +}); + +// Load and decode a QOI image from the file system into a 32bbp RGBA buffer. +// The qoi_desc struct will be filled with the width, height, number of channels +// and colorspace read from the file header. +qoi_desc desc; +void *rgba_pixels = qoi_read("image.qoi", &desc, 4); + + + +-- Documentation + +This library provides the following functions; +- qoi_read -- read and decode a QOI file +- qoi_decode -- decode the raw bytes of a QOI image from memory +- qoi_write -- encode and write a QOI file +- qoi_encode -- encode an rgba buffer into a QOI image in memory + +See the function declaration below for the signature and more information. + +If you don't want/need the qoi_read and qoi_write functions, you can define +QOI_NO_STDIO before including this library. + +This library uses malloc() and free(). To supply your own malloc implementation +you can define QOI_MALLOC and QOI_FREE before including this library. + +This library uses memset() to zero-initialize the index. To supply your own +implementation you can define QOI_ZEROARR before including this library. + + +-- Data Format + +A QOI file has a 14 byte header, followed by any number of data "chunks" and an +8-byte end marker. + +struct qoi_header_t { + char magic[4]; // magic bytes "qoif" + uint32_t width; // image width in pixels (BE) + uint32_t height; // image height in pixels (BE) + uint8_t channels; // 3 = RGB, 4 = RGBA + uint8_t colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear +}; + +Images are encoded row by row, left to right, top to bottom. The decoder and +encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value. An +image is complete when all pixels specified by width * height have been covered. + +Pixels are encoded as + - a run of the previous pixel + - an index into an array of previously seen pixels + - a difference to the previous pixel value in r,g,b + - full r,g,b or r,g,b,a values + +The color channels are assumed to not be premultiplied with the alpha channel +("un-premultiplied alpha"). + +A running array[64] (zero-initialized) of previously seen pixel values is +maintained by the encoder and decoder. Each pixel that is seen by the encoder +and decoder is put into this array at the position formed by a hash function of +the color value. In the encoder, if the pixel value at the index matches the +current pixel, this index position is written to the stream as QOI_OP_INDEX. +The hash function for the index is: + + index_position = (r * 3 + g * 5 + b * 7 + a * 11) % 64 + +Each chunk starts with a 2- or 8-bit tag, followed by a number of data bits. The +bit length of chunks is divisible by 8 - i.e. all chunks are byte aligned. All +values encoded in these data bits have the most significant bit on the left. + +The 8-bit tags have precedence over the 2-bit tags. A decoder must check for the +presence of an 8-bit tag first. + +The byte stream's end is marked with 7 0x00 bytes followed a single 0x01 byte. + + +The possible chunks are: + + +.- QOI_OP_INDEX ----------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----------------| +| 0 0 | index | +`-------------------------` +2-bit tag b00 +6-bit index into the color index array: 0..63 + +A valid encoder must not issue 2 or more consecutive QOI_OP_INDEX chunks to the +same index. QOI_OP_RUN should be used instead. + + +.- QOI_OP_DIFF -----------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----+-----+-----| +| 0 1 | dr | dg | db | +`-------------------------` +2-bit tag b01 +2-bit red channel difference from the previous pixel between -2..1 +2-bit green channel difference from the previous pixel between -2..1 +2-bit blue channel difference from the previous pixel between -2..1 + +The difference to the current channel values are using a wraparound operation, +so "1 - 2" will result in 255, while "255 + 1" will result in 0. + +Values are stored as unsigned integers with a bias of 2. E.g. -2 is stored as +0 (b00). 1 is stored as 3 (b11). + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_LUMA -------------------------------------. +| Byte[0] | Byte[1] | +| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | +|-------+-----------------+-------------+-----------| +| 1 0 | green diff | dr - dg | db - dg | +`---------------------------------------------------` +2-bit tag b10 +6-bit green channel difference from the previous pixel -32..31 +4-bit red channel difference minus green channel difference -8..7 +4-bit blue channel difference minus green channel difference -8..7 + +The green channel is used to indicate the general direction of change and is +encoded in 6 bits. The red and blue channels (dr and db) base their diffs off +of the green channel difference and are encoded in 4 bits. I.e.: + dr_dg = (cur_px.r - prev_px.r) - (cur_px.g - prev_px.g) + db_dg = (cur_px.b - prev_px.b) - (cur_px.g - prev_px.g) + +The difference to the current channel values are using a wraparound operation, +so "10 - 13" will result in 253, while "250 + 7" will result in 1. + +Values are stored as unsigned integers with a bias of 32 for the green channel +and a bias of 8 for the red and blue channel. + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_RUN ------------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----------------| +| 1 1 | run | +`-------------------------` +2-bit tag b11 +6-bit run-length repeating the previous pixel: 1..62 + +The run-length is stored with a bias of -1. Note that the run-lengths 63 and 64 +(b111110 and b111111) are illegal as they are occupied by the QOI_OP_RGB and +QOI_OP_RGBA tags. + + +.- QOI_OP_RGB ------------------------------------------. +| Byte[0] | Byte[1] | Byte[2] | Byte[3] | +| 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | +|-------------------------+---------+---------+---------| +| 1 1 1 1 1 1 1 0 | red | green | blue | +`-------------------------------------------------------` +8-bit tag b11111110 +8-bit red channel value +8-bit green channel value +8-bit blue channel value + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_RGBA ---------------------------------------------------. +| Byte[0] | Byte[1] | Byte[2] | Byte[3] | Byte[4] | +| 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | +|-------------------------+---------+---------+---------+---------| +| 1 1 1 1 1 1 1 1 | red | green | blue | alpha | +`-----------------------------------------------------------------` +8-bit tag b11111111 +8-bit red channel value +8-bit green channel value +8-bit blue channel value +8-bit alpha channel value + +*/ + +/* ----------------------------------------------------------------------------- +Header - Public functions */ + +#ifndef GD_QOI_H +#define GD_QOI_H + +#define QOI_NO_STDIO +#define QOI_MALLOC(sz) gdMalloc(sz) +#define QOI_FREE(p) gdFree(p) +#define qoi_encode gdQoiEncode +#define qoi_decode gdQoiDecode + +#ifdef __cplusplus +extern "C" { +#endif + +/* A pointer to a qoi_desc struct has to be supplied to all of qoi's functions. +It describes either the input format (for qoi_write and qoi_encode), or is +filled with the description read from the file header (for qoi_read and +qoi_decode). + +The colorspace in this qoi_desc is an enum where + 0 = sRGB, i.e. gamma scaled RGB channels and a linear alpha channel + 1 = all channels are linear +You may use the constants QOI_SRGB or QOI_LINEAR. The colorspace is purely +informative. It will be saved to the file header, but does not affect +how chunks are en-/decoded. */ + +#define QOI_SRGB 0 +#define QOI_LINEAR 1 + +typedef struct { + unsigned int width; + unsigned int height; + unsigned char channels; + unsigned char colorspace; +} qoi_desc; + +#ifndef QOI_NO_STDIO + +/* Encode raw RGB or RGBA pixels into a QOI image and write it to the file +system. The qoi_desc struct must be filled with the image width, height, +number of channels (3 = RGB, 4 = RGBA) and the colorspace. + +The function returns 0 on failure (invalid parameters, or fopen or malloc +failed) or the number of bytes written on success. */ + +int qoi_write(const char *filename, const void *data, const qoi_desc *desc); + +/* Read and decode a QOI image from the file system. If channels is 0, the +number of channels from the file header is used. If channels is 3 or 4 the +output format will be forced into this number of channels. + +The function either returns NULL on failure (invalid data, or malloc or fopen +failed) or a pointer to the decoded pixels. On success, the qoi_desc struct +will be filled with the description from the file header. + +The returned pixel data should be free()d after use. */ + +void *qoi_read(const char *filename, qoi_desc *desc, int channels); + +#endif /* QOI_NO_STDIO */ + +/* Encode raw RGB or RGBA pixels into a QOI image in memory. + +The function either returns NULL on failure (invalid parameters or malloc +failed) or a pointer to the encoded data on success. On success the out_len +is set to the size in bytes of the encoded data. + +The returned qoi data should be free()d after use. */ + +void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len); + +/* Decode a QOI image from memory. + +The function either returns NULL on failure (invalid parameters or malloc +failed) or a pointer to the decoded pixels. On success, the qoi_desc struct +is filled with the description from the file header. + +The returned pixel data should be free()d after use. */ + +void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels); + +#ifdef __cplusplus +} +#endif +#endif /* GD_QOI_H */ + +/* ----------------------------------------------------------------------------- +Implementation */ + +#ifdef QOI_IMPLEMENTATION +#include +#include + +#ifndef QOI_MALLOC +#define QOI_MALLOC(sz) malloc(sz) +#define QOI_FREE(p) free(p) +#endif +#ifndef QOI_ZEROARR +#define QOI_ZEROARR(a) memset((a), 0, sizeof(a)) +#endif + +#define QOI_OP_INDEX 0x00 /* 00xxxxxx */ +#define QOI_OP_DIFF 0x40 /* 01xxxxxx */ +#define QOI_OP_LUMA 0x80 /* 10xxxxxx */ +#define QOI_OP_RUN 0xc0 /* 11xxxxxx */ +#define QOI_OP_RGB 0xfe /* 11111110 */ +#define QOI_OP_RGBA 0xff /* 11111111 */ + +#define QOI_MASK_2 0xc0 /* 11000000 */ + +#define QOI_COLOR_HASH(C) (C.rgba.r * 3 + C.rgba.g * 5 + C.rgba.b * 7 + C.rgba.a * 11) +#define QOI_MAGIC \ + (((unsigned int)'q') << 24 | ((unsigned int)'o') << 16 | ((unsigned int)'i') << 8 | \ + ((unsigned int)'f')) +#define QOI_HEADER_SIZE 14 + +/* 2GB is the max file size that this implementation can safely handle. We guard +against anything larger than that, assuming the worst case with 5 bytes per +pixel, rounded down to a nice clean value. 400 million pixels ought to be +enough for anybody. */ +#define QOI_PIXELS_MAX ((unsigned int)400000000) + +typedef union { + struct { + unsigned char r, g, b, a; + } rgba; + unsigned int v; +} qoi_rgba_t; + +static const unsigned char qoi_padding[8] = {0, 0, 0, 0, 0, 0, 0, 1}; + +static void qoi_write_32(unsigned char *bytes, int *p, unsigned int v) +{ + bytes[(*p)++] = (0xff000000 & v) >> 24; + bytes[(*p)++] = (0x00ff0000 & v) >> 16; + bytes[(*p)++] = (0x0000ff00 & v) >> 8; + bytes[(*p)++] = (0x000000ff & v); +} + +static unsigned int qoi_read_32(const unsigned char *bytes, int *p) +{ + unsigned int a = bytes[(*p)++]; + unsigned int b = bytes[(*p)++]; + unsigned int c = bytes[(*p)++]; + unsigned int d = bytes[(*p)++]; + return a << 24 | b << 16 | c << 8 | d; +} + +void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) +{ + int i, max_size, p, run; + int px_len, px_end, px_pos, channels; + unsigned char *bytes; + const unsigned char *pixels; + qoi_rgba_t index[64]; + qoi_rgba_t px, px_prev; + + if (data == NULL || out_len == NULL || desc == NULL || desc->width == 0 || desc->height == 0 || + desc->channels < 3 || desc->channels > 4 || desc->colorspace > 1 || + desc->height >= QOI_PIXELS_MAX / desc->width) { + return NULL; + } + + max_size = + desc->width * desc->height * (desc->channels + 1) + QOI_HEADER_SIZE + sizeof(qoi_padding); + + p = 0; + bytes = (unsigned char *)QOI_MALLOC(max_size); + if (!bytes) { + return NULL; + } + + qoi_write_32(bytes, &p, QOI_MAGIC); + qoi_write_32(bytes, &p, desc->width); + qoi_write_32(bytes, &p, desc->height); + bytes[p++] = desc->channels; + bytes[p++] = desc->colorspace; + + pixels = (const unsigned char *)data; + + QOI_ZEROARR(index); + + run = 0; + px_prev.rgba.r = 0; + px_prev.rgba.g = 0; + px_prev.rgba.b = 0; + px_prev.rgba.a = 255; + px = px_prev; + + px_len = desc->width * desc->height * desc->channels; + px_end = px_len - desc->channels; + channels = desc->channels; + + for (px_pos = 0; px_pos < px_len; px_pos += channels) { + px.rgba.r = pixels[px_pos + 0]; + px.rgba.g = pixels[px_pos + 1]; + px.rgba.b = pixels[px_pos + 2]; + + if (channels == 4) { + px.rgba.a = pixels[px_pos + 3]; + } + + if (px.v == px_prev.v) { + run++; + if (run == 62 || px_pos == px_end) { + bytes[p++] = QOI_OP_RUN | (run - 1); + run = 0; + } + } else { + int index_pos; + + if (run > 0) { + bytes[p++] = QOI_OP_RUN | (run - 1); + run = 0; + } + + index_pos = QOI_COLOR_HASH(px) & (64 - 1); + + if (index[index_pos].v == px.v) { + bytes[p++] = QOI_OP_INDEX | index_pos; + } else { + index[index_pos] = px; + + if (px.rgba.a == px_prev.rgba.a) { + signed char vr = px.rgba.r - px_prev.rgba.r; + signed char vg = px.rgba.g - px_prev.rgba.g; + signed char vb = px.rgba.b - px_prev.rgba.b; + + signed char vg_r = vr - vg; + signed char vg_b = vb - vg; + + if (vr > -3 && vr < 2 && vg > -3 && vg < 2 && vb > -3 && vb < 2) { + bytes[p++] = QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2); + } else if (vg_r > -9 && vg_r < 8 && vg > -33 && vg < 32 && vg_b > -9 && + vg_b < 8) { + bytes[p++] = QOI_OP_LUMA | (vg + 32); + bytes[p++] = (vg_r + 8) << 4 | (vg_b + 8); + } else { + bytes[p++] = QOI_OP_RGB; + bytes[p++] = px.rgba.r; + bytes[p++] = px.rgba.g; + bytes[p++] = px.rgba.b; + } + } else { + bytes[p++] = QOI_OP_RGBA; + bytes[p++] = px.rgba.r; + bytes[p++] = px.rgba.g; + bytes[p++] = px.rgba.b; + bytes[p++] = px.rgba.a; + } + } + } + px_prev = px; + } + + for (i = 0; i < (int)sizeof(qoi_padding); i++) { + bytes[p++] = qoi_padding[i]; + } + + *out_len = p; + return bytes; +} + +void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) +{ + const unsigned char *bytes; + unsigned int header_magic; + unsigned char *pixels; + qoi_rgba_t index[64]; + qoi_rgba_t px; + int px_len, chunks_len, px_pos; + int p = 0, run = 0; + + if (data == NULL || desc == NULL || (channels != 0 && channels != 3 && channels != 4) || + size < QOI_HEADER_SIZE + (int)sizeof(qoi_padding)) { + return NULL; + } + + bytes = (const unsigned char *)data; + + header_magic = qoi_read_32(bytes, &p); + desc->width = qoi_read_32(bytes, &p); + desc->height = qoi_read_32(bytes, &p); + desc->channels = bytes[p++]; + desc->colorspace = bytes[p++]; + + if (desc->width == 0 || desc->height == 0 || desc->channels < 3 || desc->channels > 4 || + desc->colorspace > 1 || header_magic != QOI_MAGIC || + desc->height >= QOI_PIXELS_MAX / desc->width) { + return NULL; + } + + if (channels == 0) { + channels = desc->channels; + } + + px_len = desc->width * desc->height * channels; + pixels = (unsigned char *)QOI_MALLOC(px_len); + if (!pixels) { + return NULL; + } + + QOI_ZEROARR(index); + px.rgba.r = 0; + px.rgba.g = 0; + px.rgba.b = 0; + px.rgba.a = 255; + + chunks_len = size - (int)sizeof(qoi_padding); + for (px_pos = 0; px_pos < px_len; px_pos += channels) { + if (run > 0) { + run--; + } else if (p < chunks_len) { + int b1 = bytes[p++]; + + if (b1 == QOI_OP_RGB) { + px.rgba.r = bytes[p++]; + px.rgba.g = bytes[p++]; + px.rgba.b = bytes[p++]; + } else if (b1 == QOI_OP_RGBA) { + px.rgba.r = bytes[p++]; + px.rgba.g = bytes[p++]; + px.rgba.b = bytes[p++]; + px.rgba.a = bytes[p++]; + } else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX) { + px = index[b1]; + } else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF) { + px.rgba.r += ((b1 >> 4) & 0x03) - 2; + px.rgba.g += ((b1 >> 2) & 0x03) - 2; + px.rgba.b += (b1 & 0x03) - 2; + } else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA) { + int b2 = bytes[p++]; + int vg = (b1 & 0x3f) - 32; + px.rgba.r += vg - 8 + ((b2 >> 4) & 0x0f); + px.rgba.g += vg; + px.rgba.b += vg - 8 + (b2 & 0x0f); + } else if ((b1 & QOI_MASK_2) == QOI_OP_RUN) { + run = (b1 & 0x3f); + } + + index[QOI_COLOR_HASH(px) & (64 - 1)] = px; + } + + pixels[px_pos + 0] = px.rgba.r; + pixels[px_pos + 1] = px.rgba.g; + pixels[px_pos + 2] = px.rgba.b; + + if (channels == 4) { + pixels[px_pos + 3] = px.rgba.a; + } + } + + return pixels; +} + +#ifndef QOI_NO_STDIO +#include + +int qoi_write(const char *filename, const void *data, const qoi_desc *desc) +{ + FILE *f = fopen(filename, "wb"); + int size, err; + void *encoded; + + if (!f) { + return 0; + } + + encoded = qoi_encode(data, desc, &size); + if (!encoded) { + fclose(f); + return 0; + } + + fwrite(encoded, 1, size, f); + fflush(f); + err = ferror(f); + fclose(f); + + QOI_FREE(encoded); + return err ? 0 : size; +} + +void *qoi_read(const char *filename, qoi_desc *desc, int channels) +{ + FILE *f = fopen(filename, "rb"); + int size, bytes_read; + void *pixels, *data; + + if (!f) { + return NULL; + } + + fseek(f, 0, SEEK_END); + size = ftell(f); + if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) { + fclose(f); + return NULL; + } + + data = QOI_MALLOC(size); + if (!data) { + fclose(f); + return NULL; + } + + bytes_read = fread(data, 1, size, f); + fclose(f); + pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels); + QOI_FREE(data); + return pixels; +} + +#endif /* QOI_NO_STDIO */ +#endif /* QOI_IMPLEMENTATION */ diff --git a/ext/gd/libgd/gd_readimage.c b/ext/gd/libgd/gd_readimage.c new file mode 100644 index 000000000000..65db6368f51b --- /dev/null +++ b/ext/gd/libgd/gd_readimage.c @@ -0,0 +1,289 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd.h" +#include "gd_errors.h" +#include +#include + +#define GD_READIMAGE_PROBE_SIZE 32 + +typedef gdImagePtr(BGD_STDCALL *ReadCtxFn)(gdIOCtxPtr); + +struct FormatEntry { + const char *name; + size_t offset; + const unsigned char *sig; + size_t sig_len; + ReadCtxFn reader; + int enabled; +}; + +#ifdef HAVE_LIBPNG +#define GD_READIMAGE_PNG_READER gdImageCreateFromPngCtx +#define GD_READIMAGE_PNG_ENABLED 1 +#else +#define GD_READIMAGE_PNG_READER NULL +#define GD_READIMAGE_PNG_ENABLED 0 +#endif + +#ifdef HAVE_LIBJXL +#define GD_READIMAGE_JXL_READER gdImageCreateFromJxlCtx +#define GD_READIMAGE_JXL_ENABLED 1 +#else +#define GD_READIMAGE_JXL_READER NULL +#define GD_READIMAGE_JXL_ENABLED 0 +#endif + +#ifdef HAVE_LIBJPEG +#define GD_READIMAGE_JPEG_READER gdImageCreateFromJpegCtx +#define GD_READIMAGE_JPEG_ENABLED 1 +#else +#define GD_READIMAGE_JPEG_READER NULL +#define GD_READIMAGE_JPEG_ENABLED 0 +#endif + +#ifdef HAVE_LIBTIFF +#define GD_READIMAGE_TIFF_READER gdImageCreateFromTiffCtx +#define GD_READIMAGE_TIFF_ENABLED 1 +#else +#define GD_READIMAGE_TIFF_READER NULL +#define GD_READIMAGE_TIFF_ENABLED 0 +#endif + +#ifdef HAVE_LIBWEBP +#define GD_READIMAGE_WEBP_READER gdImageCreateFromWebpCtx +#define GD_READIMAGE_WEBP_ENABLED 1 +#else +#define GD_READIMAGE_WEBP_READER NULL +#define GD_READIMAGE_WEBP_ENABLED 0 +#endif + +#ifdef HAVE_LIBAVIF +#define GD_READIMAGE_AVIF_READER gdImageCreateFromAvifCtx +#define GD_READIMAGE_AVIF_ENABLED 1 +#else +#define GD_READIMAGE_AVIF_READER NULL +#define GD_READIMAGE_AVIF_ENABLED 0 +#endif + +#ifdef HAVE_LIBHEIF +#define GD_READIMAGE_HEIF_READER gdImageCreateFromHeifCtx +#define GD_READIMAGE_HEIF_ENABLED 1 +#else +#define GD_READIMAGE_HEIF_READER NULL +#define GD_READIMAGE_HEIF_ENABLED 0 +#endif + +#if ENABLE_GD_FORMATS +#define GD_READIMAGE_GD_READER gdImageCreateFromGdCtx +#define GD_READIMAGE_GD_ENABLED 1 +#else +#define GD_READIMAGE_GD_READER NULL +#define GD_READIMAGE_GD_ENABLED 0 +#endif + +#if ENABLE_GD_FORMATS && defined(HAVE_LIBZ) +#define GD_READIMAGE_GD2_READER gdImageCreateFromGd2Ctx +#define GD_READIMAGE_GD2_ENABLED 1 +#else +#define GD_READIMAGE_GD2_READER NULL +#define GD_READIMAGE_GD2_ENABLED 0 +#endif + +#ifdef HAVE_LIBXPM +#define GD_READIMAGE_XPM_ENABLED 1 +#else +#define GD_READIMAGE_XPM_ENABLED 0 +#endif + +#define ENTRY(n, off, reader_fn, is_enabled, ...) \ + { \ + (n), (off), (const unsigned char[]){__VA_ARGS__}, \ + sizeof((const unsigned char[]){__VA_ARGS__}) / sizeof(unsigned char), (reader_fn), \ + (is_enabled) \ + } + +static const struct FormatEntry format_table[] = { + ENTRY("PNG", 0, GD_READIMAGE_PNG_READER, GD_READIMAGE_PNG_ENABLED, 0x89, 0x50, 0x4E, 0x47, 0x0D, + 0x0A, 0x1A, 0x0A), + ENTRY("JXL", 0, GD_READIMAGE_JXL_READER, GD_READIMAGE_JXL_ENABLED, 0x00, 0x00, 0x00, 0x0C, 0x4A, + 0x58, 0x4C, 0x20, 0x0D, 0x0A, 0x87, 0x0A), + ENTRY("JXL", 0, GD_READIMAGE_JXL_READER, GD_READIMAGE_JXL_ENABLED, 0xFF, 0x0A), + ENTRY("JPEG", 0, GD_READIMAGE_JPEG_READER, GD_READIMAGE_JPEG_ENABLED, 0xFF, 0xD8, 0xFF), + ENTRY("GIF", 0, gdImageCreateFromGifCtx, 1, 0x47, 0x49, 0x46, 0x38, 0x39, 0x61), + ENTRY("GIF", 0, gdImageCreateFromGifCtx, 1, 0x47, 0x49, 0x46, 0x38, 0x37, 0x61), + ENTRY("BMP", 0, gdImageCreateFromBmpCtx, 1, 0x42, 0x4D), + ENTRY("TIFF", 0, GD_READIMAGE_TIFF_READER, GD_READIMAGE_TIFF_ENABLED, 0x4D, 0x4D, 0x00, 0x2A), + ENTRY("TIFF", 0, GD_READIMAGE_TIFF_READER, GD_READIMAGE_TIFF_ENABLED, 0x49, 0x49, 0x2A, 0x00), + ENTRY("WEBP", 8, GD_READIMAGE_WEBP_READER, GD_READIMAGE_WEBP_ENABLED, 0x57, 0x45, 0x42, 0x50), + ENTRY("AVIF", 4, GD_READIMAGE_AVIF_READER, GD_READIMAGE_AVIF_ENABLED, 0x66, 0x74, 0x79, 0x70, + 0x61, 0x76, 0x69, 0x66), + ENTRY("HEIC", 4, GD_READIMAGE_HEIF_READER, GD_READIMAGE_HEIF_ENABLED, 0x66, 0x74, 0x79, 0x70, + 0x68, 0x65, 0x69, 0x63), + ENTRY("GD2", 0, GD_READIMAGE_GD2_READER, GD_READIMAGE_GD2_ENABLED, 0x67, 0x64, 0x32, 0x00), + ENTRY("GD", 0, GD_READIMAGE_GD_READER, GD_READIMAGE_GD_ENABLED, 0xFF, 0xFE), + ENTRY("GD", 0, GD_READIMAGE_GD_READER, GD_READIMAGE_GD_ENABLED, 0xFF, 0xFF), + ENTRY("QOI", 0, gdImageCreateFromQoiCtx, 1, 0x71, 0x6F, 0x69, 0x66), + ENTRY("XPM", 0, NULL, GD_READIMAGE_XPM_ENABLED, 0x2F, 0x2A, 0x20, 0x58, 0x50, 0x4D, 0x20, 0x2A), + ENTRY("XBM", 0, NULL, 1, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6E, 0x65, 0x20), + {NULL, 0, NULL, 0, NULL, 0}}; + +static int sig_match(const unsigned char *probe, size_t probe_len, const struct FormatEntry *e) +{ + if (e->offset + e->sig_len > probe_len) + return 0; + return memcmp(probe + e->offset, e->sig, e->sig_len) == 0; +} + +static const struct FormatEntry *find_format(const unsigned char *probe, size_t probe_len) +{ + size_t i; + + for (i = 0; format_table[i].name != NULL; i++) { + const struct FormatEntry *e = &format_table[i]; + if (sig_match(probe, probe_len, e)) + return e; + } + + return NULL; +} + +static void report_unreadable_format(const struct FormatEntry *e, const char *source) +{ + if (e == NULL) { + gd_error("gd-readimage: unknown image format"); + return; + } + + if (!e->enabled) { + gd_error("gd-readimage: %s image support has been disabled", e->name); + return; + } + + gd_error("gd-readimage: %s image does not support reading from %s", e->name, source); +} + +/* + Function: gdImageReadCtx + + Read an image from a , auto-detecting the format by + magic-byte signatures. + + reads the first bytes from the ctx, determines + the image format by matching known magic-byte signatures, and + dispatches to the appropriate codec's Ctx reader. The ctx must + support seeking so it can be rewound after probing. + + Formats without a Ctx reader (XPM, XBM) are not supported by + this function. Use for those formats. + + NULL is returned on error or if the format is not recognized. + + Parameters: + + ctx - the input + + Returns: + + A pointer to the new image or NULL if an error occurred. + +*/ +BGD_DECLARE(gdImagePtr) gdImageReadCtx(gdIOCtxPtr ctx) +{ + unsigned char probe[GD_READIMAGE_PROBE_SIZE]; + size_t probe_len; + const struct FormatEntry *e; + + if (ctx == NULL) + return NULL; + + probe_len = (size_t)gdGetBuf(probe, GD_READIMAGE_PROBE_SIZE, ctx); + gdSeek(ctx, 0); + + e = find_format(probe, probe_len); + if (e != NULL && e->reader != NULL) + return e->reader(ctx); + + report_unreadable_format(e, "gdIOCtx"); + return NULL; +} + +/* + Function: gdImageReadFile + + Read an image file, auto-detecting the format by magic-byte + signatures rather than filename extension. + + opens the file, probes its header bytes to + determine the format, and calls the appropriate + _gdImageCreateFrom*Ctx_ function. If the format has no Ctx + reader (XPM, XBM), it falls back to the filename-based or + FILE*-based reader. + + NULL is returned on error or if the format is not recognized. + + Parameters: + + filename - the input file name + + Returns: + + A pointer to the new image or NULL if an error occurred. + +*/ +BGD_DECLARE(gdImagePtr) gdImageReadFile(const char *filename) +{ + FILE *fh; + gdIOCtxPtr ctx; + unsigned char probe[GD_READIMAGE_PROBE_SIZE]; + size_t probe_len; + gdImagePtr im; + const struct FormatEntry *e; + + if (filename == NULL) + return NULL; + + fh = fopen(filename, "rb"); + if (!fh) + return NULL; + + ctx = gdNewFileCtx(fh); + if (!ctx) { + fclose(fh); + return NULL; + } + + probe_len = (size_t)gdGetBuf(probe, GD_READIMAGE_PROBE_SIZE, ctx); + gdSeek(ctx, 0); + + e = find_format(probe, probe_len); + if (e != NULL && e->reader != NULL) { + im = e->reader(ctx); + ctx->gd_free(ctx); + fclose(fh); + return im; + } + + ctx->gd_free(ctx); + fclose(fh); + + if (e != NULL && e->enabled) { +#ifdef HAVE_LIBXPM + if (strcmp(e->name, "XPM") == 0) + return gdImageCreateFromXpm((char *)filename); +#endif + if (strcmp(e->name, "XBM") == 0) { + FILE *xbm_fh = fopen(filename, "rb"); + if (!xbm_fh) + return NULL; + im = gdImageCreateFromXbm(xbm_fh); + fclose(xbm_fh); + return im; + } + } + + report_unreadable_format(e, "file"); + return NULL; +} diff --git a/ext/gd/libgd/gd_rotate.c b/ext/gd/libgd/gd_rotate.c index 53c6c9470db7..82f9c8a745b9 100644 --- a/ext/gd/libgd/gd_rotate.c +++ b/ext/gd/libgd/gd_rotate.c @@ -11,331 +11,333 @@ #ifdef ROTATE_PI #undef ROTATE_PI #endif /* ROTATE_PI */ - -#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180 -void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent) +typedef int(BGD_STDCALL *FuncPtr)(gdImagePtr, int, int); +#define ROTATE_DEG2RAD 3.1415926535897932384626433832795 / 180 +void gdImageSkewX(gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, + int clrBack, int ignoretransparent) { - typedef int (*FuncPtr)(gdImagePtr, int, int); - int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA; - FuncPtr f; - - int pxlOldLeft, pxlLeft=0, pxlSrc; - - /* Keep clrBack as color index if required */ - if (src->trueColor) { - pxlOldLeft = clrBack; - f = gdImageGetTrueColorPixel; - } else { - pxlOldLeft = clrBack; - clrBackR = gdImageRed(src, clrBack); - clrBackG = gdImageGreen(src, clrBack); - clrBackB = gdImageBlue(src, clrBack); - clrBackA = gdImageAlpha(src, clrBack); - clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA); - f = gdImageGetPixel; - } - - for (i = 0; i < iOffset; i++) { - gdImageSetPixel (dst, i, uRow, clrBack); - } - - if (i < dst->sx) { - gdImageSetPixel (dst, i, uRow, clrBack); - } - - for (i = 0; i < src->sx; i++) { - pxlSrc = f (src,i,uRow); - - r = (int)(gdImageRed(src,pxlSrc) * dWeight); - g = (int)(gdImageGreen(src,pxlSrc) * dWeight); - b = (int)(gdImageBlue(src,pxlSrc) * dWeight); - a = (int)(gdImageAlpha(src,pxlSrc) * dWeight); - - pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); - - if (pxlLeft == -1) { - pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); - } - - r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft)); - g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft)); - b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft)); - a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft)); - - if (r>255) { - r = 255; + int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA; + FuncPtr f; + + int pxlOldLeft, pxlLeft = 0, pxlSrc; + + /* Keep clrBack as color index if required */ + if (src->trueColor) { + pxlOldLeft = clrBack; + f = gdImageGetTrueColorPixel; + } else { + pxlOldLeft = clrBack; + clrBackR = gdImageRed(src, clrBack); + clrBackG = gdImageGreen(src, clrBack); + clrBackB = gdImageBlue(src, clrBack); + clrBackA = gdImageAlpha(src, clrBack); + clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA); + f = gdImageGetPixel; + } + + for (i = 0; i < iOffset; i++) { + gdImageSetPixel(dst, i, uRow, clrBack); + } + + if (i < dst->sx) { + gdImageSetPixel(dst, i, uRow, clrBack); + } + + for (i = 0; i < src->sx; i++) { + pxlSrc = f(src, i, uRow); + + r = (int)(gdImageRed(src, pxlSrc) * dWeight); + g = (int)(gdImageGreen(src, pxlSrc) * dWeight); + b = (int)(gdImageBlue(src, pxlSrc) * dWeight); + a = (int)(gdImageAlpha(src, pxlSrc) * dWeight); + + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); + + if (pxlLeft == -1) { + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); } - if (g>255) { - g = 255; - } + r = gdImageRed(src, pxlSrc) - (gdImageRed(src, pxlLeft) - gdImageRed(src, pxlOldLeft)); + g = gdImageGreen(src, pxlSrc) - + (gdImageGreen(src, pxlLeft) - gdImageGreen(src, pxlOldLeft)); + b = gdImageBlue(src, pxlSrc) - (gdImageBlue(src, pxlLeft) - gdImageBlue(src, pxlOldLeft)); + a = gdImageAlpha(src, pxlSrc) - + (gdImageAlpha(src, pxlLeft) - gdImageAlpha(src, pxlOldLeft)); - if (b>255) { - b = 255; - } + if (r > 255) { + r = 255; + } - if (a>127) { - a = 127; - } + if (g > 255) { + g = 255; + } - if (ignoretransparent && pxlSrc == dst->transparent) { - pxlSrc = dst->transparent; - } else { - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); + if (b > 255) { + b = 255; + } - if (pxlSrc == -1) { - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); - } - } + if (a > 127) { + a = 127; + } - if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) { - gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc); - } + if (ignoretransparent && pxlSrc == dst->transparent) { + pxlSrc = dst->transparent; + } else { + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); + + if (pxlSrc == -1) { + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + } + } + + if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) { + gdImageSetPixel(dst, i + iOffset, uRow, pxlSrc); + } - pxlOldLeft = pxlLeft; - } + pxlOldLeft = pxlLeft; + } - i += iOffset; + i += iOffset; - if (i < dst->sx) { - gdImageSetPixel (dst, i, uRow, pxlLeft); - } + if (i < dst->sx) { + gdImageSetPixel(dst, i, uRow, pxlLeft); + } - gdImageSetPixel (dst, iOffset, uRow, clrBack); + gdImageSetPixel(dst, iOffset, uRow, clrBack); - i--; + i--; - while (++i < dst->sx) { - gdImageSetPixel (dst, i, uRow, clrBack); - } + while (++i < dst->sx) { + gdImageSetPixel(dst, i, uRow, clrBack); + } } -void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent) +void gdImageSkewY(gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, + int clrBack, int ignoretransparent) { - typedef int (*FuncPtr)(gdImagePtr, int, int); - int i, iYPos=0, r, g, b, a; - FuncPtr f; - int pxlOldLeft, pxlLeft=0, pxlSrc; - - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } - - for (i = 0; i<=iOffset; i++) { - gdImageSetPixel (dst, uCol, i, clrBack); - } - r = (int)((double)gdImageRed(src,clrBack) * dWeight); - g = (int)((double)gdImageGreen(src,clrBack) * dWeight); - b = (int)((double)gdImageBlue(src,clrBack) * dWeight); - a = (int)((double)gdImageAlpha(src,clrBack) * dWeight); - - pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a); - - for (i = 0; i < src->sy; i++) { - pxlSrc = f (src, uCol, i); - iYPos = i + iOffset; - - r = (int)((double)gdImageRed(src,pxlSrc) * dWeight); - g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight); - b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight); - a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight); - - pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); - - if (pxlLeft == -1) { - pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); - } - - r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft)); - g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft)); - b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft)); - a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft)); - - if (r>255) { - r = 255; - } - - if (g>255) { - g = 255; - } - - if (b>255) { - b = 255; - } - - if (a>127) { - a = 127; - } - - if (ignoretransparent && pxlSrc == dst->transparent) { - pxlSrc = dst->transparent; - } else { - pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); - - if (pxlSrc == -1) { - pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); - } - } - - if ((iYPos >= 0) && (iYPos < dst->sy)) { - gdImageSetPixel (dst, uCol, iYPos, pxlSrc); - } - - pxlOldLeft = pxlLeft; - } - - i = iYPos; - if (i < dst->sy) { - gdImageSetPixel (dst, uCol, i, pxlLeft); - } - - i--; - while (++i < dst->sy) { - gdImageSetPixel (dst, uCol, i, clrBack); - } + int i, iYPos = 0, r, g, b, a; + FuncPtr f; + int pxlOldLeft, pxlLeft = 0, pxlSrc; + + if (src->trueColor) { + f = gdImageGetTrueColorPixel; + } else { + f = gdImageGetPixel; + } + + for (i = 0; i <= iOffset; i++) { + gdImageSetPixel(dst, uCol, i, clrBack); + } + r = (int)((double)gdImageRed(src, clrBack) * dWeight); + g = (int)((double)gdImageGreen(src, clrBack) * dWeight); + b = (int)((double)gdImageBlue(src, clrBack) * dWeight); + a = (int)((double)gdImageAlpha(src, clrBack) * dWeight); + + pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a); + + for (i = 0; i < src->sy; i++) { + pxlSrc = f(src, uCol, i); + iYPos = i + iOffset; + + r = (int)((double)gdImageRed(src, pxlSrc) * dWeight); + g = (int)((double)gdImageGreen(src, pxlSrc) * dWeight); + b = (int)((double)gdImageBlue(src, pxlSrc) * dWeight); + a = (int)((double)gdImageAlpha(src, pxlSrc) * dWeight); + + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a); + + if (pxlLeft == -1) { + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a); + } + + r = gdImageRed(src, pxlSrc) - (gdImageRed(src, pxlLeft) - gdImageRed(src, pxlOldLeft)); + g = gdImageGreen(src, pxlSrc) - + (gdImageGreen(src, pxlLeft) - gdImageGreen(src, pxlOldLeft)); + b = gdImageBlue(src, pxlSrc) - (gdImageBlue(src, pxlLeft) - gdImageBlue(src, pxlOldLeft)); + a = gdImageAlpha(src, pxlSrc) - + (gdImageAlpha(src, pxlLeft) - gdImageAlpha(src, pxlOldLeft)); + + if (r > 255) { + r = 255; + } + + if (g > 255) { + g = 255; + } + + if (b > 255) { + b = 255; + } + + if (a > 127) { + a = 127; + } + + if (ignoretransparent && pxlSrc == dst->transparent) { + pxlSrc = dst->transparent; + } else { + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a); + + if (pxlSrc == -1) { + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a); + } + } + + if ((iYPos >= 0) && (iYPos < dst->sy)) { + gdImageSetPixel(dst, uCol, iYPos, pxlSrc); + } + + pxlOldLeft = pxlLeft; + } + + i = iYPos; + if (i < dst->sy) { + gdImageSetPixel(dst, uCol, i, pxlLeft); + } + + i--; + while (++i < dst->sy) { + gdImageSetPixel(dst, uCol, i, clrBack); + } } /* Rotates an image by 90 degrees (counter clockwise) */ -gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent) +gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent) { - int uY, uX; - int c,r,g,b,a; - gdImagePtr dst; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } - dst = gdImageCreateTrueColor(src->sy, src->sx); - - if (dst != NULL) { - int old_blendmode = dst->alphaBlendingFlag; - dst->alphaBlendingFlag = 0; - dst->saveAlphaFlag = 1; - dst->transparent = src->transparent; - - gdImagePaletteCopy (dst, src); - - for (uY = 0; uYsy; uY++) { - for (uX = 0; uXsx; uX++) { - c = f (src, uX, uY); - if (!src->trueColor) { - r = gdImageRed(src,c); - g = gdImageGreen(src,c); - b = gdImageBlue(src,c); - a = gdImageAlpha(src,c); - c = gdTrueColorAlpha(r, g, b, a); - } - if (ignoretransparent && c == dst->transparent) { - gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent); - } else { - gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c); - } - } - } - dst->alphaBlendingFlag = old_blendmode; - } - - return dst; + int uY, uX; + int c, r, g, b, a; + gdImagePtr dst; + typedef int (*FuncPtr)(gdImagePtr, int, int); + FuncPtr f; + + if (src->trueColor) { + f = gdImageGetTrueColorPixel; + } else { + f = gdImageGetPixel; + } + dst = gdImageCreateTrueColor(src->sy, src->sx); + + if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + dst->saveAlphaFlag = 1; + dst->transparent = src->transparent; + + gdImagePaletteCopy(dst, src); + + for (uY = 0; uY < src->sy; uY++) { + for (uX = 0; uX < src->sx; uX++) { + c = f(src, uX, uY); + if (!src->trueColor) { + r = gdImageRed(src, c); + g = gdImageGreen(src, c); + b = gdImageBlue(src, c); + a = gdImageAlpha(src, c); + c = gdTrueColorAlpha(r, g, b, a); + } + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent); + } else { + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c); + } + } + } + dst->alphaBlendingFlag = old_blendmode; + } + + return dst; } /* Rotates an image by 180 degrees (counter clockwise) */ -gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent) +gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent) { - int uY, uX; - int c,r,g,b,a; - gdImagePtr dst; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } - dst = gdImageCreateTrueColor(src->sx, src->sy); - - if (dst != NULL) { - int old_blendmode = dst->alphaBlendingFlag; - dst->alphaBlendingFlag = 0; - dst->saveAlphaFlag = 1; - dst->transparent = src->transparent; - - gdImagePaletteCopy (dst, src); - - for (uY = 0; uYsy; uY++) { - for (uX = 0; uXsx; uX++) { - c = f (src, uX, uY); - if (!src->trueColor) { - r = gdImageRed(src,c); - g = gdImageGreen(src,c); - b = gdImageBlue(src,c); - a = gdImageAlpha(src,c); - c = gdTrueColorAlpha(r, g, b, a); - } - - if (ignoretransparent && c == dst->transparent) { - gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent); - } else { - gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c); - } - } - } - dst->alphaBlendingFlag = old_blendmode; - } - - return dst; + int uY, uX; + int c, r, g, b, a; + gdImagePtr dst; + FuncPtr f; + + if (src->trueColor) { + f = gdImageGetTrueColorPixel; + } else { + f = gdImageGetPixel; + } + dst = gdImageCreateTrueColor(src->sx, src->sy); + + if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + dst->saveAlphaFlag = 1; + dst->transparent = src->transparent; + + gdImagePaletteCopy(dst, src); + + for (uY = 0; uY < src->sy; uY++) { + for (uX = 0; uX < src->sx; uX++) { + c = f(src, uX, uY); + if (!src->trueColor) { + r = gdImageRed(src, c); + g = gdImageGreen(src, c); + b = gdImageBlue(src, c); + a = gdImageAlpha(src, c); + c = gdTrueColorAlpha(r, g, b, a); + } + + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent); + } else { + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c); + } + } + } + dst->alphaBlendingFlag = old_blendmode; + } + + return dst; } /* Rotates an image by 270 degrees (counter clockwise) */ -gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) +gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent) { - int uY, uX; - int c,r,g,b,a; - gdImagePtr dst; - typedef int (*FuncPtr)(gdImagePtr, int, int); - FuncPtr f; - - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } - dst = gdImageCreateTrueColor (src->sy, src->sx); - - if (dst != NULL) { - int old_blendmode = dst->alphaBlendingFlag; - dst->alphaBlendingFlag = 0; - dst->saveAlphaFlag = 1; - dst->transparent = src->transparent; - - gdImagePaletteCopy (dst, src); - - for (uY = 0; uYsy; uY++) { - for (uX = 0; uXsx; uX++) { - c = f (src, uX, uY); - if (!src->trueColor) { - r = gdImageRed(src,c); - g = gdImageGreen(src,c); - b = gdImageBlue(src,c); - a = gdImageAlpha(src,c); - c = gdTrueColorAlpha(r, g, b, a); - } - - if (ignoretransparent && c == dst->transparent) { - gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent); - } else { - gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c); - } - } - } - dst->alphaBlendingFlag = old_blendmode; - } - - return dst; + int uY, uX; + int c, r, g, b, a; + gdImagePtr dst; + FuncPtr f; + + if (src->trueColor) { + f = gdImageGetTrueColorPixel; + } else { + f = gdImageGetPixel; + } + dst = gdImageCreateTrueColor(src->sy, src->sx); + + if (dst != NULL) { + int old_blendmode = dst->alphaBlendingFlag; + dst->alphaBlendingFlag = 0; + dst->saveAlphaFlag = 1; + dst->transparent = src->transparent; + + gdImagePaletteCopy(dst, src); + + for (uY = 0; uY < src->sy; uY++) { + for (uX = 0; uX < src->sx; uX++) { + c = f(src, uX, uY); + if (!src->trueColor) { + r = gdImageRed(src, c); + g = gdImageGreen(src, c); + b = gdImageBlue(src, c); + a = gdImageAlpha(src, c); + c = gdTrueColorAlpha(r, g, b, a); + } + + if (ignoretransparent && c == dst->transparent) { + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent); + } else { + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c); + } + } + } + dst->alphaBlendingFlag = old_blendmode; + } + + return dst; } diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c index 438a564ff17c..5e4d7da04826 100644 --- a/ext/gd/libgd/gd_security.c +++ b/ext/gd/libgd/gd_security.c @@ -1,32 +1,61 @@ /* - * gd_security.c - * - * Implements buffer overflow check routines. - * - * Written 2004, Phil Knirsch. - * Based on netpbm fixes by Alan Cox. - * + * gd_security.c + * + * Implements buffer overflow check routines. + * + * Written 2004, Phil Knirsch. + * Based on netpbm fixes by Alan Cox. + * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include -#include #include "gd.h" #include "gd_errors.h" +#include +#include +#include +#include int overflow2(int a, int b) { - if(a <= 0 || b <= 0) { - gd_error("One parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n"); - return 1; - } - if(a > INT_MAX / b) { - gd_error("Product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); - return 1; - } - return 0; + if (a <= 0 || b <= 0) { + gd_error_ex(GD_WARNING, "one parameter to a memory allocation multiplication is " + "negative or zero, failing operation gracefully\n"); + return 1; + } + if (a > INT_MAX / b) { + gd_error_ex(GD_WARNING, "Product of memory allocation multiplication would exceed " + "INT_MAX, failing operation gracefully\n"); + return 1; + } + return 0; +} + +int overflowMul3(int a, int b, int c) +{ + if (a < 0 || b < 0 || c < 0) { + return 1; + } + if (a == 0 || b == 0 || c == 0) { + return 0; + } + /* check a*b fits in int first */ + if (a > INT_MAX / b) { + return 1; + } +#ifdef HAVE_INT64_T + /* check a*b*c fits in int64 */ + if ((int64_t)a * b > INT64_MAX / c) { + return 1; + } +#else + /* no 64-bit type available, check against INT_MAX */ + if (a > INT_MAX / b / c) { + return 1; + } +#endif + return 0; } diff --git a/ext/gd/libgd/gd_span_rle.c b/ext/gd/libgd/gd_span_rle.c new file mode 100644 index 000000000000..23b46de4a825 --- /dev/null +++ b/ext/gd/libgd/gd_span_rle.c @@ -0,0 +1,466 @@ +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gd_errors.h" +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "ftraster/gd_ft_math.h" +#include "ftraster/gd_ft_raster.h" +#include "ftraster/gd_ft_stroker.h" +#include "ftraster/gd_ft_types.h" +#include "gd_array.h" +#include "gd_path.h" +#include "gd_path_dash.h" +#include "gd_path_matrix.h" +#include "gd_path_outline.h" +#include "gd_span_rle.h" +#include "gd_surface.h" + +#define SQRT2 1.41421356237309504880 + +gdSpanRlePtr gdSpanRleCreate() +{ + gdSpanRlePtr rle = gdMalloc(sizeof(gdSpanRle)); + if (!rle) + return NULL; + rle->ref = 1; + _rle_spans_init(rle->spans); + rle->x = 0; + rle->y = 0; + rle->w = 0; + rle->h = 0; + return rle; +} + +gdSpanRlePtr gdSpanRleRetain(gdSpanRlePtr rle) +{ + if (rle != NULL) + rle->ref++; + return rle; +} + +void gdSpanRleDestroy(gdSpanRlePtr rle) +{ + if (rle == NULL) + return; + if (--rle->ref > 0) + return; + gdFree(rle->spans.data); + gdFree(rle); +} + +void gdSpanRleClear(gdSpanRlePtr rle) +{ + rle->spans.size = 0; + rle->x = 0; + rle->y = 0; + rle->w = 0; + rle->h = 0; +} + +gdSpanRlePtr gdSpanRleClone(gdSpanRlePtr rle) +{ + if (rle == NULL) + return NULL; + + gdSpanRlePtr clone = gdMalloc(sizeof(gdSpanRle)); + if (!clone) + return NULL; + + clone->ref = 1; + _rle_spans_init(clone->spans); + if (rle->spans.size > 0) { + clone->spans.data = gdMalloc((size_t)rle->spans.size * sizeof(gdSpan)); + if (!clone->spans.data) { + gdFree(clone); + return NULL; + } + clone->spans.capacity = rle->spans.size; + memcpy(clone->spans.data, rle->spans.data, (size_t)rle->spans.size * sizeof(gdSpan)); + } + clone->spans.size = rle->spans.size; + clone->x = rle->x; + clone->y = rle->y; + clone->w = rle->w; + clone->h = rle->h; + return clone; +} + +#define DIV255(x) (((x) + ((x) >> 8) + 0x80) >> 8) +gdSpanRlePtr gdSpanHorizontalClip(const gdSpanRlePtr a, const gdSpanRlePtr b) +{ + gdSpanRlePtr result = gdMalloc(sizeof(gdSpanRle)); + if (!result) { + return NULL; + } + + result->ref = 1; + _rle_spans_init(result->spans); + if (a->spans.size == 0 || b->spans.size == 0) { + result->x = 0; + result->y = 0; + result->w = 0; + result->h = 0; + return result; + } + int capacity = MAX(a->spans.size, b->spans.size); + if (capacity > 0) { + result->spans.data = gdMalloc((size_t)capacity * sizeof(gdSpan)); + if (!result->spans.data) { + gdFree(result); + return NULL; + } + result->spans.capacity = capacity; + } + + gdSpanPtr a_spans = a->spans.data; + gdSpanPtr a_end = a_spans + a->spans.size; + + gdSpanPtr b_spans = b->spans.data; + gdSpanPtr b_end = b_spans + b->spans.size; + + while (a_spans < a_end && b_spans < b_end) { + if (b_spans->y > a_spans->y) { + ++a_spans; + continue; + } + + if (a_spans->y != b_spans->y) { + ++b_spans; + continue; + } + + int ax1 = a_spans->x; + int ax2 = ax1 + a_spans->len; + int bx1 = b_spans->x; + int bx2 = bx1 + b_spans->len; + + if (bx1 < ax1 && bx2 < ax1) { + ++b_spans; + continue; + } + + if (ax1 < bx1 && ax2 < bx1) { + ++a_spans; + continue; + } + + int x = MAX(ax1, bx1); + int len = MIN(ax2, bx2) - x; + if (len) { + gdSpanPtr span = result->spans.data + result->spans.size; + span->x = (short)x; + span->len = (unsigned short)len; + span->y = a_spans->y; + span->coverage = DIV255(a_spans->coverage * b_spans->coverage); + result->spans.size += 1; + } + + if (ax2 < bx2) { + ++a_spans; + } else { + ++b_spans; + } + } + + if (result->spans.size == 0) { + result->x = 0; + result->y = 0; + result->w = 0; + result->h = 0; + return result; + } + + gdSpanPtr spans = (result->spans.data); + int x1 = INT_MAX; + int y1 = spans[0].y; + int x2 = 0; + int y2 = spans[result->spans.size - 1].y; + for (int i = 0; i < result->spans.size; i++) { + if (spans[i].x < x1) + x1 = spans[i].x; + if (spans[i].x + spans[i].len > x2) + x2 = spans[i].x + spans[i].len; + } + + result->x = x1; + result->y = y1; + result->w = x2 - x1; + result->h = y2 - y1 + 1; + return result; +} + +void gdSpanRlePathClip(gdSpanRlePtr rle, const gdSpanRlePtr clip) +{ + if (rle == NULL || clip == NULL) + return; + + gdSpanRlePtr result = gdSpanHorizontalClip(rle, clip); + if (!result) { + return; + } + _rle_spans_allocate(rle->spans, result->spans.size); + if (result->spans.size > 0) { + memcpy(rle->spans.data, result->spans.data, (size_t)result->spans.size * sizeof(gdSpan)); + } + rle->spans.size = result->spans.size; + rle->x = result->x; + rle->y = result->y; + rle->w = result->w; + rle->h = result->h; + gdSpanRleDestroy(result); +} + +GD_FT_Outline *gd_ft_outline_create(int points, int contours) +{ + GD_FT_Outline *ft = gdMalloc(sizeof(GD_FT_Outline)); + if (!ft) + return NULL; + ft->points = malloc((size_t)(points + contours) * sizeof(GD_FT_Vector)); + ft->tags = malloc((size_t)(points + contours) * sizeof(char)); + ft->contours = malloc((size_t)contours * sizeof(short)); + ft->contours_flag = malloc((size_t)contours * sizeof(char)); + ft->n_points = ft->n_contours = 0; + ft->flags = 0x0; + return ft; +} + +void gd_ft_outline_close(GD_FT_Outline *ft) +{ + ft->contours_flag[ft->n_contours] = 0; + int index = ft->n_contours ? ft->contours[ft->n_contours - 1] + 1 : 0; + if (index == ft->n_points) + return; + + ft->points[ft->n_points].x = ft->points[index].x; + ft->points[ft->n_points].y = ft->points[index].y; + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_ON; + ft->n_points++; +} + +void gd_ft_outline_end(GD_FT_Outline *ft) +{ + if (ft->n_points) { + ft->contours[ft->n_contours] = ft->n_points - 1; + ft->n_contours++; + } +} + +#define FT_COORD(x) (GD_FT_Pos)((x) * 64) +void gd_ft_outline_move_to(GD_FT_Outline *ft, double x, double y) +{ + ft->points[ft->n_points].x = FT_COORD(x); + ft->points[ft->n_points].y = FT_COORD(y); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_ON; + if (ft->n_points) { + ft->contours[ft->n_contours] = ft->n_points - 1; + ft->n_contours++; + } + + ft->contours_flag[ft->n_contours] = 1; + ft->n_points++; +} + +void gd_ft_outline_line_to(GD_FT_Outline *ft, double x, double y) +{ + ft->points[ft->n_points].x = FT_COORD(x); + ft->points[ft->n_points].y = FT_COORD(y); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_ON; + ft->n_points++; +} + +void gd_ft_outline_cubic_to(GD_FT_Outline *ft, double x1, double y1, double x2, double y2, + double x3, double y3) +{ + ft->points[ft->n_points].x = FT_COORD(x1); + ft->points[ft->n_points].y = FT_COORD(y1); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_CUBIC; + ft->n_points++; + + ft->points[ft->n_points].x = FT_COORD(x2); + ft->points[ft->n_points].y = FT_COORD(y2); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_CUBIC; + ft->n_points++; + + ft->points[ft->n_points].x = FT_COORD(x3); + ft->points[ft->n_points].y = FT_COORD(y3); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_ON; + ft->n_points++; +} + +void gd_ft_outline_conic_to(GD_FT_Outline *ft, double x1, double y1, double x2, double y2) +{ + ft->points[ft->n_points].x = FT_COORD(x1); + ft->points[ft->n_points].y = FT_COORD(y1); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_CONIC; + ft->n_points++; + + ft->points[ft->n_points].x = FT_COORD(x2); + ft->points[ft->n_points].y = FT_COORD(y2); + ft->tags[ft->n_points] = GD_FT_CURVE_TAG_ON; + ft->n_points++; +} + +GD_FT_Outline *gd_ft_outline_convert(const gdPathPtr path, const gdPathMatrixPtr matrix) +{ + /* A path may begin with LineTo/CurveTo. The outline bridge treats that + prefix as an implicit contour before the first explicit MoveTo. */ + int contour_capacity = path->contours + 1; + GD_FT_Outline *outline = + gd_ft_outline_create(gdArrayNumElements(&path->points), contour_capacity); + gdPointF p[3]; + unsigned int numElements = gdArrayNumElements(&path->elements); + unsigned int pointsIndex = 0; + unsigned int i = 0; + int contour_open = 0; + + memset(p, 0, sizeof(gdPointF) * 3); + if (!outline) + return NULL; + for (i = 0; i < numElements; i++) { + gdPathOpsPtr element = (gdPathOpsPtr)gdArrayIndex(&path->elements, i); + gdPointFPtr point = gdArrayIndex(&path->points, pointsIndex); + switch (*element) { + case gdPathOpsMoveTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + gd_ft_outline_move_to(outline, p[0].x, p[0].y); + contour_open = 1; + pointsIndex += 1; + break; + case gdPathOpsLineTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + if (contour_open) + gd_ft_outline_line_to(outline, p[0].x, p[0].y); + else { + gd_ft_outline_move_to(outline, p[0].x, p[0].y); + contour_open = 1; + } + pointsIndex += 1; + break; + case gdPathOpsCubicTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + point = gdArrayIndex(&path->points, pointsIndex + 2); + gdPathMatrixMapPoint(matrix, point, &p[2]); + if (contour_open) + gd_ft_outline_cubic_to(outline, p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y); + else { + gd_ft_outline_move_to(outline, p[2].x, p[2].y); + contour_open = 1; + } + pointsIndex += 3; + break; + case gdPathOpsClose: + if (contour_open) { + gd_ft_outline_close(outline); + contour_open = 0; + } + pointsIndex += 1; + break; + case gdPathOpsQuadTo: + gdPathMatrixMapPoint(matrix, point, &p[0]); + point = gdArrayIndex(&path->points, pointsIndex + 1); + gdPathMatrixMapPoint(matrix, point, &p[1]); + if (contour_open) + gd_ft_outline_conic_to(outline, p[0].x, p[0].y, p[1].x, p[1].y); + else { + gd_ft_outline_move_to(outline, p[1].x, p[1].y); + contour_open = 1; + } + pointsIndex += 2; + break; + } + } + + gd_ft_outline_end(outline); + return outline; +} + +void gd_ft_outline_destroy(GD_FT_Outline *ft) +{ + gdFree(ft->points); + gdFree(ft->tags); + gdFree(ft->contours); + gdFree(ft->contours_flag); + gdFree(ft); +} + +static void generation_callback(int count, const GD_FT_Span *spans, void *user) +{ + gdSpanRlePtr rle = user; + _rle_spans_allocate(rle->spans, count); + gdSpanPtr data = rle->spans.data + rle->spans.size; + memcpy(data, spans, (size_t)count * sizeof(gdSpan)); + rle->spans.size += count; +} + +static void bbox_callback(int x, int y, int w, int h, void *user) +{ + gdSpanRlePtr rle = user; + rle->x = x; + rle->y = y; + rle->w = w; + rle->h = h; +} + +static void _rasterize_fill(gdSpanRlePtr rle, const gdPathPtr path, const gdPathMatrixPtr matrix, + const gdRectFPtr clip, gdFillRule winding) +{ + static gdPathMatrix identity_matrix = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; + GD_FT_Raster_Params params = {0}; + params.flags = GD_FT_RASTER_FLAG_DIRECT | GD_FT_RASTER_FLAG_AA; + params.gray_spans = generation_callback; + params.bbox_cb = bbox_callback; + params.user = rle; + + if (clip) { + params.flags |= GD_FT_RASTER_FLAG_CLIP; + params.clip_box.xMin = (GD_FT_Pos)clip->x; + params.clip_box.yMin = (GD_FT_Pos)clip->y; + params.clip_box.xMax = (GD_FT_Pos)(clip->x + clip->w); + params.clip_box.yMax = (GD_FT_Pos)(clip->y + clip->h); + } + + gd_ft_raster_render_path(path, matrix ? matrix : &identity_matrix, ¶ms, + winding == gdFillRuleEvenOdd ? GD_FT_OUTLINE_EVEN_ODD_FILL + : GD_FT_OUTLINE_NONE); +} + +void gdSpanRleRasterize(gdSpanRlePtr rle, const gdPathPtr path, const gdPathMatrixPtr matrix, + const gdRectFPtr clip, const gdStrokePtr stroke, gdFillRule winding) +{ + if (stroke && stroke->width > 0) { + gdPathPtr pathToStroke = (gdPathPtr)path; + + // Apply dash pattern to original path BEFORE stroke conversion + if (stroke->dash) { + pathToStroke = gdPathApplyDash(stroke->dash, path); + if (!pathToStroke) + return; + } + + gdPathPtr strokePath = gdPathStrokeToPath(pathToStroke, stroke, matrix); + if (!strokePath) { + if (pathToStroke != path) + gdPathDestroy(pathToStroke); + return; + } + + if (pathToStroke != path) + gdPathDestroy(pathToStroke); + + _rasterize_fill(rle, strokePath, NULL, clip, winding); + gdPathDestroy(strokePath); + } else { + _rasterize_fill(rle, path, matrix, clip, winding); + } +} diff --git a/ext/gd/libgd/gd_span_rle.h b/ext/gd/libgd/gd_span_rle.h new file mode 100644 index 000000000000..99eb94c3f70c --- /dev/null +++ b/ext/gd/libgd/gd_span_rle.h @@ -0,0 +1,35 @@ +#ifndef GD_SPAN_RLE_H +#define GD_SPAN_RLE_H + +#include "gd_vector2d_private.h" + +#define _rle_spans_init(rle_s) \ + do { \ + rle_s.data = NULL; \ + rle_s.size = 0; \ + rle_s.capacity = 0; \ + } while (0) + +#define _rle_spans_allocate(rle_s, count) \ + do { \ + if (rle_s.size + count > rle_s.capacity) { \ + int capacity = rle_s.size + count; \ + int newcapacity = rle_s.capacity == 0 ? 8 : rle_s.capacity; \ + while (newcapacity < capacity) { \ + newcapacity *= 2; \ + } \ + rle_s.data = gdRealloc(rle_s.data, (size_t)newcapacity * sizeof(rle_s.data[0])); \ + rle_s.capacity = newcapacity; \ + } \ + } while (0) + +gdSpanRlePtr gdSpanRleCreate(); +gdSpanRlePtr gdSpanRleRetain(gdSpanRlePtr rle); +void gdSpanRleDestroy(gdSpanRlePtr rle); +void gdSpanRleClear(gdSpanRlePtr rle); +void gdSpanRleRasterize(gdSpanRlePtr rle, const gdPathPtr path, const gdPathMatrixPtr matrix, + const gdRectFPtr clip, const gdStrokePtr stroke, gdFillRule winding); +void gdSpanRlePathClip(gdSpanRlePtr rle, const gdSpanRlePtr clip); +gdSpanRlePtr gdSpanRleClone(gdSpanRlePtr rle); +gdSpanRlePtr gdSpanHorizontalClip(const gdSpanRlePtr a, const gdSpanRlePtr b); +#endif // GD_SPAN_RLE_H diff --git a/ext/gd/libgd/gd_ss.c b/ext/gd/libgd/gd_ss.c index 048ac0a70085..affbaec3e873 100644 --- a/ext/gd/libgd/gd_ss.c +++ b/ext/gd/libgd/gd_ss.c @@ -1,15 +1,16 @@ -#include +#include "gd.h" +#include "gd_errors.h" #include -#include +#include #include -#include "gd.h" +#include #define TRUE 1 #define FALSE 0 /* Exported functions: */ -extern void gdImagePngToSink (gdImagePtr im, gdSinkPtr out); -extern gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource); +extern void gdImagePngToSink(gdImagePtr im, gdSinkPtr out); +extern gdImagePtr gdImageCreateFromPngSource(gdSourcePtr inSource); /* Use this for commenting out debug-print statements. */ /* Just use the first '#define' to allow all the prints... */ @@ -17,33 +18,45 @@ extern gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource); #define GD_SS_DBG(s) #ifdef HAVE_LIBPNG -void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +/* + Function: gdImagePngToSink +*/ +BGD_DECLARE(void) gdImagePngToSink(gdImagePtr im, gdSinkPtr outSink) { - gdIOCtx *out = gdNewSSCtx(NULL, outSink); - gdImagePngCtx(im, out); - out->gd_free(out); + gdIOCtx *out = gdNewSSCtx(NULL, outSink); + gdImagePngCtx(im, out); + out->gd_free(out); } -gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) +/* + Function: gdImageCreateFromPngSource + + See for documentation. This is obsolete; use + instead. + */ +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngSource(gdSourcePtr inSource) { - gdIOCtx *in = gdNewSSCtx(inSource, NULL); - gdImagePtr im; + gdIOCtx *in = gdNewSSCtx(inSource, NULL); + gdImagePtr im; - im = gdImageCreateFromPngCtx(in); + im = gdImageCreateFromPngCtx(in); - in->gd_free(in); + in->gd_free(in); - return im; + return im; } -#else /* no HAVE_LIBPNG */ -void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +#else /* no HAVE_LIBPNG */ +BGD_DECLARE(void) gdImagePngToSink(gdImagePtr im, gdSinkPtr outSink) { - gd_error("PNG support is not available"); + (void)im; + (void)outSink; + gd_error("PNG support is not available\n"); } -gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) + +BGD_DECLARE(gdImagePtr) gdImageCreateFromPngSource(gdSourcePtr inSource) { - gd_error("PNG support is not available"); - return NULL; + (void)inSource; + gd_error("PNG support is not available\n"); + return NULL; } #endif /* HAVE_LIBPNG */ - diff --git a/ext/gd/libgd/gd_surface.c b/ext/gd/libgd/gd_surface.c new file mode 100644 index 000000000000..fe157032aab9 --- /dev/null +++ b/ext/gd/libgd/gd_surface.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd_errors.h" +#include "gd_intern.h" +#include "gd_vector2d_private.h" +#include "gdhelpers.h" + +#include "gd_array.h" +#include "gd_surface.h" + +static int checkOverflowAndType(int width, int height, unsigned type) +{ + int bytes_per_pixel; + if (type == GD_SURFACE_NONE || type >= GD_SURFACE_COUNT || width <= 0 || height <= 0) { + gd_error("gdSurface: invalid dimensions or surface type\n"); + return 1; + } + bytes_per_pixel = type == GD_SURFACE_A8 ? 1 : 4; + if (overflow2(width, bytes_per_pixel) || overflow2(width * bytes_per_pixel, height)) { + return 1; + } + return 0; +} + +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceCreate(int width, int height, unsigned int type) +{ + gdSurfacePtr surface; + + if (type >= GD_SURFACE_COUNT) { + return NULL; + } + if (checkOverflowAndType(width, height, type)) { + return NULL; + } + surface = gdMalloc(sizeof(gdSurface)); + if (!surface) { + return NULL; + } + + const int bytes_per_pixel = type == GD_SURFACE_A8 ? 1 : 4; + const size_t size = (size_t)width * (size_t)height * (size_t)bytes_per_pixel; + surface->data = gdCalloc(1, size); + if (!surface->data) { + gdFree(surface); + return NULL; + } + surface->type = type; + surface->ref = 1; + surface->gdOwned = 1; + surface->width = width; + surface->height = height; + surface->stride = width * bytes_per_pixel; + return surface; +} + +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceCreateForData(unsigned char *data, int width, int height, + int stride, unsigned int type) +{ + gdSurfacePtr surface; + + if (!data) { + return NULL; + } + if (checkOverflowAndType(width, height, type)) { + return NULL; + } + if (stride < width * (type == GD_SURFACE_A8 ? 1 : 4)) { + return NULL; + } + + surface = gdMalloc(sizeof(gdSurface)); + if (!surface) { + return NULL; + } + surface->ref = 1; + surface->gdOwned = 0; + surface->data = data; + surface->width = width; + surface->height = height; + surface->stride = stride; + surface->type = type; + return surface; +} + +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceAddRef(gdSurfacePtr surface) +{ + if (surface == NULL) { + return NULL; + } + surface->ref++; + return surface; +} + +GD_VECTOR2D_INTERNAL unsigned char *gdSurfaceGetData(const gdSurfacePtr surface) +{ + if (surface == NULL) { + return NULL; + } + return surface->data; +} + +GD_VECTOR2D_INTERNAL gdSurfaceType gdSurfaceGetType(const gdSurfacePtr surface) +{ + if (surface == NULL) { + return GD_SURFACE_NONE; + } + return surface->type; +} + +GD_VECTOR2D_INTERNAL int gdSurfaceGetWidth(const gdSurfacePtr surface) { return surface->width; } + +GD_VECTOR2D_INTERNAL int gdSurfaceGetHeight(const gdSurfacePtr surface) { return surface->height; } + +GD_VECTOR2D_INTERNAL int gdSurfaceGetStride(const gdSurfacePtr surface) { return surface->stride; } + +GD_VECTOR2D_INTERNAL void gdSurfaceDestroy(gdSurfacePtr surface) +{ + if (!surface) { + return; + } + if (--surface->ref == 0) { + if (surface->gdOwned) { + gdFree(surface->data); + } + gdFree(surface); + } +} diff --git a/ext/gd/libgd/gd_surface.h b/ext/gd/libgd/gd_surface.h new file mode 100644 index 000000000000..85446d49dccc --- /dev/null +++ b/ext/gd/libgd/gd_surface.h @@ -0,0 +1,6 @@ +#ifndef GD_SURFACE_H +#define GD_SURFACE_H + +#include "gd_vector2d_private.h" + +#endif // GD_SURFACE_H diff --git a/ext/gd/libgd/gd_tga.c b/ext/gd/libgd/gd_tga.c index f888f9ea6fbe..14aefcdeae0b 100644 --- a/ext/gd/libgd/gd_tga.c +++ b/ext/gd/libgd/gd_tga.c @@ -8,356 +8,550 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#include #include +#include #include #include -#include "gd_tga.h" #include "gd.h" #include "gd_errors.h" +#include "gd_io.h" +#include "gd_tga.h" #include "gdhelpers.h" +static int tga_is_rle(uint8_t imagetype); +static int tga_pixel_size(uint8_t bits); +static int tga_read_color_map(gdIOCtx *ctx, oTga *tga); +static int tga_read_pixel(gdIOCtx *ctx, oTga *tga, int *pixel); +static void tga_apply_attribute_type(gdIOCtx *ctx, oTga *tga, int pixel_count); +static int tga_decode_color(const unsigned char *buf, int bits, int alpha_bits, int *has_alpha); +static int tga_decode_16(unsigned int value, int alpha_bits, int *has_alpha); +static int tga_scale_5_to_8(int c); +static int tga_alpha_8_to_gd(int a); +static void tga_strip_alpha(oTga *tga, int pixel_count); + /* - Function: gdImageCreateFromTga + Function: gdImageCreateFromTga - Creates a gdImage from a TGA file + Creates a gdImage from a TGA file - Parameters: + Parameters: - infile - Pointer to TGA binary file + infile - Pointer to TGA binary file */ -gdImagePtr gdImageCreateFromTga(FILE *fp) +BGD_DECLARE(gdImagePtr) gdImageCreateFromTga(FILE *fp) { - gdImagePtr image; - gdIOCtx* in = gdNewFileCtx(fp); - if (in == NULL) return NULL; - image = gdImageCreateFromTgaCtx(in); - in->gd_free( in ); - return image; + gdImagePtr image; + gdIOCtx *in = gdNewFileCtx(fp); + if (in == NULL) + return NULL; + image = gdImageCreateFromTgaCtx(in); + in->gd_free(in); + return image; } /* - Function: gdImageCreateFromTgaPtr + Function: gdImageCreateFromTgaPtr */ -gdImagePtr gdImageCreateFromTgaPtr(int size, void *data) +BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaPtr(int size, void *data) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0); - if (in == NULL) return NULL; - im = gdImageCreateFromTgaCtx(in); - in->gd_free(in); - return im; + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) + return NULL; + im = gdImageCreateFromTgaCtx(in); + in->gd_free(in); + return im; } - /* - Function: gdImageCreateFromTgaCtx + Function: gdImageCreateFromTgaCtx - Creates a gdImage from a gdIOCtx referencing a TGA binary file. + Creates a gdImage from a gdIOCtx referencing a TGA binary file. - Parameters: - ctx - Pointer to a gdIOCtx structure + Parameters: + ctx - Pointer to a gdIOCtx structure */ -gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx* ctx) +BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtx *ctx) { - int bitmap_caret = 0; - oTga *tga = NULL; - /* int pixel_block_size = 0; - int image_block_size = 0; */ - volatile gdImagePtr image = NULL; - int x = 0; - int y = 0; - - tga = (oTga *) gdMalloc(sizeof(oTga)); - if (!tga) { - return NULL; - } - - tga->bitmap = NULL; - tga->ident = NULL; - - if (read_header_tga(ctx, tga) < 0) { - free_tga(tga); - return NULL; - } - - /*TODO: Will this be used? - pixel_block_size = tga->bits / 8; - image_block_size = (tga->width * tga->height) * pixel_block_size; - */ - - if (read_image_tga(ctx, tga) < 0) { - free_tga(tga); - return NULL; - } - - image = gdImageCreateTrueColor((int)tga->width, (int)tga->height ); - - if (image == 0) { - free_tga( tga ); - return NULL; - } - - /*! \brief Populate GD image object - * Copy the pixel data from our tga bitmap buffer into the GD image - * Disable blending and save the alpha channel per default - */ - if (tga->alphabits) { - gdImageAlphaBlending(image, 0); - gdImageSaveAlpha(image, 1); - } - - /* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */ - for (y = 0; y < tga->height; y++) { - register int *tpix = image->tpixels[y]; - for ( x = 0; x < tga->width; x++, tpix++) { - if (tga->bits == TGA_BPP_24) { - *tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]); - bitmap_caret += 3; - } else if (tga->bits == TGA_BPP_32 && tga->alphabits) { - register int a = tga->bitmap[bitmap_caret + 3]; - - *tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1)); - bitmap_caret += 4; - } - } - } - - if (tga->flipv && tga->fliph) { - gdImageFlipBoth(image); - } else if (tga->flipv) { - gdImageFlipVertical(image); - } else if (tga->fliph) { - gdImageFlipHorizontal(image); - } - - free_tga(tga); - - return image; + int bitmap_caret = 0; + oTga *tga = NULL; + volatile gdImagePtr image = NULL; + int x = 0; + int y = 0; + + if (ctx == NULL) { + return NULL; + } + + tga = (oTga *)gdMalloc(sizeof(oTga)); + if (!tga) { + return NULL; + } + + tga->bitmap = NULL; + tga->colormap = NULL; + tga->ident = NULL; + tga->has_alpha = 0; + + if (read_header_tga(ctx, tga) < 0) { + free_tga(tga); + return NULL; + } + + if (read_image_tga(ctx, tga) < 0) { + free_tga(tga); + return NULL; + } + + image = gdImageCreateTrueColor((int)tga->width, (int)tga->height); + + if (image == 0) { + free_tga(tga); + return NULL; + } + + /*! \brief Populate GD image object + * Copy the pixel data from our tga bitmap buffer into the GD image + * Disable blending and save the alpha channel per default + */ + if (tga->has_alpha) { + gdImageAlphaBlending(image, 0); + gdImageSaveAlpha(image, 1); + } + + for (y = 0; y < tga->height; y++) { + register int *tpix = image->tpixels[y]; + for (x = 0; x < tga->width; x++, tpix++) { + *tpix = tga->bitmap[bitmap_caret++]; + } + } + + if (tga->flipv && tga->fliph) { + gdImageFlipBoth(image); + } else if (tga->flipv) { + gdImageFlipVertical(image); + } else if (tga->fliph) { + gdImageFlipHorizontal(image); + } + + free_tga(tga); + + return image; } /*! \brief Reads a TGA header. - * Reads the header block from a binary TGA file populating the referenced TGA structure. - * \param ctx Pointer to TGA binary file - * \param tga Pointer to TGA structure - * \return int 1 on success, -1 on failure + * Reads the header block from a binary TGA file populating the referenced TGA + *structure. \param ctx Pointer to TGA binary file \param tga Pointer to TGA + *structure \return int 1 on sucess, -1 on failure */ int read_header_tga(gdIOCtx *ctx, oTga *tga) { - unsigned char header[18]; - - if (gdGetBuf(header, sizeof(header), ctx) < 18) { - gd_error("Fail to read header"); - return -1; - } - - tga->identsize = header[0]; - tga->colormaptype = header[1]; - tga->imagetype = header[2]; - tga->colormapstart = header[3] + (header[4] << 8); - tga->colormaplength = header[5] + (header[6] << 8); - tga->colormapbits = header[7]; - tga->xstart = header[8] + (header[9] << 8); - tga->ystart = header[10] + (header[11] << 8); - tga->width = header[12] + (header[13] << 8); - tga->height = header[14] + (header[15] << 8); - tga->bits = header[16]; - tga->alphabits = header[17] & 0x0f; - tga->fliph = (header[17] & 0x10) ? 1 : 0; - tga->flipv = (header[17] & 0x20) ? 0 : 1; + unsigned char header[18]; + + if (gdGetBuf(header, sizeof(header), ctx) < 18) { + gd_error("fail to read header"); + return -1; + } + + tga->identsize = header[0]; + tga->colormaptype = header[1]; + tga->imagetype = header[2]; + tga->colormapstart = header[3] + (header[4] << 8); + tga->colormaplength = header[5] + (header[6] << 8); + tga->colormapbits = header[7]; + tga->xstart = header[8] + (header[9] << 8); + tga->ystart = header[10] + (header[11] << 8); + tga->width = header[12] + (header[13] << 8); + tga->height = header[14] + (header[15] << 8); + tga->bits = header[16]; + tga->alphabits = header[17] & 0x0f; + tga->fliph = (header[17] & 0x10) ? 1 : 0; + tga->flipv = (header[17] & 0x20) ? 0 : 1; + tga->has_alpha = 0; #ifdef DEBUG - printf("format bps: %i\n", tga->bits); - printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv); - printf("alpha: %i\n", tga->alphabits); - printf("wxh: %i %i\n", tga->width, tga->height); + printf("format bps: %i\n", tga->bits); + printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv); + printf("alpha: %i\n", tga->alphabits); + printf("wxh: %i %i\n", tga->width, tga->height); #endif - if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0) - || (tga->bits == TGA_BPP_32 && tga->alphabits == 8))) - { - gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n", - tga->bits, tga->alphabits); - return -1; - } - - tga->ident = NULL; - - if (tga->identsize > 0) { - tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char)); - if(tga->ident == NULL) { - return -1; - } - - if (gdGetBuf(tga->ident, tga->identsize, ctx) != tga->identsize) { - gd_error("fail to read header ident"); - return -1; - } - } - - return 1; + if (tga->width <= 0 || tga->height <= 0) { + gd_error("gd-tga: invalid image dimensions\n"); + return -1; + } + + if (tga->colormaptype > 1) { + gd_error_ex(GD_WARNING, "gd-tga: unsupported color map type %u\n", tga->colormaptype); + return -1; + } + + switch (tga->imagetype) { + case TGA_TYPE_INDEXED: + case TGA_TYPE_INDEXED_RLE: + if (tga->colormaptype != 1 || tga->bits != TGA_BPP_8 || + !(tga->colormapbits == 15 || tga->colormapbits == 16 || tga->colormapbits == 24 || + tga->colormapbits == 32)) { + gd_error_ex(GD_WARNING, "gd-tga: unsupported color mapped image\n"); + return -1; + } + break; + + case TGA_TYPE_RGB: + case TGA_TYPE_RGB_RLE: + if (!(tga->bits == TGA_BPP_16 || tga->bits == TGA_BPP_24 || + (tga->bits == TGA_BPP_32 && tga->alphabits == 8))) { + gd_error_ex(GD_WARNING, "gd-tga: unsupported truecolor depth %u\n", tga->bits); + return -1; + } + break; + + case TGA_TYPE_GREYSCALE: + case TGA_TYPE_GREYSCALE_RLE: + if (tga->bits != TGA_BPP_8) { + gd_error_ex(GD_WARNING, "gd-tga: unsupported grayscale depth %u\n", tga->bits); + return -1; + } + break; + + default: + gd_error_ex(GD_WARNING, "gd-tga: unsupported image type %u\n", tga->imagetype); + return -1; + } + + tga->ident = NULL; + + if (tga->identsize > 0) { + tga->ident = (char *)gdMalloc(tga->identsize * sizeof(char)); + if (tga->ident == NULL) { + return -1; + } + + if (gdGetBuf(tga->ident, tga->identsize, ctx) != tga->identsize) { + gd_error("fail to read header ident"); + return -1; + } + } + + return 1; } /*! \brief Reads a TGA image data into buffer. - * Reads the image data block from a binary TGA file populating the referenced TGA structure. - * \param ctx Pointer to TGA binary file - * \param tga Pointer to TGA structure - * \return int 0 on success, -1 on failure + * Reads the image data block from a binary TGA file populating the referenced + *TGA structure. \param ctx Pointer to TGA binary file \param tga Pointer to TGA + *structure \return int 0 on sucess, -1 on failure */ -int read_image_tga( gdIOCtx *ctx, oTga *tga ) +int read_image_tga(gdIOCtx *ctx, oTga *tga) +{ + int pixel_count; + int bitmap_caret = 0; + + if (overflow2(tga->width, tga->height)) { + return -1; + } + + pixel_count = tga->width * tga->height; + if (overflow2(pixel_count, sizeof(int))) { + return -1; + } + + if (tga_read_color_map(ctx, tga) < 0) { + return -1; + } + + /*! \brief Allocate memory for image block + * Allocate a chunk of memory for the image block to be passed into. + */ + tga->bitmap = (int *)gdMalloc(pixel_count * sizeof(int)); + if (tga->bitmap == NULL) + return -1; + + if (tga_is_rle(tga->imagetype)) { + while (bitmap_caret < pixel_count) { + int packet = gdGetC(ctx); + int encoded_pixels; + int pixel; + int i; + + if (packet == EOF) { + gd_error("gd-tga: premature end of image data\n"); + return -1; + } + + encoded_pixels = (packet & ~TGA_RLE_FLAG) + 1; + if (encoded_pixels > pixel_count - bitmap_caret) { + return -1; + } + + if ((packet & TGA_RLE_FLAG) == TGA_RLE_FLAG) { + if (tga_read_pixel(ctx, tga, &pixel) < 0) { + return -1; + } + for (i = 0; i < encoded_pixels; i++) { + tga->bitmap[bitmap_caret++] = pixel; + } + } else { + for (i = 0; i < encoded_pixels; i++) { + if (tga_read_pixel(ctx, tga, &pixel) < 0) { + return -1; + } + tga->bitmap[bitmap_caret++] = pixel; + } + } + } + } else { + while (bitmap_caret < pixel_count) { + if (tga_read_pixel(ctx, tga, &tga->bitmap[bitmap_caret]) < 0) { + return -1; + } + bitmap_caret++; + } + } + + tga_apply_attribute_type(ctx, tga, pixel_count); + + return 1; +} + +static int tga_is_rle(uint8_t imagetype) +{ + return imagetype == TGA_TYPE_INDEXED_RLE || imagetype == TGA_TYPE_RGB_RLE || + imagetype == TGA_TYPE_GREYSCALE_RLE; +} + +static int tga_pixel_size(uint8_t bits) { return (bits + 7) / 8; } + +static int tga_read_color_map(gdIOCtx *ctx, oTga *tga) +{ + int i; + int has_alpha = 0; + int entry_size; + + if (tga->colormaptype == 0) { + return 1; + } + + if (tga->colormaplength <= 0) { + return -1; + } + + if (overflow2(tga->colormaplength, sizeof(int))) { + return -1; + } + + entry_size = tga_pixel_size(tga->colormapbits); + tga->colormap = (int *)gdMalloc(tga->colormaplength * sizeof(int)); + if (tga->colormap == NULL) { + return -1; + } + + for (i = 0; i < tga->colormaplength; i++) { + unsigned char buf[4] = {0, 0, 0, 0}; + + if (gdGetBuf(buf, entry_size, ctx) != entry_size) { + gd_error("gd-tga: premature end of color map data\n"); + return -1; + } + + tga->colormap[i] = + tga_decode_color(buf, tga->colormapbits, tga->colormapbits == 32 ? 8 : 0, &has_alpha); + } + + if (has_alpha) { + tga->has_alpha = 1; + } + + return 1; +} + +static int tga_read_pixel(gdIOCtx *ctx, oTga *tga, int *pixel) +{ + unsigned char buf[4] = {0, 0, 0, 0}; + int size = tga_pixel_size(tga->bits); + int has_alpha = 0; + + if (gdGetBuf(buf, size, ctx) != size) { + gd_error("gd-tga: premature end of image data\n"); + return -1; + } + + switch (tga->imagetype) { + case TGA_TYPE_INDEXED: + case TGA_TYPE_INDEXED_RLE: { + int index = buf[0] - tga->colormapstart; + + if (index < 0 || index >= tga->colormaplength || tga->colormap == NULL) { + return -1; + } + *pixel = tga->colormap[index]; + break; + } + + case TGA_TYPE_RGB: + case TGA_TYPE_RGB_RLE: + *pixel = tga_decode_color(buf, tga->bits, tga->alphabits, &has_alpha); + if (has_alpha) { + tga->has_alpha = 1; + } + break; + + case TGA_TYPE_GREYSCALE: + case TGA_TYPE_GREYSCALE_RLE: + *pixel = gdTrueColor(buf[0], buf[0], buf[0]); + break; + + default: + return -1; + } + + return 1; +} + +static void tga_apply_attribute_type(gdIOCtx *ctx, oTga *tga, int pixel_count) +{ + static const unsigned char signature[18] = {'T', 'R', 'U', 'E', 'V', 'I', 'S', 'I', 'O', + 'N', '-', 'X', 'F', 'I', 'L', 'E', '.', '\0'}; + unsigned char footer_ring[26]; + unsigned char footer[26]; + size_t trailing_size = 0; + size_t i; + int c; + long start; + uint32_t extension_offset; + uint32_t attr_type_offset; + uint32_t end_offset; + int attr_type; + + if (!tga->has_alpha) { + return; + } + + if (ctx->tell == NULL || ctx->seek == NULL) { + return; + } + + start = gdTell(ctx); + if (start < 0 || start > INT_MAX) { + return; + } + + while ((c = gdGetC(ctx)) != EOF) { + footer_ring[trailing_size % sizeof(footer_ring)] = (unsigned char)c; + if (trailing_size == SIZE_MAX) { + return; + } + trailing_size++; + } + + if (trailing_size < sizeof(footer)) { + return; + } + + for (i = 0; i < sizeof(footer); i++) { + footer[i] = footer_ring[(trailing_size + i) % sizeof(footer_ring)]; + } + if (memcmp(footer + 8, signature, sizeof(signature)) != 0) { + return; + } + + extension_offset = (uint32_t)footer[0] | ((uint32_t)footer[1] << 8) | + ((uint32_t)footer[2] << 16) | ((uint32_t)footer[3] << 24); + if (extension_offset == 0 || extension_offset < (uint32_t)start || + extension_offset > (uint32_t)INT_MAX - 494) { + return; + } + + attr_type_offset = extension_offset + 494; + if (trailing_size > (size_t)INT_MAX - (size_t)start || + attr_type_offset >= (uint32_t)start + (uint32_t)trailing_size - sizeof(footer)) { + return; + } + end_offset = (uint32_t)start + (uint32_t)trailing_size; + + if (!gdSeek(ctx, (int)attr_type_offset)) { + return; + } + attr_type = gdGetC(ctx); + gdSeek(ctx, (int)end_offset); + if (attr_type == EOF) { + return; + } + if (attr_type != 3 && attr_type != 4) { + tga_strip_alpha(tga, pixel_count); + } +} + +static int tga_decode_color(const unsigned char *buf, int bits, int alpha_bits, int *has_alpha) +{ + switch (bits) { + case 15: + case 16: + return tga_decode_16((unsigned int)buf[0] | ((unsigned int)buf[1] << 8), alpha_bits, + has_alpha); + + case 24: + return gdTrueColor(buf[2], buf[1], buf[0]); + + case 32: + if (has_alpha) { + *has_alpha = 1; + } + return gdTrueColorAlpha(buf[2], buf[1], buf[0], tga_alpha_8_to_gd(buf[3])); + } + + return 0; +} + +static int tga_decode_16(unsigned int value, int alpha_bits, int *has_alpha) { - int pixel_block_size = (tga->bits / 8); - int image_block_size; - int* decompression_buffer = NULL; - unsigned char* conversion_buffer = NULL; - int buffer_caret = 0; - int bitmap_caret = 0; - int i = 0; - int encoded_pixels; - int rle_size; - - if(overflow2(tga->width, tga->height)) { - return -1; - } - - if(overflow2(tga->width * tga->height, pixel_block_size)) { - return -1; - } - - image_block_size = (tga->width * tga->height) * pixel_block_size; - if(overflow2(image_block_size, sizeof(int))) { - return -1; - } - - /*! \todo Add more image type support. - */ - if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE) - return -1; - - /*! \brief Allocate memmory for image block - * Allocate a chunk of memory for the image block to be passed into. - */ - tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int)); - if (tga->bitmap == NULL) - return -1; - - switch (tga->imagetype) { - case TGA_TYPE_RGB: - /*! \brief Read in uncompressed RGB TGA - * Chunk load the pixel data from an uncompressed RGB type TGA. - */ - conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char)); - if (conversion_buffer == NULL) { - return -1; - } - - if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) { - gd_error("gd-tga: premature end of image data\n"); - gdFree(conversion_buffer); - return -1; - } - - while (buffer_caret < image_block_size) { - tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret]; - buffer_caret++; - } - - gdFree(conversion_buffer); - break; - - case TGA_TYPE_RGB_RLE: - /*! \brief Read in RLE compressed RGB TGA - * Chunk load the pixel data from an RLE compressed RGB type TGA. - */ - decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int)); - if (decompression_buffer == NULL) { - return -1; - } - conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char)); - if (conversion_buffer == NULL) { - gd_error("gd-tga: premature end of image data\n"); - gdFree( decompression_buffer ); - return -1; - } - - rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx); - if (rle_size <= 0) { - gdFree(conversion_buffer); - gdFree(decompression_buffer); - return -1; - } - - buffer_caret = 0; - - while( buffer_caret < rle_size) { - decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret]; - buffer_caret++; - } - - buffer_caret = 0; - - while( bitmap_caret < image_block_size ) { - - if (buffer_caret + pixel_block_size > rle_size) { - gdFree( decompression_buffer ); - gdFree( conversion_buffer ); - return -1; - } - - if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) { - encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 ); - buffer_caret++; - - if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size - || buffer_caret + pixel_block_size > rle_size) { - gdFree( decompression_buffer ); - gdFree( conversion_buffer ); - return -1; - } - - for (i = 0; i < encoded_pixels; i++) { - memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int)); - bitmap_caret += pixel_block_size; - } - buffer_caret += pixel_block_size; - - } else { - encoded_pixels = decompression_buffer[ buffer_caret ] + 1; - buffer_caret++; - - if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size - || buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) { - gdFree( decompression_buffer ); - gdFree( conversion_buffer ); - return -1; - } - - memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int)); - bitmap_caret += (encoded_pixels * pixel_block_size); - buffer_caret += (encoded_pixels * pixel_block_size); - } - } - gdFree( decompression_buffer ); - gdFree( conversion_buffer ); - break; - } - - return 1; + int b = tga_scale_5_to_8(value & 0x1f); + int g = tga_scale_5_to_8((value >> 5) & 0x1f); + int r = tga_scale_5_to_8((value >> 10) & 0x1f); + + if (alpha_bits > 0) { + int a = (value & 0x8000) ? gdAlphaOpaque : gdAlphaTransparent; + + if (has_alpha) { + *has_alpha = 1; + } + return gdTrueColorAlpha(r, g, b, a); + } + + return gdTrueColor(r, g, b); +} + +static int tga_scale_5_to_8(int c) { return (c * 255) / 31; } + +static int tga_alpha_8_to_gd(int a) { return gdAlphaMax - (a >> 1); } + +static void tga_strip_alpha(oTga *tga, int pixel_count) +{ + int i; + + for (i = 0; i < pixel_count; i++) { + int pixel = tga->bitmap[i]; + + tga->bitmap[i] = gdTrueColor(gdTrueColorGetRed(pixel), gdTrueColorGetGreen(pixel), + gdTrueColorGetBlue(pixel)); + } + tga->has_alpha = 0; } /*! \brief Cleans up a TGA structure. - * Dereferences the bitmap referenced in a TGA structure, then the structure itself - * \param tga Pointer to TGA structure + * Dereferences the bitmap referenced in a TGA structure, then the structure + *itself \param tga Pointer to TGA structure */ -void free_tga(oTga * tga) +void free_tga(oTga *tga) { - if (tga) { - if (tga->ident) - gdFree(tga->ident); - if (tga->bitmap) - gdFree(tga->bitmap); - gdFree(tga); - } + if (tga) { + if (tga->ident) + gdFree(tga->ident); + if (tga->bitmap) + gdFree(tga->bitmap); + if (tga->colormap) + gdFree(tga->colormap); + gdFree(tga); + } } diff --git a/ext/gd/libgd/gd_tga.h b/ext/gd/libgd/gd_tga.h index 297f3dc99d6d..539500f07407 100644 --- a/ext/gd/libgd/gd_tga.h +++ b/ext/gd/libgd/gd_tga.h @@ -1,5 +1,5 @@ #ifndef __TGA_H -#define __TGA_H 1 +#define __TGA_H 1 #include "gd.h" #include "gdhelpers.h" @@ -7,46 +7,49 @@ #include "gd_intern.h" typedef struct oTga_ { - uint8_t identsize; // size of ID field that follows 18 uint8_t header (0 usually) - uint8_t colormaptype; // type of colour map 0=none, 1=has palette [IGNORED] Adrian requested no support - uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - int colormapstart; // first colour map entry in palette [IGNORED] Adrian requested no support - int colormaplength; // number of colours in palette [IGNORED] Adrian requested no support - uint8_t colormapbits; // number of bits per palette entry 15,16,24,32 [IGNORED] Adrian requested no support - - int xstart; // image x origin - int ystart; // image y origin - int width; // image width in pixels - int height; // image height in pixels - uint8_t bits; // image bits per pixel 8,16,24,32 - uint8_t alphabits; // alpha bits (low 4bits of header 17) - uint8_t fliph; // horizontal or vertical - uint8_t flipv; // flip - char *ident; // identifcation tag string - int *bitmap; // bitmap data + uint8_t identsize; // size of ID field that follows 18 uint8_t header (0 + // usually) + uint8_t colormaptype; // type of colour map 0=none, 1=has palette + uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + int colormapstart; // first colour map entry in palette + int colormaplength; // number of colours in palette + uint8_t colormapbits; // number of bits per palette entry 15,16,24,32 + + int xstart; // image x origin + int ystart; // image y origin + int width; // image width in pixels + int height; // image height in pixels + uint8_t bits; // image bits per pixel 8,16,24,32 + uint8_t alphabits; // alpha bits (low 4bits of header 17) + uint8_t fliph; // horizontal or vertical + uint8_t flipv; // flip + uint8_t has_alpha; // decoded image contains alpha + char *ident; // identifcation tag string + int *bitmap; // bitmap data + int *colormap; // decoded color map } oTga; -#define TGA_TYPE_NO_IMAGE 0 -#define TGA_TYPE_INDEXED 1 -#define TGA_TYPE_RGB 2 -#define TGA_TYPE_GREYSCALE 3 -#define TGA_TYPE_INDEXED_RLE 9 -#define TGA_TYPE_RGB_RLE 10 -#define TGA_TYPE_GREYSCALE_RLE 11 -#define TGA_TYPE_INDEXED_HUFFMAN_DELTA_RLE 32 -#define TGA_TYPE_RGB_HUFFMAN_DELTA_QUADTREE_RLE 33 - -#define TGA_BPP_8 8 -#define TGA_BPP_16 16 -#define TGA_BPP_24 24 -#define TGA_BPP_32 32 - -#define TGA_RLE_FLAG 128 - -int read_header_tga(gdIOCtx *ctx, oTga *tga); -int read_image_tga(gdIOCtx *ctx, oTga *tga); +#define TGA_TYPE_NO_IMAGE 0 +#define TGA_TYPE_INDEXED 1 +#define TGA_TYPE_RGB 2 +#define TGA_TYPE_GREYSCALE 3 +#define TGA_TYPE_INDEXED_RLE 9 +#define TGA_TYPE_RGB_RLE 10 +#define TGA_TYPE_GREYSCALE_RLE 11 +#define TGA_TYPE_INDEXED_HUFFMAN_DELTA_RLE 32 +#define TGA_TYPE_RGB_HUFFMAN_DELTA_QUADTREE_RLE 33 + +#define TGA_BPP_8 8 +#define TGA_BPP_16 16 +#define TGA_BPP_24 24 +#define TGA_BPP_32 32 + +#define TGA_RLE_FLAG 128 + +int read_header_tga(gdIOCtxPtr ctx, oTga *tga); +int read_image_tga(gdIOCtxPtr ctx, oTga *tga); void free_tga(oTga *tga); #endif //__TGA_H diff --git a/ext/gd/libgd/gd_tiff.c b/ext/gd/libgd/gd_tiff.c new file mode 100644 index 000000000000..3b40b15c5faa --- /dev/null +++ b/ext/gd/libgd/gd_tiff.c @@ -0,0 +1,2422 @@ +/* + TIFF - Tagged Image File Format Encapsulation for GD Library + + gd_tiff.c + Copyright (C) Pierre-A. Joye, M. Retallack + + --------------------------------------------------------------------------- + ** + ** Permission to use, copy, modify, and distribute this software and its + ** documentation for any purpose and without fee is hereby granted, provided + ** that the above copyright notice appear in all copies and that both that + ** copyright notice and this permission notice appear in supporting + ** documentation. This software is provided "as is" without express or + ** implied warranty. + ** + --------------------------------------------------------------------------- + Ctx code written by M. Retallack + + Todo: + + If we fail - cleanup + Writer: Use gd error function, overflow check may not be necessary as + we write our own data (check already done) + + Implement 2 color black/white saving using group4 fax compression + Implement function to specify encoding to use when writing tiff data + + ---------------------------------------------------------------------------- + */ + +/** + * File: TIFF IO + * + * Read and write TIFF images. + * + * Multi-page TIFF reading is supported via the gdTiffRead* API. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd.h" +#include "gd_errors.h" +#include "gd_intern.h" +#include "gdfonts.h" +#include +#include +#include +#include + +#include "gdhelpers.h" + +#ifdef HAVE_LIBTIFF + +#include "tiff.h" +#include "tiffio.h" + +#define GD_SUCCESS 1 +#define GD_FAILURE 0 + +#define TRUE 1 +#define FALSE 0 + +/* I define those here until the new formats + * are commited. We can then rely on the global + * def + */ +#define GD_PALETTE 1 +#define GD_TRUECOLOR 2 +#define GD_GRAY 3 +#define GD_INDEXED 4 +#define GD_RGB 5 + +typedef struct tiff_handle { + int size; + int pos; + gdIOCtx *ctx; + int written; +} tiff_handle; + +/* + Functions for reading, writing and seeking in gdIOCtx + This allows for non-file i/o operations with no + explicit use of libtiff fileio wrapper functions + + Note: because libtiff requires random access, but gdIOCtx + only supports streams, all writes are buffered + into memory and written out on close, also all + reads are done from a memory mapped version of the + tiff (assuming one already exists) +*/ + +static tiff_handle *new_tiff_handle(gdIOCtx *g, int initial_size) +{ + tiff_handle *t; + + if (!g) { + gd_error("Cannot create a new tiff handle, missing Ctx argument"); + return NULL; + } + + t = (tiff_handle *)gdMalloc(sizeof(tiff_handle)); + if (!t) { + gd_error("Failed to allocate a new tiff handle"); + return NULL; + } + + t->size = initial_size; + t->pos = 0; + t->ctx = g; + t->written = 0; + + return t; +} + +/* TIFFReadWriteProc tiff_readproc - Will use gdIOCtx procs to read required + (previously written) TIFF file content */ +static tsize_t tiff_readproc(thandle_t clientdata, tdata_t data, tsize_t size) +{ + tiff_handle *th = (tiff_handle *)clientdata; + gdIOCtx *ctx = th->ctx; + + size = (ctx->getBuf)(ctx, data, size); + if (size > 0) { + th->pos += size; + } + + return size; +} + +/* TIFFReadWriteProc tiff_writeproc - Will use gdIOCtx procs to write out + TIFF data */ +static tsize_t tiff_writeproc(thandle_t clientdata, tdata_t data, tsize_t size) +{ + tiff_handle *th = (tiff_handle *)clientdata; + gdIOCtx *ctx = th->ctx; + + size = (ctx->putBuf)(ctx, data, size); + if (size > 0) { + th->pos += size; + } + if (th->pos > th->size) { + th->size = th->pos; + } + + return size; +} + +/* TIFFSeekProc tiff_seekproc + * used to move around the partially written TIFF */ +static toff_t tiff_seekproc(thandle_t clientdata, toff_t offset, int from) +{ + tiff_handle *th = (tiff_handle *)clientdata; + gdIOCtx *ctx = th->ctx; + int result; + + switch (from) { + default: + case SEEK_SET: + /* just use offset */ + break; + + case SEEK_END: + /* invert offset, so that it is from start, not end as supplied */ + offset = th->size + offset; + break; + + case SEEK_CUR: + /* add current position to translate it to 'from start', + * not from durrent as supplied + */ + offset += th->pos; + break; + } + + /* now, move pos in both io context and buf */ + if ((result = (ctx->seek)(ctx, offset))) { + th->pos = offset; + } + + return result ? offset : (toff_t)-1; +} + +/* TIFFCloseProc tiff_closeproc - used to finally close the TIFF file */ +static int tiff_closeproc(thandle_t clientdata) +{ + (void)clientdata; + /*tiff_handle *th = (tiff_handle *)clientdata; + gdIOCtx *ctx = th->ctx; + + (ctx->gd_free)(ctx);*/ + + return 0; +} + +/* TIFFSizeProc tiff_sizeproc */ +static toff_t tiff_sizeproc(thandle_t clientdata) +{ + tiff_handle *th = (tiff_handle *)clientdata; + return th->size; +} + +/* TIFFMapFileProc tiff_mapproc() */ +static int tiff_mapproc(thandle_t h, tdata_t *d, toff_t *o) +{ + (void)h; + (void)d; + (void)o; + return 0; +} + +/* TIFFUnmapFileProc tiff_unmapproc */ +static void tiff_unmapproc(thandle_t h, tdata_t d, toff_t o) +{ + (void)h; + (void)d; + (void)o; +} + +static int tiff_file_size(FILE *fp) +{ + long current_pos; + long end_pos; + + if (!fp) { + return 0; + } + + current_pos = ftell(fp); + if (current_pos < 0) { + return 0; + } + + if (fseek(fp, 0, SEEK_END) != 0) { + (void)fseek(fp, current_pos, SEEK_SET); + return 0; + } + + end_pos = ftell(fp); + (void)fseek(fp, current_pos, SEEK_SET); + + if (end_pos < 0) { + return 0; + } + + if (end_pos > INT_MAX) { + return INT_MAX; + } + + return (int)end_pos; +} + +static int tiff_ctx_size(gdIOCtx *ctx) +{ + unsigned char buffer[4096]; + long current_pos; + long end_pos; + + if (ctx == NULL || ctx->tell == NULL || ctx->seek == NULL) + return 0; + + current_pos = ctx->tell(ctx); + if (current_pos < 0) + return 0; + + while (ctx->getBuf(ctx, buffer, sizeof(buffer)) > 0) + ; + end_pos = ctx->tell(ctx); + (void)ctx->seek(ctx, (int)current_pos); + + if (end_pos < 0) + return 0; + if (end_pos > INT_MAX) + return INT_MAX; + + return (int)end_pos; +} + +/* tiffWriter + * ---------- + * Write the gd image as a tiff file (called by gdImageTiffCtx) + * Parameters are: + * image: gd image structure; + * out: the stream where to write + * bitDepth: depth in bits of each pixel + */ +static void tiffWriter(gdImagePtr image, gdIOCtx *out, int bitDepth) +{ + int x, y; + int i; + int r, g, b, a; + TIFF *tiff; + int width, height; + int color; + char *scan; + int samplesPerPixel = 3; + int bitsPerSample; + int transparentColorR = -1; + int transparentColorG = -1; + int transparentColorB = -1; + uint16_t extraSamples[1]; + uint16_t *colorMapRed = NULL; + uint16_t *colorMapGreen = NULL; + uint16_t *colorMapBlue = NULL; + size_t colorMapSize; + + tiff_handle *th; + + th = new_tiff_handle(out, 0); + if (!th) { + return; + } + extraSamples[0] = EXTRASAMPLE_ASSOCALPHA; + + /* read in the width/height of gd image */ + width = gdImageSX(image); + height = gdImageSY(image); + + /* reset clip region to whole image */ + gdImageSetClip(image, 0, 0, width, height); + + /* handle old-style single-colour mapping to 100% transparency */ + if (image->transparent != -1) { + /* set our 100% transparent colour value */ + transparentColorR = gdImageRed(image, image->transparent); + transparentColorG = gdImageGreen(image, image->transparent); + transparentColorB = gdImageBlue(image, image->transparent); + } + + /* Open tiff file writing routines, but use special read/write/seek + * functions so that tiff lib writes correct bits of tiff content to + * correct areas of file opened and modifieable by the gdIOCtx functions + */ + tiff = TIFFClientOpen("", "w", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + + TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_ADOBE_DEFLATE); + TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, + (bitDepth == 24) ? PHOTOMETRIC_RGB : PHOTOMETRIC_PALETTE); + + bitsPerSample = (bitDepth == 24 || bitDepth == 8) ? 8 : 1; + TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bitsPerSample); + + TIFFSetField(tiff, TIFFTAG_XRESOLUTION, (float)image->res_x); + TIFFSetField(tiff, TIFFTAG_YRESOLUTION, (float)image->res_y); + + /* build the color map for 8 bit images */ + if (bitDepth != 24) { + if (overflow2(1 << bitsPerSample, sizeof(uint16_t))) { + gdFree(th); + return; + } + colorMapSize = (size_t)(1 << bitsPerSample) * sizeof(uint16_t); + colorMapRed = (uint16_t *)gdMalloc(colorMapSize); + if (!colorMapRed) { + gdFree(th); + return; + } + colorMapGreen = (uint16_t *)gdMalloc(colorMapSize); + if (!colorMapGreen) { + gdFree(colorMapRed); + gdFree(th); + return; + } + colorMapBlue = (uint16_t *)gdMalloc(colorMapSize); + if (!colorMapBlue) { + gdFree(colorMapRed); + gdFree(colorMapGreen); + gdFree(th); + return; + } + + for (i = 0; i < image->colorsTotal; i++) { + colorMapRed[i] = gdImageRed(image, i) + (gdImageRed(image, i) * 256); + colorMapGreen[i] = gdImageGreen(image, i) + (gdImageGreen(image, i) * 256); + colorMapBlue[i] = gdImageBlue(image, i) + (gdImageBlue(image, i) * 256); + } + + TIFFSetField(tiff, TIFFTAG_COLORMAP, colorMapRed, colorMapGreen, colorMapBlue); + samplesPerPixel = 1; + } + + /* here, we check if the 'save alpha' flag is set on the source gd image */ + if ((bitDepth == 24) && (image->saveAlphaFlag || image->transparent != -1)) { + /* so, we need to store the alpha values too! + * Also, tell TIFF what the extra sample means (associated alpha) */ + samplesPerPixel = 4; + TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel); + TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, extraSamples); + } else { + TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel); + } + + TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1); + + if (overflow2(width, samplesPerPixel)) { + if (colorMapRed) + gdFree(colorMapRed); + if (colorMapGreen) + gdFree(colorMapGreen); + if (colorMapBlue) + gdFree(colorMapBlue); + gdFree(th); + return; + } + + if (!(scan = (char *)gdMalloc(width * samplesPerPixel))) { + if (colorMapRed) + gdFree(colorMapRed); + if (colorMapGreen) + gdFree(colorMapGreen); + if (colorMapBlue) + gdFree(colorMapBlue); + gdFree(th); + return; + } + + /* loop through y-coords, and x-coords */ + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + /* generate scan line for writing to tiff */ + color = gdImageGetPixel(image, x, y); + + a = (127 - gdImageAlpha(image, color)) * 2; + a = (a == 0xfe) ? 0xff : a & 0xff; + b = gdImageBlue(image, color); + g = gdImageGreen(image, color); + r = gdImageRed(image, color); + + /* if this pixel has the same RGB as the transparent colour, + * then set alpha fully transparent */ + if (transparentColorR == r && transparentColorG == g && transparentColorB == b) { + a = 0x00; + } + + if (bitDepth != 24) { + /* write out 1 or 8 bit value in 1 byte + * (currently treats 1bit as 8bit) */ + scan[(x * samplesPerPixel) + 0] = color; + } else { + /* write out 24 bit value in 3 (or 4 if transparent) bytes */ + if (image->saveAlphaFlag || image->transparent != -1) { + scan[(x * samplesPerPixel) + 3] = a; + } + + scan[(x * samplesPerPixel) + 2] = b; + scan[(x * samplesPerPixel) + 1] = g; + scan[(x * samplesPerPixel) + 0] = r; + } + } + + /* Write the scan line to the tiff */ + if (TIFFWriteEncodedStrip(tiff, y, scan, width * samplesPerPixel) == -1) { + if (colorMapRed) + gdFree(colorMapRed); + if (colorMapGreen) + gdFree(colorMapGreen); + if (colorMapBlue) + gdFree(colorMapBlue); + gdFree(th); + /* error handler here */ + gd_error("Could not create TIFF\n"); + return; + } + } + + /* now cloase and free up resources */ + TIFFClose(tiff); + gdFree(scan); + gdFree(th); + + if (bitDepth != 24) { + gdFree(colorMapRed); + gdFree(colorMapGreen); + gdFree(colorMapBlue); + } +} + +/* + Function: gdImageTiffCtx + + Write the gd image as a tiff file. + + Parameters: + + image - gd image structure; + out - the stream where to write +*/ +BGD_DECLARE(void) gdImageTiffCtx(gdImagePtr image, gdIOCtx *out) +{ + int clipx1P, clipy1P, clipx2P, clipy2P; + int bitDepth = 24; + + /* First, switch off clipping, or we'll not get all the image! */ + gdImageGetClip(image, &clipx1P, &clipy1P, &clipx2P, &clipy2P); + + /* use the appropriate routine depending on the bit depth of the image */ + if (image->trueColor) { + bitDepth = 24; + } else if (image->colorsTotal == 2) { + bitDepth = 1; + } else { + bitDepth = 8; + } + + tiffWriter(image, out, bitDepth); + + /* reset clipping area to the gd image's original values */ + gdImageSetClip(image, clipx1P, clipy1P, clipx2P, clipy2P); +} + +/* Check if we are really in 8bit mode */ +static int checkColorMap(int n, uint16_t *r, uint16_t *g, uint16_t *b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + return (8); +} + +/* Read and convert a TIFF colormap */ +static int readTiffColorMap(gdImagePtr im, TIFF *tif, char is_bw, int photometric) +{ + uint16_t *redcmap, *greencmap, *bluecmap; + uint16_t bps; + int i; + + if (is_bw) { + if (photometric == PHOTOMETRIC_MINISWHITE) { + gdImageColorAllocate(im, 255, 255, 255); + gdImageColorAllocate(im, 0, 0, 0); + } else { + gdImageColorAllocate(im, 0, 0, 0); + gdImageColorAllocate(im, 255, 255, 255); + } + } else { + uint16_t min_sample_val, max_sample_val; + + if (!TIFFGetField(tif, TIFFTAG_MINSAMPLEVALUE, &min_sample_val)) { + min_sample_val = 0; + } + if (!TIFFGetField(tif, TIFFTAG_MAXSAMPLEVALUE, &max_sample_val)) { + max_sample_val = 255; + } + + if (photometric == PHOTOMETRIC_MINISBLACK || photometric == PHOTOMETRIC_MINISWHITE) { + /* TODO: use TIFFTAG_MINSAMPLEVALUE and TIFFTAG_MAXSAMPLEVALUE */ + /* Gray level palette */ + for (i = min_sample_val; i <= max_sample_val; i++) { + gdImageColorAllocate(im, i, i, i); + } + return GD_SUCCESS; + + } else if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap)) { + gd_error("Cannot read the color map"); + return GD_FAILURE; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps); + +#define CVT(x) (((x) * 255) / ((1L << 16) - 1)) + if (checkColorMap(1 << bps, redcmap, greencmap, bluecmap) == 16) { + for (i = (1 << bps) - 1; i > 0; i--) { + redcmap[i] = CVT(redcmap[i]); + greencmap[i] = CVT(greencmap[i]); + bluecmap[i] = CVT(bluecmap[i]); + } + } + for (i = 0; i < 256; i++) { + gdImageColorAllocate(im, redcmap[i], greencmap[i], bluecmap[i]); + } +#undef CVT + } + return GD_SUCCESS; +} + +static void readTiffBw(const unsigned char *src, gdImagePtr im, uint16_t photometric, int startx, + int starty, int width, int height, char has_alpha, int extra, int align) +{ + int x = startx, y = starty; + + (void)has_alpha; + (void)extra; + (void)align; + + for (y = starty; y < starty + height; y++) { + for (x = startx; x < startx + width;) { + register unsigned char curr = *src++; + register unsigned char mask; + + if (photometric == PHOTOMETRIC_MINISWHITE) { + curr = ~curr; + } + for (mask = 0x80; mask != 0 && x < startx + width; x++, mask >>= 1) { + gdImageSetPixel(im, x, y, ((curr & mask) != 0) ? 0 : 1); + } + } + } +} + +static void readTiff8bit(const unsigned char *src, gdImagePtr im, uint16_t photometric, int startx, + int starty, int width, int height, char has_alpha, int extra, int align) +{ + int red, green, blue, alpha; + int x, y; + + (void)extra; + (void)align; + + switch (photometric) { + case PHOTOMETRIC_PALETTE: + /* Palette has no alpha (see TIFF specs for more details */ + for (y = starty; y < starty + height; y++) { + for (x = startx; x < startx + width; x++) { + gdImageSetPixel(im, x, y, *(src++)); + } + } + break; + + case PHOTOMETRIC_RGB: + if (has_alpha) { + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, 1); + + for (y = starty; y < starty + height; y++) { + for (x = startx; x < startx + width; x++) { + red = *src++; + green = *src++; + blue = *src++; + alpha = *src++; + red = MIN(red, alpha); + blue = MIN(blue, alpha); + green = MIN(green, alpha); + + if (alpha) { + gdImageSetPixel(im, x, y, + gdTrueColorAlpha(red * 255 / alpha, green * 255 / alpha, + blue * 255 / alpha, + gdAlphaMax - (alpha >> 1))); + } else { + gdImageSetPixel( + im, x, y, + gdTrueColorAlpha(red, green, blue, gdAlphaMax - (alpha >> 1))); + } + } + } + + } else { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + register unsigned char r = *src++; + register unsigned char g = *src++; + register unsigned char b = *src++; + + gdImageSetPixel(im, x, y, gdTrueColor(r, g, b)); + } + } + } + break; + + case PHOTOMETRIC_MINISWHITE: + if (has_alpha) { + /* We don't process the extra yet */ + } else { + for (y = starty; y < starty + height; y++) { + for (x = startx; x < startx + width; x++) { + gdImageSetPixel(im, x, y, ~(*src++)); + } + } + } + break; + + case PHOTOMETRIC_MINISBLACK: + if (has_alpha) { + /* We don't process the extra yet */ + } else { + for (y = starty; y < height; y++) { + for (x = 0; x < width; x++) { + gdImageSetPixel(im, x, y, *src++); + } + } + } + break; + } +} + +static int createFromTiffTiles(TIFF *tif, gdImagePtr im, uint16_t bps, uint16_t photometric, + char has_alpha, char is_bw, int extra) +{ + uint16_t planar; + int im_width, im_height; + int tile_width, tile_height; + int x, y, height, width; + unsigned char *buffer; + tmsize_t tile_size; + int success = GD_SUCCESS; + + if (!TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar)) { + planar = PLANARCONFIG_CONTIG; + } + if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &im_width) == 0 || + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &im_height) == 0 || + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) == 0 || + TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height) == 0) { + return FALSE; + } + if (tile_width <= 0 || tile_height <= 0) { + return FALSE; + } + + tile_size = TIFFTileSize(tif); + if (tile_size <= 0) { + return FALSE; + } + buffer = (unsigned char *)gdMalloc((size_t)tile_size); + if (!buffer) { + return FALSE; + } + + for (y = 0; y < im_height; y += tile_height) { + for (x = 0; x < im_width; x += tile_width) { + if (TIFFReadTile(tif, buffer, x, y, 0, 0) < 0) { + success = GD_FAILURE; + goto end; + } + width = MIN(im_width - x, tile_width); + height = MIN(im_height - y, tile_height); + if (bps == 8) { + readTiff8bit(buffer, im, photometric, x, y, width, height, has_alpha, extra, 0); + } else if (is_bw) { + readTiffBw(buffer, im, photometric, x, y, width, height, has_alpha, extra, 0); + } else { + gd_error("TIFF error, unsupported tiled image format in direct " + "reader"); + success = GD_FAILURE; + goto end; + } + } + } +end: + gdFree(buffer); + return success; +} + +static int createFromTiffLines(TIFF *tif, gdImagePtr im, uint16_t bps, uint16_t photometric, + char has_alpha, char is_bw, int extra) +{ + uint16_t planar; + uint32_t im_height, im_width, y; + + unsigned char *buffer; + int success = GD_SUCCESS; + + if (!TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar)) { + planar = PLANARCONFIG_CONTIG; + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &im_height)) { + gd_error("Can't fetch TIFF height\n"); + return FALSE; + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &im_width)) { + gd_error("Can't fetch TIFF width \n"); + return FALSE; + } + + if (im_width > INT_MAX || overflow2((int)im_width, 4)) { + return GD_FAILURE; + } + buffer = (unsigned char *)gdMalloc((size_t)im_width * 4); + if (!buffer) { + return GD_FAILURE; + } + if (planar == PLANARCONFIG_CONTIG) { + switch (bps) { + case 8: + for (y = 0; y < im_height; y++) { + if (TIFFReadScanline(tif, buffer, y, 0) < 0) { + gd_error("Error while reading scanline %i", y); + success = GD_FAILURE; + break; + } + /* reading one line at a time */ + readTiff8bit(buffer, im, photometric, 0, y, im_width, 1, has_alpha, extra, 0); + } + break; + + default: + if (is_bw) { + for (y = 0; y < im_height; y++) { + if (TIFFReadScanline(tif, buffer, y, 0) < 0) { + gd_error("Error while reading scanline %i", y); + success = GD_FAILURE; + break; + } + /* reading one line at a time */ + readTiffBw(buffer, im, photometric, 0, y, im_width, 1, has_alpha, extra, 0); + } + } else { + gd_error("TIFF error, unsupported scanline image format in " + "direct reader"); + success = GD_FAILURE; + } + break; + } + } else { + gd_error("TIFF error, unsupported separate planar image in direct reader"); + success = GD_FAILURE; + } + + gdFree(buffer); + return success; +} + +static int createFromTiffRgba(TIFF *tif, gdImagePtr im) +{ + int a; + int x, y; + int alphaBlendingFlag = 0; + int color; + int width = im->sx; + int height = im->sy; + uint32_t *buffer; + uint32_t rgba; + int success; + + buffer = (uint32_t *)gdCalloc(sizeof(uint32_t), width * height); + if (!buffer) { + return GD_FAILURE; + } + + /* switch off colour merging on target gd image just while we write out + * content - we want to preserve the alpha data until the user chooses + * what to do with the image */ + alphaBlendingFlag = im->alphaBlendingFlag; + gdImageAlphaBlending(im, 0); + + success = TIFFReadRGBAImage(tif, width, height, buffer, 1); + + if (success) { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + /* if it doesn't already exist, allocate a new colour, + * else use existing one */ + rgba = buffer[(y * width + x)]; + a = (0xff - TIFFGetA(rgba)) / 2; + color = gdTrueColorAlpha(TIFFGetR(rgba), TIFFGetG(rgba), TIFFGetB(rgba), a); + + /* set pixel colour to this colour */ + gdImageSetPixel(im, x, height - y - 1, color); + } + } + } + + gdFree(buffer); + + /* now reset colour merge for alpha blending routines */ + gdImageAlphaBlending(im, alphaBlendingFlag); + return success; +} + +/* + Function: gdImageCreateFromTiffCtx + + Create a gdImage from a TIFF file input from an gdIOCtx. +*/ +static gdImagePtr TiffDecodeCurrentDirectory(TIFF *tif) +{ + uint16_t bps, spp, photometric; + uint16_t orientation; + int width, height; + uint16_t extra, *extra_types; + uint16_t planar; + char has_alpha, is_bw, is_gray; + char force_rgba = FALSE; + char save_transparent; + int image_type; + int ret; + float res_float; + + gdImagePtr im = NULL; + + if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width)) { + gd_error("TIFF error, Cannot read image width"); + return NULL; + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)) { + gd_error("TIFF error, Cannot read image height"); + return NULL; + } + + if (width <= 0 || height <= 0) { + gd_error("TIFF error, image dimensions must be greater than 0"); + return NULL; + } + + if (overflow2(width, height)) { + gd_error("TIFF error, image dimensions are too large"); + return NULL; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps); + + if (bps == 0 || bps > 32) { + gd_error("TIFF error, invalid bits per sample: %u", (unsigned)bps); + return NULL; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); + + if (spp == 0 || spp > 4) { + gd_error("TIFF error, invalid samples per pixel: %u", (unsigned)spp); + return NULL; + } + + if (!TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra, &extra_types)) { + extra = 0; + } + + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + uint16_t compression; + if (TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression) && + (compression == COMPRESSION_CCITTFAX3 || compression == COMPRESSION_CCITTFAX4 || + compression == COMPRESSION_CCITTRLE || compression == COMPRESSION_CCITTRLEW)) { + gd_error("Could not get photometric. " + "Image is CCITT compressed, assuming min-is-white"); + photometric = PHOTOMETRIC_MINISWHITE; + } else { + gd_error("Could not get photometric. " + "Assuming min-is-black"); + + photometric = PHOTOMETRIC_MINISBLACK; + } + } + save_transparent = FALSE; + + /* test if the extrasample represents an associated alpha channel... */ + if (extra > 0 && (extra_types[0] == EXTRASAMPLE_ASSOCALPHA)) { + has_alpha = TRUE; + save_transparent = FALSE; + --extra; + } else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNASSALPHA)) { + has_alpha = TRUE; + save_transparent = TRUE; + --extra; + } else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNSPECIFIED)) { + /* assuming unassociated alpha if unspecified */ + gd_error("alpha channel type not defined, assuming alpha is not " + "premultiplied"); + has_alpha = TRUE; + save_transparent = TRUE; + --extra; + } else { + has_alpha = FALSE; + } + + if (photometric == PHOTOMETRIC_RGB && spp > 3 + extra) { + has_alpha = TRUE; + extra = spp - 4; + } else if (photometric != PHOTOMETRIC_RGB && spp > 1 + extra) { + has_alpha = TRUE; + extra = spp - 2; + } + + is_bw = FALSE; + is_gray = FALSE; + + switch (photometric) { + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + if (!has_alpha && bps == 1 && spp == 1) { + image_type = GD_INDEXED; + is_bw = TRUE; + } else { + image_type = GD_GRAY; + } + break; + + case PHOTOMETRIC_RGB: + image_type = GD_RGB; + break; + + case PHOTOMETRIC_PALETTE: + image_type = GD_INDEXED; + break; + + default: + force_rgba = TRUE; + break; + } + + if (!TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar)) { + planar = PLANARCONFIG_CONTIG; + } + + /* The direct scanline/tile readers only implement contiguous 1-bit BW + * images. */ + if (!is_bw || bps != 1 || spp != 1 || has_alpha || planar != PLANARCONFIG_CONTIG) { + force_rgba = TRUE; + } + + /* Force rgba if image planes are not contiguous or the format is otherwise + * unsupported. */ + if (force_rgba) { + image_type = GD_RGB; + } + + if (!force_rgba && + (image_type == GD_PALETTE || image_type == GD_INDEXED || image_type == GD_GRAY)) { + im = gdImageCreate(width, height); + if (!im) + return NULL; + readTiffColorMap(im, tif, is_bw, photometric); + } else { + im = gdImageCreateTrueColor(width, height); + if (!im) + return NULL; + } + +#ifdef DEBUG + printf("force rgba: %i\n", force_rgba); + printf("has_alpha: %i\n", has_alpha); + printf("save trans: %i\n", save_transparent); + printf("is_bw: %i\n", is_bw); + printf("is_gray: %i\n", is_gray); + printf("type: %i\n", image_type); +#else + (void)is_gray; + (void)save_transparent; +#endif + + if (force_rgba) { + ret = createFromTiffRgba(tif, im); + } else if (TIFFIsTiled(tif)) { + ret = createFromTiffTiles(tif, im, bps, photometric, has_alpha, is_bw, extra); + } else { + ret = createFromTiffLines(tif, im, bps, photometric, has_alpha, is_bw, extra); + } + + if (!ret) { + gdImageDestroy(im); + return NULL; + } + + if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &res_float)) { + im->res_x = (unsigned int)res_float; // truncate + } + if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &res_float)) { + im->res_y = (unsigned int)res_float; // truncate + } + + if (TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) { + switch (orientation) { + case ORIENTATION_TOPLEFT: + case ORIENTATION_TOPRIGHT: + case ORIENTATION_BOTRIGHT: + case ORIENTATION_BOTLEFT: + break; + + default: + gd_error("Orientation %d not handled yet!", orientation); + break; + } + } + + return im; +} + +static gdImagePtr gdImageCreateFromTiffCtxEx(gdIOCtx *infile, int initial_size) +{ + TIFF *tif; + tiff_handle *th; + gdImagePtr im = NULL; + + th = new_tiff_handle(infile, initial_size); + if (!th) { + return NULL; + } + + tif = TIFFClientOpen("", "rb", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + + if (!tif) { + gd_error("Cannot open TIFF image"); + gdFree(th); + return NULL; + } + + im = TiffDecodeCurrentDirectory(tif); + + TIFFClose(tif); + gdFree(th); + return im; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffCtx(gdIOCtx *infile) +{ + return gdImageCreateFromTiffCtxEx(infile, tiff_ctx_size(infile)); +} + +/* + Function: gdImageCreateFromTIFF +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiff(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + int initial_size = tiff_file_size(inFile); + + if (in == NULL) + return NULL; + im = gdImageCreateFromTiffCtxEx(in, initial_size); + in->gd_free(in); + return im; +} + +/* + Function: gdImageCreateFromTiffPtr +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) + return NULL; + im = gdImageCreateFromTiffCtxEx(in, size); + in->gd_free(in); + return im; +} + +/* + Function: gdImageTiff +*/ +BGD_DECLARE(void) gdImageTiff(gdImagePtr im, FILE *outFile) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageTiffCtx(im, out); /* what's an fg again? */ + out->gd_free(out); +} + +/* + Function: gdImageTiffPtr +*/ +BGD_DECLARE(void *) gdImageTiffPtr(gdImagePtr im, int *size) +{ + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + gdImageTiffCtx(im, out); /* what's an fg again? */ + rv = gdDPExtractData(out, size); + out->gd_free(out); + return rv; +} + +#define GD_TIFF_ALLOC_STEP (4 * 1024) + +typedef struct gdTiffReadStruct { + uint8_t *data; + size_t size; + TIFF *tif; + tiff_handle *th; + gdIOCtx *memCtx; + int pageCount; + int currentPage; + gdImagePtr image; +} gdTiffRead; + +static uint8_t *TiffReadCtxData(gdIOCtx *infile, size_t *size) +{ + uint8_t *filedata = NULL, *temp, *read; + ssize_t n; + + *size = 0; + do { + temp = gdRealloc(filedata, *size + GD_TIFF_ALLOC_STEP); + if (temp == NULL) { + gdFree(filedata); + gd_error("TIFF decode: realloc failed"); + return NULL; + } + filedata = temp; + read = temp + *size; + n = gdGetBuf(read, GD_TIFF_ALLOC_STEP, infile); + if (n > 0 && n != EOF) { + *size += n; + } + } while (n > 0 && n != EOF); + + if (*size == 0) { + gdFree(filedata); + return NULL; + } + + return filedata; +} + +static void TiffFillInfo(TIFF *tif, gdTiffInfo *info, int pageCount) +{ + uint16_t bps, spp, photometric, compression; + float res_float; + uint16_t resUnit; + + if (info == NULL || tif == NULL) { + return; + } + memset(info, 0, sizeof(*info)); + info->pageCount = pageCount; + + TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGEWIDTH, (uint32_t *)&info->width); + TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGELENGTH, (uint32_t *)&info->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps); + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); + info->bitsPerSample = bps; + info->samplesPerPixel = spp; + + if (TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) { + info->compression = compression; + } + if (TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + info->photometric = photometric; + } + if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &res_float)) { + info->xResolution = res_float; + } + if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &res_float)) { + info->yResolution = res_float; + } + if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resUnit)) { + info->resolutionUnit = resUnit; + } else { + info->resolutionUnit = 2; + } +} + +static void TiffFillPageInfo(TIFF *tif, gdTiffPageInfo *info, int pageIndex) +{ + uint16_t bps, spp, photometric, compression, planar; + uint16_t extra, *extra_types; + uint16_t resUnit; + float res_float; + + if (info == NULL || tif == NULL) { + return; + } + memset(info, 0, sizeof(*info)); + info->pageIndex = pageIndex; + + TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGEWIDTH, (uint32_t *)&info->width); + TIFFGetFieldDefaulted(tif, TIFFTAG_IMAGELENGTH, (uint32_t *)&info->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps); + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); + info->bitsPerSample = bps; + info->samplesPerPixel = spp; + info->isTiled = TIFFIsTiled(tif); + + if (TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) { + info->compression = compression; + } + if (TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + info->photometric = photometric; + } + if (TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar)) { + info->planar = planar; + } else { + info->planar = PLANARCONFIG_CONTIG; + } + + if (!TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra, &extra_types)) { + extra = 0; + } + info->hasAlpha = (extra > 0); + + if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &res_float)) { + info->xResolution = res_float; + } + if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &res_float)) { + info->yResolution = res_float; + } + if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resUnit)) { + info->resolutionUnit = resUnit; + } else { + info->resolutionUnit = 2; + } +} + +static gdTiffReadPtr TiffReadOpenFromData(uint8_t *data, size_t size) +{ + gdTiffReadPtr tiff; + gdIOCtx *memCtx; + tiff_handle *th; + TIFF *tif; + + tiff = (gdTiffReadPtr)gdCalloc(1, sizeof(gdTiffRead)); + if (tiff == NULL) { + return NULL; + } + + tiff->data = data; + tiff->size = size; + + memCtx = gdNewDynamicCtxEx((int)size, data, 0); + if (memCtx == NULL) { + gdFree(tiff); + return NULL; + } + tiff->memCtx = memCtx; + + th = new_tiff_handle(memCtx, (int)size); + if (th == NULL) { + memCtx->gd_free(memCtx); + gdFree(tiff); + return NULL; + } + tiff->th = th; + + tif = TIFFClientOpen("", "rb", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + if (tif == NULL) { + gdFree(th); + memCtx->gd_free(memCtx); + gdFree(tiff); + return NULL; + } + tiff->tif = tif; + + tiff->pageCount = (int)TIFFNumberOfDirectories(tif); + if (tiff->pageCount <= 0) { + gd_error("TIFF error, invalid page count: %d", tiff->pageCount); + TIFFClose(tif); + tiff->tif = NULL; + gdFree(th); + tiff->th = NULL; + memCtx->gd_free(memCtx); + tiff->memCtx = NULL; + gdFree(tiff); + return NULL; + } + tiff->currentPage = -1; + tiff->image = NULL; + + return tiff; +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpen(FILE *fd) +{ + gdIOCtx *in; + gdTiffReadPtr tiff; + uint8_t *data; + size_t size; + + if (fd == NULL) { + return NULL; + } + in = gdNewFileCtx(fd); + if (in == NULL) { + return NULL; + } + data = TiffReadCtxData(in, &size); + in->gd_free(in); + if (data == NULL) { + return NULL; + } + tiff = TiffReadOpenFromData(data, size); + if (tiff == NULL) { + gdFree(data); + } + return tiff; +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenCtx(gdIOCtxPtr in) +{ + uint8_t *data; + size_t size; + + if (in == NULL) { + return NULL; + } + data = TiffReadCtxData(in, &size); + if (data == NULL) { + return NULL; + } + return TiffReadOpenFromData(data, size); +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenPtr(int size, void *data) +{ + uint8_t *buf; + + if (size <= 0 || data == NULL) { + return NULL; + } + buf = (uint8_t *)gdMalloc((size_t)size); + if (buf == NULL) { + return NULL; + } + memcpy(buf, data, (size_t)size); + return TiffReadOpenFromData(buf, (size_t)size); +} + +BGD_DECLARE(void) gdTiffReadClose(gdTiffReadPtr tiff) +{ + if (tiff == NULL) { + return; + } + if (tiff->image != NULL) { + gdImageDestroy(tiff->image); + } + if (tiff->tif != NULL) { + TIFFClose(tiff->tif); + } + if (tiff->th != NULL) { + gdFree(tiff->th); + } + if (tiff->memCtx != NULL) { + tiff->memCtx->gd_free(tiff->memCtx); + } + if (tiff->data != NULL) { + gdFree(tiff->data); + } + gdFree(tiff); +} + +BGD_DECLARE(int) gdTiffReadGetInfo(gdTiffReadPtr tiff, gdTiffInfo *info) +{ + tdir_t savedDir; + + if (tiff == NULL || info == NULL || tiff->tif == NULL) { + return 0; + } + savedDir = TIFFCurrentDirectory(tiff->tif); + TIFFSetDirectory(tiff->tif, 0); + TiffFillInfo(tiff->tif, info, tiff->pageCount); + TIFFSetDirectory(tiff->tif, savedDir); + return 1; +} + +BGD_DECLARE(int) +gdTiffReadNextImage(gdTiffReadPtr tiff, gdTiffPageInfo *info, gdImagePtr *image) +{ + int ok; + + if (image != NULL) { + *image = NULL; + } + if (tiff == NULL || tiff->tif == NULL || tiff->pageCount <= 0) { + return -1; + } + + if (tiff->currentPage >= tiff->pageCount - 1 && tiff->currentPage >= 0) { + return 0; + } + + if (tiff->currentPage < 0) { + if (!TIFFSetDirectory(tiff->tif, 0)) { + return 0; + } + tiff->currentPage = 0; + } else { + if (!TIFFReadDirectory(tiff->tif)) { + return 0; + } + tiff->currentPage++; + } + + TiffFillPageInfo(tiff->tif, info, tiff->currentPage); + + if (tiff->image != NULL) { + gdImageDestroy(tiff->image); + tiff->image = NULL; + } + + tiff->image = TiffDecodeCurrentDirectory(tiff->tif); + if (tiff->image == NULL) { + ok = TIFFSetDirectory(tiff->tif, TIFFCurrentDirectory(tiff->tif)); + (void)ok; + return -1; + } + + if (image != NULL) { + *image = tiff->image; + } + return 1; +} + +BGD_DECLARE(gdImagePtr) gdTiffReadCloneImage(gdTiffReadPtr tiff) +{ + gdImagePtr dst; + int x, y; + + if (tiff == NULL || tiff->image == NULL) { + return NULL; + } + dst = gdImageCreateTrueColor(gdImageSX(tiff->image), gdImageSY(tiff->image)); + if (dst == NULL) { + return NULL; + } + gdImageAlphaBlending(dst, 0); + gdImageSaveAlpha(dst, tiff->image->saveAlphaFlag); + for (y = 0; y < gdImageSY(tiff->image); y++) { + for (x = 0; x < gdImageSX(tiff->image); x++) { + dst->tpixels[y][x] = gdImageGetPixel(tiff->image, x, y); + } + } + return dst; +} + +BGD_DECLARE(int) gdTiffIsMultiPage(FILE *fd) +{ + gdIOCtx *in; + uint8_t *data; + size_t size; + gdIOCtx *memCtx; + tiff_handle *th; + TIFF *tif; + tdir_t dirCount; + int pos; + + if (fd == NULL) { + return -1; + } + in = gdNewFileCtx(fd); + if (in == NULL) { + return -1; + } + pos = (int)gdTell(in); + if (pos < 0) { + in->gd_free(in); + return -1; + } + data = TiffReadCtxData(in, &size); + if (data == NULL) { + in->gd_free(in); + return -1; + } + memCtx = gdNewDynamicCtxEx((int)size, data, 0); + if (memCtx == NULL) { + gdFree(data); + in->gd_free(in); + return -1; + } + th = new_tiff_handle(memCtx, (int)size); + if (th == NULL) { + memCtx->gd_free(memCtx); + gdFree(data); + in->gd_free(in); + return -1; + } + tif = TIFFClientOpen("", "rb", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + if (tif == NULL) { + gdFree(th); + memCtx->gd_free(memCtx); + gdFree(data); + in->gd_free(in); + return -1; + } + dirCount = TIFFNumberOfDirectories(tif); + TIFFClose(tif); + gdFree(th); + memCtx->gd_free(memCtx); + gdFree(data); + if (!gdSeek(in, pos)) { + in->gd_free(in); + return -1; + } + in->gd_free(in); + return dirCount > 1 ? 1 : 0; +} + +BGD_DECLARE(int) gdTiffIsMultiPageCtx(gdIOCtxPtr in) +{ + uint8_t *data; + size_t size; + gdIOCtx *memCtx; + tiff_handle *th; + TIFF *tif; + tdir_t dirCount; + int pos; + + if (in == NULL || in->tell == NULL || in->seek == NULL) { + return -1; + } + pos = (int)gdTell(in); + if (pos < 0) { + return -1; + } + data = TiffReadCtxData(in, &size); + if (data == NULL) { + return -1; + } + memCtx = gdNewDynamicCtxEx((int)size, data, 0); + if (memCtx == NULL) { + gdFree(data); + return -1; + } + th = new_tiff_handle(memCtx, (int)size); + if (th == NULL) { + memCtx->gd_free(memCtx); + gdFree(data); + return -1; + } + tif = TIFFClientOpen("", "rb", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + if (tif == NULL) { + gdFree(th); + memCtx->gd_free(memCtx); + gdFree(data); + return -1; + } + dirCount = TIFFNumberOfDirectories(tif); + TIFFClose(tif); + gdFree(th); + memCtx->gd_free(memCtx); + gdFree(data); + if (!gdSeek(in, pos)) { + return -1; + } + return dirCount > 1 ? 1 : 0; +} + +BGD_DECLARE(int) gdTiffIsMultiPagePtr(int size, void *data) +{ + gdIOCtx *in; + int result; + + if (size <= 0 || data == NULL) { + return -1; + } + in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) { + return -1; + } + result = gdTiffIsMultiPageCtx(in); + in->gd_free(in); + return result; +} + +/* ========== TIFF Write API ========== */ + +struct gdTiffWriteStruct { + gdIOCtx *out; + int ownsCtx; + int memoryWriter; + TIFF *tif; + tiff_handle *th; + gdTiffWriteOptions options; + int pageCount; + int finalized; +}; + +static int TiffWriteValidateOptions(const gdTiffWriteOptions *opts) +{ + if (opts == NULL) { + gd_error("gd-tiff write: options is NULL"); + return 0; + } + switch (opts->colorspace) { + case GD_TIFF_RGB: + case GD_TIFF_RGBA: + case GD_TIFF_GRAY: + case GD_TIFF_BILEVEL: + break; + default: + gd_error("gd-tiff write: invalid colorspace %d", opts->colorspace); + return 0; + } + switch (opts->bitDepth) { + case 1: + case 8: + case 16: + break; + default: + gd_error("gd-tiff write: invalid bit depth %d", opts->bitDepth); + return 0; + } + if (opts->bitDepth == 1 && opts->colorspace != GD_TIFF_BILEVEL) { + gd_error("gd-tiff write: 1-bit depth requires GD_TIFF_BILEVEL colorspace"); + return 0; + } + if (opts->colorspace == GD_TIFF_BILEVEL && opts->bitDepth != 1) { + gd_error("gd-tiff write: GD_TIFF_BILEVEL requires 1-bit depth"); + return 0; + } + switch (opts->compression) { + case COMPRESSION_NONE: + break; + case COMPRESSION_LZW: + case COMPRESSION_ADOBE_DEFLATE: + case COMPRESSION_DEFLATE: + case COMPRESSION_PACKBITS: + if (opts->bitDepth == 1 && opts->colorspace != GD_TIFF_BILEVEL) { + gd_error("gd-tiff write: LZW/Deflate/PackBits at 1-bit requires " + "BILEVEL"); + return 0; + } + break; + case COMPRESSION_JPEG: + if (opts->bitDepth != 8) { + gd_error("gd-tiff write: JPEG compression requires 8-bit depth"); + return 0; + } + break; + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + if (opts->bitDepth != 1) { + gd_error("gd-tiff write: CCITT compression requires 1-bit depth"); + return 0; + } + break; + default: + gd_error("gd-tiff write: unsupported compression %d", opts->compression); + return 0; + } + if (opts->colorspace == GD_TIFF_RGB && opts->bitDepth == 1) { + gd_error("gd-tiff write: RGB at 1-bit is not valid"); + return 0; + } + if (opts->colorspace == GD_TIFF_RGBA && opts->bitDepth == 1) { + gd_error("gd-tiff write: RGBA at 1-bit is not valid"); + return 0; + } + return 1; +} + +static void TiffWriteSetDefaults(gdTiffWriteOptions *opts) +{ + if (opts->bitDepth == 0) + opts->bitDepth = 8; + if (opts->colorspace == 0) + opts->colorspace = GD_TIFF_RGBA; + if (opts->compression == 0) + opts->compression = COMPRESSION_ADOBE_DEFLATE; + if (opts->jpegQuality == 0 && opts->compression == COMPRESSION_JPEG) + opts->jpegQuality = 75; + if (opts->resolutionUnit == 0) + opts->resolutionUnit = GD_TIFF_RESUNIT_INCH; + if (opts->xResolution == 0) + opts->xResolution = 72.0f; + if (opts->yResolution == 0) + opts->yResolution = 72.0f; + if (opts->alphaType == 0) + opts->alphaType = GD_TIFF_ALPHA_UNASSOCIATED; +} + +static int TiffWriteSamplesPerPixel(const gdTiffWriteOptions *opts) +{ + switch (opts->colorspace) { + case GD_TIFF_RGBA: + return 4; + case GD_TIFF_RGB: + return 3; + case GD_TIFF_GRAY: + case GD_TIFF_BILEVEL: + return 1; + default: + return 3; + } +} + +static int TiffWritePhotometric(const gdTiffWriteOptions *opts) +{ + switch (opts->colorspace) { + case GD_TIFF_RGB: + case GD_TIFF_RGBA: + return PHOTOMETRIC_RGB; + case GD_TIFF_GRAY: + return opts->minIsWhite ? PHOTOMETRIC_MINISWHITE : PHOTOMETRIC_MINISBLACK; + case GD_TIFF_BILEVEL: + return opts->minIsWhite ? PHOTOMETRIC_MINISWHITE : PHOTOMETRIC_MINISBLACK; + default: + return PHOTOMETRIC_RGB; + } +} + +static int TiffWriteBitsPerSample(const gdTiffWriteOptions *opts) +{ + if (opts->colorspace == GD_TIFF_BILEVEL) + return 1; + return opts->bitDepth; +} + +static void TiffWriteConvertRowRGBA8(gdImagePtr im, int y, uint8_t *buf, int width) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int a = gdImageAlpha(im, c); + a = (127 - a) * 2; + if (a > 255) + a = 255; + if (a == 254) + a = 255; + buf[x * 4 + 0] = (uint8_t)r; + buf[x * 4 + 1] = (uint8_t)g; + buf[x * 4 + 2] = (uint8_t)b; + buf[x * 4 + 3] = (uint8_t)a; + } +} + +static void TiffWriteConvertRowRGB8(gdImagePtr im, int y, uint8_t *buf, int width) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int a = gdImageAlpha(im, c); + a = (127 - a) * 2; + if (a > 255) + a = 255; + if (a == 254) + a = 255; + if (a < 255) { + int af = a + 1; + r = (r * af + 127) / 255; + g = (g * af + 127) / 255; + b = (b * af + 127) / 255; + } + buf[x * 3 + 0] = (uint8_t)r; + buf[x * 3 + 1] = (uint8_t)g; + buf[x * 3 + 2] = (uint8_t)b; + } +} + +static void TiffWriteConvertRowGray8(gdImagePtr im, int y, uint8_t *buf, int width, int minIsWhite) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int gray = (int)(0.2126f * r + 0.7152f * g + 0.0722f * b + 0.5f); + if (gray > 255) + gray = 255; + if (minIsWhite) + gray = 255 - gray; + buf[x] = (uint8_t)gray; + } +} + +static void TiffWriteConvertRowBilevel(gdImagePtr im, int y, uint8_t *buf, int width, + int minIsWhite) +{ + int x; + memset(buf, 0, (width + 7) / 8); + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int gray = (int)(0.2126f * r + 0.7152f * g + 0.0722f * b + 0.5f); + int bit; + if (minIsWhite) + bit = (gray < 128) ? 1 : 0; + else + bit = (gray >= 128) ? 1 : 0; + if (bit) + buf[x / 8] |= (uint8_t)(0x80 >> (x & 7)); + } +} + +static void TiffWriteConvertRowRGBA16(gdImagePtr im, int y, uint16_t *buf, int width) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int a = gdImageAlpha(im, c); + a = (127 - a) * 2; + if (a > 255) + a = 255; + if (a == 254) + a = 255; + buf[x * 4 + 0] = (uint16_t)(r * 257); + buf[x * 4 + 1] = (uint16_t)(g * 257); + buf[x * 4 + 2] = (uint16_t)(b * 257); + buf[x * 4 + 3] = (uint16_t)(a * 257); + } +} + +static void TiffWriteConvertRowRGB16(gdImagePtr im, int y, uint16_t *buf, int width) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int a = gdImageAlpha(im, c); + a = (127 - a) * 2; + if (a > 255) + a = 255; + if (a == 254) + a = 255; + if (a < 255) { + int af = a + 1; + r = (r * af + 127) / 255; + g = (g * af + 127) / 255; + b = (b * af + 127) / 255; + } + buf[x * 3 + 0] = (uint16_t)(r * 257); + buf[x * 3 + 1] = (uint16_t)(g * 257); + buf[x * 3 + 2] = (uint16_t)(b * 257); + } +} + +static void TiffWriteConvertRowGray16(gdImagePtr im, int y, uint16_t *buf, int width, + int minIsWhite) +{ + int x; + for (x = 0; x < width; x++) { + int c = im->tpixels[y][x]; + int r = gdImageRed(im, c); + int g = gdImageGreen(im, c); + int b = gdImageBlue(im, c); + int gray = (int)(0.2126f * r + 0.7152f * g + 0.0722f * b + 0.5f); + if (gray > 255) + gray = 255; + if (minIsWhite) + gray = 255 - gray; + buf[x] = (uint16_t)(gray * 257); + } +} + +static int TiffWriteWritePage(gdTiffWritePtr write, gdImagePtr im) +{ + TIFF *tif = write->tif; + gdTiffWriteOptions *opts = &write->options; + int width, height; + int nsamples, bps, photometric; + int y; + uint8_t *scanbuf = NULL; + + width = gdImageSX(im); + height = gdImageSY(im); + nsamples = TiffWriteSamplesPerPixel(opts); + bps = TiffWriteBitsPerSample(opts); + photometric = TiffWritePhotometric(opts); + + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, nsamples); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(tif, TIFFTAG_COMPRESSION, opts->compression); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0)); + + if (opts->colorspace == GD_TIFF_RGBA) { + uint16_t extra = (opts->alphaType == GD_TIFF_ALPHA_ASSOCIATED) ? EXTRASAMPLE_ASSOCALPHA + : EXTRASAMPLE_UNASSALPHA; + TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, &extra); + } + + if (opts->compression == COMPRESSION_LZW || opts->compression == COMPRESSION_ADOBE_DEFLATE || + opts->compression == COMPRESSION_DEFLATE) { + TIFFSetField(tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL); + } + + if (opts->compression == COMPRESSION_JPEG && opts->jpegQuality > 0) { + TIFFSetField(tif, TIFFTAG_JPEGQUALITY, opts->jpegQuality); + } + + if (opts->colorspace == GD_TIFF_BILEVEL && (opts->compression == COMPRESSION_CCITTFAX3 || + opts->compression == COMPRESSION_CCITTFAX4)) { + uint32_t g3opts = 0; + if (opts->compression == COMPRESSION_CCITTFAX3) { + TIFFSetField(tif, TIFFTAG_GROUP3OPTIONS, g3opts); + } + if (opts->compression == COMPRESSION_CCITTFAX4) { + TIFFSetField(tif, TIFFTAG_GROUP4OPTIONS, 0); + } + TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); + } + + { + uint16_t resUnit; + switch (opts->resolutionUnit) { + case GD_TIFF_RESUNIT_NONE: + resUnit = RESUNIT_NONE; + break; + case GD_TIFF_RESUNIT_INCH: + resUnit = RESUNIT_INCH; + break; + case GD_TIFF_RESUNIT_CENTIMETER: + resUnit = RESUNIT_CENTIMETER; + break; + default: + resUnit = RESUNIT_INCH; + break; + } + TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, resUnit); + TIFFSetField(tif, TIFFTAG_XRESOLUTION, opts->xResolution); + TIFFSetField(tif, TIFFTAG_YRESOLUTION, opts->yResolution); + } + + if (opts->colorspace == GD_TIFF_BILEVEL) { + size_t scanline_size = (size_t)((width + 7) / 8); + if (opts->compression == COMPRESSION_CCITTFAX3 || + opts->compression == COMPRESSION_CCITTFAX4) { + scanline_size = (size_t)TIFFScanlineSize(tif); + if (scanline_size == 0) + scanline_size = (size_t)((width + 7) / 8); + } + scanbuf = (uint8_t *)gdMalloc(scanline_size); + if (scanbuf == NULL) { + gd_error("gd-tiff write: could not allocate scanline buffer"); + return 0; + } + for (y = 0; y < height; y++) { + TiffWriteConvertRowBilevel(im, y, scanbuf, width, opts->minIsWhite); + if (TIFFWriteScanline(tif, scanbuf, y, 0) < 0) { + gdFree(scanbuf); + gd_error("gd-tiff write: could not write scanline"); + return 0; + } + } + } else if (opts->bitDepth == 16) { + size_t scanline_size = (size_t)TIFFScanlineSize(tif); + scanbuf = (uint8_t *)gdMalloc(scanline_size); + if (scanbuf == NULL) { + gd_error("gd-tiff write: could not allocate scanline buffer"); + return 0; + } + for (y = 0; y < height; y++) { + uint16_t *buf16 = (uint16_t *)scanbuf; + switch (opts->colorspace) { + case GD_TIFF_RGBA: + TiffWriteConvertRowRGBA16(im, y, buf16, width); + break; + case GD_TIFF_RGB: + TiffWriteConvertRowRGB16(im, y, buf16, width); + break; + case GD_TIFF_GRAY: + TiffWriteConvertRowGray16(im, y, buf16, width, opts->minIsWhite); + break; + default: + break; + } + if (TIFFWriteScanline(tif, scanbuf, y, 0) < 0) { + gdFree(scanbuf); + gd_error("gd-tiff write: could not write scanline"); + return 0; + } + } + } else { + size_t scanline_size = (size_t)TIFFScanlineSize(tif); + scanbuf = (uint8_t *)gdMalloc(scanline_size); + if (scanbuf == NULL) { + gd_error("gd-tiff write: could not allocate scanline buffer"); + return 0; + } + for (y = 0; y < height; y++) { + switch (opts->colorspace) { + case GD_TIFF_RGBA: + TiffWriteConvertRowRGBA8(im, y, scanbuf, width); + break; + case GD_TIFF_RGB: + TiffWriteConvertRowRGB8(im, y, scanbuf, width); + break; + case GD_TIFF_GRAY: + TiffWriteConvertRowGray8(im, y, scanbuf, width, opts->minIsWhite); + break; + default: + break; + } + if (TIFFWriteScanline(tif, scanbuf, y, 0) < 0) { + gdFree(scanbuf); + gd_error("gd-tiff write: could not write scanline"); + return 0; + } + } + } + + gdFree(scanbuf); + + if (!TIFFWriteDirectory(tif)) { + gd_error("gd-tiff write: could not write directory for page %d", write->pageCount); + return 0; + } + + write->pageCount++; + return 1; +} + +static void TiffWriteFree(gdTiffWritePtr write) +{ + if (write == NULL) + return; + if (write->tif) { + TIFFClose(write->tif); + write->tif = NULL; + } + if (write->th) { + gdFree(write->th); + write->th = NULL; + } + if (write->ownsCtx && write->out) { + write->out->gd_free(write->out); + write->out = NULL; + } + gdFree(write); +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpen(FILE *outFile, const gdTiffWriteOptions *options) +{ + gdIOCtx *out; + gdTiffWritePtr write; + + if (outFile == NULL) + return NULL; + out = gdNewFileCtx(outFile); + if (out == NULL) + return NULL; + write = gdTiffWriteOpenCtx(out, options); + if (write == NULL) { + out->gd_free(out); + return NULL; + } + write->ownsCtx = 1; + return write; +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenCtx(gdIOCtxPtr out, const gdTiffWriteOptions *options) +{ + gdTiffWritePtr write; + tiff_handle *th; + TIFF *tif; + + if (out == NULL) + return NULL; + + write = (gdTiffWritePtr)gdCalloc(1, sizeof(struct gdTiffWriteStruct)); + if (write == NULL) + return NULL; + + write->out = out; + write->ownsCtx = 0; + + if (options != NULL) { + write->options = *options; + } else { + memset(&write->options, 0, sizeof(write->options)); + } + TiffWriteSetDefaults(&write->options); + + if (!TiffWriteValidateOptions(&write->options)) { + gdFree(write); + return NULL; + } + + th = new_tiff_handle(out, 0); + if (th == NULL) { + gdFree(write); + return NULL; + } + write->th = th; + + tif = TIFFClientOpen("", "w", th, tiff_readproc, tiff_writeproc, tiff_seekproc, tiff_closeproc, + tiff_sizeproc, tiff_mapproc, tiff_unmapproc); + if (tif == NULL) { + gdFree(th); + gdFree(write); + gd_error("gd-tiff write: could not open TIFF for writing"); + return NULL; + } + write->tif = tif; + + return write; +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenPtr(const gdTiffWriteOptions *options) +{ + gdIOCtx *out; + gdTiffWritePtr write; + + out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + write = gdTiffWriteOpenCtx(out, options); + if (write == NULL) { + out->gd_free(out); + return NULL; + } + write->ownsCtx = 1; + write->memoryWriter = 1; + return write; +} + +BGD_DECLARE(int) gdTiffWriteAddImage(gdTiffWritePtr write, gdImagePtr image) +{ + if (write == NULL || image == NULL || write->finalized) + return 0; + if (!image->trueColor) { + gd_error("gd-tiff write: only truecolor images are supported by the " + "new write API"); + return 0; + } + return TiffWriteWritePage(write, image); +} + +BGD_DECLARE(void) gdTiffWriteClose(gdTiffWritePtr write) +{ + if (write == NULL) + return; + write->finalized = 1; + TiffWriteFree(write); +} + +BGD_DECLARE(void *) gdTiffWritePtrFinish(gdTiffWritePtr write, int *size) +{ + void *rv = NULL; + + if (size != NULL) + *size = 0; + if (write == NULL || !write->memoryWriter) { + TiffWriteFree(write); + return NULL; + } + write->finalized = 1; + if (write->tif != NULL) { + TIFFClose(write->tif); + write->tif = NULL; + } + if (write->out != NULL) { + rv = gdDPExtractData(write->out, size); + } + TiffWriteFree(write); + return rv; +} + +#else + +static void _noTiffError(void) { gd_error("TIFF image support has been disabled\n"); } + +BGD_DECLARE(void) gdImageTiffCtx(gdImagePtr image, gdIOCtx *out) +{ + ARG_NOT_USED(image); + ARG_NOT_USED(out); + _noTiffError(); +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffCtx(gdIOCtx *infile) +{ + ARG_NOT_USED(infile); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiff(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromTiffPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(void) gdImageTiff(gdImagePtr im, FILE *outFile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + _noTiffError(); +} + +BGD_DECLARE(void *) gdImageTiffPtr(gdImagePtr im, int *size) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpen(FILE *fd) +{ + ARG_NOT_USED(fd); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenCtx(gdIOCtxPtr in) +{ + ARG_NOT_USED(in); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdTiffReadPtr) gdTiffReadOpenPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(void) gdTiffReadClose(gdTiffReadPtr tiff) +{ + ARG_NOT_USED(tiff); + _noTiffError(); +} + +BGD_DECLARE(int) gdTiffReadGetInfo(gdTiffReadPtr tiff, gdTiffInfo *info) +{ + ARG_NOT_USED(tiff); + ARG_NOT_USED(info); + _noTiffError(); + return 0; +} + +BGD_DECLARE(int) +gdTiffReadNextImage(gdTiffReadPtr tiff, gdTiffPageInfo *info, gdImagePtr *image) +{ + ARG_NOT_USED(tiff); + ARG_NOT_USED(info); + ARG_NOT_USED(image); + _noTiffError(); + return -1; +} + +BGD_DECLARE(gdImagePtr) gdTiffReadCloneImage(gdTiffReadPtr tiff) +{ + ARG_NOT_USED(tiff); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(int) gdTiffIsMultiPage(FILE *fd) +{ + ARG_NOT_USED(fd); + _noTiffError(); + return -1; +} + +BGD_DECLARE(int) gdTiffIsMultiPageCtx(gdIOCtxPtr in) +{ + ARG_NOT_USED(in); + _noTiffError(); + return -1; +} + +BGD_DECLARE(int) gdTiffIsMultiPagePtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noTiffError(); + return -1; +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpen(FILE *outFile, const gdTiffWriteOptions *options) +{ + ARG_NOT_USED(outFile); + ARG_NOT_USED(options); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenCtx(gdIOCtxPtr out, const gdTiffWriteOptions *options) +{ + ARG_NOT_USED(out); + ARG_NOT_USED(options); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(gdTiffWritePtr) +gdTiffWriteOpenPtr(const gdTiffWriteOptions *options) +{ + ARG_NOT_USED(options); + _noTiffError(); + return NULL; +} + +BGD_DECLARE(int) gdTiffWriteAddImage(gdTiffWritePtr write, gdImagePtr image) +{ + ARG_NOT_USED(write); + ARG_NOT_USED(image); + _noTiffError(); + return 0; +} + +BGD_DECLARE(void) gdTiffWriteClose(gdTiffWritePtr write) +{ + ARG_NOT_USED(write); + _noTiffError(); +} + +BGD_DECLARE(void *) gdTiffWritePtrFinish(gdTiffWritePtr write, int *size) +{ + ARG_NOT_USED(write); + ARG_NOT_USED(size); + _noTiffError(); + return NULL; +} + +#endif diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c index 2a9fb3d608dc..7beefbc10b7e 100644 --- a/ext/gd/libgd/gd_topal.c +++ b/ext/gd/libgd/gd_topal.c @@ -2,12 +2,12 @@ correct use of stub (sigh). */ /* 2.0.12: a new adaptation from the same original, this time - by Barend Gehrels. My attempt to incorporate alpha channel - into the result worked poorly and degraded the quality of - palette conversion even when the source contained no - alpha channel data. This version does not attempt to produce - an output file with transparency in some of the palette - indexes, which, in practice, doesn't look so hot anyway. TBB */ + by Barend Gehrels. My attempt to incorporate alpha channel + into the result worked poorly and degraded the quality of + palette conversion even when the source contained no + alpha channel data. This version does not attempt to produce + an output file with transparency in some of the palette + indexes, which, in practice, doesn't look so hot anyway. TBB */ /* * gd_topal, adapted from jquant2.c @@ -28,34 +28,42 @@ * fundamental assumptions even hold with an irregularly spaced color map. */ +/** + * File: Color Quantization + * + * Functions for truecolor to palette conversion + */ + /* * THOMAS BOUTELL & BAREND GEHRELS, february 2003 * adapted the code to work within gd rather than within libjpeg. * If it is not working, it's not Thomas G. Lane's fault. */ - -#include #include "gd.h" #include "gdhelpers.h" +#include + +#ifdef HAVE_LIBIMAGEQUANT +#include +#endif /* (Re)define some defines known by libjpeg */ #define QUANT_2PASS_SUPPORTED -#define RGB_RED 0 -#define RGB_GREEN 1 -#define RGB_BLUE 2 +#define RGB_RED 0 +#define RGB_GREEN 1 +#define RGB_BLUE 2 #define JSAMPLE unsigned char -#define MAXJSAMPLE (gdMaxColors-1) +#define MAXJSAMPLE (gdMaxColors - 1) #define BITS_IN_JSAMPLE 8 -#define JSAMPROW int* +#define JSAMPROW int * #define JDIMENSION int #define METHODDEF(type) static type -#define LOCAL(type) static type - +#define LOCAL(type) static type /* We assume that right shift corresponds to signed division by 2 with * rounding towards minus infinity. This is correct for typical "arithmetic @@ -68,22 +76,25 @@ */ #ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; -#define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x, shft) \ + ((shift_temp = (x)) < 0 ? (shift_temp >> (shft)) | ((~((INT32)0)) << (32 - (shft))) \ + : (shift_temp >> (shft))) #else #define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#define RIGHT_SHIFT(x, shft) ((x) >> (shft)) #endif - -#define range_limit(x) { if(x<0) x=0; if (x>255) x=255; } - +#define range_limit(x) \ + { \ + if (x < 0) \ + x = 0; \ + if (x > 255) \ + x = 255; \ + } #ifndef INT16 -#define INT16 short +#define INT16 short #endif #ifndef UINT16 @@ -98,8 +109,6 @@ #define FAR #endif - - #ifndef boolean #define boolean int #endif @@ -112,13 +121,11 @@ #define FALSE 0 #endif - #define input_buf (oim->tpixels) #define output_buf (nim->pixels) #ifdef QUANT_2PASS_SUPPORTED - /* * This module implements the well-known Heckbert paradigm for color * quantization. Most of the ideas used here can be traced back to @@ -165,9 +172,9 @@ * probably need to change these scale factors. */ -#define R_SCALE 2 /* scale R distances by this much */ -#define G_SCALE 3 /* scale G distances by this much */ -#define B_SCALE 1 /* and B by this much */ +#define R_SCALE 2 /* scale R distances by this much */ +#define G_SCALE 3 /* scale G distances by this much */ +#define B_SCALE 1 /* and B by this much */ /* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B @@ -192,7 +199,6 @@ #define C2_SCALE B_SCALE #endif - /* * First we have the histogram data structure and routines for creating it. * @@ -219,34 +225,32 @@ * arrays are in far memory (same arrangement as we use for image arrays). */ -#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ +#define MAXNUMCOLORS (MAXJSAMPLE + 1) /* maximum size of colormap */ /* These will do the right thing for either R,G,B or B,G,R color order, * but you may not like the results for other color orders. */ -#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ -#define HIST_C1_BITS 6 /* bits of precision in G histogram */ -#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ +#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ +#define HIST_C1_BITS 6 /* bits of precision in G histogram */ +#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ /* Number of elements along histogram axes. */ -#define HIST_C0_ELEMS (1<histogram; - int row; - JDIMENSION col; - int width = oim->sx; - int num_rows = oim->sy; - - for (row = 0; row < num_rows; row++) - { - ptr = input_buf[row]; - for (col = width; col > 0; col--) - { - int r = gdTrueColorGetRed (*ptr) >> C0_SHIFT; - int g = gdTrueColorGetGreen (*ptr) >> C1_SHIFT; - int b = gdTrueColorGetBlue (*ptr) >> C2_SHIFT; - /* 2.0.12: Steven Brown: support a single totally transparent - color in the original. */ - if ((oim->transparent >= 0) && (*ptr == oim->transparent)) - { - ptr++; - continue; - } - /* get pixel value and index into the histogram */ - histp = &histogram[r][g][b]; - /* increment, check for overflow and undo increment if so. */ - if (++(*histp) == 0) - (*histp)--; - ptr++; - } + register JSAMPROW ptr; + register histptr histp; + register hist3d histogram = cquantize->histogram; + int row; + JDIMENSION col; + int width = oim->sx; + int num_rows = oim->sy; + + (void)nim; + + for (row = 0; row < num_rows; row++) { + ptr = input_buf[row]; + for (col = width; col > 0; col--) { + int r = gdTrueColorGetRed(*ptr) >> C0_SHIFT; + int g = gdTrueColorGetGreen(*ptr) >> C1_SHIFT; + int b = gdTrueColorGetBlue(*ptr) >> C2_SHIFT; + /* 2.0.12: Steven Brown: support a single totally transparent + color in the original. */ + if ((oim->transparent >= 0) && (*ptr == oim->transparent)) { + ptr++; + continue; + } + /* get pixel value and index into the histogram */ + histp = &histogram[r][g][b]; + /* increment, check for overflow and undo increment if so. */ + if (++(*histp) == 0) + (*histp)--; + ptr++; + } } } - /* * Next we have the really interesting routines: selection of a colormap * given the completed histogram. @@ -356,394 +353,357 @@ prescan_quantize (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) * subset of the input color space (to histogram precision). */ -typedef struct -{ - /* The bounds of the box (inclusive); expressed as histogram indexes */ - int c0min, c0max; - int c1min, c1max; - int c2min, c2max; - /* The volume (actually 2-norm) of the box */ - INT32 volume; - /* The number of nonzero histogram cells within this box */ - long colorcount; -} -box; +typedef struct { + /* The bounds of the box (inclusive); expressed as histogram indexes */ + int c0min, c0max; + int c1min, c1max; + int c2min, c2max; + /* The volume (actually 2-norm) of the box */ + INT32 volume; + /* The number of nonzero histogram cells within this box */ + long colorcount; +} box; typedef box *boxptr; - -LOCAL (boxptr) find_biggest_color_pop (boxptr boxlist, int numboxes) +LOCAL(boxptr) +find_biggest_color_pop(boxptr boxlist, int numboxes) /* Find the splittable box with the largest color population */ /* Returns NULL if no splittable boxes remain */ { - register boxptr boxp; - register int i; - register long maxc = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) - { - if (boxp->colorcount > maxc && boxp->volume > 0) - { - which = boxp; - maxc = boxp->colorcount; - } + register boxptr boxp; + register int i; + register long maxc = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->colorcount > maxc && boxp->volume > 0) { + which = boxp; + maxc = boxp->colorcount; + } } - return which; + return which; } - -LOCAL (boxptr) find_biggest_volume (boxptr boxlist, int numboxes) +LOCAL(boxptr) +find_biggest_volume(boxptr boxlist, int numboxes) /* Find the splittable box with the largest (scaled) volume */ /* Returns NULL if no splittable boxes remain */ { - register boxptr boxp; - register int i; - register INT32 maxv = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) - { - if (boxp->volume > maxv) - { - which = boxp; - maxv = boxp->volume; - } + register boxptr boxp; + register int i; + register INT32 maxv = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->volume > maxv) { + which = boxp; + maxv = boxp->volume; + } } - return which; + return which; } - -LOCAL (void) - update_box (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp) +LOCAL(void) +update_box(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp) { - hist3d histogram = cquantize->histogram; - histptr histp; - int c0, c1, c2; - int c0min, c0max, c1min, c1max, c2min, c2max; - INT32 dist0, dist1, dist2; - long ccount; - - c0min = boxp->c0min; - c0max = boxp->c0max; - c1min = boxp->c1min; - c1max = boxp->c1max; - c2min = boxp->c2min; - c2max = boxp->c2max; - - if (c0max > c0min) - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) - { - boxp->c0min = c0min = c0; - goto have_c0min; - } - } + hist3d histogram = cquantize->histogram; + histptr histp; + int c0, c1, c2; + int c0min, c0max, c1min, c1max, c2min, c2max; + INT32 dist0, dist1, dist2; + long ccount; + (void)oim; + (void)nim; + + c0min = boxp->c0min; + c0max = boxp->c0max; + c1min = boxp->c1min; + c1max = boxp->c1max; + c2min = boxp->c2min; + c2max = boxp->c2max; + + if (c0max > c0min) + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0min = c0min = c0; + goto have_c0min; + } + } have_c0min: - if (c0max > c0min) - for (c0 = c0max; c0 >= c0min; c0--) - for (c1 = c1min; c1 <= c1max; c1++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) - { - boxp->c0max = c0max = c0; - goto have_c0max; - } - } + if (c0max > c0min) + for (c0 = c0max; c0 >= c0min; c0--) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0max = c0max = c0; + goto have_c0max; + } + } have_c0max: - if (c1max > c1min) - for (c1 = c1min; c1 <= c1max; c1++) - for (c0 = c0min; c0 <= c0max; c0++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) - { - boxp->c1min = c1min = c1; - goto have_c1min; - } - } + if (c1max > c1min) + for (c1 = c1min; c1 <= c1max; c1++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1min = c1min = c1; + goto have_c1min; + } + } have_c1min: - if (c1max > c1min) - for (c1 = c1max; c1 >= c1min; c1--) - for (c0 = c0min; c0 <= c0max; c0++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) - { - boxp->c1max = c1max = c1; - goto have_c1max; - } - } + if (c1max > c1min) + for (c1 = c1max; c1 >= c1min; c1--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1max = c1max = c1; + goto have_c1max; + } + } have_c1max: - if (c2max > c2min) - for (c2 = c2min; c2 <= c2max; c2++) - for (c0 = c0min; c0 <= c0max; c0++) - { - histp = &histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) - { - boxp->c2min = c2min = c2; - goto have_c2min; - } - } + if (c2max > c2min) + for (c2 = c2min; c2 <= c2max; c2++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = &histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2min = c2min = c2; + goto have_c2min; + } + } have_c2min: - if (c2max > c2min) - for (c2 = c2max; c2 >= c2min; c2--) - for (c0 = c0min; c0 <= c0max; c0++) - { - histp = &histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) - { - boxp->c2max = c2max = c2; - goto have_c2max; - } - } + if (c2max > c2min) + for (c2 = c2max; c2 >= c2min; c2--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = &histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2max = c2max = c2; + goto have_c2max; + } + } have_c2max: - /* Update box volume. - * We use 2-norm rather than real volume here; this biases the method - * against making long narrow boxes, and it has the side benefit that - * a box is splittable iff norm > 0. - * Since the differences are expressed in histogram-cell units, - * we have to shift back to JSAMPLE units to get consistent distances; - * after which, we scale according to the selected distance scale factors. - */ - dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; - dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; - dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; - boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2; - - /* Now scan remaining volume of box and compute population */ - ccount = 0; - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++, histp++) - if (*histp != 0) - { - ccount++; - } - } - boxp->colorcount = ccount; + /* Update box volume. + * We use 2-norm rather than real volume here; this biases the method + * against making long narrow boxes, and it has the side benefit that + * a box is splittable iff norm > 0. + * Since the differences are expressed in histogram-cell units, + * we have to shift back to JSAMPLE units to get consistent distances; + * after which, we scale according to the selected distance scale factors. + */ + dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; + dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; + dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; + boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2; + + /* Now scan remaining volume of box and compute population */ + ccount = 0; + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++, histp++) + if (*histp != 0) { + ccount++; + } + } + boxp->colorcount = ccount; } - -LOCAL (int) -median_cut (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, - boxptr boxlist, int numboxes, int desired_colors) +LOCAL(int) +median_cut(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxlist, int numboxes, + int desired_colors) /* Repeatedly select and split the largest box until we have enough boxes */ { - int n, lb; - int c0, c1, c2, cmax; - register boxptr b1, b2; - - while (numboxes < desired_colors) - { - /* Select box to split. - * Current algorithm: by population for first half, then by volume. - */ - if (numboxes * 2 <= desired_colors) - { - b1 = find_biggest_color_pop (boxlist, numboxes); - } - else - { - b1 = find_biggest_volume (boxlist, numboxes); - } - if (b1 == NULL) /* no splittable boxes left! */ - break; - b2 = &boxlist[numboxes]; /* where new box will go */ - /* Copy the color bounds to the new box. */ - b2->c0max = b1->c0max; - b2->c1max = b1->c1max; - b2->c2max = b1->c2max; - b2->c0min = b1->c0min; - b2->c1min = b1->c1min; - b2->c2min = b1->c2min; - /* Choose which axis to split the box on. - * Current algorithm: longest scaled axis. - * See notes in update_box about scaling distances. - */ - c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; - c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; - c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; - /* We want to break any ties in favor of green, then red, blue last. - * This code does the right thing for R,G,B or B,G,R color orders only. - */ + int n, lb; + int c0, c1, c2, cmax; + register boxptr b1, b2; + + while (numboxes < desired_colors) { + /* Select box to split. + * Current algorithm: by population for first half, then by volume. + */ + if (numboxes * 2 <= desired_colors) { + b1 = find_biggest_color_pop(boxlist, numboxes); + } else { + b1 = find_biggest_volume(boxlist, numboxes); + } + if (b1 == NULL) /* no splittable boxes left! */ + break; + b2 = &boxlist[numboxes]; /* where new box will go */ + /* Copy the color bounds to the new box. */ + b2->c0max = b1->c0max; + b2->c1max = b1->c1max; + b2->c2max = b1->c2max; + b2->c0min = b1->c0min; + b2->c1min = b1->c1min; + b2->c2min = b1->c2min; + /* Choose which axis to split the box on. + * Current algorithm: longest scaled axis. + * See notes in update_box about scaling distances. + */ + c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; + c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; + c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; + /* We want to break any ties in favor of green, then red, blue last. + * This code does the right thing for R,G,B or B,G,R color orders only. + */ #if RGB_RED == 0 - cmax = c1; - n = 1; - if (c0 > cmax) - { - cmax = c0; - n = 0; - } - if (c2 > cmax) - { - n = 2; - } + cmax = c1; + n = 1; + if (c0 > cmax) { + cmax = c0; + n = 0; + } + if (c2 > cmax) { + n = 2; + } #else - cmax = c1; - n = 1; - if (c2 > cmax) - { - cmax = c2; - n = 2; - } - if (c0 > cmax) - { - n = 0; - } + cmax = c1; + n = 1; + if (c2 > cmax) { + cmax = c2; + n = 2; + } + if (c0 > cmax) { + n = 0; + } #endif - /* Choose split point along selected axis, and update box bounds. - * Current algorithm: split at halfway point. - * (Since the box has been shrunk to minimum volume, - * any split will produce two nonempty subboxes.) - * Note that lb value is max for lower box, so must be < old max. - */ - switch (n) - { - case 0: - lb = (b1->c0max + b1->c0min) / 2; - b1->c0max = lb; - b2->c0min = lb + 1; - break; - case 1: - lb = (b1->c1max + b1->c1min) / 2; - b1->c1max = lb; - b2->c1min = lb + 1; - break; - case 2: - lb = (b1->c2max + b1->c2min) / 2; - b1->c2max = lb; - b2->c2min = lb + 1; - break; - } - /* Update stats for boxes */ - update_box (oim, nim, cquantize, b1); - update_box (oim, nim, cquantize, b2); - numboxes++; + /* Choose split point along selected axis, and update box bounds. + * Current algorithm: split at halfway point. + * (Since the box has been shrunk to minimum volume, + * any split will produce two nonempty subboxes.) + * Note that lb value is max for lower box, so must be < old max. + */ + switch (n) { + case 0: + lb = (b1->c0max + b1->c0min) / 2; + b1->c0max = lb; + b2->c0min = lb + 1; + break; + case 1: + lb = (b1->c1max + b1->c1min) / 2; + b1->c1max = lb; + b2->c1min = lb + 1; + break; + case 2: + lb = (b1->c2max + b1->c2min) / 2; + b1->c2max = lb; + b2->c2min = lb + 1; + break; + } + /* Update stats for boxes */ + update_box(oim, nim, cquantize, b1); + update_box(oim, nim, cquantize, b2); + numboxes++; } - return numboxes; + return numboxes; } - -LOCAL (void) - compute_color (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, - boxptr boxp, int icolor) -/* Compute representative color for a box, put it in colormap[icolor] */ +LOCAL(void) +compute_color(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp, int icolor) { - /* Current algorithm: mean weighted by pixels (not colors) */ - /* Note it is important to get the rounding correct! */ - hist3d histogram = cquantize->histogram; - histptr histp; - int c0, c1, c2; - int c0min, c0max, c1min, c1max, c2min, c2max; - long count = 0; /* 2.0.28: = 0 */ - long total = 0; - long c0total = 0; - long c1total = 0; - long c2total = 0; - - c0min = boxp->c0min; - c0max = boxp->c0max; - c1min = boxp->c1min; - c1max = boxp->c1max; - c2min = boxp->c2min; - c2max = boxp->c2max; - - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) - { - histp = &histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - { - if ((count = *histp++) != 0) - { - total += count; - c0total += - ((c0 << C0_SHIFT) + ((1 << C0_SHIFT) >> 1)) * count; - c1total += - ((c1 << C1_SHIFT) + ((1 << C1_SHIFT) >> 1)) * count; - c2total += - ((c2 << C2_SHIFT) + ((1 << C2_SHIFT) >> 1)) * count; - } - } - } - - /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */ - if (total) - { - nim->red[icolor] = (int) ((c0total + (total >> 1)) / total); - nim->green[icolor] = (int) ((c1total + (total >> 1)) / total); - nim->blue[icolor] = (int) ((c2total + (total >> 1)) / total); - } - else - { - nim->red[icolor] = 255; - nim->green[icolor] = 255; - nim->blue[icolor] = 255; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0, c1, c2; + int c0min, c0max, c1min, c1max, c2min, c2max; + long count = 0; /* 2.0.28: = 0 */ + long total = 0; + long c0total = 0; + long c1total = 0; + long c2total = 0; + (void)oim; + + c0min = boxp->c0min; + c0max = boxp->c0max; + c1min = boxp->c1min; + c1max = boxp->c1max; + c2min = boxp->c2min; + c2max = boxp->c2max; + + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = &histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) { + if ((count = *histp++) != 0) { + total += count; + c0total += ((c0 << C0_SHIFT) + ((1 << C0_SHIFT) >> 1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1 << C1_SHIFT) >> 1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1 << C2_SHIFT) >> 1)) * count; + } + } + } + + /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */ + if (total) { + nim->red[icolor] = (int)((c0total + (total >> 1)) / total); + nim->green[icolor] = (int)((c1total + (total >> 1)) / total); + nim->blue[icolor] = (int)((c2total + (total >> 1)) / total); + } else { + nim->red[icolor] = 255; + nim->green[icolor] = 255; + nim->blue[icolor] = 255; } - nim->open[icolor] = 0; + nim->open[icolor] = 0; } - -LOCAL (void) -select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors) +LOCAL(void) +select_colors(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors) /* Master routine for color selection */ { - boxptr boxlist; - int numboxes; - int i; - - /* Allocate workspace for box list */ - boxlist = (boxptr) safe_emalloc(desired_colors, sizeof (box), 1); - /* Initialize one box containing whole space */ - numboxes = 1; - boxlist[0].c0min = 0; - boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; - boxlist[0].c1min = 0; - boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; - boxlist[0].c2min = 0; - boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; - /* Shrink it to actually-used volume and set its statistics */ - update_box (oim, nim, cquantize, &boxlist[0]); - /* Perform median-cut to produce final box list */ - numboxes = median_cut (oim, nim, cquantize, boxlist, numboxes, desired_colors); - /* Compute the representative color for each box, fill colormap */ - for (i = 0; i < numboxes; i++) - compute_color (oim, nim, cquantize, &boxlist[i], i); - nim->colorsTotal = numboxes; - - /* If we had a pure transparency color, add it as the last palette entry. - * Skip incrementing the color count so that the dither / matching phase - * won't use it on pixels that shouldn't have been transparent. We'll - * increment it after all that finishes. */ - if (oim->transparent >= 0) - { - /* Save the transparent color. */ - nim->red[nim->colorsTotal] = gdTrueColorGetRed (oim->transparent); - nim->green[nim->colorsTotal] = gdTrueColorGetGreen (oim->transparent); - nim->blue[nim->colorsTotal] = gdTrueColorGetBlue (oim->transparent); - nim->alpha[nim->colorsTotal] = gdAlphaTransparent; - nim->open[nim->colorsTotal] = 0; + boxptr boxlist; + int numboxes; + int i; + + /* Allocate workspace for box list */ + /* This can't happen because we clamp desired_colors at gdMaxColors, + but anyway */ + if (overflow2(desired_colors, sizeof(box))) { + return; + } + boxlist = (boxptr)gdMalloc(desired_colors * sizeof(box)); + if (!boxlist) { + return; + } + /* Initialize one box containing whole space */ + numboxes = 1; + boxlist[0].c0min = 0; + boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; + boxlist[0].c1min = 0; + boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; + boxlist[0].c2min = 0; + boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; + /* Shrink it to actually-used volume and set its statistics */ + update_box(oim, nim, cquantize, &boxlist[0]); + /* Perform median-cut to produce final box list */ + numboxes = median_cut(oim, nim, cquantize, boxlist, numboxes, desired_colors); + /* Compute the representative color for each box, fill colormap */ + for (i = 0; i < numboxes; i++) + compute_color(oim, nim, cquantize, &boxlist[i], i); + nim->colorsTotal = numboxes; + + /* If we had a pure transparency color, add it as the last palette entry. + * Skip incrementing the color count so that the dither / matching phase + * won't use it on pixels that shouldn't have been transparent. We'll + * increment it after all that finishes. */ + if (oim->transparent >= 0) { + /* Save the transparent color. */ + nim->red[nim->colorsTotal] = gdTrueColorGetRed(oim->transparent); + nim->green[nim->colorsTotal] = gdTrueColorGetGreen(oim->transparent); + nim->blue[nim->colorsTotal] = gdTrueColorGetBlue(oim->transparent); + nim->alpha[nim->colorsTotal] = gdAlphaTransparent; + nim->open[nim->colorsTotal] = 0; } - gdFree (boxlist); + gdFree(boxlist); } - /* * These routines are concerned with the time-critical task of mapping input * colors to the nearest color in the selected colormap. @@ -797,20 +757,18 @@ select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int d * it might not be any faster, and it's certainly more complicated. */ - /* log2(histogram cells in update box) for each axis; this can be adjusted */ -#define BOX_C0_LOG (HIST_C0_BITS-3) -#define BOX_C1_LOG (HIST_C1_BITS-3) -#define BOX_C2_LOG (HIST_C2_BITS-3) - -#define BOX_C0_ELEMS (1<colorsTotal; - int maxc0, maxc1, maxc2; - int centerc0, centerc1, centerc2; - int i, x, ncolors; - INT32 minmaxdist, min_dist, max_dist, tdist; - INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ - - /* Compute true coordinates of update box's upper corner and center. - * Actually we compute the coordinates of the center of the upper-corner - * histogram cell, which are the upper bounds of the volume we care about. - * Note that since ">>" rounds down, the "center" values may be closer to - * min than to max; hence comparisons to them must be "<=", not "<". - */ - maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); - centerc0 = (minc0 + maxc0) >> 1; - maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); - centerc1 = (minc1 + maxc1) >> 1; - maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); - centerc2 = (minc2 + maxc2) >> 1; - - /* For each color in colormap, find: - * 1. its minimum squared-distance to any point in the update box - * (zero if color is within update box); - * 2. its maximum squared-distance to any point in the update box. - * Both of these can be found by considering only the corners of the box. - * We save the minimum distance for each color in mindist[]; - * only the smallest maximum distance is of interest. - */ - minmaxdist = 0x7FFFFFFFL; - - for (i = 0; i < numcolors; i++) - { - /* We compute the squared-c0-distance term, then add in the other two. */ - x = nim->red[i]; - if (x < minc0) - { - tdist = (x - minc0) * C0_SCALE; - min_dist = tdist * tdist; - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist * tdist; - } - else if (x > maxc0) - { - tdist = (x - maxc0) * C0_SCALE; - min_dist = tdist * tdist; - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist * tdist; - } - else - { - /* within cell range so no contribution to min_dist */ - min_dist = 0; - if (x <= centerc0) - { - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist * tdist; - } - else - { - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist * tdist; - } - } - - x = nim->green[i]; - if (x < minc1) - { - tdist = (x - minc1) * C1_SCALE; - min_dist += tdist * tdist; - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist * tdist; - } - else if (x > maxc1) - { - tdist = (x - maxc1) * C1_SCALE; - min_dist += tdist * tdist; - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist * tdist; - } - else - { - /* within cell range so no contribution to min_dist */ - if (x <= centerc1) - { - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist * tdist; - } - else - { - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist * tdist; - } - } - - x = nim->blue[i]; - if (x < minc2) - { - tdist = (x - minc2) * C2_SCALE; - min_dist += tdist * tdist; - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist * tdist; - } - else if (x > maxc2) - { - tdist = (x - maxc2) * C2_SCALE; - min_dist += tdist * tdist; - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist * tdist; - } - else - { - /* within cell range so no contribution to min_dist */ - if (x <= centerc2) - { - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist * tdist; - } - else - { - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist * tdist; - } - } - - mindist[i] = min_dist; /* save away the results */ - if (max_dist < minmaxdist) - minmaxdist = max_dist; + int numcolors = nim->colorsTotal; + int maxc0, maxc1, maxc2; + int centerc0, centerc1, centerc2; + int i, x, ncolors; + INT32 minmaxdist, min_dist, max_dist, tdist; + INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ + (void)oim; + (void)cquantize; + + /* Compute true coordinates of update box's upper corner and center. + * Actually we compute the coordinates of the center of the upper-corner + * histogram cell, which are the upper bounds of the volume we care about. + * Note that since ">>" rounds down, the "center" values may be closer to + * min than to max; hence comparisons to them must be "<=", not "<". + */ + maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); + centerc0 = (minc0 + maxc0) >> 1; + maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); + centerc1 = (minc1 + maxc1) >> 1; + maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); + centerc2 = (minc2 + maxc2) >> 1; + + /* For each color in colormap, find: + * 1. its minimum squared-distance to any point in the update box + * (zero if color is within update box); + * 2. its maximum squared-distance to any point in the update box. + * Both of these can be found by considering only the corners of the box. + * We save the minimum distance for each color in mindist[]; + * only the smallest maximum distance is of interest. + */ + minmaxdist = 0x7FFFFFFFL; + + for (i = 0; i < numcolors; i++) { + /* We compute the squared-c0-distance term, then add in the other two. + */ + x = nim->red[i]; + if (x < minc0) { + tdist = (x - minc0) * C0_SCALE; + min_dist = tdist * tdist; + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist * tdist; + } else if (x > maxc0) { + tdist = (x - maxc0) * C0_SCALE; + min_dist = tdist * tdist; + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist * tdist; + } else { + /* within cell range so no contribution to min_dist */ + min_dist = 0; + if (x <= centerc0) { + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist * tdist; + } else { + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist * tdist; + } + } + + x = nim->green[i]; + if (x < minc1) { + tdist = (x - minc1) * C1_SCALE; + min_dist += tdist * tdist; + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist * tdist; + } else if (x > maxc1) { + tdist = (x - maxc1) * C1_SCALE; + min_dist += tdist * tdist; + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist * tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc1) { + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist * tdist; + } else { + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist * tdist; + } + } + + x = nim->blue[i]; + if (x < minc2) { + tdist = (x - minc2) * C2_SCALE; + min_dist += tdist * tdist; + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist * tdist; + } else if (x > maxc2) { + tdist = (x - maxc2) * C2_SCALE; + min_dist += tdist * tdist; + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist * tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc2) { + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist * tdist; + } else { + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist * tdist; + } + } + + mindist[i] = min_dist; /* save away the results */ + if (max_dist < minmaxdist) + minmaxdist = max_dist; } - /* Now we know that no cell in the update box is more than minmaxdist - * away from some colormap entry. Therefore, only colors that are - * within minmaxdist of some part of the box need be considered. - */ - ncolors = 0; - for (i = 0; i < numcolors; i++) - { - if (mindist[i] <= minmaxdist) - colorlist[ncolors++] = (JSAMPLE) i; + /* Now we know that no cell in the update box is more than minmaxdist + * away from some colormap entry. Therefore, only colors that are + * within minmaxdist of some part of the box need be considered. + */ + ncolors = 0; + for (i = 0; i < numcolors; i++) { + if (mindist[i] <= minmaxdist) + colorlist[ncolors++] = (JSAMPLE)i; } - return ncolors; + return ncolors; } - -LOCAL (void) find_best_colors ( - gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, - int minc0, int minc1, int minc2, - int numcolors, JSAMPLE colorlist[], - JSAMPLE bestcolor[]) +LOCAL(void) +find_best_colors(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int minc0, int minc1, + int minc2, int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) /* Find the closest colormap entry for each cell in the update box, * given the list of candidate colors prepared by find_nearby_colors. * Return the indexes of the closest entries in the bestcolor[] array. @@ -988,369 +919,350 @@ LOCAL (void) find_best_colors ( * find the distance from a colormap entry to successive cells in the box. */ { - int ic0, ic1, ic2; - int i, icolor; - register INT32 *bptr; /* pointer into bestdist[] array */ - JSAMPLE *cptr; /* pointer into bestcolor[] array */ - INT32 dist0, dist1; /* initial distance values */ - register INT32 dist2; /* current distance in inner loop */ - INT32 xx0, xx1; /* distance increments */ - register INT32 xx2; - INT32 inc0, inc1, inc2; /* initial values for increments */ - /* This array holds the distance to the nearest-so-far color for each cell */ - INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Initialize best-distance for each cell of the update box */ - bptr = bestdist; - for (i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--) - *bptr++ = 0x7FFFFFFFL; - - /* For each color selected by find_nearby_colors, - * compute its distance to the center of each cell in the box. - * If that's less than best-so-far, update best distance and color number. - */ - - /* Nominal steps between cell centers ("x" in Thomas article) */ -#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) -#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) -#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) - - for (i = 0; i < numcolors; i++) - { - int r, g, b; - icolor = colorlist[i]; - r = nim->red[icolor]; - g = nim->green[icolor]; - b = nim->blue[icolor]; - - /* Compute (square of) distance from minc0/c1/c2 to this color */ - inc0 = (minc0 - r) * C0_SCALE; - dist0 = inc0 * inc0; - inc1 = (minc1 - g) * C1_SCALE; - dist0 += inc1 * inc1; - inc2 = (minc2 - b) * C2_SCALE; - dist0 += inc2 * inc2; - /* Form the initial difference increments */ - inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; - inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; - inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; - /* Now loop over all cells in box, updating distance per Thomas method */ - bptr = bestdist; - cptr = bestcolor; - xx0 = inc0; - for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--) - { - dist1 = dist0; - xx1 = inc1; - for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--) - { - dist2 = dist1; - xx2 = inc2; - for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) - { - if (dist2 < *bptr) - { - *bptr = dist2; - *cptr = (JSAMPLE) icolor; - } - dist2 += xx2; - xx2 += 2 * STEP_C2 * STEP_C2; - bptr++; - cptr++; - } - dist1 += xx1; - xx1 += 2 * STEP_C1 * STEP_C1; - } - dist0 += xx0; - xx0 += 2 * STEP_C0 * STEP_C0; - } + int ic0, ic1, ic2; + int i, icolor; + register INT32 *bptr; /* pointer into bestdist[] array */ + JSAMPLE *cptr; /* pointer into bestcolor[] array */ + INT32 dist0, dist1; /* initial distance values */ + register INT32 dist2; /* current distance in inner loop */ + INT32 xx0, xx1; /* distance increments */ + register INT32 xx2; + INT32 inc0, inc1, inc2; /* initial values for increments */ + /* This array holds the distance to the nearest-so-far color for each cell + */ + INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + (void)oim; + (void)cquantize; + + /* Initialize best-distance for each cell of the update box */ + bptr = bestdist; + for (i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--) + *bptr++ = 0x7FFFFFFFL; + + /* For each color selected by find_nearby_colors, + * compute its distance to the center of each cell in the box. + * If that's less than best-so-far, update best distance and color + * number. + */ + + /* Nominal steps between cell centers ("x" in Thomas article) */ +#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) +#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) +#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) + + for (i = 0; i < numcolors; i++) { + int r, g, b; + icolor = colorlist[i]; + r = nim->red[icolor]; + g = nim->green[icolor]; + b = nim->blue[icolor]; + + /* Compute (square of) distance from minc0/c1/c2 to this color */ + inc0 = (minc0 - r) * C0_SCALE; + dist0 = inc0 * inc0; + inc1 = (minc1 - g) * C1_SCALE; + dist0 += inc1 * inc1; + inc2 = (minc2 - b) * C2_SCALE; + dist0 += inc2 * inc2; + /* Form the initial difference increments */ + inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + /* Now loop over all cells in box, updating distance per Thomas method + */ + bptr = bestdist; + cptr = bestcolor; + xx0 = inc0; + for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--) { + dist1 = dist0; + xx1 = inc1; + for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--) { + dist2 = dist1; + xx2 = inc2; + for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) { + if (dist2 < *bptr) { + *bptr = dist2; + *cptr = (JSAMPLE)icolor; + } + dist2 += xx2; + xx2 += 2 * STEP_C2 * STEP_C2; + bptr++; + cptr++; + } + dist1 += xx1; + xx1 += 2 * STEP_C1 * STEP_C1; + } + dist0 += xx0; + xx0 += 2 * STEP_C0 * STEP_C0; + } } } - -LOCAL (void) -fill_inverse_cmap ( - gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, - int c0, int c1, int c2) +LOCAL(void) +fill_inverse_cmap(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int c0, int c1, + int c2) /* Fill the inverse-colormap entries in the update box that contains */ /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ /* we can fill as many others as we wish.) */ { - hist3d histogram = cquantize->histogram; - int minc0, minc1, minc2; /* lower left corner of update box */ - int ic0, ic1, ic2; - register JSAMPLE *cptr; /* pointer into bestcolor[] array */ - register histptr cachep; /* pointer into main cache array */ - /* This array lists the candidate colormap indexes. */ - JSAMPLE colorlist[MAXNUMCOLORS]; - int numcolors; /* number of candidate colors */ - /* This array holds the actually closest colormap index for each cell. */ - JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Convert cell coordinates to update box ID */ - c0 >>= BOX_C0_LOG; - c1 >>= BOX_C1_LOG; - c2 >>= BOX_C2_LOG; - - /* Compute true coordinates of update box's origin corner. - * Actually we compute the coordinates of the center of the corner - * histogram cell, which are the lower bounds of the volume we care about. - */ - minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); - minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); - minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); - - /* Determine which colormap entries are close enough to be candidates - * for the nearest entry to some cell in the update box. - */ - numcolors = - find_nearby_colors (oim, nim, cquantize, minc0, minc1, minc2, colorlist); - find_best_colors (oim, nim, cquantize, minc0, minc1, minc2, numcolors, - colorlist, bestcolor); - - /* Save the best color numbers (plus 1) in the main cache array */ - c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ - c1 <<= BOX_C1_LOG; - c2 <<= BOX_C2_LOG; - cptr = bestcolor; - for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) - { - for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) - { - cachep = &histogram[c0 + ic0][c1 + ic1][c2]; - for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) - { - *cachep++ = (histcell) ((*cptr++) + 1); - } - } + hist3d histogram = cquantize->histogram; + int minc0, minc1, minc2; /* lower left corner of update box */ + int ic0, ic1, ic2; + register JSAMPLE *cptr; /* pointer into bestcolor[] array */ + register histptr cachep; /* pointer into main cache array */ + /* This array lists the candidate colormap indexes. */ + JSAMPLE colorlist[MAXNUMCOLORS]; + int numcolors; /* number of candidate colors */ + /* This array holds the actually closest colormap index for each cell. */ + JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Convert cell coordinates to update box ID */ + c0 >>= BOX_C0_LOG; + c1 >>= BOX_C1_LOG; + c2 >>= BOX_C2_LOG; + + /* Compute true coordinates of update box's origin corner. + * Actually we compute the coordinates of the center of the corner + * histogram cell, which are the lower bounds of the volume we care about. + */ + minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); + minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); + minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); + + /* Determine which colormap entries are close enough to be candidates + * for the nearest entry to some cell in the update box. + */ + numcolors = find_nearby_colors(oim, nim, cquantize, minc0, minc1, minc2, colorlist); + find_best_colors(oim, nim, cquantize, minc0, minc1, minc2, numcolors, colorlist, bestcolor); + + /* Save the best color numbers (plus 1) in the main cache array */ + c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ + c1 <<= BOX_C1_LOG; + c2 <<= BOX_C2_LOG; + cptr = bestcolor; + for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { + for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { + cachep = &histogram[c0 + ic0][c1 + ic1][c2]; + for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { + *cachep++ = (histcell)((*cptr++) + 1); + } + } } } - /* * Map some rows of pixels to the output colormapped representation. */ -METHODDEF (void) -pass2_no_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) +METHODDEF(void) +pass2_no_dither(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) { - register int *inptr; - register unsigned char *outptr; - int width = oim->sx; - int num_rows = oim->sy; - hist3d histogram = cquantize->histogram; - register int c0, c1, c2; - int row; - JDIMENSION col; - register histptr cachep; - - - for (row = 0; row < num_rows; row++) - { - inptr = input_buf[row]; - outptr = output_buf[row]; - for (col = width; col > 0; col--) - { - /* get pixel value and index into the cache */ - int r, g, b; - r = gdTrueColorGetRed (*inptr); - g = gdTrueColorGetGreen (*inptr); - /* - 2.0.24: inptr must not be incremented until after - transparency check, if any. Thanks to "Super Pikeman." - */ - b = gdTrueColorGetBlue (*inptr); - - /* If the pixel is transparent, we assign it the palette index that - * will later be added at the end of the palette as the transparent - * index. */ - if ((oim->transparent >= 0) && (oim->transparent == *inptr)) - { - *outptr++ = nim->colorsTotal; - inptr++; - continue; - } - inptr++; - c0 = r >> C0_SHIFT; - c1 = g >> C1_SHIFT; - c2 = b >> C2_SHIFT; - cachep = &histogram[c0][c1][c2]; - /* If we have not seen this color before, find nearest colormap entry */ - /* and update the cache */ - if (*cachep == 0) - fill_inverse_cmap (oim, nim, cquantize, c0, c1, c2); - /* Now emit the colormap index for this cell */ - *outptr++ = (*cachep - 1); - } + register int *inptr; + register unsigned char *outptr; + int width = oim->sx; + int num_rows = oim->sy; + hist3d histogram = cquantize->histogram; + register int c0, c1, c2; + int row; + JDIMENSION col; + register histptr cachep; + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the cache */ + int r, g, b; + r = gdTrueColorGetRed(*inptr); + g = gdTrueColorGetGreen(*inptr); + /* + 2.0.24: inptr must not be incremented until after + transparency check, if any. Thanks to "Super Pikeman." + */ + b = gdTrueColorGetBlue(*inptr); + + /* If the pixel is transparent, we assign it the palette index that + * will later be added at the end of the palette as the transparent + * index. */ + if ((oim->transparent >= 0) && (oim->transparent == *inptr)) { + *outptr++ = nim->colorsTotal; + inptr++; + continue; + } + inptr++; + c0 = r >> C0_SHIFT; + c1 = g >> C1_SHIFT; + c2 = b >> C2_SHIFT; + cachep = &histogram[c0][c1][c2]; + /* If we have not seen this color before, find nearest colormap + * entry */ + /* and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(oim, nim, cquantize, c0, c1, c2); + /* Now emit the colormap index for this cell */ + *outptr++ = (*cachep - 1); + } } } - -METHODDEF (void) -pass2_fs_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) +METHODDEF(void) +pass2_fs_dither(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) { - hist3d histogram = cquantize->histogram; - register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ - LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ - LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - histptr cachep; - int dir; /* +1 or -1 depending on direction */ - int dir3; /* 3*dir, for advancing inptr & errorptr */ - int row; - JDIMENSION col; - int *inptr; /* => current input pixel */ - unsigned char *outptr; /* => current output pixel */ - int width = oim->sx; - int num_rows = oim->sy; - int *colormap0 = nim->red; - int *colormap1 = nim->green; - int *colormap2 = nim->blue; - int *error_limit = cquantize->error_limiter; - - - SHIFT_TEMPS for (row = 0; row < num_rows; row++) + hist3d histogram = cquantize->histogram; + register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ + LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + histptr cachep; + int dir; /* +1 or -1 depending on direction */ + int dir3; /* 3*dir, for advancing inptr & errorptr */ + int row; + JDIMENSION col; + int *inptr; /* => current input pixel */ + unsigned char *outptr; /* => current output pixel */ + int width = oim->sx; + int num_rows = oim->sy; + int *colormap0 = nim->red; + int *colormap1 = nim->green; + int *colormap2 = nim->blue; + int *error_limit = cquantize->error_limiter; + + SHIFT_TEMPS for (row = 0; row < num_rows; row++) { - inptr = input_buf[row]; - outptr = output_buf[row]; - if (cquantize->on_odd_row) - { - /* work right to left in this row */ - inptr += (width - 1) * 3; /* so point to rightmost pixel */ - outptr += width - 1; - dir = -1; - dir3 = -3; - errorptr = cquantize->fserrors + (width + 1) * 3; /* => entry after last column */ - } - else - { - /* work left to right in this row */ - dir = 1; - dir3 = 3; - errorptr = cquantize->fserrors; /* => entry before first real column */ - } - /* Preset error values: no error propagated to first pixel from left */ - cur0 = cur1 = cur2 = 0; - /* and no error propagated to row below yet */ - belowerr0 = belowerr1 = belowerr2 = 0; - bpreverr0 = bpreverr1 = bpreverr2 = 0; - - for (col = width; col > 0; col--) - { - - /* If this pixel is transparent, we want to assign it to the special - * transparency color index past the end of the palette rather than - * go through matching / dithering. */ - if ((oim->transparent >= 0) && (*inptr == oim->transparent)) - { - *outptr = nim->colorsTotal; - errorptr[0] = 0; - errorptr[1] = 0; - errorptr[2] = 0; - errorptr[3] = 0; - inptr += dir; - outptr += dir; - errorptr += dir3; - continue; - } - /* curN holds the error propagated from the previous pixel on the - * current line. Add the error propagated from the previous line - * to form the complete error correction term for this pixel, and - * round the error term (which is expressed * 16) to an integer. - * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct - * for either sign of the error value. - * Note: errorptr points to *previous* column's array entry. - */ - cur0 = RIGHT_SHIFT (cur0 + errorptr[dir3 + 0] + 8, 4); - cur1 = RIGHT_SHIFT (cur1 + errorptr[dir3 + 1] + 8, 4); - cur2 = RIGHT_SHIFT (cur2 + errorptr[dir3 + 2] + 8, 4); - /* Limit the error using transfer function set by init_error_limit. - * See comments with init_error_limit for rationale. - */ - cur0 = error_limit[cur0]; - cur1 = error_limit[cur1]; - cur2 = error_limit[cur2]; - /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. - * The maximum error is +- MAXJSAMPLE (or less with error limiting); - * this sets the required size of the range_limit array. - */ - cur0 += gdTrueColorGetRed (*inptr); - cur1 += gdTrueColorGetGreen (*inptr); - cur2 += gdTrueColorGetBlue (*inptr); - range_limit (cur0); - range_limit (cur1); - range_limit (cur2); - - /* Index into the cache with adjusted pixel value */ - cachep = - &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT]; - /* If we have not seen this color before, find nearest colormap */ - /* entry and update the cache */ - if (*cachep == 0) - fill_inverse_cmap (oim, nim, cquantize, cur0 >> C0_SHIFT, - cur1 >> C1_SHIFT, cur2 >> C2_SHIFT); - /* Now emit the colormap index for this cell */ - { - register int pixcode = *cachep - 1; - *outptr = (JSAMPLE) pixcode; - /* Compute representation error for this pixel */ + inptr = input_buf[row]; + outptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + inptr += (width - 1) * 3; /* so point to rightmost pixel */ + outptr += width - 1; + dir = -1; + dir3 = -3; + errorptr = cquantize->fserrors + (width + 1) * 3; /* => entry after last column */ + } else { + /* work left to right in this row */ + dir = 1; + dir3 = 3; + errorptr = cquantize->fserrors; /* => entry before first real column */ + } + /* Preset error values: no error propagated to first pixel from left */ + cur0 = cur1 = cur2 = 0; + /* and no error propagated to row below yet */ + belowerr0 = belowerr1 = belowerr2 = 0; + bpreverr0 = bpreverr1 = bpreverr2 = 0; + + for (col = width; col > 0; col--) { + + /* If this pixel is transparent, we want to assign it to the special + * transparency color index past the end of the palette rather than + * go through matching / dithering. */ + if ((oim->transparent >= 0) && (*inptr == oim->transparent)) { + *outptr = nim->colorsTotal; + errorptr[0] = 0; + errorptr[1] = 0; + errorptr[2] = 0; + errorptr[3] = 0; + inptr += dir; + outptr += dir; + errorptr += dir3; + continue; + } + /* curN holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3 + 0] + 8, 4); + cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3 + 1] + 8, 4); + cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3 + 2] + 8, 4); + /* Limit the error using transfer function set by init_error_limit. + * See comments with init_error_limit for rationale. + */ + cur0 = error_limit[cur0]; + cur1 = error_limit[cur1]; + cur2 = error_limit[cur2]; + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE (or less with error limiting); + * this sets the required size of the range_limit array. + */ + cur0 += gdTrueColorGetRed(*inptr); + cur1 += gdTrueColorGetGreen(*inptr); + cur2 += gdTrueColorGetBlue(*inptr); + range_limit(cur0); + range_limit(cur1); + range_limit(cur2); + + /* Index into the cache with adjusted pixel value */ + cachep = &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT]; + /* If we have not seen this color before, find nearest colormap */ + /* entry and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(oim, nim, cquantize, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, + cur2 >> C2_SHIFT); + /* Now emit the colormap index for this cell */ + { + register int pixcode = *cachep - 1; + *outptr = (JSAMPLE)pixcode; + /* Compute representation error for this pixel */ #define GETJSAMPLE - cur0 -= GETJSAMPLE (colormap0[pixcode]); - cur1 -= GETJSAMPLE (colormap1[pixcode]); - cur2 -= GETJSAMPLE (colormap2[pixcode]); + cur0 -= GETJSAMPLE(colormap0[pixcode]); + cur1 -= GETJSAMPLE(colormap1[pixcode]); + cur2 -= GETJSAMPLE(colormap2[pixcode]); #undef GETJSAMPLE - } - /* Compute error fractions to be propagated to adjacent pixels. - * Add these into the running sums, and simultaneously shift the - * next-line error sums left by 1 column. - */ - { - register LOCFSERROR bnexterr, delta; - - bnexterr = cur0; /* Process component 0 */ - delta = cur0 * 2; - cur0 += delta; /* form error * 3 */ - errorptr[0] = (FSERROR) (bpreverr0 + cur0); - cur0 += delta; /* form error * 5 */ - bpreverr0 = belowerr0 + cur0; - belowerr0 = bnexterr; - cur0 += delta; /* form error * 7 */ - bnexterr = cur1; /* Process component 1 */ - delta = cur1 * 2; - cur1 += delta; /* form error * 3 */ - errorptr[1] = (FSERROR) (bpreverr1 + cur1); - cur1 += delta; /* form error * 5 */ - bpreverr1 = belowerr1 + cur1; - belowerr1 = bnexterr; - cur1 += delta; /* form error * 7 */ - bnexterr = cur2; /* Process component 2 */ - delta = cur2 * 2; - cur2 += delta; /* form error * 3 */ - errorptr[2] = (FSERROR) (bpreverr2 + cur2); - cur2 += delta; /* form error * 5 */ - bpreverr2 = belowerr2 + cur2; - belowerr2 = bnexterr; - cur2 += delta; /* form error * 7 */ - } - /* At this point curN contains the 7/16 error value to be propagated - * to the next pixel on the current line, and all the errors for the - * next line have been shifted over. We are therefore ready to move on. - */ - inptr += dir; /* Advance pixel pointers to next column */ - outptr += dir; - errorptr += dir3; /* advance errorptr to current column */ - } - /* Post-loop cleanup: we must unload the final error values into the - * final fserrors[] entry. Note we need not unload belowerrN because - * it is for the dummy column before or after the actual array. - */ - errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ - errorptr[1] = (FSERROR) bpreverr1; - errorptr[2] = (FSERROR) bpreverr2; + } + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + { + register LOCFSERROR bnexterr, delta; + + bnexterr = cur0; /* Process component 0 */ + delta = cur0 * 2; + cur0 += delta; /* form error * 3 */ + errorptr[0] = (FSERROR)(bpreverr0 + cur0); + cur0 += delta; /* form error * 5 */ + bpreverr0 = belowerr0 + cur0; + belowerr0 = bnexterr; + cur0 += delta; /* form error * 7 */ + bnexterr = cur1; /* Process component 1 */ + delta = cur1 * 2; + cur1 += delta; /* form error * 3 */ + errorptr[1] = (FSERROR)(bpreverr1 + cur1); + cur1 += delta; /* form error * 5 */ + bpreverr1 = belowerr1 + cur1; + belowerr1 = bnexterr; + cur1 += delta; /* form error * 7 */ + bnexterr = cur2; /* Process component 2 */ + delta = cur2 * 2; + cur2 += delta; /* form error * 3 */ + errorptr[2] = (FSERROR)(bpreverr2 + cur2); + cur2 += delta; /* form error * 5 */ + bpreverr2 = belowerr2 + cur2; + belowerr2 = bnexterr; + cur2 += delta; /* form error * 7 */ + } + /* At this point curN contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move + * on. + */ + inptr += dir; /* Advance pixel pointers to next column */ + outptr += dir; + errorptr += dir3; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error values into the + * final fserrors[] entry. Note we need not unload belowerrN because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR)bpreverr0; /* unload prev errs into array */ + errorptr[1] = (FSERROR)bpreverr1; + errorptr[2] = (FSERROR)bpreverr2; } } - /* * Initialize the error-limiting transfer function (lookup table). * The raw F-S error computation can potentially compute error values of up to @@ -1368,312 +1280,567 @@ pass2_fs_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) * to Aaron Giles for this idea. */ -LOCAL (void) -init_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) +LOCAL(void) +init_error_limit(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) /* Allocate and fill in the error_limiter table */ { - int *table; - int in, out; - - cquantize->error_limiter_storage = - (int *) safe_emalloc ((MAXJSAMPLE * 2 + 1), sizeof (int), 0); - if (!cquantize->error_limiter_storage) - { - return; + int *table; + int in, out; + (void)oim; + (void)nim; + + cquantize->error_limiter_storage = (int *)gdMalloc((MAXJSAMPLE * 2 + 1) * sizeof(int)); + if (!cquantize->error_limiter_storage) { + return; } - table = cquantize->error_limiter_storage; + table = cquantize->error_limiter_storage; - table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ - cquantize->error_limiter = table; + table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ + cquantize->error_limiter = table; -#define STEPSIZE ((MAXJSAMPLE+1)/16) - /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ - out = 0; - for (in = 0; in < STEPSIZE; in++, out++) - { - table[in] = out; - table[-in] = -out; +#define STEPSIZE ((MAXJSAMPLE + 1) / 16) + /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ + out = 0; + for (in = 0; in < STEPSIZE; in++, out++) { + table[in] = out; + table[-in] = -out; } - /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ - for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) - { - table[in] = out; - table[-in] = -out; + /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ + for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) { + table[in] = out; + table[-in] = -out; } - /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ - for (; in <= MAXJSAMPLE; in++) - { - table[in] = out; - table[-in] = -out; + /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ + for (; in <= MAXJSAMPLE; in++) { + table[in] = out; + table[-in] = -out; } #undef STEPSIZE } - /* * Finish up at the end of each pass. */ -static void -zeroHistogram (hist3d histogram) +static void zeroHistogram(hist3d histogram) { - int i; - /* Zero the histogram or inverse color map */ - for (i = 0; i < HIST_C0_ELEMS; i++) - { - memset (histogram[i], - 0, HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof (histcell)); + int i; + /* Zero the histogram or inverse color map */ + for (i = 0; i < HIST_C0_ELEMS; i++) { + memset(histogram[i], 0, HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof(histcell)); + } +} + +/** + * Function: gdImageTrueColorToPaletteSetMethod + * + * Selects the quantization method + * + * That quantization method is used for all subsequent + * and calls. + * + * Parameters: + * im - The image. + * method - The quantization method, see . + * speed - The quantization speed between 1 (highest quality) and + * 10 (fastest). 0 selects a method-specific default (recommended). + * + * Returns: + * Zero if the given method is invalid or not available; non-zero otherwise. + * + * See also: + * - + */ +BGD_DECLARE(int) +gdImageTrueColorToPaletteSetMethod(gdImagePtr im, int method, int speed) +{ +#ifndef HAVE_LIBIMAGEQUANT + if (method == GD_QUANT_LIQ) { + return FALSE; + } +#endif + + if (method >= GD_QUANT_DEFAULT && method <= GD_QUANT_LIQ) { + im->paletteQuantizationMethod = method; + + if (speed < 0 || speed > 10) { + speed = 0; + } + im->paletteQuantizationSpeed = speed; + } + return TRUE; +} + +/** + * Function: gdImageTrueColorToPaletteSetQuality + * + * Chooses a quality range for quantization + * + * That quality range is used in all subsequent calls to + * and + * if the quantization method is . + * + * Parameters: + * im - The image. + * min_quality - The minimum quality in range 1-100 (1 = ugly, 100 = perfect). + * If the palette cannot represent the image with at least + * min_quality, then no conversion is done. + * max_quality - The maximum quality in range 1-100 (1 = ugly, 100 = perfect), + * which must be higher than the min_quality. If the palette can + * represent the image with a quality better than max_quality, + * then fewer colors than requested will be used. + */ +BGD_DECLARE(void) +gdImageTrueColorToPaletteSetQuality(gdImagePtr im, int min_quality, int max_quality) +{ + if (min_quality >= 0 && min_quality <= 100 && max_quality >= 0 && max_quality <= 100 && + min_quality <= max_quality) { + im->paletteQuantizationMinQuality = min_quality; + im->paletteQuantizationMaxQuality = max_quality; + } +} + +static int gdImageTrueColorToPaletteBody(gdImagePtr oim, int dither, int colorsWanted, + gdImagePtr *cimP); + +/** + * Function: gdImageCreatePaletteFromTrueColor + * + * Creates a new palette image from a truecolor image + * + * Parameters: + * im - The image. + * dither - Whether dithering should be applied. + * colorsWanted - The number of desired palette entries. + * + * Returns: + * A newly create palette image; NULL on failure. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(gdImagePtr) +gdImageCreatePaletteFromTrueColor(gdImagePtr im, int dither, int colorsWanted) +{ + gdImagePtr nim; + if (TRUE == gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim)) { + return nim; } + return NULL; } -static int gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP); +/** + * Function: gdImageTrueColorToPalette + * + * Converts a truecolor image to a palette image + * + * Parameters: + * im - The image. + * dither - Whether dithering should be applied. + * colorsWanted - The number of desired palette entries. + * + * Returns: + * Non-zero if the conversion succeeded, zero otherwise. + * + * See also: + * - + * - + * - + */ +BGD_DECLARE(int) +gdImageTrueColorToPalette(gdImagePtr im, int dither, int colorsWanted) +{ + return gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0); +} -gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int dither, int colorsWanted) +#ifdef HAVE_LIBIMAGEQUANT +/** + LIQ library needs pixels in RGBA order with alpha 0-255 (opaque 255). + This callback is run whenever source rows need to be converted from GD's + format. +*/ +static void convert_gdpixel_to_rgba(liq_color output_row[], int y, int width, void *userinfo) { - gdImagePtr nim; - if (TRUE == gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim)) { - return nim; - } - return NULL; + gdImagePtr oim = userinfo; + int x; + for (x = 0; x < width; x++) { + int pixel = input_buf[y][x]; + output_row[x].r = gdTrueColorGetRed(pixel) * 255 / gdRedMax; + output_row[x].g = gdTrueColorGetGreen(pixel) * 255 / gdGreenMax; + output_row[x].b = gdTrueColorGetBlue(pixel) * 255 / gdBlueMax; + if (oim->transparent >= 0 && pixel == oim->transparent) { + output_row[x].a = 0; + } else { + int alpha = gdTrueColorGetAlpha(pixel); + if (gdAlphaOpaque < gdAlphaTransparent) { + alpha = gdAlphaTransparent - alpha; + } + output_row[x].a = alpha * 255 / gdAlphaMax; + } + } } +#endif -int gdImageTrueColorToPalette (gdImagePtr im, int dither, int colorsWanted) +static int ensure_transparent_palette_entry(gdImagePtr im, int transparentColor) { - return gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0); + int transparent; + + if (transparentColor < 0) { + return -1; + } + + transparent = im->transparent; + if (transparent >= 0 && transparent < im->colorsTotal) { + im->alpha[transparent] = gdAlphaTransparent; + return transparent; + } + + if (im->colorsTotal >= gdMaxColors) { + return -1; + } + + transparent = im->colorsTotal; + im->red[transparent] = gdTrueColorGetRed(transparentColor); + im->green[transparent] = gdTrueColorGetGreen(transparentColor); + im->blue[transparent] = gdTrueColorGetBlue(transparentColor); + im->alpha[transparent] = gdAlphaTransparent; + im->open[transparent] = 0; + im->transparent = transparent; + im->colorsTotal++; + + return transparent; +} + +static void remap_transparent_pixels(gdImagePtr src, gdImagePtr dst, int transparentColor, + int transparentIndex) +{ + int x, y; + + if (transparentColor < 0 || transparentIndex < 0) { + return; + } + + for (y = 0; y < src->sy; y++) { + for (x = 0; x < src->sx; x++) { + if (src->tpixels[y][x] == transparentColor) { + dst->pixels[y][x] = transparentIndex; + } + } + } +} + +static void copy_palette_image_data(gdImagePtr dst, gdImagePtr src) +{ + int i, y; + + for (y = 0; y < src->sy; y++) { + memcpy(dst->pixels[y], src->pixels[y], src->sx); + } + + dst->trueColor = 0; + dst->colorsTotal = src->colorsTotal; + dst->transparent = src->transparent; + for (i = 0; i < gdMaxColors; i++) { + dst->red[i] = src->red[i]; + dst->green[i] = src->green[i]; + dst->blue[i] = src->blue[i]; + dst->alpha[i] = src->alpha[i]; + dst->open[i] = src->open[i]; + } } static void free_truecolor_image_data(gdImagePtr oim) { - int i; - oim->trueColor = 0; - /* Junk the truecolor pixels */ - for (i = 0; i < oim->sy; i++) - { - gdFree (oim->tpixels[i]); + int i; + oim->trueColor = 0; + /* Junk the truecolor pixels */ + for (i = 0; i < oim->sy; i++) { + gdFree(oim->tpixels[i]); } - gdFree (oim->tpixels); - oim->tpixels = 0; + gdFree(oim->tpixels); + oim->tpixels = 0; } +#ifdef HAVE_LIBIMAGEQUANT +/* liq requires 16 byte aligned heap memory */ +static void *malloc16(size_t size) +{ +#ifndef _WIN32 + void *p; + return posix_memalign(&p, 16, size) == 0 ? p : NULL; +#else + return _aligned_malloc(size, 16); +#endif +} +static void free16(void *ptr) +{ +#ifndef _WIN32 + free(ptr); +#else + _aligned_free(ptr); +#endif +} +#endif + /* * Module initialization routine for 2-pass color quantization. */ -static int gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP) +static int gdImageTrueColorToPaletteBody(gdImagePtr oim, int dither, int colorsWanted, + gdImagePtr *cimP) { - my_cquantize_ptr cquantize = NULL; - int i, conversionSucceeded=0; - - /* Allocate the JPEG palette-storage */ - size_t arraysize; - int maxColors = gdMaxColors; - gdImagePtr nim; - if (cimP) { - nim = gdImageCreate(oim->sx, oim->sy); - *cimP = nim; - if (!nim) { - return FALSE; - } - } else { - nim = oim; - } - if (!oim->trueColor) - { - /* (Almost) nothing to do! */ - if (cimP) { - gdImageCopy(nim, oim, 0, 0, 0, 0, oim->sx, oim->sy); + my_cquantize_ptr cquantize = NULL; + int i, conversionSucceeded = 0; + int transparentColor; + + /* Allocate the JPEG palette-storage */ + size_t arraysize; + int maxColors = gdMaxColors; + gdImagePtr nim; + + if (cimP) { + nim = gdImageCreate(oim->sx, oim->sy); *cimP = nim; - } - return TRUE; + if (!nim) { + return FALSE; + } + } else { + nim = oim; } - /* If we have a transparent color (the alphaless mode of transparency), we - * must reserve a palette entry for it at the end of the palette. */ - if (oim->transparent >= 0) - { - maxColors--; + if (!oim->trueColor) { + /* (Almost) nothing to do! */ + if (cimP) { + gdImageCopy(nim, oim, 0, 0, 0, 0, oim->sx, oim->sy); + *cimP = nim; + } + return TRUE; } - if (colorsWanted > maxColors) - { - colorsWanted = maxColors; + + transparentColor = oim->transparent; + + /* If we have a transparent color (the alphaless mode of transparency), we + * must reserve a palette entry for it at the end of the palette. */ + if (transparentColor >= 0) { + maxColors--; } - if (!cimP) { - nim->pixels = gdCalloc (oim->sy, sizeof (unsigned char *)); - if (!nim->pixels) - { - /* No can do */ - goto outOfMemory; - } - for (i = 0; (i < nim->sy); i++) - { - nim->pixels[i] = gdCalloc (oim->sx, sizeof (unsigned char *)); - if (!nim->pixels[i]) - { - goto outOfMemory; - } - } - } - - cquantize = (my_cquantize_ptr) gdCalloc (1, sizeof (my_cquantizer)); - if (!cquantize) - { - /* No can do */ - goto outOfMemory; + if (colorsWanted > maxColors) { + colorsWanted = maxColors; + } + if (!cimP) { + nim->pixels = gdCalloc(sizeof(unsigned char *), oim->sy); + if (!nim->pixels) { + /* No can do */ + goto outOfMemory; + } + for (i = 0; (i < nim->sy); i++) { + nim->pixels[i] = (unsigned char *)gdCalloc(sizeof(unsigned char), oim->sx); + if (!nim->pixels[i]) { + goto outOfMemory; + } + } } - cquantize->fserrors = NULL; /* flag optional arrays not allocated */ - cquantize->error_limiter = NULL; - - /* Allocate the histogram/inverse colormap storage */ - cquantize->histogram = (hist3d) safe_emalloc (HIST_C0_ELEMS, sizeof (hist2d), 0); - for (i = 0; i < HIST_C0_ELEMS; i++) - { - cquantize->histogram[i] = - (hist2d) safe_emalloc (HIST_C1_ELEMS * HIST_C2_ELEMS, sizeof (histcell), 0); - if (!cquantize->histogram[i]) - { - goto outOfMemory; - } + if (oim->paletteQuantizationMethod == GD_QUANT_NEUQUANT) { + if (cimP) { /* NeuQuant always creates a copy, so the new blank image + can't be used */ + gdImageDestroy(nim); + } + nim = gdImageNeuQuant(oim, colorsWanted, + oim->paletteQuantizationSpeed ? oim->paletteQuantizationSpeed : 2); + if (!nim) { + return FALSE; + } + if (transparentColor >= 0) { + int transparent = ensure_transparent_palette_entry(nim, transparentColor); + if (transparent < 0) { + gdImageDestroy(nim); + return FALSE; + } + remap_transparent_pixels(oim, nim, transparentColor, transparent); + } + if (cimP) { + *cimP = nim; + return TRUE; + } + free_truecolor_image_data(oim); + copy_palette_image_data(oim, nim); + gdImageDestroy(nim); + return TRUE; } - cquantize->fserrors = (FSERRPTR) safe_emalloc (3, sizeof (FSERROR), 0); - init_error_limit (oim, nim, cquantize); - arraysize = (size_t) ((nim->sx + 2) * (3 * sizeof (FSERROR))); - /* Allocate Floyd-Steinberg workspace. */ - cquantize->fserrors = gdRealloc(cquantize->fserrors, arraysize); - memset(cquantize->fserrors, 0, arraysize); - if (!cquantize->fserrors) - { - goto outOfMemory; +#ifdef HAVE_LIBIMAGEQUANT + if (oim->paletteQuantizationMethod == GD_QUANT_DEFAULT || + oim->paletteQuantizationMethod == GD_QUANT_LIQ) { + liq_attr *attr = liq_attr_create_with_allocator(malloc16, free16); + liq_image *image; + liq_result *remap; + int remapped_ok = 0; + + liq_set_max_colors(attr, colorsWanted); + + /* by default make it fast to match speed of previous implementation */ + liq_set_speed(attr, oim->paletteQuantizationSpeed ? oim->paletteQuantizationSpeed : 9); + if (oim->paletteQuantizationMaxQuality) { + liq_set_quality(attr, oim->paletteQuantizationMinQuality, + oim->paletteQuantizationMaxQuality); + } + image = liq_image_create_custom(attr, convert_gdpixel_to_rgba, oim, oim->sx, oim->sy, 0); + remap = liq_quantize_image(attr, image); + if (!remap) { /* minimum quality not met, leave image unmodified */ + liq_image_destroy(image); + liq_attr_destroy(attr); + goto outOfMemory; + } + + liq_set_dithering_level(remap, dither ? 1 : 0); + if (LIQ_OK == liq_write_remapped_image_rows(remap, image, output_buf)) { + remapped_ok = 1; + const liq_palette *pal = liq_get_palette(remap); + nim->transparent = -1; + unsigned int icolor; + for (icolor = 0; icolor < pal->count; icolor++) { + nim->open[icolor] = 0; + nim->red[icolor] = pal->entries[icolor].r * gdRedMax / 255; + nim->green[icolor] = pal->entries[icolor].g * gdGreenMax / 255; + nim->blue[icolor] = pal->entries[icolor].b * gdBlueMax / 255; + int alpha = pal->entries[icolor].a * gdAlphaMax / 255; + if (gdAlphaOpaque < gdAlphaTransparent) { + alpha = gdAlphaTransparent - alpha; + } + nim->alpha[icolor] = alpha; + if (nim->transparent == -1 && alpha == gdAlphaTransparent) { + nim->transparent = icolor; + } + } + nim->colorsTotal = pal->count; + if (transparentColor >= 0) { + int transparent = ensure_transparent_palette_entry(nim, transparentColor); + if (transparent >= 0) { + remap_transparent_pixels(oim, nim, transparentColor, transparent); + } else { + remapped_ok = 0; + } + } + } + liq_result_destroy(remap); + liq_image_destroy(image); + liq_attr_destroy(attr); + + if (remapped_ok) { + if (!cimP) { + free_truecolor_image_data(oim); + } + return TRUE; + } } - cquantize->on_odd_row = FALSE; - - /* Do the work! */ - zeroHistogram (cquantize->histogram); - prescan_quantize (oim, nim, cquantize); - /* TBB 2.0.5: pass colorsWanted, not 256! */ - select_colors (oim, nim, cquantize, colorsWanted); - zeroHistogram (cquantize->histogram); - if (dither) - { - pass2_fs_dither (oim, nim, cquantize); +#endif + + cquantize = (my_cquantize_ptr)gdCalloc(sizeof(my_cquantizer), 1); + if (!cquantize) { + /* No can do */ + goto outOfMemory; } - else - { - pass2_no_dither (oim, nim, cquantize); + cquantize->fserrors = NULL; /* flag optional arrays not allocated */ + cquantize->error_limiter = NULL; + + /* Allocate the histogram/inverse colormap storage */ + cquantize->histogram = (hist3d)gdMalloc(HIST_C0_ELEMS * sizeof(hist2d)); + for (i = 0; i < HIST_C0_ELEMS; i++) { + cquantize->histogram[i] = + (hist2d)gdMalloc(HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof(histcell)); + if (!cquantize->histogram[i]) { + goto outOfMemory; + } } -#if 0 /* 2.0.12; we no longer attempt full alpha in palettes */ - if (cquantize->transparentIsPresent) - { - int mt = -1; - int mtIndex = -1; - for (i = 0; (i < im->colorsTotal); i++) - { - if (im->alpha[i] > mt) - { - mtIndex = i; - mt = im->alpha[i]; - } - } - for (i = 0; (i < im->colorsTotal); i++) - { - if (im->alpha[i] == mt) - { - im->alpha[i] = gdAlphaTransparent; - } - } + + cquantize->fserrors = (FSERRPTR)gdMalloc(3 * sizeof(FSERROR)); + init_error_limit(oim, nim, cquantize); + arraysize = (size_t)((nim->sx + 2) * (3 * sizeof(FSERROR))); + /* Allocate Floyd-Steinberg workspace. */ + cquantize->fserrors = gdReallocEx(cquantize->fserrors, arraysize); + if (!cquantize->fserrors) { + goto outOfMemory; } - if (cquantize->opaqueIsPresent) - { - int mo = 128; - int moIndex = -1; - for (i = 0; (i < im->colorsTotal); i++) - { - if (im->alpha[i] < mo) - { - moIndex = i; - mo = im->alpha[i]; - } - } - for (i = 0; (i < im->colorsTotal); i++) - { - if (im->alpha[i] == mo) - { - im->alpha[i] = gdAlphaOpaque; - } - } + memset(cquantize->fserrors, 0, arraysize); + cquantize->on_odd_row = FALSE; + + /* Do the work! */ + zeroHistogram(cquantize->histogram); + prescan_quantize(oim, nim, cquantize); + /* TBB 2.0.5: pass colorsWanted, not 256! */ + select_colors(oim, nim, cquantize, colorsWanted); + zeroHistogram(cquantize->histogram); + if (dither) { + if (cquantize->error_limiter == NULL) { + goto outOfMemory; + } + pass2_fs_dither(oim, nim, cquantize); + } else { + pass2_no_dither(oim, nim, cquantize); } -#endif - /* If we had a 'transparent' color, increment the color count so it's - * officially in the palette and convert the transparent variable to point to - * an index rather than a color (Its data already exists and transparent - * pixels have already been mapped to it by this point, it is done late as to - * avoid color matching / dithering with it). */ - if (oim->transparent >= 0) - { - nim->transparent = nim->colorsTotal; - nim->colorsTotal++; + /* If we had a 'transparent' color, increment the color count so it's + * officially in the palette and convert the transparent variable to point + * to an index rather than a color (Its data already exists and transparent + * pixels have already been mapped to it by this point, it is done late as + * to avoid color matching / dithering with it). */ + if (transparentColor >= 0) { + nim->transparent = nim->colorsTotal; + nim->colorsTotal++; } - /* Success! Get rid of the truecolor image data. */ - conversionSucceeded = TRUE; - if (!cimP) - { - free_truecolor_image_data(oim); + /* Success! Get rid of the truecolor image data. */ + conversionSucceeded = TRUE; + if (!cimP) { + free_truecolor_image_data(oim); } - goto freeQuantizeData; - /* Tediously free stuff. */ + goto freeQuantizeData; + /* Tediously free stuff. */ outOfMemory: - conversionSucceeded = FALSE; - if (oim->trueColor) - { - if (!cimP) { - /* On failure only */ - for (i = 0; i < nim->sy; i++) - { - if (nim->pixels[i]) - { - gdFree (nim->pixels[i]); - } - } - if (nim->pixels) - { - gdFree (nim->pixels); - } - nim->pixels = 0; - } else { - gdImageDestroy(nim); - *cimP = 0; - } + conversionSucceeded = FALSE; + if (oim->trueColor) { + if (!cimP) { + /* On failure only */ + if (nim->pixels) { + for (i = 0; i < nim->sy; i++) { + if (nim->pixels[i]) { + gdFree(nim->pixels[i]); + } + } + gdFree(nim->pixels); + } + nim->pixels = NULL; + } else { + gdImageDestroy(nim); + *cimP = 0; + } } + freeQuantizeData: - for (i = 0; i < HIST_C0_ELEMS; i++) - { - if (cquantize->histogram[i]) - { - gdFree (cquantize->histogram[i]); - } - } - if (cquantize->histogram) - { - gdFree (cquantize->histogram); - } - if (cquantize->fserrors) - { - gdFree (cquantize->fserrors); + if (cquantize) { + if (cquantize->histogram) { + for (i = 0; i < HIST_C0_ELEMS; i++) { + if (cquantize->histogram[i]) { + gdFree(cquantize->histogram[i]); + } + } + } + if (cquantize->histogram) { + gdFree(cquantize->histogram); + } + if (cquantize->fserrors) { + gdFree(cquantize->fserrors); + } + if (cquantize->error_limiter_storage) { + gdFree(cquantize->error_limiter_storage); + } + gdFree(cquantize); } - if (cquantize->error_limiter_storage) - { - gdFree (cquantize->error_limiter_storage); - } - if (cquantize) - { - gdFree (cquantize); - } - return conversionSucceeded; + return conversionSucceeded; } - #endif diff --git a/ext/gd/libgd/gd_transform.c b/ext/gd/libgd/gd_transform.c index 9051525eecca..0b125398b88c 100644 --- a/ext/gd/libgd/gd_transform.c +++ b/ext/gd/libgd/gd_transform.c @@ -1,73 +1,121 @@ +/** + * File: Transformations + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "gd.h" -void gdImageFlipVertical(gdImagePtr im) +/** + * Function: gdImageFlipVertical + * + * Flip an image vertically + * + * The image is mirrored upside-down. + * + * Parameters: + * im - The image. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) gdImageFlipVertical(gdImagePtr im) { - register int x, y; + register int x, y; - if (im->trueColor) { - for (y = 0; y < im->sy / 2; y++) { - int *row_dst = im->tpixels[y]; - int *row_src = im->tpixels[im->sy - 1 - y]; - for (x = 0; x < im->sx; x++) { - register int p; - p = row_dst[x]; - row_dst[x] = im->tpixels[im->sy - 1 - y][x]; - row_src[x] = p; - } - } - } else { - unsigned char p; - for (y = 0; y < im->sy / 2; y++) { - for (x = 0; x < im->sx; x++) { - p = im->pixels[y][x]; - im->pixels[y][x] = im->pixels[im->sy - 1 - y][x]; - im->pixels[im->sy - 1 - y][x] = p; - } - } - } - return; + if (im->trueColor) { + for (y = 0; y < im->sy / 2; y++) { + int *row_dst = im->tpixels[y]; + int *row_src = im->tpixels[im->sy - 1 - y]; + for (x = 0; x < im->sx; x++) { + register int p; + p = row_dst[x]; + row_dst[x] = im->tpixels[im->sy - 1 - y][x]; + row_src[x] = p; + } + } + } else { + unsigned char p; + for (y = 0; y < im->sy / 2; y++) { + for (x = 0; x < im->sx; x++) { + p = im->pixels[y][x]; + im->pixels[y][x] = im->pixels[im->sy - 1 - y][x]; + im->pixels[im->sy - 1 - y][x] = p; + } + } + } + return; } -void gdImageFlipHorizontal(gdImagePtr im) +/** + * Function: gdImageFlipHorizontal + * + * Flip an image horizontally + * + * The image is mirrored left-right. + * + * Parameters: + * im - The image. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) gdImageFlipHorizontal(gdImagePtr im) { - int x, y; + int x, y; - if (im->trueColor) { - int *px1, *px2, tmp; + if (im->trueColor) { + int *px1, *px2, tmp; - for (y = 0; y < im->sy; y++) { - px1 = im->tpixels[y]; - px2 = im->tpixels[y] + im->sx - 1; - for (x = 0; x < (im->sx >> 1); x++) { - tmp = *px1; - *px1 = *px2; - *px2 = tmp; - px1++; - px2--; - } - } - } else { - unsigned char *px1, *px2, tmp; + for (y = 0; y < im->sy; y++) { + px1 = im->tpixels[y]; + px2 = im->tpixels[y] + im->sx - 1; + for (x = 0; x < (im->sx >> 1); x++) { + tmp = *px1; + *px1 = *px2; + *px2 = tmp; + px1++; + px2--; + } + } + } else { + unsigned char *px1, *px2, tmp; - for (y = 0; y < im->sy; y++) { - px1 = im->pixels[y]; - px2 = im->pixels[y] + im->sx - 1; - for (x = 0; x < (im->sx >> 1); x++) { - tmp = *px1; - *px1 = *px2; - *px2 = tmp; - px1++; - px2--; - } - } - } + for (y = 0; y < im->sy; y++) { + px1 = im->pixels[y]; + px2 = im->pixels[y] + im->sx - 1; + for (x = 0; x < (im->sx >> 1); x++) { + tmp = *px1; + *px1 = *px2; + *px2 = tmp; + px1++; + px2--; + } + } + } } -void gdImageFlipBoth(gdImagePtr im) +/** + * Function: gdImageFlipBoth + * + * Flip an image vertically and horizontally + * + * The image is mirrored upside-down and left-right. + * + * Parameters: + * im - The image. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) gdImageFlipBoth(gdImagePtr im) { - gdImageFlipVertical(im); - gdImageFlipHorizontal(im); + gdImageFlipVertical(im); + gdImageFlipHorizontal(im); } - - diff --git a/ext/gd/libgd/gd_uhdr.c b/ext/gd/libgd/gd_uhdr.c new file mode 100644 index 000000000000..8417032ff9b9 --- /dev/null +++ b/ext/gd/libgd/gd_uhdr.c @@ -0,0 +1,1321 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/** + * File: UltraHDR IO + * + * Read and write UltraHDR images with gain map preservation. + */ + +#include +#include +#include +#include + +#include "gd.h" +#include "gd_errors.h" +#include "gd_intern.h" +#include "gdhelpers.h" + +#ifdef HAVE_LIBUHDR +#include +#endif + +typedef enum { + GD_UHDR_OP_RESIZE = 0, + GD_UHDR_OP_CROP, + GD_UHDR_OP_ROTATE, + GD_UHDR_OP_MIRROR +} gdUhdrOpType; + +typedef struct { + gdUhdrOpType type; + int p1; + int p2; + int p3; + int p4; +} gdUhdrOp; + +struct gdUhdrImageStruct { + int format; + int width; + int height; + int has_gain_map; + void *blob; + int blob_size; + gdUhdrOp *ops; + int op_count; + int op_capacity; +}; + +static void gdUhdrSetError(gdUhdrErrorPtr err, int code, int provider_code, const char *message) +{ + if (!err) { + return; + } + + err->code = code; + err->provider_code = provider_code; + err->message[0] = '\0'; + if (message) { + strncpy(err->message, message, sizeof(err->message) - 1); + err->message[sizeof(err->message) - 1] = '\0'; + } +} + +#ifdef HAVE_LIBUHDR + +static int gdUhdrIsSupportedFormat(int format) { return format == GD_UHDR_FORMAT_JPEG; } + +static int gdUhdrIntAddOverflow(int a, int b) +{ + if (a < 0 || b < 0) { + return 1; + } + + if (a > INT_MAX - b) { + return 1; + } + + return 0; +} + +static int gdUhdrReadAllFromCtx(gdIOCtxPtr ctx, void **out_data, int *out_size) +{ + const int step = 4096; + unsigned char buf[4096]; + unsigned char *data = NULL; + int size = 0; + + if (!ctx || !out_data || !out_size) { + return GD_UHDR_E_INVALID; + } + + for (;;) { + int n = gdGetBuf(buf, step, ctx); + int new_size; + if (n <= 0) { + break; + } + + if (gdUhdrIntAddOverflow(size, n)) { + gd_error("gd-uhdr read size overflow: size=%d n=%d\n", size, n); + gdFree(data); + return GD_UHDR_E_INVALID; + } + + new_size = size + n; + + { + unsigned char *tmp = (unsigned char *)gdRealloc(data, (size_t)new_size); + if (!tmp) { + gd_error("gd-uhdr realloc failed: requested=%d\n", new_size); + gdFree(data); + return GD_UHDR_E_DECODE; + } + data = tmp; + } + + memcpy(data + size, buf, (size_t)n); + size = new_size; + } + + if (!data || size <= 0) { + gdFree(data); + return GD_UHDR_E_DECODE; + } + + *out_data = data; + *out_size = size; + return GD_UHDR_SUCCESS; +} + +static void gdUhdrInitCompressedImage(uhdr_compressed_image_t *image, void *data, int size) +{ + memset(image, 0, sizeof(*image)); + image->data = data; + image->data_sz = (size_t)size; + image->capacity = (size_t)size; + image->cg = UHDR_CG_UNSPECIFIED; + image->ct = UHDR_CT_UNSPECIFIED; + image->range = UHDR_CR_FULL_RANGE; +} + +static int gdUhdrCopyMetadataProfile(gdImageMetadata **dst, const gdImageMetadata *src, + const char *key, gdUhdrErrorPtr err) +{ + const unsigned char *profile; + size_t profile_size; + int status; + + profile = gdImageMetadataGetProfile(src, key, &profile_size); + if (!profile) { + return GD_UHDR_SUCCESS; + } + + if (!*dst) { + *dst = gdImageMetadataCreate(); + if (!*dst) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Out of memory copying JPEG metadata"); + return GD_UHDR_E_ENCODE; + } + } + + status = gdImageMetadataSetProfile(*dst, key, profile, profile_size); + if (status != GD_META_OK) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, status, "Failed to copy JPEG metadata"); + return GD_UHDR_E_ENCODE; + } + + return GD_UHDR_SUCCESS; +} + +static int gdUhdrCreateJpegMetadataFromBlock(uhdr_mem_block_t *block, int copy_exif, int copy_icc, + gdImageMetadata **out, gdUhdrErrorPtr err) +{ + gdImageMetadata *src_metadata; + gdImagePtr decoded; + int status; + + *out = NULL; + if (!block || !block->data || block->data_sz == 0) { + return GD_UHDR_SUCCESS; + } + if (block->data_sz > (size_t)INT_MAX) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "JPEG metadata block is too large"); + return GD_UHDR_E_INVALID; + } + + src_metadata = gdImageMetadataCreate(); + if (!src_metadata) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Out of memory reading JPEG metadata"); + return GD_UHDR_E_ENCODE; + } + + decoded = gdImageCreateFromJpegPtrWithMetadata((int)block->data_sz, block->data, src_metadata); + if (!decoded) { + gdImageMetadataFree(src_metadata); + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to read JPEG metadata"); + return GD_UHDR_E_DECODE; + } + gdImageDestroy(decoded); + + if (copy_exif) { + status = gdUhdrCopyMetadataProfile(out, src_metadata, "exif", err); + if (status != GD_UHDR_SUCCESS) { + gdImageMetadataFree(src_metadata); + return status; + } + } + if (copy_icc) { + status = gdUhdrCopyMetadataProfile(out, src_metadata, "icc", err); + if (status != GD_UHDR_SUCCESS) { + gdImageMetadataFree(src_metadata); + return status; + } + } + + gdImageMetadataFree(src_metadata); + return GD_UHDR_SUCCESS; +} + +static gdImagePtr gdUhdrCreateGdImageFromJpegBlock(uhdr_mem_block_t *block, const char *label, + gdUhdrErrorPtr err) +{ + gdImagePtr image; + + if (!block || !block->data || block->data_sz == 0 || block->data_sz > (size_t)INT_MAX) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Invalid compressed UltraHDR component"); + return NULL; + } + + image = gdImageCreateFromJpegPtr((int)block->data_sz, block->data); + if (!image) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, + label && label[0] ? label : "Failed to decode UltraHDR JPEG component"); + return NULL; + } + + return image; +} + +static int gdUhdrScaleValue(int value, int from_extent, int to_extent, int *out) +{ + long long scaled; + + if (!out || value < 0 || from_extent <= 0 || to_extent <= 0) { + return 0; + } + + scaled = ((long long)value * (long long)to_extent + from_extent / 2) / from_extent; + if (scaled < 0 || scaled > INT_MAX) { + return 0; + } + + *out = (int)scaled; + return 1; +} + +static int gdUhdrReplaceImage(gdImagePtr *image, gdImagePtr replacement, gdUhdrErrorPtr err) +{ + if (!replacement) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to transform UltraHDR image component"); + return GD_UHDR_E_ENCODE; + } + + gdImageDestroy(*image); + *image = replacement; + return GD_UHDR_SUCCESS; +} + +static gdImagePtr gdUhdrScaleImage(gdImagePtr image, unsigned int width, unsigned int height) +{ + /* Mitchell uses GD's two-pass scaler and reduces downscale aliasing. */ + if (!gdImageSetInterpolationMethod(image, GD_MITCHELL)) { + return NULL; + } + + return gdImageScale(image, width, height); +} + +static int gdUhdrApplyGdOps(gdImagePtr *base_image, gdImagePtr *gainmap_image, gdUhdrImagePtr im, + gdUhdrErrorPtr err) +{ + int i; + + if (!base_image || !*base_image || !gainmap_image || !*gainmap_image || !im) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR transform state"); + return GD_UHDR_E_INVALID; + } + + for (i = 0; i < im->op_count; i++) { + gdUhdrOp *op = &im->ops[i]; + int base_w = gdImageSX(*base_image); + int base_h = gdImageSY(*base_image); + int gain_w = gdImageSX(*gainmap_image); + int gain_h = gdImageSY(*gainmap_image); + int status; + + switch (op->type) { + case GD_UHDR_OP_RESIZE: { + int scaled_gain_w; + int scaled_gain_h; + + if (!gdUhdrScaleValue(op->p1, base_w, gain_w, &scaled_gain_w) || + !gdUhdrScaleValue(op->p2, base_h, gain_h, &scaled_gain_h)) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR resize operation"); + return GD_UHDR_E_INVALID; + } + if (scaled_gain_w <= 0) { + scaled_gain_w = 1; + } + if (scaled_gain_h <= 0) { + scaled_gain_h = 1; + } + + status = gdUhdrReplaceImage( + base_image, + gdUhdrScaleImage(*base_image, (unsigned int)op->p1, (unsigned int)op->p2), err); + if (status != GD_UHDR_SUCCESS) { + return status; + } + status = + gdUhdrReplaceImage(gainmap_image, + gdUhdrScaleImage(*gainmap_image, (unsigned int)scaled_gain_w, + (unsigned int)scaled_gain_h), + err); + if (status != GD_UHDR_SUCCESS) { + return status; + } + break; + } + case GD_UHDR_OP_CROP: { + gdRect base_crop; + gdRect gain_crop; + int gain_left; + int gain_right; + int gain_top; + int gain_bottom; + + if (op->p1 < 0 || op->p3 < 0 || op->p2 <= op->p1 || op->p4 <= op->p3 || + op->p2 > base_w || op->p4 > base_h) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR crop operation"); + return GD_UHDR_E_INVALID; + } + if (!gdUhdrScaleValue(op->p1, base_w, gain_w, &gain_left) || + !gdUhdrScaleValue(op->p2, base_w, gain_w, &gain_right) || + !gdUhdrScaleValue(op->p3, base_h, gain_h, &gain_top) || + !gdUhdrScaleValue(op->p4, base_h, gain_h, &gain_bottom) || + gain_right <= gain_left || gain_bottom <= gain_top) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, + "Invalid UltraHDR gain map crop operation"); + return GD_UHDR_E_INVALID; + } + + base_crop.x = op->p1; + base_crop.y = op->p3; + base_crop.width = op->p2 - op->p1; + base_crop.height = op->p4 - op->p3; + gain_crop.x = gain_left; + gain_crop.y = gain_top; + gain_crop.width = gain_right - gain_left; + gain_crop.height = gain_bottom - gain_top; + + status = gdUhdrReplaceImage(base_image, gdImageCrop(*base_image, &base_crop), err); + if (status != GD_UHDR_SUCCESS) { + return status; + } + status = + gdUhdrReplaceImage(gainmap_image, gdImageCrop(*gainmap_image, &gain_crop), err); + if (status != GD_UHDR_SUCCESS) { + return status; + } + break; + } + case GD_UHDR_OP_ROTATE: { + gdImagePtr rotated_base = NULL; + gdImagePtr rotated_gainmap = NULL; + + if (op->p1 == 90) { + rotated_base = gdImageRotate90(*base_image, 0); + rotated_gainmap = gdImageRotate90(*gainmap_image, 0); + } else if (op->p1 == 180) { + rotated_base = gdImageRotate180(*base_image, 0); + rotated_gainmap = gdImageRotate180(*gainmap_image, 0); + } else if (op->p1 == 270) { + rotated_base = gdImageRotate270(*base_image, 0); + rotated_gainmap = gdImageRotate270(*gainmap_image, 0); + } + + status = gdUhdrReplaceImage(base_image, rotated_base, err); + if (status != GD_UHDR_SUCCESS) { + if (rotated_gainmap) { + gdImageDestroy(rotated_gainmap); + } + return status; + } + status = gdUhdrReplaceImage(gainmap_image, rotated_gainmap, err); + if (status != GD_UHDR_SUCCESS) { + return status; + } + break; + } + case GD_UHDR_OP_MIRROR: + if (op->p1 == GD_UHDR_MIRROR_HORIZONTAL) { + gdImageFlipHorizontal(*base_image); + gdImageFlipHorizontal(*gainmap_image); + } else { + gdImageFlipVertical(*base_image); + gdImageFlipVertical(*gainmap_image); + } + break; + default: + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Unknown queued UltraHDR operation"); + return GD_UHDR_E_INVALID; + } + } + + return GD_UHDR_SUCCESS; +} + +static int gdUhdrEncodeJpegComponent(gdImagePtr image, int quality, const gdImageMetadata *metadata, + int no_subsampling, void **out_data, int *out_size, + gdUhdrErrorPtr err) +{ + void *jpeg; + int jpeg_size = 0; + + if (no_subsampling) { + jpeg = gdImageJpegPtrWithMetadataNoSubsampling(image, &jpeg_size, quality, metadata); + } else { + jpeg = gdImageJpegPtrWithMetadata(image, &jpeg_size, quality, metadata); + } + if (!jpeg || jpeg_size <= 0) { + gdFree(jpeg); + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to encode UltraHDR JPEG component"); + return GD_UHDR_E_ENCODE; + } + + *out_data = jpeg; + *out_size = jpeg_size; + return GD_UHDR_SUCCESS; +} + +static int gdUhdrQueueOp(gdUhdrImagePtr im, gdUhdrOpType type, int p1, int p2, int p3, int p4) +{ + if (im->op_count == im->op_capacity) { + int new_cap = im->op_capacity == 0 ? 8 : im->op_capacity * 2; + gdUhdrOp *tmp; + + if (overflow2(new_cap, (int)sizeof(gdUhdrOp))) { + return GD_UHDR_E_INVALID; + } + + tmp = (gdUhdrOp *)gdRealloc(im->ops, (size_t)new_cap * sizeof(gdUhdrOp)); + if (!tmp) { + return GD_UHDR_E_INVALID; + } + + im->ops = tmp; + im->op_capacity = new_cap; + } + + im->ops[im->op_count].type = type; + im->ops[im->op_count].p1 = p1; + im->ops[im->op_count].p2 = p2; + im->ops[im->op_count].p3 = p3; + im->ops[im->op_count].p4 = p4; + im->op_count++; + + return GD_UHDR_SUCCESS; +} + +static gdUhdrImagePtr gdUhdrImageCreateFromData(void *data, int size, int format, + gdUhdrErrorPtr err) +{ + gdUhdrImagePtr im; + uhdr_codec_private_t *dec; + uhdr_compressed_image_t input; + uhdr_error_info_t rc; + + if (!data || size <= 0 || !gdUhdrIsSupportedFormat(format)) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR input"); + return NULL; + } + + if (!is_uhdr_image(data, size)) { + gdUhdrSetError(err, GD_UHDR_E_UNSUPPORTED, 0, "Input is not a valid UltraHDR image"); + return NULL; + } + + dec = uhdr_create_decoder(); + if (!dec) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to create UltraHDR decoder"); + return NULL; + } + + input.data = data; + input.data_sz = (size_t)size; + input.capacity = (size_t)size; + input.cg = UHDR_CG_UNSPECIFIED; + input.ct = UHDR_CT_UNSPECIFIED; + input.range = UHDR_CR_FULL_RANGE; + + rc = uhdr_dec_set_image(dec, &input); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_set_image failed"); + uhdr_release_decoder(dec); + return NULL; + } + + rc = uhdr_dec_probe(dec); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_probe failed"); + uhdr_release_decoder(dec); + return NULL; + } + + im = (gdUhdrImagePtr)gdCalloc(1, sizeof(*im)); + if (!im) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Out of memory"); + uhdr_release_decoder(dec); + return NULL; + } + + im->blob = gdMalloc((size_t)size); + if (!im->blob) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Out of memory"); + gdFree(im); + uhdr_release_decoder(dec); + return NULL; + } + + memcpy(im->blob, data, (size_t)size); + im->blob_size = size; + im->format = format; + im->width = uhdr_dec_get_image_width(dec); + im->height = uhdr_dec_get_image_height(dec); + im->has_gain_map = + (uhdr_dec_get_gainmap_width(dec) > 0 && uhdr_dec_get_gainmap_height(dec) > 0) ? 1 : 0; + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + uhdr_release_decoder(dec); + return im; +} + +#endif + +#ifndef HAVE_LIBUHDR + +static int gdUhdrUnavailableCode(void) { return GD_UHDR_NOT_AVAILABLE; } + +static const char *gdUhdrUnavailableMessage(void) +{ + return "UltraHDR support is not enabled in this build"; +} + +#endif + +/* + Function: gdUhdrIsAvailable + + Returns whether UltraHDR support is available in this libgd build. + + Returns: + + 1 if available, 0 otherwise. +*/ +BGD_DECLARE(int) gdUhdrIsAvailable(void) +{ +#ifdef HAVE_LIBUHDR + return 1; +#else + return 0; +#endif +} + +/* + Function: gdUhdrImageCreateFromFile + + Loads an UltraHDR image from a file. + + Variants: + + loads from a . + + loads from memory. + + Parameters: + + filename - input file path. + format - input format (currently ). + err - optional output error details. + + Returns: + + A new on success, or NULL on error. +*/ +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromFile(const char *filename, int format, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + FILE *fp; + gdIOCtxPtr in; + gdUhdrImagePtr im; + + if (!filename) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "filename must not be NULL"); + return NULL; + } + + fp = fopen(filename, "rb"); + if (!fp) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to open input file"); + return NULL; + } + + in = gdNewFileCtx(fp); + if (!in) { + fclose(fp); + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to create IO context"); + return NULL; + } + + im = gdUhdrImageCreateFromCtx(in, format, err); + in->gd_free(in); + fclose(fp); + return im; +#else + ARG_NOT_USED(filename); + ARG_NOT_USED(format); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return NULL; +#endif +} + +/* + Function: gdUhdrImageCreateFromCtx + + See . +*/ +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromCtx(gdIOCtxPtr ctx, int format, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + void *data = NULL; + int size = 0; + int rc; + gdUhdrImagePtr im; + + if (!gdUhdrIsSupportedFormat(format)) { + gdUhdrSetError(err, GD_UHDR_E_UNSUPPORTED, 0, "Unsupported UltraHDR format"); + return NULL; + } + + rc = gdUhdrReadAllFromCtx(ctx, &data, &size); + if (rc != GD_UHDR_SUCCESS) { + gdUhdrSetError(err, rc, 0, "Failed to read UltraHDR stream"); + return NULL; + } + + im = gdUhdrImageCreateFromData(data, size, format, err); + gdFree(data); + return im; +#else + ARG_NOT_USED(ctx); + ARG_NOT_USED(format); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return NULL; +#endif +} + +/* + Function: gdUhdrImageCreateFromPtr + + See . +*/ +BGD_DECLARE(gdUhdrImagePtr) +gdUhdrImageCreateFromPtr(int size, void *data, int format, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + if (!gdUhdrIsSupportedFormat(format)) { + gdUhdrSetError(err, GD_UHDR_E_UNSUPPORTED, 0, "Unsupported UltraHDR format"); + return NULL; + } + + return gdUhdrImageCreateFromData(data, size, format, err); +#else + ARG_NOT_USED(size); + ARG_NOT_USED(data); + ARG_NOT_USED(format); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return NULL; +#endif +} + +/* + Function: gdUhdrImageDestroy + + Releases an UltraHDR image created by or its + variants. +*/ +BGD_DECLARE(void) gdUhdrImageDestroy(gdUhdrImagePtr im) +{ + if (!im) { + return; + } + + gdFree(im->ops); + gdFree(im->blob); + gdFree(im); +} + +/* + Function: gdUhdrImageWidth + + Returns the image width in pixels. +*/ +BGD_DECLARE(int) gdUhdrImageWidth(gdUhdrImagePtr im) +{ + if (!im) { + return 0; + } + return im->width; +} + +/* + Function: gdUhdrImageHeight + + Returns the image height in pixels. +*/ +BGD_DECLARE(int) gdUhdrImageHeight(gdUhdrImagePtr im) +{ + if (!im) { + return 0; + } + return im->height; +} + +/* + Function: gdUhdrImageHasGainMap + + Returns nonzero when the loaded image contains a gain map. +*/ +BGD_DECLARE(int) gdUhdrImageHasGainMap(gdUhdrImagePtr im) +{ + if (!im) { + return 0; + } + return im->has_gain_map; +} + +/* + Function: gdUhdrImageResize + + Queues a resize operation to be applied at save time. +*/ +BGD_DECLARE(int) +gdUhdrImageResize(gdUhdrImagePtr im, int width, int height, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + int rc; + if (!im || width <= 0 || height <= 0) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid resize arguments"); + return GD_UHDR_E_INVALID; + } + + rc = gdUhdrQueueOp(im, GD_UHDR_OP_RESIZE, width, height, 0, 0); + if (rc != GD_UHDR_SUCCESS) { + gdUhdrSetError(err, rc, 0, "Failed to queue resize effect"); + return rc; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return GD_UHDR_SUCCESS; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(width); + ARG_NOT_USED(height); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageCrop + + Queues a crop operation to be applied at save time. +*/ +BGD_DECLARE(int) +gdUhdrImageCrop(gdUhdrImagePtr im, int left, int top, int width, int height, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + int rc; + int right; + int bottom; + + if (!im || left < 0 || top < 0 || width <= 0 || height <= 0) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid crop arguments"); + return GD_UHDR_E_INVALID; + } + + if (gdUhdrIntAddOverflow(left, width) || gdUhdrIntAddOverflow(top, height)) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid crop arguments"); + return GD_UHDR_E_INVALID; + } + + right = left + width; + bottom = top + height; + + rc = gdUhdrQueueOp(im, GD_UHDR_OP_CROP, left, right, top, bottom); + if (rc != GD_UHDR_SUCCESS) { + gdUhdrSetError(err, rc, 0, "Failed to queue crop effect"); + return rc; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return GD_UHDR_SUCCESS; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(left); + ARG_NOT_USED(top); + ARG_NOT_USED(width); + ARG_NOT_USED(height); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageRotate + + Queues a clockwise rotation (90, 180, or 270 degrees) to be applied at + save time. +*/ +BGD_DECLARE(int) +gdUhdrImageRotate(gdUhdrImagePtr im, int degrees, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + int rc; + if (!im || (degrees != 90 && degrees != 180 && degrees != 270)) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid rotation angle"); + return GD_UHDR_E_INVALID; + } + + rc = gdUhdrQueueOp(im, GD_UHDR_OP_ROTATE, degrees, 0, 0, 0); + if (rc != GD_UHDR_SUCCESS) { + gdUhdrSetError(err, rc, 0, "Failed to queue rotation effect"); + return rc; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return GD_UHDR_SUCCESS; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(degrees); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageMirror + + Queues a mirror operation to be applied at save time. +*/ +BGD_DECLARE(int) +gdUhdrImageMirror(gdUhdrImagePtr im, int axis, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + int rc; + if (!im || (axis != GD_UHDR_MIRROR_HORIZONTAL && axis != GD_UHDR_MIRROR_VERTICAL)) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid mirror axis"); + return GD_UHDR_E_INVALID; + } + + rc = gdUhdrQueueOp(im, GD_UHDR_OP_MIRROR, axis, 0, 0, 0); + if (rc != GD_UHDR_SUCCESS) { + gdUhdrSetError(err, rc, 0, "Failed to queue mirror effect"); + return rc; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return GD_UHDR_SUCCESS; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(axis); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageFile + + Saves an UltraHDR image to a file path. + + Variants: + + writes via . + + writes to memory. +*/ +BGD_DECLARE(int) +gdUhdrImageFile(gdUhdrImagePtr im, const char *filename, int format, int quality, + gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + FILE *fp; + gdIOCtxPtr out; + int rc; + + if (!filename) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "filename must not be NULL"); + return GD_UHDR_E_INVALID; + } + + fp = fopen(filename, "wb"); + if (!fp) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to open output file"); + return GD_UHDR_E_ENCODE; + } + + out = gdNewFileCtx(fp); + if (!out) { + fclose(fp); + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to create IO context"); + return GD_UHDR_E_ENCODE; + } + + rc = gdUhdrImageCtx(im, out, format, quality, err); + out->gd_free(out); + fclose(fp); + return rc; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(filename); + ARG_NOT_USED(format); + ARG_NOT_USED(quality); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageCtx + + See . +*/ +BGD_DECLARE(int) +gdUhdrImageCtx(gdUhdrImagePtr im, gdIOCtxPtr ctx, int format, int quality, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + uhdr_codec_private_t *dec = NULL; + uhdr_codec_private_t *enc = NULL; + uhdr_compressed_image_t source; + uhdr_compressed_image_t base_jpeg; + uhdr_compressed_image_t gainmap_jpeg; + uhdr_error_info_t rc; + uhdr_compressed_image_t *encoded; + uhdr_gainmap_metadata_t *source_metadata; + uhdr_gainmap_metadata_t metadata; + uhdr_mem_block_t *base_block = NULL; + uhdr_mem_block_t *gainmap_block = NULL; + gdImageMetadata *base_metadata = NULL; + gdImageMetadata *gainmap_metadata = NULL; + gdImagePtr base_image = NULL; + gdImagePtr gainmap_image = NULL; + void *base_jpeg_data = NULL; + void *gainmap_jpeg_data = NULL; + int base_jpeg_size = 0; + int gainmap_jpeg_size = 0; + int write_result; + int status = GD_UHDR_SUCCESS; + + if (!im || !ctx || !im->blob || im->blob_size <= 0) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR image or output context"); + return GD_UHDR_E_INVALID; + } + + if (!gdUhdrIsSupportedFormat(format)) { + gdUhdrSetError(err, GD_UHDR_E_UNSUPPORTED, 0, "Unsupported UltraHDR output format"); + return GD_UHDR_E_UNSUPPORTED; + } + + if (quality < 1 || quality > 95) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "quality must be in [1..95]"); + return GD_UHDR_E_INVALID; + } + + if (im->op_count == 0) { + write_result = gdPutBuf(im->blob, im->blob_size, ctx); + if (write_result != im->blob_size) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to write UltraHDR output"); + return GD_UHDR_E_ENCODE; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return GD_UHDR_SUCCESS; + } + + dec = uhdr_create_decoder(); + enc = uhdr_create_encoder(); + if (!dec || !enc) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to create UltraHDR codec contexts"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + gdUhdrInitCompressedImage(&source, im->blob, im->blob_size); + + rc = uhdr_dec_set_image(dec, &source); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_set_image failed"); + status = GD_UHDR_E_DECODE; + goto cleanup; + } + + rc = uhdr_dec_probe(dec); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_probe failed"); + status = GD_UHDR_E_DECODE; + goto cleanup; + } + + source_metadata = uhdr_dec_get_gainmap_metadata(dec); + if (!source_metadata) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "UltraHDR gain map metadata is missing"); + status = GD_UHDR_E_DECODE; + goto cleanup; + } + metadata = *source_metadata; + + base_block = uhdr_dec_get_base_image(dec); + gainmap_block = uhdr_dec_get_gainmap_image(dec); + + /* + * Geometry transforms make source EXIF dimensions, orientation, and + * thumbnails stale. Preserve ICC, but copy EXIF only for pass-through + * writes unless GD learns to rewrite those tags. + */ + status = + gdUhdrCreateJpegMetadataFromBlock(base_block, im->op_count == 0, 1, &base_metadata, err); + if (status != GD_UHDR_SUCCESS) { + goto cleanup; + } + + if (!metadata.use_base_cg) { + status = gdUhdrCreateJpegMetadataFromBlock(gainmap_block, 0, 1, &gainmap_metadata, err); + if (status != GD_UHDR_SUCCESS) { + goto cleanup; + } + } + + base_image = + gdUhdrCreateGdImageFromJpegBlock(base_block, "Failed to decode UltraHDR base image", err); + if (!base_image) { + status = GD_UHDR_E_DECODE; + goto cleanup; + } + + gainmap_image = gdUhdrCreateGdImageFromJpegBlock( + gainmap_block, "Failed to decode UltraHDR gain map image", err); + if (!gainmap_image) { + status = GD_UHDR_E_DECODE; + goto cleanup; + } + + status = gdUhdrApplyGdOps(&base_image, &gainmap_image, im, err); + if (status != GD_UHDR_SUCCESS) { + goto cleanup; + } + + status = gdUhdrEncodeJpegComponent(base_image, quality, base_metadata, 0, &base_jpeg_data, + &base_jpeg_size, err); + if (status != GD_UHDR_SUCCESS) { + goto cleanup; + } + + status = gdUhdrEncodeJpegComponent(gainmap_image, quality, gainmap_metadata, 1, + &gainmap_jpeg_data, &gainmap_jpeg_size, err); + if (status != GD_UHDR_SUCCESS) { + goto cleanup; + } + + gdUhdrInitCompressedImage(&base_jpeg, base_jpeg_data, base_jpeg_size); + gdUhdrInitCompressedImage(&gainmap_jpeg, gainmap_jpeg_data, gainmap_jpeg_size); + + rc = uhdr_enc_set_output_format(enc, UHDR_CODEC_JPG); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_enc_set_output_format failed"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + rc = uhdr_enc_set_compressed_image(enc, &base_jpeg, UHDR_BASE_IMG); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_enc_set_compressed_image(base) failed"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + rc = uhdr_enc_set_gainmap_image(enc, &gainmap_jpeg, &metadata); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_enc_set_gainmap_image failed"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + rc = uhdr_encode(enc); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_encode failed"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + encoded = uhdr_get_encoded_stream(enc); + if (!encoded || !encoded->data || encoded->data_sz == 0) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Encoded UltraHDR stream is empty"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + write_result = gdPutBuf(encoded->data, (int)encoded->data_sz, ctx); + if (write_result != (int)encoded->data_sz) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to write UltraHDR output"); + status = GD_UHDR_E_ENCODE; + goto cleanup; + } + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + status = GD_UHDR_SUCCESS; + +cleanup: + gdFree(gainmap_jpeg_data); + gdFree(base_jpeg_data); + if (gainmap_image) { + gdImageDestroy(gainmap_image); + } + if (base_image) { + gdImageDestroy(base_image); + } + if (gainmap_metadata) { + gdImageMetadataFree(gainmap_metadata); + } + if (base_metadata) { + gdImageMetadataFree(base_metadata); + } + if (enc) { + uhdr_release_encoder(enc); + } + if (dec) { + uhdr_release_decoder(dec); + } + return status; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(ctx); + ARG_NOT_USED(format); + ARG_NOT_USED(quality); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return gdUhdrUnavailableCode(); +#endif +} + +/* + Function: gdUhdrImageWritePtr + + See . +*/ +BGD_DECLARE(void *) +gdUhdrImageWritePtr(gdUhdrImagePtr im, int *size, int format, int quality, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + gdIOCtxPtr out; + void *rv; + + if (size) { + *size = 0; + } + + out = gdNewDynamicCtx(2048, NULL); + if (!out) { + gdUhdrSetError(err, GD_UHDR_E_ENCODE, 0, "Failed to create dynamic output context"); + return NULL; + } + + if (gdUhdrImageCtx(im, out, format, quality, err) != GD_UHDR_SUCCESS) { + out->gd_free(out); + return NULL; + } + + rv = gdDPExtractData(out, size); + out->gd_free(out); + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + return rv; +#else + ARG_NOT_USED(im); + ARG_NOT_USED(format); + ARG_NOT_USED(quality); + if (size) { + *size = 0; + } + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return NULL; +#endif +} + +/* + Function: gdUhdrImageGetSdr + + Decodes and returns the SDR base image as a . +*/ +BGD_DECLARE(gdImagePtr) +gdUhdrImageGetSdr(gdUhdrImagePtr im, gdUhdrErrorPtr err) +{ +#ifdef HAVE_LIBUHDR + uhdr_codec_private_t *dec; + uhdr_compressed_image_t input; + uhdr_error_info_t rc; + uhdr_raw_image_t *raw; + gdImagePtr out; + int x, y; + unsigned int stride; + unsigned char *row; + + if (!im || !im->blob || im->blob_size <= 0) { + gdUhdrSetError(err, GD_UHDR_E_INVALID, 0, "Invalid UltraHDR image"); + return NULL; + } + + dec = uhdr_create_decoder(); + if (!dec) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to create UltraHDR decoder"); + return NULL; + } + + input.data = im->blob; + input.data_sz = (size_t)im->blob_size; + input.capacity = (size_t)im->blob_size; + input.cg = UHDR_CG_UNSPECIFIED; + input.ct = UHDR_CT_UNSPECIFIED; + input.range = UHDR_CR_FULL_RANGE; + + rc = uhdr_dec_set_image(dec, &input); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_set_image failed"); + uhdr_release_decoder(dec); + return NULL; + } + + rc = uhdr_dec_set_out_img_format(dec, UHDR_IMG_FMT_32bppRGBA8888); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_set_out_img_format failed"); + uhdr_release_decoder(dec); + return NULL; + } + + rc = uhdr_dec_set_out_color_transfer(dec, UHDR_CT_SRGB); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_dec_set_out_color_transfer failed"); + uhdr_release_decoder(dec); + return NULL; + } + + rc = uhdr_decode(dec); + if (rc.error_code != UHDR_CODEC_OK) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, rc.error_code, + rc.has_detail ? rc.detail : "uhdr_decode failed"); + uhdr_release_decoder(dec); + return NULL; + } + + raw = uhdr_get_decoded_image(dec); + if (!raw || !raw->planes[UHDR_PLANE_PACKED] || raw->w == 0 || raw->h == 0) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Decoded SDR image unavailable"); + uhdr_release_decoder(dec); + return NULL; + } + + out = gdImageCreateTrueColor((int)raw->w, (int)raw->h); + if (!out) { + gdUhdrSetError(err, GD_UHDR_E_DECODE, 0, "Failed to allocate SDR gdImage"); + uhdr_release_decoder(dec); + return NULL; + } + + stride = raw->stride[UHDR_PLANE_PACKED] ? raw->stride[UHDR_PLANE_PACKED] : raw->w; + for (y = 0; y < (int)raw->h; y++) { + row = (unsigned char *)raw->planes[UHDR_PLANE_PACKED] + ((size_t)y * stride * 4); + for (x = 0; x < (int)raw->w; x++) { + unsigned char r = row[(size_t)x * 4 + 0]; + unsigned char g = row[(size_t)x * 4 + 1]; + unsigned char b = row[(size_t)x * 4 + 2]; + unsigned char a8 = row[(size_t)x * 4 + 3]; + int a7 = gdAlphaMax - (a8 >> 1); + out->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a7); + } + } + out->saveAlphaFlag = 1; + + gdUhdrSetError(err, GD_UHDR_SUCCESS, 0, NULL); + uhdr_release_decoder(dec); + return out; +#else + ARG_NOT_USED(im); + gdUhdrSetError(err, gdUhdrUnavailableCode(), 0, gdUhdrUnavailableMessage()); + return NULL; +#endif +} diff --git a/ext/gd/libgd/gd_vector2d.h b/ext/gd/libgd/gd_vector2d.h new file mode 100644 index 000000000000..e21cb02761a5 --- /dev/null +++ b/ext/gd/libgd/gd_vector2d.h @@ -0,0 +1,631 @@ +#ifndef GD_VECTOR2D_H +#define GD_VECTOR2D_H + +#include "gd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Experimental API: source and ABI compatibility are not yet guaranteed. */ +#define GD_VECTOR2D_EXPERIMENTAL 1 +#define GD_VECTOR2D_VERSION 1 + +typedef struct gdContextStruct gdContext; +typedef gdContext *gdContextPtr; +typedef struct gdPathStruct gdPath; +typedef gdPath *gdPathPtr; +typedef struct gdPaintStruct gdPaint; +typedef gdPaint *gdPaintPtr; +typedef struct gdPathPatternStruct gdPathPattern; +typedef gdPathPattern *gdPathPatternPtr; + +typedef struct gdPathMatrixStruct { + double m00, m10, m01, m11, m02, m12; +} gdPathMatrix; +typedef gdPathMatrix *gdPathMatrixPtr; + +typedef struct gdRectFStruct { + double x, y, w, h; +} gdRectF; +typedef gdRectF *gdRectFPtr; + +typedef enum { GD_EXTEND_NONE, GD_EXTEND_REPEAT, GD_EXTEND_REFLECT, GD_EXTEND_PAD } gdExtendMode; +typedef enum { gdLineCapButt, gdLineCapRound, gdLineCapSquare } gdLineCap; +typedef enum { gdLineJoinMiter, gdLineJoinRound, gdLineJoinBevel } gdLineJoin; +typedef enum { gdFillRuleNonZero, gdFillRuleEvenOdd } gdFillRule; + +typedef enum { + GD_OP_CLEAR, + GD_OP_SOURCE, + GD_OP_OVER, + GD_OP_IN, + GD_OP_OUT, + GD_OP_ATOP, + GD_OP_DEST, + GD_OP_DEST_OVER, + GD_OP_DEST_IN, + GD_OP_DEST_OUT, + GD_OP_DEST_ATOP, + GD_OP_XOR, + GD_OP_ADD, + GD_OP_SATURATE, + GD_OP_MULTIPLY, + GD_OP_SCREEN, + GD_OP_OVERLAY, + GD_OP_DARKEN, + GD_OP_LIGHTEN, + GD_OP_COLOR_DODGE, + GD_OP_COLOR_BURN, + GD_OP_HARD_LIGHT, + GD_OP_SOFT_LIGHT, + GD_OP_DIFFERENCE, + GD_OP_EXCLUSION, + GD_OP_HSL_HUE, + GD_OP_HSL_SATURATION, + GD_OP_HSL_COLOR, + GD_OP_HSL_LUMINOSITY, + GD_OP_COUNT +} gdCompositeOperator; +typedef gdCompositeOperator gdImageOp; +#define gdImageOpsSrc GD_OP_SOURCE +#define gdImageOpsSrcOver GD_OP_OVER +#define gdImageOpsDstIn GD_OP_DEST_IN +#define gdImageOpsDstOut GD_OP_DEST_OUT + +BGD_DECLARE(gdContextPtr) gdContextCreateForImage(gdImagePtr image); +BGD_DECLARE(void) gdContextFlushImage(gdContextPtr context); +BGD_DECLARE(gdImagePtr) gdContextGetImage(gdContextPtr context); +BGD_DECLARE(void) gdContextDestroy(gdContextPtr context); +BGD_DECLARE(int) gdContextSave(gdContextPtr context); +BGD_DECLARE(int) gdContextRestore(gdContextPtr context); +BGD_DECLARE(int) gdContextClip(gdContextPtr context); +BGD_DECLARE(int) gdContextClipPreserve(gdContextPtr context); +BGD_DECLARE(void) gdContextNewPath(gdContextPtr context); +BGD_DECLARE(void) gdContextAppendPath(gdContextPtr context, gdPathPtr path); +BGD_DECLARE(void) +gdContextSetSourceRgba(gdContextPtr context, double r, double g, double b, double a); +BGD_DECLARE(void) gdContextSetSourceRgb(gdContextPtr context, double r, double g, double b); +BGD_DECLARE(void) +gdContextSetSourceImage(gdContextPtr context, gdImagePtr image, double x, double y); +BGD_DECLARE(void) gdContextSetSource(gdContextPtr context, gdPaintPtr source); +BGD_DECLARE(void) gdContextSetOperator(gdContextPtr context, gdCompositeOperator op); +BGD_DECLARE(void) gdContextSetOpacity(gdContextPtr context, double opacity); +BGD_DECLARE(void) gdContextMoveTo(gdContextPtr context, double x, double y); +BGD_DECLARE(void) gdContextRelMoveTo(gdContextPtr context, double dx, double dy); +BGD_DECLARE(void) gdContextLineTo(gdContextPtr context, double x, double y); +BGD_DECLARE(void) gdContextRelLineTo(gdContextPtr context, double dx, double dy); +BGD_DECLARE(void) +gdContextCurveTo(gdContextPtr context, double x1, double y1, double x2, double y2, double x3, + double y3); +BGD_DECLARE(void) +gdContextRelCurveTo(gdContextPtr context, double dx1, double dy1, double dx2, double dy2, + double dx3, double dy3); +BGD_DECLARE(void) gdContextQuadTo(gdContextPtr context, double x1, double y1, double x2, double y2); +BGD_DECLARE(void) +gdContextRelQuadTo(gdContextPtr context, double dx1, double dy1, double dx2, double dy2); +BGD_DECLARE(void) +gdContextArc(gdContextPtr context, double cx, double cy, double radius, double a0, double a1); +BGD_DECLARE(void) +gdContextNegativeArc(gdContextPtr context, double cx, double cy, double radius, double a0, + double a1); +BGD_DECLARE(void) +gdContextRectangle(gdContextPtr context, double x, double y, double width, double height); +BGD_DECLARE(void) gdContextClosePath(gdContextPtr context); +BGD_DECLARE(void) gdContextScale(gdContextPtr context, double x, double y); +BGD_DECLARE(void) gdContextTranslate(gdContextPtr context, double x, double y); +BGD_DECLARE(void) gdContextRotate(gdContextPtr context, double radians); +BGD_DECLARE(void) gdContextTransform(gdContextPtr context, const gdPathMatrixPtr matrix); +BGD_DECLARE(void) gdContextSetLineWidth(gdContextPtr context, double width); +BGD_DECLARE(void) gdContextSetLineCap(gdContextPtr context, gdLineCap cap); +BGD_DECLARE(void) gdContextSetLineJoin(gdContextPtr context, gdLineJoin join); +BGD_DECLARE(void) +gdContextSetDash(gdContextPtr context, double offset, const double *data, int size); +BGD_DECLARE(void) gdContextSetFillRule(gdContextPtr context, gdFillRule rule); +BGD_DECLARE(void) gdContextStroke(gdContextPtr context); +BGD_DECLARE(void) gdContextStrokePreserve(gdContextPtr context); +BGD_DECLARE(void) gdContextFill(gdContextPtr context); +BGD_DECLARE(void) gdContextFillPreserve(gdContextPtr context); +BGD_DECLARE(void) gdContextPaint(gdContextPtr context); + +BGD_DECLARE(gdPaintPtr) gdPaintCreateFromPattern(gdPathPatternPtr pattern); +BGD_DECLARE(gdPaintPtr) gdPaintCreateLinear(double x0, double y0, double x1, double y1); +BGD_DECLARE(gdPaintPtr) +gdPaintCreateRadial(double x0, double y0, double r0, double x1, double y1, double r1); +BGD_DECLARE(int) +gdPaintAddColorStopRgb(gdPaintPtr paint, double offset, double r, double g, double b); +BGD_DECLARE(int) +gdPaintAddColorStopRgba(gdPaintPtr paint, double offset, double r, double g, double b, double a); +BGD_DECLARE(int) gdPaintSetExtend(gdPaintPtr paint, gdExtendMode extend); +BGD_DECLARE(int) gdPaintSetMatrix(gdPaintPtr paint, const gdPathMatrixPtr matrix); +BGD_DECLARE(void) gdPaintDestroy(gdPaintPtr paint); + +BGD_DECLARE(gdPathPatternPtr) gdPathPatternCreateForImage(gdImagePtr image); +BGD_DECLARE(void) gdPathPatternDestroy(gdPathPatternPtr pattern); +BGD_DECLARE(void) gdPathPatternSetExtend(gdPathPatternPtr pattern, gdExtendMode extend); +BGD_DECLARE(void) gdPathPatternSetMatrix(gdPathPatternPtr pattern, gdPathMatrixPtr matrix); +BGD_DECLARE(void) gdPathPatternSetOpacity(gdPathPatternPtr pattern, double opacity); + +/** + * Function: gdPathMatrixInit + * + * Initialize an affine transformation matrix from its six coefficients. + * + * A point is mapped to (x * m00 + y * m01 + m02, + * x * m10 + y * m11 + m12). + * + * Parameters: + * matrix - The matrix to initialize. + * m00 - The horizontal x coefficient. + * m10 - The vertical x coefficient. + * m01 - The horizontal y coefficient. + * m11 - The vertical y coefficient. + * m02 - The horizontal translation. + * m12 - The vertical translation. + * + * See also: + * - + * - + */ +BGD_DECLARE(void) +gdPathMatrixInit(gdPathMatrixPtr matrix, double m00, double m10, double m01, double m11, double m02, + double m12); +/** + * Function: gdPathMatrixInitIdentity + * + * Initialize a matrix to the identity transformation. + * + * Parameters: + * matrix - The matrix to initialize. + */ +BGD_DECLARE(void) gdPathMatrixInitIdentity(gdPathMatrixPtr matrix); + +/** + * Function: gdPathMatrixInitTranslate + * + * Initialize a translation matrix. + * + * Parameters: + * matrix - The matrix to initialize. + * x - The horizontal translation. + * y - The vertical translation. + */ +BGD_DECLARE(void) gdPathMatrixInitTranslate(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixInitScale + * + * Initialize a scaling matrix. + * + * Parameters: + * matrix - The matrix to initialize. + * x - The horizontal scale factor. + * y - The vertical scale factor. + */ +BGD_DECLARE(void) gdPathMatrixInitScale(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixInitShear + * + * Initialize a shear matrix. The shear factors are the tangents of the + * supplied angles. + * + * Parameters: + * matrix - The matrix to initialize. + * x - The horizontal shear angle, in radians. + * y - The vertical shear angle, in radians. + */ +BGD_DECLARE(void) gdPathMatrixInitShear(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixInitRotate + * + * Initialize a rotation matrix about the origin. + * + * Parameters: + * matrix - The matrix to initialize. + * radians - The rotation angle, in radians. + */ +BGD_DECLARE(void) gdPathMatrixInitRotate(gdPathMatrixPtr matrix, double radians); + +/** + * Function: gdPathMatrixInitRotateTranslate + * + * Initialize a rotation matrix about a specified point. The point (x, y) + * remains unchanged by the resulting transformation. + * + * Parameters: + * matrix - The matrix to initialize. + * radians - The rotation angle, in radians. + * x - The horizontal coordinate of the rotation center. + * y - The vertical coordinate of the rotation center. + */ +BGD_DECLARE(void) +gdPathMatrixInitRotateTranslate(gdPathMatrixPtr matrix, double radians, double x, double y); + +/** + * Function: gdPathMatrixTranslate + * + * Apply a translation before the transformation already in a matrix. + * + * Parameters: + * matrix - The matrix to modify. + * x - The horizontal translation. + * y - The vertical translation. + */ +BGD_DECLARE(void) gdPathMatrixTranslate(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixScale + * + * Apply scaling before the transformation already in a matrix. + * + * Parameters: + * matrix - The matrix to modify. + * x - The horizontal scale factor. + * y - The vertical scale factor. + */ +BGD_DECLARE(void) gdPathMatrixScale(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixShear + * + * Apply a shear before the transformation already in a matrix. + * + * Parameters: + * matrix - The matrix to modify. + * x - The horizontal shear angle, in radians. + * y - The vertical shear angle, in radians. + */ +BGD_DECLARE(void) gdPathMatrixShear(gdPathMatrixPtr matrix, double x, double y); + +/** + * Function: gdPathMatrixRotate + * + * Apply a rotation about the origin before the transformation already in a + * matrix. + * + * Parameters: + * matrix - The matrix to modify. + * radians - The rotation angle, in radians. + */ +BGD_DECLARE(void) gdPathMatrixRotate(gdPathMatrixPtr matrix, double radians); + +/** + * Function: gdPathMatrixRotateTranslate + * + * Apply a rotation about a specified point before the transformation already + * in a matrix. + * + * Parameters: + * matrix - The matrix to modify. + * radians - The rotation angle, in radians. + * x - The horizontal coordinate of the rotation center. + * y - The vertical coordinate of the rotation center. + */ +BGD_DECLARE(void) +gdPathMatrixRotateTranslate(gdPathMatrixPtr matrix, double radians, double x, double y); + +/** + * Function: gdPathMatrixMultiply + * + * Compose two affine transformations. The result maps through a first and + * then through b. matrix may alias a or b. + * + * Parameters: + * matrix - The destination matrix. + * a - The transformation applied first. + * b - The transformation applied second. + */ +BGD_DECLARE(void) +gdPathMatrixMultiply(gdPathMatrixPtr matrix, const gdPathMatrixPtr a, const gdPathMatrixPtr b); + +/** + * Function: gdPathMatrixInvert + * + * Invert an affine transformation in place. A singular matrix is left + * unchanged. + * + * Parameters: + * matrix - The matrix to invert. + * + * Returns: + * Non-zero on success, or zero if the matrix is singular. + */ +BGD_DECLARE(int) gdPathMatrixInvert(gdPathMatrixPtr matrix); + +/** + * Function: gdPathMatrixMap + * + * Transform a pair of coordinates. + * + * Parameters: + * matrix - The transformation matrix. + * x - The source horizontal coordinate. + * y - The source vertical coordinate. + * result_x - Where to store the transformed horizontal coordinate. + * result_y - Where to store the transformed vertical coordinate. + */ +BGD_DECLARE(void) +gdPathMatrixMap(const gdPathMatrixPtr matrix, double x, double y, double *result_x, + double *result_y); + +/** + * Function: gdPathMatrixMapPoint + * + * Transform a point. src and dst may point to the same object. + * + * Parameters: + * matrix - The transformation matrix. + * src - The source point. + * dst - Where to store the transformed point. + */ +BGD_DECLARE(void) +gdPathMatrixMapPoint(const gdPathMatrixPtr matrix, const gdPointFPtr src, gdPointFPtr dst); + +/** + * Function: gdPathMatrixMapRect + * + * Transform all four corners of a rectangle and calculate their axis-aligned + * bounding box. src and dst may point to the same object. + * + * Parameters: + * matrix - The transformation matrix. + * src - The source rectangle. + * dst - Where to store the transformed bounding rectangle. + */ +BGD_DECLARE(void) +gdPathMatrixMapRect(const gdPathMatrixPtr matrix, const gdRectFPtr src, gdRectFPtr dst); + +/** + * Function: gdPathCreate + * + * Create an empty path. + * + * Returns: + * A new path, or NULL if allocation fails. Destroy it with . + */ +BGD_DECLARE(gdPathPtr) gdPathCreate(void); + +/** + * Function: gdPathDuplicate + * + * Create an independent copy of a path. + * + * Parameters: + * path - The path to copy. Must not be NULL. + * + * Returns: + * A new path, or NULL if path is NULL or allocation fails. Destroy the copy + * with . + */ +BGD_DECLARE(gdPathPtr) gdPathDuplicate(const gdPathPtr path); + +/** + * Function: gdPathDestroy + * + * Release a path. Passing NULL has no effect. + * + * Parameters: + * path - The path to release. + */ +BGD_DECLARE(void) gdPathDestroy(gdPathPtr path); + +/** + * Function: gdPathAppendPath + * + * Append all contours from one path to another. + * + * Parameters: + * path - The destination path. + * source - The path to append. + */ +BGD_DECLARE(void) gdPathAppendPath(gdPathPtr path, const gdPathPtr source); + +/** + * Function: gdPathTransform + * + * Transform every point in a path in place. + * + * Parameters: + * path - The path to transform. + * matrix - The transformation matrix. + */ +BGD_DECLARE(void) gdPathTransform(gdPathPtr path, const gdPathMatrixPtr matrix); + +/** + * Function: gdPathMoveTo + * + * Start a new contour at an absolute position. + * + * Parameters: + * path - The path to modify. + * x - The horizontal coordinate. + * y - The vertical coordinate. + */ +BGD_DECLARE(void) gdPathMoveTo(gdPathPtr path, double x, double y); + +/** + * Function: gdPathRelMoveTo + * + * Start a new contour at an offset from the current point. For an empty path, + * the offset is relative to (0, 0). + * + * Parameters: + * path - The path to modify. + * dx - The horizontal offset. + * dy - The vertical offset. + */ +BGD_DECLARE(void) gdPathRelMoveTo(gdPathPtr path, double dx, double dy); + +/** + * Function: gdPathLineTo + * + * Add a straight line to an absolute position. + * + * Parameters: + * path - The path to modify. + * x - The endpoint's horizontal coordinate. + * y - The endpoint's vertical coordinate. + */ +BGD_DECLARE(void) gdPathLineTo(gdPathPtr path, double x, double y); + +/** + * Function: gdPathRelLineTo + * + * Add a straight line using an offset from the current point. + * + * Parameters: + * path - The path to modify. + * dx - The horizontal offset. + * dy - The vertical offset. + */ +BGD_DECLARE(void) gdPathRelLineTo(gdPathPtr path, double dx, double dy); + +/** + * Function: gdPathQuadTo + * + * Add a quadratic Bezier curve. + * + * Parameters: + * path - The path to modify. + * x1 - The control point's horizontal coordinate. + * y1 - The control point's vertical coordinate. + * x2 - The endpoint's horizontal coordinate. + * y2 - The endpoint's vertical coordinate. + */ +BGD_DECLARE(void) gdPathQuadTo(gdPathPtr path, double x1, double y1, double x2, double y2); + +/** + * Function: gdPathRelQuadTo + * + * Add a quadratic Bezier curve using offsets from the current point. + * + * Parameters: + * path - The path to modify. + * dx1 - The control point's horizontal offset. + * dy1 - The control point's vertical offset. + * dx2 - The endpoint's horizontal offset. + * dy2 - The endpoint's vertical offset. + */ +BGD_DECLARE(void) gdPathRelQuadTo(gdPathPtr path, double dx1, double dy1, double dx2, double dy2); + +/** + * Function: gdPathCurveTo + * + * Add a cubic Bezier curve. + * + * Parameters: + * path - The path to modify. + * x1 - The first control point's horizontal coordinate. + * y1 - The first control point's vertical coordinate. + * x2 - The second control point's horizontal coordinate. + * y2 - The second control point's vertical coordinate. + * x3 - The endpoint's horizontal coordinate. + * y3 - The endpoint's vertical coordinate. + */ +BGD_DECLARE(void) +gdPathCurveTo(gdPathPtr path, double x1, double y1, double x2, double y2, double x3, double y3); + +/** + * Function: gdPathRelCurveTo + * + * Add a cubic Bezier curve using offsets from the current point. + * + * Parameters: + * path - The path to modify. + * dx1 - The first control point's horizontal offset. + * dy1 - The first control point's vertical offset. + * dx2 - The second control point's horizontal offset. + * dy2 - The second control point's vertical offset. + * dx3 - The endpoint's horizontal offset. + * dy3 - The endpoint's vertical offset. + */ +BGD_DECLARE(void) +gdPathRelCurveTo(gdPathPtr path, double dx1, double dy1, double dx2, double dy2, double dx3, + double dy3); + +/** + * Function: gdPathArc + * + * Add a circular arc in the positive-angle direction. Angles are in radians. + * A line is added from the current point to the beginning of the arc when + * necessary. + * + * Parameters: + * path - The path to modify. + * cx - The center's horizontal coordinate. + * cy - The center's vertical coordinate. + * radius - The arc radius. + * angle1 - The starting angle in radians. + * angle2 - The ending angle in radians. + */ +BGD_DECLARE(void) +gdPathArc(gdPathPtr path, double cx, double cy, double radius, double angle1, double angle2); + +/** + * Function: gdPathNegativeArc + * + * Add a circular arc in the negative-angle direction. Angles are in radians. + * A line is added from the current point to the beginning of the arc when + * necessary. + * + * Parameters: + * path - The path to modify. + * cx - The center's horizontal coordinate. + * cy - The center's vertical coordinate. + * radius - The arc radius. + * angle1 - The starting angle in radians. + * angle2 - The ending angle in radians. + */ +BGD_DECLARE(void) +gdPathNegativeArc(gdPathPtr path, double cx, double cy, double radius, double angle1, + double angle2); + +/** + * Function: gdPathArcTo + * + * Connect the current point to (x1, y1) and (x2, y2) with a circular arc + * tangent to both line segments. Degenerate geometry or a non-positive radius + * adds a line to (x1, y1). + * + * Parameters: + * path - The path to modify. + * x1 - The corner's horizontal coordinate. + * y1 - The corner's vertical coordinate. + * x2 - The second tangent line's horizontal endpoint. + * y2 - The second tangent line's vertical endpoint. + * radius - The arc radius. + */ +BGD_DECLARE(void) +gdPathArcTo(gdPathPtr path, double x1, double y1, double x2, double y2, double radius); + +/** + * Function: gdPathRectangle + * + * Add a closed rectangular contour. + * + * Parameters: + * path - The path to modify. + * x - The rectangle's left coordinate. + * y - The rectangle's top coordinate. + * width - The rectangle width. + * height - The rectangle height. + */ +BGD_DECLARE(void) gdPathRectangle(gdPathPtr path, double x, double y, double width, double height); + +/** + * Function: gdPathClose + * + * Close the current contour with a line to its starting point. An empty path + * or an already closed contour is unchanged. + * + * Parameters: + * path - The path to modify. + */ +BGD_DECLARE(void) gdPathClose(gdPathPtr path); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/gd/libgd/gd_vector2d_private.h b/ext/gd/libgd/gd_vector2d_private.h new file mode 100644 index 000000000000..3a98aa452c54 --- /dev/null +++ b/ext/gd/libgd/gd_vector2d_private.h @@ -0,0 +1,134 @@ +#ifndef GD_VECTOR2D_PRIVATE_H +#define GD_VECTOR2D_PRIVATE_H + +#include "gd_array.h" +#include "gd_vector2d.h" + +#if defined(__GNUC__) && !defined(_WIN32) +#define GD_VECTOR2D_INTERNAL __attribute__((visibility("hidden"))) +#else +#define GD_VECTOR2D_INTERNAL +#endif + +typedef enum { + GD_SURFACE_NONE, + GD_SURFACE_ARGB32, + GD_SURFACE_XRGB32, + GD_SURFACE_A8, + GD_SURFACE_COUNT +} gdSurfaceType; +typedef struct gdSurfaceStruct { + int ref; + unsigned char *data; + gdSurfaceType type; + int gdOwned; + int width, height, stride; +} gdSurface; +typedef gdSurface *gdSurfacePtr; + +typedef struct gdSpanStruct { + short x, y; + unsigned short len; + unsigned char coverage; +} gdSpan; +typedef gdSpan *gdSpanPtr; +typedef struct gdSpanRleStruct { + int ref; + struct { + gdSpanPtr data; + int size, capacity; + } spans; + int x, y, w, h; +} gdSpanRle; +typedef gdSpanRle *gdSpanRlePtr; + +typedef enum { + gdPaintTypeColor, + gdPaintTypeGradient, + gdPaintTypeSurface, + gdPaintTypePattern +} gdPaintType; +typedef struct gdColorStruct { + double r, g, b, a; +} gdColor; +typedef gdColor *gdColorPtr; +struct gdPathPatternStruct { + int ref; + gdExtendMode extend; + gdSurfacePtr surface; + gdPathMatrix matrix; + double opacity; +}; +typedef struct gdGradientStruct gdGradient; +struct gdPaintStruct { + int ref; + gdPaintType type; + union { + gdColorPtr color; + gdSurfacePtr surface; + gdPathPatternPtr pattern; + gdGradient *gradient; + }; +}; +typedef struct gdPathDashStruct { + double *data; + int size; + double offset; +} gdPathDash; +typedef gdPathDash *gdPathDashPtr; +typedef struct gdStrokeStruct { + double width, miterlimit; + gdLineCap cap; + gdLineJoin join; + gdPathDashPtr dash; +} gdStroke; +typedef gdStroke *gdStrokePtr; +typedef struct gdStateStruct { + gdSpanRlePtr clippath; + gdPaintPtr source; + gdPathMatrix matrix; + gdFillRule winding; + gdStroke stroke; + gdCompositeOperator op; + double opacity; + struct gdStateStruct *next; +} gdState; +typedef gdState *gdStatePtr; +typedef enum { + gdPathOpsMoveTo, + gdPathOpsLineTo, + gdPathOpsCubicTo, + gdPathOpsQuadTo, + gdPathOpsClose +} gdPathOps; +typedef gdPathOps *gdPathOpsPtr; +struct gdPathStruct { + int ref, contours; + gdPointF start; + gdArray elements; + gdArray points; +}; +struct gdContextStruct { + int ref; + gdSurfacePtr surface; + gdPathPtr path; + gdStatePtr state; + gdSpanRlePtr rle, clippath; + gdRectF clip; + gdImagePtr image; + int imageOwned; +}; + +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceCreate(int width, int height, unsigned int type); +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceCreateForData(unsigned char *data, int width, int height, + int stride, unsigned int type); +GD_VECTOR2D_INTERNAL gdSurfacePtr gdSurfaceAddRef(gdSurfacePtr surface); +GD_VECTOR2D_INTERNAL void gdSurfaceDestroy(gdSurfacePtr surface); +GD_VECTOR2D_INTERNAL gdContextPtr gdContextCreate(gdSurfacePtr surface); +GD_VECTOR2D_INTERNAL gdPathPatternPtr gdPathPatternCreate(gdSurfacePtr surface); +GD_VECTOR2D_INTERNAL void gdContextSetSourceSurface(gdContextPtr context, gdSurfacePtr surface, + double x, double y); +GD_VECTOR2D_INTERNAL gdPathPtr gdPathStrokeToPath(const gdPathPtr path, const gdStrokePtr stroke, + const gdPathMatrixPtr matrix); + +#endif diff --git a/ext/gd/libgd/gd_version.c b/ext/gd/libgd/gd_version.c new file mode 100644 index 000000000000..1573a47dff8b --- /dev/null +++ b/ext/gd/libgd/gd_version.c @@ -0,0 +1,34 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "gd.h" + +/* These functions return the version information. We use functions + * so that changes in the shared library will automatically be + * reflected in executables using it without recompiling them. */ + +/* + Function: gdMajorVersion +*/ +BGD_DECLARE(int) gdMajorVersion() { return GD_MAJOR_VERSION; } + +/* + Function: gdMinorVersion +*/ +BGD_DECLARE(int) gdMinorVersion() { return GD_MINOR_VERSION; } + +/* + Function: gdReleaseVersion +*/ +BGD_DECLARE(int) gdReleaseVersion() { return GD_RELEASE_VERSION; } + +/* + Function: gdExtraVersion +*/ +BGD_DECLARE(const char *) gdExtraVersion() { return GD_EXTRA_VERSION; } + +/* + Function: gdVersionString +*/ +BGD_DECLARE(const char *) gdVersionString() { return GD_VERSION_STRING; } diff --git a/ext/gd/libgd/gd_wbmp.c b/ext/gd/libgd/gd_wbmp.c index 22d1c4f4c66d..aab120ac7389 100644 --- a/ext/gd/libgd/gd_wbmp.c +++ b/ext/gd/libgd/gd_wbmp.c @@ -1,227 +1,288 @@ /* - WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap - Specification of the WBMP format can be found in the file: - SPEC-WAESpec-19990524.pdf - You can download the WAP specification on: http://www.wapforum.com/ - - gd_wbmp.c - - Copyright (C) Johan Van den Brande (johan@vandenbrande.com) - - Fixed: gdImageWBMPPtr, gdImageWBMP - - Recoded: gdImageWBMPCtx for use with my wbmp library - (wbmp library included, but you can find the latest distribution - at http://www.vandenbrande.com/wbmp) - - Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP - - --------------------------------------------------------------------------- - - Parts of this code are from Maurice Smurlo. - - - ** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000 - ** (Maurice.Szmurlo@info.unicaen.fr) - - ** Permission to use, copy, modify, and distribute this software and its - ** documentation for any purpose and without fee is hereby granted, provided - ** that the above copyright notice appear in all copies and that both that - ** copyright notice and this permission notice appear in supporting - ** documentation. This software is provided "as is" without express or - ** implied warranty. - - --------------------------------------------------------------------------- - Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by - Terje Sannum . - ** - ** Permission to use, copy, modify, and distribute this software and its - ** documentation for any purpose and without fee is hereby granted, provided - ** that the above copyright notice appear in all copies and that both that - ** copyright notice and this permission notice appear in supporting - ** documentation. This software is provided "as is" without express or - ** implied warranty. - ** - --------------------------------------------------------------------------- - - Todo: - - gdCreateFromWBMP function for reading WBMP files + * WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap + * Specification of the WBMP format can be found in the file: + * SPEC-WAESpec-19990524.pdf + * You can download the WAP specification on: http://www.wapforum.com/ + * + * gd_wbmp.c + * + * Copyright (C) Johan Van den Brande (johan@vandenbrande.com) + * + * Fixed: gdImageWBMPPtr, gdImageWBMP + * + * Recoded: gdImageWBMPCtx for use with my wbmp library + * (wbmp library included, but you can find the latest distribution + * at http://www.vandenbrande.com/wbmp) + * + * Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP + * + *-------------------------------------------------------------------------- + * + * Parts of this code are from Maurice Smurlo. + * + ** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000 + ** (Maurice.Szmurlo@info.unicaen.fr) + ** + ** Permission to use, copy, modify, and distribute this software and its + ** documentation for any purpose and without fee is hereby granted, provided + ** that the above copyright notice appear in all copies and that both that + ** copyright notice and this permission notice appear in supporting + ** documentation. This software is provided "as is" without express or + ** implied warranty. + * + *-------------------------------------------------------------------------- + * + * Parts of this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by + * Terje Sannum . + * + ** Permission to use, copy, modify, and distribute this software and its + ** documentation for any purpose and without fee is hereby granted, provided + ** that the above copyright notice appear in all copies and that both that + ** copyright notice and this permission notice appear in supporting + ** documentation. This software is provided "as is" without express or + ** implied warranty. + * + *-------------------------------------------------------------------------- + * + * Todo: + * + * gdCreateFromWBMP function for reading WBMP files + * + *-------------------------------------------------------------------------- + */ - ---------------------------------------------------------------------------- +/** + * File: WBMP IO + * + * Read and write WBMP images. */ -#include -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "gd.h" -#include "gdfonts.h" #include "gd_errors.h" -#include "wbmp.h" +#include "gdfonts.h" +#include +#include +#include +#include "wbmp.h" /* gd_putout - ** --------- - ** Wrapper around gdPutC for use with writewbmp - ** + * --------- + * Wrapper around gdPutC for use with writewbmp */ -void gd_putout (int i, void *out) -{ - gdPutC(i, (gdIOCtx *) out); -} - +static void gd_putout(int i, void *out) { gdPutC(i, (gdIOCtx *)out); } /* gd_getin - ** -------- - ** Wrapper around gdGetC for use with readwbmp - ** + * -------- + * Wrapper around gdGetC for use with readwbmp */ -int gd_getin (void *in) -{ - return (gdGetC((gdIOCtx *) in)); -} +static int gd_getin(void *in) { return (gdGetC((gdIOCtx *)in)); } static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); -/* gdImageWBMPCtx - ** -------------- - ** Write the image as a wbmp file - ** Parameters are: - ** image: gd image structure; - ** fg: the index of the foreground color. any other value will be - ** considered as background and will not be written - ** out: the stream where to write +/* + Function: gdImageWBMPCtx + + Write the image as a wbmp file + + Parameters: + image - gd image structure + fg - the index of the foreground color. any other value will be + considered as background and will not be written + out - the stream where to write */ -void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out) +BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) { - _gdImageWBMPCtx(image, fg, out); + _gdImageWBMPCtx(image, fg, out); } /* returns 0 on success, 1 on failure */ static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) { - int x, y, pos; - Wbmp *wbmp; - - /* create the WBMP */ - if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) { - gd_error("Could not create WBMP"); - return 1; - } - - /* fill up the WBMP structure */ - pos = 0; - for (y = 0; y < gdImageSY(image); y++) { - for (x = 0; x < gdImageSX(image); x++) { - if (gdImageGetPixel (image, x, y) == fg) { - wbmp->bitmap[pos] = WBMP_BLACK; - } - pos++; - } - } - - /* write the WBMP to a gd file descriptor */ - if (writewbmp (wbmp, &gd_putout, out)) { - freewbmp(wbmp); - gd_error("Could not save WBMP"); - return 1; - } - - /* des submitted this bugfix: gdFree the memory. */ - freewbmp(wbmp); - - return 0; + int x, y, pos; + Wbmp *wbmp; + + /* create the WBMP */ + if ((wbmp = createwbmp(gdImageSX(image), gdImageSY(image), WBMP_WHITE)) == NULL) { + gd_error("Could not create WBMP\n"); + return 1; + } + + /* fill up the WBMP structure */ + pos = 0; + for (y = 0; y < gdImageSY(image); y++) { + for (x = 0; x < gdImageSX(image); x++) { + if (gdImageGetPixel(image, x, y) == fg) { + wbmp->bitmap[pos] = WBMP_BLACK; + } + pos++; + } + } + + /* write the WBMP to a gd file descriptor */ + if (writewbmp(wbmp, &gd_putout, out)) { + freewbmp(wbmp); + gd_error("Could not save WBMP\n"); + return 1; + } + + /* des submitted this bugfix: gdFree the memory. */ + freewbmp(wbmp); + + return 0; } -/* gdImageCreateFromWBMPCtx - ** ------------------------ - ** Create a gdImage from a WBMP file input from an gdIOCtx +/* + Function: gdImageCreateFromWBMPCtx + + Reads in a WBMP image via a struct. See + . */ -gdImagePtr gdImageCreateFromWBMPCtx (gdIOCtx * infile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPCtx(gdIOCtx *infile) { - /* FILE *wbmp_file; */ - Wbmp *wbmp; - gdImagePtr im = NULL; - int black, white; - int col, row, pos; - - if (readwbmp (&gd_getin, infile, &wbmp)) { - return NULL; - } - - if (!(im = gdImageCreate (wbmp->width, wbmp->height))) { - freewbmp (wbmp); - return NULL; - } - - /* create the background color */ - white = gdImageColorAllocate(im, 255, 255, 255); - /* create foreground color */ - black = gdImageColorAllocate(im, 0, 0, 0); - - /* fill in image (in a wbmp 1 = white/ 0 = black) */ - pos = 0; - for (row = 0; row < wbmp->height; row++) { - for (col = 0; col < wbmp->width; col++) { - if (wbmp->bitmap[pos++] == WBMP_WHITE) { - gdImageSetPixel(im, col, row, white); - } else { - gdImageSetPixel(im, col, row, black); - } - } - } - - freewbmp(wbmp); - - return im; + Wbmp *wbmp; + gdImagePtr im = NULL; + int black, white; + int col, row, pos; + + if (readwbmp(&gd_getin, infile, &wbmp)) { + return (NULL); + } + + if (!(im = gdImageCreate(wbmp->width, wbmp->height))) { + freewbmp(wbmp); + return NULL; + } + + /* create the background color */ + white = gdImageColorAllocate(im, 255, 255, 255); + /* create foreground color */ + black = gdImageColorAllocate(im, 0, 0, 0); + + /* fill in image (in a wbmp 1 = white/ 0 = black) */ + pos = 0; + for (row = 0; row < wbmp->height; row++) { + for (col = 0; col < wbmp->width; col++) { + if (wbmp->bitmap[pos++] == WBMP_WHITE) { + gdImageSetPixel(im, col, row, white); + } else { + gdImageSetPixel(im, col, row, black); + } + } + } + + freewbmp(wbmp); + + return im; } -/* gdImageCreateFromWBMP - ** --------------------- +/* + Function: gdImageCreateFromWBMP + + is called to load images from WBMP format + files. Invoke with an already opened + pointer to a file containing the desired + image. returns a gdImagePtr to the new + image, or NULL if unable to load the image (most often because the + file is corrupt or does not contain a WBMP + image). does not close the file. You can + inspect the sx and sy members of the image to determine its + size. The image must eventually be destroyed using + . + + Variants: + + creates an image from WBMP data (i.e. the + contents of a WBMP file) already in memory. + + reads in an image using the functions in + a struct. + + Parameters: + + infile - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + (start code) + + gdImagePtr im; + FILE *in; + in = fopen("mywbmp.wbmp", "rb"); + im = gdImageCreateFromWBMP(in); + fclose(in); + // ... Use the image ... + gdImageDestroy(im); + + (end code) */ -gdImagePtr gdImageCreateFromWBMP (FILE * inFile) -{ - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx(inFile); - im = gdImageCreateFromWBMPCtx(in); - in->gd_free(in); - return im; +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMP(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (in == NULL) + return NULL; + im = gdImageCreateFromWBMPCtx(in); + in->gd_free(in); + return im; } -gdImagePtr gdImageCreateFromWBMPPtr (int size, void *data) +/* + Function: gdImageCreateFromWBMPPtr + + Parameters: + + size - size of WBMP data in bytes. + data - WBMP data (i.e. contents of a WBMP file). + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPPtr(int size, void *data) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - im = gdImageCreateFromWBMPCtx(in); - in->gd_free(in); - return im; + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) { + return 0; + } + im = gdImageCreateFromWBMPCtx(in); + in->gd_free(in); + return im; } -/* gdImageWBMP - ** ----------- +/* + Function: gdImageWBMP */ -void gdImageWBMP (gdImagePtr im, int fg, FILE * outFile) +BGD_DECLARE(void) gdImageWBMP(gdImagePtr im, int fg, FILE *outFile) { - gdIOCtx *out = gdNewFileCtx(outFile); - gdImageWBMPCtx(im, fg, out); - out->gd_free(out); + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) + return; + gdImageWBMPCtx(im, fg, out); + out->gd_free(out); } -/* gdImageWBMPPtr - ** -------------- +/* + Function: gdImageWBMPPtr */ -void * gdImageWBMPPtr (gdImagePtr im, int *size, int fg) +BGD_DECLARE(void *) gdImageWBMPPtr(gdImagePtr im, int *size, int fg) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - if (!_gdImageWBMPCtx(im, fg, out)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } - out->gd_free(out); - - return rv; + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) + return NULL; + if (!_gdImageWBMPCtx(im, fg, out)) { + rv = gdDPExtractData(out, size); + } else { + rv = NULL; + } + out->gd_free(out); + return rv; } diff --git a/ext/gd/libgd/gd_webp.c b/ext/gd/libgd/gd_webp.c index 6277e09710f9..2045cbe84afb 100644 --- a/ext/gd/libgd/gd_webp.c +++ b/ext/gd/libgd/gd_webp.c @@ -1,207 +1,1322 @@ -#include -#include -#include -#include +/** + * File: WebP IO + * + * Read and write WebP images. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "gd.h" #include "gd_errors.h" +#include "gd_intern.h" #include "gdhelpers.h" +#include +#include +#include +#include #ifdef HAVE_LIBWEBP #include "webp/decode.h" +#include "webp/demux.h" #include "webp/encode.h" +#include "webp/mux.h" + +#define GD_WEBP_ALLOC_STEP (4 * 1024) + +struct gdWebpReadStruct { + uint8_t *data; + size_t size; + WebPDemuxer *demux; + WebPAnimDecoder *decoder; + WebPIterator iter; + int haveIter; + int rawIndex; + int imageIndex; + int rawTimestamp; + int imageTimestamp; + gdImagePtr rawFrame; + gdImagePtr canvas; +}; + +struct gdWebpWriteStruct { + gdIOCtxPtr out; + int ownsCtx; + int memoryWriter; + WebPAnimEncoder *encoder; + gdWebpWriteOptions options; + int canvasWidth; + int canvasHeight; + int timestamp; + int frameCount; + int finalized; +}; + +static uint8_t *WebpReadCtxData(gdIOCtx *infile, size_t *size) +{ + uint8_t *filedata = NULL, *temp, *read; + ssize_t n; + + *size = 0; + do { + temp = gdRealloc(filedata, *size + GD_WEBP_ALLOC_STEP); + if (temp == NULL) { + gdFree(filedata); + gd_error("WebP decode: realloc failed"); + return NULL; + } + filedata = temp; + read = temp + *size; + n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile); + if (n > 0 && n != EOF) { + *size += n; + } + } while (n > 0 && n != EOF); + + if (*size == 0) { + gdFree(filedata); + return NULL; + } + + return filedata; +} + +static int WebpGdAlphaToWebp(int alpha) +{ + if (alpha == gdAlphaTransparent) { + return 0; + } + return 255 - ((alpha << 1) + (alpha >> 6)); +} + +static int WebpWebpAlphaToGd(uint8_t alpha) { return gdAlphaMax - (alpha >> 1); } + +static gdImagePtr WebpImageFromRGBA(const uint8_t *rgba, int width, int height) +{ + gdImagePtr im; + const uint8_t *p; + int x, y; + + if (rgba == NULL || width <= 0 || height <= 0) { + return NULL; + } + im = gdImageCreateTrueColor(width, height); + if (im == NULL) { + return NULL; + } + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, 1); + for (y = 0, p = rgba; y < height; y++) { + for (x = 0; x < width; x++) { + uint8_t r = *(p++); + uint8_t g = *(p++); + uint8_t b = *(p++); + uint8_t a = *(p++); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, WebpWebpAlphaToGd(a)); + } + } + return im; +} + +static gdImagePtr WebpImageFromARGB(const uint8_t *argb, int width, int height) +{ + gdImagePtr im; + const uint8_t *p; + int x, y; + + if (argb == NULL || width <= 0 || height <= 0) { + return NULL; + } + im = gdImageCreateTrueColor(width, height); + if (im == NULL) { + return NULL; + } + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, 1); + for (y = 0, p = argb; y < height; y++) { + for (x = 0; x < width; x++) { + uint8_t a = *(p++); + uint8_t r = *(p++); + uint8_t g = *(p++); + uint8_t b = *(p++); + im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, WebpWebpAlphaToGd(a)); + } + } + return im; +} + +static gdImagePtr WebpCloneImage(gdImagePtr src) +{ + gdImagePtr dst; + int x, y; + + if (src == NULL) { + return NULL; + } + dst = gdImageCreateTrueColor(gdImageSX(src), gdImageSY(src)); + if (dst == NULL) { + return NULL; + } + gdImageAlphaBlending(dst, 0); + gdImageSaveAlpha(dst, src->saveAlphaFlag); + for (y = 0; y < gdImageSY(src); y++) { + for (x = 0; x < gdImageSX(src); x++) { + dst->tpixels[y][x] = gdImageGetPixel(src, x, y); + } + } + return dst; +} + +static void WebpFillInfo(const WebPDemuxer *demux, gdWebpInfo *info) +{ + if (info == NULL) { + return; + } + info->width = (int)WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); + info->height = (int)WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); + info->frameCount = (int)WebPDemuxGetI(demux, WEBP_FF_FRAME_COUNT); + info->loopCount = (int)WebPDemuxGetI(demux, WEBP_FF_LOOP_COUNT); + info->backgroundColor = (int)WebPDemuxGetI(demux, WEBP_FF_BACKGROUND_COLOR); + info->formatFlags = (int)WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); +} + +static void WebpFillFrameInfo(const WebPIterator *iter, int frameIndex, int timestamp, + gdWebpFrameInfo *info) +{ + if (info == NULL || iter == NULL) { + return; + } + info->frameIndex = frameIndex; + info->x = iter->x_offset; + info->y = iter->y_offset; + info->width = iter->width; + info->height = iter->height; + info->duration = iter->duration; + info->timestamp = timestamp; + info->dispose = iter->dispose_method; + info->blend = iter->blend_method; + info->hasAlpha = iter->has_alpha; + info->complete = iter->complete; +} + +static int WebpProbeData(const uint8_t *data, size_t size) +{ + WebPData webpData; + WebPDemuxer *demux; + uint32_t flags; + int frameCount; + + if (data == NULL || size == 0) { + return -1; + } + webpData.bytes = data; + webpData.size = size; + demux = WebPDemux(&webpData); + if (demux == NULL) { + return -1; + } + flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); + frameCount = (int)WebPDemuxGetI(demux, WEBP_FF_FRAME_COUNT); + WebPDemuxDelete(demux); + return ((flags & ANIMATION_FLAG) != 0 || frameCount > 1) ? 1 : 0; +} + +static gdImagePtr WebpDecodeFirstImage(const uint8_t *filedata, size_t size) +{ + WebPData webpData; + WebPAnimDecoderOptions options; + WebPAnimDecoder *decoder; + uint8_t *rgba = NULL; + int timestamp = 0; + gdImagePtr im; + + if (!WebPAnimDecoderOptionsInit(&options)) { + return NULL; + } + options.color_mode = MODE_RGBA; + webpData.bytes = filedata; + webpData.size = size; + decoder = WebPAnimDecoderNew(&webpData, &options); + if (decoder == NULL) { + return NULL; + } + if (!WebPAnimDecoderGetNext(decoder, &rgba, ×tamp)) { + WebPAnimDecoderDelete(decoder); + return NULL; + } + { + WebPAnimInfo info; + if (!WebPAnimDecoderGetInfo(decoder, &info)) { + WebPAnimDecoderDelete(decoder); + return NULL; + } + im = WebpImageFromRGBA(rgba, (int)info.canvas_width, (int)info.canvas_height); + } + WebPAnimDecoderDelete(decoder); + return im; +} + +/* + Function: gdImageCreateFromWebp + + is called to load truecolor images from + WebP format files. Invoke with an + already opened pointer to a file containing the desired + image. returns a to the new + truecolor image, or NULL if unable to load the image (most often + because the file is corrupt or does not contain a WebP + image). does not close the file. + + You can inspect the sx and sy members of the image to determine + its size. The image must eventually be destroyed using + . + + *The returned image is always a truecolor image.* + + Variants: + + creates an image from WebP data + already in memory. + + reads its data via the function + pointers in a structure. + + Parameters: + + infile - The input FILE pointer. + + Returns: + + A pointer to the new *truecolor* image. This will need to be + destroyed with once it is no longer needed. + + On error, returns NULL. +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebp(FILE *inFile) +{ + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + if (!in) { + return 0; + } + im = gdImageCreateFromWebpCtx(in); + in->gd_free(in); + + return im; +} + +/* + Function: gdImageCreateFromWebpPtr + + See . + + Parameters: -#define GD_WEBP_ALLOC_STEP (4*1024) - -gdImagePtr gdImageCreateFromWebp (FILE * inFile) -{ - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx(inFile); - if (!in) - return 0; - im = gdImageCreateFromWebpCtx(in); - in->gd_free(in); - - return im; -} - - -gdImagePtr gdImageCreateFromWebpPtr (int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - if (!in) - return 0; - im = gdImageCreateFromWebpCtx(in); - in->gd_free(in); - return im; -} - -gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) -{ - int width, height; - uint8_t *filedata = NULL; - uint8_t *argb = NULL; - size_t size = 0, n; - gdImagePtr im; - int x, y; - uint8_t *p; - - do { - unsigned char *read, *temp; - - temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP); - if (temp) { - filedata = temp; - read = temp + size; - } else { - if (filedata) { - gdFree(filedata); - } - gd_error("WebP decode: realloc failed"); - return NULL; - } - - n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile); - if (n>0 && n!=EOF) { - size += n; - } - } while (n>0 && n!=EOF); - - if (WebPGetInfo(filedata,size, &width, &height) == 0) { - gd_error("gd-webp cannot get webp info"); - gdFree(filedata); - return NULL; - } - - im = gdImageCreateTrueColor(width, height); - if (!im) { - gdFree(filedata); - return NULL; - } - argb = WebPDecodeARGB(filedata, size, &width, &height); - if (!argb) { - gd_error("gd-webp cannot allocate temporary buffer"); - gdFree(filedata); - gdImageDestroy(im); - return NULL; - } - for (y = 0, p = argb; y < height; y++) { - for (x = 0; x < width; x++) { - register uint8_t a = gdAlphaMax - (*(p++) >> 1); - register uint8_t r = *(p++); - register uint8_t g = *(p++); - register uint8_t b = *(p++); - im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a); - } - } - gdFree(filedata); - /* do not use gdFree here, in case gdFree/alloc is mapped to something else than libc */ - free(argb); - im->saveAlphaFlag = 1; - return im; -} - -void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality) -{ - uint8_t *argb; - int x, y; - uint8_t *p; - uint8_t *out; - size_t out_size; - - if (im == NULL) { - return; - } - - if (!gdImageTrueColor(im)) { - gd_error("Palette image not supported by webp"); - return; - } - - if (quality == -1) { - quality = 80; - } - - if (overflow2(gdImageSX(im), 4)) { - return; - } - - if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) { - return; - } - - argb = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im)); - if (!argb) { - return; - } - p = argb; - for (y = 0; y < gdImageSY(im); y++) { - for (x = 0; x < gdImageSX(im); x++) { - register int c; - register char a; - c = im->tpixels[y][x]; - a = gdTrueColorGetAlpha(c); - if (a == 127) { - a = 0; - } else { - a = 255 - ((a << 1) + (a >> 6)); - } - *(p++) = gdTrueColorGetRed(c); - *(p++) = gdTrueColorGetGreen(c); - *(p++) = gdTrueColorGetBlue(c); - *(p++) = a; - } - } - - if (quality >= gdWebpLossless) { - out_size = WebPEncodeLosslessRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, &out); - } else { - out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out); - } - - if (out_size == 0) { - gd_error("gd-webp encoding failed"); - goto freeargb; - } - gdPutBuf(out, out_size, outfile); - free(out); + size - size of WebP data in bytes. + data - pointer to WebP data. +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if (!in) + return 0; + im = gdImageCreateFromWebpCtx(in); + in->gd_free(in); + return im; +} + +/* + Function: gdImageCreateFromWebpCtx + + See . +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpCtx(gdIOCtx *infile) +{ + int width, height; + uint8_t *filedata = NULL; + uint8_t *argb = NULL; + size_t size = 0; + gdImagePtr im; + + filedata = WebpReadCtxData(infile, &size); + if (filedata == NULL) { + gd_error("gd-webp cannot get webp info"); + return NULL; + } + + if (WebPGetInfo(filedata, size, &width, &height) == 0) { + im = WebpDecodeFirstImage(filedata, size); + if (im == NULL) { + gd_error("gd-webp cannot get webp info"); + } + gdFree(filedata); + return im; + } + argb = WebPDecodeARGB(filedata, size, &width, &height); + if (!argb) { + im = WebpDecodeFirstImage(filedata, size); + if (im == NULL) { + gd_error("gd-webp cannot allocate temporary buffer"); + } + gdFree(filedata); + return im; + } + im = WebpImageFromARGB(argb, width, height); + /* do not use gdFree here, in case gdFree/alloc is mapped to something else + * than libc */ + WebPFree(argb); + gdFree(filedata); + return im; +} + +BGD_DECLARE(int) gdWebpIsAnimated(FILE *fdFile) +{ + gdIOCtx *fd; + uint8_t *data; + size_t size; + int result, pos; + + if (fdFile == NULL) { + return -1; + } + fd = gdNewFileCtx(fdFile); + if (fd == NULL) { + return -1; + } + pos = (int)gdTell(fd); + if (pos < 0) { + fd->gd_free(fd); + return -1; + } + data = WebpReadCtxData(fd, &size); + result = WebpProbeData(data, size); + gdFree(data); + if (!gdSeek(fd, pos)) { + result = -1; + } + fd->gd_free(fd); + return result; +} + +BGD_DECLARE(int) gdWebpIsAnimatedCtx(gdIOCtxPtr in) +{ + uint8_t *data; + size_t size; + int result, pos; + + if (in == NULL || in->tell == NULL || in->seek == NULL) { + return -1; + } + pos = (int)gdTell(in); + if (pos < 0) { + return -1; + } + data = WebpReadCtxData(in, &size); + result = WebpProbeData(data, size); + gdFree(data); + if (!gdSeek(in, pos)) { + return -1; + } + return result; +} + +BGD_DECLARE(int) gdWebpIsAnimatedPtr(int size, void *data) +{ + if (size <= 0 || data == NULL) { + return -1; + } + return WebpProbeData((const uint8_t *)data, (size_t)size); +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpen(FILE *fdFile) +{ + gdIOCtx *fd; + gdWebpReadPtr webp; + + if (fdFile == NULL) { + return NULL; + } + fd = gdNewFileCtx(fdFile); + if (fd == NULL) { + return NULL; + } + webp = gdWebpReadOpenCtx(fd); + fd->gd_free(fd); + return webp; +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenPtr(int size, void *data) +{ + gdIOCtx *in; + gdWebpReadPtr webp; + + if (size <= 0 || data == NULL) { + return NULL; + } + in = gdNewDynamicCtxEx(size, data, 0); + if (in == NULL) { + return NULL; + } + webp = gdWebpReadOpenCtx(in); + in->gd_free(in); + return webp; +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenCtx(gdIOCtxPtr in) +{ + gdWebpReadPtr webp; + WebPData webpData; + WebPAnimDecoderOptions decOptions; + + if (in == NULL) { + return NULL; + } + webp = (gdWebpReadPtr)gdCalloc(1, sizeof(struct gdWebpReadStruct)); + if (webp == NULL) { + return NULL; + } + webp->data = WebpReadCtxData(in, &webp->size); + if (webp->data == NULL) { + gdFree(webp); + return NULL; + } + webpData.bytes = webp->data; + webpData.size = webp->size; + webp->demux = WebPDemux(&webpData); + if (webp->demux == NULL || !WebPAnimDecoderOptionsInit(&decOptions)) { + gdWebpReadClose(webp); + return NULL; + } + decOptions.color_mode = MODE_RGBA; + webp->decoder = WebPAnimDecoderNew(&webpData, &decOptions); + if (webp->decoder == NULL) { + gdWebpReadClose(webp); + return NULL; + } + return webp; +} + +BGD_DECLARE(void) gdWebpReadClose(gdWebpReadPtr webp) +{ + if (webp == NULL) { + return; + } + if (webp->haveIter) { + WebPDemuxReleaseIterator(&webp->iter); + } + if (webp->decoder != NULL) { + WebPAnimDecoderDelete(webp->decoder); + } + if (webp->demux != NULL) { + WebPDemuxDelete(webp->demux); + } + if (webp->rawFrame != NULL) { + gdImageDestroy(webp->rawFrame); + } + if (webp->canvas != NULL) { + gdImageDestroy(webp->canvas); + } + gdFree(webp->data); + gdFree(webp); +} + +BGD_DECLARE(int) gdWebpReadGetInfo(gdWebpReadPtr webp, gdWebpInfo *info) +{ + if (webp == NULL || info == NULL || webp->demux == NULL) { + return 0; + } + WebpFillInfo(webp->demux, info); + return 1; +} + +BGD_DECLARE(int) +gdWebpReadNextFrame(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *frame) +{ + uint8_t *rgba; + int width, height; + + if (frame != NULL) { + *frame = NULL; + } + if (webp == NULL || webp->demux == NULL) { + return -1; + } + if (webp->haveIter) { + if (!WebPDemuxNextFrame(&webp->iter)) { + return 0; + } + } else { + if (!WebPDemuxGetFrame(webp->demux, 1, &webp->iter)) { + return 0; + } + webp->haveIter = 1; + } + if (webp->rawFrame != NULL) { + gdImageDestroy(webp->rawFrame); + webp->rawFrame = NULL; + } + rgba = WebPDecodeRGBA(webp->iter.fragment.bytes, webp->iter.fragment.size, &width, &height); + if (rgba == NULL) { + return -1; + } + webp->rawFrame = WebpImageFromRGBA(rgba, width, height); + WebPFree(rgba); + if (webp->rawFrame == NULL) { + return -1; + } + WebpFillFrameInfo(&webp->iter, webp->rawIndex, webp->rawTimestamp, info); + webp->rawTimestamp += webp->iter.duration; + webp->rawIndex++; + if (frame != NULL) { + *frame = webp->rawFrame; + } + return 1; +} + +BGD_DECLARE(int) +gdWebpReadNextImage(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *image) +{ + uint8_t *rgba; + int timestamp, duration; + WebPIterator iter; + int haveFrameInfo = 0; + WebPAnimInfo animInfo; + + if (image != NULL) { + *image = NULL; + } + if (webp == NULL || webp->decoder == NULL) { + return -1; + } + if (!WebPAnimDecoderGetNext(webp->decoder, &rgba, ×tamp)) { + return 0; + } + if (!WebPAnimDecoderGetInfo(webp->decoder, &animInfo)) { + return -1; + } + duration = timestamp - webp->imageTimestamp; + if (duration < 0) { + duration = 0; + } + if (WebPDemuxGetFrame(webp->demux, webp->imageIndex + 1, &iter)) { + haveFrameInfo = 1; + WebpFillFrameInfo(&iter, webp->imageIndex, webp->imageTimestamp, info); + if (info != NULL) { + info->duration = duration; + } + WebPDemuxReleaseIterator(&iter); + } else if (info != NULL) { + memset(info, 0, sizeof(*info)); + info->frameIndex = webp->imageIndex; + info->width = (int)animInfo.canvas_width; + info->height = (int)animInfo.canvas_height; + info->duration = duration; + info->timestamp = webp->imageTimestamp; + } + if (webp->canvas != NULL) { + gdImageDestroy(webp->canvas); + webp->canvas = NULL; + } + webp->canvas = WebpImageFromRGBA(rgba, (int)animInfo.canvas_width, (int)animInfo.canvas_height); + if (webp->canvas == NULL) { + return -1; + } + if (!haveFrameInfo && info != NULL) { + info->complete = 1; + } + webp->imageTimestamp = timestamp; + webp->imageIndex++; + if (image != NULL) { + *image = webp->canvas; + } + return 1; +} + +BGD_DECLARE(gdImagePtr) gdWebpReadCloneImage(gdWebpReadPtr webp) +{ + if (webp == NULL || webp->canvas == NULL) { + return NULL; + } + return WebpCloneImage(webp->canvas); +} + +/* returns 0 on success, 1 on failure */ +static int _gdImageWebpCtx(gdImagePtr im, gdIOCtx *outfile, int quality) +{ + uint8_t *argb; + int x, y; + uint8_t *p; + uint8_t *out; + size_t out_size; + size_t ret = 0; + + if (im == NULL) { + return 1; + } + + if (!gdImageTrueColor(im)) { + gd_error("Palette image not supported by webp"); + return 1; + } + + if (quality == -1) { + quality = 80; + } + + if (overflow2(gdImageSX(im), 4)) { + return 1; + } + + if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) { + return 1; + } + + argb = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im)); + if (!argb) { + return 1; + } + p = argb; + for (y = 0; y < gdImageSY(im); y++) { + for (x = 0; x < gdImageSX(im); x++) { + register int c; + register char a; + c = im->tpixels[y][x]; + a = gdTrueColorGetAlpha(c); + if (a == 127) { + a = 0; + } else { + a = 255 - ((a << 1) + (a >> 6)); + } + *(p++) = gdTrueColorGetRed(c); + *(p++) = gdTrueColorGetGreen(c); + *(p++) = gdTrueColorGetBlue(c); + *(p++) = a; + } + } + if (quality >= gdWebpLossless) { + out_size = + WebPEncodeLosslessRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, &out); + } else { + out_size = + WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out); + } + if (out_size == 0) { + gd_error("gd-webp encoding failed"); + ret = 1; + goto freeargb; + } + + int res = gdPutBuf(out, out_size, outfile); + WebPFree(out); + if (res < 0 || (size_t)res != out_size) { + gd_error("gd-webp write error\n"); + ret = 1; + } freeargb: - gdFree(argb); + gdFree(argb); + + return ret; } -void gdImageWebpEx (gdImagePtr im, FILE * outFile, int quality) +/* + Function: gdImageWebpCtx + + Write the image as WebP data via a . See + for more details. + + Parameters: + + im - The image to write. + outfile - The output sink. + quality - Image quality. + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) gdImageWebpCtx(gdImagePtr im, gdIOCtx *outfile, int quality) { - gdIOCtx *out = gdNewFileCtx(outFile); - gdImageWebpCtx(im, out, quality); - out->gd_free(out); + _gdImageWebpCtx(im, outfile, quality); } -void gdImageWebp (gdImagePtr im, FILE * outFile) +/* + Function: gdImageWebpEx + + outputs the specified image to the specified file in + WebP format. The file must be open for writing. Under MSDOS and + all versions of Windows, it is important to use "wb" as opposed to + simply "w" as the mode when opening the file, and under Unix there + is no penalty for doing so. does not close the file; + your code must do so. + + If _quality_ is -1, a reasonable quality value (which should yield a + good general quality / size tradeoff for most situations) is used. Otherwise + _quality_ should be a value in the range 0-100, higher quality values + usually implying both higher quality and larger image sizes. + + If _quality_ is greater than or equal to then the image + will be written in the lossless WebP format. + + Variants: + + stores the image using a struct. + + stores the image to RAM. + + Parameters: + + im - The image to save. + outFile - The FILE pointer to write to. + quality - Compression quality (0-100). + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) gdImageWebpEx(gdImagePtr im, FILE *outFile, int quality) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageWebpCtx(im, out, quality); + out->gd_free(out); +} + +/* + Function: gdImageWebp + + Variant of which uses the default quality (-1). + + Parameters: + + im - The image to save + outFile - The FILE pointer to write to. + + Returns: + + Nothing. +*/ +BGD_DECLARE(void) gdImageWebp(gdImagePtr im, FILE *outFile) +{ + gdIOCtx *out = gdNewFileCtx(outFile); + if (out == NULL) { + return; + } + _gdImageWebpCtx(im, out, -1); + out->gd_free(out); +} + +/* + Function: gdImageWebpPtr + + See . +*/ +BGD_DECLARE(void *) gdImageWebpPtr(gdImagePtr im, int *size) { - gdIOCtx *out = gdNewFileCtx(outFile); - gdImageWebpCtx(im, out, -1); - out->gd_free(out); + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageWebpCtx(im, out, -1)) { + rv = NULL; + } else { + rv = gdDPExtractData(out, size); + } + out->gd_free(out); + + return rv; } -void * gdImageWebpPtr (gdImagePtr im, int *size) +/* + Function: gdImageWebpPtrEx + + See . +*/ +BGD_DECLARE(void *) gdImageWebpPtrEx(gdImagePtr im, int *size, int quality) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImageWebpCtx(im, out, -1); - rv = gdDPExtractData(out, size); - out->gd_free(out); + void *rv; - return rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + if (_gdImageWebpCtx(im, out, quality)) { + rv = NULL; + } else { + rv = gdDPExtractData(out, size); + } + out->gd_free(out); + return rv; } -void * gdImageWebpPtrEx (gdImagePtr im, int *size, int quality) +static void WebpWriteFree(gdWebpWritePtr webp) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx(2048, NULL); - gdImageWebpCtx(im, out, quality); - rv = gdDPExtractData(out, size); - out->gd_free(out); - return rv; + if (webp == NULL) { + return; + } + if (webp->encoder != NULL) { + WebPAnimEncoderDelete(webp->encoder); + } + if (webp->ownsCtx && webp->out != NULL) { + webp->out->gd_free(webp->out); + } + gdFree(webp); } + +static int WebpWriteEnsureEncoder(gdWebpWritePtr webp, gdImagePtr image) +{ + WebPAnimEncoderOptions encOptions; + + if (webp->encoder != NULL) { + return 1; + } + if (image == NULL) { + return 0; + } + webp->canvasWidth = + webp->options.canvasWidth > 0 ? webp->options.canvasWidth : gdImageSX(image); + webp->canvasHeight = + webp->options.canvasHeight > 0 ? webp->options.canvasHeight : gdImageSY(image); + if (webp->canvasWidth <= 0 || webp->canvasHeight <= 0) { + return 0; + } + if (!WebPAnimEncoderOptionsInit(&encOptions)) { + return 0; + } + encOptions.anim_params.loop_count = webp->options.loopCount; + encOptions.anim_params.bgcolor = (uint32_t)webp->options.backgroundColor; + if (webp->options.minimizeSize) { + encOptions.minimize_size = webp->options.minimizeSize; + } + if (webp->options.kmin || webp->options.kmax) { + encOptions.kmin = webp->options.kmin; + encOptions.kmax = webp->options.kmax; + } + if (webp->options.allowMixed) { + encOptions.allow_mixed = webp->options.allowMixed; + } + webp->encoder = WebPAnimEncoderNew(webp->canvasWidth, webp->canvasHeight, &encOptions); + return webp->encoder != NULL; +} + +static int WebpImageToRGBA(gdImagePtr im, uint8_t **rgba) +{ + uint8_t *p; + int x, y; + + *rgba = NULL; + if (im == NULL || !gdImageTrueColor(im)) { + gd_error("Palette image not supported by webp"); + return 0; + } + if (overflow2(gdImageSX(im), 4) || overflow2(gdImageSX(im) * 4, gdImageSY(im))) { + return 0; + } + *rgba = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im)); + if (*rgba == NULL) { + return 0; + } + p = *rgba; + for (y = 0; y < gdImageSY(im); y++) { + for (x = 0; x < gdImageSX(im); x++) { + int c = im->tpixels[y][x]; + *(p++) = gdTrueColorGetRed(c); + *(p++) = gdTrueColorGetGreen(c); + *(p++) = gdTrueColorGetBlue(c); + *(p++) = WebpGdAlphaToWebp(gdTrueColorGetAlpha(c)); + } + } + return 1; +} + +static int WebpWriteAssemble(gdWebpWritePtr webp) +{ + WebPData webpData; + int ok = 0; + + if (webp == NULL || webp->out == NULL || webp->finalized) { + return 0; + } + if (webp->encoder == NULL || webp->frameCount == 0) { + gd_error("gd-webp animation has no frames"); + return 0; + } + WebPDataInit(&webpData); + if (!WebPAnimEncoderAdd(webp->encoder, NULL, webp->timestamp, NULL)) { + gd_error("gd-webp animation flush failed: %s", WebPAnimEncoderGetError(webp->encoder)); + goto done; + } + if (!WebPAnimEncoderAssemble(webp->encoder, &webpData)) { + gd_error("gd-webp animation assembly failed: %s", WebPAnimEncoderGetError(webp->encoder)); + goto done; + } + if ((size_t)gdPutBuf(webpData.bytes, webpData.size, webp->out) != webpData.size) { + gd_error("gd-webp animation write error"); + goto done; + } + webp->finalized = 1; + ok = 1; +done: + WebPDataClear(&webpData); + return ok; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpen(FILE *outFile, const gdWebpWriteOptions *options) +{ + gdIOCtx *out; + gdWebpWritePtr webp; + + if (outFile == NULL) { + return NULL; + } + out = gdNewFileCtx(outFile); + if (out == NULL) { + return NULL; + } + webp = gdWebpWriteOpenCtx(out, options); + if (webp == NULL) { + out->gd_free(out); + return NULL; + } + webp->ownsCtx = 1; + return webp; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenCtx(gdIOCtxPtr out, const gdWebpWriteOptions *options) +{ + gdWebpWritePtr webp; + + if (out == NULL) { + return NULL; + } + webp = (gdWebpWritePtr)gdCalloc(1, sizeof(struct gdWebpWriteStruct)); + if (webp == NULL) { + return NULL; + } + webp->out = out; + webp->ownsCtx = 0; + if (options != NULL) { + webp->options = *options; + } + if (webp->options.quality == 0) { + webp->options.quality = -1; + } + return webp; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenPtr(const gdWebpWriteOptions *options) +{ + gdIOCtx *out; + gdWebpWritePtr webp; + + out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) { + return NULL; + } + webp = gdWebpWriteOpenCtx(out, options); + if (webp == NULL) { + out->gd_free(out); + return NULL; + } + webp->ownsCtx = 1; + webp->memoryWriter = 1; + return webp; +} + +BGD_DECLARE(int) +gdWebpWriteAddImage(gdWebpWritePtr webp, gdImagePtr image, int durationMs) +{ + WebPConfig config; + WebPPicture picture; + uint8_t *rgba = NULL; + int ok = 0; + + if (webp == NULL || image == NULL || durationMs < 0 || webp->finalized) { + return 0; + } + if (!WebpWriteEnsureEncoder(webp, image)) { + return 0; + } + if (gdImageSX(image) != webp->canvasWidth || gdImageSY(image) != webp->canvasHeight) { + gd_error("gd-webp animation frames must match canvas size"); + return 0; + } + if (!WebpImageToRGBA(image, &rgba)) { + return 0; + } + if (!WebPConfigInit(&config) || !WebPPictureInit(&picture)) { + goto done; + } + config.quality = webp->options.quality == -1 ? 80.0f : (float)webp->options.quality; + if (webp->options.lossless || webp->options.quality >= gdWebpLossless) { + config.lossless = 1; + if (config.quality > 100.0f) { + config.quality = 100.0f; + } + } + if (webp->options.method >= 0) { + config.method = webp->options.method; + } + if (!WebPValidateConfig(&config)) { + gd_error("gd-webp invalid animation encoder configuration"); + goto done; + } + picture.width = gdImageSX(image); + picture.height = gdImageSY(image); + picture.use_argb = 1; + if (!WebPPictureImportRGBA(&picture, rgba, gdImageSX(image) * 4)) { + goto free_picture; + } + if (!WebPAnimEncoderAdd(webp->encoder, &picture, webp->timestamp, &config)) { + gd_error("gd-webp animation add frame failed: %s", WebPAnimEncoderGetError(webp->encoder)); + goto free_picture; + } + webp->timestamp += durationMs; + webp->frameCount++; + ok = 1; +free_picture: + WebPPictureFree(&picture); +done: + gdFree(rgba); + return ok; +} + +BGD_DECLARE(void) gdWebpWriteClose(gdWebpWritePtr webp) +{ + if (webp == NULL) { + return; + } + if (!webp->memoryWriter) { + WebpWriteAssemble(webp); + } + WebpWriteFree(webp); +} + +BGD_DECLARE(void *) gdWebpWritePtrFinish(gdWebpWritePtr webp, int *size) +{ + void *rv = NULL; + + if (size != NULL) { + *size = 0; + } + if (webp == NULL || !webp->memoryWriter) { + WebpWriteFree(webp); + return NULL; + } + if (WebpWriteAssemble(webp)) { + rv = gdDPExtractData(webp->out, size); + } + WebpWriteFree(webp); + return rv; +} + +#else /* !HAVE_LIBWEBP */ + +static void _noWebpError(void) { gd_error("WEBP image support has been disabled\n"); } + +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebp(FILE *inFile) +{ + ARG_NOT_USED(inFile); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpCtx(gdIOCtx *infile) +{ + ARG_NOT_USED(infile); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(void) gdImageWebpCtx(gdImagePtr im, gdIOCtx *outfile, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outfile); + ARG_NOT_USED(quality); + _noWebpError(); +} + +BGD_DECLARE(void) gdImageWebpEx(gdImagePtr im, FILE *outFile, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + ARG_NOT_USED(quality); + _noWebpError(); +} + +BGD_DECLARE(void) gdImageWebp(gdImagePtr im, FILE *outFile) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(outFile); + _noWebpError(); +} + +BGD_DECLARE(void *) gdImageWebpPtr(gdImagePtr im, int *size) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(void *) gdImageWebpPtrEx(gdImagePtr im, int *size, int quality) +{ + ARG_NOT_USED(im); + ARG_NOT_USED(size); + ARG_NOT_USED(quality); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(int) gdWebpIsAnimated(FILE *fd) +{ + ARG_NOT_USED(fd); + _noWebpError(); + return -1; +} + +BGD_DECLARE(int) gdWebpIsAnimatedCtx(gdIOCtxPtr in) +{ + ARG_NOT_USED(in); + _noWebpError(); + return -1; +} + +BGD_DECLARE(int) gdWebpIsAnimatedPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noWebpError(); + return -1; +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpen(FILE *fd) +{ + ARG_NOT_USED(fd); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenCtx(gdIOCtxPtr in) +{ + ARG_NOT_USED(in); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdWebpReadPtr) gdWebpReadOpenPtr(int size, void *data) +{ + ARG_NOT_USED(size); + ARG_NOT_USED(data); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(void) gdWebpReadClose(gdWebpReadPtr webp) +{ + ARG_NOT_USED(webp); + _noWebpError(); +} + +BGD_DECLARE(int) gdWebpReadGetInfo(gdWebpReadPtr webp, gdWebpInfo *info) +{ + ARG_NOT_USED(webp); + ARG_NOT_USED(info); + _noWebpError(); + return 0; +} + +BGD_DECLARE(int) +gdWebpReadNextFrame(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *frame) +{ + ARG_NOT_USED(webp); + ARG_NOT_USED(info); + ARG_NOT_USED(frame); + _noWebpError(); + return -1; +} + +BGD_DECLARE(int) +gdWebpReadNextImage(gdWebpReadPtr webp, gdWebpFrameInfo *info, gdImagePtr *image) +{ + ARG_NOT_USED(webp); + ARG_NOT_USED(info); + ARG_NOT_USED(image); + _noWebpError(); + return -1; +} + +BGD_DECLARE(gdImagePtr) gdWebpReadCloneImage(gdWebpReadPtr webp) +{ + ARG_NOT_USED(webp); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpen(FILE *outFile, const gdWebpWriteOptions *options) +{ + ARG_NOT_USED(outFile); + ARG_NOT_USED(options); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenCtx(gdIOCtxPtr out, const gdWebpWriteOptions *options) +{ + ARG_NOT_USED(out); + ARG_NOT_USED(options); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(gdWebpWritePtr) +gdWebpWriteOpenPtr(const gdWebpWriteOptions *options) +{ + ARG_NOT_USED(options); + _noWebpError(); + return NULL; +} + +BGD_DECLARE(int) +gdWebpWriteAddImage(gdWebpWritePtr webp, gdImagePtr image, int durationMs) +{ + ARG_NOT_USED(webp); + ARG_NOT_USED(image); + ARG_NOT_USED(durationMs); + _noWebpError(); + return 0; +} + +BGD_DECLARE(void) gdWebpWriteClose(gdWebpWritePtr webp) +{ + ARG_NOT_USED(webp); + _noWebpError(); +} + +BGD_DECLARE(void *) gdWebpWritePtrFinish(gdWebpWritePtr webp, int *size) +{ + ARG_NOT_USED(webp); + ARG_NOT_USED(size); + _noWebpError(); + return NULL; +} + #endif /* HAVE_LIBWEBP */ diff --git a/ext/gd/libgd/gd_xbm.c b/ext/gd/libgd/gd_xbm.c index 3c655a2998c1..3e8a75a18054 100644 --- a/ext/gd/libgd/gd_xbm.c +++ b/ext/gd/libgd/gd_xbm.c @@ -1,235 +1,303 @@ -/* - +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: Marcus Boerger | - +----------------------------------------------------------------------+ +/** + * File: XBM IO + * + * Read and write XBM images. */ /* $Id$ */ -#include -#include -#include -#include #include "gd.h" -#include "gdhelpers.h" #include "gd_errors.h" - +#include "gd_intern.h" +#include "gdhelpers.h" +#include +#include +#include +#include +#include +#include #include "php.h" - #define MAX_XBM_LINE_SIZE 255 -/* {{{ gdImagePtr gdImageCreateFromXbm */ -gdImagePtr gdImageCreateFromXbm(FILE * fd) +/* + Function: gdImageCreateFromXbm + + is called to load images from X bitmap + format files. Invoke with an already opened + pointer to a file containing the desired + image. returns a to the new + image, or NULL if unable to load the image (most often because the + file is corrupt or does not contain an X bitmap format + image). does not close the file. + + You can inspect the sx and sy members of the image to determine + its size. The image must eventually be destroyed using + . + + X11 X bitmaps (which define a char[]) as well as X10 X bitmaps (which define + a short[]) are supported. + + Parameters: + + fd - The input FILE pointer + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + (start code) + + gdImagePtr im; + FILE *in; + in = fopen("myxbm.xbm", "rb"); + im = gdImageCreateFromXbm(in); + fclose(in); + // ... Use the image ... + gdImageDestroy(im); + + (end code) +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE *fd) { - char fline[MAX_XBM_LINE_SIZE]; - char iname[MAX_XBM_LINE_SIZE]; - char *type; - int value; - unsigned int width = 0, height = 0; - int fail = 0; - int max_bit = 0; - - gdImagePtr im; - int bytes = 0, i; - int bit, x = 0, y = 0; - int ch; - char h[8]; - unsigned int b; - - rewind(fd); - while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) { - fline[MAX_XBM_LINE_SIZE-1] = '\0'; - if (strlen(fline) == MAX_XBM_LINE_SIZE-1) { - return 0; - } - if (sscanf(fline, "#define %s %d", iname, &value) == 2) { - if (!(type = strrchr(iname, '_'))) { - type = iname; - } else { - type++; - } - - if (!strcmp("width", type)) { - width = (unsigned int) value; - } - if (!strcmp("height", type)) { - height = (unsigned int) value; - } - } else { - if ( sscanf(fline, "static unsigned char %s = {", iname) == 1 - || sscanf(fline, "static char %s = {", iname) == 1) - { - max_bit = 128; - } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1 - || sscanf(fline, "static short %s = {", iname) == 1) - { - max_bit = 32768; - } - if (max_bit) { - bytes = (width + 7) / 8 * height; - if (!bytes) { - return 0; - } - if (!(type = strrchr(iname, '_'))) { - type = iname; - } else { - type++; - } - if (!strcmp("bits[]", type)) { - break; - } - } - } - } - if (!bytes || !max_bit) { - return 0; - } - - if(!(im = gdImageCreate(width, height))) { - return 0; - } - gdImageColorAllocate(im, 255, 255, 255); - gdImageColorAllocate(im, 0, 0, 0); - h[2] = '\0'; - h[4] = '\0'; - for (i = 0; i < bytes; i++) { - while (1) { - if ((ch=getc(fd)) == EOF) { - fail = 1; - break; - } - if (ch == 'x') { - break; - } - } - if (fail) { - break; - } - /* Get hex value */ - if ((ch=getc(fd)) == EOF) { - break; - } - h[0] = ch; - if ((ch=getc(fd)) == EOF) { - break; - } - h[1] = ch; - if (max_bit == 32768) { - if ((ch=getc(fd)) == EOF) { - break; - } - h[2] = ch; - if ((ch=getc(fd)) == EOF) { - break; - } - h[3] = ch; - } - if (sscanf(h, "%x", &b) != 1) { - gd_error("Invalid XBM"); - gdImageDestroy(im); - return 0; - } - for (bit = 1; bit <= max_bit; bit = bit << 1) { - gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0); - if (x == im->sx) { - x = 0; - y++; - if (y == im->sy) { - return im; - } - break; - } - } - } - - gd_error("EOF before image was complete"); - gdImageDestroy(im); - return 0; + char fline[MAX_XBM_LINE_SIZE]; + char iname[MAX_XBM_LINE_SIZE]; + char *type; + int value; + unsigned int width = 0, height = 0; + int fail = 0; + int max_bit = 0; + + gdImagePtr im; + int bytes = 0, i; + int bit, x = 0, y = 0; + int ch; + char h[8]; + unsigned int b; + + rewind(fd); + while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) { + fline[MAX_XBM_LINE_SIZE - 1] = '\0'; + if (strlen(fline) == MAX_XBM_LINE_SIZE - 1) { + return 0; + } + if (sscanf(fline, "#define %s %d", iname, &value) == 2) { + if (!(type = strrchr(iname, '_'))) { + type = iname; + } else { + type++; + } + + if (!strcmp("width", type)) { + width = (unsigned int)value; + } + if (!strcmp("height", type)) { + height = (unsigned int)value; + } + } else { + if (sscanf(fline, "static unsigned char %s = {", iname) == 1 || + sscanf(fline, "static char %s = {", iname) == 1) { + max_bit = 128; + } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1 || + sscanf(fline, "static short %s = {", iname) == 1) { + max_bit = 32768; + } + if (max_bit) { + bytes = (width + 7) / 8 * height; + if (!bytes) { + return 0; + } + if (!(type = strrchr(iname, '_'))) { + type = iname; + } else { + type++; + } + if (!strcmp("bits[]", type)) { + break; + } + } + } + } + if (!bytes || !max_bit) { + return 0; + } + + if (!(im = gdImageCreate(width, height))) { + return 0; + } + gdImageColorAllocate(im, 255, 255, 255); + gdImageColorAllocate(im, 0, 0, 0); + h[2] = '\0'; + h[4] = '\0'; + for (i = 0; i < bytes; i++) { + while (1) { + if ((ch = getc(fd)) == EOF) { + fail = 1; + break; + } + if (ch == 'x') { + break; + } + } + if (fail) { + break; + } + /* Get hex value */ + if ((ch = getc(fd)) == EOF) { + break; + } + h[0] = ch; + if ((ch = getc(fd)) == EOF) { + break; + } + h[1] = ch; + if (max_bit == 32768) { + if ((ch = getc(fd)) == EOF) { + break; + } + h[2] = ch; + if ((ch = getc(fd)) == EOF) { + break; + } + h[3] = ch; + } + if (sscanf(h, "%x", &b) != 1) { + gd_error("Invalid XBM"); + gdImageDestroy(im); + return 0; + } + for (bit = 1; bit <= max_bit; bit = bit << 1) { + gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0); + if (x == im->sx) { + x = 0; + y++; + if (y == im->sy) { + return im; + } + break; + } + } + } + + gd_error("EOF before image was complete"); + gdImageDestroy(im); + return 0; } -/* }}} */ /* {{{ gdCtxPrintf */ -void gdCtxPrintf(gdIOCtx * out, const char *format, ...) +static void gdCtxPrintf(gdIOCtx *out, const char *format, ...) { - char *buf; - int len; - va_list args; - - va_start(args, format); - len = vspprintf(&buf, 0, format, args); - va_end(args); - out->putBuf(out, buf, len); - efree(buf); + char *buf; + int len; + va_list args; + + va_start(args, format); + len = vspprintf(&buf, 0, format, args); + va_end(args); + out->putBuf(out, buf, len); + gdFree(buf); } /* }}} */ -/* {{{ gdImageXbmCtx */ -void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out) +/* The compiler will optimize strlen(constant) to a constant number. */ +#define gdCtxPuts(out, s) out->putBuf(out, s, strlen(s)) + +/** + * Function: gdImageXbmCtx + * + * Writes an image to an IO context in X11 bitmap format. + * + * Parameters: + * + * image - The to write. + * file_name - The prefix of the XBM's identifiers. Illegal characters are + * automatically stripped. + * gd - Which color to use as forground color. All pixels with another + * color are unset. + * out - The to write the image file to. + * + */ +BGD_DECLARE(void) +gdImageXbmCtx(gdImagePtr image, char *file_name, int fg, gdIOCtx *out) { - int x, y, c, b, sx, sy, p; - char *name, *f; - size_t i, l; - - name = file_name; - if ((f = strrchr(name, '/')) != NULL) name = f+1; - if ((f = strrchr(name, '\\')) != NULL) name = f+1; - name = estrdup(name); - if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0'; - if ((l = strlen(name)) == 0) { - efree(name); - name = estrdup("image"); - } else { - for (i=0; i= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || + (c == '_'))) { + + // Anything else (spaces, punctuation, accents, UTF-8 bytes) + // becomes '_' + name[i] = '_'; + } + } + } + + /* Since "name" comes from the user, run it through a direct puts. + * Trying to printf it into a local buffer means we'd need a large + * or dynamic buffer to hold it all. */ + + /* #define _width 1234 */ + gdCtxPuts(out, "#define "); + gdCtxPuts(out, name); + gdCtxPuts(out, "_width "); + gdCtxPrintf(out, "%d\n", gdImageSX(image)); + + /* #define _height 1234 */ + gdCtxPuts(out, "#define "); + gdCtxPuts(out, name); + gdCtxPuts(out, "_height "); + gdCtxPrintf(out, "%d\n", gdImageSY(image)); + + /* static unsigned char _bits[] = {\n */ + gdCtxPuts(out, "static unsigned char "); + gdCtxPuts(out, name); + gdCtxPuts(out, "_bits[] = {\n "); + + gdFree(name); + + b = 1; + p = 0; + c = 0; + sx = gdImageSX(image); + sy = gdImageSY(image); + for (y = 0; y < sy; y++) { + for (x = 0; x < sx; x++) { + if (gdImageGetPixel(image, x, y) == fg) { + c |= b; + } + if ((b == 128) || (x == sx - 1)) { + b = 1; + if (p) { + gdCtxPuts(out, ", "); + if (!(p % 12)) { + gdCtxPuts(out, "\n "); + p = 12; + } + } + p++; + gdCtxPrintf(out, "0x%02X", c); + c = 0; + } else { + b <<= 1; + } + } + } + gdCtxPuts(out, "};\n"); } -/* }}} */ diff --git a/ext/gd/libgd/gdcache.c b/ext/gd/libgd/gdcache.c index 0d6e65194a8f..85675865e3bd 100644 --- a/ext/gd/libgd/gdcache.c +++ b/ext/gd/libgd/gdcache.c @@ -17,7 +17,9 @@ * John Ellson (ellson@graphviz.org) Oct 31, 1997 * * Test this with: - * gcc -o gdcache -g -Wall -DTEST gdcache.c + * gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c -lgd + * or + * gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c libgd.a * * The cache is implemented by a singly-linked list of elements * each containing a pointer to a user struct that is being managed by @@ -51,159 +53,163 @@ /* implementation */ /*********************************************************/ - /* create a new cache */ -gdCache_head_t * -gdCacheCreate ( - int size, - gdCacheTestFn_t gdCacheTest, - gdCacheFetchFn_t gdCacheFetch, - gdCacheReleaseFn_t gdCacheRelease) +gdCache_head_t *gdCacheCreate(int size, gdCacheTestFn_t gdCacheTest, gdCacheFetchFn_t gdCacheFetch, + gdCacheReleaseFn_t gdCacheRelease) { - gdCache_head_t *head; - - head = (gdCache_head_t *) gdPMalloc(sizeof (gdCache_head_t)); - head->mru = NULL; - head->size = size; - head->gdCacheTest = gdCacheTest; - head->gdCacheFetch = gdCacheFetch; - head->gdCacheRelease = gdCacheRelease; - return head; + gdCache_head_t *head; + + head = (gdCache_head_t *)gdMalloc(sizeof(gdCache_head_t)); + if (!head) { + return NULL; + } + + head->mru = NULL; + head->size = size; + head->gdCacheTest = gdCacheTest; + head->gdCacheFetch = gdCacheFetch; + head->gdCacheRelease = gdCacheRelease; + + return head; } -void -gdCacheDelete (gdCache_head_t * head) +void gdCacheDelete(gdCache_head_t *head) { - gdCache_element_t *elem, *prev; - - elem = head->mru; - while (elem) - { - (*(head->gdCacheRelease)) (elem->userdata); - prev = elem; - elem = elem->next; - gdPFree ((char *) prev); + gdCache_element_t *elem, *prev; + + elem = head->mru; + while (elem) { + (*(head->gdCacheRelease))(elem->userdata); + prev = elem; + elem = elem->next; + gdFree((char *)prev); } - gdPFree ((char *) head); + gdFree((char *)head); } -void * -gdCacheGet (gdCache_head_t * head, void *keydata) +void *gdCacheGet(gdCache_head_t *head, void *keydata) { - int i = 0; - gdCache_element_t *elem, *prev = NULL, *prevprev = NULL; - void *userdata; - - elem = head->mru; - while (elem) - { - if ((*(head->gdCacheTest)) (elem->userdata, keydata)) - { - if (i) - { /* if not already most-recently-used */ - /* relink to top of list */ - prev->next = elem->next; - elem->next = head->mru; - head->mru = elem; - } - return elem->userdata; - } - prevprev = prev; - prev = elem; - elem = elem->next; - i++; - } - userdata = (*(head->gdCacheFetch)) (&(head->error), keydata); - if (!userdata) - { - /* if there was an error in the fetch then don't cache */ - return NULL; + int i = 0; + gdCache_element_t *elem, *prev = NULL, *prevprev = NULL; + void *userdata; + + elem = head->mru; + while (elem) { + if ((*(head->gdCacheTest))(elem->userdata, keydata)) { + if (i) { + /* if not already most-recently-used */ + /* relink to top of list */ + prev->next = elem->next; + elem->next = head->mru; + head->mru = elem; + } + return elem->userdata; + } + prevprev = prev; + prev = elem; + elem = elem->next; + i++; } - if (i < head->size) - { /* cache still growing - add new elem */ - elem = (gdCache_element_t *) gdPMalloc(sizeof (gdCache_element_t)); + userdata = (*(head->gdCacheFetch))(&(head->error), keydata); + if (!userdata) { + /* if there was an error in the fetch then don't cache */ + return NULL; } - else - { /* cache full - replace least-recently-used */ - /* preveprev becomes new end of list */ - prevprev->next = NULL; - elem = prev; - (*(head->gdCacheRelease)) (elem->userdata); + + if (i < head->size) { + /* cache still growing - add new elem */ + elem = (gdCache_element_t *)gdMalloc(sizeof(gdCache_element_t)); + if (!elem) { + (*(head->gdCacheRelease))(userdata); + return NULL; + } + } else { + /* cache full - replace least-recently-used */ + if (!prevprev) { + /* cache size is 1 */ + head->mru = NULL; + } else { + /* prevprev becomes new end of list */ + prevprev->next = NULL; + } + elem = prev; + if (!elem) { + /* Happen only with an invalid cache size (<= 0). Bad state but + * still worth handling it here before deref */ + (*(head->gdCacheRelease))(userdata); + return NULL; + } + (*(head->gdCacheRelease))(elem->userdata); } - /* relink to top of list */ - elem->next = head->mru; - head->mru = elem; - elem->userdata = userdata; - return userdata; -} + /* relink to top of list */ + elem->next = head->mru; + head->mru = elem; + elem->userdata = userdata; + return userdata; +} /*********************************************************/ /* test stub */ /*********************************************************/ - #ifdef TEST #include -typedef struct -{ - int key; - int value; -} -key_value_t; +typedef struct { + int key; + int value; +} key_value_t; -static int -cacheTest (void *map, void *key) -{ - return (((key_value_t *) map)->key == *(int *) key); -} +static int cacheTest(void *map, void *key) { return (((key_value_t *)map)->key == *(int *)key); } -static void * -cacheFetch (char **error, void *key) +static void *cacheFetch(char **error, void *key) { - key_value_t *map; + key_value_t *map; - map = (key_value_t *) gdMalloc (sizeof (key_value_t)); - map->key = *(int *) key; - map->value = 3; + map = (key_value_t *)gdMalloc(sizeof(key_value_t)); + if (!map) { + *error = "gdMalloc failed"; + return NULL; + } + map->key = *(int *)key; + map->value = 3; - *error = NULL; - return (void *) map; -} + *error = NULL; -static void -cacheRelease (void *map) -{ - gdFree ((char *) map); + return (void *)map; } -int -main (char *argv[], int argc) +static void cacheRelease(void *map) { gdFree((char *)map); } + +int main(int argc, char **argv) { - gdCache_head_t *cacheTable; - int elem, key; - - cacheTable = gdCacheCreate (3, cacheTest, cacheFetch, cacheRelease); - - key = 20; - elem = *(int *) gdCacheGet (cacheTable, &key); - key = 30; - elem = *(int *) gdCacheGet (cacheTable, &key); - key = 40; - elem = *(int *) gdCacheGet (cacheTable, &key); - key = 50; - elem = *(int *) gdCacheGet (cacheTable, &key); - key = 30; - elem = *(int *) gdCacheGet (cacheTable, &key); - key = 30; - elem = *(int *) gdCacheGet (cacheTable, &key); - - gdCacheDelete (cacheTable); - - return 0; + gdCache_head_t *cacheTable; + int elem, key; + + cacheTable = gdCacheCreate(3, cacheTest, cacheFetch, cacheRelease); + if (!cacheTable) { + exit(1); + } + + key = 20; + elem = *(int *)gdCacheGet(cacheTable, &key); + key = 30; + elem = *(int *)gdCacheGet(cacheTable, &key); + key = 40; + elem = *(int *)gdCacheGet(cacheTable, &key); + key = 50; + elem = *(int *)gdCacheGet(cacheTable, &key); + key = 30; + elem = *(int *)gdCacheGet(cacheTable, &key); + key = 30; + elem = *(int *)gdCacheGet(cacheTable, &key); + + gdCacheDelete(cacheTable); + + return 0; } #endif /* TEST */ diff --git a/ext/gd/libgd/gdcache.h b/ext/gd/libgd/gdcache.h index dd262e3e98da..4531d6c33e66 100644 --- a/ext/gd/libgd/gdcache.h +++ b/ext/gd/libgd/gdcache.h @@ -1,3 +1,7 @@ +#ifdef __cplusplus +extern "C" { +#endif + /* * gdcache.h * @@ -8,7 +12,9 @@ * John Ellson (ellson@graphviz.org) Oct 31, 1997 * * Test this with: - * gcc -o gdcache -g -Wall -DTEST gdcache.c + * gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c -lgd + * or + * gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c libgd.a * * The cache is implemented by a singly-linked list of elements * each containing a pointer to a user struct that is being managed by @@ -53,31 +59,29 @@ typedef void (*gdCacheReleaseFn_t)(void *userdata); /* element structure */ typedef struct gdCache_element_s gdCache_element_t; struct gdCache_element_s { - gdCache_element_t *next; - void *userdata; + gdCache_element_t *next; + void *userdata; }; /* head structure */ typedef struct gdCache_head_s gdCache_head_t; struct gdCache_head_s { - gdCache_element_t *mru; - int size; - char *error; - gdCacheTestFn_t gdCacheTest; - gdCacheFetchFn_t gdCacheFetch; - gdCacheReleaseFn_t gdCacheRelease; + gdCache_element_t *mru; + int size; + char *error; + gdCacheTestFn_t gdCacheTest; + gdCacheFetchFn_t gdCacheFetch; + gdCacheReleaseFn_t gdCacheRelease; }; /* function templates */ -gdCache_head_t * -gdCacheCreate( - int size, - gdCacheTestFn_t gdCacheTest, - gdCacheFetchFn_t gdCacheFetch, - gdCacheReleaseFn_t gdCacheRelease ); +gdCache_head_t *gdCacheCreate(int size, gdCacheTestFn_t gdCacheTest, gdCacheFetchFn_t gdCacheFetch, + gdCacheReleaseFn_t gdCacheRelease); -void -gdCacheDelete( gdCache_head_t *head ); +void gdCacheDelete(gdCache_head_t *head); -void * -gdCacheGet( gdCache_head_t *head, void *keydata ); +void *gdCacheGet(gdCache_head_t *head, void *keydata); + +#ifdef __cplusplus +} +#endif diff --git a/ext/gd/libgd/gddemo.c b/ext/gd/libgd/gddemo.c index a5ceeb53b86b..b7f7184c88fa 100644 --- a/ext/gd/libgd/gddemo.c +++ b/ext/gd/libgd/gddemo.c @@ -1,118 +1,107 @@ -#include #include "gd.h" #include "gdfontg.h" #include "gdfonts.h" +#include -int -main (void) +int main(void) { - /* Input and output files */ - FILE *in; - FILE *out; + /* Input and output files */ + FILE *in; + FILE *out; - /* Input and output images */ - gdImagePtr im_in = 0, im_out = 0; + /* Input and output images */ + gdImagePtr im_in = 0, im_out = 0; - /* Brush image */ - gdImagePtr brush; + /* Brush image */ + gdImagePtr brush; - /* Color indexes */ - int white; - int blue; - int red; - int green; + /* Color indexes */ + int white; + int blue; + int red; + int green; - /* Points for polygon */ - gdPoint points[3]; + /* Points for polygon */ + gdPoint points[3]; - /* Create output image, 256 by 256 pixels, true color. */ - im_out = gdImageCreateTrueColor (256, 256); - /* First color allocated is background. */ - white = gdImageColorAllocate (im_out, 255, 255, 255); + /* Create output image, 256 by 256 pixels, true color. */ + im_out = gdImageCreateTrueColor(256, 256); + /* First color allocated is background. */ + white = gdImageColorAllocate(im_out, 255, 255, 255); - /* Set transparent color. */ - gdImageColorTransparent (im_out, white); + /* Set transparent color. */ + gdImageColorTransparent(im_out, white); - /* Try to load demoin.png and paste part of it into the - output image. */ - in = fopen ("demoin.png", "rb"); - if (!in) - { - fprintf (stderr, "Can't load source image; this demo\n"); - fprintf (stderr, "is much more impressive if demoin.png\n"); - fprintf (stderr, "is available.\n"); - im_in = 0; - } - else - { - im_in = gdImageCreateFromPng (in); - fclose (in); - /* Now copy, and magnify as we do so */ - gdImageCopyResized (im_out, im_in, - 32, 32, 0, 0, 192, 192, 255, 255); + /* Try to load demoin.png and paste part of it into the + output image. */ + in = fopen("demoin.png", "rb"); + if (!in) { + fprintf(stderr, "Can't load source image; this demo\n"); + fprintf(stderr, "is much more impressive if demoin.png\n"); + fprintf(stderr, "is available.\n"); + im_in = 0; + } else { + im_in = gdImageCreateFromPng(in); + fclose(in); + /* Now copy, and magnify as we do so */ + gdImageCopyResized(im_out, im_in, 32, 32, 0, 0, 192, 192, 255, 255); } - red = gdImageColorAllocate (im_out, 255, 0, 0); - green = gdImageColorAllocate (im_out, 0, 255, 0); - blue = gdImageColorAllocate (im_out, 0, 0, 255); - /* Rectangle */ - gdImageLine (im_out, 16, 16, 240, 16, green); - gdImageLine (im_out, 240, 16, 240, 240, green); - gdImageLine (im_out, 240, 240, 16, 240, green); - gdImageLine (im_out, 16, 240, 16, 16, green); - /* Circle */ - gdImageArc (im_out, 128, 128, 60, 20, 0, 720, blue); - /* Arc */ - gdImageArc (im_out, 128, 128, 40, 40, 90, 270, blue); - /* Flood fill: doesn't do much on a continuously - variable tone jpeg original. */ - gdImageFill (im_out, 8, 8, blue); - /* Polygon */ - points[0].x = 64; - points[0].y = 0; - points[1].x = 0; - points[1].y = 128; - points[2].x = 128; - points[2].y = 128; - gdImageFilledPolygon (im_out, points, 3, green); - /* Brush. A fairly wild example also involving a line style! */ - if (im_in) - { - int style[8]; - brush = gdImageCreateTrueColor (16, 16); - gdImageCopyResized (brush, im_in, - 0, 0, 0, 0, - gdImageSX (brush), gdImageSY (brush), - gdImageSX (im_in), gdImageSY (im_in)); - gdImageSetBrush (im_out, brush); - /* With a style, so they won't overprint each other. - Normally, they would, yielding a fat-brush effect. */ - style[0] = 0; - style[1] = 0; - style[2] = 0; - style[3] = 0; - style[4] = 0; - style[5] = 0; - style[6] = 0; - style[7] = 1; - gdImageSetStyle (im_out, style, 8); - /* Draw the styled, brushed line */ - gdImageLine (im_out, 0, 255, 255, 0, gdStyledBrushed); + red = gdImageColorAllocate(im_out, 255, 0, 0); + green = gdImageColorAllocate(im_out, 0, 255, 0); + blue = gdImageColorAllocate(im_out, 0, 0, 255); + /* Rectangle */ + gdImageLine(im_out, 16, 16, 240, 16, green); + gdImageLine(im_out, 240, 16, 240, 240, green); + gdImageLine(im_out, 240, 240, 16, 240, green); + gdImageLine(im_out, 16, 240, 16, 16, green); + /* Circle */ + gdImageArc(im_out, 128, 128, 60, 20, 0, 720, blue); + /* Arc */ + gdImageArc(im_out, 128, 128, 40, 40, 90, 270, blue); + /* Flood fill: doesn't do much on a continuously + variable tone jpeg original. */ + gdImageFill(im_out, 8, 8, blue); + /* Polygon */ + points[0].x = 64; + points[0].y = 0; + points[1].x = 0; + points[1].y = 128; + points[2].x = 128; + points[2].y = 128; + gdImageFilledPolygon(im_out, points, 3, green); + /* Brush. A fairly wild example also involving a line style! */ + if (im_in) { + int style[8]; + brush = gdImageCreateTrueColor(16, 16); + gdImageCopyResized(brush, im_in, 0, 0, 0, 0, gdImageSX(brush), gdImageSY(brush), + gdImageSX(im_in), gdImageSY(im_in)); + gdImageSetBrush(im_out, brush); + /* With a style, so they won't overprint each other. + Normally, they would, yielding a fat-brush effect. */ + style[0] = 0; + style[1] = 0; + style[2] = 0; + style[3] = 0; + style[4] = 0; + style[5] = 0; + style[6] = 0; + style[7] = 1; + gdImageSetStyle(im_out, style, 8); + /* Draw the styled, brushed line */ + gdImageLine(im_out, 0, 255, 255, 0, gdStyledBrushed); } - /* Text */ - gdImageString (im_out, gdFontGiant, 32, 32, - (unsigned char *) "hi", red); - gdImageStringUp (im_out, gdFontSmall, 64, 64, - (unsigned char *) "hi", red); - /* Make output image interlaced (progressive, in the case of JPEG) */ - gdImageInterlace (im_out, 1); - out = fopen ("demoout.png", "wb"); - /* Write PNG */ - gdImagePng (im_out, out); - fclose (out); - gdImageDestroy (im_out); - if (im_in) - { - gdImageDestroy (im_in); + /* Text */ + gdImageString(im_out, gdFontGiant, 32, 32, (unsigned char *)"hi", red); + gdImageStringUp(im_out, gdFontSmall, 64, 64, (unsigned char *)"hi", red); + /* Make output image interlaced (progressive, in the case of JPEG) */ + gdImageInterlace(im_out, 1); + out = fopen("demoout.png", "wb"); + /* Write PNG */ + gdImagePng(im_out, out); + fclose(out); + gdImageDestroy(im_out); + if (im_in) { + gdImageDestroy(im_in); } - return 0; + return 0; } diff --git a/ext/gd/libgd/gdfontg.c b/ext/gd/libgd/gdfontg.c index edddd0990d8e..c7306fc89f8f 100644 --- a/ext/gd/libgd/gdfontg.c +++ b/ext/gd/libgd/gdfontg.c @@ -1,5 +1,3 @@ - - /* This is a header file for gd font, generated using bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz @@ -10,4380 +8,35100 @@ "Libor Skarvada, libor@informatics.muni.cz" */ - +/** + * File: Giant Font + * + * A very large ISO-8859-2 raster font (9x15 pixels). + * + * The font is supposed to be used with and + * and their variants. + */ #include "gdfontg.h" -static const char gdFontGiantData[] = -{ -/* Char 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 1 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 1, 0, - -/* Char 3 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 4 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 5 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 6 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 7 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 10 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 11 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 12 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 13 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 14 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 15 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 16 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 17 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 18 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 19 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 20 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 21 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 22 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 23 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 24 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 25 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 26 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 27 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 28 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 29 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 30 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 31 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 32 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 33 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 34 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 35 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 36 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 37 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 38 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 39 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 40 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 42 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 43 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 44 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 45 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 46 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 47 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 48 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 49 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 50 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 51 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 52 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 53 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 54 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 55 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 56 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 57 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 58 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 59 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 60 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 61 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 62 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 63 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 64 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 65 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 66 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 67 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 68 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 69 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 70 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 71 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 72 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 73 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 74 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 75 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 76 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 77 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 78 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 79 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 80 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 81 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 82 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 83 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 84 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 85 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 86 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 87 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 88 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 89 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 90 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 91 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 92 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 93 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 94 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 95 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 96 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 97 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 98 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 99 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 100 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 101 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 102 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 103 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - -/* Char 104 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 105 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 106 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, - -/* Char 107 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 108 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 109 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 110 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 111 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 112 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - -/* Char 113 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - -/* Char 114 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 115 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 116 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 117 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 118 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 119 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 120 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 121 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - -/* Char 122 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 123 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 124 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 125 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 126 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 127 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 128 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 129 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 130 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 131 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 132 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 133 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 134 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 135 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 136 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 137 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 138 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 139 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 140 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 141 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 142 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 143 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 144 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 145 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 146 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 147 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 148 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 149 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 150 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 151 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 152 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 153 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 154 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 155 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 156 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 157 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 158 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 159 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 160 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 161 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - -/* Char 162 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 163 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 164 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 165 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 166 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 167 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 168 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 169 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 170 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - -/* Char 171 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 172 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 173 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 174 */ - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 175 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 176 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 177 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, - -/* Char 178 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, - -/* Char 179 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 180 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 181 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 182 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 183 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 184 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - -/* Char 185 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 186 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - -/* Char 187 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 188 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 189 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 190 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 191 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 192 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 193 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 194 */ - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 195 */ - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 196 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 197 */ - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 198 */ - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 199 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - -/* Char 200 */ - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 201 */ - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 202 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - -/* Char 203 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 204 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 205 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 206 */ - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 207 */ - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 208 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 209 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 210 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 211 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 212 */ - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 213 */ - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 214 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 215 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 216 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 217 */ - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 218 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 219 */ - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 220 */ - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 221 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 222 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - -/* Char 223 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 224 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 225 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 226 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 227 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 228 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 229 */ - 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 230 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 231 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - -/* Char 232 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 233 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 234 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - -/* Char 235 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 236 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 237 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 238 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 239 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 240 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 241 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 242 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 243 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 244 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 245 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 246 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 247 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 248 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 249 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 250 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 251 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 252 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 253 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, - -/* Char 254 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, - -/* Char 255 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - +char gdFontGiantData[] = { + /* Char 0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 1 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 2 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + + /* Char 3 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 4 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 5 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 6 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 7 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 9 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 11 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 12 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 13 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 14 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 15 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 16 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 17 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 18 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 19 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 20 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 21 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 22 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 23 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 24 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 25 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 26 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 27 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 28 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 29 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 30 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 31 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 32 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 33 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 34 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 35 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 36 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 37 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 38 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 39 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 40 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 41 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 42 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 43 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 44 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 45 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 46 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 47 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 48 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 49 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 50 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 51 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 52 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 53 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 54 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 55 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 56 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 57 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 58 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 59 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 60 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 61 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 62 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 63 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 64 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 65 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 66 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 67 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 68 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 69 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 70 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 71 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 72 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 73 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 74 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 75 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 76 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 77 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 78 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 79 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 80 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 81 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 82 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 83 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 84 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 85 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 86 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 87 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 88 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 89 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 90 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 91 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 92 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 93 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 94 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 95 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 96 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 97 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 98 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 99 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 100 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 101 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 102 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 103 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 104 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 105 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 106 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 107 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 108 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 109 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 110 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 111 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 112 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 113 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 114 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 115 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 116 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 117 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 118 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 119 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 120 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 121 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 122 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 123 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 124 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 125 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 126 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 127 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 128 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 129 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 130 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 131 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 132 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 133 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 134 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 135 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 136 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 137 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 138 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 139 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 140 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 141 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 142 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 143 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 144 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 145 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 146 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 147 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 148 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 149 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 150 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 151 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 152 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 153 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 154 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 155 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 156 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 157 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 158 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 159 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 160 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 161 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 162 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 163 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 164 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 165 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 166 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 167 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 168 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 169 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 170 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + + /* Char 171 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 172 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 173 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 174 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 175 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 176 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 177 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + + /* Char 178 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + + /* Char 179 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 180 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 181 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 182 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 183 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 184 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 185 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 186 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + + /* Char 187 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 188 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 189 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 190 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 191 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 192 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 193 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 194 */ + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 195 */ + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 196 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 197 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 198 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 199 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 200 */ + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 201 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 202 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + + /* Char 203 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 204 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 205 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 206 */ + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 207 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 208 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 209 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 210 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 211 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 212 */ + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 213 */ + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 214 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 215 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 216 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 217 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 218 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 219 */ + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 220 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 221 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 222 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 223 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 224 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 225 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 226 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 227 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 228 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 229 */ + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 230 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 231 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 232 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 233 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 234 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + + /* Char 235 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 236 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 237 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 238 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 239 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 240 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 241 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 242 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 243 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 244 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 245 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 246 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 247 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 248 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 249 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 250 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 251 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 252 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 253 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 254 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 255 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, }; -gdFont gdFontGiantRep = -{ - 256, - 0, - 9, - 15, - (char*)gdFontGiantData -}; +gdFont gdFontGiantRep = {256, 0, 9, 15, gdFontGiantData}; -gdFontPtr gdFontGiant = &gdFontGiantRep; +BGD_EXPORT_DATA_PROT gdFontPtr gdFontGiant = &gdFontGiantRep; -gdFontPtr gdFontGetGiant(void) -{ - return gdFontGiant; -} +/** + * Function: gdFontGetGiant + * + * Returns the built-in giant font. + */ +BGD_DECLARE(gdFontPtr) gdFontGetGiant(void) { return gdFontGiant; } /* This file has not been truncated. */ diff --git a/ext/gd/libgd/gdfontg.h b/ext/gd/libgd/gdfontg.h index 8a3e95e8bc82..9b3a3e5213ef 100644 --- a/ext/gd/libgd/gdfontg.h +++ b/ext/gd/libgd/gdfontg.h @@ -1,4 +1,3 @@ - #ifndef _GDFONTG_H_ #define _GDFONTG_H_ 1 @@ -7,24 +6,22 @@ extern "C" { #endif /* - This is a header file for gd font, generated using - bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz - from bdf font - -Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2 - at Mon Jan 26 14:45:58 1998. - The original bdf was holding following copyright: - "Libor Skarvada, libor@informatics.muni.cz" + This is a header file for gd font, generated using + bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz + from bdf font + -Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2 + at Mon Jan 26 14:45:58 1998. + The original bdf was holding following copyright: + "Libor Skarvada, libor@informatics.muni.cz" */ - #include "gd.h" -extern gdFontPtr gdFontGiant; -extern gdFontPtr gdFontGetGiant(void); +extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontGiant; +BGD_DECLARE(gdFontPtr) gdFontGetGiant(void); #ifdef __cplusplus } #endif #endif - diff --git a/ext/gd/libgd/gdfontl.c b/ext/gd/libgd/gdfontl.c index 093954ba3c61..758adfb1cdc9 100644 --- a/ext/gd/libgd/gdfontl.c +++ b/ext/gd/libgd/gdfontl.c @@ -11,4636 +11,33309 @@ "Libor Skarvada, libor@informatics.muni.cz" */ +/** + * File: Large Font + * + * A large ISO-8859-2 raster font (8x16 pixels). + * + * The font is supposed to be used with and + * and their variants. + */ #include "gdfontl.h" -static const char gdFontLargeData[] = -{ -/* Char 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 1 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 2 */ - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - -/* Char 3 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 4 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 5 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 6 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 7 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 8 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 0, 0, 0, - 1, 0, 1, 0, 1, 0, 0, 0, - 1, 0, 0, 1, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 10 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 11 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 12 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 13 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 14 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 15 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 16 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 17 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 18 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 19 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 20 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 21 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 22 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 23 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 24 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 25 */ - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 26 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 27 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 28 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 1, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 29 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 30 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 1, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 31 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 32 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 33 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 34 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 35 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 36 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 37 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 1, 0, 0, - 1, 0, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 1, 1, 0, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 38 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 0, - 1, 0, 0, 0, 1, 0, 1, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 39 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 40 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 41 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 42 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 1, 0, 1, 0, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 43 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 44 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 45 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 46 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 47 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 48 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 49 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 50 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 51 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 52 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 53 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 54 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 55 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 56 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 57 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 58 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 59 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 60 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 61 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 62 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 63 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 64 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 65 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 66 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 67 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 68 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 69 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 70 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 71 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 72 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 73 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 74 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 75 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 76 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 77 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 1, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 78 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 79 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 80 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 81 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 1, 0, 1, 0, - 0, 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 82 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 83 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 84 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 85 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 86 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 87 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 88 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 89 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 90 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 91 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 92 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 93 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 94 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 95 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 96 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 97 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 98 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 99 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 100 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 101 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 102 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 103 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - -/* Char 104 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 105 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 106 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - -/* Char 107 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 108 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 109 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 1, 1, 0, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 110 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 111 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 112 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - -/* Char 113 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - -/* Char 114 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 115 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 116 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 117 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 118 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 119 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 120 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 121 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - -/* Char 122 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 123 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 124 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 125 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 126 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 127 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 128 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 129 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 130 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 131 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 132 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 133 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 134 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 135 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 136 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 137 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 138 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 139 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 140 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 141 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 142 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 143 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 144 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 145 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 146 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 147 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 148 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 149 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 150 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 151 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 152 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 153 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 154 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 155 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 156 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 157 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 158 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 159 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 160 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 161 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - -/* Char 162 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 163 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 164 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 165 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 166 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 167 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 168 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 169 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 170 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 171 */ - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 172 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 173 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 174 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 175 */ - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 176 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 177 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - -/* Char 178 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - -/* Char 179 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 180 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 181 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 182 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 183 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 184 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - -/* Char 185 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 186 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 187 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, 1, 0, - 1, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 188 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 189 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 190 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 191 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 192 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 193 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 194 */ - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 195 */ - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 196 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 197 */ - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 198 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 199 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - -/* Char 200 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 201 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 202 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, - -/* Char 203 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 204 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 205 */ - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 206 */ - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 207 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 208 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 209 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 210 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 211 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 212 */ - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 213 */ - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 214 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 215 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 216 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 217 */ - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 218 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 219 */ - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 220 */ - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 221 */ - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 222 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 223 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 224 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 225 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 226 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 227 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 228 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 229 */ - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 230 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 231 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - -/* Char 232 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 233 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 234 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - -/* Char 235 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 236 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 237 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 238 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 239 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 240 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 241 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 242 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 243 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 244 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 245 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 1, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 246 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 247 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 248 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 249 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 250 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 251 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 1, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 252 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* Char 253 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, - -/* Char 254 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, - -/* Char 255 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - +char gdFontLargeData[] = { + /* Char 0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 1 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 2 */ + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + + /* Char 3 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 4 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 5 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 6 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 7 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 9 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 11 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 12 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 13 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 14 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 15 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 16 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 17 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 18 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 19 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 20 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 21 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 22 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 23 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 24 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 25 */ + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 26 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 27 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 28 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 29 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 30 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 31 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 32 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 33 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 34 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 35 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 36 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 37 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 38 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 39 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 40 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 41 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 42 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 43 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 44 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 45 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 46 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 47 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 48 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 49 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 50 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 51 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 52 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 53 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 54 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 55 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 56 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 57 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 58 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 59 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 60 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 61 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 62 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 63 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 64 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 65 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 66 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 67 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 68 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 69 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 70 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 71 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 72 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 73 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 74 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 75 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 76 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 77 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 78 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 79 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 80 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 81 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 82 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 83 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 84 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 85 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 86 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 87 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 88 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 89 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 90 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 91 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 92 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 93 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 94 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 95 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 96 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 97 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 98 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 99 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 100 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 101 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 102 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 103 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 104 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 105 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 106 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 107 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 108 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 109 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 110 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 111 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 112 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 113 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + + /* Char 114 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 115 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 116 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 117 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 118 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 119 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 120 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 121 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 122 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 123 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 124 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 125 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 126 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 127 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 128 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 129 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 130 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 131 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 132 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 133 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 134 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 135 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 136 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 137 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 138 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 139 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 140 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 141 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 142 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 143 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 144 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 145 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 146 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 147 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 148 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 149 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 150 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 151 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 152 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 153 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 154 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 155 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 156 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 157 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 158 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 159 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 160 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 161 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 162 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 163 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 164 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 165 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 166 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 167 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 168 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 169 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 170 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 171 */ + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 172 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 173 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 174 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 175 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 176 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 177 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 178 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + + /* Char 179 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 180 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 181 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 182 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 183 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 184 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 185 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 186 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 187 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 188 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 189 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 190 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 191 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 192 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 193 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 194 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 195 */ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 196 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 197 */ + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 198 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 199 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 200 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 201 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 202 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 203 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 204 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 205 */ + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 206 */ + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 207 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 208 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 209 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 210 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 211 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 212 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 213 */ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 214 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 215 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 216 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 217 */ + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 218 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 219 */ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 220 */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 221 */ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 222 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 223 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 224 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 225 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 226 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 227 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 228 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 229 */ + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 230 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 231 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 232 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 233 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 234 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + + /* Char 235 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 236 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 237 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 238 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 239 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 240 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 241 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 242 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 243 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 244 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 245 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 246 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 247 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 248 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 249 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 250 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 251 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 252 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 253 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 254 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + + /* Char 255 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, }; +gdFont gdFontLargeRep = {256, 0, 8, 16, gdFontLargeData}; -gdFont gdFontLargeRep = -{ - 256, - 0, - 8, - 16, - (char*)gdFontLargeData -}; +BGD_EXPORT_DATA_PROT gdFontPtr gdFontLarge = &gdFontLargeRep; -gdFontPtr gdFontLarge = &gdFontLargeRep; - -gdFontPtr gdFontGetLarge(void) -{ - return gdFontLarge; -} +/** + * Function: gdFontGetLarge + * + * Returns the built-in large font. + */ +BGD_DECLARE(gdFontPtr) +gdFontGetLarge(void) { return gdFontLarge; } /* This file has not been truncated. */ diff --git a/ext/gd/libgd/gdfontl.h b/ext/gd/libgd/gdfontl.h index 92fee14ff334..a1980083e407 100644 --- a/ext/gd/libgd/gdfontl.h +++ b/ext/gd/libgd/gdfontl.h @@ -1,4 +1,3 @@ - #ifndef _GDFONTL_H_ #define _GDFONTL_H_ 1 @@ -7,25 +6,23 @@ extern "C" { #endif /* - This is a header file for gd font, generated using - bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz - from bdf font - -misc-fixed-medium-r-normal--16-140-75-75-c-80-iso8859-2 - at Tue Jan 6 19:39:27 1998. - - The original bdf was holding following copyright: - "Libor Skarvada, libor@informatics.muni.cz" + This is a header file for gd font, generated using + bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz + from bdf font + -misc-fixed-medium-r-normal--16-140-75-75-c-80-iso8859-2 + at Tue Jan 6 19:39:27 1998. + + The original bdf was holding following copyright: + "Libor Skarvada, libor@informatics.muni.cz" */ - #include "gd.h" -extern gdFontPtr gdFontLarge; -extern gdFontPtr gdFontGetLarge(void); +extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontLarge; +BGD_DECLARE(gdFontPtr) gdFontGetLarge(void); #ifdef __cplusplus } #endif #endif - diff --git a/ext/gd/libgd/gdfontmb.c b/ext/gd/libgd/gdfontmb.c index b60110507251..d10ea9e05e5f 100644 --- a/ext/gd/libgd/gdfontmb.c +++ b/ext/gd/libgd/gdfontmb.c @@ -1,5 +1,3 @@ - - /* This is a header file for gd font, generated using bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz @@ -9,3868 +7,23838 @@ No copyright info was found in the original bdf. */ +/** + * File: Medium Bold Font + * + * A medium bold ISO-8859-2 raster font (7x13 pixels). + * + * The font is supposed to be used with and + * and their variants. + */ #include "gdfontmb.h" -static const char gdFontMediumBoldData[] = -{ -/* Char 0 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 1 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 2 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 3 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 4 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 5 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 0, - 0, 0, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 6 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 7 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 8 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 9 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 10 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 11 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 12 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 13 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 14 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 15 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 16 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 17 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 18 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 19 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 20 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 21 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 22 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 23 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 24 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 25 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 26 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 27 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 28 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 29 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 30 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 1, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 31 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 32 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 33 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 34 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 35 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 0, 1, 0, 0, - 0, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 36 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 0, 1, 1, 0, 1, 0, - 1, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 0, - 1, 0, 1, 1, 0, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 37 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 1, 0, - 1, 0, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 0, 1, 0, - 1, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 38 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 0, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 39 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 40 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 41 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 42 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 43 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 44 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 45 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 46 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 47 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 48 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 49 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 50 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 51 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 52 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 53 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 54 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 55 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 56 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 57 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 58 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 59 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 60 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 61 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 62 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 63 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 64 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, - 1, 0, 1, 1, 1, 1, 0, - 1, 0, 1, 0, 1, 1, 0, - 1, 0, 1, 1, 1, 1, 0, - 1, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 65 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 66 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 67 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 68 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 69 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 70 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 71 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 72 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 73 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 74 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 75 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 76 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 77 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 78 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 79 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 80 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 81 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 82 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 83 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 84 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 85 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 86 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 87 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 88 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 89 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 90 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 91 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 92 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 93 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 94 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 95 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 96 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 97 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 98 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 99 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 100 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 101 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 102 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 103 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - -/* Char 104 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 105 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 106 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - -/* Char 107 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 108 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 109 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 110 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 111 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 112 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - -/* Char 113 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - -/* Char 114 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 115 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 116 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 117 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 118 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 119 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 120 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 121 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - -/* Char 122 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 123 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 124 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 125 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 126 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 127 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 128 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 129 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 130 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 131 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 132 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 133 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 134 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 135 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 136 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 137 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 138 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 139 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 140 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 141 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 142 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 143 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 144 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 145 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 146 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 147 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 148 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 149 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 150 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 151 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 152 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 153 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 154 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 155 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 156 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 157 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 158 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 159 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 160 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 161 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - -/* Char 162 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 163 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 164 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 165 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 166 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 167 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 168 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 169 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 170 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - -/* Char 171 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 172 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 173 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 174 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 175 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 176 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 177 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - -/* Char 178 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - -/* Char 179 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 180 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 181 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 182 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 183 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 184 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - -/* Char 185 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 186 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - -/* Char 187 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 188 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 189 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 190 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 191 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 192 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 193 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 194 */ - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 195 */ - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 196 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 197 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 198 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 199 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - -/* Char 200 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 201 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 202 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - -/* Char 203 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 204 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 205 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 206 */ - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 207 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 208 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 209 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 210 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 211 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 212 */ - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 213 */ - 0, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 214 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 215 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 216 */ - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 217 */ - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 218 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 219 */ - 0, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 220 */ - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 221 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 222 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - -/* Char 223 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 224 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 225 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 226 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 227 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 228 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 229 */ - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 230 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 231 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - -/* Char 232 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 233 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 234 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, - -/* Char 235 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 236 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 237 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 238 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 239 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, 0, 1, - 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 240 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 241 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 242 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 243 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 244 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 245 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 246 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 247 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 248 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 249 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 250 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 251 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 252 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - -/* Char 253 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 0, - -/* Char 254 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - -/* Char 255 */ - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - +char gdFontMediumBoldData[] = { + /* Char 0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 1 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 2 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 3 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 4 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 5 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 6 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 7 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 9 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 11 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 12 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 13 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 14 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 15 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 16 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 17 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 18 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 19 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 20 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 21 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 22 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 23 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 24 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 25 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 26 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 27 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 28 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 29 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 30 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 31 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 32 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 33 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 34 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 35 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 36 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 37 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 38 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 39 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 40 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 41 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 42 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 43 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 44 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 45 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 46 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 47 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 48 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 49 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 50 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 51 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 52 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 53 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 54 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 55 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 56 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 57 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 58 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 59 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 60 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 61 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 62 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 63 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 64 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 65 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 66 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 67 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 68 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 69 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 70 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 71 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 72 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 73 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 74 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 75 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 76 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 77 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 78 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 79 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 80 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 81 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 82 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 83 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 84 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 85 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 86 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 87 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 88 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 89 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 90 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 91 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 92 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 93 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 94 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 95 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 96 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 97 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 98 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 99 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 100 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 101 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 102 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 103 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 104 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 105 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 106 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 107 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 108 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 109 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 110 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 111 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 112 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + + /* Char 113 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 114 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 115 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 116 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 117 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 118 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 119 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 120 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 121 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 122 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 123 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 124 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 125 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 126 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 127 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 128 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 129 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 130 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 131 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 132 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 133 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 134 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 135 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 136 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 137 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 138 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 139 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 140 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 141 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 142 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 143 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 144 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 145 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 146 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 147 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 148 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 149 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 150 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 151 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 152 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 153 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 154 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 155 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 156 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 157 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 158 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 159 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 160 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 161 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 162 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 163 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 164 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 165 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 166 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 167 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 168 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 169 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 170 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 171 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 172 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 173 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 174 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 175 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 176 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 177 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 178 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + + /* Char 179 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 180 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 181 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 182 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 183 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 184 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + + /* Char 185 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 186 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 187 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 188 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 189 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 190 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 191 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 192 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 193 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 194 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 195 */ + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 196 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 197 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 198 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 199 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 200 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 201 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 202 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + + /* Char 203 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 204 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 205 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 206 */ + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 207 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 208 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 209 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 210 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 211 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 212 */ + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 213 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 214 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 215 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 216 */ + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 217 */ + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 218 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 219 */ + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 220 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 221 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 222 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + + /* Char 223 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 224 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 225 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 226 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 227 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 228 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 229 */ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 230 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 231 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 232 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 233 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 234 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + + /* Char 235 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 236 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 237 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 238 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 239 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 240 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 241 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 242 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 243 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 244 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 245 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 246 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 247 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 248 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 249 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 250 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 251 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 252 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + /* Char 253 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + + /* Char 254 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + + /* Char 255 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, }; -gdFont gdFontMediumBoldRep = -{ - 256, - 0, - 7, - 13, - (char*)gdFontMediumBoldData -}; +gdFont gdFontMediumBoldRep = {256, 0, 7, 13, gdFontMediumBoldData}; -gdFontPtr gdFontMediumBold = &gdFontMediumBoldRep; +BGD_EXPORT_DATA_PROT gdFontPtr gdFontMediumBold = &gdFontMediumBoldRep; -gdFontPtr gdFontGetMediumBold(void) -{ - return gdFontMediumBold; -} +/** + * Function: gdFontGetMediumBold + * + * Returns the built-in medium bold font. + */ +BGD_DECLARE(gdFontPtr) +gdFontGetMediumBold(void) { return gdFontMediumBold; } /* This file has not been truncated. */ diff --git a/ext/gd/libgd/gdfontmb.h b/ext/gd/libgd/gdfontmb.h index 2e2f0cbe4798..6239286cc212 100644 --- a/ext/gd/libgd/gdfontmb.h +++ b/ext/gd/libgd/gdfontmb.h @@ -1,4 +1,3 @@ - #ifndef _GDFONTMB_H_ #define _GDFONTMB_H_ 1 @@ -7,23 +6,21 @@ extern "C" { #endif /* - This is a header file for gd font, generated using - bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz - from bdf font - -misc-fixed-bold-r-normal-sans-13-94-100-100-c-70-iso8859-2 - at Thu Jan 8 13:54:57 1998. - No copyright info was found in the original bdf. + This is a header file for gd font, generated using + bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz + from bdf font + -misc-fixed-bold-r-normal-sans-13-94-100-100-c-70-iso8859-2 + at Thu Jan 8 13:54:57 1998. + No copyright info was found in the original bdf. */ - #include "gd.h" -extern gdFontPtr gdFontMediumBold; -extern gdFontPtr gdFontGetMediumBold(void); +extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontMediumBold; +BGD_DECLARE(gdFontPtr) gdFontGetMediumBold(void); #ifdef __cplusplus } #endif #endif - diff --git a/ext/gd/libgd/gdfonts.c b/ext/gd/libgd/gdfonts.c index bcc0717cafe4..3f23c0d669a0 100644 --- a/ext/gd/libgd/gdfonts.c +++ b/ext/gd/libgd/gdfonts.c @@ -1,5 +1,3 @@ - - /* This is a header file for gd font, generated using bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz @@ -9,11 +7,19 @@ No copyright info was found in the original bdf. */ +/** + * File: Small Font + * + * A small ISO-8859-2 raster font (6x13 pixels). + * + * The font is supposed to be used with and + * and their variants. + */ #include "gdfonts.h" -static const char gdFontSmallData[] = -{ +// clang-format off +char gdFontSmallData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3853,24 +3859,19 @@ static const char gdFontSmallData[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - }; +// clang-format on -gdFont gdFontSmallRep = -{ - 256, - 0, - 6, - 13, - (char*)gdFontSmallData -}; +gdFont gdFontSmallRep = {256, 0, 6, 13, gdFontSmallData}; -gdFontPtr gdFontSmall = &gdFontSmallRep; +BGD_EXPORT_DATA_PROT gdFontPtr gdFontSmall = &gdFontSmallRep; -gdFontPtr gdFontGetSmall(void) -{ - return gdFontSmall; -} +/** + * Function: gdFontGetSmall + * + * Returns the built-in small font. + */ +BGD_DECLARE(gdFontPtr) +gdFontGetSmall(void) { return gdFontSmall; } /* This file has not been truncated. */ diff --git a/ext/gd/libgd/gdfonts.h b/ext/gd/libgd/gdfonts.h index 55d0e1f0b2ad..1f762f7a8dc2 100644 --- a/ext/gd/libgd/gdfonts.h +++ b/ext/gd/libgd/gdfonts.h @@ -1,4 +1,3 @@ - #ifndef _GDFONTS_H_ #define _GDFONTS_H_ 1 @@ -7,23 +6,21 @@ extern "C" { #endif /* - This is a header file for gd font, generated using - bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz - from bdf font - -misc-fixed-medium-r-semicondensed-sans-12-116-75-75-c-60-iso8859-2 - at Thu Jan 8 14:13:20 1998. - No copyright info was found in the original bdf. + This is a header file for gd font, generated using + bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz + from bdf font + -misc-fixed-medium-r-semicondensed-sans-12-116-75-75-c-60-iso8859-2 + at Thu Jan 8 14:13:20 1998. + No copyright info was found in the original bdf. */ - #include "gd.h" -extern gdFontPtr gdFontSmall; -extern gdFontPtr gdFontGetSmall(void); +extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontSmall; +BGD_DECLARE(gdFontPtr) gdFontGetSmall(void); #ifdef __cplusplus } #endif #endif - diff --git a/ext/gd/libgd/gdfontt.c b/ext/gd/libgd/gdfontt.c index d4e0cf9573d2..4580f3488c2d 100644 --- a/ext/gd/libgd/gdfontt.c +++ b/ext/gd/libgd/gdfontt.c @@ -1,5 +1,3 @@ - - /* This is a header file for gd font, generated using bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz @@ -10,11 +8,18 @@ "Libor Skarvada, libor@informatics.muni.cz" */ - +/** + * File: Tiny Font + * + * A very small ISO-8859-2 raster font (5x8 pixels). + * + * The font is supposed to be used with and + * and their variants. + */ #include "gdfontt.h" -static const char gdFontTinyData[] = -{ +// clang-format off +char gdFontTinyData[] = { /* Char 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2574,24 +2579,19 @@ static const char gdFontTinyData[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - }; +// clang-format on -gdFont gdFontTinyRep = -{ - 256, - 0, - 5, - 8, - (char*)gdFontTinyData -}; +gdFont gdFontTinyRep = {256, 0, 5, 8, gdFontTinyData}; -gdFontPtr gdFontTiny = &gdFontTinyRep; +BGD_EXPORT_DATA_PROT gdFontPtr gdFontTiny = &gdFontTinyRep; -gdFontPtr gdFontGetTiny(void) -{ - return gdFontTiny; -} +/** + * Function: gdFontGetTiny + * + * Returns the built-in tiny font. + */ +BGD_DECLARE(gdFontPtr) +gdFontGetTiny(void) { return gdFontTiny; } /* This file has not been truncated. */ diff --git a/ext/gd/libgd/gdfontt.h b/ext/gd/libgd/gdfontt.h index 102fec991b4b..9b9ca2085cf2 100644 --- a/ext/gd/libgd/gdfontt.h +++ b/ext/gd/libgd/gdfontt.h @@ -1,4 +1,3 @@ - #ifndef _GDFONTT_H_ #define _GDFONTT_H_ 1 @@ -7,24 +6,22 @@ extern "C" { #endif /* - This is a header file for gd font, generated using - bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz - from bdf font - -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2 - at Thu Jan 8 13:49:54 1998. - The original bdf was holding following copyright: - "Libor Skarvada, libor@informatics.muni.cz" + This is a header file for gd font, generated using + bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz + from bdf font + -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2 + at Thu Jan 8 13:49:54 1998. + The original bdf was holding following copyright: + "Libor Skarvada, libor@informatics.muni.cz" */ - #include "gd.h" -extern gdFontPtr gdFontTiny; -extern gdFontPtr gdFontGetTiny(void); +extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontTiny; +BGD_DECLARE(gdFontPtr) gdFontGetTiny(void); #ifdef __cplusplus } #endif #endif - diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 34a4064f5fcb..59213c3014b8 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -1,69 +1,113 @@ - /********************************************/ /* gd interface to freetype library */ /* */ /* John Ellson ellson@graphviz.org */ /********************************************/ +/** + * File: FreeType font rendering + */ + +#include #include #include #include -#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "gd.h" +#include "gd_intern.h" #include "gdhelpers.h" -#ifndef _WIN32 +/* The bundled PHP font cache can outlive the request which populated it. */ +#define GD_FT_CACHE_MALLOC(size) gdPMalloc(size) +#define GD_FT_CACHE_FREE(ptr) gdPFree(ptr) +#define GD_FT_ACCESS(path, mode) VCWD_ACCESS(path, mode) +#define GD_FT_IS_PATH(path) \ + (IS_ABSOLUTE_PATH(path, strlen(path)) || strchr(path, '/') || strchr(path, '\\')) + +/* 2.0.10: WIN32, not MSWIN32 */ +#if !defined(_WIN32) && !defined(_WIN32_WCE) #include -#else +#elif defined(_WIN32_WCE) +#include /* getenv() */ +#include /* access() */ +#define getenv wceex_getenv +#define access wceex_access +#else /* _WIN32_WCE */ #include #ifndef R_OK -# define R_OK 04 /* Needed in Windows */ -#endif -#endif - -#ifdef _WIN32 -#define access _access -#ifndef R_OK -#define R_OK 2 +#define R_OK 04 /* Needed in Windows */ #endif #endif /* number of antialised colors for indexed bitmaps */ -/* overwrite Windows GDI define in case of windows build */ -#ifdef NUMCOLORS -#undef NUMCOLORS -#endif -#define NUMCOLORS 8 - -char * -gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) -{ - /* 2.0.6: valid return */ - return gdImageStringFT (im, brect, fg, fontlist, ptsize, angle, x, y, string); -} +#define GD_NUMCOLORS 8 #ifndef HAVE_LIBFREETYPE -char * -gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string, - gdFTStringExtraPtr strex) +BGD_DECLARE(char *) +gdImageStringFTEx(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string, gdFTStringExtraPtr strex) { - return "libgd was not built with FreeType font support\n"; + (void)im; + (void)brect; + (void)fg; + (void)fontlist; + (void)ptsize; + (void)angle; + (void)x; + (void)y; + (void)string; + (void)strex; + + return "libgd was not built with FreeType font support\n"; } -char * -gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) +BGD_DECLARE(char *) +gdImageStringFT(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string) { - return "libgd was not built with FreeType font support\n"; + (void)im; + (void)brect; + (void)fg; + (void)fontlist; + (void)ptsize; + (void)angle; + (void)x; + (void)y; + (void)string; + + return "libgd was not built with FreeType font support\n"; } #else - #include "gdcache.h" +/* 2.0.16 Christophe Thomas: starting with FreeType 2.1.6, this is + mandatory, and it has been supported for a long while. */ +#ifdef HAVE_FT2BUILD_H #include #include FT_FREETYPE_H #include FT_GLYPH_H +#include FT_SIZES_H +#else +#include +#include +#include +#endif + +#ifdef HAVE_LIBFONTCONFIG +static int fontConfigFlag = 0; + +/* translate a fontconfig fontpattern into a fontpath. + return NULL if OK, else return error string */ +static char *font_pattern(char **fontpath, char *fontpattern); +#endif + +#ifdef HAVE_LIBFREETYPE +#include "entities.h" +static char *font_path(char **fontpath, char *name_list); +#endif /* number of fonts cached before least recently used is replaced */ #define FONTCACHESIZE 6 @@ -80,7 +124,8 @@ gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, /* * The character (space) used to separate alternate fonts in the - * fontlist parameter to gdImageStringFT. 2.0.18: space was a oor choice for this. + * fontlist parameter to gdImageStringFT. 2.0.18: space was a + * poor choice for this. */ #define LISTSEPARATOR ";" @@ -92,69 +137,73 @@ gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, */ #ifndef DEFAULT_FONTPATH -# if defined(_WIN32) -# define DEFAULT_FONTPATH "C:\\WINDOWS\\FONTS;C:\\WINNT\\FONTS" -# elif defined(__APPLE__) || (defined(__MWERKS__) && defined(macintosh)) -# define DEFAULT_FONTPATH "/usr/share/fonts/truetype:/System/Library/Fonts:/Library/Fonts" -# else - /* default fontpath for unix systems - whatever happened to standards ! */ -# define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:/usr/lib/X11/fonts/Type1:/usr/openwin/lib/X11/fonts/Type1" -# endif +#if defined(_WIN32) +#define DEFAULT_FONTPATH "C:\\WINDOWS\\FONTS;C:\\WINNT\\FONTS" +#elif defined(__APPLE__) || (defined(__MWERKS__) && defined(macintosh)) +#define DEFAULT_FONTPATH "/usr/share/fonts/truetype:/System/Library/Fonts:/Library/Fonts" +#else +/* default fontpath for unix systems - whatever happened to standards ! */ +#define DEFAULT_FONTPATH \ + "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/" \ + "usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/" \ + "truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/" \ + "Type1:/usr/lib/X11/fonts/Type1:/usr/openwin/lib/X11/fonts/Type1" +#endif #endif #ifndef PATHSEPARATOR -# if defined(_WIN32) -# define PATHSEPARATOR ";" -# else -# define PATHSEPARATOR ":" -# endif +#if defined(_WIN32) +#define PATHSEPARATOR ";" +#else +#define PATHSEPARATOR ":" +#endif #endif - #ifndef TRUE #define FALSE 0 #define TRUE !FALSE #endif -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -typedef struct +/** + * Function: gdImageStringTTF + * + * Alias of . + */ +BGD_DECLARE(char *) +gdImageStringTTF(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string) { - char *fontlist; /* key */ - FT_Library *library; - FT_Face face; - FT_Bool have_char_map_unicode, have_char_map_big5, have_char_map_sjis, have_char_map_apple_roman; - gdCache_head_t *glyphCache; + /* 2.0.6: valid return */ + return gdImageStringFT(im, brect, fg, fontlist, ptsize, angle, x, y, string); +} + +typedef struct { + char *fontlist; /* key */ + int flags; /* key */ + char *fontpath; + FT_Library *library; + FT_Face face; } font_t; -typedef struct -{ - char *fontlist; /* key */ - int preferred_map; - FT_Library *library; +typedef struct { + const char *fontlist; /* key */ + int flags; /* key */ + FT_Library *library; } fontkey_t; -typedef struct -{ - int pixel; /* key */ - int bgcolor; /* key */ - int fgcolor; /* key *//* -ve means no antialias */ - gdImagePtr im; /* key */ - int tweencolor; +typedef struct { + int pixel; /* key */ + int bgcolor; /* key */ + int fgcolor; /* key */ /* -ve means no antialias */ + gdImagePtr im; /* key */ + int tweencolor; } tweencolor_t; -typedef struct -{ - int pixel; /* key */ - int bgcolor; /* key */ - int fgcolor; /* key *//* -ve means no antialias */ - gdImagePtr im; /* key */ +typedef struct { + int pixel; /* key */ + int bgcolor; /* key */ + int fgcolor; /* key */ /* -ve means no antialias */ + gdImagePtr im; /* key */ } tweencolorkey_t; /******************************************************************** @@ -203,7 +252,14 @@ typedef struct #include "jisx0208.h" #endif -extern int any2eucjp (char *, char *, unsigned int); +static int comp_entities(const void *e1, const void *e2) +{ + struct entities_s *en1 = (struct entities_s *)e1; + struct entities_s *en2 = (struct entities_s *)e2; + return strcmp(en1->name, en2->name); +} + +extern int any2eucjp(char *, const char *, unsigned int); /* Persistent font cache until explicitly cleared */ /* Fonts can be used across multiple images */ @@ -215,1026 +271,1624 @@ static FT_Library library; #define Tcl_UniChar int #define TCL_UTF_MAX 3 -static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr) +static int gdTcl_UtfToUniChar(const char *str, Tcl_UniChar *chPtr) /* str is the UTF8 next character pointer */ /* chPtr is the int for the result */ { - int byte; - - /* HTML4.0 entities in decimal form, e.g. Å */ - byte = *((unsigned char *) str); - if (byte == '&') { - int i, n = 0; - - byte = *((unsigned char *) (str + 1)); - if (byte == '#') { - byte = *((unsigned char *) (str + 2)); - if (byte == 'x' || byte == 'X') { - for (i = 3; i < 8; i++) { - byte = *((unsigned char *) (str + i)); - if (byte >= 'A' && byte <= 'F') - byte = byte - 'A' + 10; - else if (byte >= 'a' && byte <= 'f') - byte = byte - 'a' + 10; - else if (byte >= '0' && byte <= '9') - byte = byte - '0'; - else - break; - n = (n * 16) + byte; - } - } else { - for (i = 2; i < 8; i++) { - byte = *((unsigned char *) (str + i)); - if (byte >= '0' && byte <= '9') { - n = (n * 10) + (byte - '0'); - } else { - break; - } - } - } - if (byte == ';') { - *chPtr = (Tcl_UniChar) n; - return ++i; - } - } - } - - /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */ - - byte = *((unsigned char *) str); + int byte; + char entity_name_buf[ENTITY_NAME_LENGTH_MAX + 1]; + char *p; + struct entities_s key, *res; + + /* HTML4.0 entities in decimal form, e.g. Å */ + /* or in hexadecimal form, e.g. 水 */ + byte = *((unsigned char *)str); + if (byte == '&') { + int i, n = 0; + + byte = *((unsigned char *)(str + 1)); + if (byte == '#') { + byte = *((unsigned char *)(str + 2)); + if (byte == 'x' || byte == 'X') { + for (i = 3; i < 8; i++) { + byte = *((unsigned char *)(str + i)); + if (byte >= 'A' && byte <= 'F') + byte = byte - 'A' + 10; + else if (byte >= 'a' && byte <= 'f') + byte = byte - 'a' + 10; + else if (byte >= '0' && byte <= '9') + byte = byte - '0'; + else + break; + n = (n * 16) + byte; + } + } else { + for (i = 2; i < 8; i++) { + byte = *((unsigned char *)(str + i)); + if (byte >= '0' && byte <= '9') { + n = (n * 10) + (byte - '0'); + } else { + break; + } + } + } + if (byte == ';') { + *chPtr = (Tcl_UniChar)n; + return ++i; + } + } else { + key.name = p = entity_name_buf; + for (i = 1; i <= 1 + ENTITY_NAME_LENGTH_MAX; i++) { + byte = *((unsigned char *)(str + i)); + if (byte == '\0') + break; + if (byte == ';') { + *p++ = '\0'; + res = bsearch(&key, entities, NR_OF_ENTITIES, sizeof(entities[0]), + *comp_entities); + if (res) { + *chPtr = (Tcl_UniChar)res->value; + return ++i; + } + break; + } + *p++ = byte; + } + } + } + + /* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones. */ + byte = *((unsigned char *)str); #ifdef JISX0208 - if (0xA1 <= byte && byte <= 0xFE) { - int ku, ten; - - ku = (byte & 0x7F) - 0x20; - ten = (str[1] & 0x7F) - 0x20; - if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) { - *chPtr = (Tcl_UniChar) byte; - return 1; - } - - *chPtr = (Tcl_UniChar) UnicodeTbl[ku - 1][ten - 1]; - return 2; - } else + if (0xA1 <= byte && byte <= 0xFE) { + int ku, ten; + + ku = (byte & 0x7F) - 0x20; + ten = (str[1] & 0x7F) - 0x20; + if ((ku < 1 || ku > 92) || (ten < 1 || ten > 94)) { + *chPtr = (Tcl_UniChar)byte; + return 1; + } + + *chPtr = (Tcl_UniChar)UnicodeTbl[ku - 1][ten - 1]; + return 2; + } else #endif /* JISX0208 */ - if (byte < 0xC0) { - /* Handles properly formed UTF-8 characters between - * 0x01 and 0x7F. Also treats \0 and naked trail - * bytes 0x80 to 0xBF as valid characters representing - * themselves. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } else if (byte < 0xE0) { - if ((str[1] & 0xC0) == 0x80) { - /* Two-byte-character lead-byte followed by a trail-byte. */ - - *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F)); - return 2; - } - /* - * A two-byte-character lead-byte not followed by trail-byte - * represents itself. - */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } else if (byte < 0xF0) { - if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) { - /* Three-byte-character lead byte followed by two trail bytes. */ - - *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); - return 3; - } - /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. */ - - *chPtr = (Tcl_UniChar) byte; - return 1; - } + if (byte < 0xC0) { + /* Handles properly formed UTF-8 characters between + * 0x01 and 0x7F. Also treats \0 and naked trail + * bytes 0x80 to 0xBF as valid characters representing + * themselves. + */ + + *chPtr = (Tcl_UniChar)byte; + return 1; + } else if (byte < 0xE0) { + if ((str[1] & 0xC0) == 0x80) { + /* Two-byte-character lead-byte followed by a trail-byte. */ + *chPtr = (Tcl_UniChar)(((byte & 0x1F) << 6) | (str[1] & 0x3F)); + return 2; + } + /* + * A two-byte-character lead-byte not followed by trail-byte + * represents itself. + */ + + *chPtr = (Tcl_UniChar)byte; + return 1; + } else if (byte < 0xF0) { + if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) { + /* Three-byte-character lead byte followed by two trail bytes. */ + *chPtr = + (Tcl_UniChar)(((byte & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F)); + return 3; + } + /* A three-byte-character lead-byte not followed by two trail-bytes represents itself. + */ + *chPtr = (Tcl_UniChar)byte; + return 1; + } #if TCL_UTF_MAX > 3 - else { - int ch, total, trail; - - total = totalBytes[byte]; - trail = total - 1; - - if (trail > 0) { - ch = byte & (0x3F >> trail); - do { - str++; - if ((*str & 0xC0) != 0x80) { - *chPtr = byte; - return 1; - } - ch <<= 6; - ch |= (*str & 0x3F); - trail--; - } while (trail > 0); - *chPtr = ch; - return total; - } - } + else { + int ch, total, trail; + + total = totalBytes[byte]; + trail = total - 1; + if (trail > 0) { + ch = byte & (0x3F >> trail); + do { + str++; + if ((*str & 0xC0) != 0x80) { + *chPtr = byte; + return 1; + } + ch <<= 6; + ch |= (*str & 0x3F); + trail--; + } while (trail > 0); + *chPtr = ch; + return total; + } + } +#endif + + *chPtr = (Tcl_UniChar)byte; + return 1; +} + +#ifdef HAVE_LIBRAQM +#include +#else +#define RAQM_VERSION_ATLEAST(a, b, c) 0 +#endif + +typedef struct { + unsigned int index; + FT_Pos x_advance; + FT_Pos y_advance; + FT_Pos x_offset; + FT_Pos y_offset; + uint32_t cluster; +} glyphInfo; + +static ssize_t textLayout(uint32_t *text, size_t len, FT_Face face, gdFTStringExtraPtr strex, + glyphInfo **glyph_info) +{ + size_t count; + glyphInfo *info; + + if (!len) { + return 0; + } + +#ifdef HAVE_LIBRAQM + size_t i; + raqm_glyph_t *glyphs; + raqm_t *rq = raqm_create(); + + if (!rq || !raqm_set_text(rq, text, len) || !raqm_set_freetype_face(rq, face) || + !raqm_set_par_direction(rq, RAQM_DIRECTION_DEFAULT) || !raqm_layout(rq)) { + raqm_destroy(rq); + return -1; + } + + glyphs = raqm_get_glyphs(rq, &count); + if (!glyphs) { + raqm_destroy(rq); + return -1; + } + + info = (glyphInfo *)gdMalloc(sizeof(glyphInfo) * count); + if (!info) { + raqm_destroy(rq); + return -1; + } + + for (i = 0; i < count; i++) { + info[i].index = glyphs[i].index; + info[i].x_offset = glyphs[i].x_offset; + info[i].y_offset = glyphs[i].y_offset; + info[i].x_advance = glyphs[i].x_advance; + info[i].y_advance = glyphs[i].y_advance; + info[i].cluster = glyphs[i].cluster; + } + + raqm_destroy(rq); +#else + FT_UInt glyph_index = 0, previous = 0; + FT_Vector delta; + FT_Error err; + info = (glyphInfo *)gdMalloc(sizeof(glyphInfo) * len); + if (!info) { + return -1; + } + for (count = 0; count < len; count++) { + /* Convert character code to glyph index */ + glyph_index = FT_Get_Char_Index(face, text[count]); + + /* retrieve kerning distance */ + if (!(strex && (strex->flags & gdFTEX_DISABLE_KERNING)) && !FT_IS_FIXED_WIDTH(face) && + FT_HAS_KERNING(face) && previous && glyph_index) + FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta); + else + delta.x = delta.y = 0; + + err = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if (err) { + gdFree(info); + return -1; + } + info[count].index = glyph_index; + info[count].x_offset = 0; + info[count].y_offset = 0; + if (delta.x != 0) + info[count - 1].x_advance += delta.x; + info[count].x_advance = face->glyph->metrics.horiAdvance; + info[count].y_advance = 0; + info[count].cluster = count; + + /* carriage returns or newlines */ + if (text[count] == '\r' || text[count] == '\n') + previous = 0; /* clear kerning flag */ + else + previous = glyph_index; + } #endif - *chPtr = (Tcl_UniChar) byte; - return 1; + *glyph_info = info; + if (count <= (size_t)SSIZE_MAX) { + return (ssize_t)count; + } + return -1; } /********************************************************************/ /* font cache functions */ -static int fontTest (void *element, void *key) +static int fontTest(void *element, void *key) { - font_t *a = (font_t *) element; - fontkey_t *b = (fontkey_t *) key; - - if (strcmp (a->fontlist, b->fontlist) == 0) { - switch (b->preferred_map) { - case gdFTEX_Unicode: - if (a->have_char_map_unicode) { - return 1; - } - break; - case gdFTEX_Shift_JIS: - if (a->have_char_map_sjis) { - return 1; - } - break; - case gdFTEX_Big5: - if (a->have_char_map_sjis) { - return 1; - } - break; - } - } - return 0; + font_t *a = (font_t *)element; + fontkey_t *b = (fontkey_t *)key; + + return a->flags == b->flags && strcmp(a->fontlist, b->fontlist) == 0; } -static void *fontFetch (char **error, void *key) +#ifdef HAVE_LIBFONTCONFIG +static int useFontConfig(int flag) { - font_t *a; - fontkey_t *b = (fontkey_t *) key; - int n; - int font_found = 0; - unsigned short platform, encoding; - char *fontsearchpath, *fontlist; - char fullname[MAXPATHLEN], cur_dir[MAXPATHLEN]; - char *name, *path=NULL, *dir; - char *strtok_ptr; - FT_Error err; - FT_CharMap found = 0; - FT_CharMap charmap; - - a = (font_t *) gdPMalloc(sizeof(font_t)); - a->fontlist = gdPEstrdup(b->fontlist); - a->library = b->library; - - /* - * Search the pathlist for any of a list of font names. - */ - fontsearchpath = getenv ("GDFONTPATH"); - if (!fontsearchpath) { - fontsearchpath = DEFAULT_FONTPATH; - } - fontlist = gdEstrdup(a->fontlist); - - /* - * Must use gd_strtok_r becasuse strtok() isn't thread safe - */ - for (name = gd_strtok_r (fontlist, LISTSEPARATOR, &strtok_ptr); name; name = gd_strtok_r (0, LISTSEPARATOR, &strtok_ptr)) { - char *strtok_ptr_path; - /* make a fresh copy each time - strtok corrupts it. */ - path = gdEstrdup (fontsearchpath); - - /* if name is an absolute filename then test directly */ - /* Actual length doesn't matter, just the minimum does up to length 2. */ - unsigned int min_length = 0; - if (name[0] != '\0') { - if (name[1] != '\0') { - min_length = 2; - } else { - min_length = 1; - } - } - ZEND_IGNORE_VALUE(min_length); /* On Posix systems this may be unused */ - if (IS_ABSOLUTE_PATH(name, min_length)) { - snprintf(fullname, sizeof(fullname) - 1, "%s", name); - if (access(fullname, R_OK) == 0) { - font_found++; - break; - } - } - for (dir = gd_strtok_r (path, PATHSEPARATOR, &strtok_ptr_path); dir; - dir = gd_strtok_r (0, PATHSEPARATOR, &strtok_ptr_path)) { - if (!strcmp(dir, ".")) { - #ifdef HAVE_GETCWD - dir = VCWD_GETCWD(cur_dir, MAXPATHLEN); -#elif defined(HAVE_GETWD) - dir = VCWD_GETWD(cur_dir); + if (fontConfigFlag) { + return (!(flag & gdFTEX_FONTPATHNAME)); + } + return flag & gdFTEX_FONTCONFIG; +} #endif - if (!dir) { - continue; - } - } -#define GD_CHECK_FONT_PATH(ext) \ - snprintf(fullname, sizeof(fullname) - 1, "%s/%s%s", dir, name, ext); \ - if (access(fullname, R_OK) == 0) { \ - font_found++; \ - break; \ - } \ - - GD_CHECK_FONT_PATH(""); - GD_CHECK_FONT_PATH(".ttf"); - GD_CHECK_FONT_PATH(".pfa"); - GD_CHECK_FONT_PATH(".pfb"); - GD_CHECK_FONT_PATH(".dfont"); - } - gdFree(path); - path = NULL; - if (font_found) { - break; - } - } - - if (path) { - gdFree(path); - } - - gdFree(fontlist); - - if (!font_found) { - gdPFree(a->fontlist); - gdPFree(a); - *error = "Could not find/open font"; - return NULL; - } - - err = FT_New_Face (*b->library, fullname, 0, &a->face); - if (err) { - gdPFree(a->fontlist); - gdPFree(a); - *error = "Could not read font"; - return NULL; - } - - /* FIXME - This mapping stuff is incomplete - where is the spec? */ - /* EAM - It's worse than that. It's pointless to match character encodings here. - * As currently written, the stored a->face->charmap only matches one of - * the actual charmaps and we cannot know at this stage if it is the right - * one. We should just skip all this stuff, and check in gdImageStringFTEx - * if some particular charmap is preferred and if so whether it is held in - * one of the a->face->charmaps[0..num_charmaps]. - * And why is it so bad not to find any recognized charmap? The user may - * still know what mapping to use, even if we do not. In that case we can - * just use the map in a->face->charmaps[num_charmaps] and be done with it. - */ - - for (n = 0; n < a->face->num_charmaps; n++) { - charmap = a->face->charmaps[n]; - platform = charmap->platform_id; - encoding = charmap->encoding_id; - - /* Whatever is the last value is what should be set */ - a->have_char_map_unicode = 0; - a->have_char_map_big5 = 0; - a->have_char_map_sjis = 0; - a->have_char_map_apple_roman = 0; - -/* EAM DEBUG - Newer versions of libfree2 make it easier by defining encodings */ -#if (defined(FREETYPE_MAJOR) && ((FREETYPE_MAJOR == 2 && ((FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3) || FREETYPE_MINOR > 1) || FREETYPE_MAJOR > 2))) - if (charmap->encoding == FT_ENCODING_MS_SYMBOL - || charmap->encoding == FT_ENCODING_ADOBE_CUSTOM - || charmap->encoding == FT_ENCODING_ADOBE_STANDARD) { - a->have_char_map_unicode = 1; - found = charmap; - a->face->charmap = charmap; - return (void *)a; - } -#endif /* Freetype 2.1.3 or better */ -/* EAM DEBUG */ - - if ((platform == 3 && encoding == 1) /* Windows Unicode */ - || (platform == 3 && encoding == 0) /* Windows Symbol */ - || (platform == 2 && encoding == 1) /* ISO Unicode */ - || (platform == 0)) - { /* Apple Unicode */ - a->have_char_map_unicode = 1; - found = charmap; - if (b->preferred_map == gdFTEX_Unicode) { - break; - } - } else if (platform == 3 && encoding == 4) { /* Windows Big5 */ - a->have_char_map_big5 = 1; - found = charmap; - if (b->preferred_map == gdFTEX_Big5) { - break; - } - } else if (platform == 3 && encoding == 2) { /* Windows Sjis */ - a->have_char_map_sjis = 1; - found = charmap; - if (b->preferred_map == gdFTEX_Shift_JIS) { - break; - } - } else if ((platform == 1 && encoding == 0) /* Apple Roman */ - || (platform == 2 && encoding == 0)) - { /* ISO ASCII */ - a->have_char_map_apple_roman = 1; - found = charmap; - if (b->preferred_map == gdFTEX_MacRoman) { - break; - } - } - } - if (!found) { - gdPFree(a->fontlist); - gdPFree(a); - *error = "Unable to find a CharMap that I can handle"; - return NULL; - } - - /* 2.0.5: we should actually return this */ - a->face->charmap = found; - return (void *) a; +static void *fontFetch(char **error, void *key) +{ + font_t *a; + fontkey_t *b = (fontkey_t *)key; + char *fontpath = NULL; + char *suffix; + FT_Error err; + const unsigned int b_font_list_len = strlen(b->fontlist); + + *error = NULL; + + a = (font_t *)GD_FT_CACHE_MALLOC(sizeof(font_t)); + if (!a) { + *error = "could not alloc font cache entry"; + return NULL; + } + + a->fontlist = (char *)GD_FT_CACHE_MALLOC(b_font_list_len + 1); + if (a->fontlist == NULL) { + GD_FT_CACHE_FREE(a); + *error = "could not alloc full list of fonts"; + return NULL; + } + memcpy(a->fontlist, b->fontlist, b_font_list_len); + a->fontlist[b_font_list_len] = 0; + + a->flags = b->flags; + a->library = b->library; + a->fontpath = NULL; + +#ifdef HAVE_LIBFONTCONFIG + if (!useFontConfig(b->flags)) + *error = font_path(&fontpath, a->fontlist); + else + *error = font_pattern(&fontpath, a->fontlist); +#else + *error = font_path(&fontpath, a->fontlist); +#endif /* HAVE_LIBFONTCONFIG */ + if (*error || !fontpath || !fontpath[0]) { + GD_FT_CACHE_FREE(a->fontlist); + gdFree(fontpath); + GD_FT_CACHE_FREE(a); + + if (!*error) + *error = "font_path() returned an empty font pathname"; + + return NULL; + } + a->fontpath = (char *)GD_FT_CACHE_MALLOC(strlen(fontpath) + 1); + if (!a->fontpath) { + GD_FT_CACHE_FREE(a->fontlist); + gdFree(fontpath); + GD_FT_CACHE_FREE(a); + *error = "could not alloc font path"; + return NULL; + } + memcpy(a->fontpath, fontpath, strlen(fontpath) + 1); + gdFree(fontpath); + + err = FT_New_Face(*b->library, a->fontpath, 0, &a->face); + + /* Read kerning metrics for Postscript fonts. */ + if (!err && + ((suffix = strstr(a->fontpath, ".pfa")) || (suffix = strstr(a->fontpath, ".pfb"))) && + ((strcpy(suffix, ".afm") && (GD_FT_ACCESS(a->fontpath, R_OK) == 0)) || + (strcpy(suffix, ".pfm") && (GD_FT_ACCESS(a->fontpath, R_OK) == 0)))) { + err = FT_Attach_File(a->face, a->fontpath); + } + + if (err) { + GD_FT_CACHE_FREE(a->fontlist); + GD_FT_CACHE_FREE(a->fontpath); + GD_FT_CACHE_FREE(a); + *error = "Could not read font"; + return NULL; + } + + return (void *)a; } -static void fontRelease (void *element) +static void fontRelease(void *element) { - font_t *a = (font_t *) element; + font_t *a = (font_t *)element; - FT_Done_Face (a->face); - gdPFree(a->fontlist); - gdPFree((char *) element); + FT_Done_Face(a->face); + GD_FT_CACHE_FREE(a->fontlist); + GD_FT_CACHE_FREE(a->fontpath); + GD_FT_CACHE_FREE((char *)element); } /********************************************************************/ /* tweencolor cache functions */ -static int tweenColorTest (void *element, void *key) +static int tweenColorTest(void *element, void *key) { - tweencolor_t *a = (tweencolor_t *) element; - tweencolorkey_t *b = (tweencolorkey_t *) key; + tweencolor_t *a = (tweencolor_t *)element; + tweencolorkey_t *b = (tweencolorkey_t *)key; - return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == b->fgcolor && a->im == b->im); + return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == b->fgcolor && + a->im == b->im); } /* * Computes a color in im's color table that is part way between * the background and foreground colors proportional to the gray - * pixel value in the range 0-NUMCOLORS. The fg and bg colors must already + * pixel value in the range 0-GD_NUMCOLORS. The fg and bg colors must already * be in the color table for palette images. For truecolor images the * returned value simply has an alpha component and gdImageAlphaBlend * does the work so that text can be alpha blended across a complex * background (TBB; and for real in 2.0.2). */ -static void * tweenColorFetch (char **error, void *key) +static void *tweenColorFetch(char **error, void *key) { - tweencolor_t *a; - tweencolorkey_t *b = (tweencolorkey_t *) key; - int pixel, npixel, bg, fg; - gdImagePtr im; - - a = (tweencolor_t *) gdMalloc (sizeof (tweencolor_t)); - pixel = a->pixel = b->pixel; - bg = a->bgcolor = b->bgcolor; - fg = a->fgcolor = b->fgcolor; - im = a->im = b->im; - - /* if fg is specified by a negative color idx, then don't antialias */ - if (fg < 0) { - if ((pixel + pixel) >= NUMCOLORS) { - a->tweencolor = -fg; - } else { - a->tweencolor = bg; - } - } else { - npixel = NUMCOLORS - pixel; - if (im->trueColor) { - /* 2.0.1: use gdImageSetPixel to do the alpha blending work, - * or to just store the alpha level. All we have to do here - * is incorporate our knowledge of the percentage of this - * pixel that is really "lit" by pushing the alpha value - * up toward transparency in edge regions. - */ - a->tweencolor = gdTrueColorAlpha( - gdTrueColorGetRed(fg), - gdTrueColorGetGreen(fg), - gdTrueColorGetBlue(fg), - gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); - } else { - a->tweencolor = gdImageColorResolve(im, - (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS, - (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, - (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS); - } - } - return (void *) a; + tweencolor_t *a; + tweencolorkey_t *b = (tweencolorkey_t *)key; + int pixel, npixel, bg, fg; + gdImagePtr im; + + (void)error; + + a = (tweencolor_t *)gdMalloc(sizeof(tweencolor_t)); + if (!a) { + return NULL; + } + + pixel = a->pixel = b->pixel; + bg = a->bgcolor = b->bgcolor; + fg = a->fgcolor = b->fgcolor; + im = a->im = b->im; + + /* if fg is specified by a negative color idx, then don't antialias */ + if (fg < 0) { + if ((pixel + pixel) >= GD_NUMCOLORS) + a->tweencolor = -fg; + else + a->tweencolor = bg; + } else { + npixel = GD_NUMCOLORS - pixel; + if (im->trueColor) { + /* 2.0.1: use gdImageSetPixel to do the alpha blending work, + or to just store the alpha level. All we have to do here + is incorporate our knowledge of the percentage of this + pixel that is really "lit" by pushing the alpha value + up toward transparency in edge regions. */ + a->tweencolor = gdTrueColorAlpha( + gdTrueColorGetRed(fg), gdTrueColorGetGreen(fg), gdTrueColorGetBlue(fg), + gdAlphaMax - (gdTrueColorGetAlpha(fg) * pixel / GD_NUMCOLORS)); + } else { + a->tweencolor = + gdImageColorResolve(im, (pixel * im->red[fg] + npixel * im->red[bg]) / GD_NUMCOLORS, + (pixel * im->green[fg] + npixel * im->green[bg]) / GD_NUMCOLORS, + (pixel * im->blue[fg] + npixel * im->blue[bg]) / GD_NUMCOLORS); + } + } + return (void *)a; } -static void tweenColorRelease (void *element) -{ - gdFree((char *) element); -} +static void tweenColorRelease(void *element) { gdFree((char *)element); } /* draw_bitmap - transfers glyph bitmap to GD image */ -static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) -{ - unsigned char *pixel = NULL; - int *tpixel = NULL; - int opixel; - int x, y, row, col, pc, pcr; - - tweencolor_t *tc_elem; - tweencolorkey_t tc_key; - - /* copy to image, mapping colors */ - tc_key.fgcolor = fg; - tc_key.im = im; - /* Truecolor version; does not require the cache */ - if (im->trueColor) { - for (row = 0; row < bitmap.rows; row++) { - pc = row * bitmap.pitch; - pcr = pc; - y = pen_y + row; - /* clip if out of bounds */ - /* 2.0.16: clipping rectangle, not image bounds */ - if ((y > im->cy2) || (y < im->cy1)) { - continue; - } - for (col = 0; col < bitmap.width; col++, pc++) { - int level; - if (bitmap.pixel_mode == ft_pixel_mode_grays) { - /* Scale to 128 levels of alpha for gd use. - * alpha 0 is opacity, so be sure to invert at the end - */ - level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1)); - } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { - /* 2.0.5: mode_mono fix from Giuliano Pochini */ - level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? gdAlphaTransparent : gdAlphaOpaque; - } else { - return "Unsupported ft_pixel_mode"; - } - if (level == 0) /* if background */ - continue; - if ((fg >= 0) && (im->trueColor)) { - /* Consider alpha in the foreground color itself to be an - * upper bound on how opaque things get, when truecolor is - * available. Without truecolor this results in far too many - * color indexes. - */ - level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; - } - level = gdAlphaMax - level; - x = pen_x + col; - /* clip if out of bounds */ - /* 2.0.16: clip to clipping rectangle, Matt McNabb */ - if ((x > im->cx2) || (x < im->cx1)) { - continue; - } - /* get pixel location in gd buffer */ - tpixel = &im->tpixels[y][x]; - if (fg < 0) { - if (level < (gdAlphaMax / 2)) { - *tpixel = -fg; - } - } else { - if (im->alphaBlendingFlag) { - opixel = *tpixel; - if (gdTrueColorGetAlpha(opixel) != gdAlphaTransparent) { - *tpixel = gdAlphaBlend (opixel, - (level << 24) + (fg & 0xFFFFFF)); - } else { - *tpixel = (level << 24) + (fg & 0xFFFFFF); - } - } else { - *tpixel = (level << 24) + (fg & 0xFFFFFF); - } - } - } - } - return (char *) NULL; - } - /* Non-truecolor case, restored to its more or less original form */ - for (row = 0; row < bitmap.rows; row++) { - int pcr; - pc = row * bitmap.pitch; - pcr = pc; - if (bitmap.pixel_mode==ft_pixel_mode_mono) { - pc *= 8; /* pc is measured in bits for monochrome images */ - } - y = pen_y + row; - - /* clip if out of bounds */ - if (y > im->cy2 || y < im->cy1) { - continue; - } - - for (col = 0; col < bitmap.width; col++, pc++) { - if (bitmap.pixel_mode == ft_pixel_mode_grays) { - /* - * Round to NUMCOLORS levels of antialiasing for - * index color images since only 256 colors are - * available. - */ - tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); - } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { - tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; - /* 2.0.5: mode_mono fix from Giuliano Pochini */ - tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07))) ? NUMCOLORS : 0; - } else { - return "Unsupported ft_pixel_mode"; - } - if (tc_key.pixel > 0) { /* if not background */ - x = pen_x + col; - - /* clip if out of bounds */ - if (x > im->cx2 || x < im->cx1) { - continue; - } - /* get pixel location in gd buffer */ - pixel = &im->pixels[y][x]; - if (tc_key.pixel == NUMCOLORS) { - /* use fg color directly. gd 2.0.2: watch out for - * negative indexes (thanks to David Marwood). - */ - *pixel = (fg < 0) ? -fg : fg; - } else { - /* find antialised color */ - tc_key.bgcolor = *pixel; - tc_elem = (tweencolor_t *) gdCacheGet(tc_cache, &tc_key); - *pixel = tc_elem->tweencolor; - } - } - } - } - return (char *) NULL; -} - -static int -gdroundupdown (FT_F26Dot6 v1, int roundup) +static char *gdft_draw_bitmap(gdCache_head_t *tc_cache, gdImagePtr im, int fg, FT_Bitmap bitmap, + int pen_x, int pen_y) { - return (!roundup) ? v1 >> 6 : (v1 + 63) >> 6; + unsigned char *pixel = NULL; + int *tpixel = NULL; + int opixel; + int x, y, pc, pcr; + unsigned int col; + unsigned int row; + + tweencolor_t *tc_elem; + tweencolorkey_t tc_key; + + /* copy to image, mapping colors */ + tc_key.fgcolor = fg; + tc_key.im = im; + /* Truecolor version; does not require the cache */ + if (im->trueColor) { + for (row = 0; row < bitmap.rows; row++) { + pc = row * bitmap.pitch; + pcr = pc; + y = pen_y + row; + /* clip if out of bounds */ + /* 2.0.16: clipping rectangle, not image bounds */ + if ((y > im->cy2) || (y < im->cy1)) + continue; + for (col = 0; col < bitmap.width; col++, pc++) { + int level; + if (bitmap.pixel_mode == ft_pixel_mode_grays) { + /* + * Scale to 128 levels of alpha for gd use. + * alpha 0 is opacity, so be sure to invert at the end + */ + level = (bitmap.buffer[pc] * gdAlphaMax / (bitmap.num_grays - 1)); + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { + /* 2.0.5: mode_mono fix from Giuliano Pochini */ + level = ((bitmap.buffer[(col >> 3) + pcr]) & (1 << (~col & 0x07))) + ? gdAlphaTransparent + : gdAlphaOpaque; + } else { + return "Unsupported ft_pixel_mode"; + } + if (level == 0) /* if background */ + continue; + + if ((fg >= 0) && (im->trueColor)) { + /* Consider alpha in the foreground color itself to be an + upper bound on how opaque things get, when truecolor is + available. Without truecolor this results in far too many + color indexes. */ + level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; + } + level = gdAlphaMax - level; /* inverting to get alpha */ + x = pen_x + col; + /* clip if out of bounds */ + /* 2.0.16: clip to clipping rectangle, Matt McNabb */ + if ((x > im->cx2) || (x < im->cx1)) + continue; + /* get pixel location in gd buffer */ + tpixel = &im->tpixels[y][x]; + if (fg < 0) { + if (level < (gdAlphaMax / 2)) { + *tpixel = -fg; + } + } else { + if (im->alphaBlendingFlag) { + opixel = *tpixel; + if (gdTrueColorGetAlpha(opixel) != gdAlphaTransparent) { + *tpixel = gdAlphaBlend(opixel, (level << 24) + (fg & 0xFFFFFF)); + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } + } + } + } + return (char *)NULL; + } + /* Non-truecolor case, restored to its more or less original form */ + for (row = 0; row < bitmap.rows; row++) { + int pcr; + pc = row * bitmap.pitch; + pcr = pc; + if (bitmap.pixel_mode == ft_pixel_mode_mono) + pc *= 8; /* pc is measured in bits for monochrome images */ + + y = pen_y + row; + + /* clip if out of bounds */ + if (y > im->cy2 || y < im->cy1) + continue; + + for (col = 0; col < bitmap.width; col++, pc++) { + if (bitmap.pixel_mode == ft_pixel_mode_grays) { + /* + * Round to GD_NUMCOLORS levels of antialiasing for + * index color images since only 256 colors are + * available. + */ + tc_key.pixel = ((bitmap.buffer[pc] * GD_NUMCOLORS) + bitmap.num_grays / 2) / + (bitmap.num_grays - 1); + } else if (bitmap.pixel_mode == ft_pixel_mode_mono) { + /* 2.0.5: mode_mono fix from Giuliano Pochini */ + tc_key.pixel = + ((bitmap.buffer[(col >> 3) + pcr]) & (1 << (~col & 0x07))) ? GD_NUMCOLORS : 0; + } else { + return "Unsupported ft_pixel_mode"; + } + if (tc_key.pixel == 0) /* if background */ + continue; + + x = pen_x + col; + + /* clip if out of bounds */ + if (x > im->cx2 || x < im->cx1) + continue; + /* get pixel location in gd buffer */ + pixel = &im->pixels[y][x]; + if (tc_key.pixel == GD_NUMCOLORS) { + /* use fg color directly. gd 2.0.2: watch out for + negative indexes (thanks to David Marwood). */ + *pixel = (fg < 0) ? -fg : fg; + } else { + /* find antialised color */ + + tc_key.bgcolor = *pixel; + tc_elem = (tweencolor_t *)gdCacheGet(tc_cache, &tc_key); + if (!tc_elem) + return tc_cache->error; + *pixel = tc_elem->tweencolor; + } + } + } + return (char *)NULL; } -void gdFontCacheShutdown() -{ - gdMutexLock(gdFontCacheMutex); +/** + * Function: gdFreeFontCache + * + * Alias of . + */ +BGD_DECLARE(void) gdFreeFontCache() { gdFontCacheShutdown(); } - if (fontCache) { - gdCacheDelete(fontCache); - fontCache = NULL; - FT_Done_FreeType(library); - } +BGD_DECLARE(void) gdFontCacheMutexSetup(void) { gdMutexSetup(gdFontCacheMutex); } - gdMutexUnlock(gdFontCacheMutex); -} +BGD_DECLARE(void) gdFontCacheMutexShutdown(void) { gdMutexShutdown(gdFontCacheMutex); } -void gdFreeFontCache(void) +/** + * Function: gdFontCacheShutdown + * + * Shut down the font cache and free the allocated resources. + * + * Important: + * This function has to be called whenever FreeType operations have been + * invoked, to avoid resource leaks. It doesn't harm to call this function + * multiple times. + */ +BGD_DECLARE(void) gdFontCacheShutdown() { - gdFontCacheShutdown(); + if (fontCache) { + gdMutexLock(gdFontCacheMutex); + gdCacheDelete(fontCache); + /* 2.0.16: Gustavo Scotti: make sure we don't free this twice */ + fontCache = 0; + gdMutexUnlock(gdFontCacheMutex); + FT_Done_FreeType(library); + } } -void gdFontCacheMutexSetup() +/** + * Function: gdImageStringFT + * + * Render an UTF-8 string onto a gd image. + * + * Parameters: + * im - The image to draw onto. + * brect - The bounding rectangle as array of 8 integers where each pair + * represents the x- and y-coordinate of a point. The points + * specify the lower left, lower right, upper right and upper left + * corner. + * fg - The font color. + * fontlist - The semicolon delimited list of font filenames to look for. + * ptsize - The height of the font in typographical points (pt). + * angle - The angle in radian to rotate the font counter-clockwise. + * x - The x-coordinate of the basepoint (roughly the lower left corner) + *of the first letter. y - The y-coordinate of the basepoint (roughly the + *lower left corner) of the first letter. string - The string to render. + * + * Variant: + * - + * + * See also: + * - + */ +BGD_DECLARE(char *) +gdImageStringFT(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string) { - gdMutexSetup(gdFontCacheMutex); + return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 0); } -void gdFontCacheMutexShutdown() +/** + * Function: gdFontCacheSetup + * + * Set up the font cache. + * + * This is called automatically from the string rendering functions, if it + * has not already been called. So there's no need to call this function + * explicitly. + */ +BGD_DECLARE(int) gdFontCacheSetup(void) { - gdMutexShutdown(gdFontCacheMutex); + if (fontCache) { + /* Already set up */ + return 0; + } + if (FT_Init_FreeType(&library)) { + return -1; + } + fontCache = gdCacheCreate(FONTCACHESIZE, fontTest, fontFetch, fontRelease); + if (!fontCache) { + return -2; + } + return 0; } -int gdFontCacheSetup(void) -{ - if (fontCache) { - /* Already set up */ - return 0; - } - if (FT_Init_FreeType(&library)) { - return -1; - } - fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease); - return 0; -} +/* + Function: gdImageStringFTEx + gdImageStringFTEx extends the capabilities of gdImageStringFT by + providing a way to pass additional parameters. -/********************************************************************/ -/* gdImageStringFT - render a utf8 string onto a gd image */ + If the strex parameter is not null, it must point to a + gdFTStringExtra structure. As of gd 2.0.5, this structure is defined + as follows: + (start code) -char * -gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) -{ - return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 0); -} + typedef struct { + // logical OR of gdFTEX_ values + int flags; + + // fine tune line spacing for '\n' + double linespacing; + + // Preferred character mapping + int charmap; + + // Rendering resolution + int hdpi; + int vdpi; + char *xshow; + char *fontpath; + } gdFTStringExtra, *gdFTStringExtraPtr; + + (end code) + + To output multiline text with a specific line spacing, include + gdFTEX_LINESPACE in the setting of flags: + + > flags |= gdFTEX_LINESPACE; + + And also set linespacing to the desired spacing, expressed as a + multiple of the font height. Thus a line spacing of 1.0 is the + minimum to guarantee that lines of text do not collide. + + If gdFTEX_LINESPACE is not present, or strex is null, or + gdImageStringFT is called, linespacing defaults to 1.05. + + To specify a preference for Unicode, Shift_JIS Big5 character + encoding, set or To output multiline text with a specific line + spacing, include gdFTEX_CHARMAP in the setting of flags: + + > flags |= gdFTEX_CHARMAP; + + And set charmap to the desired value, which can be any of + gdFTEX_Unicode, gdFTEX_Shift_JIS, gdFTEX_Big5, or + gdFTEX_Adobe_Custom. If you do not specify a preference, Unicode + will be tried first. If the preferred character mapping is not found + in the font, other character mappings are attempted. + + GD operates on the assumption that the output image will be rendered + to a computer screen. By default, gd passes a resolution of 96 dpi + to the freetype text rendering engine. This influences the "hinting" + decisions made by the renderer. To specify a different resolution, + set hdpi and vdpi accordingly (in dots per inch) and add + gdFTEX_RESOLUTION to flags: + + > flags | gdFTEX_RESOLUTION; + + GD 2.0.29 and later will normally attempt to apply kerning tables, + if fontconfig is available, to adjust the relative positions of + consecutive characters more ideally for that pair of + characters. This can be turn off by specifying the + gdFTEX_DISABLE_KERNING flag: + + > flags | gdFTEX_DISABLE_KERNING; -char * -gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex) + GD 2.0.29 and later can return a vector of individual character + position advances, occasionally useful in applications that must + know exactly where each character begins. This is returned in the + xshow element of the gdFTStringExtra structure if the gdFTEX_XSHOW + flag is set: + + > flags | gdFTEX_XSHOW; + + The caller is responsible for calling gdFree() on the xshow element + after the call if gdFTEX_XSHOW is set. + + GD 2.0.29 and later can also return the path to the actual font file + used if the gdFTEX_RETURNFONTPATHNAME flag is set. This is useful + because GD 2.0.29 and above are capable of selecting a font + automatically based on a fontconfig font pattern when fontconfig is + available. This information is returned in the fontpath element of + the gdFTStringExtra structure. + + > flags | gdFTEX_RETURNFONTPATHNAME; + + The caller is responsible for calling gdFree() on the fontpath + element after the call if gdFTEX_RETURNFONTPATHNAME is set. + + GD 2.0.29 and later can use fontconfig to resolve font names, + including fontconfig patterns, if the gdFTEX_FONTCONFIG flag is + set. As a convenience, this behavior can be made the default by + calling with a nonzero value. In that situation it + is not necessary to set the gdFTEX_FONTCONFIG flag on every call; + however explicit font path names can still be used if the + gdFTEX_FONTPATHNAME flag is set: + + > flags | gdFTEX_FONTPATHNAME; + + Unless has been called with a nonzero value, GD + 2.0.29 and later will still expect the fontlist argument to the + freetype text output functions to be a font file name or list + thereof as in previous versions. If you do not wish to make + fontconfig the default, it is still possible to force the use of + fontconfig for a single call to the freetype text output functions + by setting the gdFTEX_FONTCONFIG flag: + + > flags | gdFTEX_FONTCONFIG; + + GD 2.0.29 and above can use fontconfig to resolve font names, + including fontconfig patterns, if the gdFTEX_FONTCONFIG flag is + set. As a convenience, this behavior can be made the default by + calling with a nonzero value. In that situation it + is not necessary to set the gdFTEX_FONTCONFIG flag on every call; + however explicit font path names can still be used if the + gdFTEX_FONTPATHNAME flag is set: + + > flags | gdFTEX_FONTPATHNAME; + + For more information, see . +*/ + +/* the platform-independent resolution used for size and position calculations + */ +/* the size of the error introduced by rounding is affected by this number */ +#define METRIC_RES 300 + +BGD_DECLARE(char *) +gdImageStringFTEx(gdImagePtr im, int *brect, int fg, const char *fontlist, double ptsize, + double angle, int x, int y, const char *string, gdFTStringExtraPtr strex) { - FT_BBox bbox, glyph_bbox; - FT_Matrix matrix; - FT_Vector pen, delta, penf; - FT_Face face; - FT_Glyph image; - FT_GlyphSlot slot; - FT_Bool use_kerning; - FT_UInt glyph_index, previous; - double sin_a = sin (angle); - double cos_a = cos (angle); - int len, i = 0, ch; - int x1 = 0, y1 = 0; - font_t *font; - fontkey_t fontkey; - char *next; - char *tmpstr = NULL; - int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); - FT_BitmapGlyph bm; - /* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing freetype and doesn't look as good */ - int render_mode = FT_LOAD_DEFAULT; - int m, mfound; - /* Now tuneable thanks to Wez Furlong */ - double linespace = LINESPACE; - /* 2.0.6: put this declaration with the other declarations! */ - /* - * make a new tweenColorCache on every call - * because caching colormappings between calls - * is not safe. If the im-pointer points to a - * brand new image, the cache gives out bogus - * colorindexes. -- 27.06.2001 - */ - gdCache_head_t *tc_cache; - /* Tuneable horizontal and vertical resolution in dots per inch */ - int hdpi, vdpi; - - if (strex && ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE)) { - linespace = strex->linespacing; - } - tc_cache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease); - - /***** initialize font library and font cache on first call ******/ - - gdMutexLock(gdFontCacheMutex); - if (!fontCache) { - if (gdFontCacheSetup() != 0) { - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Failure to initialize font library"; - } - } - /*****/ - - /* 2.0.12: allow explicit specification of the preferred map; - * but we still fall back if it is not available. - */ - m = gdFTEX_Unicode; - if (strex && (strex->flags & gdFTEX_CHARMAP)) { - m = strex->charmap; - } - - /* get the font (via font cache) */ - fontkey.fontlist = fontlist; - fontkey.library = &library; - fontkey.preferred_map = m; - font = (font_t *) gdCacheGet (fontCache, &fontkey); - if (!font) { - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return fontCache->error; - } - face = font->face; /* shortcut */ - slot = face->glyph; /* shortcut */ - - /* - * Added hdpi and vdpi to support images at non-screen resolutions, i.e. 300 dpi TIFF, - * or 100h x 50v dpi FAX format. 2.0.23. - * 2004/02/27 Mark Shackelford, mark.shackelford@acs-inc.com - */ - hdpi = GD_RESOLUTION; - vdpi = GD_RESOLUTION; - if (strex && (strex->flags & gdFTEX_RESOLUTION)) { - hdpi = strex->hdpi; - vdpi = strex->vdpi; - } - - if (FT_Set_Char_Size(face, 0, (FT_F26Dot6) (ptsize * 64), hdpi, vdpi)) { - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Could not set character size"; - } - - matrix.xx = (FT_Fixed) (cos_a * (1 << 16)); - matrix.yx = (FT_Fixed) (sin_a * (1 << 16)); - matrix.xy = -matrix.yx; - matrix.yy = matrix.xx; - - penf.x = penf.y = 0; /* running position of non-rotated string */ - pen.x = pen.y = 0; /* running position of rotated string */ - bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0; - - use_kerning = FT_HAS_KERNING (face); - previous = 0; - if (fg < 0) { - render_mode |= FT_LOAD_MONOCHROME; - } - - /* Try all three types of maps, but start with the specified one */ - mfound = 0; - for (i = 0; i < 3; i++) { - switch (m) { - case gdFTEX_Unicode: - if (font->have_char_map_unicode) { - mfound = 1; - } - break; - case gdFTEX_Shift_JIS: - if (font->have_char_map_sjis) { - mfound = 1; - } - break; - case gdFTEX_Big5: - /* This was the 'else' case, we can't really 'detect' it */ - mfound = 1; - break; - } - if (mfound) { - break; - } - m++; - m %= 3; - } - if (!mfound) { - /* No character set found! */ - gdMutexUnlock(gdFontCacheMutex); - return "No character set found"; - } + FT_Matrix matrix; + FT_Vector penf, oldpenf, total_min = {0, 0}, total_max = {0, 0}, glyph_min, glyph_max; + FT_Face face; + FT_CharMap charmap = NULL; + FT_CharMap fallback_charmap = NULL; + FT_Glyph image; + FT_GlyphSlot slot; + FT_Error err; + FT_UInt glyph_index; + double sin_a = sin(angle); + double cos_a = cos(angle); + int i, ch; + font_t *font; + fontkey_t fontkey; + const char *next; + char *tmpstr = 0; + uint32_t *text; + glyphInfo *info = NULL; + ssize_t count; + int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); + FT_BitmapGlyph bm; + /* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing + freetype and doesn't look as good */ + int render_mode = FT_LOAD_DEFAULT; + int encoding, encodingfound; + /* Now tuneable thanks to Wez Furlong */ + double linespace = LINESPACE; + /* 2.0.6: put this declaration with the other declarations! */ + /* + * make a new tweenColorCache on every call + * because caching colormappings between calls + * is not safe. If the im-pointer points to a + * brand new image, the cache gives out bogus + * colorindexes. -- 27.06.2001 + */ + gdCache_head_t *tc_cache; + /* Tuneable horizontal and vertical resolution in dots per inch */ + int hdpi, vdpi, horiAdvance, vertAdvance, xshow_alloc = 0, xshow_pos = 0; + FT_Size platform_specific = NULL, platform_independent; + + if (strex) { + if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) { + linespace = strex->linespacing; + } + } + tc_cache = + gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease); + + /***** initialize font library and font cache on first call ******/ + if (!fontCache) { + if (gdFontCacheSetup() != 0) { + gdCacheDelete(tc_cache); + return "Failure to initialize font library"; + } + } + /*****/ + gdMutexLock(gdFontCacheMutex); + /* get the font (via font cache) */ + fontkey.fontlist = fontlist; + if (strex) + fontkey.flags = strex->flags & (gdFTEX_FONTPATHNAME | gdFTEX_FONTCONFIG); + else + fontkey.flags = 0; + fontkey.library = &library; + font = (font_t *)gdCacheGet(fontCache, &fontkey); + if (!font) { + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return fontCache->error; + } + face = font->face; /* shortcut */ + slot = face->glyph; /* shortcut */ + + if (brect) { + total_min.x = total_min.y = 0; + total_max.x = total_max.y = 0; + } + + /* + * Added hdpi and vdpi to support images at non-screen resolutions, i.e. 300 + * dpi TIFF, or 100h x 50v dpi FAX format. 2.0.23. 2004/02/27 Mark + * Shackelford, mark.shackelford@acs-inc.com + */ + hdpi = GD_RESOLUTION; + vdpi = GD_RESOLUTION; + encoding = gdFTEX_Unicode; + if (strex) { + if (strex->flags & gdFTEX_RESOLUTION) { + hdpi = strex->hdpi; + vdpi = strex->vdpi; + } + if (strex->flags & gdFTEX_XSHOW) { + strex->xshow = NULL; + } + /* 2.0.12: allow explicit specification of the preferred map; + but we still fall back if it is not available. */ + if (strex->flags & gdFTEX_CHARMAP) { + encoding = strex->charmap; + } + /* 2.0.29: we can return the font path if desired */ + if (strex->flags & gdFTEX_RETURNFONTPATHNAME) { + const unsigned int fontpath_len = strlen(font->fontpath); + + strex->fontpath = (char *)gdMalloc(fontpath_len + 1); + if (strex->fontpath == NULL) { + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return "could not alloc full list of fonts"; + } + memcpy(strex->fontpath, font->fontpath, fontpath_len); + strex->fontpath[fontpath_len] = 0; + } + } + + matrix.xx = (FT_Fixed)(cos_a * (1 << 16)); + matrix.yx = (FT_Fixed)(sin_a * (1 << 16)); + matrix.xy = -matrix.yx; + matrix.yy = matrix.xx; + + /* Keep RAQM layout in text space; apply transform later only for + * the render glyph load. */ +#ifdef HAVE_LIBRAQM + FT_Set_Transform(face, NULL, NULL); +#else + /* set rotation transform */ + FT_Set_Transform(face, &matrix, NULL); +#endif + + FT_New_Size(face, &platform_independent); + FT_Activate_Size(platform_independent); + if (FT_Set_Char_Size(face, 0, (FT_F26Dot6)(ptsize * 64), METRIC_RES, METRIC_RES)) { + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return "Could not set character size"; + } + + if (render) { + FT_New_Size(face, &platform_specific); + FT_Activate_Size(platform_specific); + if (FT_Set_Char_Size(face, 0, (FT_F26Dot6)(ptsize * 64), hdpi, vdpi)) { + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return "Could not set character size"; + } + } + + if (fg < 0) + render_mode |= FT_LOAD_MONOCHROME; + + /* find requested charmap */ + encodingfound = 0; + for (i = 0; i < face->num_charmaps; i++) { + charmap = face->charmaps[i]; + + if (encoding == gdFTEX_Unicode) { + if (charmap->encoding == FT_ENCODING_UNICODE) { + encodingfound++; + break; + } + if (!fallback_charmap && (charmap->encoding == FT_ENCODING_MS_SYMBOL || + charmap->encoding == FT_ENCODING_ADOBE_CUSTOM || + charmap->encoding == FT_ENCODING_ADOBE_STANDARD)) { + fallback_charmap = charmap; + } + } else if (encoding == gdFTEX_Adobe_Custom) { + if (charmap->encoding == FT_ENCODING_ADOBE_CUSTOM) { + encodingfound++; + break; + } + if (!fallback_charmap && charmap->encoding == FT_ENCODING_APPLE_ROMAN) { + fallback_charmap = charmap; + } + } else if (encoding == gdFTEX_Big5) { + /* renamed sometime after freetype-2.1.4 */ +#ifndef FT_ENCODING_BIG5 +#define FT_ENCODING_BIG5 FT_ENCODING_MS_BIG5 +#endif + if (charmap->encoding == FT_ENCODING_BIG5) { + encodingfound++; + break; + } + } else if (encoding == gdFTEX_Shift_JIS) { + /* renamed sometime after freetype-2.1.4 */ +#ifndef FT_ENCODING_SJIS +#define FT_ENCODING_SJIS FT_ENCODING_MS_SJIS +#endif + if (charmap->encoding == FT_ENCODING_SJIS) { + encodingfound++; + break; + } + } + } + if (!encodingfound && fallback_charmap) { + charmap = fallback_charmap; + encodingfound = 1; + } + if (encodingfound) { + FT_Set_Charmap(face, charmap); + } else { + /* No character set found! */ + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return "No character set found"; + } #ifndef JISX0208 - if (font->have_char_map_sjis) { + if (encoding == gdFTEX_Shift_JIS) { #endif - tmpstr = (char *) gdMalloc(BUFSIZ); - any2eucjp(tmpstr, string, BUFSIZ); - next = tmpstr; + if ((tmpstr = (char *)gdMalloc(BUFSIZ))) { + any2eucjp(tmpstr, string, BUFSIZ); + next = tmpstr; + } else { + next = string; + } #ifndef JISX0208 - } else { - next = string; - } + } else { + next = string; + } #endif - i = 0; - while (*next) { - ch = *next; - - /* carriage returns */ - if (ch == '\r') { - penf.x = 0; - x1 = (int)(- penf.y * sin_a + 32) / 64; - y1 = (int)(- penf.y * cos_a + 32) / 64; - pen.x = pen.y = 0; - previous = 0; /* clear kerning flag */ - next++; - continue; - } - /* newlines */ - if (ch == '\n') { - if (!*(++next)) break; - /* 2.0.13: reset penf.x. Christopher J. Grayce */ - penf.x = 0; - penf.y -= (long)(face->size->metrics.height * linespace); - penf.y = (penf.y - 32) & -64; /* round to next pixel row */ - x1 = (int)(- penf.y * sin_a + 32) / 64; - y1 = (int)(- penf.y * cos_a + 32) / 64; - pen.x = pen.y = 0; - previous = 0; /* clear kerning flag */ - continue; - } - -/* EAM DEBUG */ -#if (defined(FREETYPE_MAJOR) && ((FREETYPE_MAJOR == 2 && ((FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3) || FREETYPE_MINOR > 1) || FREETYPE_MAJOR > 2))) - if (font->face->family_name && font->face->charmap->encoding && - font->face->charmap->encoding == FT_ENCODING_MS_SYMBOL && strcmp(font->face->family_name, "Symbol") == 0) { - /* I do not know the significance of the constant 0xf000. - * It was determined by inspection of the character codes - * stored in Microsoft font symbol. - * Added by Pierre (pajoye@php.net): - * Convert to the Symbol glyph range only for a Symbol family member - */ - len = gdTcl_UtfToUniChar (next, &ch); - ch |= 0xf000; - next += len; - } else -#endif /* Freetype 2.1 or better */ -/* EAM DEBUG */ - - switch (m) { - case gdFTEX_Unicode: - if (font->have_char_map_unicode) { - /* use UTF-8 mapping from ASCII */ - len = gdTcl_UtfToUniChar(next, &ch); - next += len; - } - break; - case gdFTEX_Shift_JIS: - if (font->have_char_map_sjis) { - unsigned char c; - int jiscode; - c = *next; - if (0xA1 <= c && c <= 0xFE) { - next++; - jiscode = 0x100 * (c & 0x7F) + ((*next) & 0x7F); - - ch = (jiscode >> 8) & 0xFF; - jiscode &= 0xFF; - - if (ch & 1) { - jiscode += 0x40 - 0x21; - } else { - jiscode += 0x9E - 0x21; - } - - if (jiscode >= 0x7F) { - jiscode++; - } - ch = (ch - 0x21) / 2 + 0x81; - if (ch >= 0xA0) { - ch += 0x40; - } - - ch = (ch << 8) + jiscode; - } else { - ch = c & 0xFF; /* don't extend sign */ - } - if (*next) next++; - } - break; - case gdFTEX_Big5: { - /* - * Big 5 mapping: - * use "JIS-8 half-width katakana" coding from 8-bit characters. Ref: - * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs - */ - ch = (*next) & 0xFF; /* don't extend sign */ - next++; - if (ch >= 161 /* first code of JIS-8 pair */ - && *next) { /* don't advance past '\0' */ - /* TBB: Fix from Kwok Wah On: & 255 needed */ - ch = (ch * 256) + ((*next) & 255); - next++; - } - } - break; - } - - /* set rotation transform */ - FT_Set_Transform(face, &matrix, NULL); - /* Convert character code to glyph index */ - glyph_index = FT_Get_Char_Index(face, ch); - - /* retrieve kerning distance and move pen position */ - if (use_kerning && previous && glyph_index) { - FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta); - pen.x += (int)(delta.x * cos_a); - pen.y -= (int)(delta.x * sin_a); - penf.x += delta.x; - } - - if (brect) { /* only if need brect */ - /* load glyph image into the slot (erase previous one) */ - if (FT_Load_Glyph(face, glyph_index, render_mode | FT_LOAD_IGNORE_TRANSFORM)) { - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Problem loading glyph"; - } - - /* transform glyph image */ - if (FT_Get_Glyph(slot, &image)) { - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Problem loading glyph"; - } + oldpenf.x = oldpenf.y = 0; /* for postscript xshow operator */ + penf.x = penf.y = 0; /* running position of non-rotated glyphs */ + text = (uint32_t *)gdCalloc(sizeof(uint32_t), strlen(next)); + i = 0; + while (*next) { + int len; + ch = *next; + switch (encoding) { + case gdFTEX_Unicode: { + /* use UTF-8 mapping from ASCII */ + len = gdTcl_UtfToUniChar(next, &ch); + /* EAM DEBUG */ + /* TBB: get this exactly right: 2.1.3 *or better*, all possible + * cases. */ + /* 2.0.24: David R. Morrison: use the more complete ifdef here. */ + if (charmap->encoding == FT_ENCODING_MS_SYMBOL) { + /* I do not know the significance of the constant 0xf000. */ + /* It was determined by inspection of the character codes */ + /* stored in Microsoft font symbol.ttf */ + ch |= 0xf000; + } + /* EAM DEBUG */ + next += len; + } break; + case gdFTEX_Shift_JIS: { + unsigned char c; + int jiscode; + c = *next; + if (0xA1 <= c && c <= 0xFE) { + next++; + jiscode = 0x100 * (c & 0x7F) + ((*next) & 0x7F); + + ch = (jiscode >> 8) & 0xFF; + jiscode &= 0xFF; + + if (ch & 1) + jiscode += 0x40 - 0x21; + else + jiscode += 0x9E - 0x21; + + if (jiscode >= 0x7F) + jiscode++; + ch = (ch - 0x21) / 2 + 0x81; + if (ch >= 0xA0) + ch += 0x40; + + ch = (ch << 8) + jiscode; + } else { + ch = c & 0xFF; /* don't extend sign */ + } + if (*next) + next++; + } break; + case gdFTEX_Big5: { + /* + * Big 5 mapping: + * use "JIS-8 half-width katakana" coding from 8-bit characters. + * Ref: + * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs + */ + ch = (*next) & 0xFF; /* don't extend sign */ + next++; + if (ch >= 161 /* first code of JIS-8 pair */ + && *next) { + /* don't advance past '\0' */ + /* TBB: Fix from Kwok Wah On: & 255 needed */ + ch = (ch * 256) + ((*next) & 255); + next++; + } + } break; + + case gdFTEX_Adobe_Custom: + default: + ch &= 0xFF; + next++; + break; + } + text[i] = ch; + i++; + } + + FT_Activate_Size(platform_independent); + + count = textLayout(text, i, face, strex, &info); + + if (count < 0) { + gdFree(text); + gdFree(tmpstr); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + if (info) { + gdFree(info); + } + return "Problem doing text layout"; + } + + for (i = 0; i < count; i++) { + FT_Activate_Size(platform_independent); + + ch = text[info[i].cluster]; + + /* carriage returns */ + if (ch == '\r') { + penf.x = 0; + continue; + } + + /* newlines */ + if (ch == '\n') { + /* 2.0.13: reset penf.x. Christopher J. Grayce */ + penf.x = 0; + penf.y += linespace * ptsize * 64 * METRIC_RES / 72; + penf.y &= ~63; /* round down to 1/METRIC_RES */ + continue; + } + + glyph_index = info[i].index; + /* When we know the position of the second or subsequent character, + save the (kerned) advance from the preceeding character in the + xshow vector */ + if (i && strex && (strex->flags & gdFTEX_XSHOW)) { + /* make sure we have enough allocation for two numbers + so we don't have to recheck for the terminating number */ + if (!xshow_alloc) { + xshow_alloc = 100; + strex->xshow = gdMalloc(xshow_alloc); + if (!strex->xshow) { + if (tmpstr) + gdFree(tmpstr); + gdFree(text); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + gdFree(info); + return "Problem allocating memory"; + } + xshow_pos = 0; + } else if (xshow_pos + 20 > xshow_alloc) { + xshow_alloc += 100; + strex->xshow = gdReallocEx(strex->xshow, xshow_alloc); + if (!strex->xshow) { + if (tmpstr) + gdFree(tmpstr); + gdFree(text); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + gdFree(info); + return "Problem allocating memory"; + } + } + xshow_pos += sprintf(strex->xshow + xshow_pos, "%g ", + (double)(penf.x - oldpenf.x) * hdpi / (64 * METRIC_RES)); + } + oldpenf.x = penf.x; + +#ifdef HAVE_LIBRAQM + /* Keep RAQM brect/layout metrics in unrotated text space. */ + FT_Set_Transform(face, NULL, NULL); +#endif - FT_Glyph_Get_CBox(image, ft_glyph_bbox_gridfit, &glyph_bbox); - glyph_bbox.xMin += penf.x; - glyph_bbox.yMin += penf.y; - glyph_bbox.xMax += penf.x; - glyph_bbox.yMax += penf.y; - if (ch == ' ') { /* special case for trailing space */ - glyph_bbox.xMax += slot->metrics.horiAdvance; - } - if (!i) { /* if first character, init BB corner values */ - bbox.xMin = glyph_bbox.xMin; - bbox.yMin = glyph_bbox.yMin; - bbox.xMax = glyph_bbox.xMax; - bbox.yMax = glyph_bbox.yMax; + /* load glyph image into the slot (erase previous one) */ + err = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if (err) { + if (tmpstr) + gdFree(tmpstr); + gdFree(text); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + gdFree(info); + return "Problem loading glyph"; + } + + horiAdvance = info[i].x_advance; + vertAdvance = info[i].y_advance; + + if (brect) { + /* only if need brect */ + + glyph_min.x = penf.x + slot->metrics.horiBearingX; + glyph_min.y = penf.y - slot->metrics.horiBearingY; + +#if 0 + if (ch == ' ') { /* special case for trailing space */ + glyph_max.x = penf.x + horiAdvance; } else { - if (bbox.xMin > glyph_bbox.xMin) { - bbox.xMin = glyph_bbox.xMin; - } - if (bbox.yMin > glyph_bbox.yMin) { - bbox.yMin = glyph_bbox.yMin; - } - if (bbox.xMax < glyph_bbox.xMax) { - bbox.xMax = glyph_bbox.xMax; - } - if (bbox.yMax < glyph_bbox.yMax) { - bbox.yMax = glyph_bbox.yMax; - } - } - i++; - } - - /* increment (unrotated) pen position */ - penf.x += slot->metrics.horiAdvance; - - if (render) { - if (!brect || angle != 0) { - /* reload the rotated glyph (for bbox we needed FT_LOAD_IGNORE_TRANSFORM - bbox is rotated later) */ - FT_Done_Glyph(image); - - /* load glyph image into the slot (erase previous one) */ - if (FT_Load_Glyph(face, glyph_index, render_mode)) { - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Problem loading glyph"; - } - - /* transform glyph image */ - if (FT_Get_Glyph(slot, &image)) { - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Problem loading glyph"; - } - } - - if (image->format != ft_glyph_format_bitmap && FT_Glyph_To_Bitmap(&image, ft_render_mode_normal, 0, 1)) { - FT_Done_Glyph(image); - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return "Problem rendering glyph"; + glyph_max.x = glyph_min.x + slot->metrics.width; } +#else + glyph_max.x = penf.x + horiAdvance; +#endif + glyph_max.y = glyph_min.y + slot->metrics.height; + + if (i == 0) { + total_min = glyph_min; + total_max = glyph_max; + } else { + if (glyph_min.x < total_min.x) + total_min.x = glyph_min.x; + if (glyph_min.y < total_min.y) + total_min.y = glyph_min.y; + if (glyph_max.x > total_max.x) + total_max.x = glyph_max.x; + if (glyph_max.y > total_max.y) + total_max.y = glyph_max.y; + } + } + + if (render) { + FT_Activate_Size(platform_specific); + +#ifdef HAVE_LIBRAQM + /* Render rotated glyph bitmaps while RAQM pen advances remain in + * layout space. */ + FT_Set_Transform(face, &matrix, NULL); +#endif - /* now, draw to our target surface */ - bm = (FT_BitmapGlyph) image; - gdft_draw_bitmap(tc_cache, im, fg, bm->bitmap, x + x1 + ((pen.x + 31) >> 6) + bm->left, y + y1 + ((pen.y + 31) >> 6) - bm->top); - } - - /* record current glyph index for kerning */ - previous = glyph_index; - - /* increment pen position */ - pen.x += image->advance.x >> 10; - pen.y -= image->advance.y >> 10; - - FT_Done_Glyph(image); - } - - if (brect) { /* only if need brect */ - /* For perfect rounding, must get sin(a + pi/4) and sin(a - pi/4). */ - double d1 = sin (angle + 0.78539816339744830962); - double d2 = sin (angle - 0.78539816339744830962); - - /* rotate bounding rectangle (at 0, 0) */ - brect[0] = (int) (bbox.xMin * cos_a - bbox.yMin * sin_a); - brect[1] = (int) (bbox.xMin * sin_a + bbox.yMin * cos_a); - brect[2] = (int) (bbox.xMax * cos_a - bbox.yMin * sin_a); - brect[3] = (int) (bbox.xMax * sin_a + bbox.yMin * cos_a); - brect[4] = (int) (bbox.xMax * cos_a - bbox.yMax * sin_a); - brect[5] = (int) (bbox.xMax * sin_a + bbox.yMax * cos_a); - brect[6] = (int) (bbox.xMin * cos_a - bbox.yMax * sin_a); - brect[7] = (int) (bbox.xMin * sin_a + bbox.yMax * cos_a); - - /* scale, round and offset brect */ - brect[0] = x + gdroundupdown(brect[0], d2 > 0); - brect[1] = y - gdroundupdown(brect[1], d1 < 0); - brect[2] = x + gdroundupdown(brect[2], d1 > 0); - brect[3] = y - gdroundupdown(brect[3], d2 > 0); - brect[4] = x + gdroundupdown(brect[4], d2 < 0); - brect[5] = y - gdroundupdown(brect[5], d1 > 0); - brect[6] = x + gdroundupdown(brect[6], d1 < 0); - brect[7] = y - gdroundupdown(brect[7], d2 < 0); - } - - if (tmpstr) { - gdFree(tmpstr); - } - gdCacheDelete(tc_cache); - gdMutexUnlock(gdFontCacheMutex); - return (char *) NULL; + /* load glyph again into the slot (erase previous one) - this time + * with scaling */ + err = FT_Load_Glyph(face, glyph_index, render_mode); + if (err) { + if (tmpstr) + gdFree(tmpstr); + gdFree(text); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + gdFree(info); + return "Problem loading glyph"; + } + + /* load and transform glyph image */ + FT_Get_Glyph(slot, &image); + + if (image->format != ft_glyph_format_bitmap) { + err = FT_Glyph_To_Bitmap(&image, ft_render_mode_normal, 0, 1); + if (err) { + FT_Done_Glyph(image); + if (tmpstr) + gdFree(tmpstr); + gdFree(text); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + gdFree(info); + return "Problem rendering glyph"; + } + } + + /* now, draw to our target surface */ + bm = (FT_BitmapGlyph)image; + /* position rounded down to nearest pixel at current dpi + (the estimate was rounded up to next 1/METRIC_RES, so this should + fit) */ + FT_Pos pen_x = penf.x + info[i].x_offset; + FT_Pos pen_y = penf.y - info[i].y_offset; + gdft_draw_bitmap( + tc_cache, im, fg, bm->bitmap, + (int)(x + (pen_x * cos_a + pen_y * sin_a) * hdpi / (METRIC_RES * 64) + bm->left), + (int)(y - (pen_x * sin_a - pen_y * cos_a) * vdpi / (METRIC_RES * 64) - bm->top)); + + FT_Done_Glyph(image); + } + + penf.x += horiAdvance; + penf.y += vertAdvance; + } + + gdFree(text); + if (info) { + gdFree(info); + } + + /* Save the (unkerned) advance from the last character in the xshow vector + */ + if (strex && (strex->flags & gdFTEX_XSHOW) && strex->xshow) { + sprintf(strex->xshow + xshow_pos, "%g", + (double)(penf.x - oldpenf.x) * hdpi / (64 * METRIC_RES)); + } + + if (brect) { + /* only if need brect */ + double scalex = (double)hdpi / (64 * METRIC_RES); + double scaley = (double)vdpi / (64 * METRIC_RES); + + /* rotate bounding rectangle, scale and round to int pixels, and + * translate */ + brect[0] = x + (total_min.x * cos_a + total_max.y * sin_a) * scalex; + brect[1] = y - (total_min.x * sin_a - total_max.y * cos_a) * scaley; + brect[2] = x + (total_max.x * cos_a + total_max.y * sin_a) * scalex; + brect[3] = y - (total_max.x * sin_a - total_max.y * cos_a) * scaley; + brect[4] = x + (total_max.x * cos_a + total_min.y * sin_a) * scalex; + brect[5] = y - (total_max.x * sin_a - total_min.y * cos_a) * scaley; + brect[6] = x + (total_min.x * cos_a + total_min.y * sin_a) * scalex; + brect[7] = y - (total_min.x * sin_a - total_min.y * cos_a) * scaley; + } + + FT_Done_Size(platform_independent); + if (render) + FT_Done_Size(platform_specific); + + if (tmpstr) + gdFree(tmpstr); + gdCacheDelete(tc_cache); + gdMutexUnlock(gdFontCacheMutex); + return (char *)NULL; } #endif /* HAVE_LIBFREETYPE */ + +#ifdef HAVE_LIBFONTCONFIG +/* Code to find font path, with special mapping for Postscript font names. + * + * Dag Lem + */ + +#include + +/* #define NO_POSTSCRIPT_ALIAS 1 */ +#ifndef NO_POSTSCRIPT_ALIAS +typedef struct _PostscriptAlias { + char *name; + char *family; + char *style; +} PostscriptAlias; + +/* This table maps standard Postscript font names to URW Type 1 fonts. + The mapping is converted from Ghostscript (Fontmap.GS) + for use with fontconfig. */ +static PostscriptAlias postscript_alias[] = { + {"AvantGarde-Book", "URW Gothic L", "Book"}, + {"AvantGarde-BookOblique", "URW Gothic L", "Book Oblique"}, + {"AvantGarde-Demi", "URW Gothic L", "Demi"}, + {"AvantGarde-DemiOblique", "URW Gothic L", "Demi Oblique"}, + + {"Bookman-Demi", "URW Bookman L", "Demi Bold"}, + {"Bookman-DemiItalic", "URW Bookman L", "Demi Bold Italic"}, + {"Bookman-Light", "URW Bookman L", "Light"}, + {"Bookman-LightItalic", "URW Bookman L", "Light Italic"}, + + {"Courier", "Nimbus Mono L", "Regular"}, + {"Courier-Oblique", "Nimbus Mono L", "Regular Oblique"}, + {"Courier-Bold", "Nimbus Mono L", "Bold"}, + {"Courier-BoldOblique", "Nimbus Mono L", "Bold Oblique"}, + + {"Helvetica", "Nimbus Sans L", "Regular"}, + {"Helvetica-Oblique", "Nimbus Sans L", "Regular Italic"}, + {"Helvetica-Bold", "Nimbus Sans L", "Bold"}, + {"Helvetica-BoldOblique", "Nimbus Sans L", "Bold Italic"}, + + {"Helvetica-Narrow", "Nimbus Sans L", "Regular Condensed"}, + {"Helvetica-Narrow-Oblique", "Nimbus Sans L", "Regular Condensed Italic"}, + {"Helvetica-Narrow-Bold", "Nimbus Sans L", "Bold Condensed"}, + {"Helvetica-Narrow-BoldOblique", "Nimbus Sans L", "Bold Condensed Italic"}, + + {"NewCenturySchlbk-Roman", "Century Schoolbook L", "Roman"}, + {"NewCenturySchlbk-Italic", "Century Schoolbook L", "Italic"}, + {"NewCenturySchlbk-Bold", "Century Schoolbook L", "Bold"}, + {"NewCenturySchlbk-BoldItalic", "Century Schoolbook L", "Bold Italic"}, + + {"Palatino-Roman", "URW Palladio L", "Roman"}, + {"Palatino-Italic", "URW Palladio L", "Italic"}, + {"Palatino-Bold", "URW Palladio L", "Bold"}, + {"Palatino-BoldItalic", "URW Palladio L", "Bold Italic"}, + + {"Symbol", "Standard Symbols L", "Regular"}, + + {"Times-Roman", "Nimbus Roman No9 L", "Regular"}, + {"Times-Italic", "Nimbus Roman No9 L", "Regular Italic"}, + {"Times-Bold", "Nimbus Roman No9 L", "Medium"}, + {"Times-BoldItalic", "Nimbus Roman No9 L", "Medium Italic"}, + + {"ZapfChancery-MediumItalic", "URW Chancery L", "Medium Italic"}, + + {"ZapfDingbats", "Dingbats", ""}, +}; +#endif + +static FcPattern *find_font(FcPattern *pattern) +{ + FcResult result; + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcConfigSubstitute(0, pattern, FcMatchFont); + FcDefaultSubstitute(pattern); + + return FcFontMatch(0, pattern, &result); +} + +#ifndef NO_POSTSCRIPT_ALIAS +static char *find_postscript_font(FcPattern **fontpattern, char *fontname) +{ + FcPattern *font = NULL; + size_t i; + + *fontpattern = NULL; + for (i = 0; i < sizeof(postscript_alias) / sizeof(*postscript_alias); i++) { + if (strcmp(fontname, postscript_alias[i].name) == 0) { + FcChar8 *family; + + FcPattern *pattern = + FcPatternBuild(0, FC_FAMILY, FcTypeString, postscript_alias[i].family, FC_STYLE, + FcTypeString, postscript_alias[i].style, (char *)0); + font = find_font(pattern); + FcPatternDestroy(pattern); + + if (!font) + return "fontconfig: Couldn't find font."; + if (FcPatternGetString(font, FC_FAMILY, 0, &family) != FcResultMatch) { + FcPatternDestroy(font); + return "fontconfig: Couldn't retrieve font family name."; + } + + /* Check whether we got the font family we wanted. */ + if (strcmp((const char *)family, postscript_alias[i].family) != 0) { + FcPatternDestroy(font); + return "fontconfig: Didn't find expected font family. Perhaps " + "URW Type 1 fonts need installing?"; + } + break; + } + } + + *fontpattern = font; + return NULL; +} +#endif + +static char *font_pattern(char **fontpath, char *fontpattern) +{ + FcPattern *font = NULL; + FcChar8 *file; + FcPattern *pattern; +#ifndef NO_POSTSCRIPT_ALIAS + char *error; +#endif + + *fontpath = NULL; +#ifndef NO_POSTSCRIPT_ALIAS + error = find_postscript_font(&font, fontpattern); + + if (!font) { + if (error) + return error; +#endif + pattern = FcNameParse((const FcChar8 *)fontpattern); + font = find_font(pattern); + FcPatternDestroy(pattern); +#ifndef NO_POSTSCRIPT_ALIAS + } +#endif + + if (!font) + return "fontconfig: Couldn't find font."; + if (FcPatternGetString(font, FC_FILE, 0, &file) != FcResultMatch) { + FcPatternDestroy(font); + return "fontconfig: Couldn't retrieve font file name."; + } else { + const unsigned int file_len = strlen((const char *)file); + + *fontpath = (char *)gdMalloc(file_len + 1); + if (*fontpath == NULL) { + return "could not alloc font path"; + } + memcpy(*fontpath, (const char *)file, file_len); + (*fontpath)[file_len] = 0; + } + FcPatternDestroy(font); + + return NULL; +} + +#endif /* HAVE_LIBFONTCONFIG */ + +#ifdef HAVE_LIBFREETYPE +/* Look up font using font names as file names. */ +static char *font_path(char **fontpath, char *name_list) +{ + int font_found = 0; + char *fontsearchpath, *fontlist; + char *fullname = NULL; + char *name, *dir; + char *path; + char *strtok_ptr = NULL; + const unsigned int name_list_len = strlen(name_list); + + /* + * Search the pathlist for any of a list of font names. + */ + *fontpath = NULL; + fontsearchpath = getenv("GDFONTPATH"); + if (!fontsearchpath) + fontsearchpath = DEFAULT_FONTPATH; + path = (char *)gdMalloc(sizeof(char) * strlen(fontsearchpath) + 1); + if (path == NULL) { + return "could not alloc full list of fonts"; + } + path[0] = 0; + + fontlist = (char *)gdMalloc(name_list_len + 1); + if (fontlist == NULL) { + gdFree(path); + return "could not alloc full list of fonts"; + } + memcpy(fontlist, name_list, name_list_len); + fontlist[name_list_len] = 0; + + /* + * Must use gd_strtok_r else pointer corrupted by strtok in nested loop. + */ + for (name = gd_strtok_r(fontlist, LISTSEPARATOR, &strtok_ptr); name; + name = gd_strtok_r(0, LISTSEPARATOR, &strtok_ptr)) { + char *path_ptr = NULL; + + /* make a fresh copy each time - strtok corrupts it. */ + sprintf(path, "%s", fontsearchpath); + /* + * Allocate an oversized buffer that is guaranteed to be + * big enough for all paths to be tested. + */ + /* 2.0.22: Thorben Kundinger: +8 is needed, not +6. */ + fullname = gdReallocEx(fullname, strlen(fontsearchpath) + strlen(name) + 8); + if (!fullname) { + gdFree(fontlist); + gdFree(path); + return "could not alloc full path of font"; + } + /* if name is an absolute or relative pathname then test directly */ + if (GD_FT_IS_PATH(name)) { + sprintf(fullname, "%s", name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } + } + for (dir = gd_strtok_r(path, PATHSEPARATOR, &path_ptr); dir; + dir = gd_strtok_r(0, PATHSEPARATOR, &path_ptr)) { + if (strchr(name, '.')) { + sprintf(fullname, "%s/%s", dir, name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } else { + continue; + } + } + sprintf(fullname, "%s/%s.ttf", dir, name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } + sprintf(fullname, "%s/%s.pfa", dir, name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } + sprintf(fullname, "%s/%s.pfb", dir, name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } + sprintf(fullname, "%s/%s.dfont", dir, name); + if (GD_FT_ACCESS(fullname, R_OK) == 0) { + font_found++; + break; + } + } + + if (font_found) + break; + } + gdFree(path); + if (fontlist != NULL) { + gdFree(fontlist); + fontlist = NULL; + } + if (!font_found) { + gdFree(fullname); + return "Could not find/open font"; + } + + *fontpath = fullname; + return NULL; +} +#endif + +/** + * Function: gdFTUseFontConfig + * + * Enable or disable fontconfig by default. + * + * If GD is built without libfontconfig support, this function is a NOP. + * + * Parameters: + * flag - Zero to disable, nonzero to enable. + * + * See also: + * - + */ +BGD_DECLARE(int) gdFTUseFontConfig(int flag) +{ +#ifdef HAVE_LIBFONTCONFIG + fontConfigFlag = flag; + return 1; +#else + (void)flag; + return 0; +#endif /* HAVE_LIBFONTCONFIG */ +} diff --git a/ext/gd/libgd/gdfx.c b/ext/gd/libgd/gdfx.c new file mode 100644 index 000000000000..3acb0afcc113 --- /dev/null +++ b/ext/gd/libgd/gdfx.c @@ -0,0 +1,472 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "gd.h" +#include "gd_errors.h" +#include "gd_intern.h" +#include + +/* In tests this is sufficient to prevent obvious artifacts */ +#define MAG 4 + +#define PI 3.141592 +#define DEG2RAD(x) ((x) * PI / 180.) + +#define MAX4(x, y, z, w) ((MAX((x), (y))) > (MAX((z), (w))) ? (MAX((x), (y))) : (MAX((z), (w)))) +#define MIN4(x, y, z, w) ((MIN((x), (y))) < (MIN((z), (w))) ? (MIN((x), (y))) : (MIN((z), (w)))) + +#define MAXX(x) MAX4(x[0], x[2], x[4], x[6]) +#define MINX(x) MIN4(x[0], x[2], x[4], x[6]) +#define MAXY(x) MAX4(x[1], x[3], x[5], x[7]) +#define MINY(x) MIN4(x[1], x[3], x[5], x[7]) + +/** + * Function: gdImageStringFTCircle + * + * Draw text curved along the top and bottom of a circular area of an image. + * + * Parameters: + * im - The image to draw onto. + * cx - The x-coordinate of the center of the circular area. + * cy - The y-coordinate of the center of the circular area. + * radius - The radius of the circular area. + * textRadius - The height of each character; if textRadius is 1/2 of radius, + * characters extend halfway from the edge to the center. + * fillPortion - The percentage of the 180 degrees of the circular area + * assigned to each section of text, that is actually occupied + * by text. The value has to be in range 0.0 to 1.0, with useful + * values from about 0.4 to 0.9; 0.9 looks better than 1.0 which + * is rather crowded. + * font - The fontlist that is passed to . + * points - The point size, which functions as a hint. Although the size + * of the text is determined by radius, textRadius and + * fillPortion, a point size that 'hints' appropriately should be + * passed. If it's known that the text will be large, a large + * point size such as 24.0 should be passed to get the best + * results. + * top - The text to draw clockwise at the top of the circular area. + * bottom - The text to draw counterclockwise at the bottom of the + * circular area. + * fgcolor - The font color. + * + * Returns: + * NULL on success, or an error string on failure. + */ +BGD_DECLARE(char *) +gdImageStringFTCircle(gdImagePtr im, int cx, int cy, double radius, double textRadius, + double fillPortion, char *font, double points, char *top, char *bottom, + int fgcolor) +{ + char *err; + int w; + int brect[8]; + int sx1, sx2, sy1, sy2, sx, sy; + int x, y; + int fr, fg, fb, fa; + int ox, oy; + double prop; + gdImagePtr im1; + gdImagePtr im2; + gdImagePtr im3; + /* obtain brect so that we can size the image */ + err = gdImageStringFT((gdImagePtr)NULL, &brect[0], 0, font, points * MAG, 0, 0, 0, bottom); + if (err) { + return err; + } + sx1 = MAXX(brect) - MINX(brect) + 6; + sy1 = MAXY(brect) - MINY(brect) + 6; + err = gdImageStringFT((gdImagePtr)NULL, &brect[0], 0, font, points * MAG, 0, 0, 0, top); + if (err) { + return err; + } + sx2 = MAXX(brect) - MINX(brect) + 6; + sy2 = MAXY(brect) - MINY(brect) + 6; + /* Pad by 4 pixels to allow for slight errors + observed in the bounding box returned by freetype */ + if (sx1 > sx2) { + sx = sx1 * 2 + 4; + } else { + sx = sx2 * 2 + 4; + } + if (sy1 > sy2) { + sy = sy1; + } else { + sy = sy2; + } + im1 = gdImageCreateTrueColor(sx, sy); + if (!im1) { + return "could not create first image"; + } + err = gdImageStringFT(im1, 0, gdTrueColor(255, 255, 255), font, points * MAG, 0, + ((sx / 2) - sx1) / 2, points * MAG, bottom); + if (err) { + gdImageDestroy(im1); + return err; + } + /* We don't know the descent, which would be needed to do this + with the angle parameter. Instead, implement a simple + flip operation ourselves. */ + err = gdImageStringFT(im1, 0, gdTrueColor(255, 255, 255), font, points * MAG, 0, + sx / 2 + ((sx / 2) - sx2) / 2, points * MAG, top); + if (err) { + gdImageDestroy(im1); + return err; + } + /* Flip in place is tricky, be careful not to double-swap things */ + if (sy & 1) { + for (y = 0; (y <= (sy / 2)); y++) { + int xlimit = sx - 2; + if (y == (sy / 2)) { + /* If there is a "middle" row, be careful + not to swap twice! */ + xlimit -= (sx / 4); + } + for (x = (sx / 2) + 2; (x < xlimit); x++) { + int t; + int ox = sx - x + (sx / 2) - 1; + int oy = sy - y - 1; + t = im1->tpixels[oy][ox]; + im1->tpixels[oy][ox] = im1->tpixels[y][x]; + im1->tpixels[y][x] = t; + } + } + } else { + for (y = 0; (y < (sy / 2)); y++) { + int xlimit = sx - 2; + for (x = (sx / 2) + 2; (x < xlimit); x++) { + int t; + int ox = sx - x + (sx / 2) - 1; + int oy = sy - y - 1; + t = im1->tpixels[oy][ox]; + im1->tpixels[oy][ox] = im1->tpixels[y][x]; + im1->tpixels[y][x] = t; + } + } + } +#if STEP_PNGS + { + FILE *out = fopen("gdfx1.png", "wb"); + gdImagePng(im1, out); + fclose(out); + } +#endif /* STEP_PNGS */ + /* Resample taller; the exact proportions of the text depend on the + ratio of textRadius to radius, and the value of fillPortion */ + if (sx > sy * 10) { + w = sx; + } else { + w = sy * 10; + } + im2 = gdImageCreateTrueColor(w, w); + if (!im2) { + gdImageDestroy(im1); + return "could not create resampled image"; + } + prop = textRadius / radius; + gdImageCopyResampled(im2, im1, gdImageSX(im2) * (1.0 - fillPortion) / 4, sy * 10 * (1.0 - prop), + 0, 0, gdImageSX(im2) * fillPortion / 2, sy * 10 * prop, gdImageSX(im1) / 2, + gdImageSY(im1)); + gdImageCopyResampled(im2, im1, (gdImageSX(im2) / 2) + gdImageSX(im2) * (1.0 - fillPortion) / 4, + sy * 10 * (1.0 - prop), gdImageSX(im1) / 2, 0, + gdImageSX(im2) * fillPortion / 2, sy * 10 * prop, gdImageSX(im1) / 2, + gdImageSY(im1)); +#if STEP_PNGS + { + FILE *out = fopen("gdfx2.png", "wb"); + gdImagePng(im2, out); + fclose(out); + } +#endif /* STEP_PNGS */ + + gdImageDestroy(im1); + + /* Ready to produce a circle */ + im3 = gdImageSquareToCircle(im2, radius); + if (im3 == NULL) { + gdImageDestroy(im2); + return 0; + } + gdImageDestroy(im2); + /* Now blend im3 with the destination. Cheat a little. The + source (im3) is white-on-black, so we can use the + red component as a basis for alpha as long as we're + careful to shift off the extra bit and invert + (alpha ranges from 0 to 127 where 0 is OPAQUE). + Also be careful to allow for an alpha component + in the fgcolor parameter itself (gug!) */ + fr = gdTrueColorGetRed(fgcolor); + fg = gdTrueColorGetGreen(fgcolor); + fb = gdTrueColorGetBlue(fgcolor); + fa = gdTrueColorGetAlpha(fgcolor); + ox = cx - (im3->sx / 2); + oy = cy - (im3->sy / 2); + for (y = 0; (y < im3->sy); y++) { + for (x = 0; (x < im3->sx); x++) { + int a = gdTrueColorGetRed(im3->tpixels[y][x]) >> 1; + a *= (127 - fa); + a /= 127; + a = 127 - a; + gdImageSetPixel(im, x + ox, y + oy, gdTrueColorAlpha(fr, fg, fb, a)); + } + } + gdImageDestroy(im3); + return 0; +} + +#if GDFX_MAIN + +int main(int argc, char *argv[]) +{ + FILE *in; + FILE *out; + gdImagePtr im; + int radius; + /* Create an image of text on a circle, with an + alpha channel so that we can copy it onto a + background */ + in = fopen("eleanor.jpg", "rb"); + if (!in) { + im = gdImageCreateTrueColor(300, 300); + } else { + im = gdImageCreateFromJpeg(in); + fclose(in); + } + if (gdImageSX(im) < gdImageSY(im)) { + radius = gdImageSX(im) / 2; + } else { + radius = gdImageSY(im) / 2; + } + gdImageStringFTCircle(im, gdImageSX(im) / 2, gdImageSY(im) / 2, radius, radius / 2, 0.8, + "arial", 24, "top text", "bottom text", + gdTrueColorAlpha(240, 240, 255, 32)); + out = fopen("gdfx.png", "wb"); + if (!out) { + gd_error("Can't create gdfx.png\n"); + return 1; + } + gdImagePng(im, out); + fclose(out); + gdImageDestroy(im); + return 0; +} + +#endif /* GDFX_MAIN */ + +/* Note: don't change these */ +#define SUPER 2 +#define SUPERBITS1 1 +#define SUPERBITS2 2 + +/** + * Function: gdImageSquareToCircle + * + * Apply polar coordinate transformation to an image. + * + * The X axis of the original will be remapped to theta (angle) and the Y axis + * of the original will be remapped to rho (distance from center). + * + * Parameters: + * im - The image, which must be square, i.e. width == height. + * radius - The radius of the new image, i.e. width == height == radius * 2. + * + * Returns: + * The transformed image, or NULL on failure. + */ +BGD_DECLARE(gdImagePtr) +gdImageSquareToCircle(gdImagePtr im, int radius) +{ + int x, y; + double c; + gdImagePtr im2; + if (im->sx != im->sy) { + /* Source image must be square */ + return 0; + } + im2 = gdImageCreateTrueColor(radius * 2, radius * 2); + if (!im2) { + return 0; + } + /* Supersampling for a nicer result */ + c = (im2->sx / 2) * SUPER; + for (y = 0; (y < im2->sy * SUPER); y++) { + for (x = 0; (x < im2->sx * SUPER); x++) { + double rho = sqrt((x - c) * (x - c) + (y - c) * (y - c)); + int pix; + int cpix; + double theta; + double ox; + double oy; + int red, green, blue, alpha; + if (rho > c) { + continue; + } + theta = atan2(x - c, y - c) + PI / 2; + if (theta < 0) { + theta += 2 * PI; + } + /* Undo supersampling */ + oy = (rho * im->sx) / (im2->sx * SUPER / 2); + ox = theta * im->sx / (3.141592653 * 2); + pix = gdImageGetPixel(im, ox, oy); + cpix = im2->tpixels[y >> SUPERBITS1][x >> SUPERBITS1]; + red = (gdImageRed(im, pix) >> SUPERBITS2) + gdTrueColorGetRed(cpix); + green = (gdImageGreen(im, pix) >> SUPERBITS2) + gdTrueColorGetGreen(cpix); + blue = (gdImageBlue(im, pix) >> SUPERBITS2) + gdTrueColorGetBlue(cpix); + alpha = (gdImageAlpha(im, pix) >> SUPERBITS2) + gdTrueColorGetAlpha(cpix); + im2->tpixels[y >> SUPERBITS1][x >> SUPERBITS1] = + gdTrueColorAlpha(red, green, blue, alpha); + } + } + /* Restore full dynamic range, 0-63 yields 0-252. Replication of + first 2 bits in last 2 bits has the desired effect. Note + slightly different arithmetic for alpha which is 7-bit. + NOTE: only correct for SUPER == 2 */ + for (y = 0; (y < im2->sy); y++) { + for (x = 0; (x < im2->sx); x++) { + /* Copy first 2 bits to last 2 bits, matching the + dynamic range of the original cheaply */ + int cpix = im2->tpixels[y][x]; + + im2->tpixels[y][x] = gdTrueColorAlpha( + (gdTrueColorGetRed(cpix) & 0xFC) + ((gdTrueColorGetRed(cpix) & 0xC0) >> 6), + (gdTrueColorGetGreen(cpix) & 0xFC) + ((gdTrueColorGetGreen(cpix) & 0xC0) >> 6), + (gdTrueColorGetBlue(cpix) & 0xFC) + ((gdTrueColorGetBlue(cpix) & 0xC0) >> 6), + (gdTrueColorGetAlpha(cpix) & 0x7C) + ((gdTrueColorGetAlpha(cpix) & 0x60) >> 6)); + } + } + return im2; +} + +/* 2.0.16: Called by gdImageSharpen to avoid excessive code repetition + Added on 2003-11-19 by + Paul Troughton (paultroughtonieeeorg) + Given filter coefficents and colours of three adjacent pixels, +returns new colour for centre pixel +*/ + +static int gdImageSubSharpen(int pc, int c, int nc, float inner_coeff, float outer_coeff) +{ + float red, green, blue, alpha; + + red = inner_coeff * gdTrueColorGetRed(c) + + outer_coeff * (gdTrueColorGetRed(pc) + gdTrueColorGetRed(nc)); + green = inner_coeff * gdTrueColorGetGreen(c) + + outer_coeff * (gdTrueColorGetGreen(pc) + gdTrueColorGetGreen(nc)); + blue = inner_coeff * gdTrueColorGetBlue(c) + + outer_coeff * (gdTrueColorGetBlue(pc) + gdTrueColorGetBlue(nc)); + alpha = gdTrueColorGetAlpha(c); + + /* Clamping, as can overshoot bounds in either direction */ + if (red > 255.0f) { + red = 255.0f; + } + if (green > 255.0f) { + green = 255.0f; + } + if (blue > 255.0f) { + blue = 255.0f; + } + if (red < 0.0f) { + red = 0.0f; + } + if (green < 0.0f) { + green = 0.0f; + } + if (blue < 0.0f) { + blue = 0.0f; + } + + return gdTrueColorAlpha((int)red, (int)green, (int)blue, (int)alpha); +} + +/** + * Function: gdImageSharpen + * + * Sharpen an image. + * + * Uses a simple 3x3 convolution kernel and makes use of separability. + * It's faster, but less flexible, than full-blown unsharp masking. + * Silently does nothing to non-truecolor images and for pct<0, as it's not a + * useful blurring function. + * + * Parameters: + * pct - The sharpening percentage, which can be greater than 100. + * + * Author: + * Paul Troughton (paultroughtonieeeorg) + */ +BGD_DECLARE(void) +gdImageSharpen(gdImagePtr im, int pct) +{ + int x, y; + int sx, sy; + float inner_coeff, outer_coeff; + + sx = im->sx; + sy = im->sy; + + /* Must sum to 1 to avoid overall change in brightness. + * Scaling chosen so that pct=100 gives 1-D filter [-1 6 -1]/4, + * resulting in a 2-D filter [1 -6 1; -6 36 -6; 1 -6 1]/16, + * which gives noticeable, but not excessive, sharpening + */ + + outer_coeff = -pct / 400.0; + inner_coeff = 1 - 2 * outer_coeff; + + /* Don't try to do anything with non-truecolor images, as + pointless, + * nor for pct<=0, as small kernel size leads to nasty + artefacts when blurring + */ + if ((im->trueColor) && (pct > 0)) { + + /* First pass, 1-D convolution column-wise */ + for (x = 0; x < sx; x++) { + + /* pc is colour of previous pixel; c of the + current pixel and nc of the next */ + int pc, c, nc; + + /* Replicate edge pixel at image boundary */ + pc = gdImageGetPixel(im, x, 0); + + /* Stop looping before last pixel to avoid + conditional within loop */ + for (y = 0; y < sy - 1; y++) { + + c = gdImageGetPixel(im, x, y); + + nc = gdImageGetTrueColorPixel(im, x, y + 1); + + /* Update centre pixel to new colour */ + gdImageSetPixel(im, x, y, gdImageSubSharpen(pc, c, nc, inner_coeff, outer_coeff)); + + /* Save original colour of current + pixel for next time round */ + pc = c; + } + + /* Deal with last pixel, replicating current + pixel at image boundary */ + c = gdImageGetPixel(im, x, y); + gdImageSetPixel(im, x, y, gdImageSubSharpen(pc, c, c, inner_coeff, outer_coeff)); + } + + /* Second pass, 1-D convolution row-wise */ + for (y = 0; y < sy; y++) { + int pc, c; + pc = gdImageGetPixel(im, 0, y); + for (x = 0; x < sx - 1; x++) { + int c, nc; + c = gdImageGetPixel(im, x, y); + nc = gdImageGetTrueColorPixel(im, x + 1, y); + gdImageSetPixel(im, x, y, gdImageSubSharpen(pc, c, nc, inner_coeff, outer_coeff)); + pc = c; + } + c = gdImageGetPixel(im, x, y); + gdImageSetPixel(im, x, y, gdImageSubSharpen(pc, c, c, inner_coeff, outer_coeff)); + } + } +} diff --git a/ext/gd/libgd/gdfx.h b/ext/gd/libgd/gdfx.h new file mode 100644 index 000000000000..0de97cabf37c --- /dev/null +++ b/ext/gd/libgd/gdfx.h @@ -0,0 +1,21 @@ +#ifndef GDFX_H +#define GDFX_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +BGD_DECLARE(gdImagePtr) gdImageSquareToCircle(gdImagePtr im, int radius); + +BGD_DECLARE(char *) +gdImageStringFTCircle(gdImagePtr im, int cx, int cy, double radius, double textRadius, + double fillPortion, char *font, double points, char *top, char *bottom, + int fgcolor); + +BGD_DECLARE(void) gdImageSharpen(gdImagePtr im, int pct); + +#ifdef __cplusplus +} +#endif + +#endif /* GDFX_H */ diff --git a/ext/gd/libgd/gdhelpers.c b/ext/gd/libgd/gdhelpers.c index 44b79ac77f32..121123321ddc 100644 --- a/ext/gd/libgd/gdhelpers.c +++ b/ext/gd/libgd/gdhelpers.c @@ -4,71 +4,71 @@ #include "gd.h" #include "gdhelpers.h" + +#ifdef HAVE_LIBPNG +#include + +#endif #include #include /* TBB: gd_strtok_r is not portable; provide an implementation */ -#define SEP_TEST (separators[*((unsigned char *) s)]) +#define SEP_TEST (separators[*((unsigned char *)s)]) -char * -gd_strtok_r (char *s, char *sep, char **state) +char *gd_strtok_r(char *s, const char *sep, char **state) { - char separators[256]; - char *result = 0; - memset (separators, 0, sizeof (separators)); - while (*sep) - { - separators[*((unsigned char *) sep)] = 1; - sep++; - } - if (!s) - { - /* Pick up where we left off */ - s = *state; + char separators[256]; + char *result = 0; + memset(separators, 0, sizeof(separators)); + while (*sep) { + separators[*((const unsigned char *)sep)] = 1; + sep++; } - /* 1. EOS */ - if (!(*s)) - { - *state = s; - return 0; + if (!s) { + /* Pick up where we left off */ + s = *state; } - /* 2. Leading separators, if any */ - if (SEP_TEST) - { - do - { - s++; - } - while (SEP_TEST); - /* 2a. EOS after separators only */ - if (!(*s)) - { - *state = s; - return 0; - } + /* 1. EOS */ + if (!(*s)) { + *state = s; + return 0; } - /* 3. A token */ - result = s; - do - { - /* 3a. Token at end of string */ - if (!(*s)) - { - *state = s; - return result; - } - s++; + /* 2. Leading separators, if any */ + if (SEP_TEST) { + do { + s++; + } while (SEP_TEST); + /* 2a. EOS after separators only */ + if (!(*s)) { + *state = s; + return 0; + } } - while (!SEP_TEST); - /* 4. Terminate token and skip trailing separators */ - *s = '\0'; - do - { - s++; - } - while (SEP_TEST); - /* 5. Return token */ - *state = s; - return result; + /* 3. A token */ + result = s; + do { + /* 3a. Token at end of string */ + if (!(*s)) { + *state = s; + return result; + } + s++; + } while (!SEP_TEST); + /* 4. Terminate token and skip trailing separators */ + *s = '\0'; + do { + s++; + } while (SEP_TEST); + /* 5. Return token */ + *state = s; + return result; +} + +void *gdReallocEx(void *ptr, size_t size) +{ + void *newPtr = gdRealloc(ptr, size); + if (!newPtr && ptr) + gdFree(ptr); + return newPtr; } diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index afb45f0e67de..931c5fb83a73 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -1,32 +1,41 @@ #ifndef GDHELPERS_H #define GDHELPERS_H 1 -#include #include "php.h" +#include /* TBB: strtok_r is not universal; provide an implementation of it. */ -extern char *gd_strtok_r(char *s, char *sep, char **state); +char *gd_strtok_r(char *s, const char *sep, char **state); /* These functions wrap memory management. gdFree is - in gd.h, where callers can utilize it to correctly - free memory allocated by these functions with the - right version of free(). */ -#define gdCalloc(nmemb, size) ecalloc(nmemb, size) -#define gdMalloc(size) emalloc(size) -#define gdRealloc(ptr, size) erealloc(ptr, size) -#define gdEstrdup(ptr) estrdup(ptr) -#define gdFree(ptr) efree(ptr) -#define gdPMalloc(ptr) pemalloc(ptr, 1) -#define gdPFree(ptr) pefree(ptr, 1) -#define gdPEstrdup(ptr) pestrdup(ptr, 1) + in gd.h, where callers can utilize it to correctly + free memory allocated by these functions with the + right version of free(). */ +#define gdCalloc(nmemb, size) ecalloc((nmemb), (size)) +#define gdMalloc(size) emalloc(size) +#define gdRealloc(ptr, size) erealloc(ptr, size) +#define gdEstrdup(ptr) estrdup(ptr) +#define gdFree(ptr) efree(ptr) +#define gdPMalloc(ptr) pemalloc(ptr, 1) +#define gdPFree(ptr) pefree(ptr, 1) +#define gdPEstrdup(ptr) pestrdup(ptr, 1) + +/* The extended version of gdReallocEx will free *ptr if the + * realloc fails. */ +void *gdReallocEx(void *ptr, size_t size); + +/* Internal deterministic allocation hook used by the vector2d failure tests. */ +void *gdVector2dMalloc(size_t size); +void gdVector2dTestSetAllocationFailureCountdown(int countdown); /* Returns nonzero if multiplying the two quantities will - result in integer overflow. Also returns nonzero if - either quantity is negative. By Phil Knirsch based on - netpbm fixes by Alan Cox. */ + result in integer overflow. Also returns nonzero if + either quantity is negative. By Phil Knirsch based on + netpbm fixes by Alan Cox. */ int overflow2(int a, int b); +int overflowMul3(int a, int b, int c); #ifdef ZTS #define gdMutexDeclare(x) MUTEX_T x @@ -42,10 +51,9 @@ int overflow2(int a, int b); #define gdMutexUnlock(x) #endif -#define DPCM2DPI(dpcm) (unsigned int)((dpcm)*2.54 + 0.5) -#define DPM2DPI(dpm) (unsigned int)((dpm)*0.0254 + 0.5) -#define DPI2DPCM(dpi) (unsigned int)((dpi)/2.54 + 0.5) -#define DPI2DPM(dpi) (unsigned int)((dpi)/0.0254 + 0.5) +#define DPCM2DPI(dpcm) (unsigned int)((dpcm) * 2.54 + 0.5) +#define DPM2DPI(dpm) (unsigned int)((dpm) * 0.0254 + 0.5) +#define DPI2DPCM(dpi) (unsigned int)((dpi) / 2.54 + 0.5) +#define DPI2DPM(dpi) (unsigned int)((dpi) / 0.0254 + 0.5) #endif /* GDHELPERS_H */ - diff --git a/ext/gd/libgd/gdkanji.c b/ext/gd/libgd/gdkanji.c index ef769f89badd..1c539310cee5 100644 --- a/ext/gd/libgd/gdkanji.c +++ b/ext/gd/libgd/gdkanji.c @@ -2,25 +2,62 @@ /* gdkanji.c (Kanji code converter) */ /* written by Masahito Yamaga (ma@yama-ga.com) */ -#include -#include -#include #include "gd.h" +#include "gd_errors.h" #include "gdhelpers.h" - +#include #include +#include +#include +#include #if defined(HAVE_ICONV_H) || defined(HAVE_ICONV) -#include #include +#include #endif #if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV) #define HAVE_ICONV 1 #endif +#ifndef HAVE_ICONV_T_DEF +typedef void *iconv_t; +#endif + +#ifndef HAVE_ICONV +#define ICONV_CONST /**/ +iconv_t iconv_open(const char *, const char *); +size_t iconv(iconv_t, ICONV_CONST char **, size_t *, char **, size_t *); +int iconv_close(iconv_t); + +iconv_t iconv_open(const char *tocode, const char *fromcode) +{ + (void)tocode; + (void)fromcode; + return (iconv_t)(-1); +} + +size_t iconv(iconv_t cd, ICONV_CONST char **inbuf, size_t *inbytesleft, char **outbuf, + size_t *outbytesleft) +{ + (void)cd; + (void)inbuf; + (void)inbytesleft; + (void)outbuf; + (void)outbytesleft; + return 0; +} + +int iconv_close(iconv_t cd) +{ + (void)cd; + return 0; +} + +#endif /* !HAVE_ICONV */ #define LIBNAME "any2eucjp()" -#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS) +#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || \ + defined(MSDOS) #ifndef SJISPRE #define SJISPRE 1 #endif @@ -33,7 +70,7 @@ #undef FALSE #endif -#define TRUE 1 +#define TRUE 1 #define FALSE 0 #define NEW 1 @@ -47,194 +84,144 @@ #define NEWJISSTR "JIS7" #define OLDJISSTR "jis" -#define EUCSTR "eucJP" -#define SJISSTR "SJIS" +#define EUCSTR "eucJP" +#define SJISSTR "SJIS" #define ESC 27 #define SS2 142 -static void -debug (const char *format,...) -{ -#ifdef DEBUG - va_list args; - - va_start (args, format); - fprintf (stdout, "%s: ", LIBNAME); - vfprintf (stdout, format, args); - fprintf (stdout, "\n"); - va_end (args); -#endif -} +/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */ -static void -error (const char *format,...) +static int DetectKanjiCode(const unsigned char *str) { - va_list args; - char *tmp; - - va_start(args, format); - vspprintf(&tmp, 0, format, args); - va_end(args); - php_error_docref(NULL, E_WARNING, "%s: %s", LIBNAME, tmp); - efree(tmp); -} + static int whatcode = ASCII; + int oldcode = ASCII; + int c, i; + char *lang = NULL; -/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */ + c = '\1'; + i = 0; -static int -DetectKanjiCode (unsigned char *str) -{ - static int whatcode = ASCII; - int oldcode = ASCII; - int c, i; - char *lang = NULL; - - c = '\1'; - i = 0; - - if (whatcode != EUCORSJIS && whatcode != ASCII) - { - oldcode = whatcode; - whatcode = ASCII; + if (whatcode != EUCORSJIS && whatcode != ASCII) { + oldcode = whatcode; + whatcode = ASCII; } - while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0') - { - if ((c = str[i++]) != '\0') - { - if (c == ESC) - { - c = str[i++]; - if (c == '$') - { - c = str[i++]; - if (c == 'B') - whatcode = NEW; - else if (c == '@') - whatcode = OLD; - } - else if (c == '(') - { - c = str[i++]; - if (c == 'I') - whatcode = ESCI; - } - else if (c == 'K') - whatcode = NEC; - } - else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159)) - whatcode = SJIS; - else if (c == SS2) - { - c = str[i++]; - if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252)) - whatcode = SJIS; - else if (c >= 161 && c <= 223) - whatcode = EUCORSJIS; - } - else if (c >= 161 && c <= 223) - { - c = str[i++]; - if (c >= 240 && c <= 254) - whatcode = EUC; - else if (c >= 161 && c <= 223) - whatcode = EUCORSJIS; - else if (c >= 224 && c <= 239) - { - whatcode = EUCORSJIS; - while (c >= 64 && whatcode == EUCORSJIS) - { - if (c >= 129) - { - if (c <= 141 || (c >= 143 && c <= 159)) - whatcode = SJIS; - else if (c >= 253 && c <= 254) - whatcode = EUC; - } - c = str[i++]; - } - } - else if (c <= 159) - whatcode = SJIS; - } - else if (c >= 240 && c <= 254) - whatcode = EUC; - else if (c >= 224 && c <= 239) - { - c = str[i++]; - if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160)) - whatcode = SJIS; - else if (c >= 253 && c <= 254) - whatcode = EUC; - else if (c >= 161 && c <= 252) - whatcode = EUCORSJIS; - } - } + while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0') { + if ((c = str[i++]) != '\0') { + if (c == ESC) { + c = str[i++]; + if (c == '$') { + c = str[i++]; + if (c == 'B') + whatcode = NEW; + else if (c == '@') + whatcode = OLD; + } else if (c == '(') { + c = str[i++]; + if (c == 'I') + whatcode = ESCI; + } else if (c == 'K') + whatcode = NEC; + } else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159)) + whatcode = SJIS; + else if (c == SS2) { + c = str[i++]; + if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252)) + whatcode = SJIS; + else if (c >= 161 && c <= 223) + whatcode = EUCORSJIS; + } else if (c >= 161 && c <= 223) { + c = str[i++]; + if (c >= 240 && c <= 254) + whatcode = EUC; + else if (c >= 161 && c <= 223) + whatcode = EUCORSJIS; + else if (c >= 224 && c <= 239) { + whatcode = EUCORSJIS; + while (c >= 64 && whatcode == EUCORSJIS) { + if (c >= 129) { + if (c <= 141 || (c >= 143 && c <= 159)) + whatcode = SJIS; + else if (c >= 253 && c <= 254) + whatcode = EUC; + } + c = str[i++]; + } + } else if (c <= 159) + whatcode = SJIS; + } else if (c >= 240 && c <= 254) + whatcode = EUC; + else if (c >= 224 && c <= 239) { + c = str[i++]; + if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160)) + whatcode = SJIS; + else if (c >= 253 && c <= 254) + whatcode = EUC; + else if (c >= 161 && c <= 252) + whatcode = EUCORSJIS; + } + } } #ifdef DEBUG - if (whatcode == ASCII) - debug ("Kanji code not included."); - else if (whatcode == EUCORSJIS) - debug ("Kanji code not detected."); - else - debug ("Kanji code detected at %d byte.", i); + if (whatcode == ASCII) + gd_error_ex(GD_DEBUG, "Kanji code not included."); + else if (whatcode == EUCORSJIS) + gd_error_ex(GD_DEBUG, "Kanji code not detected."); + else + gd_error_ex(GD_DEBUG, "Kanji code detected at %d byte.", i); #endif - if (whatcode == EUCORSJIS && oldcode != ASCII) - whatcode = oldcode; - - if (whatcode == EUCORSJIS) - { - if (getenv ("LC_ALL")) - lang = getenv ("LC_ALL"); - else if (getenv ("LC_CTYPE")) - lang = getenv ("LC_CTYPE"); - else if (getenv ("LANG")) - lang = getenv ("LANG"); - - if (lang) - { - if (strcmp (lang, "ja_JP.SJIS") == 0 || + if (whatcode == EUCORSJIS && oldcode != ASCII) + whatcode = oldcode; + + if (whatcode == EUCORSJIS) { + if (getenv("LC_ALL")) + lang = getenv("LC_ALL"); + else if (getenv("LC_CTYPE")) + lang = getenv("LC_CTYPE"); + else if (getenv("LANG")) + lang = getenv("LANG"); + + if (lang) { + if (strcmp(lang, "ja_JP.SJIS") == 0 || #ifdef hpux - strcmp (lang, "japanese") == 0 || + strcmp(lang, "japanese") == 0 || #endif - strcmp (lang, "ja_JP.mscode") == 0 || - strcmp (lang, "ja_JP.PCK") == 0) - whatcode = SJIS; - else if (strncmp (lang, "ja", 2) == 0) + strcmp(lang, "ja_JP.mscode") == 0 || strcmp(lang, "ja_JP.PCK") == 0) + whatcode = SJIS; + else if (strncmp(lang, "ja", 2) == 0) #ifdef SJISPRE - whatcode = SJIS; + whatcode = SJIS; #else - whatcode = EUC; + whatcode = EUC; #endif - } + } } - if (whatcode == EUCORSJIS) + if (whatcode == EUCORSJIS) #ifdef SJISPRE - whatcode = SJIS; + whatcode = SJIS; #else - whatcode = EUC; + whatcode = EUC; #endif - return whatcode; + return whatcode; } /* SJIStoJIS() is sjis2jis() by Ken Lunde. */ -static void -SJIStoJIS (int *p1, int *p2) +static void SJIStoJIS(int *p1, int *p2) { - register unsigned char c1 = *p1; - register unsigned char c2 = *p2; - register int adjust = c2 < 159; - register int rowOffset = c1 < 160 ? 112 : 176; - register int cellOffset = adjust ? (31 + (c2 > 127)) : 126; - - *p1 = ((c1 - rowOffset) << 1) - adjust; - *p2 -= cellOffset; + register unsigned char c1 = *p1; + register unsigned char c2 = *p2; + register int adjust = c2 < 159; + register int rowOffset = c1 < 160 ? 112 : 176; + register int cellOffset = adjust ? (31 + (c2 > 127)) : 126; + + *p1 = ((c1 - rowOffset) << 1) - adjust; + *p2 -= cellOffset; } /* han2zen() was derived from han2zen() written by Ken Lunde. */ @@ -242,340 +229,250 @@ SJIStoJIS (int *p1, int *p2) #define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179)) #define IS_HANDAKU(c) (c >= 202 && c <= 206) -static void -han2zen (int *p1, int *p2) +static void han2zen(int *p1, int *p2) { - int c = *p1; - int daku = FALSE; - int handaku = FALSE; - int mtable[][2] = - { - {129, 66}, - {129, 117}, - {129, 118}, - {129, 65}, - {129, 69}, - {131, 146}, - {131, 64}, - {131, 66}, - {131, 68}, - {131, 70}, - {131, 72}, - {131, 131}, - {131, 133}, - {131, 135}, - {131, 98}, - {129, 91}, - {131, 65}, - {131, 67}, - {131, 69}, - {131, 71}, - {131, 73}, - {131, 74}, - {131, 76}, - {131, 78}, - {131, 80}, - {131, 82}, - {131, 84}, - {131, 86}, - {131, 88}, - {131, 90}, - {131, 92}, - {131, 94}, - {131, 96}, - {131, 99}, - {131, 101}, - {131, 103}, - {131, 105}, - {131, 106}, - {131, 107}, - {131, 108}, - {131, 109}, - {131, 110}, - {131, 113}, - {131, 116}, - {131, 119}, - {131, 122}, - {131, 125}, - {131, 126}, - {131, 128}, - {131, 129}, - {131, 130}, - {131, 132}, - {131, 134}, - {131, 136}, - {131, 137}, - {131, 138}, - {131, 139}, - {131, 140}, - {131, 141}, - {131, 143}, - {131, 147}, - {129, 74}, - {129, 75} - }; - - if (*p2 == 222 && IS_DAKU (*p1)) - daku = TRUE; /* Daku-ten */ - else if (*p2 == 223 && IS_HANDAKU (*p1)) - handaku = TRUE; /* Han-daku-ten */ - - *p1 = mtable[c - 161][0]; - *p2 = mtable[c - 161][1]; - - if (daku) - { - if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122)) - (*p2)++; - else if (*p2 == 131 || *p2 == 69) - *p2 = 148; - } - else if (handaku && *p2 >= 110 && *p2 <= 122) - (*p2) += 2; + int c = *p1; + int daku = FALSE; + int handaku = FALSE; + int mtable[][2] = { + {129, 66}, {129, 117}, {129, 118}, {129, 65}, {129, 69}, {131, 146}, {131, 64}, + {131, 66}, {131, 68}, {131, 70}, {131, 72}, {131, 131}, {131, 133}, {131, 135}, + {131, 98}, {129, 91}, {131, 65}, {131, 67}, {131, 69}, {131, 71}, {131, 73}, + {131, 74}, {131, 76}, {131, 78}, {131, 80}, {131, 82}, {131, 84}, {131, 86}, + {131, 88}, {131, 90}, {131, 92}, {131, 94}, {131, 96}, {131, 99}, {131, 101}, + {131, 103}, {131, 105}, {131, 106}, {131, 107}, {131, 108}, {131, 109}, {131, 110}, + {131, 113}, {131, 116}, {131, 119}, {131, 122}, {131, 125}, {131, 126}, {131, 128}, + {131, 129}, {131, 130}, {131, 132}, {131, 134}, {131, 136}, {131, 137}, {131, 138}, + {131, 139}, {131, 140}, {131, 141}, {131, 143}, {131, 147}, {129, 74}, {129, 75}}; + + if (*p2 == 222 && IS_DAKU(*p1)) + daku = TRUE; /* Daku-ten */ + else if (*p2 == 223 && IS_HANDAKU(*p1)) + handaku = TRUE; /* Han-daku-ten */ + + *p1 = mtable[c - 161][0]; + *p2 = mtable[c - 161][1]; + + if (daku) { + if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122)) + (*p2)++; + else if (*p2 == 131 || *p2 == 69) + *p2 = 148; + } else if (handaku && *p2 >= 110 && *p2 <= 122) + (*p2) += 2; } /* Recast strcpy to handle unsigned chars used below. */ -#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B))) - -static void -do_convert (unsigned char *to, unsigned char *from, const char *code) +#define ustrcpy(A, B) (strcpy((char *)(A), (const char *)(B))) +#define ustrncpy(A, B, maxsize) (strncpy((char *)(A), (const char *)(B), maxsize)) +static void do_convert(unsigned char **to, const unsigned char **from, const char *code) { #ifdef HAVE_ICONV - iconv_t cd; - size_t from_len, to_len; - - if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1) - { - error ("iconv_open() error"); - if (errno == EINVAL) - error ("invalid code specification: \"%s\" or \"%s\"", - EUCSTR, code); - strcpy ((char *) to, (const char *) from); - return; + iconv_t cd; + size_t from_len, to_len; + + if ((cd = iconv_open(EUCSTR, code)) == (iconv_t)-1) { + gd_error("iconv_open() error"); + if (errno == EINVAL) + gd_error("invalid code specification: \"%s\" or \"%s\"", EUCSTR, code); + ustrcpy(*to, *from); + return; } - from_len = strlen ((const char *) from) + 1; - to_len = BUFSIZ; - - if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1) - { - if (errno == EINVAL) - error ("invalid end of input string"); - else if (errno == EILSEQ) - error ("invalid code in input string"); - else if (errno == E2BIG) - error ("output buffer overflow at do_convert()"); - else - error ("something happen"); - strcpy ((char *) to, (const char *) from); - if (iconv_close (cd) != 0) - error ("iconv_close() error"); - return; + from_len = strlen((const char *)*from) + 1; + to_len = BUFSIZ; + + if ((int)(iconv(cd, (char **)from, &from_len, (char **)to, &to_len)) == -1) { + if (errno == EINVAL) + gd_error("invalid end of input string"); + else if (errno == EILSEQ) + gd_error("invalid code in input string"); + else if (errno == E2BIG) + gd_error("output buffer overflow at do_convert()"); + else + gd_error("something happen"); + ustrcpy(*to, *from); + if (iconv_close(cd) != 0) + gd_error("iconv_close() error"); + return; } - if (iconv_close (cd) != 0) - { - error ("iconv_close() error"); - } + if (iconv_close(cd) != 0) + gd_error("iconv_close() error"); #else - int p1, p2, i, j; - int jisx0208 = FALSE; - int hankaku = FALSE; - - j = 0; - if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0) - { - for (i = 0; from[i] != '\0' && j < BUFSIZ; i++) - { - if (from[i] == ESC) - { - i++; - if (from[i] == '$') - { - jisx0208 = TRUE; - hankaku = FALSE; - i++; - } - else if (from[i] == '(') - { - jisx0208 = FALSE; - i++; - if (from[i] == 'I') /* Hankaku Kana */ - hankaku = TRUE; - else - hankaku = FALSE; - } - } - else - { - if (jisx0208) - to[j++] = from[i] + 128; - else if (hankaku) - { - to[j++] = SS2; - to[j++] = from[i] + 128; - } - else - to[j++] = from[i]; - } - } - } - else if (strcmp (code, SJISSTR) == 0) - { - for (i = 0; from[i] != '\0' && j < BUFSIZ; i++) - { - p1 = from[i]; - if (p1 < 127) - to[j++] = p1; - else if ((p1 >= 161) && (p1 <= 223)) - { /* Hankaku Kana */ - to[j++] = SS2; - to[j++] = p1; - } - else - { - p2 = from[++i]; - SJIStoJIS (&p1, &p2); - to[j++] = p1 + 128; - to[j++] = p2 + 128; - } - } - } - else - { - error ("invalid code specification: \"%s\"", code); - return; + int p1, p2, i, j; + int jisx0208 = FALSE; + int hankaku = FALSE; + unsigned char *to_buf = *to; + const unsigned char *from_buf = *from; + + j = 0; + if (strcmp(code, NEWJISSTR) == 0 || strcmp(code, OLDJISSTR) == 0) { + for (i = 0; from_buf[i] != '\0' && j < BUFSIZ; i++) { + if (from_buf[i] == ESC) { + i++; + if (from_buf[i] == '$') { + jisx0208 = TRUE; + hankaku = FALSE; + i++; + } else if (from_buf[i] == '(') { + jisx0208 = FALSE; + i++; + if (from_buf[i] == 'I') + hankaku = TRUE; + else + hankaku = FALSE; + } + } else { + if (jisx0208) + to_buf[j++] = from_buf[i] + 128; + else if (hankaku) { + to_buf[j++] = SS2; + to_buf[j++] = from_buf[i] + 128; + } else + to_buf[j++] = from_buf[i]; + } + } + } else if (strcmp(code, SJISSTR) == 0) { + for (i = 0; from_buf[i] != '\0' && j < BUFSIZ; i++) { + p1 = from_buf[i]; + if (p1 < 127) + to_buf[j++] = p1; + else if ((p1 >= 161) && (p1 <= 223)) { + to_buf[j++] = SS2; + to_buf[j++] = p1; + } else { + p2 = from_buf[++i]; + SJIStoJIS(&p1, &p2); + to_buf[j++] = p1 + 128; + to_buf[j++] = p2 + 128; + } + } + } else { + gd_error("invalid code specification: \"%s\"", code); + return; } - if (j >= BUFSIZ) - { - error ("output buffer overflow at do_convert()"); - ustrcpy (to, from); - } - else - to[j] = '\0'; -#endif /* HAVE_ICONV */ + if (j >= BUFSIZ) { + gd_error("output buffer overflow at do_convert()"); + ustrcpy(*to, *from); + } else + to_buf[j] = '\0'; +#endif } -static int -do_check_and_conv (unsigned char *to, unsigned char *from) +static int do_check_and_conv(unsigned char *to, const unsigned char *from) { - static unsigned char tmp[BUFSIZ]; - int p1, p2, i, j; - int kanji = TRUE; + static unsigned char tmp[BUFSIZ]; + unsigned char *tmp_p = &tmp[0]; + int p1, p2, i, j; + int kanji = TRUE; + int copy_string = FALSE; - switch (DetectKanjiCode (from)) - { + switch (DetectKanjiCode(from)) { case NEW: - debug ("Kanji code is New JIS."); - do_convert (tmp, from, NEWJISSTR); - break; + gd_error_ex(GD_DEBUG, "Kanji code is New JIS."); + do_convert(&tmp_p, &from, NEWJISSTR); + break; case OLD: - debug ("Kanji code is Old JIS."); - do_convert (tmp, from, OLDJISSTR); - break; + gd_error_ex(GD_DEBUG, "Kanji code is Old JIS."); + do_convert(&tmp_p, &from, OLDJISSTR); + break; case ESCI: - debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I."); - do_convert (tmp, from, NEWJISSTR); - break; + gd_error_ex(GD_DEBUG, "This string includes Hankaku-Kana (jisx0201) " + "escape sequence [ESC] + ( + I."); + do_convert(&tmp_p, &from, NEWJISSTR); + break; case NEC: - debug ("Kanji code is NEC Kanji."); - error ("cannot convert NEC Kanji."); - ustrcpy (tmp, from); - kanji = FALSE; - break; + gd_error_ex(GD_DEBUG, "Kanji code is NEC Kanji."); + gd_error("cannot convert NEC Kanji."); + copy_string = TRUE; + kanji = FALSE; + break; case EUC: - debug ("Kanji code is EUC."); - ustrcpy (tmp, from); - break; + gd_error_ex(GD_DEBUG, "Kanji code is EUC."); + copy_string = TRUE; + break; case SJIS: - debug ("Kanji code is SJIS."); - do_convert (tmp, from, SJISSTR); - break; + gd_error_ex(GD_DEBUG, "Kanji code is SJIS."); + do_convert(&tmp_p, &from, SJISSTR); + break; case EUCORSJIS: - debug ("Kanji code is EUC or SJIS."); - ustrcpy (tmp, from); - kanji = FALSE; - break; + gd_error_ex(GD_DEBUG, "Kanji code is EUC or SJIS."); + copy_string = TRUE; + kanji = FALSE; + break; case ASCII: - debug ("This is ASCII string."); - ustrcpy (tmp, from); - kanji = FALSE; - break; + gd_error_ex(GD_DEBUG, "This is ASCII string."); + copy_string = TRUE; + kanji = FALSE; + break; default: - debug ("This string includes unknown code."); - ustrcpy (tmp, from); - kanji = FALSE; - break; + gd_error_ex(GD_DEBUG, "This string includes unknown code."); + copy_string = TRUE; + kanji = FALSE; + break; } - /* Hankaku Kana ---> Zenkaku Kana */ - if (kanji) - { - j = 0; - for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++) - { - if (tmp[i] == SS2) - { - p1 = tmp[++i]; - if (tmp[i + 1] == SS2) - { - p2 = tmp[i + 2]; - if (p2 == 222 || p2 == 223) - i += 2; - else - p2 = 0; - } - else - p2 = 0; - han2zen (&p1, &p2); - SJIStoJIS (&p1, &p2); - to[j++] = p1 + 128; - to[j++] = p2 + 128; - } - else - to[j++] = tmp[i]; - } - - if (j >= BUFSIZ) - { - error ("output buffer overflow at Hankaku --> Zenkaku"); - ustrcpy (to, tmp); - } - else - to[j] = '\0'; + if (copy_string) { + ustrncpy(tmp, from, BUFSIZ); + tmp[BUFSIZ - 1] = '\0'; } - else - ustrcpy (to, tmp); - return kanji; + /* Hankaku Kana ---> Zenkaku Kana */ + if (kanji) { + j = 0; + for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++) { + if (tmp[i] == SS2) { + p1 = tmp[++i]; + if (tmp[i + 1] == SS2) { + p2 = tmp[i + 2]; + if (p2 == 222 || p2 == 223) + i += 2; + else + p2 = 0; + } else + p2 = 0; + han2zen(&p1, &p2); + SJIStoJIS(&p1, &p2); + to[j++] = p1 + 128; + to[j++] = p2 + 128; + } else + to[j++] = tmp[i]; + } + + if (j >= BUFSIZ) { + gd_error("output buffer overflow at Hankaku --> Zenkaku"); + ustrcpy(to, tmp); + } else + to[j] = '\0'; + } else + ustrcpy(to, tmp); + + return kanji; } -int -any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max) +int any2eucjp(unsigned char *dest, const unsigned char *src, unsigned int dest_max) { - static unsigned char tmp_dest[BUFSIZ]; - int ret; + static unsigned char tmp_dest[BUFSIZ]; + int ret; - if (strlen ((const char *) src) >= BUFSIZ) - { - error ("input string too large"); - return -1; + if (strlen((const char *)src) >= BUFSIZ) { + gd_error("input string too large"); + return -1; } - if (dest_max > BUFSIZ) - { - error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ); - return -1; + if (dest_max > BUFSIZ) { + gd_error("invalid maximum size of destination\nit should be less than %d.", BUFSIZ); + return -1; } - ret = do_check_and_conv (tmp_dest, src); - if (strlen ((const char *) tmp_dest) >= dest_max) - { - error ("output buffer overflow"); - ustrcpy (dest, src); - return -1; + ret = do_check_and_conv(tmp_dest, src); + if (strlen((const char *)tmp_dest) >= dest_max) { + gd_error("output buffer overflow"); + ustrcpy(dest, src); + return -1; } - ustrcpy (dest, tmp_dest); - return ret; + ustrcpy(dest, tmp_dest); + return ret; } #if 0 diff --git a/ext/gd/libgd/gdparttopng.c b/ext/gd/libgd/gdparttopng.c index a82925b0ed47..5d5df9533d8c 100644 --- a/ext/gd/libgd/gdparttopng.c +++ b/ext/gd/libgd/gdparttopng.c @@ -1,59 +1,54 @@ -#include -#include /* For atoi */ #include "gd.h" +#include +#include /* For atoi */ /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in, *out; - int x, y, w, h; + gdImagePtr im; + FILE *in, *out; + int x, y, w, h; - if (argc != 7) - { - fprintf (stderr, "Usage: gdparttopng filename.gd filename.png x y w h\n"); - exit (1); + if (argc != 7) { + fprintf(stderr, "Usage: gdparttopng filename.gd filename.png x y w h\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - x = atoi (argv[3]); - y = atoi (argv[4]); - w = atoi (argv[5]); - h = atoi (argv[6]); + x = atoi(argv[3]); + y = atoi(argv[4]); + w = atoi(argv[5]); + h = atoi(argv[6]); - printf ("Extracting from (%d, %d), size is %dx%d\n", x, y, w, h); + printf("Extracting from (%d, %d), size is %dx%d\n", x, y, w, h); - im = gdImageCreateFromGd2Part (in, x, y, w, h); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in GD2 format!\n"); - exit (1); + im = gdImageCreateFromGd2Part(in, x, y, w, h); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in GD2 format!\n"); + exit(1); } - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } #ifdef HAVE_LIBPNG - gdImagePng (im, out); + gdImagePng(im, out); #else - fprintf(stderr, "No PNG library support.\n"); + fprintf(stderr, "No PNG library support.\n"); #endif - fclose (out); - gdImageDestroy (im); + fclose(out); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/gdtables.c b/ext/gd/libgd/gdtables.c index e34d8fc7cbe3..996fcace8ab8 100644 --- a/ext/gd/libgd/gdtables.c +++ b/ext/gd/libgd/gdtables.c @@ -5,730 +5,62 @@ #include "php_compat.h" -const int gdCosT[] = -{ - 1024, - 1023, - 1023, - 1022, - 1021, - 1020, - 1018, - 1016, - 1014, - 1011, - 1008, - 1005, - 1001, - 997, - 993, - 989, - 984, - 979, - 973, - 968, - 962, - 955, - 949, - 942, - 935, - 928, - 920, - 912, - 904, - 895, - 886, - 877, - 868, - 858, - 848, - 838, - 828, - 817, - 806, - 795, - 784, - 772, - 760, - 748, - 736, - 724, - 711, - 698, - 685, - 671, - 658, - 644, - 630, - 616, - 601, - 587, - 572, - 557, - 542, - 527, - 512, - 496, - 480, - 464, - 448, - 432, - 416, - 400, - 383, - 366, - 350, - 333, - 316, - 299, - 282, - 265, - 247, - 230, - 212, - 195, - 177, - 160, - 142, - 124, - 107, - 89, - 71, - 53, - 35, - 17, - 0, - -17, - -35, - -53, - -71, - -89, - -107, - -124, - -142, - -160, - -177, - -195, - -212, - -230, - -247, - -265, - -282, - -299, - -316, - -333, - -350, - -366, - -383, - -400, - -416, - -432, - -448, - -464, - -480, - -496, - -512, - -527, - -542, - -557, - -572, - -587, - -601, - -616, - -630, - -644, - -658, - -671, - -685, - -698, - -711, - -724, - -736, - -748, - -760, - -772, - -784, - -795, - -806, - -817, - -828, - -838, - -848, - -858, - -868, - -877, - -886, - -895, - -904, - -912, - -920, - -928, - -935, - -942, - -949, - -955, - -962, - -968, - -973, - -979, - -984, - -989, - -993, - -997, - -1001, - -1005, - -1008, - -1011, - -1014, - -1016, - -1018, - -1020, - -1021, - -1022, - -1023, - -1023, - -1024, - -1023, - -1023, - -1022, - -1021, - -1020, - -1018, - -1016, - -1014, - -1011, - -1008, - -1005, - -1001, - -997, - -993, - -989, - -984, - -979, - -973, - -968, - -962, - -955, - -949, - -942, - -935, - -928, - -920, - -912, - -904, - -895, - -886, - -877, - -868, - -858, - -848, - -838, - -828, - -817, - -806, - -795, - -784, - -772, - -760, - -748, - -736, - -724, - -711, - -698, - -685, - -671, - -658, - -644, - -630, - -616, - -601, - -587, - -572, - -557, - -542, - -527, - -512, - -496, - -480, - -464, - -448, - -432, - -416, - -400, - -383, - -366, - -350, - -333, - -316, - -299, - -282, - -265, - -247, - -230, - -212, - -195, - -177, - -160, - -142, - -124, - -107, - -89, - -71, - -53, - -35, - -17, - 0, - 17, - 35, - 53, - 71, - 89, - 107, - 124, - 142, - 160, - 177, - 195, - 212, - 230, - 247, - 265, - 282, - 299, - 316, - 333, - 350, - 366, - 383, - 400, - 416, - 432, - 448, - 464, - 480, - 496, - 512, - 527, - 542, - 557, - 572, - 587, - 601, - 616, - 630, - 644, - 658, - 671, - 685, - 698, - 711, - 724, - 736, - 748, - 760, - 772, - 784, - 795, - 806, - 817, - 828, - 838, - 848, - 858, - 868, - 877, - 886, - 895, - 904, - 912, - 920, - 928, - 935, - 942, - 949, - 955, - 962, - 968, - 973, - 979, - 984, - 989, - 993, - 997, - 1001, - 1005, - 1008, - 1011, - 1014, - 1016, - 1018, - 1020, - 1021, - 1022, - 1023, - 1023 -}; +const int gdCosT[] = { + 1024, 1023, 1023, 1022, 1021, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1001, + 997, 993, 989, 984, 979, 973, 968, 962, 955, 949, 942, 935, 928, + 920, 912, 904, 895, 886, 877, 868, 858, 848, 838, 828, 817, 806, + 795, 784, 772, 760, 748, 736, 724, 711, 698, 685, 671, 658, 644, + 630, 616, 601, 587, 572, 557, 542, 527, 512, 496, 480, 464, 448, + 432, 416, 400, 383, 366, 350, 333, 316, 299, 282, 265, 247, 230, + 212, 195, 177, 160, 142, 124, 107, 89, 71, 53, 35, 17, 0, + -17, -35, -53, -71, -89, -107, -124, -142, -160, -177, -195, -212, -230, + -247, -265, -282, -299, -316, -333, -350, -366, -383, -400, -416, -432, -448, + -464, -480, -496, -512, -527, -542, -557, -572, -587, -601, -616, -630, -644, + -658, -671, -685, -698, -711, -724, -736, -748, -760, -772, -784, -795, -806, + -817, -828, -838, -848, -858, -868, -877, -886, -895, -904, -912, -920, -928, + -935, -942, -949, -955, -962, -968, -973, -979, -984, -989, -993, -997, -1001, + -1005, -1008, -1011, -1014, -1016, -1018, -1020, -1021, -1022, -1023, -1023, -1024, -1023, + -1023, -1022, -1021, -1020, -1018, -1016, -1014, -1011, -1008, -1005, -1001, -997, -993, + -989, -984, -979, -973, -968, -962, -955, -949, -942, -935, -928, -920, -912, + -904, -895, -886, -877, -868, -858, -848, -838, -828, -817, -806, -795, -784, + -772, -760, -748, -736, -724, -711, -698, -685, -671, -658, -644, -630, -616, + -601, -587, -572, -557, -542, -527, -512, -496, -480, -464, -448, -432, -416, + -400, -383, -366, -350, -333, -316, -299, -282, -265, -247, -230, -212, -195, + -177, -160, -142, -124, -107, -89, -71, -53, -35, -17, 0, 17, 35, + 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, 230, 247, 265, + 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, 448, 464, 480, + 496, 512, 527, 542, 557, 572, 587, 601, 616, 630, 644, 658, 671, + 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, 806, 817, 828, + 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, 928, 935, 942, + 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, 1001, 1005, 1008, + 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023}; -const int gdSinT[] = -{ - 0, - 17, - 35, - 53, - 71, - 89, - 107, - 124, - 142, - 160, - 177, - 195, - 212, - 230, - 247, - 265, - 282, - 299, - 316, - 333, - 350, - 366, - 383, - 400, - 416, - 432, - 448, - 464, - 480, - 496, - 512, - 527, - 542, - 557, - 572, - 587, - 601, - 616, - 630, - 644, - 658, - 671, - 685, - 698, - 711, - 724, - 736, - 748, - 760, - 772, - 784, - 795, - 806, - 817, - 828, - 838, - 848, - 858, - 868, - 877, - 886, - 895, - 904, - 912, - 920, - 928, - 935, - 942, - 949, - 955, - 962, - 968, - 973, - 979, - 984, - 989, - 993, - 997, - 1001, - 1005, - 1008, - 1011, - 1014, - 1016, - 1018, - 1020, - 1021, - 1022, - 1023, - 1023, - 1024, - 1023, - 1023, - 1022, - 1021, - 1020, - 1018, - 1016, - 1014, - 1011, - 1008, - 1005, - 1001, - 997, - 993, - 989, - 984, - 979, - 973, - 968, - 962, - 955, - 949, - 942, - 935, - 928, - 920, - 912, - 904, - 895, - 886, - 877, - 868, - 858, - 848, - 838, - 828, - 817, - 806, - 795, - 784, - 772, - 760, - 748, - 736, - 724, - 711, - 698, - 685, - 671, - 658, - 644, - 630, - 616, - 601, - 587, - 572, - 557, - 542, - 527, - 512, - 496, - 480, - 464, - 448, - 432, - 416, - 400, - 383, - 366, - 350, - 333, - 316, - 299, - 282, - 265, - 247, - 230, - 212, - 195, - 177, - 160, - 142, - 124, - 107, - 89, - 71, - 53, - 35, - 17, - 0, - -17, - -35, - -53, - -71, - -89, - -107, - -124, - -142, - -160, - -177, - -195, - -212, - -230, - -247, - -265, - -282, - -299, - -316, - -333, - -350, - -366, - -383, - -400, - -416, - -432, - -448, - -464, - -480, - -496, - -512, - -527, - -542, - -557, - -572, - -587, - -601, - -616, - -630, - -644, - -658, - -671, - -685, - -698, - -711, - -724, - -736, - -748, - -760, - -772, - -784, - -795, - -806, - -817, - -828, - -838, - -848, - -858, - -868, - -877, - -886, - -895, - -904, - -912, - -920, - -928, - -935, - -942, - -949, - -955, - -962, - -968, - -973, - -979, - -984, - -989, - -993, - -997, - -1001, - -1005, - -1008, - -1011, - -1014, - -1016, - -1018, - -1020, - -1021, - -1022, - -1023, - -1023, - -1024, - -1023, - -1023, - -1022, - -1021, - -1020, - -1018, - -1016, - -1014, - -1011, - -1008, - -1005, - -1001, - -997, - -993, - -989, - -984, - -979, - -973, - -968, - -962, - -955, - -949, - -942, - -935, - -928, - -920, - -912, - -904, - -895, - -886, - -877, - -868, - -858, - -848, - -838, - -828, - -817, - -806, - -795, - -784, - -772, - -760, - -748, - -736, - -724, - -711, - -698, - -685, - -671, - -658, - -644, - -630, - -616, - -601, - -587, - -572, - -557, - -542, - -527, - -512, - -496, - -480, - -464, - -448, - -432, - -416, - -400, - -383, - -366, - -350, - -333, - -316, - -299, - -282, - -265, - -247, - -230, - -212, - -195, - -177, - -160, - -142, - -124, - -107, - -89, - -71, - -53, - -35, - -17 -}; +const int gdSinT[] = { + 0, 17, 35, 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, + 230, 247, 265, 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, + 448, 464, 480, 496, 512, 527, 542, 557, 572, 587, 601, 616, 630, + 644, 658, 671, 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, + 806, 817, 828, 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, + 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, + 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023, 1024, + 1023, 1023, 1022, 1021, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1001, 997, + 993, 989, 984, 979, 973, 968, 962, 955, 949, 942, 935, 928, 920, + 912, 904, 895, 886, 877, 868, 858, 848, 838, 828, 817, 806, 795, + 784, 772, 760, 748, 736, 724, 711, 698, 685, 671, 658, 644, 630, + 616, 601, 587, 572, 557, 542, 527, 512, 496, 480, 464, 448, 432, + 416, 400, 383, 366, 350, 333, 316, 299, 282, 265, 247, 230, 212, + 195, 177, 160, 142, 124, 107, 89, 71, 53, 35, 17, 0, -17, + -35, -53, -71, -89, -107, -124, -142, -160, -177, -195, -212, -230, -247, + -265, -282, -299, -316, -333, -350, -366, -383, -400, -416, -432, -448, -464, + -480, -496, -512, -527, -542, -557, -572, -587, -601, -616, -630, -644, -658, + -671, -685, -698, -711, -724, -736, -748, -760, -772, -784, -795, -806, -817, + -828, -838, -848, -858, -868, -877, -886, -895, -904, -912, -920, -928, -935, + -942, -949, -955, -962, -968, -973, -979, -984, -989, -993, -997, -1001, -1005, + -1008, -1011, -1014, -1016, -1018, -1020, -1021, -1022, -1023, -1023, -1024, -1023, -1023, + -1022, -1021, -1020, -1018, -1016, -1014, -1011, -1008, -1005, -1001, -997, -993, -989, + -984, -979, -973, -968, -962, -955, -949, -942, -935, -928, -920, -912, -904, + -895, -886, -877, -868, -858, -848, -838, -828, -817, -806, -795, -784, -772, + -760, -748, -736, -724, -711, -698, -685, -671, -658, -644, -630, -616, -601, + -587, -572, -557, -542, -527, -512, -496, -480, -464, -448, -432, -416, -400, + -383, -366, -350, -333, -316, -299, -282, -265, -247, -230, -212, -195, -177, + -160, -142, -124, -107, -89, -71, -53, -35, -17}; diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index ba036b83d974..941e675a3f99 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -1,409 +1,359 @@ #include #ifdef _WIN32 #include -int -unlink (const char *filename) -{ - return _unlink (filename); -} +int unlink(const char *filename) { return _unlink(filename); } #else -#include /* for getpid(), unlink() */ +#include /* for getpid(), unlink() */ #endif #include "gd.h" -void CompareImages (char *msg, gdImagePtr im1, gdImagePtr im2); +void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2); -static int freadWrapper (void *context, char *buf, int len); -static int fwriteWrapper (void *context, const char *buffer, int len); +static int freadWrapper(void *context, char *buf, int len); +static int fwriteWrapper(void *context, const char *buffer, int len); -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im, ref, im2, im3; - FILE *in, *out; - void *iptr; - int sz; - gdIOCtxPtr ctx; - char of[256]; - int colRed, colBlu; - gdSource imgsrc; - gdSink imgsnk; - int foreground; - int i; - if (argc != 2) - { - fprintf (stderr, "Usage: gdtest filename.png\n"); - exit (1); + gdImagePtr im, ref, im2, im3; + FILE *in, *out; + void *iptr; + int sz; + gdIOCtxPtr ctx; + char of[256]; + int colRed, colBlu; + gdSource imgsrc; + gdSink imgsnk; + int foreground; + int i; + if (argc != 2) { + fprintf(stderr, "Usage: gdtest filename.png\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromPng (in); - - rewind (in); - ref = gdImageCreateFromPng (in); + im = gdImageCreateFromPng(in); - fclose (in); + rewind(in); + ref = gdImageCreateFromPng(in); - printf ("Reference File has %d Palette entries\n", ref->colorsTotal); + fclose(in); - CompareImages ("Initial Versions", ref, im); + printf("Reference File has %d Palette entries\n", ref->colorsTotal); + CompareImages("Initial Versions", ref, im); - /* */ - /* Send to PNG File then Ptr */ - /* */ - snprintf (of, sizeof(of), "%s.png", argv[1]); - out = fopen (of, "wb"); - gdImagePng (im, out); - fclose (out); + /* */ + /* Send to PNG File then Ptr */ + /* */ + snprintf(of, sizeof(of), "%s.png", argv[1]); + out = fopen(of, "wb"); + gdImagePng(im, out); + fclose(out); - in = fopen (of, "rb"); - if (!in) - { - fprintf (stderr, "PNG Output file does not exist!\n"); - exit (1); + in = fopen(of, "rb"); + if (!in) { + fprintf(stderr, "PNG Output file does not exist!\n"); + exit(1); } - im2 = gdImageCreateFromPng (in); - fclose (in); + im2 = gdImageCreateFromPng(in); + fclose(in); - CompareImages ("GD->PNG File->GD", ref, im2); + CompareImages("GD->PNG File->GD", ref, im2); - unlink (of); - gdImageDestroy (im2); + unlink(of); + gdImageDestroy(im2); - iptr = gdImagePngPtr (im, &sz); - ctx = gdNewDynamicCtx (sz, iptr); - im2 = gdImageCreateFromPngCtx (ctx); + iptr = gdImagePngPtr(im, &sz); + ctx = gdNewDynamicCtx(sz, iptr); + im2 = gdImageCreateFromPngCtx(ctx); - CompareImages ("GD->PNG ptr->GD", ref, im2); + CompareImages("GD->PNG ptr->GD", ref, im2); - gdImageDestroy (im2); - ctx->gd_free (ctx); + gdImageDestroy(im2); + ctx->gd_free(ctx); + /* */ + /* Send to GD2 File then Ptr */ + /* */ + snprintf(of, sizeof(of), "%s.gd2", argv[1]); + out = fopen(of, "wb"); + gdImageGd2(im, out, 128, 2); + fclose(out); - /* */ - /* Send to GD2 File then Ptr */ - /* */ - snprintf (of, sizeof(of), "%s.gd2", argv[1]); - out = fopen (of, "wb"); - gdImageGd2 (im, out, 128, 2); - fclose (out); - - in = fopen (of, "rb"); - if (!in) - { - fprintf (stderr, "GD2 Output file does not exist!\n"); - exit (1); + in = fopen(of, "rb"); + if (!in) { + fprintf(stderr, "GD2 Output file does not exist!\n"); + exit(1); } - im2 = gdImageCreateFromGd2 (in); - fclose (in); - - CompareImages ("GD->GD2 File->GD", ref, im2); - - unlink (of); - gdImageDestroy (im2); - - iptr = gdImageGd2Ptr (im, 128, 2, &sz); - /*printf("Got ptr %d (size %d)\n",iptr, sz); */ - ctx = gdNewDynamicCtx (sz, iptr); - /*printf("Got ctx %d\n",ctx); */ - im2 = gdImageCreateFromGd2Ctx (ctx); - /*printf("Got img2 %d\n",im2); */ - - CompareImages ("GD->GD2 ptr->GD", ref, im2); - - gdImageDestroy (im2); - ctx->gd_free (ctx); - - - /* */ - /* Send to GD File then Ptr */ - /* */ - snprintf (of, sizeof(of), "%s.gd", argv[1]); - out = fopen (of, "wb"); - gdImageGd (im, out); - fclose (out); - - in = fopen (of, "rb"); - if (!in) - { - fprintf (stderr, "GD Output file does not exist!\n"); - exit (1); + im2 = gdImageCreateFromGd2(in); + fclose(in); + + CompareImages("GD->GD2 File->GD", ref, im2); + + unlink(of); + gdImageDestroy(im2); + + iptr = gdImageGd2Ptr(im, 128, 2, &sz); + /*printf("Got ptr %d (size %d)\n",iptr, sz); */ + ctx = gdNewDynamicCtx(sz, iptr); + /*printf("Got ctx %d\n",ctx); */ + im2 = gdImageCreateFromGd2Ctx(ctx); + /*printf("Got img2 %d\n",im2); */ + + CompareImages("GD->GD2 ptr->GD", ref, im2); + + gdImageDestroy(im2); + ctx->gd_free(ctx); + + /* */ + /* Send to GD File then Ptr */ + /* */ + snprintf(of, sizeof(of), "%s.gd", argv[1]); + out = fopen(of, "wb"); + gdImageGd(im, out); + fclose(out); + + in = fopen(of, "rb"); + if (!in) { + fprintf(stderr, "GD Output file does not exist!\n"); + exit(1); } - im2 = gdImageCreateFromGd (in); - fclose (in); + im2 = gdImageCreateFromGd(in); + fclose(in); - CompareImages ("GD->GD File->GD", ref, im2); + CompareImages("GD->GD File->GD", ref, im2); - unlink (of); - gdImageDestroy (im2); + unlink(of); + gdImageDestroy(im2); - iptr = gdImageGdPtr (im, &sz); - /*printf("Got ptr %d (size %d)\n",iptr, sz); */ - ctx = gdNewDynamicCtx (sz, iptr); - /*printf("Got ctx %d\n",ctx); */ - im2 = gdImageCreateFromGdCtx (ctx); - /*printf("Got img2 %d\n",im2); */ + iptr = gdImageGdPtr(im, &sz); + /*printf("Got ptr %d (size %d)\n",iptr, sz); */ + ctx = gdNewDynamicCtx(sz, iptr); + /*printf("Got ctx %d\n",ctx); */ + im2 = gdImageCreateFromGdCtx(ctx); + /*printf("Got img2 %d\n",im2); */ - CompareImages ("GD->GD ptr->GD", ref, im2); + CompareImages("GD->GD ptr->GD", ref, im2); - gdImageDestroy (im2); - ctx->gd_free (ctx); + gdImageDestroy(im2); + ctx->gd_free(ctx); - /* + /* ** Test gdImageCreateFromPngSource' * */ - in = fopen (argv[1], "rb"); + in = fopen(argv[1], "rb"); - imgsrc.source = freadWrapper; - imgsrc.context = in; - im2 = gdImageCreateFromPngSource (&imgsrc); - fclose (in); + imgsrc.source = freadWrapper; + imgsrc.context = in; + im2 = gdImageCreateFromPngSource(&imgsrc); + fclose(in); - if (im2 == NULL) - { - printf ("GD Source: ERROR Null returned by gdImageCreateFromPngSource\n"); - } - else - { - CompareImages ("GD Source", ref, im2); - gdImageDestroy (im2); + if (im2 == NULL) { + printf("GD Source: ERROR Null returned by gdImageCreateFromPngSource\n"); + } else { + CompareImages("GD Source", ref, im2); + gdImageDestroy(im2); }; - - /* + /* ** Test gdImagePngToSink' * */ - snprintf (of, sizeof(of), "%s.snk", argv[1]); - out = fopen (of, "wb"); - imgsnk.sink = fwriteWrapper; - imgsnk.context = out; - gdImagePngToSink (im, &imgsnk); - fclose (out); - in = fopen (of, "rb"); - if (!in) - { - fprintf (stderr, "GD Sink: ERROR - GD Sink Output file does not exist!\n"); - } - else - { - im2 = gdImageCreateFromPng (in); - fclose (in); - - CompareImages ("GD Sink", ref, im2); - gdImageDestroy (im2); + snprintf(of, sizeof(of), "%s.snk", argv[1]); + out = fopen(of, "wb"); + imgsnk.sink = fwriteWrapper; + imgsnk.context = out; + gdImagePngToSink(im, &imgsnk); + fclose(out); + in = fopen(of, "rb"); + if (!in) { + fprintf(stderr, "GD Sink: ERROR - GD Sink Output file does not exist!\n"); + } else { + im2 = gdImageCreateFromPng(in); + fclose(in); + + CompareImages("GD Sink", ref, im2); + gdImageDestroy(im2); }; - unlink (of); + unlink(of); - /* */ - /* Test Extraction */ - /* */ - in = fopen ("test/gdtest_200_300_150_100.png", "rb"); - if (!in) - { - fprintf (stderr, "gdtest_200_300_150_100.png does not exist!\n"); - exit (1); + /* */ + /* Test Extraction */ + /* */ + in = fopen("test/gdtest_200_300_150_100.png", "rb"); + if (!in) { + fprintf(stderr, "gdtest_200_300_150_100.png does not exist!\n"); + exit(1); } - im2 = gdImageCreateFromPng (in); - fclose (in); - + im2 = gdImageCreateFromPng(in); + fclose(in); - in = fopen ("test/gdtest.gd2", "rb"); - if (!in) - { - fprintf (stderr, "gdtest.gd2 does not exist!\n"); - exit (1); + in = fopen("test/gdtest.gd2", "rb"); + if (!in) { + fprintf(stderr, "gdtest.gd2 does not exist!\n"); + exit(1); } - im3 = gdImageCreateFromGd2Part (in, 200, 300, 150, 100); - fclose (in); - - CompareImages ("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))", im2, im3); - - gdImageDestroy (im2); - gdImageDestroy (im3); - - /* */ - /* Copy Blend */ - /* */ - in = fopen ("test/gdtest.png", "rb"); - if (!in) - { - fprintf (stderr, "gdtest.png does not exist!\n"); - exit (1); + im3 = gdImageCreateFromGd2Part(in, 200, 300, 150, 100); + fclose(in); + + CompareImages("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))", im2, im3); + + gdImageDestroy(im2); + gdImageDestroy(im3); + + /* */ + /* Copy Blend */ + /* */ + in = fopen("test/gdtest.png", "rb"); + if (!in) { + fprintf(stderr, "gdtest.png does not exist!\n"); + exit(1); } - im2 = gdImageCreateFromPng (in); - fclose (in); + im2 = gdImageCreateFromPng(in); + fclose(in); - im3 = gdImageCreate (100, 60); - colRed = gdImageColorAllocate (im3, 255, 0, 0); - colBlu = gdImageColorAllocate (im3, 0, 0, 255); - gdImageFilledRectangle (im3, 0, 0, 49, 30, colRed); - gdImageFilledRectangle (im3, 50, 30, 99, 59, colBlu); + im3 = gdImageCreate(100, 60); + colRed = gdImageColorAllocate(im3, 255, 0, 0); + colBlu = gdImageColorAllocate(im3, 0, 0, 255); + gdImageFilledRectangle(im3, 0, 0, 49, 30, colRed); + gdImageFilledRectangle(im3, 50, 30, 99, 59, colBlu); - gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50); - gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50); + gdImageCopyMerge(im2, im3, 150, 200, 10, 10, 90, 50, 50); + gdImageCopyMerge(im2, im3, 180, 70, 10, 10, 90, 50, 50); - gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50); - gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50); + gdImageCopyMergeGray(im2, im3, 250, 160, 10, 10, 90, 50, 50); + gdImageCopyMergeGray(im2, im3, 80, 70, 10, 10, 90, 50, 50); - gdImageDestroy (im3); + gdImageDestroy(im3); - in = fopen ("test/gdtest_merge.png", "rb"); - if (!in) - { - fprintf (stderr, "gdtest_merge.png does not exist!\n"); - exit (1); + in = fopen("test/gdtest_merge.png", "rb"); + if (!in) { + fprintf(stderr, "gdtest_merge.png does not exist!\n"); + exit(1); } - im3 = gdImageCreateFromPng (in); - fclose (in); + im3 = gdImageCreateFromPng(in); + fclose(in); - printf ("[Merged Image has %d colours]\n", im2->colorsTotal); - CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3); + printf("[Merged Image has %d colours]\n", im2->colorsTotal); + CompareImages("Merged (gdtest.png, gdtest_merge.png)", im2, im3); - gdImageDestroy (im2); - gdImageDestroy (im3); + gdImageDestroy(im2); + gdImageDestroy(im3); #ifdef HAVE_JPEG - out = fopen ("test/gdtest.jpg", "wb"); - if (!out) - { - fprintf (stderr, "Can't create file test/gdtest.jpg.\n"); - exit (1); + out = fopen("test/gdtest.jpg", "wb"); + if (!out) { + fprintf(stderr, "Can't create file test/gdtest.jpg.\n"); + exit(1); } - gdImageJpeg (im, out, -1); - fclose (out); - in = fopen ("test/gdtest.jpg", "rb"); - if (!in) - { - fprintf (stderr, "Can't open file test/gdtest.jpg.\n"); - exit (1); + gdImageJpeg(im, out, -1); + fclose(out); + in = fopen("test/gdtest.jpg", "rb"); + if (!in) { + fprintf(stderr, "Can't open file test/gdtest.jpg.\n"); + exit(1); } - im2 = gdImageCreateFromJpeg (in); - fclose (in); - if (!im2) - { - fprintf (stderr, "gdImageCreateFromJpeg failed.\n"); - exit (1); + im2 = gdImageCreateFromJpeg(in); + fclose(in); + if (!im2) { + fprintf(stderr, "gdImageCreateFromJpeg failed.\n"); + exit(1); } - gdImageDestroy (im2); - printf ("Created test/gdtest.jpg successfully. Compare this image\n" - "to the input image manually. Some difference must be\n" - "expected as JPEG is a lossy file format.\n"); + gdImageDestroy(im2); + printf("Created test/gdtest.jpg successfully. Compare this image\n" + "to the input image manually. Some difference must be\n" + "expected as JPEG is a lossy file format.\n"); #endif /* HAVE_JPEG */ - /* Assume the color closest to black is the foreground - color for the B&W wbmp image. */ - fprintf (stderr, "NOTE: the WBMP output image will NOT match the original unless the original\n" - "is also black and white. This is OK!\n"); - foreground = gdImageColorClosest (im, 0, 0, 0); - fprintf (stderr, "Foreground index is %d\n", foreground); - if (foreground == -1) - { - fprintf (stderr, "Source image has no colors, skipping wbmp test.\n"); - } - else - { - out = fopen ("test/gdtest.wbmp", "wb"); - if (!out) - { - fprintf (stderr, "Can't create file test/gdtest.wbmp.\n"); - exit (1); - } - gdImageWBMP (im, foreground, out); - fclose (out); - in = fopen ("test/gdtest.wbmp", "rb"); - if (!in) - { - fprintf (stderr, "Can't open file test/gdtest.wbmp.\n"); - exit (1); - } - im2 = gdImageCreateFromWBMP (in); - fprintf (stderr, "WBMP has %d colors\n", gdImageColorsTotal (im2)); - fprintf (stderr, "WBMP colors are:\n"); - for (i = 0; (i < gdImageColorsTotal (im2)); i++) - { - fprintf (stderr, "%02X%02X%02X\n", - gdImageRed (im2, i), - gdImageGreen (im2, i), - gdImageBlue (im2, i)); - } - fclose (in); - if (!im2) - { - fprintf (stderr, "gdImageCreateFromWBMP failed.\n"); - exit (1); - } - CompareImages ("WBMP test (gdtest.png, gdtest.wbmp)", ref, im2); - out = fopen ("test/gdtest_wbmp_to_png.png", "wb"); - if (!out) - { - fprintf (stderr, "Can't create file test/gdtest_wbmp_to_png.png.\n"); - exit (1); - } - gdImagePng (im2, out); - fclose (out); - gdImageDestroy (im2); + /* Assume the color closest to black is the foreground + color for the B&W wbmp image. */ + fprintf(stderr, "NOTE: the WBMP output image will NOT match the original unless the original\n" + "is also black and white. This is OK!\n"); + foreground = gdImageColorClosest(im, 0, 0, 0); + fprintf(stderr, "Foreground index is %d\n", foreground); + if (foreground == -1) { + fprintf(stderr, "Source image has no colors, skipping wbmp test.\n"); + } else { + out = fopen("test/gdtest.wbmp", "wb"); + if (!out) { + fprintf(stderr, "Can't create file test/gdtest.wbmp.\n"); + exit(1); + } + gdImageWBMP(im, foreground, out); + fclose(out); + in = fopen("test/gdtest.wbmp", "rb"); + if (!in) { + fprintf(stderr, "Can't open file test/gdtest.wbmp.\n"); + exit(1); + } + im2 = gdImageCreateFromWBMP(in); + fprintf(stderr, "WBMP has %d colors\n", gdImageColorsTotal(im2)); + fprintf(stderr, "WBMP colors are:\n"); + for (i = 0; (i < gdImageColorsTotal(im2)); i++) { + fprintf(stderr, "%02X%02X%02X\n", gdImageRed(im2, i), gdImageGreen(im2, i), + gdImageBlue(im2, i)); + } + fclose(in); + if (!im2) { + fprintf(stderr, "gdImageCreateFromWBMP failed.\n"); + exit(1); + } + CompareImages("WBMP test (gdtest.png, gdtest.wbmp)", ref, im2); + out = fopen("test/gdtest_wbmp_to_png.png", "wb"); + if (!out) { + fprintf(stderr, "Can't create file test/gdtest_wbmp_to_png.png.\n"); + exit(1); + } + gdImagePng(im2, out); + fclose(out); + gdImageDestroy(im2); } - gdImageDestroy (im); - gdImageDestroy (ref); + gdImageDestroy(im); + gdImageDestroy(ref); - return 0; + return 0; } -void -CompareImages (char *msg, gdImagePtr im1, gdImagePtr im2) +void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2) { - int cmpRes; + int cmpRes; - cmpRes = gdImageCompare (im1, im2); + cmpRes = gdImageCompare(im1, im2); - if (cmpRes & GD_CMP_IMAGE) - { - printf ("%%%s: ERROR images differ: BAD\n", msg); - } - else if (cmpRes != 0) - { - printf ("%%%s: WARNING images differ: WARNING - Probably OK\n", msg); - } - else - { - printf ("%%%s: OK\n", msg); - return; + if (cmpRes & GD_CMP_IMAGE) { + printf("%%%s: ERROR images differ: BAD\n", msg); + } else if (cmpRes != 0) { + printf("%%%s: WARNING images differ: WARNING - Probably OK\n", msg); + } else { + printf("%%%s: OK\n", msg); + return; } - if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) - { - printf ("-%s: INFO image sizes differ\n", msg); + if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) { + printf("-%s: INFO image sizes differ\n", msg); } - if (cmpRes & GD_CMP_NUM_COLORS) - { - printf ("-%s: INFO number of palette entries differ %d Vs. %d\n", msg, - im1->colorsTotal, im2->colorsTotal); + if (cmpRes & GD_CMP_NUM_COLORS) { + printf("-%s: INFO number of palette entries differ %d Vs. %d\n", msg, im1->colorsTotal, + im2->colorsTotal); } - if (cmpRes & GD_CMP_COLOR) - { - printf ("-%s: INFO actual colours of pixels differ\n", msg); + if (cmpRes & GD_CMP_COLOR) { + printf("-%s: INFO actual colours of pixels differ\n", msg); } } - -static int -freadWrapper (void *context, char *buf, int len) +static int freadWrapper(void *context, char *buf, int len) { - int got = fread (buf, 1, len, (FILE *) context); - return got; + int got = fread(buf, 1, len, (FILE *)context); + return got; } -static int -fwriteWrapper (void *context, const char *buffer, int len) +static int fwriteWrapper(void *context, const char *buffer, int len) { - return fwrite (buffer, 1, len, (FILE *) context); + return fwrite(buffer, 1, len, (FILE *)context); } diff --git a/ext/gd/libgd/gdtestft.c b/ext/gd/libgd/gdtestft.c index fcac75896cf1..7351b33adf22 100644 --- a/ext/gd/libgd/gdtestft.c +++ b/ext/gd/libgd/gdtestft.c @@ -3,106 +3,100 @@ #include #define PI 3.141592 -#define DEG2RAD(x) ((x)*PI/180.) +#define DEG2RAD(x) ((x) * PI / 180.) -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define MAX4(x,y,z,w) \ - ((MAX((x),(y))) > (MAX((z),(w))) ? (MAX((x),(y))) : (MAX((z),(w)))) -#define MIN4(x,y,z,w) \ - ((MIN((x),(y))) < (MIN((z),(w))) ? (MIN((x),(y))) : (MIN((z),(w)))) +#define MAX4(x, y, z, w) ((MAX((x), (y))) > (MAX((z), (w))) ? (MAX((x), (y))) : (MAX((z), (w)))) +#define MIN4(x, y, z, w) ((MIN((x), (y))) < (MIN((z), (w))) ? (MIN((x), (y))) : (MIN((z), (w)))) -#define MAXX(x) MAX4(x[0],x[2],x[4],x[6]) -#define MINX(x) MIN4(x[0],x[2],x[4],x[6]) -#define MAXY(x) MAX4(x[1],x[3],x[5],x[7]) -#define MINY(x) MIN4(x[1],x[3],x[5],x[7]) +#define MAXX(x) MAX4(x[0], x[2], x[4], x[6]) +#define MINX(x) MIN4(x[0], x[2], x[4], x[6]) +#define MAXY(x) MAX4(x[1], x[3], x[5], x[7]) +#define MINY(x) MIN4(x[1], x[3], x[5], x[7]) -int -main (int argc, char *argv[]) +int main(int argc, char *argv[]) { #ifndef HAVE_LIBFREETYPE - fprintf (stderr, "gd was not compiled with HAVE_LIBFREETYPE defined.\n"); - fprintf (stderr, "Install the FreeType library, including the\n"); - fprintf (stderr, "header files. Then edit the gd Makefile, type\n"); - fprintf (stderr, "make clean, and type make again.\n"); - return 1; + fprintf(stderr, "gd was not compiled with HAVE_LIBFREETYPE defined.\n"); + fprintf(stderr, "Install the FreeType library, including the\n"); + fprintf(stderr, "header files. Then edit the gd Makefile, type\n"); + fprintf(stderr, "make clean, and type make again.\n"); + return 1; #else - gdImagePtr im; - int black; - int white; - int brect[8]; - int x, y; - char *err; - FILE *out; + gdImagePtr im; + int black; + int white; + int brect[8]; + int x, y; + char *err; + FILE *out; #ifdef JISX0208 - char *s = "Hello. ɂ Qyjpqg,"; /* String to draw. */ + char *s = "Hello. ɂ Qyjpqg,"; /* String to draw. */ #else - char *s = "Hello. Qyjpqg,"; /* String to draw. */ + char *s = "Hello. Qyjpqg,"; /* String to draw. */ #endif - double sz = 40.; + double sz = 40.; #if 0 double angle = 0.; #else - double angle = DEG2RAD (-90); + double angle = DEG2RAD(-90); #endif #ifdef JISX0208 - char *f = "/usr/openwin/lib/locale/ja/X11/fonts/TT/HG-MinchoL.ttf"; /* UNICODE */ - /* char *f = "/usr/local/lib/fonts/truetype/DynaFont/dfpop1.ttf"; *//* SJIS */ + char *f = "/usr/openwin/lib/locale/ja/X11/fonts/TT/HG-MinchoL.ttf"; /* UNICODE */ + /* char *f = "/usr/local/lib/fonts/truetype/DynaFont/dfpop1.ttf"; */ /* SJIS */ #else - char *f = "times"; /* TrueType font */ + char *f = "times"; /* TrueType font */ #endif - /* obtain brect so that we can size the image */ - err = gdImageStringFT ((gdImagePtr) NULL, &brect[0], 0, f, sz, angle, 0, 0, s); - if (err) - { - fprintf (stderr, "%s", err); - return 1; + /* obtain brect so that we can size the image */ + err = gdImageStringFT((gdImagePtr)NULL, &brect[0], 0, f, sz, angle, 0, 0, s); + if (err) { + fprintf(stderr, "%s", err); + return 1; } - /* create an image just big enough for the string */ - x = MAXX (brect) - MINX (brect) + 6; - y = MAXY (brect) - MINY (brect) + 6; + /* create an image just big enough for the string */ + x = MAXX(brect) - MINX(brect) + 6; + y = MAXY(brect) - MINY(brect) + 6; #if 0 im = gdImageCreate (500, 500); #else - /* gd 2.0: true color images can use freetype too */ - im = gdImageCreateTrueColor (x, y); + /* gd 2.0: true color images can use freetype too */ + im = gdImageCreateTrueColor(x, y); #endif - /* Background color. gd 2.0: fill the image with it; truecolor - images have a black background otherwise. */ - white = gdImageColorResolve (im, 255, 255, 255); - gdImageFilledRectangle (im, 0, 0, x, y, white); - black = gdImageColorResolve (im, 0, 0, 0); + /* Background color. gd 2.0: fill the image with it; truecolor + images have a black background otherwise. */ + white = gdImageColorResolve(im, 255, 255, 255); + gdImageFilledRectangle(im, 0, 0, x, y, white); + black = gdImageColorResolve(im, 0, 0, 0); - /* render the string, offset origin to center string */ - x = 0 - MINX (brect) + 3; - y = 0 - MINY (brect) + 3; + /* render the string, offset origin to center string */ + x = 0 - MINX(brect) + 3; + y = 0 - MINY(brect) + 3; - err = gdImageStringFT (im, NULL, black, f, sz, angle, x, y, s); - if (err) - { - fprintf (stderr, "%s", err); - return 1; + err = gdImageStringFT(im, NULL, black, f, sz, angle, x, y, s); + if (err) { + fprintf(stderr, "%s", err); + return 1; } - /* TBB: Write img to test/fttest.png */ - out = fopen ("test/fttest.png", "wb"); - if (!out) - { - fprintf (stderr, "Can't create test/fttest.png\n"); - exit (1); + /* TBB: Write img to test/fttest.png */ + out = fopen("test/fttest.png", "wb"); + if (!out) { + fprintf(stderr, "Can't create test/fttest.png\n"); + exit(1); } - gdImagePng (im, out); - fclose (out); - fprintf (stderr, "Test image written to test/fttest.png\n"); - /* Destroy it */ - gdImageDestroy (im); + gdImagePng(im, out); + fclose(out); + fprintf(stderr, "Test image written to test/fttest.png\n"); + /* Destroy it */ + gdImageDestroy(im); - return 0; + return 0; #endif /* HAVE_LIBFREETYPE */ } diff --git a/ext/gd/libgd/gdtopng.c b/ext/gd/libgd/gdtopng.c index 9670b101976e..efe7147dcc12 100644 --- a/ext/gd/libgd/gdtopng.c +++ b/ext/gd/libgd/gdtopng.c @@ -1,44 +1,39 @@ -#include #include "gd.h" +#include /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in, *out; - if (argc != 3) - { - fprintf (stderr, "Usage: gdtopng filename.gd filename.png\n"); - exit (1); + gdImagePtr im; + FILE *in, *out; + if (argc != 3) { + fprintf(stderr, "Usage: gdtopng filename.gd filename.png\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromGd (in); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in GD format!\n"); - exit (1); + im = gdImageCreateFromGd(in); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in GD format!\n"); + exit(1); } - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } - gdImagePng (im, out); - fclose (out); - gdImageDestroy (im); + gdImagePng(im, out); + fclose(out); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/gdxpm.c b/ext/gd/libgd/gdxpm.c index 8db7fe043826..00d6475c8e62 100644 --- a/ext/gd/libgd/gdxpm.c +++ b/ext/gd/libgd/gdxpm.c @@ -1,139 +1,244 @@ - /* - add ability to load xpm files to gd, requires the xpm - library. - Caolan.McNamara@ul.ie - http://www.csn.ul.ie/~caolan + * Add ability to load xpm files to gd, requires the xpm + * library. + * Caolan.McNamara@ul.ie + * http://www.csn.ul.ie/~caolan + */ + +/** + * File: XPM Input + * + * Read XPM images. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gd.h" +#include "gd_color_map.h" +#include "gd_errors.h" +#include "gdhelpers.h" #include #include #include -#include "gd.h" -#include "gdhelpers.h" -#ifdef HAVE_XPM +#ifndef HAVE_LIBXPM +BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename) +{ + (void)filename; + gd_error_ex(GD_ERROR, "libgd was not built with xpm support\n"); + return NULL; +} +#else #include -gdImagePtr gdImageCreateFromXpm (char *filename) +/* + Function: gdImageCreateFromXpm + + is called to load images from XPM X Window + System color bitmap format files. This function is available only + if HAVE_XPM is selected in the Makefile and the Xpm library is + linked with the application. Unlike most gd file functions, the + Xpm functions *require filenames*, not file + pointers. returns a to the new + image, or NULL if unable to load the image (most often because the + file is corrupt or does not contain an XPM bitmap format + image). You can inspect the sx and sy members of the image to + determine its size. The image must eventually be destroyed using + . + + Parameters: + + filename - The input filename (*not* FILE pointer) + + Returns: + + A pointer to the new image or NULL if an error occurred. + + Example: + (start code) + + gdImagePtr im; + FILE *in; + in = fopen("myxpm.xpm", "rb"); + im = gdImageCreateFromXpm(in); + fclose(in); + // ... Use the image ... + gdImageDestroy(im); + + (end code) + +*/ +BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename) { - XpmInfo info = {0}; - XpmImage image; - int i, j, k, number; - char buf[5]; - gdImagePtr im = 0; - int *pointer; - int red = 0, green = 0, blue = 0; - int *colors; - int ret; - - ret = XpmReadFileToXpmImage(filename, &image, &info); - if (ret != XpmSuccess) { - return 0; - } - number = image.ncolors; - for(i = 0; i < number; i++) { - if (!image.colorTable[i].c_color) { - goto done; - } - } - - if (!(im = gdImageCreate(image.width, image.height))) { - goto done; - } - - colors = (int *) safe_emalloc(number, sizeof(int), 0); - for (i = 0; i < number; i++) { - switch (strlen (image.colorTable[i].c_color)) { - case 4: - buf[1] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - red = strtol(buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[2]; - green = strtol(buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[3]; - blue = strtol(buf, NULL, 16); - break; - - case 7: - buf[2] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - red = strtol(buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[3]; - buf[1] = image.colorTable[i].c_color[4]; - green = strtol(buf, NULL, 16); - - buf[0] = image.colorTable[i].c_color[5]; - buf[1] = image.colorTable[i].c_color[6]; - blue = strtol(buf, NULL, 16); - break; - - case 10: - buf[3] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - buf[2] = image.colorTable[i].c_color[3]; - red = strtol(buf, NULL, 16); - red /= 64; - - buf[0] = image.colorTable[i].c_color[4]; - buf[1] = image.colorTable[i].c_color[5]; - buf[2] = image.colorTable[i].c_color[6]; - green = strtol(buf, NULL, 16); - green /= 64; - - buf[0] = image.colorTable[i].c_color[7]; - buf[1] = image.colorTable[i].c_color[8]; - buf[2] = image.colorTable[i].c_color[9]; - blue = strtol(buf, NULL, 16); - blue /= 64; - break; - - case 13: - buf[4] = '\0'; - buf[0] = image.colorTable[i].c_color[1]; - buf[1] = image.colorTable[i].c_color[2]; - buf[2] = image.colorTable[i].c_color[3]; - buf[3] = image.colorTable[i].c_color[4]; - red = strtol(buf, NULL, 16); - red /= 256; - - buf[0] = image.colorTable[i].c_color[5]; - buf[1] = image.colorTable[i].c_color[6]; - buf[2] = image.colorTable[i].c_color[7]; - buf[3] = image.colorTable[i].c_color[8]; - green = strtol(buf, NULL, 16); - green /= 256; - - buf[0] = image.colorTable[i].c_color[9]; - buf[1] = image.colorTable[i].c_color[10]; - buf[2] = image.colorTable[i].c_color[11]; - buf[3] = image.colorTable[i].c_color[12]; - blue = strtol(buf, NULL, 16); - blue /= 256; - break; - } - - - colors[i] = gdImageColorResolve(im, red, green, blue); - } - - pointer = (int *) image.data; - for (i = 0; i < image.height; i++) { - for (j = 0; j < image.width; j++) { - k = *pointer++; - gdImageSetPixel(im, j, i, colors[k]); - } - } - - gdFree(colors); - done: - XpmFreeXpmImage(&image); - XpmFreeXpmInfo(&info); - return im; + XpmInfo info = {0}; + XpmImage image; + unsigned int i, j, k, number, len; + char buf[5]; + gdImagePtr im = 0; + int *pointer; + int red = 0, green = 0, blue = 0; + int *colors; + int ret; + + ret = XpmReadFileToXpmImage(filename, &image, &info); + if (ret != XpmSuccess) { + return 0; + } + + number = image.ncolors; + if (overflow2(sizeof(int), number)) { + goto done; + } + for (i = 0; i < number; i++) { + /* + avoid NULL pointer dereference + TODO better fix need to manage monochrome/monovisual + see m_color or g4_color or g_color + */ + if (!image.colorTable[i].c_color) { + goto done; + } + } + + colors = (int *)gdMalloc(sizeof(int) * number); + if (colors == NULL) { + goto done; + } + + if (!(im = gdImageCreate(image.width, image.height))) { + gdFree(colors); + goto done; + } + + for (i = 0; i < number; i++) { + char *c_color = image.colorTable[i].c_color; + int valid_color = 1; + if (strcmp(c_color, "None") == 0) { + colors[i] = gdImageGetTransparent(im); + if (colors[i] == -1) + colors[i] = gdImageColorAllocate(im, 0, 0, 0); + if (colors[i] != -1) + gdImageColorTransparent(im, colors[i]); + continue; + } + len = strlen(c_color); + if (len < 1) { + valid_color = 0; + } + if (c_color[0] == '#') { + switch (len) { + case 4: + buf[2] = '\0'; + buf[0] = buf[1] = c_color[1]; + red = strtol(buf, NULL, 16); + + buf[0] = buf[1] = c_color[2]; + green = strtol(buf, NULL, 16); + + buf[0] = buf[1] = c_color[3]; + blue = strtol(buf, NULL, 16); + break; + + case 7: + buf[2] = '\0'; + buf[0] = c_color[1]; + buf[1] = c_color[2]; + red = strtol(buf, NULL, 16); + + buf[0] = c_color[3]; + buf[1] = c_color[4]; + green = strtol(buf, NULL, 16); + + buf[0] = c_color[5]; + buf[1] = c_color[6]; + blue = strtol(buf, NULL, 16); + break; + + case 10: + buf[3] = '\0'; + buf[0] = c_color[1]; + buf[1] = c_color[2]; + buf[2] = c_color[3]; + red = strtol(buf, NULL, 16); + red /= 64; + + buf[0] = c_color[4]; + buf[1] = c_color[5]; + buf[2] = c_color[6]; + green = strtol(buf, NULL, 16); + green /= 64; + + buf[0] = c_color[7]; + buf[1] = c_color[8]; + buf[2] = c_color[9]; + blue = strtol(buf, NULL, 16); + blue /= 64; + break; + + case 13: + buf[4] = '\0'; + buf[0] = c_color[1]; + buf[1] = c_color[2]; + buf[2] = c_color[3]; + buf[3] = c_color[4]; + red = strtol(buf, NULL, 16); + red /= 256; + + buf[0] = c_color[5]; + buf[1] = c_color[6]; + buf[2] = c_color[7]; + buf[3] = c_color[8]; + green = strtol(buf, NULL, 16); + green /= 256; + + buf[0] = c_color[9]; + buf[1] = c_color[10]; + buf[2] = c_color[11]; + buf[3] = c_color[12]; + blue = strtol(buf, NULL, 16); + blue /= 256; + break; + default: + valid_color = 0; + break; + } + } else if (!gdColorMapLookup(GD_COLOR_MAP_X11, c_color, &red, &green, &blue)) { + valid_color = 0; + } + + if (!valid_color) { + gdFree(colors); + gdImageDestroy(im); + im = NULL; + goto done; + } + + colors[i] = gdImageColorResolve(im, red, green, blue); + } + + pointer = (int *)image.data; + + for (i = 0; i < image.height; i++) { + for (j = 0; j < image.width; j++) { + k = *pointer++; + if (k >= number) { + gdFree(colors); + gdImageDestroy(im); + im = NULL; + goto done; + } + gdImageSetPixel(im, j, i, colors[k]); + } + } + + gdFree(colors); + +done: + XpmFreeXpmImage(&image); + XpmFreeXpmInfo(&info); + return im; } -#endif +#endif /* HAVE_LIBXPM */ diff --git a/ext/gd/libgd/jisx0208.h b/ext/gd/libgd/jisx0208.h index f8a8b510fa6c..b502f0f2c5e8 100644 --- a/ext/gd/libgd/jisx0208.h +++ b/ext/gd/libgd/jisx0208.h @@ -5,1201 +5,834 @@ /* JIS -> Unicode mapping table */ static unsigned short UnicodeTbl[][94] = { -{ /* category 01 */ -0x0000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, -0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, 0xFF3E, -0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD, -0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C, -0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, 0x201C, -0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, -0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, -0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, 0x00F7, -0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, -0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04, -0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, 0x00A7, -0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7}, -{ /* category 02 */ -0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, -0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, -0x2229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200, 0x2203, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207, -0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235, -0x222B, 0x222C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, 0x2021, /**/ -0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25EF}, -{ /* category 03 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF10, -0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, -0xFF19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, -0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, -0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, -0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, -0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, -0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, -0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 04 */ -0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, -0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, -0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, -0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, -0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, -0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, -0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, -0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080, -0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, -0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, -0x3091, 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 05 */ -0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, -0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0, -0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, -0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, -0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, -0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0, -0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, -0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, 0x30E0, -0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, -0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0, -0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 06 */ -0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, -0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, -0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, -0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, -0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 07 */ -0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, -0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, -0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, -0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, -0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, -0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, -0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, -0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, -0x044F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 08 */ -0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, -0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, 0x251B, -0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, 0x252F, -0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 09 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 10 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 11 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 12 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 13 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 14 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 15 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 16 */ -0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, -0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, 0x65ED, -0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271, 0x5B9B, -0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, -0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, 0x978D, -0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2, 0x5937, -0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, -0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, 0x840E, -0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5, 0x57DF, -0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, -0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, 0x56E0, -0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D}, -{ /* category 17 */ -0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, -0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11, 0x7893, -0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B, 0x59E5, -0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, -0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620, 0x66F3, -0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E, 0x9834, -0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, -0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186, 0x5712, -0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, -0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, 0x8276, -0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC, 0x6C5A, -0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC}, -{ /* category 18 */ -0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, -0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, 0x5C4B, -0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069, -0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, -0x4FA1, 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, 0x5BB6, -0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B, -0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, -0x8377, 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, 0x8FE6, -0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B, -0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, -0x4F1A, 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, 0x602A, -0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539}, -{ /* category 19 */ -0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, -0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, 0x52BE, 0x5916, -0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB, -0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, -0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, 0x5ED3, 0x62E1, -0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A, -0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, -0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, 0x6A2B, 0x6A7F, -0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, -0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6, -0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, 0x7AC3, 0x84B2, 0x91DC, -0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431}, -{ /* category 20 */ -0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, -0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, 0x5B8C, -0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163, 0x61BE, -0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, -0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, 0x7AFF, -0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266, 0x839E, -0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, -0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, 0x5DCC, -0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1, 0x9811, -0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, -0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, 0x63EE, -0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4}, -{ /* category 21 */ -0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, -0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77, 0x8ECC, -0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100, 0x5993, -0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, -0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0, 0x5409, -0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775, 0x9ECD, -0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, -0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551, 0x673D, -0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, -0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, 0x5DE8, -0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD, 0x92F8, -0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC}, -{ /* category 22 */ -0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, -0x5321, 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, 0x5F4A, -0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2, -0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, -0x97FF, 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, 0x696D, -0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4, -0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, -0x79BD, 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, 0x8B39, -0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A, -0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, -0x5177, 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, 0x9047, -0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48}, -{ /* category 23 */ -0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, -0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, 0x541B, 0x85AB, -0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2, -0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, -0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, 0x63B2, 0x643A, -0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, -0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, -0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, 0x5287, -0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, -0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039, -0x5026, 0x5065, 0x517C, 0x5238, 0x5263, 0x55A7, 0x570F, 0x5805, -0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372}, -{ /* category 24 */ -0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, -0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, 0x9375, -0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3, 0x5E7B, -0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, -0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, 0x59D1, -0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF, 0x6E56, -0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, -0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, 0x4F0D, -0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F, 0x68A7, -0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, -0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, 0x516C, -0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411}, -{ /* category 25 */ -0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, -0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7, 0x5F18, -0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602, 0x6643, -0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, -0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0, 0x7D05, -0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1, 0x8154, -0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, -0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D, 0x9805, -0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, -0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, 0x544A, -0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09, 0x8170, -0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC}, -{ /* category 26 */ -0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, -0x61C7, 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, 0x7D3A, -0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6, -0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, -0x5750, 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, 0x54C9, -0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73, -0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, -0x7D30, 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, 0x6750, -0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4, -0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, -0x643E, 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, 0x932F, -0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237}, -{ /* category 27 */ -0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, -0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, 0x6652, 0x4E09, -0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6, -0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, -0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F, -0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9, -0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, -0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, 0x6B62, 0x6B7B, -0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, -0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE, -0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D, -0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642}, -{ /* category 28 */ -0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, -0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, 0x5F0F, -0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03, 0x53F1, -0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, -0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, 0x5C61, -0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66, 0x659C, -0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, -0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, 0x914C, -0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B, 0x53D6, -0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, -0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, 0x6388, -0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468}, -{ /* category 29 */ -0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, -0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490, 0x8846, -0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C, 0x96C6, -0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, -0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4, 0x5919, -0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F, 0x51FA, -0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, -0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3, 0x6E96, -0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, -0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, 0x7F72, -0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973, 0x5E8F, -0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F}, -{ /* category 30 */ -0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, -0x5968, 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, 0x5C1A, -0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C, -0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, -0x6A35, 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, 0x7167, -0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11, -0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, -0x8A1F, 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, 0x9266, -0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57, -0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, -0x64FE, 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, 0x84B8, -0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE}, -{ /* category 31 */ -0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, -0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, 0x5507, -0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B, -0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, -0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, 0x8A3A, 0x8EAB, -0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875, -0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, -0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, 0x53A8, 0x9017, -0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, -0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, 0x745E, -0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, 0x8DA8, 0x96DB, 0x636E, -0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE}, -{ /* category 32 */ -0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, -0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, 0x6574, -0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272, 0x751F, -0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, -0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, 0x8106, -0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790, 0x77F3, -0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, -0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, 0x7A83, -0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9, 0x5148, -0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, -0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, 0x6F5C, -0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA}, -{ /* category 33 */ -0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, -0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE, 0x524D, -0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3, 0x7CCE, -0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, -0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20, 0x7D44, -0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275, 0x53CC, -0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, -0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB, 0x64CD, -0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, -0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, 0x8349, -0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001, 0x906D, -0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E}, -{ /* category 34 */ -0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, -0x606F, 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, 0x5C5E, -0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58, -0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, -0x6C70, 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, 0x67C1, -0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE, -0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, -0x6CF0, 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, 0x9000, -0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C, -0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, -0x6258, 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, 0x9438, -0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA}, -{ /* category 35 */ -0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, -0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, 0x8AB0, 0x4E39, -0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, -0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, -0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, 0x65AD, 0x6696, -0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B, -0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, -0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, 0x84C4, 0x9010, -0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, -0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B, -0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, 0x732A, 0x82E7, 0x8457, -0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5}, -{ /* category 36 */ -0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, -0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, 0x8074, -0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3, 0x929A, -0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, -0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, 0x69CC, -0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4, 0x69FB, -0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, -0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, 0x91E3, -0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E, 0x5448, -0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, -0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, 0x7A0B, -0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013}, -{ /* category 37 */ -0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, -0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2, 0x5FB9, -0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929, 0x5C55, -0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, -0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410, 0x5835, -0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21, 0x767B, -0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, -0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC, 0x51CD, -0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, -0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, 0x76D7, -0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8, 0x7977, -0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230}, -{ /* category 38 */ -0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, -0x900F, 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, 0x52D5, -0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5, -0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, -0x5FB3, 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, 0x72EC, -0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6, -0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, -0x6C8C, 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, 0x5948, -0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A, -0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, -0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, 0x8CD1, -0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165}, -{ /* category 39 */ -0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, -0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, 0x5E74, 0x5FF5, -0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, -0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, -0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, 0x6777, 0x6CE2, -0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3, -0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, -0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, 0x6885, 0x6973, -0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, -0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF, -0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, 0x8584, 0x8FEB, 0x66DD, -0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6}, -{ /* category 40 */ -0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, -0x808C, 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, 0x9197, -0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9, 0x567A, -0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, -0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, 0x72AF, -0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4, 0x91C6, -0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, -0x8543, 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, 0x5F7C, -0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC, 0x75B2, -0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, -0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, 0x5C3E, -0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E}, -{ /* category 41 */ -0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, -0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C, 0x6867, -0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, -0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, -0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C, 0x86ED, -0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, -0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, -0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577, 0x65A7, -0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, -0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, 0x6B66, -0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8, 0x847A, -0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D}, -{ /* category 42 */ -0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, -0x4ECF, 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, 0x61A4, -0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587, -0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, -0x67C4, 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, 0x50FB, -0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F, -0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, -0x52C9, 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, 0x5703, -0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893, -0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, -0x5305, 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29, -0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B}, -{ /* category 43 */ -0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, -0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, 0x92D2, 0x98FD, -0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8, -0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, -0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, 0x8CBF, 0x927E, -0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2, -0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, -0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, 0x76C6, 0x6469, -0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, -0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52, -0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, 0x672B, 0x6CAB, 0x8FC4, -0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80}, -{ /* category 44 */ -0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, -0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, 0x7C8D, -0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB, 0x9727, -0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, -0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, 0x514D, -0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21, 0x8302, -0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, -0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, 0x5C24, -0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580, 0x5301, -0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, -0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, 0x67F3, -0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652}, -{ /* category 45 */ -0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, -0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67, 0x6D8C, -0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A, 0x9091, -0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, -0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8, 0x63DA, -0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6, 0x7194, -0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, -0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32, 0x6C83, -0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, -0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, 0x4E71, -0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7, 0x5229, -0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483}, -{ /* category 46 */ -0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, -0x7ACB, 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, 0x7409, -0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E, -0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, -0x6599, 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, 0x7CE7, -0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1, -0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, -0x96A3, 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, 0x985E, -0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2, -0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, -0x66A6, 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, 0x604B, -0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F}, -{ /* category 47 */ -0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, -0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717, 0x697C, -0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E, -0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, -0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1, 0x67A0, -0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900, -0x6E7E, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 48 */ -0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, -0x4E42, 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, 0x8212, -0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0, 0x4EB3, -0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, -0x4EED, 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, 0x4F5D, -0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B, 0x4F69, -0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, -0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, 0x4FE5, -0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C, 0x4FF6, -0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, -0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, 0x506C, -0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2}, -{ /* category 49 */ -0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, -0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, 0x5102, 0x5116, -0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C, 0x513B, -0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, -0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, 0x5189, 0x518F, -0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2, 0x51A9, -0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, -0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, 0x51ED, 0x51F0, -0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, -0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, 0x525E, -0x5254, 0x526A, 0x5274, 0x5269, 0x5273, 0x527F, 0x527D, 0x528D, -0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8}, -{ /* category 50 */ -0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, -0x52DE, 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, 0x52F8, -0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F, 0x5315, -0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, -0x5345, 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, 0x536E, -0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6, 0x53A5, -0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, -0x71EE, 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, 0x5440, -0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D, 0x544E, -0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, -0x547B, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, 0x54A2, -0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8}, -{ /* category 51 */ -0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, -0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, 0x54E2, 0x5539, -0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556, 0x5557, -0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, -0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, 0x5583, 0x55A9, -0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC, 0x55E4, -0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, -0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, 0x5638, 0x566B, -0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, -0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, 0x56BC, -0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, 0x56D1, 0x56D3, 0x56D7, -0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709}, -{ /* category 52 */ -0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, -0x5726, 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, 0x5769, -0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0, 0x57B3, -0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, -0x580A, 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, 0x5821, -0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879, 0x5885, -0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, -0x58C5, 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, 0x58DC, -0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC, 0x58FD, -0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, -0x5932, 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, 0x595A, -0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969}, -{ /* category 53 */ -0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, -0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, 0x5A1F, 0x5A11, -0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35, 0x5A36, -0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, -0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, 0x5AFB, 0x5B0C, -0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, -0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, -0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, 0x5B80, 0x5B83, -0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, -0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, 0x5BF3, -0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, 0x5C20, 0x5C22, 0x5C28, -0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53}, -{ /* category 54 */ -0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, -0x5C8C, 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, 0x5CBC, -0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD, 0x5CFA, -0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, -0x5D1B, 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, 0x5D4C, -0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87, 0x5D84, -0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, -0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, 0x5DEB, -0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B, 0x5E36, -0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, -0x5E62, 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, 0x5E7F, -0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF}, -{ /* category 55 */ -0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, -0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, 0x5EF8, 0x5EFE, -0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16, 0x5F29, -0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, -0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, 0x5F77, 0x5F83, -0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E, 0x5F99, -0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, -0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, 0x6060, 0x6019, -0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, -0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, 0x604A, -0x6046, 0x604D, 0x6063, 0x6043, 0x6064, 0x6042, 0x606C, 0x606B, -0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A}, -{ /* category 56 */ -0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, -0x60B8, 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, 0x60B5, -0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100, 0x60F4, -0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, -0x613E, 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, 0x6134, -0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615A, -0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, -0x6175, 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, 0x618A, -0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7, 0x61C8, -0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, -0x61F6, 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, 0x6200, -0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B}, -{ /* category 57 */ -0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, -0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, 0x627C, 0x6282, -0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283, 0x6294, -0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, -0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, 0x62C9, 0x630C, -0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5, 0x6350, -0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, -0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, 0x636B, 0x6369, -0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, -0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651D, -0x6417, 0x6428, 0x640F, 0x6467, 0x646F, 0x6476, 0x644E, 0x652A, -0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC}, -{ /* category 58 */ -0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, -0x64E7, 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, 0x652C, -0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518, 0x651C, -0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, -0x6538, 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, 0x655E, -0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B, 0x659F, -0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, -0x65DB, 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, 0x6603, -0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F, 0x6644, -0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, -0x6662, 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, 0x6698, -0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC}, -{ /* category 59 */ -0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, -0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, 0x6726, 0x6727, -0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746, -0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, -0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, 0x6785, 0x67B7, -0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4, 0x67DE, -0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, -0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, 0x684E, 0x68B3, -0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, -0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, 0x68B5, -0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, 0x6901, 0x68CA, 0x6908, -0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD}, -{ /* category 60 */ -0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, -0x6925, 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, 0x6923, -0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B, 0x6954, -0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, -0x695E, 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, 0x69BF, -0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD, 0x69BB, -0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, -0x69DE, 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, 0x69F2, -0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB, 0x6A0A, -0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, -0x6A78, 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, 0x6A22, -0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3}, -{ /* category 61 */ -0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, -0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, 0x6AFB, 0x6B05, -0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38, 0x6B37, -0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, -0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, 0x6B7F, 0x6B80, -0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, -0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, -0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, 0x6BEF, 0x9EBE, -0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, -0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, 0x6C7E, -0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, 0x6CF1, 0x6CD3, 0x6CBD, -0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE}, -{ /* category 62 */ -0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, -0x6D2B, 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, 0x6D0C, -0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E, 0x6D95, -0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, -0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, 0x6DC5, -0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D, 0x6E6E, -0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, -0x6E76, 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, 0x6EFF, -0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7, 0x6ED3, -0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, -0x6EC2, 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, 0x6EFE, -0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC}, -{ /* category 63 */ -0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, -0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, 0x6F58, 0x6F8E, -0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, -0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, -0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, 0x7001, 0x700F, -0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F, 0x7030, -0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, -0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, 0x70DD, 0x70D9, -0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, -0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, 0x7195, -0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, 0x71D2, 0x71C9, 0x71D4, -0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC}, -{ /* category 64 */ -0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, -0x7230, 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, 0x724B, -0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, -0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, -0x72D2, 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, 0x7317, -0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329, 0x7325, -0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, -0x7378, 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, 0x73BB, -0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F, 0x7425, -0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, -0x745C, 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, 0x748B, -0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1}, -{ /* category 65 */ -0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, -0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, 0x750E, 0x750D, -0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544, 0x754D, -0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, -0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758A, -0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3, 0x75C2, -0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, -0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, 0x75FF, 0x75FC, -0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, -0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630, -0x763B, 0x7647, 0x7648, 0x7646, 0x765C, 0x7658, 0x7661, 0x7662, -0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670}, -{ /* category 66 */ -0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, -0x768E, 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, 0x76B8, -0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE, 0x76E1, -0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, -0x7729, 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, 0x7738, -0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F, 0x777E, -0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, -0x77B9, 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, 0x77D7, -0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812, 0x7926, -0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, -0x788C, 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, 0x78CB, -0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC}, -{ /* category 67 */ -0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, -0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, 0x795A, 0x7955, -0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B, 0x79AA, -0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, -0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, 0x7A20, 0x7A1F, -0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57, 0x7A49, -0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, -0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, 0x7AB0, 0x7AB6, -0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, -0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE6, -0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, 0x7B06, 0x7B33, 0x7B18, -0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50}, -{ /* category 68 */ -0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, -0x7B74, 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, 0x7B98, -0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F, 0x7B5D, -0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, -0x7BE9, 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, 0x7C07, -0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23, 0x7C27, -0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, -0x7C4F, 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, 0x7C65, -0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2, 0x7CAB, -0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, -0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, 0x9B3B, -0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06}, -{ /* category 69 */ -0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, -0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, 0x7D72, 0x7D68, -0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, -0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, -0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, 0x7DB0, 0x7DD8, -0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, -0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, -0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, 0x7E37, 0x7E32, -0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, -0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, 0x8FAE, -0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, 0x7E90, 0x7E93, 0x7E94, -0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A}, -{ /* category 70 */ -0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, -0x7F58, 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, 0x7F82, -0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E, 0x7F9D, -0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, -0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, 0x7FE6, -0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B, 0x8012, -0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, -0x8046, 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, 0x8073, -0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084, 0x8086, -0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, -0x80E5, 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, 0x80EF, -0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B}, -{ /* category 71 */ -0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, -0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, 0x8180, 0x8182, -0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9, 0x81B0, -0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, -0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, 0x81DF, 0x81E0, -0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205, 0x8207, -0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, -0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, 0x8264, 0x8262, -0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, -0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, 0x82E3, -0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, 0x8393, 0x8303, 0x82FB, -0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9}, -{ /* category 72 */ -0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, -0x8345, 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, 0x83AA, -0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A, 0x837C, -0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, -0x83EB, 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, 0x83F7, -0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD, 0x8438, -0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, -0x846B, 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, 0x846F, -0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F, 0x84D9, -0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, -0x8521, 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, 0x8515, -0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548}, -{ /* category 73 */ -0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, -0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, 0x8587, 0x859C, -0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9, 0x85D0, -0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, -0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, 0x863F, 0x864D, -0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3, 0x86A9, -0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, -0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, 0x86EC, 0x86DF, -0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, -0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, 0x8737, -0x873B, 0x8725, 0x8729, 0x871A, 0x8760, 0x875F, 0x8778, 0x874C, -0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759}, -{ /* category 74 */ -0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, -0x87CB, 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, 0x87B3, -0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F, 0x880D, -0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, -0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, 0x8844, -0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881, 0x887E, -0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, -0x88AE, 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, 0x88B1, -0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9, 0x8902, -0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, -0x8943, 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, 0x893B, -0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E}, -{ /* category 75 */ -0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, -0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, 0x89A9, 0x89A6, -0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0, 0x89DA, -0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, -0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, 0x8A5B, 0x8A52, -0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85, 0x8A82, -0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, -0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, 0x8AE7, 0x8AE4, -0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, -0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, 0x8B33, -0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, 0x8B41, 0x8B4C, 0x8B4F, -0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B}, -{ /* category 76 */ -0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, -0x8B92, 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, 0x8C3F, -0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C, 0x8C78, -0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, -0x8C7C, 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, 0x8CB3, -0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA, 0x8CFD, -0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, -0x8D10, 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, 0x8D6D, -0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA, 0x8DCF, -0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, -0x8DE3, 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, 0x8E10, -0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A}, -{ /* category 77 */ -0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, -0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, 0x8E81, 0x8E87, -0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94, 0x8E99, -0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, -0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, 0x8EEB, 0x8EFE, -0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, -0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, -0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, 0x8F5C, 0x8F62, -0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, -0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, 0x9005, -0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, 0x900D, 0x901E, 0x9016, -0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8}, -{ /* category 78 */ -0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, -0x9058, 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, 0x9082, -0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8, 0x90AF, -0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, -0x9119, 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, 0x9165, -0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2, 0x91AB, -0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, -0x91CB, 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, 0x91F5, -0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211, 0x925E, -0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, -0x9250, 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, 0x92B9, -0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E}, -{ /* category 79 */ -0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, -0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, 0x93AD, 0x9394, -0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3, 0x93DD, -0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, -0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, 0x9441, 0x9452, -0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229, 0x9470, -0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, -0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, 0x9599, 0x95A0, -0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, -0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, 0x95DC, -0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, 0x962E, 0x962F, 0x9642, -0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E}, -{ /* category 80 */ -0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, -0x9697, 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, 0x96B6, -0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D, 0x96DC, -0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, -0x9711, 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, 0x9739, -0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975C, -0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, -0x9785, 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, 0x9790, -0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3, 0x97C6, -0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, -0x97F5, 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, 0x983D, -0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870}, -{ /* category 81 */ -0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, -0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, 0x9912, 0x9914, -0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C, 0x992E, -0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, -0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, 0x99AD, 0x99AE, -0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED, 0x99EE, -0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, -0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, 0x9A43, 0x9A3E, -0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, -0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, 0x9ACF, -0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, 0x9AE2, 0x9AE3, 0x9AE6, -0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7}, -{ /* category 82 */ -0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, -0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, 0x9B44, -0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74, 0x9B93, -0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, -0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, 0x9BE3, -0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1, 0x9BF0, -0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, -0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, 0x9C30, -0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67, 0x9C76, -0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, -0x9D06, 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, 0x9D15, -0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48}, -{ /* category 83 */ -0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, -0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, 0x9DA9, 0x9DB2, -0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, -0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, -0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, 0x9E88, 0x9E8B, -0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, -0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, -0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, 0x9EEF, 0x9EF4, -0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, -0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, 0x9F54, -0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, 0x9F67, 0x9F6C, 0x9F6A, -0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0}, -{ /* category 84 */ -0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 85 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 86 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 87 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 88 */ -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -{ /* category 89 */ -0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631, -0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC, 0x4F00, -0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD, -0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, 0x5094, -0x50F4, 0x50D8, 0x514A, 0x5164, 0x519D, 0x51BE, 0x51EC, 0x5215, -0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, 0x5372, -0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF, -0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F, 0xFA10, -0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4, -0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6, -0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, 0x5DB8, -0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7}, -{ /* category 90 */ -0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2, -0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5, 0x6460, -0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, 0x662E, -0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, 0x6699, -0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766, 0x67BB, -0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14, -0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2, -0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, 0x6D04, -0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, 0x6DFC, -0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, 0x6FF5, -0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104, 0x715C, -0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1}, -{ /* category 91 */ -0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, 0x73E3, -0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E, 0x7462, -0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, 0x769B, -0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, 0x787A, -0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B, 0x7AD1, -0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, 0x7DB7, -0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, 0x8362, -0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559, 0x856B, -0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, 0x8A37, -0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, 0x8B7F, -0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24, 0xFA25, -0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA}, -{ /* category 92 */ -0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, 0x9210, -0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, 0x9239, -0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, 0x92D0, -0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, 0xFA28, -0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, 0x93C6, -0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, 0xFA29, -0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, 0x9751, -0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, 0x999E, -0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, 0x9BBB, -0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0x0000, 0x0000, -0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, -0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02}}; + {/* category 01 */ + 0x0000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, + 0x00B4, 0xFF40, 0x00A8, 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD, + 0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C, 0xFF5E, 0x2225, 0xFF5C, 0x2026, + 0x2025, 0x2018, 0x2019, 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, + 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, + 0xFF0D, 0x00B1, 0x00D7, 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, + 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04, 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, + 0xFF06, 0xFF0A, 0xFF20, 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7}, + {/* category 02 */ + 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, 0x2192, 0x2190, + 0x2191, 0x2193, 0x3013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, 0x2229, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2227, 0x2228, 0xFFE2, + 0x21D2, 0x21D4, 0x2200, 0x2203, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, + 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235, 0x222B, 0x222C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, 0x2021, /**/ + 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25EF}, + {/* category 03 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, + 0xFF19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF21, 0xFF22, 0xFF23, 0xFF24, + 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, + 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, + 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, + 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 04 */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, + 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, + 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, + 0x307D, 0x307E, 0x307F, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 05 */ + 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, + 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, + 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, + 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0, + 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, + 0x30DD, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, + 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, + 0x30F5, 0x30F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 06 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, + 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B1, 0x03B2, 0x03B3, 0x03B4, + 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, + 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 07 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, + 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, + 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 08 */ + 0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, 0x2534, 0x253C, 0x2501, + 0x2503, 0x250F, 0x2513, 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, 0x252F, + 0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 09 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 10 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 11 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 12 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 13 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 14 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 15 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 16 */ + 0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, + 0x60AA, 0x63E1, 0x6E25, 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271, 0x5B9B, + 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, + 0x6697, 0x6848, 0x95C7, 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2, 0x5937, + 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, + 0x7DAD, 0x7DEF, 0x80C3, 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5, 0x57DF, + 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, + 0x5370, 0x54BD, 0x54E1, 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D}, + {/* category 17 */ + 0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, + 0x9D5C, 0x7ABA, 0x4E11, 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B, 0x59E5, + 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, + 0x5B30, 0x5F71, 0x6620, 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E, 0x9834, + 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, + 0x698E, 0x53AD, 0x5186, 0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, + 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, + 0x9D1B, 0x5869, 0x65BC, 0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC}, + {/* category 18 */ + 0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, + 0x6C96, 0x837B, 0x5104, 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069, + 0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1, 0x4F73, 0x52A0, 0x53EF, + 0x5609, 0x590F, 0x5AC1, 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B, + 0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377, 0x83EF, 0x83D3, 0x8766, + 0x8AB2, 0x5629, 0x8CA8, 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B, + 0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A, 0x89E3, 0x56DE, 0x584A, + 0x58CA, 0x5EFB, 0x5FEB, 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539}, + {/* category 19 */ + 0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, 0x82A5, 0x87F9, 0x958B, 0x968E, + 0x8C9D, 0x51F1, 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB, + 0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, 0x67FF, 0x86CE, 0x920E, 0x5283, + 0x5687, 0x5404, 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A, + 0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, 0x5CB3, 0x697D, 0x984D, 0x984E, + 0x639B, 0x7B20, 0x6A2B, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, + 0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, + 0x515C, 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431}, + {/* category 20 */ + 0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, + 0x559A, 0x582A, 0x59E6, 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163, 0x61BE, + 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, + 0x7518, 0x76E3, 0x770B, 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266, 0x839E, + 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, + 0x4E38, 0x542B, 0x5CB8, 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1, 0x9811, + 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, + 0x5E0C, 0x5E7E, 0x5FCC, 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4}, + {/* category 21 */ + 0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, + 0x8A18, 0x8CB4, 0x8D77, 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100, 0x5993, + 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, + 0x63AC, 0x83CA, 0x97A0, 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775, 0x9ECD, + 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, + 0x5F13, 0x6025, 0x6551, 0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, + 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, + 0x865A, 0x8A31, 0x8DDD, 0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC}, + {/* category 22 */ + 0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321, 0x537F, 0x53EB, 0x55AC, + 0x5883, 0x5CE1, 0x5F37, 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2, + 0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF, 0x9957, 0x9A5A, 0x4EF0, + 0x51DD, 0x5C2D, 0x6681, 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4, + 0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD, 0x7B4B, 0x7DCA, 0x82B9, + 0x83CC, 0x887F, 0x895F, 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A, + 0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177, 0x611A, 0x865E, 0x55B0, + 0x7A7A, 0x5076, 0x5BD3, 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48}, + {/* category 23 */ + 0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, 0x7C82, 0x6817, 0x7E70, 0x6851, + 0x936C, 0x52F2, 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2, + 0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, 0x5F62, 0x5F84, 0x6075, 0x6176, + 0x6167, 0x61A9, 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, + 0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, 0x8B66, 0x8EFD, 0x981A, 0x9D8F, + 0x82B8, 0x8FCE, 0x9BE8, 0x5287, 0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, + 0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, + 0x5263, 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372}, + {/* category 24 */ + 0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, + 0x8CE2, 0x8ED2, 0x9063, 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3, 0x5E7B, + 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, + 0x53E4, 0x547C, 0x56FA, 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF, 0x6E56, + 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, + 0x9F13, 0x4E94, 0x4E92, 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F, 0x68A7, + 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, + 0x5019, 0x5016, 0x5149, 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411}, + {/* category 25 */ + 0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, + 0x5E83, 0x5E9A, 0x5EB7, 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602, 0x6643, + 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, + 0x786C, 0x7A3F, 0x7CE0, 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1, 0x8154, + 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, + 0x92FC, 0x95A4, 0x964D, 0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, + 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, + 0x9ED2, 0x7344, 0x6F09, 0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC}, + {/* category 26 */ + 0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7, 0x660F, 0x6606, 0x6839, + 0x68B1, 0x6DF7, 0x75D5, 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6, + 0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750, 0x5EA7, 0x632B, 0x50B5, + 0x50AC, 0x518D, 0x6700, 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73, + 0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30, 0x83DC, 0x88C1, 0x8F09, + 0x969B, 0x5264, 0x5728, 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4, + 0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E, 0x6628, 0x6714, 0x67F5, + 0x7A84, 0x7B56, 0x7D22, 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237}, + {/* category 27 */ + 0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, 0x7690, 0x9BD6, 0x634C, 0x9306, + 0x9BAB, 0x76BF, 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6, + 0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, 0x9910, 0x65AC, 0x66AB, 0x6B8B, + 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9, + 0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, 0x652F, 0x5B5C, 0x65AF, 0x65BD, + 0x65E8, 0x679D, 0x6B62, 0x6B7B, 0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, + 0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, + 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642}, + {/* category 28 */ + 0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, + 0x8F9E, 0x6C50, 0x9E7F, 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03, 0x53F1, + 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, + 0x5072, 0x67F4, 0x829D, 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66, 0x659C, + 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, + 0x6753, 0x707C, 0x7235, 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B, 0x53D6, + 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, + 0x53D7, 0x546A, 0x5BFF, 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468}, + {/* category 29 */ + 0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, + 0x81ED, 0x821F, 0x8490, 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C, 0x96C6, + 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, + 0x91CD, 0x9283, 0x53D4, 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F, 0x51FA, + 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, + 0x696F, 0x6B89, 0x6DF3, 0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, + 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, + 0x52A9, 0x53D9, 0x5973, 0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F}, + {/* category 30 */ + 0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968, 0x59BE, 0x5A3C, 0x5BB5, + 0x5C06, 0x5C0F, 0x5C11, 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C, + 0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35, 0x6CBC, 0x6D88, 0x6E09, + 0x6E58, 0x713C, 0x7126, 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11, + 0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F, 0x8A3C, 0x8A54, 0x8A73, + 0x8C61, 0x8CDE, 0x91A4, 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57, + 0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE, 0x6761, 0x6756, 0x6D44, + 0x72B6, 0x7573, 0x7A63, 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE}, + {/* category 31 */ + 0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, 0x98DF, 0x8755, 0x8FB1, 0x5C3B, + 0x4F38, 0x4FE1, 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B, + 0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, 0x79E6, 0x7D33, 0x81E3, 0x82AF, + 0x85AA, 0x89AA, 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875, + 0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, 0x976D, 0x7B25, 0x8ACF, 0x9808, + 0x9162, 0x56F3, 0x53A8, 0x9017, 0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, + 0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, + 0x67A2, 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE}, + {/* category 32 */ + 0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, + 0x6027, 0x6210, 0x653F, 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272, 0x751F, + 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, + 0x9759, 0x6589, 0x7A0E, 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790, 0x77F3, + 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, + 0x6442, 0x6298, 0x8A2D, 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9, 0x5148, + 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, + 0x6D45, 0x6D17, 0x67D3, 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA}, + {/* category 33 */ + 0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, + 0x9291, 0x9583, 0x9BAE, 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3, 0x7CCE, + 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, + 0x79DF, 0x7C97, 0x7D20, 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275, 0x53CC, + 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, + 0x6383, 0x633F, 0x63BB, 0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, + 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, + 0x88C5, 0x8D70, 0x9001, 0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E}, + {/* category 34 */ + 0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F, 0x6349, 0x675F, 0x6E2C, + 0x8DB3, 0x901F, 0x4FD7, 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58, + 0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70, 0x8A51, 0x553E, 0x5815, + 0x59A5, 0x60F0, 0x6253, 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE, + 0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0, 0x6EDE, 0x80CE, 0x817F, + 0x82D4, 0x888B, 0x8CB8, 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C, + 0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258, 0x629E, 0x62D3, 0x6CA2, + 0x6FEF, 0x7422, 0x8A17, 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA}, + {/* category 35 */ + 0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, 0x8FBF, 0x68DA, 0x8C37, 0x72F8, + 0x9C48, 0x6A3D, 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, + 0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, 0x86CB, 0x8A95, 0x935B, 0x56E3, + 0x58C7, 0x5F3E, 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B, + 0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, 0x9045, 0x99B3, 0x7BC9, 0x755C, + 0x7AF9, 0x7B51, 0x84C4, 0x9010, 0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, + 0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, + 0x7026, 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5}, + {/* category 36 */ + 0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, + 0x7252, 0x753A, 0x773A, 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3, 0x929A, + 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, + 0x6D25, 0x589C, 0x690E, 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4, 0x69FB, + 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, + 0x7D2C, 0x722A, 0x540A, 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E, 0x5448, + 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, + 0x6C40, 0x7887, 0x798E, 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013}, + {/* category 37 */ + 0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, + 0x93D1, 0x6EBA, 0x54F2, 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929, 0x5C55, + 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, + 0x96FB, 0x514E, 0x5410, 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21, 0x767B, + 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, + 0x5012, 0x515A, 0x51AC, 0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, + 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, + 0x71C8, 0x5F53, 0x75D8, 0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230}, + {/* category 38 */ + 0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F, 0x9419, 0x9676, 0x982D, + 0x9A30, 0x95D8, 0x50CD, 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5, + 0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3, 0x6D9C, 0x7279, 0x7763, + 0x79BF, 0x7BE4, 0x6BD2, 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6, + 0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C, 0x8C5A, 0x9041, 0x9813, + 0x5451, 0x66C7, 0x920D, 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A, + 0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, + 0x5F10, 0x8FE9, 0x5302, 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165}, + {/* category 39 */ + 0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, 0x79B0, 0x7962, 0x5BE7, 0x8471, + 0x732B, 0x71B1, 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, + 0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, 0x8997, 0x86A4, 0x5DF4, 0x628A, + 0x64AD, 0x8987, 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3, + 0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, 0x80BA, 0x8F29, 0x914D, 0x500D, + 0x57F9, 0x5A92, 0x6885, 0x6973, 0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, + 0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, + 0x8236, 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6}, + {/* category 40 */ + 0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, + 0x9262, 0x6E8C, 0x767A, 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9, 0x567A, + 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, + 0x6C3E, 0x6C4E, 0x7248, 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4, 0x91C6, + 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, + 0x5426, 0x5983, 0x5E87, 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC, 0x75B2, + 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, + 0x6A0B, 0x7C38, 0x5099, 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E}, + {/* category 41 */ + 0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, + 0x7562, 0x7B46, 0x903C, 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, + 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, + 0x9328, 0x92F2, 0x849C, 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, + 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, + 0x6016, 0x6276, 0x6577, 0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, + 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, + 0x5C01, 0x6953, 0x98A8, 0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D}, + {/* category 42 */ + 0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF, 0x7269, 0x9B92, 0x5206, + 0x543B, 0x5674, 0x58B3, 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587, + 0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4, 0x4E26, 0x853D, 0x9589, + 0x965B, 0x7C73, 0x9801, 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F, + 0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9, 0x5A29, 0x5F01, 0x97AD, + 0x4FDD, 0x8217, 0x92EA, 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893, + 0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305, 0x5446, 0x5831, 0x5949, + 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B}, + {/* category 43 */ + 0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, 0x84EC, 0x8702, 0x8912, 0x8A2A, + 0x8C4A, 0x90A6, 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8, + 0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, 0x5192, 0x7D21, 0x80AA, 0x81A8, + 0x8B00, 0x8C8C, 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2, + 0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, 0x5800, 0x5E4C, 0x5954, 0x672C, + 0x7FFB, 0x51E1, 0x76C6, 0x6469, 0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, + 0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, + 0x62B9, 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80}, + {/* category 44 */ + 0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, + 0x7A14, 0x8108, 0x5999, 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB, 0x9727, + 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, + 0x59EA, 0x725D, 0x6EC5, 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21, 0x8302, + 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, + 0x6762, 0x52FF, 0x9905, 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580, 0x5301, + 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, + 0x8A33, 0x8E8D, 0x9756, 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652}, + {/* category 45 */ + 0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, + 0x6709, 0x67DA, 0x6E67, 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A, 0x9091, + 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, + 0x5996, 0x5BB9, 0x5EB8, 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6, 0x7194, + 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, + 0x617E, 0x6291, 0x6B32, 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, + 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, + 0x85CD, 0x862D, 0x89A7, 0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483}, + {/* category 46 */ + 0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB, 0x844E, 0x63A0, 0x7565, + 0x5289, 0x6D41, 0x6E9C, 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E, + 0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599, 0x6881, 0x6DBC, 0x731F, + 0x7642, 0x77AD, 0x7A1C, 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1, + 0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3, 0x9C57, 0x9E9F, 0x7460, + 0x5841, 0x6D99, 0x7D2F, 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2, + 0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6, 0x6B74, 0x5217, 0x52A3, + 0x70C8, 0x88C2, 0x5EC9, 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F}, + {/* category 47 */ + 0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, 0x8DEF, 0x9732, 0x52B4, 0x5A41, + 0x5ECA, 0x5F04, 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E, + 0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, 0x502D, 0x548C, 0x8A71, 0x6B6A, + 0x8CC4, 0x8107, 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900, + 0x6E7E, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 48 */ + 0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, 0x4E42, 0x4E56, 0x4E58, 0x4E82, + 0x4E85, 0x8C6B, 0x4E8A, 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0, 0x4EB3, + 0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, 0x4EED, 0x4EDF, 0x4EF7, 0x4F09, + 0x4F5A, 0x4F30, 0x4F5B, 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B, 0x4F69, + 0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, 0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, + 0x4FDA, 0x4FD0, 0x4FE4, 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C, 0x4FF6, + 0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, + 0x5048, 0x505A, 0x5056, 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2}, + {/* category 49 */ + 0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, 0x50E3, 0x50EE, 0x50F9, 0x50F5, + 0x5109, 0x5101, 0x5102, 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C, 0x513B, + 0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, 0x516A, 0x516E, 0x5180, 0x5182, + 0x56D8, 0x518C, 0x5189, 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2, 0x51A9, + 0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, 0x51C5, 0x51C9, 0x51DB, 0x51E0, + 0x8655, 0x51E9, 0x51ED, 0x51F0, 0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, + 0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, + 0x5273, 0x527F, 0x527D, 0x528D, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8}, + {/* category 50 */ + 0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, 0x52DE, 0x52E3, 0x52E6, 0x98ED, + 0x52E0, 0x52F3, 0x52F5, 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F, 0x5315, + 0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345, 0x4E17, 0x5349, 0x534D, + 0x51D6, 0x535E, 0x5369, 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6, 0x53A5, + 0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, 0x71EE, 0x53EE, 0x53E8, 0x53ED, + 0x53FA, 0x5401, 0x543D, 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D, 0x544E, + 0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, 0x547B, 0x5480, 0x5476, 0x5484, + 0x5490, 0x5486, 0x54C7, 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8}, + {/* category 51 */ + 0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, 0x550F, 0x5514, 0x54FD, 0x54EE, + 0x54ED, 0x54FA, 0x54E2, 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556, 0x5557, + 0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, 0x557B, 0x557E, 0x5598, 0x559E, + 0x55AE, 0x557C, 0x5583, 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC, 0x55E4, + 0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, 0x564E, 0x5650, 0x71DF, 0x5634, + 0x5636, 0x5632, 0x5638, 0x566B, 0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, + 0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, + 0x56CE, 0x56D1, 0x56D3, 0x56D7, 0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709}, + {/* category 52 */ + 0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, 0x5726, 0x5737, 0x5738, 0x574E, + 0x573B, 0x5740, 0x574F, 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0, 0x57B3, + 0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, 0x580A, 0x57D6, 0x57E3, 0x580B, + 0x5819, 0x581D, 0x5872, 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879, 0x5885, + 0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, 0x58C5, 0x58D3, 0x58D1, 0x58D7, + 0x58D9, 0x58D8, 0x58E5, 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC, 0x58FD, + 0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, 0x5932, 0x5938, 0x593E, 0x7AD2, + 0x5955, 0x5950, 0x594E, 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969}, + {/* category 53 */ + 0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, 0x59E8, 0x59DC, 0x598D, 0x59D9, + 0x59DA, 0x5A25, 0x5A1F, 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35, 0x5A36, + 0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, + 0x5AD6, 0x5AFA, 0x5AFB, 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, + 0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, 0x5B70, 0x5B73, 0x5B75, 0x5B78, + 0x6588, 0x5B7A, 0x5B80, 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, + 0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, + 0x5C13, 0x5C20, 0x5C22, 0x5C28, 0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53}, + {/* category 54 */ + 0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, 0x5C8C, 0x5C91, 0x5C94, 0x599B, + 0x5CAB, 0x5CBB, 0x5CB6, 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD, 0x5CFA, + 0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, 0x5D1B, 0x5D11, 0x5D14, 0x5D22, + 0x5D1A, 0x5D19, 0x5D18, 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87, 0x5D84, + 0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, 0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, + 0x5DD2, 0x5DD6, 0x5DDB, 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B, 0x5E36, + 0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, 0x5E62, 0x5E64, 0x5E47, 0x5E75, + 0x5E76, 0x5E7A, 0x9EBC, 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF}, + {/* category 55 */ + 0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, + 0x5EF0, 0x5EF4, 0x5EF8, 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16, 0x5F29, + 0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, 0x5F56, 0x5F57, 0x5F59, 0x5F61, + 0x5F6D, 0x5F73, 0x5F77, 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E, 0x5F99, + 0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, + 0x5FFF, 0x6021, 0x6060, 0x6019, 0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, + 0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, + 0x6064, 0x6042, 0x606C, 0x606B, 0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A}, + {/* category 56 */ + 0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, 0x60B8, 0x60E0, 0x60D3, 0x60B4, + 0x5FF0, 0x60BD, 0x60C6, 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100, 0x60F4, + 0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, 0x613E, 0x6128, 0x6127, 0x614A, + 0x613F, 0x613C, 0x612C, 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615A, + 0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, + 0x61AC, 0x6194, 0x619A, 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7, 0x61C8, + 0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, 0x61F6, 0x61FA, 0x61F4, 0x61FF, + 0x61FD, 0x61FC, 0x61FE, 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B}, + {/* category 57 */ + 0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, 0x624E, 0x625E, 0x6263, 0x625B, + 0x6260, 0x6268, 0x627C, 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283, 0x6294, + 0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, 0x62DC, 0x62CC, 0x62CA, 0x62C2, + 0x62C7, 0x629B, 0x62C9, 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5, 0x6350, + 0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, 0x6376, 0x63A3, 0x638F, 0x6389, + 0x639F, 0x63B5, 0x636B, 0x6369, 0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, + 0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, + 0x646F, 0x6476, 0x644E, 0x652A, 0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC}, + {/* category 58 */ + 0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, 0x64E7, 0x8209, 0x64E0, 0x64E1, + 0x62AC, 0x64E3, 0x64EF, 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518, 0x651C, + 0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538, 0x754B, 0x6548, 0x6556, + 0x6555, 0x654D, 0x6558, 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B, 0x659F, + 0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, 0x65DB, 0x65D9, 0x65E0, 0x65E1, + 0x65F1, 0x6772, 0x660A, 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F, 0x6644, + 0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, 0x6662, 0x6670, 0x6683, 0x6688, + 0x668E, 0x6689, 0x6684, 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC}, + {/* category 59 */ + 0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, 0x66F0, 0x66F5, 0x66F7, 0x670F, + 0x6716, 0x671E, 0x6726, 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746, + 0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, 0x677C, 0x676A, 0x678C, 0x678B, + 0x67A6, 0x67A1, 0x6785, 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4, 0x67DE, + 0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, 0x681E, 0x6846, 0x6829, 0x6840, + 0x684D, 0x6832, 0x684E, 0x68B3, 0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, + 0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, + 0x687E, 0x6901, 0x68CA, 0x6908, 0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD}, + {/* category 60 */ + 0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, 0x6925, 0x68F9, 0x68E0, 0x68EF, + 0x6928, 0x692A, 0x691A, 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B, 0x6954, + 0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, 0x695E, 0x695D, 0x6981, 0x696A, + 0x69B2, 0x69AE, 0x69D0, 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD, 0x69BB, + 0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, 0x69DE, 0x69E8, 0x6A02, 0x6A1B, + 0x69FF, 0x6B0A, 0x69F9, 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB, 0x6A0A, + 0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, 0x6A78, 0x6A47, 0x6A62, 0x6A59, + 0x6A66, 0x6A48, 0x6A38, 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3}, + {/* category 61 */ + 0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, + 0x6ADA, 0x6AEA, 0x6AFB, 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38, 0x6B37, + 0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, + 0x6B78, 0x6B79, 0x6B7F, 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, + 0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, + 0x6BEB, 0x6BF3, 0x6BEF, 0x9EBE, 0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, + 0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, + 0x6CC4, 0x6CF1, 0x6CD3, 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE}, + {/* category 62 */ + 0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, 0x6D2B, 0x6D3D, 0x6D38, 0x6D19, + 0x6D35, 0x6D33, 0x6D12, 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E, 0x6D95, + 0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, 0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, + 0x6DCC, 0x6DE8, 0x6DD2, 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D, 0x6E6E, + 0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, 0x6E76, 0x6E4D, 0x6E1F, 0x6E43, + 0x6E3A, 0x6E4E, 0x6E24, 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7, 0x6ED3, + 0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, 0x6EC2, 0x6E9F, 0x6F41, 0x6F11, + 0x704C, 0x6EEC, 0x6EF8, 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC}, + {/* category 63 */ + 0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, + 0x6F82, 0x6F7C, 0x6F58, 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, + 0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, 0x6FEE, 0x6FDB, 0x7009, 0x700B, + 0x6FFA, 0x7011, 0x7001, 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F, 0x7030, + 0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, 0x70AC, 0x70B8, 0x70B3, 0x70AE, + 0x70DF, 0x70CB, 0x70DD, 0x70D9, 0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, + 0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, + 0x71BE, 0x71D2, 0x71C9, 0x71D4, 0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC}, + {/* category 64 */ + 0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, 0x7230, 0x7232, 0x723B, 0x723C, + 0x723F, 0x7240, 0x7246, 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, + 0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, 0x72D2, 0x72E2, 0x72E0, 0x72E1, + 0x72F9, 0x72F7, 0x500F, 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329, 0x7325, + 0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, 0x7378, 0x7375, 0x737B, 0x737A, + 0x73C8, 0x73B3, 0x73CE, 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F, 0x7425, + 0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, 0x745C, 0x7469, 0x7470, 0x7463, + 0x746A, 0x7476, 0x747E, 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1}, + {/* category 65 */ + 0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, 0x74F8, 0x74F7, 0x7504, 0x7503, + 0x7505, 0x750C, 0x750E, 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544, 0x754D, + 0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, 0x756B, 0x756D, 0x7578, 0x7576, + 0x7586, 0x7587, 0x7574, 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3, 0x75C2, + 0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, 0x75CA, 0x75D2, 0x75D9, 0x75E3, + 0x75DE, 0x75FE, 0x75FF, 0x75FC, 0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, + 0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, + 0x765C, 0x7658, 0x7661, 0x7662, 0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670}, + {/* category 66 */ + 0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, 0x768E, 0x7696, 0x7693, 0x7699, + 0x769A, 0x76B0, 0x76B4, 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE, 0x76E1, + 0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, 0x7729, 0x7724, 0x771E, 0x7725, + 0x7726, 0x771B, 0x7737, 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F, 0x777E, + 0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, 0x77B9, 0x77BF, 0x77BC, 0x77BD, + 0x77BB, 0x77C7, 0x77CD, 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812, 0x7926, + 0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, 0x788C, 0x78A3, 0x78B5, 0x78AA, + 0x78AF, 0x78D1, 0x78C6, 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC}, + {/* category 67 */ + 0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, 0x792C, 0x792B, 0x7940, 0x7960, + 0x7957, 0x795F, 0x795A, 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B, 0x79AA, + 0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, 0x79E1, 0x79E3, 0x7A08, 0x7A0D, + 0x7A18, 0x7A19, 0x7A20, 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57, 0x7A49, + 0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, 0x7A97, 0x7A95, 0x7A98, 0x7A96, + 0x7AA9, 0x7AC8, 0x7AB0, 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, + 0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, + 0x7B0A, 0x7B06, 0x7B33, 0x7B18, 0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50}, + {/* category 68 */ + 0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, 0x7B74, 0x7B67, 0x7B70, 0x7B71, + 0x7B6C, 0x7B6E, 0x7B9D, 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F, 0x7B5D, + 0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, 0x7BE9, 0x7C11, 0x7C14, 0x7BE6, + 0x7BE5, 0x7C60, 0x7C00, 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23, 0x7C27, + 0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, 0x7C4F, 0x7C40, 0x7C50, 0x7C58, + 0x7C5F, 0x7C64, 0x7C56, 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2, 0x7CAB, + 0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, 0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, + 0x7CD2, 0x7CDC, 0x7CE2, 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06}, + {/* category 69 */ + 0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, 0x7D3F, 0x7D35, 0x7D46, 0x7D73, + 0x7D56, 0x7D4E, 0x7D72, 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, + 0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, + 0x7DB8, 0x7D9F, 0x7DB0, 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, + 0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, 0x7E46, 0x7E66, 0x7E3B, 0x7E35, + 0x7E39, 0x7E43, 0x7E37, 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, + 0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, + 0x7E92, 0x7E90, 0x7E93, 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A}, + {/* category 70 */ + 0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, 0x7F58, 0x7F5F, 0x7F60, 0x7F68, + 0x7F69, 0x7F67, 0x7F78, 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E, 0x7F9D, + 0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, 0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, + 0x7FD5, 0x7FD4, 0x7FE1, 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B, 0x8012, + 0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, 0x8046, 0x8052, 0x8058, 0x805A, + 0x805F, 0x8062, 0x8068, 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084, 0x8086, + 0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, 0x80E5, 0x80D9, 0x80DD, 0x80C4, + 0x80DA, 0x80D6, 0x8109, 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B}, + {/* category 71 */ + 0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, 0x8165, 0x8166, 0x8174, 0x8183, + 0x8188, 0x818A, 0x8180, 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9, 0x81B0, + 0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, 0x81CD, 0x81D1, 0x81D9, 0x81D8, + 0x81C8, 0x81DA, 0x81DF, 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205, 0x8207, + 0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, 0x8240, 0x8259, 0x8258, 0x825D, + 0x825A, 0x825F, 0x8264, 0x8262, 0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, + 0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, + 0x82FA, 0x8393, 0x8303, 0x82FB, 0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9}, + {/* category 72 */ + 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345, 0x832F, 0x832B, 0x8317, + 0x8318, 0x8385, 0x839A, 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A, 0x837C, + 0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, 0x83EB, 0x83CE, 0x83FD, 0x8403, + 0x83D8, 0x840B, 0x83C1, 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD, 0x8438, + 0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, 0x846B, 0x84AD, 0x846E, 0x8482, + 0x8469, 0x8446, 0x842C, 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F, 0x84D9, + 0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, 0x8521, 0x84FF, 0x84F4, 0x8517, + 0x8518, 0x852C, 0x851F, 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548}, + {/* category 73 */ + 0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, 0x858A, 0x85A8, 0x856D, 0x8594, + 0x859B, 0x85EA, 0x8587, 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9, 0x85D0, + 0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, 0x85FE, 0x85FA, 0x8606, 0x8622, + 0x861A, 0x8630, 0x863F, 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3, 0x86A9, + 0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, 0x86C9, 0x8823, 0x86AB, 0x86D4, + 0x86DE, 0x86E9, 0x86EC, 0x86DF, 0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, + 0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, + 0x8760, 0x875F, 0x8778, 0x874C, 0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759}, + {/* category 74 */ + 0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, 0x87CB, 0x87BD, 0x87C0, 0x87D0, + 0x96D6, 0x87AB, 0x87C4, 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F, 0x880D, + 0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, + 0x8839, 0x8827, 0x883B, 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881, 0x887E, + 0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88AE, 0x8899, 0x88A2, 0x888D, + 0x88A4, 0x88B0, 0x88BF, 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9, 0x8902, + 0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, 0x8943, 0x891E, 0x8925, 0x892A, + 0x892B, 0x8941, 0x8944, 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E}, + {/* category 75 */ + 0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, 0x8983, 0x8988, 0x898A, 0x8993, + 0x8998, 0x89A1, 0x89A9, 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0, 0x89DA, + 0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, + 0x8A36, 0x8A41, 0x8A5B, 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85, 0x8A82, + 0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, + 0x8AEB, 0x8AF3, 0x8AE7, 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, + 0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, + 0x8B28, 0x8B41, 0x8B4C, 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B}, + {/* category 76 */ + 0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, 0x8B92, 0x8B93, 0x8B96, 0x8B99, + 0x8B9A, 0x8C3A, 0x8C41, 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C, 0x8C78, + 0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, 0x8C7C, 0x8C98, 0x621D, 0x8CAD, + 0x8CAA, 0x8CBD, 0x8CB2, 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA, 0x8CFD, + 0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, 0x8D10, 0x9F4E, 0x8D13, 0x8CCD, + 0x8D14, 0x8D16, 0x8D67, 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA, 0x8DCF, + 0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, 0x8DE3, 0x8DFC, 0x8E08, 0x8E09, + 0x8DFF, 0x8E1D, 0x8E1E, 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A}, + {/* category 77 */ + 0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, 0x8E2A, 0x8E63, 0x8E55, 0x8E76, + 0x8E72, 0x8E7C, 0x8E81, 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94, 0x8E99, + 0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, + 0x8EFC, 0x8EFB, 0x8EEB, 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, + 0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, + 0x8F4E, 0x8F57, 0x8F5C, 0x8F62, 0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, + 0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, + 0x9021, 0x900D, 0x901E, 0x9016, 0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8}, + {/* category 78 */ + 0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, 0x9058, 0x905E, 0x9068, 0x906F, + 0x9076, 0x96A8, 0x9072, 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8, 0x90AF, + 0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, 0x9119, 0x9132, 0x9130, 0x914A, + 0x9156, 0x9158, 0x9163, 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2, 0x91AB, + 0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, 0x91CB, 0x91D0, 0x91D6, 0x91DF, + 0x91E1, 0x91DB, 0x91FC, 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211, 0x925E, + 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, 0x9250, 0x929C, 0x9296, 0x9293, + 0x929B, 0x925A, 0x92CF, 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E}, + {/* category 79 */ + 0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, 0x9360, 0x937C, 0x936E, 0x9356, + 0x93B0, 0x93AC, 0x93AD, 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3, 0x93DD, + 0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, 0x9410, 0x9436, 0x942B, 0x9435, + 0x9421, 0x943A, 0x9441, 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229, 0x9470, + 0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, 0x9582, 0x9587, 0x958A, 0x9594, + 0x9596, 0x9598, 0x9599, 0x95A0, 0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, + 0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, + 0x9628, 0x962E, 0x962F, 0x9642, 0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E}, + {/* category 80 */ + 0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, 0x9697, 0x96AA, 0x96A7, 0x96B1, + 0x96B2, 0x96B0, 0x96B4, 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D, 0x96DC, + 0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, 0x9711, 0x970F, 0x9716, 0x9719, + 0x9724, 0x972A, 0x9730, 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975C, + 0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, 0x9785, 0x977C, 0x9781, 0x977A, + 0x9786, 0x978B, 0x978F, 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3, 0x97C6, + 0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, 0x97F5, 0x980F, 0x980C, 0x9838, + 0x9824, 0x9821, 0x9837, 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870}, + {/* category 81 */ + 0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, 0x98C3, 0x98C6, 0x98E9, 0x98EB, + 0x9903, 0x9909, 0x9912, 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C, 0x992E, + 0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, 0x9952, 0x994C, 0x9955, 0x9997, + 0x9998, 0x99A5, 0x99AD, 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED, 0x99EE, + 0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, 0x9A19, 0x9A2B, 0x9A37, 0x9A45, + 0x9A42, 0x9A40, 0x9A43, 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, + 0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, + 0x9ADF, 0x9AE2, 0x9AE3, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7}, + {/* category 82 */ + 0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, + 0x9B2E, 0x9B2F, 0x9B32, 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74, 0x9B93, + 0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, 0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, + 0x9BCF, 0x9BD1, 0x9BD2, 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1, 0x9BF0, + 0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, 0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, + 0x9C25, 0x9C24, 0x9C21, 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67, 0x9C76, + 0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, 0x9D06, 0x9D2A, 0x9D26, 0x9DAF, + 0x9D23, 0x9D1F, 0x9D44, 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48}, + {/* category 83 */ + 0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, + 0x9D9A, 0x9DA4, 0x9DA9, 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, + 0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, + 0x9E7D, 0x9E81, 0x9E88, 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, + 0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, + 0x9EE5, 0x9EE8, 0x9EEF, 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, + 0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, + 0x9F66, 0x9F67, 0x9F6C, 0x9F6A, 0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0}, + {/* category 84 */ + 0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 85 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 86 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 87 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 88 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {/* category 89 */ + 0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631, 0x68C8, 0x92F9, 0x66FB, 0x5F45, + 0x4E28, 0x4EE1, 0x4EFC, 0x4F00, 0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD, + 0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, 0x5094, 0x50F4, 0x50D8, 0x514A, 0x5164, + 0x519D, 0x51BE, 0x51EC, 0x5215, 0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, 0x5372, + 0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF, 0x5586, 0x5759, 0x5765, 0x57AC, + 0x57C8, 0x57C7, 0xFA0F, 0xFA10, 0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4, + 0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6, 0x5CBA, 0x5CF5, 0x5D27, 0x5D53, + 0xFA11, 0x5D42, 0x5D6D, 0x5DB8, 0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7}, + {/* category 90 */ + 0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2, 0x6111, 0x6137, 0x6130, 0x6198, + 0x6213, 0x62A6, 0x63F5, 0x6460, 0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, 0x662E, + 0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, 0x6699, 0x66A0, 0x66B2, 0x66BF, 0x66FA, + 0x670E, 0xF929, 0x6766, 0x67BB, 0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14, + 0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, + 0x6C86, 0x6C6F, 0x6CDA, 0x6D04, 0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, 0x6DFC, + 0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, 0x6FF5, 0x7005, 0x7007, 0x7028, 0x7085, + 0x70AB, 0x710F, 0x7104, 0x715C, 0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1}, + {/* category 91 */ + 0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, 0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, + 0x742A, 0x7429, 0x742E, 0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, 0x769B, + 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, 0x787A, 0x7930, 0xFA18, 0xFA19, 0xFA1A, + 0x7994, 0xFA1B, 0x799B, 0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, 0x7DB7, + 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, 0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, + 0x84B4, 0x8553, 0x8559, 0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, 0x8A37, + 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, 0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, + 0xFA23, 0x8ECF, 0xFA24, 0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA}, + {/* category 92 */ + 0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, + 0x924E, 0x9259, 0x9251, 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, 0x92D0, + 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, + 0x9370, 0x9357, 0x93A4, 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, 0xFA29, + 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, + 0xFA2B, 0x9927, 0xFA2C, 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, 0x9BBB, + 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0x0000, 0x0000, 0x2170, 0x2171, 0x2172, 0x2173, + 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02}}; #endif /* JISX0208_H */ diff --git a/ext/gd/libgd/pngtogd.c b/ext/gd/libgd/pngtogd.c index b663b170b710..6c90db66dcbd 100644 --- a/ext/gd/libgd/pngtogd.c +++ b/ext/gd/libgd/pngtogd.c @@ -1,45 +1,40 @@ -#include #include "gd.h" +#include /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in, *out; - if (argc != 3) - { - fprintf (stderr, "Usage: pngtogd filename.png filename.gd\n"); - exit (1); + gdImagePtr im; + FILE *in, *out; + if (argc != 3) { + fprintf(stderr, "Usage: pngtogd filename.png filename.gd\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromPng (in); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in PNG format!\n"); - exit (1); + im = gdImageCreateFromPng(in); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in PNG format!\n"); + exit(1); } - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } - gdImageGd (im, out); - fclose (out); - gdImageDestroy (im); + gdImageGd(im, out); + fclose(out); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/pngtogd2.c b/ext/gd/libgd/pngtogd2.c index c8b1d843af13..75f52c0dcd6b 100644 --- a/ext/gd/libgd/pngtogd2.c +++ b/ext/gd/libgd/pngtogd2.c @@ -1,52 +1,47 @@ +#include "gd.h" #include #include -#include "gd.h" /* A short program which converts a .png file into a .gd file, for your convenience in creating images on the fly from a basis image that must be loaded quickly. The .gd format is not intended to be a general-purpose format. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - gdImagePtr im; - FILE *in, *out; - int cs, fmt; + gdImagePtr im; + FILE *in, *out; + int cs, fmt; - if (argc != 5) - { - fprintf (stderr, "Usage: pngtogd2 filename.png filename.gd2 cs fmt\n"); - fprintf (stderr, " where cs is the chunk size\n"); - fprintf (stderr, " fmt is 1 for raw, 2 for compressed\n"); - exit (1); + if (argc != 5) { + fprintf(stderr, "Usage: pngtogd2 filename.png filename.gd2 cs fmt\n"); + fprintf(stderr, " where cs is the chunk size\n"); + fprintf(stderr, " fmt is 1 for raw, 2 for compressed\n"); + exit(1); } - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Input file does not exist!\n"); - exit (1); + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Input file does not exist!\n"); + exit(1); } - im = gdImageCreateFromPng (in); - fclose (in); - if (!im) - { - fprintf (stderr, "Input is not in PNG format!\n"); - exit (1); + im = gdImageCreateFromPng(in); + fclose(in); + if (!im) { + fprintf(stderr, "Input is not in PNG format!\n"); + exit(1); } - out = fopen (argv[2], "wb"); - if (!out) - { - fprintf (stderr, "Output file cannot be written to!\n"); - gdImageDestroy (im); - exit (1); + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "Output file cannot be written to!\n"); + gdImageDestroy(im); + exit(1); } - cs = atoi (argv[3]); - fmt = atoi (argv[4]); - gdImageGd2 (im, out, cs, fmt); - fclose (out); - gdImageDestroy (im); + cs = atoi(argv[3]); + fmt = atoi(argv[4]); + gdImageGd2(im, out, cs, fmt); + fclose(out); + gdImageDestroy(im); - return 0; + return 0; } diff --git a/ext/gd/libgd/testac.c b/ext/gd/libgd/testac.c index 30c54e1641fa..31300784d9d7 100644 --- a/ext/gd/libgd/testac.c +++ b/ext/gd/libgd/testac.c @@ -1,129 +1,108 @@ -#include #include "gd.h" +#include /* If palette is true, we convert from truecolor to palette at the end, to test gdImageTrueColorToPalette and see file size/ quality tradeoffs. */ -void testDrawing ( - gdImagePtr im_in, - double scale, - int blending, - int palette, - char *filename); +void testDrawing(gdImagePtr im_in, double scale, int blending, int palette, char *filename); -int -main (int argc, char *argv[]) +int main(int argc, char *argv[]) { - /* Input and output files */ - FILE *in; - FILE *out; + /* Input and output files */ + FILE *in; + FILE *out; - /* Input image */ - gdImagePtr im_in = 0; + /* Input image */ + gdImagePtr im_in = 0; - /* Colors */ - int lightBlue; + /* Colors */ + int lightBlue; - if (argc != 2) - { - fprintf (stderr, "Usage: testac filename.png\n"); - exit (1); - } - /* Load original PNG, which should contain alpha channel - information. We will use it in two ways: preserving it - literally, for use with compatible browsers, and - compositing it ourselves against a background of our - choosing (alpha blending). We'll change its size - and try creating palette versions of it. */ - in = fopen (argv[1], "rb"); - if (!in) - { - fprintf (stderr, "Can't load %s.\n", argv[1]); - exit (1); + if (argc != 2) { + fprintf(stderr, "Usage: testac filename.png\n"); + exit(1); } - else - { - im_in = gdImageCreateFromPng (in); - fclose (in); + /* Load original PNG, which should contain alpha channel + information. We will use it in two ways: preserving it + literally, for use with compatible browsers, and + compositing it ourselves against a background of our + choosing (alpha blending). We'll change its size + and try creating palette versions of it. */ + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Can't load %s.\n", argv[1]); + exit(1); + } else { + im_in = gdImageCreateFromPng(in); + fclose(in); } - testDrawing (im_in, 1.0, 0, 0, "noblending-fullsize-truecolor.png"); - testDrawing (im_in, 1.0, 1, 0, "blending-fullsize-truecolor.png"); - testDrawing (im_in, 0.5, 0, 0, "noblending-halfsize-truecolor.png"); - testDrawing (im_in, 0.5, 1, 0, "blending-halfsize-truecolor.png"); - testDrawing (im_in, 2.0, 0, 0, "noblending-doublesize-truecolor.png"); - testDrawing (im_in, 2.0, 1, 0, "blending-doublesize-truecolor.png"); - testDrawing (im_in, 1.0, 0, 1, "noblending-fullsize-palette.png"); - testDrawing (im_in, 1.0, 1, 1, "blending-fullsize-palette.png"); - testDrawing (im_in, 0.5, 0, 1, "noblending-halfsize-palette.png"); - testDrawing (im_in, 0.5, 1, 1, "blending-halfsize-palette.png"); - testDrawing (im_in, 2.0, 0, 1, "noblending-doublesize-palette.png"); - testDrawing (im_in, 2.0, 1, 1, "blending-doublesize-palette.png"); - gdImageDestroy (im_in); - return 0; + testDrawing(im_in, 1.0, 0, 0, "noblending-fullsize-truecolor.png"); + testDrawing(im_in, 1.0, 1, 0, "blending-fullsize-truecolor.png"); + testDrawing(im_in, 0.5, 0, 0, "noblending-halfsize-truecolor.png"); + testDrawing(im_in, 0.5, 1, 0, "blending-halfsize-truecolor.png"); + testDrawing(im_in, 2.0, 0, 0, "noblending-doublesize-truecolor.png"); + testDrawing(im_in, 2.0, 1, 0, "blending-doublesize-truecolor.png"); + testDrawing(im_in, 1.0, 0, 1, "noblending-fullsize-palette.png"); + testDrawing(im_in, 1.0, 1, 1, "blending-fullsize-palette.png"); + testDrawing(im_in, 0.5, 0, 1, "noblending-halfsize-palette.png"); + testDrawing(im_in, 0.5, 1, 1, "blending-halfsize-palette.png"); + testDrawing(im_in, 2.0, 0, 1, "noblending-doublesize-palette.png"); + testDrawing(im_in, 2.0, 1, 1, "blending-doublesize-palette.png"); + gdImageDestroy(im_in); + return 0; } /* If palette is true, we convert from truecolor to palette at the end, to test gdImageTrueColorToPalette and see file size/ quality tradeoffs. */ -void -testDrawing ( - gdImagePtr im_in, - double scale, - int blending, - int palette, - char *filename) +void testDrawing(gdImagePtr im_in, double scale, int blending, int palette, char *filename) { - gdImagePtr im_out; - FILE *out; - /* Create output image. */ - im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale), - (int) (gdImageSY (im_in) * scale)); - /* - Request alpha blending. This causes future - drawing operations to perform alpha channel blending - with the background, resulting in an opaque image. - Without this call, pixels in the foreground color are - copied literally, *including* the alpha channel value, - resulting in an output image which is potentially - not opaque. This flag can be set and cleared as often - as desired. */ - gdImageAlphaBlending (im_out, blending); + gdImagePtr im_out; + FILE *out; + /* Create output image. */ + im_out = + gdImageCreateTrueColor((int)(gdImageSX(im_in) * scale), (int)(gdImageSY(im_in) * scale)); + /* + Request alpha blending. This causes future + drawing operations to perform alpha channel blending + with the background, resulting in an opaque image. + Without this call, pixels in the foreground color are + copied literally, *including* the alpha channel value, + resulting in an output image which is potentially + not opaque. This flag can be set and cleared as often + as desired. */ + gdImageAlphaBlending(im_out, blending); - /* Flood with light blue. */ - gdImageFill (im_out, (int) (gdImageSX (im_in) * scale / 2), - (int) (gdImageSY (im_in) * scale / 2), - gdTrueColor (192, 192, 255)); - /* Copy the source image. Alpha blending should result in - compositing against red. With blending turned off, the - browser or viewer will composite against its preferred - background, or, if it does not support an alpha channel, - we will see the original colors for the pixels that - ought to be transparent or semitransparent. */ - gdImageCopyResampled (im_out, im_in, - 0, 0, - 0, 0, - (int) (gdImageSX (im_in) * scale), (int) (gdImageSY (im_in) * scale), - gdImageSX (im_in), gdImageSY (im_in)); - /* Write PNG */ - out = fopen (filename, "wb"); + /* Flood with light blue. */ + gdImageFill(im_out, (int)(gdImageSX(im_in) * scale / 2), (int)(gdImageSY(im_in) * scale / 2), + gdTrueColor(192, 192, 255)); + /* Copy the source image. Alpha blending should result in + compositing against red. With blending turned off, the + browser or viewer will composite against its preferred + background, or, if it does not support an alpha channel, + we will see the original colors for the pixels that + ought to be transparent or semitransparent. */ + gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0, (int)(gdImageSX(im_in) * scale), + (int)(gdImageSY(im_in) * scale), gdImageSX(im_in), gdImageSY(im_in)); + /* Write PNG */ + out = fopen(filename, "wb"); - /* If this image is the result of alpha channel blending, - it will not contain an interesting alpha channel itself. - Save a little file size by not saving the alpha channel. - Otherwise the file would typically be slightly larger. */ - gdImageSaveAlpha (im_out, !blending); + /* If this image is the result of alpha channel blending, + it will not contain an interesting alpha channel itself. + Save a little file size by not saving the alpha channel. + Otherwise the file would typically be slightly larger. */ + gdImageSaveAlpha(im_out, !blending); - /* If requested, convert from truecolor to palette. */ - if (palette) - { - /* Dithering, 256 colors. */ - gdImageTrueColorToPalette (im_out, 1, 256); + /* If requested, convert from truecolor to palette. */ + if (palette) { + /* Dithering, 256 colors. */ + gdImageTrueColorToPalette(im_out, 1, 256); } - gdImagePng (im_out, out); - fclose (out); + gdImagePng(im_out, out); + fclose(out); - gdImageDestroy (im_out); + gdImageDestroy(im_out); } diff --git a/ext/gd/libgd/wbmp.c b/ext/gd/libgd/wbmp.c index dbca0f0178c6..cc237130ee76 100644 --- a/ext/gd/libgd/wbmp.c +++ b/ext/gd/libgd/wbmp.c @@ -1,389 +1,324 @@ - /* WBMP - ** ---- - ** WBMP Level 0: B/W, Uncompressed - ** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2. - ** It does not support ExtHeaders as defined in the spec. The spec states - ** that a WAP client does not need to implement ExtHeaders. - ** - ** (c) 2000 Johan Van den Brande + * ---- + * WBMP Level 0: B/W, Uncompressed + * This implements the WBMP format as specified in WAPSpec 1.1 and 1.2. + * It does not support ExtHeaders as defined in the spec. The spec states + * that a WAP client does not need to implement ExtHeaders. + * + * (c) 2000 Johan Van den Brande */ - -#include #include +#include #include #include -#include "wbmp.h" #include "gd.h" #include "gdhelpers.h" +#include "wbmp.h" #ifdef NOTDEF -#define __TEST /* Compile with main function */ -#define __DEBUG /* Extra verbose when with __TEST */ -#define __WRITE /* readwbmp and writewbmp(stdout) */ -#define __VIEW /* view the wbmp on stdout */ +#define __TEST /* Compile with main function */ +#define __DEBUG /* Extra verbose when with __TEST */ +#define __WRITE /* readwbmp and writewbmp(stdout) */ +#define __VIEW /* view the wbmp on stdout */ #endif /* getmbi - ** ------ - ** Get a multibyte integer from a generic getin function - ** 'getin' can be getc, with in = NULL - ** you can find getin as a function just above the main function - ** This way you gain a lot of flexibilty about how this package - ** reads a wbmp file. + * ------ + * Get a multibyte integer from a generic getin function + * 'getin' can be getc, with in = NULL + * you can find getin as a function just above the main function + * This way you gain a lot of flexibility about how this package + * reads a wbmp file. */ -int -getmbi (int (*getin) (void *in), void *in) +int getmbi(int (*getin)(void *in), void *in) { - unsigned int mbi = 0; - int i; - - do - { - i = getin (in); - if (i < 0) - return (-1); - mbi = (mbi << 7) | (i & 0x7f); - } - while (i & 0x80); - - return (mbi); + unsigned int mbi = 0; + int i; + + do { + i = getin(in); + if (i < 0) { + return (-1); + } + mbi = (mbi << 7) | (i & 0x7f); + } while (i & 0x80); + + return mbi; } - /* putmbi - ** ------ - ** Put a multibyte intgerer in some kind of output stream - ** I work here with a function pointer, to make it as generic - ** as possible. Look at this function as an iterator on the - ** mbi integers it spits out. - ** + * ------ + * Put a multibyte intgerer in some kind of output stream + * I work here with a function pointer, to make it as generic + * as possible. Look at this function as an iterator on the + * mbi integers it spits out. + * */ -void -putmbi (int i, void (*putout) (int c, void *out), void *out) +void putmbi(int i, void (*putout)(int c, void *out), void *out) { - int cnt, l, accu; + int cnt, l, accu; - /* Get number of septets */ - cnt = 0; - accu = 0; - while (accu != i) - accu += i & 0x7f << 7 * cnt++; - - /* Produce the multibyte output */ - for (l = cnt - 1; l > 0; l--) - putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out); + /* Get number of septets */ + accu = cnt = 0; + while (accu != i) { + accu += i & 0x7f << 7 * cnt++; + } - putout (i & 0x7f, out); + /* Produce the multibyte output */ + for (l = cnt - 1; l > 0; l--) { + putout(0x80 | (i & 0x7f << 7 * l) >> 7 * l, out); + } + putout(i & 0x7f, out); } - - /* skipheader - ** ---------- - ** Skips the ExtHeader. Not needed for the moment - ** + * ---------- + * Skips the ExtHeader. Not needed for the moment */ -int -skipheader (int (*getin) (void *in), void *in) +int skipheader(int (*getin)(void *in), void *in) { - int i; + int i; - do - { - i = getin (in); - if (i < 0) - return (-1); - } - while (i & 0x80); + do { + i = getin(in); + if (i < 0) { + return (-1); + } + } while (i & 0x80); - return (0); + return 0; } /* create wbmp - ** ----------- - ** create an empty wbmp - ** + * ----------- + * create an empty wbmp */ -Wbmp * -createwbmp (int width, int height, int color) +Wbmp *createwbmp(int width, int height, int color) { - int i; - - Wbmp *wbmp; - if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL) - return (NULL); + int i; + Wbmp *wbmp; - if (overflow2(sizeof (int), width)) { - gdFree(wbmp); - return NULL; - } - if (overflow2(sizeof (int) * width, height)) { - gdFree(wbmp); - return NULL; - } + if ((wbmp = (Wbmp *)gdMalloc(sizeof(Wbmp))) == NULL) { + return (NULL); + } - if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL) - { - gdFree (wbmp); - return (NULL); + if (overflow2(sizeof(int), width)) { + gdFree(wbmp); + return NULL; } - wbmp->width = width; - wbmp->height = height; + if (overflow2(sizeof(int) * width, height)) { + gdFree(wbmp); + return NULL; + } - for (i = 0; i < width * height; wbmp->bitmap[i++] = color); + if ((wbmp->bitmap = (int *)gdMalloc(sizeof(int) * width * height)) == NULL) { + gdFree(wbmp); + return NULL; + } - return (wbmp); -} + wbmp->width = width; + wbmp->height = height; + for (i = 0; i < width * height; wbmp->bitmap[i++] = color) + ; + return wbmp; +} /* readwbmp - ** ------- - ** Actually reads the WBMP format from an open file descriptor - ** It goes along by returning a pointer to a WBMP struct. - ** + * ------- + * Actually reads the WBMP format from an open file descriptor + * It goes along by returning a pointer to a WBMP struct. */ -int -readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp) +int readwbmp(int (*getin)(void *in), void *in, Wbmp **return_wbmp) { - int row, col, byte, pel, pos; - Wbmp *wbmp; - - if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL) - return (-1); + int row, col, byte, pel, pos; + Wbmp *wbmp; - wbmp->type = getin (in); - if (wbmp->type != 0) - { - gdFree (wbmp); - return (-1); + if ((wbmp = (Wbmp *)gdMalloc(sizeof(Wbmp))) == NULL) { + return -1; } - if (skipheader (getin, in)) - { - gdFree (wbmp); - return (-1); + wbmp->type = getin(in); + if (wbmp->type != 0) { + gdFree(wbmp); + return -1; } + if (skipheader(getin, in)) { + gdFree(wbmp); + return -1; + } - wbmp->width = getmbi (getin, in); - if (wbmp->width == -1) - { - gdFree (wbmp); - return (-1); + wbmp->width = getmbi(getin, in); + if (wbmp->width == -1) { + gdFree(wbmp); + return -1; } - wbmp->height = getmbi (getin, in); - if (wbmp->height == -1) - { - gdFree (wbmp); - return (-1); + wbmp->height = getmbi(getin, in); + if (wbmp->height == -1) { + gdFree(wbmp); + return -1; } #ifdef __DEBUG - printf ("W: %d, H: %d\n", wbmp->width, wbmp->height); + printf("W: %d, H: %d\n", wbmp->width, wbmp->height); #endif - if (overflow2(sizeof (int), wbmp->width) || - overflow2(sizeof (int) * wbmp->width, wbmp->height)) - { - gdFree(wbmp); - return (-1); + if (overflow2(sizeof(int), wbmp->width) || overflow2(sizeof(int) * wbmp->width, wbmp->height)) { + gdFree(wbmp); + return -1; } - if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL) - { - gdFree (wbmp); - return (-1); + if ((wbmp->bitmap = (int *)gdMalloc(sizeof(int) * wbmp->width * wbmp->height)) == NULL) { + gdFree(wbmp); + return -1; } #ifdef __DEBUG - printf ("DATA CONSTRUCTED\n"); + printf("DATA CONSTRUCTED\n"); #endif - pos = 0; - for (row = 0; row < wbmp->height; row++) - { - for (col = 0; col < wbmp->width;) - { - byte = getin (in); - - for (pel = 7; pel >= 0; pel--) - { - if (col++ < wbmp->width) - { - if (byte & 1 << pel) - { - wbmp->bitmap[pos] = WBMP_WHITE; - } - else - { - wbmp->bitmap[pos] = WBMP_BLACK; - } - pos++; - } - } - } + pos = 0; + for (row = 0; row < wbmp->height; row++) { + for (col = 0; col < wbmp->width;) { + byte = getin(in); + + for (pel = 7; pel >= 0; pel--) { + if (col++ < wbmp->width) { + if (byte & 1 << pel) { + wbmp->bitmap[pos] = WBMP_WHITE; + } else { + wbmp->bitmap[pos] = WBMP_BLACK; + } + pos++; + } + } + } } - *return_wbmp = wbmp; + *return_wbmp = wbmp; - return (0); + return 0; } - /* writewbmp - ** --------- - ** Write a wbmp to a file descriptor - ** - ** Why not just giving a filedescriptor to this function? - ** Well, the incentive to write this function was the complete - ** integration in gd library from www.boutell.com. They use - ** their own io functions, so the passing of a function seemed to be - ** a logic(?) decision ... - ** + * --------- + * Write a wbmp to a file descriptor + * + * Why not just giving a filedescriptor to this function? + * Well, the incentive to write this function was the complete + * integration in gd library from www.libgd.org. They use + * their own io functions, so the passing of a function seemed to be + * a logic(?) decision ... */ -int -writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out) +int writewbmp(Wbmp *wbmp, void (*putout)(int c, void *out), void *out) { - int row, col; - int bitpos, octet; - - /* Generate the header */ - putout (0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */ - putout (0, out); /* FixHeaderField */ - - - - /* Size of the image */ - putmbi (wbmp->width, putout, out); /* width */ - putmbi (wbmp->height, putout, out); /* height */ - - - /* Image data */ - for (row = 0; row < wbmp->height; row++) - { - bitpos = 8; - octet = 0; - for (col = 0; col < wbmp->width; col++) - { - octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos; - if (bitpos == 0) - { - bitpos = 8; - putout (octet, out); - octet = 0; - } - } - if (bitpos != 8) - putout (octet, out); - + int row, col; + int bitpos, octet; + + /* Generate the header */ + putout(0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */ + putout(0, out); /* FixHeaderField */ + + /* Size of the image */ + putmbi(wbmp->width, putout, out); /* width */ + putmbi(wbmp->height, putout, out); /* height */ + + /* Image data */ + for (row = 0; row < wbmp->height; row++) { + bitpos = 8; + octet = 0; + + for (col = 0; col < wbmp->width; col++) { + octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) + << --bitpos; + if (bitpos == 0) { + bitpos = 8; + putout(octet, out); + octet = 0; + } + } + + if (bitpos != 8) { + putout(octet, out); + } } - return (0); + return 0; } - /* freewbmp - ** -------- - ** gdFrees up memory occupied by a WBMP structure - ** + * -------- + * gdFrees up memory occupied by a WBMP structure */ -void -freewbmp (Wbmp * wbmp) +void freewbmp(Wbmp *wbmp) { - gdFree (wbmp->bitmap); - gdFree (wbmp); + gdFree(wbmp->bitmap); + gdFree(wbmp); } - /* printwbmp - ** --------- - ** print a WBMP to stdout for visualisation - ** + * --------- + * print a WBMP to stdout for visualisation */ -void -printwbmp (Wbmp * wbmp) +void printwbmp(Wbmp *wbmp) { - int row, col; - for (row = 0; row < wbmp->height; row++) - { - for (col = 0; col < wbmp->width; col++) - { - if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK) - { - putchar ('#'); - } - else - { - putchar (' '); - } - } - putchar ('\n'); + int row, col; + for (row = 0; row < wbmp->height; row++) { + for (col = 0; col < wbmp->width; col++) { + if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK) { + putchar('#'); + } else { + putchar(' '); + } + } + putchar('\n'); } } #ifdef __TEST /* putout to file descriptor - ** ------------------------- + * ------------------------- */ -int -putout (int c, void *out) -{ - return (putc (c, (FILE *) out)); -} +int putout(int c, void *out) { return (putc(c, (FILE *)out)); } /* getin from file descriptor - ** -------------------------- + * -------------------------- */ -int -getin (void *in) -{ - return (getc ((FILE *) in)); -} - +int getin(void *in) { return (getc((FILE *)in)); } /* Main function - ** ------------- - ** + * ------------- */ -int -main (int argc, char *argv[]) +int main(int argc, char *argv[]) { - FILE *wbmp_file; - Wbmp *wbmp; - - wbmp_file = fopen (argv[1], "rb"); - if (wbmp_file) - { - readwbmp (&getin, wbmp_file, &wbmp); + FILE *wbmp_file; + Wbmp *wbmp; + wbmp_file = fopen(argv[1], "rb"); + if (wbmp_file) { + readwbmp(&getin, wbmp_file, &wbmp); #ifdef __VIEW - #ifdef __DEBUG - printf ("\nVIEWING IMAGE\n"); + printf("\nVIEWING IMAGE\n"); #endif - - printwbmp (wbmp); + printwbmp(wbmp); #endif - #ifdef __WRITE - #ifdef __DEBUG - printf ("\nDUMPING WBMP to STDOUT\n"); + printf("\nDUMPING WBMP to STDOUT\n"); #endif - - writewbmp (wbmp, &putout, stdout); + writewbmp(wbmp, &putout, stdout); #endif - - freewbmp (wbmp); - fclose (wbmp_file); + freewbmp(wbmp); + fclose(wbmp_file); } } #endif diff --git a/ext/gd/libgd/wbmp.h b/ext/gd/libgd/wbmp.h index 89b64c7d1c0d..496a7e2be7b6 100644 --- a/ext/gd/libgd/wbmp.h +++ b/ext/gd/libgd/wbmp.h @@ -1,16 +1,16 @@ /* WBMP -** ---- -** WBMP Level 0: B/W, Uncompressed -** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2. -** It does not support ExtHeaders as defined in the spec. The spec states -** that a WAP client does not need to implement ExtHeaders. -** -** (c) 2000 Johan Van den Brande -** -** Header file + * ---- + * WBMP Level 0: B/W, Uncompressed + * This implements the WBMP format as specified in WAPSpec 1.1 and 1.2. + * It does not support ExtHeaders as defined in the spec. The spec states + * that a WAP client does not need to implement ExtHeaders. + * + * (c) 2000 Johan Van den Brande + * + * Header file */ #ifndef __WBMP_H -#define __WBMP_H 1 +#define __WBMP_H 1 #ifdef HAVE_CONFIG_H #include "config.h" @@ -19,34 +19,30 @@ #include "php_compat.h" /* WBMP struct -** ----------- -** A Wireless bitmap structure -** + * ----------- + * A Wireless bitmap structure */ -typedef struct Wbmp_ -{ - int type; /* type of the wbmp */ - int width; /* width of the image */ - int height; /* height of the image */ - int *bitmap; /* pointer to data: 0 = WHITE , 1 = BLACK */ +typedef struct Wbmp_ { + int type; /* type of the wbmp */ + int width; /* width of the image */ + int height; /* height of the image */ + int *bitmap; /* pointer to data: 0 = WHITE , 1 = BLACK */ } Wbmp; -#define WBMP_WHITE 1 -#define WBMP_BLACK 0 - +#define WBMP_WHITE 1 +#define WBMP_BLACK 0 /* Proto's -** ------- -** + * ------- */ -void putmbi( int i, void (*putout)(int c, void *out), void *out); -int getmbi ( int (*getin)(void *in), void *in ); -int skipheader( int (*getin)(void *in), void *in ); -Wbmp *createwbmp( int width, int height, int color ); -int readwbmp( int (*getin)(void *in), void *in, Wbmp **wbmp ); -int writewbmp( Wbmp *wbmp, void (*putout)( int c, void *out), void *out); -void freewbmp( Wbmp *wbmp ); -void printwbmp( Wbmp *wbmp ); +void putmbi(int i, void (*putout)(int c, void *out), void *out); +int getmbi(int (*getin)(void *in), void *in); +int skipheader(int (*getin)(void *in), void *in); +Wbmp *createwbmp(int width, int height, int color); +int readwbmp(int (*getin)(void *in), void *in, Wbmp **wbmp); +int writewbmp(Wbmp *wbmp, void (*putout)(int c, void *out), void *out); +void freewbmp(Wbmp *wbmp); +void printwbmp(Wbmp *wbmp); #endif diff --git a/ext/gd/libgd/webpng.c b/ext/gd/libgd/webpng.c index c01dd82f23d5..e10d6d9ed9be 100644 --- a/ext/gd/libgd/webpng.c +++ b/ext/gd/libgd/webpng.c @@ -3,287 +3,217 @@ /* Bring in standard I/O and string manipulation functions */ #include -#include /* for atoi() */ +#include /* for atoi() */ #include #ifdef _WIN32 #include -int -getpid () -{ - return _getpid (); -} +int getpid() { return _getpid(); } #else -#include /* for getpid(), unlink() */ +#include /* for getpid(), unlink() */ #endif -int -main (int argc, char **argv) +int main(int argc, char **argv) { - FILE *in; - FILE *out; - char outFn[20]; - int useStdinStdout = 0; + FILE *in; + FILE *out; + char outFn[20]; + int useStdinStdout = 0; - /* Declare our image pointer */ - gdImagePtr im = 0; - int i; - /* We'll clear 'no' once we know the user has made a - reasonable request. */ - int no = 1; - /* We'll set 'write' once we know the user's request - requires that the image be written back to disk. */ - int write = 0; - /* C programs always get at least one argument; we want at - least one more (the image), more in practice. */ - if (argc < 2 || !strcmp (argv[1], "--help")) - { - no = 1; - goto usage; + /* Declare our image pointer */ + gdImagePtr im = 0; + int i; + /* We'll clear 'no' once we know the user has made a + reasonable request. */ + int no = 1; + /* We'll set 'write' once we know the user's request + requires that the image be written back to disk. */ + int write = 0; + /* C programs always get at least one argument; we want at + least one more (the image), more in practice. */ + if (argc < 2 || !strcmp(argv[1], "--help")) { + no = 1; + goto usage; } - /* The last argument should be the image. Open the file. */ - if (strcmp ("-", argv[argc - 1]) == 0) - { /* - is synonymous with STDIN */ - useStdinStdout = 1; - in = stdin; + /* The last argument should be the image. Open the file. */ + if (strcmp("-", argv[argc - 1]) == 0) { /* - is synonymous with STDIN */ + useStdinStdout = 1; + in = stdin; + } else { + in = fopen(argv[argc - 1], "rb"); } - else - { - in = fopen (argv[argc - 1], "rb"); + if (!in) { + fprintf(stderr, "Error: can't open file %s.\n", argv[argc - 1]); + exit(1); } - if (!in) - { - fprintf (stderr, - "Error: can't open file %s.\n", argv[argc - 1]); - exit (1); + /* Now load the image. */ + im = gdImageCreateFromPng(in); + fclose(in); + /* If the load failed, it must not be a PNG file. */ + if (!im) { + fprintf(stderr, "Error: %s is not a valid PNG file.\n", argv[argc - 1]); + exit(1); } - /* Now load the image. */ - im = gdImageCreateFromPng (in); - fclose (in); - /* If the load failed, it must not be a PNG file. */ - if (!im) - { - fprintf (stderr, - "Error: %s is not a valid PNG file.\n", argv[argc - 1]); - exit (1); - } - /* Consider each argument in turn. */ - for (i = 1; (i < (argc - 1)); i++) - { - /* -i turns on and off interlacing. */ - if (!strcmp (argv[i], "--help")) - { - /* Every program should use this for help! :) */ - no = 1; - goto usage; - } - else if (!strcmp (argv[i], "-i")) - { - if (i == (argc - 2)) - { - fprintf (stderr, - "Error: -i specified without y or n.\n"); - no = 1; - goto usage; - } - if (!strcmp (argv[i + 1], "y")) - { - /* Set interlace. */ - gdImageInterlace (im, 1); - } - else if (!strcmp (argv[i + 1], "n")) - { - /* Clear interlace. */ - gdImageInterlace (im, 0); - } - else - { - fprintf (stderr, - "Error: -i specified without y or n.\n"); - no = 1; - goto usage; - } - i++; - no = 0; - write = 1; - } - else if (!strcmp (argv[i], "-t")) - { - /* Set transparent index (or none). */ - int index; - if (i == (argc - 2)) - { - fprintf (stderr, - "Error: -t specified without a color table index.\n"); - no = 1; - goto usage; - } - if (!strcmp (argv[i + 1], "none")) - { - /* -1 means not transparent. */ - gdImageColorTransparent (im, -1); - } - else - { - /* OK, get an integer and set the index. */ - index = atoi (argv[i + 1]); - gdImageColorTransparent (im, index); - } - i++; - write = 1; - no = 0; - } - else if (!strcmp (argv[i], "-l")) - { - /* List the colors in the color table. */ - int j; - if (!im->trueColor) - { - /* Tabs used below. */ - printf ("Index Red Green Blue Alpha\n"); - for (j = 0; (j < gdImageColorsTotal (im)); j++) - { - /* Use access macros to learn colors. */ - printf ("%d %d %d %d %d\n", - j, - gdImageRed (im, j), - gdImageGreen (im, j), - gdImageBlue (im, j), - gdImageAlpha (im, j)); - } - } - else - { - printf ("Truecolor image, no palette entries to list.\n"); - } - no = 0; - } - else if (!strcmp (argv[i], "-d")) - { - /* Output dimensions, etc. */ - int t; - printf ("Width: %d Height: %d Colors: %d\n", - gdImageSX (im), gdImageSY (im), - gdImageColorsTotal (im)); - t = gdImageGetTransparent (im); - if (t != (-1)) - { - printf ("First 100%% transparent index: %d\n", t); - } - else - { - /* -1 means the image is not transparent. */ - printf ("First 100%% transparent index: none\n"); - } - if (gdImageGetInterlaced (im)) - { - printf ("Interlaced: yes\n"); - } - else - { - printf ("Interlaced: no\n"); - } - no = 0; - } - else if (!strcmp(argv[i], "-a")) - { - int maxx, maxy, x, y, alpha, pix, nalpha = 0; - - maxx = gdImageSX(im); - maxy = gdImageSY(im); + /* Consider each argument in turn. */ + for (i = 1; (i < (argc - 1)); i++) { + /* -i turns on and off interlacing. */ + if (!strcmp(argv[i], "--help")) { + /* Every program should use this for help! :) */ + no = 1; + goto usage; + } else if (!strcmp(argv[i], "-i")) { + if (i == (argc - 2)) { + fprintf(stderr, "Error: -i specified without y or n.\n"); + no = 1; + goto usage; + } + if (!strcmp(argv[i + 1], "y")) { + /* Set interlace. */ + gdImageInterlace(im, 1); + } else if (!strcmp(argv[i + 1], "n")) { + /* Clear interlace. */ + gdImageInterlace(im, 0); + } else { + fprintf(stderr, "Error: -i specified without y or n.\n"); + no = 1; + goto usage; + } + i++; + no = 0; + write = 1; + } else if (!strcmp(argv[i], "-t")) { + /* Set transparent index (or none). */ + int index; + if (i == (argc - 2)) { + fprintf(stderr, "Error: -t specified without a color table index.\n"); + no = 1; + goto usage; + } + if (!strcmp(argv[i + 1], "none")) { + /* -1 means not transparent. */ + gdImageColorTransparent(im, -1); + } else { + /* OK, get an integer and set the index. */ + index = atoi(argv[i + 1]); + gdImageColorTransparent(im, index); + } + i++; + write = 1; + no = 0; + } else if (!strcmp(argv[i], "-l")) { + /* List the colors in the color table. */ + int j; + if (!im->trueColor) { + /* Tabs used below. */ + printf("Index Red Green Blue Alpha\n"); + for (j = 0; (j < gdImageColorsTotal(im)); j++) { + /* Use access macros to learn colors. */ + printf("%d %d %d %d %d\n", j, gdImageRed(im, j), + gdImageGreen(im, j), gdImageBlue(im, j), gdImageAlpha(im, j)); + } + } else { + printf("Truecolor image, no palette entries to list.\n"); + } + no = 0; + } else if (!strcmp(argv[i], "-d")) { + /* Output dimensions, etc. */ + int t; + printf("Width: %d Height: %d Colors: %d\n", gdImageSX(im), gdImageSY(im), + gdImageColorsTotal(im)); + t = gdImageGetTransparent(im); + if (t != (-1)) { + printf("First 100%% transparent index: %d\n", t); + } else { + /* -1 means the image is not transparent. */ + printf("First 100%% transparent index: none\n"); + } + if (gdImageGetInterlaced(im)) { + printf("Interlaced: yes\n"); + } else { + printf("Interlaced: no\n"); + } + no = 0; + } else if (!strcmp(argv[i], "-a")) { + int maxx, maxy, x, y, alpha, pix, nalpha = 0; - printf("alpha channel information:\n"); + maxx = gdImageSX(im); + maxy = gdImageSY(im); - if (im->trueColor) { - for (y = 0; y < maxy; y++) { - for (x = 0; x < maxx; x++) { - pix = gdImageGetPixel(im, x, y); - alpha = gdTrueColorGetAlpha(pix); + printf("alpha channel information:\n"); - if (alpha > gdAlphaOpaque) { - /* Use access macros to learn colors. */ - printf ("%d %d %d %d\n", - gdTrueColorGetRed(pix), - gdTrueColorGetGreen(pix), - gdTrueColorGetBlue(pix), - alpha); - nalpha++; - } + if (im->trueColor) { + for (y = 0; y < maxy; y++) { + for (x = 0; x < maxx; x++) { + pix = gdImageGetPixel(im, x, y); + alpha = gdTrueColorGetAlpha(pix); - } - } - } - else - printf("NOT a true color image\n"); - no = 0; - printf("%d alpha channels\n", nalpha); + if (alpha > gdAlphaOpaque) { + /* Use access macros to learn colors. */ + printf("%d %d %d %d\n", gdTrueColorGetRed(pix), + gdTrueColorGetGreen(pix), gdTrueColorGetBlue(pix), alpha); + nalpha++; + } + } + } + } else + printf("NOT a true color image\n"); + no = 0; + printf("%d alpha channels\n", nalpha); - } - else - { - fprintf (stderr, "Unknown argument: %s\n", argv[i]); - break; - } + } else { + fprintf(stderr, "Unknown argument: %s\n", argv[i]); + break; + } } usage: - if (no) - { - /* If the command failed, output an explanation. */ - fprintf (stderr, - "Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n" + if (no) { + /* If the command failed, output an explanation. */ + fprintf( + stderr, + "Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n" - " -i [y|n] Turns on/off interlace\n" - " -l Prints the table of color indexes\n" - " -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n" - " -d Reports the dimensions and other characteristics of the image.\n" - " -a Prints all alpha channels that are not 100%% opaque.\n" - "\n" - "If you specify '-' as the input file, stdin/stdout will be used input/output.\n" - ); + " -i [y|n] Turns on/off interlace\n" + " -l Prints the table of color indexes\n" + " -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n" + " -d Reports the dimensions and other characteristics of the image.\n" + " -a Prints all alpha channels that are not 100%% opaque.\n" + "\n" + "If you specify '-' as the input file, stdin/stdout will be used input/output.\n"); } - if (write) - { - if (useStdinStdout) - { - out = stdout; - } - else - { - /* Open a temporary file. */ + if (write) { + if (useStdinStdout) { + out = stdout; + } else { + /* Open a temporary file. */ - /* "temp.tmp" is not good temporary filename. */ - snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ()); - out = fopen (outFn, "wb"); + /* "temp.tmp" is not good temporary filename. */ + snprintf(outFn, sizeof(outFn), "webpng.tmp%d", getpid()); + out = fopen(outFn, "wb"); - if (!out) - { - fprintf (stderr, - "Unable to write to %s -- exiting\n", outFn); - exit (1); - } - } + if (!out) { + fprintf(stderr, "Unable to write to %s -- exiting\n", outFn); + exit(1); + } + } - /* Write the new PNG. */ - gdImagePng (im, out); + /* Write the new PNG. */ + gdImagePng(im, out); - if (!useStdinStdout) - { - fclose (out); - /* Erase the old PNG. */ - unlink (argv[argc - 1]); - /* Rename the new to the old. */ - if (rename (outFn, argv[argc - 1]) != 0) - { - perror ("rename"); - exit (1); - } - } + if (!useStdinStdout) { + fclose(out); + /* Erase the old PNG. */ + unlink(argv[argc - 1]); + /* Rename the new to the old. */ + if (rename(outFn, argv[argc - 1]) != 0) { + perror("rename"); + exit(1); + } + } } - /* Delete the image from memory. */ - if (im) - { - gdImageDestroy (im); + /* Delete the image from memory. */ + if (im) { + gdImageDestroy(im); } - /* All's well that ends well. */ - return 0; + /* All's well that ends well. */ + return 0; } diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 1ef57cb3c4d9..de83a8e0313e 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | diff --git a/ext/gd/tests/001-mb.phpt b/ext/gd/tests/001-mb.phpt index 3093a59783d6..4c0971cf194f 100644 --- a/ext/gd/tests/001-mb.phpt +++ b/ext/gd/tests/001-mb.phpt @@ -19,7 +19,7 @@ var_dump(imagecreatefrompng($file)); echo "Done\n"; ?> --EXPECTF-- -Warning: imagecreatefrompng(%s001私はガラスを食べられます.test): Failed to open stream: No such file or directory in %s on line %d +Warning: imagecreatefrompng(): Failed to open stream: No such file or directory in %s on line %d bool(false) Warning: imagecreatefrompng(): "%s001私はガラスを食べられます.test" is not a valid PNG file in %s on line %d diff --git a/ext/gd/tests/001.phpt b/ext/gd/tests/001.phpt index 7c2fcf365231..a589a66ffa06 100644 --- a/ext/gd/tests/001.phpt +++ b/ext/gd/tests/001.phpt @@ -19,7 +19,7 @@ var_dump(imagecreatefrompng($file)); echo "Done\n"; ?> --EXPECTF-- -Warning: imagecreatefrompng(%s001.test): Failed to open stream: No such file or directory in %s on line %d +Warning: imagecreatefrompng(): Failed to open stream: No such file or directory in %s on line %d bool(false) Warning: imagecreatefrompng(): "%s001.test" is not a valid PNG file in %s on line %d diff --git a/ext/gd/tests/bug43073.phpt b/ext/gd/tests/bug43073.phpt index 80c6480fea57..9867eb98a268 100644 --- a/ext/gd/tests/bug43073.phpt +++ b/ext/gd/tests/bug43073.phpt @@ -13,21 +13,21 @@ gd = $exp[$i][$j] - 1 && $bbox[$j] <= $exp[$i][$j] + 1) { echo '.'; } else { - echo "(expected $exp[$i][$j], got $bbox[$j])"; + echo "(expected {$exp[$i][$j]}, got {$bbox[$j]})"; } } echo "\n"; diff --git a/ext/gd/tests/bug48732-mb.phpt b/ext/gd/tests/bug48732-mb.phpt index 361c1ac4d88f..e57a913de007 100644 --- a/ext/gd/tests/bug48732-mb.phpt +++ b/ext/gd/tests/bug48732-mb.phpt @@ -22,6 +22,7 @@ imagepng($g, "$cwd/bug48732私はガラスを食べられます.png"); echo 'Left Bottom: (' . $bbox[0] . ', ' . $bbox[1] . ')'; ?> --CLEAN-- - + --EXPECT-- -Left Bottom: (0, 46) +Left Bottom: (0, 40) diff --git a/ext/gd/tests/bug48732.phpt b/ext/gd/tests/bug48732.phpt index ed73954de333..7a3775776d64 100644 --- a/ext/gd/tests/bug48732.phpt +++ b/ext/gd/tests/bug48732.phpt @@ -22,6 +22,7 @@ imagepng($g, "$cwd/bug48732.png"); echo 'Left Bottom: (' . $bbox[0] . ', ' . $bbox[1] . ')'; ?> --CLEAN-- - + --EXPECT-- -Left Bottom: (0, 46) +Left Bottom: (0, 40) diff --git a/ext/gd/tests/bug48801-mb.phpt b/ext/gd/tests/bug48801-mb.phpt index 247161518b19..f07361694a2e 100644 --- a/ext/gd/tests/bug48801-mb.phpt +++ b/ext/gd/tests/bug48801-mb.phpt @@ -18,7 +18,7 @@ echo '(' . $bbox[4] . ', ' . $bbox[5] . ")\n"; echo '(' . $bbox[6] . ', ' . $bbox[7] . ")\n"; ?> --EXPECTREGEX-- -\(4, 15\) -\(16[0-1], 15\) -\(16[0-1], -4[7-8]\) -\(4, -4[7-8]\) +\(4, 1[4-5]\) +\(16[0-1], 1[4-5]\) +\(16[0-1], -4[6-8]\) +\(4, -4[6-8]\) diff --git a/ext/gd/tests/bug48801.phpt b/ext/gd/tests/bug48801.phpt index 361bf59a65b9..c9ca3c16c1fa 100644 --- a/ext/gd/tests/bug48801.phpt +++ b/ext/gd/tests/bug48801.phpt @@ -17,7 +17,7 @@ echo '(' . $bbox[4] . ', ' . $bbox[5] . ")\n"; echo '(' . $bbox[6] . ', ' . $bbox[7] . ")\n"; ?> --EXPECTREGEX-- -\(4, 15\) -\(16[0-1], 15\) -\(16[0-1], -4[7-8]\) -\(4, -4[7-8]\) +\(4, 14\) +\(16[0-1], 14\) +\(16[0-1], -4[6-8]\) +\(4, -4[5-8]\) diff --git a/ext/gd/tests/bug53504.phpt b/ext/gd/tests/bug53504.phpt index 5bd81f35aa0c..fb96ac3c8f2a 100644 --- a/ext/gd/tests/bug53504.phpt +++ b/ext/gd/tests/bug53504.phpt @@ -22,35 +22,35 @@ $blue = imagecolorallocate($g, 0, 0, 255); $tests = [ // Kerning examples (unfortunately not available in "Tuffy" test font): - ['fontSize' => 50, 'angle' => 0, 'x' => 20, 'y' => 70, 'text' => 'AV Teg', 'exp' => [2,15, 208,15, 208,-48, 2,-48]], - ['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 350, 'text' => 'AV Teg', 'exp' => [15,-1, 15,-208, -48,-208, -48,-2]], - ['fontSize' => 50, 'angle' => 40, 'x' => 130, 'y' => 280, 'text' => 'AV Teg', 'exp' => [11,11, 169,-122, 129,-171, -30,-39]], + ['fontSize' => 50, 'angle' => 0, 'x' => 20, 'y' => 70, 'text' => 'AV Teg', 'exp' => [2,14, 209,14, 209,-47, 2,-47]], + ['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 350, 'text' => 'AV Teg', 'exp' => [14,-2, 14,-209, -47,-209, -47,-2]], + ['fontSize' => 50, 'angle' => 40, 'x' => 130, 'y' => 280, 'text' => 'AV Teg', 'exp' => [11,9, 169,-123, 129,-170, -28,-37]], // Shift-Test: - ['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 110, 'text' => 'H-Shift', 'exp' => [8,2, 386,2, 386,-97, 8,-97]], + ['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 110, 'text' => 'H-Shift', 'exp' => [8,1, 393,1, 393,-97, 8,-97]], // Small/single chars: - ['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 220, 'text' => '-', 'exp' => [7,-37, 51,-37, 51,-46, 7,-46]], - ['fontSize' => 100, 'angle' => 0, 'x' => 430, 'y' => 220, 'text' => ',', 'exp' => [7,15, 21,15, 21,-13, 7,-13]], - ['fontSize' => 100, 'angle' => 0, 'x' => 510, 'y' => 220, 'text' => '.', 'exp' => [7,1, 21,1, 21,-13, 7,-13]], - ['fontSize' => 100, 'angle' => 0, 'x' => 590, 'y' => 220, 'text' => '|', 'exp' => [8,0, 17,0, 17,-95, 8,-95]], - ['fontSize' => 100, 'angle' => 0, 'x' => 670, 'y' => 220, 'text' => 'g', 'exp' => [5,29, 60,29, 60,-72, 5,-72]], + ['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 220, 'text' => '-', 'exp' => [7,-36, 56,-36, 56,-46, 7,-46]], + ['fontSize' => 100, 'angle' => 0, 'x' => 430, 'y' => 220, 'text' => ',', 'exp' => [6,14, 25,14, 25,-13, 6,-13]], + ['fontSize' => 100, 'angle' => 0, 'x' => 510, 'y' => 220, 'text' => '.', 'exp' => [6,0, 26,0, 26,-13, 6,-13]], + ['fontSize' => 100, 'angle' => 0, 'x' => 590, 'y' => 220, 'text' => '|', 'exp' => [8,0, 23,0, 23,-95, 8,-95]], + ['fontSize' => 100, 'angle' => 0, 'x' => 670, 'y' => 220, 'text' => 'g', 'exp' => [4,29, 66,29, 66,-71, 4,-71]], // Multi-Line + rotation: - ['fontSize' => 30, 'angle' => 0, 'x' => 20, 'y' => 400, 'text' => "Multi\nLine\nTest", 'exp' => [2,107, 80,107, 80,-29, 2,-29]], - ['fontSize' => 30, 'angle' => 40, 'x' => 150, 'y' => 420, 'text' => "Multi\nLine\nTest", 'exp' => [70,81, 131,31, 43,-74, -18,-24]], - ['fontSize' => 30, 'angle' => 90, 'x' => 250, 'y' => 340, 'text' => "Multi\nLine\nTest", 'exp' => [107,-1, 107,-80, -29,-80, -29,-2]], + ['fontSize' => 30, 'angle' => 0, 'x' => 20, 'y' => 400, 'text' => "Multi\nLine\nTest", 'exp' => [1,84, 81,84, 81,-28, 1,-28]], + ['fontSize' => 30, 'angle' => 40, 'x' => 150, 'y' => 420, 'text' => "Multi\nLine\nTest", 'exp' => [55,63, 116,12, 43,-74, -17,-22]], + ['fontSize' => 30, 'angle' => 90, 'x' => 250, 'y' => 340, 'text' => "Multi\nLine\nTest", 'exp' => [84,-1, 84,-81, -28,-81, -28,-1]], // Some edge case glyphs: - ['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 750, 'text' => "iiiiiiiiiiii", 'exp' => [0,-4, 0,-165, -47,-165, -47,-4]], - ['fontSize' => 50, 'angle' => 90, 'x' => 150, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [-19,-2, -18,-167, -29,-167, -29,-2]], - ['fontSize' => 50, 'angle' => 50, 'x' => 210, 'y' => 750, 'text' => "iiiiiiiiiiii", 'exp' => [3,-3, 107,-127, 70,-157, -34,-33]], - ['fontSize' => 50, 'angle' => 50, 'x' => 300, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [-13,-13, 93,-141, 85,-147, -21,-20]], - ['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 650, 'text' => "iiiiiiiiiiii", 'exp' => [4,0, 165,0, 165,-47, 4,-47]], - ['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [2,-19, 167,-19, 167,-29, 2,-29]], + ['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 750, 'text' => "iiiiiiiiiiii", 'exp' => [0,-4, 0,-165, -46,-165, -46,-4]], + ['fontSize' => 50, 'angle' => 90, 'x' => 150, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [-18,-1, -18,-168, -27,-168, -27,-1]], + ['fontSize' => 50, 'angle' => 50, 'x' => 210, 'y' => 750, 'text' => "iiiiiiiiiiii", 'exp' => [2,-3, 108,-129, 73,-159, -32,-33]], + ['fontSize' => 50, 'angle' => 50, 'x' => 300, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [-12,-13, 94,-140, 86,-146, -20,-19]], + ['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 650, 'text' => "iiiiiiiiiiii", 'exp' => [4,0, 165,0, 165,-46, 4,-46]], + ['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 750, 'text' => "~~~~~~~", 'exp' => [1,-18, 168,-18, 168,-27, 1,-27]], // "Big" test: - ['fontSize' => 200, 'angle' => 0, 'x' => 400, 'y' => 500, 'text' => "Big", 'exp' => [16,59, 329,59, 329,-190, 16,-190]], + ['fontSize' => 200, 'angle' => 0, 'x' => 400, 'y' => 500, 'text' => "Big", 'exp' => [15,58, 342,58, 342,-189, 15,-189]], ]; foreach ($tests as $testnum => $test) { @@ -71,8 +71,8 @@ foreach ($tests as $testnum => $test) { // check if both bboxes match when adding x/y offset: for ($i = 0; $i < count($bbox); $i += 2) { - if ($bbox[$i] + $test['x'] !== $bboxDrawn[$i]) echo "imageftbbox and imagefttext differ!\n"; - if ($bbox[$i + 1] + $test['y'] !== $bboxDrawn[$i + 1]) echo "imageftbbox and imagefttext differ!\n"; + if (abs($bbox[$i] + $test['x'] - $bboxDrawn[$i]) > 1) echo "imageftbbox and imagefttext differ!\n"; + if (abs($bbox[$i + 1] + $test['y'] - $bboxDrawn[$i + 1]) > 1) echo "imageftbbox and imagefttext differ!\n"; } // draw bounding box: diff --git a/ext/gd/tests/bug65148.phpt b/ext/gd/tests/bug65148.phpt index 0d71655aad10..77f4a384f186 100644 --- a/ext/gd/tests/bug65148.phpt +++ b/ext/gd/tests/bug65148.phpt @@ -46,128 +46,128 @@ Array ( [IMG_BELL] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BESSEL] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BICUBIC] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BICUBIC_FIXED] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BILINEAR_FIXED] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BLACKMAN] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BOX] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_BSPLINE] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_CATMULLROM] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_GAUSSIAN] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_GENERALIZED_CUBIC] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_HERMITE] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_HAMMING] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_HANNING] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_MITCHELL] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_POWER] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_QUADRATIC] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_SINC] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_NEAREST_NEIGHBOUR] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_WEIGHTED4] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) [IMG_TRIANGLE] => Array ( - [x] => 40 - [y] => 23 + [x] => 42 + [y] => 24 ) ) diff --git a/ext/gd/tests/bug66356.phpt b/ext/gd/tests/bug66356.phpt index b65fb54f5718..616a270115c1 100644 --- a/ext/gd/tests/bug66356.phpt +++ b/ext/gd/tests/bug66356.phpt @@ -7,10 +7,14 @@ gd $img = imagecreatetruecolor(10, 10); // POC #1 -var_dump(imagecrop($img, array("x" => "a", "y" => 0, "width" => 10, "height" => 10))); +var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 10, "height" => 10))); -$arr = array("x" => "a", "y" => "12b", "width" => 10, "height" => 10); -var_dump(imagecrop($img, $arr)); +$arr = array("x" => 2147483647, "y" => 2147483647, "width" => 10, "height" => 10); +try { + imagecrop($img, $arr); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} print_r($arr); // POC #2 @@ -28,12 +32,11 @@ var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 65535, "height" => --EXPECTF-- object(GdImage)#2 (0) { } -object(GdImage)#2 (0) { -} +imagecrop(): Argument #2 ($rectangle) overflow with "x" and "width" keys Array ( - [x] => a - [y] => 12b + [x] => 2147483647 + [y] => 2147483647 [width] => 10 [height] => 10 ) @@ -41,9 +44,9 @@ Array Warning: imagecrop(): %cne parameter to a memory allocation multiplication is negative or zero, failing operation gracefully in %s on line %d bool(false) -object(GdImage)#2 (0) { +object(GdImage)#3 (0) { } -object(GdImage)#2 (0) { +object(GdImage)#3 (0) { } Warning: imagecrop(): %croduct of memory allocation multiplication would exceed INT_MAX, failing operation gracefully diff --git a/ext/gd/tests/bug73272.png b/ext/gd/tests/bug73272.png index 514e012a9298..6de8ac4715bd 100644 Binary files a/ext/gd/tests/bug73272.png and b/ext/gd/tests/bug73272.png differ diff --git a/ext/gd/tests/bug73291.phpt b/ext/gd/tests/bug73291.phpt index e23b1fc7d17a..3d54c2878a18 100644 --- a/ext/gd/tests/bug73291.phpt +++ b/ext/gd/tests/bug73291.phpt @@ -25,7 +25,7 @@ foreach ([0.1, 0.5, 1.0, 10.0] as $threshold) { ?> --EXPECT-- -size: 247*247 -size: 237*237 -size: 229*229 -size: 175*175 +size: 255*255 +size: 253*253 +size: 253*253 +size: 225*225 diff --git a/ext/gd/tests/bug79945.phpt b/ext/gd/tests/bug79945.phpt index 5db958e36d35..46dac358d8e2 100644 --- a/ext/gd/tests/bug79945.phpt +++ b/ext/gd/tests/bug79945.phpt @@ -9,17 +9,17 @@ if (!(imagetypes() & IMG_PNG)) { } set_error_handler(function($errno, $errstr) { if (str_contains($errstr, 'Cannot cast a filtered stream on this system')) { - die('skip: fopencookie not support on this system'); + die('skip: fopencookie not supported on this system'); } }); -imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png'); +imagecreatefrompng('php://filter/read=string.rot13/resource=' . __DIR__ . '/test.png'); restore_error_handler(); ?> --FILE-- --CLEAN-- --EXPECTF-- -Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d +Warning: imagecreatefrompng(): "php://filter/read=string.rot13/resource=%s" is not a valid PNG file in %s on line %d diff --git a/ext/gd/tests/createfromwbmp2_extern.phpt b/ext/gd/tests/createfromwbmp2_extern.phpt index 5cd178cb59e5..68895f9a3570 100644 --- a/ext/gd/tests/createfromwbmp2_extern.phpt +++ b/ext/gd/tests/createfromwbmp2_extern.phpt @@ -2,10 +2,6 @@ imagecreatefromwbmp with invalid wbmp --EXTENSIONS-- gd ---SKIPIF-- - --FILE-- --FILE-- --FILE-- +--FILE-- +getMessage() . PHP_EOL; +} +try { + imagesetstyle($img, [0, PHP_INT_MIN]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagefilter($img, IMG_FILTER_SCATTER, 0, 0, [new A()]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagefilter($img, IMG_FILTER_SCATTER, 0, 0, [-1]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => PHP_INT_MIN, "y" => 0, "width" => 0, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => PHP_INT_MIN, "width" => 0, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => PHP_INT_MAX, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => 0, "height" => PHP_INT_MAX]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + imagecrop($img, ["x" => new A(), "y" => 0, "width" => 0, "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => new A(), "width" => 0, "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => new A(), "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => 0, "height" => new A()]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} + +$one = 1; +var_dump(imagecrop($img, ["x" => &$one, "y" => &$one, "width" => &$one, "height" => &$one])); +?> +--EXPECTF-- +imagesetstyle(): Argument #2 ($style) must only have elements of type int, A given +imagesetstyle(): Argument #2 ($style) elements must be between %i and %d +imagefilter(): Argument #5 must be of type int, A given +imagefilter(): Argument #5 value must be between 0 and 2147483647 +imagecrop(): Argument #2 ($rectangle) "x" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "y" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "width" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "height" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "x" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "y" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "width" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "height" key must be of type int, A given +object(GdImage)#2 (0) { +} diff --git a/ext/gd/tests/gh19666.phpt b/ext/gd/tests/gh19666.phpt new file mode 100644 index 000000000000..469cd88302f2 --- /dev/null +++ b/ext/gd/tests/gh19666.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-19666 (Unexpected nan value in imageconvolution) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +array(4) { + ["red"]=> + int(0) + ["green"]=> + int(0) + ["blue"]=> + int(0) + ["alpha"]=> + int(0) +} diff --git a/ext/gd/tests/gh19730.phpt b/ext/gd/tests/gh19730.phpt new file mode 100644 index 000000000000..5ea4a2846a9e --- /dev/null +++ b/ext/gd/tests/gh19730.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19730 (undefined behavior in gd_interpolation.c) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) diff --git a/ext/gd/tests/gh19739.phpt b/ext/gd/tests/gh19739.phpt new file mode 100644 index 000000000000..7ef73aeab67d --- /dev/null +++ b/ext/gd/tests/gh19739.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-19739 (integer overflow in imageellipse / imagefilledellipse) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +done diff --git a/ext/gd/tests/imagebmp_basic.phpt b/ext/gd/tests/imagebmp_basic.phpt index ff302a8b0742..82b14f06b3cd 100644 --- a/ext/gd/tests/imagebmp_basic.phpt +++ b/ext/gd/tests/imagebmp_basic.phpt @@ -2,6 +2,12 @@ imagebmp() - basic functionality --EXTENSIONS-- gd +--SKIPIF-- + --FILE-- --EXPECTF-- -Warning: imageloadfont(\src\invalidfile.font): Failed to open stream: No such file or directory in %s on line %d +Warning: imageloadfont(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/gd/tests/imageloadfont_short_read.phpt b/ext/gd/tests/imageloadfont_short_read.phpt new file mode 100644 index 000000000000..406c64b99595 --- /dev/null +++ b/ext/gd/tests/imageloadfont_short_read.phpt @@ -0,0 +1,67 @@ +--TEST-- +imageloadfont(): header read must stay in bounds on short reads +--EXTENSIONS-- +gd +--FILE-- +data = pack('i4', 1, 32, 1, 1) . "\x00"; + return true; + } + + public function stream_read($count): string + { + return $this->pos < strlen($this->data) ? $this->data[$this->pos++] : ''; + } + + public function stream_eof(): bool + { + return $this->pos >= strlen($this->data); + } + + public function stream_stat() + { + return []; + } + + public function stream_tell(): int + { + return $this->pos; + } + + public function stream_seek($offset, $whence): bool + { + if ($whence === SEEK_CUR) { + $this->pos += $offset; + } elseif ($whence === SEEK_END) { + $this->pos = strlen($this->data) + $offset; + } else { + $this->pos = $offset; + } + return true; + } + + public function stream_set_option($option, $arg1, $arg2): bool + { + return false; + } +} + +stream_wrapper_register('drip', drip::class); +var_dump(imageloadfont('drip://font') instanceof GdFont); +?> +--EXPECT-- +bool(true) diff --git a/ext/gd/tests/imagepng_filters.phpt b/ext/gd/tests/imagepng_filters.phpt new file mode 100644 index 000000000000..ecb5f51f61d4 --- /dev/null +++ b/ext/gd/tests/imagepng_filters.phpt @@ -0,0 +1,59 @@ +--TEST-- +imagepng() supports all PNG filter constants with bundled GD +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 6badea4a1769..172ae76d3876 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alex Plotnick | +----------------------------------------------------------------------+ diff --git a/ext/gettext/php_gettext.h b/ext/gettext/php_gettext.h index f98e459f127c..5799ecf1d89b 100644 --- a/ext/gettext/php_gettext.h +++ b/ext/gettext/php_gettext.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alex Plotnick | +----------------------------------------------------------------------+ diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index b5451b8035e3..7f8799a7ae2d 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -285,7 +283,7 @@ static HashTable *gmp_get_debug_info(zend_object *obj, int *is_temp) /* {{{ */ static zend_object *gmp_clone_obj(zend_object *obj) /* {{{ */ { - gmp_object *old_object = GET_GMP_OBJECT_FROM_OBJ(obj); + const gmp_object *old_object = GET_GMP_OBJECT_FROM_OBJ(obj); gmp_object *new_object = GET_GMP_OBJECT_FROM_OBJ(gmp_create_object(obj->ce)); zend_objects_clone_members( &new_object->std, &old_object->std); @@ -329,16 +327,25 @@ static zend_result binop_operator_helper(gmp_binary_op_t gmp_op, zval *return_va typedef void (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, gmp_ulong); +static void gmp_shift_operator_range_error(uint8_t opcode) { + zend_throw_error( + zend_ce_value_error, "%s must be between 0 and %lu", + opcode == ZEND_POW ? "Exponent" : "Shift", ULONG_MAX + ); +} + static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2, uint8_t opcode) { zend_long shift = 0; + gmp_ulong shift_ui = 0; + bool have_shift_ui = false; if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { if (UNEXPECTED(!IS_GMP(op2))) { - // For PHP 8.3 and up use zend_try_get_long() + bool failed; switch (Z_TYPE_P(op2)) { case IS_DOUBLE: - shift = zval_get_long(op2); - if (UNEXPECTED(EG(exception))) { + shift = zval_try_get_long(op2, &failed); + if (UNEXPECTED(failed)) { return FAILURE; } break; @@ -351,32 +358,36 @@ static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_val goto typeof_op_failure; } } else { - // TODO We shouldn't cast the GMP object to int here - shift = zval_get_long(op2); + mpz_ptr gmpnum_shift = GET_GMP_FROM_ZVAL(op2); + if (!mpz_fits_ulong_p(gmpnum_shift)) { + gmp_shift_operator_range_error(opcode); + return FAILURE; + } + shift_ui = (gmp_ulong) mpz_get_ui(gmpnum_shift); + have_shift_ui = true; } } else { shift = Z_LVAL_P(op2); } - if (shift < 0) { - zend_throw_error( - zend_ce_value_error, "%s must be greater than or equal to 0", - opcode == ZEND_POW ? "Exponent" : "Shift" - ); - ZVAL_UNDEF(return_value); - return FAILURE; - } else { - mpz_ptr gmpnum_op, gmpnum_result; - - if (!gmp_zend_parse_arg_into_mpz_ex(op1, &gmpnum_op, 1, true)) { - goto typeof_op_failure; + if (!have_shift_ui) { + if (shift < 0 || shift > ULONG_MAX) { + gmp_shift_operator_range_error(opcode); + return FAILURE; } + shift_ui = (gmp_ulong) shift; + } - INIT_GMP_RETVAL(gmpnum_result); - op(gmpnum_result, gmpnum_op, (gmp_ulong) shift); - return SUCCESS; + mpz_ptr gmpnum_op, gmpnum_result; + + if (!gmp_zend_parse_arg_into_mpz_ex(op1, &gmpnum_op, 1, true)) { + goto typeof_op_failure; } + INIT_GMP_RETVAL(gmpnum_result); + op(gmpnum_result, gmpnum_op, shift_ui); + return SUCCESS; + typeof_op_failure: ; /* Returning FAILURE without throwing an exception would emit the * Unsupported operand types: GMP OP TypeOfOp2 @@ -393,7 +404,7 @@ typeof_op_failure: ; case ZEND_SR: op_sigil = ">>"; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } zend_type_error("Unsupported operand types: %s %s %s", zend_zval_type_name(op1), op_sigil, zend_zval_type_name(op2)); return FAILURE; @@ -588,7 +599,7 @@ ZEND_MINIT_FUNCTION(gmp) gmp_ce->unserialize = gmp_unserialize; memcpy(&gmp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - gmp_object_handlers.offset = XtOffsetOf(gmp_object, std); + gmp_object_handlers.offset = offsetof(gmp_object, std); gmp_object_handlers.free_obj = gmp_free_object_storage; gmp_object_handlers.cast_object = gmp_cast_object; gmp_object_handlers.get_debug_info = gmp_get_debug_info; @@ -633,8 +644,17 @@ static zend_result convert_zstr_to_gmp(mpz_t gmp_number, const zend_string *val, const char *num_str = ZSTR_VAL(val); bool skip_lead = false; + if (UNEXPECTED(zend_str_has_nul_byte(val))) { + if (arg_pos == 0) { + zend_value_error("Number is not an integer string"); + } else { + zend_argument_value_error(arg_pos, "is not an integer string"); + } + return FAILURE; + } + size_t num_len = ZSTR_LEN(val); - while (isspace(*num_str)) { + while (isspace((unsigned char)*num_str)) { ++num_str; --num_len; } @@ -929,7 +949,7 @@ ZEND_FUNCTION(gmp_div_qr) case GMP_ROUND_MINUSINF: mpz_fdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1089,14 +1109,11 @@ ZEND_FUNCTION(gmp_fact) GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum) ZEND_PARSE_PARAMETERS_END(); - if (mpz_sgn(gmpnum) < 0) { - zend_argument_value_error(1, "must be greater than or equal to 0"); + if (!mpz_fits_ulong_p(gmpnum)) { + zend_argument_value_error(1, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } - // TODO: Check that we don't an int that is larger than an unsigned long? - // Could use mpz_fits_slong_p() if we revert to using mpz_get_si() - INIT_GMP_RETVAL(gmpnum_result); mpz_fac_ui(gmpnum_result, mpz_get_ui(gmpnum)); } @@ -1114,8 +1131,8 @@ ZEND_FUNCTION(gmp_binomial) Z_PARAM_LONG(k) ZEND_PARSE_PARAMETERS_END(); - if (k < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (k < 0 || k > ULONG_MAX) { + zend_argument_value_error(2, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1136,8 +1153,8 @@ ZEND_FUNCTION(gmp_pow) Z_PARAM_LONG(exp) ZEND_PARSE_PARAMETERS_END(); - if (exp < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (exp < 0 || exp > ULONG_MAX) { + zend_argument_value_error(2, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1163,7 +1180,7 @@ ZEND_FUNCTION(gmp_powm) } if (!mpz_cmp_ui(gmpnum_mod, 0)) { - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + zend_argument_error(zend_ce_division_by_zero_error, 3, "Modulo by zero"); RETURN_THROWS(); } @@ -1226,13 +1243,13 @@ ZEND_FUNCTION(gmp_root) Z_PARAM_LONG(nth) ZEND_PARSE_PARAMETERS_END(); - if (nth <= 0) { - zend_argument_value_error(2, "must be greater than 0"); + if (nth <= 0 || nth > ULONG_MAX) { + zend_argument_value_error(2, "must be between 1 and %lu", ULONG_MAX); RETURN_THROWS(); } if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) { - zend_argument_value_error(2, "must be odd if argument #1 ($a) is negative"); + zend_argument_value_error(2, "must be odd if argument #1 ($num) is negative"); RETURN_THROWS(); } @@ -1253,13 +1270,13 @@ ZEND_FUNCTION(gmp_rootrem) Z_PARAM_LONG(nth) ZEND_PARSE_PARAMETERS_END(); - if (nth <= 0) { - zend_argument_value_error(2, "must be greater than or equal to 1"); + if (nth <= 0 || nth > ULONG_MAX) { + zend_argument_value_error(2, "must be between 1 and %lu", ULONG_MAX); RETURN_THROWS(); } if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) { - zend_argument_value_error(2, "must be odd if argument #1 ($a) is negative"); + zend_argument_value_error(2, "must be odd if argument #1 ($num) is negative"); RETURN_THROWS(); } @@ -1511,7 +1528,7 @@ ZEND_FUNCTION(gmp_random_range) gmp_init_random(); if (mpz_cmp(gmpnum_max, gmpnum_min) <= 0) { - zend_argument_value_error(1, "must be less than argument #2 ($maximum)"); + zend_argument_value_error(1, "must be less than argument #2 ($max)"); RETURN_THROWS(); } diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index 597c7a9146c2..220a36d64285 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/gmp/php_gmp_int.h b/ext/gmp/php_gmp_int.h index 32f1d32f592a..d563a43ba553 100644 --- a/ext/gmp/php_gmp_int.h +++ b/ext/gmp/php_gmp_int.h @@ -1,3 +1,15 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + */ + /* interface header; needs to be installed; FIXME rename? */ #ifndef incl_PHP_GMP_INT_H @@ -23,9 +35,7 @@ typedef struct _gmp_object { zend_object std; } gmp_object; -static inline gmp_object *php_gmp_object_from_zend_object(zend_object *zobj) { - return (gmp_object *)( ((char *)zobj) - XtOffsetOf(gmp_object, std) ); -} +#define php_gmp_object_from_zend_object(zobj) ZEND_CONTAINER_OF(zobj, gmp_object, std) PHP_GMP_API zend_class_entry *php_gmp_class_entry(void); diff --git a/ext/gmp/tests/gh22549.phpt b/ext/gmp/tests/gh22549.phpt new file mode 100644 index 000000000000..82a66901bd09 --- /dev/null +++ b/ext/gmp/tests/gh22549.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-22549 (Assertion failure in _zendi_try_convert_scalar_to_number with compound GMP shift/pow) +--EXTENSIONS-- +gmp +--FILE-- + [2, fn(&$x) => $x **= gmp_init(-5)], + 'gmp ** gmp' => [gmp_init(2), fn(&$x) => $x **= gmp_init(-5)], + 'array ** gmp' => [[0], fn(&$x) => $x **= gmp_init(-5)], + 'int << gmp' => [8, fn(&$x) => $x <<= gmp_init(-2)], + 'int >> gmp' => [8, fn(&$x) => $x >>= gmp_init(-2)], + 'gmp << gmp' => [gmp_init(8), fn(&$x) => $x <<= gmp_init(-2)], +]; + +foreach ($cases as $label => [$x, $op]) { + try { + $op($x); + echo "$label: no exception\n"; + } catch (\Throwable $e) { + echo "$label: ", $e::class, ": ", $e->getMessage(), "\n"; + } + var_dump($x); +} + +// Valid operations must still succeed (guard against an over-broad regression). +$p = 2; $p **= gmp_init(3); echo "valid pow: ", gmp_strval($p), "\n"; +$s = 1; $s <<= gmp_init(4); echo "valid shift: ", gmp_strval($s), "\n"; +?> +--EXPECTF-- +int ** gmp: ValueError: Exponent must be between 0 and %d +int(2) +gmp ** gmp: ValueError: Exponent must be between 0 and %d +object(GMP)#%d (1) { + ["num"]=> + string(1) "2" +} +array ** gmp: ValueError: Exponent must be between 0 and %d +array(1) { + [0]=> + int(0) +} +int << gmp: ValueError: Shift must be between 0 and %d +int(8) +int >> gmp: ValueError: Shift must be between 0 and %d +int(8) +gmp << gmp: ValueError: Shift must be between 0 and %d +object(GMP)#%d (1) { + ["num"]=> + string(1) "8" +} +valid pow: 8 +valid shift: 16 diff --git a/ext/gmp/tests/gmp_binomial.phpt b/ext/gmp/tests/gmp_binomial.phpt index 4598a4c47ee8..1bf371e68a14 100644 --- a/ext/gmp/tests/gmp_binomial.phpt +++ b/ext/gmp/tests/gmp_binomial.phpt @@ -26,7 +26,7 @@ try { echo $e->getMessage() . \PHP_EOL; } ?> ---EXPECT-- +--EXPECTF-- object(GMP)#1 (1) { ["num"]=> string(3) "252" @@ -67,4 +67,4 @@ object(GMP)#2 (1) { ["num"]=> string(1) "7" } -gmp_binomial(): Argument #2 ($k) must be greater than or equal to 0 +gmp_binomial(): Argument #2 ($k) must be between 0 and %d diff --git a/ext/gmp/tests/gmp_fact.phpt b/ext/gmp/tests/gmp_fact.phpt index e03931454940..b28f572c6975 100644 --- a/ext/gmp/tests/gmp_fact.phpt +++ b/ext/gmp/tests/gmp_fact.phpt @@ -45,17 +45,17 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(1) "1" gmp_fact(): Argument #1 ($num) is not an integer string string(1) "1" -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 +gmp_fact(): Argument #1 ($num) must be between 0 and %d +gmp_fact(): Argument #1 ($num) must be between 0 and %d string(19) "2432902008176640000" string(65) "30414093201713378043612608166064768844377641568960512000000000000" string(7) "3628800" string(1) "1" string(9) "479001600" -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 +gmp_fact(): Argument #1 ($num) must be between 0 and %d gmp_fact(): Argument #1 ($num) must be of type GMP|string|int, array given Done diff --git a/ext/gmp/tests/gmp_fact_overflow.phpt b/ext/gmp/tests/gmp_fact_overflow.phpt new file mode 100644 index 000000000000..2d22005818c5 --- /dev/null +++ b/ext/gmp/tests/gmp_fact_overflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +gmp_fact() rejects values larger than unsigned long +--EXTENSIONS-- +gmp +--FILE-- +getMessage() . \PHP_EOL; +} + +try { + var_dump(gmp_fact(gmp_init("18446744073709551616"))); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +gmp_fact(): Argument #1 ($num) must be between 0 and %d +gmp_fact(): Argument #1 ($num) must be between 0 and %d +Done diff --git a/ext/gmp/tests/gmp_null_bytes.phpt b/ext/gmp/tests/gmp_null_bytes.phpt new file mode 100644 index 000000000000..1518d342dda2 --- /dev/null +++ b/ext/gmp/tests/gmp_null_bytes.phpt @@ -0,0 +1,28 @@ +--TEST-- +GMP rejects integer strings containing null bytes +--EXTENSIONS-- +gmp +--FILE-- + fn() => gmp_init("123\0abc"), + 'gmp_init prefix' => fn() => gmp_init("0x10\0ff"), + 'gmp_add' => fn() => gmp_add("123\0abc", 1), + 'constructor' => fn() => new GMP("123\0abc"), +]; + +foreach ($tests as $label => $test) { + try { + $test(); + } catch (ValueError $e) { + echo $label, ": ", $e->getMessage(), PHP_EOL; + } +} + +?> +--EXPECT-- +gmp_init: gmp_init(): Argument #1 ($num) is not an integer string +gmp_init prefix: gmp_init(): Argument #1 ($num) is not an integer string +gmp_add: gmp_add(): Argument #1 ($num1) is not an integer string +constructor: GMP::__construct(): Argument #1 ($num) is not an integer string diff --git a/ext/gmp/tests/gmp_operator_rhs_gmp_overflow.phpt b/ext/gmp/tests/gmp_operator_rhs_gmp_overflow.phpt new file mode 100644 index 000000000000..e8b6139ace0f --- /dev/null +++ b/ext/gmp/tests/gmp_operator_rhs_gmp_overflow.phpt @@ -0,0 +1,33 @@ +--TEST-- +GMP operator right operand rejects values outside the unsigned long range +--EXTENSIONS-- +gmp +--FILE-- +getMessage(), PHP_EOL; +} + +try { + var_dump(gmp_init(2) << $too_large); +} catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(gmp_init(2) >> $too_large); +} catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +Exponent must be between 0 and %d +Shift must be between 0 and %d +Shift must be between 0 and %d +Done diff --git a/ext/gmp/tests/gmp_overflow_llp64.phpt b/ext/gmp/tests/gmp_overflow_llp64.phpt new file mode 100644 index 000000000000..ea242bc52155 --- /dev/null +++ b/ext/gmp/tests/gmp_overflow_llp64.phpt @@ -0,0 +1,58 @@ +--TEST-- +GMP functions reject values larger than unsigned long on LLP64 +--EXTENSIONS-- +gmp +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; +} + +try { + gmp_binomial(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + gmp_root(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + gmp_rootrem(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +$n = gmp_init(2); +try { + $n << PHP_INT_MAX; +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + $n ** PHP_INT_MAX; +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d +gmp_binomial(): Argument #2 ($k) must be between 0 and %d +gmp_root(): Argument #2 ($nth) must be between 1 and %d +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d +Shift must be between 0 and %d +Exponent must be between 0 and %d +Done diff --git a/ext/gmp/tests/gmp_php_int_max.phpt b/ext/gmp/tests/gmp_php_int_max.phpt index a4974dac6057..d26d1b064897 100644 --- a/ext/gmp/tests/gmp_php_int_max.phpt +++ b/ext/gmp/tests/gmp_php_int_max.phpt @@ -4,7 +4,7 @@ PHP_INT_MAX tests gmp --SKIPIF-- --FILE-- ---EXPECT-- +--EXPECTF-- string(4) "1024" string(4) "1024" string(5) "-2048" string(4) "1024" string(1) "1" -gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d string(4) "1024" string(14) "10240000000000" string(17) "97656250000000000" -gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d string(14) "10240000000000" string(14) "10240000000000" gmp_pow(): Argument #2 ($exponent) must be of type int, array given diff --git a/ext/gmp/tests/gmp_pow2.phpt b/ext/gmp/tests/gmp_pow2.phpt index 43bf9bb5aaa5..96f33e8c25ca 100644 --- a/ext/gmp/tests/gmp_pow2.phpt +++ b/ext/gmp/tests/gmp_pow2.phpt @@ -31,5 +31,5 @@ object(GMP)#%d (1) { ["num"]=> string(4) "1024" } -Exponent must be greater than or equal to 0 -Exponent must be greater than or equal to 0 +Exponent must be between 0 and %d +Exponent must be between 0 and %d diff --git a/ext/gmp/tests/gmp_pown.phpt b/ext/gmp/tests/gmp_pown.phpt index 0e7b3bd1fa5d..79709f272715 100644 --- a/ext/gmp/tests/gmp_pown.phpt +++ b/ext/gmp/tests/gmp_pown.phpt @@ -63,7 +63,7 @@ var_dump(gmp_powm(10, $n, 10)); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(1) "0" string(1) "5" string(1) "5" @@ -73,8 +73,8 @@ string(3) "533" string(3) "331" string(3) "171" string(3) "371" -Modulo by zero -Modulo by zero +gmp_powm(): Argument #3 ($modulus) Modulo by zero +gmp_powm(): Argument #3 ($modulus) Modulo by zero gmp_powm(): Argument #1 ($num) must be of type GMP|string|int, array given gmp_powm(): Argument #2 ($exponent) must be of type GMP|string|int, array given gmp_powm(): Argument #2 ($exponent) must be of type GMP|string|int, TypeError given diff --git a/ext/gmp/tests/gmp_random_range.phpt b/ext/gmp/tests/gmp_random_range.phpt index ae87dbd82b18..59ac5762fce0 100644 --- a/ext/gmp/tests/gmp_random_range.phpt +++ b/ext/gmp/tests/gmp_random_range.phpt @@ -74,7 +74,7 @@ while (1) { echo "Done\n"; ?> --EXPECT-- -gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($maximum) -gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($maximum) -gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($maximum) +gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($max) +gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($max) +gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($max) Done diff --git a/ext/gmp/tests/gmp_remroot.phpt b/ext/gmp/tests/gmp_remroot.phpt index 8e53858c6047..fe7a8316e596 100644 --- a/ext/gmp/tests/gmp_remroot.phpt +++ b/ext/gmp/tests/gmp_remroot.phpt @@ -92,7 +92,7 @@ array(2) { string(2) "19" } } -gmp_rootrem(): Argument #2 ($nth) must be odd if argument #1 ($a) is negative +gmp_rootrem(): Argument #2 ($nth) must be odd if argument #1 ($num) is negative array(2) { [0]=> object(GMP)#%d (1) { @@ -105,5 +105,5 @@ array(2) { string(1) "0" } } -gmp_rootrem(): Argument #2 ($nth) must be greater than or equal to 1 -gmp_rootrem(): Argument #2 ($nth) must be greater than or equal to 1 +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d diff --git a/ext/gmp/tests/gmp_root.phpt b/ext/gmp/tests/gmp_root.phpt index 2313b207cc8d..b4a88405a211 100644 --- a/ext/gmp/tests/gmp_root.phpt +++ b/ext/gmp/tests/gmp_root.phpt @@ -53,10 +53,10 @@ object(GMP)#%d (1) { ["num"]=> string(1) "3" } -gmp_root(): Argument #2 ($nth) must be odd if argument #1 ($a) is negative +gmp_root(): Argument #2 ($nth) must be odd if argument #1 ($num) is negative object(GMP)#%d (1) { ["num"]=> string(1) "0" } -gmp_root(): Argument #2 ($nth) must be greater than 0 -gmp_root(): Argument #2 ($nth) must be greater than 0 +gmp_root(): Argument #2 ($nth) must be between 1 and %d +gmp_root(): Argument #2 ($nth) must be between 1 and %d diff --git a/ext/gmp/tests/overloading.phpt b/ext/gmp/tests/overloading.phpt index 14c35ea8470c..f55a83f0bd5f 100644 --- a/ext/gmp/tests/overloading.phpt +++ b/ext/gmp/tests/overloading.phpt @@ -123,7 +123,7 @@ $a .= '17'; var_dump($a); ?> ---EXPECT-- +--EXPECTF-- object(GMP)#3 (1) { ["num"]=> string(2) "59" @@ -254,8 +254,8 @@ object(GMP)#5 (1) { ["num"]=> string(3) "-11" } -Shift must be greater than or equal to 0 -Shift must be greater than or equal to 0 +Shift must be between 0 and %d +Shift must be between 0 and %d object(GMP)#5 (1) { ["num"]=> string(3) "-43" diff --git a/ext/gmp/tests/overloading_with_float_fractional.phpt b/ext/gmp/tests/overloading_with_float_fractional.phpt index fc078eeec3e9..a86356a9dd54 100644 --- a/ext/gmp/tests/overloading_with_float_fractional.phpt +++ b/ext/gmp/tests/overloading_with_float_fractional.phpt @@ -100,6 +100,8 @@ object(GMP)#2 (1) { ["num"]=> string(1) "0" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(69) "150130937545296572356771972164254457814047970568738777235893533016064" @@ -122,10 +124,14 @@ object(GMP)#2 (1) { ["num"]=> string(1) "0" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(15) "184717953466368" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(1) "0" diff --git a/ext/hash/config.m4 b/ext/hash/config.m4 index 2da44c503a62..72b7db8f9deb 100644 --- a/ext/hash/config.m4 +++ b/ext/hash/config.m4 @@ -57,7 +57,7 @@ PHP_NEW_EXTENSION([hash], m4_normalize([ murmur/PMurHash128.c ]), [no],, - [$PHP_HASH_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [$PHP_HASH_CFLAGS]) PHP_ADD_BUILD_DIR([$ext_builddir/murmur]) AS_VAR_IF([SHA3_DIR],,, [PHP_ADD_BUILD_DIR([$ext_builddir/$SHA3_DIR])]) PHP_INSTALL_HEADERS([ext/hash], m4_normalize([ diff --git a/ext/hash/config.w32 b/ext/hash/config.w32 index e63efcfd84cb..347dbddea6b4 100644 --- a/ext/hash/config.w32 +++ b/ext/hash/config.w32 @@ -27,7 +27,7 @@ if (!CHECK_HEADER('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) { ERROR('Unable to locate SHA3 headers'); } -ADD_FLAG('CFLAGS_HASH', '/DKeccakP200_excluded /DKeccakP400_excluded /DKeccakP800_excluded /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); +ADD_FLAG('CFLAGS_HASH', '/DKeccakP200_excluded /DKeccakP400_excluded /DKeccakP800_excluded'); ADD_SOURCES('ext/hash/murmur', 'PMurHash.c PMurHash128.c', 'hash'); diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 8a9494fb62d0..21bee4a64e13 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | | Scott MacVicar | @@ -104,9 +102,7 @@ static struct mhash_bc_entry mhash_to_hash[MHASH_NUM_ALGOS] = { PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo) /* {{{ */ { - zend_string *lower = zend_string_tolower(algo); - const php_hash_ops *ops = zend_hash_find_ptr(&php_hash_hashtable, lower); - zend_string_release(lower); + const php_hash_ops *ops = zend_hash_find_ptr_lc(&php_hash_hashtable, algo); return ops; } @@ -388,7 +384,7 @@ static void php_hash_do_hash( } php_stream_close(stream); if (n < 0) { - efree(context); + php_hash_free_context(ops, context); RETURN_FALSE; } } else { @@ -397,7 +393,7 @@ static void php_hash_do_hash( digest = zend_string_alloc(ops->digest_size, 0); ops->hash_final((unsigned char *) ZSTR_VAL(digest), context); - efree(context); + php_hash_free_context(ops, context); if (raw_output) { ZSTR_VAL(digest)[ops->digest_size] = 0; @@ -405,7 +401,7 @@ static void php_hash_do_hash( } else { zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0); - php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); + zend_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; zend_string_efree(digest); RETURN_NEW_STR(hex_digest); @@ -536,7 +532,7 @@ static void php_hash_do_hash_hmac( } php_stream_close(stream); if (n < 0) { - efree(context); + php_hash_free_context(ops, context); efree(K); zend_string_efree(digest); RETURN_FALSE; @@ -554,7 +550,7 @@ static void php_hash_do_hash_hmac( /* Zero the key */ ZEND_SECURE_ZERO(K, ops->block_size); efree(K); - efree(context); + php_hash_free_context(ops, context); if (raw_output) { ZSTR_VAL(digest)[ops->digest_size] = 0; @@ -562,7 +558,7 @@ static void php_hash_do_hash_hmac( } else { zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0); - php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); + zend_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; zend_string_efree(digest); RETURN_NEW_STR(hex_digest); @@ -815,7 +811,7 @@ PHP_FUNCTION(hash_final) ZSTR_VAL(digest)[digest_len] = 0; /* Invalidate the object from further use */ - efree(hash->context); + php_hash_free_context(hash->ops, hash->context); hash->context = NULL; if (raw_output) { @@ -823,7 +819,7 @@ PHP_FUNCTION(hash_final) } else { zend_string *hex_digest = zend_string_safe_alloc(digest_len, 2, 0, 0); - php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), digest_len); + zend_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), digest_len); ZSTR_VAL(hex_digest)[2 * digest_len] = 0; zend_string_efree(digest); RETURN_NEW_STR(hex_digest); @@ -969,7 +965,7 @@ PHP_FUNCTION(hash_hkdf) ZEND_SECURE_ZERO(digest, ops->digest_size); ZEND_SECURE_ZERO(prk, ops->digest_size); efree(K); - efree(context); + php_hash_free_context(ops, context); efree(prk); efree(digest); ZSTR_VAL(returnval)[length] = 0; @@ -1085,7 +1081,7 @@ PHP_FUNCTION(hash_pbkdf2) efree(K1); efree(K2); efree(computed_salt); - efree(context); + php_hash_free_context(ops, context); efree(digest); efree(temp); @@ -1093,7 +1089,7 @@ PHP_FUNCTION(hash_pbkdf2) if (raw_output) { memcpy(ZSTR_VAL(returnval), result, length); } else { - php_hash_bin2hex(ZSTR_VAL(returnval), result, digest_length); + zend_bin2hex(ZSTR_VAL(returnval), result, digest_length); } ZSTR_VAL(returnval)[length] = 0; efree(result); @@ -1114,12 +1110,12 @@ PHP_FUNCTION(hash_equals) /* We only allow comparing string to prevent unexpected results. */ if (Z_TYPE_P(known_zval) != IS_STRING) { - zend_argument_type_error(1, "must be of type string, %s given", zend_zval_value_name(known_zval)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_STRING, known_zval); RETURN_THROWS(); } if (Z_TYPE_P(user_zval) != IS_STRING) { - zend_argument_type_error(2, "must be of type string, %s given", zend_zval_value_name(user_zval)); + zend_wrong_parameter_type_error(2, Z_EXPECTED_STRING, user_zval); RETURN_THROWS(); } @@ -1350,7 +1346,7 @@ PHP_FUNCTION(mhash_keygen_s2k) RETVAL_STRINGL(key, bytes); ZEND_SECURE_ZERO(key, bytes); efree(digest); - efree(context); + php_hash_free_context(ops, context); efree(key); } } @@ -1380,7 +1376,7 @@ static void php_hashcontext_dtor(zend_object *obj) { php_hashcontext_object *hash = php_hashcontext_from_object(obj); if (hash->context) { - efree(hash->context); + php_hash_free_context(hash->ops, hash->context); hash->context = NULL; } @@ -1399,7 +1395,7 @@ static void php_hashcontext_free(zend_object *obj) { /* {{{ php_hashcontext_clone */ static zend_object *php_hashcontext_clone(zend_object *zobj) { - php_hashcontext_object *oldobj = php_hashcontext_from_object(zobj); + const php_hashcontext_object *oldobj = php_hashcontext_from_object(zobj); zend_object *znew = php_hashcontext_create(zobj->ce); php_hashcontext_object *newobj = php_hashcontext_from_object(znew); @@ -1416,7 +1412,7 @@ static zend_object *php_hashcontext_clone(zend_object *zobj) { newobj->ops->hash_init(newobj->context, NULL); if (SUCCESS != newobj->ops->hash_copy(newobj->ops, oldobj->context, newobj->context)) { - efree(newobj->context); + php_hash_free_context(newobj->ops, newobj->context); newobj->context = NULL; return znew; } @@ -1654,7 +1650,7 @@ PHP_MINIT_FUNCTION(hash) memcpy(&php_hashcontext_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_hashcontext_handlers.offset = XtOffsetOf(php_hashcontext_object, std); + php_hashcontext_handlers.offset = offsetof(php_hashcontext_object, std); php_hashcontext_handlers.free_obj = php_hashcontext_free; php_hashcontext_handlers.clone_obj = php_hashcontext_clone; diff --git a/ext/hash/hash_adler32.c b/ext/hash/hash_adler32.c index 3898ea60e877..1f5ae3756a0a 100644 --- a/ext/hash/hash_adler32.c +++ b/ext/hash/hash_adler32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -70,5 +68,6 @@ const php_hash_ops php_hash_adler32_ops = { 4, /* what to say here? */ 4, sizeof(PHP_ADLER32_CTX), + 0, 0 }; diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index a770d0b55416..407150a1cdd3 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -102,6 +100,7 @@ const php_hash_ops php_hash_crc32_ops = { 4, /* what to say here? */ 4, sizeof(PHP_CRC32_CTX), + 0, 0 }; @@ -117,6 +116,7 @@ const php_hash_ops php_hash_crc32b_ops = { 4, /* what to say here? */ 4, sizeof(PHP_CRC32_CTX), + 0, 0 }; @@ -132,5 +132,6 @@ const php_hash_ops php_hash_crc32c_ops = { 4, /* what to say here? */ 4, sizeof(PHP_CRC32_CTX), + 0, 0 }; diff --git a/ext/hash/hash_fnv.c b/ext/hash/hash_fnv.c index 92d4922bd810..7859e5908870 100644 --- a/ext/hash/hash_fnv.c +++ b/ext/hash/hash_fnv.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Maclean | +----------------------------------------------------------------------+ @@ -32,6 +30,7 @@ const php_hash_ops php_hash_fnv132_ops = { 4, 4, sizeof(PHP_FNV132_CTX), + 0, 0 }; @@ -47,6 +46,7 @@ const php_hash_ops php_hash_fnv1a32_ops = { 4, 4, sizeof(PHP_FNV132_CTX), + 0, 0 }; @@ -62,6 +62,7 @@ const php_hash_ops php_hash_fnv164_ops = { 8, 4, sizeof(PHP_FNV164_CTX), + 0, 0 }; @@ -77,6 +78,7 @@ const php_hash_ops php_hash_fnv1a64_ops = { 8, 4, sizeof(PHP_FNV164_CTX), + 0, 0 }; diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index bba585a11f9f..91edbd50834f 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -329,7 +327,8 @@ const php_hash_ops php_hash_gost_ops = { 32, 32, sizeof(PHP_GOST_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_gost_crypto_ops = { @@ -344,5 +343,6 @@ const php_hash_ops php_hash_gost_crypto_ops = { 32, 32, sizeof(PHP_GOST_CTX), - 1 + 1, + 0 }; diff --git a/ext/hash/hash_haval.c b/ext/hash/hash_haval.c index 67bc2b2e4780..b326142cc7ef 100644 --- a/ext/hash/hash_haval.c +++ b/ext/hash/hash_haval.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -252,7 +250,7 @@ const php_hash_ops php_hash_##p##haval##b##_ops = { \ php_hash_serialize, \ php_hash_unserialize, \ PHP_HAVAL_SPEC, \ - ((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1 }; \ + ((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1, 0 }; \ PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context, ZEND_ATTRIBUTE_UNUSED HashTable *args) \ { int i; context->count[0] = context->count[1] = 0; \ for(i = 0; i < 8; i++) context->state[i] = D0[i]; \ diff --git a/ext/hash/hash_joaat.c b/ext/hash/hash_joaat.c index 328f9292c4ca..0550af18dce7 100644 --- a/ext/hash/hash_joaat.c +++ b/ext/hash/hash_joaat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Martin Jansen | +----------------------------------------------------------------------+ @@ -33,6 +31,7 @@ const php_hash_ops php_hash_joaat_ops = { 4, 4, sizeof(PHP_JOAAT_CTX), + 0, 0 }; diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c index dd299e695891..44d43e16777f 100644 --- a/ext/hash/hash_md.c +++ b/ext/hash/hash_md.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Taken from: ext/standard/md5.c | +----------------------------------------------------------------------+ @@ -29,7 +27,8 @@ const php_hash_ops php_hash_md5_ops = { 16, 64, sizeof(PHP_MD5_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_md4_ops = { @@ -44,7 +43,8 @@ const php_hash_ops php_hash_md4_ops = { 16, 64, sizeof(PHP_MD4_CTX), - 1 + 1, + 0 }; static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv); @@ -61,7 +61,8 @@ const php_hash_ops php_hash_md2_ops = { 16, 16, sizeof(PHP_MD2_CTX), - 1 + 1, + 0 }; /* MD common stuff */ diff --git a/ext/hash/hash_murmur.c b/ext/hash/hash_murmur.c index 0117b2e57d36..1e63262c20ed 100644 --- a/ext/hash/hash_murmur.c +++ b/ext/hash/hash_murmur.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ @@ -33,6 +31,7 @@ const php_hash_ops php_hash_murmur3a_ops = { 4, 4, sizeof(PHP_MURMUR3A_CTX), + 0, 0 }; @@ -95,6 +94,7 @@ const php_hash_ops php_hash_murmur3c_ops = { 16, 4, sizeof(PHP_MURMUR3C_CTX), + 0, 0 }; @@ -174,6 +174,7 @@ const php_hash_ops php_hash_murmur3f_ops = { 16, 8, sizeof(PHP_MURMUR3F_CTX), + 0, 0 }; diff --git a/ext/hash/hash_ripemd.c b/ext/hash/hash_ripemd.c index 4802fdf9a1fc..c6396ba2a60a 100644 --- a/ext/hash/hash_ripemd.c +++ b/ext/hash/hash_ripemd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -33,7 +31,8 @@ const php_hash_ops php_hash_ripemd128_ops = { 16, 64, sizeof(PHP_RIPEMD128_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_ripemd160_ops = { @@ -48,7 +47,8 @@ const php_hash_ops php_hash_ripemd160_ops = { 20, 64, sizeof(PHP_RIPEMD160_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_ripemd256_ops = { @@ -63,7 +63,8 @@ const php_hash_ops php_hash_ripemd256_ops = { 32, 64, sizeof(PHP_RIPEMD256_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_ripemd320_ops = { @@ -78,7 +79,8 @@ const php_hash_ops php_hash_ripemd320_ops = { 40, 64, sizeof(PHP_RIPEMD320_CTX), - 1 + 1, + 0 }; /* {{{ PHP_RIPEMD128Init diff --git a/ext/hash/hash_sha.c b/ext/hash/hash_sha.c index 3129446fcde4..3a7729e31fc0 100644 --- a/ext/hash/hash_sha.c +++ b/ext/hash/hash_sha.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Steffan Esser | | Sara Golemon | @@ -75,7 +73,8 @@ const php_hash_ops php_hash_sha1_ops = { 20, 64, sizeof(PHP_SHA1_CTX), - 1 + 1, + 0 }; /* sha224/sha256 */ @@ -92,7 +91,8 @@ const php_hash_ops php_hash_sha256_ops = { 32, 64, sizeof(PHP_SHA256_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_sha224_ops = { @@ -107,7 +107,8 @@ const php_hash_ops php_hash_sha224_ops = { 28, 64, sizeof(PHP_SHA224_CTX), - 1 + 1, + 0 }; #define ROTR32(b,x) ((x >> b) | (x << (32 - b))) @@ -624,7 +625,8 @@ const php_hash_ops php_hash_sha384_ops = { 48, 128, sizeof(PHP_SHA384_CTX), - 1 + 1, + 0 }; /* {{{ PHP_SHA512InitArgs @@ -803,7 +805,8 @@ const php_hash_ops php_hash_sha512_ops = { 64, 128, sizeof(PHP_SHA512_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_sha512_256_ops = { @@ -818,7 +821,8 @@ const php_hash_ops php_hash_sha512_256_ops = { 32, 128, sizeof(PHP_SHA512_CTX), - 1 + 1, + 0 }; const php_hash_ops php_hash_sha512_224_ops = { @@ -833,5 +837,6 @@ const php_hash_ops php_hash_sha512_224_ops = { 28, 128, sizeof(PHP_SHA512_CTX), - 1 + 1, + 0 }; diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 8fa0a4b4e522..3f5d966820cd 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -251,7 +249,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ bits >> 3, \ (1600 - (2 * bits)) >> 3, \ sizeof(PHP_SHA3_##bits##_CTX), \ - 1 \ + 1, \ + 0 \ } #else @@ -339,7 +338,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ bits >> 3, \ (1600 - (2 * bits)) >> 3, \ sizeof(PHP_SHA3_CTX), \ - 1 \ + 1, \ + 0 \ } #endif diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c index b9b70f364208..3fe16b4398a3 100644 --- a/ext/hash/hash_snefru.c +++ b/ext/hash/hash_snefru.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -214,5 +212,6 @@ const php_hash_ops php_hash_snefru_ops = { 32, 32, sizeof(PHP_SNEFRU_CTX), - 1 + 1, + 0 }; diff --git a/ext/hash/hash_tiger.c b/ext/hash/hash_tiger.c index 62d1b7347143..f9b4dc737581 100644 --- a/ext/hash/hash_tiger.c +++ b/ext/hash/hash_tiger.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -265,7 +263,8 @@ static hash_spec_result php_tiger_unserialize(php_hashcontext_object *hash, zend b/8, \ 64, \ sizeof(PHP_TIGER_CTX), \ - 1 \ + 1, \ + 0 \ } PHP_HASH_TIGER_OPS(3, 128); diff --git a/ext/hash/hash_whirlpool.c b/ext/hash/hash_whirlpool.c index fa3c216a64c4..9d895efa06e7 100644 --- a/ext/hash/hash_whirlpool.c +++ b/ext/hash/hash_whirlpool.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -457,5 +455,6 @@ const php_hash_ops php_hash_whirlpool_ops = { 64, 64, sizeof(PHP_WHIRLPOOL_CTX), - 1 + 1, + 0 }; diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index add922e8e84f..e0f400fc517e 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ @@ -34,6 +32,7 @@ const php_hash_ops php_hash_xxh32_ops = { 4, 4, sizeof(PHP_XXH32_CTX), + 0, 0 }; @@ -101,6 +100,7 @@ const php_hash_ops php_hash_xxh64_ops = { 8, 8, sizeof(PHP_XXH64_CTX), + 0, 0 }; @@ -152,7 +152,8 @@ const php_hash_ops php_hash_xxh3_64_ops = { 8, 8, sizeof(PHP_XXH3_64_CTX), - 0 + 0, + 64 }; typedef XXH_errorcode (*xxh3_reset_with_secret_func_t)(XXH3_state_t*, const void*, size_t); @@ -257,7 +258,8 @@ const php_hash_ops php_hash_xxh3_128_ops = { 16, 8, sizeof(PHP_XXH3_128_CTX), - 0 + 0, + 64 }; PHP_HASH_API void PHP_XXH3_128_Init(PHP_XXH3_128_CTX *ctx, HashTable *args) diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index f56605a33be6..0a11b4749326 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -60,6 +58,7 @@ typedef struct _php_hash_ops { size_t block_size; size_t context_size; unsigned is_crypto: 1; + size_t context_align; } php_hash_ops; struct _php_hashcontext_object { @@ -163,18 +162,24 @@ PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object * static inline void *php_hash_alloc_context(const php_hash_ops *ops) { /* Zero out context memory so serialization doesn't expose internals */ + if (ops->context_align > 0) { + size_t align = ops->context_align; + char *base = ecalloc(1, ops->context_size + align); + size_t offset = align - ((uintptr_t)base & (align - 1)); + char *ptr = base + offset; + ptr[-1] = (char)offset; + return ptr; + } return ecalloc(1, ops->context_size); } -static inline void php_hash_bin2hex(char *out, const unsigned char *in, size_t in_len) -{ - static const char hexits[17] = "0123456789abcdef"; - size_t i; - - for(i = 0; i < in_len; i++) { - out[i * 2] = hexits[in[i] >> 4]; - out[(i * 2) + 1] = hexits[in[i] & 0x0F]; +static inline void php_hash_free_context(const php_hash_ops *ops, void *ctx) { + if (ops->context_align > 0) { + unsigned char offset = ((unsigned char *)ctx)[-1]; + efree((char *)ctx - offset); + return; } + efree(ctx); } #endif /* PHP_HASH_H */ diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index bacb47ff1c91..c076893cb76f 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_crc32.h b/ext/hash/php_hash_crc32.h index b6accea17bb6..f50bff1c69ea 100644 --- a/ext/hash/php_hash_crc32.h +++ b/ext/hash/php_hash_crc32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_crc32_tables.h b/ext/hash/php_hash_crc32_tables.h index d126f177bdbe..28b70e4226b3 100644 --- a/ext/hash/php_hash_crc32_tables.h +++ b/ext/hash/php_hash_crc32_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_fnv.h b/ext/hash/php_hash_fnv.h index e9d1ce8d0b44..5e82bc4dab66 100644 --- a/ext/hash/php_hash_fnv.h +++ b/ext/hash/php_hash_fnv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Maclean | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 66992b09b976..f1116c3852d6 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_haval.h b/ext/hash/php_hash_haval.h index e3a3a31b3685..c857d84b0abd 100644 --- a/ext/hash/php_hash_haval.h +++ b/ext/hash/php_hash_haval.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_joaat.h b/ext/hash/php_hash_joaat.h index fcc4cc3911bb..26e5adc03532 100644 --- a/ext/hash/php_hash_joaat.h +++ b/ext/hash/php_hash_joaat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Martin Jansen | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_md.h b/ext/hash/php_hash_md.h index f648fbf7c3c2..f9abbd5583b5 100644 --- a/ext/hash/php_hash_md.h +++ b/ext/hash/php_hash_md.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Original Author: Rasmus Lerdorf | | Modified for pHASH by: Sara Golemon diff --git a/ext/hash/php_hash_murmur.h b/ext/hash/php_hash_murmur.h index 6180a9b8f341..1539011156b3 100644 --- a/ext/hash/php_hash_murmur.h +++ b/ext/hash/php_hash_murmur.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_ripemd.h b/ext/hash/php_hash_ripemd.h index 0065450d21bb..1d30330d9e7f 100644 --- a/ext/hash/php_hash_ripemd.h +++ b/ext/hash/php_hash_ripemd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index 50eef82e858a..e2c6eac30b4c 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | SHA1 Author: Stefan Esser | | SHA256 Author: Sara Golemon | diff --git a/ext/hash/php_hash_sha3.h b/ext/hash/php_hash_sha3.h index 8381a8943b4d..2692fd5de766 100644 --- a/ext/hash/php_hash_sha3.h +++ b/ext/hash/php_hash_sha3.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_snefru.h b/ext/hash/php_hash_snefru.h index df90e8e46968..2fbeb7c42ebe 100644 --- a/ext/hash/php_hash_snefru.h +++ b/ext/hash/php_hash_snefru.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_snefru_tables.h b/ext/hash/php_hash_snefru_tables.h index 0fc186b14cbe..075b2fe3e620 100644 --- a/ext/hash/php_hash_snefru_tables.h +++ b/ext/hash/php_hash_snefru_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_tiger.h b/ext/hash/php_hash_tiger.h index 92515c4dbf75..aa0f6cafbe8d 100644 --- a/ext/hash/php_hash_tiger.h +++ b/ext/hash/php_hash_tiger.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_tiger_tables.h b/ext/hash/php_hash_tiger_tables.h index 594bf836fd04..f2d1bb69f1ec 100644 --- a/ext/hash/php_hash_tiger_tables.h +++ b/ext/hash/php_hash_tiger_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | diff --git a/ext/hash/php_hash_whirlpool.h b/ext/hash/php_hash_whirlpool.h index f28ab234861b..b12e6c50a9f6 100644 --- a/ext/hash/php_hash_whirlpool.h +++ b/ext/hash/php_hash_whirlpool.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_whirlpool_tables.h b/ext/hash/php_hash_whirlpool_tables.h index ef121efe9449..cd58d6c53a3e 100644 --- a/ext/hash/php_hash_whirlpool_tables.h +++ b/ext/hash/php_hash_whirlpool_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_xxhash.h b/ext/hash/php_hash_xxhash.h index f099039f3711..e2003ba4c584 100644 --- a/ext/hash/php_hash_xxhash.h +++ b/ext/hash/php_hash_xxhash.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/hash/tests/hash_file_error.phpt b/ext/hash/tests/hash_file_error.phpt index 44f3d0925597..68ba55f4a373 100644 --- a/ext/hash/tests/hash_file_error.phpt +++ b/ext/hash/tests/hash_file_error.phpt @@ -38,5 +38,5 @@ hash_file(): Argument #1 ($algo) must be a valid hashing algorithm -- Testing hash_file() function with a non-existent file -- -Warning: hash_file(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: hash_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/iconv/config.m4 b/ext/iconv/config.m4 index e86f3535a97c..bea97b27f4f7 100644 --- a/ext/iconv/config.m4 +++ b/ext/iconv/config.m4 @@ -112,6 +112,8 @@ int main(void) { char *out = malloc(out_left); char *out_p = out; size_t result = iconv(cd, (char **) &in_p, &in_left, (char **) &out_p, &out_left); + free(out); + iconv_close(cd); if(result == (size_t)-1) { return 1; } diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 7c812f5af44b..d9b54388a8f8 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rui Hirokawa | | Stig Bakken | @@ -460,59 +458,65 @@ PHP_ICONV_API php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len, out_left = in_len + 32; /* Avoid realloc() most cases */ out_size = 0; bsz = out_left; - out_buf = zend_string_alloc(bsz, 0); - out_p = ZSTR_VAL(out_buf); - - while (in_left > 0) { - result = iconv(cd, (ICONV_CONST char **) &in_p, &in_left, (char **) &out_p, &out_left); - out_size = bsz - out_left; - if (result == (size_t)(-1)) { - if (ignore_ilseq && errno == EILSEQ) { - if (in_left <= 1) { - result = 0; - } else { - errno = 0; - in_p++; - in_left--; - continue; + + zend_try { + out_buf = zend_string_alloc(bsz, 0); + out_p = ZSTR_VAL(out_buf); + + while (in_left > 0) { + result = iconv(cd, (ICONV_CONST char **) &in_p, &in_left, (char **) &out_p, &out_left); + out_size = bsz - out_left; + if (result == (size_t)(-1)) { + if (ignore_ilseq && errno == EILSEQ) { + if (in_left <= 1) { + result = 0; + } else { + errno = 0; + in_p++; + in_left--; + continue; + } } - } - if (errno == E2BIG && in_left > 0) { - /* converted string is longer than out buffer */ - bsz += in_len; + if (errno == E2BIG && in_left > 0) { + /* converted string is longer than out buffer */ + bsz += in_len; - out_buf = zend_string_extend(out_buf, bsz, 0); - out_p = ZSTR_VAL(out_buf); - out_p += out_size; - out_left = bsz - out_size; - continue; + out_buf = zend_string_extend(out_buf, bsz, 0); + out_p = ZSTR_VAL(out_buf); + out_p += out_size; + out_left = bsz - out_size; + continue; + } } + break; } - break; - } - if (result != (size_t)(-1)) { - /* flush the shift-out sequences */ - for (;;) { - result = iconv(cd, NULL, NULL, (char **) &out_p, &out_left); - out_size = bsz - out_left; + if (result != (size_t)(-1)) { + /* flush the shift-out sequences */ + for (;;) { + result = iconv(cd, NULL, NULL, (char **) &out_p, &out_left); + out_size = bsz - out_left; - if (result != (size_t)(-1)) { - break; - } + if (result != (size_t)(-1)) { + break; + } - if (errno == E2BIG) { - bsz += 16; - out_buf = zend_string_extend(out_buf, bsz, 0); - out_p = ZSTR_VAL(out_buf); - out_p += out_size; - out_left = bsz - out_size; - } else { - break; + if (errno == E2BIG) { + bsz += 16; + out_buf = zend_string_extend(out_buf, bsz, 0); + out_p = ZSTR_VAL(out_buf); + out_p += out_size; + out_left = bsz - out_size; + } else { + break; + } } } - } + } zend_catch { + iconv_close(cd); + zend_bailout(); + } zend_end_try(); iconv_close(cd); @@ -685,58 +689,63 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval, errno = 0; more = nbytes > 0 && len > 0; - for (in_p = str, in_left = nbytes, cnt = 0; more; ++cnt) { - out_p = buf; - out_left = sizeof(buf); + bool bailout = false; + zend_try { + for (in_p = str, in_left = nbytes, cnt = 0; more; ++cnt) { + out_p = buf; + out_left = sizeof(buf); - more = in_left > 0 && len > 0; + more = in_left > 0 && len > 0; - iconv(cd1, more ? (ICONV_CONST char **)&in_p : NULL, more ? &in_left : NULL, (char **) &out_p, &out_left); - if (out_left == sizeof(buf)) { - break; - } + iconv(cd1, more ? (ICONV_CONST char **)&in_p : NULL, more ? &in_left : NULL, (char **) &out_p, &out_left); + if (out_left == sizeof(buf)) { + break; + } - if ((zend_long)cnt >= offset) { - if (cd2 == (iconv_t)NULL) { - cd2 = iconv_open(enc, GENERIC_SUPERSET_NAME); + if ((zend_long)cnt >= offset) { + if (cd2 == (iconv_t)NULL) { + cd2 = iconv_open(enc, GENERIC_SUPERSET_NAME); - if (cd2 == (iconv_t)(-1)) { - cd2 = (iconv_t)NULL; - if (errno == EINVAL) { - err = PHP_ICONV_ERR_WRONG_CHARSET; - } else { - err = PHP_ICONV_ERR_CONVERTER; + if (cd2 == (iconv_t)(-1)) { + cd2 = (iconv_t)NULL; + if (errno == EINVAL) { + err = PHP_ICONV_ERR_WRONG_CHARSET; + } else { + err = PHP_ICONV_ERR_CONVERTER; + } + break; } + } + + if (_php_iconv_appendl(pretval, buf, sizeof(buf), cd2) != PHP_ICONV_ERR_SUCCESS) { break; } + --len; } - if (_php_iconv_appendl(pretval, buf, sizeof(buf), cd2) != PHP_ICONV_ERR_SUCCESS) { - break; - } - --len; } - } - - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - break; + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - break; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; - case E2BIG: - break; - } - if (err == PHP_ICONV_ERR_SUCCESS) { - if (cd2 != (iconv_t)NULL) { - _php_iconv_appendl(pretval, NULL, 0, cd2); + case E2BIG: + break; } - smart_str_0(pretval); - } + if (err == PHP_ICONV_ERR_SUCCESS) { + if (cd2 != (iconv_t)NULL) { + _php_iconv_appendl(pretval, NULL, 0, cd2); + } + smart_str_0(pretval); + } + } zend_catch { + bailout = true; + } zend_end_try(); if (cd1 != (iconv_t)NULL) { iconv_close(cd1); @@ -745,6 +754,9 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval, if (cd2 != (iconv_t)NULL) { iconv_close(cd2); } + if (bailout) { + zend_bailout(); + } return err; } @@ -904,6 +916,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn { php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); + bool bailout = false; size_t char_cnt = 0; size_t out_charset_len; size_t lfchars_len; @@ -962,215 +975,221 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn goto out; } - buf = safe_emalloc(1, max_line_len, 5); + zend_try { + buf = safe_emalloc(1, max_line_len, 5); - char_cnt = max_line_len; + char_cnt = max_line_len; - _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); - char_cnt -= fname_nbytes; - smart_str_appendl(pretval, ": ", sizeof(": ") - 1); - char_cnt -= 2; + _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); + char_cnt -= fname_nbytes; + smart_str_appendl(pretval, ": ", sizeof(": ") - 1); + char_cnt -= 2; - in_p = fval; - in_left = fval_nbytes; + in_p = fval; + in_left = fval_nbytes; - do { - size_t prev_in_left; - size_t out_size; - size_t encoded_word_min_len = sizeof("=\?\?X\?\?=")-1 + out_charset_len + (enc_scheme == PHP_ICONV_ENC_SCHEME_BASE64 ? 4 : 3); + do { + size_t prev_in_left; + size_t out_size; + size_t encoded_word_min_len = sizeof("=\?\?X\?\?=")-1 + out_charset_len + (enc_scheme == PHP_ICONV_ENC_SCHEME_BASE64 ? 4 : 3); - if (char_cnt < encoded_word_min_len + lfchars_len + 1) { - /* lfchars must be encoded in ASCII here*/ - smart_str_appendl(pretval, lfchars, lfchars_len); - smart_str_appendc(pretval, ' '); - char_cnt = max_line_len - 1; - } + if (char_cnt < encoded_word_min_len + lfchars_len + 1) { + /* lfchars must be encoded in ASCII here*/ + smart_str_appendl(pretval, lfchars, lfchars_len); + smart_str_appendc(pretval, ' '); + char_cnt = max_line_len - 1; + } - smart_str_appendl(pretval, "=?", sizeof("=?") - 1); - char_cnt -= 2; - smart_str_appendl(pretval, out_charset, out_charset_len); - char_cnt -= out_charset_len; - smart_str_appendc(pretval, '?'); - char_cnt --; + smart_str_appendl(pretval, "=?", sizeof("=?") - 1); + char_cnt -= 2; + smart_str_appendl(pretval, out_charset, out_charset_len); + char_cnt -= out_charset_len; + smart_str_appendc(pretval, '?'); + char_cnt --; - switch (enc_scheme) { - case PHP_ICONV_ENC_SCHEME_BASE64: { - size_t ini_in_left; - const char *ini_in_p; - size_t out_reserved = 4; + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: { + size_t ini_in_left; + const char *ini_in_p; + size_t out_reserved = 4; - smart_str_appendc(pretval, 'B'); - char_cnt--; - smart_str_appendc(pretval, '?'); - char_cnt--; + smart_str_appendc(pretval, 'B'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; - prev_in_left = ini_in_left = in_left; - ini_in_p = in_p; + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; - out_size = (char_cnt - 2) / 4 * 3; + out_size = (char_cnt - 2) / 4 * 3; - for (;;) { - out_p = buf; + for (;;) { + out_p = buf; - if (out_size <= out_reserved) { - err = PHP_ICONV_ERR_TOO_BIG; - goto out; - } + if (out_size <= out_reserved) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out_try; + } - out_left = out_size - out_reserved; + out_left = out_size - out_reserved; - if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - goto out; + if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out_try; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - goto out; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out_try; - case E2BIG: - if (prev_in_left == in_left) { - err = PHP_ICONV_ERR_TOO_BIG; - goto out; - } - break; + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out_try; + } + break; - default: - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + default: + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } } - } - out_left += out_reserved; + out_left += out_reserved; - if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { - if (errno != E2BIG) { + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { + if (errno != E2BIG) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } + } else { + break; + } + + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { err = PHP_ICONV_ERR_UNKNOWN; - goto out; + goto out_try; } - } else { - break; - } - if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + out_reserved += 4; + in_left = ini_in_left; + in_p = ini_in_p; } - out_reserved += 4; - in_left = ini_in_left; - in_p = ini_in_p; - } + prev_in_left = in_left; - prev_in_left = in_left; + encoded = php_base64_encode((unsigned char *) buf, (out_size - out_left)); - encoded = php_base64_encode((unsigned char *) buf, (out_size - out_left)); + if (char_cnt < ZSTR_LEN(encoded)) { + /* something went wrong! */ + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } - if (char_cnt < ZSTR_LEN(encoded)) { - /* something went wrong! */ - err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } + smart_str_append(pretval, encoded); + char_cnt -= ZSTR_LEN(encoded); + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; - smart_str_appendl(pretval, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); - char_cnt -= ZSTR_LEN(encoded); - smart_str_appendl(pretval, "?=", sizeof("?=") - 1); - char_cnt -= 2; + zend_string_release_ex(encoded, 0); + encoded = NULL; + } break; /* case PHP_ICONV_ENC_SCHEME_BASE64: */ - zend_string_release_ex(encoded, 0); - encoded = NULL; - } break; /* case PHP_ICONV_ENC_SCHEME_BASE64: */ + case PHP_ICONV_ENC_SCHEME_QPRINT: { + size_t ini_in_left; + const char *ini_in_p; + const unsigned char *p; + size_t nbytes_required; - case PHP_ICONV_ENC_SCHEME_QPRINT: { - size_t ini_in_left; - const char *ini_in_p; - const unsigned char *p; - size_t nbytes_required; + smart_str_appendc(pretval, 'Q'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; - smart_str_appendc(pretval, 'Q'); - char_cnt--; - smart_str_appendc(pretval, '?'); - char_cnt--; + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; - prev_in_left = ini_in_left = in_left; - ini_in_p = in_p; + for (out_size = (char_cnt - 2); out_size > 0;) { - for (out_size = (char_cnt - 2); out_size > 0;) { + nbytes_required = 0; - nbytes_required = 0; + out_p = buf; + out_left = out_size; - out_p = buf; - out_left = out_size; + if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out_try; - if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - goto out; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out_try; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - goto out; + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } + break; - case E2BIG: - if (prev_in_left == in_left) { + default: err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } - break; - - default: + goto out_try; + } + } + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { + if (errno != E2BIG) { err = PHP_ICONV_ERR_UNKNOWN; - goto out; + goto out_try; + } } - } - if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { - if (errno != E2BIG) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + nbytes_required += qp_table[*p]; } - } - for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { - nbytes_required += qp_table[*p]; + if (nbytes_required <= char_cnt - 2) { + break; + } + + out_size -= ((nbytes_required - (char_cnt - 2)) + 2) / 3; + in_left = ini_in_left; + in_p = ini_in_p; } - if (nbytes_required <= char_cnt - 2) { - break; + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + if (qp_table[*p] == 1) { + smart_str_appendc(pretval, *(char *)p); + char_cnt--; + } else { + static const char qp_digits[] = "0123456789ABCDEF"; + smart_str_appendc(pretval, '='); + smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); + smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); + char_cnt -= 3; + } } - out_size -= ((nbytes_required - (char_cnt - 2)) + 2) / 3; - in_left = ini_in_left; - in_p = ini_in_p; - } + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; - for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { - if (qp_table[*p] == 1) { - smart_str_appendc(pretval, *(char *)p); - char_cnt--; - } else { - static const char qp_digits[] = "0123456789ABCDEF"; - smart_str_appendc(pretval, '='); - smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); - smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); - char_cnt -= 3; + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; } - } - - smart_str_appendl(pretval, "?=", sizeof("?=") - 1); - char_cnt -= 2; - if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } + } break; /* case PHP_ICONV_ENC_SCHEME_QPRINT: */ + } + } while (in_left > 0); - } break; /* case PHP_ICONV_ENC_SCHEME_QPRINT: */ - } - } while (in_left > 0); + smart_str_0(pretval); - smart_str_0(pretval); +out_try: ; + } zend_catch { + bailout = true; + } zend_end_try(); out: if (cd != (iconv_t)(-1)) { @@ -1185,6 +1204,9 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn if (buf != NULL) { efree(buf); } + if (bailout) { + zend_bailout(); + } return err; } /* }}} */ @@ -1193,6 +1215,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *str, size_t str_nbytes, const char *enc, const char **next_pos, int mode) { php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + bool bailout = false; iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); @@ -1224,206 +1247,229 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st } p1 = str; - for (str_left = str_nbytes; str_left > 0; str_left--, p1++) { - int eos = 0; - - switch (scan_stat) { - case 0: /* expecting any character */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + zend_try { + for (str_left = str_nbytes; str_left > 0; str_left--, p1++) { + int eos = 0; + + switch (scan_stat) { + case 0: /* expecting any character */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case '\n': - scan_stat = 8; - break; + case '\n': + scan_stat = 8; + break; - case '=': /* first letter of an encoded chunk */ - encoded_word = p1; - scan_stat = 1; - break; + case '=': /* first letter of an encoded chunk */ + encoded_word = p1; + scan_stat = 1; + break; - case ' ': case '\t': /* a chunk of whitespaces */ - spaces = p1; - scan_stat = 11; - break; + case ' ': case '\t': /* a chunk of whitespaces */ + spaces = p1; + scan_stat = 11; + break; - default: /* first letter of a non-encoded word */ - err = _php_iconv_appendc(pretval, *p1, cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - if (mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR) { - err = PHP_ICONV_ERR_SUCCESS; - } else { - goto out; + default: /* first letter of a non-encoded word */ + err = _php_iconv_appendc(pretval, *p1, cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + if (mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR) { + err = PHP_ICONV_ERR_SUCCESS; + } else { + goto out_try; + } } - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } - break; - } - break; - - case 1: /* expecting a delimiter */ - if (*p1 != '?') { - if (*p1 == '\r' || *p1 == '\n') { - --p1; - } - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } + break; } break; - } - csname = p1 + 1; - scan_stat = 2; - break; - - case 2: /* expecting a charset name */ - switch (*p1) { - case '?': /* normal delimiter: encoding scheme follows */ - scan_stat = 3; - break; - - case '*': /* new style delimiter: locale id follows */ - scan_stat = 10; - break; - case '\r': case '\n': /* not an encoded-word */ - --p1; - _php_iconv_appendc(pretval, '=', cd_pl); - _php_iconv_appendc(pretval, '?', cd_pl); - err = _php_iconv_appendl(pretval, csname, (size_t)((p1 + 1) - csname), cd_pl); + case 1: /* expecting a delimiter */ + if (*p1 != '?') { + if (*p1 == '\r' || *p1 == '\n') { + --p1; + } + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } - csname = NULL; + encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { scan_stat = 12; - } - else { + } else { scan_stat = 0; } - continue; - } - if (scan_stat != 2) { - char tmpbuf[80]; - - if (csname == NULL) { - err = PHP_ICONV_ERR_MALFORMED; - goto out; + break; } + csname = p1 + 1; + scan_stat = 2; + break; - csname_len = (size_t)(p1 - csname); + case 2: /* expecting a charset name */ + switch (*p1) { + case '?': /* normal delimiter: encoding scheme follows */ + scan_stat = 3; + break; - if (csname_len > sizeof(tmpbuf) - 1) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + case '*': /* new style delimiter: locale id follows */ + scan_stat = 10; + break; + + case '\r': case '\n': /* not an encoded-word */ + --p1; + _php_iconv_appendc(pretval, '=', cd_pl); + _php_iconv_appendc(pretval, '?', cd_pl); + err = _php_iconv_appendl(pretval, csname, (size_t)((p1 + 1) - csname), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } - encoded_word = NULL; + csname = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { scan_stat = 12; - } else { + } + else { scan_stat = 0; } - break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; - } + continue; } + if (scan_stat != 2) { + char tmpbuf[80]; - memcpy(tmpbuf, csname, csname_len); - tmpbuf[csname_len] = '\0'; - - if (cd != (iconv_t)(-1)) { - iconv_close(cd); - } + if (csname == NULL) { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; + } - cd = iconv_open(enc, tmpbuf); + csname_len = (size_t)(p1 - csname); - if (cd == (iconv_t)(-1)) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* Bad character set, but the user wants us to - * press on. In this case, we'll just insert the - * undecoded encoded word, since there isn't really - * a more sensible behaviour available; the only - * other options are to swallow the encoded word - * entirely or decode it with an arbitrarily chosen - * single byte encoding, both of which seem to have - * a higher WTF factor than leaving it undecoded. - * - * Given this approach, we need to skip ahead to - * the end of the encoded word. */ - int qmarks = 2; - while (qmarks > 0 && str_left > 1) { - if (*(++p1) == '?') { - --qmarks; + if (csname_len > sizeof(tmpbuf) - 1) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; } - --str_left; + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } + } + + memcpy(tmpbuf, csname, csname_len); + tmpbuf[csname_len] = '\0'; - /* Look ahead to check for the terminating = that - * should be there as well; if it's there, we'll - * also include that. If it's not, there isn't much - * we can do at this point. */ - if (*(p1 + 1) == '=') { - ++p1; - if (str_left > 1) { + if (cd != (iconv_t)(-1)) { + iconv_close(cd); + } + + cd = iconv_open(enc, tmpbuf); + + if (cd == (iconv_t)(-1)) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* Bad character set, but the user wants us to + * press on. In this case, we'll just insert the + * undecoded encoded word, since there isn't really + * a more sensible behaviour available; the only + * other options are to swallow the encoded word + * entirely or decode it with an arbitrarily chosen + * single byte encoding, both of which seem to have + * a higher WTF factor than leaving it undecoded. + * + * Given this approach, we need to skip ahead to + * the end of the encoded word. */ + int qmarks = 2; + while (qmarks > 0 && str_left > 1) { + if (*(++p1) == '?') { + --qmarks; + } --str_left; } - } - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } + /* Look ahead to check for the terminating = that + * should be there as well; if it's there, we'll + * also include that. If it's not, there isn't much + * we can do at this point. */ + if (*(p1 + 1) == '=') { + ++p1; + if (str_left > 1) { + --str_left; + } + } - /* Let's go back and see if there are further - * encoded words or bare content, and hope they - * might actually have a valid character set. */ - scan_stat = 12; - break; - } else { - if (errno == EINVAL) { - err = PHP_ICONV_ERR_WRONG_CHARSET; + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + + /* Let's go back and see if there are further + * encoded words or bare content, and hope they + * might actually have a valid character set. */ + scan_stat = 12; + break; } else { - err = PHP_ICONV_ERR_CONVERTER; + if (errno == EINVAL) { + err = PHP_ICONV_ERR_WRONG_CHARSET; + } else { + err = PHP_ICONV_ERR_CONVERTER; + } + goto out_try; } - goto out; } } - } - break; + break; - case 3: /* expecting a encoding scheme specifier */ - switch (*p1) { - case 'b': - case 'B': - enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; - scan_stat = 4; - break; + case 3: /* expecting a encoding scheme specifier */ + switch (*p1) { + case 'b': + case 'B': + enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; + scan_stat = 4; + break; - case 'q': - case 'Q': - enc_scheme = PHP_ICONV_ENC_SCHEME_QPRINT; - scan_stat = 4; - break; + case 'q': + case 'Q': + enc_scheme = PHP_ICONV_ENC_SCHEME_QPRINT; + scan_stat = 4; + break; - default: + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; + } + } + break; + + case 4: /* expecting a delimiter */ + if (*p1 != '?') { if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { @@ -1434,301 +1480,285 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st break; } else { err = PHP_ICONV_ERR_MALFORMED; - goto out; + goto out_try; } - } - break; - - case 4: /* expecting a delimiter */ - if (*p1 != '?') { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } - break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; } - } - encoded_text = p1 + 1; - scan_stat = 5; - break; - - case 5: /* expecting an encoded portion */ - if (*p1 == '?') { - encoded_text_len = (size_t)(p1 - encoded_text); - scan_stat = 6; - } - break; + encoded_text = p1 + 1; + scan_stat = 5; + break; - case 7: /* expecting a "\n" character */ - if (*p1 == '\n') { - scan_stat = 8; - } else { - /* bare CR */ - _php_iconv_appendc(pretval, '\r', cd_pl); - _php_iconv_appendc(pretval, *p1, cd_pl); - scan_stat = 0; - } - break; + case 5: /* expecting an encoded portion */ + if (*p1 == '?') { + encoded_text_len = (size_t)(p1 - encoded_text); + scan_stat = 6; + } + break; - case 8: /* checking whether the following line is part of a - folded header */ - if (*p1 != ' ' && *p1 != '\t') { - --p1; - str_left = 1; /* quit_loop */ + case 7: /* expecting a "\n" character */ + if (*p1 == '\n') { + scan_stat = 8; + } else { + /* bare CR */ + _php_iconv_appendc(pretval, '\r', cd_pl); + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 0; + } break; - } - if (encoded_word == NULL) { - _php_iconv_appendc(pretval, ' ', cd_pl); - } - spaces = NULL; - scan_stat = 11; - break; - case 6: /* expecting a End-Of-Chunk character "=" */ - if (*p1 != '=') { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } + case 8: /* checking whether the following line is part of a + folded header */ + if (*p1 != ' ' && *p1 != '\t') { + --p1; + str_left = 1; /* quit_loop */ break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; } - } - scan_stat = 9; - if (str_left == 1) { - eos = 1; - } else { + if (encoded_word == NULL) { + _php_iconv_appendc(pretval, ' ', cd_pl); + } + spaces = NULL; + scan_stat = 11; break; - } - /* TODO might want to rearrange logic so this is more obvious */ - ZEND_FALLTHROUGH; - case 9: /* choice point, seeing what to do next.*/ - switch (*p1) { - default: - /* Handle non-RFC-compliant formats - * - * RFC2047 requires the character that comes right - * after an encoded word (chunk) to be a whitespace, - * while there are lots of broken implementations that - * generate such malformed headers that don't fulfill - * that requirement. - */ - if (!eos) { + case 6: /* expecting a End-Of-Chunk character "=" */ + if (*p1 != '=') { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } scan_stat = 12; - break; + } else { + scan_stat = 0; } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } - ZEND_FALLTHROUGH; - - case '\r': case '\n': case ' ': case '\t': { - zend_string *decoded_text; - - switch (enc_scheme) { - case PHP_ICONV_ENC_SCHEME_BASE64: - decoded_text = php_base64_decode((unsigned char*)encoded_text, encoded_text_len); - break; - - case PHP_ICONV_ENC_SCHEME_QPRINT: - decoded_text = php_quot_print_decode((unsigned char*)encoded_text, encoded_text_len, 1); - break; - default: - decoded_text = NULL; - break; - } + } + scan_stat = 9; + if (str_left == 1) { + eos = 1; + } else { + break; + } + /* TODO might want to rearrange logic so this is more obvious */ + ZEND_FALLTHROUGH; - if (decoded_text == NULL) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; + case 9: /* choice point, seeing what to do next.*/ + switch (*p1) { + default: + /* Handle non-RFC-compliant formats + * + * RFC2047 requires the character that comes right + * after an encoded word (chunk) to be a whitespace, + * while there are lots of broken implementations that + * generate such malformed headers that don't fulfill + * that requirement. + */ + if (!eos) { if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } scan_stat = 12; - } else { - scan_stat = 0; + break; } - break; - } else { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; } - } + ZEND_FALLTHROUGH; - err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); - if (err == PHP_ICONV_ERR_SUCCESS) { - err = _php_iconv_appendl(pretval, NULL, 0, cd); - } - zend_string_release_ex(decoded_text, 0); + case '\r': case '\n': case ' ': case '\t': { + zend_string *decoded_text; - if (err != PHP_ICONV_ERR_SUCCESS) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)(p1 - encoded_word), cd_pl); - encoded_word = NULL; - if (err != PHP_ICONV_ERR_SUCCESS) { + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: + decoded_text = php_base64_decode((unsigned char*)encoded_text, encoded_text_len); + break; + + case PHP_ICONV_ENC_SCHEME_QPRINT: + decoded_text = php_quot_print_decode((unsigned char*)encoded_text, encoded_text_len, 1); + break; + default: + decoded_text = NULL; + break; + } + + if (decoded_text == NULL) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } break; + } else { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; } - } else { - goto out; } - } - if (eos) { /* reached end-of-string. done. */ - scan_stat = 0; - break; - } + err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); + if (err == PHP_ICONV_ERR_SUCCESS) { + err = _php_iconv_appendl(pretval, NULL, 0, cd); + } + zend_string_release_ex(decoded_text, 0); - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + if (err != PHP_ICONV_ERR_SUCCESS) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)(p1 - encoded_word), cd_pl); + encoded_word = NULL; + if (err != PHP_ICONV_ERR_SUCCESS) { + break; + } + } else { + goto out_try; + } + } - case '\n': - scan_stat = 8; + if (eos) { /* reached end-of-string. done. */ + scan_stat = 0; break; + } - case '=': /* first letter of an encoded chunk */ - scan_stat = 1; - break; + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case ' ': case '\t': /* medial whitespaces */ - spaces = p1; - scan_stat = 11; - break; + case '\n': + scan_stat = 8; + break; - default: /* first letter of a non-encoded word */ - _php_iconv_appendc(pretval, *p1, cd_pl); - scan_stat = 12; - break; - } - } break; - } - break; + case '=': /* first letter of an encoded chunk */ + scan_stat = 1; + break; - case 10: /* expects a language specifier. dismiss it for now */ - if (*p1 == '?') { - scan_stat = 3; - } - break; + case ' ': case '\t': /* medial whitespaces */ + spaces = p1; + scan_stat = 11; + break; - case 11: /* expecting a chunk of whitespaces */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + default: /* first letter of a non-encoded word */ + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 12; + break; + } + } break; + } + break; - case '\n': - scan_stat = 8; - break; + case 10: /* expects a language specifier. dismiss it for now */ + if (*p1 == '?') { + scan_stat = 3; + } + break; - case '=': /* first letter of an encoded chunk */ - if (spaces != NULL && encoded_word == NULL) { - _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); - spaces = NULL; - } - encoded_word = p1; - scan_stat = 1; - break; + case 11: /* expecting a chunk of whitespaces */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case ' ': case '\t': - break; + case '\n': + scan_stat = 8; + break; - default: /* first letter of a non-encoded word */ - if (spaces != NULL) { - _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); - spaces = NULL; - } - _php_iconv_appendc(pretval, *p1, cd_pl); - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } - break; - } - break; + case '=': /* first letter of an encoded chunk */ + if (spaces != NULL && encoded_word == NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + encoded_word = p1; + scan_stat = 1; + break; - case 12: /* expecting a non-encoded word */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + case ' ': case '\t': + break; - case '\n': - scan_stat = 8; - break; + default: /* first letter of a non-encoded word */ + if (spaces != NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + _php_iconv_appendc(pretval, *p1, cd_pl); + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } + break; - case ' ': case '\t': - spaces = p1; - scan_stat = 11; - break; + case 12: /* expecting a non-encoded word */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case '=': /* first letter of an encoded chunk */ - if (!(mode & PHP_ICONV_MIME_DECODE_STRICT)) { - encoded_word = p1; - scan_stat = 1; + case '\n': + scan_stat = 8; break; - } - ZEND_FALLTHROUGH; - default: - _php_iconv_appendc(pretval, *p1, cd_pl); - break; - } - break; + case ' ': case '\t': + spaces = p1; + scan_stat = 11; + break; + + case '=': /* first letter of an encoded chunk */ + if (!(mode & PHP_ICONV_MIME_DECODE_STRICT)) { + encoded_word = p1; + scan_stat = 1; + break; + } + ZEND_FALLTHROUGH; + + default: + _php_iconv_appendc(pretval, *p1, cd_pl); + break; + } + break; + } } - } - switch (scan_stat) { - case 0: case 8: case 11: case 12: - break; - default: - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - if (scan_stat == 1) { - _php_iconv_appendc(pretval, '=', cd_pl); + switch (scan_stat) { + case 0: case 8: case 11: case 12: + break; + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + if (scan_stat == 1) { + _php_iconv_appendc(pretval, '=', cd_pl); + } + err = PHP_ICONV_ERR_SUCCESS; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } - err = PHP_ICONV_ERR_SUCCESS; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; - } - } + } - if (next_pos != NULL) { - *next_pos = p1; - } + if (next_pos != NULL) { + *next_pos = p1; + } + + smart_str_0(pretval); + +out_try: ; + } zend_catch { + bailout = true; + } zend_end_try(); - smart_str_0(pretval); out: if (cd != (iconv_t)(-1)) { iconv_close(cd); @@ -1736,6 +1766,9 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st if (cd_pl != (iconv_t)(-1)) { iconv_close(cd_pl); } + if (bailout) { + zend_bailout(); + } return err; } /* }}} */ @@ -2554,6 +2587,33 @@ static php_stream_filter_status_t php_iconv_stream_filter_do_filter( } /* }}} */ +/* {{{ php_iconv_stream_filter_seek */ +static zend_result php_iconv_stream_filter_seek( + php_stream *stream, + php_stream_filter *filter, + zend_off_t offset, + int whence) +{ + php_iconv_stream_filter *self = (php_iconv_stream_filter *)Z_PTR(filter->abstract); + + /* Reset stub buffer */ + self->stub_len = 0; + + /* Reset iconv conversion state by closing and reopening the converter */ + iconv_close(self->cd); + + self->cd = iconv_open(self->to_charset, self->from_charset); + if ((iconv_t)-1 == self->cd) { + php_error_docref(NULL, E_WARNING, + "iconv stream filter (\"%s\"=>\"%s\"): failed to reset conversion state", + self->from_charset, self->to_charset); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + /* {{{ php_iconv_stream_filter_cleanup */ static void php_iconv_stream_filter_cleanup(php_stream_filter *filter) { @@ -2564,17 +2624,23 @@ static void php_iconv_stream_filter_cleanup(php_stream_filter *filter) static const php_stream_filter_ops php_iconv_stream_filter_ops = { php_iconv_stream_filter_do_filter, + php_iconv_stream_filter_seek, php_iconv_stream_filter_cleanup, "convert.iconv.*" }; /* {{{ php_iconv_stream_filter_create */ -static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, uint8_t persistent) +static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, bool persistent) { php_iconv_stream_filter *inst; + php_stream_filter_seekable_t write_seekable; const char *from_charset = NULL, *to_charset = NULL; size_t from_charset_len, to_charset_len; + if (php_stream_filter_parse_write_seek_mode(params, &write_seekable) == FAILURE) { + return NULL; + } + if ((from_charset = strchr(name, '.')) == NULL) { return NULL; } @@ -2601,7 +2667,8 @@ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *nam return NULL; } - return php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent); + return php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent, + PSFS_SEEKABLE_START, write_seekable); } /* }}} */ diff --git a/ext/iconv/php_iconv.h b/ext/iconv/php_iconv.h index fcabdfaf6449..84a934e1e98b 100644 --- a/ext/iconv/php_iconv.h +++ b/ext/iconv/php_iconv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rui Hirokawa | | Stig Bakken | diff --git a/ext/iconv/tests/bug48147.phpt b/ext/iconv/tests/bug48147.phpt index ce304eecfb3c..434f71e517bb 100644 --- a/ext/iconv/tests/bug48147.phpt +++ b/ext/iconv/tests/bug48147.phpt @@ -2,17 +2,41 @@ Bug #48147 (iconv with //IGNORE cuts the string) --EXTENSIONS-- iconv +--SKIPIF-- + --FILE-- --EXPECTF-- Notice: iconv(): Detected an illegal character in input string in %s on line %d @@ -20,8 +44,8 @@ bool(false) string(10) "aa%C3%B8aa" Notice: iconv(): Detected an incomplete multibyte character in input string in %s on line %d -string(0) "" +bool(false) string(8) "%C3%B8aa" Notice: iconv(): Detected an incomplete multibyte character in input string in %s on line %d -string(0) "" +bool(false) diff --git a/ext/iconv/tests/bug52211.phpt b/ext/iconv/tests/bug52211.phpt index 155fad853485..7832cbeadd00 100644 --- a/ext/iconv/tests/bug52211.phpt +++ b/ext/iconv/tests/bug52211.phpt @@ -11,8 +11,22 @@ if (PHP_OS_FAMILY === 'Solaris') { --FILE-- diff --git a/ext/iconv/tests/bug76249.phpt b/ext/iconv/tests/bug76249.phpt index 37608ccc0447..2fa9b8cc0500 100644 --- a/ext/iconv/tests/bug76249.phpt +++ b/ext/iconv/tests/bug76249.phpt @@ -4,16 +4,27 @@ Bug #76249 (stream filter convert.iconv leads to infinite loop on invalid sequen iconv --FILE-- DONE ---EXPECTF-- -Warning: stream_get_contents(): iconv stream filter ("ucs-2"=>"utf%A8//IGNORE"): invalid multibyte sequence in %sbug76249.php on line %d -string(0) "" +--EXPECTREGEX-- +Warning: stream_get_contents\(\): iconv stream filter \("ucs-2"=>"utf-?8(\/\/IGNORE)?"\): invalid multibyte sequence in .*bug76249\.php on line \d+ +string\(0\) "" DONE diff --git a/ext/iconv/tests/eucjp2iso2022jp.phpt b/ext/iconv/tests/eucjp2iso2022jp.phpt index 490e772c80c2..ee64a5a52c96 100644 --- a/ext/iconv/tests/eucjp2iso2022jp.phpt +++ b/ext/iconv/tests/eucjp2iso2022jp.phpt @@ -7,6 +7,13 @@ iconv if (PHP_OS_FAMILY === 'Solaris') { die("skip Solaris iconv behaves differently"); } +// ISO-2022-JP is a stateful encoding, so the right answer is not +// unique. In particular, musl (type "unknown") is known to have an +// inefficient encoding for it that does not agree with the expected +// output below. +if (ICONV_IMPL == "unknown") { + die("skip byte-comparison of stateful encoding with unknown iconv"); +} ?> --INI-- error_reporting=2039 diff --git a/ext/iconv/tests/gh17399.phpt b/ext/iconv/tests/gh17399.phpt new file mode 100644 index 000000000000..b93fc638e84c --- /dev/null +++ b/ext/iconv/tests/gh17399.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv memory leak with large line-length in iconv_mime_encode) +--EXTENSIONS-- +iconv +--FILE-- + PHP_INT_MAX, +]; +iconv_mime_encode('Subject', 'test', $options); +?> +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_iconv.phpt b/ext/iconv/tests/gh17399_iconv.phpt new file mode 100644 index 000000000000..2cdd0e176b20 --- /dev/null +++ b/ext/iconv/tests/gh17399_iconv.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_mime_decode.phpt b/ext/iconv/tests/gh17399_mime_decode.phpt new file mode 100644 index 000000000000..95a37d364f33 --- /dev/null +++ b/ext/iconv/tests/gh17399_mime_decode.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv_mime_decode() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_substr.phpt b/ext/iconv/tests/gh17399_substr.phpt new file mode 100644 index 000000000000..12d4cff28eac --- /dev/null +++ b/ext/iconv/tests/gh17399_substr.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17399 (iconv_substr() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh21664.phpt b/ext/iconv/tests/gh21664.phpt new file mode 100644 index 000000000000..92c66049c8dd --- /dev/null +++ b/ext/iconv/tests/gh21664.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21664 (iconv_mime_decode/iconv_mime_encode bailout corruption) +--EXTENSIONS-- +iconv +--FILE-- + "UTF-8", "output-charset" => "UTF-8"]); +var_dump($r); + +echo "Done\n"; +?> +--EXPECTF-- +Notice: iconv_mime_decode(): Detected an illegal character in input string in %s on line %d +bool(false) + +Notice: iconv_mime_encode(): Detected an illegal character in input string in %s on line %d +bool(false) +Done diff --git a/ext/iconv/tests/iconv_mime_encode.phpt b/ext/iconv/tests/iconv_mime_encode.phpt index 9cf906a73e61..d2ec45df68b9 100644 --- a/ext/iconv/tests/iconv_mime_encode.phpt +++ b/ext/iconv/tests/iconv_mime_encode.phpt @@ -6,6 +6,13 @@ iconv iconv.internal_charset=iso-8859-1 --SKIPIF-- +--CLEAN-- + +--EXPECTF-- +First read (20 bytes): Hello, this is a tes +Seek to start: SUCCESS +Content after seek matches: YES + +Warning: fseek(): Stream filter convert.iconv.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE diff --git a/ext/intl/ERROR_CONVENTIONS.md b/ext/intl/ERROR_CONVENTIONS.md index 432862afd685..5c1b4eca86b8 100644 --- a/ext/intl/ERROR_CONVENTIONS.md +++ b/ext/intl/ERROR_CONVENTIONS.md @@ -6,14 +6,14 @@ conventions are enumerated in this document. * The last error is always stored globally. The global error code can be obtained in userland with `intl_get_error_code()`. -This is a `U_*` error code defined by ICU, but it does not have necessarily to -be returned obtained after a call to an ICU function. That is to say, the +This is a `U_*` error code defined by ICU, but it is not necessarily obtained +from a call to an ICU function. That is to say, the internal PHP wrapper functions can set these error codes when appropriate. For instance, in response to bad arguments (e.g. `zend_parse_parameters()` failure), the PHP wrapper function should set the global error code to -`U_ILLEGAL_ARGUMENT_ERROR`). +`U_ILLEGAL_ARGUMENT_ERROR`. -The error code (an integer) can be converter to the corresponding enum name +The error code (an integer) can be converted to the corresponding enum name string in userland with `intl_error_name()`. The associated message can be obtained with `intl_get_error_message()`. This is @@ -40,7 +40,7 @@ no way to pass ownership of the string without it being copied. unless the error is due to bad arguments, in which case only the global error should be set. -Objects store an intl_error structed in their private data. For instance: +Objects store an intl_error in their private data. For instance: ```c typedef struct { @@ -59,8 +59,8 @@ void intl_errors_set_code(intl_error* err, UErrorCode err_code); void intl_errors_set(intl_error* err, UErrorCode code, char* msg, int copyMsg); ``` -by passing a pointer to the object's `intl_error` structed as the first parameter. -Node the extra `s` in the functions' names (`errors`, not `error`). +by passing a pointer to the object's `intl_error` as the first parameter. +Note the extra `s` in the functions' names (`errors`, not `error`). Static methods should only set the global error. @@ -68,15 +68,15 @@ Static methods should only set the global error. `getErrorMessage()` methods. These methods are used to retrieve the error codes stored in the object's -private `intl_error` structured and mirror the global `intl_get_error_code()` +private `intl_error` structure and mirror the global `intl_get_error_code()` and `intl_get_error_message()`. * Intl methods and functions should return `FALSE` on error (even argument parsing errors), not `NULL`. Constructors and factory methods are the exception; these should return `NULL`, not `FALSE`. -Note that constructors in Intl generally (always?) don't throws exceptions. They -instead destroy the object to that the result of new `IntlClass()` can be +Note that constructors in Intl generally (always?) do not throw exceptions. They +instead destroy the object so that the result of new `IntlClass()` can be `NULL`. This may be surprising. * Intl functions and methods should reset the global error before doing anything diff --git a/ext/intl/breakiterator/breakiterator_class.cpp b/ext/intl/breakiterator/breakiterator_class.cpp index 4976d4ff675b..4d5793696cbb 100644 --- a/ext/intl/breakiterator/breakiterator_class.cpp +++ b/ext/intl/breakiterator/breakiterator_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -96,7 +96,7 @@ static int BreakIterator_compare_objects(zval *object1, /* {{{ clone handler for BreakIterator */ static zend_object *BreakIterator_clone_obj(zend_object *object) { - BreakIterator_object *bio_orig = php_intl_breakiterator_fetch_object(object); + const BreakIterator_object *bio_orig = php_intl_breakiterator_fetch_object(object); zend_object *ret_val = BreakIterator_ce_ptr->create_object(object->ce); BreakIterator_object *bio_new = php_intl_breakiterator_fetch_object(ret_val); @@ -212,7 +212,7 @@ U_CFUNC void breakiterator_register_BreakIterator_class(void) memcpy(&BreakIterator_handlers, &std_object_handlers, sizeof BreakIterator_handlers); - BreakIterator_handlers.offset = XtOffsetOf(BreakIterator_object, zo); + BreakIterator_handlers.offset = offsetof(BreakIterator_object, zo); BreakIterator_handlers.compare = BreakIterator_compare_objects; BreakIterator_handlers.clone_obj = BreakIterator_clone_obj; BreakIterator_handlers.get_debug_info = BreakIterator_get_debug_info; diff --git a/ext/intl/breakiterator/breakiterator_class.h b/ext/intl/breakiterator/breakiterator_class.h index 0852d86e2a82..cb4f072139ec 100644 --- a/ext/intl/breakiterator/breakiterator_class.h +++ b/ext/intl/breakiterator/breakiterator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -41,9 +41,7 @@ typedef struct { zend_object zo; } BreakIterator_object; -static inline BreakIterator_object *php_intl_breakiterator_fetch_object(zend_object *obj) { - return (BreakIterator_object *)((char*)(obj) - XtOffsetOf(BreakIterator_object, zo)); -} +#define php_intl_breakiterator_fetch_object(obj) ZEND_CONTAINER_OF(obj, BreakIterator_object, zo) #define Z_INTL_BREAKITERATOR_P(zv) php_intl_breakiterator_fetch_object(Z_OBJ_P(zv)) #define BREAKITER_ERROR(bio) (bio)->err diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index 34176bf90e52..d792a6367139 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -65,7 +65,7 @@ static void _breakiterator_move_forward(zend_object_iterator *iter) return; } - int32_t pos = biter->next(); + const int32_t pos = biter->next(); if (pos != BreakIterator::DONE) { ZVAL_LONG(&zoi_iter->current, (zend_long)pos); } //else we've reached the end of the enum, nothing more is required @@ -76,7 +76,7 @@ static void _breakiterator_rewind(zend_object_iterator *iter) BreakIterator *biter = _breakiter_prolog(iter); zoi_with_current *zoi_iter = (zoi_with_current*)iter; - int32_t pos = biter->first(); + const int32_t pos = biter->first(); ZVAL_LONG(&zoi_iter->current, (zend_long)pos); } diff --git a/ext/intl/breakiterator/breakiterator_iterators.h b/ext/intl/breakiterator/breakiterator_iterators.h index e52d066ac9ed..3ac07cd271c8 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.h +++ b/ext/intl/breakiterator/breakiterator_iterators.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/breakiterator_methods.cpp b/ext/intl/breakiterator/breakiterator_methods.cpp index c9791d4b23ae..60659915bf85 100644 --- a/ext/intl/breakiterator/breakiterator_methods.cpp +++ b/ext/intl/breakiterator/breakiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -171,7 +171,7 @@ static void _breakiter_no_args_ret_int32( BREAKITER_METHOD_FETCH_OBJECT; - int32_t res = (bio->biter->*func)(); + const int32_t res = (bio->biter->*func)(); RETURN_LONG((zend_long)res); } @@ -195,7 +195,7 @@ static void _breakiter_int32_ret_int32( RETURN_THROWS(); } - int32_t res = (bio->biter->*func)((int32_t)arg); + const int32_t res = (bio->biter->*func)((int32_t)arg); RETURN_LONG((zend_long)res); } @@ -246,7 +246,7 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, current) BREAKITER_METHOD_FETCH_OBJECT; - int32_t res = bio->biter->current(); + const int32_t res = bio->biter->current(); RETURN_LONG((zend_long)res); } @@ -282,7 +282,7 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, isBoundary) BREAKITER_METHOD_FETCH_OBJECT; - UBool res = bio->biter->isBoundary((int32_t)offset); + const UBool res = bio->biter->isBoundary((int32_t)offset); RETURN_BOOL((zend_long)res); } @@ -297,11 +297,9 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, getLocale) Z_PARAM_LONG(locale_type) ZEND_PARSE_PARAMETERS_END(); - /* TODO: Change to ValueError? */ if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "invalid locale type"); - RETURN_FALSE; + zend_argument_value_error(1, "must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE"); + RETURN_THROWS(); } BREAKITER_METHOD_FETCH_OBJECT; diff --git a/ext/intl/breakiterator/codepointiterator_internal.cpp b/ext/intl/breakiterator/codepointiterator_internal.cpp index 3982a599af38..0604cfa24167 100644 --- a/ext/intl/breakiterator/codepointiterator_internal.cpp +++ b/ext/intl/breakiterator/codepointiterator_internal.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -126,7 +126,7 @@ void CodePointBreakIterator::setText(const UnicodeString &text) void CodePointBreakIterator::setText(UText *text, UErrorCode &status) { - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { return; } @@ -234,7 +234,7 @@ CodePointBreakIterator *CodePointBreakIterator::createBufferClone( void *stackBuffer, int32_t &bufferSize, UErrorCode &status) { //see implementation of RuleBasedBreakIterator::createBufferClone() - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { return NULL; } @@ -273,17 +273,17 @@ CodePointBreakIterator *CodePointBreakIterator::createBufferClone( CodePointBreakIterator &CodePointBreakIterator::refreshInputText(UText *input, UErrorCode &status) { //see implementation of RuleBasedBreakIterator::createBufferClone() - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { return *this; } - if (input == NULL) { + if (UNEXPECTED(input == NULL)) { status = U_ILLEGAL_ARGUMENT_ERROR; return *this; } int64_t pos = utext_getNativeIndex(this->fText); this->fText = utext_clone(this->fText, input, false, true, &status); - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { return *this; } diff --git a/ext/intl/breakiterator/codepointiterator_internal.h b/ext/intl/breakiterator/codepointiterator_internal.h index 8090bfbbd3cc..a64d49e24d5e 100644 --- a/ext/intl/breakiterator/codepointiterator_internal.h +++ b/ext/intl/breakiterator/codepointiterator_internal.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/codepointiterator_methods.cpp b/ext/intl/breakiterator/codepointiterator_methods.cpp index 49beb41be4e9..3b5044cb45a1 100644 --- a/ext/intl/breakiterator/codepointiterator_methods.cpp +++ b/ext/intl/breakiterator/codepointiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index a7c322b1d816..4526b9faab13 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -57,7 +57,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) if (!compiled) { UnicodeString rulesStr; UParseError parseError = UParseError(); - if (intl_stringFromChar(rulesStr, ZSTR_VAL(rules), ZSTR_LEN(rules), &status) == FAILURE) { + if (UNEXPECTED(intl_stringFromChar(rulesStr, ZSTR_VAL(rules), ZSTR_LEN(rules), &status) == FAILURE)) { zend_throw_exception(IntlException_ce_ptr, "IntlRuleBasedBreakIterator::__construct(): rules were not a valid UTF-8 string", 0); RETURN_THROWS(); @@ -65,7 +65,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) rbbi = new RuleBasedBreakIterator(rulesStr, parseError, status); intl_error_set_code(NULL, status); - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { smart_str parse_error_str; parse_error_str = intl_parse_error_to_string(&parseError); zend_throw_exception_ex(IntlException_ce_ptr, 0, @@ -78,7 +78,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) } } else { // compiled rbbi = new RuleBasedBreakIterator(reinterpret_cast(ZSTR_VAL(rules)), ZSTR_LEN(rules), status); - if (U_FAILURE(status)) { + if (UNEXPECTED(U_FAILURE(status))) { zend_throw_exception(IntlException_ce_ptr, "IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules", 0); delete rbbi; @@ -165,7 +165,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getBinaryRules) uint32_t rules_len; const uint8_t *rules = fetch_rbbi(bio)->getBinaryRules(rules_len); - if (rules_len > INT_MAX - 1) { + if (UNEXPECTED(rules_len > INT_MAX - 1)) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), "the rules are too large"); RETURN_FALSE; diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index 326b5475b73a..c74f0ab9412f 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -77,7 +77,7 @@ U_CFUNC void calendar_object_construct(zval *object, /* {{{ clone handler for Calendar */ static zend_object *Calendar_clone_obj(zend_object *object) { - Calendar_object *co_orig = php_intl_calendar_fetch_object(object); + const Calendar_object *co_orig = php_intl_calendar_fetch_object(object); zend_object *ret_val = Calendar_ce_ptr->create_object(object->ce); Calendar_object *co_new = php_intl_calendar_fetch_object(ret_val); @@ -192,7 +192,7 @@ static HashTable *Calendar_get_debug_info(zend_object *object, int *is_temp) i++) { UErrorCode uec = U_ZERO_ERROR; const char *name = debug_info_fields[i].name; - int32_t res = cal->get(debug_info_fields[i].field, uec); + const int32_t res = cal->get(debug_info_fields[i].field, uec); if (U_SUCCESS(uec)) { add_assoc_long(&zfields, name, (zend_long)res); } else { @@ -256,7 +256,7 @@ void calendar_register_IntlCalendar_class(void) memcpy( &Calendar_handlers, &std_object_handlers, sizeof Calendar_handlers); - Calendar_handlers.offset = XtOffsetOf(Calendar_object, zo); + Calendar_handlers.offset = offsetof(Calendar_object, zo); Calendar_handlers.clone_obj = Calendar_clone_obj; Calendar_handlers.get_debug_info = Calendar_get_debug_info; Calendar_handlers.free_obj = Calendar_objects_free; diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h index 167bded8f31b..7c74aede9475 100644 --- a/ext/intl/calendar/calendar_class.h +++ b/ext/intl/calendar/calendar_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -38,9 +38,7 @@ typedef struct { zend_object zo; } Calendar_object; -static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj) { - return (Calendar_object *)((char*)(obj) - XtOffsetOf(Calendar_object, zo)); -} +#define php_intl_calendar_fetch_object(obj) ZEND_CONTAINER_OF(obj, Calendar_object, zo) #define Z_INTL_CALENDAR_P(zv) php_intl_calendar_fetch_object(Z_OBJ_P(zv)) #define CALENDAR_ERROR(co) (co)->err diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index c404286fe094..fcb2e56bb897 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -85,7 +85,7 @@ U_CFUNC PHP_FUNCTION(intlcal_create_instance) Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END(); - TimeZone *timeZone = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr); + TimeZone *timeZone = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr, 1); if (timeZone == nullptr) { RETURN_NULL(); } @@ -203,7 +203,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_available_locales) int32_t count; const Locale *availLocales = Calendar::getAvailableLocales(count); - array_init(return_value); + array_init_size(return_value, count); for (int i = 0; i < count; i++) { Locale locale = availLocales[i]; add_next_index_string(return_value, locale.getName()); @@ -226,7 +226,7 @@ static void _php_intlcal_field_uec_ret_in32t_method( CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = (co->ucal->*func)( + const int32_t result = (co->ucal->*func)( (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); @@ -250,7 +250,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_time) CALENDAR_METHOD_FETCH_OBJECT; - UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co)); + const UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::getTime"); RETURN_DOUBLE((double)result); @@ -316,7 +316,7 @@ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone) } TimeZone *timeZone = timezone_process_timezone_argument( - timezone_object, timezone_string, CALENDAR_ERROR_P(co)); + timezone_object, timezone_string, CALENDAR_ERROR_P(co), 2); if (timeZone == nullptr) { RETURN_FALSE; } @@ -345,7 +345,7 @@ U_CFUNC PHP_METHOD(IntlCalendar, setTimeZone) } TimeZone *timeZone = timezone_process_timezone_argument( - timezone_object, timezone_string, CALENDAR_ERROR_P(co)); + timezone_object, timezone_string, CALENDAR_ERROR_P(co), 1); if (timeZone == nullptr) { RETURN_FALSE; } @@ -373,11 +373,11 @@ static void _php_intlcal_before_after( when_co = Z_INTL_CALENDAR_P(when_object); if (when_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } - UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); + const UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)res); @@ -401,7 +401,7 @@ U_CFUNC PHP_FUNCTION(intlcal_set) object = getThis(); - int arg_num = ZEND_NUM_ARGS() - (object ? 0 : 1); + const int arg_num = ZEND_NUM_ARGS() - (object ? 0 : 1); if (object && arg_num > 2) { zend_error(E_DEPRECATED, "Calling IntlCalendar::set() with more than 2 arguments is deprecated, " @@ -419,8 +419,8 @@ U_CFUNC PHP_FUNCTION(intlcal_set) } for (int i = 0; i < arg_num; i++) { - /* Arguments start at 1 */ - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 1); + /* Count from intlcal_set($calendar, ...), so date/time arguments start at #2. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 2); } CALENDAR_METHOD_FETCH_OBJECT; @@ -455,9 +455,10 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDate) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); CALENDAR_METHOD_FETCH_OBJECT; @@ -478,18 +479,19 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDateTime) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 5); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 6); CALENDAR_METHOD_FETCH_OBJECT; if (second_is_null) { co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute); } else { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 7); co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second); } } @@ -562,7 +564,7 @@ U_CFUNC PHP_FUNCTION(intlcal_field_difference) CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = co->ucal->fieldDifference((UDate)when, + const int32_t result = co->ucal->fieldDifference((UDate)when, (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); @@ -595,7 +597,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type) CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = co->ucal->getDayOfWeekType( + const int32_t result = co->ucal->getDayOfWeekType( (UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); @@ -613,7 +615,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week) CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co)); + const int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); @@ -635,7 +637,7 @@ static void _php_intlcal_field_ret_in32t_method( CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = (co->ucal->*func)((UCalendarDateFields)field); + const int32_t result = (co->ucal->*func)((UCalendarDateFields)field); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); @@ -694,7 +696,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week) CALENDAR_METHOD_FETCH_OBJECT; - uint8_t result = co->ucal->getMinimalDaysInFirstWeek(); + const uint8_t result = co->ucal->getMinimalDaysInFirstWeek(); /* TODO Is it really a failure? */ INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); @@ -756,7 +758,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition) CALENDAR_METHOD_FETCH_OBJECT; - int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow, + const int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); @@ -774,7 +776,7 @@ U_CFUNC PHP_FUNCTION(intlcal_in_daylight_time) CALENDAR_METHOD_FETCH_OBJECT; - UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co)); + const UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); @@ -794,7 +796,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_equivalent_to) other_co = Z_INTL_CALENDAR_P(other_object); if (other_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } @@ -850,7 +852,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_weekend) if (date_is_null) { RETURN_BOOL((int)co->ucal->isWeekend()); } else { - UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co)); + const UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); } @@ -931,11 +933,11 @@ U_CFUNC PHP_FUNCTION(intlcal_equals) CALENDAR_METHOD_FETCH_OBJECT; other_co = Z_INTL_CALENDAR_P(other_object); if (other_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } - UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co)); + const UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::equals"); RETURN_BOOL((int)result); @@ -1114,7 +1116,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) /* There are no exported functions in ext/date to this * in a more native fashion */ - double date = co->ucal->getTime(CALENDAR_ERROR_CODE(co)) / 1000.; + const double date = co->ucal->getTime(CALENDAR_ERROR_CODE(co)) / 1000.; int64_t ts; char ts_str[sizeof("@-9223372036854775808")]; int ts_str_len; diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index 0cc3a94d4c56..aeb728e29de1 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -143,7 +143,7 @@ static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS, bool if (variant <= 2) { // From timezone and locale (0 to 2 arguments) - TimeZone *tz = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr); + TimeZone *tz = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr, 1); if (tz == nullptr) { // TODO: Exception should always occur already? if (!EG(exception)) { @@ -176,7 +176,7 @@ static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS, bool // From date/time (3, 5 or 6 arguments) GregorianCalendar *tmp; for (int i = 0; i < variant; i++) { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], hasThis() ? (i-1) : i); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], i + 1); } if (variant == 3) { diff --git a/ext/intl/collator/collator.h b/ext/intl/collator/collator.h index e92429f51179..959da9063e09 100644 --- a/ext/intl/collator/collator.h +++ b/ext/intl/collator/collator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_attr.cpp b/ext/intl/collator/collator_attr.cpp index f56596deb6b0..14b8abf497b4 100644 --- a/ext/intl/collator/collator_attr.cpp +++ b/ext/intl/collator/collator_attr.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_class.cpp b/ext/intl/collator/collator_class.cpp index 293a089c2679..4fd991bd156c 100644 --- a/ext/intl/collator/collator_class.cpp +++ b/ext/intl/collator/collator_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -76,7 +76,7 @@ U_CFUNC void collator_register_Collator_symbols(int module_number) sizeof Collator_handlers); /* Collator has no usable clone semantics - ucol_cloneBinary/ucol_openBinary require binary buffer for which we don't have the place to keep */ - Collator_handlers.offset = XtOffsetOf(Collator_object, zo); + Collator_handlers.offset = offsetof(Collator_object, zo); Collator_handlers.clone_obj = nullptr; Collator_handlers.free_obj = Collator_objects_free; } diff --git a/ext/intl/collator/collator_class.h b/ext/intl/collator/collator_class.h index a281b2bec8ad..637d5dc490ae 100644 --- a/ext/intl/collator/collator_class.h +++ b/ext/intl/collator/collator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -47,9 +47,7 @@ typedef struct { #define COLLATOR_ERROR_CODE(co) INTL_ERROR_CODE(COLLATOR_ERROR(co)) #define COLLATOR_ERROR_CODE_P(co) &(INTL_ERROR_CODE(COLLATOR_ERROR(co))) -static inline Collator_object *php_intl_collator_fetch_object(zend_object *obj) { - return (Collator_object *)((char*)(obj) - XtOffsetOf(Collator_object, zo)); -} +#define php_intl_collator_fetch_object(obj) ZEND_CONTAINER_OF(obj, Collator_object, zo) #define Z_INTL_COLLATOR_P(zv) php_intl_collator_fetch_object(Z_OBJ_P(zv)) #ifdef __cplusplus diff --git a/ext/intl/collator/collator_compare.cpp b/ext/intl/collator/collator_compare.cpp index 38e283a6d853..bac0bbf50b21 100644 --- a/ext/intl/collator/collator_compare.cpp +++ b/ext/intl/collator/collator_compare.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_convert.cpp b/ext/intl/collator/collator_convert.cpp index d4de15aa0b82..dd3360a69092 100644 --- a/ext/intl/collator/collator_convert.cpp +++ b/ext/intl/collator/collator_convert.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -289,7 +289,7 @@ U_CFUNC zval* collator_convert_string_to_double( zval* str, zval *rv ) /* {{{ collator_convert_string_to_number_if_possible * - * Convert string to numer. + * Convert string to number. * * @param zval* str String to convert. * diff --git a/ext/intl/collator/collator_convert.h b/ext/intl/collator/collator_convert.h index 8c5356095b7a..1d65d9d2d76b 100644 --- a/ext/intl/collator/collator_convert.h +++ b/ext/intl/collator/collator_convert.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_create.cpp b/ext/intl/collator/collator_create.cpp index 59280bcdbed5..d2f16b67a26f 100644 --- a/ext/intl/collator/collator_create.cpp +++ b/ext/intl/collator/collator_create.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -44,6 +44,10 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); COLLATOR_METHOD_FETCH_OBJECT; + if (co->ucoll) { + zend_throw_error(NULL, "Collator object is already constructed"); + return FAILURE; + } if(locale_len == 0) { locale = (char *)intl_locale_get_default(); diff --git a/ext/intl/collator/collator_error.cpp b/ext/intl/collator/collator_error.cpp index aa333b5098a0..2a1eda8f9f36 100644 --- a/ext/intl/collator/collator_error.cpp +++ b/ext/intl/collator/collator_error.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_is_numeric.cpp b/ext/intl/collator/collator_is_numeric.cpp index b3cc52085dea..85a6eb695c0b 100644 --- a/ext/intl/collator/collator_is_numeric.cpp +++ b/ext/intl/collator/collator_is_numeric.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_is_numeric.h b/ext/intl/collator/collator_is_numeric.h index d30acd0b5843..e2f6ed83a178 100644 --- a/ext/intl/collator/collator_is_numeric.h +++ b/ext/intl/collator/collator_is_numeric.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_locale.cpp b/ext/intl/collator/collator_locale.cpp index 67b3d1342cc7..ea1393779846 100644 --- a/ext/intl/collator/collator_locale.cpp +++ b/ext/intl/collator/collator_locale.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_sort.cpp b/ext/intl/collator/collator_sort.cpp index 003d7f45a837..b7c2b8736596 100644 --- a/ext/intl/collator/collator_sort.cpp +++ b/ext/intl/collator/collator_sort.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -262,12 +262,13 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) UCollator* saved_collator; zval* array = nullptr; HashTable* hash = nullptr; + zend_array* sorted = nullptr; zend_long sort_flags = COLLATOR_SORT_REGULAR; COLLATOR_METHOD_INIT_VARS /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa/|l", + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa|l", &object, Collator_ce_ptr, &array, &sort_flags ) == FAILURE ) { RETURN_THROWS(); @@ -286,8 +287,14 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) hash = Z_ARRVAL_P( array ); + /* Copy array, so the in-place modifications will not be visible to the callback function */ + sorted = zend_array_dup( hash ); + /* Convert strings in the specified array from UTF-8 to UTF-16. */ - collator_convert_hash_from_utf8_to_utf16( hash, COLLATOR_ERROR_CODE_P( co ) ); + collator_convert_hash_from_utf8_to_utf16( sorted, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) { + zend_array_destroy( sorted ); + } COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-8 to UTF-16" ); /* Save specified collator in the request-global (?) variable. */ @@ -295,15 +302,23 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) INTL_G( current_collator ) = co->ucoll; /* Sort specified array. */ - zend_hash_sort(hash, collator_compare_func, renumber); + zend_hash_sort( sorted, collator_compare_func, renumber ); /* Restore saved collator. */ INTL_G( current_collator ) = saved_collator; /* Convert strings in the specified array back to UTF-8. */ - collator_convert_hash_from_utf16_to_utf8( hash, COLLATOR_ERROR_CODE_P( co ) ); + collator_convert_hash_from_utf16_to_utf8( sorted, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) { + zend_array_destroy( sorted ); + } COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-16 to UTF-8" ); + zval garbage; + ZVAL_COPY_VALUE( &garbage, array ); + ZVAL_ARR( array, sorted ); + zval_ptr_dtor( &garbage ); + RETURN_TRUE; } /* }}} */ @@ -380,7 +395,7 @@ U_CFUNC PHP_FUNCTION( collator_sort_with_sort_keys ) if( !hash || zend_hash_num_elements( hash ) == 0 ) RETURN_TRUE; - /* Create bufers */ + /* Create buffers */ sortKeyBuf = reinterpret_cast(ecalloc( sortKeyBufSize, sizeof( char ) )); sortKeyIndxBuf = reinterpret_cast(ecalloc( sortKeyIndxBufSize, sizeof( uint8_t ) )); utf16_buf = eumalloc( utf16_buf_size ); diff --git a/ext/intl/collator/collator_sort.h b/ext/intl/collator/collator_sort.h index 53abc1028a0e..6b4c5766da6b 100644 --- a/ext/intl/collator/collator_sort.h +++ b/ext/intl/collator/collator_sort.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp index f2ca077554b4..c9eb45b0f2d9 100644 --- a/ext/intl/common/common_date.cpp +++ b/ext/intl/common/common_date.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -55,9 +55,9 @@ U_CFUNC TimeZone *timezone_convert_datetimezone( minutes = offset_mins - hours * 60; minutes *= minutes > 0 ? 1 : -1; - if (offset_mins <= -24 * 60 || offset_mins >= 24 * 60) { + if (UNEXPECTED(offset_mins <= -24 * 60 || offset_mins >= 24 * 60)) { intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - "object has an time zone offset that's too large"); + "object has a time zone offset that is too large"); return NULL; } @@ -202,7 +202,6 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err) } } } else { - /* TODO: try with cast(), get() to obtain a number */ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, "invalid object type for date/time " "(only IntlCalendar and DateTimeInterface permitted)"); diff --git a/ext/intl/common/common_date.h b/ext/intl/common/common_date.h index 988f279294c3..a3a58eb3b037 100644 --- a/ext/intl/common/common_date.h +++ b/ext/intl/common/common_date.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp index 8cf9796717f4..4260e3cce57f 100644 --- a/ext/intl/common/common_enum.cpp +++ b/ext/intl/common/common_enum.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -226,7 +226,7 @@ PHP_METHOD(IntlIterator, current) INTLITERATOR_METHOD_FETCH_OBJECT; data = ii->iterator->funcs->get_current_data(ii->iterator); - if (data) { + if (data && !Z_ISUNDEF_P(data)) { RETURN_COPY_DEREF(data); } } @@ -294,7 +294,7 @@ U_CFUNC void intl_register_common_symbols(int module_number) memcpy(&IntlIterator_handlers, &std_object_handlers, sizeof IntlIterator_handlers); - IntlIterator_handlers.offset = XtOffsetOf(IntlIterator_object, zo); + IntlIterator_handlers.offset = offsetof(IntlIterator_object, zo); IntlIterator_handlers.clone_obj = NULL; IntlIterator_handlers.dtor_obj = IntlIterator_objects_dtor; IntlIterator_handlers.free_obj = IntlIterator_objects_free; diff --git a/ext/intl/common/common_enum.h b/ext/intl/common/common_enum.h index 6f0828528901..e4a8b5461df6 100644 --- a/ext/intl/common/common_enum.h +++ b/ext/intl/common/common_enum.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -51,10 +51,7 @@ typedef struct { zend_object zo; } IntlIterator_object; - -static inline IntlIterator_object *php_intl_iterator_fetch_object(zend_object *obj) { - return (IntlIterator_object *)((char*)(obj) - XtOffsetOf(IntlIterator_object, zo)); -} +#define php_intl_iterator_fetch_object(obj) ZEND_CONTAINER_OF(obj, IntlIterator_object, zo) #define Z_INTL_ITERATOR_P(zv) php_intl_iterator_fetch_object(Z_OBJ_P(zv)) typedef struct { diff --git a/ext/intl/common/common_error.cpp b/ext/intl/common/common_error.cpp index cb12d8dff8f3..8d0cca52bb77 100644 --- a/ext/intl/common/common_error.cpp +++ b/ext/intl/common/common_error.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 7251f2283534..62ea18c4470d 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -9,6 +9,7 @@ if test "$PHP_INTL" != "no"; then INTL_COMMON_FLAGS="$ICU_CFLAGS -Wno-write-strings -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" PHP_NEW_EXTENSION([intl], m4_normalize([ intl_convert.c + intl_icu_compat.c intl_error.c php_intl.c ]), diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index da8285b50d0c..016f17835f8e 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -9,7 +9,7 @@ if (PHP_INTL != "no") { CHECK_LIB("icuuc.lib", "intl", PHP_INTL) && CHECK_HEADER("unicode/utf.h", "CFLAGS_INTL")) { // always build as shared - zend_strtod.c/ICU type conflict - EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true, + EXTENSION("intl", "php_intl.c intl_convert.c intl_icu_compat.c intl_convertcpp.cpp intl_error.c ", true, "/I \"" + configure_module_dirname + "\" /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_EXTENSION_DEP('intl', 'date'); ADD_SOURCES(configure_module_dirname + "/collator", "\ @@ -92,13 +92,11 @@ if (PHP_INTL != "no") { resourcebundle_iterator.cpp", "intl"); - if (CHECK_HEADER("unicode/uspoof.h", "CFLAGS_INTL")) { - ADD_SOURCES(configure_module_dirname + "/spoofchecker", "\ - spoofchecker_class.cpp \ - spoofchecker_create.cpp \ - spoofchecker_main.cpp", - "intl"); - } + ADD_SOURCES(configure_module_dirname + "/spoofchecker", "\ + spoofchecker_class.cpp \ + spoofchecker_create.cpp \ + spoofchecker_main.cpp", + "intl"); ADD_SOURCES(configure_module_dirname + "/transliterator", "\ transliterator_class.cpp \ diff --git a/ext/intl/converter/converter.cpp b/ext/intl/converter/converter.cpp index ad68909b5ea3..402a50482485 100644 --- a/ext/intl/converter/converter.cpp +++ b/ext/intl/converter/converter.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ @@ -20,6 +20,8 @@ #include #include +#include "../intl_icu_compat.h" + extern "C" { #include "converter.h" #include "php_intl.h" @@ -37,7 +39,7 @@ typedef struct _php_converter_object { static inline php_converter_object *php_converter_fetch_object(zend_object *obj) { - return (php_converter_object *)((char*)(obj) - XtOffsetOf(php_converter_object, obj)); + return (php_converter_object *)((char*)(obj) - offsetof(php_converter_object, obj)); } #define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv)) @@ -159,17 +161,17 @@ static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicode return; case IS_LONG: { - zend_long lval = Z_LVAL_P(val); - if ((lval < 0) || (lval > 0x10FFFF)) { + const zend_long lval = Z_LVAL_P(val); + if (UNEXPECTED((lval < 0) || (lval > 0x10FFFF))) { php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, "Invalid codepoint U+%04lx", lval); return; } if (lval > 0xFFFF) { /* Supplemental planes U+010000 - U+10FFFF */ if (TARGET_CHECK(args, 2)) { - /* TODO: Find the ICU call which does this properly */ - *(args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800); - *(args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00); + int32_t offset = 0; + U16_APPEND_UNSAFE(args->target, offset, lval); + args->target += offset; } return; } @@ -265,7 +267,7 @@ static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUni return; case IS_STRING: { - size_t vallen = Z_STRLEN_P(val); + const size_t vallen = Z_STRLEN_P(val); if (TARGET_CHECK(args, vallen)) { args->target = reinterpret_cast(zend_mempcpy(args->target, Z_STRVAL_P(val), vallen)); } @@ -634,7 +636,7 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, zend_string *ret; UChar *temp; - if (!src_cnv || !dest_cnv) { + if (UNEXPECTED(!src_cnv || !dest_cnv)) { php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Internal converters not initialized"); return nullptr; @@ -682,6 +684,16 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv, } /* }}} */ +static void php_converter_set_subst_chars(UConverter *cnv, const zend_string *subst, UErrorCode *error) +{ + if (UNEXPECTED(ZSTR_LEN(subst) > SCHAR_MAX)) { + *error = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + ucnv_setSubstChars(cnv, ZSTR_VAL(subst), (int8_t) ZSTR_LEN(subst), error); +} + /* {{{ */ #define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1); PHP_METHOD(UConverter, reasonText) { @@ -761,13 +773,13 @@ PHP_METHOD(UConverter, transcode) { (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL && Z_TYPE_P(tmpzval) == IS_STRING) { error = U_ZERO_ERROR; - ucnv_setSubstChars(src_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); + php_converter_set_subst_chars(src_cnv, Z_STR_P(tmpzval), &error); } if (U_SUCCESS(error) && (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL && Z_TYPE_P(tmpzval) == IS_STRING) { error = U_ZERO_ERROR; - ucnv_setSubstChars(dest_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); + php_converter_set_subst_chars(dest_cnv, Z_STR_P(tmpzval), &error); } } @@ -934,22 +946,15 @@ static zend_object *php_converter_create_object(zend_class_entry *ce) { } static zend_object *php_converter_clone_object(zend_object *object) { - php_converter_object *objval, *oldobj = php_converter_fetch_object(object); + const php_converter_object *oldobj = php_converter_fetch_object(object); + php_converter_object *objval; zend_object *retval = php_converter_object_ctor(object->ce, &objval); UErrorCode error = U_ZERO_ERROR; -#if U_ICU_VERSION_MAJOR_NUM > 70 - objval->src = ucnv_clone(oldobj->src, &error); -#else - objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error); -#endif + objval->src = intl_icu_compat_ucnv_clone(oldobj->src, &error); if (U_SUCCESS(error)) { error = U_ZERO_ERROR; -#if U_ICU_VERSION_MAJOR_NUM > 70 - objval->dest = ucnv_clone(oldobj->dest, &error); -#else - objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error); -#endif + objval->dest = intl_icu_compat_ucnv_clone(oldobj->dest, &error); } if (U_FAILURE(error)) { @@ -975,7 +980,7 @@ U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) { php_converter_ce->create_object = php_converter_create_object; php_converter_ce->default_object_handlers = &php_converter_object_handlers; memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_converter_object_handlers.offset = XtOffsetOf(php_converter_object, obj); + php_converter_object_handlers.offset = offsetof(php_converter_object, obj); php_converter_object_handlers.clone_obj = php_converter_clone_object; php_converter_object_handlers.free_obj = php_converter_free_object; diff --git a/ext/intl/converter/converter.h b/ext/intl/converter/converter.h index 5d779560811d..60967d196723 100644 --- a/ext/intl/converter/converter.h +++ b/ext/intl/converter/converter.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat.cpp b/ext/intl/dateformat/dateformat.cpp index cf2b445590bb..64454a8afde9 100644 --- a/ext/intl/dateformat/dateformat.cpp +++ b/ext/intl/dateformat/dateformat.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat.h b/ext/intl/dateformat/dateformat.h index 3e0b14cf6c0d..bff8d4e1ed72 100644 --- a/ext/intl/dateformat/dateformat.h +++ b/ext/intl/dateformat/dateformat.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_attr.cpp b/ext/intl/dateformat/dateformat_attr.cpp index 1ec55a806a7c..170a85889d53 100644 --- a/ext/intl/dateformat/dateformat_attr.cpp +++ b/ext/intl/dateformat/dateformat_attr.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp index 13dadc9c9697..1c8fb88a3d51 100644 --- a/ext/intl/dateformat/dateformat_attrcpp.cpp +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -94,7 +94,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_timezone) DATE_FORMAT_METHOD_FETCH_OBJECT; TimeZone *timezone = timezone_process_timezone_argument( - timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 2); if (timezone == nullptr) { RETURN_FALSE; } @@ -119,7 +119,7 @@ U_CFUNC PHP_METHOD(IntlDateFormatter, setTimeZone) DATE_FORMAT_METHOD_FETCH_OBJECT; TimeZone *timezone = timezone_process_timezone_argument( - timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 1); if (timezone == nullptr) { RETURN_FALSE; } diff --git a/ext/intl/dateformat/dateformat_class.cpp b/ext/intl/dateformat/dateformat_class.cpp index b6ccf9799007..e9869612b873 100644 --- a/ext/intl/dateformat/dateformat_class.cpp +++ b/ext/intl/dateformat/dateformat_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -66,7 +66,7 @@ zend_object *IntlDateFormatter_object_create(zend_class_entry *ce) /* {{{ IntlDateFormatter_object_clone */ zend_object *IntlDateFormatter_object_clone(zend_object *object) { - IntlDateFormatter_object *dfo = php_intl_dateformatter_fetch_object(object); + const IntlDateFormatter_object *dfo = php_intl_dateformatter_fetch_object(object); zend_object *new_obj = IntlDateFormatter_ce_ptr->create_object(object->ce); IntlDateFormatter_object *new_dfo = php_intl_dateformatter_fetch_object(new_obj); @@ -104,7 +104,7 @@ void dateformat_register_IntlDateFormatter_class( void ) memcpy(&IntlDateFormatter_handlers, &std_object_handlers, sizeof IntlDateFormatter_handlers); - IntlDateFormatter_handlers.offset = XtOffsetOf(IntlDateFormatter_object, zo); + IntlDateFormatter_handlers.offset = offsetof(IntlDateFormatter_object, zo); IntlDateFormatter_handlers.clone_obj = IntlDateFormatter_object_clone; IntlDateFormatter_handlers.free_obj = IntlDateFormatter_object_free; } diff --git a/ext/intl/dateformat/dateformat_class.h b/ext/intl/dateformat/dateformat_class.h index e722c40b4bd9..bef8f6dd6146 100644 --- a/ext/intl/dateformat/dateformat_class.h +++ b/ext/intl/dateformat/dateformat_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -36,9 +36,7 @@ typedef struct { zend_object zo; } IntlDateFormatter_object; -static inline IntlDateFormatter_object *php_intl_dateformatter_fetch_object(zend_object *obj) { - return (IntlDateFormatter_object *)((char*)(obj) - XtOffsetOf(IntlDateFormatter_object, zo)); -} +#define php_intl_dateformatter_fetch_object(obj) ZEND_CONTAINER_OF(obj, IntlDateFormatter_object, zo) #define Z_INTL_DATEFORMATTER_P(zv) php_intl_dateformatter_fetch_object(Z_OBJ_P(zv)) #ifdef __cplusplus diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index 251f6f3fbc9b..df98c7178fc6 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | | Gustavo Lopes | @@ -99,7 +99,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } if (date_type == UDAT_PATTERN && time_type != UDAT_PATTERN) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "time format must be UDAT_PATTERN if date format is UDAT_PATTERN"); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: time format must be IntlDateFormatter::PATTERN if date format is IntlDateFormatter::PATTERN"); return FAILURE; } @@ -131,7 +131,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) if (explicit_tz || calendar_owned ) { //we have an explicit time zone or a non-object calendar - timezone = timezone_process_timezone_argument(timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo)); + timezone = timezone_process_timezone_argument(timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 4); if (timezone == nullptr) { goto error; } diff --git a/ext/intl/dateformat/dateformat_create.h b/ext/intl/dateformat/dateformat_create.h index a15828e7794c..440f91d261d9 100644 --- a/ext/intl/dateformat/dateformat_create.h +++ b/ext/intl/dateformat/dateformat_create.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_data.cpp b/ext/intl/dateformat/dateformat_data.cpp index 42e7c9522055..6246257732c1 100644 --- a/ext/intl/dateformat/dateformat_data.cpp +++ b/ext/intl/dateformat/dateformat_data.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_data.h b/ext/intl/dateformat/dateformat_data.h index 962ffbade31d..a8dcef4c500b 100644 --- a/ext/intl/dateformat/dateformat_data.h +++ b/ext/intl/dateformat/dateformat_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_format.cpp b/ext/intl/dateformat/dateformat_format.cpp index 30570a5887c1..8890332dd406 100644 --- a/ext/intl/dateformat/dateformat_format.cpp +++ b/ext/intl/dateformat/dateformat_format.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -73,8 +73,8 @@ static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo, intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); } else { - if (Z_LVAL_P(ele_value) > INT32_MAX || - Z_LVAL_P(ele_value) < INT32_MIN) { + if (UNEXPECTED(Z_LVAL_P(ele_value) > INT32_MAX || + Z_LVAL_P(ele_value) < INT32_MIN)) { spprintf(&message, 0, "value " ZEND_LONG_FMT " is out of " "bounds for a 32-bit integer in key '%s'", Z_LVAL_P(ele_value), key_name); diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp index a5113ce4cf9e..52199a305f0f 100644 --- a/ext/intl/dateformat/dateformat_format_object.cpp +++ b/ext/intl/dateformat/dateformat_format_object.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -50,9 +50,9 @@ static constexpr DateFormat::EStyle valid_styles[] = { DateFormat::kShortRelative, }; -static bool valid_format(zval *z) { +static bool valid_format(const zval *z) { if (Z_TYPE_P(z) == IS_LONG) { - zend_long lval = Z_LVAL_P(z); + const zend_long lval = Z_LVAL_P(z); for (int i = 0; i < sizeof(valid_styles) / sizeof(*valid_styles); i++) { if ((zend_long)valid_styles[i] == lval) { return true; @@ -149,7 +149,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) timeStyle = (DateFormat::EStyle)(timeStyle & ~DateFormat::kRelative); } - zend_class_entry *instance_ce = object->ce; + const zend_class_entry *instance_ce = object->ce; if (instanceof_function(instance_ce, Calendar_ce_ptr)) { Calendar *obj_cal = calendar_fetch_native_calendar(object); if (obj_cal == NULL) { diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp index 18dc594deddd..747105bb4f90 100644 --- a/ext/intl/dateformat/dateformat_helpers.cpp +++ b/ext/intl/dateformat/dateformat_helpers.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h index b931d9667e5f..f71e7f368706 100644 --- a/ext/intl/dateformat/dateformat_helpers.h +++ b/ext/intl/dateformat/dateformat_helpers.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_parse.cpp b/ext/intl/dateformat/dateformat_parse.cpp index a82a20a42f96..0537b42feec5 100644 --- a/ext/intl/dateformat/dateformat_parse.cpp +++ b/ext/intl/dateformat/dateformat_parse.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -33,7 +33,7 @@ extern "C" { * if set to 1 - store any error encountered in the parameter parse_error * if set to 0 - no need to store any error encountered in the parameter parse_error */ -static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, bool update_calendar, zval *return_value) +static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, const char* text_to_parse, size_t text_len, int32_t *parse_pos, bool update_calendar, zval *return_value) { double result = 0; UDate timestamp =0; @@ -70,9 +70,9 @@ static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* tex } /* }}} */ -static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, zend_long calendar_field, char* key_name) +static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, zend_long calendar_field, const char* key_name) { - zend_long calendar_field_val = ucal_get( parsed_calendar, static_cast(calendar_field), &INTL_DATA_ERROR_CODE(dfo)); + const zend_long calendar_field_val = ucal_get( parsed_calendar, static_cast(calendar_field), &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" ); if( strcmp(key_name, CALENDAR_YEAR )==0 ){ @@ -87,7 +87,7 @@ static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_va } /* {{{ Internal function which calls the udat_parseCalendar */ -static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value) +static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, const char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value) { UCalendar *parsed_calendar = NULL; UChar* text_utf16 = NULL; @@ -108,7 +108,7 @@ static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* tex INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); - array_init( return_value ); + array_init_size( return_value, 9 ); /* Add entries from various fields of the obtained parsed_calendar */ add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC); add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN); @@ -147,9 +147,12 @@ U_CFUNC PHP_FUNCTION(datefmt_parse) DATE_FORMAT_METHOD_FETCH_OBJECT; if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + bool failed; + const zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + if (failed) { + zend_argument_type_error(hasThis() ? 2 : 3, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); + RETURN_THROWS(); + } if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "String index is out of valid range."); @@ -188,7 +191,7 @@ U_CFUNC PHP_METHOD(IntlDateFormatter, parseToCalendar) if (z_parse_pos) { bool failed; - zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + const zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); if (failed) { zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); RETURN_THROWS(); @@ -229,9 +232,12 @@ U_CFUNC PHP_FUNCTION(datefmt_localtime) DATE_FORMAT_METHOD_FETCH_OBJECT; if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + bool failed; + const zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + if (failed) { + zend_argument_type_error(hasThis() ? 2 : 3, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); + RETURN_THROWS(); + } if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "String index is out of valid range."); diff --git a/ext/intl/dateformat/datepatterngenerator_class.cpp b/ext/intl/dateformat/datepatterngenerator_class.cpp index 38faff751fb7..4a137d916f12 100644 --- a/ext/intl/dateformat/datepatterngenerator_class.cpp +++ b/ext/intl/dateformat/datepatterngenerator_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ @@ -36,7 +36,7 @@ zend_object_handlers IntlDatePatternGenerator_handlers; static zend_object *IntlDatePatternGenerator_object_clone(zend_object *object) { - IntlDatePatternGenerator_object *dtpgo_orig = php_intl_datepatterngenerator_fetch_object(object); + const IntlDatePatternGenerator_object *dtpgo_orig = php_intl_datepatterngenerator_fetch_object(object); zend_object *ret_val = IntlDatePatternGenerator_ce_ptr->create_object(object->ce); IntlDatePatternGenerator_object *dtpgo_new = php_intl_datepatterngenerator_fetch_object(ret_val); @@ -106,7 +106,7 @@ void dateformat_register_IntlDatePatternGenerator_class( void ) memcpy(&IntlDatePatternGenerator_handlers, &std_object_handlers, sizeof IntlDatePatternGenerator_handlers); - IntlDatePatternGenerator_handlers.offset = XtOffsetOf(IntlDatePatternGenerator_object, zo); + IntlDatePatternGenerator_handlers.offset = offsetof(IntlDatePatternGenerator_object, zo); IntlDatePatternGenerator_handlers.clone_obj = IntlDatePatternGenerator_object_clone; IntlDatePatternGenerator_handlers.free_obj = IntlDatePatternGenerator_object_free; } diff --git a/ext/intl/dateformat/datepatterngenerator_class.h b/ext/intl/dateformat/datepatterngenerator_class.h index eb8f7c433d0e..c2c280e2df2c 100644 --- a/ext/intl/dateformat/datepatterngenerator_class.h +++ b/ext/intl/dateformat/datepatterngenerator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ @@ -36,9 +36,7 @@ typedef struct { zend_object zo; } IntlDatePatternGenerator_object; -static inline IntlDatePatternGenerator_object *php_intl_datepatterngenerator_fetch_object(zend_object *obj) { - return (IntlDatePatternGenerator_object *)((char*)(obj) - XtOffsetOf(IntlDatePatternGenerator_object, zo)); -} +#define php_intl_datepatterngenerator_fetch_object(obj) ZEND_CONTAINER_OF(obj, IntlDatePatternGenerator_object, zo) #define Z_INTL_DATEPATTERNGENERATOR_P(zv) php_intl_datepatterngenerator_fetch_object(Z_OBJ_P(zv)) #define DTPATTERNGEN_ERROR(dtpgo) (dtpgo)->err diff --git a/ext/intl/dateformat/datepatterngenerator_methods.cpp b/ext/intl/dateformat/datepatterngenerator_methods.cpp index beaf10d9f507..f22be1c21fc1 100644 --- a/ext/intl/dateformat/datepatterngenerator_methods.cpp +++ b/ext/intl/dateformat/datepatterngenerator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ diff --git a/ext/intl/formatter/formatter_attr.cpp b/ext/intl/formatter/formatter_attr.cpp index 905a4415ef59..ff215fdffbd7 100644 --- a/ext/intl/formatter/formatter_attr.cpp +++ b/ext/intl/formatter/formatter_attr.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -16,13 +16,16 @@ #include #endif +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" + extern "C" { #include "php_intl.h" #include "intl_convert.h" } -#include "formatter_class.h" -#include +#define FORMATTER_UNUM(nfo) reinterpret_cast(FORMATTER_OBJECT(nfo)) /* {{{ Get formatter attribute value. */ U_CFUNC PHP_FUNCTION( numfmt_get_attribute ) @@ -62,7 +65,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_attribute ) case UNUM_MIN_SIGNIFICANT_DIGITS: case UNUM_MAX_SIGNIFICANT_DIGITS: case UNUM_LENIENT_PARSE: - value = unum_getAttribute(FORMATTER_OBJECT(nfo), attribute); + value = unum_getAttribute(FORMATTER_UNUM(nfo), attribute); if(value == -1) { INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; } else { @@ -71,7 +74,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_attribute ) break; case UNUM_ROUNDING_INCREMENT: { - double value_double = unum_getDoubleAttribute(FORMATTER_OBJECT(nfo), attribute); + const double value_double = unum_getDoubleAttribute(FORMATTER_UNUM(nfo), attribute); if(value_double == -1) { INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; } else { @@ -110,12 +113,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_text_attribute ) UNumberFormatTextAttribute attribute = static_cast(lattribute); - length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) ); + length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) ); if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= value_buf_size) { ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; value = eumalloc(length); - length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) ); + length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) ); if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { efree(value); value = value_buf; @@ -166,10 +169,10 @@ U_CFUNC PHP_FUNCTION( numfmt_set_attribute ) case UNUM_MIN_SIGNIFICANT_DIGITS: case UNUM_MAX_SIGNIFICANT_DIGITS: case UNUM_LENIENT_PARSE: - unum_setAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_long(value)); + unum_setAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_long(value)); break; case UNUM_ROUNDING_INCREMENT: - unum_setDoubleAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_double(value)); + unum_setDoubleAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_double(value)); break; default: INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; @@ -185,8 +188,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_attribute ) /* {{{ Get formatter attribute value. */ U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute ) { - int32_t slength = 0; - UChar *svalue = NULL; zend_long attribute; char *value; size_t len; @@ -203,14 +204,12 @@ U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute ) FORMATTER_METHOD_FETCH_OBJECT; /* Convert given attribute value to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, len, &INTL_DATA_ERROR_CODE(nfo)); + UnicodeString svalue; + intl_stringFromChar(svalue, value, len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error converting attribute value to UTF-16" ); /* Actually set new attribute value. */ - unum_setTextAttribute(FORMATTER_OBJECT(nfo), static_cast(attribute), svalue, slength, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } + unum_setTextAttribute(FORMATTER_UNUM(nfo), static_cast(attribute), svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" ); RETURN_TRUE; @@ -235,7 +234,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_symbol ) UNumberFormatSymbol symbol = static_cast(lsymbol); - if(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { + if (UNEXPECTED(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0)) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); RETURN_FALSE; } @@ -243,12 +242,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_symbol ) /* Fetch the object. */ FORMATTER_METHOD_FETCH_OBJECT; - length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo)); + length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo)); if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; value = eumalloc(length); - length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo)); + length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo)); if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { efree(value); value = value_buf; @@ -266,8 +265,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol ) zend_long lsymbol; char* value = NULL; size_t value_len = 0; - UChar* svalue = 0; - int32_t slength = 0; FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ @@ -279,7 +276,7 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol ) UNumberFormatSymbol symbol = static_cast(lsymbol); - if (symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { + if (UNEXPECTED(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0)) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); RETURN_FALSE; } @@ -288,14 +285,12 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol ) FORMATTER_METHOD_FETCH_OBJECT; /* Convert given symbol to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); + UnicodeString svalue; + intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error converting symbol value to UTF-16" ); /* Actually set the symbol. */ - unum_setSymbol(FORMATTER_OBJECT(nfo), symbol, svalue, slength, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } + unum_setSymbol(FORMATTER_UNUM(nfo), symbol, svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" ); RETURN_TRUE; @@ -320,12 +315,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_pattern ) /* Fetch the object. */ FORMATTER_METHOD_FETCH_OBJECT; - length = unum_toPattern(FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo)); + length = unum_toPattern(FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo)); if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; value = eumalloc(length); - length = unum_toPattern( FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) ); + length = unum_toPattern( FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) ); if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { efree(value); value = value_buf; @@ -342,8 +337,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_pattern ) { char* value = NULL; size_t value_len = 0; - int32_t slength = 0; - UChar* svalue = NULL; UParseError spattern_error = {0}; FORMATTER_METHOD_INIT_VARS; @@ -357,13 +350,11 @@ U_CFUNC PHP_FUNCTION( numfmt_set_pattern ) FORMATTER_METHOD_FETCH_OBJECT; /* Convert given pattern to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); + UnicodeString svalue; + intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error converting pattern to UTF-16" ); - unum_applyPattern(FORMATTER_OBJECT(nfo), 0, svalue, slength, &spattern_error, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } + unum_applyPattern(FORMATTER_UNUM(nfo), 0, svalue.getBuffer(), svalue.length(), &spattern_error, &INTL_DATA_ERROR_CODE(nfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { char *msg; spprintf(&msg, 0, "Error setting pattern value at line %d, offset %d", spattern_error.line, spattern_error.offset); @@ -393,7 +384,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_locale ) /* Fetch the object. */ FORMATTER_METHOD_FETCH_OBJECT; - loc = unum_getLocaleByType(FORMATTER_OBJECT(nfo), static_cast(type), &INTL_DATA_ERROR_CODE(nfo)); + loc = unum_getLocaleByType(FORMATTER_UNUM(nfo), static_cast(type), &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Error getting locale" ); RETURN_STRING(loc); } diff --git a/ext/intl/formatter/formatter_class.cpp b/ext/intl/formatter/formatter_class.cpp index 214e1e57dae8..5b82b53c6d62 100644 --- a/ext/intl/formatter/formatter_class.cpp +++ b/ext/intl/formatter/formatter_class.cpp @@ -1,19 +1,17 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ */ -#include - #include "formatter_class.h" extern "C" { #include "php_intl.h" @@ -64,7 +62,7 @@ U_CFUNC zend_object *NumberFormatter_object_create(zend_class_entry *ce) /* {{{ NumberFormatter_object_clone */ U_CFUNC zend_object *NumberFormatter_object_clone(zend_object *object) { - NumberFormatter_object *nfo = php_intl_number_format_fetch_object(object); + const NumberFormatter_object *nfo = php_intl_number_format_fetch_object(object); zend_object *new_obj = NumberFormatter_ce_ptr->create_object(object->ce); NumberFormatter_object *new_nfo = php_intl_number_format_fetch_object(new_obj); @@ -72,10 +70,9 @@ U_CFUNC zend_object *NumberFormatter_object_clone(zend_object *object) zend_objects_clone_members(&new_nfo->zo, &nfo->zo); /* clone formatter object. It may fail, the destruction code must handle this case */ - if (FORMATTER_OBJECT(nfo) != NULL) { - UErrorCode error = U_ZERO_ERROR; - FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo), &error); - if (U_FAILURE(error)) { + if (FORMATTER_OBJECT(nfo) != nullptr) { + FORMATTER_OBJECT(new_nfo) = FORMATTER_OBJECT(nfo)->clone(); + if (FORMATTER_OBJECT(new_nfo) == nullptr) { zend_throw_error(NULL, "Failed to clone NumberFormatter"); } } else { @@ -101,7 +98,7 @@ U_CFUNC void formatter_register_class( void ) memcpy(&NumberFormatter_handlers, &std_object_handlers, sizeof(NumberFormatter_handlers)); - NumberFormatter_handlers.offset = XtOffsetOf(NumberFormatter_object, zo); + NumberFormatter_handlers.offset = offsetof(NumberFormatter_object, zo); NumberFormatter_handlers.clone_obj = NumberFormatter_object_clone; NumberFormatter_handlers.free_obj = NumberFormatter_object_free; } diff --git a/ext/intl/formatter/formatter_class.h b/ext/intl/formatter/formatter_class.h index bf21825b5f5f..44bdfae8debe 100644 --- a/ext/intl/formatter/formatter_class.h +++ b/ext/intl/formatter/formatter_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -15,7 +15,7 @@ #ifndef FORMATTER_CLASS_H #define FORMATTER_CLASS_H -#include +#include "formatter_data.h" #ifdef __cplusplus extern "C" { @@ -23,7 +23,6 @@ extern "C" { #include "intl_common.h" #include "intl_error.h" #include "intl_data.h" -#include "formatter_data.h" #ifdef __cplusplus } #endif @@ -33,9 +32,7 @@ typedef struct { zend_object zo; } NumberFormatter_object; -static inline NumberFormatter_object *php_intl_number_format_fetch_object(zend_object *obj) { - return (NumberFormatter_object *)((char*)(obj) - XtOffsetOf(NumberFormatter_object, zo)); -} +#define php_intl_number_format_fetch_object(obj) ZEND_CONTAINER_OF(obj, NumberFormatter_object, zo) #define Z_INTL_NUMBERFORMATTER_P(zv) php_intl_number_format_fetch_object(Z_OBJ_P(zv)) #ifdef __cplusplus diff --git a/ext/intl/formatter/formatter_data.cpp b/ext/intl/formatter/formatter_data.cpp index 095be92ed29e..506972e72088 100644 --- a/ext/intl/formatter/formatter_data.cpp +++ b/ext/intl/formatter/formatter_data.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -26,23 +26,21 @@ void formatter_data_init( formatter_data* nf_data ) if( !nf_data ) return; - nf_data->unum = NULL; + nf_data->unum = nullptr; intl_error_reset( &nf_data->error ); } /* }}} */ /* {{{ void formatter_data_free( formatter_data* nf_data ) - * Clean up mem allocted by internals of formatter_data + * Clean up mem allocated by internals of formatter_data */ void formatter_data_free( formatter_data* nf_data ) { if( !nf_data ) return; - if( nf_data->unum ) - unum_close( nf_data->unum ); - - nf_data->unum = NULL; + delete nf_data->unum; + nf_data->unum = nullptr; intl_error_reset( &nf_data->error ); } /* }}} */ diff --git a/ext/intl/formatter/formatter_data.h b/ext/intl/formatter/formatter_data.h index 35acc242a8db..46a82cb9bd0f 100644 --- a/ext/intl/formatter/formatter_data.h +++ b/ext/intl/formatter/formatter_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -15,9 +15,20 @@ #ifndef FORMATTER_DATA_H #define FORMATTER_DATA_H +#ifdef __cplusplus +extern "C" { +#endif #include +#ifdef __cplusplus +} +#endif -#include +#ifdef __cplusplus +#include +using icu::NumberFormat; +#else +typedef void NumberFormat; +#endif #ifdef __cplusplus extern "C" { @@ -32,7 +43,7 @@ typedef struct { intl_error error; // formatter handling - UNumberFormat* unum; + NumberFormat* unum; } formatter_data; #ifdef __cplusplus diff --git a/ext/intl/formatter/formatter_format.cpp b/ext/intl/formatter/formatter_format.cpp index f28ea30b9ff8..48edabc8ccde 100644 --- a/ext/intl/formatter/formatter_format.cpp +++ b/ext/intl/formatter/formatter_format.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -16,24 +16,21 @@ #include #endif +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" +#include "formatter_format.h" + extern "C" { #include "php_intl.h" -#include "intl_convert.h" } -#include - -#include "formatter_class.h" -#include "formatter_format.h" - /* {{{ Format a number. */ U_CFUNC PHP_FUNCTION( numfmt_format ) { zval *number; zend_long type = FORMAT_TYPE_DEFAULT; - UChar format_buf[32]; - UChar* formatted = format_buf; - int32_t formatted_len = USIZE(format_buf); FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ @@ -55,54 +52,31 @@ U_CFUNC PHP_FUNCTION( numfmt_format ) case IS_DOUBLE: type = FORMAT_TYPE_DOUBLE; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } + icu::UnicodeString result; + icu::FieldPosition pos; + switch(type) { case FORMAT_TYPE_INT32: convert_to_long(number); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } + FORMATTER_OBJECT(nfo)->format((int32_t)Z_LVAL_P(number), result, pos, INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); break; case FORMAT_TYPE_INT64: { int64_t value = (Z_TYPE_P(number) == IS_DOUBLE)?(int64_t)Z_DVAL_P(number):Z_LVAL_P(number); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } + FORMATTER_OBJECT(nfo)->format(value, result, pos, INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); } break; case FORMAT_TYPE_DOUBLE: convert_to_double(number); - formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } + FORMATTER_OBJECT(nfo)->format(Z_DVAL_P(number), result, pos, INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); break; case FORMAT_TYPE_CURRENCY: @@ -120,7 +94,9 @@ U_CFUNC PHP_FUNCTION( numfmt_format ) RETURN_THROWS(); } - INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); + zend_string *u8str = intl_charFromString(result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error converting result to UTF-8"); + RETVAL_STR(u8str); } /* }}} */ @@ -128,13 +104,8 @@ U_CFUNC PHP_FUNCTION( numfmt_format ) U_CFUNC PHP_FUNCTION( numfmt_format_currency ) { double number; - UChar format_buf[32]; - UChar* formatted = format_buf; - int32_t formatted_len = USIZE(format_buf); char* currency = NULL; size_t currency_len = 0; - UChar* scurrency = NULL; - int32_t scurrency_len = 0; FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ @@ -148,36 +119,31 @@ U_CFUNC PHP_FUNCTION( numfmt_format_currency ) FORMATTER_METHOD_FETCH_OBJECT; /* Convert currency to UTF-16. */ - intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); + icu::UnicodeString ucurrency; + intl_stringFromChar(ucurrency, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" ); - /* Format the number using a fixed-length buffer. */ - formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - - /* If the buffer turned out to be too small - * then allocate another buffer dynamically - * and use it to format the number. - */ - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); + /* Format using CurrencyAmount. */ + icu::CurrencyAmount *currAmt = new icu::CurrencyAmount(number, ucurrency.getTerminatedBuffer(), INTL_DATA_ERROR_CODE(nfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + delete currAmt; + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), "Number formatting failed"); + RETURN_FALSE; } - - if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) { - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((nfo)) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed"); - RETVAL_FALSE; - if (formatted != format_buf) { - efree(formatted); - } - } else { - INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); + icu::Formattable fmt; + fmt.adoptObject(currAmt); + icu::UnicodeString result; + icu::FieldPosition pos; + FORMATTER_OBJECT(nfo)->format(fmt, result, pos, INTL_DATA_ERROR_CODE(nfo)); + + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), "Number formatting failed"); + RETURN_FALSE; } - if(scurrency) { - efree(scurrency); - } + zend_string *u8str = intl_charFromString(result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error converting result to UTF-8"); + RETVAL_STR(u8str); } /* }}} */ diff --git a/ext/intl/formatter/formatter_format.h b/ext/intl/formatter/formatter_format.h index 0238d5d4b8b0..14aa91193ba2 100644 --- a/ext/intl/formatter/formatter_format.h +++ b/ext/intl/formatter/formatter_format.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/formatter/formatter_main.cpp b/ext/intl/formatter/formatter_main.cpp index a014323089a7..79750714a5f0 100644 --- a/ext/intl/formatter/formatter_main.cpp +++ b/ext/intl/formatter/formatter_main.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -16,14 +16,17 @@ #include #endif -#include -#include +#include +#include +#include +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" extern "C" { #include "php_intl.h" -#include "intl_convert.h" } -#include "formatter_class.h" /* {{{ */ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) @@ -32,8 +35,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) char* pattern = NULL; size_t locale_len = 0, pattern_len = 0; zend_long style; - UChar* spattern = NULL; - int32_t spattern_len = 0; + UnicodeString upattern; FORMATTER_METHOD_INIT_VARS; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -53,7 +55,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) /* Convert pattern (if specified) to UTF-16. */ if(pattern && pattern_len) { - intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); + intl_stringFromChar(upattern, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_CTOR_CHECK_STATUS(nfo, "error converting pattern to UTF-16"); } @@ -61,7 +63,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) locale = (char *)intl_locale_get_default(); } - if (strlen(uloc_getISO3Language(locale)) == 0) { + if (icu::Locale(locale).getISO3Language()[0] == '\0') { zend_argument_value_error(1, "\"%s\" is invalid", locale); return FAILURE; } @@ -70,12 +72,55 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) const char* final_locale = canonicalized_locale ? canonicalized_locale : locale; /* Create an ICU number formatter. */ - FORMATTER_OBJECT(nfo) = unum_open(static_cast(style), spattern, spattern_len, final_locale, nullptr, &INTL_DATA_ERROR_CODE(nfo)); - - if (spattern) { - efree(spattern); + icu::Locale loc(final_locale); + switch (style) { + case UNUM_PATTERN_DECIMAL: { + icu::DecimalFormatSymbols *syms = new icu::DecimalFormatSymbols(loc, INTL_DATA_ERROR_CODE(nfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + delete syms; + break; + } + FORMATTER_OBJECT(nfo) = new icu::DecimalFormat(upattern, syms, INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo) == nullptr) { + delete syms; + } + break; + } + case UNUM_PATTERN_RULEBASED: { + UParseError parseError; + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(upattern, loc, parseError, INTL_DATA_ERROR_CODE(nfo)); + break; + } + case UNUM_SPELLOUT: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_ORDINAL: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_DURATION: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_DURATION, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_NUMBERING_SYSTEM: { + UErrorCode localErr = U_ZERO_ERROR; + int32_t keywordLength = loc.getKeywordValue("numbers", nullptr, 0, localErr); + if (keywordLength > 0) { + FORMATTER_OBJECT(nfo) = NumberFormat::createInstance(loc, UNUM_DEFAULT, INTL_DATA_ERROR_CODE(nfo)); + } else { + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_NUMBERING_SYSTEM, loc, INTL_DATA_ERROR_CODE(nfo)); + } + break; + } + case UNUM_DECIMAL_COMPACT_SHORT: + FORMATTER_OBJECT(nfo) = icu::CompactDecimalFormat::createInstance(loc, UNUM_SHORT, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_DECIMAL_COMPACT_LONG: + FORMATTER_OBJECT(nfo) = icu::CompactDecimalFormat::createInstance(loc, UNUM_LONG, INTL_DATA_ERROR_CODE(nfo)); + break; + default: + FORMATTER_OBJECT(nfo) = NumberFormat::createInstance(loc, static_cast(style), INTL_DATA_ERROR_CODE(nfo)); + break; } - + if (canonicalized_locale) { efree(canonicalized_locale); } diff --git a/ext/intl/formatter/formatter_parse.cpp b/ext/intl/formatter/formatter_parse.cpp index c7d0df8cbda0..40107229e0ae 100644 --- a/ext/intl/formatter/formatter_parse.cpp +++ b/ext/intl/formatter/formatter_parse.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -16,16 +16,18 @@ #include #endif +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" +#include "formatter_format.h" + extern "C" { #include "php_intl.h" -#include "intl_convert.h" } -#include #include - -#include "formatter_class.h" -#include "formatter_format.h" +#include #define ICU_LOCALE_BUG 1 @@ -33,14 +35,9 @@ extern "C" { U_CFUNC PHP_FUNCTION( numfmt_parse ) { zend_long type = FORMAT_TYPE_DOUBLE; - UChar* sstr = NULL; - int32_t sstr_len = 0; char* str = NULL; size_t str_len; - int32_t val32, position = 0; - int64_t val64; - double val_double; - int32_t* position_p = NULL; + int32_t position = 0; zval *zposition = NULL; char *oldlocale; FORMATTER_METHOD_INIT_VARS; @@ -53,15 +50,20 @@ U_CFUNC PHP_FUNCTION( numfmt_parse ) } if (zposition) { - position = (int32_t) zval_get_long(zposition); - position_p = &position; + zend_long long_position = zval_get_long(zposition); + if (UNEXPECTED(long_position < INT32_MIN || long_position > INT32_MAX)) { + zend_argument_value_error(hasThis() ? 3 : 4, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); + } + position = (int32_t) long_position; } /* Fetch the object. */ FORMATTER_METHOD_FETCH_OBJECT; /* Convert given string to UTF-16. */ - intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); + icu::UnicodeString ustr; + intl_stringFromChar(ustr, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); #if ICU_LOCALE_BUG && defined(LC_NUMERIC) @@ -72,21 +74,38 @@ U_CFUNC PHP_FUNCTION( numfmt_parse ) switch(type) { case FORMAT_TYPE_INT32: - val32 = unum_parse(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - RETVAL_LONG(val32); - break; case FORMAT_TYPE_INT64: - val64 = unum_parseInt64(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - if(val64 > ZEND_LONG_MAX || val64 < ZEND_LONG_MIN) { - RETVAL_DOUBLE(val64); + case FORMAT_TYPE_DOUBLE: + { + icu::Formattable result; + icu::ParsePosition pp(position); + FORMATTER_OBJECT(nfo)->parse(ustr, result, pp); + + if (pp.getErrorIndex() >= 0) { + INTL_DATA_ERROR_CODE(nfo) = U_PARSE_ERROR; } else { - RETVAL_LONG((zend_long)val64); + position = pp.getIndex(); + switch(type) { + case FORMAT_TYPE_INT32: + RETVAL_LONG(result.getLong(INTL_DATA_ERROR_CODE(nfo))); + break; + case FORMAT_TYPE_INT64: + { + int64_t val64 = result.getInt64(INTL_DATA_ERROR_CODE(nfo)); + if(val64 > ZEND_LONG_MAX || val64 < ZEND_LONG_MIN) { + RETVAL_DOUBLE(val64); + } else { + RETVAL_LONG((zend_long)val64); + } + break; + } + case FORMAT_TYPE_DOUBLE: + RETVAL_DOUBLE(result.getDouble(INTL_DATA_ERROR_CODE(nfo))); + break; + } } break; - case FORMAT_TYPE_DOUBLE: - val_double = unum_parseDouble(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - RETVAL_DOUBLE(val_double); - break; + } case FORMAT_TYPE_CURRENCY: if (hasThis()) { const char *space; @@ -113,10 +132,6 @@ U_CFUNC PHP_FUNCTION( numfmt_parse ) efree(oldlocale); #endif - if (sstr) { - efree(sstr); - } - INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); } /* }}} */ @@ -124,14 +139,8 @@ U_CFUNC PHP_FUNCTION( numfmt_parse ) /* {{{ Parse a number as currency. */ U_CFUNC PHP_FUNCTION( numfmt_parse_currency ) { - double number; - UChar currency[5] = {0}; - UChar* sstr = NULL; - int32_t sstr_len = 0; - zend_string *u8str; char *str; size_t str_len; - int32_t* position_p = NULL; int32_t position = 0; zval *zcurrency, *zposition = NULL; FORMATTER_METHOD_INIT_VARS; @@ -147,27 +156,39 @@ U_CFUNC PHP_FUNCTION( numfmt_parse_currency ) FORMATTER_METHOD_FETCH_OBJECT; /* Convert given string to UTF-16. */ - intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); + icu::UnicodeString ustr; + intl_stringFromChar(ustr, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); - if(zposition) { - position = (int32_t) zval_get_long(zposition); - position_p = &position; + if (zposition) { + zend_long long_position = zval_get_long(zposition); + if (UNEXPECTED(long_position < INT32_MIN || long_position > INT32_MAX)) { + zend_argument_value_error(hasThis() ? 3 : 4, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); + } + position = (int32_t) long_position; } - number = unum_parseDoubleCurrency(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, currency, &INTL_DATA_ERROR_CODE(nfo)); - if(zposition) { - ZEND_TRY_ASSIGN_REF_LONG(zposition, position); + icu::ParsePosition pp(position); + std::unique_ptr currAmt(FORMATTER_OBJECT(nfo)->parseCurrency(ustr, pp)); + + if (currAmt == nullptr || pp.getErrorIndex() >= 0) { + INTL_DATA_ERROR_CODE(nfo) = U_PARSE_ERROR; + INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); } - if (sstr) { - efree(sstr); + + if(zposition) { + ZEND_TRY_ASSIGN_REF_LONG(zposition, pp.getIndex()); } - INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); + + const double number = currAmt->getNumber().getDouble(INTL_DATA_ERROR_CODE(nfo)); /* Convert parsed currency to UTF-8 and pass it back to caller. */ - u8str = intl_convert_utf16_to_utf8(currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo)); + icu::UnicodeString ucurrency(currAmt->getISOCurrency()); + + zend_string *u8str = intl_charFromString(ucurrency, &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" ); - ZEND_TRY_ASSIGN_REF_NEW_STR(zcurrency, u8str); + ZEND_TRY_ASSIGN_REF_STR(zcurrency, u8str); RETVAL_DOUBLE( number ); } diff --git a/ext/intl/grapheme/grapheme.h b/ext/intl/grapheme/grapheme.h index 8ec470d47927..b52f48f9d142 100644 --- a/ext/intl/grapheme/grapheme.h +++ b/ext/intl/grapheme/grapheme.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ diff --git a/ext/intl/grapheme/grapheme_string.cpp b/ext/intl/grapheme/grapheme_string.cpp index 36c0cc0f732c..5e614be6ae72 100644 --- a/ext/intl/grapheme/grapheme_string.cpp +++ b/ext/intl/grapheme/grapheme_string.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ed Batutis | +----------------------------------------------------------------------+ @@ -104,7 +104,7 @@ U_CFUNC PHP_FUNCTION(grapheme_strpos) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if ( OUTSIDE_STRING(loffset, haystack_len) ) { + if (UNEXPECTED(OUTSIDE_STRING(loffset, haystack_len))) { zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); RETURN_THROWS(); } @@ -158,7 +158,7 @@ U_CFUNC PHP_FUNCTION(grapheme_stripos) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if ( OUTSIDE_STRING(loffset, haystack_len) ) { + if (UNEXPECTED(OUTSIDE_STRING(loffset, haystack_len))) { zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); RETURN_THROWS(); } @@ -224,7 +224,7 @@ U_CFUNC PHP_FUNCTION(grapheme_strrpos) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if ( OUTSIDE_STRING(loffset, haystack_len) ) { + if (UNEXPECTED(OUTSIDE_STRING(loffset, haystack_len))) { zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); RETURN_THROWS(); } @@ -283,7 +283,7 @@ U_CFUNC PHP_FUNCTION(grapheme_strripos) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if ( OUTSIDE_STRING(loffset, haystack_len) ) { + if (UNEXPECTED(OUTSIDE_STRING(loffset, haystack_len))) { zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); RETURN_THROWS(); } @@ -345,7 +345,6 @@ U_CFUNC PHP_FUNCTION(grapheme_substr) int32_t start = 0; int iter_val; UErrorCode status; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = nullptr; int sub_str_start_pos, sub_str_end_pos; int32_t (*iter_func)(UBreakIterator *); @@ -359,7 +358,7 @@ U_CFUNC PHP_FUNCTION(grapheme_substr) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if (lstart < INT32_MIN || lstart > INT32_MAX) { + if (UNEXPECTED(lstart < INT32_MIN || lstart > INT32_MAX)) { zend_argument_value_error(2, "is too large"); RETURN_THROWS(); } @@ -370,7 +369,7 @@ U_CFUNC PHP_FUNCTION(grapheme_substr) length = str_len; } - if (length < INT32_MIN || length > INT32_MAX) { + if (UNEXPECTED(length < INT32_MIN || length > INT32_MAX)) { zend_argument_value_error(3, "is too large"); RETURN_THROWS(); } @@ -407,7 +406,7 @@ U_CFUNC PHP_FUNCTION(grapheme_substr) RETURN_FALSE; } - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); + bi = grapheme_get_break_iterator(&status); if( U_FAILURE(status) ) { RETURN_FALSE; @@ -729,7 +728,6 @@ U_CFUNC PHP_FUNCTION(grapheme_extract) int32_t start = 0; zend_long extract_type = GRAPHEME_EXTRACT_TYPE_COUNT; UErrorCode status; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = nullptr; int ret_pos; zval *next = nullptr; /* return offset of next part of the string */ @@ -760,17 +758,17 @@ U_CFUNC PHP_FUNCTION(grapheme_extract) RETURN_THROWS(); } - if ( lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len ) { + if (UNEXPECTED(lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len)) { intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "start not contained in string"); RETURN_FALSE; } - if (size < 0) { + if (UNEXPECTED(size < 0)) { zend_argument_value_error(2, "must be greater than or equal to 0"); RETURN_THROWS(); } - if (size > INT32_MAX) { + if (UNEXPECTED(size > INT32_MAX)) { zend_argument_value_error(2, "is too large"); RETURN_THROWS(); } @@ -829,7 +827,7 @@ U_CFUNC PHP_FUNCTION(grapheme_extract) bi = nullptr; status = U_ZERO_ERROR; - bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); + bi = grapheme_get_break_iterator(&status); ubrk_setUText(bi, &ut, &status); /* if the caller put us in the middle of a grapheme, we can't detect it in all cases since we @@ -855,7 +853,6 @@ U_CFUNC PHP_FUNCTION(grapheme_str_split) zend_string *str; zend_long split_len = 1; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UErrorCode ustatus = U_ZERO_ERROR; int32_t pos, current, i, end_len = 0; UBreakIterator* bi; @@ -867,7 +864,7 @@ U_CFUNC PHP_FUNCTION(grapheme_str_split) Z_PARAM_LONG(split_len) ZEND_PARSE_PARAMETERS_END(); - if (split_len <= 0 || split_len > UINT_MAX / 4) { + if (UNEXPECTED(split_len <= 0 || split_len > UINT_MAX / 4)) { zend_argument_value_error(2, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); RETURN_THROWS(); } @@ -891,7 +888,7 @@ U_CFUNC PHP_FUNCTION(grapheme_str_split) bi = nullptr; ustatus = U_ZERO_ERROR; - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); + bi = grapheme_get_break_iterator(&ustatus); if( U_FAILURE(ustatus) ) { RETURN_FALSE; @@ -946,17 +943,17 @@ U_CFUNC PHP_FUNCTION(grapheme_levenshtein) Z_PARAM_PATH(locale, locale_len) ZEND_PARSE_PARAMETERS_END(); - if (cost_ins <= 0 || cost_ins > UINT_MAX / 4) { + if (UNEXPECTED(cost_ins <= 0 || cost_ins > UINT_MAX / 4)) { zend_argument_value_error(3, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); RETURN_THROWS(); } - if (cost_rep <= 0 || cost_rep > UINT_MAX / 4) { + if (UNEXPECTED(cost_rep <= 0 || cost_rep > UINT_MAX / 4)) { zend_argument_value_error(4, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); RETURN_THROWS(); } - if (cost_del <= 0 || cost_del > UINT_MAX / 4) { + if (UNEXPECTED(cost_del <= 0 || cost_del > UINT_MAX / 4)) { zend_argument_value_error(5, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); RETURN_THROWS(); } @@ -1031,9 +1028,7 @@ U_CFUNC PHP_FUNCTION(grapheme_levenshtein) goto out_ustring2; } - unsigned char u_break_iterator_buffer1[U_BRK_SAFECLONE_BUFFERSIZE]; - unsigned char u_break_iterator_buffer2[U_BRK_SAFECLONE_BUFFERSIZE]; - bi1 = grapheme_get_break_iterator(u_break_iterator_buffer1, &ustatus); + bi1 = grapheme_get_break_iterator(&ustatus); if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #1 ($string1)"); @@ -1041,7 +1036,7 @@ U_CFUNC PHP_FUNCTION(grapheme_levenshtein) goto out_bi1; } - bi2 = grapheme_get_break_iterator(u_break_iterator_buffer2, &ustatus); + bi2 = grapheme_get_break_iterator(&ustatus); if (U_FAILURE(ustatus)) { intl_error_set_code(NULL, ustatus); intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #2 ($string2)"); @@ -1144,7 +1139,6 @@ U_CFUNC PHP_FUNCTION(grapheme_strrev) char *pstr, *end, *p; zend_string *ret; int32_t pos = 0, current = 0, end_len = 0; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(string) @@ -1168,7 +1162,7 @@ U_CFUNC PHP_FUNCTION(grapheme_strrev) bi = nullptr; ustatus = U_ZERO_ERROR; - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); + bi = grapheme_get_break_iterator(&ustatus); ret = zend_string_alloc(ZSTR_LEN(string), 0); p = ZSTR_VAL(ret); diff --git a/ext/intl/grapheme/grapheme_util.cpp b/ext/intl/grapheme/grapheme_util.cpp index a04f3db0b8a6..031f1c717891 100644 --- a/ext/intl/grapheme/grapheme_util.cpp +++ b/ext/intl/grapheme/grapheme_util.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ed Batutis | +----------------------------------------------------------------------+ @@ -35,6 +35,8 @@ extern "C" { #include #include +#include "../intl_icu_compat.h" + ZEND_EXTERN_MODULE_GLOBALS( intl ) /* }}} */ @@ -57,7 +59,7 @@ U_CFUNC void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t int32_t str_len2 = (int32_t)str_len; /* in order to avoid signed/unsigned problems */ *sub_str = NULL; - if(str_len > INT32_MAX) { + if (UNEXPECTED(str_len > INT32_MAX)) { /* We cannot return long strings from ICU functions, so we won't here too */ return; } @@ -105,7 +107,6 @@ U_CFUNC int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char { UChar *uhaystack = NULL, *uneedle = NULL; int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = NULL; UErrorCode status; UStringSearch* src = NULL; @@ -125,7 +126,7 @@ U_CFUNC int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char /* get a pointer to the haystack taking into account the offset */ status = U_ZERO_ERROR; - bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); + bi = grapheme_get_break_iterator(&status); STRPOS_CHECK_STATUS(status, "Failed to get iterator"); status = U_ZERO_ERROR; ubrk_setText(bi, uhaystack, uhaystack_len, &status); @@ -235,12 +236,11 @@ U_CFUNC zend_long grapheme_ascii_check(const unsigned char *day, size_t len) /* {{{ grapheme_split_string: find and optionally return grapheme boundaries */ U_CFUNC int32_t grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len ) { - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UErrorCode status = U_ZERO_ERROR; int ret_len, pos; UBreakIterator* bi; - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); + bi = grapheme_get_break_iterator(&status); if( U_FAILURE(status) ) { return -1; @@ -375,7 +375,7 @@ U_CFUNC zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, ch /* }}} */ /* {{{ grapheme_get_break_iterator: get a clone of the global character break iterator */ -U_CFUNC UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ) +U_CFUNC UBreakIterator* grapheme_get_break_iterator(UErrorCode *status ) { UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator ); @@ -390,12 +390,6 @@ U_CFUNC UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCo INTL_G(grapheme_iterator) = global_break_iterator; } -#if U_ICU_VERSION_MAJOR_NUM >= 69 - return ubrk_clone(global_break_iterator, status); -#else - int32_t buffer_size = U_BRK_SAFECLONE_BUFFERSIZE; - - return ubrk_safeClone(global_break_iterator, stack_buffer, &buffer_size, status); -#endif + return intl_icu_compat_ubrk_clone(global_break_iterator, status); } /* }}} */ diff --git a/ext/intl/grapheme/grapheme_util.h b/ext/intl/grapheme/grapheme_util.h index 57d2ace384f8..0ddfcd3da88f 100644 --- a/ext/intl/grapheme/grapheme_util.h +++ b/ext/intl/grapheme/grapheme_util.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ @@ -22,7 +22,7 @@ extern "C" { #include "intl_convert.h" /* get_break_interator: get a break iterator from the global structure */ -UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ); +UBreakIterator* grapheme_get_break_iterator(UErrorCode *status ); zend_long grapheme_ascii_check(const unsigned char *day, size_t len); void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char **sub_str, int32_t *sub_str_len); @@ -37,7 +37,7 @@ int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t stri int32_t grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset); -UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ); +UBreakIterator* grapheme_get_break_iterator(UErrorCode *status ); #ifdef __cplusplus } #endif diff --git a/ext/intl/idn/idn.cpp b/ext/intl/idn/idn.cpp index 6c7e4d8c6d68..76cca2281296 100644 --- a/ext/intl/idn/idn.cpp +++ b/ext/intl/idn/idn.cpp @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre A. Joye | | Gustavo Lopes | @@ -42,7 +40,7 @@ enum { static zend_result php_intl_idn_check_status(UErrorCode err, const char *msg) { intl_error_set_code(NULL, err); - if (U_FAILURE(err)) { + if (UNEXPECTED(U_FAILURE(err))) { intl_error_set_custom_msg(NULL, msg); return FAILURE; } @@ -61,7 +59,7 @@ static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, UIDNAInfo info = UIDNA_INFO_INITIALIZER; uts46 = uidna_openUTS46(option, &status); - if (php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE) { + if (UNEXPECTED(php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE)) { RETURN_FALSE; } @@ -76,7 +74,7 @@ static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, len = uidna_nameToUnicodeUTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), ZSTR_VAL(buffer), buffer_capac, &info, &status); } - if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) { + if (UNEXPECTED(len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE)) { uidna_close(uts46); zend_string_efree(buffer); RETURN_FALSE; @@ -123,7 +121,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } - if (ZSTR_LEN(domain) > INT32_MAX - 1) { + if (UNEXPECTED(ZSTR_LEN(domain) > INT32_MAX - 1)) { zend_argument_value_error(1, "must be less than " PRId32 " bytes", INT32_MAX); RETURN_THROWS(); } @@ -135,7 +133,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) if (idna_info != NULL) { idna_info = zend_try_array_init(idna_info); - if (!idna_info) { + if (UNEXPECTED(!idna_info)) { RETURN_THROWS(); } } diff --git a/ext/intl/idn/idn.h b/ext/intl/idn/idn.h index 596e63f207e0..cf3af63a26ae 100644 --- a/ext/intl/idn/idn.h +++ b/ext/intl/idn/idn.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre A. Joye | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_common.h b/ext/intl/intl_common.h index cef96325e9af..1fdb1c16efed 100644 --- a/ext/intl/intl_common.h +++ b/ext/intl/intl_common.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/intl_convert.c b/ext/intl/intl_convert.c index 39f70821e117..5497e84508b4 100644 --- a/ext/intl/intl_convert.c +++ b/ext/intl/intl_convert.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -59,7 +59,7 @@ void intl_convert_utf8_to_utf16( */ *status = U_ZERO_ERROR; - if(src_len > INT32_MAX) { + if (UNEXPECTED(src_len > INT32_MAX)) { /* we cannot fit this string */ *status = U_BUFFER_OVERFLOW_ERROR; return; @@ -120,7 +120,7 @@ zend_string *intl_convert_utf8_to_utf16_zstr( *status = U_ZERO_ERROR; - if(src_len > INT32_MAX) { + if (UNEXPECTED(src_len > INT32_MAX)) { /* we cannot fit this string */ *status = U_BUFFER_OVERFLOW_ERROR; return NULL; diff --git a/ext/intl/intl_convert.h b/ext/intl/intl_convert.h index 5cc3a671333d..443d373d55c2 100644 --- a/ext/intl/intl_convert.h +++ b/ext/intl/intl_convert.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/intl_convertcpp.cpp b/ext/intl/intl_convertcpp.cpp index b919c3fb4087..b305ff201c74 100644 --- a/ext/intl/intl_convertcpp.cpp +++ b/ext/intl/intl_convertcpp.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -62,6 +62,10 @@ zend_string* intl_charFromString(const UnicodeString &from, UErrorCode *status) //the number of UTF-8 code units is not larger than that of UTF-16 code //units * 3 + if (UNEXPECTED(from.length() > INT32_MAX / 3)) { + *status = U_BUFFER_OVERFLOW_ERROR; + return NULL; + } int32_t capacity = from.length() * 3; if (from.isEmpty()) { @@ -72,7 +76,7 @@ zend_string* intl_charFromString(const UnicodeString &from, UErrorCode *status) const UChar *utf16buf = from.getBuffer(); int32_t actual_len; - u_strToUTF8WithSub(ZSTR_VAL(u8res), capacity, &actual_len, utf16buf, from.length(), + u_strToUTF8WithSub(ZSTR_VAL(u8res), capacity + 1, &actual_len, utf16buf, from.length(), U_SENTINEL, NULL, status); if (U_FAILURE(*status)) { diff --git a/ext/intl/intl_convertcpp.h b/ext/intl/intl_convertcpp.h index 28948c2e01ca..ef4310bac4ff 100644 --- a/ext/intl/intl_convertcpp.h +++ b/ext/intl/intl_convertcpp.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h index 169448a2edf3..d2bc5f9a240d 100644 --- a/ext/intl/intl_cppshims.h +++ b/ext/intl/intl_cppshims.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_data.h b/ext/intl/intl_data.h index c818427e07e1..d2021caf18e3 100644 --- a/ext/intl/intl_data.h +++ b/ext/intl/intl_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -114,7 +114,7 @@ typedef struct _intl_data { #define INTL_MAX_LOCALE_LEN (ULOC_FULLNAME_CAPACITY-1) #define INTL_CHECK_LOCALE_LEN(locale_len) \ - if((locale_len) > INTL_MAX_LOCALE_LEN) { \ + if (UNEXPECTED((locale_len) > INTL_MAX_LOCALE_LEN)) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ @@ -123,7 +123,7 @@ typedef struct _intl_data { } #define INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len) \ - if((locale_len) > INTL_MAX_LOCALE_LEN) { \ + if (UNEXPECTED((locale_len) > INTL_MAX_LOCALE_LEN)) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index be6e53fb5439..eab1b7478155 100644 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -132,7 +132,7 @@ zend_string * intl_error_get_message( intl_error* err ) return ZSTR_EMPTY_ALLOC(); uErrorName = u_errorName( err->code ); - size_t uErrorLen = strlen(uErrorName); + const size_t uErrorLen = strlen(uErrorName); /* Format output string */ if (err->custom_error_message) { diff --git a/ext/intl/intl_error.h b/ext/intl/intl_error.h index 8a9bff0b271c..dd13cf84ebd2 100644 --- a/ext/intl/intl_error.h +++ b/ext/intl/intl_error.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -37,7 +37,7 @@ void intl_error_set( intl_error* err, UErrorCode code, const char* msg); UErrorCode intl_error_get_code( intl_error* err ); zend_string* intl_error_get_message( intl_error* err ); -// Wrappers to synchonize object's and global error structures. +// Wrappers to synchronize object's and global error structures. void intl_errors_reset( intl_error* err ); void intl_errors_set_custom_msg( intl_error* err, const char* msg); void intl_errors_set_code( intl_error* err, UErrorCode err_code ); diff --git a/ext/intl/intl_icu_compat.c b/ext/intl/intl_icu_compat.c new file mode 100644 index 000000000000..5aa12851cfb5 --- /dev/null +++ b/ext/intl/intl_icu_compat.c @@ -0,0 +1,114 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Weilin Du | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "intl_icu_compat.h" +#include +#include +#include +#include + +UConverter *intl_icu_compat_ucnv_clone(const UConverter *converter, UErrorCode *status) +{ +#if INTL_ICU_HAS_UCNV_CLONE + return ucnv_clone(converter, status); +#else + return ucnv_safeClone(converter, NULL, NULL, status); +#endif +} + +UBreakIterator *intl_icu_compat_ubrk_clone(const UBreakIterator *break_iterator, UErrorCode *status) +{ +#if INTL_ICU_HAS_UBRK_CLONE + return ubrk_clone(break_iterator, status); +#else + return ubrk_safeClone(break_iterator, NULL, NULL, status); +#endif +} + +void intl_icu_compat_uspoof_init_checker(USpoofChecker *checker, IntlIcuSpoofCheckResult **check_result, UErrorCode *status) +{ +#if INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT + /* ICU 58 removed WSC/MSC handling in favor of TR39 restriction levels. + * Keep the default highly restrictive behavior and allocate the extended + * check result used by uspoof_check2*(). */ + uspoof_setRestrictionLevel(checker, USPOOF_HIGHLY_RESTRICTIVE); + *check_result = uspoof_openCheckResult(status); +#else + int checks = uspoof_getChecks(checker, status); + + /* Single-script enforcement rejects legitimate mixed-script languages like Japanese. */ + uspoof_setChecks(checker, checks & ~USPOOF_SINGLE_SCRIPT, status); + *check_result = NULL; +#endif +} + +void intl_icu_compat_uspoof_close_check_result(IntlIcuSpoofCheckResult *check_result) +{ +#if INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT + if (check_result) { + uspoof_closeCheckResult(check_result); + } +#else + (void) check_result; +#endif +} + +int32_t intl_icu_compat_uspoof_check_utf8(const USpoofChecker *checker, const char *text, int32_t length, IntlIcuSpoofCheckResult *check_result, UErrorCode *status) +{ +#if INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT + return uspoof_check2UTF8(checker, text, length, check_result, status); +#else + (void) check_result; + return uspoof_checkUTF8(checker, text, length, NULL, status); +#endif +} + +UBool intl_icu_compat_uspoof_check_result_mismatch(IntlIcuSpoofCheckResult *check_result, int32_t checks, int32_t *result_checks, UErrorCode *status) +{ +#if INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT + *result_checks = uspoof_getCheckResultChecks(check_result, status); + return *result_checks != checks; +#else + (void) check_result; + (void) status; + *result_checks = checks; + return 0; +#endif +} + +UBool intl_icu_compat_uspoof_is_allowed_chars_pattern_option(int64_t pattern_option) +{ + return pattern_option == 0 + || pattern_option == USET_IGNORE_SPACE +#if INTL_ICU_HAS_USET_SIMPLE_CASE_INSENSITIVE + || pattern_option == (USET_IGNORE_SPACE|USET_SIMPLE_CASE_INSENSITIVE) +#endif + || pattern_option == (USET_IGNORE_SPACE|USET_CASE_INSENSITIVE) + || pattern_option == (USET_IGNORE_SPACE|USET_ADD_CASE_MAPPINGS); +} + +const char *intl_icu_compat_uspoof_allowed_chars_pattern_option_error_message(void) +{ +#if INTL_ICU_HAS_USET_SIMPLE_CASE_INSENSITIVE + return "must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::CASE_INSENSITIVE or SpoofChecker::ADD_CASE_MAPPINGS or SpoofChecker::SIMPLE_CASE_INSENSITIVE))"; +#else + return "must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::CASE_INSENSITIVE or SpoofChecker::ADD_CASE_MAPPINGS))"; +#endif +} diff --git a/ext/intl/intl_icu_compat.h b/ext/intl/intl_icu_compat.h new file mode 100644 index 000000000000..ae3a6aa126e3 --- /dev/null +++ b/ext/intl/intl_icu_compat.h @@ -0,0 +1,56 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Weilin Du | + +----------------------------------------------------------------------+ + */ + +#ifndef INTL_ICU_COMPAT_H +#define INTL_ICU_COMPAT_H + +#include +#include +#include +#include +#include + +#define INTL_ICU_VERSION_AT_LEAST(major, minor) \ + (U_ICU_VERSION_MAJOR_NUM > (major) || \ + (U_ICU_VERSION_MAJOR_NUM == (major) && U_ICU_VERSION_MINOR_NUM >= (minor))) + +#define INTL_ICU_HAS_UBRK_CLONE INTL_ICU_VERSION_AT_LEAST(69, 0) +#define INTL_ICU_HAS_UCNV_CLONE INTL_ICU_VERSION_AT_LEAST(71, 0) +#define INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT INTL_ICU_VERSION_AT_LEAST(58, 0) +#define INTL_ICU_HAS_USET_SIMPLE_CASE_INSENSITIVE INTL_ICU_VERSION_AT_LEAST(73, 0) + +#if INTL_ICU_HAS_SPOOFCHECKER_CHECK_RESULT +typedef USpoofCheckResult IntlIcuSpoofCheckResult; +#else +typedef void IntlIcuSpoofCheckResult; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +UConverter *intl_icu_compat_ucnv_clone(const UConverter *converter, UErrorCode *status); +UBreakIterator *intl_icu_compat_ubrk_clone(const UBreakIterator *break_iterator, UErrorCode *status); +void intl_icu_compat_uspoof_init_checker(USpoofChecker *checker, IntlIcuSpoofCheckResult **check_result, UErrorCode *status); +void intl_icu_compat_uspoof_close_check_result(IntlIcuSpoofCheckResult *check_result); +int32_t intl_icu_compat_uspoof_check_utf8(const USpoofChecker *checker, const char *text, int32_t length, IntlIcuSpoofCheckResult *check_result, UErrorCode *status); +UBool intl_icu_compat_uspoof_check_result_mismatch(IntlIcuSpoofCheckResult *check_result, int32_t checks, int32_t *result_checks, UErrorCode *status); +UBool intl_icu_compat_uspoof_is_allowed_chars_pattern_option(int64_t pattern_option); +const char *intl_icu_compat_uspoof_allowed_chars_pattern_option_error_message(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/intl/listformatter/listformatter_class.cpp b/ext/intl/listformatter/listformatter_class.cpp index 8a7f9ffef9c2..59c01259227d 100644 --- a/ext/intl/listformatter/listformatter_class.cpp +++ b/ext/intl/listformatter/listformatter_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bogdan Ungureanu | +----------------------------------------------------------------------+ @@ -14,22 +14,27 @@ extern "C" { #include "php.h" +} + +#include +#include +#include "../intl_convertcpp.h" + +extern "C" { #include "php_intl.h" -#include "intl_convert.h" } -#include #include "listformatter_class.h" #include "listformatter_arginfo.h" +#include + static zend_object_handlers listformatter_handlers; static void listformatter_free_obj(zend_object *object) { ListFormatter_object *obj = php_intl_listformatter_fetch_object(object); - if( obj->lf_data.ulistfmt ) - ulistfmt_close( obj->lf_data.ulistfmt ); - + delete obj->lf_data.ulistfmt; obj->lf_data.ulistfmt = nullptr; intl_error_reset( &obj->lf_data.error ); @@ -69,16 +74,21 @@ PHP_METHOD(IntlListFormatter, __construct) Z_PARAM_LONG(width) ZEND_PARSE_PARAMETERS_END(); + if (LISTFORMATTER_OBJECT(obj)) { + zend_throw_error(NULL, "IntlListFormatter object is already constructed"); + RETURN_THROWS(); + } + if(locale_len == 0) { locale = (char *)intl_locale_get_default(); } - if (locale_len > INTL_MAX_LOCALE_LEN) { + if (UNEXPECTED(locale_len > INTL_MAX_LOCALE_LEN)) { zend_argument_value_error(1, "must be less than or equal to %d characters", INTL_MAX_LOCALE_LEN); RETURN_THROWS(); } - if (strlen(uloc_getISO3Language(locale)) == 0) { + if (icu::Locale(locale).getISO3Language()[0] == '\0') { zend_argument_value_error(1, "\"%s\" is invalid", locale); RETURN_THROWS(); } @@ -89,13 +99,13 @@ PHP_METHOD(IntlListFormatter, __construct) zend_argument_value_error(2, "must be one of IntlListFormatter::TYPE_AND, IntlListFormatter::TYPE_OR, or IntlListFormatter::TYPE_UNITS"); RETURN_THROWS(); } - + if (width != ULISTFMT_WIDTH_WIDE && width != ULISTFMT_WIDTH_SHORT && width != ULISTFMT_WIDTH_NARROW) { zend_argument_value_error(3, "must be one of IntlListFormatter::WIDTH_WIDE, IntlListFormatter::WIDTH_SHORT, or IntlListFormatter::WIDTH_NARROW"); RETURN_THROWS(); } - LISTFORMATTER_OBJECT(obj) = ulistfmt_openForType(locale, static_cast(type), static_cast(width), &status); + LISTFORMATTER_OBJECT(obj) = ListFormatter::createInstance(icu::Locale(locale), static_cast(type), static_cast(width), status); #else if (type != INTL_LISTFORMATTER_FALLBACK_TYPE_AND) { zend_argument_value_error(2, "contains an unsupported type. ICU 66 and below only support IntlListFormatter::TYPE_AND"); @@ -107,7 +117,7 @@ PHP_METHOD(IntlListFormatter, __construct) RETURN_THROWS(); } - LISTFORMATTER_OBJECT(obj) = ulistfmt_open(locale, &status); + LISTFORMATTER_OBJECT(obj) = ListFormatter::createInstance(icu::Locale(locale), status); #endif if (U_FAILURE(status)) { @@ -126,89 +136,54 @@ PHP_METHOD(IntlListFormatter, format) Z_PARAM_ARRAY_HT(ht) ZEND_PARSE_PARAMETERS_END(); - uint32_t count = zend_hash_num_elements(ht); + intl_errors_reset(LISTFORMATTER_ERROR_P(obj)); + + const uint32_t count = zend_hash_num_elements(ht); if (count == 0) { RETURN_EMPTY_STRING(); } - const UChar **items = (const UChar **)safe_emalloc(count, sizeof(const UChar *), 0); - int32_t *itemLengths = (int32_t *)safe_emalloc(count, sizeof(int32_t), 0); + std::unique_ptr items(new UnicodeString[count]); uint32_t i = 0; zval *val; ZEND_HASH_FOREACH_VAL(ht, val) { zend_string *str_val, *tmp_str; - - str_val = zval_get_tmp_string(val, &tmp_str); - - // Convert PHP string to UTF-16 - UChar *ustr = nullptr; - int32_t ustr_len = 0; - UErrorCode status = U_ZERO_ERROR; - - intl_convert_utf8_to_utf16(&ustr, &ustr_len, ZSTR_VAL(str_val), ZSTR_LEN(str_val), &status); + UErrorCode conv_status = U_ZERO_ERROR; + + str_val = zval_try_get_tmp_string(val, &tmp_str); + if (UNEXPECTED(!str_val)) { + RETURN_THROWS(); + } + intl_stringFromChar(items[i], ZSTR_VAL(str_val), ZSTR_LEN(str_val), &conv_status); zend_tmp_string_release(tmp_str); - if (U_FAILURE(status)) { - // We can't use goto cleanup because items and itemLengths are incompletely allocated - for (uint32_t j = 0; j < i; j++) { - efree((void *)items[j]); - } - efree(items); - efree(itemLengths); - intl_error_set(nullptr, status, "Failed to convert string to UTF-16"); + if (U_FAILURE(conv_status)) { + intl_errors_set(LISTFORMATTER_ERROR_P(obj), conv_status, "Failed to convert string to UTF-16"); RETURN_FALSE; } - - items[i] = ustr; - itemLengths[i] = ustr_len; + i++; } ZEND_HASH_FOREACH_END(); UErrorCode status = U_ZERO_ERROR; - int32_t resultLength; - UChar *result = nullptr; - zend_string *ret = nullptr; - - resultLength = ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, nullptr, 0, &status); + UnicodeString result; - if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { - intl_error_set(nullptr, status, "Failed to format list"); - RETVAL_FALSE; - goto cleanup; - } - - // Allocate buffer and try again - status = U_ZERO_ERROR; - result = (UChar *)safe_emalloc(resultLength + 1, sizeof(UChar), 0); - ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, result, resultLength, &status); + LISTFORMATTER_OBJECT(obj)->format(items.get(), count, result, status); if (U_FAILURE(status)) { - if (result) { - efree(result); - } - intl_error_set(nullptr, status, "Failed to format list"); - RETVAL_FALSE; - goto cleanup; + intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list"); + RETURN_FALSE; } - // Convert result back to UTF-8 - ret = intl_convert_utf16_to_utf8(result, resultLength, &status); - efree(result); - + zend_string *ret = intl_charFromString(result, &status); + if (!ret) { - intl_error_set(nullptr, status, "Failed to convert result to UTF-8"); - RETVAL_FALSE; - } else { - RETVAL_NEW_STR(ret); + intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to convert result to UTF-8"); + RETURN_FALSE; } -cleanup: - for (i = 0; i < count; i++) { - efree((void *)items[i]); - } - efree(items); - efree(itemLengths); + RETVAL_STR(ret); } PHP_METHOD(IntlListFormatter, getErrorCode) @@ -236,9 +211,9 @@ void listformatter_register_class(void) { zend_class_entry *class_entry = register_class_IntlListFormatter(); class_entry->create_object = listformatter_create_object; - + memcpy(&listformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - listformatter_handlers.offset = XtOffsetOf(ListFormatter_object, zo); + listformatter_handlers.offset = offsetof(ListFormatter_object, zo); listformatter_handlers.free_obj = listformatter_free_obj; listformatter_handlers.clone_obj = nullptr; } diff --git a/ext/intl/listformatter/listformatter_class.h b/ext/intl/listformatter/listformatter_class.h index 8edbf8d63e2d..bdf21b6886e0 100644 --- a/ext/intl/listformatter/listformatter_class.h +++ b/ext/intl/listformatter/listformatter_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bogdan Ungureanu | +----------------------------------------------------------------------+ @@ -21,14 +21,19 @@ #include "intl_error.h" #include "intl_data.h" -#include +#ifdef __cplusplus +#include +using icu::ListFormatter; +#else +typedef void ListFormatter; +#endif typedef struct { // error handling intl_error error; // formatter handling - UListFormatter* ulistfmt; + ListFormatter* ulistfmt; } listformatter_data; typedef struct { @@ -36,9 +41,7 @@ typedef struct { zend_object zo; } ListFormatter_object; -static inline ListFormatter_object *php_intl_listformatter_fetch_object(zend_object *obj) { - return (ListFormatter_object *)((char*)(obj) - XtOffsetOf(ListFormatter_object, zo)); -} +#define php_intl_listformatter_fetch_object(obj) ZEND_CONTAINER_OF(obj, ListFormatter_object, zo) #define Z_INTL_LISTFORMATTER_P(zv) php_intl_listformatter_fetch_object(Z_OBJ_P(zv)) #define LISTFORMATTER_ERROR(lfo) (lfo)->lf_data.error diff --git a/ext/intl/locale/locale.cpp b/ext/intl/locale/locale.cpp index 76b269ca85e3..bad1c775c1b0 100644 --- a/ext/intl/locale/locale.cpp +++ b/ext/intl/locale/locale.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/locale/locale.h b/ext/intl/locale/locale.h index 31aef035050d..1c40871d2065 100644 --- a/ext/intl/locale/locale.h +++ b/ext/intl/locale/locale.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/locale/locale.stub.php b/ext/intl/locale/locale.stub.php index 03813ecaf194..fc012768de9f 100644 --- a/ext/intl/locale/locale.stub.php +++ b/ext/intl/locale/locale.stub.php @@ -92,6 +92,16 @@ public static function getDisplayLanguage(string $locale, ?string $displayLocale */ public static function getDisplayVariant(string $locale, ?string $displayLocale = null): string|false {} + /** + * @alias locale_get_display_keyword + */ + public static function getDisplayKeyword(string $keyword, ?string $displayLocale = null): string|false {} + + /** + * @alias locale_get_display_keyword_value + */ + public static function getDisplayKeywordValue(string $locale, string $keyword, ?string $displayLocale = null): string|false {} + /** * @tentative-return-type * @alias locale_compose diff --git a/ext/intl/locale/locale_arginfo.h b/ext/intl/locale/locale_arginfo.h index 1d6e6683e21a..a01f583b0451 100644 --- a/ext/intl/locale/locale_arginfo.h +++ b/ext/intl/locale/locale_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit locale.stub.php instead. - * Stub hash: ff1f75bd34a52f57210734e2f5e29efb87566137 */ + * Stub hash: 43dbc3aa294044e9cef923a5f39249dae86b67f0 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Locale_getDefault, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -33,6 +33,17 @@ ZEND_END_ARG_INFO() #define arginfo_class_Locale_getDisplayVariant arginfo_class_Locale_getDisplayScript +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Locale_getDisplayKeyword, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, keyword, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, displayLocale, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Locale_getDisplayKeywordValue, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, keyword, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, displayLocale, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_Locale_composeLocale, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, subtags, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -83,6 +94,8 @@ ZEND_FUNCTION(locale_get_display_region); ZEND_FUNCTION(locale_get_display_name); ZEND_FUNCTION(locale_get_display_language); ZEND_FUNCTION(locale_get_display_variant); +ZEND_FUNCTION(locale_get_display_keyword); +ZEND_FUNCTION(locale_get_display_keyword_value); ZEND_FUNCTION(locale_compose); ZEND_FUNCTION(locale_parse); ZEND_FUNCTION(locale_get_all_variants); @@ -106,6 +119,8 @@ static const zend_function_entry class_Locale_methods[] = { ZEND_RAW_FENTRY("getDisplayName", zif_locale_get_display_name, arginfo_class_Locale_getDisplayName, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("getDisplayLanguage", zif_locale_get_display_language, arginfo_class_Locale_getDisplayLanguage, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("getDisplayVariant", zif_locale_get_display_variant, arginfo_class_Locale_getDisplayVariant, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) + ZEND_RAW_FENTRY("getDisplayKeyword", zif_locale_get_display_keyword, arginfo_class_Locale_getDisplayKeyword, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) + ZEND_RAW_FENTRY("getDisplayKeywordValue", zif_locale_get_display_keyword_value, arginfo_class_Locale_getDisplayKeywordValue, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("composeLocale", zif_locale_compose, arginfo_class_Locale_composeLocale, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("parseLocale", zif_locale_parse, arginfo_class_Locale_parseLocale, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("getAllVariants", zif_locale_get_all_variants, arginfo_class_Locale_getAllVariants, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) diff --git a/ext/intl/locale/locale_class.cpp b/ext/intl/locale/locale_class.cpp index 75fde45d53d6..a8d34f2e9f24 100644 --- a/ext/intl/locale/locale_class.cpp +++ b/ext/intl/locale/locale_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/locale/locale_class.h b/ext/intl/locale/locale_class.h index 64a661ca2b44..86cbc6ed9421 100644 --- a/ext/intl/locale/locale_class.h +++ b/ext/intl/locale/locale_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/locale/locale_methods.cpp b/ext/intl/locale/locale_methods.cpp index 5cf6928a8cd3..05ec5825d8cb 100644 --- a/ext/intl/locale/locale_methods.cpp +++ b/ext/intl/locale/locale_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -44,6 +44,8 @@ ZEND_EXTERN_MODULE_GLOBALS( intl ) #define EXTLANG_PREFIX "a" #define PRIVATE_PREFIX "x" #define DISP_NAME "name" +#define DISP_KEYWORD "keyword" +#define DISP_KEYWORD_VALUE "keyword_value" #define MAX_NO_VARIANT 15 #define MAX_NO_EXTLANG 3 @@ -254,7 +256,7 @@ static zend_off_t getStrrtokenPos(char* str, zend_off_t savedPos) } } if(result < 1){ - /* Just in case inavlid locale e.g. '-x-xyz' or '-sl_Latn' */ + /* Just in case invalid locale e.g. '-x-xyz' or '-sl_Latn' */ result =-1; } return result; @@ -351,7 +353,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t int32_t buflen = 512; UErrorCode status = U_ZERO_ERROR; - if (strlen(loc_name) > INTL_MAX_LOCALE_LEN) { + if (UNEXPECTED(strlen(loc_name) > INTL_MAX_LOCALE_LEN)) { return NULL; } @@ -362,7 +364,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ return zend_string_init(loc_name, strlen(loc_name), 0); } else { - /* Since Grandfathered , no value , do nothing , retutn NULL */ + /* Since Grandfathered , no value , do nothing , return NULL */ return NULL; } } @@ -457,7 +459,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t efree( mod_loc_name); } - tag_value->len = strlen(tag_value->val); + tag_value->len = buflen; return tag_value; } /* }}} */ @@ -573,7 +575,7 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_ Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) ZEND_PARSE_PARAMETERS_END(); - if(loc_name_len > ULOC_FULLNAME_CAPACITY) { + if (UNEXPECTED(loc_name_len > ULOC_FULLNAME_CAPACITY)) { /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long"); RETURN_FALSE; @@ -671,6 +673,107 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_ } /* }}} */ +/* {{{ + * common code shared by display keyword functions to get the value from ICU + }}} */ +static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FUNCTION_PARAMETERS) +{ + char* loc_name = NULL; + size_t loc_name_len = 0; + char* keyword_name = NULL; + size_t keyword_name_len = 0; + char* disp_loc_name = NULL; + size_t disp_loc_name_len = 0; + int free_loc_name = 0; + + UChar* disp_name = NULL; + int32_t disp_name_len = 0; + int32_t buflen = 512; + UErrorCode status = U_ZERO_ERROR; + + zend_string* u8str; + char* msg = NULL; + + intl_error_reset( NULL ); + + if (strcmp(tag_name, DISP_KEYWORD) == 0) { + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH(keyword_name, keyword_name_len) + Z_PARAM_OPTIONAL + Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + } else { + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_PATH(loc_name, loc_name_len) + Z_PARAM_PATH(keyword_name, keyword_name_len) + Z_PARAM_OPTIONAL + Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(loc_name_len > ULOC_FULLNAME_CAPACITY)) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long"); + RETURN_FALSE; + } + + if (loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + } + } + + if (!disp_loc_name) { + disp_loc_name = estrdup(intl_locale_get_default()); + free_loc_name = 1; + } + + do { + disp_name = reinterpret_cast(erealloc(disp_name, buflen * sizeof(UChar))); + disp_name_len = buflen; + + if (strcmp(tag_name, DISP_KEYWORD) == 0) { + buflen = uloc_getDisplayKeyword(keyword_name, disp_loc_name, disp_name, disp_name_len, &status); + } else { + buflen = uloc_getDisplayKeywordValue(loc_name, keyword_name, disp_loc_name, disp_name, disp_name_len, &status); + } + + /* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */ + if (U_FAILURE(status)) { + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + continue; + } + + spprintf(&msg, 0, "unable to get locale %s", tag_name); + intl_error_set( NULL, status, msg); + efree(msg); + if (disp_name) { + efree(disp_name); + } + if (free_loc_name) { + efree((void *)disp_loc_name); + disp_loc_name = NULL; + } + RETURN_FALSE; + } + } while (buflen > disp_name_len); + + if (free_loc_name) { + efree((void *)disp_loc_name); + disp_loc_name = NULL; + } + + u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status); + efree(disp_name); + if (!u8str) { + spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name); + intl_error_set( NULL, status, msg); + efree(msg); + RETURN_FALSE; + } + + RETVAL_NEW_STR(u8str); +} +/* }}} */ + /* {{{ gets the name for the $locale in $in_locale or default_locale */ U_CFUNC PHP_FUNCTION(locale_get_display_name) { @@ -711,6 +814,20 @@ U_CFUNC PHP_FUNCTION(locale_get_display_variant) { get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } +/* }}} */ + +/* {{{ gets the keyword display label in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_keyword) +{ + get_icu_disp_keyword_value_src_php(DISP_KEYWORD, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ gets the keyword value display label in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_keyword_value) +{ + get_icu_disp_keyword_value_src_php(DISP_KEYWORD_VALUE, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} /* }}} */ /* {{{ return an associative array containing keyword-value @@ -736,7 +853,7 @@ U_CFUNC PHP_FUNCTION( locale_get_keywords ) Z_PARAM_PATH(loc_name, loc_name_len) ZEND_PARSE_PARAMETERS_END(); - INTL_CHECK_LOCALE_LEN(strlen(loc_name)); + INTL_CHECK_LOCALE_LEN(loc_name_len); if(loc_name_len == 0) { loc_name = (char *)intl_locale_get_default(); @@ -815,7 +932,7 @@ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, const char /* not lang or grandfathered tag */ smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); } - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); + smart_str_append(loc_name, Z_STR_P(ele_value)); return SUCCESS; } @@ -853,7 +970,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, add_prefix( loc_name , key_name); smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); + smart_str_append(loc_name, Z_STR_P(ele_value)); return SUCCESS; } else if(Z_TYPE_P(ele_value) == IS_ARRAY ) { HashTable *arr = Z_ARRVAL_P(ele_value); @@ -868,7 +985,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, add_prefix(loc_name , key_name); } smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(data) , Z_STRLEN_P(data)); + smart_str_append(loc_name, Z_STR_P(data)); } ZEND_HASH_FOREACH_END(); return SUCCESS; } else { @@ -902,7 +1019,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, add_prefix(loc_name , cur_key_name); } smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); + smart_str_append(loc_name, Z_STR_P(ele_value)); } } /* end of for */ } /* end of else */ @@ -1127,7 +1244,7 @@ U_CFUNC PHP_FUNCTION(locale_parse) Z_PARAM_PATH(loc_name, loc_name_len) ZEND_PARSE_PARAMETERS_END(); - INTL_CHECK_LOCALE_LEN(strlen(loc_name)); + INTL_CHECK_LOCALE_LEN(loc_name_len); if(loc_name_len == 0) { loc_name = (char *)intl_locale_get_default(); @@ -1217,7 +1334,7 @@ static int strToMatch(const char* str ,char *retstr) if( *str == '-' ){ *retstr = '_'; } else { - *retstr = tolower(*str); + *retstr = tolower((unsigned char)*str); } str++; retstr++; @@ -1318,7 +1435,7 @@ U_CFUNC PHP_FUNCTION(locale_filter_matches) if( token && (token==cur_lang_tag) ){ /* check if the char. after match is SEPARATOR */ - chrcheck = token + (strlen(cur_loc_range)); + chrcheck = token + can_loc_range->len; if( isIDSeparator(*chrcheck) || isKeywordSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ efree( cur_lang_tag ); efree( cur_loc_range ); @@ -1350,14 +1467,14 @@ U_CFUNC PHP_FUNCTION(locale_filter_matches) } /* end of if isCanonical */ else{ /* Convert to lower case for case-insensitive comparison */ - cur_lang_tag = reinterpret_cast(ecalloc( 1, strlen(lang_tag ) + 1)); + cur_lang_tag = reinterpret_cast(ecalloc(1, lang_tag_len + 1)); result = strToMatch( lang_tag , cur_lang_tag); if( result == 0) { efree( cur_lang_tag ); RETURN_FALSE; } - cur_loc_range = reinterpret_cast(ecalloc( 1, strlen(loc_range ) + 1)); + cur_loc_range = reinterpret_cast(ecalloc(1, loc_range_len + 1)); result = strToMatch( loc_range , cur_loc_range ); if( result == 0) { efree( cur_lang_tag ); @@ -1370,7 +1487,7 @@ U_CFUNC PHP_FUNCTION(locale_filter_matches) if( token && (token==cur_lang_tag) ){ /* check if the char. after match is SEPARATOR */ - chrcheck = token + (strlen(cur_loc_range)); + chrcheck = token + loc_range_len; if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ efree( cur_lang_tag ); efree( cur_loc_range ); @@ -1435,14 +1552,15 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, zend_argument_value_error(2, "must not contain any null bytes"); LOOKUP_CLEAN_RETURN(NULL); } - cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); - result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[cur_arr_len*2]); + i = cur_arr_len*2; + cur_arr[i] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); + cur_arr_len++; + result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[i]); if(result == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); LOOKUP_CLEAN_RETURN(NULL); } - cur_arr[cur_arr_len*2+1] = Z_STRVAL_P(ele_value); - cur_arr_len++ ; + cur_arr[i+1] = Z_STRVAL_P(ele_value); } ZEND_HASH_FOREACH_END(); /* end of for */ /* Canonicalize array elements */ @@ -1562,6 +1680,15 @@ U_CFUNC PHP_FUNCTION(locale_lookup) } result_str = lookup_loc_range(loc_range, hash_arr, boolCanonical); + if (EG(exception)) { + RETURN_THROWS(); + } + if (U_FAILURE(intl_error_get_code(NULL))) { + if (result_str) { + zend_string_release_ex(result_str, 0); + } + RETURN_NULL(); + } if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') { if( fallback_loc_str ) { result_str = zend_string_copy(fallback_loc_str); @@ -1588,7 +1715,7 @@ U_CFUNC PHP_FUNCTION(locale_accept_from_http) ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STRING(http_accept, http_accept_len) ZEND_PARSE_PARAMETERS_END(); - if(http_accept_len > ULOC_FULLNAME_CAPACITY) { + if (UNEXPECTED(http_accept_len > ULOC_FULLNAME_CAPACITY)) { /* check each fragment, if any bigger than capacity, can't do it due to bug #72533 */ char *start = http_accept; char *end; @@ -1596,7 +1723,7 @@ U_CFUNC PHP_FUNCTION(locale_accept_from_http) do { end = strchr(start, ','); len = end ? end-start : http_accept_len-(start-http_accept); - if(len > ULOC_FULLNAME_CAPACITY) { + if (UNEXPECTED(len > ULOC_FULLNAME_CAPACITY)) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale string too long"); RETURN_FALSE; @@ -1613,7 +1740,7 @@ U_CFUNC PHP_FUNCTION(locale_accept_from_http) &outResult, http_accept, available, &status); uenum_close(available); INTL_CHECK_STATUS(status, "failed to find acceptable locale"); - if (len < 0 || outResult == ULOC_ACCEPT_FAILED) { + if (UNEXPECTED(len < 0 || outResult == ULOC_ACCEPT_FAILED)) { RETURN_FALSE; } RETURN_STRINGL(resultLocale, len); @@ -1650,9 +1777,9 @@ U_CFUNC PHP_FUNCTION(locale_add_likely_subtags) locale = (char *)intl_locale_get_default(); } - int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status); + const int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status); INTL_CHECK_STATUS(status, "invalid locale"); - if (maximized_locale_len < 0) { + if (UNEXPECTED(maximized_locale_len < 0)) { RETURN_FALSE; } @@ -1673,9 +1800,9 @@ U_CFUNC PHP_FUNCTION(locale_minimize_subtags) locale = (char *)intl_locale_get_default(); } - int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status); + const int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status); INTL_CHECK_STATUS(status, "invalid locale"); - if (minimized_locale_len < 0) { + if (UNEXPECTED(minimized_locale_len < 0)) { RETURN_FALSE; } diff --git a/ext/intl/msgformat/msgformat.cpp b/ext/intl/msgformat/msgformat.cpp index a9e1f71bfc60..3857e97b4a4a 100644 --- a/ext/intl/msgformat/msgformat.cpp +++ b/ext/intl/msgformat/msgformat.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_attr.cpp b/ext/intl/msgformat/msgformat_attr.cpp index e7ec006e5e79..15c3525b858f 100644 --- a/ext/intl/msgformat/msgformat_attr.cpp +++ b/ext/intl/msgformat/msgformat_attr.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_class.cpp b/ext/intl/msgformat/msgformat_class.cpp index e762febf0d1b..c4d74924b04a 100644 --- a/ext/intl/msgformat/msgformat_class.cpp +++ b/ext/intl/msgformat/msgformat_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -58,7 +58,7 @@ U_CFUNC zend_object *MessageFormatter_object_create(zend_class_entry *ce) /* {{{ MessageFormatter_object_clone */ U_CFUNC zend_object *MessageFormatter_object_clone(zend_object *object) { - MessageFormatter_object *mfo = php_intl_messageformatter_fetch_object(object); + const MessageFormatter_object *mfo = php_intl_messageformatter_fetch_object(object); zend_object *new_obj = MessageFormatter_ce_ptr->create_object(object->ce); MessageFormatter_object *new_mfo = php_intl_messageformatter_fetch_object(new_obj); @@ -96,7 +96,7 @@ void msgformat_register_class( void ) memcpy(&MessageFormatter_handlers, &std_object_handlers, sizeof MessageFormatter_handlers); - MessageFormatter_handlers.offset = XtOffsetOf(MessageFormatter_object, zo); + MessageFormatter_handlers.offset = offsetof(MessageFormatter_object, zo); MessageFormatter_handlers.clone_obj = MessageFormatter_object_clone; MessageFormatter_handlers.free_obj = MessageFormatter_object_free; } diff --git a/ext/intl/msgformat/msgformat_class.h b/ext/intl/msgformat/msgformat_class.h index 809fdec65418..849c45c14729 100644 --- a/ext/intl/msgformat/msgformat_class.h +++ b/ext/intl/msgformat/msgformat_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -30,10 +30,7 @@ typedef struct { zend_object zo; } MessageFormatter_object; - -static inline MessageFormatter_object *php_intl_messageformatter_fetch_object(zend_object *obj) { - return (MessageFormatter_object *)((char*)(obj) - XtOffsetOf(MessageFormatter_object, zo)); -} +#define php_intl_messageformatter_fetch_object(obj) ZEND_CONTAINER_OF(obj, MessageFormatter_object, zo) #define Z_INTL_MESSAGEFORMATTER_P(zv) php_intl_messageformatter_fetch_object(Z_OBJ_P(zv)) void msgformat_register_class( void ); diff --git a/ext/intl/msgformat/msgformat_data.cpp b/ext/intl/msgformat/msgformat_data.cpp index f8b7ec39601e..c629e8a3d818 100644 --- a/ext/intl/msgformat/msgformat_data.cpp +++ b/ext/intl/msgformat/msgformat_data.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h index bac94cbec34c..121c8360efea 100644 --- a/ext/intl/msgformat/msgformat_data.h +++ b/ext/intl/msgformat/msgformat_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_format.cpp b/ext/intl/msgformat/msgformat_format.cpp index 8e3ec28b389e..c0a02ad8db17 100644 --- a/ext/intl/msgformat/msgformat_format.cpp +++ b/ext/intl/msgformat/msgformat_format.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index 25e8dbf86968..e676a07416c2 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -184,7 +184,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, (void*)&bogusType, sizeof(bogusType)); } } else if (name_part.getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) { - int32_t argNumber = name_part.getValue(); + const int32_t argNumber = name_part.getValue(); if (argNumber < 0) { intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Found part with negative number"); @@ -341,7 +341,7 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, } if (used_tz == NULL) { - used_tz = timezone_process_timezone_argument(nullptr, nullptr, &err); + used_tz = timezone_process_timezone_argument(nullptr, nullptr, &err, 1); if (used_tz == NULL) { continue; } @@ -364,7 +364,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, UChar **formatted, int32_t *formatted_len) { - int arg_count = zend_hash_num_elements(args); + const int arg_count = zend_hash_num_elements(args); std::vector fargs; std::vector farg_names; MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; @@ -408,10 +408,10 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } UChar temp[16]; - int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index); + const int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index); key.append(temp, len); - storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, (zend_ulong)num_index); + storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, num_index); } else { //string; assumed to be in UTF-8 intl_stringFromChar(key, ZSTR_VAL(str_index), ZSTR_LEN(str_index), &err.code); @@ -467,7 +467,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } case Formattable::kDouble: { - double d = zval_get_double(elem); + const double d = zval_get_double(elem); formattable.setDouble(d); break; } @@ -523,7 +523,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } case Formattable::kDate: { - double dd = intl_zval_to_millis(elem, &err); + const double dd = intl_zval_to_millis(elem, &err); if (U_FAILURE(err.code)) { char *message; zend_string *u8key; @@ -649,7 +649,7 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval **args, UCh case Formattable::kInt64: aInt64 = fargs[i].getInt64(); - if(aInt64 > ZEND_LONG_MAX || aInt64 < -ZEND_LONG_MAX) { + if(aInt64 > ZEND_LONG_MAX || aInt64 < ZEND_LONG_MIN) { ZVAL_DOUBLE(&(*args)[i], (double)aInt64); } else { ZVAL_LONG(&(*args)[i], (zend_long)aInt64); diff --git a/ext/intl/msgformat/msgformat_helpers.h b/ext/intl/msgformat/msgformat_helpers.h index 20282526cbfb..c1a153783511 100644 --- a/ext/intl/msgformat/msgformat_helpers.h +++ b/ext/intl/msgformat/msgformat_helpers.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_parse.cpp b/ext/intl/msgformat/msgformat_parse.cpp index 28d7ce710802..e177d3aca7fb 100644 --- a/ext/intl/msgformat/msgformat_parse.cpp +++ b/ext/intl/msgformat/msgformat_parse.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -27,7 +27,7 @@ extern "C" { } /* {{{ */ -static void msgfmt_do_parse(MessageFormatter_object *mfo, char *source, size_t src_len, zval *return_value) +static void msgfmt_do_parse(MessageFormatter_object *mfo, const char *source, size_t src_len, zval *return_value) { zval *fargs; int count = 0; diff --git a/ext/intl/normalizer/normalizer.h b/ext/intl/normalizer/normalizer.h index 3c6aa0e6eafc..c6feaa106eb1 100644 --- a/ext/intl/normalizer/normalizer.h +++ b/ext/intl/normalizer/normalizer.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ diff --git a/ext/intl/normalizer/normalizer_class.cpp b/ext/intl/normalizer/normalizer_class.cpp index 3838f7546325..1898df04e2e1 100644 --- a/ext/intl/normalizer/normalizer_class.cpp +++ b/ext/intl/normalizer/normalizer_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ diff --git a/ext/intl/normalizer/normalizer_class.h b/ext/intl/normalizer/normalizer_class.h index 8f88f215abcc..e30c29237041 100644 --- a/ext/intl/normalizer/normalizer_class.h +++ b/ext/intl/normalizer/normalizer_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ diff --git a/ext/intl/normalizer/normalizer_normalize.cpp b/ext/intl/normalizer/normalizer_normalize.cpp index 92e8f1166ad0..e5b8db14bafb 100644 --- a/ext/intl/normalizer/normalizer_normalize.cpp +++ b/ext/intl/normalizer/normalizer_normalize.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ @@ -37,19 +37,14 @@ static const UNormalizer2 *intl_get_normalizer(zend_long form, UErrorCode *err) { case NORMALIZER_FORM_C: return unorm2_getNFCInstance(err); - break; case NORMALIZER_FORM_D: return unorm2_getNFDInstance(err); - break; case NORMALIZER_FORM_KC: return unorm2_getNFKCInstance(err); - break; case NORMALIZER_FORM_KD: return unorm2_getNFKDInstance(err); - break; case NORMALIZER_FORM_KC_CF: return unorm2_getNFKCCasefoldInstance(err); - break; } *err = U_ILLEGAL_ARGUMENT_ERROR; @@ -59,7 +54,7 @@ static const UNormalizer2 *intl_get_normalizer(zend_long form, UErrorCode *err) static int32_t intl_normalize(zend_long form, const UChar *src, int32_t src_len, UChar *dst, int32_t dst_len, UErrorCode *err) {/*{{{*/ const UNormalizer2 *norm = intl_get_normalizer(form, err); - if (U_FAILURE(*err)) { + if (UNEXPECTED(U_FAILURE(*err))) { return -1; } @@ -70,7 +65,7 @@ static UBool intl_is_normalized(zend_long form, const UChar *uinput, int32_t uin {/*{{{*/ const UNormalizer2 *norm = intl_get_normalizer(form, err); - if(U_FAILURE(*err)) { + if (UNEXPECTED(U_FAILURE(*err))) { return false; } @@ -120,7 +115,7 @@ U_CFUNC PHP_FUNCTION( normalizer_normalize ) case NORMALIZER_FORM_KC_CF: break; default: - zend_argument_value_error(2, "must be a a valid normalization form"); + zend_argument_value_error(2, "must be a valid normalization form"); RETURN_THROWS(); } @@ -156,7 +151,7 @@ U_CFUNC PHP_FUNCTION( normalizer_normalize ) * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough). * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). */ - if( U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING ) { + if (UNEXPECTED(U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING)) { intl_error_set_custom_msg( NULL, "Error normalizing string"); efree( uret_buf ); efree( uinput ); @@ -177,7 +172,7 @@ U_CFUNC PHP_FUNCTION( normalizer_normalize ) size_needed = intl_normalize(form, uinput, uinput_len, uret_buf, uret_len, &status); /* Bail out if an unexpected error occurred. */ - if( U_FAILURE(status) ) { + if (UNEXPECTED(U_FAILURE(status))) { /* Set error messages. */ intl_error_set_custom_msg( NULL,"Error normalizing string"); efree( uret_buf ); @@ -237,7 +232,7 @@ U_CFUNC PHP_FUNCTION( normalizer_is_normalized ) case NORMALIZER_FORM_KC_CF: break; default: - zend_argument_value_error(2, "must be a a valid normalization form"); + zend_argument_value_error(2, "must be a valid normalization form"); RETURN_THROWS(); } @@ -269,7 +264,7 @@ U_CFUNC PHP_FUNCTION( normalizer_is_normalized ) efree( uinput ); /* Bail out if an unexpected error occurred. */ - if( U_FAILURE(status) ) { + if (UNEXPECTED(U_FAILURE(status))) { /* Set error messages. */ intl_error_set_custom_msg( NULL,"Error testing if string is the given normalization form."); RETURN_FALSE; @@ -309,20 +304,20 @@ U_CFUNC PHP_FUNCTION( normalizer_get_raw_decomposition ) norm = intl_get_normalizer(form, &status); U8_NEXT(input, offset, input_length, codepoint); - if ((size_t)offset != input_length) { + if (UNEXPECTED((size_t)offset != input_length)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "Input string must be exactly one UTF-8 encoded code point long."); return; } - if ((codepoint < UCHAR_MIN_VALUE) || (codepoint > UCHAR_MAX_VALUE)) { + if (UNEXPECTED((codepoint < UCHAR_MIN_VALUE) || (codepoint > UCHAR_MAX_VALUE))) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "Code point out of range"); return; } decomposition_length = unorm2_getRawDecomposition(norm, codepoint, decomposition, 32, &status); - if (decomposition_length == -1) { + if (UNEXPECTED(decomposition_length == -1)) { RETURN_NULL(); } diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index 441b26ae088d..697d77a98bfa 100644 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -106,7 +106,7 @@ char* canonicalize_locale_string(const char* locale) { canonicalized_len = uloc_canonicalize(locale, canonicalized, sizeof(canonicalized), &status); - if (U_FAILURE(status) || canonicalized_len <= 0) { + if (UNEXPECTED(U_FAILURE(status) || canonicalized_len <= 0)) { return NULL; } diff --git a/ext/intl/php_intl.h b/ext/intl/php_intl.h index a56c34f3dce4..1a9b4f769e86 100644 --- a/ext/intl/php_intl.h +++ b/ext/intl/php_intl.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index 4bcb8587f786..1e6c5cacf203 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -487,6 +487,10 @@ function locale_get_display_language(string $locale, ?string $displayLocale = nu function locale_get_display_variant(string $locale, ?string $displayLocale = null): string|false {} +function locale_get_display_keyword(string $keyword, ?string $displayLocale = null): string|false {} + +function locale_get_display_keyword_value(string $locale, string $keyword, ?string $displayLocale = null): string|false {} + function locale_compose(array $subtags): string|false {} function locale_parse(string $locale): ?array {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 81160349980c..00de5986f1ef 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_intl.stub.php instead. - * Stub hash: c52fd0def2530be628beedbbcdcfecdcb07449a8 */ + * Stub hash: f94e7c9cc372878f1f8bd0e948092ea72076e687 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") @@ -553,6 +553,17 @@ ZEND_END_ARG_INFO() #define arginfo_locale_get_display_variant arginfo_locale_get_display_script +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_locale_get_display_keyword, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, keyword, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, displayLocale, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_locale_get_display_keyword_value, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, keyword, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, displayLocale, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_locale_compose, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, subtags, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -941,6 +952,8 @@ ZEND_FUNCTION(locale_get_display_region); ZEND_FUNCTION(locale_get_display_name); ZEND_FUNCTION(locale_get_display_language); ZEND_FUNCTION(locale_get_display_variant); +ZEND_FUNCTION(locale_get_display_keyword); +ZEND_FUNCTION(locale_get_display_keyword_value); ZEND_FUNCTION(locale_compose); ZEND_FUNCTION(locale_parse); ZEND_FUNCTION(locale_get_all_variants); @@ -1133,6 +1146,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(locale_get_display_name, arginfo_locale_get_display_name) ZEND_FE(locale_get_display_language, arginfo_locale_get_display_language) ZEND_FE(locale_get_display_variant, arginfo_locale_get_display_variant) + ZEND_FE(locale_get_display_keyword, arginfo_locale_get_display_keyword) + ZEND_FE(locale_get_display_keyword_value, arginfo_locale_get_display_keyword_value) ZEND_FE(locale_compose, arginfo_locale_compose) ZEND_FE(locale_parse, arginfo_locale_parse) ZEND_FE(locale_get_all_variants, arginfo_locale_get_all_variants) diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 2042966177cb..2dbb60c5b639 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bogdan Ungureanu | +----------------------------------------------------------------------+ @@ -22,6 +22,7 @@ extern "C" { #include #include #include +#include #include "../intl_convertcpp.h" extern "C" { @@ -30,7 +31,6 @@ extern "C" { #include "../intl_data.h" #include "rangeformatter_arginfo.h" #include "rangeformatter_class.h" - #include "intl_convert.h" } using icu::number::NumberRangeFormatter; @@ -60,6 +60,19 @@ zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) return &intern->zo; } +static icu::Formattable rangeformatter_create_formattable(const zval *number) +{ + icu::Formattable formattable; + + if (Z_TYPE_P(number) == IS_DOUBLE) { + formattable.setDouble(Z_DVAL_P(number)); + } else { + formattable.setInt64(static_cast(Z_LVAL_P(number))); + } + + return formattable; +} + U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) { ZEND_PARSE_PARAMETERS_NONE(); @@ -86,12 +99,12 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) locale = (char *)intl_locale_get_default(); } - if (locale_len > INTL_MAX_LOCALE_LEN) { + if (UNEXPECTED(locale_len > INTL_MAX_LOCALE_LEN)) { zend_argument_value_error(2, "must be no longer than %d characters", INTL_MAX_LOCALE_LEN); RETURN_THROWS(); } - if (strlen(uloc_getISO3Language(locale)) == 0) { + if (icu::Locale(locale).getISO3Language()[0] == '\0') { zend_argument_value_error(2, "\"%s\" is invalid", locale); RETURN_THROWS(); } @@ -154,8 +167,8 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) UErrorCode error = U_ZERO_ERROR; - icu::Formattable start_formattable(Z_TYPE_P(start) == IS_DOUBLE ? Z_DVAL_P(start) : Z_LVAL_P(start)); - icu::Formattable end_formattable(Z_TYPE_P(end) == IS_DOUBLE ? Z_DVAL_P(end) : Z_LVAL_P(end)); + icu::Formattable start_formattable = rangeformatter_create_formattable(start); + icu::Formattable end_formattable = rangeformatter_create_formattable(end); UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start_formattable, end_formattable, error).toString(error); @@ -219,7 +232,7 @@ void rangeformatter_register_class(void) class_entry_IntlNumberRangeFormatter->create_object = IntlNumberRangeFormatter_object_create; memcpy(&rangeformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - rangeformatter_handlers.offset = XtOffsetOf(IntlNumberRangeFormatter_object, zo); + rangeformatter_handlers.offset = offsetof(IntlNumberRangeFormatter_object, zo); rangeformatter_handlers.free_obj = IntlNumberRangeFormatter_object_free; rangeformatter_handlers.clone_obj = NULL; } diff --git a/ext/intl/rangeformatter/rangeformatter_class.h b/ext/intl/rangeformatter/rangeformatter_class.h index 661641c2ce0f..494a6d09a05f 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.h +++ b/ext/intl/rangeformatter/rangeformatter_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bogdan Ungureanu | +----------------------------------------------------------------------+ @@ -36,9 +36,7 @@ typedef struct { zend_object zo; } IntlNumberRangeFormatter_object; -static inline IntlNumberRangeFormatter_object *php_intl_numberrangeformatter_fetch_object(zend_object *obj) { - return (IntlNumberRangeFormatter_object *)((char*)(obj) - XtOffsetOf(IntlNumberRangeFormatter_object, zo)); -} +#define php_intl_numberrangeformatter_fetch_object(obj) ZEND_CONTAINER_OF(obj, IntlNumberRangeFormatter_object, zo) #define Z_INTL_RANGEFORMATTER_P(zv) php_intl_numberrangeformatter_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/resourcebundle/resourcebundle.cpp b/ext/intl/resourcebundle/resourcebundle.cpp index b8c5c00efaba..d3a41b7c8d92 100644 --- a/ext/intl/resourcebundle/resourcebundle.cpp +++ b/ext/intl/resourcebundle/resourcebundle.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -74,7 +74,7 @@ U_CFUNC void resourcebundle_extract_value( zval *return_value, ResourceBundle_ob source->child = NULL; intl_errors_reset(INTL_DATA_ERROR_P(source)); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle.h b/ext/intl/resourcebundle/resourcebundle.h index c46908a8edff..e7c79c480d35 100644 --- a/ext/intl/resourcebundle/resourcebundle.h +++ b/ext/intl/resourcebundle/resourcebundle.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ diff --git a/ext/intl/resourcebundle/resourcebundle_class.cpp b/ext/intl/resourcebundle/resourcebundle_class.cpp index d88ba2ad1317..a997691f6423 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.cpp +++ b/ext/intl/resourcebundle/resourcebundle_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -108,7 +108,7 @@ static zend_result resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) locale = (char *)intl_locale_get_default(); } - if (bundlename_len >= MAXPATHLEN) { + if (UNEXPECTED(bundlename_len >= MAXPATHLEN)) { zend_argument_value_error(2, "is too long"); return FAILURE; } @@ -174,7 +174,7 @@ static zval *resource_bundle_array_fetch( { int32_t index = 0; char *key = NULL; - bool is_numeric = offset_str == NULL; + const bool is_numeric = offset_str == NULL; char *pbuf; ResourceBundle_object *rb; @@ -220,12 +220,12 @@ static zval *resource_bundle_array_fetch( } if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { - UErrorCode icuerror; + UErrorCode icuerror = U_ZERO_ERROR; const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror ); if (is_numeric) { - spprintf(&pbuf, 0, "Cannot load element %d without fallback from to %s", index, locale); + spprintf(&pbuf, 0, "Cannot load element %d without fallback to %s", index, locale); } else { - spprintf(&pbuf, 0, "Cannot load element '%s' without fallback from to %s", key, locale); + spprintf(&pbuf, 0, "Cannot load element '%s' without fallback to %s", key, locale); } intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf); efree(pbuf); @@ -339,6 +339,7 @@ U_CFUNC PHP_FUNCTION( resourcebundle_locales ) size_t bundlename_len = 0; const char * entry; int entry_len; + int32_t count; UEnumeration *icuenum; UErrorCode icuerror = U_ZERO_ERROR; @@ -348,7 +349,7 @@ U_CFUNC PHP_FUNCTION( resourcebundle_locales ) Z_PARAM_STRING(bundlename, bundlename_len) ZEND_PARSE_PARAMETERS_END(); - if (bundlename_len >= MAXPATHLEN) { + if (UNEXPECTED(bundlename_len >= MAXPATHLEN)) { zend_argument_value_error(1, "is too long"); RETURN_THROWS(); } @@ -364,7 +365,13 @@ U_CFUNC PHP_FUNCTION( resourcebundle_locales ) uenum_reset( icuenum, &icuerror ); INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); - array_init( return_value ); + count = uenum_count( icuenum, &icuerror ); + if (U_FAILURE(icuerror)) { + count = 0; + icuerror = U_ZERO_ERROR; + } + + array_init_size( return_value, count ); while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) { add_next_index_stringl( return_value, (char *) entry, entry_len); } @@ -424,7 +431,7 @@ U_CFUNC void resourcebundle_register_class( void ) ResourceBundle_ce_ptr->get_iterator = resourcebundle_get_iterator; ResourceBundle_object_handlers = std_object_handlers; - ResourceBundle_object_handlers.offset = XtOffsetOf(ResourceBundle_object, zend); + ResourceBundle_object_handlers.offset = offsetof(ResourceBundle_object, zend); ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */ ResourceBundle_object_handlers.free_obj = ResourceBundle_object_free; ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get; diff --git a/ext/intl/resourcebundle/resourcebundle_class.h b/ext/intl/resourcebundle/resourcebundle_class.h index 334532bde99b..1ec2ac592222 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.h +++ b/ext/intl/resourcebundle/resourcebundle_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -36,7 +36,7 @@ typedef struct { } ResourceBundle_object; static inline ResourceBundle_object *php_intl_resourcebundle_fetch_object(zend_object *obj) { - return (ResourceBundle_object *)((char*)(obj) - XtOffsetOf(ResourceBundle_object, zend)); + return ZEND_CONTAINER_OF(obj, ResourceBundle_object, zend); } #define Z_INTL_RESOURCEBUNDLE_P(zv) php_intl_resourcebundle_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.cpp b/ext/intl/resourcebundle/resourcebundle_iterator.cpp index 7747b34adbd4..29288418437a 100644 --- a/ext/intl/resourcebundle/resourcebundle_iterator.cpp +++ b/ext/intl/resourcebundle/resourcebundle_iterator.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.h b/ext/intl/resourcebundle/resourcebundle_iterator.h index c323d4e17b4c..762c12f363b5 100644 --- a/ext/intl/resourcebundle/resourcebundle_iterator.h +++ b/ext/intl/resourcebundle/resourcebundle_iterator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php index 0141252d478d..51a9c7d39074 100644 --- a/ext/intl/spoofchecker/spoofchecker.stub.php +++ b/ext/intl/spoofchecker/spoofchecker.stub.php @@ -19,7 +19,6 @@ class Spoofchecker public const int INVISIBLE = UNKNOWN; /** @cvalue USPOOF_CHAR_LIMIT */ public const int CHAR_LIMIT = UNKNOWN; -#if U_ICU_VERSION_MAJOR_NUM >= 58 /** @cvalue USPOOF_ASCII */ public const int ASCII = UNKNOWN; /** @cvalue USPOOF_HIGHLY_RESTRICTIVE */ @@ -34,7 +33,6 @@ class Spoofchecker public const int SINGLE_SCRIPT_RESTRICTIVE = UNKNOWN; /** @cvalue USPOOF_MIXED_NUMBERS */ public const int MIXED_NUMBERS = UNKNOWN; -#endif #if U_ICU_VERSION_MAJOR_NUM >= 62 /** @cvalue USPOOF_HIDDEN_OVERLAY */ public const int HIDDEN_OVERLAY = UNKNOWN; @@ -71,9 +69,7 @@ public function setAllowedLocales(string $locales): void {} /** @tentative-return-type */ public function setChecks(int $checks): void {} -#if U_ICU_VERSION_MAJOR_NUM >= 58 /** @tentative-return-type */ public function setRestrictionLevel(int $level): void {} -#endif public function setAllowedChars(string $pattern, int $patternOptions = 0): void {} } diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index 536798914428..8704065e479b 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit spoofchecker.stub.php instead. - * Stub hash: 4834be57a3f0cb74dbc4422e609846139f09f6cb */ + * Stub hash: 4634f8ef9157fb3670a2ddc5e3246340660fc68c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Spoofchecker___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -23,11 +23,9 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_set ZEND_ARG_TYPE_INFO(0, checks, IS_LONG, 0) ZEND_END_ARG_INFO() -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_setRestrictionLevel, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0) ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_setAllowedChars, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) @@ -39,9 +37,7 @@ ZEND_METHOD(Spoofchecker, isSuspicious); ZEND_METHOD(Spoofchecker, areConfusable); ZEND_METHOD(Spoofchecker, setAllowedLocales); ZEND_METHOD(Spoofchecker, setChecks); -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_METHOD(Spoofchecker, setRestrictionLevel); -#endif ZEND_METHOD(Spoofchecker, setAllowedChars); static const zend_function_entry class_Spoofchecker_methods[] = { @@ -50,9 +46,7 @@ static const zend_function_entry class_Spoofchecker_methods[] = { ZEND_ME(Spoofchecker, areConfusable, arginfo_class_Spoofchecker_areConfusable, ZEND_ACC_PUBLIC) ZEND_ME(Spoofchecker, setAllowedLocales, arginfo_class_Spoofchecker_setAllowedLocales, ZEND_ACC_PUBLIC) ZEND_ME(Spoofchecker, setChecks, arginfo_class_Spoofchecker_setChecks, ZEND_ACC_PUBLIC) -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_ME(Spoofchecker, setRestrictionLevel, arginfo_class_Spoofchecker_setRestrictionLevel, ZEND_ACC_PUBLIC) -#endif ZEND_ME(Spoofchecker, setAllowedChars, arginfo_class_Spoofchecker_setAllowedChars, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -105,7 +99,6 @@ static zend_class_entry *register_class_Spoofchecker(void) zend_string *const_CHAR_LIMIT_name = zend_string_init_interned("CHAR_LIMIT", sizeof("CHAR_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_LIMIT_name, &const_CHAR_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release_ex(const_CHAR_LIMIT_name, true); -#if U_ICU_VERSION_MAJOR_NUM >= 58 zval const_ASCII_value; ZVAL_LONG(&const_ASCII_value, USPOOF_ASCII); @@ -148,7 +141,6 @@ static zend_class_entry *register_class_Spoofchecker(void) zend_string *const_MIXED_NUMBERS_name = zend_string_init_interned("MIXED_NUMBERS", sizeof("MIXED_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIXED_NUMBERS_name, &const_MIXED_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release_ex(const_MIXED_NUMBERS_name, true); -#endif #if U_ICU_VERSION_MAJOR_NUM >= 62 zval const_HIDDEN_OVERLAY_value; diff --git a/ext/intl/spoofchecker/spoofchecker_class.cpp b/ext/intl/spoofchecker/spoofchecker_class.cpp index ba4c64321f14..7f5f66bcc80e 100644 --- a/ext/intl/spoofchecker/spoofchecker_class.cpp +++ b/ext/intl/spoofchecker/spoofchecker_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -63,7 +63,7 @@ U_CFUNC zend_object *Spoofchecker_object_create(zend_class_entry *ce) static zend_object *spoofchecker_clone_obj(zend_object *object) /* {{{ */ { - Spoofchecker_object *spoofchecker_orig = php_intl_spoofchecker_fetch_object(object); + const Spoofchecker_object *spoofchecker_orig = php_intl_spoofchecker_fetch_object(object); zend_object *new_obj_val = Spoofchecker_ce_ptr->create_object(object->ce); Spoofchecker_object *spoofchecker_new = php_intl_spoofchecker_fetch_object(new_obj_val); @@ -98,7 +98,7 @@ U_CFUNC void spoofchecker_register_Spoofchecker_class(void) memcpy(&Spoofchecker_handlers, &std_object_handlers, sizeof Spoofchecker_handlers); - Spoofchecker_handlers.offset = XtOffsetOf(Spoofchecker_object, zo); + Spoofchecker_handlers.offset = offsetof(Spoofchecker_object, zo); Spoofchecker_handlers.clone_obj = spoofchecker_clone_obj; Spoofchecker_handlers.free_obj = Spoofchecker_objects_free; } @@ -132,12 +132,8 @@ U_CFUNC void spoofchecker_object_destroy(Spoofchecker_object* co) co->uspoof = NULL; } -#if U_ICU_VERSION_MAJOR_NUM >= 58 - if (co->uspoofres) { - uspoof_closeCheckResult(co->uspoofres); - co->uspoofres = NULL; - } -#endif + intl_icu_compat_uspoof_close_check_result(co->uspoofres); + co->uspoofres = NULL; intl_error_reset(SPOOFCHECKER_ERROR_P(co)); } diff --git a/ext/intl/spoofchecker/spoofchecker_class.h b/ext/intl/spoofchecker/spoofchecker_class.h index 06701eb60e36..68d5daf2b5a1 100644 --- a/ext/intl/spoofchecker/spoofchecker_class.h +++ b/ext/intl/spoofchecker/spoofchecker_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -27,6 +27,7 @@ extern "C" { } #endif +#include "intl_icu_compat.h" #include typedef struct { @@ -35,16 +36,12 @@ typedef struct { // ICU Spoofchecker USpoofChecker* uspoof; -#if U_ICU_VERSION_MAJOR_NUM >= 58 - USpoofCheckResult* uspoofres; -#endif + IntlIcuSpoofCheckResult* uspoofres; zend_object zo; } Spoofchecker_object; -static inline Spoofchecker_object *php_intl_spoofchecker_fetch_object(zend_object *obj) { - return (Spoofchecker_object *)((char*)(obj) - XtOffsetOf(Spoofchecker_object, zo)); -} +#define php_intl_spoofchecker_fetch_object(obj) ZEND_CONTAINER_OF(obj, Spoofchecker_object, zo) #define Z_INTL_SPOOFCHECKER_P(zv) php_intl_spoofchecker_fetch_object((Z_OBJ_P(zv))) #define SPOOFCHECKER_ERROR(co) (co)->err @@ -89,8 +86,4 @@ extern zend_class_entry *Spoofchecker_ce_ptr; RETURN_FALSE; \ } \ -#if U_ICU_VERSION_MAJOR_NUM >= 58 -#define SPOOFCHECKER_DEFAULT_RESTRICTION_LEVEL USPOOF_HIGHLY_RESTRICTIVE -#endif - #endif // #ifndef SPOOFCHECKER_CLASS_H diff --git a/ext/intl/spoofchecker/spoofchecker_create.cpp b/ext/intl/spoofchecker/spoofchecker_create.cpp index 1ed4055cccd1..8a322c0d64c2 100644 --- a/ext/intl/spoofchecker/spoofchecker_create.cpp +++ b/ext/intl/spoofchecker/spoofchecker_create.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -30,14 +30,15 @@ extern "C" { /* {{{ Spoofchecker object constructor. */ U_CFUNC PHP_METHOD(Spoofchecker, __construct) { -#if U_ICU_VERSION_MAJOR_NUM < 58 - int checks; -#endif SPOOFCHECKER_METHOD_INIT_VARS; ZEND_PARSE_PARAMETERS_NONE(); SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK; + if (co->uspoof) { + zend_throw_error(NULL, "Spoofchecker object is already constructed"); + RETURN_THROWS(); + } co->uspoof = uspoof_open(SPOOFCHECKER_ERROR_CODE_P(co)); if (U_FAILURE(INTL_DATA_ERROR_CODE(co))) { @@ -45,23 +46,7 @@ U_CFUNC PHP_METHOD(Spoofchecker, __construct) "Spoofchecker::__construct(): unable to open ICU Spoof Checker", 0); } -#if U_ICU_VERSION_MAJOR_NUM >= 58 - /* TODO save it into the object for further suspiction check comparison. */ - /* ICU 58 removes WSC and MSC handling. However there are restriction - levels as defined in - http://www.unicode.org/reports/tr39/tr39-15.html#Restriction_Level_Detection - and the default is high restrictive. In further, we might want to utilize - uspoof_check2 APIs when it became stable, to use extended check result APIs. - Subsequent changes in the unicode security algos are to be watched.*/ - uspoof_setRestrictionLevel(co->uspoof, SPOOFCHECKER_DEFAULT_RESTRICTION_LEVEL); - co->uspoofres = uspoof_openCheckResult(SPOOFCHECKER_ERROR_CODE_P(co)); -#else - /* Single-script enforcement is on by default. This fails for languages - like Japanese that legally use multiple scripts within a single word, - so we turn it off. - */ - checks = uspoof_getChecks(co->uspoof, SPOOFCHECKER_ERROR_CODE_P(co)); - uspoof_setChecks(co->uspoof, checks & ~USPOOF_SINGLE_SCRIPT, SPOOFCHECKER_ERROR_CODE_P(co)); -#endif + /* Applies the default spoof checker behavior consistently across ICU versions. */ + intl_icu_compat_uspoof_init_checker(co->uspoof, &co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); } /* }}} */ diff --git a/ext/intl/spoofchecker/spoofchecker_main.cpp b/ext/intl/spoofchecker/spoofchecker_main.cpp index e49ddec87a3c..1e8e9ac2a78d 100644 --- a/ext/intl/spoofchecker/spoofchecker_main.cpp +++ b/ext/intl/spoofchecker/spoofchecker_main.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -43,21 +43,14 @@ U_CFUNC PHP_METHOD(Spoofchecker, isSuspicious) SPOOFCHECKER_METHOD_FETCH_OBJECT; -#if U_ICU_VERSION_MAJOR_NUM >= 58 - ret = uspoof_check2UTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); -#else - ret = uspoof_checkUTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), NULL, SPOOFCHECKER_ERROR_CODE_P(co)); -#endif + ret = intl_icu_compat_uspoof_check_utf8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); -#if U_ICU_VERSION_MAJOR_NUM >= 58 - errmask = uspoof_getCheckResultChecks(co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); - if (errmask != ret) { + if (intl_icu_compat_uspoof_check_result_mismatch(co->uspoofres, ret, &errmask, SPOOFCHECKER_ERROR_CODE_P(co))) { php_error_docref(NULL, E_WARNING, "unexpected error (%d), does not relate to the flags passed to setChecks (%d)", ret, errmask); } -#endif RETURN_TRUE; } @@ -84,7 +77,7 @@ U_CFUNC PHP_METHOD(Spoofchecker, areConfusable) ZEND_PARSE_PARAMETERS_END(); SPOOFCHECKER_METHOD_FETCH_OBJECT; - if(ZSTR_LEN(s1) > INT32_MAX || ZSTR_LEN(s2) > INT32_MAX) { + if (UNEXPECTED(ZSTR_LEN(s1) > INT32_MAX || ZSTR_LEN(s2) > INT32_MAX)) { SPOOFCHECKER_ERROR_CODE(co) = U_BUFFER_OVERFLOW_ERROR; } else { ret = uspoof_areConfusableUTF8(co->uspoof, ZSTR_VAL(s1), (int32_t)ZSTR_LEN(s1), ZSTR_VAL(s2), (int32_t)ZSTR_LEN(s2), SPOOFCHECKER_ERROR_CODE_P(co)); @@ -142,7 +135,7 @@ U_CFUNC PHP_METHOD(Spoofchecker, setChecks) } /* }}} */ -#if U_ICU_VERSION_MAJOR_NUM >= 58 +/* TODO Document this method on PHP.net */ /* {{{ Set the loosest restriction level allowed for strings. */ U_CFUNC PHP_METHOD(Spoofchecker, setRestrictionLevel) { @@ -170,7 +163,6 @@ U_CFUNC PHP_METHOD(Spoofchecker, setRestrictionLevel) uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level); } /* }}} */ -#endif U_CFUNC PHP_METHOD(Spoofchecker, setAllowedChars) { @@ -187,7 +179,7 @@ U_CFUNC PHP_METHOD(Spoofchecker, setAllowedChars) ZEND_PARSE_PARAMETERS_END(); SPOOFCHECKER_METHOD_FETCH_OBJECT; - if (ZSTR_LEN(pattern) > INT32_MAX) { + if (UNEXPECTED(ZSTR_LEN(pattern) > INT32_MAX)) { zend_argument_value_error(1, "must be less than or equal to " ZEND_LONG_FMT " bytes long", INT32_MAX); RETURN_THROWS(); } @@ -207,19 +199,8 @@ U_CFUNC PHP_METHOD(Spoofchecker, setAllowedChars) USet *set = uset_openEmpty(); /* pattern is either USE_IGNORE_SPACE alone or in conjunction with the following flags (but mutually exclusive) */ - if (pattern_option && - pattern_option != USET_IGNORE_SPACE && -#if U_ICU_VERSION_MAJOR_NUM >= 73 - pattern_option != (USET_IGNORE_SPACE|USET_SIMPLE_CASE_INSENSITIVE) && -#endif - pattern_option != (USET_IGNORE_SPACE|USET_CASE_INSENSITIVE) && - pattern_option != (USET_IGNORE_SPACE|USET_ADD_CASE_MAPPINGS)) { - zend_argument_value_error(2, "must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::USET_CASE_INSENSITIVE or SpoofChecker::USET_ADD_CASE_MAPPINGS" -#if U_ICU_VERSION_MAJOR_NUM >= 73 - " or SpoofChecker::USET_SIMPLE_CASE_INSENSITIVE" -#endif - "))" - ); + if (!intl_icu_compat_uspoof_is_allowed_chars_pattern_option(pattern_option)) { + zend_argument_value_error(2, "%s", intl_icu_compat_uspoof_allowed_chars_pattern_option_error_message()); uset_close(set); efree(upattern); RETURN_THROWS(); diff --git a/ext/intl/tests/breakiter_getLocale_error.phpt b/ext/intl/tests/breakiter_getLocale_error.phpt new file mode 100644 index 000000000000..07d57dbc4265 --- /dev/null +++ b/ext/intl/tests/breakiter_getLocale_error.phpt @@ -0,0 +1,25 @@ +--TEST-- +IntlBreakIterator::getLocale(): bad arguments +--EXTENSIONS-- +intl +--FILE-- +getLocale(2); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +try { + $bi->getLocale(-1); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: IntlBreakIterator::getLocale(): Argument #1 ($type) must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE +ValueError: IntlBreakIterator::getLocale(): Argument #1 ($type) must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE diff --git a/ext/intl/tests/bug75317.phpt b/ext/intl/tests/bug75317.phpt index 4df45f37bf80..a38fa2578b9c 100644 --- a/ext/intl/tests/bug75317.phpt +++ b/ext/intl/tests/bug75317.phpt @@ -29,7 +29,7 @@ var_dump($c->setSourceEncoding('utf-32')); printResult($c->getDestinationEncoding(), $utf8); printResult($c->getSourceEncoding(), $utf32); -// test invalid inputs dont change values +// test invalid inputs don't change values var_dump($c->setDestinationEncoding('foobar') === false); var_dump($c->setSourceEncoding('foobar') === false); printResult($c->getDestinationEncoding(), $utf8); diff --git a/ext/intl/tests/calendar_fromDateTime_error.phpt b/ext/intl/tests/calendar_fromDateTime_error.phpt index b0a6a6d0fe0c..33d9f9cf1259 100644 --- a/ext/intl/tests/calendar_fromDateTime_error.phpt +++ b/ext/intl/tests/calendar_fromDateTime_error.phpt @@ -35,6 +35,6 @@ DateMalformedStringException: Failed to parse time string (foobar) at position 0 NULL string(88) "IntlCalendar::fromDateTime(): DateTime object is unconstructed: U_ILLEGAL_ARGUMENT_ERROR" NULL -string(103) "IntlCalendar::fromDateTime(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" +string(103) "IntlCalendar::fromDateTime(): object has a time zone offset that is too large: U_ILLEGAL_ARGUMENT_ERROR" NULL string(127) "IntlCalendar::fromDateTime(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_setTimeZone_error2.phpt b/ext/intl/tests/calendar_setTimeZone_error2.phpt index 6b65aa1a0e7c..277311e0c6b6 100644 --- a/ext/intl/tests/calendar_setTimeZone_error2.phpt +++ b/ext/intl/tests/calendar_setTimeZone_error2.phpt @@ -25,5 +25,5 @@ bool(false) string(126) "IntlCalendar::setTimeZone(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" bool(false) -string(102) "IntlCalendar::setTimeZone(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" +string(102) "IntlCalendar::setTimeZone(): object has a time zone offset that is too large: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" diff --git a/ext/intl/tests/calendar_set_date_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt new file mode 100644 index 000000000000..db9d18275ae8 --- /dev/null +++ b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt @@ -0,0 +1,32 @@ +--TEST-- +IntlCalendar::setDate(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDate(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDate(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt new file mode 100644 index 000000000000..798ab1ebb01f --- /dev/null +++ b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt @@ -0,0 +1,53 @@ +--TEST-- +IntlCalendar::setDateTime(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDateTime(99999999999, 1, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 99999999999, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 99999999999, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDateTime(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #4 ($hour) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #5 ($minute) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #6 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_out_of_bounds.phpt b/ext/intl/tests/calendar_set_out_of_bounds.phpt new file mode 100644 index 000000000000..1ca407d3f713 --- /dev/null +++ b/ext/intl/tests/calendar_set_out_of_bounds.phpt @@ -0,0 +1,55 @@ +--TEST-- +IntlCalendar::set(): out-of-bounds date/time arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +set(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #1 ($year) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #3 ($month) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #7 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_uninitialized_argument_position.phpt b/ext/intl/tests/calendar_uninitialized_argument_position.phpt new file mode 100644 index 000000000000..f92367180549 --- /dev/null +++ b/ext/intl/tests/calendar_uninitialized_argument_position.phpt @@ -0,0 +1,36 @@ +--TEST-- +IntlCalendar methods report the correct argument position for uninitialized calendar arguments +--EXTENSIONS-- +intl +--FILE-- +newInstanceWithoutConstructor(); + +foreach (['equals', 'before', 'after', 'isEquivalentTo'] as $method) { + try { + $calendar->$method($uninitialized); + } catch (Error $e) { + echo $method, ': ', $e->getMessage(), PHP_EOL; + } +} + +foreach (['intlcal_equals', 'intlcal_before', 'intlcal_after', 'intlcal_is_equivalent_to'] as $function) { + try { + $function($calendar, $uninitialized); + } catch (Error $e) { + echo $function, ': ', $e->getMessage(), PHP_EOL; + } +} + +?> +--EXPECT-- +equals: IntlCalendar::equals(): Argument #1 ($other) is uninitialized +before: IntlCalendar::before(): Argument #1 ($other) is uninitialized +after: IntlCalendar::after(): Argument #1 ($other) is uninitialized +isEquivalentTo: IntlCalendar::isEquivalentTo(): Argument #1 ($other) is uninitialized +intlcal_equals: intlcal_equals(): Argument #2 ($other) is uninitialized +intlcal_before: intlcal_before(): Argument #2 ($other) is uninitialized +intlcal_after: intlcal_after(): Argument #2 ($other) is uninitialized +intlcal_is_equivalent_to: intlcal_is_equivalent_to(): Argument #2 ($other) is uninitialized diff --git a/ext/intl/tests/collator_double_ctor.phpt b/ext/intl/tests/collator_double_ctor.phpt new file mode 100644 index 000000000000..93b72f7392b3 --- /dev/null +++ b/ext/intl/tests/collator_double_ctor.phpt @@ -0,0 +1,16 @@ +--TEST-- +Collator double construction should not be allowed +--EXTENSIONS-- +intl +--FILE-- +__construct('en_US'); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Collator object is already constructed diff --git a/ext/intl/tests/collator_sort_modify_during_compare.phpt b/ext/intl/tests/collator_sort_modify_during_compare.phpt new file mode 100644 index 000000000000..427f5833f1fc --- /dev/null +++ b/ext/intl/tests/collator_sort_modify_during_compare.phpt @@ -0,0 +1,36 @@ +--TEST-- +Collator::sort(): mutating the array from __toString() during comparison must not corrupt the sort +--EXTENSIONS-- +intl +--FILE-- +sort($arr)); +var_dump($arr); +?> +--EXPECT-- +bool(true) +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + object(Grow)#2 (0) { + } + [3]=> + string(1) "z" +} diff --git a/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt b/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt new file mode 100644 index 000000000000..5c3d03cd4f65 --- /dev/null +++ b/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt @@ -0,0 +1,44 @@ +--TEST-- +datefmt_parse() and datefmt_localtime() validate offset type +--EXTENSIONS-- +intl +--FILE-- +setPattern('VV'); + +$offset = 'offset'; +try { + $fmt->parse('America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + datefmt_parse($fmt, 'America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + $fmt->localtime('America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + datefmt_localtime($fmt, 'America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +IntlDateFormatter::parse(): Argument #2 ($offset) must be of type int, string given +datefmt_parse(): Argument #3 ($offset) must be of type int, string given +IntlDateFormatter::localtime(): Argument #2 ($offset) must be of type int, string given +datefmt_localtime(): Argument #3 ($offset) must be of type int, string given diff --git a/ext/intl/tests/formatter_fail.phpt b/ext/intl/tests/formatter_fail.phpt index 53f6b4ac7c7b..678b87b8c1b8 100644 --- a/ext/intl/tests/formatter_fail.phpt +++ b/ext/intl/tests/formatter_fail.phpt @@ -137,9 +137,9 @@ TypeError: numfmt_create(): Argument #1 ($locale) must be of type string, array 'U_ZERO_ERROR' IntlException: NumberFormatter::__construct(): number formatter creation failed -'NumberFormatter::__construct(): number formatter creation failed: U_UNSUPPORTED_ERROR' -'NumberFormatter::create(): number formatter creation failed: U_UNSUPPORTED_ERROR' -'numfmt_create(): number formatter creation failed: U_UNSUPPORTED_ERROR' +'NumberFormatter::__construct(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'NumberFormatter::create(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'numfmt_create(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' IntlException: NumberFormatter::__construct(): number formatter creation failed 'NumberFormatter::__construct(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' diff --git a/ext/intl/tests/formatter_parse_offset_overflow.phpt b/ext/intl/tests/formatter_parse_offset_overflow.phpt new file mode 100644 index 000000000000..9421c8897511 --- /dev/null +++ b/ext/intl/tests/formatter_parse_offset_overflow.phpt @@ -0,0 +1,46 @@ +--TEST-- +NumberFormatter parse offset overflow +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; + } +} + +$offset = PHP_INT_MAX; +print_error(function () use ($fmt, &$offset) { + $fmt->parse('123', NumberFormatter::TYPE_DOUBLE, $offset); +}); + +$offset = PHP_INT_MAX; +print_error(function () use ($fmt, &$offset) { + numfmt_parse($fmt, '123', NumberFormatter::TYPE_DOUBLE, $offset); +}); + +$currency = ''; +$offset = PHP_INT_MAX; +print_error(function () use ($currencyFmt, &$currency, &$offset) { + $currencyFmt->parseCurrency('$123.00', $currency, $offset); +}); + +$currency = ''; +$offset = PHP_INT_MAX; +print_error(function () use ($currencyFmt, &$currency, &$offset) { + numfmt_parse_currency($currencyFmt, '$123.00', $currency, $offset); +}); +?> +--EXPECT-- +ValueError: NumberFormatter::parse(): Argument #3 ($offset) must be between -2147483648 and 2147483647 +ValueError: numfmt_parse(): Argument #4 ($offset) must be between -2147483648 and 2147483647 +ValueError: NumberFormatter::parseCurrency(): Argument #3 ($offset) must be between -2147483648 and 2147483647 +ValueError: numfmt_parse_currency(): Argument #4 ($offset) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/gh12243.phpt b/ext/intl/tests/gh12243.phpt index 786a9bd1ee8f..324ed9a65661 100644 --- a/ext/intl/tests/gh12243.phpt +++ b/ext/intl/tests/gh12243.phpt @@ -1,5 +1,5 @@ --TEST-- -GitHub #12043 segfault with IntlDateFormatter::dateType where it equals to UDAT_PATTERN (icu 50) but +GitHub #12043 segfault with IntlDateFormatter::dateType where it equals to IntlDateFormatter::PATTERN (icu 50) but IntldateFormatter::timeType needs to be set as such. --EXTENSIONS-- intl @@ -21,4 +21,4 @@ try { ?> --EXPECT-- -IntlDateFormatter::__construct(): time format must be UDAT_PATTERN if date format is UDAT_PATTERN +IntlDateFormatter::__construct(): datefmt_create: time format must be IntlDateFormatter::PATTERN if date format is IntlDateFormatter::PATTERN diff --git a/ext/intl/tests/gh21998.phpt b/ext/intl/tests/gh21998.phpt new file mode 100644 index 000000000000..392336dab522 --- /dev/null +++ b/ext/intl/tests/gh21998.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-21998 (NumberFormatter::format(INF) leaves a non-NUL-terminated zend_string) +--EXTENSIONS-- +intl +--FILE-- +format(INF)); +var_dump($fmt->format(-INF)); +var_dump($fmt->format(NAN)); +?> +--EXPECT-- +string(3) "∞" +string(4) "-∞" +string(3) "NaN" diff --git a/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt b/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt new file mode 100644 index 000000000000..5b084b25d869 --- /dev/null +++ b/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt @@ -0,0 +1,53 @@ +--TEST-- +IntlGregorianCalendar::__construct(): out-of-bounds date/time arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #2 ($localeOrMonth) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #6 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/intl_iterator_current_invalid.phpt b/ext/intl/tests/intl_iterator_current_invalid.phpt new file mode 100644 index 000000000000..5276bee5baeb --- /dev/null +++ b/ext/intl/tests/intl_iterator_current_invalid.phpt @@ -0,0 +1,22 @@ +--TEST-- +IntlIterator::current() returns null when the iterator is not valid +--EXTENSIONS-- +intl +--FILE-- +getPartsIterator(); +var_dump($iterator->current()); + +$breakIterator = IntlBreakIterator::createWordInstance('en_US'); +$breakIterator->setText('foo'); +$iterator = $breakIterator->getPartsIterator(); +$iterator->rewind(); +$iterator->next(); +$iterator->next(); +var_dump($iterator->valid()); +var_dump($iterator->current()); +?> +--EXPECT-- +NULL +bool(false) +NULL diff --git a/ext/intl/tests/intlchar_reset_error.phpt b/ext/intl/tests/intlchar_reset_error.phpt new file mode 100644 index 000000000000..45f6d1df2961 --- /dev/null +++ b/ext/intl/tests/intlchar_reset_error.phpt @@ -0,0 +1,19 @@ +--TEST-- +IntlChar methods reset intl error on success +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/tests/listformatter/listformatter_double_ctor.phpt b/ext/intl/tests/listformatter/listformatter_double_ctor.phpt new file mode 100644 index 000000000000..f8b0ca1e1633 --- /dev/null +++ b/ext/intl/tests/listformatter/listformatter_double_ctor.phpt @@ -0,0 +1,16 @@ +--TEST-- +IntlListFormatter double construction should not be allowed +--EXTENSIONS-- +intl +--FILE-- +__construct('en_US'); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlListFormatter object is already constructed diff --git a/ext/intl/tests/listformatter/listformatter_get_error.phpt b/ext/intl/tests/listformatter/listformatter_get_error.phpt new file mode 100644 index 000000000000..a2a23b3473d2 --- /dev/null +++ b/ext/intl/tests/listformatter/listformatter_get_error.phpt @@ -0,0 +1,25 @@ +--TEST-- +IntlListFormatter getErrorCode()/getErrorMessage() reflect format() failures +--EXTENSIONS-- +intl +--FILE-- +format(["\x80"])); +var_dump($formatter->getErrorCode() === U_INVALID_CHAR_FOUND); +var_dump($formatter->getErrorMessage()); + +var_dump($formatter->format(['a', 'b'])); +var_dump($formatter->getErrorCode() === U_ZERO_ERROR); +var_dump($formatter->getErrorMessage()); + +?> +--EXPECT-- +bool(false) +bool(true) +string(85) "IntlListFormatter::format(): Failed to convert string to UTF-16: U_INVALID_CHAR_FOUND" +string(7) "a and b" +bool(true) +string(12) "U_ZERO_ERROR" diff --git a/ext/intl/tests/locale/bug74993.phpt b/ext/intl/tests/locale/bug74993.phpt index 1d0a1a97b75c..7bcf931c4e2b 100644 --- a/ext/intl/tests/locale/bug74993.phpt +++ b/ext/intl/tests/locale/bug74993.phpt @@ -5,6 +5,8 @@ intl --FILE-- --EXPECT-- +Function [ function locale_get_display_keyword ] { + + - Parameters [2] { + Parameter #0 [ string $keyword ] + Parameter #1 [ ?string $displayLocale = null ] + } + - Return [ string|false ] +} +Function [ function locale_get_display_keyword_value ] { + + - Parameters [3] { + Parameter #0 [ string $locale ] + Parameter #1 [ string $keyword ] + Parameter #2 [ ?string $displayLocale = null ] + } + - Return [ string|false ] +} Function [ function locale_get_display_language ] { - Parameters [2] { diff --git a/ext/intl/tests/locale_get_display_keyword.phpt b/ext/intl/tests/locale_get_display_keyword.phpt new file mode 100644 index 000000000000..9d53d7a02586 --- /dev/null +++ b/ext/intl/tests/locale_get_display_keyword.phpt @@ -0,0 +1,40 @@ +--TEST-- +locale_get_display_keyword() basic +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTREGEX-- +string\([1-9][0-9]*\) "[A-Za-z ]*Calendar[A-Za-z ]*" +bool\(true\) +string\([1-9][0-9]*\) "[A-Za-z ]*Gregorian[A-Za-z ]*" +bool\(true\) +string\([1-9][0-9]*\) "[A-Za-z ]*Phonebook[A-Za-z ]*" +string\([1-9][0-9]*\) "[A-Za-z ]*Calendar[A-Za-z ]*" +bool\(true\) +string\([1-9][0-9]*\) "[A-Za-z ]*Gregorian[A-Za-z ]*" +bool\(true\) +string\([1-9][0-9]*\) "[A-Za-z ]*Phonebook[A-Za-z ]*" diff --git a/ext/intl/tests/locale_get_display_keyword_error.phpt b/ext/intl/tests/locale_get_display_keyword_error.phpt new file mode 100644 index 000000000000..6f489ccfe8fa --- /dev/null +++ b/ext/intl/tests/locale_get_display_keyword_error.phpt @@ -0,0 +1,20 @@ +--TEST-- +locale_get_display_keyword_value() error path +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +string(73) "Locale::getDisplayKeywordValue(): name too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(75) "locale_get_display_keyword_value(): name too long: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/locale_get_display_keyword_null_bytes.phpt b/ext/intl/tests/locale_get_display_keyword_null_bytes.phpt new file mode 100644 index 000000000000..fe83ac1b731f --- /dev/null +++ b/ext/intl/tests/locale_get_display_keyword_null_bytes.phpt @@ -0,0 +1,40 @@ +--TEST-- +locale_get_display_keyword() throwing null bytes exceptions. +--EXTENSIONS-- +intl +--FILE-- + ut_loc_get_display_keyword("cur\0rency", "fr"), + fn() => ut_loc_get_display_keyword("currency", "f\0r"), + fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian\0", "calendar", "en"), + fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian", "cal\0endar", "en"), + fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian", "calendar", "e\0n"), + ]; + + foreach ($calls as $call) { + try { + $call(); + } catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; + } + } +} + +include_once 'ut_common.inc'; +ut_run(); +?> +--EXPECT-- +Locale::getDisplayKeyword(): Argument #1 ($keyword) must not contain any null bytes +Locale::getDisplayKeyword(): Argument #2 ($displayLocale) must not contain any null bytes +Locale::getDisplayKeywordValue(): Argument #1 ($locale) must not contain any null bytes +Locale::getDisplayKeywordValue(): Argument #2 ($keyword) must not contain any null bytes +Locale::getDisplayKeywordValue(): Argument #3 ($displayLocale) must not contain any null bytes +locale_get_display_keyword(): Argument #1 ($keyword) must not contain any null bytes +locale_get_display_keyword(): Argument #2 ($displayLocale) must not contain any null bytes +locale_get_display_keyword_value(): Argument #1 ($locale) must not contain any null bytes +locale_get_display_keyword_value(): Argument #2 ($keyword) must not contain any null bytes +locale_get_display_keyword_value(): Argument #3 ($displayLocale) must not contain any null bytes diff --git a/ext/intl/tests/locale_lookup_invalid_language_tag.phpt b/ext/intl/tests/locale_lookup_invalid_language_tag.phpt new file mode 100644 index 000000000000..3ba48f61334b --- /dev/null +++ b/ext/intl/tests/locale_lookup_invalid_language_tag.phpt @@ -0,0 +1,35 @@ +--TEST-- +Locale::lookup() returns null for invalid language tags +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; +} + +try { + locale_lookup([''], 'de-DE', false, 'en-US'); +} catch (IntlException $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +NULL +string(75) "Locale::lookup(): unable to canonicalize lang_tag: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(74) "locale_lookup(): unable to canonicalize lang_tag: U_ILLEGAL_ARGUMENT_ERROR" +Locale::lookup(): unable to canonicalize lang_tag +locale_lookup(): unable to canonicalize lang_tag diff --git a/ext/intl/tests/msgfmt_parse_int64_min_64.phpt b/ext/intl/tests/msgfmt_parse_int64_min_64.phpt new file mode 100644 index 000000000000..2d003667813c --- /dev/null +++ b/ext/intl/tests/msgfmt_parse_int64_min_64.phpt @@ -0,0 +1,26 @@ +--TEST-- +MessageFormatter::parse() with PHP_INT_MIN on 64-bit platform +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +parse('-9,223,372,036,854,775,808'); +var_dump($parsed); + +$parsed = MessageFormatter::parseMessage('en_US', '{0,number,integer}', '-9,223,372,036,854,775,808'); +var_dump($parsed); + +?> +--EXPECT-- +array(1) { + [0]=> + int(-9223372036854775808) +} +array(1) { + [0]=> + int(-9223372036854775808) +} diff --git a/ext/intl/tests/rangeformatter/rangeformatter_format_int64.phpt b/ext/intl/tests/rangeformatter/rangeformatter_format_int64.phpt new file mode 100644 index 000000000000..9cefbcfb1ea8 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_format_int64.phpt @@ -0,0 +1,27 @@ +--TEST-- +IntlNumberRangeFormatter::format() preserves int64 precision +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(9007199254740993, 9007199254740993); +var_dump(preg_replace('/[^0-9]/', '', $formatted)); +?> +--EXPECT-- +string(16) "9007199254740993" diff --git a/ext/intl/tests/resourcebundle_get_without_fallback.phpt b/ext/intl/tests/resourcebundle_get_without_fallback.phpt new file mode 100644 index 000000000000..9f9941227972 --- /dev/null +++ b/ext/intl/tests/resourcebundle_get_without_fallback.phpt @@ -0,0 +1,48 @@ +--TEST-- +ResourceBundle::get() rejects fallback results when fallback is disabled with correct error message +--EXTENSIONS-- +intl +--FILE-- +get('teststring', false)); + +$bundle = resourcebundle_create('en', $fixture); +echo debug(resourcebundle_get($bundle, 'teststring', false)); +?> +--EXPECTF-- +NULL + %i: ResourceBundle::get(): Cannot load element 'teststring' without fallback to %s: U_USING_%s_WARNING +NULL + %i: resourcebundle_get(): Cannot load element 'teststring' without fallback to %s: U_USING_%s_WARNING +--CLEAN-- + diff --git a/ext/intl/tests/spoofchecker_007.phpt b/ext/intl/tests/spoofchecker_007.phpt index b5fc5814ddf8..5f3dbb47f192 100644 --- a/ext/intl/tests/spoofchecker_007.phpt +++ b/ext/intl/tests/spoofchecker_007.phpt @@ -4,12 +4,6 @@ spoofchecker with restriction level intl --SKIPIF-- -getConstant("SINGLE_SCRIPT_RESTRICTIVE")) { - die("skip Incompatible ICU version"); - } -?> --FILE-- or SpoofChecker::USET_CASE_INSENSITIVE%s)) +Spoofchecker::setAllowedChars(): Argument #2 ($patternOptions) must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::CASE_INSENSITIVE%s)) Spoofchecker::setAllowedChars(): Argument #1 ($pattern) must be a valid regular expression character set pattern Spoofchecker::setAllowedChars(): Argument #1 ($pattern) must be a valid regular expression character set pattern diff --git a/ext/intl/tests/spoofchecker_double_ctor.phpt b/ext/intl/tests/spoofchecker_double_ctor.phpt new file mode 100644 index 000000000000..01dae5ab4bc5 --- /dev/null +++ b/ext/intl/tests/spoofchecker_double_ctor.phpt @@ -0,0 +1,18 @@ +--TEST-- +Spoofchecker double construction should not be allowed +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +__construct(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Spoofchecker object is already constructed diff --git a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt new file mode 100644 index 000000000000..56cc194991ee --- /dev/null +++ b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt @@ -0,0 +1,36 @@ +--TEST-- +Spoofchecker exposes restriction-level APIs on all supported ICU versions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getConstant("ASCII"); +$singleScriptRestrictive = $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE"); +$mixedNumbers = $r->getConstant("MIXED_NUMBERS"); + +var_dump($ascii !== false); +var_dump($singleScriptRestrictive !== false); +var_dump($mixedNumbers !== false); +var_dump(is_int($ascii)); +var_dump(is_int($singleScriptRestrictive)); +var_dump(is_int($mixedNumbers)); +var_dump($ascii !== $singleScriptRestrictive); +var_dump($ascii !== $mixedNumbers); +var_dump($singleScriptRestrictive !== $mixedNumbers); +var_dump($r->hasMethod("setRestrictionLevel")); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt index 6b7e9474755d..187be350f594 100644 --- a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt +++ b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt @@ -5,8 +5,6 @@ intl --SKIPIF-- --FILE-- getMessage(), PHP_EOL; + } +} + +$std = new stdClass(); +$calendar = IntlCalendar::createInstance(); +$formatter = new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE); + +dump_exception(fn() => intlcal_create_instance($std)); +dump_exception(fn() => IntlCalendar::createInstance($std)); +dump_exception(fn() => intlcal_set_time_zone($calendar, $std)); +dump_exception(fn() => $calendar->setTimeZone($std)); +dump_exception(fn() => new IntlGregorianCalendar($std)); +dump_exception(fn() => datefmt_create(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => IntlDateFormatter::create(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => datefmt_set_timezone($formatter, $std)); +dump_exception(fn() => $formatter->setTimeZone($std)); + +?> +--EXPECT-- +TypeError: intlcal_create_instance(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlCalendar::createInstance(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: intlcal_set_time_zone(): Argument #2 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlCalendar::setTimeZone(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) Object of class stdClass could not be converted to string +TypeError: datefmt_create(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::create(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::__construct(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: datefmt_set_timezone(): Argument #2 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::setTimeZone(): Argument #1 ($timezone) Object of class stdClass could not be converted to string diff --git a/ext/intl/tests/timezone_getDisplayName_error.phpt b/ext/intl/tests/timezone_getDisplayName_error.phpt index ca845b2830ed..032b22e50908 100644 --- a/ext/intl/tests/timezone_getDisplayName_error.phpt +++ b/ext/intl/tests/timezone_getDisplayName_error.phpt @@ -8,8 +8,12 @@ intl $tz = IntlTimeZone::createTimeZone('Europe/Lisbon'); var_dump($tz->getDisplayName(false, -1)); echo intl_get_error_message(), PHP_EOL; +var_dump($tz->getErrorCode()); +echo $tz->getErrorMessage(), PHP_EOL; ?> --EXPECT-- bool(false) IntlTimeZone::getDisplayName(): wrong display type: U_ILLEGAL_ARGUMENT_ERROR +int(1) +IntlTimeZone::getDisplayName(): wrong display type: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/transliterator_transliterate_error.phpt b/ext/intl/tests/transliterator_transliterate_error.phpt index e11de9333d4c..61190abc6d33 100644 --- a/ext/intl/tests/transliterator_transliterate_error.phpt +++ b/ext/intl/tests/transliterator_transliterate_error.phpt @@ -9,17 +9,38 @@ intl.use_exceptions=true $tr = Transliterator::create("latin"); -try { - var_dump(transliterator_transliterate($tr, "str", 7)); -} catch (Throwable $e) { - echo $e::class, ': ', $e->getMessage(), PHP_EOL; +function dump_throwable(callable $callback): void { + try { + $callback(); + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + } } -try { +//Arguments +dump_throwable(function() use ($tr) { + var_dump(transliterator_transliterate($tr, "str", 7)); +}); + +dump_throwable(function() use ($tr) { transliterator_transliterate($tr, "str", 7, 6); -} catch (Throwable $e) { - echo $e::class, ': ', $e->getMessage(), PHP_EOL; -} +}); + +dump_throwable(function() use ($tr) { + transliterator_transliterate($tr, "str", 0, -2); +}); + +dump_throwable(function() use ($tr) { + transliterator_transliterate($tr, "str", -1); +}); + +dump_throwable(function() { + transliterator_transliterate("latin", "str", -1); +}); + +dump_throwable(function() use ($tr) { + $tr->transliterate("str", 7, 6); +}); //bad UTF-8 try { @@ -31,5 +52,9 @@ try { ?> --EXPECT-- IntlException: transliterator_transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) -ValueError: transliterator_transliterate(): Argument #2 ($string) must be less than or equal to argument #3 ($end) +ValueError: transliterator_transliterate(): Argument #3 ($start) must be less than or equal to argument #4 ($end) +ValueError: transliterator_transliterate(): Argument #4 ($end) must be greater than or equal to -1 +ValueError: transliterator_transliterate(): Argument #3 ($start) must be greater than or equal to 0 +ValueError: transliterator_transliterate(): Argument #3 ($start) must be greater than or equal to 0 +ValueError: Transliterator::transliterate(): Argument #2 ($start) must be less than or equal to argument #3 ($end) IntlException: transliterator_transliterate(): String conversion of string to UTF-16 failed diff --git a/ext/intl/tests/uconverter_transcode_subst_length.phpt b/ext/intl/tests/uconverter_transcode_subst_length.phpt new file mode 100644 index 000000000000..93001b16680c --- /dev/null +++ b/ext/intl/tests/uconverter_transcode_subst_length.phpt @@ -0,0 +1,20 @@ +--TEST-- +UConverter::transcode() rejects too long substitution strings +--EXTENSIONS-- +intl +--INI-- +intl.use_exceptions=false +--FILE-- + $subst])); +echo intl_get_error_message(), "\n"; +var_dump(UConverter::transcode('abc', 'UTF-8', 'ASCII', ['to_subst' => $subst])); +echo intl_get_error_message(), "\n"; +?> +--EXPECT-- +bool(false) +UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +bool(false) +UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/ut_common.inc b/ext/intl/tests/ut_common.inc index fdc013dea41c..26f33f75f7fe 100644 --- a/ext/intl/tests/ut_common.inc +++ b/ext/intl/tests/ut_common.inc @@ -272,6 +272,14 @@ function ut_loc_get_display_variant( $locale , $dispLocale ) { return $GLOBALS['oo-mode'] ? Locale::getDisplayVariant( $locale , $dispLocale ) : locale_get_display_variant( $locale, $dispLocale ); } +function ut_loc_get_display_keyword( $keyword , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayKeyword( $keyword , $dispLocale ) : locale_get_display_keyword( $keyword, $dispLocale ); +} +function ut_loc_get_display_keyword_value( $locale , $keyword , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayKeywordValue( $locale , $keyword , $dispLocale ) : locale_get_display_keyword_value( $locale, $keyword, $dispLocale ); +} function ut_loc_locale_compose( $loc_parts_arr ) { return $GLOBALS['oo-mode'] ? Locale::composeLocale( $loc_parts_arr ) : locale_compose( $loc_parts_arr ); diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index c613edf5585f..23b5511cf361 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -121,7 +121,7 @@ static void timezone_throw_exception_with_call_location(const char *msg, const c /* {{{ timezone_process_timezone_argument * TimeZone argument processor. outside_error may be nullptr (for static functions/constructors) */ U_CFUNC TimeZone *timezone_process_timezone_argument( - zend_object *timezone_object, zend_string *timezone_string, intl_error *outside_error) + zend_object *timezone_object, zend_string *timezone_string, intl_error *outside_error, uint32_t arg_num) { std::unique_ptr timeZone; bool free_string = false; @@ -160,8 +160,9 @@ U_CFUNC TimeZone *timezone_process_timezone_argument( free_string = true; } else { if (!EG(exception)) { - // TODO Proper type error - zend_throw_error(nullptr, "Object of class %s could not be converted to string", ZSTR_VAL(timezone_object->ce->name)); + zend_argument_type_error(arg_num, + "Object of class %s could not be converted to string", + ZSTR_VAL(timezone_object->ce->name)); } return nullptr; } @@ -206,7 +207,7 @@ U_CFUNC TimeZone *timezone_process_timezone_argument( /* {{{ clone handler for TimeZone */ static zend_object *TimeZone_clone_obj(zend_object *object) { - TimeZone_object *to_orig = php_intl_timezone_fetch_object(object); + const TimeZone_object *to_orig = php_intl_timezone_fetch_object(object); zend_object *ret_val = TimeZone_ce_ptr->create_object(object->ce); TimeZone_object *to_new = php_intl_timezone_fetch_object(ret_val); @@ -291,7 +292,7 @@ static HashTable *TimeZone_get_debug_info(zend_object *object, int *is_temp) zend_hash_str_update(debug_info, "id", sizeof("id") - 1, &zv); int32_t rawOffset, dstOffset; - UDate now = Calendar::getNow(); + const UDate now = Calendar::getNow(); tz->getOffset(now, false, rawOffset, dstOffset, uec); if (U_FAILURE(uec)) { return debug_info; @@ -357,7 +358,7 @@ U_CFUNC void timezone_register_IntlTimeZone_class(void) memcpy(&TimeZone_handlers, &std_object_handlers, sizeof TimeZone_handlers); - TimeZone_handlers.offset = XtOffsetOf(TimeZone_object, zo); + TimeZone_handlers.offset = offsetof(TimeZone_object, zo); TimeZone_handlers.clone_obj = TimeZone_clone_obj; TimeZone_handlers.compare = TimeZone_compare_objects; TimeZone_handlers.get_debug_info = TimeZone_get_debug_info; diff --git a/ext/intl/timezone/timezone_class.h b/ext/intl/timezone/timezone_class.h index bbfd8adcae23..cb74709c965a 100644 --- a/ext/intl/timezone/timezone_class.h +++ b/ext/intl/timezone/timezone_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -46,9 +46,7 @@ typedef struct { zend_object zo; } TimeZone_object; -static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) { - return (TimeZone_object *)((char*)(obj) - XtOffsetOf(TimeZone_object, zo)); -} +#define php_intl_timezone_fetch_object(obj) ZEND_CONTAINER_OF(obj, TimeZone_object, zo) #define Z_INTL_TIMEZONE_P(zv) php_intl_timezone_fetch_object(Z_OBJ_P(zv)) #define TIMEZONE_ERROR(to) (to)->err @@ -67,7 +65,7 @@ static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) } zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, zval *ret); -TimeZone *timezone_process_timezone_argument(zend_object *timezone_object, zend_string *timezone_string, intl_error *error); +TimeZone *timezone_process_timezone_argument(zend_object *timezone_object, zend_string *timezone_string, intl_error *error, uint32_t arg_num); void timezone_object_construct(const TimeZone *zone, zval *object, int owned); diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index 3de186a9ca03..c2246c5406b1 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -176,7 +176,7 @@ U_CFUNC PHP_FUNCTION(intltz_count_equivalent_ids) RETURN_FALSE; } - int32_t result = TimeZone::countEquivalentIDs(id); + const int32_t result = TimeZone::countEquivalentIDs(id); RETURN_LONG((zend_long)result); } @@ -279,7 +279,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_region) RETURN_FALSE; } - int32_t region_len = TimeZone::getRegion(id, outbuf, sizeof(outbuf), status); + const int32_t region_len = TimeZone::getRegion(id, outbuf, sizeof(outbuf), status); INTL_CHECK_STATUS(status, "error obtaining region"); RETURN_STRINGL(outbuf, region_len); @@ -483,13 +483,16 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) RETURN_THROWS(); } + TIMEZONE_METHOD_FETCH_OBJECT; + bool found = false; for (int i = 0; !found && i < sizeof(display_types)/sizeof(*display_types); i++) { if (display_types[i] == display_type) found = true; } if (!found) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "wrong display type"); + intl_errors_set(TIMEZONE_ERROR_P(to), U_ILLEGAL_ARGUMENT_ERROR, + "wrong display type"); RETURN_FALSE; } @@ -497,8 +500,6 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) locale_str = intl_locale_get_default(); } - TIMEZONE_METHOD_FETCH_OBJECT; - UnicodeString result; to->utimezone->getDisplayName((UBool)daylight, (TimeZone::EDisplayType)display_type, Locale::createFromName(locale_str), result); diff --git a/ext/intl/transliterator/transliterator.h b/ext/intl/transliterator/transliterator.h index f98ca0682965..2a86eb6781be 100644 --- a/ext/intl/transliterator/transliterator.h +++ b/ext/intl/transliterator/transliterator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/transliterator/transliterator_class.cpp b/ext/intl/transliterator/transliterator_class.cpp index fd0cd4f3c3e6..737c51fcf4dd 100644 --- a/ext/intl/transliterator/transliterator_class.cpp +++ b/ext/intl/transliterator/transliterator_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -80,7 +80,7 @@ static void transliterator_object_init( Transliterator_object* to ) /* }}} */ /* {{{ void transliterator_object_destroy( Transliterator_object* to ) - * Clean up mem allocted by internals of Transliterator_object + * Clean up mem allocated by internals of Transliterator_object */ static void transliterator_object_destroy( Transliterator_object* to ) { @@ -130,7 +130,7 @@ static zend_object *Transliterator_object_create( zend_class_entry *ce ) /* {{{ clone handler for Transliterator */ static zend_object *Transliterator_clone_obj( zend_object *object ) { - Transliterator_object *to_orig = php_intl_transliterator_fetch_object(object); + const Transliterator_object *to_orig = php_intl_transliterator_fetch_object(object); zend_object *ret_val = Transliterator_ce_ptr->create_object(object->ce); Transliterator_object *to_new = php_intl_transliterator_fetch_object(ret_val); @@ -167,7 +167,7 @@ U_CFUNC void transliterator_register_Transliterator_class( void ) Transliterator_ce_ptr->create_object = Transliterator_object_create; Transliterator_ce_ptr->default_object_handlers = &Transliterator_handlers; memcpy( &Transliterator_handlers, &std_object_handlers, sizeof Transliterator_handlers ); - Transliterator_handlers.offset = XtOffsetOf(Transliterator_object, zo); + Transliterator_handlers.offset = offsetof(Transliterator_object, zo); Transliterator_handlers.free_obj = Transliterator_objects_free; Transliterator_handlers.clone_obj = Transliterator_clone_obj; } diff --git a/ext/intl/transliterator/transliterator_class.h b/ext/intl/transliterator/transliterator_class.h index 7e02d6fa5e28..1bdcd60eadc5 100644 --- a/ext/intl/transliterator/transliterator_class.h +++ b/ext/intl/transliterator/transliterator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -38,9 +38,7 @@ typedef struct { zend_object zo; } Transliterator_object; -static inline Transliterator_object *php_intl_transliterator_fetch_object(zend_object *obj) { - return (Transliterator_object *)((char*)(obj) - XtOffsetOf(Transliterator_object, zo)); -} +#define php_intl_transliterator_fetch_object(obj) ZEND_CONTAINER_OF(obj, Transliterator_object, zo) #define Z_INTL_TRANSLITERATOR_P(zv) php_intl_transliterator_fetch_object(Z_OBJ_P(zv)) #define TRANSLITERATOR_FORWARD UTRANS_FORWARD diff --git a/ext/intl/transliterator/transliterator_methods.cpp b/ext/intl/transliterator/transliterator_methods.cpp index d8a8cbb7a49e..9cdec2611a24 100644 --- a/ext/intl/transliterator/transliterator_methods.cpp +++ b/ext/intl/transliterator/transliterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | 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. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -21,6 +21,8 @@ #include #endif +#include + extern "C" { #include "php_intl.h" #include "intl_data.h" @@ -31,7 +33,7 @@ extern "C" { #include -static int create_transliterator( char *str_id, size_t str_id_len, zend_long direction, zval *object ) +static int create_transliterator( const char *str_id, size_t str_id_len, zend_long direction, zval *object ) { Transliterator_object *to; UChar *ustr_id = nullptr; @@ -226,6 +228,7 @@ U_CFUNC PHP_FUNCTION( transliterator_list_ids ) UEnumeration *en; const UChar *elem; int32_t elem_len; + int32_t count; UErrorCode status = U_ZERO_ERROR; intl_error_reset( nullptr ); @@ -236,7 +239,14 @@ U_CFUNC PHP_FUNCTION( transliterator_list_ids ) INTL_CHECK_STATUS( status, "Failed to obtain registered transliterators" ); - array_init( return_value ); + count = uenum_count( en, &status ); + if( U_FAILURE( status ) ) + { + count = 0; + status = U_ZERO_ERROR; + } + + array_init_size( return_value, count ); while( (elem = uenum_unext( en, &elem_len, &status )) ) { zend_string *el = intl_convert_utf16_to_utf8(elem, elem_len, &status ); @@ -276,14 +286,16 @@ U_CFUNC PHP_FUNCTION( transliterator_transliterate ) zend_long start = 0, limit = -1; int success = 0; + bool is_method; zval tmp_object; TRANSLITERATOR_METHOD_INIT_VARS; object = getThis(); + is_method = object != NULL; ZVAL_UNDEF(&tmp_object); - if (object == nullptr) { + if (!is_method) { /* in non-OOP version, accept both a transliterator and a string */ zend_string *arg1_str; zend_object *arg1_obj; @@ -319,18 +331,18 @@ U_CFUNC PHP_FUNCTION( transliterator_transliterate ) RETURN_THROWS(); } - if (limit < -1) { - zend_argument_value_error(object ? 3 : 4, "must be greater than or equal to -1"); + if (UNEXPECTED(limit < -1)) { + zend_argument_value_error(is_method ? 3 : 4, "must be greater than or equal to -1"); goto cleanup_object; } - if (start < 0) { - zend_argument_value_error(object ? 2 : 3, "must be greater than or equal to 0"); + if (UNEXPECTED(start < 0)) { + zend_argument_value_error(is_method ? 2 : 3, "must be greater than or equal to 0"); goto cleanup_object; } - if (limit != -1 && start > limit) { - zend_argument_value_error(object ? 2 : 3, "must be less than or equal to argument #%d ($end)", object ? 3 : 4); + if (UNEXPECTED(limit != -1 && start > limit)) { + zend_argument_value_error(is_method ? 2 : 3, "must be less than or equal to argument #%d ($end)", is_method ? 3 : 4); goto cleanup_object; } @@ -343,7 +355,7 @@ U_CFUNC PHP_FUNCTION( transliterator_transliterate ) /* we've started allocating resources, goto from now on */ - if( ( start > ustr_len ) || (( limit != -1 ) && (limit > ustr_len ) ) ) + if (UNEXPECTED((start > ustr_len) || ((limit != -1) && (limit > ustr_len)))) { char *msg; spprintf( &msg, 0, diff --git a/ext/intl/uchar/uchar.cpp b/ext/intl/uchar/uchar.cpp index f1f777f0ea3e..80bdd2bdb9fa 100644 --- a/ext/intl/uchar/uchar.cpp +++ b/ext/intl/uchar/uchar.cpp @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + extern "C" { #include "uchar.h" #include "intl_data.h" @@ -11,26 +25,26 @@ extern "C" { #define IC_METHOD(mname) PHP_METHOD(IntlChar, mname) -static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_long int_codepoint) { +static inline int convert_cp(UChar32* pcp, const zend_string *string_codepoint, zend_long int_codepoint) { if (string_codepoint != NULL) { int32_t i = 0; - size_t string_codepoint_length = ZSTR_LEN(string_codepoint); + const size_t string_codepoint_length = ZSTR_LEN(string_codepoint); - if (ZEND_SIZE_T_INT_OVFL(string_codepoint_length)) { + if (UNEXPECTED(ZEND_SIZE_T_INT_OVFL(string_codepoint_length))) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "Input string is too long."); return FAILURE; } U8_NEXT(ZSTR_VAL(string_codepoint), i, string_codepoint_length, int_codepoint); - if ((size_t)i != string_codepoint_length) { + if (UNEXPECTED((size_t)i != string_codepoint_length)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "Passing a UTF-8 character for codepoint requires a string which is exactly one UTF-8 codepoint long."); return FAILURE; } } - if ((int_codepoint < UCHAR_MIN_VALUE) || (int_codepoint > UCHAR_MAX_VALUE)) { + if (UNEXPECTED((int_codepoint < UCHAR_MIN_VALUE) || (int_codepoint > UCHAR_MAX_VALUE))) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "Codepoint out of range"); return FAILURE; @@ -56,6 +70,8 @@ IC_METHOD(chr) { char buffer[5]; int buffer_len = 0; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -75,6 +91,8 @@ IC_METHOD(chr) { IC_METHOD(ord) { UChar32 cp; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -90,6 +108,8 @@ IC_METHOD(hasBinaryProperty) { zend_string *string_codepoint; zend_long int_codepoint = 0; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) Z_PARAM_LONG(prop) @@ -110,6 +130,8 @@ IC_METHOD(getIntPropertyValue) { zend_string *string_codepoint; zend_long int_codepoint = 0; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) Z_PARAM_LONG(prop) @@ -127,6 +149,8 @@ IC_METHOD(getIntPropertyValue) { IC_METHOD(getIntPropertyMinValue) { zend_long prop; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(prop) ZEND_PARSE_PARAMETERS_END(); @@ -139,6 +163,8 @@ IC_METHOD(getIntPropertyMinValue) { IC_METHOD(getIntPropertyMaxValue) { zend_long prop; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(prop) ZEND_PARSE_PARAMETERS_END(); @@ -151,6 +177,8 @@ IC_METHOD(getIntPropertyMaxValue) { IC_METHOD(getNumericValue) { UChar32 cp; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -193,6 +221,8 @@ static UBool enumCharType_callback(enumCharType_data *context, IC_METHOD(enumCharTypes) { enumCharType_data context; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_FUNC(context.fci, context.fci_cache) ZEND_PARSE_PARAMETERS_END(); @@ -204,6 +234,8 @@ IC_METHOD(enumCharTypes) { IC_METHOD(getBlockCode) { UChar32 cp; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -222,6 +254,8 @@ IC_METHOD(charName) { zend_string *buffer = NULL; int32_t buffer_len; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) Z_PARAM_OPTIONAL @@ -252,6 +286,8 @@ IC_METHOD(charFromName) { UChar32 ret; UErrorCode error = U_ZERO_ERROR; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STRING(name, name_len) Z_PARAM_OPTIONAL @@ -303,6 +339,7 @@ IC_METHOD(enumCharNames) { zend_long nameChoice = U_UNICODE_CHAR_NAME; UErrorCode error = U_ZERO_ERROR; + intl_error_reset(NULL); ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_STR_OR_LONG(string_start, int_start) @@ -328,6 +365,8 @@ IC_METHOD(getPropertyName) { zend_long nameChoice = U_LONG_PROPERTY_NAME; const char *ret; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_LONG(property) Z_PARAM_OPTIONAL @@ -350,6 +389,8 @@ IC_METHOD(getPropertyEnum) { char *alias; size_t alias_len; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STRING(alias, alias_len) ZEND_PARSE_PARAMETERS_END(); @@ -363,6 +404,8 @@ IC_METHOD(getPropertyValueName) { zend_long property, value, nameChoice = U_LONG_PROPERTY_NAME; const char *ret; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_LONG(property) Z_PARAM_LONG(value) @@ -387,6 +430,8 @@ IC_METHOD(getPropertyValueEnum) { char *name; size_t name_len; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_LONG(property) Z_PARAM_STRING(name, name_len) @@ -403,6 +448,8 @@ IC_METHOD(foldCase) { zend_string *string_codepoint; zend_long int_codepoint = 0; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) Z_PARAM_OPTIONAL @@ -434,6 +481,8 @@ IC_METHOD(digit) { zend_string *string_codepoint; zend_long int_codepoint = 0; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) Z_PARAM_OPTIONAL @@ -458,6 +507,8 @@ IC_METHOD(digit) { IC_METHOD(forDigit) { zend_long digit, radix = 10; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_LONG(digit) Z_PARAM_OPTIONAL @@ -474,6 +525,8 @@ IC_METHOD(charAge) { UVersionInfo version; int i; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -491,6 +544,8 @@ IC_METHOD(getUnicodeVersion) { UVersionInfo version; int i; + intl_error_reset(NULL); + ZEND_PARSE_PARAMETERS_NONE(); u_getUnicodeVersion(version); @@ -509,6 +564,8 @@ IC_METHOD(getFC_NFKC_Closure) { int32_t closure_len; UErrorCode error = U_ZERO_ERROR; + intl_error_reset(NULL); + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { RETURN_NULL(); } @@ -527,8 +584,8 @@ IC_METHOD(getFC_NFKC_Closure) { error = U_ZERO_ERROR; u8str = intl_convert_utf16_to_utf8(closure, closure_len, &error); - INTL_CHECK_STATUS(error, "Failed converting output to UTF8"); efree(closure); + INTL_CHECK_STATUS(error, "Failed converting output to UTF8"); RETVAL_NEW_STR(u8str); } /* }}} */ @@ -537,6 +594,7 @@ IC_METHOD(getFC_NFKC_Closure) { #define IC_BOOL_METHOD_CHAR(name) \ IC_METHOD(name) { \ UChar32 cp; \ + intl_error_reset(NULL); \ if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ RETURN_NULL(); \ } \ @@ -577,6 +635,7 @@ IC_BOOL_METHOD_CHAR(isJavaIDPart) #define IC_INT_METHOD_CHAR(name) \ IC_METHOD(name) { \ UChar32 cp; \ + intl_error_reset(NULL); \ if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ RETURN_NULL(); \ } \ @@ -597,6 +656,7 @@ IC_METHOD(name) { \ UChar32 cp, ret; \ zend_string *string_codepoint; \ zend_long int_codepoint = -1; \ + intl_error_reset(NULL); \ ZEND_PARSE_PARAMETERS_START(1, 1) \ Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) \ ZEND_PARSE_PARAMETERS_END(); \ diff --git a/ext/intl/uchar/uchar.h b/ext/intl/uchar/uchar.h index 25bab1f2156f..7b472163ab0f 100644 --- a/ext/intl/uchar/uchar.h +++ b/ext/intl/uchar/uchar.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + #ifndef incl_PHP_INTL_UCHAR_H #define incl_PHP_INTL_UCHAR_H diff --git a/ext/json/config.m4 b/ext/json/config.m4 index 5697dbff8d2f..a3ae54a7ac23 100644 --- a/ext/json/config.m4 +++ b/ext/json/config.m4 @@ -4,8 +4,7 @@ PHP_NEW_EXTENSION([json], m4_normalize([ json_scanner.c json.c ]), - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) PHP_INSTALL_HEADERS([ext/json], m4_normalize([ php_json_parser.h php_json_scanner.h diff --git a/ext/json/config.w32 b/ext/json/config.w32 index 84f77b6f8c9c..9d9a37df08a8 100644 --- a/ext/json/config.w32 +++ b/ext/json/config.w32 @@ -1,6 +1,6 @@ // vim:ft=javascript -EXTENSION('json', 'json.c', false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION('json', 'json.c', false /* never shared */); PHP_JSON="yes"; ADD_SOURCES(configure_module_dirname, "json_encoder.c json_parser.tab.c json_scanner.c", "json"); diff --git a/ext/json/json.c b/ext/json/json.c index 079f67a5c400..04a62f52152f 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -62,18 +60,14 @@ static PHP_GINIT_FUNCTION(json) ZEND_TSRMLS_CACHE_UPDATE(); #endif json_globals->encoder_depth = 0; - json_globals->error_code = 0; - json_globals->error_line = 0; - json_globals->error_column = 0; + php_json_error_details_clear(&json_globals->error_details); json_globals->encode_max_depth = PHP_JSON_PARSER_DEFAULT_DEPTH; } /* }}} */ static PHP_RINIT_FUNCTION(json) { - JSON_G(error_code) = 0; - JSON_G(error_line) = 0; - JSON_G(error_column) = 0; + php_json_error_details_clear(&JSON_G(error_details)); return SUCCESS; } @@ -136,7 +130,11 @@ PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int optio encoder.max_depth = depth; return_code = php_json_encode_zval(buf, val, options, &encoder); - JSON_G(error_code) = encoder.error_code; + JSON_G(error_details) = (php_json_error_details){ + .code = encoder.error_code, + .line = 0, + .column = 0, + }; return return_code; } @@ -181,12 +179,12 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ -static zend_string *php_json_get_error_msg_with_location(php_json_error_code error_code, size_t line, size_t column) /* {{{ */ +static zend_string *php_json_get_error_msg_with_location(const php_json_error_details *details) /* {{{ */ { - const char *base_msg = php_json_get_error_msg(error_code); + const char *base_msg = php_json_get_error_msg(details->code); - if (line > 0 && column > 0) { - return zend_strpprintf(0, "%s near location %zu:%zu", base_msg, line, column); + if (details->line > 0 && details->column > 0) { + return zend_strpprintf(0, "%s near location %" PRIu64 ":%" PRIu64, base_msg, details->line, details->column); } return zend_string_init(base_msg, strlen(base_msg), 0); @@ -200,17 +198,14 @@ PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, php_json_parser_init(&parser, return_value, str, str_len, (int)options, (int)depth); if (php_json_yyparse(&parser)) { - php_json_error_code error_code = php_json_parser_error_code(&parser); - size_t error_line = php_json_parser_error_line(&parser); - size_t error_column = php_json_parser_error_column(&parser); + php_json_error_details details; + php_json_parser_error_details(&parser, &details); if (!(options & PHP_JSON_THROW_ON_ERROR)) { - JSON_G(error_code) = error_code; - JSON_G(error_line) = error_line; - JSON_G(error_column) = error_column; + JSON_G(error_details) = details; } else { - zend_string *error_msg = php_json_get_error_msg_with_location(error_code, error_line, error_column); - zend_throw_exception(php_json_exception_ce, ZSTR_VAL(error_msg), error_code); + zend_string *error_msg = php_json_get_error_msg_with_location(&details); + zend_throw_exception(php_json_exception_ce, ZSTR_VAL(error_msg), details.code); zend_string_release(error_msg); } RETVAL_NULL(); @@ -230,13 +225,8 @@ PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_lon php_json_parser_init_ex(&parser, &tmp, str, str_len, (int)options, (int)depth, parser_validate_methods); if (php_json_yyparse(&parser)) { - php_json_error_code error_code = php_json_parser_error_code(&parser); - size_t error_line = php_json_parser_error_line(&parser); - size_t error_column = php_json_parser_error_column(&parser); + php_json_parser_error_details(&parser, &JSON_G(error_details)); - JSON_G(error_code) = error_code; - JSON_G(error_line) = error_line; - JSON_G(error_column) = error_column; return false; } @@ -265,7 +255,12 @@ PHP_FUNCTION(json_encode) php_json_encode_zval(&buf, parameter, (int)options, &encoder); if (!(options & PHP_JSON_THROW_ON_ERROR) || (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { - JSON_G(error_code) = encoder.error_code; + JSON_G(error_details) = (php_json_error_details){ + .code = encoder.error_code, + .line = 0, + .column = 0, + }; + if (encoder.error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { smart_str_free(&buf); RETURN_FALSE; @@ -301,16 +296,16 @@ PHP_FUNCTION(json_decode) ZEND_PARSE_PARAMETERS_END(); if (!(options & PHP_JSON_THROW_ON_ERROR)) { - JSON_G(error_code) = PHP_JSON_ERROR_NONE; - JSON_G(error_line) = 0; - JSON_G(error_column) = 0; + php_json_error_details_clear(&JSON_G(error_details)); } if (!str_len) { if (!(options & PHP_JSON_THROW_ON_ERROR)) { - JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; - JSON_G(error_line) = 0; - JSON_G(error_column) = 0; + JSON_G(error_details) = (php_json_error_details){ + .code = PHP_JSON_ERROR_SYNTAX, + .line = 0, + .column = 0, + }; } else { zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(PHP_JSON_ERROR_SYNTAX), PHP_JSON_ERROR_SYNTAX); } @@ -362,15 +357,16 @@ PHP_FUNCTION(json_validate) } if (!str_len) { - JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; - JSON_G(error_line) = 0; - JSON_G(error_column) = 0; + JSON_G(error_details) = (php_json_error_details){ + .code = PHP_JSON_ERROR_SYNTAX, + .line = 0, + .column = 0, + }; + RETURN_FALSE; } - JSON_G(error_code) = PHP_JSON_ERROR_NONE; - JSON_G(error_line) = 0; - JSON_G(error_column) = 0; + php_json_error_details_clear(&JSON_G(error_details)); if (depth <= 0) { zend_argument_value_error(2, "must be greater than 0"); @@ -391,7 +387,7 @@ PHP_FUNCTION(json_last_error) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_LONG(JSON_G(error_code)); + RETURN_LONG(JSON_G(error_details).code); } /* }}} */ @@ -400,10 +396,6 @@ PHP_FUNCTION(json_last_error_msg) { ZEND_PARSE_PARAMETERS_NONE(); - RETVAL_STR(php_json_get_error_msg_with_location( - JSON_G(error_code), - JSON_G(error_line), - JSON_G(error_column) - )); + RETURN_STR(php_json_get_error_msg_with_location(&JSON_G(error_details))); } /* }}} */ diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 186485c05c6f..22af1c15a833 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -54,6 +52,7 @@ static inline void php_json_pretty_print_char(smart_str *buf, int options, char static inline void php_json_pretty_print_indent(smart_str *buf, int options, const php_json_encoder *encoder) /* {{{ */ { if (options & PHP_JSON_PRETTY_PRINT) { + smart_str_alloc(buf, encoder->depth * 4, 0); for (int i = 0; i < encoder->depth; ++i) { smart_str_appendl(buf, " ", 4); } @@ -578,6 +577,11 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zend_obje ZEND_GUARD_PROTECT_RECURSION(guard, JSON); + /* jsonSerialize() may drop the last reference to the object, e.g. by + * nulling a reference that aliases the encoded array slot; keep it alive + * so the recursion guard and the identity check below stay valid. */ + GC_ADDREF(obj); + zend_function *json_serialize_method = zend_hash_str_find_ptr(&ce->function_table, ZEND_STRL("jsonserialize")); ZEND_ASSERT(json_serialize_method != NULL && "This should be guaranteed prior to calling this function"); zend_call_known_function(json_serialize_method, obj, ce, &retval, 0, NULL, NULL); @@ -587,6 +591,7 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zend_obje smart_str_appendl(buf, "null", 4); } ZEND_GUARD_UNPROTECT_RECURSION(guard, JSON); + OBJ_RELEASE(obj); return FAILURE; } @@ -601,6 +606,7 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zend_obje } zval_ptr_dtor(&retval); + OBJ_RELEASE(obj); return return_code; } diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index 2fd4edfe3693..0fd3e2c4e364 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -2,15 +2,13 @@ %code top { /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -41,7 +39,6 @@ int json_yydebug = 1; } -%locations %define api.prefix {php_json_yy} %define api.pure full %param { php_json_parser *parser } @@ -66,8 +63,8 @@ int json_yydebug = 1; %destructor { zval_ptr_dtor_nogc(&$$); } %code { -static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser); -static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg); +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); +static void php_json_yyerror(php_json_parser *parser, char const *msg); static int php_json_parser_array_create(php_json_parser *parser, zval *array); static int php_json_parser_object_create(php_json_parser *parser, zval *array); @@ -277,7 +274,7 @@ static int php_json_parser_object_update_validate(php_json_parser *parser, zval return SUCCESS; } -static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser) +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) { int token = php_json_scan(&parser->scanner); @@ -293,15 +290,10 @@ static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_pars value->value = parser->scanner.value; } - location->first_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_column); - location->first_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_line); - location->last_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_column); - location->last_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_line); - return token; } -static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg) +static void php_json_yyerror(php_json_parser *parser, char const *msg) { if (!parser->scanner.errcode) { parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; @@ -313,14 +305,28 @@ PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parse return parser->scanner.errcode; } -PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser) +static uint64_t php_json_compute_error_column(const php_json_scanner *s) { - return parser->scanner.errloc.first_line; + const php_json_ctype *p = s->line_start; + const php_json_ctype *end = s->token; + /* Count characters from the start of the line to the failing token, + * folding UTF-8 continuation bytes into their leading byte. */ + uint64_t column = 1; + + while (p < end) { + if ((*p & 0b11000000) != 0b10000000) { + column++; + } + p++; + } + return column; } -PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser) +PHP_JSON_API void php_json_parser_error_details(const php_json_parser *parser, php_json_error_details *out) { - return parser->scanner.errloc.first_column; + out->code = parser->scanner.errcode; + out->line = parser->scanner.line; + out->column = php_json_compute_error_column(&parser->scanner); } static const php_json_parser_methods default_parser_methods = diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index d6eaaf65b2e1..be62875a00e0 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -53,7 +51,6 @@ #define PHP_JSON_INT_MAX_LENGTH (MAX_LENGTH_OF_LONG - 1) #define PHP_JSON_TOKEN_LENGTH() ((size_t) (s->cursor - s->token)) -#define PHP_JSON_TOKEN_LOCATION(location) (s)->errloc.location static void php_json_scanner_copy_string(php_json_scanner *s, size_t esc_size) { @@ -98,10 +95,8 @@ void php_json_scanner_init(php_json_scanner *s, const char *str, size_t str_len, s->cursor = (php_json_ctype *) str; s->limit = (php_json_ctype *) str + str_len; s->options = options; - PHP_JSON_TOKEN_LOCATION(first_column) = 1; - PHP_JSON_TOKEN_LOCATION(first_line) = 1; - PHP_JSON_TOKEN_LOCATION(last_column) = 1; - PHP_JSON_TOKEN_LOCATION(last_line) = 1; + s->line = 1; + s->line_start = (php_json_ctype *) str; PHP_JSON_CONDITION_SET(JS); } @@ -110,8 +105,6 @@ int php_json_scan(php_json_scanner *s) ZVAL_NULL(&s->value); std: - PHP_JSON_TOKEN_LOCATION(first_column) = s->errloc.last_column; - PHP_JSON_TOKEN_LOCATION(first_line) = s->errloc.last_line; s->token = s->cursor; /*!re2c @@ -157,49 +150,27 @@ std: UTF16_3 = UTFPREF ( ( ( HEXC | [efEF] ) HEX ) | ( [dD] HEX7 ) ) HEX{2} ; UTF16_4 = UTFPREF [dD] [89abAB] HEX{2} UTFPREF [dD] [c-fC-F] HEX{2} ; - "{" { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return '{'; - } - "}" { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return '}'; - } - "[" { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return '['; - } - "]" { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return ']'; - } - ":" { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return ':'; - } - "," { - PHP_JSON_TOKEN_LOCATION(last_column)++; - return ','; - } + "{" { return '{'; } + "}" { return '}'; } + "[" { return '['; } + "]" { return ']'; } + ":" { return ':'; } + "," { return ','; } "null" { - PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_NULL(&s->value); return PHP_JSON_T_NUL; } "true" { - PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_TRUE(&s->value); return PHP_JSON_T_TRUE; } "false" { - PHP_JSON_TOKEN_LOCATION(last_column) += 5; ZVAL_FALSE(&s->value); return PHP_JSON_T_FALSE; } INT { bool bigint = 0, negative = s->token[0] == '-'; size_t digits = PHP_JSON_TOKEN_LENGTH(); - PHP_JSON_TOKEN_LOCATION(last_column) += digits; digits -= negative; if (digits >= PHP_JSON_INT_MAX_LENGTH) { if (digits == PHP_JSON_INT_MAX_LENGTH) { @@ -223,19 +194,15 @@ std: } } FLOAT|EXP { - PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(); ZVAL_DOUBLE(&s->value, zend_strtod((char *) s->token, NULL)); return PHP_JSON_T_DOUBLE; } NL { - PHP_JSON_TOKEN_LOCATION(last_line)++; - PHP_JSON_TOKEN_LOCATION(last_column) = 1; - goto std; - } - WS { - PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(); + s->line++; + s->line_start = s->cursor; goto std; } + WS { goto std; } EOI { if (s->limit < s->cursor) { return PHP_JSON_T_EOI; @@ -245,7 +212,6 @@ std: } } ["] { - PHP_JSON_TOKEN_LOCATION(last_column)++; s->str_start = s->cursor; s->str_esc = 0; s->utf8_invalid = 0; @@ -264,28 +230,31 @@ std: s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } - + EOI { + if (s->limit < s->cursor) { + s->errcode = PHP_JSON_ERROR_SYNTAX; + } else { + s->errcode = PHP_JSON_ERROR_CTRL_CHAR; + } + return PHP_JSON_T_ERROR; + } CTRL { s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } UTF16_1 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 5; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -294,7 +263,6 @@ std: return PHP_JSON_T_ERROR; } ESC { - PHP_JSON_TOKEN_LOCATION(last_column) += 2; s->str_esc++; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -303,7 +271,6 @@ std: return PHP_JSON_T_ERROR; } ["] { - PHP_JSON_TOKEN_LOCATION(last_column)++; zend_string *str; size_t len = (size_t)(s->cursor - s->str_start - s->str_esc - 1 + s->utf8_invalid_count); if (len == 0) { @@ -324,22 +291,7 @@ std: return PHP_JSON_T_STRING; } } - UTF8_1 { - PHP_JSON_TOKEN_LOCATION(last_column)++; - PHP_JSON_CONDITION_GOTO(STR_P1); - } - UTF8_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; - PHP_JSON_CONDITION_GOTO(STR_P1); - } - UTF8_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; - PHP_JSON_CONDITION_GOTO(STR_P1); - } - UTF8_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; - PHP_JSON_CONDITION_GOTO(STR_P1); - } + UTF8 { PHP_JSON_CONDITION_GOTO(STR_P1); } ANY { if (s->options & (PHP_JSON_INVALID_UTF8_IGNORE | PHP_JSON_INVALID_UTF8_SUBSTITUTE)) { if (s->options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) { diff --git a/ext/json/php_json.h b/ext/json/php_json.h index bbe8be9d60ad..f20b20964a71 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -54,6 +52,18 @@ typedef enum { PHP_JSON_ERROR_NON_BACKED_ENUM, } php_json_error_code; +typedef struct php_json_error_details { + php_json_error_code code; + uint64_t line; + uint64_t column; +} php_json_error_details; + +static inline void php_json_error_details_clear(php_json_error_details *out) { + out->code = PHP_JSON_ERROR_NONE; + out->line = 0; + out->column = 0; +} + /* json_decode() options */ #define PHP_JSON_OBJECT_AS_ARRAY (1<<0) #define PHP_JSON_BIGINT_AS_STRING (1<<1) @@ -85,9 +95,7 @@ typedef enum { ZEND_BEGIN_MODULE_GLOBALS(json) int encoder_depth; int encode_max_depth; - php_json_error_code error_code; - size_t error_line; - size_t error_column; + php_json_error_details error_details; ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) diff --git a/ext/json/php_json_encoder.h b/ext/json/php_json_encoder.h index d66d71cb5538..30cc1d564fa5 100644 --- a/ext/json/php_json_encoder.h +++ b/ext/json/php_json_encoder.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ diff --git a/ext/json/php_json_parser.h b/ext/json/php_json_parser.h index 8fee3d11c6bf..ae927d880aeb 100644 --- a/ext/json/php_json_parser.h +++ b/ext/json/php_json_parser.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -50,20 +48,12 @@ typedef struct _php_json_parser_methods { php_json_parser_func_object_end_t object_end; } php_json_parser_methods; - typedef struct _php_json_parser_location { - size_t first_line; - size_t first_column; - size_t last_line; - size_t last_column; -} php_json_parser_location; - struct _php_json_parser { php_json_scanner scanner; zval *return_value; int depth; int max_depth; php_json_parser_methods methods; - php_json_parser_location *location; }; PHP_JSON_API void php_json_parser_init_ex( @@ -85,9 +75,7 @@ PHP_JSON_API void php_json_parser_init( PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser); -PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser); - -PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser); +PHP_JSON_API void php_json_parser_error_details(const php_json_parser *parser, php_json_error_details *out); PHP_JSON_API int php_json_parse(php_json_parser *parser); diff --git a/ext/json/php_json_scanner.h b/ext/json/php_json_scanner.h index a6de149391dc..f432f66b6d78 100644 --- a/ext/json/php_json_scanner.h +++ b/ext/json/php_json_scanner.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -22,17 +20,6 @@ typedef unsigned char php_json_ctype; -typedef struct _php_json_error_location { - /** first column of the error */ - size_t first_column; - /** first line of the error */ - size_t first_line; - /** last column of the error */ - size_t last_column; - /** last line of the error */ - size_t last_line; -} php_json_error_location; - typedef struct _php_json_scanner { php_json_ctype *cursor; /* cursor position */ php_json_ctype *token; /* token position */ @@ -41,18 +28,17 @@ typedef struct _php_json_scanner { php_json_ctype *ctxmarker; /* marker position for context backtracking */ php_json_ctype *str_start; /* start position of the string */ php_json_ctype *pstr; /* string pointer for escapes conversion */ + php_json_ctype *line_start; /* start position of the current line */ + uint64_t line; /* current line number (1-based) */ zval value; /* value */ int str_esc; /* number of extra characters for escaping */ int state; /* condition state */ int options; /* options */ php_json_error_code errcode; /* error type if there is an error */ - php_json_error_location errloc; /* error location */ int utf8_invalid; /* whether utf8 is invalid */ int utf8_invalid_count; /* number of extra character for invalid utf8 */ } php_json_scanner; -#define PHP_JSON_SCANNER_LOCATION(scanner, slocation) (scanner).errloc.slocation - void php_json_scanner_init(php_json_scanner *scanner, const char *str, size_t str_len, int options); int php_json_scan(php_json_scanner *s); diff --git a/ext/json/tests/bug68546.phpt b/ext/json/tests/bug68546.phpt index 1847eabf3a8e..40ea085ba23b 100644 --- a/ext/json/tests/bug68546.phpt +++ b/ext/json/tests/bug68546.phpt @@ -16,5 +16,5 @@ NULL bool(true) NULL bool(true) -string(55) "The decoded property name is invalid near location 1:27" +string(55) "The decoded property name is invalid near location 1:37" Done diff --git a/ext/json/tests/gh21024.phpt b/ext/json/tests/gh21024.phpt new file mode 100644 index 000000000000..612c577b2d88 --- /dev/null +++ b/ext/json/tests/gh21024.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21024 (UAF in json_encode() when jsonSerialize() frees the object) +--EXTENSIONS-- +json +--FILE-- + 1]; + } +} +$arr = [new Bar]; +$ref = &$arr[0]; +var_dump(json_encode($arr)); +echo "survived\n"; +?> +--EXPECT-- +string(9) "[{"k":1}]" +survived diff --git a/ext/json/tests/gh22420.phpt b/ext/json/tests/gh22420.phpt new file mode 100644 index 000000000000..eecdc6d97a8d --- /dev/null +++ b/ext/json/tests/gh22420.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22420: json_encode() errors don't clear the error position +--FILE-- + +--EXPECTF-- +NULL +string(30) "Syntax error near location 1:2" +bool(false) +string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" diff --git a/ext/json/tests/gh22514.phpt b/ext/json/tests/gh22514.phpt new file mode 100644 index 000000000000..9e7d2adfff8a --- /dev/null +++ b/ext/json/tests/gh22514.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-22514: Incorrect error column in JSON parser after escape sequences +--FILE-- + +--EXPECT-- +NULL +string(31) "Syntax error near location 2:10" +NULL +string(30) "Syntax error near location 2:5" diff --git a/ext/json/tests/gh22527.phpt b/ext/json/tests/gh22527.phpt new file mode 100644 index 000000000000..cb0dd982d50b --- /dev/null +++ b/ext/json/tests/gh22527.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-22527: Unterminated JSON strings are misleadingly reported as “Control character error” +--FILE-- + +--EXPECT-- +NULL +int(4) +string(30) "Syntax error near location 1:1" +NULL +int(4) +string(30) "Syntax error near location 1:1" +NULL +int(4) +string(30) "Syntax error near location 1:9" +NULL +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:1" diff --git a/ext/json/tests/json_last_error_msg_error_location_001.phpt b/ext/json/tests/json_last_error_msg_error_location_001.phpt index e0553f9f7d65..72cb1c42f23f 100644 --- a/ext/json/tests/json_last_error_msg_error_location_001.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_001.phpt @@ -66,8 +66,8 @@ string(30) "Syntax error near location 1:1" Error at position 1:10: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error at position 1:9: bool(false) @@ -118,4 +118,3 @@ Error at position 1:10: bool(false) int(3) string(72) "Control character error, possibly incorrectly encoded near location 1:10" - diff --git a/ext/json/tests/json_last_error_msg_error_location_002.phpt b/ext/json/tests/json_last_error_msg_error_location_002.phpt index df7fc981ccba..31438255b31a 100644 --- a/ext/json/tests/json_last_error_msg_error_location_002.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_002.phpt @@ -53,51 +53,50 @@ Testing error locations with Unicode UTF-8 characters Error after Japanese characters: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:12" +int(4) +string(31) "Syntax error near location 1:12" Error after Russian characters: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error after Chinese characters: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:8" +int(4) +string(30) "Syntax error near location 1:8" Error after Arabic characters: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error after Emoji: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" +int(4) +string(31) "Syntax error near location 1:11" Error in mixed ASCII and UTF-8: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:27" +int(4) +string(31) "Syntax error near location 1:27" Error with UTF-8 escaped sequences: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error in object with multiple UTF-8 keys: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:22" +int(4) +string(31) "Syntax error near location 1:22" Error in array with UTF-8 strings: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:18" +int(4) +string(31) "Syntax error near location 1:18" Error in nested object with UTF-8: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:15" - +int(4) +string(31) "Syntax error near location 1:15" diff --git a/ext/json/tests/json_last_error_msg_error_location_004.phpt b/ext/json/tests/json_last_error_msg_error_location_004.phpt index 165449600fb3..fcde3faa38a3 100644 --- a/ext/json/tests/json_last_error_msg_error_location_004.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_004.phpt @@ -53,8 +53,8 @@ Testing error locations in deeply nested structures Error in deeply nested object: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:31" +int(4) +string(31) "Syntax error near location 1:31" Error in deeply nested array: bool(true) @@ -78,16 +78,15 @@ string(31) "Syntax error near location 1:21" Error in complex structure: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:93" +int(4) +string(31) "Syntax error near location 1:93" Error in array of objects: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:68" +int(4) +string(31) "Syntax error near location 1:68" Error in object with array values: bool(false) int(2) string(61) "State mismatch (invalid or malformed JSON) near location 1:82" - diff --git a/ext/json/tests/json_last_error_msg_error_location_005.phpt b/ext/json/tests/json_last_error_msg_error_location_005.phpt index d12ce387e73e..ca798fcb01fe 100644 --- a/ext/json/tests/json_last_error_msg_error_location_005.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_005.phpt @@ -19,8 +19,8 @@ json_validate_trycatchdump('{"test": "\uD83D\uDE00\uD83C\uDF89}'); echo "\nError with mixed UTF-8 and UTF-16:\n"; json_validate_trycatchdump('{"mixed": "Hello \u4E16\u754C world}'); -// UTF-16 in key and value -echo "\nError with UTF-16 in key:\n"; +// Missing closing quote after a UTF-16 key +echo "\nError on unterminated value after UTF-16 key:\n"; json_validate_trycatchdump('{"\u30D7\u30EC\u30B9": "value}'); // Multiple keys with UTF-16 @@ -53,51 +53,50 @@ Testing error locations with UTF-16 surrogate pairs and escape sequences Error after UTF-16 escaped emoji: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" +int(4) +string(31) "Syntax error near location 1:11" Error after multiple UTF-16 pairs: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with mixed UTF-8 and UTF-16: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" +int(4) +string(31) "Syntax error near location 1:11" -Error with UTF-16 in key: +Error on unterminated value after UTF-16 key: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(31) "Syntax error near location 1:24" Error with multiple UTF-16 keys: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:22" +int(4) +string(31) "Syntax error near location 1:42" Error with BMP characters: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with supplementary plane: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" +int(4) +string(31) "Syntax error near location 1:11" Error in array with UTF-16: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:12" +int(4) +string(31) "Syntax error near location 1:22" Error in nested structure with UTF-16: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:18" +int(4) +string(31) "Syntax error near location 1:28" Error with UTF-16 and control chars: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" - +int(4) +string(31) "Syntax error near location 1:10" diff --git a/ext/json/tests/json_last_error_msg_error_location_006.phpt b/ext/json/tests/json_last_error_msg_error_location_006.phpt index e6aab1af8f27..4a6c221c8f92 100644 --- a/ext/json/tests/json_last_error_msg_error_location_006.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_006.phpt @@ -107,8 +107,8 @@ string(33) "Syntax error near location 1:1011" Error with very long key: bool(false) -int(3) -string(73) "Control character error, possibly incorrectly encoded near location 1:506" +int(4) +string(32) "Syntax error near location 1:506" Error after empty object: bool(false) @@ -149,4 +149,3 @@ Error with mixed whitespace: bool(false) int(3) string(71) "Control character error, possibly incorrectly encoded near location 3:2" - diff --git a/ext/json/tests/json_last_error_msg_error_location_007.phpt b/ext/json/tests/json_last_error_msg_error_location_007.phpt index 0e24889bbbbe..168afc4dbfe2 100644 --- a/ext/json/tests/json_last_error_msg_error_location_007.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_007.phpt @@ -118,8 +118,8 @@ string(30) "Syntax error near location 1:9" Unclosed string: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Invalid escape sequence: bool(false) @@ -175,4 +175,3 @@ Missing comma between object properties: bool(false) int(4) string(30) "Syntax error near location 1:9" - diff --git a/ext/json/tests/json_last_error_msg_error_location_008.phpt b/ext/json/tests/json_last_error_msg_error_location_008.phpt index 4d8a1012316b..60dd9513472b 100644 --- a/ext/json/tests/json_last_error_msg_error_location_008.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_008.phpt @@ -82,101 +82,100 @@ Testing error locations with various UTF-8 multi-byte character widths Error with 2-byte UTF-8 (Latin Extended): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with 2-byte UTF-8 (Greek): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:14" +int(4) +string(31) "Syntax error near location 1:14" Error with 2-byte UTF-8 (Cyrillic): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:12" +int(4) +string(31) "Syntax error near location 1:12" Error with 3-byte UTF-8 (Chinese): bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:8" +int(4) +string(30) "Syntax error near location 1:8" Error with 3-byte UTF-8 (Japanese Hiragana): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with 3-byte UTF-8 (Japanese Katakana): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with 3-byte UTF-8 (Korean): bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:8" +int(4) +string(30) "Syntax error near location 1:8" Error with 4-byte UTF-8 (Emoji faces): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" +int(4) +string(31) "Syntax error near location 1:11" Error with 4-byte UTF-8 (Emoji objects): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:13" +int(4) +string(31) "Syntax error near location 1:13" Error with 4-byte UTF-8 (Mathematical symbols): bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with mixed 1-2-3 byte UTF-8: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error with mixed 2-3-4 byte UTF-8: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error with all byte widths: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error with UTF-8 key at start: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:7" +int(4) +string(30) "Syntax error near location 1:7" Error with multiple UTF-8 keys: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:35" +int(4) +string(31) "Syntax error near location 1:35" Error in array with mixed UTF-8: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:25" +int(4) +string(31) "Syntax error near location 1:25" Error in nested structure with various UTF-8: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:22" +int(4) +string(31) "Syntax error near location 1:22" Error with combining diacritical marks: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with Hebrew: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" +int(4) +string(31) "Syntax error near location 1:10" Error with Arabic with diacritics: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:11" - +int(4) +string(31) "Syntax error near location 1:11" diff --git a/ext/json/tests/json_last_error_msg_error_location_009.phpt b/ext/json/tests/json_last_error_msg_error_location_009.phpt index 406179693ef6..9d4403838f63 100644 --- a/ext/json/tests/json_last_error_msg_error_location_009.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_009.phpt @@ -75,18 +75,18 @@ string(46) "Maximum stack depth exceeded near location 1:7" Syntax error at deep nesting level: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:31" +int(4) +string(31) "Syntax error near location 1:31" Syntax error in deep array: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:6" +int(4) +string(30) "Syntax error near location 1:6" Error after valid deep structure: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:48" +int(4) +string(31) "Syntax error near location 1:48" Error in middle of nested structure: bool(false) @@ -95,16 +95,15 @@ string(31) "Syntax error near location 1:29" Error in array with nested objects: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:30" +int(4) +string(31) "Syntax error near location 1:30" Error in deep UTF-8 structure: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:16" +int(4) +string(31) "Syntax error near location 1:16" Valid deep structure within limit: bool(true) int(0) string(8) "No error" - diff --git a/ext/json/tests/json_last_error_msg_error_location_010.phpt b/ext/json/tests/json_last_error_msg_error_location_010.phpt index 108570205838..d187afff86cc 100644 --- a/ext/json/tests/json_last_error_msg_error_location_010.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_010.phpt @@ -119,13 +119,13 @@ string(30) "Syntax error near location 4:2" Error in string with spaces: bool(false) -int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1:9" +int(4) +string(30) "Syntax error near location 1:9" Error with whitespace around colon: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:12" +int(4) +string(31) "Syntax error near location 1:12" Error with whitespace around comma: bool(true) @@ -154,11 +154,10 @@ string(72) "Control character error, possibly incorrectly encoded near location Error in compact JSON: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:22" +int(4) +string(31) "Syntax error near location 1:22" Error with regular spaces: bool(false) -int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1:10" - +int(4) +string(31) "Syntax error near location 1:10" diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 14174bd5dc26..65a3d3b90eed 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -134,7 +134,6 @@ if test "$PHP_LDAP" != "no"; then dnl nor ldap_start_tls_s() AC_CHECK_FUNCS(m4_normalize([ ldap_control_find - ldap_extended_operation ldap_extended_operation_s ldap_parse_extended_result ldap_parse_reference diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index 7dbb353dd80b..1fa1fe3f777c 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -23,8 +23,7 @@ if (PHP_LDAP != "no") { AC_DEFINE('HAVE_LDAP_PASSWD', 1); AC_DEFINE('HAVE_LDAP_WHOAMI_S', 1); AC_DEFINE('HAVE_LDAP_REFRESH_S', 1); - AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION', 1); - + AC_DEFINE('HAVE_3ARG_SETREBINDPROC', 1); } else { WARNING("ldap not enabled; libraries and headers not found"); } diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 5cc462d624ac..7a089625aa48 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Amitay Isaacs | | Eric Warnke | @@ -102,9 +100,7 @@ ZEND_TSRMLS_CACHE_DEFINE() ZEND_GET_MODULE(ldap) #endif -static inline ldap_linkdata *ldap_link_from_obj(zend_object *obj) { - return (ldap_linkdata *)((char *)(obj) - XtOffsetOf(ldap_linkdata, std)); -} +#define ldap_link_from_obj(obj) ZEND_CONTAINER_OF(obj, ldap_linkdata, std) #define Z_LDAP_LINK_P(zv) ldap_link_from_obj(Z_OBJ_P(zv)) @@ -149,9 +145,7 @@ static void ldap_link_free_obj(zend_object *obj) zend_object_std_dtor(&ld->std); } -static inline ldap_resultdata *ldap_result_from_obj(zend_object *obj) { - return (ldap_resultdata *)((char *)(obj) - XtOffsetOf(ldap_resultdata, std)); -} +#define ldap_result_from_obj(obj) ZEND_CONTAINER_OF(obj, ldap_resultdata, std) #define Z_LDAP_RESULT_P(zv) ldap_result_from_obj(Z_OBJ_P(zv)) @@ -186,9 +180,7 @@ static void ldap_result_free_obj(zend_object *obj) zend_object_std_dtor(&result->std); } -static inline ldap_result_entry *ldap_result_entry_from_obj(zend_object *obj) { - return (ldap_result_entry *)((char *)(obj) - XtOffsetOf(ldap_result_entry, std)); -} +#define ldap_result_entry_from_obj(obj) ZEND_CONTAINER_OF(obj, ldap_result_entry, std) #define Z_LDAP_RESULT_ENTRY_P(zv) ldap_result_entry_from_obj(Z_OBJ_P(zv)) @@ -273,7 +265,7 @@ static zend_string* php_ldap_try_get_ldap_value_from_zval(zval *zv) { /* The char pointer MUST refer to the char* of a zend_string struct */ static void php_ldap_zend_string_release_from_char_pointer(char *ptr) { - zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val))); + zend_string_release((zend_string*) (ptr - offsetof(zend_string, val))); } /* {{{ Parse controls from and to arrays */ @@ -585,6 +577,7 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT uint32_t num_keys = zend_hash_num_elements(Z_ARRVAL_P(val)); sort_keys = safe_emalloc((num_keys+1), sizeof(LDAPSortKey*), 0); + memset(sort_keys, 0, (num_keys+1) * sizeof(LDAPSortKey*)); tmpstrings1 = safe_emalloc(num_keys, sizeof(zend_string*), 0); tmpstrings2 = safe_emalloc(num_keys, sizeof(zend_string*), 0); num_tmpstrings1 = 0; @@ -879,7 +872,7 @@ PHP_MINIT_FUNCTION(ldap) ldap_link_ce->default_object_handlers = &ldap_link_object_handlers; memcpy(&ldap_link_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_link_object_handlers.offset = XtOffsetOf(ldap_linkdata, std); + ldap_link_object_handlers.offset = offsetof(ldap_linkdata, std); ldap_link_object_handlers.free_obj = ldap_link_free_obj; ldap_link_object_handlers.get_constructor = ldap_link_get_constructor; ldap_link_object_handlers.clone_obj = NULL; @@ -890,7 +883,7 @@ PHP_MINIT_FUNCTION(ldap) ldap_result_ce->default_object_handlers = &ldap_result_object_handlers; memcpy(&ldap_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_result_object_handlers.offset = XtOffsetOf(ldap_resultdata, std); + ldap_result_object_handlers.offset = offsetof(ldap_resultdata, std); ldap_result_object_handlers.free_obj = ldap_result_free_obj; ldap_result_object_handlers.get_constructor = ldap_result_get_constructor; ldap_result_object_handlers.clone_obj = NULL; @@ -901,7 +894,7 @@ PHP_MINIT_FUNCTION(ldap) ldap_result_entry_ce->default_object_handlers = &ldap_result_entry_object_handlers; memcpy(&ldap_result_entry_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_result_entry_object_handlers.offset = XtOffsetOf(ldap_result_entry, std); + ldap_result_entry_object_handlers.offset = offsetof(ldap_result_entry, std); ldap_result_entry_object_handlers.free_obj = ldap_result_entry_free_obj; ldap_result_entry_object_handlers.get_constructor = ldap_result_entry_get_constructor; ldap_result_entry_object_handlers.clone_obj = NULL; @@ -2209,6 +2202,8 @@ PHP_FUNCTION(ldap_explode_dn) zend_long with_attrib; char *dn, **ldap_value; size_t dn_len; + int i, count; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl", &dn, &dn_len, &with_attrib) != SUCCESS) { RETURN_THROWS(); @@ -2220,11 +2215,15 @@ PHP_FUNCTION(ldap_explode_dn) } array_init(return_value); - int i; - for (i = 0; ldap_value[i] != NULL; i++) { + i = 0; + while (ldap_value[i] != NULL) i++; + count = i; + + add_assoc_long(return_value, "count", count); + + for (i = 0; i < count; i++) { add_index_string(return_value, i, ldap_value[i]); } - add_assoc_long(return_value, "count", i); ldap_memvfree((void **)ldap_value); } @@ -2434,7 +2433,9 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, bool ext) object_init_ex(return_value, ldap_result_ce); result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; - } else RETVAL_TRUE; + } else { + RETVAL_TRUE; + } } cleanup: @@ -2781,7 +2782,7 @@ PHP_FUNCTION(ldap_modify_batch) case LDAP_MODIFY_BATCH_REPLACE: ldap_operation = LDAP_MOD_REPLACE; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } /* fill in the basic info */ diff --git a/ext/ldap/ldap.stub.php b/ext/ldap/ldap.stub.php index 84befe3f43f8..52cf3828dba3 100644 --- a/ext/ldap/ldap.stub.php +++ b/ext/ldap/ldap.stub.php @@ -659,7 +659,7 @@ function ldap_list($ldap, array|string $base, array|string $filter, array $attri /** @param LDAP\Connection|array $ldap */ function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} - function ldap_free_result(LDAP\Result $result): bool {} + function ldap_free_result(LDAP\Result $result): true {} function ldap_count_entries(LDAP\Connection $ldap, LDAP\Result $result): int {} diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index aa371b7a8d49..8f5e7e34ba32 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit ldap.stub.php instead. - * Stub hash: 9e47a0d85336f0e149abbdf56468513c5d31780f */ + * Stub hash: 0dde8fd813f43640dee842c03365d7431858a56d */ #if defined(HAVE_ORALDAP) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_connect, 0, 0, LDAP\\Connection, MAY_BE_FALSE) @@ -75,7 +75,7 @@ ZEND_END_ARG_INFO() #define arginfo_ldap_search arginfo_ldap_read -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ldap_free_result, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ldap_free_result, 0, 1, IS_TRUE, 0) ZEND_ARG_OBJ_INFO(0, result, LDAP\\Result, 0) ZEND_END_ARG_INFO() diff --git a/ext/ldap/php_ldap.h b/ext/ldap/php_ldap.h index a8c4a77af801..a8591888fa83 100644 --- a/ext/ldap/php_ldap.h +++ b/ext/ldap/php_ldap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Amitay Isaacs | | Eric Warnke | diff --git a/ext/ldap/tests/ldap_explode_dn.phpt b/ext/ldap/tests/ldap_explode_dn.phpt index 047078c7beb7..2012506c3ef0 100644 --- a/ext/ldap/tests/ldap_explode_dn.phpt +++ b/ext/ldap/tests/ldap_explode_dn.phpt @@ -34,16 +34,18 @@ echo "Done\n"; ?> --EXPECT-- array(4) { + ["count"]=> + int(3) [0]=> string(6) "cn=bob" [1]=> string(10) "dc=example" [2]=> string(6) "dc=com" - ["count"]=> - int(3) } array(5) { + ["count"]=> + int(4) [0]=> string(6) "cn=bob" [1]=> @@ -52,20 +54,20 @@ array(5) { string(10) "dc=example" [3]=> string(6) "dc=com" - ["count"]=> - int(4) } array(4) { + ["count"]=> + int(3) [0]=> string(3) "bob" [1]=> string(7) "example" [2]=> string(3) "com" - ["count"]=> - int(3) } array(5) { + ["count"]=> + int(4) [0]=> string(3) "bob" [1]=> @@ -74,8 +76,6 @@ array(5) { string(7) "example" [3]=> string(3) "com" - ["count"]=> - int(4) } bool(false) bool(false) diff --git a/ext/ldap/tests/ldap_sort_control_missing_attr.phpt b/ext/ldap/tests/ldap_sort_control_missing_attr.phpt new file mode 100644 index 000000000000..0d6c3921f008 --- /dev/null +++ b/ext/ldap/tests/ldap_sort_control_missing_attr.phpt @@ -0,0 +1,30 @@ +--TEST-- +ldap_search(): malformed sort control (sort key missing "attr") must not free uninitialized memory +--EXTENSIONS-- +ldap +--FILE-- + LDAP_CONTROL_SORTREQUEST, + 'value' => [ + ['attr' => 'cn'], + ['reverse' => true], + ], + ], + ]); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "ok\n"; +?> +--EXPECT-- +ldap_search(): Sort key list must have an "attr" key +ok diff --git a/ext/lexbor/config.m4 b/ext/lexbor/config.m4 index 3e67c10fdfc3..43123578a727 100644 --- a/ext/lexbor/config.m4 +++ b/ext/lexbor/config.m4 @@ -1,8 +1,7 @@ -PHP_LEXBOR_CFLAGS="-I@ext_srcdir@/" +PHP_LEXBOR_CFLAGS="-Wno-unknown-warning-option -Wno-unterminated-string-initialization -I@ext_srcdir@/" LEXBOR_DIR="lexbor" AC_DEFINE([HAVE_LEXBOR], [1], [Define to 1 if the PHP extension 'lexbor' is available.]) -AC_DEFINE([LEXBOR_VERSION], ["2.5.0"], [Define the main Lexbor version]) PHP_NEW_EXTENSION([lexbor], m4_normalize([ php_lexbor.c @@ -23,15 +22,23 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/core/shs.c $LEXBOR_DIR/core/str.c $LEXBOR_DIR/core/strtod.c + $LEXBOR_DIR/css/at_rule.c + $LEXBOR_DIR/css/at_rule/state.c + $LEXBOR_DIR/css/blank.c $LEXBOR_DIR/css/css.c + $LEXBOR_DIR/css/declaration.c $LEXBOR_DIR/css/log.c $LEXBOR_DIR/css/parser.c + $LEXBOR_DIR/css/property.c + $LEXBOR_DIR/css/property/state.c + $LEXBOR_DIR/css/rule.c $LEXBOR_DIR/css/selectors/pseudo_state.c $LEXBOR_DIR/css/selectors/pseudo.c $LEXBOR_DIR/css/selectors/selector.c $LEXBOR_DIR/css/selectors/selectors.c $LEXBOR_DIR/css/selectors/state.c $LEXBOR_DIR/css/state.c + $LEXBOR_DIR/css/stylesheet.c $LEXBOR_DIR/css/syntax/anb.c $LEXBOR_DIR/css/syntax/parser.c $LEXBOR_DIR/css/syntax/state.c @@ -39,6 +46,8 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/css/syntax/token.c $LEXBOR_DIR/css/syntax/tokenizer.c $LEXBOR_DIR/css/syntax/tokenizer/error.c + $LEXBOR_DIR/css/unit.c + $LEXBOR_DIR/css/value.c $LEXBOR_DIR/dom/interface.c $LEXBOR_DIR/dom/interfaces/attr.c $LEXBOR_DIR/dom/interfaces/cdata_section.c @@ -114,7 +123,9 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/interfaces/progress_element.c $LEXBOR_DIR/html/interfaces/quote_element.c $LEXBOR_DIR/html/interfaces/script_element.c + $LEXBOR_DIR/html/interfaces/search_element.c $LEXBOR_DIR/html/interfaces/select_element.c + $LEXBOR_DIR/html/interfaces/selectedcontent_element.c $LEXBOR_DIR/html/interfaces/slot_element.c $LEXBOR_DIR/html/interfaces/source_element.c $LEXBOR_DIR/html/interfaces/span_element.c @@ -135,6 +146,7 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/interfaces/video_element.c $LEXBOR_DIR/html/interfaces/window.c $LEXBOR_DIR/html/parser.c + $LEXBOR_DIR/html/tag.c $LEXBOR_DIR/html/token_attr.c $LEXBOR_DIR/html/token.c $LEXBOR_DIR/html/tokenizer.c @@ -164,8 +176,6 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/tree/insertion_mode/in_head_noscript.c $LEXBOR_DIR/html/tree/insertion_mode/in_head.c $LEXBOR_DIR/html/tree/insertion_mode/in_row.c - $LEXBOR_DIR/html/tree/insertion_mode/in_select_in_table.c - $LEXBOR_DIR/html/tree/insertion_mode/in_select.c $LEXBOR_DIR/html/tree/insertion_mode/in_table_body.c $LEXBOR_DIR/html/tree/insertion_mode/in_table_text.c $LEXBOR_DIR/html/tree/insertion_mode/in_table.c @@ -182,11 +192,13 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/url/url.c ]), [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $PHP_LEXBOR_CFLAGS]) + [$PHP_LEXBOR_CFLAGS]) PHP_ADD_BUILD_DIR([ $ext_builddir/ $ext_builddir/$LEXBOR_DIR/core + $ext_builddir/$LEXBOR_DIR/css/at_rule + $ext_builddir/$LEXBOR_DIR/css/property $ext_builddir/$LEXBOR_DIR/css/selectors $ext_builddir/$LEXBOR_DIR/css/syntax/tokenizer $ext_builddir/$LEXBOR_DIR/css/tokenizer diff --git a/ext/lexbor/config.w32 b/ext/lexbor/config.w32 index bd1f3b383a7e..403c3b98afb5 100644 --- a/ext/lexbor/config.w32 +++ b/ext/lexbor/config.w32 @@ -1,6 +1,6 @@ // vim:ft=javascript -EXTENSION("lexbor", "php_lexbor.c", false, "/I " + configure_module_dirname + " /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("lexbor", "php_lexbor.c", false, "/I " + configure_module_dirname); PHP_LEXBOR="yes"; ADD_SOURCES("ext/lexbor/lexbor/ports/windows_nt/lexbor/core", "memory.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/core", "array_obj.c array.c avl.c bst.c diyfp.c conv.c dobject.c dtoa.c hash.c mem.c mraw.c plog.c print.c serialize.c shs.c str.c strtod.c", "lexbor"); @@ -8,11 +8,13 @@ ADD_SOURCES("ext/lexbor/lexbor/dom", "interface.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/dom/interfaces", "attr.c cdata_section.c character_data.c comment.c document.c document_fragment.c document_type.c element.c node.c processing_instruction.c shadow_root.c text.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/html/tokenizer", "error.c state_comment.c state_doctype.c state_rawtext.c state_rcdata.c state_script.c state.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/html/tree", "active_formatting.c open_elements.c error.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html/tree/insertion_mode", "after_after_body.c after_after_frameset.c after_body.c after_frameset.c after_head.c before_head.c before_html.c foreign_content.c in_body.c in_caption.c in_cell.c in_column_group.c in_frameset.c in_head.c in_head_noscript.c initial.c in_row.c in_select.c in_select_in_table.c in_table_body.c in_table.c in_table_text.c in_template.c text.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html", "encoding.c interface.c parser.c token.c token_attr.c tokenizer.c tree.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html/tree/insertion_mode", "after_after_body.c after_after_frameset.c after_body.c after_frameset.c after_head.c before_head.c before_html.c foreign_content.c in_body.c in_caption.c in_cell.c in_column_group.c in_frameset.c in_head.c in_head_noscript.c initial.c in_row.c in_table_body.c in_table.c in_table_text.c in_template.c text.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html", "encoding.c interface.c parser.c tag.c token.c token_attr.c tokenizer.c tree.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/encoding", "decode.c encode.c encoding.c multi.c range.c res.c single.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html/interfaces", "anchor_element.c area_element.c audio_element.c base_element.c body_element.c br_element.c button_element.c canvas_element.c data_element.c data_list_element.c details_element.c dialog_element.c directory_element.c div_element.c d_list_element.c document.c element.c embed_element.c field_set_element.c font_element.c form_element.c frame_element.c frame_set_element.c head_element.c heading_element.c hr_element.c html_element.c iframe_element.c image_element.c input_element.c label_element.c legend_element.c li_element.c link_element.c map_element.c marquee_element.c media_element.c menu_element.c meta_element.c meter_element.c mod_element.c object_element.c o_list_element.c opt_group_element.c option_element.c output_element.c paragraph_element.c param_element.c picture_element.c pre_element.c progress_element.c quote_element.c script_element.c select_element.c slot_element.c source_element.c span_element.c style_element.c table_caption_element.c table_cell_element.c table_col_element.c table_element.c table_row_element.c table_section_element.c template_element.c text_area_element.c time_element.c title_element.c track_element.c u_list_element.c unknown_element.c video_element.c window.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/css", "state.c log.c parser.c css.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html/interfaces", "anchor_element.c area_element.c audio_element.c base_element.c body_element.c br_element.c button_element.c canvas_element.c data_element.c data_list_element.c details_element.c dialog_element.c directory_element.c div_element.c d_list_element.c document.c element.c embed_element.c field_set_element.c font_element.c form_element.c frame_element.c frame_set_element.c head_element.c heading_element.c hr_element.c html_element.c iframe_element.c image_element.c input_element.c label_element.c legend_element.c li_element.c link_element.c map_element.c marquee_element.c media_element.c menu_element.c meta_element.c meter_element.c mod_element.c object_element.c o_list_element.c opt_group_element.c option_element.c output_element.c paragraph_element.c param_element.c picture_element.c pre_element.c progress_element.c quote_element.c script_element.c search_element.c select_element.c selectedcontent_element.c slot_element.c source_element.c span_element.c style_element.c table_caption_element.c table_cell_element.c table_col_element.c table_element.c table_row_element.c table_section_element.c template_element.c text_area_element.c time_element.c title_element.c track_element.c u_list_element.c unknown_element.c video_element.c window.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css", "at_rule.c blank.c css.c declaration.c log.c parser.c property.c rule.c state.c stylesheet.c unit.c value.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css/at_rule", "state.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css/property", "state.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/selectors", "state.c selectors.c selector.c pseudo_state.c pseudo.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/syntax", "state.c parser.c syntax.c anb.c tokenizer.c token.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/syntax/tokenizer", "error.c","lexbor"); @@ -24,6 +26,5 @@ ADD_SOURCES("ext/lexbor/lexbor/url", "url.c","lexbor"); ADD_FLAG("CFLAGS_LEXBOR", "/D LEXBOR_BUILDING /utf-8"); AC_DEFINE("HAVE_LEXBOR", 1, "Define to 1 if the PHP extension 'lexbor' is available."); -AC_DEFINE("LEXBOR_VERSION", "2.5.0", "Define the main Lexbor version") PHP_INSTALL_HEADERS("ext/lexbor", "php_lexbor.h lexbor/"); diff --git a/ext/lexbor/lexbor/core/base.h b/ext/lexbor/lexbor/core/base.h index d3a04880f220..e488dcf7334b 100644 --- a/ext/lexbor/lexbor/core/base.h +++ b/ext/lexbor/lexbor/core/base.h @@ -27,7 +27,7 @@ extern "C" { #include "lexbor/core/lexbor.h" #define LEXBOR_VERSION_MAJOR 2 -#define LEXBOR_VERSION_MINOR 0 +#define LEXBOR_VERSION_MINOR 7 #define LEXBOR_VERSION_PATCH 0 #define LEXBOR_VERSION_STRING LEXBOR_STRINGIZE(LEXBOR_VERSION_MAJOR) "." \ @@ -39,6 +39,10 @@ extern "C" { #define lexbor_max(val1, val2) ((val1) > (val2) ? (val1) : (val2)) #define lexbor_min(val1, val2) ((val1) < (val2) ? (val1) : (val2)) +#define LEXBOR_STR_RES_MAP_CHAR_OTHER 0x00 +#define LEXBOR_STR_RES_MAP_CHAR_A_Z_a_z 0x01 +#define LEXBOR_STR_RES_MAP_CHAR_WHITESPACE 0x02 +#define LEXBOR_STR_RES_SLIP 0xFF /* * Very important!!! diff --git a/ext/lexbor/lexbor/core/def.h b/ext/lexbor/lexbor/core/def.h index 5a48f59e994d..c8b94400a2df 100644 --- a/ext/lexbor/lexbor/core/def.h +++ b/ext/lexbor/lexbor/core/def.h @@ -54,4 +54,6 @@ #define LXB_EXTERN extern LXB_API +#define lxb_size(_size) ((size_t) (_size)) + #endif /* LEXBOR_DEF_H */ diff --git a/ext/lexbor/lexbor/core/diyfp.c b/ext/lexbor/lexbor/core/diyfp.c index 62020bbc645e..7bdbcbbcb08f 100644 --- a/ext/lexbor/lexbor/core/diyfp.c +++ b/ext/lexbor/lexbor/core/diyfp.c @@ -1,16 +1,44 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_diyfp.c from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov * + * Based on nxt_diyfp.h from NGINX NJS project * An internal diy_fp implementation. * For details, see Loitsch, Florian. "Printing floating-point numbers quickly * and accurately with integers." ACM Sigplan Notices 45.6 (2010): 233-243. */ + #include "lexbor/core/diyfp.h" diff --git a/ext/lexbor/lexbor/core/diyfp.h b/ext/lexbor/lexbor/core/diyfp.h index 47fedb9da997..86c5336f2e03 100644 --- a/ext/lexbor/lexbor/core/diyfp.h +++ b/ext/lexbor/lexbor/core/diyfp.h @@ -1,11 +1,38 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_diyfp.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov * + * Based on nxt_diyfp.h from NGINX NJS project * An internal diy_fp implementation. * For details, see Loitsch, Florian. "Printing floating-point numbers quickly * and accurately with integers." ACM Sigplan Notices 45.6 (2010): 233-243. diff --git a/ext/lexbor/lexbor/core/dtoa.c b/ext/lexbor/lexbor/core/dtoa.c index b1a4ee03258d..7da7ce013227 100644 --- a/ext/lexbor/lexbor/core/dtoa.c +++ b/ext/lexbor/lexbor/core/dtoa.c @@ -1,39 +1,36 @@ /* - * Copyright (C) Alexander Borisov - * - * Based on nxt_dtoa.c from NGINX NJS project - * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. - * - * Grisu2 algorithm implementation for printing floating-point numbers based - * upon the work of Milo Yip and Doug Currie. - * - * For algorithm information, see Loitsch, Florian. "Printing - * floating-point numbers quickly and accurately with integers." ACM Sigplan - * Notices 45.6 (2010): 233-243. - * - * Copyright (C) 2015 Doug Currie - * based on dtoa_milo.h - * Copyright (C) 2014 Milo Yip + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #include "lexbor/core/str.h" diff --git a/ext/lexbor/lexbor/core/dtoa.h b/ext/lexbor/lexbor/core/dtoa.h index c60c28803b7b..2d569cfff973 100644 --- a/ext/lexbor/lexbor/core/dtoa.h +++ b/ext/lexbor/lexbor/core/dtoa.h @@ -1,10 +1,36 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_dtoa.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) Nginx, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #ifndef LEXBOR_DTOA_H diff --git a/ext/lexbor/lexbor/core/hash.c b/ext/lexbor/lexbor/core/hash.c index 2fdd4caa9d98..c16466effd35 100644 --- a/ext/lexbor/lexbor/core/hash.c +++ b/ext/lexbor/lexbor/core/hash.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -10,9 +10,10 @@ #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_uppercase[256]; +#endif /* Insert variable. */ diff --git a/ext/lexbor/lexbor/core/in.c b/ext/lexbor/lexbor/core/in.c index 951e585cbd39..363256b732a4 100644 --- a/ext/lexbor/lexbor/core/in.c +++ b/ext/lexbor/lexbor/core/in.c @@ -1,11 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/in.h" -#include "lexbor/core/str_res.h" lexbor_in_t * diff --git a/ext/lexbor/lexbor/core/shs.c b/ext/lexbor/lexbor/core/shs.c index 679143bf45cc..c2753457d74a 100644 --- a/ext/lexbor/lexbor/core/shs.c +++ b/ext/lexbor/lexbor/core/shs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/core/shs.h" #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_uppercase[256]; +#endif #define lexbor_shs_make_id_m(key, size, table_size) \ (((((key[0] * key[size - 1]) * key[0]) + size) % table_size) + 0x01) diff --git a/ext/lexbor/lexbor/core/str.c b/ext/lexbor/lexbor/core/str.c index bf8fc547d88d..3d164ebf82dd 100644 --- a/ext/lexbor/lexbor/core/str.c +++ b/ext/lexbor/lexbor/core/str.c @@ -1,14 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/str.h" - -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE #include "lexbor/core/str_res.h" @@ -381,6 +377,30 @@ lexbor_str_whitespace_from_end(lexbor_str_t *target) return 0; } +lxb_char_t * +lexbor_str_copy_to(lexbor_str_t *str, const lxb_char_t *buff, size_t length) +{ + lxb_char_t *data_begin; + + data_begin = &str->data[str->length]; + memcpy(data_begin, buff, sizeof(lxb_char_t) * length); + + str->length += length; + + return data_begin; +} + +lxb_char_t * +lexbor_str_copy_to_with_null(lexbor_str_t *str, + const lxb_char_t *buff, size_t length) +{ + lxb_char_t *data_begin = lexbor_str_copy_to(str, buff, length); + + str->data[str->length] = '\0'; + + return data_begin; +} + /* * Data utils * TODO: All functions need optimization. diff --git a/ext/lexbor/lexbor/core/str.h b/ext/lexbor/lexbor/core/str.h index 3bee14537387..8e5f3806fe93 100644 --- a/ext/lexbor/lexbor/core/str.h +++ b/ext/lexbor/lexbor/core/str.h @@ -21,7 +21,6 @@ extern "C" { #define lexbor_str_len(str) lexbor_str_get(str, length) #define lexbor_str(p) {.data = (lxb_char_t *) (p), sizeof(p) - 1} - #define lexbor_str_check_size_arg_m(str, size, mraw, plus_len, return_fail) \ do { \ void *tmp; \ @@ -117,6 +116,12 @@ lexbor_str_whitespace_from_begin(lexbor_str_t *target); LXB_API size_t lexbor_str_whitespace_from_end(lexbor_str_t *target); +LXB_API lxb_char_t * +lexbor_str_copy_to(lexbor_str_t *str, const lxb_char_t *buff, size_t length); + +LXB_API lxb_char_t * +lexbor_str_copy_to_with_null(lexbor_str_t *str, + const lxb_char_t *buff, size_t length); /* Data utils */ /* diff --git a/ext/lexbor/lexbor/core/str_res.h b/ext/lexbor/lexbor/core/str_res.h index cebbda8aa534..be34a0eeb42c 100644 --- a/ext/lexbor/lexbor/core/str_res.h +++ b/ext/lexbor/lexbor/core/str_res.h @@ -1,32 +1,16 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ -#ifndef LEXBOR_STR_RES_H -#define LEXBOR_STR_RES_H -#define LEXBOR_STR_RES_MAP_CHAR_OTHER '\00' -#define LEXBOR_STR_RES_MAP_CHAR_A_Z_a_z '\01' -#define LEXBOR_STR_RES_MAP_CHAR_WHITESPACE '\02' +LXB_API const lxb_char_t +lexbor_str_res_ansi_replacement_character[4] = "\xEF\xBF\xBD"; -#define LEXBOR_STR_RES_SLIP 0xFF - -#endif /* LEXBOR_STR_RES_H */ - -#ifdef LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#ifndef LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED -static const lxb_char_t -lexbor_str_res_ansi_replacement_character[] = "\xEF\xBF\xBD"; -#endif /* LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER */ - -#ifdef LEXBOR_STR_RES_MAP_NUM -#ifndef LEXBOR_STR_RES_MAP_NUM_ENABLED -#define LEXBOR_STR_RES_MAP_NUM_ENABLED -static const lxb_char_t lexbor_str_res_map_num[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_num[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -57,14 +41,10 @@ static const lxb_char_t lexbor_str_res_map_num[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_NUM_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_NUM */ - -#ifdef LEXBOR_STR_RES_MAP_HEX -#ifndef LEXBOR_STR_RES_MAP_HEX_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_ENABLED -static const lxb_char_t lexbor_str_res_map_hex[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -95,14 +75,10 @@ static const lxb_char_t lexbor_str_res_map_hex[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_HEX_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX */ - -#ifdef LEXBOR_STR_RES_MAP_LOWERCASE -#ifndef LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_lowercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_lowercase[256] = +{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, @@ -133,14 +109,10 @@ static const lxb_char_t lexbor_str_res_map_lowercase[] = { 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_LOWERCASE */ - -#ifdef LEXBOR_STR_RES_MAP_UPPERCASE -#ifndef LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_uppercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_uppercase[256] = +{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, @@ -171,14 +143,10 @@ static const lxb_char_t lexbor_str_res_map_uppercase[] = { 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_UPPERCASE */ - -#ifdef LEXBOR_STR_RES_REPLACEMENT_CHARACTER -#ifndef LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED -#define LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED -static const size_t lexbor_str_res_replacement_character[] = { +LXB_API const size_t +lexbor_str_res_replacement_character[160] = +{ 65533, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, @@ -198,14 +166,10 @@ static const size_t lexbor_str_res_replacement_character[] = { 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376 }; -#endif /* LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_REPLACEMENT_CHARACTER */ - -#ifdef LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#ifndef LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED -static const size_t lexbor_str_res_alphanumeric_character[] = { +LXB_API const size_t +lexbor_str_res_alphanumeric_character[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -236,14 +200,10 @@ static const size_t lexbor_str_res_alphanumeric_character[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER */ - -#ifdef LEXBOR_STR_RES_ALPHA_CHARACTER -#ifndef LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED -static const size_t lexbor_str_res_alpha_character[] = { +LXB_API const size_t +lexbor_str_res_alpha_character[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -274,14 +234,10 @@ static const size_t lexbor_str_res_alpha_character[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ALPHA_CHARACTER */ - -#ifdef LEXBOR_TOKENIZER_CHARS_MAP -#ifndef LEXBOR_TOKENIZER_CHARS_MAP_ENABLED -#define LEXBOR_TOKENIZER_CHARS_MAP_ENABLED -static const unsigned char lexbor_tokenizer_chars_map[] = { +LXB_API const unsigned char +lexbor_tokenizer_chars_map[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x02, 0xff, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -312,35 +268,24 @@ static const unsigned char lexbor_tokenizer_chars_map[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_TOKENIZER_CHARS_MAP_ENABLED */ -#endif /* LEXBOR_TOKENIZER_CHARS_MAP */ - -#ifdef LEXBOR_STR_RES_MAP_HEX_TO_CHAR -#ifndef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED -static const lxb_char_t lexbor_str_res_map_hex_to_char[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex_to_char[17] = +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00 }; -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR */ -#ifdef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE -#ifndef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex_to_char_lowercase[17] = +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x00 }; -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE */ - -#ifdef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE -#ifndef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED -static const char * lexbor_str_res_char_to_two_hex_value[257] = { +LXB_API const char * +lexbor_str_res_char_to_two_hex_value[257] = +{ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", @@ -375,13 +320,10 @@ static const char * lexbor_str_res_char_to_two_hex_value[257] = { "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF", NULL }; -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED */ -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE */ -#ifdef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE -#ifndef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED -static const char * lexbor_str_res_char_to_two_hex_value_lowercase[257] = { +LXB_API const char * +lexbor_str_res_char_to_two_hex_value_lowercase[257] = +{ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", @@ -416,5 +358,3 @@ static const char * lexbor_str_res_char_to_two_hex_value_lowercase[257] = { "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff", NULL }; -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE */ diff --git a/ext/lexbor/lexbor/core/strtod.c b/ext/lexbor/lexbor/core/strtod.c index 6389fc3156fc..2dad45c109b5 100644 --- a/ext/lexbor/lexbor/core/strtod.c +++ b/ext/lexbor/lexbor/core/strtod.c @@ -1,14 +1,36 @@ /* - * Copyright (C) Alexander Borisov - * - * Based on nxt_strtod.c from NGINX NJS project + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * An internal strtod() implementation based upon V8 src/strtod.cc - * without bignum support. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright 2012 the V8 project authors. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #include diff --git a/ext/lexbor/lexbor/core/strtod.h b/ext/lexbor/lexbor/core/strtod.h index 7f15706bc946..0f834bab4868 100644 --- a/ext/lexbor/lexbor/core/strtod.h +++ b/ext/lexbor/lexbor/core/strtod.h @@ -1,10 +1,36 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_strtod.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) Nginx, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #ifndef LEXBOR_STRTOD_H diff --git a/ext/lexbor/lexbor/css/at_rule.c b/ext/lexbor/lexbor/css/at_rule.c new file mode 100644 index 000000000000..6c5435d22e06 --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/at_rule.h" +#include "lexbor/css/css.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/at_rule/state.h" +#include "lexbor/css/at_rule/types.h" +#include "lexbor/css/at_rule/res.h" +#include "lexbor/core/serialize.h" + + +const lxb_css_entry_at_rule_data_t * +lxb_css_at_rule_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_at_rule_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_entry_at_rule_data_t * +lxb_css_at_rule_by_id(uintptr_t id) +{ + return &lxb_css_at_rule_data[id]; +} + +lxb_css_rule_at_t * +lxb_css_at_rule_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_at_rule_data_t **out_entry) +{ + void *prop; + const lxb_css_entry_at_rule_data_t *entry; + lxb_css_at_rule__custom_t *custom; + lxb_css_rule_at_t *at; + + at = lxb_css_rule_at_create(parser->memory); + if (at == NULL) { + return NULL; + } + + entry = lxb_css_at_rule_by_name(name, length); + if (entry == NULL) { + entry = lxb_css_at_rule_by_id(LXB_CSS_AT_RULE__CUSTOM); + + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + + custom = prop; + + (void) lexbor_str_init(&custom->name, parser->memory->mraw, length); + if (custom->name.data == NULL) { + goto failed; + } + + memcpy(custom->name.data, name, length); + + custom->name.length = length; + custom->name.data[custom->name.length] = 0x00; + } + else { + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + } + + at->type = entry->unique; + at->u.user = prop; + + if (out_entry != NULL) { + *out_entry = entry; + } + + return at; + +failed: + + if (prop != NULL) { + (void) entry->destroy(parser->memory, prop, true); + } + + if (at != NULL) { + (void) lxb_css_rule_at_destroy(at, true); + } + + if (out_entry != NULL) { + *out_entry = NULL; + } + + return NULL; +} + +void * +lxb_css_at_rule_destroy(lxb_css_memory_t *memory, void *value, + lxb_css_at_rule_type_t type, bool self_destroy) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return value; + } + + return data->destroy(memory, value, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_convert_to_undef(lxb_css_parser_t *parser, + lxb_css_rule_at_t *at) +{ + lxb_css_at_rule__undef_t *undef; + + undef = lxb_css_at_rule__undef_create(parser->memory); + if (undef == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + + undef->type = at->type; + + (void) lxb_css_at_rule_destroy(parser->memory, at, undef->type, false); + + at->type = LXB_CSS_AT_RULE__UNDEF; + at->u.undef = undef; + + return lxb_css_make_data(parser, &at->u.undef->prelude, + at->prelude_begin, at->prelude_end); +} + +lxb_status_t +lxb_css_at_rule_serialize(const void *style, lxb_css_at_rule_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return data->serialize(style, cb, ctx); +} + +lxb_status_t +lxb_css_at_rule_serialize_str(const void *style, lxb_css_at_rule_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return lxb_css_serialize_str_handler(style, str, mraw, data->serialize); +} + +lxb_status_t +lxb_css_at_rule_serialize_name(const void *style, lxb_css_at_rule_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + + if (type == LXB_CSS_AT_RULE__UNDEF) { + return lxb_css_at_rule__undef_serialize_name(style, cb, ctx); + } + else if (type == LXB_CSS_AT_RULE__CUSTOM) { + return lxb_css_at_rule__custom_serialize_name(style, cb, ctx); + } + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_at_rule_serialize_name_str(const void *style, lxb_css_at_rule_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_at_rule_data_t *data; + + if (type == LXB_CSS_AT_RULE__UNDEF) { + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_at_rule__undef_serialize_name); + } + else if (type == LXB_CSS_AT_RULE__CUSTOM) { + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_at_rule__custom_serialize_name); + } + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + if (str->data == NULL) { + lexbor_str_init(str, mraw, data->length); + if (str->data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + (void) lexbor_str_append(str, mraw, data->name, data->length); + + return LXB_STATUS_OK; +} + +/* _undef. */ + +void * +lxb_css_at_rule__undef_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule__undef_t)); +} + +void * +lxb_css_at_rule__undef_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_at_rule__undef_serialize(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_entry_at_rule_data_t *data; + const lxb_css_at_rule__undef_t *undef = at; + + static const lxb_char_t wc_str[] = " "; + static const lxb_char_t lb_str[] = "{"; + static const lxb_char_t rb_str[] = "}"; + static const lxb_char_t sm_str[] = ";"; + + data = lxb_css_at_rule_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + if (undef->prelude.data != NULL) { + lexbor_serialize_write(cb, wc_str, (sizeof(wc_str) - 1), ctx, status); + lexbor_serialize_write(cb, undef->prelude.data, undef->prelude.length, + ctx, status); + } + + if (undef->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(undef->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + else { + lexbor_serialize_write(cb, sm_str, (sizeof(sm_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_at_rule__undef_serialize_name(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + const lxb_css_at_rule__undef_t *undef = at; + + data = lxb_css_at_rule_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return cb(data->name, data->length, ctx); +} + +/* _custom. */ + +void * +lxb_css_at_rule__custom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule__custom_t)); +} + +void * +lxb_css_at_rule__custom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_at_rule__custom_serialize(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule__custom_t *custom = at; + + static const lxb_char_t ws_str[] = " "; + static const lxb_char_t lb_str[] = "{"; + static const lxb_char_t rb_str[] = "}"; + + + if (custom->prelude.data != NULL) { + lexbor_serialize_write(cb, ws_str, (sizeof(ws_str) - 1), ctx, status); + lexbor_serialize_write(cb, custom->prelude.data, custom->prelude.length, + ctx, status); + } + + if (custom->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(custom->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_at_rule__custom_serialize_name(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + const lxb_css_at_rule__custom_t *custom = at; + + return cb(custom->name.data, custom->name.length, ctx); +} + +/* Media. */ + +void * +lxb_css_at_rule_media_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule_media_t)); +} + +void * +lxb_css_at_rule_media_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_media_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx) +{ + return LXB_STATUS_OK; +} + +/* Namespace. */ + +void * +lxb_css_at_rule_namespace_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_at_rule_namespace_t)); +} + +void * +lxb_css_at_rule_namespace_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_namespace_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx) +{ + return LXB_STATUS_OK; +} + +/* Font-face. */ + +void * +lxb_css_at_rule_font_face_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_at_rule_font_face_t)); +} + +void * +lxb_css_at_rule_font_face_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_font_face_serialize(const void *font_face, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule_font_face_t *ff = font_face; + + static const lxb_char_t lb_str[] = " {"; + static const lxb_char_t rb_str[] = "}"; + + if (ff->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(ff->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/at_rule.h b/ext/lexbor/lexbor/css/at_rule.h index a11455c14cd0..cacfa4c8cf2d 100644 --- a/ext/lexbor/lexbor/css/at_rule.h +++ b/ext/lexbor/lexbor/css/at_rule.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -19,19 +19,19 @@ extern "C" { typedef struct { lxb_css_at_rule_type_t type; lexbor_str_t prelude; - lexbor_str_t block; + lxb_css_rule_list_t *block; } lxb_css_at_rule__undef_t; typedef struct { - lexbor_str_t name; - lexbor_str_t prelude; - lexbor_str_t block; + lexbor_str_t name; + lexbor_str_t prelude; + lxb_css_rule_list_t *block; } lxb_css_at_rule__custom_t; typedef struct { - uintptr_t reserved; + lxb_css_rule_list_t *block; } lxb_css_at_rule_media_t; @@ -40,17 +40,31 @@ typedef struct { } lxb_css_at_rule_namespace_t; +typedef struct { + lxb_css_rule_list_t *block; +} +lxb_css_at_rule_font_face_t; -LXB_API const lxb_css_entry_data_t * + +LXB_API const lxb_css_entry_at_rule_data_t * lxb_css_at_rule_by_name(const lxb_char_t *name, size_t length); -LXB_API const lxb_css_entry_data_t * +LXB_API const lxb_css_entry_at_rule_data_t * lxb_css_at_rule_by_id(uintptr_t id); +LXB_API lxb_css_rule_at_t * +lxb_css_at_rule_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_at_rule_data_t **out_entry); + LXB_API void * lxb_css_at_rule_destroy(lxb_css_memory_t *memory, void *value, lxb_css_at_rule_type_t type, bool self_destroy); +LXB_API lxb_status_t +lxb_css_at_rule_convert_to_undef(lxb_css_parser_t *parser, + lxb_css_rule_at_t *at); + LXB_API lxb_status_t lxb_css_at_rule_serialize(const void *style, lxb_css_at_rule_type_t type, lexbor_serialize_cb_f cb, void *ctx); @@ -73,10 +87,6 @@ LXB_API void * lxb_css_at_rule__undef_destroy(lxb_css_memory_t *memory, void *style, bool self_destroy); LXB_API lxb_status_t -lxb_css_at_rule__undef_make(lxb_css_parser_t *parser, - lxb_css_at_rule__undef_t *undef, - const lxb_css_syntax_at_rule_offset_t *at_rule); -LXB_API lxb_status_t lxb_css_at_rule__undef_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); LXB_API lxb_status_t @@ -92,10 +102,6 @@ LXB_API void * lxb_css_at_rule__custom_destroy(lxb_css_memory_t *memory, void *style, bool self_destroy); LXB_API lxb_status_t -lxb_css_at_rule__custom_make(lxb_css_parser_t *parser, - lxb_css_at_rule__custom_t *custom, - const lxb_css_syntax_at_rule_offset_t *at_rule); -LXB_API lxb_status_t lxb_css_at_rule__custom_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); LXB_API lxb_status_t @@ -126,6 +132,18 @@ LXB_API lxb_status_t lxb_css_at_rule_namespace_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); +/* Font-face. */ + +LXB_API void * +lxb_css_at_rule_font_face_create(lxb_css_memory_t *memory); + +LXB_API void * +lxb_css_at_rule_font_face_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy); + +LXB_API lxb_status_t +lxb_css_at_rule_font_face_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/at_rule/const.h b/ext/lexbor/lexbor/css/at_rule/const.h index 961f933a2367..29ba3dd95488 100644 --- a/ext/lexbor/lexbor/css/at_rule/const.h +++ b/ext/lexbor/lexbor/css/at_rule/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -21,9 +21,10 @@ enum { LXB_CSS_AT_RULE__UNDEF = 0x0000, LXB_CSS_AT_RULE__CUSTOM = 0x0001, - LXB_CSS_AT_RULE_MEDIA = 0x0002, - LXB_CSS_AT_RULE_NAMESPACE = 0x0003, - LXB_CSS_AT_RULE__LAST_ENTRY = 0x0004 + LXB_CSS_AT_RULE_FONT_FACE = 0x0002, + LXB_CSS_AT_RULE_MEDIA = 0x0003, + LXB_CSS_AT_RULE_NAMESPACE = 0x0004, + LXB_CSS_AT_RULE__LAST_ENTRY = 0x0005 }; typedef uintptr_t lxb_css_at_rule_type_t; diff --git a/ext/lexbor/lexbor/css/at_rule/res.h b/ext/lexbor/lexbor/css/at_rule/res.h index 026a88ae0dd6..6604fb923f40 100644 --- a/ext/lexbor/lexbor/css/at_rule/res.h +++ b/ext/lexbor/lexbor/css/at_rule/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -18,16 +18,19 @@ #include "lexbor/css/at_rule/const.h" -static const lxb_css_entry_data_t lxb_css_at_rule_data[LXB_CSS_AT_RULE__LAST_ENTRY] = +static const lxb_css_entry_at_rule_data_t lxb_css_at_rule_data[LXB_CSS_AT_RULE__LAST_ENTRY] = { - {(lxb_char_t *) "#undef", 6, LXB_CSS_AT_RULE__UNDEF, lxb_css_at_rule_state__undef, + {(lxb_char_t *) "#undef", 6, LXB_CSS_AT_RULE__UNDEF, &lxb_css_at_rule__undef_cb, lxb_css_at_rule__undef_create, lxb_css_at_rule__undef_destroy, lxb_css_at_rule__undef_serialize, (void *) (uintptr_t) LXB_CSS_AT_RULE__UNDEF}, - {(lxb_char_t *) "#сustom", 7, LXB_CSS_AT_RULE__CUSTOM, lxb_css_at_rule_state__custom, + {(lxb_char_t *) "#сustom", 7, LXB_CSS_AT_RULE__CUSTOM, &lxb_css_at_rule__custom_cb, lxb_css_at_rule__custom_create, lxb_css_at_rule__custom_destroy, lxb_css_at_rule__custom_serialize, (void *) (uintptr_t) LXB_CSS_AT_RULE__CUSTOM}, - {(lxb_char_t *) "media", 5, LXB_CSS_AT_RULE_MEDIA, lxb_css_at_rule_state_media, + {(lxb_char_t *) "font-face", 9, LXB_CSS_AT_RULE_FONT_FACE, &lxb_css_at_rule_font_face_cb, + lxb_css_at_rule_font_face_create, lxb_css_at_rule_font_face_destroy, lxb_css_at_rule_font_face_serialize, + NULL}, + {(lxb_char_t *) "media", 5, LXB_CSS_AT_RULE_MEDIA, &lxb_css_at_rule_media_cb, lxb_css_at_rule_media_create, lxb_css_at_rule_media_destroy, lxb_css_at_rule_media_serialize, NULL}, - {(lxb_char_t *) "namespace", 9, LXB_CSS_AT_RULE_NAMESPACE, lxb_css_at_rule_state_namespace, + {(lxb_char_t *) "namespace", 9, LXB_CSS_AT_RULE_NAMESPACE, &lxb_css_at_rule_namespace_cb, lxb_css_at_rule_namespace_create, lxb_css_at_rule_namespace_destroy, lxb_css_at_rule_namespace_serialize, NULL} }; @@ -38,7 +41,7 @@ static const lexbor_shs_entry_t lxb_css_at_rule_shs[6] = {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"media", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_MEDIA], 5, 0}, - {NULL, NULL, 0, 0}, + {"font-face", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_FONT_FACE], 9, 0}, {"namespace", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_NAMESPACE], 9, 0} }; diff --git a/ext/lexbor/lexbor/css/at_rule/state.c b/ext/lexbor/lexbor/css/at_rule/state.c new file mode 100644 index 000000000000..4df2f6085adf --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule/state.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/at_rule.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/blank.h" +#include "lexbor/css/at_rule/state.h" + + +/* Undef */ + +bool +lxb_css_at_rule__undef_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + /* Skip all prelude. */ + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule__undef_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &at->u.undef->prelude, + at->prelude_begin, at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__undef_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule__undef_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + /* For _UNDEF and _CUSTOM, access here is not possible. */ + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule__undef_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + /* + * Here we do not check for failed because it cannot happen; we do not call + * failed anywhere in _UNDEF and _CUSTOM, we simply skip the tokens. + */ + + at->u.undef->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Custom */ + +bool +lxb_css_at_rule__custom_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_at_rule__undef_prelude(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule__custom_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &at->u.custom->prelude, + at->prelude_begin, at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__custom_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule__custom_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule__custom_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + /* + * Here we do not check for failed because it cannot happen; we do not call + * failed anywhere in _UNDEF and _CUSTOM, we simply skip the tokens. + */ + + at->u.custom->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Namespace */ + +bool +lxb_css_at_rule_namespace_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_namespace_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_namespace_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_parser_failed_set(parser, true); + + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_namespace_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_namespace_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + if (failed) { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = lxb_css_syntax_returned(parser); + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Media */ + +bool +lxb_css_at_rule_media_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_media_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_media_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_media_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_media_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *list = lxb_css_syntax_returned(parser); + + if (list != NULL && !failed) { + at->u.media->block = list; + } + else { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = list; + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Font-face */ + +bool +lxb_css_at_rule_font_face_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + if (token->type != LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_font_face_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_font_face_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_font_face_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_font_face_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + if (!failed) { + at->u.font_face->block = block; + } + else { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = block; + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/at_rule/state.h b/ext/lexbor/lexbor/css/at_rule/state.h index 65e17e40d0ff..337a23c86714 100644 --- a/ext/lexbor/lexbor/css/at_rule/state.h +++ b/ext/lexbor/lexbor/css/at_rule/state.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,18 +15,110 @@ extern "C" { LXB_API bool -lxb_css_at_rule_state__undef(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule__undef_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__undef_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__undef_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); LXB_API bool -lxb_css_at_rule_state__custom(lxb_css_parser_t *parser, +lxb_css_at_rule__undef_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__undef_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule__custom_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__custom_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__custom_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule__custom_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__custom_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule_namespace_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_namespace_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_namespace_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule_namespace_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_namespace_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule_media_prelude(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_media_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_media_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); LXB_API bool -lxb_css_at_rule_state_media(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule_media_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_media_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + LXB_API bool -lxb_css_at_rule_state_namespace(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule_font_face_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_font_face_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_font_face_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule_font_face_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_font_face_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/css/at_rule/types.h b/ext/lexbor/lexbor/css/at_rule/types.h new file mode 100644 index 000000000000..1079bb632230 --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule/types.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +/* + * Caution! + * This file generated by the script "utils/lexbor/css/names.py"! + * Do not change this file! + */ + + +#ifndef LXB_CSS_AT_RULE_TYPES_H +#define LXB_CSS_AT_RULE_TYPES_H + + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule__undef_cb = { + .prelude = lxb_css_at_rule__undef_prelude, + .prelude_end = lxb_css_at_rule__undef_prelude_end, + .block = lxb_css_at_rule__undef_block, + .cb.failed = lxb_css_at_rule__undef_prelude_failed, + .cb.end = lxb_css_at_rule__undef_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule__custom_cb = { + .prelude = lxb_css_at_rule__custom_prelude, + .prelude_end = lxb_css_at_rule__custom_prelude_end, + .block = lxb_css_at_rule__custom_block, + .cb.failed = lxb_css_at_rule__custom_prelude_failed, + .cb.end = lxb_css_at_rule__custom_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_font_face_cb = { + .prelude = lxb_css_at_rule_font_face_prelude, + .prelude_end = lxb_css_at_rule_font_face_prelude_end, + .block = lxb_css_at_rule_font_face_block, + .cb.failed = lxb_css_at_rule_font_face_prelude_failed, + .cb.end = lxb_css_at_rule_font_face_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_media_cb = { + .prelude = lxb_css_at_rule_media_prelude, + .prelude_end = lxb_css_at_rule_media_prelude_end, + .block = lxb_css_at_rule_media_block, + .cb.failed = lxb_css_at_rule_media_prelude_failed, + .cb.end = lxb_css_at_rule_media_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_namespace_cb = { + .prelude = lxb_css_at_rule_namespace_prelude, + .prelude_end = lxb_css_at_rule_namespace_prelude_end, + .block = lxb_css_at_rule_namespace_block, + .cb.failed = lxb_css_at_rule_namespace_prelude_failed, + .cb.end = lxb_css_at_rule_namespace_end +}; + + + +#endif /* LXB_CSS_AT_RULE_TYPES_H */ diff --git a/ext/lexbor/lexbor/css/base.h b/ext/lexbor/lexbor/css/base.h index 3d3cdc6a7f28..26712ce7048f 100644 --- a/ext/lexbor/lexbor/css/base.h +++ b/ext/lexbor/lexbor/css/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2025 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -18,7 +18,7 @@ extern "C" { #define LXB_CSS_VERSION_MAJOR 1 -#define LXB_CSS_VERSION_MINOR 3 +#define LXB_CSS_VERSION_MINOR 4 #define LXB_CSS_VERSION_PATCH 0 #define LXB_CSS_VERSION_STRING \ @@ -45,6 +45,8 @@ typedef struct lxb_css_parser_error lxb_css_parser_error_t; typedef struct lxb_css_syntax_tokenizer lxb_css_syntax_tokenizer_t; typedef struct lxb_css_syntax_token lxb_css_syntax_token_t; +/* Callbacks. */ + typedef bool (*lxb_css_parser_state_f)(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); @@ -82,6 +84,21 @@ typedef struct { } lxb_css_entry_data_t; +typedef struct { + lxb_char_t *name; + size_t length; + uintptr_t unique; + + /* const lxb_css_syntax_cb_at_rule_t */ + const void *cbs; + + lxb_css_style_create_f create; + lxb_css_style_destroy_f destroy; + lxb_css_style_serialize_f serialize; + void *initial; +} +lxb_css_entry_at_rule_data_t; + typedef struct { lxb_char_t *name; size_t length; diff --git a/ext/lexbor/lexbor/css/blank.c b/ext/lexbor/lexbor/css/blank.c new file mode 100644 index 000000000000..80e60f76e198 --- /dev/null +++ b/ext/lexbor/lexbor/css/blank.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/blank.h" +#include "lexbor/css/state.h" +#include "lexbor/css/css.h" +#include "lexbor/css/at_rule/state.h" + + +static bool +lxb_css_blank_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule); + +static bool +lxb_css_blank_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_blank_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +static bool +lxb_css_blank_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_blank_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_blank_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_blank_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_blank_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_blank_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_blank_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_css_parser_state_f +lxb_css_blank_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +static bool +lxb_css_blank_declaration_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +static lxb_status_t +lxb_css_blank_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static bool +lxb_css_blank_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + + +static const lxb_css_syntax_cb_list_rules_t lxb_css_blank_list_rules = { + .at_rule = lxb_css_blank_at_rule_begin, + .qualified_rule = lxb_css_blank_qualified_rule_begin, + .next = lxb_css_blank_list_rules_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_blank_list_rules_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_blank_at_rule = { + .prelude = lxb_css_blank_at_rule_prelude, + .prelude_end = lxb_css_blank_at_rule_prelude_end, + .block = lxb_css_blank_at_rule_block_begin, + .cb.failed = lxb_css_blank_at_rule_prelude_failed, + .cb.end = lxb_css_blank_at_rule_end +}; + +static const lxb_css_syntax_cb_qualified_rule_t lxb_css_blank_qualified_rule = { + .prelude = lxb_css_blank_qualified_rule_prelude, + .prelude_end = lxb_css_blank_qualified_rule_prelude_end, + .block = lxb_css_blank_qualified_rule_block_begin, + .cb.failed = lxb_css_blank_qualified_rule_prelude_failed, + .cb.end = lxb_css_blank_qualified_rule_end +}; + +static const lxb_css_syntax_cb_block_t lxb_css_blank_block = { + .at_rule = lxb_css_blank_at_rule_begin, + .declarations = lxb_css_blank_declarations_begin, + .qualified_rule = lxb_css_blank_qualified_rule_begin, + .next = lxb_css_blank_block_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_blank_block_end, +}; + +static const lxb_css_syntax_cb_declarations_t lxb_css_blank_declaration = { + .name = lxb_css_blank_declaration_name, + .end = lxb_css_blank_declaration_end, + .cb.failed = lxb_css_blank_declarations_bad, + .cb.end = lxb_css_blank_declarations_end +}; + + +const lxb_css_syntax_cb_list_rules_t * +lxb_css_blank_cb_list_rules(void) +{ + return &lxb_css_blank_list_rules; +} + +const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_cb_at_rule(void) +{ + return &lxb_css_blank_at_rule; +} + +const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_cb_qualified_rule(void) +{ + return &lxb_css_blank_qualified_rule; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_blank_cb_block(void) +{ + return &lxb_css_blank_block; +} + +const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_cb_declarations(void) +{ + return &lxb_css_blank_declaration; +} + +static bool +lxb_css_blank_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule) +{ + return &lxb_css_blank_at_rule; +} + +static bool +lxb_css_blank_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_block; +} + +static bool +lxb_css_blank_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_qualified_rule; +} + +static bool +lxb_css_blank_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_block; +} + +static bool +lxb_css_blank_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static bool +lxb_css_blank_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_declaration; +} + +static lxb_css_parser_state_f +lxb_css_blank_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_blank_declaration_value; +} + +static bool +lxb_css_blank_declaration_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed) +{ + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_blank_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static bool +lxb_css_blank_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/blank.h b/ext/lexbor/lexbor/css/blank.h new file mode 100644 index 000000000000..05a13bfa1207 --- /dev/null +++ b/ext/lexbor/lexbor/css/blank.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LXB_CSS_BLANK_H +#define LXB_CSS_BLANK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/css/base.h" +#include "lexbor/css/syntax/syntax.h" + + +LXB_API const lxb_css_syntax_cb_list_rules_t * +lxb_css_blank_cb_list_rules(void); + +LXB_API const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_cb_at_rule(void); + +LXB_API const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_cb_qualified_rule(void); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_blank_cb_block(void); + +LXB_API const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_cb_declarations(void); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LXB_CSS_BLANK_H */ diff --git a/ext/lexbor/lexbor/css/css.c b/ext/lexbor/lexbor/css/css.c index 3b6f0cb0f2f4..68c6c977e834 100644 --- a/ext/lexbor/lexbor/css/css.c +++ b/ext/lexbor/lexbor/css/css.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -155,15 +155,12 @@ lxb_css_memory_ref_dec_destroy(lxb_css_memory_t *memory) lxb_status_t lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, - uintptr_t begin, uintptr_t end) + size_t begin, size_t end) { - size_t length, offlen, len; - const lxb_char_t *pos; - const lexbor_str_t *tmp; + size_t length; + const lxb_char_t *p; - tmp = &parser->str; - - offlen = begin - parser->offset; + p = parser->tkz->in_begin; length = end - begin; if (str->data == NULL) { @@ -173,31 +170,9 @@ lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, } } - if (tmp->length > offlen) { - len = tmp->length - offlen; - - if (len >= length) { - memcpy(str->data + str->length, tmp->data + offlen, length); - goto done; - } - else { - memcpy(str->data + str->length, tmp->data + offlen, len); - } - - str->length += len; - - pos = parser->pos; - length -= len; - } - else { - pos = parser->pos + (offlen - tmp->length); - } - - memcpy(str->data + str->length, pos, length); - -done: + memcpy(str->data, p + begin, length); - str->length += length; + str->length = length; str->data[str->length] = '\0'; return LXB_STATUS_OK; diff --git a/ext/lexbor/lexbor/css/css.h b/ext/lexbor/lexbor/css/css.h index bb12978e3ee2..4ba7152334ba 100644 --- a/ext/lexbor/lexbor/css/css.h +++ b/ext/lexbor/lexbor/css/css.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -35,7 +35,7 @@ extern "C" { LXB_API lxb_status_t lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, - uintptr_t begin, uintptr_t end); + size_t begin, size_t end); LXB_API lxb_char_t * lxb_css_serialize_char_handler(const void *style, lxb_css_style_serialize_f cb, diff --git a/ext/lexbor/lexbor/css/declaration.c b/ext/lexbor/lexbor/css/declaration.c new file mode 100644 index 000000000000..e27571486f1f --- /dev/null +++ b/ext/lexbor/lexbor/css/declaration.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2022-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/declaration.h" + + +lxb_css_rule_declaration_t * +lxb_css_declaration_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_data_t **out_entry) +{ + void *prop; + const lxb_css_entry_data_t *entry; + lxb_css_property__custom_t *custom; + lxb_css_rule_declaration_t *declar; + + declar = lxb_css_rule_declaration_create(parser->memory); + if (declar == NULL) { + return NULL; + } + + entry = lxb_css_property_by_name(name, length); + if (entry == NULL) { + entry = lxb_css_property_by_id(LXB_CSS_PROPERTY__CUSTOM); + + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + + custom = prop; + + (void) lexbor_str_init(&custom->name, parser->memory->mraw, length); + if (custom->name.data == NULL) { + goto failed; + } + + memcpy(custom->name.data, name, length); + + custom->name.length = length; + custom->name.data[custom->name.length] = 0x00; + } + else { + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + } + + declar->type = entry->unique; + declar->u.user = prop; + + if (out_entry != NULL) { + *out_entry = entry; + } + + return declar; + +failed: + + if (prop != NULL) { + (void) entry->destroy(parser->memory, prop, true); + } + + if (declar != NULL) { + (void) lxb_css_rule_declaration_destroy(declar, true); + } + + if (out_entry != NULL) { + *out_entry = NULL; + } + + return NULL; +} + +lxb_css_rule_declaration_list_t * +lxb_css_declaration_list_parse(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + return lxb_css_syntax_parse_declarations(parser, + lxb_css_state_cb_declarations(), + data, length); +} diff --git a/ext/lexbor/lexbor/css/declaration.h b/ext/lexbor/lexbor/css/declaration.h index 1ea414e10bc7..53ab061aaa4c 100644 --- a/ext/lexbor/lexbor/css/declaration.h +++ b/ext/lexbor/lexbor/css/declaration.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Alexander Borisov + * Copyright (C) 2022-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,19 +15,14 @@ extern "C" { #include "lexbor/core/mraw.h" -LXB_API lxb_status_t -lxb_css_declaration_list_prepare(lxb_css_parser_t *parser, - lxb_css_memory_t *mem); +LXB_API lxb_css_rule_declaration_t * +lxb_css_declaration_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_data_t **out_entry); -LXB_API lxb_css_rule_declaration_list_t * -lxb_css_declaration_list_process(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - -LXB_API void -lxb_css_declaration_list_finish(lxb_css_parser_t *parser); LXB_API lxb_css_rule_declaration_list_t * -lxb_css_declaration_list_parse(lxb_css_parser_t *parser, lxb_css_memory_t *mem, +lxb_css_declaration_list_parse(lxb_css_parser_t *parser, const lxb_char_t *data, size_t length); diff --git a/ext/lexbor/lexbor/css/log.c b/ext/lexbor/lexbor/css/log.c index 08f6fc4fc5a1..d993e4715c62 100644 --- a/ext/lexbor/lexbor/css/log.c +++ b/ext/lexbor/lexbor/css/log.c @@ -152,7 +152,7 @@ lxb_css_log_format(lxb_css_log_t *log, lxb_css_log_type_t type, return NULL; } - msg = lxb_css_log_push(log, LXB_CSS_LOG_SYNTAX_ERROR, psize); + msg = lxb_css_log_push(log, type, psize); if (msg == NULL) { return NULL; } diff --git a/ext/lexbor/lexbor/css/parser.c b/ext/lexbor/lexbor/css/parser.c index 5ceffed0f970..625143864888 100644 --- a/ext/lexbor/lexbor/css/parser.c +++ b/ext/lexbor/lexbor/css/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -73,7 +73,6 @@ lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz) parser->rules->context = NULL; /* Temp */ - parser->pos = NULL; parser->str.length = 0; parser->str_size = 4096; @@ -93,13 +92,35 @@ lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz) parser->types_pos = NULL; parser->types_end = NULL; parser->stage = LXB_CSS_PARSER_CLEAN; - parser->receive_endings = false; parser->status = LXB_STATUS_OK; parser->fake_null = false; + parser->token_end.type = LXB_CSS_SYNTAX_TOKEN__END; return LXB_STATUS_OK; } +lxb_status_t +lxb_css_parser_selectors_init(lxb_css_parser_t *parser) +{ + lxb_status_t status; + + parser->selectors = lxb_css_selectors_create(); + status = lxb_css_selectors_init(parser->selectors); + if (status != LXB_STATUS_OK) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); + } + + return status; +} + +void +lxb_css_parser_selectors_destroy(lxb_css_parser_t *parser) +{ + if (parser->selectors != NULL) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); + } +} + void lxb_css_parser_clean(lxb_css_parser_t *parser) { @@ -111,7 +132,6 @@ lxb_css_parser_clean(lxb_css_parser_t *parser) parser->types_pos = parser->types_begin; parser->stage = LXB_CSS_PARSER_CLEAN; parser->status = LXB_STATUS_OK; - parser->pos = NULL; parser->str.length = 0; parser->fake_null = false; } @@ -331,6 +351,14 @@ lxb_css_parser_unexpected_data_status(lxb_css_parser_t *parser, return LXB_STATUS_ERROR_UNEXPECTED_DATA; } +void * +lxb_css_parser_memory_fail_null(lxb_css_parser_t *parser) +{ + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + parser->loop = false; + return NULL; +} + bool lxb_css_parser_memory_fail(lxb_css_parser_t *parser) { @@ -347,3 +375,189 @@ lxb_css_parser_memory_fail_status(lxb_css_parser_t *parser) return LXB_STATUS_ERROR_MEMORY_ALLOCATION; } + +/* + * No-inline functions for ABI. + */ +lxb_status_t +lxb_css_parser_status_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_status(parser); +} + +lxb_css_memory_t * +lxb_css_parser_memory_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_memory(parser); +} + +void +lxb_css_parser_memory_set_noi(lxb_css_parser_t *parser, lxb_css_memory_t *memory) +{ + lxb_css_parser_memory_set(parser, memory); +} + +lxb_css_selectors_t * +lxb_css_parser_selectors_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_selectors(parser); +} + +void +lxb_css_parser_selectors_set_noi(lxb_css_parser_t *parser, + lxb_css_selectors_t *selectors) +{ + lxb_css_parser_selectors_set(parser, selectors); +} + +bool +lxb_css_parser_is_running_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_is_running(parser); +} + +bool +lxb_css_parser_status_is_unexpected_data_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_status_is_unexpected_data(parser); +} + +void +lxb_css_parser_failed_set_noi(lxb_css_parser_t *parser, bool is) +{ + lxb_css_parser_failed_set(parser, is); +} + +void +lxb_css_parser_failed_set_by_id_noi(lxb_css_parser_t *parser, int idx, bool is) +{ + lxb_css_parser_failed_set_by_id(parser, idx, is); +} + +bool +lxb_css_parser_is_failed_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_is_failed(parser); +} + +void +lxb_css_parser_set_ok_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_set_ok(parser); +} + +const lxb_char_t * +lxb_css_parser_buffer_noi(lxb_css_parser_t *parser, size_t *length) +{ + return lxb_css_parser_buffer(parser, length); +} + +void +lxb_css_parser_buffer_set_noi(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + lxb_css_parser_buffer_set(parser, data, length); +} + +lxb_css_parser_state_f +lxb_css_parser_state_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_state(parser); +} + +void +lxb_css_parser_state_set_noi(lxb_css_parser_t *parser, lxb_css_parser_state_f state) +{ + lxb_css_parser_state_set(parser, state); +} + +lxb_css_syntax_rule_t * +lxb_css_parser_current_rule_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_current_rule(parser); +} + +size_t +lxb_css_parser_rule_deep_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_rule_deep(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_pop_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_pop(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_to_root_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_to_root(parser); +} + +bool +lxb_css_parser_states_set_back_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_set_back(parser); +} + +void +lxb_css_parser_states_clean_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_clean(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_current_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_current(parser); +} + +void +lxb_css_parser_states_set_noi(lxb_css_parser_state_t *states, + lxb_css_parser_state_f state, void *context) +{ + lxb_css_parser_states_set(states, state, context); +} + +void +lxb_css_parser_states_up_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_up(parser); +} + +void +lxb_css_parser_states_down_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_down(parser); +} + +lxb_css_log_t * +lxb_css_parser_log_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_log(parser); +} + +const lxb_css_syntax_token_t * +lxb_css_parser_token_end_noi(lxb_css_parser_t *parser, size_t offset) +{ + return lxb_css_parser_token_end(parser, offset); +} + +void +lxb_css_parser_set_context_noi(lxb_css_parser_t *parser, void *ctx) +{ + lxb_css_parser_set_context(parser, ctx); +} + +void +lxb_css_syntax_set_return_noi(lxb_css_parser_t *parser, void *value) +{ + lxb_css_syntax_set_return(parser, value); +} + +void * +lxb_css_syntax_returned_noi(lxb_css_parser_t *parser) +{ + return lxb_css_syntax_returned(parser); +} diff --git a/ext/lexbor/lexbor/css/parser.h b/ext/lexbor/lexbor/css/parser.h index 9a4dfae0b702..d703dcc2f13d 100644 --- a/ext/lexbor/lexbor/css/parser.h +++ b/ext/lexbor/lexbor/css/parser.h @@ -1,6 +1,5 @@ /* - - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -70,7 +69,6 @@ extern "C" { } \ while (false) - #define lxb_css_parser_token_status_wo_ws_m(parser, token) \ do { \ if ((token = lxb_css_syntax_parser_token(parser)) == NULL) { \ @@ -129,49 +127,44 @@ typedef enum { lxb_css_parser_stage_t; struct lxb_css_parser { - lxb_css_parser_state_f block; - void *context; - /* Modules */ - lxb_css_syntax_tokenizer_t *tkz; - lxb_css_selectors_t *selectors; - lxb_css_selectors_t *old_selectors; + lxb_css_syntax_tokenizer_t *tkz; + lxb_css_selectors_t *selectors; /* Memory for all structures. */ - lxb_css_memory_t *memory; - lxb_css_memory_t *old_memory; + lxb_css_memory_t *memory; /* Syntax parse rules. */ - lxb_css_syntax_rule_t *rules_begin; - lxb_css_syntax_rule_t *rules_end; - lxb_css_syntax_rule_t *rules; + lxb_css_syntax_rule_t *rules_begin; + lxb_css_syntax_rule_t *rules_end; + lxb_css_syntax_rule_t *rules; /* States */ - lxb_css_parser_state_t *states_begin; - lxb_css_parser_state_t *states_end; - lxb_css_parser_state_t *states; + lxb_css_parser_state_t *states_begin; + lxb_css_parser_state_t *states_end; + lxb_css_parser_state_t *states; /* Types */ - lxb_css_syntax_token_type_t *types_begin; - lxb_css_syntax_token_type_t *types_end; - lxb_css_syntax_token_type_t *types_pos; + lxb_css_syntax_token_type_t *types_begin; + lxb_css_syntax_token_type_t *types_end; + lxb_css_syntax_token_type_t *types_pos; - const lxb_char_t *pos; - uintptr_t offset; + lxb_css_syntax_token_t token_end; - lexbor_str_t str; - size_t str_size; + lexbor_str_t str; + size_t str_size; - lxb_css_log_t *log; + lxb_css_log_t *log; - lxb_css_parser_stage_t stage; + lxb_css_parser_stage_t stage; - bool loop; - bool fake_null; - bool my_tkz; - bool receive_endings; + lxb_css_syntax_declaration_offset_t offset; - lxb_status_t status; + bool loop; + bool fake_null; + bool my_tkz; + + lxb_status_t status; }; struct lxb_css_parser_state { @@ -185,47 +178,197 @@ struct lxb_css_parser_error { }; +/* + * Create a new CSS parser object. + * + * @return lxb_css_parser_t* if successful, otherwise NULL. + */ LXB_API lxb_css_parser_t * lxb_css_parser_create(void); +/* + * Initialize the CSS parser with a tokenizer. + * + * @param[in] parser Required. The CSS parser object. + * If NULL, the function returns + * LXB_STATUS_ERROR_OBJECT_IS_NULL. + * @param[in] tkz Optional. The tokenizer object. + * If NULL, a new tokenizer will be created and used. + * (In that case the parser manages the tokenizer lifetime.) + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz); +/* + * Initialize the Selectors module in the parser. + * + * Note: + * Be sure to destroy the Selectors object you created yourself using + * the lxb_css_parser_selectors_destroy() function. + * + * @param[in] parser Required. The CSS parser object. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ +LXB_API lxb_status_t +lxb_css_parser_selectors_init(lxb_css_parser_t *parser); + +/* + * Destroy the selectors module in the parser. + * + * @param[in] parser Required. The CSS parser object. + */ +LXB_API void +lxb_css_parser_selectors_destroy(lxb_css_parser_t *parser); + +/* + * Clean the parser object. + * + * This resets internal parser state, but keeps allocated memory so the parser + * can be reused. + * + * @param[in] parser Required. The CSS parser object. + */ LXB_API void lxb_css_parser_clean(lxb_css_parser_t *parser); +/* + * Erase the parser object. + * + * This resets internal parser state and releases internal allocations owned by + * the parser so it can be re-initialized. + * + * @param[in] parser Required. The CSS parser object. + */ LXB_API void lxb_css_parser_erase(lxb_css_parser_t *parser); +/* + * Destroy the parser object. + * + * @param[in] parser Optional. The CSS parser object. + * If NULL, the function returns NULL. + * @param[in] self_destroy Optional flag. + * If true, also frees the parser object itself. + * If false, only inner resources are freed and the + * parser object remains valid. + * + * @return parser if self_destroy is false, otherwise NULL. + */ LXB_API lxb_css_parser_t * lxb_css_parser_destroy(lxb_css_parser_t *parser, bool self_destroy); -LXB_API lxb_css_parser_state_t * -lxb_css_parser_states_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state, - void *context, bool stop); - -LXB_API lxb_css_parser_state_t * -lxb_css_parser_states_next(lxb_css_parser_t *parser, - lxb_css_parser_state_f next, - lxb_css_parser_state_f back, void *ctx, bool root); - -LXB_API lxb_status_t -lxb_css_parser_types_push(lxb_css_parser_t *parser, - lxb_css_syntax_token_type_t type); - +/* + * Stop the parser main loop. + * + * This is a helper for state callbacks that want to immediately stop parsing + * without marking the current rule as failed. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_stop(lxb_css_parser_t *parser); +/* + * Fail the parser with a status and stop the main loop. + * + * This is used for hard errors (OOM, overflow, etc.). It sets parser->status + * and stops the parser loop. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] status Required. Status code describing the failure. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_fail(lxb_css_parser_t *parser, lxb_status_t status); +/* + * Mark the current token as unexpected. + * + * This is a specialized helper for the common "unexpected data" parse error. + * It sets parser->status to LXB_STATUS_ERROR_UNEXPECTED_DATA and marks the + * current rule as failed. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_unexpected(lxb_css_parser_t *parser); +/* + * Mark parsing of the current grammar/rule as successful. + * + * Why this function exists: + * - Most callbacks in the CSS parser work as a state machine: each callback + * receives the current token and returns bool to decide what to do next. + * - "Success" is not just a bool. The parser must switch to a special + * lxb_css_state_success state to properly handle trailing whitespace and + * the end-of-input token. + * - If you don't consume all tokens up to LXB_CSS_SYNTAX_TOKEN__END in the + * current rule and call this function, the parser will switch to "failed" + * mode. This is the same as calling the lxb_css_parser_failed() function. + * The exception is the LXB_CSS_SYNTAX_TOKEN_WHITESPACE token. If you are + * sure that only this token remains, the parser will simply exclude it. + * + * What it does: + * - Sets the current rule state to lxb_css_state_success. + * - Does not stop the parser loop by itself. + * + * Typical usage: + * - In css/property/state.c, after you have parsed and consumed the last token + * of a property value, you do: + * return lxb_css_parser_success(parser); + * - That transfers control to lxb_css_state_success, which consumes any + * whitespace and completes on LXB_CSS_SYNTAX_TOKEN__END. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_success(lxb_css_parser_t *parser); +/* + * Mark parsing of the current grammar/rule as failed. + * + * Why this function exists: + * - In the state machine, failure is also not "just return false". The parser + * needs to switch to a rule-specific recovery state so it can safely skip + * input until it is allowed to stop (usually until end-of-input or a known + * synchronisation point). + * + * What it does: + * - Sets the current rule state to the rule-specific "failed" handler + * (rule->cbx.cb->failed). + * - Sets rule->failed = true. + * - Does not directly change parser->status. Use lxb_css_parser_fail() or + * lxb_css_parser_unexpected() when you need a concrete status code. + * + * Typical usage: + * - In css/property/state.c, if a token doesn't match the expected grammar, + * you do: + * return lxb_css_parser_failed(parser); + * - That switches the parser into the failed handler. For properties this lets + * the parser consume/skip tokens until it reaches LXB_CSS_SYNTAX_TOKEN__END. + * (See lxb_css_state_failed(): it consumes tokens until end, then calls + * lxb_css_parser_success() to finish.) + * + * Important! + * The user sets the callback to "failed" and must decide what to do in this + * situation. If the user does not consume all tokens before + * LXB_CSS_SYNTAX_TOKEN__END, there will be an infinite loop. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ + LXB_API bool lxb_css_parser_failed(lxb_css_parser_t *parser); @@ -240,12 +383,64 @@ LXB_API lxb_status_t lxb_css_parser_unexpected_data_status(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token); +LXB_API void * +lxb_css_parser_memory_fail_null(lxb_css_parser_t *parser); + LXB_API bool lxb_css_parser_memory_fail(lxb_css_parser_t *parser); -lxb_status_t +LXB_API lxb_status_t lxb_css_parser_memory_fail_status(lxb_css_parser_t *parser); +/* + * Push a new state to the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] state Required. State callback to execute. + * @param[in] context Optional user pointer associated with this state. + * Stored as-is; the parser doesn't own it. + * @param[in] stop If true, the pushed state is marked as a "stop point". + * This is used by the parser to stop/return control when + * this state is reached. + * + * @return lxb_css_parser_state_t* if successful, otherwise NULL. + */ +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_push(lxb_css_parser_t *parser, + lxb_css_parser_state_f state, + void *context, bool stop); + +/* + * Go to the next state in the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] next Required. Next state callback. + * @param[in] back Required. State callback to return to. + * @param[in] ctx Optional user pointer for the next state. + * Stored as-is; the parser doesn't own it. + * @param[in] root If true, marks this state as a "root" state. Root states + * are used by helper functions (e.g. to rewind to root). + * + * @return lxb_css_parser_state_t* if successful, otherwise NULL. + */ +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_next(lxb_css_parser_t *parser, + lxb_css_parser_state_f next, + lxb_css_parser_state_f back, void *ctx, bool root); + +/* + * Push a token type to the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] type Required. Token type to push. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ +LXB_API lxb_status_t +lxb_css_parser_types_push(lxb_css_parser_t *parser, + lxb_css_syntax_token_type_t type); + + /* * Inline functions */ @@ -350,32 +545,6 @@ lxb_css_parser_state_set(lxb_css_parser_t *parser, lxb_css_parser_state_f state) parser->rules->state = state; } -lxb_inline void -lxb_css_parser_state_block_set(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - parser->block = state; -} - -lxb_inline void -lxb_css_parser_state_value_set(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - lxb_css_parser_state_block_set(parser, state); -} - -lxb_inline void * -lxb_css_parser_context(lxb_css_parser_t *parser) -{ - return parser->context; -} - -lxb_inline void -lxb_css_parser_context_set(lxb_css_parser_t *parser, void *context) -{ - parser->context = context; -} - lxb_inline lxb_css_syntax_rule_t * lxb_css_parser_current_rule(lxb_css_parser_t *parser) { @@ -420,13 +589,6 @@ lxb_css_parser_states_set_back(lxb_css_parser_t *parser) return true; } -lxb_inline void -lxb_css_parser_states_change_back(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - parser->rules->state_back = state; -} - lxb_inline void lxb_css_parser_states_clean(lxb_css_parser_t *parser) { @@ -465,47 +627,127 @@ lxb_css_parser_log(lxb_css_parser_t *parser) return parser->log; } -lxb_inline void -lxb_css_parser_offset_set(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token) +lxb_inline const lxb_css_syntax_token_t * +lxb_css_parser_token_end(lxb_css_parser_t *parser, size_t offset) { - if (parser->pos == NULL) { - if (token == NULL) { - parser->pos = parser->tkz->in_begin; - parser->offset = 0; - } - else { - parser->pos = lxb_css_syntax_token_base(token)->begin - + lxb_css_syntax_token_base(token)->length; - parser->offset = token->offset + lxb_css_syntax_token_base(token)->length; - } - } + parser->token_end.offset = offset; + return &parser->token_end; } -lxb_inline const lxb_css_syntax_list_rules_offset_t * -lxb_css_parser_list_rules_offset(lxb_css_parser_t *parser) +lxb_inline void +lxb_css_parser_set_context(lxb_css_parser_t *parser, void *ctx) { - return &parser->rules->u.list_rules; + parser->rules->context = ctx; } -lxb_inline const lxb_css_syntax_at_rule_offset_t * -lxb_css_parser_at_rule_offset(lxb_css_parser_t *parser) +lxb_inline void +lxb_css_syntax_set_return(lxb_css_parser_t *parser, void *value) { - return &parser->rules->u.at_rule; + parser->rules[-1].returned = value; } -lxb_inline const lxb_css_syntax_qualified_offset_t * -lxb_css_parser_qualified_rule_offset(lxb_css_parser_t *parser) +lxb_inline void * +lxb_css_syntax_returned(lxb_css_parser_t *parser) { - return &parser->rules->u.qualified; + return parser->rules->returned; } -lxb_inline const lxb_css_syntax_declarations_offset_t * -lxb_css_parser_declarations_offset(lxb_css_parser_t *parser) -{ - return &parser->rules->u.declarations; -} +/* + * No-inline functions for ABI. + */ +LXB_API lxb_status_t +lxb_css_parser_status_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_memory_t * +lxb_css_parser_memory_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_memory_set_noi(lxb_css_parser_t *parser, lxb_css_memory_t *memory); + +LXB_API lxb_css_selectors_t * +lxb_css_parser_selectors_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_selectors_set_noi(lxb_css_parser_t *parser, + lxb_css_selectors_t *selectors); + +LXB_API bool +lxb_css_parser_is_running_noi(lxb_css_parser_t *parser); + +LXB_API bool +lxb_css_parser_status_is_unexpected_data_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_failed_set_noi(lxb_css_parser_t *parser, bool is); + +LXB_API void +lxb_css_parser_failed_set_by_id_noi(lxb_css_parser_t *parser, int idx, bool is); + +LXB_API bool +lxb_css_parser_is_failed_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_set_ok_noi(lxb_css_parser_t *parser); + +LXB_API const lxb_char_t * +lxb_css_parser_buffer_noi(lxb_css_parser_t *parser, size_t *length); + +LXB_API void +lxb_css_parser_buffer_set_noi(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_parser_state_f +lxb_css_parser_state_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_state_set_noi(lxb_css_parser_t *parser, + lxb_css_parser_state_f state); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_parser_current_rule_noi(lxb_css_parser_t *parser); + +LXB_API size_t +lxb_css_parser_rule_deep_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_pop_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_to_root_noi(lxb_css_parser_t *parser); + +LXB_API bool +lxb_css_parser_states_set_back_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_clean_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_current_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_set_noi(lxb_css_parser_state_t *states, + lxb_css_parser_state_f state, void *context); + +LXB_API void +lxb_css_parser_states_up_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_down_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_log_t * +lxb_css_parser_log_noi(lxb_css_parser_t *parser); + +LXB_API const lxb_css_syntax_token_t * +lxb_css_parser_token_end_noi(lxb_css_parser_t *parser, size_t offset); + +LXB_API void +lxb_css_parser_set_context_noi(lxb_css_parser_t *parser, void *ctx); + +LXB_API void +lxb_css_syntax_set_return_noi(lxb_css_parser_t *parser, void *value); +LXB_API void * +lxb_css_syntax_returned_noi(lxb_css_parser_t *parser); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/property.c b/ext/lexbor/lexbor/css/property.c new file mode 100644 index 000000000000..6e460c3492f8 --- /dev/null +++ b/ext/lexbor/lexbor/css/property.c @@ -0,0 +1,3171 @@ +/* + * Copyright (C) 2021-2023 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/property.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/property/state.h" +#include "lexbor/css/property/res.h" +#include "lexbor/core/serialize.h" +#include "lexbor/core/conv.h" + + +const lxb_css_entry_data_t * +lxb_css_property_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_property_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_entry_data_t * +lxb_css_property_by_id(uintptr_t id) +{ + return &lxb_css_property_data[id]; +} + +const void * +lxb_css_property_initial_by_id(uintptr_t id) +{ + if (id >= LXB_CSS_PROPERTY__LAST_ENTRY) { + return NULL; + } + + return lxb_css_property_data[id].initial; +} + +void * +lxb_css_property_destroy(lxb_css_memory_t *memory, void *style, + lxb_css_property_type_t type, bool self_destroy) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return style; + } + + return data->destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_serialize(const void *style, lxb_css_property_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return data->serialize(style, cb, ctx); +} + +lxb_status_t +lxb_css_property_serialize_str(const void *style, lxb_css_property_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return lxb_css_serialize_str_handler(style, str, mraw, data->serialize); +} + +lxb_status_t +lxb_css_property_serialize_name(const void *style, lxb_css_property_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_data_t *data; + + switch (type) { + case LXB_CSS_PROPERTY__UNDEF: + return lxb_css_property__undef_serialize_name(style, cb, ctx); + + case LXB_CSS_PROPERTY__CUSTOM: + return lxb_css_property__custom_serialize_name(style, cb, ctx); + + default: + break; + } + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_property_serialize_name_str(const void *style, lxb_css_property_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_data_t *data; + + switch (type) { + case LXB_CSS_PROPERTY__UNDEF: + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_property__undef_serialize_name); + + case LXB_CSS_PROPERTY__CUSTOM: + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_property__custom_serialize_name); + + default: + break; + } + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + if (str->data == NULL) { + lexbor_str_init(str, mraw, data->length); + if (str->data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + (void) lexbor_str_append(str, mraw, data->name, data->length); + + return LXB_STATUS_OK; +} + +/* _undef. */ + +void * +lxb_css_property__undef_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property__undef_t)); +} + +void * +lxb_css_property__undef_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_property__undef_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + + return cb(undef->value.data, undef->value.length, ctx); +} + +lxb_status_t +lxb_css_property__undef_serialize_name(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + const lxb_css_entry_data_t *data; + + if (undef->type == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + data = lxb_css_property_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_property__undef_serialize_value(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + + if (undef->type == LXB_CSS_PROPERTY__UNDEF) { + return cb(undef->value.data, undef->value.length, ctx); + } + + return LXB_STATUS_OK; +} + +/* _custom. */ + +void * +lxb_css_property__custom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property__custom_t)); +} + +void * +lxb_css_property__custom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_property__custom_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + if (custom->value.data == NULL) { + return LXB_STATUS_OK; + } + + return cb(custom->value.data, custom->value.length, ctx); +} + +lxb_status_t +lxb_css_property__custom_serialize_name(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + return cb(custom->name.data, custom->name.length, ctx); +} + +lxb_status_t +lxb_css_property__custom_serialize_value(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + if (custom->value.data == NULL) { + return LXB_STATUS_OK; + } + + return cb(custom->value.data, custom->value.length, ctx); +} + +/* Display. */ + +void * +lxb_css_property_display_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_display_t)); +} + +void * +lxb_css_property_display_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_display_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_data_t *data; + const lxb_css_property_display_t *display = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + data = lxb_css_value_by_id(display->a); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + if (display->b == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + data = lxb_css_value_by_id(display->b); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + if (display->c == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + data = lxb_css_value_by_id(display->c); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + return LXB_STATUS_OK; +} + +/* Order. */ + +void * +lxb_css_property_order_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_order_t)); +} + +void * +lxb_css_property_order_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_order_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_integer_type_sr(style, cb, ctx); +} + +/* Visibility. */ + +void * +lxb_css_property_visibility_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_visibility_t)); +} + +void * +lxb_css_property_visibility_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_visibility_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_visibility_t *vb = style; + + return lxb_css_value_serialize(vb->type, cb, ctx); +} + +/* Width. */ + +void * +lxb_css_property_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_width_t)); +} + +void * +lxb_css_property_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_width_t *width = property; + + switch (width->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&width->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&width->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(width->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Height. */ + +void * +lxb_css_property_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_height_t)); +} + +void * +lxb_css_property_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Box-sizing. */ + +void * +lxb_css_property_box_sizing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_box_sizing_t)); +} + +void * +lxb_css_property_box_sizing_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_box_sizing_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_box_sizing_t *bsize = property; + + return lxb_css_value_serialize(bsize->type, cb, ctx); +} + +/* Min-width. */ + +void * +lxb_css_property_min_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_min_width_t)); +} + +void * +lxb_css_property_min_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_min_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Min-height. */ + +void * +lxb_css_property_min_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_min_height_t)); +} + +void * +lxb_css_property_min_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_min_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Max-width. */ + +void * +lxb_css_property_max_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_max_width_t)); +} + +void * +lxb_css_property_max_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_max_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Max-height. */ + +void * +lxb_css_property_max_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_max_height_t)); +} + +void * +lxb_css_property_max_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_max_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Margin. */ + +void * +lxb_css_property_margin_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_t)); +} + +void * +lxb_css_property_margin_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_margin_t *margin = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + /* Top. */ + + status = lxb_css_value_length_percentage_sr(&margin->top, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->right.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Right. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_length_percentage_sr(&margin->right, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->bottom.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Bottom. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_length_percentage_sr(&margin->bottom, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->left.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Left. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_length_percentage_sr(&margin->left, cb, ctx); +} + +/* Margin-top. */ + +void * +lxb_css_property_margin_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_top_t)); +} + +void * +lxb_css_property_margin_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-right. */ + +void * +lxb_css_property_margin_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_right_t)); +} + +void * +lxb_css_property_margin_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-bottom. */ + +void * +lxb_css_property_margin_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_bottom_t)); +} + +void * +lxb_css_property_margin_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-left. */ + +void * +lxb_css_property_margin_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_left_t)); +} + +void * +lxb_css_property_margin_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding. */ + +void * +lxb_css_property_padding_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_t)); +} + +void * +lxb_css_property_padding_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_margin_serialize(property, cb, ctx); +} + +/* Padding-top. */ + +void * +lxb_css_property_padding_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_top_t)); +} + +void * +lxb_css_property_padding_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-right. */ + +void * +lxb_css_property_padding_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_right_t)); +} + +void * +lxb_css_property_padding_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-bottom. */ + +void * +lxb_css_property_padding_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_bottom_t)); +} + +void * +lxb_css_property_padding_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-left. */ + +void * +lxb_css_property_padding_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_left_t)); +} + +void * +lxb_css_property_padding_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Border. */ + +void * +lxb_css_property_border_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_t)); +} + +void * +lxb_css_property_border_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_border_t *border = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_length_type_sr(&border->width, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (border->style != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(border->style, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (border->color.type != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_color_serialize(&border->color, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Border-top. */ + +void * +lxb_css_property_border_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_top_t)); +} + +void * +lxb_css_property_border_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-right. */ + +void * +lxb_css_property_border_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_right_t)); +} + +void * +lxb_css_property_border_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-bottom. */ + +void * +lxb_css_property_border_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_bottom_t)); +} + +void * +lxb_css_property_border_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-left. */ + +void * +lxb_css_property_border_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_left_t)); +} + +void * +lxb_css_property_border_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +void * +lxb_css_property_border_top_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_top_color_t)); +} + +void * +lxb_css_property_border_top_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_top_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_right_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_right_color_t)); +} + +void * +lxb_css_property_border_right_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_right_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_bottom_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_bottom_color_t)); +} + +void * +lxb_css_property_border_bottom_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_bottom_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_left_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_left_color_t)); +} + +void * +lxb_css_property_border_left_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_left_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_background_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_background_color_t)); +} + +void * +lxb_css_property_background_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_background_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +/* Color. */ + +void * +lxb_css_property_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_color_t)); +} + +void * +lxb_css_property_color_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_color_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(property, cb, ctx); +} + +void * +lxb_css_property_opacity_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_opacity_t)); +} + +void * +lxb_css_property_opacity_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_opacity_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_percentage_sr(style, cb, ctx); +} + +void * +lxb_css_property_position_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_position_t)); +} + +void * +lxb_css_property_position_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_position_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_position_t *position = style; + + return lxb_css_value_serialize(position->type, cb, ctx); +} + +void * +lxb_css_property_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_top_t)); +} + +void * +lxb_css_property_top_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_top_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +void * +lxb_css_property_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_right_t)); +} + +void * +lxb_css_property_right_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_right_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_bottom_t)); +} + +void * +lxb_css_property_bottom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_bottom_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_left_t)); +} + +void * +lxb_css_property_left_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_left_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_block_start_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_block_start_t)); +} + +void * +lxb_css_property_inset_block_start_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_block_start_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_inline_start_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_inline_start_t)); +} + +void * +lxb_css_property_inset_inline_start_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_inline_start_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_block_end_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_block_end_t)); +} + +void * +lxb_css_property_inset_block_end_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_block_end_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_inline_end_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_inline_end_t)); +} + +void * +lxb_css_property_inset_inline_end_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_inline_end_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +/* Text-transform. */ + +LXB_API void * +lxb_css_property_text_transform_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_transform_t)); +} + +LXB_API void * +lxb_css_property_text_transform_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_transform_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_text_transform_t *tt = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (tt->type_case != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(tt->type_case, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (tt->full_width != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tt->full_width, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (tt->full_size_kana != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(tt->full_size_kana, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Text-align. */ + +LXB_API void * +lxb_css_property_text_align_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_t)); +} + +LXB_API void * +lxb_css_property_text_align_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_t *ta = style; + + return lxb_css_value_serialize(ta->type, cb, ctx); +} + +/* Text-align-all. */ + +LXB_API void * +lxb_css_property_text_align_all_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_all_t)); +} + +LXB_API void * +lxb_css_property_text_align_all_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_all_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_all_t *taa = style; + + return lxb_css_value_serialize(taa->type, cb, ctx); +} + +/* Text-align-last. */ + +LXB_API void * +lxb_css_property_text_align_last_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_last_t)); +} + +LXB_API void * +lxb_css_property_text_align_last_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_last_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_last_t *tal = style; + + return lxb_css_value_serialize(tal->type, cb, ctx); +} + +/* Text-justify. */ + +LXB_API void * +lxb_css_property_text_justify_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_justify_t)); +} + +LXB_API void * +lxb_css_property_text_justify_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_justify_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_justify_t *tj = style; + + return lxb_css_value_serialize(tj->type, cb, ctx); +} + +/* Text-indent. */ + +LXB_API void * +lxb_css_property_text_indent_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_indent_t)); +} + +LXB_API void * +lxb_css_property_text_indent_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_indent_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_text_indent_t *ti = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (ti->type == LXB_CSS_VALUE__LENGTH) { + status = lxb_css_value_length_percentage_sr(&ti->length, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + else if (ti->type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(ti->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ti->hanging != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_serialize(ti->hanging, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ti->each_line != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_serialize(ti->each_line, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* White-space. */ + +LXB_API void * +lxb_css_property_white_space_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_white_space_t)); +} + +LXB_API void * +lxb_css_property_white_space_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_white_space_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_white_space_t *ws = style; + + return lxb_css_value_serialize(ws->type, cb, ctx); +} + +/* Tab-size. */ + +LXB_API void * +lxb_css_property_tab_size_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_tab_size_t)); +} + +LXB_API void * +lxb_css_property_tab_size_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_tab_size_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_length_sr(style, cb, ctx); +} + +/* Word-break. */ + +LXB_API void * +lxb_css_property_word_break_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_break_t)); +} + +LXB_API void * +lxb_css_property_word_break_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_break_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_word_break_t *wb = style; + + return lxb_css_value_serialize(wb->type, cb, ctx); +} + +/* Line-break. */ + +LXB_API void * +lxb_css_property_line_break_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_line_break_t)); +} + +LXB_API void * +lxb_css_property_line_break_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_line_break_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_line_break_t *lb = style; + + return lxb_css_value_serialize(lb->type, cb, ctx); +} + +/* Hyphens. */ + +LXB_API void * +lxb_css_property_hyphens_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_hyphens_t)); +} + +LXB_API void * +lxb_css_property_hyphens_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_hyphens_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_hyphens_t *hpns = style; + + return lxb_css_value_serialize(hpns->type, cb, ctx); +} + +/* Overflow-wrap. */ + +LXB_API void * +lxb_css_property_overflow_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_wrap_t)); +} + +LXB_API void * +lxb_css_property_overflow_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_wrap_t *ow = style; + + return lxb_css_value_serialize(ow->type, cb, ctx); +} + +/* Word-wrap. */ + +LXB_API void * +lxb_css_property_word_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_wrap_t)); +} + +LXB_API void * +lxb_css_property_word_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_word_wrap_t *ww = style; + + return lxb_css_value_serialize(ww->type, cb, ctx); +} + +/* Word-spacing. */ + +LXB_API void * +lxb_css_property_word_spacing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_spacing_t)); +} + +LXB_API void * +lxb_css_property_word_spacing_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_spacing_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_type_sr(style, cb, ctx); +} + +/* Letter-spacing. */ + +LXB_API void * +lxb_css_property_letter_spacing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_letter_spacing_t)); +} + +LXB_API void * +lxb_css_property_letter_spacing_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_letter_spacing_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_type_sr(style, cb, ctx); +} + +/* Hanging-punctuation. */ + +LXB_API void * +lxb_css_property_hanging_punctuation_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_hanging_punctuation_t)); +} + +LXB_API void * +lxb_css_property_hanging_punctuation_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_hanging_punctuation_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_hanging_punctuation_t *hp = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (hp->type_first != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(hp->type_first, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (hp->force_allow != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(hp->force_allow, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (hp->last != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(hp->last, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Font-family. */ + +void * +lxb_css_property_font_family_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_family_t)); +} + +void * +lxb_css_property_font_family_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + lxb_css_property_font_family_t *ff = style; + lxb_css_property_family_name_t *name, *next; + + name = ff->first; + + while (name != NULL) { + next = name->next; + + if (!name->generic) { + (void) lexbor_str_destroy(&name->u.str, memory->mraw, false); + } + + lexbor_mraw_free(memory->mraw, name); + + name = next; + } + + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_family_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_font_family_t *ff = style; + const lxb_css_property_family_name_t *name; + + static const lexbor_str_t str_comma = lexbor_str(", "); + + name = ff->first; + + while (name != NULL) { + if (name->generic) { + status = lxb_css_value_serialize(name->u.type, cb, ctx); + } + else { + status = lxb_css_syntax_ident_or_string_serialize(name->u.str.data, + name->u.str.length, + cb, ctx); + } + + if (status != LXB_STATUS_OK) { + return status; + } + + name = name->next; + + if (name != NULL) { + lexbor_serialize_write(cb, str_comma.data, str_comma.length, + ctx, status); + } + } + + return LXB_STATUS_OK; +} + +/* Font-weight. */ + +void * +lxb_css_property_font_weight_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_weight_t)); +} + +void * +lxb_css_property_font_weight_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_weight_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Font-stretch. */ + +void * +lxb_css_property_font_stretch_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_stretch_t)); +} + +void * +lxb_css_property_font_stretch_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_stretch_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_percentage_type_sr(style, cb, ctx); +} + +/* Font-style. */ + +void * +lxb_css_property_font_style_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_style_t)); +} + +void * +lxb_css_property_font_style_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_style_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_font_style_t *fs = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + status = lxb_css_value_serialize(fs->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (fs->angle.unit != (lxb_css_unit_angle_t) LXB_CSS_UNIT__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_angle_sr(&fs->angle, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + return LXB_STATUS_OK; +} + +/* Font-size. */ + +LXB_API void * +lxb_css_property_font_size_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_size_t)); +} + +LXB_API void * +lxb_css_property_font_size_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_font_size_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_type_sr(style, cb, ctx); +} + +/* Float-reference. */ + +LXB_API void * +lxb_css_property_float_reference_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_reference_t)); +} + +LXB_API void * +lxb_css_property_float_reference_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_reference_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_float_reference_t *fr = style; + + return lxb_css_value_serialize(fr->type, cb, ctx); +} + +/* Float. */ + +LXB_API void * +lxb_css_property_float_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_float_t)); +} + +LXB_API void * +lxb_css_property_float_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_float_t *flt = style; + + static const lexbor_str_t str_o = lexbor_str("("); + static const lexbor_str_t str_cm = lexbor_str(", "); + static const lexbor_str_t str_c = lexbor_str(")"); + + status = lxb_css_value_serialize(flt->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flt->length.type != LXB_CSS_VALUE__LENGTH) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_o.data, str_o.length, ctx, status); + + status = lxb_css_value_length_sr(&flt->length.length, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flt->snap_type == LXB_CSS_VALUE__UNDEF) { + return cb(str_c.data, str_c.length, ctx); + } + + lexbor_serialize_write(cb, str_cm.data, str_cm.length, ctx, status); + + status = lxb_css_value_serialize(flt->snap_type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(str_c.data, str_c.length, ctx); +} + +/* Clear. */ + +LXB_API void * +lxb_css_property_clear_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_clear_t)); +} + +LXB_API void * +lxb_css_property_clear_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_clear_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_clear_t *cls = style; + + return lxb_css_value_serialize(cls->type, cb, ctx); +} + +/* Float-defer. */ + +LXB_API void * +lxb_css_property_float_defer_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_defer_t)); +} + +LXB_API void * +lxb_css_property_float_defer_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_defer_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_float_defer_t *def = style; + + if (def->type == LXB_CSS_FLOAT_DEFER__INTEGER) { + return lxb_css_value_integer_sr(&def->integer, cb, ctx); + } + + return lxb_css_value_serialize(def->type, cb, ctx); +} + +/* Float-offset. */ + +LXB_API void * +lxb_css_property_float_offset_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_offset_t)); +} + +LXB_API void * +lxb_css_property_float_offset_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_offset_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +/* Wrap-flow. */ + +LXB_API void * +lxb_css_property_wrap_flow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_wrap_flow_t)); +} + +LXB_API void * +lxb_css_property_wrap_flow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_wrap_flow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_wrap_flow_t *wf = style; + + return lxb_css_value_serialize(wf->type, cb, ctx); +} + +/* Wrap-through. */ + +LXB_API void * +lxb_css_property_wrap_through_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_wrap_through_t)); +} + +LXB_API void * +lxb_css_property_wrap_through_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_wrap_through_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_wrap_through_t *wt = style; + + return lxb_css_value_serialize(wt->type, cb, ctx); +} + +/* Flex-direction. */ + +LXB_API void * +lxb_css_property_flex_direction_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_direction_t)); +} + +LXB_API void * +lxb_css_property_flex_direction_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_direction_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_flex_direction_t *fd = style; + + return lxb_css_value_serialize(fd->type, cb, ctx); +} + +/* Flex-wrap. */ + +LXB_API void * +lxb_css_property_flex_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_wrap_t)); +} + +LXB_API void * +lxb_css_property_flex_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_flex_wrap_t *fw = style; + + return lxb_css_value_serialize(fw->type, cb, ctx); +} + +/* Flex-flow. */ + +LXB_API void * +lxb_css_property_flex_flow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_flow_t)); +} + +LXB_API void * +lxb_css_property_flex_flow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_flow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_flex_flow_t *ff = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (ff->type_direction != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(ff->type_direction, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ff->wrap != LXB_CSS_VALUE__UNDEF) { + if (ff->type_direction != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(ff->wrap, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Flex. */ + +LXB_API void * +lxb_css_property_flex_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_flex_t)); +} + +LXB_API void * +lxb_css_property_flex_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_flex_t *flex = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (flex->type != LXB_CSS_VALUE__UNDEF) { + return lxb_css_value_serialize(flex->type, cb, ctx); + } + + if (flex->grow.type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_number_sr(&flex->grow.number, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flex->shrink.type != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_number_sr(&flex->shrink.number, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + } + + if (flex->basis.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + if (flex->grow.type != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_property_flex_basis_serialize(&flex->basis, cb, ctx); +} + +/* Flex-grow. */ + +LXB_API void * +lxb_css_property_flex_grow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_grow_t)); +} + +LXB_API void * +lxb_css_property_flex_grow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_grow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Flex-shrink. */ + +LXB_API void * +lxb_css_property_flex_shrink_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_shrink_t)); +} + +LXB_API void * +lxb_css_property_flex_shrink_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_shrink_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Flex-basis. */ + +LXB_API void * +lxb_css_property_flex_basis_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_basis_t)); +} + +LXB_API void * +lxb_css_property_flex_basis_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_basis_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(style, cb, ctx); +} + +/* Justify-content. */ + +LXB_API void * +lxb_css_property_justify_content_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_justify_content_t)); +} + +LXB_API void * +lxb_css_property_justify_content_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_justify_content_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_justify_content_t *jc = style; + + return lxb_css_value_serialize(jc->type, cb, ctx); +} + +/* Align-items. */ + +LXB_API void * +lxb_css_property_align_items_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_items_t)); +} + +LXB_API void * +lxb_css_property_align_items_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_items_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_items_t *ai = style; + + return lxb_css_value_serialize(ai->type, cb, ctx); +} + +/* Align-self. */ + +LXB_API void * +lxb_css_property_align_self_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_self_t)); +} + +LXB_API void * +lxb_css_property_align_self_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_self_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_self_t *as = style; + + return lxb_css_value_serialize(as->type, cb, ctx); +} + +/* Align-content. */ + +LXB_API void * +lxb_css_property_align_content_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_content_t)); +} + +LXB_API void * +lxb_css_property_align_content_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_content_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_content_t *ac = style; + + return lxb_css_value_serialize(ac->type, cb, ctx); +} + +/* Dominant-baseline. */ + +LXB_API void * +lxb_css_property_dominant_baseline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_dominant_baseline_t)); +} + +LXB_API void * +lxb_css_property_dominant_baseline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_dominant_baseline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_dominant_baseline_t *db = style; + + return lxb_css_value_serialize(db->type, cb, ctx); +} + +/* Vertical-align. */ + +LXB_API void * +lxb_css_property_vertical_align_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_vertical_align_t)); +} + +LXB_API void * +lxb_css_property_vertical_align_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_vertical_align_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool is; + lxb_status_t status; + const lxb_css_property_vertical_align_t *va = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + is = false; + + if (va->type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(va->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + is = true; + } + + if (va->alignment.type != LXB_CSS_VALUE__UNDEF) { + if (is) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(va->alignment.type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + is = true; + } + + if (va->shift.type != LXB_CSS_VALUE__UNDEF) { + if (is) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_length_percentage_sr(&va->shift, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + return LXB_STATUS_OK; +} + +/* Baseline-source. */ + +LXB_API void * +lxb_css_property_baseline_source_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_baseline_source_t)); +} + +LXB_API void * +lxb_css_property_baseline_source_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_baseline_source_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_baseline_source_t *bs = style; + + return lxb_css_value_serialize(bs->type, cb, ctx); +} + +/* Alignment-baseline. */ + +LXB_API void * +lxb_css_property_alignment_baseline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_alignment_baseline_t)); +} + +LXB_API void * +lxb_css_property_alignment_baseline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_alignment_baseline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_alignment_baseline_t *ab = style; + + return lxb_css_value_serialize(ab->type, cb, ctx); +} + +/* Baseline-shift. */ + +LXB_API void * +lxb_css_property_baseline_shift_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_baseline_shift_t)); +} + +LXB_API void * +lxb_css_property_baseline_shift_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_baseline_shift_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +/* Line-height. */ + +LXB_API void * +lxb_css_property_line_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_line_height_t)); +} + +LXB_API void * +lxb_css_property_line_height_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_line_height_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_length_percentage_type_sr(style, cb, ctx); +} + +/* Z-index. */ + +LXB_API void * +lxb_css_property_z_index_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_z_index_t)); +} + +LXB_API void * +lxb_css_property_z_index_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_z_index_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_integer_type_sr(style, cb, ctx); +} + +/* Direction. */ + +LXB_API void * +lxb_css_property_direction_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_direction_t)); +} + +LXB_API void * +lxb_css_property_direction_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_direction_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_direction_t *dr = style; + + return lxb_css_value_serialize(dr->type, cb, ctx); +} + +/* Unicode-bidi. */ + +LXB_API void * +lxb_css_property_unicode_bidi_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_unicode_bidi_t)); +} + +LXB_API void * +lxb_css_property_unicode_bidi_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_unicode_bidi_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_unicode_bidi_t *ub = style; + + return lxb_css_value_serialize(ub->type, cb, ctx); +} + +/* Writing-mode. */ + +LXB_API void * +lxb_css_property_writing_mode_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_writing_mode_t)); +} + +LXB_API void * +lxb_css_property_writing_mode_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_writing_mode_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_writing_mode_t *wm = style; + + return lxb_css_value_serialize(wm->type, cb, ctx); +} + +/* Text-orientation. */ + +LXB_API void * +lxb_css_property_text_orientation_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_orientation_t)); +} + +LXB_API void * +lxb_css_property_text_orientation_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_orientation_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_orientation_t *to = style; + + return lxb_css_value_serialize(to->type, cb, ctx); +} + +/* Text-combine-upright. */ + +LXB_API void * +lxb_css_property_text_combine_upright_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_combine_upright_t)); +} + +LXB_API void * +lxb_css_property_text_combine_upright_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_combine_upright_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_text_combine_upright_t *tcu = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (tcu->type == LXB_CSS_TEXT_COMBINE_UPRIGHT_DIGITS) { + status = lxb_css_value_serialize(tcu->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (tcu->digits.num != 0) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_integer_sr(&tcu->digits, cb, ctx); + } + + return LXB_STATUS_OK; + } + + return lxb_css_value_serialize(tcu->type, cb, ctx); +} + +/* Overflow-x. */ + +LXB_API void * +lxb_css_property_overflow_x_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_x_t)); +} + +LXB_API void * +lxb_css_property_overflow_x_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_x_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_x_t *ox = style; + + return lxb_css_value_serialize(ox->type, cb, ctx); +} + +/* Overflow-y. */ + +LXB_API void * +lxb_css_property_overflow_y_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_y_t)); +} + +LXB_API void * +lxb_css_property_overflow_y_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_y_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_y_t *oy = style; + + return lxb_css_value_serialize(oy->type, cb, ctx); +} + +/* Overflow-block. */ + +LXB_API void * +lxb_css_property_overflow_block_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_block_t)); +} + +LXB_API void * +lxb_css_property_overflow_block_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_block_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_block_t *ob = style; + + return lxb_css_value_serialize(ob->type, cb, ctx); +} + +/* Overflow-inline. */ + +LXB_API void * +lxb_css_property_overflow_inline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_inline_t)); +} + +LXB_API void * +lxb_css_property_overflow_inline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_inline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_inline_t *oi = style; + + return lxb_css_value_serialize(oi->type, cb, ctx); +} + +/* Text-overflow. */ + +LXB_API void * +lxb_css_property_text_overflow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_overflow_t)); +} + +LXB_API void * +lxb_css_property_text_overflow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_overflow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_overflow_t *to = style; + + return lxb_css_value_serialize(to->type, cb, ctx); +} + +/* Text-decoration-line. */ + +LXB_API void * +lxb_css_property_text_decoration_line_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_line_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_line_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_line_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool itis; + lxb_status_t status; + const lxb_css_property_text_decoration_line_t *tdl = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + itis = false; + + if (tdl->underline != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(tdl->underline, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->overline != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tdl->overline, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->line_through != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tdl->line_through, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->blink != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(tdl->blink, cb, ctx); + } + + if (itis) { + return LXB_STATUS_OK; + } + + return lxb_css_value_serialize(tdl->type, cb, ctx); +} + +/* Text-decoration-style. */ + +LXB_API void * +lxb_css_property_text_decoration_style_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_style_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_style_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_style_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_decoration_style_t *tds = style; + + return lxb_css_value_serialize(tds->type, cb, ctx); +} + +/* Text-decoration-color. */ + +LXB_API void * +lxb_css_property_text_decoration_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_color_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_color_serialize(style, cb, ctx); +} + +/* Text-decoration. */ + +LXB_API void * +lxb_css_property_text_decoration_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool itis; + lxb_status_t status; + const lxb_css_property_text_decoration_t *td = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + itis = false; + + if (td->line.type != LXB_CSS_VALUE__UNDEF + || td->line.underline != LXB_CSS_VALUE__UNDEF + || td->line.overline != LXB_CSS_VALUE__UNDEF + || td->line.line_through != LXB_CSS_VALUE__UNDEF + || td->line.blink != LXB_CSS_VALUE__UNDEF) + { + status = lxb_css_property_text_decoration_line_serialize(&td->line, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (td->style.type != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_property_text_decoration_style_serialize(&td->style, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (td->color.type != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_property_text_decoration_color_serialize(&td->color, + cb, ctx); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/property/const.h b/ext/lexbor/lexbor/css/property/const.h index 8ee24481c6a3..4f90bc1c107b 100644 --- a/ext/lexbor/lexbor/css/property/const.h +++ b/ext/lexbor/lexbor/css/property/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/property/res.h b/ext/lexbor/lexbor/css/property/res.h index 35cce1959013..eb5b90304a09 100644 --- a/ext/lexbor/lexbor/css/property/res.h +++ b/ext/lexbor/lexbor/css/property/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/property/state.c b/ext/lexbor/lexbor/css/property/state.c new file mode 100644 index 000000000000..198ef145615d --- /dev/null +++ b/ext/lexbor/lexbor/css/property/state.c @@ -0,0 +1,5343 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/property.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/value.h" +#include "lexbor/css/unit.h" +#include "lexbor/css/property/state.h" +#include "lexbor/css/property/res.h" + + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif + +#include "lexbor/core/conv.h" + + +#define lxb_css_property_state_check_token(parser, token) \ + if ((token) == NULL) { \ + return lxb_css_parser_memory_fail(parser); \ + } + +#define lxb_css_property_state_get_type(parser, token, type) \ + do { \ + lxb_css_syntax_parser_consume(parser); \ + \ + token = lxb_css_syntax_parser_token_wo_ws(parser); \ + lxb_css_property_state_check_token(parser, token); \ + \ + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { \ + return lxb_css_parser_success(parser); \ + } \ + \ + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, \ + lxb_css_syntax_token_ident(token)->length); \ + } \ + while (false) + +#define LXB_CSS_PROPERTY_STATE_HEX_MASK(n) \ + ((((uint32_t) 1 << (32 - (n))) - 1) << (n)) + + +static bool +lxb_css_property_state_color_rgba_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color); +static bool +lxb_css_property_state_color_hsla_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_hsla_t *hsl); + +static bool +lxb_css_property_state_length(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_length_t *length) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + length->num = lxb_css_syntax_token_dimension(token)->num.num; + length->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + length->unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (lxb_css_syntax_token_number(token)->num != 0) { + return false; + } + + length->num = lxb_css_syntax_token_number(token)->num; + length->is_float = lxb_css_syntax_token_number(token)->is_float; + length->unit = LXB_CSS_UNIT__UNDEF; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_length_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_length_percentage_t *lp) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + lp->type = LXB_CSS_VALUE__LENGTH; + lp->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + lp->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + lp->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (lxb_css_syntax_token_number(token)->num != 0) { + return false; + } + + lp->type = LXB_CSS_VALUE__NUMBER; + lp->u.length.num = lxb_css_syntax_token_number(token)->num; + lp->u.length.is_float = lxb_css_syntax_token_number(token)->is_float; + lp->u.length.unit = LXB_CSS_UNIT__UNDEF; + break; + + case LXB_CSS_SYNTAX_TOKEN_PERCENTAGE: + lp->type = LXB_CSS_VALUE__PERCENTAGE; + lp->u.percentage.num = lxb_css_syntax_token_percentage(token)->num; + lp->u.percentage.is_float = lxb_css_syntax_token_percentage(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_length_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_length_percentage_t *nlp) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + nlp->type = LXB_CSS_VALUE__LENGTH; + nlp->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + nlp->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + nlp->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + nlp->type = LXB_CSS_VALUE__NUMBER; + nlp->u.number.num = lxb_css_syntax_token_number(token)->num; + nlp->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + case LXB_CSS_SYNTAX_TOKEN_PERCENTAGE: + nlp->type = LXB_CSS_VALUE__PERCENTAGE; + nlp->u.percentage.num = lxb_css_syntax_token_percentage(token)->num; + nlp->u.percentage.is_float = lxb_css_syntax_token_percentage(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_length(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_length_t *nl) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + nl->type = LXB_CSS_VALUE__LENGTH; + nl->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + nl->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + nl->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + nl->type = LXB_CSS_VALUE__NUMBER; + nl->u.number.num = lxb_css_syntax_token_number(token)->num; + nl->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_t *number) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_NUMBER) { + return false; + } + + number->num = lxb_css_syntax_token_number(token)->num; + number->is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_integer(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_integer_t *intg) +{ + long ln; + double num; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_NUMBER) { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + ln = lexbor_conv_double_to_long(num); + + num = num - (double) ln; + + if (num < 0.0 || num > 0.0) { + return false; + } + + intg->num = ln; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_percentage_t *perc) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + return false; + } + + perc->num = lxb_css_syntax_token_percentage(token)->num; + perc->is_float = lxb_css_syntax_token_percentage(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_percentage_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_percentage_t *np) +{ + double num; + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_NUMBER) { + np->type = LXB_CSS_VALUE__NUMBER; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + np->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->u.number.num = num; + np->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_percentage_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_percentage_type_t *np) +{ + double num; + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + np->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->percentage.num = num; + np->percentage.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_percentage_t *np) +{ + double num; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_NUMBER) { + np->type = LXB_CSS_VALUE__NUMBER; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->u.number.num = num; + np->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_angle(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_angle_t *angle) +{ + const lxb_css_data_t *unit; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_DIMENSION) { + return false; + } + + unit = lxb_css_unit_angle_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + angle->num = lxb_css_syntax_token_dimension(token)->num.num; + angle->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + angle->unit = (lxb_css_unit_angle_t) unit->unique; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +bool +lxb_css_property_state_width_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_width_t *width) +{ + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_AUTO: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + width->type = type; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; + } + + return lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *)width); +} + +static bool +lxb_css_property_state_hue(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_hue_t *hue) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_angle_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + hue->type = LXB_CSS_VALUE__ANGLE; + hue->u.angle.num = lxb_css_syntax_token_dimension(token)->num.num; + hue->u.angle.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + hue->u.angle.unit = (lxb_css_unit_angle_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + hue->type = LXB_CSS_VALUE__NUMBER; + hue->u.number.num = lxb_css_syntax_token_number(token)->num; + hue->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +lxb_inline bool +lxb_css_property_state_hue_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_hue_t *hue) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_property_state_hue(parser, token, hue); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + hue->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hex(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color) +{ + size_t length; + uint32_t chex; + lxb_char_t ch; + const lxb_char_t *end, *p; + lxb_css_value_color_hex_rgba_t *rgba; + + length = token->types.hash.length; + + if (length > 8) { + return false; + } + + p = token->types.hash.data; + end = p + length; + + chex = 0; + + while (p < end) { + ch = lexbor_str_res_map_lowercase[lexbor_str_res_map_hex[*p]]; + + if (ch == 0xff) { + return false; + } + + chex = chex << 4 | ch; + + p++; + } + + rgba = &color->u.hex.rgba; + + switch (length) { + case 3: + rgba->r = chex >> 8; + rgba->g = chex >> 4 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->b = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->a = 0xff; + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_3; + break; + + case 4: + rgba->r = chex >> 12; + rgba->g = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->b = chex >> 4 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->a = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4; + break; + + case 6: + rgba->r = chex >> 16; + rgba->g = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->b = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->a = 0xff; + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_6; + break; + + case 8: + rgba->r = chex >> 24; + rgba->g = chex >> 16 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->b = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->a = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8; + break; + + default: + return false; + } + + color->type = LXB_CSS_COLOR_HEX; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_rgba(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_color_type_t type; + lxb_css_value_color_rgba_t *rgb; + const lxb_css_syntax_token_t *token; + + rgb = &color->u.rgb; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->r); + if (res == false) { + return false; + } + + type = rgb->r.type; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_COMMA) { + /* Deprecated format. */ + + if (type == LXB_CSS_VALUE_NONE) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + rgb->old = true; + + return lxb_css_property_state_color_rgba_old(parser, token, color); + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->g); + if (res == false) { + return false; + } + + if (type != rgb->g.type) { + if (type == LXB_CSS_VALUE_NONE) { + type = rgb->g.type; + } + else if (rgb->g.type != LXB_CSS_VALUE_NONE) { + return false; + } + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->b); + if (res == false) { + return false; + } + + if (type != rgb->b.type && type != LXB_CSS_VALUE_NONE + && rgb->b.type != LXB_CSS_VALUE_NONE) + { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_rgba_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_rgba_t *rgb; + + rgb = &color->u.rgb; + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->g); + if (res == false) { + return false; + } + + if (rgb->r.type != rgb->g.type) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->b); + if (res == false) { + return false; + } + + if (rgb->r.type != rgb->b.type) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hsla(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_hsla_t *hsl; + const lxb_css_syntax_token_t *token; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + hsl = &color->u.hsl; + + res = lxb_css_property_state_hue_none(parser, token, &hsl->h); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_COMMA) { + /* Deprecated format. */ + + if (hsl->h.type == LXB_CSS_VALUE_NONE) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + hsl->old = true; + + return lxb_css_property_state_color_hsla_old(parser, token, hsl); + } + + res = lxb_css_property_state_percentage_none(parser, token, &hsl->s); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_percentage_none(parser, token, &hsl->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &hsl->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hsla_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_hsla_t *hsl) +{ + bool res; + + res = lxb_css_property_state_percentage(parser, token, &hsl->s.percentage); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_percentage(parser, token, &hsl->l.percentage); + if (res == false) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + goto done; + } + else if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &hsl->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + +done: + + lxb_css_syntax_parser_consume(parser); + + hsl->s.type = LXB_CSS_VALUE__PERCENTAGE; + hsl->l.type = LXB_CSS_VALUE__PERCENTAGE; + + return true; +} + +static bool +lxb_css_property_state_color_lab(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_lab_t *lab; + const lxb_css_syntax_token_t *token; + + lab = &color->u.lab; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->b); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, + &lab->alpha); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_lch(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_lch_t *lch; + const lxb_css_syntax_token_t *token; + + lch = &color->u.lch; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->c); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_hue_none(parser, token, &lch->h); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +/* + * Return: + * true and status always LXB_STATUS_OK — token consumed, ok. + * false and status != LXB_STATUS_OK — token consumed, not ok. + * false and status == LXB_STATUS_OK — token not consumed, not ok. + */ +static bool +lxb_css_property_state_color_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color, + lxb_status_t *status) +{ + bool res; + lxb_css_value_type_t type; + + *status = LXB_STATUS_OK; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_HASH: + color->type = LXB_CSS_VALUE_HEX; + + return lxb_css_property_state_color_hex(parser, token, color); + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + type = lxb_css_value_by_name(lxb_css_syntax_token_function(token)->data, + lxb_css_syntax_token_function(token)->length); + color->type = type; + + switch (type) { + /* */ + case LXB_CSS_VALUE_RGB: + case LXB_CSS_VALUE_RGBA: + res = lxb_css_property_state_color_rgba(parser, color); + break; + + case LXB_CSS_VALUE_HSL: + case LXB_CSS_VALUE_HSLA: + case LXB_CSS_VALUE_HWB: + res = lxb_css_property_state_color_hsla(parser, color); + break; + + case LXB_CSS_VALUE_LAB: + case LXB_CSS_VALUE_OKLAB: + res = lxb_css_property_state_color_lab(parser, color); + break; + + case LXB_CSS_VALUE_LCH: + case LXB_CSS_VALUE_OKLCH: + res = lxb_css_property_state_color_lch(parser, color); + break; + + case LXB_CSS_VALUE_COLOR: + default: + *status = LXB_STATUS_OK; + return false; + } + + if (!res) { + *status = LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return res; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* */ + case LXB_CSS_VALUE_CURRENTCOLOR: + /* */ + case LXB_CSS_VALUE_CANVAS: + case LXB_CSS_VALUE_CANVASTEXT: + case LXB_CSS_VALUE_LINKTEXT: + case LXB_CSS_VALUE_VISITEDTEXT: + case LXB_CSS_VALUE_ACTIVETEXT: + case LXB_CSS_VALUE_BUTTONFACE: + case LXB_CSS_VALUE_BUTTONTEXT: + case LXB_CSS_VALUE_BUTTONBORDER: + case LXB_CSS_VALUE_FIELD: + case LXB_CSS_VALUE_FIELDTEXT: + case LXB_CSS_VALUE_HIGHLIGHT: + case LXB_CSS_VALUE_HIGHLIGHTTEXT: + case LXB_CSS_VALUE_SELECTEDITEM: + case LXB_CSS_VALUE_SELECTEDITEMTEXT: + case LXB_CSS_VALUE_MARK: + case LXB_CSS_VALUE_MARKTEXT: + case LXB_CSS_VALUE_GRAYTEXT: + case LXB_CSS_VALUE_ACCENTCOLOR: + case LXB_CSS_VALUE_ACCENTCOLORTEXT: + /* */ + case LXB_CSS_VALUE_TRANSPARENT: + /* */ + case LXB_CSS_VALUE_ALICEBLUE: + case LXB_CSS_VALUE_ANTIQUEWHITE: + case LXB_CSS_VALUE_AQUA: + case LXB_CSS_VALUE_AQUAMARINE: + case LXB_CSS_VALUE_AZURE: + case LXB_CSS_VALUE_BEIGE: + case LXB_CSS_VALUE_BISQUE: + case LXB_CSS_VALUE_BLACK: + case LXB_CSS_VALUE_BLANCHEDALMOND: + case LXB_CSS_VALUE_BLUE: + case LXB_CSS_VALUE_BLUEVIOLET: + case LXB_CSS_VALUE_BROWN: + case LXB_CSS_VALUE_BURLYWOOD: + case LXB_CSS_VALUE_CADETBLUE: + case LXB_CSS_VALUE_CHARTREUSE: + case LXB_CSS_VALUE_CHOCOLATE: + case LXB_CSS_VALUE_CORAL: + case LXB_CSS_VALUE_CORNFLOWERBLUE: + case LXB_CSS_VALUE_CORNSILK: + case LXB_CSS_VALUE_CRIMSON: + case LXB_CSS_VALUE_CYAN: + case LXB_CSS_VALUE_DARKBLUE: + case LXB_CSS_VALUE_DARKCYAN: + case LXB_CSS_VALUE_DARKGOLDENROD: + case LXB_CSS_VALUE_DARKGRAY: + case LXB_CSS_VALUE_DARKGREEN: + case LXB_CSS_VALUE_DARKGREY: + case LXB_CSS_VALUE_DARKKHAKI: + case LXB_CSS_VALUE_DARKMAGENTA: + case LXB_CSS_VALUE_DARKOLIVEGREEN: + case LXB_CSS_VALUE_DARKORANGE: + case LXB_CSS_VALUE_DARKORCHID: + case LXB_CSS_VALUE_DARKRED: + case LXB_CSS_VALUE_DARKSALMON: + case LXB_CSS_VALUE_DARKSEAGREEN: + case LXB_CSS_VALUE_DARKSLATEBLUE: + case LXB_CSS_VALUE_DARKSLATEGRAY: + case LXB_CSS_VALUE_DARKSLATEGREY: + case LXB_CSS_VALUE_DARKTURQUOISE: + case LXB_CSS_VALUE_DARKVIOLET: + case LXB_CSS_VALUE_DEEPPINK: + case LXB_CSS_VALUE_DEEPSKYBLUE: + case LXB_CSS_VALUE_DIMGRAY: + case LXB_CSS_VALUE_DIMGREY: + case LXB_CSS_VALUE_DODGERBLUE: + case LXB_CSS_VALUE_FIREBRICK: + case LXB_CSS_VALUE_FLORALWHITE: + case LXB_CSS_VALUE_FORESTGREEN: + case LXB_CSS_VALUE_FUCHSIA: + case LXB_CSS_VALUE_GAINSBORO: + case LXB_CSS_VALUE_GHOSTWHITE: + case LXB_CSS_VALUE_GOLD: + case LXB_CSS_VALUE_GOLDENROD: + case LXB_CSS_VALUE_GRAY: + case LXB_CSS_VALUE_GREEN: + case LXB_CSS_VALUE_GREENYELLOW: + case LXB_CSS_VALUE_GREY: + case LXB_CSS_VALUE_HONEYDEW: + case LXB_CSS_VALUE_HOTPINK: + case LXB_CSS_VALUE_INDIANRED: + case LXB_CSS_VALUE_INDIGO: + case LXB_CSS_VALUE_IVORY: + case LXB_CSS_VALUE_KHAKI: + case LXB_CSS_VALUE_LAVENDER: + case LXB_CSS_VALUE_LAVENDERBLUSH: + case LXB_CSS_VALUE_LAWNGREEN: + case LXB_CSS_VALUE_LEMONCHIFFON: + case LXB_CSS_VALUE_LIGHTBLUE: + case LXB_CSS_VALUE_LIGHTCORAL: + case LXB_CSS_VALUE_LIGHTCYAN: + case LXB_CSS_VALUE_LIGHTGOLDENRODYELLOW: + case LXB_CSS_VALUE_LIGHTGRAY: + case LXB_CSS_VALUE_LIGHTGREEN: + case LXB_CSS_VALUE_LIGHTGREY: + case LXB_CSS_VALUE_LIGHTPINK: + case LXB_CSS_VALUE_LIGHTSALMON: + case LXB_CSS_VALUE_LIGHTSEAGREEN: + case LXB_CSS_VALUE_LIGHTSKYBLUE: + case LXB_CSS_VALUE_LIGHTSLATEGRAY: + case LXB_CSS_VALUE_LIGHTSLATEGREY: + case LXB_CSS_VALUE_LIGHTSTEELBLUE: + case LXB_CSS_VALUE_LIGHTYELLOW: + case LXB_CSS_VALUE_LIME: + case LXB_CSS_VALUE_LIMEGREEN: + case LXB_CSS_VALUE_LINEN: + case LXB_CSS_VALUE_MAGENTA: + case LXB_CSS_VALUE_MAROON: + case LXB_CSS_VALUE_MEDIUMAQUAMARINE: + case LXB_CSS_VALUE_MEDIUMBLUE: + case LXB_CSS_VALUE_MEDIUMORCHID: + case LXB_CSS_VALUE_MEDIUMPURPLE: + case LXB_CSS_VALUE_MEDIUMSEAGREEN: + case LXB_CSS_VALUE_MEDIUMSLATEBLUE: + case LXB_CSS_VALUE_MEDIUMSPRINGGREEN: + case LXB_CSS_VALUE_MEDIUMTURQUOISE: + case LXB_CSS_VALUE_MEDIUMVIOLETRED: + case LXB_CSS_VALUE_MIDNIGHTBLUE: + case LXB_CSS_VALUE_MINTCREAM: + case LXB_CSS_VALUE_MISTYROSE: + case LXB_CSS_VALUE_MOCCASIN: + case LXB_CSS_VALUE_NAVAJOWHITE: + case LXB_CSS_VALUE_NAVY: + case LXB_CSS_VALUE_OLDLACE: + case LXB_CSS_VALUE_OLIVE: + case LXB_CSS_VALUE_OLIVEDRAB: + case LXB_CSS_VALUE_ORANGE: + case LXB_CSS_VALUE_ORANGERED: + case LXB_CSS_VALUE_ORCHID: + case LXB_CSS_VALUE_PALEGOLDENROD: + case LXB_CSS_VALUE_PALEGREEN: + case LXB_CSS_VALUE_PALETURQUOISE: + case LXB_CSS_VALUE_PALEVIOLETRED: + case LXB_CSS_VALUE_PAPAYAWHIP: + case LXB_CSS_VALUE_PEACHPUFF: + case LXB_CSS_VALUE_PERU: + case LXB_CSS_VALUE_PINK: + case LXB_CSS_VALUE_PLUM: + case LXB_CSS_VALUE_POWDERBLUE: + case LXB_CSS_VALUE_PURPLE: + case LXB_CSS_VALUE_REBECCAPURPLE: + case LXB_CSS_VALUE_RED: + case LXB_CSS_VALUE_ROSYBROWN: + case LXB_CSS_VALUE_ROYALBLUE: + case LXB_CSS_VALUE_SADDLEBROWN: + case LXB_CSS_VALUE_SALMON: + case LXB_CSS_VALUE_SANDYBROWN: + case LXB_CSS_VALUE_SEAGREEN: + case LXB_CSS_VALUE_SEASHELL: + case LXB_CSS_VALUE_SIENNA: + case LXB_CSS_VALUE_SILVER: + case LXB_CSS_VALUE_SKYBLUE: + case LXB_CSS_VALUE_SLATEBLUE: + case LXB_CSS_VALUE_SLATEGRAY: + case LXB_CSS_VALUE_SLATEGREY: + case LXB_CSS_VALUE_SNOW: + case LXB_CSS_VALUE_SPRINGGREEN: + case LXB_CSS_VALUE_STEELBLUE: + case LXB_CSS_VALUE_TAN: + case LXB_CSS_VALUE_TEAL: + case LXB_CSS_VALUE_THISTLE: + case LXB_CSS_VALUE_TOMATO: + case LXB_CSS_VALUE_TURQUOISE: + case LXB_CSS_VALUE_VIOLET: + case LXB_CSS_VALUE_WHEAT: + case LXB_CSS_VALUE_WHITE: + case LXB_CSS_VALUE_WHITESMOKE: + case LXB_CSS_VALUE_YELLOW: + case LXB_CSS_VALUE_YELLOWGREEN: + color->type = type; + break; + + default: + return false; + } + + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +bool +lxb_css_property_state__undef(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_failed(parser); +} + +bool +lxb_css_property_state__custom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_status_t status; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property__custom_t *custom = declar->u.custom; + + (void) lexbor_str_init(&custom->value, parser->memory->mraw, 0); + if (custom->value.data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + status = lxb_css_syntax_token_serialize_str(token, &custom->value, + parser->memory->mraw); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_display(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_property_display_t *display; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + display = declar->u.display; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->a = type; + goto inside_listitem; + + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->a = type; + goto outside_listitem; + + case LXB_CSS_DISPLAY_TABLE: + case LXB_CSS_DISPLAY_FLEX: + case LXB_CSS_DISPLAY_GRID: + case LXB_CSS_DISPLAY_RUBY: + display->a = type; + goto outside; + + /* */ + case LXB_CSS_DISPLAY_LIST_ITEM: + display->a = type; + goto listitem_only; + + /* */ + case LXB_CSS_DISPLAY_TABLE_ROW_GROUP: + case LXB_CSS_DISPLAY_TABLE_HEADER_GROUP: + case LXB_CSS_DISPLAY_TABLE_FOOTER_GROUP: + case LXB_CSS_DISPLAY_TABLE_ROW: + case LXB_CSS_DISPLAY_TABLE_CELL: + case LXB_CSS_DISPLAY_TABLE_COLUMN_GROUP: + case LXB_CSS_DISPLAY_TABLE_COLUMN: + case LXB_CSS_DISPLAY_TABLE_CAPTION: + case LXB_CSS_DISPLAY_RUBY_BASE: + case LXB_CSS_DISPLAY_RUBY_TEXT: + case LXB_CSS_DISPLAY_RUBY_BASE_CONTAINER: + case LXB_CSS_DISPLAY_RUBY_TEXT_CONTAINER: + /* */ + case LXB_CSS_DISPLAY_CONTENTS: + case LXB_CSS_DISPLAY_NONE: + /* */ + case LXB_CSS_DISPLAY_INLINE_BLOCK: + case LXB_CSS_DISPLAY_INLINE_TABLE: + case LXB_CSS_DISPLAY_INLINE_FLEX: + case LXB_CSS_DISPLAY_INLINE_GRID: + display->a = type; + goto done; + + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + display->a = type; + goto done; + + default: + return lxb_css_parser_failed(parser); + } + +inside_listitem: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->b = type; + break; + + case LXB_CSS_DISPLAY_TABLE: + case LXB_CSS_DISPLAY_FLEX: + case LXB_CSS_DISPLAY_GRID: + case LXB_CSS_DISPLAY_RUBY: + display->b = type; + goto done; + + case LXB_CSS_DISPLAY_LIST_ITEM: + display->b = type; + goto flow_only; + + default: + return lxb_css_parser_failed(parser); + } + +listitem: + + lxb_css_property_state_get_type(parser, token, type); + + if (type == LXB_CSS_DISPLAY_LIST_ITEM) { + display->c = type; + goto done; + } + + return lxb_css_parser_failed(parser); + +outside: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + if (display->b == LXB_CSS_PROPERTY__UNDEF) { + display->b = type; + } + else { + display->c = type; + } + + goto done; + + default: + return lxb_css_parser_failed(parser); + } + +outside_listitem: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->b = type; + goto listitem; + + case LXB_CSS_DISPLAY_LIST_ITEM: + display->b = type; + goto outside; + + default: + return lxb_css_parser_failed(parser); + } + +listitem_only: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->b = type; + break; + + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->b = type; + goto outside; + + default: + return lxb_css_parser_failed(parser); + } + +flow_only: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->c = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + +done: + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_order(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_integer(parser, token, + &declar->u.order->integer); + if (res) { + declar->u.order->type = LXB_CSS_ORDER__INTEGER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.order->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_visibility(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_VISIBILITY_VISIBLE: + case LXB_CSS_VISIBILITY_HIDDEN: + case LXB_CSS_VISIBILITY_COLLAPSE: + declar->u.visibility->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_AUTO: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + declar->u.width->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_box_sizing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_CONTENT_BOX: + case LXB_CSS_VALUE_BORDER_BOX: + declar->u.box_sizing->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_min_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_min_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_max_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_NONE: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + declar->u.width->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_max_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_max_width(parser, token, ctx); +} + +static bool +lxb_css_property_state_mp(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_rule_declaration_t *declar, bool with_auto) +{ + unsigned int state; + lxb_css_value_type_t type; + lxb_css_property_margin_top_t *top; + + state = 1; + +next: + + switch (state) { + case 1: + top = &declar->u.margin->top; + break; + + case 2: + top = &declar->u.margin->right; + break; + + case 3: + top = &declar->u.margin->bottom; + break; + + case 4: + top = &declar->u.margin->left; + break; + + default: + return lxb_css_parser_failed(parser); + } + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + top->type = type; + break; + + case LXB_CSS_VALUE_AUTO: + if (with_auto) { + top->type = type; + break; + } + + /* Fall through. */ + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + } + else if (!lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *) top)) + { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + state++; + + goto next; +} + +static bool +lxb_css_property_state_mp_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_rule_declaration_t *declar, bool with_auto) +{ + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.margin_top->type = type; + break; + + case LXB_CSS_VALUE_AUTO: + if (with_auto) { + declar->u.margin_top->type = type; + break; + } + + /* Fall through. */ + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_margin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_padding(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +static bool +lxb_css_property_state_line_width_style_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_border_t *border) +{ + lxb_status_t status; + lxb_css_value_type_t type; + const lxb_css_data_t *unit; + lxb_css_value_length_t *length; + lxb_css_syntax_token_string_t *str; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + str = &lxb_css_syntax_token_dimension(token)->str; + + unit = lxb_css_unit_absolute_relative_by_name(str->data, + str->length); + if (unit == NULL) { + return false; + } + + length = &border->width.length; + + border->width.type = LXB_CSS_VALUE__LENGTH; + length->num = lxb_css_syntax_token_dimension(token)->num.num; + length->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + length->unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + length = &border->width.length; + + border->width.type = LXB_CSS_VALUE__NUMBER; + length->num = lxb_css_syntax_token_number(token)->num; + length->is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_THIN: + case LXB_CSS_VALUE_MEDIUM: + case LXB_CSS_VALUE_THICK: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + border->width.type = type; + break; + + case LXB_CSS_VALUE_NONE: + case LXB_CSS_VALUE_HIDDEN: + case LXB_CSS_VALUE_DOTTED: + case LXB_CSS_VALUE_DASHED: + case LXB_CSS_VALUE_SOLID: + case LXB_CSS_VALUE_DOUBLE: + case LXB_CSS_VALUE_GROOVE: + case LXB_CSS_VALUE_RIDGE: + case LXB_CSS_VALUE_INSET: + case LXB_CSS_VALUE_OUTSET: + if (border->style != LXB_CSS_VALUE__UNDEF) { + return false; + } + + border->style = type; + break; + + default: + goto color; + } + + break; + + default: + goto color; + } + + lxb_css_syntax_parser_consume(parser); + + return true; + +color: + + if (border->color.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + return lxb_css_property_state_color_handler(parser, token, &border->color, + &status); +} + +bool +lxb_css_property_state_border(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.border->style = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_border_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_top_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_right_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_bottom_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_left_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_background_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.color->type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + } + + res = lxb_css_property_state_color_handler(parser, token, + (lxb_css_value_color_t *) declar->u.color, + &status); + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_opacity(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_opacity_t *opacity = declar->u.opacity; + + res = lxb_css_property_state_number_percentage(parser, token, + (lxb_css_value_number_percentage_t *) opacity); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + opacity->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_position(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_POSITION_STATIC: + case LXB_CSS_POSITION_RELATIVE: + case LXB_CSS_POSITION_ABSOLUTE: + case LXB_CSS_POSITION_STICKY: + case LXB_CSS_POSITION_FIXED: + declar->u.position->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_block_start(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_inline_start(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_inline_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_text_transform(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_transform_t *tt; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + tt = declar->u.text_transform; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_TRANSFORM_NONE: + tt->type_case = type; + break; + + case LXB_CSS_TEXT_TRANSFORM_CAPITALIZE: + case LXB_CSS_TEXT_TRANSFORM_UPPERCASE: + case LXB_CSS_TEXT_TRANSFORM_LOWERCASE: + tt->type_case = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_WIDTH: + tt->full_width = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_SIZE_KANA: + tt->full_size_kana = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_TEXT_TRANSFORM_CAPITALIZE: + case LXB_CSS_TEXT_TRANSFORM_UPPERCASE: + case LXB_CSS_TEXT_TRANSFORM_LOWERCASE: + if (tt->type_case != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->type_case = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_WIDTH: + if (tt->full_width != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->full_width = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_SIZE_KANA: + if (tt->full_size_kana != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->full_size_kana = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_text_align(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_START: + case LXB_CSS_TEXT_ALIGN_END: + case LXB_CSS_TEXT_ALIGN_LEFT: + case LXB_CSS_TEXT_ALIGN_RIGHT: + case LXB_CSS_TEXT_ALIGN_CENTER: + case LXB_CSS_TEXT_ALIGN_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_MATCH_PARENT: + case LXB_CSS_TEXT_ALIGN_JUSTIFY_ALL: + declar->u.text_align->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_align_all(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_ALL_START: + case LXB_CSS_TEXT_ALIGN_ALL_END: + case LXB_CSS_TEXT_ALIGN_ALL_LEFT: + case LXB_CSS_TEXT_ALIGN_ALL_RIGHT: + case LXB_CSS_TEXT_ALIGN_ALL_CENTER: + case LXB_CSS_TEXT_ALIGN_ALL_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_ALL_MATCH_PARENT: + declar->u.text_align_all->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_align_last(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_LAST_AUTO: + case LXB_CSS_TEXT_ALIGN_LAST_START: + case LXB_CSS_TEXT_ALIGN_LAST_END: + case LXB_CSS_TEXT_ALIGN_LAST_LEFT: + case LXB_CSS_TEXT_ALIGN_LAST_RIGHT: + case LXB_CSS_TEXT_ALIGN_LAST_CENTER: + case LXB_CSS_TEXT_ALIGN_LAST_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_LAST_MATCH_PARENT: + declar->u.text_align_last->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_justify(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_JUSTIFY_AUTO: + case LXB_CSS_TEXT_JUSTIFY_NONE: + case LXB_CSS_TEXT_JUSTIFY_INTER_WORD: + case LXB_CSS_TEXT_JUSTIFY_INTER_CHARACTER: + declar->u.text_justify->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_indent(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_indent_t *text_indent; + + text_indent = declar->u.text_indent; + + res = lxb_css_property_state_length_percentage(parser, token, + &text_indent->length); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + text_indent->type = LXB_CSS_VALUE__LENGTH; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + if (res) { + return lxb_css_parser_failed(parser); + } + + text_indent->type = type; + break; + + /* Local. */ + case LXB_CSS_TEXT_INDENT_HANGING: + text_indent->hanging = type; + goto next; + + case LXB_CSS_TEXT_INDENT_EACH_LINE: + text_indent->each_line = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_length_percentage(parser, token, + &text_indent->length); + if (res) { + if (text_indent->type != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + text_indent->type = LXB_CSS_VALUE__LENGTH; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (text_indent->type == LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_TEXT_INDENT_HANGING: + if (text_indent->hanging != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + text_indent->hanging = type; + goto next; + + case LXB_CSS_TEXT_INDENT_EACH_LINE: + if (text_indent->each_line != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + text_indent->each_line = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_white_space(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WHITE_SPACE_NORMAL: + case LXB_CSS_WHITE_SPACE_PRE: + case LXB_CSS_WHITE_SPACE_NOWRAP: + case LXB_CSS_WHITE_SPACE_PRE_WRAP: + case LXB_CSS_WHITE_SPACE_BREAK_SPACES: + case LXB_CSS_WHITE_SPACE_PRE_LINE: + declar->u.white_space->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_tab_size(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_number_length(parser, token, + (lxb_css_value_number_length_t *) declar->u.tab_size); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.tab_size->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_word_break(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WORD_BREAK_NORMAL: + case LXB_CSS_WORD_BREAK_KEEP_ALL: + case LXB_CSS_WORD_BREAK_BREAK_ALL: + case LXB_CSS_WORD_BREAK_BREAK_WORD: + declar->u.word_break->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_line_break(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_LINE_BREAK_AUTO: + case LXB_CSS_LINE_BREAK_LOOSE: + case LXB_CSS_LINE_BREAK_NORMAL: + case LXB_CSS_LINE_BREAK_STRICT: + case LXB_CSS_LINE_BREAK_ANYWHERE: + declar->u.line_break->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_hyphens(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_HYPHENS_NONE: + case LXB_CSS_HYPHENS_MANUAL: + case LXB_CSS_HYPHENS_AUTO: + declar->u.hyphens->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_OVERFLOW_WRAP_NORMAL: + case LXB_CSS_OVERFLOW_WRAP_BREAK_WORD: + case LXB_CSS_OVERFLOW_WRAP_ANYWHERE: + declar->u.overflow_wrap->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_word_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_wrap(parser, token, ctx); +} + +bool +lxb_css_property_state_word_spacing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_length(parser, token, + &declar->u.word_spacing->length); + if (res) { + declar->u.word_spacing->type = LXB_CSS_VALUE__LENGTH; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WORD_SPACING_NORMAL: + declar->u.word_spacing->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_letter_spacing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_word_spacing(parser, token, ctx); +} + +bool +lxb_css_property_state_hanging_punctuation(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_hanging_punctuation_t *hp; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + hp = declar->u.hanging_punctuation; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_HANGING_PUNCTUATION_NONE: + hp->type_first = type; + break; + + case LXB_CSS_HANGING_PUNCTUATION_FIRST: + hp->type_first = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_FORCE_END: + case LXB_CSS_HANGING_PUNCTUATION_ALLOW_END: + hp->force_allow = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_LAST: + hp->last = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_HANGING_PUNCTUATION_FIRST: + if (hp->type_first != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->type_first = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_FORCE_END: + case LXB_CSS_HANGING_PUNCTUATION_ALLOW_END: + if (hp->force_allow != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->force_allow = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_LAST: + if (hp->last != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->last = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_font_family(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + size_t length; + const lxb_char_t *data; + lexbor_str_t *str; + lexbor_mraw_t *mraw; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_family_t *ff; + lxb_css_property_family_name_t *name; + + mraw = parser->memory->mraw; + ff = declar->u.font_family; + + while (token != NULL) { + name = lexbor_mraw_alloc(mraw, sizeof(lxb_css_property_family_name_t)); + if (name == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + data = lxb_css_syntax_token_ident(token)->data; + length = lxb_css_syntax_token_ident(token)->length; + + type = lxb_css_value_by_name(data, length); + if (type != LXB_CSS_VALUE__UNDEF) { + name->generic = true; + name->u.type = type; + + goto next; + } + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_STRING) { + data = lxb_css_syntax_token_string(token)->data; + length = lxb_css_syntax_token_string(token)->length; + } + else { + return lxb_css_parser_failed(parser); + } + + name->generic = false; + + str = &name->u.str; + + (void) lexbor_str_init(str, mraw, length); + if (name->u.str.data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + memcpy(str->data, data, length); + + str->data[length] = '\0'; + str->length = length; + + next: + + if (ff->first == NULL) { + ff->first = name; + } + else { + ff->last->next = name; + } + + name->next = NULL; + name->prev = ff->last; + ff->last = name; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + } + + lxb_css_property_state_check_token(parser, token); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_weight(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx)\ +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_weight_t *fw = declar->u.font_weight; + + res = lxb_css_property_state_number(parser, token, &fw->number); + + if (res) { + if (fw->number.num < 1 || fw->number.num > 1000) { + return lxb_css_parser_failed(parser); + } + + fw->type = LXB_CSS_FONT_WEIGHT__NUMBER; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_WEIGHT_NORMAL: + case LXB_CSS_FONT_WEIGHT_BOLD: + case LXB_CSS_FONT_WEIGHT_BOLDER: + case LXB_CSS_FONT_WEIGHT_LIGHTER: + fw->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_stretch(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_stretch_t *fs = declar->u.font_stretch; + + res = lxb_css_property_state_percentage(parser, token, &fs->percentage); + + if (res) { + if (fs->percentage.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FONT_STRETCH__PERCENTAGE; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_STRETCH_NORMAL: + case LXB_CSS_FONT_STRETCH_ULTRA_CONDENSED: + case LXB_CSS_FONT_STRETCH_EXTRA_CONDENSED: + case LXB_CSS_FONT_STRETCH_CONDENSED: + case LXB_CSS_FONT_STRETCH_SEMI_CONDENSED: + case LXB_CSS_FONT_STRETCH_SEMI_EXPANDED: + case LXB_CSS_FONT_STRETCH_EXPANDED: + case LXB_CSS_FONT_STRETCH_EXTRA_EXPANDED: + case LXB_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_style(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_style_t *fs = declar->u.font_style; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_STYLE_NORMAL: + case LXB_CSS_FONT_STYLE_ITALIC: + fs->type = type; + break; + + case LXB_CSS_FONT_STYLE_OBLIQUE: + fs->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_angle(parser, token, &fs->angle); + + if (res) { + if (fs->angle.num < -90 || fs->angle.num > 90) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + else { + fs->angle.unit = (lxb_css_unit_angle_t) LXB_CSS_UNIT__UNDEF; + } + + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_size(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_size_t *fs = declar->u.font_size; + + res = lxb_css_property_state_length_percentage(parser, token, &fs->length); + + if (res) { + if (fs->length.u.length.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FONT_SIZE__LENGTH; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_SIZE_XX_SMALL: + case LXB_CSS_FONT_SIZE_X_SMALL: + case LXB_CSS_FONT_SIZE_SMALL: + case LXB_CSS_FONT_SIZE_MEDIUM: + case LXB_CSS_FONT_SIZE_LARGE: + case LXB_CSS_FONT_SIZE_X_LARGE: + case LXB_CSS_FONT_SIZE_XX_LARGE: + case LXB_CSS_FONT_SIZE_XXX_LARGE: + case LXB_CSS_FONT_SIZE_MATH: + case LXB_CSS_FONT_SIZE_LARGER: + case LXB_CSS_FONT_SIZE_SMALLER: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_reference(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_REFERENCE_INLINE: + case LXB_CSS_FLOAT_REFERENCE_COLUMN: + case LXB_CSS_FLOAT_REFERENCE_REGION: + case LXB_CSS_FLOAT_REFERENCE_PAGE: + declar->u.float_reference->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_t *fp = declar->u.floatp; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (token->type == LXB_CSS_SYNTAX_TOKEN_FUNCTION) { + goto snap; + } + + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_BLOCK_START: + case LXB_CSS_FLOAT_BLOCK_END: + case LXB_CSS_FLOAT_INLINE_START: + case LXB_CSS_FLOAT_INLINE_END: + case LXB_CSS_FLOAT_SNAP_BLOCK: + case LXB_CSS_FLOAT_SNAP_INLINE: + case LXB_CSS_FLOAT_LEFT: + case LXB_CSS_FLOAT_RIGHT: + case LXB_CSS_FLOAT_TOP: + case LXB_CSS_FLOAT_BOTTOM: + case LXB_CSS_FLOAT_NONE: + fp->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +snap: + + type = lxb_css_value_by_name(lxb_css_syntax_token_function(token)->data, + lxb_css_syntax_token_function(token)->length); + + if (type != LXB_CSS_FLOAT_SNAP_BLOCK + && type != LXB_CSS_FLOAT_SNAP_INLINE) + { + return lxb_css_parser_failed(parser); + } + + fp->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_length(parser, token, &fp->length.length); + if (!res) { + return lxb_css_parser_failed(parser); + } + + fp->length.type = LXB_CSS_VALUE__LENGTH; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + fp->snap_type = LXB_CSS_VALUE__UNDEF; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLOAT_START: + case LXB_CSS_FLOAT_END: + if (fp->type != LXB_CSS_FLOAT_SNAP_BLOCK) { + return lxb_css_parser_failed(parser); + } + + fp->snap_type = type; + break; + + case LXB_CSS_FLOAT_LEFT: + case LXB_CSS_FLOAT_RIGHT: + if (fp->type != LXB_CSS_FLOAT_SNAP_INLINE) { + return lxb_css_parser_failed(parser); + } + + fp->snap_type = type; + break; + + case LXB_CSS_FLOAT_NEAR: + fp->snap_type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); +} + +bool +lxb_css_property_state_clear(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_CLEAR_INLINE_START: + case LXB_CSS_CLEAR_INLINE_END: + case LXB_CSS_CLEAR_BLOCK_START: + case LXB_CSS_CLEAR_BLOCK_END: + case LXB_CSS_CLEAR_LEFT: + case LXB_CSS_CLEAR_RIGHT: + case LXB_CSS_CLEAR_TOP: + case LXB_CSS_CLEAR_BOTTOM: + case LXB_CSS_CLEAR_NONE: + declar->u.clear->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_defer(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_defer_t *fd = declar->u.float_defer; + + res = lxb_css_property_state_integer(parser, token, &fd->integer); + if (res) { + fd->type = LXB_CSS_FLOAT_DEFER__INTEGER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_DEFER_LAST: + case LXB_CSS_FLOAT_DEFER_NONE: + fd->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_offset(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_offset_t *fo = declar->u.float_offset; + + res = lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *) fo); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fo->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_wrap_flow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRAP_FLOW_AUTO: + case LXB_CSS_WRAP_FLOW_BOTH: + case LXB_CSS_WRAP_FLOW_START: + case LXB_CSS_WRAP_FLOW_END: + case LXB_CSS_WRAP_FLOW_MINIMUM: + case LXB_CSS_WRAP_FLOW_MAXIMUM: + case LXB_CSS_WRAP_FLOW_CLEAR: + declar->u.wrap_flow->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_wrap_through(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRAP_THROUGH_WRAP: + case LXB_CSS_WRAP_THROUGH_NONE: + declar->u.wrap_through->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_direction(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + declar->u.flex_direction->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + declar->u.flex_wrap->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_flow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_flow_t *ff = declar->u.flex_flow; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + ff->type_direction = type; + goto direction; + + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + ff->wrap = type; + goto wrap; + + default: + return lxb_css_parser_failed(parser); + } + +direction: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + ff->wrap = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + goto done; + +wrap: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + ff->type_direction = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + +done: + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +lxb_inline bool +lxb_css_property_state_flex_grow_shrink(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_flex_t *flex) +{ + bool res; + + res = lxb_css_property_state_number(parser, token, &flex->grow.number); + if (!res) { + return false; + } + + flex->grow.type = LXB_CSS_FLEX_GROW__NUMBER; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number(parser, token, &flex->shrink.number); + if (res) { + flex->shrink.type = LXB_CSS_FLEX_SHRINK__NUMBER; + } + + return true; +} + +lxb_inline bool +lxb_css_property_state_flex_grow_basis(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_flex_t *flex) +{ + bool res; + lxb_css_value_type_t type; + + res = lxb_css_property_state_width_handler(parser, token, + (lxb_css_property_flex_basis_t *) &flex->basis); + if (res) { + return true; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + if (type == LXB_CSS_FLEX_BASIS_CONTENT) { + flex->basis.type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + } + + return false; +} + +bool +lxb_css_property_state_flex(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_t *flex = declar->u.flex; + + res = lxb_css_property_state_flex_grow_shrink(parser, token, flex); + + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_flex_grow_basis(parser, token, flex); + + if (!res && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + flex->basis.type = LXB_CSS_VALUE__NUMBER; + flex->basis.u.length.num = flex->grow.number.num; + flex->basis.u.length.unit = LXB_CSS_UNIT__UNDEF; + flex->basis.u.length.is_float = flex->grow.number.is_float; + + flex->grow.type = LXB_CSS_VALUE__UNDEF; + + if (flex->shrink.type != LXB_CSS_VALUE__UNDEF) { + flex->grow = flex->shrink; + flex->shrink.type = LXB_CSS_VALUE__UNDEF; + + goto try_shrink_last; + } + + res = lxb_css_property_state_flex_grow_shrink(parser, token, flex); + if (!res) { + return lxb_css_parser_failed(parser); + } + } + + return lxb_css_parser_success(parser); + } + else { + res = lxb_css_property_state_flex_grow_basis(parser, token, flex); + + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + (void) lxb_css_property_state_flex_grow_shrink(parser, token, flex); + + return lxb_css_parser_success(parser); + } + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_NONE: + flex->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +try_shrink_last: + + res = lxb_css_property_state_number(parser, token, &flex->shrink.number); + if (res) { + flex->shrink.type = LXB_CSS_FLEX_SHRINK__NUMBER; + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_grow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_grow_t *fg = declar->u.flex_grow; + + res = lxb_css_property_state_number(parser, token, &fg->number); + if (res) { + if (fg->number.num < 0) { + return lxb_css_parser_failed(parser); + } + + fg->type = LXB_CSS_FLEX_GROW__NUMBER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fg->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_shrink(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_grow_t *fs = declar->u.flex_shrink; + + res = lxb_css_property_state_number(parser, token, &fs->number); + if (res) { + if (fs->number.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FLEX_SHRINK__NUMBER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_basis(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_basis_t *fb = declar->u.flex_basis; + + res = lxb_css_property_state_width_handler(parser, token, + (lxb_css_property_width_t *) fb); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_FLEX_BASIS_CONTENT: + fb->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_justify_content(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_JUSTIFY_CONTENT_FLEX_START: + case LXB_CSS_JUSTIFY_CONTENT_FLEX_END: + case LXB_CSS_JUSTIFY_CONTENT_CENTER: + case LXB_CSS_JUSTIFY_CONTENT_SPACE_BETWEEN: + case LXB_CSS_JUSTIFY_CONTENT_SPACE_AROUND: + declar->u.justify_content->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_items(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_ITEMS_FLEX_START: + case LXB_CSS_ALIGN_ITEMS_FLEX_END: + case LXB_CSS_ALIGN_ITEMS_CENTER: + case LXB_CSS_ALIGN_ITEMS_BASELINE: + case LXB_CSS_ALIGN_ITEMS_STRETCH: + declar->u.align_items->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_self(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_SELF_AUTO: + case LXB_CSS_ALIGN_SELF_FLEX_START: + case LXB_CSS_ALIGN_SELF_FLEX_END: + case LXB_CSS_ALIGN_SELF_CENTER: + case LXB_CSS_ALIGN_SELF_BASELINE: + case LXB_CSS_ALIGN_SELF_STRETCH: + declar->u.align_self->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_content(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_CONTENT_FLEX_START: + case LXB_CSS_ALIGN_CONTENT_FLEX_END: + case LXB_CSS_ALIGN_CONTENT_CENTER: + case LXB_CSS_ALIGN_CONTENT_SPACE_BETWEEN: + case LXB_CSS_ALIGN_CONTENT_SPACE_AROUND: + case LXB_CSS_ALIGN_CONTENT_STRETCH: + declar->u.align_content->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_dominant_baseline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_DOMINANT_BASELINE_AUTO: + case LXB_CSS_DOMINANT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_DOMINANT_BASELINE_ALPHABETIC: + case LXB_CSS_DOMINANT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_DOMINANT_BASELINE_MIDDLE: + case LXB_CSS_DOMINANT_BASELINE_CENTRAL: + case LXB_CSS_DOMINANT_BASELINE_MATHEMATICAL: + case LXB_CSS_DOMINANT_BASELINE_HANGING: + case LXB_CSS_DOMINANT_BASELINE_TEXT_TOP: + declar->u.dominant_baseline->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_alignment_baseline_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_alignment_baseline_t *ab) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_ALIGNMENT_BASELINE_BASELINE: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_ALIGNMENT_BASELINE_ALPHABETIC: + case LXB_CSS_ALIGNMENT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_ALIGNMENT_BASELINE_MIDDLE: + case LXB_CSS_ALIGNMENT_BASELINE_CENTRAL: + case LXB_CSS_ALIGNMENT_BASELINE_MATHEMATICAL: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_TOP: + ab->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_baseline_shift_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_baseline_shift_t *bs) +{ + bool res; + lxb_css_value_type_t type; + + res = lxb_css_property_state_length_percentage(parser, token, bs); + + if (res) { + return true; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_BASELINE_SHIFT_SUB: + case LXB_CSS_BASELINE_SHIFT_SUPER: + case LXB_CSS_BASELINE_SHIFT_TOP: + case LXB_CSS_BASELINE_SHIFT_CENTER: + case LXB_CSS_BASELINE_SHIFT_BOTTOM: + bs->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_vertical_align(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + uint8_t maps; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_vertical_align_t *va = declar->u.vertical_align; + + maps = 0; + +again: + + res = lxb_css_property_state_alignment_baseline_h(parser, token, + &va->alignment); + if (res) { + if (maps & 1 << 1) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 1; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_baseline_shift_h(parser, token, + &va->shift); + if (res) { + if (maps & 1 << 2) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 2; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + } + else { + res = lxb_css_property_state_baseline_shift_h(parser, token, + &va->shift); + if (res) { + if (maps & 1 << 2) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 2; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_alignment_baseline_h(parser, token, + &va->alignment); + if (res) { + if (maps & 1 << 1) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 1; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + } + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (maps != 0) { + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + if (maps & 1 << 3) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_VERTICAL_ALIGN_FIRST: + case LXB_CSS_VERTICAL_ALIGN_LAST: + va->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + maps = 1 << 3; + + goto again; +} + +bool +lxb_css_property_state_baseline_source(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_BASELINE_SOURCE_AUTO: + case LXB_CSS_BASELINE_SOURCE_FIRST: + case LXB_CSS_BASELINE_SOURCE_LAST: + declar->u.baseline_source->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_alignment_baseline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGNMENT_BASELINE_BASELINE: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_ALIGNMENT_BASELINE_ALPHABETIC: + case LXB_CSS_ALIGNMENT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_ALIGNMENT_BASELINE_MIDDLE: + case LXB_CSS_ALIGNMENT_BASELINE_CENTRAL: + case LXB_CSS_ALIGNMENT_BASELINE_MATHEMATICAL: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_TOP: + declar->u.alignment_baseline->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_baseline_shift(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_length_percentage(parser, token, + declar->u.baseline_shift); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_BASELINE_SHIFT_SUB: + case LXB_CSS_BASELINE_SHIFT_SUPER: + case LXB_CSS_BASELINE_SHIFT_TOP: + case LXB_CSS_BASELINE_SHIFT_CENTER: + case LXB_CSS_BASELINE_SHIFT_BOTTOM: + declar->u.baseline_shift->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_line_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_number_length_percentage(parser, token, + declar->u.line_height); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_LINE_HEIGHT_NORMAL: + declar->u.line_height->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_z_index(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_integer(parser, token, + &declar->u.z_index->integer); + if (res) { + declar->u.z_index->type = LXB_CSS_VALUE__INTEGER; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_Z_INDEX_AUTO: + declar->u.line_height->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_direction(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_DIRECTION_LTR: + case LXB_CSS_DIRECTION_RTL: + declar->u.direction->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_unicode_bidi(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_UNICODE_BIDI_NORMAL: + case LXB_CSS_UNICODE_BIDI_EMBED: + case LXB_CSS_UNICODE_BIDI_ISOLATE: + case LXB_CSS_UNICODE_BIDI_BIDI_OVERRIDE: + case LXB_CSS_UNICODE_BIDI_ISOLATE_OVERRIDE: + case LXB_CSS_UNICODE_BIDI_PLAINTEXT: + declar->u.unicode_bidi->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_writing_mode(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRITING_MODE_HORIZONTAL_TB: + case LXB_CSS_WRITING_MODE_VERTICAL_RL: + case LXB_CSS_WRITING_MODE_VERTICAL_LR: + case LXB_CSS_WRITING_MODE_SIDEWAYS_RL: + case LXB_CSS_WRITING_MODE_SIDEWAYS_LR: + declar->u.writing_mode->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_orientation(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ORIENTATION_MIXED: + case LXB_CSS_TEXT_ORIENTATION_UPRIGHT: + case LXB_CSS_TEXT_ORIENTATION_SIDEWAYS: + declar->u.text_orientation->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_combine_upright(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_combine_upright_t *tcu = declar->u.text_combine_upright; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_COMBINE_UPRIGHT_NONE: + case LXB_CSS_TEXT_COMBINE_UPRIGHT_ALL: + tcu->type = type; + break; + + case LXB_CSS_TEXT_COMBINE_UPRIGHT_DIGITS: + tcu->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_integer(parser, token, + &tcu->digits); + if (res) { + if (tcu->digits.num != 2 && tcu->digits.num != 4) { + return lxb_css_parser_failed(parser); + } + } + + return lxb_css_parser_success(parser); + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_x(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_OVERFLOW_X_VISIBLE: + case LXB_CSS_OVERFLOW_X_HIDDEN: + case LXB_CSS_OVERFLOW_X_CLIP: + case LXB_CSS_OVERFLOW_X_SCROLL: + case LXB_CSS_OVERFLOW_X_AUTO: + declar->u.overflow_x->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_y(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_overflow_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_overflow_inline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_text_overflow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_OVERFLOW_CLIP: + case LXB_CSS_TEXT_OVERFLOW_ELLIPSIS: + declar->u.text_overflow->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_property_state_text_decoration_line_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_text_decoration_line_t *tdl) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return LXB_STATUS_NEXT; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_TEXT_DECORATION_LINE_NONE: + tdl->type = type; + + lxb_css_syntax_parser_consume(parser); + return LXB_STATUS_OK; + + default: + goto first; + } + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + if (token == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return LXB_STATUS_OK; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + +first: + + switch (type) { + case LXB_CSS_TEXT_DECORATION_LINE_UNDERLINE: + if (tdl->underline != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->underline = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_OVERLINE: + if (tdl->overline != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->overline = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_LINE_THROUGH: + if (tdl->line_through != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->line_through = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_BLINK: + if (tdl->blink != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->blink = type; + goto next; + + default: + if (tdl->underline != LXB_CSS_VALUE__UNDEF + || tdl->overline != LXB_CSS_VALUE__UNDEF + || tdl->line_through != LXB_CSS_VALUE__UNDEF + || tdl->blink != LXB_CSS_VALUE__UNDEF) + { + return LXB_STATUS_OK; + } + + return LXB_STATUS_NEXT; + } +} + +bool +lxb_css_property_state_text_decoration_line(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_decoration_line_t *tdl = declar->u.text_decoration_line; + + status = lxb_css_property_state_text_decoration_line_h(parser, token, tdl); + + if (status == LXB_STATUS_OK) { + return lxb_css_parser_success(parser); + } + else if (status == LXB_STATUS_STOP) { + return lxb_css_parser_failed(parser); + } + else if (status != LXB_STATUS_NEXT) { + return lxb_css_parser_memory_fail(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + tdl->type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_text_decoration_style_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_text_decoration_style_t *tds) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_TEXT_DECORATION_STYLE_SOLID: + case LXB_CSS_TEXT_DECORATION_STYLE_DOUBLE: + case LXB_CSS_TEXT_DECORATION_STYLE_DOTTED: + case LXB_CSS_TEXT_DECORATION_STYLE_DASHED: + case LXB_CSS_TEXT_DECORATION_STYLE_WAVY: + tds->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_text_decoration_style(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_DECORATION_STYLE_SOLID: + case LXB_CSS_TEXT_DECORATION_STYLE_DOUBLE: + case LXB_CSS_TEXT_DECORATION_STYLE_DOTTED: + case LXB_CSS_TEXT_DECORATION_STYLE_DASHED: + case LXB_CSS_TEXT_DECORATION_STYLE_WAVY: + declar->u.text_decoration_style->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_decoration_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_text_decoration(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res, line, style, color; + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_decoration_t *td = declar->u.text_decoration; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + goto lsc; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + td->line.type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + +lsc: + + line = false; + style = false; + color = false; + + for (size_t i = 0; i < 3; i++) { + if (!line) { + status = lxb_css_property_state_text_decoration_line_h(parser, token, + &td->line); + if (status == LXB_STATUS_OK) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + line = true; + } + else if (status == LXB_STATUS_STOP) { + return lxb_css_parser_failed(parser); + } + else if (status != LXB_STATUS_NEXT) { + return lxb_css_parser_memory_fail(parser); + } + } + + if (!style) { + res = lxb_css_property_state_text_decoration_style_h(parser, token, + &td->style); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + style = true; + } + } + + if (!color) { + res = lxb_css_property_state_color_handler(parser, token, + (lxb_css_value_color_t *) &td->color, + &status); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + color = true; + } + else { + if (status != LXB_STATUS_OK) { + return lxb_css_parser_failed(parser); + } + } + } + } + + if (!line && !style && !color) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/property/types.h b/ext/lexbor/lexbor/css/property/types.h new file mode 100644 index 000000000000..3a23f125a698 --- /dev/null +++ b/ext/lexbor/lexbor/css/property/types.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +/* + * Caution! + * This file generated by the script "utils/lexbor/css/names.py"! + * Do not change this file! + */ + + +#ifndef LXB_CSS_PROPERTY_TYPES_H +#define LXB_CSS_PROPERTY_TYPES_H + + + + + +#endif /* LXB_CSS_PROPERTY_TYPES_H */ diff --git a/ext/lexbor/lexbor/css/rule.c b/ext/lexbor/lexbor/css/rule.c new file mode 100644 index 000000000000..5ee938730ea8 --- /dev/null +++ b/ext/lexbor/lexbor/css/rule.c @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/rule.h" +#include "lexbor/css/parser.h" +#include "lexbor/core/serialize.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/selectors/selectors.h" + + +void * +lxb_css_rule_destroy(lxb_css_rule_t *rule, bool self_destroy) +{ + switch (rule->type) { + case LXB_CSS_RULE_LIST: + return lxb_css_rule_list_destroy(lxb_css_rule_list(rule), + self_destroy); + case LXB_CSS_RULE_AT_RULE: + return lxb_css_rule_at_destroy(lxb_css_rule_at(rule), + self_destroy); + case LXB_CSS_RULE_STYLE: + return lxb_css_rule_style_destroy(lxb_css_rule_style(rule), + self_destroy); + case LXB_CSS_RULE_BAD_STYLE: + return lxb_css_rule_bad_style_destroy(lxb_css_rule_bad_style(rule), + self_destroy); + case LXB_CSS_RULE_DECLARATION: + return lxb_css_rule_declaration_destroy(lxb_css_rule_declaration(rule), + self_destroy); + case LXB_CSS_RULE_DECLARATION_LIST: + return lxb_css_rule_declaration_list_destroy(lxb_css_rule_declaration_list(rule), + self_destroy); + case LXB_CSS_RULE_STYLESHEET: + case LXB_CSS_RULE_UNDEF: + return NULL; + } + + return NULL; +} + +lxb_status_t +lxb_css_rule_serialize(const lxb_css_rule_t *rule, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (rule->type) { + case LXB_CSS_RULE_LIST: + return lxb_css_rule_list_serialize(lxb_css_rule_list(rule), cb, ctx); + + case LXB_CSS_RULE_AT_RULE: + return lxb_css_rule_at_serialize(lxb_css_rule_at(rule), cb, ctx); + + case LXB_CSS_RULE_STYLE: + return lxb_css_rule_style_serialize(lxb_css_rule_style(rule), + cb, ctx); + case LXB_CSS_RULE_BAD_STYLE: + return lxb_css_rule_bad_style_serialize(lxb_css_rule_bad_style(rule), + cb, ctx); + case LXB_CSS_RULE_DECLARATION: + return lxb_css_rule_declaration_serialize(lxb_css_rule_declaration(rule), + cb, ctx); + case LXB_CSS_RULE_DECLARATION_LIST: + return lxb_css_rule_declaration_list_serialize(lxb_css_rule_declaration_list(rule), + cb, ctx); + case LXB_CSS_RULE_STYLESHEET: + case LXB_CSS_RULE_UNDEF: + break; + } + + return LXB_STATUS_ERROR_WRONG_ARGS; +} + +lxb_status_t +lxb_css_rule_serialize_chain(const lxb_css_rule_t *rule, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t ws_str[] = "\n"; + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + + while (rule != NULL) { + lexbor_serialize_write(cb, ws_str, (sizeof(ws_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_list_t * +lxb_css_rule_list_destroy(lxb_css_rule_list_t *list, bool self_destroy) +{ + lxb_css_rule_t *rule, *next, *parent; + lxb_css_rule_t *child_rule; + lxb_css_memory_t *memory; + lxb_css_rule_at_t *at; + lxb_css_rule_style_t *style; + lxb_css_rule_bad_style_t *bad; + lxb_css_rule_list_t *sub_list; + lxb_css_rule_declaration_list_t *declr_list; + + if (list == NULL) { + return NULL; + } + + rule = list->first; + memory = lxb_css_rule(list)->memory; + + while (rule != NULL) { + child_rule = NULL; + + switch (rule->type) { + case LXB_CSS_RULE_LIST: + sub_list = lxb_css_rule_list(rule); + + if (sub_list->first != NULL) { + child_rule = sub_list->first; + + sub_list->first = NULL; + sub_list->last = NULL; + } + break; + + case LXB_CSS_RULE_STYLE: + style = lxb_css_rule_style(rule); + + if (style->child != NULL) { + child_rule = lxb_css_rule(style->child); + style->child = NULL; + } + break; + + case LXB_CSS_RULE_BAD_STYLE: + bad = lxb_css_rule_bad_style(rule); + + if (bad->child != NULL) { + child_rule = lxb_css_rule(bad->child); + bad->child = NULL; + } + break; + + case LXB_CSS_RULE_AT_RULE: + at = lxb_css_rule_at(rule); + + if (at->type == LXB_CSS_AT_RULE_MEDIA) { + if (at->u.media != NULL && at->u.media->block != NULL) { + child_rule = lxb_css_rule(at->u.media->block); + at->u.media->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE__UNDEF) { + if (at->u.undef != NULL && at->u.undef->block != NULL) { + child_rule = lxb_css_rule(at->u.undef->block); + at->u.undef->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE__CUSTOM) { + if (at->u.custom != NULL && at->u.custom->block != NULL) { + child_rule = lxb_css_rule(at->u.custom->block); + at->u.custom->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE_FONT_FACE) { + if (at->u.font_face != NULL && at->u.font_face->block != NULL) { + child_rule = lxb_css_rule(at->u.font_face->block); + at->u.font_face->block = NULL; + } + } + break; + + case LXB_CSS_RULE_DECLARATION_LIST: + declr_list = lxb_css_rule_declaration_list(rule); + + if (declr_list->first != NULL) { + child_rule = declr_list->first; + + declr_list->first = NULL; + declr_list->last = NULL; + } + break; + + default: + break; + } + + if (child_rule != NULL) { + rule = child_rule; + continue; + } + + next = rule->next; + parent = rule->parent; + + (void) lxb_css_rule_destroy(rule, true); + + if (next != NULL) { + rule = next; + } + else { + if (parent == lxb_css_rule(list)) { + break; + } + + rule = parent; + } + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, list); + } + + list->first = NULL; + list->last = NULL; + + return list; +} + +lxb_status_t +lxb_css_rule_list_serialize(const lxb_css_rule_list_t *list, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + lxb_css_rule_t *rule; + + static const lxb_char_t nl_str[] = "\n"; + + rule = list->first; + + if (rule == NULL) { + return LXB_STATUS_OK; + } + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + + while (rule != NULL) { + lexbor_serialize_write(cb, nl_str, (sizeof(nl_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_at_t * +lxb_css_rule_at_destroy(lxb_css_rule_at_t *at, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(at)->memory; + + switch (at->type) { + case LXB_CSS_AT_RULE__UNDEF: + (void) lxb_css_at_rule__undef_destroy(memory, at->u.undef, true); + break; + + case LXB_CSS_AT_RULE_MEDIA: + (void) lxb_css_at_rule_media_destroy(memory, at->u.media, true); + break; + + case LXB_CSS_AT_RULE_NAMESPACE: + (void) lxb_css_at_rule_namespace_destroy(memory, at->u.ns, true); + break; + + case LXB_CSS_AT_RULE__LAST_ENTRY: + break; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, at); + } + + return at; +} + +lxb_status_t +lxb_css_rule_at_serialize(const lxb_css_rule_at_t *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule__undef_t *undef; + const lxb_css_at_rule__custom_t *custom; + const lxb_css_entry_at_rule_data_t *data, *undata; + + static const lxb_char_t at_str[] = "@"; + + data = lxb_css_at_rule_by_id(at->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, at_str, (sizeof(at_str) - 1), ctx, status); + + if (at->type == LXB_CSS_AT_RULE__UNDEF) { + undef = at->u.undef; + + undata = lxb_css_at_rule_by_id(undef->type); + if (undata == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, undata->name, undata->length, ctx, status); + } + else if (at->type == LXB_CSS_AT_RULE__CUSTOM) { + custom = at->u.custom; + + lexbor_serialize_write(cb, custom->name.data, + custom->name.length, ctx, status); + } + else { + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + } + + return data->serialize(at->u.user, cb, ctx); +} + +lxb_status_t +lxb_css_rule_at_serialize_name(const lxb_css_rule_at_t *at, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_at_rule_serialize_name(at->u.user, at->type, cb, ctx); +} + +lxb_css_rule_style_t * +lxb_css_rule_style_destroy(lxb_css_rule_style_t *style, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(style)->memory; + + lxb_css_selector_list_destroy(style->selector); + (void) lxb_css_rule_declaration_list_destroy(style->declarations, true); + (void) lxb_css_rule_list_destroy(style->child, true); + + style->selector = NULL; + style->declarations = NULL; + style->child = NULL; + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, style); + } + + return style; +} + +lxb_status_t +lxb_css_rule_style_serialize(const lxb_css_rule_style_t *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t lc_str[] = " {"; + static const lxb_char_t rc_str[] = "}"; + static const lxb_char_t cm_str[] = "; "; + + status = lxb_css_selector_serialize_list_chain(style->selector, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (style->declarations != NULL) { + lexbor_serialize_write(cb, lc_str, (sizeof(lc_str) - 1), ctx, status); + + status = lxb_css_rule_declaration_list_serialize(style->declarations, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (style->child == NULL) { + lexbor_serialize_write(cb, rc_str, (sizeof(rc_str) - 1), + ctx, status); + } + } + + if (style->child != NULL && style->child->first != NULL) { + lexbor_serialize_write(cb, cm_str, (sizeof(cm_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(style->child, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (style->declarations != NULL) { + lexbor_serialize_write(cb, rc_str, (sizeof(rc_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_bad_style_t * +lxb_css_rule_bad_style_destroy(lxb_css_rule_bad_style_t *bad, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(bad)->memory; + + (void) lexbor_str_destroy(&bad->selectors, memory->mraw, false); + bad->declarations = lxb_css_rule_declaration_list_destroy(bad->declarations, + true); + bad->child = lxb_css_rule_list_destroy(bad->child, true); + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, bad); + } + + return bad; +} + +lxb_status_t +lxb_css_rule_bad_style_serialize(const lxb_css_rule_bad_style_t *bad, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t lc_str[] = "{"; + static const lxb_char_t rc_str[] = "}"; + + if (bad->selectors.data != NULL) { + lexbor_serialize_write(cb, bad->selectors.data, bad->selectors.length, + ctx, status); + } + + if (bad->declarations != NULL) { + lexbor_serialize_write(cb, lc_str, (sizeof(lc_str) - 1), ctx, status); + + status = lxb_css_rule_declaration_list_serialize(bad->declarations, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(rc_str, (sizeof(rc_str) - 1), ctx); + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_declaration_list_t * +lxb_css_rule_declaration_list_destroy(lxb_css_rule_declaration_list_t *list, + bool self_destroy) +{ + lxb_css_rule_t *declr, *next; + + if (list == NULL) { + return NULL; + } + + declr = list->first; + + while (declr != NULL) { + next = declr->next; + (void) lxb_css_rule_destroy(declr, true); + declr = next; + } + + if (self_destroy) { + return lexbor_mraw_free(lxb_css_rule(list)->memory->tree, list); + } + + list->first = NULL; + list->last = NULL; + + return list; +} + +lxb_status_t +lxb_css_rule_declaration_list_serialize(const lxb_css_rule_declaration_list_t *list, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_rule_t *declr; + + static const lxb_char_t sm_str[] = "; "; + + declr = list->first; + + if (declr == NULL) { + return LXB_STATUS_OK; + } + + status = lxb_css_rule_serialize(declr, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + declr = declr->next; + + while (declr != NULL) { + lexbor_serialize_write(cb, sm_str, (sizeof(sm_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(declr, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + declr = declr->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_declaration_t * +lxb_css_rule_declaration_destroy(lxb_css_rule_declaration_t *declr, + bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(declr)->memory; + + if (declr->u.user != NULL) { + declr->u.user = lxb_css_property_destroy(memory, declr->u.user, + declr->type, true); + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, declr); + } + + return declr; +} + +lxb_status_t +lxb_css_rule_declaration_serialize(const lxb_css_rule_declaration_t *declaration, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_entry_data_t *data, *undata; + const lxb_css_property__undef_t *undef; + const lxb_css_property__custom_t *custom; + + static const lxb_char_t cl_str[] = ": "; + static const lxb_char_t imp_str[] = " !important"; + + data = lxb_css_property_by_id(declaration->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + if (declaration->type == LXB_CSS_PROPERTY__UNDEF) { + undef = declaration->u.undef; + + if (undef->type > LXB_CSS_PROPERTY__CUSTOM) { + undata = lxb_css_property_by_id(undef->type); + if (undata == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, undata->name, undata->length, ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + } + else if (declaration->type == LXB_CSS_PROPERTY__CUSTOM) { + custom = declaration->u.custom; + + lexbor_serialize_write(cb, custom->name.data, custom->name.length, + ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + else { + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + + status = data->serialize(declaration->u.user, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (declaration->important && declaration->type != LXB_CSS_PROPERTY__UNDEF) { + lexbor_serialize_write(cb, imp_str, (sizeof(imp_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_rule_declaration_serialize_name(const lxb_css_rule_declaration_t *declr, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_serialize_name(declr->u.user, declr->type, cb, ctx); +} diff --git a/ext/lexbor/lexbor/css/rule.h b/ext/lexbor/lexbor/css/rule.h index bd191f9b6519..d192a0161ccd 100644 --- a/ext/lexbor/lexbor/css/rule.h +++ b/ext/lexbor/lexbor/css/rule.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -46,9 +46,6 @@ struct lxb_css_rule { lxb_css_rule_t *prev; lxb_css_rule_t *parent; - const lxb_char_t *begin; - const lxb_char_t *end; - lxb_css_memory_t *memory; size_t ref_count; }; @@ -68,10 +65,15 @@ struct lxb_css_rule_at { union { lxb_css_at_rule__undef_t *undef; lxb_css_at_rule__custom_t *custom; + lxb_css_at_rule_font_face_t *font_face; lxb_css_at_rule_media_t *media; lxb_css_at_rule_namespace_t *ns; void *user; } u; + + size_t name_begin; + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_style { @@ -79,6 +81,10 @@ struct lxb_css_rule_style { lxb_css_selector_list_t *selector; lxb_css_rule_declaration_list_t *declarations; + lxb_css_rule_list_t *child; + + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_bad_style { @@ -86,6 +92,10 @@ struct lxb_css_rule_bad_style { lexbor_str_t selectors; lxb_css_rule_declaration_list_t *declarations; + lxb_css_rule_list_t *child; + + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_declaration_list { @@ -97,6 +107,16 @@ struct lxb_css_rule_declaration_list { size_t count; }; +typedef struct { + size_t name_begin; + size_t name_end; + size_t value_begin; + size_t value_end; + size_t important_begin; + size_t important_end; +} +lxb_css_rule_declaration_offset_t; + struct lxb_css_rule_declaration { lxb_css_rule_t rule; uintptr_t type; @@ -204,7 +224,9 @@ struct lxb_css_rule_declaration { void *user; } u; - bool important; + lxb_css_rule_declaration_offset_t offset; + + bool important; }; diff --git a/ext/lexbor/lexbor/css/selectors/base.h b/ext/lexbor/lexbor/css/selectors/base.h index 279c1e5f68c3..3151f74b04ee 100644 --- a/ext/lexbor/lexbor/css/selectors/base.h +++ b/ext/lexbor/lexbor/css/selectors/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Alexander Borisov + * Copyright (C) 2021-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_CSS_SELECTORS_VERSION_MAJOR 1 -#define LXB_CSS_SELECTORS_VERSION_MINOR 1 +#define LXB_CSS_SELECTORS_VERSION_MINOR 3 #define LXB_CSS_SELECTORS_VERSION_PATCH 0 #define LXB_CSS_SELECTORS_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_const.h b/ext/lexbor/lexbor/css/selectors/pseudo_const.h index 2b19f1888147..9fa5bb2177c7 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_const.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_const.h @@ -69,15 +69,16 @@ typedef enum { LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS = 0x0003, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS = 0x0004, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG = 0x0005, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT = 0x0006, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0007, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL = 0x0008, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0009, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL = 0x000a, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x000b, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x000c, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE = 0x000d, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__LAST_ENTRY = 0x000e + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS = 0x0006, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT = 0x0007, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0008, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL = 0x0009, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x000a, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL = 0x000b, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x000c, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x000d, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE = 0x000e, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__LAST_ENTRY = 0x000f } lxb_css_selector_pseudo_class_function_id_t; diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_res.h b/ext/lexbor/lexbor/css/selectors/pseudo_res.h index 5ae6e048064c..108257406069 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_res.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -68,60 +68,64 @@ static const lxb_css_selectors_pseudo_data_func_t lxb_css_selectors_pseudo_data_ { {(lxb_char_t *) "#undef", 6, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__UNDEF, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function__undef, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function__undef, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "current", 7, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_current, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_current, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "dir", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_dir, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_dir, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "has", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS, false, LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT, - {.state = lxb_css_selectors_state_pseudo_class_function_has, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving_relative}, true, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_has, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving_relative}, true, true}, {(lxb_char_t *) "is", 2, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_is, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving}, true, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_is, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving}, true, true}, {(lxb_char_t *) "lang", 4, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_lang, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_lang, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, + {(lxb_char_t *) "lexbor-contains", 15, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS, + false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, + {.value = lxb_css_selectors_state_pseudo_class_function_lexbor_contains, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "not", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_not, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_not, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-child", 9, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_child, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_child, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-col", 7, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_col, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_col, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-last-child", 14, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_child, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_child, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-last-col", 12, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_col, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_col, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-last-of-type", 16, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_of_type, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_of_type, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-of-type", 11, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_of_type, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_of_type, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "where", 5, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_where, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving}, true, true} + {.value = lxb_css_selectors_state_pseudo_class_function_where, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving}, true, true} }; static const lxb_css_selectors_pseudo_data_t lxb_css_selectors_pseudo_data_pseudo_element[LXB_CSS_SELECTOR_PSEUDO_ELEMENT__LAST_ENTRY] = @@ -145,8 +149,8 @@ static const lxb_css_selectors_pseudo_data_func_t lxb_css_selectors_pseudo_data_ { {(lxb_char_t *) "#undef", 6, LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FUNCTION__UNDEF, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_element_function__undef, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false} + {.value = lxb_css_selectors_state_pseudo_element_function__undef, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false} }; static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_shs[79] = @@ -232,46 +236,50 @@ static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_shs[79] = {NULL, NULL, 0, 0} }; -static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_function_shs[39] = +static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_function_shs[43] = { - {NULL, NULL, 38, 0}, + {NULL, NULL, 42, 0}, + {"nth-last-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE], 16, 0}, {NULL, NULL, 0, 0}, - {"current", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT], 7, 0}, {NULL, NULL, 0, 0}, - {"dir", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, + {"not", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT], 3, 0}, {NULL, NULL, 0, 0}, - {"is", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD], 9, 0}, {NULL, NULL, 0, 0}, + {"has", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-last-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD], 14, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, + {"nth-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL], 7, 0}, {NULL, NULL, 0, 0}, - {"where", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE], 5, 0}, + {"lexbor-contains", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS], 15, 0}, + {NULL, NULL, 0, 0}, + {"is", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS], 2, 0}, + {"nth-last-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL], 12, 0}, + {"current", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT], 7, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL], 7, 0}, {"lang", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG], 4, 0}, - {"has", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-last-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL], 12, 0}, - {"nth-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE], 11, 0}, + {"nth-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD], 9, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"not", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT], 3, 0}, - {"nth-last-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE], 16, 0}, + {NULL, NULL, 0, 0}, + {"nth-last-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD], 14, 0}, + {"nth-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE], 11, 0}, + {NULL, NULL, 0, 0}, + {"dir", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR], 3, 0}, + {"where", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE], 5, 0}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_state.c b/ext/lexbor/lexbor/css/selectors/pseudo_state.c index f40b089d1300..263ca52f35e4 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_state.c +++ b/ext/lexbor/lexbor/css/selectors/pseudo_state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -27,10 +27,9 @@ lxb_css_selectors_state_pseudo_of_back(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_components_t lxb_css_selectors_comp = { - .state = lxb_css_selectors_state_complex_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_state_pseudo_of_end + .prelude = lxb_css_selectors_state_complex_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_state_pseudo_of_end }; @@ -182,6 +181,117 @@ lxb_css_selectors_state_pseudo_element_function__undef(lxb_css_parser_t *parser, return true; } +bool +lxb_css_selectors_state_pseudo_class_function_lexbor_contains(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_selectors_t *selectors; + lxb_css_selector_t *selector; + lxb_css_selector_contains_t *contains; + lexbor_str_t *str; + const lxb_char_t *data; + size_t length; + + selectors = parser->selectors; + selector = selectors->list_last->last; + +again: + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_STRING: + data = token->types.string.data; + length = token->types.string.length; + break; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + data = token->types.ident.data; + length = token->types.ident.length; + break; + + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + goto again; + + default: + lxb_css_parser_unexpected_data(parser, token); + return lxb_css_parser_failed(parser); + } + + contains = lexbor_mraw_alloc(parser->memory->mraw, + sizeof(lxb_css_selector_contains_t)); + if (contains == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + contains->insensitive = false; + str = &contains->str; + + str->data = lexbor_mraw_alloc(parser->memory->mraw, + sizeof(lexbor_str_t)); + if (str->data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + memcpy(str->data, data, length + 1); + + str->length = length; + str->data[length] = '\0'; + + selector->u.pseudo.data = contains; + +again_end: + + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN__END: + break; + + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + goto again_end; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + data = token->types.ident.data; + length = token->types.ident.length; + + if (length == 1 && (*data == 'i' || *data == 'I')) { + contains->insensitive = true; + + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN__END) { + goto failed; + } + + break; + } + /* Fall through. */ + + default: + goto failed; + } + + parser->selectors->list = NULL; + + return lxb_css_parser_success(parser); + +failed: + + lexbor_mraw_free(parser->memory->mraw, contains->str.data); + lexbor_mraw_free(parser->memory->mraw, contains); + + lxb_css_parser_unexpected_data(parser, token); + return lxb_css_parser_failed(parser); +} + static bool lxb_css_selectors_state_pseudo_anb(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, @@ -268,10 +378,14 @@ lxb_css_selectors_state_pseudo_of_begin(lxb_css_parser_t *parser, return lxb_css_parser_memory_fail(parser); } - rule = lxb_css_syntax_parser_components_push(parser, token, + rule = lxb_css_syntax_parser_components_push(parser, + &lxb_css_selectors_comp, lxb_css_selectors_state_pseudo_of_back, - &lxb_css_selectors_comp, list, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); + list, LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); +// rule = lxb_css_syntax_parser_components_push(parser, token, +// lxb_css_selectors_state_pseudo_of_back, +// &lxb_css_selectors_comp, list, +// LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); if (rule == NULL) { lexbor_mraw_free(parser->memory->mraw, list->last->u.pseudo.data); diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_state.h b/ext/lexbor/lexbor/css/selectors/pseudo_state.h index 5c5a31f94585..652e455f1f13 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_state.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_state.h @@ -77,6 +77,10 @@ LXB_API bool lxb_css_selectors_state_pseudo_element_function__undef(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API bool +lxb_css_selectors_state_pseudo_class_function_lexbor_contains(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/selectors/selector.c b/ext/lexbor/lexbor/css/selectors/selector.c index e8bf96ba88cf..160d19fa45a2 100644 --- a/ext/lexbor/lexbor/css/selectors/selector.c +++ b/ext/lexbor/lexbor/css/selectors/selector.c @@ -638,11 +638,45 @@ lxb_css_selector_serialize_class(lxb_css_selector_t *selector, return LXB_STATUS_OK; } +static lxb_status_t +lxb_css_selector_serialize_escape_write(lxb_char_t *p, lxb_char_t *end, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_char_t *begin; + lxb_status_t status; + + begin = p; + + lxb_css_selector_serialize_write("\"", 1); + + while (p < end) { + if (*p == '"') { + if (begin < p) { + lxb_css_selector_serialize_write(begin, p - begin); + } + + lxb_css_selector_serialize_write("\\000022", 7); + + begin = p + 1; + } + + p++; + } + + if (begin < p) { + lxb_css_selector_serialize_write(begin, p - begin); + } + + lxb_css_selector_serialize_write("\"", 1); + + return LXB_STATUS_OK; +} + static lxb_status_t lxb_css_selector_serialize_attribute(lxb_css_selector_t *selector, lexbor_serialize_cb_f cb, void *ctx) { - lxb_char_t *p, *begin, *end; + lxb_char_t *p, *end; lxb_status_t status; lxb_css_selector_attribute_t *attr; @@ -686,30 +720,11 @@ lxb_css_selector_serialize_attribute(lxb_css_selector_t *selector, p = attr->value.data; end = attr->value.data + attr->value.length; - begin = p; - - lxb_css_selector_serialize_write("\"", 1); - - while (p < end) { - if (*p == '"') { - if (begin < p) { - lxb_css_selector_serialize_write(begin, p - begin); - } - - lxb_css_selector_serialize_write("\\000022", 7); - - begin = p + 1; - } - - p++; - } - - if (begin < p) { - lxb_css_selector_serialize_write(begin, p - begin); + status = lxb_css_selector_serialize_escape_write(p, end, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; } - lxb_css_selector_serialize_write("\"", 1); - if (attr->modifier != LXB_CSS_SELECTOR_MODIFIER_UNSET) { switch (attr->modifier) { case LXB_CSS_SELECTOR_MODIFIER_I: @@ -740,7 +755,9 @@ lxb_css_selector_serialize_pseudo_class_function(lxb_css_selector_t *selector, lexbor_serialize_cb_f cb, void *ctx) { lxb_status_t status; + lxb_char_t *p, *end; lxb_css_selector_pseudo_t *pseudo; + lxb_css_selector_contains_t *contains; const lxb_css_selectors_pseudo_data_func_t *pfunc; pseudo = &selector->u.pseudo; @@ -789,6 +806,22 @@ lxb_css_selector_serialize_pseudo_class_function(lxb_css_selector_t *selector, cb, ctx); break; + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS: + contains = pseudo->data; + p = contains->str.data; + end = p + contains->str.length; + + status = lxb_css_selector_serialize_escape_write(p, end, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (contains->insensitive) { + lxb_css_selector_serialize_write(" i", 2); + } + + break; + default: status = LXB_STATUS_OK; break; diff --git a/ext/lexbor/lexbor/css/selectors/selector.h b/ext/lexbor/lexbor/css/selectors/selector.h index 52dbabc7ba5c..1862c868c8ce 100644 --- a/ext/lexbor/lexbor/css/selectors/selector.h +++ b/ext/lexbor/lexbor/css/selectors/selector.h @@ -80,6 +80,12 @@ typedef struct { } lxb_css_selector_anb_of_t; +typedef struct { + lexbor_str_t str; + bool insensitive; +} +lxb_css_selector_contains_t; + struct lxb_css_selector { lxb_css_selector_type_t type; lxb_css_selector_combinator_t combinator; diff --git a/ext/lexbor/lexbor/css/selectors/selectors.c b/ext/lexbor/lexbor/css/selectors/selectors.c index 52537873ef08..77586f4a65c6 100644 --- a/ext/lexbor/lexbor/css/selectors/selectors.c +++ b/ext/lexbor/lexbor/css/selectors/selectors.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -20,59 +20,51 @@ lxb_css_selectors_components_end(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_components_t lxb_css_selectors_complex_list_cb = { - .state = lxb_css_selectors_state_complex_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_complex_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_compound_list_cb = { - .state = lxb_css_selectors_state_compound_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_compound_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_simple_list_cb = { - .state = lxb_css_selectors_state_simple_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_simple_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_relative_list_cb = { - .state = lxb_css_selectors_state_relative_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_relative_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_complex_cb = { - .state = lxb_css_selectors_state_complex, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_complex, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_compound_cb = { - .state = lxb_css_selectors_state_compound, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_compound, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_simple_cb = { - .state = lxb_css_selectors_state_simple, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_simple, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_relative_cb = { - .state = lxb_css_selectors_state_relative, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_relative, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; @@ -170,9 +162,7 @@ lxb_css_selectors_parse_relative_list(lxb_css_parser_t *parser, } static lxb_status_t -lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser, - lxb_css_memory_t *memory, - lxb_css_selectors_t *selectors) +lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser) { if (parser->stage != LXB_CSS_PARSER_CLEAN) { if (parser->stage == LXB_CSS_PARSER_RUN) { @@ -185,12 +175,6 @@ lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser, parser->tkz->with_comment = false; parser->stage = LXB_CSS_PARSER_RUN; - parser->old_memory = parser->memory; - parser->old_selectors = parser->selectors; - - parser->memory = memory; - parser->selectors = selectors; - return LXB_STATUS_OK; } @@ -203,8 +187,7 @@ lxb_css_selectors_parse_process(lxb_css_parser_t *parser, lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_components_push(parser, NULL, NULL, - components, NULL, + rule = lxb_css_syntax_parser_components_push(parser, components, NULL, NULL, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { return NULL; @@ -222,9 +205,6 @@ static void lxb_css_selectors_parse_finish(lxb_css_parser_t *parser) { parser->stage = LXB_CSS_PARSER_END; - - parser->memory = parser->old_memory; - parser->selectors = parser->old_selectors; } static lxb_css_selector_list_t * @@ -232,41 +212,45 @@ lxb_css_selectors_parse_list(lxb_css_parser_t *parser, const lxb_css_syntax_cb_components_t *components, const lxb_char_t *data, size_t length) { - lxb_css_memory_t *memory; - lxb_css_selectors_t *selectors; + bool my_mem, my_selectors; lxb_css_selector_list_t *list; - memory = parser->memory; - selectors = parser->selectors; + my_mem = false; + my_selectors = false; - if (selectors == NULL) { - selectors = lxb_css_selectors_create(); - parser->status = lxb_css_selectors_init(selectors); + if (parser->selectors == NULL) { + parser->selectors = lxb_css_selectors_create(); + parser->status = lxb_css_selectors_init(parser->selectors); if (parser->status != LXB_STATUS_OK) { - (void) lxb_css_selectors_destroy(selectors, true); + (void) lxb_css_selectors_destroy(parser->selectors, true); return NULL; } + + my_selectors = true; } else { - lxb_css_selectors_clean(selectors); + lxb_css_selectors_clean(parser->selectors); } - if (memory == NULL) { - memory = lxb_css_memory_create(); - parser->status = lxb_css_memory_init(memory, 256); + if (parser->memory == NULL) { + parser->memory = lxb_css_memory_create(); + parser->status = lxb_css_memory_init(parser->memory, 256); if (parser->status != LXB_STATUS_OK) { - if (selectors != parser->selectors) { - (void) lxb_css_selectors_destroy(selectors, true); + if (my_selectors) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, + true); } - (void) lxb_css_memory_destroy(memory, true); + (void) lxb_css_memory_destroy(parser->memory, true); return NULL; } + + my_mem = true; } - parser->status = lxb_css_selectors_parse_prepare(parser, memory, selectors); + parser->status = lxb_css_selectors_parse_prepare(parser); if (parser->status != LXB_STATUS_OK) { list = NULL; goto end; @@ -278,12 +262,12 @@ lxb_css_selectors_parse_list(lxb_css_parser_t *parser, end: - if (list == NULL && memory != parser->memory) { - (void) lxb_css_memory_destroy(memory, true); + if (list == NULL && my_mem) { + parser->memory = lxb_css_memory_destroy(parser->memory, true); } - if (selectors != parser->selectors) { - (void) lxb_css_selectors_destroy(selectors, true); + if (my_selectors) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); } return list; diff --git a/ext/lexbor/lexbor/css/selectors/state.c b/ext/lexbor/lexbor/css/selectors/state.c index 873e7d31cfda..1f0a391ac29a 100644 --- a/ext/lexbor/lexbor/css/selectors/state.c +++ b/ext/lexbor/lexbor/css/selectors/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -1557,8 +1557,8 @@ lxb_css_selectors_state_pseudo_class_function(lxb_css_parser_t *parser, selectors->comb_default = func->combinator; selectors->parent = selector; - rule = lxb_css_syntax_parser_function_push(parser, token, success, - &func->cb, selectors->list_last); + rule = lxb_css_syntax_consume_function(parser, token, &func->cb, + success, selectors->list_last); if (rule == NULL) { goto failed; } @@ -1663,8 +1663,8 @@ lxb_css_selectors_state_pseudo_element_function(lxb_css_parser_t *parser, selectors->comb_default = func->combinator; selectors->parent = selector; - rule = lxb_css_syntax_parser_function_push(parser, token, success, - &func->cb, selectors->list_last); + rule = lxb_css_syntax_consume_function(parser, token, &func->cb, + success, selectors->list_last); if (rule == NULL) { (void) lxb_css_parser_memory_fail(parser); return parser->status; @@ -1711,7 +1711,7 @@ lxb_css_selectors_state_function_end(lxb_css_parser_t *parser, lxb_css_selectors_t *selectors = parser->selectors; if (token->type == LXB_CSS_SYNTAX_TOKEN__EOF) { - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. End Of File in pseudo function", lxb_css_selectors_module_name); } @@ -1737,7 +1737,7 @@ lxb_css_selectors_state_function_end(lxb_css_parser_t *parser, return LXB_STATUS_OK; } - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. Pseudo function can't be empty: %S()", lxb_css_selectors_module_name, &selector->name); @@ -1783,7 +1783,7 @@ lxb_css_selectors_state_forgiving_cb(lxb_css_parser_t *parser, lxb_css_parser_set_ok(parser); if (token->type == LXB_CSS_SYNTAX_TOKEN__EOF) { - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. End Of File in pseudo function", lxb_css_selectors_module_name); } @@ -1814,7 +1814,7 @@ lxb_css_selectors_state_forgiving_cb(lxb_css_parser_t *parser, return LXB_STATUS_OK; } - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. Pseudo function can't be empty: %S()", lxb_css_selectors_module_name, &selector->name); diff --git a/ext/lexbor/lexbor/css/state.c b/ext/lexbor/lexbor/css/state.c index 15a9614948f2..dda5310a9676 100644 --- a/ext/lexbor/lexbor/css/state.c +++ b/ext/lexbor/lexbor/css/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,6 +9,143 @@ #include "lexbor/css/at_rule/state.h" +static bool +lxb_css_state_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_state_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule); + +static bool +lxb_css_state_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_state_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_state_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_state_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_state_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_state_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_state_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_state_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_state_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_state_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_state_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_state_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_css_parser_state_f +lxb_css_state_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_status_t +lxb_css_state_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +static lxb_status_t +lxb_css_state_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static bool +lxb_css_state_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + + +static const lxb_css_syntax_cb_list_rules_t lxb_css_state_list_rules = { + .at_rule = lxb_css_state_at_rule_begin, + .qualified_rule = lxb_css_state_qualified_rule_begin, + .next = lxb_css_state_list_rules_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_state_list_rules_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_state_at_rule = { + .prelude = lxb_css_state_at_rule_prelude, + .prelude_end = lxb_css_state_at_rule_prelude_end, + .block = lxb_css_state_at_rule_block_begin, + .cb.failed = lxb_css_state_at_rule_prelude_failed, + .cb.end = lxb_css_state_at_rule_end +}; + +static const lxb_css_syntax_cb_qualified_rule_t lxb_css_state_qualified_rule = { + .prelude = lxb_css_state_qualified_rule_prelude, + .prelude_end = lxb_css_state_qualified_rule_prelude_end, + .block = lxb_css_state_qualified_rule_block_begin, + .cb.failed = lxb_css_state_qualified_rule_prelude_failed, + .cb.end = lxb_css_state_qualified_rule_end +}; + +static const lxb_css_syntax_cb_block_t lxb_css_state_block = { + .at_rule = lxb_css_state_at_rule_begin, + .declarations = lxb_css_state_declarations_begin, + .qualified_rule = lxb_css_state_qualified_rule_begin, + .next = lxb_css_state_block_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_state_block_end, +}; + +static const lxb_css_syntax_cb_declarations_t lxb_css_state_declaration = { + .name = lxb_css_state_declaration_name, + .end = lxb_css_state_declaration_end, + .cb.failed = lxb_css_state_declarations_bad, + .cb.end = lxb_css_state_declarations_end +}; + + bool lxb_css_state_success(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx) @@ -49,3 +186,491 @@ lxb_css_state_stop(lxb_css_parser_t *parser, { return lxb_css_parser_stop(parser); } + +bool +lxb_css_state_blank(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +const lxb_css_syntax_cb_list_rules_t * +lxb_css_state_cb_list_rules(void) +{ + return &lxb_css_state_list_rules; +} + +const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_cb_at_rule(void) +{ + return &lxb_css_state_at_rule; +} + +const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_cb_qualified_rule(void) +{ + return &lxb_css_state_qualified_rule; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_state_cb_block(void) +{ + return &lxb_css_state_block; +} + +const lxb_css_syntax_cb_declarations_t * +lxb_css_state_cb_declarations(void) +{ + return &lxb_css_state_declaration; +} + +static bool +lxb_css_state_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + void *returned = lxb_css_syntax_returned(parser); + lxb_css_rule_list_t *list = ctx; + + if (returned != NULL) { + lxb_css_rule_list_append(list, returned); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule) +{ + lxb_css_rule_at_t *at; + const lxb_css_entry_at_rule_data_t *entry; + + at = lxb_css_at_rule_create(parser, lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length, + &entry); + if (at == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = at; + + return entry->cbs; +} + +static bool +lxb_css_state_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_at_rule__custom_t *custom; + + at->prelude_end = token->offset; + + custom = at->u.custom; + + status = lxb_css_make_data(parser, &custom->prelude, at->prelude_begin, + at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_state_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_list_t *list; + + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_block; +} + +static bool +lxb_css_state_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + at->u.custom->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_style_t *style; + + style = lxb_css_rule_style_create(parser->memory); + if (style == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = style; + + return &lxb_css_state_qualified_rule; +} + +static bool +lxb_css_state_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_style_t *style = ctx; + + lxb_css_selectors_clean(parser->selectors); + lxb_css_parser_state_set(parser, lxb_css_selectors_state_complex_list); + + style->prelude_begin = token->offset; + + return false; +} + +static lxb_status_t +lxb_css_state_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + size_t begin; + lxb_status_t status; + lxb_css_rule_style_t *style = ctx; + lxb_css_rule_bad_style_t *bad; + + if (!failed) { + style->selector = parser->selectors->list; + style->prelude_end = token->offset; + + return LXB_STATUS_OK; + } + + begin = style->prelude_begin; + + (void) lxb_css_rule_style_destroy(style, true); + + bad = lxb_css_rule_bad_style_create(parser->memory); + if (bad == NULL) { + return lxb_css_parser_memory_fail_status(parser); + } + + bad->prelude_begin = begin; + bad->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &bad->selectors, bad->prelude_begin, + bad->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + lxb_css_parser_set_context(parser, bad); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_state_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_list_t *list; + + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_block; +} + +static bool +lxb_css_state_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_t *declrs; + lxb_css_rule_list_t *list; + lxb_css_rule_style_t *style; + lxb_css_rule_bad_style_t *bad; + + list = lxb_css_syntax_returned(parser); + + if (!failed) { + style = ctx; + + if (list != NULL && list->first != NULL + && list->first->type == LXB_CSS_RULE_DECLARATION_LIST) + { + declrs = list->first; + style->declarations = lxb_css_rule_declaration_list(declrs); + + declrs->parent = lxb_css_rule(style); + + if (list->first == list->last) { + list->last = NULL; + } + + if (declrs->next != NULL) { + declrs->next->prev = NULL; + } + + list->first = declrs->next; + declrs->next = NULL; + } + + style->child = list; + + lxb_css_syntax_set_return(parser, style); + } + else { + bad = ctx; + + if (list != NULL && list->first != NULL + && list->first->type == LXB_CSS_RULE_DECLARATION_LIST) + { + declrs = list->first; + bad->declarations = lxb_css_rule_declaration_list(declrs); + + declrs->parent = lxb_css_rule(bad); + + if (list->first == list->last) { + list->last = NULL; + } + + if (declrs->next != NULL) { + declrs->next->prev = NULL; + } + + list->first = declrs->next; + declrs->next = NULL; + } + + bad->child = list; + + lxb_css_syntax_set_return(parser, bad); + } + + return LXB_STATUS_OK; +} + +static bool +lxb_css_state_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + /* rule can be either a declaration list or an at rule. */ + + lxb_css_rule_t *rule = lxb_css_syntax_returned(parser); + lxb_css_rule_list_t *list = ctx; + + lxb_css_rule_list_append(list, rule); + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_state_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_declaration_list_t *list; + + list = lxb_css_rule_declaration_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_declaration; +} + +static lxb_css_parser_state_f +lxb_css_state_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + const lxb_css_entry_data_t *entry; + lxb_css_rule_declaration_t *declar; + + declar = lxb_css_declaration_create(parser, + lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length, + &entry); + if (declar == NULL) { + (void) lxb_css_parser_memory_fail_null(parser); + return NULL; + } + + /* We present an original position. */ + + declar->offset.name_begin = token->offset; + declar->offset.name_end = token->offset + + lxb_css_syntax_token_base(token)->length; + *out_rule = declar; + + return entry->state; +} + +static lxb_status_t +lxb_css_state_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed) +{ + lxb_status_t status; + lxb_css_property__undef_t *undef; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_rule_declaration_list_t *list = declarations; + + declar->offset.value_begin = offset->value_begin; + declar->offset.value_end = offset->value_end; + declar->offset.important_begin = offset->important_begin; + declar->offset.important_end = offset->important_end; + declar->important = important; + + if (failed) { + lxb_css_rule_declaration_destroy(declar, false); + + undef = lxb_css_property__undef_create(parser->memory); + if (undef == NULL) { + return lxb_css_parser_memory_fail_status(parser); + } + + undef->type = declar->type; + + status = lxb_css_make_data(parser, &undef->value, + declar->offset.value_begin, + declar->offset.value_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + declar->u.undef = undef; + declar->type = LXB_CSS_PROPERTY__UNDEF; + } + + lxb_css_rule_declaration_list_append(list, lxb_css_rule(declar)); + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_state_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_declaration_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static bool +lxb_css_state_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_declaration_t *declar; + + if (ctx == NULL) { + declar = lxb_css_rule_declaration_create(parser->memory); + if (declar == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + lxb_css_parser_current_rule(parser)->context = declar; + declar->type = LXB_CSS_PROPERTY__UNDEF; + } + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/state.h b/ext/lexbor/lexbor/css/state.h index 0a2abd803634..6ecd50343928 100644 --- a/ext/lexbor/lexbor/css/state.h +++ b/ext/lexbor/lexbor/css/state.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,7 @@ extern "C" { #endif #include "lexbor/css/base.h" +#include "lexbor/css/syntax/syntax.h" LXB_API bool @@ -26,6 +27,30 @@ LXB_API bool lxb_css_state_stop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API bool +lxb_css_state_blank(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +LXB_API const lxb_css_syntax_cb_list_rules_t * +lxb_css_state_cb_list_rules(void); + +LXB_API const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_cb_at_rule(void); + +LXB_API const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_cb_qualified_rule(void); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_state_cb_block(void); + +LXB_API const lxb_css_syntax_cb_declarations_t * +lxb_css_state_cb_declarations(void); + +const lxb_css_syntax_cb_block_t * +lxb_css_state_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/stylesheet.c b/ext/lexbor/lexbor/css/stylesheet.c new file mode 100644 index 000000000000..f03f145721c4 --- /dev/null +++ b/ext/lexbor/lexbor/css/stylesheet.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/at_rule.h" +#include "lexbor/css/property.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/state.h" +#include "lexbor/css/selectors/selectors.h" +#include "lexbor/css/selectors/state.h" + + +lxb_css_stylesheet_t * +lxb_css_stylesheet_create(lxb_css_memory_t *memory) +{ + lxb_status_t status; + lxb_css_stylesheet_t *stylesheet; + + if (memory == NULL) { + memory = lxb_css_memory_create(); + status = lxb_css_memory_init(memory, 1024); + + if (status != LXB_STATUS_OK) { + (void) lxb_css_memory_destroy(memory, true); + return NULL; + } + } + else { + (void) lxb_css_memory_ref_inc(memory); + } + + stylesheet = lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_stylesheet_t)); + if (stylesheet == NULL) { + return NULL; + } + + stylesheet->memory = memory; + + return stylesheet; +} + +lxb_css_stylesheet_t * +lxb_css_stylesheet_destroy(lxb_css_stylesheet_t *sst, bool destroy_memory) +{ + if (sst == NULL) { + return NULL; + } + + if (destroy_memory) { + (void) lxb_css_memory_ref_dec_destroy(sst->memory); + return NULL; + } + + if (sst->root != NULL) { + (void) lxb_css_rule_destroy(sst->root, true); + } + + (void) lexbor_mraw_free(sst->memory->mraw, sst); + + return NULL; +} + +lxb_status_t +lxb_css_stylesheet_parse(lxb_css_stylesheet_t *sst, lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + lxb_status_t status; + lxb_css_rule_list_t *list; + lxb_css_selectors_t selectors; + + if (sst == NULL || parser == NULL) { + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (parser->selectors == NULL) { + status = lxb_css_selectors_init(&selectors); + if (status != LXB_STATUS_OK) { + return status; + } + + parser->selectors = &selectors; + } + else { + lxb_css_selectors_clean(parser->selectors); + } + + parser->memory = sst->memory; + + list = lxb_css_syntax_parse_list_rules(parser, + lxb_css_state_cb_list_rules(), + data, length); + + if (parser->selectors == &selectors) { + parser->selectors = lxb_css_selectors_destroy(&selectors, false); + } + + if (list == NULL) { + sst->root = NULL; + return parser->status; + } + + sst->root = &list->rule; + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/stylesheet.h b/ext/lexbor/lexbor/css/stylesheet.h index 5f3e37d82e45..9d52f9897cc5 100644 --- a/ext/lexbor/lexbor/css/stylesheet.h +++ b/ext/lexbor/lexbor/css/stylesheet.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -25,26 +25,62 @@ struct lxb_css_stylesheet { void *element; /* lxb_html_style_element_t * */ }; +/* + * Create a new CSS stylesheet object. + * + * This function creates a stylesheet object which holds the parsed CSS rules. + * + * @param[in] memory Optional. A memory pool to use for allocations. + * If NULL, a new internal memory pool is created/managed + * by the stylesheet. + * + * @return A new lxb_css_stylesheet_t * or NULL on failure. + */ LXB_API lxb_css_stylesheet_t * lxb_css_stylesheet_create(lxb_css_memory_t *memory); +/* + * Destroy a CSS stylesheet object. + * + * @param[in] sst Optional. The stylesheet object to destroy. + * If NULL, the function returns NULL. + * @param[in] destroy_memory If true, the memory pool attached to + * the stylesheet is also destroyed. + * + * @return Always NULL. + */ LXB_API lxb_css_stylesheet_t * lxb_css_stylesheet_destroy(lxb_css_stylesheet_t *sst, bool destroy_memory); -LXB_API lxb_css_stylesheet_t * -lxb_css_stylesheet_parse(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - +/* + * Parse CSS content into the stylesheet. + * + * This function takes CSS text and builds the rule tree in the stylesheet. + * + * The function returns an error only in extremely unforeseen circumstances, + * such as the inability to allocate memory for objects. Any broken CSS will + * not cause an error. + * + * Selectors note: + * If the provided parser does not have an initialized selectors module, one + * will be created temporarily for this call. For better performance when + * parsing multiple stylesheets, initialize the selectors module in + * the parser once: + * + * lxb_css_parser_t *parser = lxb_css_parser_create(); + * lxb_css_parser_init(parser, NULL); + * lxb_css_parser_selectors_init(parser); + * + * @param[in] sst Required. The target stylesheet. + * @param[in] parser Required. An initialized CSS parser. + * @param[in] data Optional. The CSS text data. + * @param[in] length Required. Length of the data in bytes. + * + * @return LXB_STATUS_OK on success, or an error code on failure. + */ LXB_API lxb_status_t -lxb_css_stylesheet_prepare(lxb_css_parser_t *parser, lxb_css_memory_t *memory, - lxb_css_selectors_t *selectors); - -LXB_API lxb_css_stylesheet_t * -lxb_css_stylesheet_process(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - -LXB_API void -lxb_css_stylesheet_finish(lxb_css_parser_t *parser); +lxb_css_stylesheet_parse(lxb_css_stylesheet_t *sst, lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/css/syntax/anb.c b/ext/lexbor/lexbor/css/syntax/anb.c index ffd1751cdabf..d3f7c7bfe0a6 100644 --- a/ext/lexbor/lexbor/css/syntax/anb.c +++ b/ext/lexbor/lexbor/css/syntax/anb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -38,10 +38,9 @@ lxb_css_syntax_anb_state_ident_data(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_pipe_t lxb_css_syntax_anb_pipe = { - .state = lxb_css_syntax_anb_state, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_syntax_anb_end + .prelude = lxb_css_syntax_anb_state, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_syntax_anb_end }; @@ -66,8 +65,8 @@ lxb_css_syntax_anb_parse(lxb_css_parser_t *parser, lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_pipe_push(parser, NULL, - &lxb_css_syntax_anb_pipe, &anb, + rule = lxb_css_syntax_parser_pipe_push(parser, &lxb_css_syntax_anb_pipe, + NULL, &anb, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { return anb; diff --git a/ext/lexbor/lexbor/css/syntax/base.h b/ext/lexbor/lexbor/css/syntax/base.h index 3dc981ba3da2..627fce4c7fa5 100644 --- a/ext/lexbor/lexbor/css/syntax/base.h +++ b/ext/lexbor/lexbor/css/syntax/base.h @@ -17,7 +17,7 @@ extern "C" { #define LXB_CSS_SYNTAX_VERSION_MAJOR 1 -#define LXB_CSS_SYNTAX_VERSION_MINOR 3 +#define LXB_CSS_SYNTAX_VERSION_MINOR 4 #define LXB_CSS_SYNTAX_VERSION_PATCH 0 #define LXB_CSS_SYNTAX_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/css/syntax/parser.c b/ext/lexbor/lexbor/css/syntax/parser.c index 5a3c7abf24f8..7e7e973f75d6 100644 --- a/ext/lexbor/lexbor/css/syntax/parser.c +++ b/ext/lexbor/lexbor/css/syntax/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2025 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -11,14 +11,11 @@ #include "lexbor/css/at_rule/state.h" -static const lxb_css_syntax_token_t lxb_css_syntax_token_terminated = -{ - .types.terminated = {.begin = NULL, .length = 0, .user_id = 0}, - .type = LXB_CSS_SYNTAX_TOKEN__END, - .offset = 0, - .cloned = false -}; +static const lexbor_str_t lxb_css_err_rc = lexbor_str("Unexpected token in " + "qualified rule: RC_BRACKET"); +static lxb_css_syntax_rule_t * +lxb_css_syntax_parser_stack_pop(lxb_css_parser_t *parser); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, @@ -35,28 +32,105 @@ lxb_css_syntax_parser_list_rules_qualified(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); -static bool +static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_at_rule_f cb, + bool nested); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end_consule_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); +lxb_css_syntax_parser_qualified_rule_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_block_f cb); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_at(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_qualified(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_validate(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); -static bool -lxb_css_syntax_parser_declarations_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, @@ -69,40 +143,77 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_components(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_components_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_function(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); +lxb_css_syntax_parser_function_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_pipe(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_pipe_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + lxb_inline const lxb_css_syntax_token_t * lxb_css_syntax_parser_failed(lxb_css_parser_t *parser, lxb_status_t status) @@ -111,6 +222,31 @@ lxb_css_syntax_parser_failed(lxb_css_parser_t *parser, lxb_status_t status) return NULL; } +lxb_inline const lxb_css_syntax_token_t * +lxb_css_syntax_token_parser_do_phase_again(lxb_css_parser_t *parser) +{ + parser->fake_null = true; + return NULL; +} + +lxb_inline const lxb_css_syntax_token_t * +lxb_css_syntax_parser_call_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token) +{ + lxb_css_syntax_rule_t *rules; + + (void) lxb_css_syntax_parser_stack_pop(parser); + + rules = parser->rules; + + if (parser->rules <= parser->rules_begin) { + rules->state = lxb_css_state_stop; + return token; + } + + return rules->back(parser, token, rules); +} + lxb_status_t lxb_css_syntax_parser_run(lxb_css_parser_t *parser) @@ -177,369 +313,259 @@ lxb_css_syntax_parser_consume(lxb_css_parser_t *parser) lxb_css_syntax_rule_t * lxb_css_syntax_parser_list_rules_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_list_rules_t *cb_rules, - void *ctx, bool top_level, - lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - - parser->rules->state = lxb_css_state_success; + + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_list_rules; - rule->state = cb_rules->cb.state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_list_rules; - rule->cbx.list_rules = cb_rules; - rule->context = ctx; - rule->block_end = stop; - rule->top_level = top_level; - - if (token != NULL) { - rule->u.list_rules.begin = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_list_rules, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_list_rules_back, + .cbx.list_rules = cb_rules, + .context = ctx, + .block_end = stop + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_at_rule_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_at_rule_t *at_rule, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool nested) { - lxb_status_t status; - lxb_css_syntax_at_rule_offset_t *at; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_at_rule; - rule->state = at_rule->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_at_rule; - rule->cbx.at_rule = at_rule; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - at = &rule->u.at_rule; - - at->name = token->offset; - at->prelude = token->offset + lxb_css_syntax_token_base(token)->length; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_at_rule, + .state = at_rule->prelude, + .back = lxb_css_syntax_parser_at_back_to_prelude, + .cbx.at_rule = at_rule, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_qualified_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_qualified_rule_t *qualified, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool nested) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_qualified_rule; - rule->state = qualified->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_qualified_rule; - rule->cbx.qualified_rule = qualified; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - rule->u.qualified.prelude = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_qualified_rule, + .state = qualified->prelude, + .back = lxb_css_syntax_parser_qualified_back_to_prelude, + .cbx.qualified_rule = qualified, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_declarations_t *declarations, - void *ctx, lxb_css_syntax_token_type_t stop) +lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_declarations; - rule->state = declarations->cb.state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_declarations; - rule->cbx.declarations = declarations; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - rule->u.declarations.begin = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_block, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_block_back, + .cbx.block = block, + .context = ctx + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_components_t *comp, - void *ctx, lxb_css_syntax_token_type_t stop) +lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool name_validate, bool nested) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; + lxb_css_syntax_state_f phase; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_components; - rule->state = comp->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_components; - rule->cbx.components = comp; - rule->context = ctx; - rule->block_end = stop; + phase = (!name_validate) ? lxb_css_syntax_parser_declarations_begin + : lxb_css_syntax_parser_declarations_validate; - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = phase, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_declaration_back_to_value, + .cbx.declarations = declr, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_function_t *func, - void *ctx) +lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - if (token == NULL || token->type != LXB_CSS_SYNTAX_TOKEN_FUNCTION) { - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; - return NULL; - } - - if (parser->rules > parser->rules_begin) { - rule = parser->rules; - - if (rule->deep != 0 - && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) - { - rule->deep--; - parser->types_pos--; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; } } - parser->rules->state = lxb_css_state_success; - - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; - } + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_function; - rule->state = func->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_function; - rule->cbx.func = func; - rule->context = ctx; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_components, + .state = comp->prelude, + .back = lxb_css_syntax_parser_components_back_to_value, + .cbx.components = comp, + .context = ctx, + .block_end = stop + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_block_t *block, - void *ctx) +lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_syntax_token_type_t block_end; - - if (token == NULL) { - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; - return NULL; - } - - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - block_end = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; - break; - - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - block_end = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; - break; - - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - block_end = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; - break; - default: - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { return NULL; - } - - if (parser->rules > parser->rules_begin) { - rule = parser->rules; - - if (rule->deep != 0 && parser->types_pos[-1] == block_end) { - rule->deep--; - parser->types_pos--; } } - parser->rules->state = lxb_css_state_success; - - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; - } + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_block; - rule->state = block->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_block; - rule->cbx.block = block; - rule->context = ctx; - rule->block_end = block_end; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_function, + .state = func->value, + .back = lxb_css_syntax_parser_function_back, + .cbx.func = func, + .context = ctx + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_pipe_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_pipe_t *pipe, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_pipe; - rule->state = pipe->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_pipe; - rule->cbx.pipe = pipe; - rule->context = ctx; - rule->block_end = stop; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_pipe, + .state = pipe->prelude, + .back = lxb_css_syntax_parser_pipe_back, + .cbx.pipe = pipe, + .context = ctx, + .block_end = stop + }; return rule; } -lxb_css_syntax_rule_t * +static lxb_css_syntax_rule_t * lxb_css_syntax_parser_stack_pop(lxb_css_parser_t *parser) { return parser->rules--; @@ -554,12 +580,16 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, return token; } + rule->skip_consume = true; + begin: rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; switch (token->type) { case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + case LXB_CSS_SYNTAX_TOKEN_CDC: + case LXB_CSS_SYNTAX_TOKEN_CDO: lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -577,22 +607,6 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN__EOF: goto done; - case LXB_CSS_SYNTAX_TOKEN_CDC: - case LXB_CSS_SYNTAX_TOKEN_CDO: - if (rule->top_level) { - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - goto begin; - } - - /* fall through */ - default: if (rule->block_end == token->type && rule->deep == 0) { goto done; @@ -607,79 +621,136 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, done: rule->phase = lxb_css_syntax_parser_end; - rule->skip_consume = true; - rule->u.list_rules.end = token->offset; - - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, 0); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_at(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - return token; - } + const lxb_css_syntax_cb_list_rules_t *list_rules = rule->cbx.list_rules; - rule = lxb_css_syntax_parser_at_rule_push(parser, token, - lxb_css_syntax_parser_list_rules_back, - rule->cbx.list_rules->at_rule, - rule->context, rule->block_end); - if (rule == NULL) { - return NULL; - } - - parser->fake_null = true; - - return NULL; + return lxb_css_syntax_parser_at_begin(parser, token, rule, list_rules->next, + list_rules->at_rule, false); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_qualified(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - return token; - } + void *qualified_ctx; + lxb_css_syntax_rule_t *qualified; + lxb_css_syntax_begin_qualified_rule_f cb; + const lxb_css_syntax_cb_list_rules_t *list_rules; + const lxb_css_syntax_cb_qualified_rule_t *cb_qualified; - rule = lxb_css_syntax_parser_qualified_push(parser, token, - lxb_css_syntax_parser_list_rules_back, - rule->cbx.list_rules->qualified_rule, - rule->context, rule->block_end); - if (rule == NULL) { - return NULL; + qualified_ctx = NULL; + list_rules = rule->cbx.list_rules; + cb = list_rules->qualified_rule; + + rule->skip_consume = false; + + cb_qualified = cb(parser, token, rule->context, &qualified_ctx); + if (cb_qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - parser->fake_null = true; + qualified = lxb_css_syntax_parser_qualified_push(parser, cb_qualified, + list_rules->next, + qualified_ctx, + rule->block_end, + false); + if (qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } - return NULL; + return lxb_css_syntax_token_parser_do_phase_again(parser); } -static bool +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx) + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_css_syntax_rule_t *rule; + rule->phase = lxb_css_syntax_parser_list_rules; + rule->state = rule->back_state; + rule->skip_consume = true; - if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { - return lxb_css_parser_success(parser); + return token; +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_at_rule_f cb, + bool nested) +{ + void *at_rule_ctx; + lxb_css_syntax_rule_t *at_rule; + const lxb_css_syntax_cb_at_rule_t *cb_at_rule; + + at_rule_ctx = NULL; + rule->skip_consume = false; + + cb_at_rule = cb(parser, token, rule->context, &at_rule_ctx); + if (cb_at_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - rule = parser->rules; - rule->state = rule->cbx.list_rules->next; + at_rule = lxb_css_syntax_parser_at_rule_push(parser, cb_at_rule, + back_state, at_rule_ctx, + rule->block_end, nested); + if (at_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, parser->tkz->status); + } - return false; + if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { + lxb_css_syntax_token_consume(parser->tkz); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } +/* + * First call for this code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + * Rule -- lxb_css_syntax_rule_t with at_rule callbacks. + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { lxb_status_t status; + const lxb_css_log_message_t *msg; if (rule->offset > token->offset) { return token; @@ -688,7 +759,7 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; + rule->phase = lxb_css_syntax_parser_at_prelude_end; goto done; } @@ -706,25 +777,11 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_start_block; - - rule->u.at_rule.prelude_end = token->offset; - rule->u.at_rule.block = token->offset - + lxb_css_syntax_token_base(token)->length; - + rule->phase = lxb_css_syntax_parser_at_block; + rule->back = lxb_css_syntax_parser_end_back; rule->skip_consume = true; - parser->block = rule->cbx.cb->block; - - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - token = &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } status = lxb_css_parser_types_push(parser, @@ -732,13 +789,25 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - if (rule->deep == 1) { - goto done; + if (rule->deep != 0) { + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + } + else { + msg = lxb_css_log_format(parser->log, + LXB_CSS_LOG_SYNTAX_ERROR, + "%S", &lxb_css_err_rc); + if (msg == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - parser->types_pos--; - rule->deep--; + if (rule->nested) { + rule->phase = lxb_css_syntax_parser_at_prelude_end; + goto done; + } } return token; @@ -754,12 +823,14 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_at_prelude_end_consule_token; goto done; } return token; case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_at_prelude_end; goto done; default: @@ -776,17 +847,91 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - if (rule->u.at_rule.prelude_end != 0) { - rule->u.at_rule.block_end = token->offset; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - else { - rule->u.at_rule.prelude_end = token->offset; + + return lxb_css_syntax_parser_block_begin(parser, token, rule, + at_rule->prelude, at_rule->block); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_success; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - return &lxb_css_syntax_token_terminated; + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end_consule_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + rule->phase = lxb_css_syntax_parser_end_consume_token; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_at_rule; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; } static const lxb_css_syntax_token_t * @@ -795,8 +940,7 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { lxb_status_t status; - - /* It is necessary to avoid re-entry of the token into the phase. */ + const lxb_css_log_message_t *msg; if (rule->offset > token->offset) { return token; @@ -805,7 +949,6 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -823,25 +966,11 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_start_block; - - rule->u.qualified.prelude_end = token->offset; - rule->u.qualified.block = token->offset - + lxb_css_syntax_token_base(token)->length; - + rule->phase = lxb_css_syntax_parser_qualified_rule_block; + rule->back = lxb_css_syntax_parser_end_back; rule->skip_consume = true; - parser->block = rule->cbx.cb->block; - - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - token = &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } status = lxb_css_parser_types_push(parser, @@ -849,13 +978,24 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - if (rule->deep == 1) { - goto done; + if (rule->deep != 0) { + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + } + else { + msg = lxb_css_log_format(parser->log, + LXB_CSS_LOG_SYNTAX_ERROR, + "%S", &lxb_css_err_rc); + if (msg == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - parser->types_pos--; - rule->deep--; + if (rule->nested) { + goto done; + } } return token; @@ -868,7 +1008,7 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, } return token; - + case LXB_CSS_SYNTAX_TOKEN__EOF: goto done; @@ -886,23 +1026,113 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; + rule->phase = lxb_css_syntax_parser_qualified_prelude_end; rule->skip_consume = true; - if (rule->u.qualified.block != 0) { - rule->u.qualified.block_end = token->offset; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_rule_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; + + qualified_rule = rule->cbx.qualified_rule; + + parser->status = qualified_rule->prelude_end(parser, token, + rule->context, rule->failed); + if (parser->status != LXB_STATUS_OK) { + return NULL; } - else { - rule->u.qualified.prelude_end = token->offset; + + return lxb_css_syntax_parser_block_begin(parser, token, rule, + qualified_rule->prelude, + qualified_rule->block); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; + + qualified_rule = rule->cbx.qualified_rule; + + parser->status = qualified_rule->prelude_end(parser, token, + rule->context, rule->failed); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } + + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_success; + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_qualified_rule; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_block_f cb) +{ + void *block_ctx; + lxb_css_syntax_rule_t *block; + const lxb_css_syntax_cb_block_t *cb_block; + + block_ctx = NULL; + rule->skip_consume = false; + + cb_block = cb(parser, token, rule->context, &block_ctx); + if (cb_block == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + block = lxb_css_syntax_parser_block_push(parser, cb_block, back_state, + block_ctx); + if (block == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - return &lxb_css_syntax_token_terminated; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_syntax_token_parser_do_phase_again(parser); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { if (rule->offset > token->offset) { return token; @@ -912,11 +1142,6 @@ lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; - goto done; - } - switch (token->type) { case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: @@ -930,93 +1155,221 @@ lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, goto begin; - case LXB_CSS_SYNTAX_TOKEN_IDENT: - rule->u.declarations.name_begin = token->offset; - - if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { - rule->phase = lxb_css_syntax_parser_declarations_name; - parser->block = rule->cbx.cb->block; + case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_end_consume_token; + break; + } - return token; + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; } - rule->state = rule->cbx.cb->failed; - rule->phase = lxb_css_syntax_parser_declarations_drop; - rule->failed = true; + return token; + case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_end; break; case LXB_CSS_SYNTAX_TOKEN_AT_KEYWORD: - rule->u.declarations.name_begin = 0; - - rule = lxb_css_syntax_parser_at_rule_push(parser, token, - lxb_css_syntax_parser_declarations_back, - rule->cbx.declarations->at_rule, rule->context, - rule->block_end); - if (rule != NULL) { - parser->fake_null = true; - } + rule->phase = lxb_css_syntax_parser_block_at; + break; - return NULL; + case LXB_CSS_SYNTAX_TOKEN_IDENT: + if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { + rule->phase = lxb_css_syntax_parser_block_declarations; + break; + } - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; + /* Fall Through. */ default: - rule->state = rule->cbx.cb->failed; - rule->phase = lxb_css_syntax_parser_declarations_drop; - rule->failed = true; - - rule->u.declarations.name_begin = token->offset; + rule->phase = lxb_css_syntax_parser_block_qualified; break; } - parser->fake_null = true; + rule->skip_consume = true; - return NULL; + return lxb_css_parser_token_end(parser, 0); +} -done: +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_at(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_block_t *block = rule->cbx.block; - rule->phase = lxb_css_syntax_parser_end; - rule->state = lxb_css_state_success; - rule->skip_consume = true; + return lxb_css_syntax_parser_at_begin(parser, token, rule, + block->next, block->at_rule, true); +} - rule->u.declarations.name_begin = 0; - rule->u.declarations.end = token->offset; +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + void *declr_ctx; + lxb_css_syntax_rule_t *declr_rule; + lxb_css_syntax_begin_declarations_f cb; + const lxb_css_syntax_cb_block_t *block; + const lxb_css_syntax_cb_declarations_t *cb_declr; - parser->fake_null = true; + declr_ctx = NULL; + block = rule->cbx.block; + cb = block->declarations; - return NULL; + rule->skip_consume = false; + + cb_declr = cb(parser, token, rule->context, &declr_ctx); + if (cb_declr == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + declr_rule = lxb_css_syntax_parser_declarations_push(parser, cb_declr, + block->next, declr_ctx, + LXB_CSS_SYNTAX_TOKEN_RC_BRACKET, + false, true); + if (declr_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } -static bool -lxb_css_syntax_parser_declarations_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx) +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_qualified(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_css_syntax_rule_t *rules = parser->rules; + void *qualified_ctx; + lxb_css_syntax_rule_t *qualified; + const lxb_css_syntax_cb_block_t *block; + lxb_css_syntax_begin_qualified_rule_f cb; + const lxb_css_syntax_cb_qualified_rule_t *cb_qualified; - rules->state = rules->cbx.declarations->cb.state; + qualified_ctx = NULL; + block = rule->cbx.block; + cb = block->qualified_rule; + + rule->skip_consume = false; - return rules->state(parser, token, ctx); + cb_qualified = cb(parser, token, rule->context, &qualified_ctx); + if (cb_qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + qualified = lxb_css_syntax_parser_qualified_push(parser, cb_qualified, + block->next, qualified_ctx, + LXB_CSS_SYNTAX_TOKEN_SEMICOLON, + true); + if (qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_block_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - if (rule->offset > token->offset) { - return token; + rule->phase = lxb_css_syntax_parser_block; + rule->state = rule->back_state; + rule->skip_consume = true; + + return token; +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_validate(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT + || !lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) + { + rule->phase = lxb_css_syntax_parser_declarations_drop; + rule->state = rule->cbx.cb->failed; + rule->begin = token->offset; + rule->context_old = rule->context; + rule->context = NULL; + rule->failed = true; + + parser->offset.value_end = 0; + + return lxb_css_syntax_token_parser_do_phase_again(parser); } - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + return lxb_css_syntax_parser_declarations_begin(parser, token, rule); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + void *declr_ctx; + lxb_css_syntax_declaration_name_f cb; - return &lxb_css_syntax_token_terminated; + declr_ctx = NULL; + cb = rule->cbx.declarations->name; + + rule->state = cb(parser, token, rule->context, &declr_ctx); + if (rule->state == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } + rule->phase = lxb_css_syntax_parser_declarations_name; + rule->context_old = rule->context; + rule->context = declr_ctx; rule->skip_consume = false; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ /* 1. */ if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { @@ -1049,8 +1402,6 @@ lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, return NULL; } - rule->u.declarations.name_end = token->offset; - lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1069,12 +1420,12 @@ lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, } } - rule->u.declarations.value_begin = token->offset; + rule->begin = token->offset; + parser->offset.value_end = 0; /* 4. */ rule->phase = lxb_css_syntax_parser_declarations_value; - rule->state = parser->block; return lxb_css_syntax_parser_declarations_value(parser, token, rule); } @@ -1085,7 +1436,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { bool imp; - uintptr_t before_important; + size_t offset; lxb_status_t status; if (rule->offset > token->offset) { @@ -1097,7 +1448,6 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -1115,7 +1465,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return token; } - before_important = token->offset; + parser->offset.value_end = token->offset; lxb_css_syntax_token_consume(parser->tkz); @@ -1128,7 +1478,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { rule->important = true; - rule->u.declarations.before_important = before_important; + parser->offset.important_begin = token->offset; lxb_css_syntax_token_consume(parser->tkz); @@ -1138,6 +1488,10 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (token == NULL) { return lxb_css_syntax_parser_failed(parser, parser->tkz->status); } + + parser->offset.important_end = token->offset + + lxb_css_syntax_token_base(token)->length; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1155,6 +1509,10 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, } } } + else { + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } goto again; @@ -1162,17 +1520,20 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (rule->deep == 0) { rule->phase = lxb_css_syntax_parser_declarations_next; - rule->u.declarations.value_end = token->offset; + offset = token->offset; - lxb_css_syntax_token_consume(parser->tkz); + parser->offset.value_begin = rule->begin; + parser->offset.end = offset; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); + if (parser->offset.value_end == 0) { + parser->offset.value_end = offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; } - return &lxb_css_syntax_token_terminated; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_parser_token_end(parser, offset); } return token; @@ -1190,9 +1551,11 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return token; } - rule->u.declarations.before_important = token->offset; rule->important = true; + parser->offset.value_end = token->offset; + parser->offset.important_begin = token->offset; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1200,6 +1563,9 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return lxb_css_syntax_parser_failed(parser, parser->tkz->status); } + parser->offset.important_end = token->offset + + lxb_css_syntax_token_base(token)->length; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1262,177 +1628,304 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_declarations_end; - rule->skip_consume = true; + parser->offset.value_begin = rule->begin; + parser->offset.end = token->offset; + + if (parser->offset.value_end == 0) { + parser->offset.value_end = token->offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } - rule->u.declarations.value_end = token->offset; - rule->u.declarations.end = token->offset; + rule->phase = lxb_css_syntax_parser_declaration_end; + rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { + size_t offset; lxb_status_t status; - lxb_css_syntax_declarations_offset_t *decl; - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + if (rule->offset > token->offset) { + return token; + } - return &lxb_css_syntax_token_terminated; + rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; + + if (rule->block_end == token->type && rule->deep == 0) { + goto done; + } + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_declarations_next; + + offset = token->offset; + + parser->offset.value_begin = rule->begin; + parser->offset.end = offset; + + if (parser->offset.value_end == 0) { + parser->offset.value_end = offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } + + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_parser_token_end(parser, offset); + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); + break; + + case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: + if (rule->deep == 0) { + if (rule->nested) { + goto done; + } + } + else if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: + case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: + if (rule->deep != 0 && parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN__EOF: + goto done; + + default: + return token; } - status = rule->cbx.declarations->declaration_end(parser, rule->context, - rule->important, - rule->failed); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } - rule->phase = lxb_css_syntax_parser_declarations; - rule->state = rule->cbx.cb->state; + rule->deep++; - rule->skip_consume = false; - rule->important = false; - rule->failed = false; + return token; + +done: + + parser->offset.value_begin = rule->begin; + parser->offset.end = token->offset; - decl = &rule->u.declarations; + if (parser->offset.value_end == 0) { + parser->offset.value_end = token->offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } - decl->name_begin = 0; - decl->name_end = 0; - decl->value_begin = 0; - decl->before_important = 0; - decl->value_end = 0; + rule->phase = lxb_css_syntax_parser_declaration_end; + rule->skip_consume = true; - return lxb_css_syntax_parser_declarations(parser, token, rule); + return lxb_css_parser_token_end(parser, token->offset); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { + void *out_rule; lxb_status_t status; + lxb_css_syntax_declaration_name_f name; - /* It is necessary to avoid re-entry of the token into the phase. */ + if (rule->state != lxb_css_state_success) { + rule->skip_consume = true; - if (rule->offset > token->offset) { - return token; + return lxb_css_parser_token_end(parser, token->offset); } - rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - - if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; - goto done; + status = rule->cbx.declarations->end(parser, rule->context_old, + rule->context, token, &parser->offset, + rule->important, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: - if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_declarations_next; +begin: + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, + parser->tkz->status); + } + + goto begin; - rule->u.declarations.name_end = token->offset; + case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_declarations_end; + break; - lxb_css_syntax_token_consume(parser->tkz); + case LXB_CSS_SYNTAX_TOKEN_IDENT: + if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { + out_rule = NULL; + name = rule->cbx.declarations->name; + rule->skip_consume = true; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { + rule->state = name(parser, token, rule->context, &out_rule); + if (rule->state == NULL) { return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; - } + rule->context = out_rule; - return token; + lxb_css_syntax_token_consume(parser->tkz); - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); - break; + rule->phase = lxb_css_syntax_parser_declarations_name; + rule->context = out_rule; - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); - break; + break; + } - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); - break; + /* Fall through. */ - case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; + default: + if (rule->nested) { + rule->phase = lxb_css_syntax_parser_declarations_end; } + else { + rule->phase = lxb_css_syntax_parser_declarations_drop; + rule->state = rule->cbx.cb->failed; + rule->begin = token->offset; + rule->context = NULL; + rule->failed = true; - return token; - - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; + parser->offset.value_end = 0; - default: - return token; - } + return lxb_css_syntax_token_parser_do_phase_again(parser); + } - if (status != LXB_STATUS_OK) { - return lxb_css_syntax_parser_failed(parser, status); + break; } - rule->deep++; - - return token; + rule->skip_consume = false; + rule->important = false; + rule->failed = false; -done: + return lxb_css_syntax_token_parser_do_phase_again(parser); +} - rule->phase = lxb_css_syntax_parser_declarations_end; - rule->skip_consume = true; +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_declarations_value; + rule->state = rule->back_state; + rule->skip_consume = false; - rule->u.declarations.name_end = token->offset; - rule->u.declarations.end = token->offset; + return token; +} - return &lxb_css_syntax_token_terminated; +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + return lxb_css_syntax_parser_declaration_end_handler(parser, token, + rule, false); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_declaration_end_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token) { lxb_status_t status; - lxb_css_syntax_rule_t *rules; if (rule->state != lxb_css_state_success) { rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } - status = rule->cbx.declarations->declaration_end(parser, rule->context, - rule->important, - rule->failed); + status = rule->cbx.declarations->end(parser, rule->context_old, + rule->context, token, &parser->offset, + rule->important, rule->failed); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } + return lxb_css_syntax_parser_declarations_end_h(parser, token, + rule, skip_token); +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + return lxb_css_syntax_parser_declarations_end_h(parser, token, + rule, false); +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token) +{ + lxb_status_t status; + /* This code will be called exclusively from the lxb_css_parser_run(...). */ + rule->context = rule->context_old; + status = rule->cbx.cb->end(parser, token, rule->context, false); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } - if (!rule->skip_ending) { + if (skip_token) { lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1442,18 +1935,7 @@ lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, } } - (void) lxb_css_syntax_parser_stack_pop(parser); - - rules = parser->rules; - - if (parser->rules <= parser->rules_begin) { - rules->state = lxb_css_state_stop; - return token; - } - - rules->phase = rules->back; - - return rules->phase(parser, token, rules); + return lxb_css_syntax_parser_call_back(parser, token); } static const lxb_css_syntax_token_t * @@ -1470,7 +1952,6 @@ lxb_css_syntax_parser_components(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -1521,7 +2002,23 @@ lxb_css_syntax_parser_components(lxb_css_parser_t *parser, rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_components_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_components; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; } static const lxb_css_syntax_token_t * @@ -1555,16 +2052,16 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - if (rule->deep != 0) { - if (parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; - } - } - else { + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_end_consume_token; goto done; } + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + return token; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: @@ -1577,6 +2074,7 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, return token; case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_end; goto done; default: @@ -1593,77 +2091,25 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_function_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_status_t status; - - if (rule->offset > token->offset) { - return token; - } - - rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - - if (rule->block_end == token->type && rule->deep == 0) { - goto done; - } - - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); - break; - - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); - break; - - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); - break; - - case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; - } - - return token; - - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; - - default: - return token; - } - - if (status != LXB_STATUS_OK) { - return lxb_css_syntax_parser_failed(parser, status); - } - - rule->deep++; + rule->phase = lxb_css_syntax_parser_function; + rule->state = rule->back_state; + rule->skip_consume = false; return token; - -done: - - rule->phase = lxb_css_syntax_parser_end; - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; } static const lxb_css_syntax_token_t * @@ -1677,31 +2123,41 @@ lxb_css_syntax_parser_pipe(lxb_css_parser_t *parser, rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } return token; } -const lxb_css_syntax_token_t * -lxb_css_syntax_parser_start_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_pipe_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; - } - - /* This code will be called exclusively from the lxb_css_parser_run(...). */ - + rule->phase = lxb_css_syntax_parser_pipe; + rule->state = rule->back_state; rule->skip_consume = false; - rule->phase = rule->back; - rule->state = parser->block; + return token; +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_blank; - return rule->back(parser, token, rule); + return token; } const lxb_css_syntax_token_t * @@ -1710,13 +2166,12 @@ lxb_css_syntax_parser_end(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { lxb_status_t status; - lxb_css_syntax_rule_t *rules; lxb_css_syntax_cb_base_t *base; - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + if (rule->state != lxb_css_state_success) { + return lxb_css_parser_token_end(parser, token->offset); } /* This code will be called exclusively from the lxb_css_parser_run(...). */ @@ -1728,27 +2183,43 @@ lxb_css_syntax_parser_end(lxb_css_parser_t *parser, return lxb_css_syntax_parser_failed(parser, status); } - if (!rule->skip_ending) { - lxb_css_syntax_token_consume(parser->tkz); + rule->skip_consume = false; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } + return lxb_css_syntax_parser_call_back(parser, token); +} + +const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_consume_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + lxb_css_syntax_cb_base_t *base; + + rule->skip_consume = true; + + if (rule->state != lxb_css_state_success) { + return lxb_css_parser_token_end(parser, token->offset); } - (void) lxb_css_syntax_parser_stack_pop(parser); + /* This code will be called exclusively from the lxb_css_parser_run(...). */ - rules = parser->rules; + base = rule->cbx.user; - if (parser->rules <= parser->rules_begin) { - rules->state = lxb_css_state_stop; - return token; + status = base->end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - rules->phase = rules->back; - rules->state = rule->state_back; + rule->skip_consume = false; + + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, + parser->tkz->status); + } - return rules->phase(parser, token, rules); + return lxb_css_syntax_parser_call_back(parser, token); } diff --git a/ext/lexbor/lexbor/css/syntax/parser.h b/ext/lexbor/lexbor/css/syntax/parser.h index f41d62f1ff87..2e7aff644509 100644 --- a/ext/lexbor/lexbor/css/syntax/parser.h +++ b/ext/lexbor/lexbor/css/syntax/parser.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2025 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -30,70 +30,63 @@ lxb_css_syntax_parser_consume(lxb_css_parser_t *parser); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_list_rules_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_list_rules_t *list_rules, - void *ctx, bool top_level, - lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_at_rule_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_at_rule_t *at_rule, - void *ctx, lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop, + bool nested); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_qualified_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_qualified_rule_t *qualified, - void *ctx, lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop, + bool nested); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_declarations_t *declarations, - void *ctx, lxb_css_syntax_token_type_t stop); + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool name_validate, bool nested); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, void *ctx, lxb_css_syntax_token_type_t stop); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_function_t *func, - void *ctx); - -LXB_API lxb_css_syntax_rule_t * -lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_block_t *block, - void *ctx); + lxb_css_parser_state_f back, void *ctx); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_pipe_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_pipe_t *pipe, - void *ctx, lxb_css_syntax_token_type_t stop); - -LXB_API const lxb_css_syntax_token_t * -lxb_css_syntax_parser_start_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop); LXB_API const lxb_css_syntax_token_t * lxb_css_syntax_parser_end(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +LXB_API const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_consume_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/syntax/res.h b/ext/lexbor/lexbor/css/syntax/res.h index cd33446f81d5..7fa2f8ba705f 100644 --- a/ext/lexbor/lexbor/css/syntax/res.h +++ b/ext/lexbor/lexbor/css/syntax/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,12 +7,9 @@ #ifndef LEXBOR_CSS_SYNTAX_RES_H #define LEXBOR_CSS_SYNTAX_RES_H -#ifdef LXB_CSS_SYNTAX_RES_NAME_MAP -#ifndef LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED -#define LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED #define LXB_CSS_SYNTAX_RES_NAME_START 0x01 -static const lxb_char_t lxb_css_syntax_res_name_map[256] = +LXB_API const lxb_char_t lxb_css_syntax_res_name_map[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -42,7 +39,4 @@ static const lxb_char_t lxb_css_syntax_res_name_map[256] = 0x01, 0x01, 0x01, 0x01, 0x01 }; -#endif /* LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED */ -#endif /* LXB_CSS_SYNTAX_RES_NAME_MAP */ - #endif /* LEXBOR_CSS_SYNTAX_RES_H */ diff --git a/ext/lexbor/lexbor/css/syntax/state.c b/ext/lexbor/lexbor/css/syntax/state.c index 99cd30c1868f..a93731e11235 100644 --- a/ext/lexbor/lexbor/css/syntax/state.c +++ b/ext/lexbor/lexbor/css/syntax/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,12 +14,11 @@ #include "lexbor/css/syntax/syntax.h" #include "lexbor/css/syntax/tokenizer/error.h" -#define LXB_CSS_SYNTAX_RES_NAME_MAP #include "lexbor/css/syntax/res.h" -#define LEXBOR_STR_RES_MAP_HEX -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #define LXB_CSS_SYNTAX_ERROR_CODEPOINT 0x1FFFFF @@ -1101,7 +1100,9 @@ lxb_css_syntax_state_consume_numeric(lxb_css_syntax_tokenizer_t *tkz, /* U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) */ do { - e_digit = (*data - 0x30) + e_digit * 0x0A; + if (e_digit < INT_MAX / 10) { + e_digit = (*data - 0x30) + e_digit * 0x0A; + } data += 1; @@ -1523,7 +1524,7 @@ lxb_css_syntax_state_url(lxb_css_syntax_tokenizer_t *tkz, lxb_css_syntax_tokenizer_error_add(tkz->parse_errors, data, LXB_CSS_SYNTAX_TOKENIZER_ERROR_EOINUR); - return lxb_css_syntax_state_string_set(tkz, token, data); + goto done; default: if (*data >= 0x80) { diff --git a/ext/lexbor/lexbor/css/syntax/state_res.h b/ext/lexbor/lexbor/css/syntax/state_res.h index 2f6e2899fdc0..e98909a5bff4 100644 --- a/ext/lexbor/lexbor/css/syntax/state_res.h +++ b/ext/lexbor/lexbor/css/syntax/state_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/syntax/syntax.c b/ext/lexbor/lexbor/css/syntax/syntax.c index b148d8a043c1..f8a1e944df23 100644 --- a/ext/lexbor/lexbor/css/syntax/syntax.c +++ b/ext/lexbor/lexbor/css/syntax/syntax.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,58 +9,315 @@ #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[17]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value_lowercase[257]; + LXB_EXTERN const lxb_char_t lxb_css_syntax_res_name_map[256]; +#endif -#define LXB_CSS_SYNTAX_RES_NAME_MAP -#include "lexbor/css/syntax/res.h" +static const lexbor_str_t lxb_css_syntax_str_ws = lexbor_str(" "); -static const lexbor_str_t lxb_str_ws = lexbor_str(" "); - - -lxb_status_t +lxb_css_rule_list_t * lxb_css_syntax_parse_list_rules(lxb_css_parser_t *parser, const lxb_css_syntax_cb_list_rules_t *cb, - const lxb_char_t *data, size_t length, - void *ctx, bool top_level) + const lxb_char_t *data, size_t length) { - lxb_status_t status; + lxb_css_rule_list_t *list; lxb_css_syntax_rule_t *rule; if (lxb_css_parser_is_running(parser)) { parser->status = LXB_STATUS_ERROR_WRONG_STAGE; - return parser->status; + return NULL; } lxb_css_parser_clean(parser); - lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_list_rules_push(parser, NULL, NULL, cb, - ctx, top_level, + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + goto failed; + } + + rule = lxb_css_syntax_parser_list_rules_push(parser, cb, NULL, list, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { - status = parser->status; - goto end; + goto failed; + } + + parser->tkz->with_comment = false; + parser->stage = LXB_CSS_PARSER_RUN; + + parser->status = lxb_css_syntax_parser_run(parser); + if (parser->status != LXB_STATUS_OK) { + goto failed; + } + + parser->stage = LXB_CSS_PARSER_END; + + return list; + +failed: + + if (list != NULL) { + lxb_css_rule_list_destroy(list, true); + } + + parser->stage = LXB_CSS_PARSER_END; + + return NULL; +} + +lxb_css_rule_declaration_list_t * +lxb_css_syntax_parse_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *cb, + const lxb_char_t *data, size_t length) +{ + lxb_css_rule_declaration_list_t *list; + lxb_css_syntax_rule_t *rule; + + if (lxb_css_parser_is_running(parser)) { + parser->status = LXB_STATUS_ERROR_WRONG_STAGE; + return NULL; + } + + lxb_css_parser_clean(parser); + lxb_css_parser_buffer_set(parser, data, length); + + list = lxb_css_rule_declaration_list_create(parser->memory); + if (list == NULL) { + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + goto failed; + } + + rule = lxb_css_syntax_parser_declarations_push(parser, cb, NULL, list, + LXB_CSS_SYNTAX_TOKEN_UNDEF, + true, false); + if (rule == NULL) { + goto failed; } parser->tkz->with_comment = false; parser->stage = LXB_CSS_PARSER_RUN; - status = lxb_css_syntax_parser_run(parser); - if (status != LXB_STATUS_OK) { - /* Destroy StyleSheet. */ + parser->status = lxb_css_syntax_parser_run(parser); + if (parser->status != LXB_STATUS_OK) { + goto failed; } -end: + parser->stage = LXB_CSS_PARSER_END; + + return list; + +failed: + + if (list != NULL) { + lxb_css_rule_declaration_list_destroy(list, true); + } parser->stage = LXB_CSS_PARSER_END; - return status; + return NULL; +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_list_rules(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_list_rules_t *list_rules, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + return lxb_css_syntax_parser_list_rules_push(parser, list_rules, back, + ctx, stop); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_at_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_at_rule_t *at_rule, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_AT_KEYWORD) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_at_rule_push(parser, at_rule, back, ctx, + stop, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_qualified_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_qualified_rule_t *qualified, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_qualified_push(parser, qualified, back, + ctx, stop, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_LC_BRACKET) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_RC_BRACKET) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_block_push(parser, block, back, ctx); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_declarations_push(parser, declr, back, + ctx, stop, true, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_components(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_components_push(parser, comp, back, ctx, stop); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_function(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_FUNCTION) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_function_push(parser, func, back, ctx); } lxb_status_t @@ -69,22 +326,20 @@ lxb_css_syntax_stack_expand(lxb_css_parser_t *parser, size_t count) size_t length, cur_len, size; lxb_css_syntax_rule_t *p; - if ((parser->rules + count) >= parser->rules_end) { - cur_len = parser->rules - parser->rules_begin; + cur_len = parser->rules - parser->rules_begin; - length = cur_len + count + 1024; - size = length * sizeof(lxb_css_syntax_rule_t); + length = cur_len + count + 1024; + size = length * sizeof(lxb_css_syntax_rule_t); - p = lexbor_realloc(parser->rules_begin, size); - if (p == NULL) { - return LXB_STATUS_ERROR_MEMORY_ALLOCATION; - } - - parser->rules_begin = p; - parser->rules_end = p + length; - parser->rules = p + cur_len; + p = lexbor_realloc(parser->rules_begin, size); + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; } + parser->rules_begin = p; + parser->rules_end = p + length; + parser->rules = p + cur_len; + return LXB_STATUS_OK; } @@ -166,8 +421,9 @@ lxb_css_syntax_ident_serialize(const lxb_char_t *data, size_t length, data = ++p; if (p < end && lexbor_str_res_map_hex[*p] != 0xff) { - lexbor_serialize_write(cb, lxb_str_ws.data, - lxb_str_ws.length, ctx, status); + lexbor_serialize_write(cb, lxb_css_syntax_str_ws.data, + lxb_css_syntax_str_ws.length, + ctx, status); } continue; @@ -231,8 +487,9 @@ lxb_css_syntax_string_serialize(const lxb_char_t *data, size_t length, p++; if (p < end && lexbor_str_res_map_hex[*p] != 0xff) { - lexbor_serialize_write(cb, lxb_str_ws.data, - lxb_str_ws.length, ctx, status); + lexbor_serialize_write(cb, lxb_css_syntax_str_ws.data, + lxb_css_syntax_str_ws.length, + ctx, status); } data = p; diff --git a/ext/lexbor/lexbor/css/syntax/syntax.h b/ext/lexbor/lexbor/css/syntax/syntax.h index 91ed9088f29a..08e9c5c8618d 100644 --- a/ext/lexbor/lexbor/css/syntax/syntax.h +++ b/ext/lexbor/lexbor/css/syntax/syntax.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Alexander Borisov + * Copyright (C) 2022-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,7 @@ extern "C" { #endif #include "lexbor/css/syntax/tokenizer.h" +#include "lexbor/css/syntax/tokenizer.h" typedef struct lxb_css_syntax_rule lxb_css_syntax_rule_t; @@ -21,124 +22,211 @@ typedef const lxb_css_syntax_token_t * const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); -typedef lxb_status_t -(*lxb_css_syntax_declaration_end_f)(lxb_css_parser_t *parser, void *ctx, - bool important, bool failed); + +typedef struct lxb_css_syntax_cb_base lxb_css_syntax_cb_base_t; +typedef struct lxb_css_syntax_cb_list_rules lxb_css_syntax_cb_list_rules_t; +typedef struct lxb_css_syntax_cb_at_rule lxb_css_syntax_cb_at_rule_t; +typedef struct lxb_css_syntax_cb_qualified_rule lxb_css_syntax_cb_qualified_rule_t; +typedef struct lxb_css_syntax_cb_block lxb_css_syntax_cb_block_t; +typedef struct lxb_css_syntax_cb_declarations lxb_css_syntax_cb_declarations_t; +typedef struct lxb_css_syntax_cb_function lxb_css_syntax_cb_function_t; +typedef struct lxb_css_syntax_cb_components lxb_css_syntax_cb_components_t; +typedef struct lxb_css_syntax_cb_pipe lxb_css_syntax_cb_pipe_t; + +typedef struct lxb_css_syntax_declaration_offset lxb_css_syntax_declaration_offset_t; typedef lxb_status_t (*lxb_css_syntax_cb_done_f)(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx, bool failed); -typedef struct { - uintptr_t begin; - uintptr_t end; -} -lxb_css_syntax_list_rules_offset_t; - -typedef struct { - uintptr_t name; - uintptr_t prelude; - uintptr_t prelude_end; - uintptr_t block; - uintptr_t block_end; -} -lxb_css_syntax_at_rule_offset_t; - -typedef struct { - uintptr_t prelude; - uintptr_t prelude_end; - uintptr_t block; - uintptr_t block_end; -} -lxb_css_syntax_qualified_offset_t; - -typedef struct { - uintptr_t begin; - uintptr_t end; - uintptr_t name_begin; - uintptr_t name_end; - uintptr_t value_begin; - uintptr_t before_important; - uintptr_t value_end; -} -lxb_css_syntax_declarations_offset_t; - -typedef struct { - lxb_css_parser_state_f state; - lxb_css_parser_state_f block; +typedef const lxb_css_syntax_cb_at_rule_t * +(*lxb_css_syntax_begin_at_rule_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_qualified_rule_t * +(*lxb_css_syntax_begin_qualified_rule_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_block_t * +(*lxb_css_syntax_begin_block_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_declarations_t * +(*lxb_css_syntax_begin_declarations_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +typedef lxb_css_parser_state_f +(*lxb_css_syntax_declaration_name_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +typedef lxb_status_t +(*lxb_css_syntax_declaration_end_f)(lxb_css_parser_t *parser, + void *declaration, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +struct lxb_css_syntax_cb_base { lxb_css_parser_state_f failed; lxb_css_syntax_cb_done_f end; -} -lxb_css_syntax_cb_base_t; +}; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_pipe_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_block_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_function_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_components_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_at_rule_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_qualified_rule_t; +struct lxb_css_syntax_cb_list_rules { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f next; + lxb_css_syntax_begin_at_rule_f at_rule; + lxb_css_syntax_begin_qualified_rule_f qualified_rule; +}; + +struct lxb_css_syntax_cb_at_rule { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; + lxb_css_syntax_cb_done_f prelude_end; + lxb_css_syntax_begin_block_f block; +}; + +struct lxb_css_syntax_cb_qualified_rule { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; + lxb_css_syntax_cb_done_f prelude_end; + lxb_css_syntax_begin_block_f block; +}; + +struct lxb_css_syntax_cb_block { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f next; + lxb_css_syntax_begin_at_rule_f at_rule; + lxb_css_syntax_begin_declarations_f declarations; + lxb_css_syntax_begin_qualified_rule_f qualified_rule; +}; -typedef struct { +struct lxb_css_syntax_cb_declarations { lxb_css_syntax_cb_base_t cb; - lxb_css_syntax_declaration_end_f declaration_end; - const lxb_css_syntax_cb_at_rule_t *at_rule; -} -lxb_css_syntax_cb_declarations_t; - -typedef struct { - lxb_css_syntax_cb_base_t cb; - lxb_css_parser_state_f next; - const lxb_css_syntax_cb_at_rule_t *at_rule; - const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; -} -lxb_css_syntax_cb_list_rules_t; + lxb_css_syntax_declaration_name_f name; + lxb_css_syntax_declaration_end_f end; +}; + +struct lxb_css_syntax_cb_function { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f value; +}; + +struct lxb_css_syntax_cb_components { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; +}; + +struct lxb_css_syntax_cb_pipe { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; +}; + +struct lxb_css_syntax_declaration_offset { + size_t value_begin; + size_t value_end; + size_t important_begin; + size_t important_end; + size_t end; +}; struct lxb_css_syntax_rule { lxb_css_syntax_state_f phase; lxb_css_parser_state_f state; - lxb_css_parser_state_f state_back; + + /* + * This callback will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ lxb_css_syntax_state_f back; + lxb_css_parser_state_f back_state; + void *context; + void *context_old; + void *returned; union { const lxb_css_syntax_cb_base_t *cb; const lxb_css_syntax_cb_list_rules_t *list_rules; const lxb_css_syntax_cb_at_rule_t *at_rule; const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; - const lxb_css_syntax_cb_declarations_t *declarations; const lxb_css_syntax_cb_components_t *components; + const lxb_css_syntax_cb_declarations_t *declarations; const lxb_css_syntax_cb_function_t *func; const lxb_css_syntax_cb_block_t *block; const lxb_css_syntax_cb_pipe_t *pipe; void *user; } cbx; - void *context; - - uintptr_t offset; - size_t deep; - lxb_css_syntax_token_type_t block_end; - bool skip_ending; - bool skip_consume; - bool important; - bool failed; - bool top_level; - - union { - lxb_css_syntax_list_rules_offset_t list_rules; - lxb_css_syntax_at_rule_offset_t at_rule; - lxb_css_syntax_qualified_offset_t qualified; - lxb_css_syntax_declarations_offset_t declarations; - void *user; - } u; + size_t offset; + size_t deep; + size_t begin; + lxb_css_syntax_token_type_t block_end; + bool nested; + bool skip_consume; + bool important; + bool failed; }; -LXB_API lxb_status_t +LXB_API lxb_css_rule_list_t * lxb_css_syntax_parse_list_rules(lxb_css_parser_t *parser, const lxb_css_syntax_cb_list_rules_t *cb, - const lxb_char_t *data, size_t length, - void *ctx, bool top_level); + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_rule_declaration_list_t * +lxb_css_syntax_parse_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *cb, + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_list_rules(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_list_rules_t *list_rules, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_at_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_at_rule_t *at_rule, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_qualified_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_qualified_rule_t *qualified, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_components(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_function(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx); + LXB_API lxb_status_t lxb_css_syntax_stack_expand(lxb_css_parser_t *parser, size_t count); @@ -159,6 +247,7 @@ LXB_API lxb_status_t lxb_css_syntax_ident_or_string_serialize(const lxb_char_t *data, size_t length, lexbor_serialize_cb_f cb, void *ctx); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/ext/lexbor/lexbor/css/syntax/token.c b/ext/lexbor/lexbor/css/syntax/token.c index be1cc7809c43..ff53c4531e8b 100644 --- a/ext/lexbor/lexbor/css/syntax/token.c +++ b/ext/lexbor/lexbor/css/syntax/token.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,15 +12,12 @@ #include "lexbor/css/parser.h" #include "lexbor/css/syntax/token.h" #include "lexbor/css/syntax/state.h" -#include "lexbor/css/syntax/state_res.h" - -#define LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP #include "lexbor/css/syntax/token_res.h" -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif lxb_css_syntax_token_t * lxb_css_syntax_tokenizer_token(lxb_css_syntax_tokenizer_t *tkz); diff --git a/ext/lexbor/lexbor/css/syntax/token_res.h b/ext/lexbor/lexbor/css/syntax/token_res.h index 7a8e1c4d2594..d5ee29cf3b22 100644 --- a/ext/lexbor/lexbor/css/syntax/token_res.h +++ b/ext/lexbor/lexbor/css/syntax/token_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,6 @@ #ifndef LEXBOR_CSS_SYNTAX_TOKEN_RES_H #define LEXBOR_CSS_SYNTAX_TOKEN_RES_H - -#ifdef LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP -#ifndef LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED -#define LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED static const lexbor_shs_entry_t lxb_css_syntax_token_res_name_shs_map[136] = { {NULL, NULL, 135, 0}, {NULL, NULL, 0, 0}, @@ -83,8 +79,4 @@ static const lexbor_shs_entry_t lxb_css_syntax_token_res_name_shs_map[136] = {NULL, NULL, 0, 0}, {"semicolon", (void *) LXB_CSS_SYNTAX_TOKEN_SEMICOLON, 9, 0} }; -#endif /* LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED */ -#endif /* LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP */ - - #endif /* LEXBOR_CSS_SYNTAX_TOKEN_RES_H */ diff --git a/ext/lexbor/lexbor/css/syntax/tokenizer.c b/ext/lexbor/lexbor/css/syntax/tokenizer.c index 9eecac657546..a44b2c7194a6 100644 --- a/ext/lexbor/lexbor/css/syntax/tokenizer.c +++ b/ext/lexbor/lexbor/css/syntax/tokenizer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,9 +12,10 @@ #include "lexbor/core/array.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif static const lxb_char_t lxb_css_syntax_tokenizer_important[] = "important"; @@ -297,7 +298,7 @@ lxb_css_syntax_tokenizer_lookup_important_ch(lxb_css_syntax_tokenizer_t *tkz, { static const size_t length = sizeof(lxb_css_syntax_tokenizer_important) - 1; - if (!(end - p >= length + if (!(lxb_size(end - p) >= length && lexbor_str_data_ncasecmp(p, lxb_css_syntax_tokenizer_important, length))) { diff --git a/ext/lexbor/lexbor/css/unit.c b/ext/lexbor/lexbor/css/unit.c new file mode 100644 index 000000000000..f3cc9c8ef28e --- /dev/null +++ b/ext/lexbor/lexbor/css/unit.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2021 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/unit/res.h" + + +const lxb_css_data_t * +lxb_css_unit_absolute_relative_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_absolute_relative_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_absolute_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_absolute_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_relative_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_relative_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_angle_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_angle_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_frequency_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_frequency_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_resolution_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_resolution_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_duration_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_duration_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_by_id(lxb_css_type_t id) +{ + return &lxb_css_unit_data[id]; +} diff --git a/ext/lexbor/lexbor/css/unit/const.h b/ext/lexbor/lexbor/css/unit/const.h index 9b7ba1c311b1..9f5e515834e8 100644 --- a/ext/lexbor/lexbor/css/unit/const.h +++ b/ext/lexbor/lexbor/css/unit/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/unit/res.h b/ext/lexbor/lexbor/css/unit/res.h index 4cca189b6f45..ac24503d1a6f 100644 --- a/ext/lexbor/lexbor/css/unit/res.h +++ b/ext/lexbor/lexbor/css/unit/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/value.c b/ext/lexbor/lexbor/css/value.c new file mode 100644 index 000000000000..23e2472d625c --- /dev/null +++ b/ext/lexbor/lexbor/css/value.c @@ -0,0 +1,678 @@ +/* + * Copyright (C) 2022-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/value/res.h" + +#include "lexbor/core/serialize.h" +#include "lexbor/core/conv.h" + + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[17]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value_lowercase[257]; +#endif + +static const lexbor_str_t lxb_css_value_str_ws = lexbor_str(" "); +static const lexbor_str_t lxb_str_comma = lexbor_str(", "); +static const lexbor_str_t lxb_str_alpha = lexbor_str(" / "); +static const lexbor_str_t lxb_str_rp = lexbor_str(")"); + + +const lxb_css_data_t * +lxb_css_value_by_id(uintptr_t id) +{ + if (id < LXB_CSS_VALUE__LAST_ENTRY) { + return &lxb_css_value_data[id]; + } + + return NULL; +} + +lxb_css_value_type_t +lxb_css_value_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_value_shs, name, length); + if (entry == NULL) { + return LXB_CSS_VALUE__UNDEF; + } + + return (lxb_css_value_type_t) (uintptr_t) entry->value; +} + +lxb_status_t +lxb_css_value_serialize(lxb_css_value_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_data_t *data; + + if (type >= LXB_CSS_VALUE__LAST_ENTRY) { + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + data = &lxb_css_value_data[type]; + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_value_percentage_sr(const lxb_css_value_percentage_t *percent, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + static const lexbor_str_t str_per = lexbor_str("%"); + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(percent->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + lexbor_serialize_write(cb, str_per.data, str_per.length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_sr(const lxb_css_value_length_t *len, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + const lxb_css_data_t *unit; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(len->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + if (len->unit == LXB_CSS_UNIT__UNDEF) { + return LXB_STATUS_OK; + } + + unit = lxb_css_unit_by_id(len->unit); + if (unit == NULL) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, unit->name, unit->length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_sr(const lxb_css_value_number_t *number, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(number->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_integer_sr(const lxb_css_value_integer_t *integer, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_long_to_data(integer->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_percentage_sr(const lxb_css_value_length_percentage_t *lp, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lp->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&lp->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&lp->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(lp->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_length_sr(const lxb_css_value_number_length_t *nl, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (nl->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&nl->u.length, cb, ctx); + + default: + return lxb_css_value_serialize(nl->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_percentage_sr(const lxb_css_value_number_percentage_t *np, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (np->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&np->u.number, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&np->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(np->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_type_sr(const lxb_css_value_length_type_t *lt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lt->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(<->length, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(lt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_percentage_type_sr(const lxb_css_value_percentage_type_t *pt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (pt->type) { + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&pt->percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(pt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_type_sr(const lxb_css_value_number_type_t *num, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (num->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&num->number, cb, ctx); + + default: + return lxb_css_value_serialize(num->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_integer_type_sr(const lxb_css_value_integer_type_t *num, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (num->type) { + case LXB_CSS_VALUE__INTEGER: + return lxb_css_value_integer_sr(&num->integer, cb, ctx); + + default: + return lxb_css_value_serialize(num->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_percentage_type_sr(const lxb_css_value_length_percentage_type_t *lpt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lpt->type) { + case LXB_CSS_VALUE__LENGTH: + return lxb_css_value_length_percentage_sr(&lpt->length, cb, ctx); + + default: + return lxb_css_value_serialize(lpt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_length_percentage_type_sr(const lxb_css_value_number_length_percentage_t *nlp, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (nlp->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&nlp->u.number, cb, ctx); + + case LXB_CSS_VALUE__LENGTH: + return lxb_css_value_length_sr(&nlp->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&nlp->u.percentage, cb, ctx); + + default: + return lxb_css_value_serialize(nlp->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_angle_sr(const lxb_css_value_angle_t *angle, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + const lxb_css_data_t *data; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(angle->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + data = lxb_css_unit_by_id(angle->unit); + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_value_hue_sr(const lxb_css_value_hue_t *hue, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (hue->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&hue->u.number, cb, ctx); + + case LXB_CSS_VALUE__ANGLE: + return lxb_css_value_angle_sr(&hue->u.angle, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(hue->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_value_color_hex_sr(const lxb_css_value_color_hex_t *hex, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + static const lexbor_str_t str_hash = lexbor_str("#"); + const lxb_css_value_color_hex_rgba_t *rgba = &hex->rgba; + + const lxb_char_t *hmo = lexbor_str_res_map_hex_to_char_lowercase; + const char **hmt = lexbor_str_res_char_to_two_hex_value_lowercase; + + lexbor_serialize_write(cb, str_hash.data, str_hash.length, ctx, status); + + switch (hex->type) { + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_3: + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4: + lexbor_serialize_write(cb, &hmo[rgba->r], 1, ctx, status); + lexbor_serialize_write(cb, &hmo[rgba->g], 1, ctx, status); + lexbor_serialize_write(cb, &hmo[rgba->b], 1, ctx, status); + + if (hex->type == LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4) { + lexbor_serialize_write(cb, &hmo[rgba->a], 1, ctx, status); + } + + break; + + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_6: + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8: + lexbor_serialize_write(cb, hmt[rgba->r], 2, ctx, status); + lexbor_serialize_write(cb, hmt[rgba->g], 2, ctx, status); + lexbor_serialize_write(cb, hmt[rgba->b], 2, ctx, status); + + if (hex->type == LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8) { + lexbor_serialize_write(cb, hmt[rgba->a], 2, ctx, status); + } + + break; + + default: + break; + } + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_value_color_rgb_sr(const lxb_css_value_color_rgba_t *rgb, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + const lexbor_str_t *sep; + static const lexbor_str_t str_rgb = lexbor_str("rgb("); + static const lexbor_str_t str_rgba = lexbor_str("rgba("); + + if (type == LXB_CSS_COLOR_RGB) { + lexbor_serialize_write(cb, str_rgb.data, str_rgb.length, ctx, status); + } + else { + lexbor_serialize_write(cb, str_rgba.data, str_rgba.length, ctx, status); + } + + sep = (rgb->old) ? &lxb_str_comma : &lxb_css_value_str_ws; + + status = lxb_css_value_number_percentage_sr(&rgb->r, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->g, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->b, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (rgb->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + sep = (rgb->old) ? &lxb_str_comma : &lxb_str_alpha; + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_hsl_sr(const lxb_css_value_color_hsla_t *hsl, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + const lexbor_str_t *sep; + static const lexbor_str_t str_hsl = lexbor_str("hsl("); + static const lexbor_str_t str_hsla = lexbor_str("hsla("); + static const lexbor_str_t str_hwb = lexbor_str("hwb("); + + switch (type) { + case LXB_CSS_COLOR_HSL: + status = cb(str_hsl.data, str_hsl.length, ctx); + break; + + case LXB_CSS_COLOR_HSLA: + status = cb(str_hsla.data, str_hsla.length, ctx); + break; + + case LXB_CSS_COLOR_HWB: + status = cb(str_hwb.data, str_hwb.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + sep = (hsl->old) ? &lxb_str_comma : &lxb_css_value_str_ws; + + status = lxb_css_value_hue_sr(&hsl->h, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_percentage_type_sr(&hsl->s, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_percentage_type_sr(&hsl->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (hsl->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + sep = (hsl->old) ? &lxb_str_comma : &lxb_str_alpha; + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&hsl->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_lab_sr(const lxb_css_value_color_lab_t *lab, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + static const lexbor_str_t str_lab = lexbor_str("lab("); + static const lexbor_str_t str_oklab = lexbor_str("oklab("); + + switch (type) { + case LXB_CSS_COLOR_LAB: + status = cb(str_lab.data, str_lab.length, ctx); + break; + + case LXB_CSS_COLOR_OKLAB: + status = cb(str_oklab.data, str_oklab.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + status = lxb_css_value_number_percentage_sr(&lab->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->b, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (lab->alpha.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + lexbor_serialize_write(cb, lxb_str_alpha.data, lxb_str_alpha.length, + ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->alpha, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_lch_sr(const lxb_css_value_color_lch_t *lch, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + static const lexbor_str_t str_lch = lexbor_str("lch("); + static const lexbor_str_t str_oklch = lexbor_str("oklch("); + + switch (type) { + case LXB_CSS_COLOR_LCH: + status = cb(str_lch.data, str_lch.length, ctx); + break; + + case LXB_CSS_COLOR_OKLCH: + status = cb(str_oklch.data, str_oklch.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + status = lxb_css_value_number_percentage_sr(&lch->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lch->c, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_hue_sr(&lch->h, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (lch->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + lexbor_serialize_write(cb, lxb_str_alpha.data, lxb_str_alpha.length, + ctx, status); + + status = lxb_css_value_number_percentage_sr(&lch->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +lxb_status_t +lxb_css_value_color_serialize(const lxb_css_value_color_t *color, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (color->type) { + case LXB_CSS_COLOR_HEX: + return lxb_css_value_color_hex_sr(&color->u.hex, cb, ctx); + + case LXB_CSS_COLOR_RGB: + case LXB_CSS_COLOR_RGBA: + return lxb_css_value_color_rgb_sr(&color->u.rgb, cb, ctx, + color->type); + + case LXB_CSS_COLOR_HSL: + case LXB_CSS_COLOR_HSLA: + case LXB_CSS_COLOR_HWB: + return lxb_css_value_color_hsl_sr(&color->u.hsl, cb, ctx, + color->type); + + case LXB_CSS_COLOR_LAB: + case LXB_CSS_COLOR_OKLAB: + return lxb_css_value_color_lab_sr(&color->u.lab, cb, ctx, + color->type); + + case LXB_CSS_COLOR_LCH: + case LXB_CSS_COLOR_OKLCH: + return lxb_css_value_color_lch_sr(&color->u.lch, cb, ctx, + color->type); + + case LXB_CSS_VALUE__UNDEF: + break; + + default: + return lxb_css_value_serialize(color->type, cb, ctx); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/value/const.h b/ext/lexbor/lexbor/css/value/const.h index c9b5241e1d73..a7bd64c60349 100644 --- a/ext/lexbor/lexbor/css/value/const.h +++ b/ext/lexbor/lexbor/css/value/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/value/res.h b/ext/lexbor/lexbor/css/value/res.h index 79b3c6b0322f..180dc95f10e9 100644 --- a/ext/lexbor/lexbor/css/value/res.h +++ b/ext/lexbor/lexbor/css/value/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/dom/base.h b/ext/lexbor/lexbor/dom/base.h index 167e43d7691c..3894aa13ca6c 100644 --- a/ext/lexbor/lexbor/dom/base.h +++ b/ext/lexbor/lexbor/dom/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,8 +15,8 @@ extern "C" { #include "lexbor/core/base.h" -#define LXB_DOM_VERSION_MAJOR 1 -#define LXB_DOM_VERSION_MINOR 8 +#define LXB_DOM_VERSION_MAJOR 2 +#define LXB_DOM_VERSION_MINOR 0 #define LXB_DOM_VERSION_PATCH 0 #define LXB_DOM_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/dom/exception.c b/ext/lexbor/lexbor/dom/exception.c index 44fcf65d6b4e..5433ce42aac6 100644 --- a/ext/lexbor/lexbor/dom/exception.c +++ b/ext/lexbor/lexbor/dom/exception.c @@ -1,18 +1,372 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/dom/exception.h" +#include "lexbor/dom/interfaces/document.h" -/* - * No inline functions for ABI. - */ -void * -lxb_dom_exception_code_ref_set_noi(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code) +typedef struct { + lexbor_str_t name; + lexbor_str_t message; +} +lxb_dom_exception_data_t; + + +static const lxb_dom_exception_data_t lxb_dom_exception_data[LXB_DOM_EXCEPTION__LAST_ENTRY] = +{ + { + lexbor_str("Error"), + lexbor_str("") + }, + { + lexbor_str("IndexSizeError"), + lexbor_str("Deprecated. Use RangeError instead.") + }, + { + lexbor_str("DOMStringSizeError"), + lexbor_str("") + }, + { + lexbor_str("HierarchyRequestError"), + lexbor_str("The operation would yield an incorrect node tree.") + }, + { + lexbor_str("WrongDocumentError"), + lexbor_str("The object is in the wrong document.") + }, + { + lexbor_str("InvalidCharacterError"), + lexbor_str("The string contains invalid characters.") + }, + { + lexbor_str("NoDataAllowedError"), + lexbor_str("") + }, + { + lexbor_str("NoModificationAllowedError"), + lexbor_str("The object can not be modified.") + }, + { + lexbor_str("NotFoundError"), + lexbor_str("The object can not be found here.") + }, + { + lexbor_str("NotSupportedError"), + lexbor_str("The operation is not supported.") + }, + { + lexbor_str("InUseAttributeError"), + lexbor_str("The attribute is in use by another element.") + }, + { + lexbor_str("InvalidStateError"), + lexbor_str("The object is in an invalid state.") + }, + { + lexbor_str("SyntaxError"), + lexbor_str("The string did not match the expected pattern.") + }, + { + lexbor_str("InvalidModificationError"), + lexbor_str("The object can not be modified in this way.") + }, + { + lexbor_str("NamespaceError"), + lexbor_str("The operation is not allowed by Namespaces in XML.") + }, + { + lexbor_str("InvalidAccessError"), + lexbor_str("Deprecated. Use TypeError for invalid arguments, " + "\"NotSupportedError\" DOMException for unsupported operations, " + "and \"NotAllowedError\" DOMException for denied requests instead.") + }, + { + lexbor_str("ValidationError"), + lexbor_str("") + }, + { + lexbor_str("TypeMismatchError"), + lexbor_str("Deprecated. Use TypeError instead.") + }, + { + lexbor_str("SecurityError"), + lexbor_str("The operation is insecure.") + }, + { + lexbor_str("NetworkError"), + lexbor_str("A network error occurred.") + }, + { + lexbor_str("AbortError"), + lexbor_str("The operation was aborted.") + }, + { + lexbor_str("URLMismatchError"), + lexbor_str("Deprecated.") + }, + { + lexbor_str("QuotaExceededError"), + lexbor_str("Deprecated. Use the QuotaExceededError DOMException-derived " + "interface instead.") + }, + { + lexbor_str("TimeoutError"), + lexbor_str("The operation timed out.") + }, + { + lexbor_str("InvalidNodeTypeError"), + lexbor_str("The supplied node is incorrect or has an incorrect ancestor " + "for this operation.") + }, + { + lexbor_str("DataCloneError"), + lexbor_str("The object can not be cloned.") + }, + { + lexbor_str("EncodingError"), + lexbor_str("The encoding operation (either encoded or decoding) failed.") + }, + { + lexbor_str("NotReadableError"), + lexbor_str("The I/O read operation failed.") + }, + { + lexbor_str("UnknownError"), + lexbor_str("The operation failed for an unknown transient reason " + "(e.g. out of memory).") + }, + { + lexbor_str("ConstraintError"), + lexbor_str("A mutation operation in a transaction failed because a " + "constraint was not satisfied.") + }, + { + lexbor_str("DataError"), + lexbor_str("Provided data is inadequate.") + }, + { + lexbor_str("TransactionInactiveError"), + lexbor_str("A request was placed against a transaction which is currently" + " not active, or which is finished.") + }, + { + lexbor_str("ReadOnlyError"), + lexbor_str("The mutating operation was attempted in a \"readonly\" transaction.") + }, + { + lexbor_str("VersionError"), + lexbor_str("An attempt was made to open a database using a lower version" + " than the existing version.") + }, + { + lexbor_str("OperationError"), + lexbor_str("The operation failed for an operation-specific reason.") + }, + { + lexbor_str("NotAllowedError"), + lexbor_str("The request is not allowed by the user agent or the platform" + " in the current context, possibly because the user denied permission.") + }, + { + lexbor_str("OptOutError"), + lexbor_str("The user opted out of the process.") + } +}; + + +lxb_dom_exception_t * +lxb_dom_exception_create(lxb_dom_document_t *document, + const lxb_char_t *message, size_t message_length, + const lxb_char_t *name, size_t name_length) +{ + lexbor_str_t *str; + const lxb_dom_exception_data_t *data; + lxb_dom_exception_t *exception; + + exception = lexbor_mraw_alloc(document->mraw, sizeof(lxb_dom_exception_t)); + if (exception == NULL) { + return NULL; + } + + exception->document = document; + + if (name != NULL && name_length > 0) { + exception->code = lxb_dom_exception_code_by_name(name, name_length); + } + else { + exception->code = LXB_DOM_EXCEPTION_ERR; + } + + /* Message. */ + + if (message == NULL || message_length == 0) { + data = &lxb_dom_exception_data[exception->code]; + exception->message = *((lexbor_str_t *) &data->message); + } + else { + str = &exception->message; + str->data = lexbor_mraw_alloc(document->mraw, message_length + 1); + if (str->data == NULL) { + goto failed; + } + + memcpy(str->data, message, message_length); + + str->data[message_length] = '\0'; + str->length = message_length; + } + + /* Name. */ + + if (exception->code != LXB_DOM_EXCEPTION_ERR + || name == NULL || name_length == 0) + { + data = &lxb_dom_exception_data[exception->code]; + exception->name = *((lexbor_str_t *) &data->name); + } + else { + str = &exception->name; + str->data = lexbor_mraw_alloc(document->mraw, name_length + 1); + if (str->data == NULL) { + if (exception->message.length != 0) { + lexbor_mraw_free(document->mraw, exception->message.data); + } + + goto failed; + } + + memcpy(str->data, name, name_length); + + str->data[name_length] = '\0'; + str->length = name_length; + } + + return exception; + +failed: + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +lxb_dom_exception_t * +lxb_dom_exception_create_by_code(lxb_dom_document_t *document, + const lxb_char_t *message, size_t length, + lxb_dom_exception_code_t code) { - return lxb_dom_exception_code_ref_set(var, code); + lexbor_str_t *str; + const lxb_dom_exception_data_t *data; + lxb_dom_exception_t *exception; + + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + exception = lexbor_mraw_alloc(document->mraw, sizeof(lxb_dom_exception_t)); + if (exception == NULL) { + return NULL; + } + + exception->document = document; + exception->code = code; + + data = &lxb_dom_exception_data[code]; + + /* Message. */ + + if (message == NULL || length == 0) { + exception->message = *((lexbor_str_t *) &data->message); + } + else { + str = &exception->message; + str->data = lexbor_mraw_alloc(document->mraw, length + 1); + if (str->data == NULL) { + goto failed; + } + + memcpy(str->data, message, length); + + str->data[length] = '\0'; + str->length = length; + } + + /* Name. */ + + exception->name = *((lexbor_str_t *) &data->name); + + return exception; + +failed: + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +lxb_dom_exception_t * +lxb_dom_exception_destroy(lxb_dom_exception_t *exception) +{ + const lxb_dom_exception_data_t *data; + lxb_dom_document_t *document = exception->document; + + data = &lxb_dom_exception_data[exception->code]; + + if (exception->message.data != NULL + && exception->message.data != data->message.data) + { + lexbor_mraw_free(document->mraw, exception->message.data); + } + + if (exception->name.data != NULL + && exception->name.data != data->name.data) + { + lexbor_mraw_free(document->mraw, exception->name.data); + } + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +const lexbor_str_t * +lxb_dom_exception_message_by_code(lxb_dom_exception_code_t code) +{ + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + return &lxb_dom_exception_data[code].message; +} + +const lexbor_str_t * +lxb_dom_exception_name_by_code(lxb_dom_exception_code_t code) +{ + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + return &lxb_dom_exception_data[code].name; +} + +lxb_dom_exception_code_t +lxb_dom_exception_code_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_str_t *str; + lxb_dom_exception_code_t code; + + for (code = 0; code < LXB_DOM_EXCEPTION__LAST_ENTRY; code++) { + str = &lxb_dom_exception_data[code].name; + + if (length == str->length + && lexbor_str_data_ncasecmp(str->data, name, length)) + { + return code; + } + } + + return LXB_DOM_EXCEPTION_ERR; } diff --git a/ext/lexbor/lexbor/dom/exception.h b/ext/lexbor/lexbor/dom/exception.h index 47a7cfee040c..b306ed1443a3 100644 --- a/ext/lexbor/lexbor/dom/exception.h +++ b/ext/lexbor/lexbor/dom/exception.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,58 +12,84 @@ extern "C" { #endif #include "lexbor/core/base.h" +#include "lexbor/core/str.h" +#include "lexbor/dom/interface.h" typedef enum { - LXB_DOM_INDEX_SIZE_ERR = 0x00, - LXB_DOM_DOMSTRING_SIZE_ERR, - LXB_DOM_HIERARCHY_REQUEST_ERR, - LXB_DOM_WRONG_DOCUMENT_ERR, - LXB_DOM_INVALID_CHARACTER_ERR, - LXB_DOM_NO_DATA_ALLOWED_ERR, - LXB_DOM_NO_MODIFICATION_ALLOWED_ERR, - LXB_DOM_NOT_FOUND_ERR, - LXB_DOM_NOT_SUPPORTED_ERR, - LXB_DOM_INUSE_ATTRIBUTE_ERR, - LXB_DOM_INVALID_STATE_ERR, - LXB_DOM_SYNTAX_ERR, - LXB_DOM_INVALID_MODIFICATION_ERR, - LXB_DOM_NAMESPACE_ERR, - LXB_DOM_INVALID_ACCESS_ERR, - LXB_DOM_VALIDATION_ERR, - LXB_DOM_TYPE_MISMATCH_ERR, - LXB_DOM_SECURITY_ERR, - LXB_DOM_NETWORK_ERR, - LXB_DOM_ABORT_ERR, - LXB_DOM_URL_MISMATCH_ERR, - LXB_DOM_QUOTA_EXCEEDED_ERR, - LXB_DOM_TIMEOUT_ERR, - LXB_DOM_INVALID_NODE_TYPE_ERR, - LXB_DOM_DATA_CLONE_ERR + LXB_DOM_EXCEPTION_OK = -1, + LXB_DOM_EXCEPTION_ERR = 0, + LXB_DOM_EXCEPTION_INDEX_SIZE_ERR = 1, /* Deprecated. */ + LXB_DOM_EXCEPTION_DOMSTRING_SIZE_ERR, + LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR, + LXB_DOM_EXCEPTION_WRONG_DOCUMENT_ERR, + LXB_DOM_EXCEPTION_INVALID_CHARACTER_ERR, + LXB_DOM_EXCEPTION_NO_DATA_ALLOWED_ERR, + LXB_DOM_EXCEPTION_NO_MODIFICATION_ALLOWED_ERR, + LXB_DOM_EXCEPTION_NOT_FOUND_ERR, + LXB_DOM_EXCEPTION_NOT_SUPPORTED_ERR, + LXB_DOM_EXCEPTION_INUSE_ATTRIBUTE_ERR, + LXB_DOM_EXCEPTION_INVALID_STATE_ERR, + LXB_DOM_EXCEPTION_SYNTAX_ERR, + LXB_DOM_EXCEPTION_INVALID_MODIFICATION_ERR, + LXB_DOM_EXCEPTION_NAMESPACE_ERR, + LXB_DOM_EXCEPTION_INVALID_ACCESS_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_VALIDATION_ERR, + LXB_DOM_EXCEPTION_TYPE_MISMATCH_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_SECURITY_ERR, + LXB_DOM_EXCEPTION_NETWORK_ERR, + LXB_DOM_EXCEPTION_ABORT_ERR, + LXB_DOM_EXCEPTION_URL_MISMATCH_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_QUOTA_EXCEEDED_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_TIMEOUT_ERR, + LXB_DOM_EXCEPTION_INVALID_NODE_TYPE_ERR, + LXB_DOM_EXCEPTION_DATA_CLONE_ERR, + LXB_DOM_EXCEPTION_ENCODING_ERR, + LXB_DOM_EXCEPTION_NOT_READABLE_ERR, + LXB_DOM_EXCEPTION_UNKNOWN_ERR, + LXB_DOM_EXCEPTION_CONSTRAINT_ERR, + LXB_DOM_EXCEPTION_DATA_ERR, + LXB_DOM_EXCEPTION_TRANSACTION_INACTIVE_ERR, + LXB_DOM_EXCEPTION_READ_ONLY_ERR, + LXB_DOM_EXCEPTION_VERSION_ERR, + LXB_DOM_EXCEPTION_OPERATION_ERR, + LXB_DOM_EXCEPTION_NOT_ALLOWED_ERR, + LXB_DOM_EXCEPTION_OPT_OUT_ERR, + LXB_DOM_EXCEPTION__LAST_ENTRY } lxb_dom_exception_code_t; - -/* - * Inline functions - */ -lxb_inline void * -lxb_dom_exception_code_ref_set(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code) -{ - if (var != NULL) { - *var = code; - } - - return NULL; +typedef struct { + lexbor_str_t name; + lexbor_str_t message; + lxb_dom_exception_code_t code; + lxb_dom_document_t *document; } +lxb_dom_exception_t; -/* - * No inline functions for ABI. - */ -LXB_API void * -lxb_dom_exception_code_ref_set_noi(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_create(lxb_dom_document_t *document, + const lxb_char_t *message, size_t message_length, + const lxb_char_t *name, size_t name_length); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_create_by_code(lxb_dom_document_t *document, + const lxb_char_t *message, size_t length, + lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_destroy(lxb_dom_exception_t *exception); + + +LXB_API const lexbor_str_t * +lxb_dom_exception_message_by_code(lxb_dom_exception_code_t code); + +LXB_API const lexbor_str_t * +lxb_dom_exception_name_by_code(lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_code_t +lxb_dom_exception_code_by_name(const lxb_char_t *name, size_t length); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/dom/interface.h b/ext/lexbor/lexbor/dom/interface.h index 3eb4b133e9cd..30753e0b43ab 100644 --- a/ext/lexbor/lexbor/dom/interface.h +++ b/ext/lexbor/lexbor/dom/interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,8 +16,6 @@ extern "C" { #include "lexbor/tag/const.h" #include "lexbor/ns/const.h" -#include "lexbor/dom/exception.h" - #define lxb_dom_interface_cdata_section(obj) ((lxb_dom_cdata_section_t *) (obj)) #define lxb_dom_interface_character_data(obj) ((lxb_dom_character_data_t *) (obj)) diff --git a/ext/lexbor/lexbor/dom/interfaces/attr_const.h b/ext/lexbor/lexbor/dom/interfaces/attr_const.h index 756ad5548e45..28afac5e0bdd 100644 --- a/ext/lexbor/lexbor/dom/interfaces/attr_const.h +++ b/ext/lexbor/lexbor/dom/interfaces/attr_const.h @@ -39,22 +39,23 @@ typedef enum { LXB_DOM_ATTR_ID = 0x0012, LXB_DOM_ATTR_IS = 0x0013, LXB_DOM_ATTR_MAXLENGTH = 0x0014, - LXB_DOM_ATTR_PLACEHOLDER = 0x0015, - LXB_DOM_ATTR_POOL = 0x0016, - LXB_DOM_ATTR_PUBLIC = 0x0017, - LXB_DOM_ATTR_READONLY = 0x0018, - LXB_DOM_ATTR_REQUIRED = 0x0019, - LXB_DOM_ATTR_SCHEME = 0x001a, - LXB_DOM_ATTR_SELECTED = 0x001b, - LXB_DOM_ATTR_SIZE = 0x001c, - LXB_DOM_ATTR_SLOT = 0x001d, - LXB_DOM_ATTR_SRC = 0x001e, - LXB_DOM_ATTR_STYLE = 0x001f, - LXB_DOM_ATTR_SYSTEM = 0x0020, - LXB_DOM_ATTR_TITLE = 0x0021, - LXB_DOM_ATTR_TYPE = 0x0022, - LXB_DOM_ATTR_WIDTH = 0x0023, - LXB_DOM_ATTR__LAST_ENTRY = 0x0024 + LXB_DOM_ATTR_MULTIPLE = 0x0015, + LXB_DOM_ATTR_PLACEHOLDER = 0x0016, + LXB_DOM_ATTR_POOL = 0x0017, + LXB_DOM_ATTR_PUBLIC = 0x0018, + LXB_DOM_ATTR_READONLY = 0x0019, + LXB_DOM_ATTR_REQUIRED = 0x001a, + LXB_DOM_ATTR_SCHEME = 0x001b, + LXB_DOM_ATTR_SELECTED = 0x001c, + LXB_DOM_ATTR_SIZE = 0x001d, + LXB_DOM_ATTR_SLOT = 0x001e, + LXB_DOM_ATTR_SRC = 0x001f, + LXB_DOM_ATTR_STYLE = 0x0020, + LXB_DOM_ATTR_SYSTEM = 0x0021, + LXB_DOM_ATTR_TITLE = 0x0022, + LXB_DOM_ATTR_TYPE = 0x0023, + LXB_DOM_ATTR_WIDTH = 0x0024, + LXB_DOM_ATTR__LAST_ENTRY = 0x0025 } lxb_dom_attr_id_enum_t; diff --git a/ext/lexbor/lexbor/dom/interfaces/attr_res.h b/ext/lexbor/lexbor/dom/interfaces/attr_res.h index 85aa2c5061fc..0796043cafd7 100644 --- a/ext/lexbor/lexbor/dom/interfaces/attr_res.h +++ b/ext/lexbor/lexbor/dom/interfaces/attr_res.h @@ -63,6 +63,8 @@ static const lxb_dom_attr_data_t lxb_dom_attr_res_data_default[LXB_DOM_ATTR__LAS LXB_DOM_ATTR_IS, 1, true}, {{.u.short_str = "maxlength", .length = 9, .next = NULL}, LXB_DOM_ATTR_MAXLENGTH, 1, true}, + {{.u.short_str = "multiple", .length = 8, .next = NULL}, + LXB_DOM_ATTR_MULTIPLE, 1, true}, {{.u.short_str = "placeholder", .length = 11, .next = NULL}, LXB_DOM_ATTR_PLACEHOLDER, 1, true}, {{.u.short_str = "pool", .length = 4, .next = NULL}, @@ -127,7 +129,7 @@ static const lexbor_shs_entry_t lxb_dom_attr_res_shs_data[40] = {"is", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_IS], 2, 0}, {"type", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_TYPE], 4, 0}, {"title", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_TITLE], 5, 0}, - {NULL, NULL, 0, 0}, + {"multiple", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_MULTIPLE], 8, 0}, {"for", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_FOR], 3, 0}, {"face", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_FACE], 4, 22}, {"alt", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_ALT], 3, 23}, @@ -135,7 +137,7 @@ static const lexbor_shs_entry_t lxb_dom_attr_res_shs_data[40] = {"charset", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHARSET], 7, 26}, {"maxlength", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_MAXLENGTH], 9, 0}, {NULL, NULL, 0, 0}, - {"checked", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHECKED], 7, 0}, + {"checked", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHECKED], 7, 30}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/dom/interfaces/character_data.c b/ext/lexbor/lexbor/dom/interfaces/character_data.c index bbca1865b39d..12c7dfdd0d6c 100644 --- a/ext/lexbor/lexbor/dom/interfaces/character_data.c +++ b/ext/lexbor/lexbor/dom/interfaces/character_data.c @@ -22,7 +22,7 @@ lxb_dom_character_data_interface_create(lxb_dom_document_t *document) lxb_dom_node_t *node = lxb_dom_interface_node(element); node->owner_document = lxb_dom_document_owner(document); - node->type = LXB_DOM_NODE_TYPE_UNDEF; + node->type = LXB_DOM_NODE_TYPE_CHARACTER_DATA; return element; } diff --git a/ext/lexbor/lexbor/dom/interfaces/document_type.c b/ext/lexbor/lexbor/dom/interfaces/document_type.c index 8c7465f4d62b..46889162717f 100644 --- a/ext/lexbor/lexbor/dom/interfaces/document_type.c +++ b/ext/lexbor/lexbor/dom/interfaces/document_type.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,10 @@ LXB_API lxb_dom_attr_data_t * lxb_dom_attr_qualified_name_append(lexbor_hash_t *hash, const lxb_char_t *name, size_t length); +LXB_API lxb_dom_attr_data_t * +lxb_dom_attr_local_name_append(lexbor_hash_t *hash, + const lxb_char_t *name, size_t length); + lxb_dom_document_type_t * lxb_dom_document_type_interface_create(lxb_dom_document_t *document) @@ -29,6 +33,8 @@ lxb_dom_document_type_interface_create(lxb_dom_document_t *document) node->owner_document = lxb_dom_document_owner(document); node->type = LXB_DOM_NODE_TYPE_DOCUMENT_TYPE; + element->name = LXB_DOM_ATTR_HTML; + return element; } @@ -105,6 +111,103 @@ lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type) return NULL; } +lxb_dom_document_type_t * +lxb_dom_document_type_create(lxb_dom_document_t *document, + const lxb_char_t *name, size_t name_len, + const lxb_char_t *pub, size_t pub_len, + const lxb_char_t *sys, size_t sys_len, + lxb_dom_exception_code_t *code) +{ + lxb_dom_attr_data_t *data; + lxb_dom_document_type_t *doctype; + + if (!lxb_dom_document_type_valid_name(name, name_len)) { + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_INVALID_CHARACTER_ERR; + } + + return NULL; + } + + doctype = lxb_dom_document_type_interface_create(document); + if (doctype == NULL) { + goto failed; + } + + data = lxb_dom_attr_local_name_append(document->attrs, name, name_len); + if (data == NULL) { + goto failed; + } + + doctype->name = data->attr_id; + + if (pub != NULL && pub_len != 0) { + doctype->public_id.data = lxb_dom_document_create_text(document, + pub_len + 1); + if (doctype->public_id.data == NULL) { + goto failed; + } + + (void) lexbor_str_copy_to_with_null(&doctype->public_id, pub, pub_len); + } + + if (sys != NULL && sys_len != 0) { + doctype->system_id.data = lxb_dom_document_create_text(document, + sys_len + 1); + if (doctype->system_id.data == NULL) { + goto failed; + } + + (void) lexbor_str_copy_to_with_null(&doctype->system_id, sys, sys_len); + } + + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_OK; + } + + return doctype; + +failed: + + if (doctype != NULL && doctype->public_id.data != NULL) { + lxb_dom_document_destroy_text(document, doctype->public_id.data); + } + + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_ERR; + } + + return NULL; +} + +bool +lxb_dom_document_type_valid_name(const lxb_char_t *name, size_t length) +{ + lxb_char_t c; + const lxb_char_t *end; + + if (name == NULL || length == 0) { + return false; + } + + end = name + length; + + while (name < end) { + c = *name++; + /* + * U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE, + * or U+0000 NULL, or U+003E (>) + */ + if (c == 0x09 || c == 0x0A || c == 0x0C || c == 0x0D || c == 0x20 + || c == 0x00 || c == 0x3E) + { + return false; + } + } + + return true; +} + /* * No inline functions for ABI. */ diff --git a/ext/lexbor/lexbor/dom/interfaces/document_type.h b/ext/lexbor/lexbor/dom/interfaces/document_type.h index 366aaba409ac..c7a1960af668 100644 --- a/ext/lexbor/lexbor/dom/interfaces/document_type.h +++ b/ext/lexbor/lexbor/dom/interfaces/document_type.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -37,6 +37,34 @@ lxb_dom_document_type_interface_clone(lxb_dom_document_t *document, LXB_API lxb_dom_document_type_t * lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type); +/* + * Create DocumentType by specification. + * + * https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype + * + * @param[in] lxb_dom_document_t *. Not NULL. + * @param[in] const lxb_char_t *. Name. May be NULL, but then the return value + * will be NULL and an exception code will be recorded. + * @param[in] size_t. Length of name. May be 0, but then the return value + * will be NULL and an exception code will be recorded. + * @param[in] const lxb_char_t *. PublicID. Can be NULL. + * @param[in] size_t. Length of PublicID. Can be 0. + * @param[in] const lxb_char_t *. SystemID. Can be NULL. + * @param[in] size_t. Length of SystemID. Can be 0. + * @param[out] lxb_dom_exception_code_t. Can be NULL. If the variable is passed, + * the code will definitely be assigned. LXB_DOM_EXCEPTION_OK + * if successful. + * + * @return lxb_dom_document_type_t * if successful, otherwise NULL. + */ +LXB_API lxb_dom_document_type_t * +lxb_dom_document_type_create(lxb_dom_document_t *document, + const lxb_char_t *name, size_t name_len, + const lxb_char_t *pub, size_t pub_len, + const lxb_char_t *sys, size_t sys_len, + lxb_dom_exception_code_t *code); +LXB_API bool +lxb_dom_document_type_valid_name(const lxb_char_t *ame, size_t name_len); /* * Inline functions diff --git a/ext/lexbor/lexbor/dom/interfaces/element.c b/ext/lexbor/lexbor/dom/interfaces/element.c index 09d9736e5d8c..90d707d078bb 100644 --- a/ext/lexbor/lexbor/dom/interfaces/element.c +++ b/ext/lexbor/lexbor/dom/interfaces/element.c @@ -581,6 +581,18 @@ lxb_dom_element_is_set(lxb_dom_element_t *element, return LXB_STATUS_OK; } +lxb_dom_element_t * +lxb_dom_element_by_id(lxb_dom_element_t *root, + const lxb_char_t *qualified_name, size_t len) +{ + lxb_dom_node_t *node; + + node = lxb_dom_node_by_id(lxb_dom_interface_node(root), + qualified_name, len); + + return lxb_dom_interface_element(node); +} + lxb_status_t lxb_dom_elements_by_tag_name(lxb_dom_element_t *root, lxb_dom_collection_t *collection, diff --git a/ext/lexbor/lexbor/dom/interfaces/element.h b/ext/lexbor/lexbor/dom/interfaces/element.h index dd661d439cce..50d814fd3765 100644 --- a/ext/lexbor/lexbor/dom/interfaces/element.h +++ b/ext/lexbor/lexbor/dom/interfaces/element.h @@ -135,6 +135,10 @@ LXB_API lxb_status_t lxb_dom_element_is_set(lxb_dom_element_t *element, const lxb_char_t *is, size_t is_len); +LXB_API lxb_dom_element_t * +lxb_dom_element_by_id(lxb_dom_element_t *root, + const lxb_char_t *qualified_name, size_t len); + LXB_API lxb_status_t lxb_dom_elements_by_tag_name(lxb_dom_element_t *root, lxb_dom_collection_t *collection, diff --git a/ext/lexbor/lexbor/dom/interfaces/node.c b/ext/lexbor/lexbor/dom/interfaces/node.c index a588ed388e48..f2bbaa391e39 100644 --- a/ext/lexbor/lexbor/dom/interfaces/node.c +++ b/ext/lexbor/lexbor/dom/interfaces/node.c @@ -10,6 +10,7 @@ #include "lexbor/dom/interfaces/document_type.h" #include "lexbor/dom/interfaces/element.h" #include "lexbor/dom/interfaces/processing_instruction.h" +#include "lexbor/dom/interfaces/shadow_root.h" typedef struct lxb_dom_node_cb_ctx lxb_dom_node_cb_ctx_t; @@ -29,6 +30,13 @@ struct lxb_dom_node_cb_ctx { size_t value_length; }; +typedef struct { + lxb_dom_node_t *node; + const lxb_char_t *value; + size_t length; +} +lxb_dom_node_id_cb_ctx_t; + LXB_API lxb_dom_attr_data_t * lxb_dom_attr_local_name_append(lexbor_hash_t *hash, @@ -44,6 +52,9 @@ lxb_ns_append(lexbor_hash_t *hash, const lxb_char_t *link, size_t length); static lexbor_action_t lxb_dom_node_by_tag_name_cb(lxb_dom_node_t *node, void *ctx); +static lexbor_action_t +lxb_dom_node_by_id_cb(lxb_dom_node_t *node, void *ctx); + static lexbor_action_t lxb_dom_node_by_tag_name_cb_all(lxb_dom_node_t *node, void *ctx); @@ -443,6 +454,373 @@ lxb_dom_node_insert_after(lxb_dom_node_t *to, lxb_dom_node_t *node) } } +lxb_dom_exception_code_t +lxb_dom_node_pre_insert_validity(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + size_t count; + lxb_dom_node_t *tmp; + + /* + * If parent is not a Document, DocumentFragment, or Element node, then + * throw a "HierarchyRequestError" DOMException. + */ + if (parent == NULL) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + switch (parent->type) { + case LXB_DOM_NODE_TYPE_ELEMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + break; + + default: + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + if (lxb_dom_node_host_including_inclusive_ancestor(node, parent)) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + /* + * If child is non-null and its parent is not parent, + * then throw a "NotFoundError" DOMException. + */ + if (child != NULL && parent != child->parent) { + return LXB_DOM_EXCEPTION_NOT_FOUND_ERR; + } + + /* + * If node is not a DocumentFragment, DocumentType, Element, + * or CharacterData node, then throw a "HierarchyRequestError" DOMException. + */ + if (node == NULL) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + switch (parent->type) { + case LXB_DOM_NODE_TYPE_ELEMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE: + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + case LXB_DOM_NODE_TYPE_CHARACTER_DATA: + case LXB_DOM_NODE_TYPE_TEXT: + break; + + default: + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + /* + * If either node is a Text node and parent is a document, or node is + * a doctype and parent is not a document, then throw + * a "HierarchyRequestError" DOMException. + */ + if ((node->type == LXB_DOM_NODE_TYPE_TEXT + && parent->type == LXB_DOM_NODE_TYPE_DOCUMENT) + || (node->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE + && parent->type != LXB_DOM_NODE_TYPE_DOCUMENT)) + { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + if (parent->type != LXB_DOM_NODE_TYPE_DOCUMENT) { + return LXB_DOM_EXCEPTION_OK; + } + + switch (node->type) { + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + tmp = node->first_child; + + if (tmp == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + count = 0; + + do { + if (tmp->type == LXB_DOM_NODE_TYPE_TEXT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + else if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + count += 1; + + if (count > 1) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + } + + tmp = tmp->next; + } + while (tmp != NULL); + + if (count != 1) { + return LXB_DOM_EXCEPTION_OK; + } + + /* Fall Through. */ + + case LXB_DOM_NODE_TYPE_ELEMENT: + tmp = parent->first_child; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + if (child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + if (child->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = child->next; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + break; + + case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE: + tmp = parent->first_child; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + else if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT + && child == NULL) + { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + if (child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + tmp = child->prev; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->prev; + } + + break; + + default: + break; + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_pre_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + lxb_dom_exception_code_t ex_code; + + ex_code = lxb_dom_node_pre_insert_validity(parent, node, child); + if (ex_code != LXB_DOM_EXCEPTION_OK) { + return ex_code; + } + + if (child == node) { + child = node->next; + } + + return lxb_dom_node_insert(parent, node, child, false); +} + +lxb_inline lxb_dom_exception_code_t +lxb_dom_node_insert_node(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers) +{ + lxb_dom_exception_code_t code; + + code = lxb_dom_node_adopt(node); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + if (child == NULL) { + lxb_dom_node_insert_child(parent, node); + } + else { + lxb_dom_node_insert_before(child, node); + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers) +{ + lxb_dom_node_t *tmp, *next; + lxb_dom_exception_code_t code; + + if (node->type == LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + if (node->first_child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + } + + /* TODO: live range. */ + + if (node->type != LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + return lxb_dom_node_insert_node(parent, node, child, + suppress_observers); + } + + tmp = node->first_child; + + while (tmp != NULL) { + next = tmp->next; + + code = lxb_dom_node_insert_node(parent, tmp, child, + suppress_observers); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + tmp = next; + } + + /* TODO: Shadow and queue a tree mutation record. */ + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_insert_before_spec(lxb_dom_node_t *dst, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + return lxb_dom_node_pre_insert(dst, node, child); +} + +lxb_dom_exception_code_t +lxb_dom_node_append_child(lxb_dom_node_t *parent, lxb_dom_node_t *node) +{ + return lxb_dom_node_pre_insert(parent, node, NULL); +} + +lxb_dom_exception_code_t +lxb_dom_node_remove_child(lxb_dom_node_t *parent, lxb_dom_node_t *child) +{ + if (parent != child->parent) { + return LXB_DOM_EXCEPTION_NOT_FOUND_ERR; + } + + return lxb_dom_node_remove_spec(child, false); +} + +lxb_dom_exception_code_t +lxb_dom_node_replace_child(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + lxb_dom_node_t *tmp, *next; + lxb_dom_node_t *before; + lxb_dom_exception_code_t code; + + code = lxb_dom_node_pre_insert_validity(parent, node, child); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + before = child->prev; + if (before == NULL) { + before = child->next; + } + + if (child->parent != NULL) { + code = lxb_dom_node_remove_spec(child, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + } + + if (node->type != LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + return lxb_dom_node_insert_node(parent, node, before, true); + } + + tmp = node->first_child; + + while (tmp != NULL) { + next = tmp->next; + + code = lxb_dom_node_insert_node(parent, tmp, before, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + tmp = next; + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_replace_all_spec(lxb_dom_node_t *parent, lxb_dom_node_t *node) +{ + lxb_dom_node_t *child, *next; + lxb_dom_exception_code_t code; + + child = parent->first_child; + + while (child != NULL) { + next = child->next; + + code = lxb_dom_node_remove_spec(child, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + child = next; + } + + return lxb_dom_node_append_child(parent, node); +} + +lxb_dom_exception_code_t +lxb_dom_node_remove_spec(lxb_dom_node_t *node, bool suppress_observers) +{ + if (node->parent == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + /* TODO: 3. Run the live range pre-remove steps, given node. */ + + /* + * TODO: For each NodeIterator object iterator whose root’s node document + * is node’s node document, run the NodeIterator pre-remove steps given + * node and iterator. + */ + + lxb_dom_node_remove(node); + + /* TODO: finish everything else. */ + + return LXB_DOM_EXCEPTION_OK; +} + void lxb_dom_node_remove_wo_events(lxb_dom_node_t *node) { @@ -617,6 +995,52 @@ lxb_dom_node_prepare_by(lxb_dom_document_t *document, return LXB_STATUS_OK; } +lxb_dom_node_t * +lxb_dom_node_by_id(lxb_dom_node_t *root, + const lxb_char_t *qualified_name, size_t len) +{ + lxb_dom_node_id_cb_ctx_t ctx; + + ctx.node = NULL; + ctx.value = qualified_name; + ctx.length = len; + + lxb_dom_node_simple_walk(root, lxb_dom_node_by_id_cb, &ctx); + + return ctx.node; +} + +static lexbor_action_t +lxb_dom_node_by_id_cb(lxb_dom_node_t *node, void *ctx) +{ + lxb_dom_node_id_cb_ctx_t *context; + const lxb_dom_attr_t *attr_id; + + if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) { + return LEXBOR_ACTION_OK; + } + + context = ctx; + attr_id = lxb_dom_interface_element(node)->attr_id; + + if (attr_id == NULL + || attr_id->value == NULL + || attr_id->value->length != context->length) + { + return LEXBOR_ACTION_OK; + } + + const lxb_char_t *data = attr_id->value->data; + size_t length = attr_id->value->length; + + if (lexbor_str_data_ncmp(context->value, data, length)) { + context->node = node; + return LEXBOR_ACTION_STOP; + } + + return LEXBOR_ACTION_OK; +} + lxb_status_t lxb_dom_node_by_tag_name(lxb_dom_node_t *root, lxb_dom_collection_t *collection, @@ -1278,6 +1702,47 @@ lxb_dom_node_is_empty(const lxb_dom_node_t *root) return true; } +bool +lxb_dom_node_host_including_inclusive_ancestor(const lxb_dom_node_t *node, + const lxb_dom_node_t *parent) +{ + const lxb_dom_shadow_root_t *root; + + while (parent != NULL) { + if (parent == node) { + return true; + } + + if (parent->type == LXB_DOM_NODE_TYPE_SHADOW_ROOT) { + root = lxb_dom_interface_shadow_root(parent); + parent = &root->host->node; + + continue; + } + + parent = parent->parent; + } + + return false; +} + +lxb_dom_exception_code_t +lxb_dom_node_adopt(lxb_dom_node_t *node) +{ + lxb_dom_exception_code_t code; + + if (node->parent != NULL) { + code = lxb_dom_node_remove_spec(node, false); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + } + + /* TODO: If document is not oldDocument steps. */ + + return LXB_DOM_EXCEPTION_OK; +} + lxb_tag_id_t lxb_dom_node_tag_id_noi(lxb_dom_node_t *node) { @@ -1313,3 +1778,9 @@ lxb_dom_node_last_child_noi(lxb_dom_node_t *node) { return lxb_dom_node_last_child(node); } + +lxb_dom_node_type_t +lxb_dom_node_type_noi(lxb_dom_node_t *node) +{ + return lxb_dom_node_type(node); +} diff --git a/ext/lexbor/lexbor/dom/interfaces/node.h b/ext/lexbor/lexbor/dom/interfaces/node.h index b5d2c5069f0d..b95373c51952 100644 --- a/ext/lexbor/lexbor/dom/interfaces/node.h +++ b/ext/lexbor/lexbor/dom/interfaces/node.h @@ -13,6 +13,7 @@ extern "C" { #include "lexbor/dom/interface.h" #include "lexbor/dom/collection.h" +#include "lexbor/dom/exception.h" #include "lexbor/dom/interfaces/event_target.h" @@ -59,7 +60,9 @@ typedef enum { LXB_DOM_NODE_TYPE_DOCUMENT_TYPE = 0x0A, LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT = 0x0B, LXB_DOM_NODE_TYPE_NOTATION = 0x0C, // historical - LXB_DOM_NODE_TYPE_LAST_ENTRY = 0x0D + LXB_DOM_NODE_TYPE_CHARACTER_DATA, + LXB_DOM_NODE_TYPE_SHADOW_ROOT, + LXB_DOM_NODE_TYPE_LAST_ENTRY } lxb_dom_node_type_t; @@ -135,12 +138,106 @@ lxb_dom_node_insert_after_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node); LXB_API void lxb_dom_node_insert_after(lxb_dom_node_t *to, lxb_dom_node_t *node); +LXB_API lxb_dom_exception_code_t +lxb_dom_node_pre_insert_validity(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_pre_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers); + +/* + * Add a node as a child. + * + * Function according to specification. Node.appendChild(node). + * + * The function not only adds a node as a child, but also validates + * the possibility of adding it. + * For example, the lxb_dom_node_insert_child() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where to add. Not NULL. + * @param[in] lxb_dom_node_t *. Who to add. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_append_child(lxb_dom_node_t *parent, lxb_dom_node_t *node); + +/* + * Insert before child. + * + * Function according to specification. Node.insertBefore(node, child). + * + * The function not only insert a node as a child, but also validates + * the possibility of adding it. + * For example, the lxb_dom_node_insert_before() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where to add. Not NULL. + * @param[in] lxb_dom_node_t *. Who to add. Not NULL. + * @param[in] lxb_dom_node_t *. The child before need to insert. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_insert_before_spec(lxb_dom_node_t *dst, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_remove_spec(lxb_dom_node_t *node, bool suppress_observers); + LXB_API void lxb_dom_node_remove_wo_events(lxb_dom_node_t *node); LXB_API void lxb_dom_node_remove(lxb_dom_node_t *node); +/* + * Removing a node. + * + * Function according to specification. Node.removeChild(node). + * + * The function not only removing a node, but also validates the possibility + * of adding it. + * For example, the lxb_dom_node_remove() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where remove. Not NULL. + * @param[in] lxb_dom_node_t *. Who remove. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_remove_child(lxb_dom_node_t *parent, lxb_dom_node_t *child); + +/* + * The function replaces the child with a node. + * + * Function according to specification. Node.replaceChild(node, child). + * + * The function not only replace a node, but also validates the possibility + * of adding it. + * For example, the lxb_dom_node_replace_all() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where replace. Not NULL. + * @param[in] lxb_dom_node_t *. Who replace. Not NULL. + * @param[in] lxb_dom_node_t *. Replaceable child. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_replace_child(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_replace_all_spec(lxb_dom_node_t *parent, lxb_dom_node_t *node); + LXB_API lxb_status_t lxb_dom_node_replace_all(lxb_dom_node_t *parent, lxb_dom_node_t *node); @@ -148,6 +245,10 @@ LXB_API void lxb_dom_node_simple_walk(lxb_dom_node_t *root, lxb_dom_node_simple_walker_f walker_cb, void *ctx); +LXB_API lxb_dom_node_t * +lxb_dom_node_by_id(lxb_dom_node_t *root, + const lxb_char_t *qualified_name, size_t len); + LXB_API lxb_status_t lxb_dom_node_by_tag_name(lxb_dom_node_t *root, lxb_dom_collection_t *collection, const lxb_char_t *qualified_name, size_t len); @@ -193,6 +294,12 @@ lxb_dom_node_text_content_set(lxb_dom_node_t *node, LXB_API bool lxb_dom_node_is_empty(const lxb_dom_node_t *root); +LXB_API bool +lxb_dom_node_host_including_inclusive_ancestor(const lxb_dom_node_t *node, + const lxb_dom_node_t *parent); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_adopt(lxb_dom_node_t *node); /* * Inline functions @@ -233,6 +340,12 @@ lxb_dom_node_last_child(lxb_dom_node_t *node) return node->last_child; } +lxb_inline lxb_dom_node_type_t +lxb_dom_node_type(lxb_dom_node_t *node) +{ + return node->type; +} + /* * No inline functions for ABI. */ @@ -254,6 +367,9 @@ lxb_dom_node_first_child_noi(lxb_dom_node_t *node); LXB_API lxb_dom_node_t * lxb_dom_node_last_child_noi(lxb_dom_node_t *node); +LXB_API lxb_dom_node_type_t +lxb_dom_node_type_noi(lxb_dom_node_t *node); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/dom/interfaces/shadow_root.c b/ext/lexbor/lexbor/dom/interfaces/shadow_root.c index a7145bcec0d8..e2c332d58b28 100644 --- a/ext/lexbor/lexbor/dom/interfaces/shadow_root.c +++ b/ext/lexbor/lexbor/dom/interfaces/shadow_root.c @@ -22,7 +22,7 @@ lxb_dom_shadow_root_interface_create(lxb_dom_document_t *document) lxb_dom_node_t *node = lxb_dom_interface_node(element); node->owner_document = lxb_dom_document_owner(document); - node->type = LXB_DOM_NODE_TYPE_UNDEF; + node->type = LXB_DOM_NODE_TYPE_SHADOW_ROOT; return element; } diff --git a/ext/lexbor/lexbor/encoding/base.h b/ext/lexbor/lexbor/encoding/base.h index 88d74cc9bf8f..459287df3832 100644 --- a/ext/lexbor/lexbor/encoding/base.h +++ b/ext/lexbor/lexbor/encoding/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_ENCODING_VERSION_MAJOR 2 -#define LXB_ENCODING_VERSION_MINOR 2 +#define LXB_ENCODING_VERSION_MINOR 3 #define LXB_ENCODING_VERSION_PATCH 0 #define LXB_ENCODING_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/encoding/encode.c b/ext/lexbor/lexbor/encoding/encode.c index 4377fb31f58a..f9a4f9f8effb 100644 --- a/ext/lexbor/lexbor/encoding/encode.c +++ b/ext/lexbor/lexbor/encoding/encode.c @@ -111,6 +111,122 @@ return 1 +lxb_inline uint16_t +lxb_encoding_multi_big5_index(lxb_codepoint_t cp) +{ + if (cp > 0x2F8A7) { + return UINT16_MAX; + } + + if (cp < 65518) { + if (cp >= 167 && cp < 1106) { + return lxb_encoding_multi_big5_167_1106_map[cp - 167]; + } + else if (cp >= 8211) { + if (cp < 40882) { + return lxb_encoding_multi_big5_8211_40882_map[cp - 8211]; + } + else if (cp >= 64012) { + return lxb_encoding_multi_big5_64012_65518_map[cp - 64012]; + } + } + } + else if (cp >= 131210) { + if (cp < 172369) { + return lxb_encoding_multi_big5_131210_172369_map[cp - 131210]; + } + else if (cp >= 194708) { + if (cp < 194727) { + return lxb_encoding_multi_big5_194708_194727_map[cp - 194708]; + } + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_euc_kr_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE7) { + return UINT16_MAX; + } + + if (cp < 13278) { + if (cp >= 161 && cp < 1106) { + return lxb_encoding_multi_euc_kr_161_1106_map[cp - 161]; + } + else if (cp >= 8213) { + return lxb_encoding_multi_euc_kr_8213_13278_map[cp - 8213]; + } + } + else if (cp >= 19968) { + if (cp < 55204) { + return lxb_encoding_multi_euc_kr_19968_55204_map[cp - 19968]; + } + else if (cp >= 63744) { + if (cp < 65511) { + return lxb_encoding_multi_euc_kr_63744_65511_map[cp - 63744]; + } + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_gb18030_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE6) { + return UINT16_MAX; + } + + if (cp < 40892) { + if (cp >= 164 && cp < 1106) { + return lxb_encoding_multi_gb18030_164_1106_map[cp - 164]; + } + else if (cp >= 7743) { + return lxb_encoding_multi_gb18030_7743_40892_map[cp - 7743]; + } + } + else if (cp >= 57344) { + if (cp < 65510) { + return lxb_encoding_multi_gb18030_57344_65510_map[cp - 57344]; + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_jis0208_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE6) { + return UINT16_MAX; + } + + if (cp < 13262) { + if (cp >= 167 && cp < 1106) { + return lxb_encoding_multi_jis0208_167_1106_map[cp - 167]; + } + else if (cp >= 8208) { + return lxb_encoding_multi_jis0208_8208_13262_map[cp - 8208]; + } + } + else if (cp >= 19968) { + if (cp < 40865) { + return lxb_encoding_multi_jis0208_19968_40865_map[cp - 19968]; + } + else if (cp >= 63785) { + if (cp < 65510) { + return lxb_encoding_multi_jis0208_63785_65510_map[cp - 63785]; + } + } + } + + return UINT16_MAX; +} + lxb_status_t lxb_encoding_encode_default(lxb_encoding_encode_t *ctx, const lxb_codepoint_t **cps, const lxb_codepoint_t *end) @@ -327,10 +443,10 @@ lxb_encoding_encode_iso_2022_jp(lxb_encoding_encode_t *ctx, const lxb_codepoint_ unsigned state; lxb_codepoint_t cp; - size = 0; state = ctx->state; for (; *cps < end; (*cps)++) { + size = 0; cp = **cps; begin: diff --git a/ext/lexbor/lexbor/encoding/encoding.c b/ext/lexbor/lexbor/encoding/encoding.c index 19d3a1474688..2a43f0fd70a2 100644 --- a/ext/lexbor/lexbor/encoding/encoding.c +++ b/ext/lexbor/lexbor/encoding/encoding.c @@ -55,6 +55,74 @@ lxb_encoding_data_by_pre_name(const lxb_char_t *name, size_t length) return entry->value; } +lxb_encoding_t +lxb_encoding_prescan_validate(const lxb_char_t *name, size_t length) +{ + const lxb_encoding_data_t *data; + + data = lxb_encoding_data_by_pre_name(name, length); + if (data == NULL) { + return LXB_ENCODING_DEFAULT; + } + + if (data->encoding == LXB_ENCODING_UTF_16BE + || data->encoding == LXB_ENCODING_UTF_16LE) + { + return LXB_ENCODING_UTF_8; + } + + if (data->encoding == LXB_ENCODING_X_USER_DEFINED) { + return LXB_ENCODING_WINDOWS_1252; + } + + return data->encoding; +} + +const lxb_encoding_data_t * +lxb_encoding_data_prescan_validate(const lxb_char_t *name, size_t length) +{ + const lxb_encoding_data_t *data; + + data = lxb_encoding_data_by_pre_name(name, length); + if (data == NULL) { + return NULL; + } + + if (data->encoding == LXB_ENCODING_UTF_16BE + || data->encoding == LXB_ENCODING_UTF_16LE) + { + return lxb_encoding_data(LXB_ENCODING_UTF_8); + } + + if (data->encoding == LXB_ENCODING_X_USER_DEFINED) { + return lxb_encoding_data(LXB_ENCODING_WINDOWS_1252); + } + + return data; +} + +lxb_encoding_t +lxb_encoding_bom_sniff(const lxb_char_t *begin, size_t length) +{ + if (length >= 3) { + if (begin[0] == 0xEF && begin[1] == 0xBB && begin[2] == 0xBF) { + return LXB_ENCODING_UTF_8; + } + } + + if (length >= 2) { + if (begin[0] == 0xFE && begin[1] == 0xFF) { + return LXB_ENCODING_UTF_16BE; + } + + if (begin[0] == 0xFF && begin[1] == 0xFE) { + return LXB_ENCODING_UTF_16LE; + } + } + + return LXB_ENCODING_DEFAULT; +} + void lxb_encoding_utf_8_skip_bom(const lxb_char_t **begin, size_t *length) { @@ -100,6 +168,54 @@ lxb_encoding_utf_16le_skip_bom(const lxb_char_t **begin, size_t *length) } } +const lxb_encoding_data_t * +lxb_encoding_data_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + if (length == 0) { + return NULL; + } + + entry = lexbor_shs_entry_get_lower_static(lxb_encoding_res_shs_entities, + name, length); + if (entry == NULL) { + return NULL; + } + + return (const lxb_encoding_data_t *) entry->value; +} + +const lxb_encoding_data_t * +lxb_encoding_data(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return &lxb_encoding_res_map[encoding]; +} + +lxb_encoding_encode_f +lxb_encoding_encode_function(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return lxb_encoding_res_map[encoding].encode; +} + +lxb_encoding_decode_f +lxb_encoding_decode_function(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return lxb_encoding_res_map[encoding].decode; +} + /* * No inline functions for ABI. */ diff --git a/ext/lexbor/lexbor/encoding/encoding.h b/ext/lexbor/lexbor/encoding/encoding.h index 7bda3ba5f56c..7e08a3687993 100644 --- a/ext/lexbor/lexbor/encoding/encoding.h +++ b/ext/lexbor/lexbor/encoding/encoding.h @@ -27,9 +27,18 @@ extern "C" { LXB_API const lxb_encoding_data_t * lxb_encoding_data_by_pre_name(const lxb_char_t *name, size_t length); +LXB_API lxb_encoding_t +lxb_encoding_prescan_validate(const lxb_char_t *name, size_t length); + +LXB_API const lxb_encoding_data_t * +lxb_encoding_data_prescan_validate(const lxb_char_t *name, size_t length); + /* * To skip BOM. */ +LXB_API lxb_encoding_t +lxb_encoding_bom_sniff(const lxb_char_t *begin, size_t length); + LXB_API void lxb_encoding_utf_8_skip_bom(const lxb_char_t **begin, size_t *length); @@ -39,6 +48,20 @@ lxb_encoding_utf_16be_skip_bom(const lxb_char_t **begin, size_t *length); LXB_API void lxb_encoding_utf_16le_skip_bom(const lxb_char_t **begin, size_t *length); +/* + * Encoding data. + */ +LXB_API const lxb_encoding_data_t * +lxb_encoding_data_by_name(const lxb_char_t *name, size_t length); + +LXB_API const lxb_encoding_data_t * +lxb_encoding_data(lxb_encoding_t encoding); + +LXB_API lxb_encoding_encode_f +lxb_encoding_encode_function(lxb_encoding_t encoding); + +LXB_API lxb_encoding_decode_f +lxb_encoding_decode_function(lxb_encoding_t encoding); /* * Inline functions @@ -305,54 +328,6 @@ lxb_encoding_decode_finish_single(lxb_encoding_decode_t *decode) /* * Encoding data. */ -lxb_inline const lxb_encoding_data_t * -lxb_encoding_data_by_name(const lxb_char_t *name, size_t length) -{ - const lexbor_shs_entry_t *entry; - - if (length == 0) { - return NULL; - } - - entry = lexbor_shs_entry_get_lower_static(lxb_encoding_res_shs_entities, - name, length); - if (entry == NULL) { - return NULL; - } - - return (const lxb_encoding_data_t *) entry->value; -} - -lxb_inline const lxb_encoding_data_t * -lxb_encoding_data(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return &lxb_encoding_res_map[encoding]; -} - -lxb_inline lxb_encoding_encode_f -lxb_encoding_encode_function(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return lxb_encoding_res_map[encoding].encode; -} - -lxb_inline lxb_encoding_decode_f -lxb_encoding_decode_function(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return lxb_encoding_res_map[encoding].decode; -} - lxb_inline lxb_status_t lxb_encoding_data_call_encode(lxb_encoding_data_t *encoding_data, lxb_encoding_encode_t *ctx, const lxb_codepoint_t **cp, const lxb_codepoint_t *end) diff --git a/ext/lexbor/lexbor/encoding/multi.c b/ext/lexbor/lexbor/encoding/multi.c index 78cd93ea82b1..2651648c5c96 100644 --- a/ext/lexbor/lexbor/encoding/multi.c +++ b/ext/lexbor/lexbor/encoding/multi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/encoding/multi.h b/ext/lexbor/lexbor/encoding/multi.h index 4e6da7b4728b..a4c5def5ba6a 100644 --- a/ext/lexbor/lexbor/encoding/multi.h +++ b/ext/lexbor/lexbor/encoding/multi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -19,7 +19,7 @@ extern "C" { #include "lexbor/encoding/base.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_big5_map[19782]; LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_euc_kr_map[23750]; LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_gb18030_map[23940]; @@ -53,161 +53,7 @@ LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_167_1106_map[939]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_8208_13262_map[5054]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_19968_40865_map[20897]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_63785_65510_map[1725]; - -lxb_inline uint16_t -lxb_encoding_multi_big5_index(lxb_codepoint_t cp) -{ - if (cp > 0x2F8A7) { - return UINT16_MAX; - } - - if (cp < 65518) { - if (cp >= 167 && cp < 1106) { - return lxb_encoding_multi_big5_167_1106_map[cp - 167]; - } - else if (cp >= 8211) { - if (cp < 40882) { - return lxb_encoding_multi_big5_8211_40882_map[cp - 8211]; - } - else if (cp >= 64012) { - return lxb_encoding_multi_big5_64012_65518_map[cp - 64012]; - } - } - } - else if (cp >= 131210) { - if (cp < 172369) { - return lxb_encoding_multi_big5_131210_172369_map[cp - 131210]; - } - else if (cp >= 194708) { - if (cp < 194727) { - return lxb_encoding_multi_big5_194708_194727_map[cp - 194708]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_euc_kr_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE7) { - return UINT16_MAX; - } - - if (cp < 13278) { - if (cp >= 161 && cp < 1106) { - return lxb_encoding_multi_euc_kr_161_1106_map[cp - 161]; - } - else if (cp >= 8213) { - return lxb_encoding_multi_euc_kr_8213_13278_map[cp - 8213]; - } - } - else if (cp >= 19968) { - if (cp < 55204) { - return lxb_encoding_multi_euc_kr_19968_55204_map[cp - 19968]; - } - else if (cp >= 63744) { - if (cp < 65511) { - return lxb_encoding_multi_euc_kr_63744_65511_map[cp - 63744]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_gb18030_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE6) { - return UINT16_MAX; - } - - if (cp < 40892) { - if (cp >= 164 && cp < 1106) { - return lxb_encoding_multi_gb18030_164_1106_map[cp - 164]; - } - else if (cp >= 7743) { - return lxb_encoding_multi_gb18030_7743_40892_map[cp - 7743]; - } - } - else if (cp >= 57344) { - if (cp < 65510) { - return lxb_encoding_multi_gb18030_57344_65510_map[cp - 57344]; - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_iso_2022_jp_katakana_index(lxb_codepoint_t cp) -{ - if (cp >= 12289 && cp < 12541) { - return lxb_encoding_multi_iso_2022_jp_katakana_12289_12541_map[cp - 12289]; - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_jis0212_index(lxb_codepoint_t cp) -{ - if (cp > 0xFF5F) { - return UINT16_MAX; - } - - if (cp < 8483) { - if (cp >= 161 && cp < 1120) { - return lxb_encoding_multi_jis0212_161_1120_map[cp - 161]; - } - else if (cp >= 8470) { - return lxb_encoding_multi_jis0212_8470_8483_map[cp - 8470]; - } - } - else if (cp >= 19970) { - if (cp < 40870) { - return lxb_encoding_multi_jis0212_19970_40870_map[cp - 19970]; - } - else if (cp >= 65374) { - if (cp < 65375) { - return lxb_encoding_multi_jis0212_65374_65375_map[cp - 65374]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_jis0208_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE6) { - return UINT16_MAX; - } - - if (cp < 13262) { - if (cp >= 167 && cp < 1106) { - return lxb_encoding_multi_jis0208_167_1106_map[cp - 167]; - } - else if (cp >= 8208) { - return lxb_encoding_multi_jis0208_8208_13262_map[cp - 8208]; - } - } - else if (cp >= 19968) { - if (cp < 40865) { - return lxb_encoding_multi_jis0208_19968_40865_map[cp - 19968]; - } - else if (cp >= 63785) { - if (cp < 65510) { - return lxb_encoding_multi_jis0208_63785_65510_map[cp - 63785]; - } - } - } - - return UINT16_MAX; -} +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/encoding/range.h b/ext/lexbor/lexbor/encoding/range.h index 18b331034423..ed9833d1cce9 100644 --- a/ext/lexbor/lexbor/encoding/range.h +++ b/ext/lexbor/lexbor/encoding/range.h @@ -23,8 +23,9 @@ extern "C" { #define LXB_ENCODING_RANGE_INDEX_GB18030_SIZE 207 - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_range_index_t lxb_encoding_range_index_gb18030[207]; +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/encoding/res.h b/ext/lexbor/lexbor/encoding/res.h index 46a9f91ae9a9..25334ebd27cf 100644 --- a/ext/lexbor/lexbor/encoding/res.h +++ b/ext/lexbor/lexbor/encoding/res.h @@ -22,10 +22,10 @@ extern "C" { #include "lexbor/encoding/base.h" #include "lexbor/core/shs.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_data_t lxb_encoding_res_map[LXB_ENCODING_LAST_ENTRY]; LXB_EXTERN const lexbor_shs_entry_t lxb_encoding_res_shs_entities[220]; - +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/encoding/single.h b/ext/lexbor/lexbor/encoding/single.h index 906279bf33e7..c2a4271ac90c 100644 --- a/ext/lexbor/lexbor/encoding/single.h +++ b/ext/lexbor/lexbor/encoding/single.h @@ -51,7 +51,7 @@ extern "C" { #define LXB_ENCODING_SINGLE_HASH_WINDOWS_874_SIZE 359 #define LXB_ENCODING_SINGLE_HASH_X_MAC_CYRILLIC_SIZE 373 - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_ibm866[128]; LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_iso_8859_10[128]; LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_iso_8859_13[128]; @@ -107,6 +107,7 @@ LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_1257[356]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_1258[406]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_874[360]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_x_mac_cyrillic[374]; +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/html/base.h b/ext/lexbor/lexbor/html/base.h index a701dc35c680..570222c6de5e 100644 --- a/ext/lexbor/lexbor/html/base.h +++ b/ext/lexbor/lexbor/html/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_HTML_VERSION_MAJOR 2 -#define LXB_HTML_VERSION_MINOR 6 +#define LXB_HTML_VERSION_MINOR 8 #define LXB_HTML_VERSION_PATCH 0 #define LXB_HTML_VERSION_STRING LEXBOR_STRINGIZE(LXB_HTML_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/html/encoding.c b/ext/lexbor/lexbor/html/encoding.c index 5368400dab84..857661246b5c 100644 --- a/ext/lexbor/lexbor/html/encoding.c +++ b/ext/lexbor/lexbor/html/encoding.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,6 +9,31 @@ #include "lexbor/core/str.h" +typedef struct { + lexbor_str_t alias; + lexbor_str_t name; +} +lxb_html_encoding_name_t; + +static const lxb_html_encoding_name_t lxb_html_encoding_names[] = { + /* UTF-16BE */ + { lexbor_str("unicodefffe"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16be"), lexbor_str("UTF-8") }, + + /* UTF-16LE */ + { lexbor_str("csunicode"), lexbor_str("UTF-8") }, + { lexbor_str("iso-10646-ucs-2"), lexbor_str("UTF-8") }, + { lexbor_str("ucs-2"), lexbor_str("UTF-8") }, + { lexbor_str("unicode"), lexbor_str("UTF-8") }, + { lexbor_str("unicodefeff"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16le"), lexbor_str("UTF-8") }, + + /* x-user-defined */ + { lexbor_str("x-user-defined"), lexbor_str("windows-1252") } +}; + + static const lxb_char_t * lxb_html_encoding_meta(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end); @@ -99,6 +124,73 @@ lxb_html_encoding_destroy(lxb_html_encoding_t *em, bool self_destroy) return em; } +const lxb_char_t * +lxb_html_encoding_prescan(lxb_html_encoding_t *em, const lxb_char_t *data, + const lxb_char_t *end, size_t *out_length) +{ + size_t len, length; + lxb_status_t status; + lxb_html_encoding_entry_t *entry; + const lxb_html_encoding_name_t *name; + + static const lexbor_str_t lxb_html_encoding_utf_16le = lexbor_str("UTF-16LE"); + static const lexbor_str_t lxb_html_encoding_utf_16be = lexbor_str("UTF-16BE"); + + len = end - data; + + /* Prescan for UTF-16 XML declarations: If position points to. */ + if (len >= 6) { + if (data[0] == 0x3C && data[1] == 0x00 && data[2] == 0x3F + && data[3] == 0x00 && data[4] == 0x78 && data[5] == 0x00) + { + *out_length = lxb_html_encoding_utf_16le.length; + return lxb_html_encoding_utf_16le.data; + } + + if (data[0] == 0x00 && data[1] == 0x3C && data[2] == 0x00 + && data[3] == 0x3F && data[4] == 0x00 && data[5] == 0x78) + { + *out_length = lxb_html_encoding_utf_16be.length; + return lxb_html_encoding_utf_16be.data; + } + } + + status = lxb_html_encoding_determine(em, data, end); + if (status != LXB_STATUS_OK) { + goto EMPTY; + } + + if (lxb_html_encoding_meta_length(em) == 0) { + goto EMPTY; + } + + entry = lxb_html_encoding_meta_entry(em, 0); + len = entry->end - entry->name; + length = sizeof(lxb_html_encoding_names) / sizeof(lxb_html_encoding_name_t); + + for (size_t i = 0; i < length; i++) { + name = &lxb_html_encoding_names[i]; + + if (len == name->alias.length + && lexbor_str_data_ncasecmp(entry->name, name->alias.data, + name->alias.length)) + { + *out_length = lxb_html_encoding_names[i].name.length; + return lxb_html_encoding_names[i].name.data; + } + } + + *out_length = entry->end - entry->name; + + return entry->name; + +EMPTY: + + *out_length = 0; + + return NULL; +} + lxb_status_t lxb_html_encoding_determine(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end) @@ -381,12 +473,12 @@ lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, for (; data < end; data++) { if (*data == **name_end) { - break; + *name_end = data; + goto done; } } - *name_end = data; - goto done; + return NULL; } name = data; diff --git a/ext/lexbor/lexbor/html/encoding.h b/ext/lexbor/lexbor/html/encoding.h index ec65778f715e..ad5a6198f945 100644 --- a/ext/lexbor/lexbor/html/encoding.h +++ b/ext/lexbor/lexbor/html/encoding.h @@ -1,5 +1,14 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov + * + * Functions for detecting encoding in an HTML byte stream. + * + * The HTML parser accepts only UTF-8 input. The detected encoding can be used + * with the Encoding module to convert the original byte stream from its + * encoding to UTF-8 before passing it to the parser. + * + * By specification: + * https://html.spec.whatwg.org/#determining-the-character-encoding * * Author: Alexander Borisov */ @@ -12,12 +21,13 @@ extern "C" { #endif #include "lexbor/html/base.h" - #include "lexbor/core/array_obj.h" typedef struct { + /* Pointer to the beginning of the encoding name in the original data. */ const lxb_char_t *name; + /* Pointer to the end of the encoding name in the original data. */ const lxb_char_t *end; } lxb_html_encoding_entry_t; @@ -29,17 +39,101 @@ typedef struct { lxb_html_encoding_t; +/* + * Initialization of the lxb_html_encoding_t object. + * + * The object can be allocated on the stack or created using + * lxb_html_encoding_create() function. + * + * @param[in] lxb_html_encoding_t * + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_html_encoding_init(lxb_html_encoding_t *em); +/* + * Destruction of the lxb_html_encoding_t object. + * + * Releases internal resources of the object. + * If the object was created using lxb_html_encoding_create(), set self_destroy + * to true. + * + * @param[in] lxb_html_encoding_t * + * @param[in] If true, the object itself will be freed. + * + * @return NULL if self_destroy is true. Pointer to the object if false. + */ LXB_API lxb_html_encoding_t * lxb_html_encoding_destroy(lxb_html_encoding_t *em, bool self_destroy); +/* + * Prescan a byte stream to determine its encoding. + * + * By specification: + * https://html.spec.whatwg.org/#prescan-a-byte-stream-to-determine-its-encoding + * + * Returns the validated encoding name if found, or NULL otherwise. + * + * Important: + * The returned pointer is not guaranteed to point into the input data stream. + * It may reference an internal static string (e.g. when the found encoding name + * is matched against a known alias). Do not assume the returned pointer lies + * within the [data, end) range. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Pointer to the beginning of the data. Not NULL. + * @param[in] Pointer to the end of the data. Not NULL. + * @param[out] Length of the returned encoding name. Not NULL. + * + * @return Pointer to the encoding name, or NULL if no encoding was found. + */ +LXB_API const lxb_char_t * +lxb_html_encoding_prescan(lxb_html_encoding_t *em, const lxb_char_t *data, + const lxb_char_t *end, size_t *out_length); +/* + * Prescan a byte stream to determine its encoding. + * + * Implementation of the HTML specification algorithm for extracting encoding + * from tags. Scans raw HTML bytes looking for and + * declarations. + * + * Results can be retrieved using lxb_html_encoding_meta_entry() and + * lxb_html_encoding_meta_length() functions. + * + * Important: + * The HTML specification requires that if the determined charset is + * UTF-16BE/LE, it must be replaced with UTF-8, and if it is x-user-defined, + * it must be replaced with windows-1252. This function does not perform these + * replacements because it returns pointers to the original data (start and end + * of the found encoding name), which can be useful for developers. To get the + * validated encoding according to the specification, use the + * lxb_encoding_data_prescan_validate()/lxb_encoding_prescan_validate() + * functions from the Encoding module, or handle these cases manually. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Pointer to the beginning of the data. Not NULL. + * @param[in] Pointer to the end of the data. Not NULL. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_html_encoding_determine(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end); +/* + * Extract encoding name from a Content-Type string. + * + * Parses the value of a content attribute looking for "charset=" + * pattern. For example, from "text/html; charset=utf-8" extracts "utf-8". + * + * @param[in] Pointer to the beginning of the content string. Not NULL. + * @param[in] Pointer to the end of the content string. Not NULL. + * @param[out] Pointer to the end of the encoding name. Not NULL. + * + * @return Pointer to the beginning of the encoding name, or NULL if not found. + */ LXB_API const lxb_char_t * lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, const lxb_char_t **name_end); @@ -48,6 +142,14 @@ lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, /* * Inline functions */ + +/* + * Create an lxb_html_encoding_t object on the heap. + * + * The object must be initialized using lxb_html_encoding_init() after creation. + * + * @return Pointer to a new object, or NULL if memory allocation failed. + */ lxb_inline lxb_html_encoding_t * lxb_html_encoding_create(void) { @@ -55,6 +157,14 @@ lxb_html_encoding_create(void) sizeof(lxb_html_encoding_t)); } +/* + * Clean the lxb_html_encoding_t object for reuse. + * + * Resets internal state so the object can be used for a new prescan without + * reallocation. Does not free memory. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + */ lxb_inline void lxb_html_encoding_clean(lxb_html_encoding_t *em) { @@ -62,18 +172,45 @@ lxb_html_encoding_clean(lxb_html_encoding_t *em) lexbor_array_obj_clean(&em->result); } +/* + * Get an encoding entry from the results by index. + * + * Returns a pointer to the lxb_html_encoding_entry_t which contains pointers + * to the beginning and end of the encoding name in the original data. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Index of the entry. + * + * @return Pointer to the entry, or NULL if the index is out of bounds. + */ lxb_inline lxb_html_encoding_entry_t * lxb_html_encoding_meta_entry(lxb_html_encoding_t *em, size_t idx) { return (lxb_html_encoding_entry_t *) lexbor_array_obj_get(&em->result, idx); } +/* + * Get the number of encoding entries found. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * + * @return Number of entries in the result. + */ lxb_inline size_t lxb_html_encoding_meta_length(lxb_html_encoding_t *em) { return lexbor_array_obj_length(&em->result); } +/* + * Get the result array object directly. + * + * Returns the internal array of lxb_html_encoding_entry_t entries. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * + * @return Pointer to the lexbor_array_obj_t with results. + */ lxb_inline lexbor_array_obj_t * lxb_html_encoding_meta_result(lxb_html_encoding_t *em) { diff --git a/ext/lexbor/lexbor/html/interface.c b/ext/lexbor/lexbor/html/interface.c index 1e7156d92a41..1b2a57c813e9 100644 --- a/ext/lexbor/lexbor/html/interface.c +++ b/ext/lexbor/lexbor/html/interface.c @@ -26,30 +26,33 @@ lxb_html_interface_create(lxb_html_document_t *document, lxb_tag_id_t tag_id, lxb_ns_id_t ns) { lxb_dom_node_t *node; + lxb_dom_element_t *domel; + lxb_html_unknown_element_t *unel; if (tag_id >= LXB_TAG__LAST_ENTRY) { if (ns == LXB_NS_HTML) { - lxb_html_unknown_element_t *unel; - unel = lxb_html_unknown_element_interface_create(document); node = lxb_dom_interface_node(unel); } else if (ns == LXB_NS_SVG) { /* TODO: For this need implement SVGElement */ - lxb_dom_element_t *domel; domel = lxb_dom_element_interface_create(&document->dom_document); node = lxb_dom_interface_node(domel); } else { - lxb_dom_element_t *domel; - domel = lxb_dom_element_interface_create(&document->dom_document); node = lxb_dom_interface_node(domel); } } else { - node = lxb_html_interface_res_constructors[tag_id][ns](document); + if (ns < LXB_NS__LAST_ENTRY) { + node = lxb_html_interface_res_constructors[tag_id][ns](document); + } + else { + domel = lxb_dom_element_interface_create(&document->dom_document); + node = lxb_dom_interface_node(domel); + } } if (node == NULL) { diff --git a/ext/lexbor/lexbor/html/interface.h b/ext/lexbor/lexbor/html/interface.h index a58a9e7474d7..503bef6345ac 100644 --- a/ext/lexbor/lexbor/html/interface.h +++ b/ext/lexbor/lexbor/html/interface.h @@ -71,6 +71,7 @@ extern "C" { #define lxb_html_interface_quote(obj) ((lxb_html_quote_element_t *) (obj)) #define lxb_html_interface_script(obj) ((lxb_html_script_element_t *) (obj)) #define lxb_html_interface_select(obj) ((lxb_html_select_element_t *) (obj)) +#define lxb_html_interface_selectedcontent(obj) ((lxb_html_selectedcontent_element_t *) obj) #define lxb_html_interface_slot(obj) ((lxb_html_slot_element_t *) (obj)) #define lxb_html_interface_source(obj) ((lxb_html_source_element_t *) (obj)) #define lxb_html_interface_span(obj) ((lxb_html_span_element_t *) (obj)) @@ -146,6 +147,8 @@ typedef struct lxb_html_progress_element lxb_html_progress_element_t; typedef struct lxb_html_quote_element lxb_html_quote_element_t; typedef struct lxb_html_script_element lxb_html_script_element_t; typedef struct lxb_html_select_element lxb_html_select_element_t; +typedef struct lxb_html_selectedcontent_element lxb_html_selectedcontent_element_t; +typedef struct lxb_html_search_element lxb_html_search_element_t; typedef struct lxb_html_slot_element lxb_html_slot_element_t; typedef struct lxb_html_source_element lxb_html_source_element_t; typedef struct lxb_html_span_element lxb_html_span_element_t; diff --git a/ext/lexbor/lexbor/html/interface_res.h b/ext/lexbor/lexbor/html/interface_res.h index 980be3c7de01..8a2f765c30ff 100644 --- a/ext/lexbor/lexbor/html/interface_res.h +++ b/ext/lexbor/lexbor/html/interface_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,12 +14,10 @@ #ifndef LXB_HTML_INTERFACE_RES_H #define LXB_HTML_INTERFACE_RES_H -#endif /* LXB_HTML_INTERFACE_RES_H */ - #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -97,7 +95,9 @@ #include "lexbor/html/interfaces/progress_element.h" #include "lexbor/html/interfaces/quote_element.h" #include "lexbor/html/interfaces/script_element.h" +#include "lexbor/html/interfaces/search_element.h" #include "lexbor/html/interfaces/select_element.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" #include "lexbor/html/interfaces/slot_element.h" #include "lexbor/html/interfaces/source_element.h" #include "lexbor/html/interfaces/span_element.h" @@ -130,18 +130,6 @@ lxb_dom_element_interface_destroy_wrapper(void *interface) return lxb_dom_element_interface_destroy(interface); } -lxb_inline void * -lxb_html_unknown_element_interface_create_wrapper(void *interface) -{ - return lxb_html_unknown_element_interface_create(interface); -} - -lxb_inline void * -lxb_html_unknown_element_interface_destroy_wrapper(void *interface) -{ - return lxb_html_unknown_element_interface_destroy(interface); -} - lxb_inline void * lxb_html_element_interface_create_wrapper(void *interface) { @@ -166,6 +154,18 @@ lxb_dom_text_interface_destroy_wrapper(void *interface) return lxb_dom_text_interface_destroy(interface); } +lxb_inline void * +lxb_dom_document_interface_create_wrapper(void *interface) +{ + return lxb_dom_document_interface_create(interface); +} + +lxb_inline void * +lxb_dom_document_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_document_interface_destroy(interface); +} + lxb_inline void * lxb_html_document_interface_create_wrapper(void *interface) { @@ -214,6 +214,18 @@ lxb_html_anchor_element_interface_destroy_wrapper(void *interface) return lxb_html_anchor_element_interface_destroy(interface); } +lxb_inline void * +lxb_html_unknown_element_interface_create_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_unknown_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_destroy(interface); +} + lxb_inline void * lxb_html_area_element_interface_create_wrapper(void *interface) { @@ -826,6 +838,18 @@ lxb_html_script_element_interface_destroy_wrapper(void *interface) return lxb_html_script_element_interface_destroy(interface); } +lxb_inline void * +lxb_html_search_element_interface_create_wrapper(void *interface) +{ + return lxb_html_search_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_search_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_search_element_interface_destroy(interface); +} + lxb_inline void * lxb_html_select_element_interface_create_wrapper(void *interface) { @@ -838,6 +862,18 @@ lxb_html_select_element_interface_destroy_wrapper(void *interface) return lxb_html_select_element_interface_destroy(interface); } +lxb_inline void * +lxb_html_selectedcontent_element_interface_create_wrapper(void *interface) +{ + return lxb_html_selectedcontent_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_selectedcontent_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_selectedcontent_element_interface_destroy(interface); +} + lxb_inline void * lxb_html_slot_element_interface_create_wrapper(void *interface) { @@ -1019,15 +1055,12 @@ lxb_html_video_element_interface_destroy_wrapper(void *interface) } -#ifdef LXB_HTML_INTERFACE_RES_CONSTRUCTORS -#ifndef LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED -#define LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1037,8 +1070,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1048,52 +1081,52 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_document_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_anchor_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1103,8 +1136,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1114,8 +1147,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1125,8 +1158,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1136,8 +1169,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1147,8 +1180,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1158,8 +1191,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1169,8 +1202,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1180,8 +1213,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1191,8 +1224,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1202,8 +1235,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1213,8 +1246,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1224,8 +1257,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_area_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1235,8 +1268,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1246,8 +1279,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1257,8 +1290,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_audio_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1268,8 +1301,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_B */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1279,8 +1312,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_base_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1290,8 +1323,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1301,8 +1334,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1312,8 +1345,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1323,8 +1356,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1334,8 +1367,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1345,8 +1378,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1356,8 +1389,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1367,8 +1400,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_body_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1378,8 +1411,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_br_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1389,8 +1422,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_button_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1400,8 +1433,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_canvas_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1411,8 +1444,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_caption_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1422,8 +1455,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1433,8 +1466,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1444,8 +1477,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1455,8 +1488,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1466,8 +1499,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_COL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1477,8 +1510,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1488,8 +1521,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_data_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1499,8 +1532,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_data_list_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1510,8 +1543,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1521,8 +1554,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1532,8 +1565,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1543,8 +1576,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_details_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1554,8 +1587,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1565,8 +1598,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_dialog_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1576,8 +1609,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_directory_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1587,8 +1620,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_div_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1598,8 +1631,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_d_list_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1609,8 +1642,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_DT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1620,8 +1653,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_EM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1631,8 +1664,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_embed_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1642,8 +1675,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1653,8 +1686,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1664,8 +1697,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1675,8 +1708,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1686,8 +1719,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1697,8 +1730,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1708,8 +1741,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1719,8 +1752,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1730,8 +1763,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1741,8 +1774,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1752,8 +1785,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1763,8 +1796,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1774,8 +1807,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1785,8 +1818,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1796,8 +1829,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1807,8 +1840,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1818,8 +1851,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1829,8 +1862,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1840,8 +1873,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1851,8 +1884,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1862,8 +1895,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1873,8 +1906,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1884,8 +1917,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1895,8 +1928,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1906,8 +1939,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1917,8 +1950,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_field_set_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1928,8 +1961,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1939,8 +1972,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1950,8 +1983,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_font_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1961,8 +1994,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1972,8 +2005,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1983,8 +2016,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_form_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -1994,8 +2027,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_frame_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2005,8 +2038,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_frame_set_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2016,8 +2049,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2027,8 +2060,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2038,8 +2071,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2049,8 +2082,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2060,8 +2093,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2071,8 +2104,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2082,8 +2115,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2093,8 +2126,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_head_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2104,8 +2137,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2115,8 +2148,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2126,8 +2159,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_HR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_hr_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2137,8 +2170,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2148,8 +2181,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_I */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2159,8 +2192,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_iframe_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2170,8 +2203,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2181,8 +2214,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2192,8 +2225,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_input_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2203,8 +2236,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_INS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2214,8 +2247,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2225,8 +2258,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2236,8 +2269,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2247,8 +2280,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_label_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2258,8 +2291,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_legend_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2269,8 +2302,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_li_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2280,8 +2313,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2291,8 +2324,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_link_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2302,8 +2335,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2313,8 +2346,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2324,8 +2357,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2335,8 +2368,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_map_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2346,8 +2379,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2357,8 +2390,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_marquee_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2368,8 +2401,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2379,8 +2412,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_menu_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2390,8 +2423,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_META */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_meta_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2401,8 +2434,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_METER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_meter_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2412,8 +2445,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2423,8 +2456,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2434,8 +2467,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2445,8 +2478,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2456,8 +2489,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2467,8 +2500,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2478,8 +2511,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2489,8 +2522,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2500,8 +2533,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2511,8 +2544,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2522,8 +2555,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2533,8 +2566,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2544,8 +2577,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2555,8 +2588,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2566,8 +2599,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_object_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2577,8 +2610,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_OL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_o_list_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2588,8 +2621,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_opt_group_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2599,8 +2632,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_option_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2610,8 +2643,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_output_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2621,8 +2654,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_P */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_paragraph_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2632,8 +2665,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_param_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2643,8 +2676,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2654,8 +2687,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_picture_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2665,8 +2698,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2676,8 +2709,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2687,8 +2720,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_progress_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2698,8 +2731,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_Q */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2709,8 +2742,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2720,8 +2753,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2731,8 +2764,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2742,8 +2775,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2753,8 +2786,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2764,8 +2797,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2775,8 +2808,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_S */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2786,8 +2819,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2797,8 +2830,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_script_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2806,10 +2839,21 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, + /* LXB_TAG_SEARCH */ + { + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_search_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2819,8 +2863,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_select_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2828,10 +2872,21 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, + /* LXB_TAG_SELECTEDCONTENT */ + { + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_selectedcontent_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_slot_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2841,8 +2896,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2852,8 +2907,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_source_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2863,8 +2918,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2874,8 +2929,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_span_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2885,8 +2940,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2896,8 +2951,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2907,8 +2962,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_style_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2918,8 +2973,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2929,8 +2984,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2940,8 +2995,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2951,8 +3006,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2962,8 +3017,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2973,8 +3028,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2984,8 +3039,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -2995,8 +3050,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_template_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3006,8 +3061,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_text_area_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3017,8 +3072,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3028,8 +3083,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3039,8 +3094,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3050,8 +3105,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3061,8 +3116,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_time_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3072,8 +3127,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_title_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3083,8 +3138,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_table_row_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3094,8 +3149,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_track_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3105,8 +3160,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_TT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3116,8 +3171,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_U */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3127,8 +3182,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_UL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_u_list_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3138,8 +3193,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3149,8 +3204,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_video_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3160,8 +3215,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3171,8 +3226,8 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, @@ -3181,18 +3236,13 @@ static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_ (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper } }; -#endif /* LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED */ -#endif /* LXB_HTML_INTERFACE_RES_CONSTRUCTORS */ -#ifdef LXB_HTML_INTERFACE_RES_DESTRUCTOR -#ifndef LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED -#define LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3202,8 +3252,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3213,52 +3263,52 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_document_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_anchor_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3268,8 +3318,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3279,8 +3329,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3290,8 +3340,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3301,8 +3351,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3312,8 +3362,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3323,8 +3373,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3334,8 +3384,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3345,8 +3395,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3356,8 +3406,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3367,8 +3417,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3378,8 +3428,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3389,8 +3439,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_area_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3400,8 +3450,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3411,8 +3461,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3422,8 +3472,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_audio_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3433,8 +3483,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_B */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3444,8 +3494,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_base_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3455,8 +3505,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3466,8 +3516,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3477,8 +3527,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3488,8 +3538,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3499,8 +3549,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3510,8 +3560,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3521,8 +3571,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3532,8 +3582,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_body_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3543,8 +3593,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_br_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3554,8 +3604,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_button_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3565,8 +3615,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_canvas_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3576,8 +3626,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_caption_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3587,8 +3637,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3598,8 +3648,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3609,8 +3659,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3620,8 +3670,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3631,8 +3681,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_COL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3642,8 +3692,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3653,8 +3703,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_data_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3664,8 +3714,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_data_list_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3675,8 +3725,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3686,8 +3736,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3697,8 +3747,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3708,8 +3758,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_details_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3719,8 +3769,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3730,8 +3780,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_dialog_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3741,8 +3791,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_directory_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3752,8 +3802,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_div_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3763,8 +3813,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_d_list_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3774,8 +3824,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_DT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3785,8 +3835,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_EM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3796,8 +3846,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_embed_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3807,8 +3857,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3818,8 +3868,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3829,8 +3879,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3840,8 +3890,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3851,8 +3901,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3862,8 +3912,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3873,8 +3923,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3884,8 +3934,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3895,8 +3945,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3906,8 +3956,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3917,8 +3967,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3928,8 +3978,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3939,8 +3989,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3950,8 +4000,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3961,8 +4011,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3972,8 +4022,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3983,8 +4033,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -3994,8 +4044,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4005,8 +4055,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4016,8 +4066,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4027,8 +4077,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4038,8 +4088,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4049,8 +4099,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4060,8 +4110,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4071,8 +4121,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4082,8 +4132,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_field_set_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4093,8 +4143,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4104,8 +4154,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4115,8 +4165,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_font_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4126,8 +4176,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4137,8 +4187,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4148,8 +4198,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_form_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4159,8 +4209,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_frame_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4170,8 +4220,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_frame_set_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4181,8 +4231,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4192,8 +4242,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4203,8 +4253,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4214,8 +4264,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4225,8 +4275,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4236,8 +4286,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4247,8 +4297,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4258,8 +4308,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_head_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4269,8 +4319,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4280,8 +4330,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4291,8 +4341,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_HR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_hr_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4302,8 +4352,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4313,8 +4363,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_I */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4324,8 +4374,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_iframe_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4335,8 +4385,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4346,8 +4396,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4357,8 +4407,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_input_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4368,8 +4418,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_INS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4379,8 +4429,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4390,8 +4440,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4401,8 +4451,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4412,8 +4462,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_label_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4423,8 +4473,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_legend_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4434,8 +4484,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_li_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4445,8 +4495,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4456,8 +4506,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_link_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4467,8 +4517,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4478,8 +4528,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4489,8 +4539,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4500,8 +4550,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_map_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4511,8 +4561,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4522,8 +4572,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_marquee_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4533,8 +4583,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4544,8 +4594,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_menu_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4555,8 +4605,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_META */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_meta_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4566,8 +4616,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_METER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_meter_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4577,8 +4627,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4588,8 +4638,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4599,8 +4649,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4610,8 +4660,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4621,8 +4671,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4632,8 +4682,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4643,8 +4693,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4654,8 +4704,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4665,8 +4715,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4676,8 +4726,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4687,8 +4737,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4698,8 +4748,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4709,8 +4759,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4720,8 +4770,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4731,8 +4781,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_object_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4742,8 +4792,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_OL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_o_list_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4753,8 +4803,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_opt_group_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4764,8 +4814,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_option_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4775,8 +4825,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_output_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4786,8 +4836,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_P */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_paragraph_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4797,8 +4847,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_param_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4808,8 +4858,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4819,8 +4869,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_picture_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4830,8 +4880,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4841,8 +4891,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4852,8 +4902,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_progress_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4863,8 +4913,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_Q */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4874,8 +4924,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4885,8 +4935,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4896,8 +4946,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4907,8 +4957,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4918,8 +4968,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4929,8 +4979,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4940,8 +4990,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_S */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4951,8 +5001,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4962,8 +5012,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_script_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4971,10 +5021,21 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, + /* LXB_TAG_SEARCH */ + { + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_search_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4984,8 +5045,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_select_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -4993,10 +5054,21 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, + /* LXB_TAG_SELECTEDCONTENT */ + { + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_selectedcontent_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_slot_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5006,8 +5078,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5017,8 +5089,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_source_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5028,8 +5100,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5039,8 +5111,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_span_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5050,8 +5122,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5061,8 +5133,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5072,8 +5144,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_style_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5083,8 +5155,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5094,8 +5166,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5105,8 +5177,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5116,8 +5188,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5127,8 +5199,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5138,8 +5210,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5149,8 +5221,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5160,8 +5232,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_template_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5171,8 +5243,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_text_area_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5182,8 +5254,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5193,8 +5265,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5204,8 +5276,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5215,8 +5287,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5226,8 +5298,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_time_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5237,8 +5309,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_title_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5248,8 +5320,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_table_row_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5259,8 +5331,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_track_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5270,8 +5342,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_TT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5281,8 +5353,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_U */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5292,8 +5364,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_UL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_u_list_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5303,8 +5375,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5314,8 +5386,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_video_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5325,8 +5397,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5336,8 +5408,8 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, @@ -5346,5 +5418,5 @@ static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper } }; -#endif /* LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED */ -#endif /* LXB_HTML_INTERFACE_RES_DESTRUCTOR */ + +#endif /* LXB_HTML_INTERFACE_RES_H */ diff --git a/ext/lexbor/lexbor/html/interfaces/document.c b/ext/lexbor/lexbor/html/interfaces/document.c index 34a2c6db0e5a..b40c6c8692f1 100644 --- a/ext/lexbor/lexbor/html/interfaces/document.c +++ b/ext/lexbor/lexbor/html/interfaces/document.c @@ -11,16 +11,18 @@ #include "lexbor/html/interfaces/style_element.h" #include "lexbor/html/node.h" #include "lexbor/html/parser.h" +#include "lexbor/html/tokenizer.h" #include "lexbor/tag/tag.h" #include "lexbor/dom/interfaces/text.h" #include "lexbor/dom/interfaces/element.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif lxb_status_t lxb_html_parse_chunk_prepare(lxb_html_parser_t *parser, @@ -34,7 +36,7 @@ lxb_html_document_title_walker(lxb_dom_node_t *node, void *ctx); lxb_inline lxb_dom_interface_t * -lxb_html_document_interface_create_wrapper(lxb_dom_document_t *document, +lxb_html_document_interface_create_handler(lxb_dom_document_t *document, lxb_tag_id_t tag_id, lxb_ns_id_t ns) { return lxb_html_interface_create(lxb_html_interface_document(document), @@ -60,7 +62,7 @@ lxb_html_document_interface_create(lxb_html_document_t *document) } status = lxb_dom_document_init(doc, lxb_dom_interface_document(document), - lxb_html_document_interface_create_wrapper, + lxb_html_document_interface_create_handler, lxb_html_interface_clone, lxb_html_interface_destroy, LXB_DOM_DOCUMENT_DTYPE_HTML, LXB_NS_HTML); @@ -267,6 +269,7 @@ lxb_html_document_parser_prepare(lxb_html_document_t *document) { lxb_status_t status; lxb_dom_document_t *doc; + lxb_html_parser_t *parser; doc = lxb_dom_interface_document(document); @@ -278,6 +281,10 @@ lxb_html_document_parser_prepare(lxb_html_document_t *document) lxb_html_parser_destroy(doc->parser); return status; } + + parser = doc->parser; + + lxb_html_tokenizer_keep_duplicate_set(parser->tkz, true); } else if (lxb_html_parser_state(doc->parser) != LXB_HTML_PARSER_STATE_BEGIN) { lxb_html_parser_clean(doc->parser); diff --git a/ext/lexbor/lexbor/html/interfaces/option_element.c b/ext/lexbor/lexbor/html/interfaces/option_element.c index 77e1e23d3878..19f085da0423 100644 --- a/ext/lexbor/lexbor/html/interfaces/option_element.c +++ b/ext/lexbor/lexbor/html/interfaces/option_element.c @@ -5,6 +5,8 @@ */ #include "lexbor/html/interfaces/option_element.h" +#include "lexbor/html/interfaces/select_element.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" #include "lexbor/html/interfaces/document.h" @@ -33,3 +35,48 @@ lxb_html_option_element_interface_destroy(lxb_html_option_element_t *option_elem (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(option_element)); return NULL; } + +lxb_dom_exception_code_t +lxb_html_option_maybe_clone_to_selectedcontent(lxb_html_option_element_t *option) +{ + bool is; + lxb_dom_node_t *select; + lxb_html_select_element_t *select_el; + lxb_html_selectedcontent_element_t *sel_content; + + is = lxb_html_option_element_selectedness(lxb_html_interface_option(option)); + if (!is) { + return LXB_DOM_EXCEPTION_OK; + } + + select = lxb_dom_interface_node(option); + + do { + select = select->parent; + + if (select == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + } + while (select->local_name != LXB_TAG_SELECT || select->ns != LXB_NS_HTML); + + select_el = lxb_html_interface_select(select); + + sel_content = lxb_html_select_get_enabled_selectedcontent(select_el); + if (sel_content == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + return lxb_html_selectedcontent_clone_option(sel_content, option); +} + +bool +lxb_html_option_element_selectedness(lxb_html_option_element_t *option) +{ + lxb_dom_attr_t *selected; + + selected = lxb_dom_element_attr_by_id(lxb_dom_interface_element(option), + LXB_DOM_ATTR_SELECTED); + + return selected != NULL; +} diff --git a/ext/lexbor/lexbor/html/interfaces/option_element.h b/ext/lexbor/lexbor/html/interfaces/option_element.h index a59763898def..99d4977aa031 100644 --- a/ext/lexbor/lexbor/html/interfaces/option_element.h +++ b/ext/lexbor/lexbor/html/interfaces/option_element.h @@ -27,6 +27,13 @@ LXB_API lxb_html_option_element_t * lxb_html_option_element_interface_destroy(lxb_html_option_element_t *option_element); +LXB_API lxb_dom_exception_code_t +lxb_html_option_maybe_clone_to_selectedcontent(lxb_html_option_element_t *option); + +LXB_API bool +lxb_html_option_element_selectedness(lxb_html_option_element_t *option); + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/ext/lexbor/lexbor/html/interfaces/search_element.c b/ext/lexbor/lexbor/html/interfaces/search_element.c new file mode 100644 index 000000000000..00ca2a6ba3fc --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/search_element.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/html/interfaces/search_element.h" +#include "lexbor/html/interfaces/document.h" + + +lxb_html_search_element_t * +lxb_html_search_element_interface_create(lxb_html_document_t *document) +{ + lxb_html_search_element_t *element; + + element = lexbor_mraw_calloc(document->dom_document.mraw, + sizeof(lxb_html_search_element_t)); + if (element == NULL) { + return NULL; + } + + lxb_dom_node_t *node = lxb_dom_interface_node(element); + + node->owner_document = lxb_html_document_original_ref(document); + node->type = LXB_DOM_NODE_TYPE_ELEMENT; + + return element; +} + +lxb_html_search_element_t * +lxb_html_search_element_interface_destroy(lxb_html_search_element_t *search_element) +{ + (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(search_element)); + return NULL; +} diff --git a/ext/lexbor/lexbor/html/interfaces/search_element.h b/ext/lexbor/lexbor/html/interfaces/search_element.h new file mode 100644 index 000000000000..a42862176409 --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/search_element.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LEXBOR_HTML_SEARCH_ELEMENT_H +#define LEXBOR_HTML_SEARCH_ELEMENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/html/interface.h" +#include "lexbor/html/interfaces/element.h" + + +struct lxb_html_search_element { + lxb_html_element_t element; +}; + + +LXB_API lxb_html_search_element_t * +lxb_html_search_element_interface_create(lxb_html_document_t *document); + +LXB_API lxb_html_search_element_t * +lxb_html_search_element_interface_destroy(lxb_html_search_element_t *search_element); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LEXBOR_HTML_SEARCH_ELEMENT_H */ diff --git a/ext/lexbor/lexbor/html/interfaces/select_element.c b/ext/lexbor/lexbor/html/interfaces/select_element.c index 69f8abe8dd51..8b338dc76da7 100644 --- a/ext/lexbor/lexbor/html/interfaces/select_element.c +++ b/ext/lexbor/lexbor/html/interfaces/select_element.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,6 +8,10 @@ #include "lexbor/html/interfaces/document.h" +static lexbor_action_t +lxb_html_select_find_selectedcontent_cb(lxb_dom_node_t *node, void *ctx); + + lxb_html_select_element_t * lxb_html_select_element_interface_create(lxb_html_document_t *document) { @@ -33,3 +37,44 @@ lxb_html_select_element_interface_destroy(lxb_html_select_element_t *select_elem (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(select_element)); return NULL; } + +lxb_html_selectedcontent_element_t * +lxb_html_select_get_enabled_selectedcontent(lxb_html_select_element_t *el) +{ + lxb_dom_attr_t *multiple; + lxb_dom_node_t *selectedcontent, *node; + + multiple = lxb_dom_element_attr_by_id(lxb_dom_interface_element(el), + LXB_DOM_ATTR_MULTIPLE); + if (multiple != NULL) { + return NULL; + } + + selectedcontent = NULL; + node = lxb_dom_interface_node(el); + + lxb_dom_node_simple_walk(node, lxb_html_select_find_selectedcontent_cb, + &selectedcontent); + if (selectedcontent == NULL) { + return NULL; + } + + return lxb_html_interface_selectedcontent(selectedcontent); +} + +static lexbor_action_t +lxb_html_select_find_selectedcontent_cb(lxb_dom_node_t *node, void *ctx) +{ + lxb_dom_node_t **selectedcontent; + + if (node->local_name == LXB_TAG_SELECTEDCONTENT + && node->ns == LXB_NS_HTML) + { + selectedcontent = ctx; + *selectedcontent = node; + + return LEXBOR_ACTION_STOP; + } + + return LEXBOR_ACTION_OK; +} diff --git a/ext/lexbor/lexbor/html/interfaces/select_element.h b/ext/lexbor/lexbor/html/interfaces/select_element.h index 8676db5da902..03e20d197cd3 100644 --- a/ext/lexbor/lexbor/html/interfaces/select_element.h +++ b/ext/lexbor/lexbor/html/interfaces/select_element.h @@ -26,6 +26,8 @@ lxb_html_select_element_interface_create(lxb_html_document_t *document); LXB_API lxb_html_select_element_t * lxb_html_select_element_interface_destroy(lxb_html_select_element_t *select_element); +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_select_get_enabled_selectedcontent(lxb_html_select_element_t *el); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c new file mode 100644 index 000000000000..41b1c0d58b8f --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/dom/interfaces/document_fragment.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" +#include "lexbor/html/interfaces/document.h" + + +lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_create(lxb_html_document_t *document) +{ + lxb_html_selectedcontent_element_t *element; + + element = lexbor_mraw_calloc(document->dom_document.mraw, + sizeof(lxb_html_selectedcontent_element_t)); + if (element == NULL) { + return NULL; + } + + lxb_dom_node_t *node = lxb_dom_interface_node(element); + + node->owner_document = lxb_html_document_original_ref(document); + node->type = LXB_DOM_NODE_TYPE_ELEMENT; + + return element; +} + +lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_destroy(lxb_html_selectedcontent_element_t *selectedcontent_element) +{ + (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(selectedcontent_element)); + return NULL; +} + +lxb_dom_exception_code_t +lxb_html_selectedcontent_clone_option(lxb_html_selectedcontent_element_t *sc, + lxb_html_option_element_t *option) +{ + lxb_dom_node_t *node, *child, *opt_node; + lxb_dom_document_fragment_t fragment; + + memset(&fragment, 0x00, sizeof(lxb_dom_document_fragment_t)); + + opt_node = lxb_dom_interface_node(option); + + fragment.node.type = LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT; + fragment.node.owner_document = opt_node->owner_document; + + node = opt_node->first_child; + + while (node != NULL) { + child = lxb_dom_node_clone(node, true); + if (child == NULL) { + return LXB_DOM_EXCEPTION_ERR; + } + + lxb_dom_node_insert_child_wo_events(lxb_dom_interface_node(&fragment), + child); + node = node->next; + } + + return lxb_dom_node_replace_all_spec(lxb_dom_interface_node(sc), + lxb_dom_interface_node(&fragment)); +} diff --git a/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h new file mode 100644 index 000000000000..5d38b59f501c --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H +#define LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/html/interface.h" +#include "lexbor/html/interfaces/element.h" + + +struct lxb_html_selectedcontent_element { + lxb_html_element_t element; +}; + + +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_create(lxb_html_document_t *document); + +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_destroy(lxb_html_selectedcontent_element_t *selectedcontent_element); + +LXB_API lxb_dom_exception_code_t +lxb_html_selectedcontent_clone_option(lxb_html_selectedcontent_element_t *sc, + lxb_html_option_element_t *option); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H */ diff --git a/ext/lexbor/lexbor/html/parser.c b/ext/lexbor/lexbor/html/parser.c index caca15e4be26..7d051045101e 100644 --- a/ext/lexbor/lexbor/html/parser.c +++ b/ext/lexbor/lexbor/html/parser.c @@ -13,9 +13,10 @@ #include "lexbor/html/tree/template_insertion.h" #include "lexbor/html/tree/insertion_mode.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif static void @@ -43,6 +44,8 @@ lxb_html_parser_init(lxb_html_parser_t *parser) return status; } + lxb_html_tokenizer_keep_duplicate_set(parser->tkz, true); + /* Tree */ parser->tree = lxb_html_tree_create(); status = lxb_html_tree_init(parser->tree, parser->tkz); @@ -339,7 +342,9 @@ lxb_html_parse_fragment_chunk_destroy(lxb_html_parser_t *parser) parser->tree->fragment = NULL; } - if (lxb_html_document_is_original(parser->tree->document) == false) { + if (parser->tree->document != NULL + && lxb_html_document_is_original(parser->tree->document) == false) + { if (parser->root != NULL) { doc = lxb_dom_interface_node(parser->tree->document)->owner_document; parser->root->parent = &doc->node; diff --git a/ext/lexbor/lexbor/html/style.c b/ext/lexbor/lexbor/html/style.c deleted file mode 100644 index b07dbf12cae0..000000000000 --- a/ext/lexbor/lexbor/html/style.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2022-2023 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/style.h" - - -uintptr_t -lxb_html_style_id_by_name(lxb_html_document_t *doc, - const lxb_char_t *name, size_t size) -{ - const lxb_css_entry_data_t *data; - - data = lxb_css_property_by_name(name, size); - - if (data == NULL) { - return lxb_html_document_css_customs_find_id(doc, name, size); - } - - return data->unique; -} diff --git a/ext/lexbor/lexbor/html/style.h b/ext/lexbor/lexbor/html/style.h deleted file mode 100644 index 10800bcd6593..000000000000 --- a/ext/lexbor/lexbor/html/style.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2022-2023 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#ifndef LEXBOR_HTML_STYLE_H -#define LEXBOR_HTML_STYLE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lexbor/core/avl.h" -#include "lexbor/css/selectors/selector.h" -#include "lexbor/html/interfaces/document.h" - - -typedef struct lxb_html_style_weak lxb_html_style_weak_t; - -struct lxb_html_style_weak { - void *value; - lxb_css_selector_specificity_t sp; - - lxb_html_style_weak_t *next; -}; - -typedef struct { - lexbor_avl_node_t entry; - lxb_html_style_weak_t *weak; - - lxb_css_selector_specificity_t sp; -} -lxb_html_style_node_t; - - -LXB_API uintptr_t -lxb_html_style_id_by_name(lxb_html_document_t *doc, - const lxb_char_t *name, size_t size); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LEXBOR_HTML_STYLE_H */ diff --git a/ext/lexbor/lexbor/html/tag.c b/ext/lexbor/lexbor/html/tag.c new file mode 100644 index 000000000000..48f894963c56 --- /dev/null +++ b/ext/lexbor/lexbor/html/tag.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/html/tag.h" +#include "lexbor/html/tag_res.h" + + +bool +lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, + lxb_html_tag_category_t cat) +{ + if (tag_id < LXB_TAG__LAST_ENTRY && ns < LXB_NS__LAST_ENTRY) { + return lxb_html_tag_res_cats[tag_id][ns] & cat; + } + + return (LXB_HTML_TAG_CATEGORY_ORDINARY) & cat; +} + +const lxb_html_tag_fixname_t * +lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id) +{ + if (tag_id >= LXB_TAG__LAST_ENTRY) { + return NULL; + } + + return &lxb_html_tag_res_fixname_svg[tag_id]; +} diff --git a/ext/lexbor/lexbor/html/tag.h b/ext/lexbor/lexbor/html/tag.h index 6570d7d40b7c..b559d31f6882 100644 --- a/ext/lexbor/lexbor/html/tag.h +++ b/ext/lexbor/lexbor/html/tag.h @@ -28,8 +28,7 @@ enum lxb_html_tag_category { LXB_HTML_TAG_CATEGORY_SCOPE = 0x0008, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM = 0x0010, LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON = 0x0020, - LXB_HTML_TAG_CATEGORY_SCOPE_TABLE = 0x0040, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT = 0x0080, + LXB_HTML_TAG_CATEGORY_SCOPE_TABLE = 0x0040 }; typedef struct { @@ -39,35 +38,17 @@ typedef struct { lxb_html_tag_fixname_t; -#define LXB_HTML_TAG_RES_CATS -#define LXB_HTML_TAG_RES_FIXNAME_SVG -#include "lexbor/html/tag_res.h" +LXB_API bool +lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, + lxb_html_tag_category_t cat); + +LXB_API const lxb_html_tag_fixname_t * +lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id); /* * Inline functions */ -lxb_inline bool -lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, - lxb_html_tag_category_t cat) -{ - if (tag_id < LXB_TAG__LAST_ENTRY && ns < LXB_NS__LAST_ENTRY) { - return lxb_html_tag_res_cats[tag_id][ns] & cat; - } - - return (LXB_HTML_TAG_CATEGORY_ORDINARY|LXB_HTML_TAG_CATEGORY_SCOPE_SELECT) & cat; -} - -lxb_inline const lxb_html_tag_fixname_t * -lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id) -{ - if (tag_id >= LXB_TAG__LAST_ENTRY) { - return NULL; - } - - return &lxb_html_tag_res_fixname_svg[tag_id]; -} - lxb_inline bool lxb_html_tag_is_void(lxb_tag_id_t tag_id) { diff --git a/ext/lexbor/lexbor/html/tag_res.h b/ext/lexbor/lexbor/html/tag_res.h index 97c28640ccd1..5e2453a59f2a 100644 --- a/ext/lexbor/lexbor/html/tag_res.h +++ b/ext/lexbor/lexbor/html/tag_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,14 +14,10 @@ #ifndef LXB_HTML_TAG_RES_H #define LXB_HTML_TAG_RES_H -#include "lexbor/html/tag.h" - -#endif /* LXB_HTML_TAG_RES_H */ - #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -34,1835 +30,1476 @@ #error You need to include "lexbor/ns/const.h". #endif /* LXB_NS_CONST_VERSION */ -#ifdef LXB_HTML_TAG_RES_CATS -#ifndef LXB_HTML_TAG_RES_CATS_ENABLED -#define LXB_HTML_TAG_RES_CATS_ENABLED -static lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = +LXB_API lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG__END_OF_FILE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG__TEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__DOCUMENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__EM_COMMENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__EM_DOCTYPE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG_A */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ABBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ACRONYM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ADDRESS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPHDEF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPHITEM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATECOLOR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATEMOTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATETRANSFORM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANNOTATION_XML */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_APPLET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_AREA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ARTICLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ASIDE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_AUDIO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_B */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BASE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BASEFONT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BDI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BDO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BGSOUND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BIG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BLINK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BLOCKQUOTE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BODY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BUTTON */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CANVAS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CAPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CENTER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CITE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CLIPPATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CODE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_COL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_COLGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DATA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DATALIST */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DEL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DESC */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DETAILS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DFN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIALOG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIV */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_EM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_EMBED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEBLEND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOLORMATRIX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOMPOSITE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECONVOLVEMATRIX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDISTANTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDROPSHADOW */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFLOOD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEGAUSSIANBLUR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEIMAGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMERGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMERGENODE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMORPHOLOGY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEOFFSET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEPOINTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FESPECULARLIGHTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FESPOTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FETILE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FETURBULENCE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIELDSET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIGCAPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIGURE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FONT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FOOTER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FOREIGNOBJECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FORM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FRAME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FRAMESET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_GLYPHREF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H1 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H2 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H3 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H4 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H5 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H6 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HEAD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HEADER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HTML */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_I */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IFRAME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IMAGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IMG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_INPUT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_INS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ISINDEX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_KBD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_KEYGEN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LABEL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LEGEND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LINEARGRADIENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LINK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LISTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MAIN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MALIGNMARK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MAP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MARK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MARQUEE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MENU */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_META */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_METER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MFENCED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MGLYPH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MTEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MULTICOL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NAV */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NEXTID */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOEMBED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOFRAMES */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOSCRIPT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OBJECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OPTGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OUTPUT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_P */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PARAM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PICTURE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PLAINTEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PRE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PROGRESS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_Q */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RADIALGRADIENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RTC */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RUBY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_S */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SAMP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SCRIPT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF + }, + /* LXB_TAG_SEARCH */ + { + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SECTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SELECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SCOPE + |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON + |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF + }, + /* LXB_TAG_SELECTEDCONTENT */ + { + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SLOT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SMALL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SOURCE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SPACER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SPAN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STRIKE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STRONG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STYLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUMMARY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SVG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TABLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TBODY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEMPLATE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEXTAREA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEXTPATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TFOOT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_THEAD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TIME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TITLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TRACK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_U */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_UL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_VAR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_VIDEO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_WBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_XMP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF } }; -#endif /* LXB_HTML_TAG_RES_CATS_ENABLED */ -#endif /* LXB_HTML_TAG_RES_CATS */ -#ifdef LXB_HTML_TAG_RES_FIXNAME_SVG -#ifndef LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED -#define LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED -static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] = +LXB_API lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ {NULL, 0}, @@ -2188,10 +1825,14 @@ static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] {NULL, 0}, /* LXB_TAG_SCRIPT */ {NULL, 0}, + /* LXB_TAG_SEARCH */ + {NULL, 0}, /* LXB_TAG_SECTION */ {NULL, 0}, /* LXB_TAG_SELECT */ {NULL, 0}, + /* LXB_TAG_SELECTEDCONTENT */ + {NULL, 0}, /* LXB_TAG_SLOT */ {NULL, 0}, /* LXB_TAG_SMALL */ @@ -2256,7 +1897,7 @@ static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] {NULL, 0}, /* LXB_TAG_XMP */ {NULL, 0}, - + }; -#endif /* LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED */ -#endif /* LXB_HTML_TAG_RES_FIXNAME_SVG */ + +#endif /* LXB_HTML_TAG_RES_H */ diff --git a/ext/lexbor/lexbor/html/token.c b/ext/lexbor/lexbor/html/token.c index 0f5d076adf59..d4ab1bbb767d 100644 --- a/ext/lexbor/lexbor/html/token.c +++ b/ext/lexbor/lexbor/html/token.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,11 +7,12 @@ #include "lexbor/html/token.h" #include "lexbor/html/tokenizer.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #include "lexbor/dom/interfaces/document_type.h" diff --git a/ext/lexbor/lexbor/html/tokenizer.c b/ext/lexbor/lexbor/html/tokenizer.c index 0bd9aec504f0..1d9f3781255d 100644 --- a/ext/lexbor/lexbor/html/tokenizer.c +++ b/ext/lexbor/lexbor/html/tokenizer.c @@ -11,19 +11,20 @@ #include "lexbor/html/tokenizer/state_script.h" #include "lexbor/html/tree.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif #define LXB_HTML_TKZ_TEMP_SIZE (4096 * 4) enum { - LXB_HTML_TOKENIZER_OPT_UNDEF = 0x00, - LXB_HTML_TOKENIZER_OPT_TAGS_SELF = 0x01, - LXB_HTML_TOKENIZER_OPT_ATTRS_SELF = 0x02, - LXB_HTML_TOKENIZER_OPT_ATTRS_MRAW_SELF = 0x04 + LXB_HTML_TOKENIZER_OPT_TAGS_SELF = 1 << 0, + LXB_HTML_TOKENIZER_OPT_ATTRS_SELF = 1 << 1, + LXB_HTML_TOKENIZER_OPT_ATTRS_MRAW_SELF = 1 << 2 }; @@ -206,6 +207,8 @@ lxb_html_tokenizer_clean(lxb_html_tokenizer_t *tkz) tkz->is_eof = false; tkz->status = LXB_STATUS_OK; + tkz->utf8_buf_len = 0; + tkz->pos = tkz->start; lexbor_mraw_clean(tkz->mraw); @@ -304,12 +307,268 @@ lxb_html_tokenizer_begin(lxb_html_tokenizer_t *tkz) return LXB_STATUS_OK; } +/* + * Input stream validation. + * + * Per the HTML spec §13.2.3.5: surrogates, noncharacters, and controls + * (other than ASCII whitespace and NULL) in the input stream are parse errors. + * + * This is a fast linear scan that only fires when + * LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT is set. + */ + +/* + * Lookup: 1 if the byte is a single-byte control that needs reporting. + * Covers 0x01–0x08, 0x0B, 0x0E–0x1F, 0x7F. + * Excludes 0x00 (handled by tokenizer as UNNUCH), 0x09 (TAB), 0x0A (LF), + * 0x0C (FF), 0x0D (CR), 0x20 (SPACE). + */ +static const lxb_char_t +lxb_html_tkz_validate_ctl[256] = +{ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ +/* 0 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, +/* 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +/* 8+ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +lxb_html_tokenizer_validate_codepoint(lxb_html_tokenizer_t *tkz, + uint32_t cp, const lxb_char_t *pos) +{ + /* C1 controls: U+0080–U+009F */ + if (cp >= 0x0080 && cp <= 0x009F) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_COCHININST); + return; + } + + /* Surrogates: U+D800–U+DFFF */ + if (cp >= 0xD800 && cp <= 0xDFFF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_SUININST); + return; + } + + /* Noncharacters: U+FDD0–U+FDEF */ + if (cp >= 0xFDD0 && cp <= 0xFDEF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_NOININST); + return; + } + + /* Noncharacters: U+xFFFE and U+xFFFF on every plane */ + if ((cp & 0xFFFE) == 0xFFFE && cp <= 0x10FFFF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } +} + +static void +lxb_html_tokenizer_validate_flush_utf8(lxb_html_tokenizer_t *tkz, + const lxb_char_t *pos) +{ + uint32_t cp; + unsigned len = tkz->utf8_buf_len; + const lxb_char_t *b = tkz->utf8_buf; + + if (len < 2) { + goto done; + } + + if ((b[0] & 0xE0) == 0xC0) { + cp = ((uint32_t)(b[0] & 0x1F) << 6) | (b[1] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + goto done; + } + + if (len < 3) { + goto done; + } + + if ((b[0] & 0xF0) == 0xE0) { + cp = ((uint32_t)(b[0] & 0x0F) << 12) + | ((uint32_t)(b[1] & 0x3F) << 6) + | (b[2] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + goto done; + } + + if (len < 4) { + goto done; + } + + if ((b[0] & 0xF8) == 0xF0) { + cp = ((uint32_t)(b[0] & 0x07) << 18) + | ((uint32_t)(b[1] & 0x3F) << 12) + | ((uint32_t)(b[2] & 0x3F) << 6) + | (b[3] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + } + +done: + + tkz->utf8_buf_len = 0; +} + +static void +lxb_html_tokenizer_validate_input(lxb_html_tokenizer_t *tkz, + const lxb_char_t *data, size_t size) +{ + uint32_t cp; + unsigned need, len; + const lxb_char_t *p, *end; + + p = data; + end = data + size; + + /* Continue incomplete UTF-8 sequence from previous chunk. */ + if (tkz->utf8_buf_len > 0) { + lxb_char_t lead = tkz->utf8_buf[0]; + + if ((lead & 0xE0) == 0xC0) { + need = 2; + } + else if ((lead & 0xF0) == 0xE0) { + need = 3; + } + else { + need = 4; + } + + while (tkz->utf8_buf_len < need && p < end) { + if ((*p & 0xC0) != 0x80) { + /* Broken sequence, skip. */ + tkz->utf8_buf_len = 0; + break; + } + + tkz->utf8_buf[tkz->utf8_buf_len++] = *p++; + } + + if (tkz->utf8_buf_len == need) { + lxb_html_tokenizer_validate_flush_utf8(tkz, data); + } + else if (p >= end) { + /* Still incomplete, wait for more data. */ + return; + } + else { + /* Broken sequence was reset above. */ + } + } + + while (p < end) { + lxb_char_t b = *p; + + /* Fast path: printable ASCII (0x20–0x7E), TAB, LF, FF, CR, NULL. */ + if (b < 0x80) { + if (lxb_html_tkz_validate_ctl[b]) { + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_COCHININST); + } + + p++; + continue; + } + + /* Multi-byte UTF-8. Determine expected length. */ + if ((b & 0xE0) == 0xC0) { + need = 2; + } + else if ((b & 0xF0) == 0xE0) { + need = 3; + } + else if ((b & 0xF8) == 0xF0) { + need = 4; + } + else { + /* Invalid lead byte or continuation byte, skip. */ + p++; + continue; + } + + /* Check if the full sequence is available in this chunk. */ + if ((unsigned)(end - p) < need) { + /* Save partial sequence for next chunk. */ + len = (unsigned)(end - p); + memcpy(tkz->utf8_buf, p, len); + tkz->utf8_buf_len = len; + return; + } + + /* Quick filter: only decode if lead byte can start a bad codepoint. + * + * 0xC2 -> C1 controls (U+0080–U+009F): second byte 0x80–0x9F + * 0xED -> surrogates (U+D800–U+DFFF): second byte 0xA0–0xBF + * 0xEF -> nonchars U+FDD0–U+FDEF (0xEF 0xB7 0x90–0xAF) + * and U+FFFE/U+FFFF (0xEF 0xBF 0xBE/0xBF) + * 0xF0–0xF4 -> nonchars U+xFFFE/U+xFFFF on planes 1–16 + */ + if (b == 0xC2) { + if (p[1] <= 0x9F) { + cp = ((uint32_t)(b & 0x1F) << 6) | (p[1] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + else if (b == 0xED) { + if (p[1] >= 0xA0) { + cp = ((uint32_t)(b & 0x0F) << 12) + | ((uint32_t)(p[1] & 0x3F) << 6) + | (p[2] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + else if (b == 0xEF) { + if (p[1] == 0xB7 && p[2] >= 0x90 && p[2] <= 0xAF) { + /* U+FDD0–U+FDEF */ + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } + else if (p[1] == 0xBF && (p[2] == 0xBE || p[2] == 0xBF)) { + /* U+FFFE, U+FFFF */ + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } + } + else if (b >= 0xF0 && b <= 0xF4) { + /* 4-byte: check for xFFFE/xFFFF. */ + if (p[2] == 0xBF && (p[3] == 0xBE || p[3] == 0xBF)) { + cp = ((uint32_t)(b & 0x07) << 18) + | ((uint32_t)(p[1] & 0x3F) << 12) + | ((uint32_t)(p[2] & 0x3F) << 6) + | (p[3] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + + p += need; + } +} + lxb_status_t lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, size_t size) { const lxb_char_t *end = data + size; + if (tkz->opt & LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT) { + lxb_html_tokenizer_validate_input(tkz, data, size); + } + tkz->is_eof = false; tkz->status = LXB_STATUS_OK; tkz->last = end; @@ -457,6 +716,46 @@ lxb_html_tokenizer_set_state_by_tag(lxb_html_tokenizer_t *tkz, bool scripting, } } +void +lxb_html_tokenizer_attr_last_duplicate(lxb_html_tokenizer_t *tkz) +{ + lxb_html_token_t *token; + lxb_html_token_attr_t *attr, *last; + + token = tkz->token; + attr = token->attr_first; + last = token->attr_last; + + while (attr != last) { + if (attr->name == last->name) { + lxb_html_tokenizer_error_add(tkz->parse_errors, last->name_begin, + LXB_HTML_TOKENIZER_ERROR_DUAT); + + lxb_html_token_attr_remove(token, last); + lxb_html_token_attr_destroy(last, tkz->dobj_token_attr); + return; + } + + attr = attr->next; + } +} + +void +lxb_html_tokenizer_validate_close_tag(lxb_html_tokenizer_t *tkz) +{ + if (tkz->token->attr_last != NULL) { + lxb_html_tokenizer_error_add(tkz->parse_errors, + tkz->token->attr_last->name_begin, + LXB_HTML_TOKENIZER_ERROR_ENTAWIAT); + } + + if (tkz->token->type & LXB_HTML_TOKEN_TYPE_CLOSE_SELF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, tkz->token->end, + LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO); + } +} + + /* * No inline functions for ABI. */ @@ -508,6 +807,13 @@ lxb_html_tokenizer_tree_set_noi(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_tree_set(tkz, tree); } +void +lxb_html_tokenizer_input_validation_set_noi(lxb_html_tokenizer_t *tkz, + bool enabled) +{ + lxb_html_tokenizer_input_validation_set(tkz, enabled); +} + lexbor_mraw_t * lxb_html_tokenizer_mraw_noi(lxb_html_tokenizer_t *tkz) { @@ -519,3 +825,10 @@ lxb_html_tokenizer_tags_noi(lxb_html_tokenizer_t *tkz) { return lxb_html_tokenizer_tags(tkz); } + +void +lxb_html_tokenizer_keep_duplicate_set_noi(lxb_html_tokenizer_t *tkz, + bool keep) +{ + lxb_html_tokenizer_keep_duplicate_set(tkz, keep); +} diff --git a/ext/lexbor/lexbor/html/tokenizer.h b/ext/lexbor/lexbor/html/tokenizer.h index 74bb55ef0fd7..aa1ac37d996d 100644 --- a/ext/lexbor/lexbor/html/tokenizer.h +++ b/ext/lexbor/lexbor/html/tokenizer.h @@ -21,6 +21,12 @@ extern "C" { #include "lexbor/ns/ns.h" +enum { + LXB_HTML_TOKENIZER_OPT_UNDEF = 0x00, + LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT = 1 << 3, + LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE = 1 << 4 +}; + /* State */ typedef const lxb_char_t * (*lxb_html_tokenizer_state_f)(lxb_html_tokenizer_t *tkz, @@ -90,6 +96,10 @@ struct lxb_html_tokenizer { lxb_status_t status; bool is_eof; + /* Input stream validation (for cross-chunk UTF-8). */ + lxb_char_t utf8_buf[4]; + unsigned utf8_buf_len; + lxb_html_tokenizer_t *base; size_t ref_count; }; @@ -97,8 +107,9 @@ struct lxb_html_tokenizer { #include "lexbor/html/tokenizer/error.h" - -extern const lxb_char_t *lxb_html_tokenizer_eof; +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t *lxb_html_tokenizer_eof; +#endif LXB_API lxb_html_tokenizer_t * lxb_html_tokenizer_create(void); @@ -156,6 +167,11 @@ LXB_API void lxb_html_tokenizer_set_state_by_tag(lxb_html_tokenizer_t *tkz, bool scripting, lxb_tag_id_t tag_id, lxb_ns_id_t ns); +LXB_API void +lxb_html_tokenizer_attr_last_duplicate(lxb_html_tokenizer_t *tkz); + +LXB_API void +lxb_html_tokenizer_validate_close_tag(lxb_html_tokenizer_t *tkz); /* * Inline functions @@ -250,6 +266,28 @@ lxb_html_tokenizer_mraw(lxb_html_tokenizer_t *tkz) return tkz->mraw; } +lxb_inline void +lxb_html_tokenizer_input_validation_set(lxb_html_tokenizer_t *tkz, bool enabled) +{ + if (enabled) { + tkz->opt |= LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT; + } + else { + tkz->opt &= ~LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT; + } +} + +lxb_inline void +lxb_html_tokenizer_keep_duplicate_set(lxb_html_tokenizer_t *tkz, bool keep) +{ + if (keep) { + tkz->opt |= LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE; + } + else { + tkz->opt &= ~LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE; + } +} + lxb_inline lxb_status_t lxb_html_tokenizer_temp_realloc(lxb_html_tokenizer_t *tkz, size_t size) { @@ -331,12 +369,20 @@ LXB_API void lxb_html_tokenizer_tree_set_noi(lxb_html_tokenizer_t *tkz, lxb_html_tree_t *tree); +LXB_API void +lxb_html_tokenizer_input_validation_set_noi(lxb_html_tokenizer_t *tkz, + bool enabled); + LXB_API lexbor_mraw_t * lxb_html_tokenizer_mraw_noi(lxb_html_tokenizer_t *tkz); LXB_API lexbor_hash_t * lxb_html_tokenizer_tags_noi(lxb_html_tokenizer_t *tkz); +LXB_API void +lxb_html_tokenizer_keep_duplicate_set_noi(lxb_html_tokenizer_t *tkz, + bool keep); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/tokenizer/error.c b/ext/lexbor/lexbor/html/tokenizer/error.c index c2381ad97c87..241fac509768 100644 --- a/ext/lexbor/lexbor/html/tokenizer/error.c +++ b/ext/lexbor/lexbor/html/tokenizer/error.c @@ -1,9 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ +#include "lexbor/core/str.h" #include "lexbor/html/tokenizer/error.h" @@ -26,3 +27,76 @@ lxb_html_tokenizer_error_add(lexbor_array_obj_t *parse_errors, return entry; } + +const lxb_char_t * +lxb_html_tokenizer_error_to_string(lxb_html_tokenizer_error_id_t id, + size_t *len) +{ + static const lexbor_str_t unknown = lexbor_str("unknown error"); + + static const lexbor_str_t errors[LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY] = { + lexbor_str("abrupt closing of empty comment"), + lexbor_str("abrupt doctype public identifier"), + lexbor_str("abrupt doctype system identifier"), + lexbor_str("absence of digits in numeric character reference"), + lexbor_str("cdata in html content"), + lexbor_str("character reference outside unicode range"), + lexbor_str("control character in input stream"), + lexbor_str("control character reference"), + lexbor_str("end tag with attributes"), + lexbor_str("duplicate attribute"), + lexbor_str("end tag with trailing solidus"), + lexbor_str("eof before tag name"), + lexbor_str("eof in cdata"), + lexbor_str("eof in comment"), + lexbor_str("eof in doctype"), + lexbor_str("eof in script html comment like text"), + lexbor_str("eof in tag"), + lexbor_str("incorrectly closed comment"), + lexbor_str("incorrectly opened comment"), + lexbor_str("invalid character sequence after doctype name"), + lexbor_str("invalid first character of tag name"), + lexbor_str("missing attribute value"), + lexbor_str("missing doctype name"), + lexbor_str("missing doctype public identifier"), + lexbor_str("missing doctype system identifier"), + lexbor_str("missing end tag name"), + lexbor_str("missing quote before doctype public identifier"), + lexbor_str("missing quote before doctype system identifier"), + lexbor_str("missing semicolon after character reference"), + lexbor_str("missing whitespace after doctype public keyword"), + lexbor_str("missing whitespace after doctype system keyword"), + lexbor_str("missing whitespace before doctype name"), + lexbor_str("missing whitespace between attributes"), + lexbor_str("missing whitespace between doctype public and system identifiers"), + lexbor_str("nested comment"), + lexbor_str("noncharacter character reference"), + lexbor_str("noncharacter in input stream"), + lexbor_str("non void html element start tag with trailing solidus"), + lexbor_str("null character reference"), + lexbor_str("surrogate character reference"), + lexbor_str("surrogate in input stream"), + lexbor_str("unexpected character after doctype system identifier"), + lexbor_str("unexpected character in attribute name"), + lexbor_str("unexpected character in unquoted attribute value"), + lexbor_str("unexpected equals sign before attribute name"), + lexbor_str("unexpected null character"), + lexbor_str("unexpected question mark instead of tag name"), + lexbor_str("unexpected solidus in tag"), + lexbor_str("unknown named character reference") + }; + + if (id >= (sizeof(errors) / sizeof(lexbor_str_t))) { + if (len != NULL) { + *len = unknown.length; + } + + return unknown.data; + } + + if (len != NULL) { + *len = errors[id].length; + } + + return errors[id].data; +} diff --git a/ext/lexbor/lexbor/html/tokenizer/error.h b/ext/lexbor/lexbor/html/tokenizer/error.h index 2685f039d510..617ff636935b 100644 --- a/ext/lexbor/lexbor/html/tokenizer/error.h +++ b/ext/lexbor/lexbor/html/tokenizer/error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -21,102 +21,103 @@ typedef enum { /* abrupt-closing-of-empty-comment */ LXB_HTML_TOKENIZER_ERROR_ABCLOFEMCO = 0x0000, /* abrupt-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_ABDOPUID = 0x0001, + LXB_HTML_TOKENIZER_ERROR_ABDOPUID, /* abrupt-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_ABDOSYID = 0x0002, + LXB_HTML_TOKENIZER_ERROR_ABDOSYID, /* absence-of-digits-in-numeric-character-reference */ - LXB_HTML_TOKENIZER_ERROR_ABOFDIINNUCHRE = 0x0003, + LXB_HTML_TOKENIZER_ERROR_ABOFDIINNUCHRE, /* cdata-in-html-content */ - LXB_HTML_TOKENIZER_ERROR_CDINHTCO = 0x0004, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO, /* character-reference-outside-unicode-range */ - LXB_HTML_TOKENIZER_ERROR_CHREOUUNRA = 0x0005, + LXB_HTML_TOKENIZER_ERROR_CHREOUUNRA, /* control-character-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_COCHININST = 0x0006, + LXB_HTML_TOKENIZER_ERROR_COCHININST, /* control-character-reference */ - LXB_HTML_TOKENIZER_ERROR_COCHRE = 0x0007, + LXB_HTML_TOKENIZER_ERROR_COCHRE, /* end-tag-with-attributes */ - LXB_HTML_TOKENIZER_ERROR_ENTAWIAT = 0x0008, + LXB_HTML_TOKENIZER_ERROR_ENTAWIAT, /* duplicate-attribute */ - LXB_HTML_TOKENIZER_ERROR_DUAT = 0x0009, + LXB_HTML_TOKENIZER_ERROR_DUAT, /* end-tag-with-trailing-solidus */ - LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO = 0x000A, + LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO, /* eof-before-tag-name */ - LXB_HTML_TOKENIZER_ERROR_EOBETANA = 0x000B, + LXB_HTML_TOKENIZER_ERROR_EOBETANA, /* eof-in-cdata */ - LXB_HTML_TOKENIZER_ERROR_EOINCD = 0x000C, + LXB_HTML_TOKENIZER_ERROR_EOINCD, /* eof-in-comment */ - LXB_HTML_TOKENIZER_ERROR_EOINCO = 0x000D, + LXB_HTML_TOKENIZER_ERROR_EOINCO, /* eof-in-doctype */ - LXB_HTML_TOKENIZER_ERROR_EOINDO = 0x000E, + LXB_HTML_TOKENIZER_ERROR_EOINDO, /* eof-in-script-html-comment-like-text */ - LXB_HTML_TOKENIZER_ERROR_EOINSCHTCOLITE = 0x000F, + LXB_HTML_TOKENIZER_ERROR_EOINSCHTCOLITE, /* eof-in-tag */ - LXB_HTML_TOKENIZER_ERROR_EOINTA = 0x0010, + LXB_HTML_TOKENIZER_ERROR_EOINTA, /* incorrectly-closed-comment */ - LXB_HTML_TOKENIZER_ERROR_INCLCO = 0x0011, + LXB_HTML_TOKENIZER_ERROR_INCLCO, /* incorrectly-opened-comment */ - LXB_HTML_TOKENIZER_ERROR_INOPCO = 0x0012, + LXB_HTML_TOKENIZER_ERROR_INOPCO, /* invalid-character-sequence-after-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA = 0x0013, + LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA, /* invalid-first-character-of-tag-name */ - LXB_HTML_TOKENIZER_ERROR_INFICHOFTANA = 0x0014, + LXB_HTML_TOKENIZER_ERROR_INFICHOFTANA, /* missing-attribute-value */ - LXB_HTML_TOKENIZER_ERROR_MIATVA = 0x0015, + LXB_HTML_TOKENIZER_ERROR_MIATVA, /* missing-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_MIDONA = 0x0016, + LXB_HTML_TOKENIZER_ERROR_MIDONA, /* missing-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIDOPUID = 0x0017, + LXB_HTML_TOKENIZER_ERROR_MIDOPUID, /* missing-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIDOSYID = 0x0018, + LXB_HTML_TOKENIZER_ERROR_MIDOSYID, /* missing-end-tag-name */ - LXB_HTML_TOKENIZER_ERROR_MIENTANA = 0x0019, + LXB_HTML_TOKENIZER_ERROR_MIENTANA, /* missing-quote-before-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIQUBEDOPUID = 0x001A, + LXB_HTML_TOKENIZER_ERROR_MIQUBEDOPUID, /* missing-quote-before-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIQUBEDOSYID = 0x001B, + LXB_HTML_TOKENIZER_ERROR_MIQUBEDOSYID, /* missing-semicolon-after-character-reference */ - LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE = 0x001C, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE, /* missing-whitespace-after-doctype-public-keyword */ - LXB_HTML_TOKENIZER_ERROR_MIWHAFDOPUKE = 0x001D, + LXB_HTML_TOKENIZER_ERROR_MIWHAFDOPUKE, /* missing-whitespace-after-doctype-system-keyword */ - LXB_HTML_TOKENIZER_ERROR_MIWHAFDOSYKE = 0x001E, + LXB_HTML_TOKENIZER_ERROR_MIWHAFDOSYKE, /* missing-whitespace-before-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEDONA = 0x001F, + LXB_HTML_TOKENIZER_ERROR_MIWHBEDONA, /* missing-whitespace-between-attributes */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEAT = 0x0020, + LXB_HTML_TOKENIZER_ERROR_MIWHBEAT, /* missing-whitespace-between-doctype-public-and-system-identifiers */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEDOPUANSYID = 0x0021, + LXB_HTML_TOKENIZER_ERROR_MIWHBEDOPUANSYID, /* nested-comment */ - LXB_HTML_TOKENIZER_ERROR_NECO = 0x0022, + LXB_HTML_TOKENIZER_ERROR_NECO, /* noncharacter-character-reference */ - LXB_HTML_TOKENIZER_ERROR_NOCHRE = 0x0023, + LXB_HTML_TOKENIZER_ERROR_NOCHRE, /* noncharacter-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_NOININST = 0x0024, + LXB_HTML_TOKENIZER_ERROR_NOININST, /* non-void-html-element-start-tag-with-trailing-solidus */ - LXB_HTML_TOKENIZER_ERROR_NOVOHTELSTTAWITRSO = 0x0025, + LXB_HTML_TOKENIZER_ERROR_NOVOHTELSTTAWITRSO, /* null-character-reference */ - LXB_HTML_TOKENIZER_ERROR_NUCHRE = 0x0026, + LXB_HTML_TOKENIZER_ERROR_NUCHRE, /* surrogate-character-reference */ - LXB_HTML_TOKENIZER_ERROR_SUCHRE = 0x0027, + LXB_HTML_TOKENIZER_ERROR_SUCHRE, /* surrogate-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_SUININST = 0x0028, + LXB_HTML_TOKENIZER_ERROR_SUININST, /* unexpected-character-after-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_UNCHAFDOSYID = 0x0029, + LXB_HTML_TOKENIZER_ERROR_UNCHAFDOSYID, /* unexpected-character-in-attribute-name */ - LXB_HTML_TOKENIZER_ERROR_UNCHINATNA = 0x002A, + LXB_HTML_TOKENIZER_ERROR_UNCHINATNA, /* unexpected-character-in-unquoted-attribute-value */ - LXB_HTML_TOKENIZER_ERROR_UNCHINUNATVA = 0x002B, + LXB_HTML_TOKENIZER_ERROR_UNCHINUNATVA, /* unexpected-equals-sign-before-attribute-name */ - LXB_HTML_TOKENIZER_ERROR_UNEQSIBEATNA = 0x002C, + LXB_HTML_TOKENIZER_ERROR_UNEQSIBEATNA, /* unexpected-null-character */ - LXB_HTML_TOKENIZER_ERROR_UNNUCH = 0x002D, + LXB_HTML_TOKENIZER_ERROR_UNNUCH, /* unexpected-question-mark-instead-of-tag-name */ - LXB_HTML_TOKENIZER_ERROR_UNQUMAINOFTANA = 0x002E, + LXB_HTML_TOKENIZER_ERROR_UNQUMAINOFTANA, /* unexpected-solidus-in-tag */ - LXB_HTML_TOKENIZER_ERROR_UNSOINTA = 0x002F, + LXB_HTML_TOKENIZER_ERROR_UNSOINTA, /* unknown-named-character-reference */ - LXB_HTML_TOKENIZER_ERROR_UNNACHRE = 0x0030, - LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY = 0x0031, + LXB_HTML_TOKENIZER_ERROR_UNNACHRE, + + LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY } lxb_html_tokenizer_error_id_t; @@ -132,10 +133,13 @@ lxb_html_tokenizer_error_add(lexbor_array_obj_t *parse_errors, const lxb_char_t *pos, lxb_html_tokenizer_error_id_t id); +LXB_API const lxb_char_t * +lxb_html_tokenizer_error_to_string(lxb_html_tokenizer_error_id_t id, + size_t *len); + #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LEXBOR_HTML_TOKENIZER_ERROR_H */ - diff --git a/ext/lexbor/lexbor/html/tokenizer/res.h b/ext/lexbor/lexbor/html/tokenizer/res.h index 5ec5c68bf65d..55c77f9e6c39 100644 --- a/ext/lexbor/lexbor/html/tokenizer/res.h +++ b/ext/lexbor/lexbor/html/tokenizer/res.h @@ -1,12 +1,12 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ /* - * Caution!!! Important!!! - * This file is generated by the script + * Important! + * This file generated by the script * "utils/lexbor/html/tokenizer_entities_bst.py"! * Do not change this file! */ @@ -15,12 +15,6 @@ #ifndef LXB_HTML_TOKENIZER_RES_H #define LXB_HTML_TOKENIZER_RES_H -#endif /* LXB_HTML_TOKENIZER_RES */ - - -#ifdef LXB_HTML_TOKENIZER_RES_ENTITIES_SBST -#ifndef LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED -#define LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED static const lexbor_sbst_entry_static_t lxb_html_tokenizer_res_entities_sbst[] = { {0x00, {0}, 0, 0, 0, 0}, {0x61, {0}, 0, 3, 2, 53}, @@ -4951,6 +4945,6 @@ static const lexbor_sbst_entry_static_t lxb_html_tokenizer_res_entities_sbst[] = {0x3b, "\xd1\x8e", 2, 0, 0, 0}, {0x70, {0}, 0, 0, 0, 9852}, {0x66, {0}, 0, 0, 0, 9853}, {0x3b, "\xf0\x9d\x95\xaa", 4, 0, 0, 0} }; -#endif /* LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED */ -#endif /* LXB_HTML_TOKENIZER_RES_ENTITIES_SBST */ + +#endif /* LXB_HTML_TOKENIZER_RES */ diff --git a/ext/lexbor/lexbor/html/tokenizer/state.c b/ext/lexbor/lexbor/html/tokenizer/state.c index 207b909a1892..6c3cbebe92a3 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state.c +++ b/ext/lexbor/lexbor/html/tokenizer/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,16 +8,16 @@ #include "lexbor/html/tokenizer/state_comment.h" #include "lexbor/html/tokenizer/state_doctype.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#define LEXBOR_STR_RES_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" -#include "lexbor/core/swar.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alphanumeric_character[256]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const size_t lexbor_str_res_replacement_character[160]; +#endif -#define LXB_HTML_TOKENIZER_RES_ENTITIES_SBST +#include "lexbor/core/swar.h" #include "lexbor/html/tokenizer/res.h" @@ -123,11 +123,6 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, const lxb_char_t *end); /* CDATA Section */ -static const lxb_char_t * -lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, - const lxb_char_t *data, - const lxb_char_t *end); - static const lxb_char_t * lxb_html_tokenizer_state_cdata_section(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, @@ -282,7 +277,7 @@ lxb_html_tokenizer_state_data(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_token_set_end_eof(tkz); } - if (tkz->token->begin != tkz->token->end) { + if (tkz->pos != tkz->start) { tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_append_data_m(tkz, data); @@ -381,7 +376,7 @@ lxb_html_tokenizer_state_plaintext(lxb_html_tokenizer_t *tkz, } lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1451,8 +1446,8 @@ lxb_html_tokenizer_state_markup_declaration_open(lxb_html_tokenizer_t *tkz, else if (*data == 0x5B) { if ((end - data) < 7) { tkz->markup = (lxb_char_t *) "[CDATA["; - tkz->state = lxb_html_tokenizer_state_markup_declaration_cdata; + return data; } @@ -1469,6 +1464,9 @@ lxb_html_tokenizer_state_markup_declaration_open(lxb_html_tokenizer_t *tkz, return data; } + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO); + tkz->state = lxb_html_tokenizer_state_bogus_comment_before; return data; @@ -1504,6 +1502,8 @@ lxb_html_tokenizer_state_markup_declaration_comment(lxb_html_tokenizer_t *tkz, return (data + 1); } + lxb_html_tokenizer_state_append_m(tkz, "-", 1); + lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INOPCO); @@ -1538,6 +1538,8 @@ lxb_html_tokenizer_state_markup_declaration_doctype(lxb_html_tokenizer_t *tkz, return data; } + lxb_html_tokenizer_state_append_m(tkz, data, (end - data)); + tkz->markup = pos; return end; @@ -1575,6 +1577,9 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_append_m(tkz, "[CDATA", 6); + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO); + tkz->state = lxb_html_tokenizer_state_bogus_comment_before; return data; } @@ -1587,7 +1592,7 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, /* * Helper function. No in the specification. For 12.2.5.69 */ -static const lxb_char_t * +const lxb_char_t * lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) @@ -1661,7 +1666,7 @@ lxb_html_tokenizer_state_cdata_section(lxb_html_tokenizer_t *tkz, } lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1726,7 +1731,7 @@ lxb_html_tokenizer_state_cdata_section_end(lxb_html_tokenizer_t *tkz, tkz->state = lxb_html_tokenizer_state_data_before; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return (data + 1); } @@ -1857,9 +1862,28 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, */ /* U+003B SEMICOLON character (;) */ if (tkz->is_attribute && tkz->entity_match->key != 0x3B) { + lxb_char_t ch; + + /* + * The "next input character" per the spec is the character immediately + * after the matched entity, not the character that broke the SBST + * lookup. For example, for "¬i;" the match is "¬" + * and the next input character is 'i', not ';'. + * + * If there are trailing characters in the buffer after the match, + * the next input character is the first one after entity_end. + * Otherwise it is *data (the character that terminated the SBST). + */ + if (&tkz->start[tkz->entity_end + 1] < tkz->pos) { + ch = tkz->start[tkz->entity_end + 1]; + } + else { + ch = *data; + } + /* U+003D EQUALS SIGN character (=) or ASCII alphanumeric */ - if (*data == 0x3D - || lexbor_str_res_alphanumeric_character[*data] != LEXBOR_STR_RES_SLIP) + if (ch == 0x3D + || lexbor_str_res_alphanumeric_character[ch] != LEXBOR_STR_RES_SLIP) { return data; } @@ -1902,16 +1926,30 @@ lxb_html_tokenizer_state_char_ref_ambiguous_ampersand(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) { - /* ASCII alphanumeric */ - /* Skipped, not need */ + const lxb_char_t *begin = data; - /* U+003B SEMICOLON (;) */ - if (*data == 0x3B) { - lxb_html_tokenizer_error_add(tkz->parse_errors, data, - LXB_HTML_TOKENIZER_ERROR_UNNACHRE); + while (data < end) { + /* Not ASCII alphanumeric */ + if (lexbor_str_res_alphanumeric_character[ *data ] == LEXBOR_STR_RES_SLIP) { + lxb_html_tokenizer_state_append_m(tkz, begin, (data - begin)); + + /* U+003B SEMICOLON (;) */ + if (*data == 0x3B) { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_UNNACHRE); + } + + tkz->state = tkz->state_return; + + return data; + } + + data += 1; } - tkz->state = tkz->state_return; + if (begin < data) { + lxb_html_tokenizer_state_append_m(tkz, begin, (data - begin)); + } return data; } @@ -2002,6 +2040,10 @@ lxb_html_tokenizer_state_char_ref_hexademical(lxb_html_tokenizer_t *tkz, if (*data == ';') { data++; } + else { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE); + } return lxb_html_tokenizer_state_char_ref_numeric_end(tkz, data, end); } @@ -2032,6 +2074,10 @@ lxb_html_tokenizer_state_char_ref_decimal(lxb_html_tokenizer_t *tkz, if (*data == ';') { data++; } + else { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE); + } return lxb_html_tokenizer_state_char_ref_numeric_end(tkz, data, end); } diff --git a/ext/lexbor/lexbor/html/tokenizer/state.h b/ext/lexbor/lexbor/html/tokenizer/state.h index 5b095b4249d5..52eaa9a2c07b 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state.h +++ b/ext/lexbor/lexbor/html/tokenizer/state.h @@ -110,6 +110,10 @@ extern "C" { #define lxb_html_tokenizer_state_token_attr_add_m(tkz, attr, v_return) \ do { \ + if (!(tkz->opt & LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE)) { \ + lxb_html_tokenizer_attr_last_duplicate(tkz); \ + } \ + \ attr = lxb_html_token_attr_append(tkz->token, tkz->dobj_token_attr); \ if (attr == NULL) { \ tkz->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; \ @@ -145,6 +149,14 @@ extern "C" { (tkz->token->attr_last->value_end = tkz->last) #define _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ + if (!(tkz->opt & LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE)) { \ + lxb_html_tokenizer_attr_last_duplicate(tkz); \ + } \ + \ + if (tkz->token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { \ + lxb_html_tokenizer_validate_close_tag(tkz); \ + } \ + \ tkz->token = tkz->callback_token_done(tkz, tkz->token, \ tkz->callback_token_ctx); \ if (tkz->token == NULL) { \ @@ -154,23 +166,32 @@ extern "C" { return v_end; \ } -#define lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ +#define lxb_html_tokenizer_state_token_text_done_m(tkz, v_end) \ do { \ - if (tkz->token->begin != tkz->token->end) { \ - _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ + if (tkz->token->text_start != tkz->token->text_end) { \ + _lxb_html_tokenizer_state_token_done_m(tkz, v_end); \ } \ lxb_html_token_clean(tkz->token); \ tkz->pos = tkz->start; \ } \ while (0) -#define lxb_html_tokenizer_state_token_done_wo_check_m(tkz, v_end) \ +#define lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ do { \ _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ lxb_html_token_clean(tkz->token); \ + tkz->pos = tkz->start; \ } \ while (0) +/* + * This macro is alias; it serves to ensure that when reading the code, + * we clearly understand where checks are not necessary, i.e., we are 100% sure + * that the token has been collected and is ready to be sent. + */ +#define lxb_html_tokenizer_state_token_done_wo_check_m(tkz, v_end) \ + lxb_html_tokenizer_state_token_done_m(tkz, v_end) + #define lxb_html_tokenizer_state_set_text(tkz) \ do { \ tkz->token->text_start = tkz->start; \ @@ -180,7 +201,7 @@ extern "C" { #define lxb_html_tokenizer_state_token_emit_text_not_empty_m(tkz, v_end) \ do { \ - if (tkz->token->begin != tkz->token->end) { \ + if (tkz->start != tkz->pos) { \ tkz->token->tag_id = LXB_TAG__TEXT; \ \ lxb_html_tokenizer_state_set_text(tkz); \ @@ -211,6 +232,11 @@ lxb_html_tokenizer_state_self_closing_start_tag(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end); +LXB_API const lxb_char_t * +lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, + const lxb_char_t *data, + const lxb_char_t *end); + LXB_API const lxb_char_t * lxb_html_tokenizer_state_cr(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end); diff --git a/ext/lexbor/lexbor/html/tokenizer/state_comment.c b/ext/lexbor/lexbor/html/tokenizer/state_comment.c index fd1c2ead980b..870b54578c62 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_comment.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_comment.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,9 +7,9 @@ #include "lexbor/html/tokenizer/state_comment.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN +LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif static const lxb_char_t * lxb_html_tokenizer_state_comment_start(lxb_html_tokenizer_t *tkz, @@ -143,8 +143,6 @@ lxb_html_tokenizer_state_comment_start_dash(lxb_html_tokenizer_t *tkz, /* EOF */ else if (*data == 0x00) { if (tkz->is_eof) { - lxb_html_tokenizer_state_append_m(tkz, "-", 1); - lxb_html_tokenizer_error_add(tkz->parse_errors, tkz->last, LXB_HTML_TOKENIZER_ERROR_EOINCO); @@ -452,8 +450,12 @@ lxb_html_tokenizer_state_comment_end_bang(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) { + static const lexbor_str_t two = lexbor_str("--!"); + /* U+002D HYPHEN-MINUS (-) */ if (*data == 0x2D) { + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); + tkz->state = lxb_html_tokenizer_state_comment_end_dash; return (data + 1); @@ -481,6 +483,11 @@ lxb_html_tokenizer_state_comment_end_bang(lxb_html_tokenizer_t *tkz, return end; } + + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); + } + else { + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); } tkz->state = lxb_html_tokenizer_state_comment; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_doctype.c b/ext/lexbor/lexbor/html/tokenizer/state_doctype.c index 90466789cc09..7ccb02e08b2a 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_doctype.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_doctype.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,9 @@ #include "lexbor/html/tokenizer/state_doctype.h" #include "lexbor/html/tokenizer/state.h" - -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif lxb_dom_attr_data_t * lxb_dom_attr_local_name_append(lexbor_hash_t *hash, @@ -527,6 +526,7 @@ lxb_html_tokenizer_state_doctype_after_name_public(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA); + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; tkz->state = lxb_html_tokenizer_state_doctype_bogus; return data; @@ -577,6 +577,7 @@ lxb_html_tokenizer_state_doctype_after_name_system(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA); + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; tkz->state = lxb_html_tokenizer_state_doctype_bogus; return data; @@ -797,6 +798,7 @@ lxb_html_tokenizer_state_doctype_public_identifier_double_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOPUID); @@ -912,6 +914,7 @@ lxb_html_tokenizer_state_doctype_public_identifier_single_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOPUID); @@ -1350,6 +1353,7 @@ lxb_html_tokenizer_state_doctype_system_identifier_double_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOSYID); @@ -1465,6 +1469,7 @@ lxb_html_tokenizer_state_doctype_system_identifier_single_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOSYID); diff --git a/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c b/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c index 6629ca910342..456266b6e33a 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/html/tokenizer/state_rawtext.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -114,7 +114,7 @@ lxb_html_tokenizer_state_rawtext(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -246,7 +246,7 @@ lxb_html_tokenizer_state_rawtext_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -291,7 +291,7 @@ lxb_html_tokenizer_state_rawtext_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c b/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c index f47dc7e87a22..02e68b324546 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/html/tokenizer/state_rcdata.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -123,7 +123,7 @@ lxb_html_tokenizer_state_rcdata(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -255,7 +255,7 @@ lxb_html_tokenizer_state_rcdata_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -300,7 +300,7 @@ lxb_html_tokenizer_state_rcdata_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_script.c b/ext/lexbor/lexbor/html/tokenizer/state_script.c index 4d56d18f7f3f..26e694f8f517 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_script.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_script.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,12 +7,11 @@ #include "lexbor/html/tokenizer/state_script.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const size_t lexbor_str_res_replacement_character[160]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -203,7 +202,7 @@ lxb_html_tokenizer_state_script_data(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -347,7 +346,7 @@ lxb_html_tokenizer_state_script_data_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -391,7 +390,7 @@ lxb_html_tokenizer_state_script_data_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -517,7 +516,7 @@ lxb_html_tokenizer_state_script_data_escaped(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -581,7 +580,7 @@ lxb_html_tokenizer_state_script_data_escaped_dash(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -758,7 +757,7 @@ lxb_html_tokenizer_state_script_data_escaped_end_tag_name( tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -802,7 +801,7 @@ lxb_html_tokenizer_state_script_data_escaped_end_tag_name( tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -947,7 +946,7 @@ lxb_html_tokenizer_state_script_data_double_escaped(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1011,7 +1010,7 @@ lxb_html_tokenizer_state_script_data_double_escaped_dash(lxb_html_tokenizer_t *t lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1077,7 +1076,7 @@ lxb_html_tokenizer_state_script_data_double_escaped_dash_dash( lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } diff --git a/ext/lexbor/lexbor/html/tree.c b/ext/lexbor/lexbor/html/tree.c index 91bfd17ee1db..3f4c18d7fa40 100644 --- a/ext/lexbor/lexbor/html/tree.c +++ b/ext/lexbor/lexbor/html/tree.c @@ -19,6 +19,7 @@ #include "lexbor/html/interface.h" #include "lexbor/html/interfaces/template_element.h" #include "lexbor/html/interfaces/unknown_element.h" +#include "lexbor/html/interfaces/option_element.h" #include "lexbor/html/tokenizer/state_rawtext.h" #include "lexbor/html/tokenizer/state_rcdata.h" @@ -390,7 +391,8 @@ lxb_html_tree_appropriate_place_inserting_node(lxb_html_tree_t *tree, lxb_html_element_t * lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, - lxb_html_token_t *token, lxb_ns_id_t ns) + lxb_html_token_t *token, lxb_ns_id_t ns, + bool only_add_stack) { lxb_status_t status; lxb_dom_node_t *pos; @@ -407,7 +409,9 @@ lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, return NULL; } - lxb_html_tree_insert_node(pos, lxb_dom_interface_node(element), ipos); + if (only_add_stack == false) { + lxb_html_tree_insert_node(pos, lxb_dom_interface_node(element), ipos); + } status = lxb_html_tree_open_elements_push(tree, lxb_dom_interface_node(element)); @@ -1033,44 +1037,7 @@ lxb_html_tree_reset_insertion_mode_appropriately(lxb_html_tree_t *tree) continue; } - /* Step 4 */ - if (node->local_name == LXB_TAG_SELECT) { - /* Step 4.1 */ - if (last) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.2 */ - size_t ancestor = idx; - - for (;;) { - /* Step 4.3 */ - if (ancestor == 0) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.4 */ - ancestor--; - - /* Step 4.5 */ - lxb_dom_node_t *ancestor_node = list[ancestor]; - - if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TEMPLATE)) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.6 */ - else if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TABLE)) { - tree->mode = lxb_html_tree_insertion_mode_in_select_in_table; - return; - } - } - } - - /* Step 5-15 */ + /* Step 4-15 */ switch (node->local_name) { case LXB_TAG_TD: case LXB_TAG_TH: @@ -1309,6 +1276,41 @@ lxb_html_tree_element_in_scope_td_th(lxb_html_tree_t *tree) return NULL; } +lxb_dom_node_t * +lxb_html_tree_element_in_scope_option_optgroup(lxb_html_tree_t *tree) +{ + lxb_dom_node_t *node; + + size_t idx = tree->open_elements->length; + void **list = tree->open_elements->list; + + while (idx != 0) { + idx--; + node = list[idx]; + + switch (node->local_name) { + case LXB_TAG_OPTION: + case LXB_TAG_OPTGROUP: + if (node->ns == LXB_NS_HTML) { + return node; + } + + break; + + default: + break; + } + + if (lxb_html_tag_is_category(node->local_name, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE)) + { + return NULL; + } + } + + return NULL; +} + bool lxb_html_tree_check_scope_element(lxb_html_tree_t *tree) { @@ -1362,8 +1364,6 @@ lxb_html_tree_close_p_element(lxb_html_tree_t *tree, lxb_html_token_t *token) true); } -#include "lexbor/html/serialize.h" - bool lxb_html_tree_adoption_agency_algorithm(lxb_html_tree_t *tree, lxb_html_token_t *token, diff --git a/ext/lexbor/lexbor/html/tree.h b/ext/lexbor/lexbor/html/tree.h index 8ad32a4c1bec..7b2c62030497 100644 --- a/ext/lexbor/lexbor/html/tree.h +++ b/ext/lexbor/lexbor/html/tree.h @@ -114,7 +114,8 @@ lxb_html_tree_appropriate_place_inserting_node(lxb_html_tree_t *tree, LXB_API lxb_html_element_t * lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, - lxb_html_token_t *token, lxb_ns_id_t ns); + lxb_html_token_t *token, lxb_ns_id_t ns, + bool only_add_stack); LXB_API lxb_html_element_t * lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, @@ -201,6 +202,9 @@ lxb_html_tree_element_in_scope_tbody_thead_tfoot(lxb_html_tree_t *tree); LXB_API lxb_dom_node_t * lxb_html_tree_element_in_scope_td_th(lxb_html_tree_t *tree); +LXB_API lxb_dom_node_t * +lxb_html_tree_element_in_scope_option_optgroup(lxb_html_tree_t *tree); + LXB_API bool lxb_html_tree_check_scope_element(lxb_html_tree_t *tree); @@ -307,7 +311,8 @@ lxb_inline lxb_html_element_t * lxb_html_tree_insert_html_element(lxb_html_tree_t *tree, lxb_html_token_t *token) { - return lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_HTML); + return lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_HTML, + false); } lxb_inline void @@ -374,6 +379,21 @@ lxb_html_tree_attach_document(lxb_html_tree_t *tree, lxb_html_document_t *doc) tree->document = doc; } +lxb_inline bool +lxb_html_tree_is_fragment(lxb_html_tree_t *tree) +{ + return tree->fragment != NULL; +} + +lxb_inline bool +lxb_html_tree_is_fragment_element(lxb_html_tree_t *tree, + lxb_tag_id_t tag_id, lxb_ns_id_t ns) +{ + lxb_dom_node_t *fragment = tree->fragment; + + return lxb_html_tree_is_fragment(tree) + && fragment->local_name == tag_id && fragment->ns == ns; +} #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/tree/error.c b/ext/lexbor/lexbor/html/tree/error.c index 88ad8c44795a..ef36eab8d228 100644 --- a/ext/lexbor/lexbor/html/tree/error.c +++ b/ext/lexbor/lexbor/html/tree/error.c @@ -1,9 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ +#include "lexbor/core/str.h" #include "lexbor/html/tree/error.h" @@ -27,3 +28,68 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, return entry; } + +const lxb_char_t * +lxb_html_tree_error_to_string(lxb_html_tree_error_id_t id, size_t *len) +{ + static const lexbor_str_t unknown = lexbor_str("unknown error"); + + static const lexbor_str_t errors[LXB_HTML_RULES_ERROR_LAST_ENTRY] = { + lexbor_str("unexpected token"), + lexbor_str("unexpected closed token"), + lexbor_str("null character"), + lexbor_str("unexpected character token"), + lexbor_str("unexpected token in initial mode"), + lexbor_str("bad doctype token in initial mode"), + lexbor_str("doctype token in before html mode"), + lexbor_str("unexpected closed token in before html mode"), + lexbor_str("doctype token in before head mode"), + lexbor_str("unexpected closed token in before head mode"), + lexbor_str("doctype token in head mode"), + lexbor_str("non void html element start tag with trailing solidus"), + lexbor_str("head token in head mode"), + lexbor_str("unexpected closed token in head mode"), + lexbor_str("template closed token without opening in head mode"), + lexbor_str("template element is not current in head mode"), + lexbor_str("doctype token in head noscript mode"), + lexbor_str("doctype token after head mode"), + lexbor_str("head token after head mode"), + lexbor_str("doctype token in body mode"), + lexbor_str("bad ending open elements is wrong"), + lexbor_str("open elements is wrong"), + lexbor_str("unexpected element in open elements stack"), + lexbor_str("missing element in open elements stack"), + lexbor_str("no body element in scope"), + lexbor_str("missing element in scope"), + lexbor_str("unexpected element in scope"), + lexbor_str("unexpected element in active formatting stack"), + lexbor_str("unexpected end of file"), + lexbor_str("characters in table text"), + lexbor_str("doctype token in table mode"), + lexbor_str("doctype token in select mode"), + lexbor_str("doctype token after body mode"), + lexbor_str("doctype token in frameset mode"), + lexbor_str("doctype token after frameset mode"), + lexbor_str("doctype token foreign content mode"), + lexbor_str("select in scope"), + lexbor_str("fragment parsing select in context parse input"), + lexbor_str("fragment parsing select in context parse select"), + lexbor_str("hr parsing select option optgroup in scope"), + lexbor_str("option parsing option in scope"), + lexbor_str("optgroup parsing option optgroup in scope") + }; + + if (id >= (sizeof(errors) / sizeof(lexbor_str_t))) { + if (len != NULL) { + *len = unknown.length; + } + + return unknown.data; + } + + if (len != NULL) { + *len = errors[id].length; + } + + return errors[id].data; +} diff --git a/ext/lexbor/lexbor/html/tree/error.h b/ext/lexbor/lexbor/html/tree/error.h index ed1859f355a6..b1867725ef98 100644 --- a/ext/lexbor/lexbor/html/tree/error.h +++ b/ext/lexbor/lexbor/html/tree/error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -90,6 +90,18 @@ typedef enum { LXB_HTML_RULES_ERROR_DOTOAFFRMO, /* doctype-token-foreign-content-mode */ LXB_HTML_RULES_ERROR_DOTOFOCOMO, + /* select-in-scope */ + LXB_HTML_RULES_ERROR_SEINSC, + /* fragment-parsing-select-in-context-parse-input */ + LXB_HTML_RULES_ERROR_FRPASEINCOPAIN, + /* fragment-parsing-select-in-context-parse-select */ + LXB_HTML_RULES_ERROR_FRPASEINCOPASE, + /* hr-parsing-select-option-optgroup-in-scope */ + LXB_HTML_RULES_ERROR_HRPASEOPOPINSC, + /* option-parsing-option-in-scope */ + LXB_HTML_RULES_ERROR_OPPAOPINSC, + /* optgroup-parsing-option-optgroup-in-scope */ + LXB_HTML_RULES_ERROR_OPPAOPOPINSC, LXB_HTML_RULES_ERROR_LAST_ENTRY } @@ -108,10 +120,12 @@ LXB_API lxb_html_tree_error_t * lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, lxb_html_token_t *token, lxb_html_tree_error_id_t id); +LXB_API const lxb_char_t * +lxb_html_tree_error_to_string(lxb_html_tree_error_id_t id, size_t *len); + #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LEXBOR_HTML_TREE_ERROR_H */ - diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode.h b/ext/lexbor/lexbor/html/tree/insertion_mode.h index 97cc29fa6aad..5817f3c015fd 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode.h +++ b/ext/lexbor/lexbor/html/tree/insertion_mode.h @@ -91,14 +91,6 @@ LXB_API bool lxb_html_tree_insertion_mode_in_cell(lxb_html_tree_t *tree, lxb_html_token_t *token); -LXB_API bool -lxb_html_tree_insertion_mode_in_select(lxb_html_tree_t *tree, - lxb_html_token_t *token); - -LXB_API bool -lxb_html_tree_insertion_mode_in_select_in_table(lxb_html_tree_t *tree, - lxb_html_token_t *token); - LXB_API bool lxb_html_tree_insertion_mode_in_template(lxb_html_tree_t *tree, lxb_html_token_t *token); diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c b/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c index 900557a59c33..7e546e34fd9c 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,10 +8,10 @@ #include "lexbor/html/tree/open_elements.h" #include "lexbor/html/interfaces/element.h" -#define LEXBOR_TOKENIZER_CHARS_MAP -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const unsigned char lexbor_tokenizer_chars_map[256]; +#endif lxb_status_t lxb_dom_element_qualified_name_set(lxb_dom_element_t *element, @@ -87,7 +87,8 @@ lxb_html_tree_insertion_mode_foreign_content_anything_else(lxb_html_tree_t *tree tree->before_append_attr = lxb_html_tree_adjust_attributes_svg; } - element = lxb_html_tree_insert_foreign_element(tree, token, node->ns); + element = lxb_html_tree_insert_foreign_element(tree, token, node->ns, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -259,22 +260,19 @@ lxb_html_tree_insertion_mode_foreign_content_all(lxb_html_tree_t *tree, lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - if (tree->fragment != NULL) { - return lxb_html_tree_insertion_mode_foreign_content_anything_else(tree, - token); - } + node = lxb_html_tree_current_node(tree); - do { + while (node != NULL && + !(lxb_html_tree_mathml_text_integration_point(node) + || lxb_html_tree_html_integration_point(node) + || node->ns == LXB_NS_HTML)) + { lxb_html_tree_open_elements_pop(tree); node = lxb_html_tree_current_node(tree); } - while (node && - !(lxb_html_tree_mathml_text_integration_point(node) - || lxb_html_tree_html_integration_point(node) - || node->ns == LXB_NS_HTML)); - return false; + return tree->mode(tree, token); } bool @@ -286,6 +284,10 @@ lxb_html_tree_insertion_mode_foreign_content(lxb_html_tree_t *tree, case LXB_TAG_SCRIPT: return lxb_html_tree_insertion_mode_foreign_content_script_closed(tree, token); + case LXB_TAG_P: + case LXB_TAG_BR: + return lxb_html_tree_insertion_mode_foreign_content_all(tree, + token); default: return lxb_html_tree_insertion_mode_foreign_content_anything_else_closed(tree, token); diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c index 32cc40476948..38610c7cdd27 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c @@ -1,19 +1,25 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ -#define LEXBOR_TOKENIZER_CHARS_MAP -#include "lexbor/core/str_res.h" - #include "lexbor/html/tree/insertion_mode.h" #include "lexbor/html/tree/open_elements.h" #include "lexbor/html/tree/active_formatting.h" #include "lexbor/html/interfaces/head_element.h" +#include "lexbor/html/interfaces/option_element.h" #include "lexbor/html/tokenizer/state.h" +#include "lexbor/html/parser.h" #include "lexbor/html/tokenizer/state_rcdata.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const unsigned char lexbor_tokenizer_chars_map[256]; +#endif + +static bool +lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t *tree, + lxb_html_token_t *token); /* * User case insertion mode. @@ -691,7 +697,7 @@ lxb_html_tree_insertion_mode_in_body_button(lxb_html_tree_t *tree, * "address", "article", "aside", "blockquote", "button", "center", "details", * "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", * "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", "section", - * "summary", "ul" + * "select", "summary", "ul" */ lxb_inline bool lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(lxb_html_tree_t *tree, @@ -1204,13 +1210,63 @@ lxb_html_tree_insertion_mode_in_body_br_closed(lxb_html_tree_t *tree, return lxb_html_tree_insertion_mode_in_body_abeikw(tree, token); } +lxb_inline bool +lxb_html_tree_insertion_mode_in_body_option_closed(lxb_html_tree_t *tree, + lxb_html_token_t *token) +{ + bool is; + size_t index; + lxb_dom_node_t *node; + lxb_html_option_element_t *option; + lxb_dom_exception_code_t code; + + node = lxb_html_tree_open_elements_find_reverse(tree, LXB_TAG_OPTION, + LXB_NS_HTML, &index); + + lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree, token); + + if (node != NULL) { + is = lxb_html_tree_open_elements_find_by_node(tree, node, &index); + + if (!is) { + option = lxb_html_interface_option(node); + + code = lxb_html_option_maybe_clone_to_selectedcontent(option); + if (code != LXB_DOM_EXCEPTION_OK) { + tree->status = LXB_STATUS_ERROR; + + return lxb_html_tree_process_abort(tree); + } + } + } + + return true; +} + lxb_inline bool lxb_html_tree_insertion_mode_in_body_input(lxb_html_tree_t *tree, lxb_html_token_t *token) { + bool is; + lxb_dom_node_t *node; lxb_dom_attr_t *attr; lxb_html_element_t *element; + is = lxb_html_tree_is_fragment_element(tree, LXB_TAG_SELECT, LXB_NS_HTML); + if (is) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_FRPASEINCOPAIN); + return true; + } + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_SEINSC); + lxb_html_tree_open_elements_pop_until_node(tree, node, true); + } + + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); if (tree->status != LXB_STATUS_OK) { return lxb_html_tree_process_abort(tree); @@ -1277,6 +1333,19 @@ lxb_html_tree_insertion_mode_in_body_hr(lxb_html_tree_t *tree, lxb_html_tree_close_p_element(tree, token); } + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF, + LXB_NS__UNDEF); + + node = lxb_html_tree_element_in_scope_option_optgroup(tree); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_HRPASEOPOPINSC); + } + } + element = lxb_html_tree_insert_html_element(tree, token); if (element == NULL) { tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1396,8 +1465,25 @@ lxb_inline bool lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t *tree, lxb_html_token_t *token) { + bool is; + lxb_dom_node_t *node; lxb_html_element_t *element; + is = lxb_html_tree_is_fragment_element(tree, LXB_TAG_SELECT, LXB_NS_HTML); + if (is) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_FRPASEINCOPASE); + return true; + } + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_SEINSC); + lxb_html_tree_open_elements_pop_until_node(tree, node, true); + return true; + } + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); if (tree->status != LXB_STATUS_OK) { return lxb_html_tree_process_abort(tree); @@ -1412,34 +1498,81 @@ lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t *tree, tree->frameset_ok = false; - if (tree->mode == lxb_html_tree_insertion_mode_in_table - || tree->mode == lxb_html_tree_insertion_mode_in_caption - || tree->mode == lxb_html_tree_insertion_mode_in_table_body - || tree->mode == lxb_html_tree_insertion_mode_in_row - || tree->mode == lxb_html_tree_insertion_mode_in_cell) - { - tree->mode = lxb_html_tree_insertion_mode_in_select_in_table; + return true; +} + +/* + * "option" + */ +lxb_inline bool +lxb_html_tree_insertion_mode_in_body_option(lxb_html_tree_t *tree, + lxb_html_token_t *token) +{ + lxb_dom_node_t *node; + lxb_html_element_t *element; + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_OPTGROUP, + LXB_NS_HTML); + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_OPTION, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_OPPAOPINSC); + } } else { - tree->mode = lxb_html_tree_insertion_mode_in_select; + node = lxb_html_tree_current_node(tree); + if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { + lxb_html_tree_open_elements_pop(tree); + } + } + + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); + if (tree->status != LXB_STATUS_OK) { + return lxb_html_tree_process_abort(tree); + } + + element = lxb_html_tree_insert_html_element(tree, token); + if (element == NULL) { + tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + + return lxb_html_tree_process_abort(tree); } return true; } /* - * "optgroup", "option" + * "optgroup" */ lxb_inline bool -lxb_html_tree_insertion_mode_in_body_optopt(lxb_html_tree_t *tree, - lxb_html_token_t *token) +lxb_html_tree_insertion_mode_in_body_optgroup(lxb_html_tree_t *tree, + lxb_html_token_t *token) { lxb_dom_node_t *node; lxb_html_element_t *element; - node = lxb_html_tree_current_node(tree); - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF, + LXB_NS__UNDEF); + + node = lxb_html_tree_element_in_scope_option_optgroup(tree); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_OPPAOPOPINSC); + } + } + else { + node = lxb_html_tree_current_node(tree); + if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { + lxb_html_tree_open_elements_pop(tree); + } } tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); @@ -1539,7 +1672,8 @@ lxb_html_tree_insertion_mode_in_body_math(lxb_html_tree_t *tree, tree->before_append_attr = lxb_html_tree_adjust_attributes_mathml; - element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_MATH); + element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_MATH, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1570,7 +1704,8 @@ lxb_html_tree_insertion_mode_in_body_svg(lxb_html_tree_t *tree, tree->before_append_attr = lxb_html_tree_adjust_attributes_svg; - element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_SVG); + element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_SVG, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1643,7 +1778,7 @@ lxb_html_tree_insertion_mode_in_body_noscript(lxb_html_tree_t *tree, return true; } -lxb_inline bool +static bool lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t *tree, lxb_html_token_t *token) { @@ -1719,7 +1854,9 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_NAV: case LXB_TAG_OL: case LXB_TAG_PRE: + case LXB_TAG_SEARCH: case LXB_TAG_SECTION: + case LXB_TAG_SELECT: case LXB_TAG_SUMMARY: case LXB_TAG_UL: return lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(tree, @@ -1770,6 +1907,10 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, return lxb_html_tree_insertion_mode_in_body_br_closed(tree, token); + case LXB_TAG_OPTION: + return lxb_html_tree_insertion_mode_in_body_option_closed(tree, + token); + default: return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree, token); @@ -1831,6 +1972,7 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_NAV: case LXB_TAG_OL: case LXB_TAG_P: + case LXB_TAG_SEARCH: case LXB_TAG_SECTION: case LXB_TAG_SUMMARY: case LXB_TAG_UL: @@ -1934,9 +2076,11 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_SELECT: return lxb_html_tree_insertion_mode_in_body_select(tree, token); - case LXB_TAG_OPTGROUP: case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_body_optopt(tree, token); + return lxb_html_tree_insertion_mode_in_body_option(tree, token); + + case LXB_TAG_OPTGROUP: + return lxb_html_tree_insertion_mode_in_body_optgroup(tree, token); case LXB_TAG_RB: case LXB_TAG_RTC: diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c index 78e4c5919fe7..1b40ecf62d86 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c @@ -101,6 +101,13 @@ lxb_html_tree_insertion_mode_in_head_noscript_closed(lxb_html_tree_t *tree, token); } + if (token->tag_id == LXB_TAG_NOSCRIPT) { + lxb_html_tree_open_elements_pop(tree); + tree->mode = lxb_html_tree_insertion_mode_in_head; + + return true; + } + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); return true; diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c deleted file mode 100644 index b4eed2c5d3a8..000000000000 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2018-2020 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/tree/insertion_mode.h" -#include "lexbor/html/tree/open_elements.h" - - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_text(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lexbor_str_t str; - - if (token->null_count != 0) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_NUCH); - - tree->status = lxb_html_token_make_text_drop_null(token, &str, - tree->document->dom_document.text); - } - else { - tree->status = lxb_html_token_make_text(token, &str, - tree->document->dom_document.text); - } - - if (tree->status != LXB_STATUS_OK) { - return lxb_html_tree_process_abort(tree); - } - - /* Can be zero only if all NULL are gone */ - if (str.length == 0) { - lexbor_str_destroy(&str, tree->document->dom_document.text, false); - - return true; - } - - tree->status = lxb_html_tree_insert_character_for_data(tree, &str, NULL); - if (tree->status != LXB_STATUS_OK) { - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_comment(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_comment_t *comment; - - comment = lxb_html_tree_insert_comment(tree, token, NULL); - if (comment == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_doctype(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_DOTOINSEMO); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_html(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_body(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_option(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_optgroup(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_hr(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - lxb_html_tree_open_elements_pop(tree); - - lxb_html_tree_acknowledge_token_self_closing(tree, token); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_optgroup_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION) - && tree->open_elements->length > 1) - { - node = lxb_html_tree_open_elements_get(tree, - tree->open_elements->length - 2); - if (node != NULL && lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP) == false) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_UNELINOPELST); - return true; - } - - lxb_html_tree_open_elements_pop(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_option_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION) == false) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_UNELINOPELST); - return true; - } - - lxb_html_tree_open_elements_pop(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_select_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_select(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return true; -} - -/* - * "input", "keygen", "textarea" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_ikt(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -/* - * A start tag whose tag name is one of: "script", "template" - * An end tag whose tag name is "template" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_st_open_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_head(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_end_of_file(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_body(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_anything_else(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_anything_else_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - return true; -} - -bool -lxb_html_tree_insertion_mode_in_select(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - switch (token->tag_id) { - case LXB_TAG_OPTGROUP: - return lxb_html_tree_insertion_mode_in_select_optgroup_closed(tree, - token); - case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_select_option_closed(tree, - token); - case LXB_TAG_SELECT: - return lxb_html_tree_insertion_mode_in_select_select_closed(tree, - token); - case LXB_TAG_TEMPLATE: - return lxb_html_tree_insertion_mode_in_select_st_open_closed(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_anything_else_closed(tree, - token); - } - } - - switch (token->tag_id) { - case LXB_TAG__TEXT: - return lxb_html_tree_insertion_mode_in_select_text(tree, token); - - case LXB_TAG__EM_COMMENT: - return lxb_html_tree_insertion_mode_in_select_comment(tree, token); - - case LXB_TAG__EM_DOCTYPE: - return lxb_html_tree_insertion_mode_in_select_doctype(tree, token); - - case LXB_TAG_HTML: - return lxb_html_tree_insertion_mode_in_select_html(tree, token); - - case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_select_option(tree, token); - - case LXB_TAG_OPTGROUP: - return lxb_html_tree_insertion_mode_in_select_optgroup(tree, token); - - case LXB_TAG_HR: - return lxb_html_tree_insertion_mode_in_select_hr(tree, token); - - case LXB_TAG_SELECT: - return lxb_html_tree_insertion_mode_in_select_select(tree, token); - - case LXB_TAG_INPUT: - case LXB_TAG_KEYGEN: - case LXB_TAG_TEXTAREA: - return lxb_html_tree_insertion_mode_in_select_ikt(tree, token); - - case LXB_TAG_SCRIPT: - case LXB_TAG_TEMPLATE: - return lxb_html_tree_insertion_mode_in_select_st_open_closed(tree, - token); - case LXB_TAG__END_OF_FILE: - return lxb_html_tree_insertion_mode_in_select_end_of_file(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_anything_else(tree, - token); - } -} diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c deleted file mode 100644 index 7db2e259191e..000000000000 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2018-2019 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/tree/insertion_mode.h" -#include "lexbor/html/tree/open_elements.h" - - -/* - * "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_ct(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -/* - * "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_ct_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - node = lxb_html_tree_element_in_scope(tree, token->tag_id, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_TABLE); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_anything_else(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_select(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); -} - -bool -lxb_html_tree_insertion_mode_in_select_in_table(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - if (token->tag_id >= LXB_TAG__LAST_ENTRY) { - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(tree, - token); - } - - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); - } - - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - switch (token->tag_id) { - case LXB_TAG_CAPTION: - case LXB_TAG_TABLE: - case LXB_TAG_TBODY: - case LXB_TAG_TFOOT: - case LXB_TAG_THEAD: - case LXB_TAG_TR: - case LXB_TAG_TH: - case LXB_TAG_TD: - return lxb_html_tree_insertion_mode_in_select_in_table_ct_closed(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(tree, - token); - } - } - - switch (token->tag_id) { - case LXB_TAG_CAPTION: - case LXB_TAG_TABLE: - case LXB_TAG_TBODY: - case LXB_TAG_TFOOT: - case LXB_TAG_THEAD: - case LXB_TAG_TR: - case LXB_TAG_TH: - case LXB_TAG_TD: - return lxb_html_tree_insertion_mode_in_select_in_table_ct(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); - } -} diff --git a/ext/lexbor/lexbor/ns/base.h b/ext/lexbor/lexbor/ns/base.h index a5b01baa0e6c..94ee0b7f8719 100644 --- a/ext/lexbor/lexbor/ns/base.h +++ b/ext/lexbor/lexbor/ns/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_NS_VERSION_MAJOR 1 -#define LXB_NS_VERSION_MINOR 2 +#define LXB_NS_VERSION_MINOR 4 #define LXB_NS_VERSION_PATCH 0 #define LXB_NS_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/ns/const.h b/ext/lexbor/lexbor/ns/const.h index 463d8d4998bc..2115629b9bdd 100644 --- a/ext/lexbor/lexbor/ns/const.h +++ b/ext/lexbor/lexbor/ns/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/ns/ns.c b/ext/lexbor/lexbor/ns/ns.c index 87e870cf627c..4ffd02519c94 100644 --- a/ext/lexbor/lexbor/ns/ns.c +++ b/ext/lexbor/lexbor/ns/ns.c @@ -1,13 +1,14 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/shs.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif #include "lexbor/ns/ns.h" #include "lexbor/ns/res.h" diff --git a/ext/lexbor/lexbor/ns/res.h b/ext/lexbor/lexbor/ns/res.h index ca3ab04cb6e7..c953ab074696 100644 --- a/ext/lexbor/lexbor/ns/res.h +++ b/ext/lexbor/lexbor/ns/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -50,7 +50,7 @@ static const lxb_ns_prefix_data_t lxb_ns_prefix_res_data[LXB_NS__LAST_ENTRY] = {{.u.short_str = "xmlns", .length = 5, .next = NULL}, LXB_NS_XMLNS, 1, true} }; -static const lexbor_shs_entry_t lxb_ns_res_shs_data[] = +static const lexbor_shs_entry_t lxb_ns_res_shs_data[29] = { {NULL, NULL, 28, 0}, {"html", (void *) &lxb_ns_prefix_res_data[2], 4, 0}, {"xmlns", (void *) &lxb_ns_prefix_res_data[7], 5, 0}, {NULL, NULL, 0, 0}, @@ -69,7 +69,7 @@ static const lexbor_shs_entry_t lxb_ns_res_shs_data[] = {"xml", (void *) &lxb_ns_prefix_res_data[6], 3, 0} }; -static const lexbor_shs_entry_t lxb_ns_res_shs_link_data[] = +static const lexbor_shs_entry_t lxb_ns_res_shs_link_data[23] = { {NULL, NULL, 22, 0}, {"http://www.w3.org/1999/xhtml", (void *) &lxb_ns_res_data[2], 28, 0}, diff --git a/ext/lexbor/lexbor/punycode/base.h b/ext/lexbor/lexbor/punycode/base.h index de51606a69a6..ee0c08ae344e 100644 --- a/ext/lexbor/lexbor/punycode/base.h +++ b/ext/lexbor/lexbor/punycode/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Alexander Borisov + * Copyright (C) 2023-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_PUNYCODE_VERSION_MAJOR 1 -#define LXB_PUNYCODE_VERSION_MINOR 1 +#define LXB_PUNYCODE_VERSION_MINOR 2 #define LXB_PUNYCODE_VERSION_PATCH 0 #define LEXBOR_PUNYCODE_VERSION_STRING LEXBOR_STRINGIZE(LXB_PUNYCODE_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/punycode/punycode.c b/ext/lexbor/lexbor/punycode/punycode.c index 02465a4e00f1..4c3f22ea9bce 100644 --- a/ext/lexbor/lexbor/punycode/punycode.c +++ b/ext/lexbor/lexbor/punycode/punycode.c @@ -138,6 +138,13 @@ lxb_punycode_encode_body(const lxb_codepoint_t *cps, const lxb_codepoint_t *cps_ } if (p > buf) { + if (p >= end) { + p = lxb_punycode_encode_realloc(p, &buf, &end, buffer); + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + *p++ = LXB_PUNYCODE_DELIMITER; } diff --git a/ext/lexbor/lexbor/selectors/base.h b/ext/lexbor/lexbor/selectors/base.h index 64af0261a75c..19bdda73849a 100644 --- a/ext/lexbor/lexbor/selectors/base.h +++ b/ext/lexbor/lexbor/selectors/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_SELECTORS_VERSION_MAJOR 0 -#define LXB_SELECTORS_VERSION_MINOR 3 +#define LXB_SELECTORS_VERSION_MINOR 6 #define LXB_SELECTORS_VERSION_PATCH 0 #define LXB_SELECTORS_VERSION_STRING LEXBOR_STRINGIZE(LXB_SELECTORS_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/tag/base.h b/ext/lexbor/lexbor/tag/base.h index 94886ee4f47c..27ba326cf40f 100644 --- a/ext/lexbor/lexbor/tag/base.h +++ b/ext/lexbor/lexbor/tag/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_TAG_VERSION_MAJOR 1 -#define LXB_TAG_VERSION_MINOR 3 +#define LXB_TAG_VERSION_MINOR 5 #define LXB_TAG_VERSION_PATCH 0 #define LXB_TAG_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/tag/const.h b/ext/lexbor/lexbor/tag/const.h index 1a598d347472..b08e387da326 100644 --- a/ext/lexbor/lexbor/tag/const.h +++ b/ext/lexbor/lexbor/tag/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,8 +14,8 @@ #ifndef LXB_TAG_CONST_H #define LXB_TAG_CONST_H -#define LXB_TAG_CONST_VERSION "A161EC911182C3254E7A972D5C51DF86" -#define LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#define LXB_TAG_CONST_VERSION "5AB3094FB370521074947DC082575715" +#define LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 typedef uintptr_t lxb_tag_id_t; @@ -183,41 +183,43 @@ typedef enum { LXB_TAG_S = 0x009f, LXB_TAG_SAMP = 0x00a0, LXB_TAG_SCRIPT = 0x00a1, - LXB_TAG_SECTION = 0x00a2, - LXB_TAG_SELECT = 0x00a3, - LXB_TAG_SLOT = 0x00a4, - LXB_TAG_SMALL = 0x00a5, - LXB_TAG_SOURCE = 0x00a6, - LXB_TAG_SPACER = 0x00a7, - LXB_TAG_SPAN = 0x00a8, - LXB_TAG_STRIKE = 0x00a9, - LXB_TAG_STRONG = 0x00aa, - LXB_TAG_STYLE = 0x00ab, - LXB_TAG_SUB = 0x00ac, - LXB_TAG_SUMMARY = 0x00ad, - LXB_TAG_SUP = 0x00ae, - LXB_TAG_SVG = 0x00af, - LXB_TAG_TABLE = 0x00b0, - LXB_TAG_TBODY = 0x00b1, - LXB_TAG_TD = 0x00b2, - LXB_TAG_TEMPLATE = 0x00b3, - LXB_TAG_TEXTAREA = 0x00b4, - LXB_TAG_TEXTPATH = 0x00b5, - LXB_TAG_TFOOT = 0x00b6, - LXB_TAG_TH = 0x00b7, - LXB_TAG_THEAD = 0x00b8, - LXB_TAG_TIME = 0x00b9, - LXB_TAG_TITLE = 0x00ba, - LXB_TAG_TR = 0x00bb, - LXB_TAG_TRACK = 0x00bc, - LXB_TAG_TT = 0x00bd, - LXB_TAG_U = 0x00be, - LXB_TAG_UL = 0x00bf, - LXB_TAG_VAR = 0x00c0, - LXB_TAG_VIDEO = 0x00c1, - LXB_TAG_WBR = 0x00c2, - LXB_TAG_XMP = 0x00c3, - LXB_TAG__LAST_ENTRY = 0x00c4 + LXB_TAG_SEARCH = 0x00a2, + LXB_TAG_SECTION = 0x00a3, + LXB_TAG_SELECT = 0x00a4, + LXB_TAG_SELECTEDCONTENT = 0x00a5, + LXB_TAG_SLOT = 0x00a6, + LXB_TAG_SMALL = 0x00a7, + LXB_TAG_SOURCE = 0x00a8, + LXB_TAG_SPACER = 0x00a9, + LXB_TAG_SPAN = 0x00aa, + LXB_TAG_STRIKE = 0x00ab, + LXB_TAG_STRONG = 0x00ac, + LXB_TAG_STYLE = 0x00ad, + LXB_TAG_SUB = 0x00ae, + LXB_TAG_SUMMARY = 0x00af, + LXB_TAG_SUP = 0x00b0, + LXB_TAG_SVG = 0x00b1, + LXB_TAG_TABLE = 0x00b2, + LXB_TAG_TBODY = 0x00b3, + LXB_TAG_TD = 0x00b4, + LXB_TAG_TEMPLATE = 0x00b5, + LXB_TAG_TEXTAREA = 0x00b6, + LXB_TAG_TEXTPATH = 0x00b7, + LXB_TAG_TFOOT = 0x00b8, + LXB_TAG_TH = 0x00b9, + LXB_TAG_THEAD = 0x00ba, + LXB_TAG_TIME = 0x00bb, + LXB_TAG_TITLE = 0x00bc, + LXB_TAG_TR = 0x00bd, + LXB_TAG_TRACK = 0x00be, + LXB_TAG_TT = 0x00bf, + LXB_TAG_U = 0x00c0, + LXB_TAG_UL = 0x00c1, + LXB_TAG_VAR = 0x00c2, + LXB_TAG_VIDEO = 0x00c3, + LXB_TAG_WBR = 0x00c4, + LXB_TAG_XMP = 0x00c5, + LXB_TAG__LAST_ENTRY = 0x00c6 } lxb_tag_id_enum_t; diff --git a/ext/lexbor/lexbor/tag/res.h b/ext/lexbor/lexbor/tag/res.h index 4ad1f37e034e..5672d4a5a5f2 100644 --- a/ext/lexbor/lexbor/tag/res.h +++ b/ext/lexbor/lexbor/tag/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -17,9 +17,9 @@ #endif /* LXB_TAG_RES_H */ #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -188,8 +188,10 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = {{.u.short_str = "s", .length = 1, .next = NULL}, LXB_TAG_S, 1, true}, {{.u.short_str = "samp", .length = 4, .next = NULL}, LXB_TAG_SAMP, 1, true}, {{.u.short_str = "script", .length = 6, .next = NULL}, LXB_TAG_SCRIPT, 1, true}, + {{.u.short_str = "search", .length = 6, .next = NULL}, LXB_TAG_SEARCH, 1, true}, {{.u.short_str = "section", .length = 7, .next = NULL}, LXB_TAG_SECTION, 1, true}, {{.u.short_str = "select", .length = 6, .next = NULL}, LXB_TAG_SELECT, 1, true}, + {{.u.short_str = "selectedcontent", .length = 15, .next = NULL}, LXB_TAG_SELECTEDCONTENT, 1, true}, {{.u.short_str = "slot", .length = 4, .next = NULL}, LXB_TAG_SLOT, 1, true}, {{.u.short_str = "small", .length = 5, .next = NULL}, LXB_TAG_SMALL, 1, true}, {{.u.short_str = "source", .length = 6, .next = NULL}, LXB_TAG_SOURCE, 1, true}, @@ -389,8 +391,10 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] {{.u.short_str = "S", .length = 1, .next = NULL}, LXB_TAG_S, 1, true}, {{.u.short_str = "SAMP", .length = 4, .next = NULL}, LXB_TAG_SAMP, 1, true}, {{.u.short_str = "SCRIPT", .length = 6, .next = NULL}, LXB_TAG_SCRIPT, 1, true}, + {{.u.short_str = "SEARCH", .length = 6, .next = NULL}, LXB_TAG_SEARCH, 1, true}, {{.u.short_str = "SECTION", .length = 7, .next = NULL}, LXB_TAG_SECTION, 1, true}, {{.u.short_str = "SELECT", .length = 6, .next = NULL}, LXB_TAG_SELECT, 1, true}, + {{.u.short_str = "SELECTEDCONTENT", .length = 15, .next = NULL}, LXB_TAG_SELECTEDCONTENT, 1, true}, {{.u.short_str = "SLOT", .length = 4, .next = NULL}, LXB_TAG_SLOT, 1, true}, {{.u.short_str = "SMALL", .length = 5, .next = NULL}, LXB_TAG_SMALL, 1, true}, {{.u.short_str = "SOURCE", .length = 6, .next = NULL}, LXB_TAG_SOURCE, 1, true}, @@ -426,81 +430,81 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] }; #endif -static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = +static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[263] = { {NULL, NULL, 262, 0}, {"radialgradient", (void *) &lxb_tag_res_data_default[153], 14, 0}, {"fecomponenttransfer", (void *) &lxb_tag_res_data_default[58], 19, 0}, {"abbr", (void *) &lxb_tag_res_data_default[7], 4, 1}, {"feflood", (void *) &lxb_tag_res_data_default[65], 7, 0}, {"marquee", (void *) &lxb_tag_res_data_default[121], 7, 0}, {"feblend", (void *) &lxb_tag_res_data_default[56], 7, 4}, {"optgroup", (void *) &lxb_tag_res_data_default[142], 8, 0}, - {"video", (void *) &lxb_tag_res_data_default[193], 5, 10}, {"u", (void *) &lxb_tag_res_data_default[190], 1, 0}, + {"video", (void *) &lxb_tag_res_data_default[195], 5, 10}, {"u", (void *) &lxb_tag_res_data_default[192], 1, 0}, {"iframe", (void *) &lxb_tag_res_data_default[103], 6, 0}, {"animatecolor", (void *) &lxb_tag_res_data_default[13], 12, 0}, {"output", (void *) &lxb_tag_res_data_default[144], 6, 0}, {"figcaption", (void *) &lxb_tag_res_data_default[82], 10, 0}, {"mglyph", (void *) &lxb_tag_res_data_default[127], 6, 0}, {"!--", (void *) &lxb_tag_res_data_default[4], 3, 0}, {"fefuncg", (void *) &lxb_tag_res_data_default[68], 7, 0}, {"aside", (void *) &lxb_tag_res_data_default[20], 5, 0}, - {"style", (void *) &lxb_tag_res_data_default[171], 5, 0}, {"strike", (void *) &lxb_tag_res_data_default[169], 6, 0}, + {"style", (void *) &lxb_tag_res_data_default[173], 5, 0}, {"strike", (void *) &lxb_tag_res_data_default[171], 6, 0}, {"header", (void *) &lxb_tag_res_data_default[98], 6, 0}, {"glyphref", (void *) &lxb_tag_res_data_default[90], 8, 23}, {"label", (void *) &lxb_tag_res_data_default[111], 5, 0}, {"feconvolvematrix", (void *) &lxb_tag_res_data_default[60], 16, 0}, - {"altglyphdef", (void *) &lxb_tag_res_data_default[11], 11, 0}, {"title", (void *) &lxb_tag_res_data_default[186], 5, 0}, + {"altglyphdef", (void *) &lxb_tag_res_data_default[11], 11, 0}, {"title", (void *) &lxb_tag_res_data_default[188], 5, 0}, {"head", (void *) &lxb_tag_res_data_default[97], 4, 0}, {"noframes", (void *) &lxb_tag_res_data_default[138], 8, 0}, {"code", (void *) &lxb_tag_res_data_default[39], 4, 30}, {"rb", (void *) &lxb_tag_res_data_default[154], 2, 5}, {"blink", (void *) &lxb_tag_res_data_default[29], 5, 0}, {"image", (void *) &lxb_tag_res_data_default[104], 5, 0}, {"col", (void *) &lxb_tag_res_data_default[40], 3, 8}, {"object", (void *) &lxb_tag_res_data_default[140], 6, 12}, - {"template", (void *) &lxb_tag_res_data_default[179], 8, 36}, {"h2", (void *) &lxb_tag_res_data_default[92], 2, 13}, + {"template", (void *) &lxb_tag_res_data_default[181], 8, 36}, {"h2", (void *) &lxb_tag_res_data_default[92], 2, 13}, {"lineargradient", (void *) &lxb_tag_res_data_default[114], 14, 0}, {"math", (void *) &lxb_tag_res_data_default[122], 4, 0}, {"base", (void *) &lxb_tag_res_data_default[23], 4, 45}, {"dl", (void *) &lxb_tag_res_data_default[52], 2, 14}, - {"del", (void *) &lxb_tag_res_data_default[45], 3, 16}, {"svg", (void *) &lxb_tag_res_data_default[175], 3, 17}, + {"del", (void *) &lxb_tag_res_data_default[45], 3, 16}, {"svg", (void *) &lxb_tag_res_data_default[177], 3, 17}, {"dir", (void *) &lxb_tag_res_data_default[50], 3, 0}, {"article", (void *) &lxb_tag_res_data_default[19], 7, 0}, - {"strong", (void *) &lxb_tag_res_data_default[170], 6, 0}, {"dialog", (void *) &lxb_tag_res_data_default[49], 6, 0}, - {"details", (void *) &lxb_tag_res_data_default[47], 7, 0}, {"textpath", (void *) &lxb_tag_res_data_default[181], 8, 52}, + {"strong", (void *) &lxb_tag_res_data_default[172], 6, 0}, {"dialog", (void *) &lxb_tag_res_data_default[49], 6, 0}, + {"details", (void *) &lxb_tag_res_data_default[47], 7, 0}, {"textpath", (void *) &lxb_tag_res_data_default[183], 8, 52}, {"mark", (void *) &lxb_tag_res_data_default[120], 4, 0}, {"basefont", (void *) &lxb_tag_res_data_default[24], 8, 0}, {"fediffuselighting", (void *) &lxb_tag_res_data_default[61], 17, 0}, {"fespecularlighting", (void *) &lxb_tag_res_data_default[77], 18, 0}, {"blockquote", (void *) &lxb_tag_res_data_default[30], 10, 0}, {"script", (void *) &lxb_tag_res_data_default[161], 6, 58}, {"malignmark", (void *) &lxb_tag_res_data_default[118], 10, 0}, {"hr", (void *) &lxb_tag_res_data_default[100], 2, 18}, - {"source", (void *) &lxb_tag_res_data_default[166], 6, 19}, {"mn", (void *) &lxb_tag_res_data_default[129], 2, 0}, - {"select", (void *) &lxb_tag_res_data_default[163], 6, 0}, {"main", (void *) &lxb_tag_res_data_default[117], 4, 20}, + {"source", (void *) &lxb_tag_res_data_default[168], 6, 19}, {"mn", (void *) &lxb_tag_res_data_default[129], 2, 0}, + {"select", (void *) &lxb_tag_res_data_default[164], 6, 0}, {"main", (void *) &lxb_tag_res_data_default[117], 4, 20}, {"fieldset", (void *) &lxb_tag_res_data_default[81], 8, 62}, {"ins", (void *) &lxb_tag_res_data_default[107], 3, 0}, {"frameset", (void *) &lxb_tag_res_data_default[89], 8, 0}, {"button", (void *) &lxb_tag_res_data_default[33], 6, 0}, {"fecolormatrix", (void *) &lxb_tag_res_data_default[57], 13, 0}, {"q", (void *) &lxb_tag_res_data_default[152], 1, 0}, - {"animatemotion", (void *) &lxb_tag_res_data_default[14], 13, 0}, {"time", (void *) &lxb_tag_res_data_default[185], 4, 21}, - {"table", (void *) &lxb_tag_res_data_default[176], 5, 25}, {"h6", (void *) &lxb_tag_res_data_default[96], 2, 26}, + {"animatemotion", (void *) &lxb_tag_res_data_default[14], 13, 0}, {"time", (void *) &lxb_tag_res_data_default[187], 4, 21}, + {"table", (void *) &lxb_tag_res_data_default[178], 5, 25}, {"h6", (void *) &lxb_tag_res_data_default[96], 2, 26}, {"cite", (void *) &lxb_tag_res_data_default[37], 4, 28}, {"img", (void *) &lxb_tag_res_data_default[105], 3, 34}, {"fepointlight", (void *) &lxb_tag_res_data_default[76], 12, 0}, {"audio", (void *) &lxb_tag_res_data_default[21], 5, 0}, {"#end-of-file", (void *) &lxb_tag_res_data_default[1], 12, 0}, {"noscript", (void *) &lxb_tag_res_data_default[139], 8, 0}, - {"foreignobject", (void *) &lxb_tag_res_data_default[86], 13, 0}, {"spacer", (void *) &lxb_tag_res_data_default[167], 6, 0}, - {"samp", (void *) &lxb_tag_res_data_default[160], 4, 0}, {"altglyphitem", (void *) &lxb_tag_res_data_default[12], 12, 0}, - {"dt", (void *) &lxb_tag_res_data_default[53], 2, 0}, {"data", (void *) &lxb_tag_res_data_default[42], 4, 0}, + {"foreignobject", (void *) &lxb_tag_res_data_default[86], 13, 77}, {"selectedcontent", (void *) &lxb_tag_res_data_default[165], 15, 0}, + {"spacer", (void *) &lxb_tag_res_data_default[169], 6, 0}, {"samp", (void *) &lxb_tag_res_data_default[160], 4, 0}, + {"altglyphitem", (void *) &lxb_tag_res_data_default[12], 12, 0}, {"data", (void *) &lxb_tag_res_data_default[42], 4, 0}, {"mtext", (void *) &lxb_tag_res_data_default[132], 5, 0}, {"path", (void *) &lxb_tag_res_data_default[147], 4, 0}, - {"input", (void *) &lxb_tag_res_data_default[106], 5, 0}, {"th", (void *) &lxb_tag_res_data_default[183], 2, 38}, - {"p", (void *) &lxb_tag_res_data_default[145], 1, 0}, {"animatetransform", (void *) &lxb_tag_res_data_default[15], 16, 0}, - {"datalist", (void *) &lxb_tag_res_data_default[43], 8, 0}, {"small", (void *) &lxb_tag_res_data_default[165], 5, 0}, + {"input", (void *) &lxb_tag_res_data_default[106], 5, 0}, {"th", (void *) &lxb_tag_res_data_default[185], 2, 38}, + {"p", (void *) &lxb_tag_res_data_default[145], 1, 0}, {"dt", (void *) &lxb_tag_res_data_default[53], 2, 0}, + {"animatetransform", (void *) &lxb_tag_res_data_default[15], 16, 0}, {"datalist", (void *) &lxb_tag_res_data_default[43], 8, 0}, {"b", (void *) &lxb_tag_res_data_default[22], 1, 46}, {"nextid", (void *) &lxb_tag_res_data_default[135], 6, 47}, - {"noembed", (void *) &lxb_tag_res_data_default[137], 7, 0}, {"nav", (void *) &lxb_tag_res_data_default[134], 3, 0}, - {"bgsound", (void *) &lxb_tag_res_data_default[27], 7, 0}, {"slot", (void *) &lxb_tag_res_data_default[164], 4, 0}, - {"param", (void *) &lxb_tag_res_data_default[146], 5, 0}, {"font", (void *) &lxb_tag_res_data_default[84], 4, 53}, - {"figure", (void *) &lxb_tag_res_data_default[83], 6, 0}, {"femerge", (void *) &lxb_tag_res_data_default[72], 7, 0}, - {"femergenode", (void *) &lxb_tag_res_data_default[73], 11, 0}, {"feoffset", (void *) &lxb_tag_res_data_default[75], 8, 60}, - {"#text", (void *) &lxb_tag_res_data_default[2], 5, 0}, {"ul", (void *) &lxb_tag_res_data_default[191], 2, 0}, + {"noembed", (void *) &lxb_tag_res_data_default[137], 7, 0}, {"small", (void *) &lxb_tag_res_data_default[167], 5, 0}, + {"nav", (void *) &lxb_tag_res_data_default[134], 3, 0}, {"slot", (void *) &lxb_tag_res_data_default[166], 4, 0}, + {"search", (void *) &lxb_tag_res_data_default[162], 6, 0}, {"font", (void *) &lxb_tag_res_data_default[84], 4, 53}, + {"bgsound", (void *) &lxb_tag_res_data_default[27], 7, 0}, {"param", (void *) &lxb_tag_res_data_default[146], 5, 0}, + {"figure", (void *) &lxb_tag_res_data_default[83], 6, 0}, {"feoffset", (void *) &lxb_tag_res_data_default[75], 8, 60}, + {"#text", (void *) &lxb_tag_res_data_default[2], 5, 0}, {"femerge", (void *) &lxb_tag_res_data_default[72], 7, 0}, {"fespotlight", (void *) &lxb_tag_res_data_default[78], 11, 66}, {"form", (void *) &lxb_tag_res_data_default[87], 4, 72}, {"#document", (void *) &lxb_tag_res_data_default[3], 9, 76}, {"fedistantlight", (void *) &lxb_tag_res_data_default[63], 14, 0}, - {"track", (void *) &lxb_tag_res_data_default[188], 5, 0}, {"h3", (void *) &lxb_tag_res_data_default[93], 2, 77}, - {"h1", (void *) &lxb_tag_res_data_default[91], 2, 0}, {"i", (void *) &lxb_tag_res_data_default[102], 1, 0}, - {"altglyph", (void *) &lxb_tag_res_data_default[10], 8, 0}, {"legend", (void *) &lxb_tag_res_data_default[112], 6, 115}, - {"tbody", (void *) &lxb_tag_res_data_default[177], 5, 0}, {"address", (void *) &lxb_tag_res_data_default[9], 7, 0}, - {"caption", (void *) &lxb_tag_res_data_default[35], 7, 0}, {"option", (void *) &lxb_tag_res_data_default[143], 6, 0}, - {"sup", (void *) &lxb_tag_res_data_default[174], 3, 0}, {"body", (void *) &lxb_tag_res_data_default[31], 4, 78}, - {"progress", (void *) &lxb_tag_res_data_default[151], 8, 122}, {"acronym", (void *) &lxb_tag_res_data_default[8], 7, 0}, + {"track", (void *) &lxb_tag_res_data_default[190], 5, 0}, {"h3", (void *) &lxb_tag_res_data_default[93], 2, 78}, + {"femergenode", (void *) &lxb_tag_res_data_default[73], 11, 0}, {"i", (void *) &lxb_tag_res_data_default[102], 1, 0}, + {"ul", (void *) &lxb_tag_res_data_default[193], 2, 0}, {"h1", (void *) &lxb_tag_res_data_default[91], 2, 0}, + {"tbody", (void *) &lxb_tag_res_data_default[179], 5, 0}, {"altglyph", (void *) &lxb_tag_res_data_default[10], 8, 0}, + {"legend", (void *) &lxb_tag_res_data_default[112], 6, 117}, {"address", (void *) &lxb_tag_res_data_default[9], 7, 0}, + {"sup", (void *) &lxb_tag_res_data_default[176], 3, 0}, {"body", (void *) &lxb_tag_res_data_default[31], 4, 79}, + {"caption", (void *) &lxb_tag_res_data_default[35], 7, 0}, {"acronym", (void *) &lxb_tag_res_data_default[8], 7, 0}, + {"option", (void *) &lxb_tag_res_data_default[143], 6, 0}, {"progress", (void *) &lxb_tag_res_data_default[151], 8, 124}, {"fegaussianblur", (void *) &lxb_tag_res_data_default[70], 14, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"mi", (void *) &lxb_tag_res_data_default[128], 2, 79}, {NULL, NULL, 0, 0}, - {"dfn", (void *) &lxb_tag_res_data_default[48], 3, 0}, {"a", (void *) &lxb_tag_res_data_default[6], 1, 80}, - {"listing", (void *) &lxb_tag_res_data_default[116], 7, 87}, {"span", (void *) &lxb_tag_res_data_default[168], 4, 0}, + {"mi", (void *) &lxb_tag_res_data_default[128], 2, 80}, {NULL, NULL, 0, 0}, + {"dfn", (void *) &lxb_tag_res_data_default[48], 3, 0}, {"a", (void *) &lxb_tag_res_data_default[6], 1, 87}, + {"listing", (void *) &lxb_tag_res_data_default[116], 7, 88}, {"span", (void *) &lxb_tag_res_data_default[170], 4, 0}, {"area", (void *) &lxb_tag_res_data_default[18], 4, 0}, {"clippath", (void *) &lxb_tag_res_data_default[38], 8, 0}, - {"section", (void *) &lxb_tag_res_data_default[162], 7, 0}, {"li", (void *) &lxb_tag_res_data_default[113], 2, 88}, + {"section", (void *) &lxb_tag_res_data_default[163], 7, 0}, {"li", (void *) &lxb_tag_res_data_default[113], 2, 89}, {NULL, NULL, 0, 0}, {"html", (void *) &lxb_tag_res_data_default[101], 4, 0}, {NULL, NULL, 0, 0}, {"fedropshadow", (void *) &lxb_tag_res_data_default[64], 12, 0}, {"embed", (void *) &lxb_tag_res_data_default[55], 5, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"multicol", (void *) &lxb_tag_res_data_default[133], 8, 0}, - {"var", (void *) &lxb_tag_res_data_default[192], 3, 89}, {"rp", (void *) &lxb_tag_res_data_default[155], 2, 0}, + {"var", (void *) &lxb_tag_res_data_default[194], 3, 93}, {"rp", (void *) &lxb_tag_res_data_default[155], 2, 0}, {NULL, NULL, 0, 0}, {"link", (void *) &lxb_tag_res_data_default[115], 4, 0}, {"mo", (void *) &lxb_tag_res_data_default[130], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"annotation-xml", (void *) &lxb_tag_res_data_default[16], 14, 0}, @@ -510,54 +514,54 @@ static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = {"fefuncb", (void *) &lxb_tag_res_data_default[67], 7, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"meter", (void *) &lxb_tag_res_data_default[125], 5, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"tt", (void *) &lxb_tag_res_data_default[189], 2, 0}, - {"big", (void *) &lxb_tag_res_data_default[28], 3, 93}, {NULL, NULL, 0, 0}, - {"tfoot", (void *) &lxb_tag_res_data_default[182], 5, 0}, {"desc", (void *) &lxb_tag_res_data_default[46], 4, 0}, + {NULL, NULL, 0, 0}, {"tt", (void *) &lxb_tag_res_data_default[191], 2, 0}, + {"big", (void *) &lxb_tag_res_data_default[28], 3, 94}, {NULL, NULL, 0, 0}, + {"tfoot", (void *) &lxb_tag_res_data_default[184], 5, 0}, {"desc", (void *) &lxb_tag_res_data_default[46], 4, 96}, {"isindex", (void *) &lxb_tag_res_data_default[108], 7, 0}, {NULL, NULL, 0, 0}, {"menu", (void *) &lxb_tag_res_data_default[123], 4, 0}, {"hgroup", (void *) &lxb_tag_res_data_default[99], 6, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"wbr", (void *) &lxb_tag_res_data_default[194], 3, 0}, {NULL, NULL, 0, 0}, - {"pre", (void *) &lxb_tag_res_data_default[150], 3, 94}, {NULL, NULL, 0, 0}, + {"wbr", (void *) &lxb_tag_res_data_default[196], 3, 0}, {NULL, NULL, 0, 0}, + {"pre", (void *) &lxb_tag_res_data_default[150], 3, 98}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"picture", (void *) &lxb_tag_res_data_default[148], 7, 0}, {"h4", (void *) &lxb_tag_res_data_default[94], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"meta", (void *) &lxb_tag_res_data_default[124], 4, 96}, {NULL, NULL, 0, 0}, + {"meta", (void *) &lxb_tag_res_data_default[124], 4, 99}, {NULL, NULL, 0, 0}, {"rtc", (void *) &lxb_tag_res_data_default[157], 3, 0}, {NULL, NULL, 0, 0}, - {"frame", (void *) &lxb_tag_res_data_default[88], 5, 0}, {"fetile", (void *) &lxb_tag_res_data_default[79], 6, 98}, - {"feimage", (void *) &lxb_tag_res_data_default[71], 7, 99}, {NULL, NULL, 0, 0}, - {"xmp", (void *) &lxb_tag_res_data_default[195], 3, 0}, {NULL, NULL, 0, 0}, - {"fecomposite", (void *) &lxb_tag_res_data_default[59], 11, 100}, {"feturbulence", (void *) &lxb_tag_res_data_default[80], 12, 0}, - {NULL, NULL, 0, 0}, {"summary", (void *) &lxb_tag_res_data_default[173], 7, 0}, + {"frame", (void *) &lxb_tag_res_data_default[88], 5, 0}, {"fetile", (void *) &lxb_tag_res_data_default[79], 6, 100}, + {"feimage", (void *) &lxb_tag_res_data_default[71], 7, 103}, {NULL, NULL, 0, 0}, + {"xmp", (void *) &lxb_tag_res_data_default[197], 3, 0}, {NULL, NULL, 0, 0}, + {"fecomposite", (void *) &lxb_tag_res_data_default[59], 11, 110}, {"feturbulence", (void *) &lxb_tag_res_data_default[80], 12, 0}, + {NULL, NULL, 0, 0}, {"summary", (void *) &lxb_tag_res_data_default[175], 7, 0}, {"mfenced", (void *) &lxb_tag_res_data_default[126], 7, 0}, {NULL, NULL, 0, 0}, - {"sub", (void *) &lxb_tag_res_data_default[172], 3, 0}, {"colgroup", (void *) &lxb_tag_res_data_default[41], 8, 0}, + {"sub", (void *) &lxb_tag_res_data_default[174], 3, 0}, {"colgroup", (void *) &lxb_tag_res_data_default[41], 8, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"dd", (void *) &lxb_tag_res_data_default[44], 2, 103}, + {NULL, NULL, 0, 0}, {"dd", (void *) &lxb_tag_res_data_default[44], 2, 112}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"div", (void *) &lxb_tag_res_data_default[51], 3, 0}, {"textarea", (void *) &lxb_tag_res_data_default[180], 8, 0}, + {"div", (void *) &lxb_tag_res_data_default[51], 3, 0}, {"textarea", (void *) &lxb_tag_res_data_default[182], 8, 0}, {"!doctype", (void *) &lxb_tag_res_data_default[5], 8, 0}, {"applet", (void *) &lxb_tag_res_data_default[17], 6, 0}, - {NULL, NULL, 0, 0}, {"br", (void *) &lxb_tag_res_data_default[32], 2, 110}, + {NULL, NULL, 0, 0}, {"br", (void *) &lxb_tag_res_data_default[32], 2, 113}, {NULL, NULL, 0, 0}, {"keygen", (void *) &lxb_tag_res_data_default[110], 6, 0}, {"kbd", (void *) &lxb_tag_res_data_default[109], 3, 0}, {NULL, NULL, 0, 0}, {"plaintext", (void *) &lxb_tag_res_data_default[149], 9, 0}, {"s", (void *) &lxb_tag_res_data_default[159], 1, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"bdo", (void *) &lxb_tag_res_data_default[26], 3, 0}, {"td", (void *) &lxb_tag_res_data_default[178], 2, 0}, + {"bdo", (void *) &lxb_tag_res_data_default[26], 3, 0}, {"td", (void *) &lxb_tag_res_data_default[180], 2, 0}, {"fefunca", (void *) &lxb_tag_res_data_default[66], 7, 0}, {"ol", (void *) &lxb_tag_res_data_default[141], 2, 0}, - {"thead", (void *) &lxb_tag_res_data_default[184], 5, 0}, {"nobr", (void *) &lxb_tag_res_data_default[136], 4, 112}, - {NULL, NULL, 0, 0}, {"tr", (void *) &lxb_tag_res_data_default[187], 2, 0}, + {"thead", (void *) &lxb_tag_res_data_default[186], 5, 0}, {"nobr", (void *) &lxb_tag_res_data_default[136], 4, 115}, + {NULL, NULL, 0, 0}, {"tr", (void *) &lxb_tag_res_data_default[189], 2, 0}, {"map", (void *) &lxb_tag_res_data_default[119], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"#undef", (void *) &lxb_tag_res_data_default[0], 6, 113}, + {NULL, NULL, 0, 0}, {"#undef", (void *) &lxb_tag_res_data_default[0], 6, 116}, {"em", (void *) &lxb_tag_res_data_default[54], 2, 0}, {NULL, NULL, 0, 0}, {"bdi", (void *) &lxb_tag_res_data_default[25], 3, 0}, {"femorphology", (void *) &lxb_tag_res_data_default[74], 12, 0}, - {"ms", (void *) &lxb_tag_res_data_default[131], 2, 116}, {"footer", (void *) &lxb_tag_res_data_default[85], 6, 0}, - {"fefuncr", (void *) &lxb_tag_res_data_default[69], 7, 0}, {"rt", (void *) &lxb_tag_res_data_default[156], 2, 117}, + {"ms", (void *) &lxb_tag_res_data_default[131], 2, 120}, {"footer", (void *) &lxb_tag_res_data_default[85], 6, 0}, + {"fefuncr", (void *) &lxb_tag_res_data_default[69], 7, 0}, {"rt", (void *) &lxb_tag_res_data_default[156], 2, 122}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"h5", (void *) &lxb_tag_res_data_default[95], 2, 0}, - {NULL, NULL, 0, 0}, {"ruby", (void *) &lxb_tag_res_data_default[158], 4, 120}, + {NULL, NULL, 0, 0}, {"ruby", (void *) &lxb_tag_res_data_default[158], 4, 123}, {"canvas", (void *) &lxb_tag_res_data_default[34], 6, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/unicode/base.h b/ext/lexbor/lexbor/unicode/base.h index 4797b563c335..3ca2b6b2d8fb 100644 --- a/ext/lexbor/lexbor/unicode/base.h +++ b/ext/lexbor/lexbor/unicode/base.h @@ -16,7 +16,7 @@ extern "C" { #define LXB_UNICODE_VERSION_MAJOR 0 -#define LXB_UNICODE_VERSION_MINOR 3 +#define LXB_UNICODE_VERSION_MINOR 4 #define LXB_UNICODE_VERSION_PATCH 0 #define LXB_UNICODE_VERSION_STRING LEXBOR_STRINGIZE(LXB_UNICODE_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/unicode/res.h b/ext/lexbor/lexbor/unicode/res.h index 9948cc6be1a7..cd5c2c7a1d8a 100644 --- a/ext/lexbor/lexbor/unicode/res.h +++ b/ext/lexbor/lexbor/unicode/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -2212,7 +2212,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 088C (2188) */ 1, /* 088D (2189) */ 1, /* 088E (2190) */ - 56, /* 088F (2191) */ + 1, /* 088F (2191) */ 56, /* 0890 (2192) */ 56, /* 0891 (2193) */ 56, /* 0892 (2194) */ @@ -3185,7 +3185,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 0C59 (3161) */ 1, /* 0C5A (3162) */ 56, /* 0C5B (3163) */ - 56, /* 0C5C (3164) */ + 1, /* 0C5C (3164) */ 1, /* 0C5D (3165) */ 56, /* 0C5E (3166) */ 56, /* 0C5F (3167) */ @@ -3313,7 +3313,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* 0CD9 (3289) */ 56, /* 0CDA (3290) */ 56, /* 0CDB (3291) */ - 56, /* 0CDC (3292) */ + 1, /* 0CDC (3292) */ 1, /* 0CDD (3293) */ 1, /* 0CDE (3294) */ 56, /* 0CDF (3295) */ @@ -6884,35 +6884,35 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 431, /* 1ACC (6860) */ 431, /* 1ACD (6861) */ 431, /* 1ACE (6862) */ - 56, /* 1ACF (6863) */ - 56, /* 1AD0 (6864) */ - 56, /* 1AD1 (6865) */ - 56, /* 1AD2 (6866) */ - 56, /* 1AD3 (6867) */ - 56, /* 1AD4 (6868) */ - 56, /* 1AD5 (6869) */ - 56, /* 1AD6 (6870) */ - 56, /* 1AD7 (6871) */ - 56, /* 1AD8 (6872) */ - 56, /* 1AD9 (6873) */ - 56, /* 1ADA (6874) */ - 56, /* 1ADB (6875) */ - 56, /* 1ADC (6876) */ - 56, /* 1ADD (6877) */ + 431, /* 1ACF (6863) */ + 431, /* 1AD0 (6864) */ + 431, /* 1AD1 (6865) */ + 431, /* 1AD2 (6866) */ + 431, /* 1AD3 (6867) */ + 431, /* 1AD4 (6868) */ + 431, /* 1AD5 (6869) */ + 431, /* 1AD6 (6870) */ + 431, /* 1AD7 (6871) */ + 431, /* 1AD8 (6872) */ + 431, /* 1AD9 (6873) */ + 431, /* 1ADA (6874) */ + 431, /* 1ADB (6875) */ + 431, /* 1ADC (6876) */ + 433, /* 1ADD (6877) */ 56, /* 1ADE (6878) */ 56, /* 1ADF (6879) */ - 56, /* 1AE0 (6880) */ - 56, /* 1AE1 (6881) */ - 56, /* 1AE2 (6882) */ - 56, /* 1AE3 (6883) */ - 56, /* 1AE4 (6884) */ - 56, /* 1AE5 (6885) */ - 56, /* 1AE6 (6886) */ - 56, /* 1AE7 (6887) */ - 56, /* 1AE8 (6888) */ - 56, /* 1AE9 (6889) */ - 56, /* 1AEA (6890) */ - 56, /* 1AEB (6891) */ + 431, /* 1AE0 (6880) */ + 431, /* 1AE1 (6881) */ + 431, /* 1AE2 (6882) */ + 431, /* 1AE3 (6883) */ + 431, /* 1AE4 (6884) */ + 431, /* 1AE5 (6885) */ + 433, /* 1AE6 (6886) */ + 431, /* 1AE7 (6887) */ + 431, /* 1AE8 (6888) */ + 431, /* 1AE9 (6889) */ + 431, /* 1AEA (6890) */ + 446, /* 1AEB (6891) */ 56, /* 1AEC (6892) */ 56, /* 1AED (6893) */ 56, /* 1AEE (6894) */ @@ -8406,7 +8406,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 20BE (8382) */ 1, /* 20BF (8383) */ 1, /* 20C0 (8384) */ - 56, /* 20C1 (8385) */ + 1, /* 20C1 (8385) */ 56, /* 20C2 (8386) */ 56, /* 20C3 (8387) */ 56, /* 20C4 (8388) */ @@ -11179,7 +11179,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 2B93 (11155) */ 1, /* 2B94 (11156) */ 1, /* 2B95 (11157) */ - 56, /* 2B96 (11158) */ + 1, /* 2B96 (11158) */ 1, /* 2B97 (11159) */ 1, /* 2B98 (11160) */ 1, /* 2B99 (11161) */ @@ -42979,21 +42979,21 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 3245, /* A7CB (42955) */ 3246, /* A7CC (42956) */ 1, /* A7CD (42957) */ - 56, /* A7CE (42958) */ - 56, /* A7CF (42959) */ - 3247, /* A7D0 (42960) */ + 3247, /* A7CE (42958) */ + 1, /* A7CF (42959) */ + 3248, /* A7D0 (42960) */ 1, /* A7D1 (42961) */ - 56, /* A7D2 (42962) */ + 3249, /* A7D2 (42962) */ 1, /* A7D3 (42963) */ - 56, /* A7D4 (42964) */ + 3250, /* A7D4 (42964) */ 1, /* A7D5 (42965) */ - 3248, /* A7D6 (42966) */ + 3251, /* A7D6 (42966) */ 1, /* A7D7 (42967) */ - 3249, /* A7D8 (42968) */ + 3252, /* A7D8 (42968) */ 1, /* A7D9 (42969) */ - 3250, /* A7DA (42970) */ + 3253, /* A7DA (42970) */ 1, /* A7DB (42971) */ - 3251, /* A7DC (42972) */ + 3254, /* A7DC (42972) */ 56, /* A7DD (42973) */ 56, /* A7DE (42974) */ 56, /* A7DF (42975) */ @@ -43014,15 +43014,15 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* A7EE (42990) */ 56, /* A7EF (42991) */ 56, /* A7F0 (42992) */ - 56, /* A7F1 (42993) */ - 3252, /* A7F2 (42994) */ - 3253, /* A7F3 (42995) */ - 3254, /* A7F4 (42996) */ - 3255, /* A7F5 (42997) */ + 3255, /* A7F1 (42993) */ + 3256, /* A7F2 (42994) */ + 3257, /* A7F3 (42995) */ + 3258, /* A7F4 (42996) */ + 3259, /* A7F5 (42997) */ 1, /* A7F6 (42998) */ 1, /* A7F7 (42999) */ - 3256, /* A7F8 (43000) */ - 3257, /* A7F9 (43001) */ + 3260, /* A7F8 (43000) */ + 3261, /* A7F9 (43001) */ 1, /* A7FA (43002) */ 1, /* A7FB (43003) */ 1, /* A7FC (43004) */ @@ -43889,10 +43889,10 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* AB59 (43865) */ 1, /* AB5A (43866) */ 1, /* AB5B (43867) */ - 3258, /* AB5C (43868) */ - 3259, /* AB5D (43869) */ - 3260, /* AB5E (43870) */ - 3261, /* AB5F (43871) */ + 3262, /* AB5C (43868) */ + 3263, /* AB5D (43869) */ + 3264, /* AB5E (43870) */ + 3265, /* AB5F (43871) */ 1, /* AB60 (43872) */ 1, /* AB61 (43873) */ 1, /* AB62 (43874) */ @@ -43902,93 +43902,93 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* AB66 (43878) */ 1, /* AB67 (43879) */ 1, /* AB68 (43880) */ - 3262, /* AB69 (43881) */ + 3266, /* AB69 (43881) */ 1, /* AB6A (43882) */ 1, /* AB6B (43883) */ 56, /* AB6C (43884) */ 56, /* AB6D (43885) */ 56, /* AB6E (43886) */ 56, /* AB6F (43887) */ - 3263, /* AB70 (43888) */ - 3264, /* AB71 (43889) */ - 3265, /* AB72 (43890) */ - 3266, /* AB73 (43891) */ - 3267, /* AB74 (43892) */ - 3268, /* AB75 (43893) */ - 3269, /* AB76 (43894) */ - 3270, /* AB77 (43895) */ - 3271, /* AB78 (43896) */ - 3272, /* AB79 (43897) */ - 3273, /* AB7A (43898) */ - 3274, /* AB7B (43899) */ - 3275, /* AB7C (43900) */ - 3276, /* AB7D (43901) */ - 3277, /* AB7E (43902) */ - 3278, /* AB7F (43903) */ - 3279, /* AB80 (43904) */ - 3280, /* AB81 (43905) */ - 3281, /* AB82 (43906) */ - 3282, /* AB83 (43907) */ - 3283, /* AB84 (43908) */ - 3284, /* AB85 (43909) */ - 3285, /* AB86 (43910) */ - 3286, /* AB87 (43911) */ - 3287, /* AB88 (43912) */ - 3288, /* AB89 (43913) */ - 3289, /* AB8A (43914) */ - 3290, /* AB8B (43915) */ - 3291, /* AB8C (43916) */ - 3292, /* AB8D (43917) */ - 3293, /* AB8E (43918) */ - 3294, /* AB8F (43919) */ - 3295, /* AB90 (43920) */ - 3296, /* AB91 (43921) */ - 3297, /* AB92 (43922) */ - 3298, /* AB93 (43923) */ - 3299, /* AB94 (43924) */ - 3300, /* AB95 (43925) */ - 3301, /* AB96 (43926) */ - 3302, /* AB97 (43927) */ - 3303, /* AB98 (43928) */ - 3304, /* AB99 (43929) */ - 3305, /* AB9A (43930) */ - 3306, /* AB9B (43931) */ - 3307, /* AB9C (43932) */ - 3308, /* AB9D (43933) */ - 3309, /* AB9E (43934) */ - 3310, /* AB9F (43935) */ - 3311, /* ABA0 (43936) */ - 3312, /* ABA1 (43937) */ - 3313, /* ABA2 (43938) */ - 3314, /* ABA3 (43939) */ - 3315, /* ABA4 (43940) */ - 3316, /* ABA5 (43941) */ - 3317, /* ABA6 (43942) */ - 3318, /* ABA7 (43943) */ - 3319, /* ABA8 (43944) */ - 3320, /* ABA9 (43945) */ - 3321, /* ABAA (43946) */ - 3322, /* ABAB (43947) */ - 3323, /* ABAC (43948) */ - 3324, /* ABAD (43949) */ - 3325, /* ABAE (43950) */ - 3326, /* ABAF (43951) */ - 3327, /* ABB0 (43952) */ - 3328, /* ABB1 (43953) */ - 3329, /* ABB2 (43954) */ - 3330, /* ABB3 (43955) */ - 3331, /* ABB4 (43956) */ - 3332, /* ABB5 (43957) */ - 3333, /* ABB6 (43958) */ - 3334, /* ABB7 (43959) */ - 3335, /* ABB8 (43960) */ - 3336, /* ABB9 (43961) */ - 3337, /* ABBA (43962) */ - 3338, /* ABBB (43963) */ - 3339, /* ABBC (43964) */ - 3340, /* ABBD (43965) */ - 3341, /* ABBE (43966) */ - 3342, /* ABBF (43967) */ + 3267, /* AB70 (43888) */ + 3268, /* AB71 (43889) */ + 3269, /* AB72 (43890) */ + 3270, /* AB73 (43891) */ + 3271, /* AB74 (43892) */ + 3272, /* AB75 (43893) */ + 3273, /* AB76 (43894) */ + 3274, /* AB77 (43895) */ + 3275, /* AB78 (43896) */ + 3276, /* AB79 (43897) */ + 3277, /* AB7A (43898) */ + 3278, /* AB7B (43899) */ + 3279, /* AB7C (43900) */ + 3280, /* AB7D (43901) */ + 3281, /* AB7E (43902) */ + 3282, /* AB7F (43903) */ + 3283, /* AB80 (43904) */ + 3284, /* AB81 (43905) */ + 3285, /* AB82 (43906) */ + 3286, /* AB83 (43907) */ + 3287, /* AB84 (43908) */ + 3288, /* AB85 (43909) */ + 3289, /* AB86 (43910) */ + 3290, /* AB87 (43911) */ + 3291, /* AB88 (43912) */ + 3292, /* AB89 (43913) */ + 3293, /* AB8A (43914) */ + 3294, /* AB8B (43915) */ + 3295, /* AB8C (43916) */ + 3296, /* AB8D (43917) */ + 3297, /* AB8E (43918) */ + 3298, /* AB8F (43919) */ + 3299, /* AB90 (43920) */ + 3300, /* AB91 (43921) */ + 3301, /* AB92 (43922) */ + 3302, /* AB93 (43923) */ + 3303, /* AB94 (43924) */ + 3304, /* AB95 (43925) */ + 3305, /* AB96 (43926) */ + 3306, /* AB97 (43927) */ + 3307, /* AB98 (43928) */ + 3308, /* AB99 (43929) */ + 3309, /* AB9A (43930) */ + 3310, /* AB9B (43931) */ + 3311, /* AB9C (43932) */ + 3312, /* AB9D (43933) */ + 3313, /* AB9E (43934) */ + 3314, /* AB9F (43935) */ + 3315, /* ABA0 (43936) */ + 3316, /* ABA1 (43937) */ + 3317, /* ABA2 (43938) */ + 3318, /* ABA3 (43939) */ + 3319, /* ABA4 (43940) */ + 3320, /* ABA5 (43941) */ + 3321, /* ABA6 (43942) */ + 3322, /* ABA7 (43943) */ + 3323, /* ABA8 (43944) */ + 3324, /* ABA9 (43945) */ + 3325, /* ABAA (43946) */ + 3326, /* ABAB (43947) */ + 3327, /* ABAC (43948) */ + 3328, /* ABAD (43949) */ + 3329, /* ABAE (43950) */ + 3330, /* ABAF (43951) */ + 3331, /* ABB0 (43952) */ + 3332, /* ABB1 (43953) */ + 3333, /* ABB2 (43954) */ + 3334, /* ABB3 (43955) */ + 3335, /* ABB4 (43956) */ + 3336, /* ABB5 (43957) */ + 3337, /* ABB6 (43958) */ + 3338, /* ABB7 (43959) */ + 3339, /* ABB8 (43960) */ + 3340, /* ABB9 (43961) */ + 3341, /* ABBA (43962) */ + 3342, /* ABBB (43963) */ + 3343, /* ABBC (43964) */ + 3344, /* ABBD (43965) */ + 3345, /* ABBE (43966) */ + 3346, /* ABBF (43967) */ 1, /* ABC0 (43968) */ 1, /* ABC1 (43969) */ 1, /* ABC2 (43970) */ @@ -44053,11178 +44053,11178 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* ABFD (44029) */ 56, /* ABFE (44030) */ 56, /* ABFF (44031) */ - 3343, /* AC00 (44032) */ - 3343, /* AC01 (44033) */ - 3343, /* AC02 (44034) */ - 3343, /* AC03 (44035) */ - 3343, /* AC04 (44036) */ - 3343, /* AC05 (44037) */ - 3343, /* AC06 (44038) */ - 3343, /* AC07 (44039) */ - 3343, /* AC08 (44040) */ - 3343, /* AC09 (44041) */ - 3343, /* AC0A (44042) */ - 3343, /* AC0B (44043) */ - 3343, /* AC0C (44044) */ - 3343, /* AC0D (44045) */ - 3343, /* AC0E (44046) */ - 3343, /* AC0F (44047) */ - 3343, /* AC10 (44048) */ - 3343, /* AC11 (44049) */ - 3343, /* AC12 (44050) */ - 3343, /* AC13 (44051) */ - 3343, /* AC14 (44052) */ - 3343, /* AC15 (44053) */ - 3343, /* AC16 (44054) */ - 3343, /* AC17 (44055) */ - 3343, /* AC18 (44056) */ - 3343, /* AC19 (44057) */ - 3343, /* AC1A (44058) */ - 3343, /* AC1B (44059) */ - 3343, /* AC1C (44060) */ - 3343, /* AC1D (44061) */ - 3343, /* AC1E (44062) */ - 3343, /* AC1F (44063) */ - 3343, /* AC20 (44064) */ - 3343, /* AC21 (44065) */ - 3343, /* AC22 (44066) */ - 3343, /* AC23 (44067) */ - 3343, /* AC24 (44068) */ - 3343, /* AC25 (44069) */ - 3343, /* AC26 (44070) */ - 3343, /* AC27 (44071) */ - 3343, /* AC28 (44072) */ - 3343, /* AC29 (44073) */ - 3343, /* AC2A (44074) */ - 3343, /* AC2B (44075) */ - 3343, /* AC2C (44076) */ - 3343, /* AC2D (44077) */ - 3343, /* AC2E (44078) */ - 3343, /* AC2F (44079) */ - 3343, /* AC30 (44080) */ - 3343, /* AC31 (44081) */ - 3343, /* AC32 (44082) */ - 3343, /* AC33 (44083) */ - 3343, /* AC34 (44084) */ - 3343, /* AC35 (44085) */ - 3343, /* AC36 (44086) */ - 3343, /* AC37 (44087) */ - 3343, /* AC38 (44088) */ - 3343, /* AC39 (44089) */ - 3343, /* AC3A (44090) */ - 3343, /* AC3B (44091) */ - 3343, /* AC3C (44092) */ - 3343, /* AC3D (44093) */ - 3343, /* AC3E (44094) */ - 3343, /* AC3F (44095) */ - 3343, /* AC40 (44096) */ - 3343, /* AC41 (44097) */ - 3343, /* AC42 (44098) */ - 3343, /* AC43 (44099) */ - 3343, /* AC44 (44100) */ - 3343, /* AC45 (44101) */ - 3343, /* AC46 (44102) */ - 3343, /* AC47 (44103) */ - 3343, /* AC48 (44104) */ - 3343, /* AC49 (44105) */ - 3343, /* AC4A (44106) */ - 3343, /* AC4B (44107) */ - 3343, /* AC4C (44108) */ - 3343, /* AC4D (44109) */ - 3343, /* AC4E (44110) */ - 3343, /* AC4F (44111) */ - 3343, /* AC50 (44112) */ - 3343, /* AC51 (44113) */ - 3343, /* AC52 (44114) */ - 3343, /* AC53 (44115) */ - 3343, /* AC54 (44116) */ - 3343, /* AC55 (44117) */ - 3343, /* AC56 (44118) */ - 3343, /* AC57 (44119) */ - 3343, /* AC58 (44120) */ - 3343, /* AC59 (44121) */ - 3343, /* AC5A (44122) */ - 3343, /* AC5B (44123) */ - 3343, /* AC5C (44124) */ - 3343, /* AC5D (44125) */ - 3343, /* AC5E (44126) */ - 3343, /* AC5F (44127) */ - 3343, /* AC60 (44128) */ - 3343, /* AC61 (44129) */ - 3343, /* AC62 (44130) */ - 3343, /* AC63 (44131) */ - 3343, /* AC64 (44132) */ - 3343, /* AC65 (44133) */ - 3343, /* AC66 (44134) */ - 3343, /* AC67 (44135) */ - 3343, /* AC68 (44136) */ - 3343, /* AC69 (44137) */ - 3343, /* AC6A (44138) */ - 3343, /* AC6B (44139) */ - 3343, /* AC6C (44140) */ - 3343, /* AC6D (44141) */ - 3343, /* AC6E (44142) */ - 3343, /* AC6F (44143) */ - 3343, /* AC70 (44144) */ - 3343, /* AC71 (44145) */ - 3343, /* AC72 (44146) */ - 3343, /* AC73 (44147) */ - 3343, /* AC74 (44148) */ - 3343, /* AC75 (44149) */ - 3343, /* AC76 (44150) */ - 3343, /* AC77 (44151) */ - 3343, /* AC78 (44152) */ - 3343, /* AC79 (44153) */ - 3343, /* AC7A (44154) */ - 3343, /* AC7B (44155) */ - 3343, /* AC7C (44156) */ - 3343, /* AC7D (44157) */ - 3343, /* AC7E (44158) */ - 3343, /* AC7F (44159) */ - 3343, /* AC80 (44160) */ - 3343, /* AC81 (44161) */ - 3343, /* AC82 (44162) */ - 3343, /* AC83 (44163) */ - 3343, /* AC84 (44164) */ - 3343, /* AC85 (44165) */ - 3343, /* AC86 (44166) */ - 3343, /* AC87 (44167) */ - 3343, /* AC88 (44168) */ - 3343, /* AC89 (44169) */ - 3343, /* AC8A (44170) */ - 3343, /* AC8B (44171) */ - 3343, /* AC8C (44172) */ - 3343, /* AC8D (44173) */ - 3343, /* AC8E (44174) */ - 3343, /* AC8F (44175) */ - 3343, /* AC90 (44176) */ - 3343, /* AC91 (44177) */ - 3343, /* AC92 (44178) */ - 3343, /* AC93 (44179) */ - 3343, /* AC94 (44180) */ - 3343, /* AC95 (44181) */ - 3343, /* AC96 (44182) */ - 3343, /* AC97 (44183) */ - 3343, /* AC98 (44184) */ - 3343, /* AC99 (44185) */ - 3343, /* AC9A (44186) */ - 3343, /* AC9B (44187) */ - 3343, /* AC9C (44188) */ - 3343, /* AC9D (44189) */ - 3343, /* AC9E (44190) */ - 3343, /* AC9F (44191) */ - 3343, /* ACA0 (44192) */ - 3343, /* ACA1 (44193) */ - 3343, /* ACA2 (44194) */ - 3343, /* ACA3 (44195) */ - 3343, /* ACA4 (44196) */ - 3343, /* ACA5 (44197) */ - 3343, /* ACA6 (44198) */ - 3343, /* ACA7 (44199) */ - 3343, /* ACA8 (44200) */ - 3343, /* ACA9 (44201) */ - 3343, /* ACAA (44202) */ - 3343, /* ACAB (44203) */ - 3343, /* ACAC (44204) */ - 3343, /* ACAD (44205) */ - 3343, /* ACAE (44206) */ - 3343, /* ACAF (44207) */ - 3343, /* ACB0 (44208) */ - 3343, /* ACB1 (44209) */ - 3343, /* ACB2 (44210) */ - 3343, /* ACB3 (44211) */ - 3343, /* ACB4 (44212) */ - 3343, /* ACB5 (44213) */ - 3343, /* ACB6 (44214) */ - 3343, /* ACB7 (44215) */ - 3343, /* ACB8 (44216) */ - 3343, /* ACB9 (44217) */ - 3343, /* ACBA (44218) */ - 3343, /* ACBB (44219) */ - 3343, /* ACBC (44220) */ - 3343, /* ACBD (44221) */ - 3343, /* ACBE (44222) */ - 3343, /* ACBF (44223) */ - 3343, /* ACC0 (44224) */ - 3343, /* ACC1 (44225) */ - 3343, /* ACC2 (44226) */ - 3343, /* ACC3 (44227) */ - 3343, /* ACC4 (44228) */ - 3343, /* ACC5 (44229) */ - 3343, /* ACC6 (44230) */ - 3343, /* ACC7 (44231) */ - 3343, /* ACC8 (44232) */ - 3343, /* ACC9 (44233) */ - 3343, /* ACCA (44234) */ - 3343, /* ACCB (44235) */ - 3343, /* ACCC (44236) */ - 3343, /* ACCD (44237) */ - 3343, /* ACCE (44238) */ - 3343, /* ACCF (44239) */ - 3343, /* ACD0 (44240) */ - 3343, /* ACD1 (44241) */ - 3343, /* ACD2 (44242) */ - 3343, /* ACD3 (44243) */ - 3343, /* ACD4 (44244) */ - 3343, /* ACD5 (44245) */ - 3343, /* ACD6 (44246) */ - 3343, /* ACD7 (44247) */ - 3343, /* ACD8 (44248) */ - 3343, /* ACD9 (44249) */ - 3343, /* ACDA (44250) */ - 3343, /* ACDB (44251) */ - 3343, /* ACDC (44252) */ - 3343, /* ACDD (44253) */ - 3343, /* ACDE (44254) */ - 3343, /* ACDF (44255) */ - 3343, /* ACE0 (44256) */ - 3343, /* ACE1 (44257) */ - 3343, /* ACE2 (44258) */ - 3343, /* ACE3 (44259) */ - 3343, /* ACE4 (44260) */ - 3343, /* ACE5 (44261) */ - 3343, /* ACE6 (44262) */ - 3343, /* ACE7 (44263) */ - 3343, /* ACE8 (44264) */ - 3343, /* ACE9 (44265) */ - 3343, /* ACEA (44266) */ - 3343, /* ACEB (44267) */ - 3343, /* ACEC (44268) */ - 3343, /* ACED (44269) */ - 3343, /* ACEE (44270) */ - 3343, /* ACEF (44271) */ - 3343, /* ACF0 (44272) */ - 3343, /* ACF1 (44273) */ - 3343, /* ACF2 (44274) */ - 3343, /* ACF3 (44275) */ - 3343, /* ACF4 (44276) */ - 3343, /* ACF5 (44277) */ - 3343, /* ACF6 (44278) */ - 3343, /* ACF7 (44279) */ - 3343, /* ACF8 (44280) */ - 3343, /* ACF9 (44281) */ - 3343, /* ACFA (44282) */ - 3343, /* ACFB (44283) */ - 3343, /* ACFC (44284) */ - 3343, /* ACFD (44285) */ - 3343, /* ACFE (44286) */ - 3343, /* ACFF (44287) */ - 3343, /* AD00 (44288) */ - 3343, /* AD01 (44289) */ - 3343, /* AD02 (44290) */ - 3343, /* AD03 (44291) */ - 3343, /* AD04 (44292) */ - 3343, /* AD05 (44293) */ - 3343, /* AD06 (44294) */ - 3343, /* AD07 (44295) */ - 3343, /* AD08 (44296) */ - 3343, /* AD09 (44297) */ - 3343, /* AD0A (44298) */ - 3343, /* AD0B (44299) */ - 3343, /* AD0C (44300) */ - 3343, /* AD0D (44301) */ - 3343, /* AD0E (44302) */ - 3343, /* AD0F (44303) */ - 3343, /* AD10 (44304) */ - 3343, /* AD11 (44305) */ - 3343, /* AD12 (44306) */ - 3343, /* AD13 (44307) */ - 3343, /* AD14 (44308) */ - 3343, /* AD15 (44309) */ - 3343, /* AD16 (44310) */ - 3343, /* AD17 (44311) */ - 3343, /* AD18 (44312) */ - 3343, /* AD19 (44313) */ - 3343, /* AD1A (44314) */ - 3343, /* AD1B (44315) */ - 3343, /* AD1C (44316) */ - 3343, /* AD1D (44317) */ - 3343, /* AD1E (44318) */ - 3343, /* AD1F (44319) */ - 3343, /* AD20 (44320) */ - 3343, /* AD21 (44321) */ - 3343, /* AD22 (44322) */ - 3343, /* AD23 (44323) */ - 3343, /* AD24 (44324) */ - 3343, /* AD25 (44325) */ - 3343, /* AD26 (44326) */ - 3343, /* AD27 (44327) */ - 3343, /* AD28 (44328) */ - 3343, /* AD29 (44329) */ - 3343, /* AD2A (44330) */ - 3343, /* AD2B (44331) */ - 3343, /* AD2C (44332) */ - 3343, /* AD2D (44333) */ - 3343, /* AD2E (44334) */ - 3343, /* AD2F (44335) */ - 3343, /* AD30 (44336) */ - 3343, /* AD31 (44337) */ - 3343, /* AD32 (44338) */ - 3343, /* AD33 (44339) */ - 3343, /* AD34 (44340) */ - 3343, /* AD35 (44341) */ - 3343, /* AD36 (44342) */ - 3343, /* AD37 (44343) */ - 3343, /* AD38 (44344) */ - 3343, /* AD39 (44345) */ - 3343, /* AD3A (44346) */ - 3343, /* AD3B (44347) */ - 3343, /* AD3C (44348) */ - 3343, /* AD3D (44349) */ - 3343, /* AD3E (44350) */ - 3343, /* AD3F (44351) */ - 3343, /* AD40 (44352) */ - 3343, /* AD41 (44353) */ - 3343, /* AD42 (44354) */ - 3343, /* AD43 (44355) */ - 3343, /* AD44 (44356) */ - 3343, /* AD45 (44357) */ - 3343, /* AD46 (44358) */ - 3343, /* AD47 (44359) */ - 3343, /* AD48 (44360) */ - 3343, /* AD49 (44361) */ - 3343, /* AD4A (44362) */ - 3343, /* AD4B (44363) */ - 3343, /* AD4C (44364) */ - 3343, /* AD4D (44365) */ - 3343, /* AD4E (44366) */ - 3343, /* AD4F (44367) */ - 3343, /* AD50 (44368) */ - 3343, /* AD51 (44369) */ - 3343, /* AD52 (44370) */ - 3343, /* AD53 (44371) */ - 3343, /* AD54 (44372) */ - 3343, /* AD55 (44373) */ - 3343, /* AD56 (44374) */ - 3343, /* AD57 (44375) */ - 3343, /* AD58 (44376) */ - 3343, /* AD59 (44377) */ - 3343, /* AD5A (44378) */ - 3343, /* AD5B (44379) */ - 3343, /* AD5C (44380) */ - 3343, /* AD5D (44381) */ - 3343, /* AD5E (44382) */ - 3343, /* AD5F (44383) */ - 3343, /* AD60 (44384) */ - 3343, /* AD61 (44385) */ - 3343, /* AD62 (44386) */ - 3343, /* AD63 (44387) */ - 3343, /* AD64 (44388) */ - 3343, /* AD65 (44389) */ - 3343, /* AD66 (44390) */ - 3343, /* AD67 (44391) */ - 3343, /* AD68 (44392) */ - 3343, /* AD69 (44393) */ - 3343, /* AD6A (44394) */ - 3343, /* AD6B (44395) */ - 3343, /* AD6C (44396) */ - 3343, /* AD6D (44397) */ - 3343, /* AD6E (44398) */ - 3343, /* AD6F (44399) */ - 3343, /* AD70 (44400) */ - 3343, /* AD71 (44401) */ - 3343, /* AD72 (44402) */ - 3343, /* AD73 (44403) */ - 3343, /* AD74 (44404) */ - 3343, /* AD75 (44405) */ - 3343, /* AD76 (44406) */ - 3343, /* AD77 (44407) */ - 3343, /* AD78 (44408) */ - 3343, /* AD79 (44409) */ - 3343, /* AD7A (44410) */ - 3343, /* AD7B (44411) */ - 3343, /* AD7C (44412) */ - 3343, /* AD7D (44413) */ - 3343, /* AD7E (44414) */ - 3343, /* AD7F (44415) */ - 3343, /* AD80 (44416) */ - 3343, /* AD81 (44417) */ - 3343, /* AD82 (44418) */ - 3343, /* AD83 (44419) */ - 3343, /* AD84 (44420) */ - 3343, /* AD85 (44421) */ - 3343, /* AD86 (44422) */ - 3343, /* AD87 (44423) */ - 3343, /* AD88 (44424) */ - 3343, /* AD89 (44425) */ - 3343, /* AD8A (44426) */ - 3343, /* AD8B (44427) */ - 3343, /* AD8C (44428) */ - 3343, /* AD8D (44429) */ - 3343, /* AD8E (44430) */ - 3343, /* AD8F (44431) */ - 3343, /* AD90 (44432) */ - 3343, /* AD91 (44433) */ - 3343, /* AD92 (44434) */ - 3343, /* AD93 (44435) */ - 3343, /* AD94 (44436) */ - 3343, /* AD95 (44437) */ - 3343, /* AD96 (44438) */ - 3343, /* AD97 (44439) */ - 3343, /* AD98 (44440) */ - 3343, /* AD99 (44441) */ - 3343, /* AD9A (44442) */ - 3343, /* AD9B (44443) */ - 3343, /* AD9C (44444) */ - 3343, /* AD9D (44445) */ - 3343, /* AD9E (44446) */ - 3343, /* AD9F (44447) */ - 3343, /* ADA0 (44448) */ - 3343, /* ADA1 (44449) */ - 3343, /* ADA2 (44450) */ - 3343, /* ADA3 (44451) */ - 3343, /* ADA4 (44452) */ - 3343, /* ADA5 (44453) */ - 3343, /* ADA6 (44454) */ - 3343, /* ADA7 (44455) */ - 3343, /* ADA8 (44456) */ - 3343, /* ADA9 (44457) */ - 3343, /* ADAA (44458) */ - 3343, /* ADAB (44459) */ - 3343, /* ADAC (44460) */ - 3343, /* ADAD (44461) */ - 3343, /* ADAE (44462) */ - 3343, /* ADAF (44463) */ - 3343, /* ADB0 (44464) */ - 3343, /* ADB1 (44465) */ - 3343, /* ADB2 (44466) */ - 3343, /* ADB3 (44467) */ - 3343, /* ADB4 (44468) */ - 3343, /* ADB5 (44469) */ - 3343, /* ADB6 (44470) */ - 3343, /* ADB7 (44471) */ - 3343, /* ADB8 (44472) */ - 3343, /* ADB9 (44473) */ - 3343, /* ADBA (44474) */ - 3343, /* ADBB (44475) */ - 3343, /* ADBC (44476) */ - 3343, /* ADBD (44477) */ - 3343, /* ADBE (44478) */ - 3343, /* ADBF (44479) */ - 3343, /* ADC0 (44480) */ - 3343, /* ADC1 (44481) */ - 3343, /* ADC2 (44482) */ - 3343, /* ADC3 (44483) */ - 3343, /* ADC4 (44484) */ - 3343, /* ADC5 (44485) */ - 3343, /* ADC6 (44486) */ - 3343, /* ADC7 (44487) */ - 3343, /* ADC8 (44488) */ - 3343, /* ADC9 (44489) */ - 3343, /* ADCA (44490) */ - 3343, /* ADCB (44491) */ - 3343, /* ADCC (44492) */ - 3343, /* ADCD (44493) */ - 3343, /* ADCE (44494) */ - 3343, /* ADCF (44495) */ - 3343, /* ADD0 (44496) */ - 3343, /* ADD1 (44497) */ - 3343, /* ADD2 (44498) */ - 3343, /* ADD3 (44499) */ - 3343, /* ADD4 (44500) */ - 3343, /* ADD5 (44501) */ - 3343, /* ADD6 (44502) */ - 3343, /* ADD7 (44503) */ - 3343, /* ADD8 (44504) */ - 3343, /* ADD9 (44505) */ - 3343, /* ADDA (44506) */ - 3343, /* ADDB (44507) */ - 3343, /* ADDC (44508) */ - 3343, /* ADDD (44509) */ - 3343, /* ADDE (44510) */ - 3343, /* ADDF (44511) */ - 3343, /* ADE0 (44512) */ - 3343, /* ADE1 (44513) */ - 3343, /* ADE2 (44514) */ - 3343, /* ADE3 (44515) */ - 3343, /* ADE4 (44516) */ - 3343, /* ADE5 (44517) */ - 3343, /* ADE6 (44518) */ - 3343, /* ADE7 (44519) */ - 3343, /* ADE8 (44520) */ - 3343, /* ADE9 (44521) */ - 3343, /* ADEA (44522) */ - 3343, /* ADEB (44523) */ - 3343, /* ADEC (44524) */ - 3343, /* ADED (44525) */ - 3343, /* ADEE (44526) */ - 3343, /* ADEF (44527) */ - 3343, /* ADF0 (44528) */ - 3343, /* ADF1 (44529) */ - 3343, /* ADF2 (44530) */ - 3343, /* ADF3 (44531) */ - 3343, /* ADF4 (44532) */ - 3343, /* ADF5 (44533) */ - 3343, /* ADF6 (44534) */ - 3343, /* ADF7 (44535) */ - 3343, /* ADF8 (44536) */ - 3343, /* ADF9 (44537) */ - 3343, /* ADFA (44538) */ - 3343, /* ADFB (44539) */ - 3343, /* ADFC (44540) */ - 3343, /* ADFD (44541) */ - 3343, /* ADFE (44542) */ - 3343, /* ADFF (44543) */ - 3343, /* AE00 (44544) */ - 3343, /* AE01 (44545) */ - 3343, /* AE02 (44546) */ - 3343, /* AE03 (44547) */ - 3343, /* AE04 (44548) */ - 3343, /* AE05 (44549) */ - 3343, /* AE06 (44550) */ - 3343, /* AE07 (44551) */ - 3343, /* AE08 (44552) */ - 3343, /* AE09 (44553) */ - 3343, /* AE0A (44554) */ - 3343, /* AE0B (44555) */ - 3343, /* AE0C (44556) */ - 3343, /* AE0D (44557) */ - 3343, /* AE0E (44558) */ - 3343, /* AE0F (44559) */ - 3343, /* AE10 (44560) */ - 3343, /* AE11 (44561) */ - 3343, /* AE12 (44562) */ - 3343, /* AE13 (44563) */ - 3343, /* AE14 (44564) */ - 3343, /* AE15 (44565) */ - 3343, /* AE16 (44566) */ - 3343, /* AE17 (44567) */ - 3343, /* AE18 (44568) */ - 3343, /* AE19 (44569) */ - 3343, /* AE1A (44570) */ - 3343, /* AE1B (44571) */ - 3343, /* AE1C (44572) */ - 3343, /* AE1D (44573) */ - 3343, /* AE1E (44574) */ - 3343, /* AE1F (44575) */ - 3343, /* AE20 (44576) */ - 3343, /* AE21 (44577) */ - 3343, /* AE22 (44578) */ - 3343, /* AE23 (44579) */ - 3343, /* AE24 (44580) */ - 3343, /* AE25 (44581) */ - 3343, /* AE26 (44582) */ - 3343, /* AE27 (44583) */ - 3343, /* AE28 (44584) */ - 3343, /* AE29 (44585) */ - 3343, /* AE2A (44586) */ - 3343, /* AE2B (44587) */ - 3343, /* AE2C (44588) */ - 3343, /* AE2D (44589) */ - 3343, /* AE2E (44590) */ - 3343, /* AE2F (44591) */ - 3343, /* AE30 (44592) */ - 3343, /* AE31 (44593) */ - 3343, /* AE32 (44594) */ - 3343, /* AE33 (44595) */ - 3343, /* AE34 (44596) */ - 3343, /* AE35 (44597) */ - 3343, /* AE36 (44598) */ - 3343, /* AE37 (44599) */ - 3343, /* AE38 (44600) */ - 3343, /* AE39 (44601) */ - 3343, /* AE3A (44602) */ - 3343, /* AE3B (44603) */ - 3343, /* AE3C (44604) */ - 3343, /* AE3D (44605) */ - 3343, /* AE3E (44606) */ - 3343, /* AE3F (44607) */ - 3343, /* AE40 (44608) */ - 3343, /* AE41 (44609) */ - 3343, /* AE42 (44610) */ - 3343, /* AE43 (44611) */ - 3343, /* AE44 (44612) */ - 3343, /* AE45 (44613) */ - 3343, /* AE46 (44614) */ - 3343, /* AE47 (44615) */ - 3343, /* AE48 (44616) */ - 3343, /* AE49 (44617) */ - 3343, /* AE4A (44618) */ - 3343, /* AE4B (44619) */ - 3343, /* AE4C (44620) */ - 3343, /* AE4D (44621) */ - 3343, /* AE4E (44622) */ - 3343, /* AE4F (44623) */ - 3343, /* AE50 (44624) */ - 3343, /* AE51 (44625) */ - 3343, /* AE52 (44626) */ - 3343, /* AE53 (44627) */ - 3343, /* AE54 (44628) */ - 3343, /* AE55 (44629) */ - 3343, /* AE56 (44630) */ - 3343, /* AE57 (44631) */ - 3343, /* AE58 (44632) */ - 3343, /* AE59 (44633) */ - 3343, /* AE5A (44634) */ - 3343, /* AE5B (44635) */ - 3343, /* AE5C (44636) */ - 3343, /* AE5D (44637) */ - 3343, /* AE5E (44638) */ - 3343, /* AE5F (44639) */ - 3343, /* AE60 (44640) */ - 3343, /* AE61 (44641) */ - 3343, /* AE62 (44642) */ - 3343, /* AE63 (44643) */ - 3343, /* AE64 (44644) */ - 3343, /* AE65 (44645) */ - 3343, /* AE66 (44646) */ - 3343, /* AE67 (44647) */ - 3343, /* AE68 (44648) */ - 3343, /* AE69 (44649) */ - 3343, /* AE6A (44650) */ - 3343, /* AE6B (44651) */ - 3343, /* AE6C (44652) */ - 3343, /* AE6D (44653) */ - 3343, /* AE6E (44654) */ - 3343, /* AE6F (44655) */ - 3343, /* AE70 (44656) */ - 3343, /* AE71 (44657) */ - 3343, /* AE72 (44658) */ - 3343, /* AE73 (44659) */ - 3343, /* AE74 (44660) */ - 3343, /* AE75 (44661) */ - 3343, /* AE76 (44662) */ - 3343, /* AE77 (44663) */ - 3343, /* AE78 (44664) */ - 3343, /* AE79 (44665) */ - 3343, /* AE7A (44666) */ - 3343, /* AE7B (44667) */ - 3343, /* AE7C (44668) */ - 3343, /* AE7D (44669) */ - 3343, /* AE7E (44670) */ - 3343, /* AE7F (44671) */ - 3343, /* AE80 (44672) */ - 3343, /* AE81 (44673) */ - 3343, /* AE82 (44674) */ - 3343, /* AE83 (44675) */ - 3343, /* AE84 (44676) */ - 3343, /* AE85 (44677) */ - 3343, /* AE86 (44678) */ - 3343, /* AE87 (44679) */ - 3343, /* AE88 (44680) */ - 3343, /* AE89 (44681) */ - 3343, /* AE8A (44682) */ - 3343, /* AE8B (44683) */ - 3343, /* AE8C (44684) */ - 3343, /* AE8D (44685) */ - 3343, /* AE8E (44686) */ - 3343, /* AE8F (44687) */ - 3343, /* AE90 (44688) */ - 3343, /* AE91 (44689) */ - 3343, /* AE92 (44690) */ - 3343, /* AE93 (44691) */ - 3343, /* AE94 (44692) */ - 3343, /* AE95 (44693) */ - 3343, /* AE96 (44694) */ - 3343, /* AE97 (44695) */ - 3343, /* AE98 (44696) */ - 3343, /* AE99 (44697) */ - 3343, /* AE9A (44698) */ - 3343, /* AE9B (44699) */ - 3343, /* AE9C (44700) */ - 3343, /* AE9D (44701) */ - 3343, /* AE9E (44702) */ - 3343, /* AE9F (44703) */ - 3343, /* AEA0 (44704) */ - 3343, /* AEA1 (44705) */ - 3343, /* AEA2 (44706) */ - 3343, /* AEA3 (44707) */ - 3343, /* AEA4 (44708) */ - 3343, /* AEA5 (44709) */ - 3343, /* AEA6 (44710) */ - 3343, /* AEA7 (44711) */ - 3343, /* AEA8 (44712) */ - 3343, /* AEA9 (44713) */ - 3343, /* AEAA (44714) */ - 3343, /* AEAB (44715) */ - 3343, /* AEAC (44716) */ - 3343, /* AEAD (44717) */ - 3343, /* AEAE (44718) */ - 3343, /* AEAF (44719) */ - 3343, /* AEB0 (44720) */ - 3343, /* AEB1 (44721) */ - 3343, /* AEB2 (44722) */ - 3343, /* AEB3 (44723) */ - 3343, /* AEB4 (44724) */ - 3343, /* AEB5 (44725) */ - 3343, /* AEB6 (44726) */ - 3343, /* AEB7 (44727) */ - 3343, /* AEB8 (44728) */ - 3343, /* AEB9 (44729) */ - 3343, /* AEBA (44730) */ - 3343, /* AEBB (44731) */ - 3343, /* AEBC (44732) */ - 3343, /* AEBD (44733) */ - 3343, /* AEBE (44734) */ - 3343, /* AEBF (44735) */ - 3343, /* AEC0 (44736) */ - 3343, /* AEC1 (44737) */ - 3343, /* AEC2 (44738) */ - 3343, /* AEC3 (44739) */ - 3343, /* AEC4 (44740) */ - 3343, /* AEC5 (44741) */ - 3343, /* AEC6 (44742) */ - 3343, /* AEC7 (44743) */ - 3343, /* AEC8 (44744) */ - 3343, /* AEC9 (44745) */ - 3343, /* AECA (44746) */ - 3343, /* AECB (44747) */ - 3343, /* AECC (44748) */ - 3343, /* AECD (44749) */ - 3343, /* AECE (44750) */ - 3343, /* AECF (44751) */ - 3343, /* AED0 (44752) */ - 3343, /* AED1 (44753) */ - 3343, /* AED2 (44754) */ - 3343, /* AED3 (44755) */ - 3343, /* AED4 (44756) */ - 3343, /* AED5 (44757) */ - 3343, /* AED6 (44758) */ - 3343, /* AED7 (44759) */ - 3343, /* AED8 (44760) */ - 3343, /* AED9 (44761) */ - 3343, /* AEDA (44762) */ - 3343, /* AEDB (44763) */ - 3343, /* AEDC (44764) */ - 3343, /* AEDD (44765) */ - 3343, /* AEDE (44766) */ - 3343, /* AEDF (44767) */ - 3343, /* AEE0 (44768) */ - 3343, /* AEE1 (44769) */ - 3343, /* AEE2 (44770) */ - 3343, /* AEE3 (44771) */ - 3343, /* AEE4 (44772) */ - 3343, /* AEE5 (44773) */ - 3343, /* AEE6 (44774) */ - 3343, /* AEE7 (44775) */ - 3343, /* AEE8 (44776) */ - 3343, /* AEE9 (44777) */ - 3343, /* AEEA (44778) */ - 3343, /* AEEB (44779) */ - 3343, /* AEEC (44780) */ - 3343, /* AEED (44781) */ - 3343, /* AEEE (44782) */ - 3343, /* AEEF (44783) */ - 3343, /* AEF0 (44784) */ - 3343, /* AEF1 (44785) */ - 3343, /* AEF2 (44786) */ - 3343, /* AEF3 (44787) */ - 3343, /* AEF4 (44788) */ - 3343, /* AEF5 (44789) */ - 3343, /* AEF6 (44790) */ - 3343, /* AEF7 (44791) */ - 3343, /* AEF8 (44792) */ - 3343, /* AEF9 (44793) */ - 3343, /* AEFA (44794) */ - 3343, /* AEFB (44795) */ - 3343, /* AEFC (44796) */ - 3343, /* AEFD (44797) */ - 3343, /* AEFE (44798) */ - 3343, /* AEFF (44799) */ - 3343, /* AF00 (44800) */ - 3343, /* AF01 (44801) */ - 3343, /* AF02 (44802) */ - 3343, /* AF03 (44803) */ - 3343, /* AF04 (44804) */ - 3343, /* AF05 (44805) */ - 3343, /* AF06 (44806) */ - 3343, /* AF07 (44807) */ - 3343, /* AF08 (44808) */ - 3343, /* AF09 (44809) */ - 3343, /* AF0A (44810) */ - 3343, /* AF0B (44811) */ - 3343, /* AF0C (44812) */ - 3343, /* AF0D (44813) */ - 3343, /* AF0E (44814) */ - 3343, /* AF0F (44815) */ - 3343, /* AF10 (44816) */ - 3343, /* AF11 (44817) */ - 3343, /* AF12 (44818) */ - 3343, /* AF13 (44819) */ - 3343, /* AF14 (44820) */ - 3343, /* AF15 (44821) */ - 3343, /* AF16 (44822) */ - 3343, /* AF17 (44823) */ - 3343, /* AF18 (44824) */ - 3343, /* AF19 (44825) */ - 3343, /* AF1A (44826) */ - 3343, /* AF1B (44827) */ - 3343, /* AF1C (44828) */ - 3343, /* AF1D (44829) */ - 3343, /* AF1E (44830) */ - 3343, /* AF1F (44831) */ - 3343, /* AF20 (44832) */ - 3343, /* AF21 (44833) */ - 3343, /* AF22 (44834) */ - 3343, /* AF23 (44835) */ - 3343, /* AF24 (44836) */ - 3343, /* AF25 (44837) */ - 3343, /* AF26 (44838) */ - 3343, /* AF27 (44839) */ - 3343, /* AF28 (44840) */ - 3343, /* AF29 (44841) */ - 3343, /* AF2A (44842) */ - 3343, /* AF2B (44843) */ - 3343, /* AF2C (44844) */ - 3343, /* AF2D (44845) */ - 3343, /* AF2E (44846) */ - 3343, /* AF2F (44847) */ - 3343, /* AF30 (44848) */ - 3343, /* AF31 (44849) */ - 3343, /* AF32 (44850) */ - 3343, /* AF33 (44851) */ - 3343, /* AF34 (44852) */ - 3343, /* AF35 (44853) */ - 3343, /* AF36 (44854) */ - 3343, /* AF37 (44855) */ - 3343, /* AF38 (44856) */ - 3343, /* AF39 (44857) */ - 3343, /* AF3A (44858) */ - 3343, /* AF3B (44859) */ - 3343, /* AF3C (44860) */ - 3343, /* AF3D (44861) */ - 3343, /* AF3E (44862) */ - 3343, /* AF3F (44863) */ - 3343, /* AF40 (44864) */ - 3343, /* AF41 (44865) */ - 3343, /* AF42 (44866) */ - 3343, /* AF43 (44867) */ - 3343, /* AF44 (44868) */ - 3343, /* AF45 (44869) */ - 3343, /* AF46 (44870) */ - 3343, /* AF47 (44871) */ - 3343, /* AF48 (44872) */ - 3343, /* AF49 (44873) */ - 3343, /* AF4A (44874) */ - 3343, /* AF4B (44875) */ - 3343, /* AF4C (44876) */ - 3343, /* AF4D (44877) */ - 3343, /* AF4E (44878) */ - 3343, /* AF4F (44879) */ - 3343, /* AF50 (44880) */ - 3343, /* AF51 (44881) */ - 3343, /* AF52 (44882) */ - 3343, /* AF53 (44883) */ - 3343, /* AF54 (44884) */ - 3343, /* AF55 (44885) */ - 3343, /* AF56 (44886) */ - 3343, /* AF57 (44887) */ - 3343, /* AF58 (44888) */ - 3343, /* AF59 (44889) */ - 3343, /* AF5A (44890) */ - 3343, /* AF5B (44891) */ - 3343, /* AF5C (44892) */ - 3343, /* AF5D (44893) */ - 3343, /* AF5E (44894) */ - 3343, /* AF5F (44895) */ - 3343, /* AF60 (44896) */ - 3343, /* AF61 (44897) */ - 3343, /* AF62 (44898) */ - 3343, /* AF63 (44899) */ - 3343, /* AF64 (44900) */ - 3343, /* AF65 (44901) */ - 3343, /* AF66 (44902) */ - 3343, /* AF67 (44903) */ - 3343, /* AF68 (44904) */ - 3343, /* AF69 (44905) */ - 3343, /* AF6A (44906) */ - 3343, /* AF6B (44907) */ - 3343, /* AF6C (44908) */ - 3343, /* AF6D (44909) */ - 3343, /* AF6E (44910) */ - 3343, /* AF6F (44911) */ - 3343, /* AF70 (44912) */ - 3343, /* AF71 (44913) */ - 3343, /* AF72 (44914) */ - 3343, /* AF73 (44915) */ - 3343, /* AF74 (44916) */ - 3343, /* AF75 (44917) */ - 3343, /* AF76 (44918) */ - 3343, /* AF77 (44919) */ - 3343, /* AF78 (44920) */ - 3343, /* AF79 (44921) */ - 3343, /* AF7A (44922) */ - 3343, /* AF7B (44923) */ - 3343, /* AF7C (44924) */ - 3343, /* AF7D (44925) */ - 3343, /* AF7E (44926) */ - 3343, /* AF7F (44927) */ - 3343, /* AF80 (44928) */ - 3343, /* AF81 (44929) */ - 3343, /* AF82 (44930) */ - 3343, /* AF83 (44931) */ - 3343, /* AF84 (44932) */ - 3343, /* AF85 (44933) */ - 3343, /* AF86 (44934) */ - 3343, /* AF87 (44935) */ - 3343, /* AF88 (44936) */ - 3343, /* AF89 (44937) */ - 3343, /* AF8A (44938) */ - 3343, /* AF8B (44939) */ - 3343, /* AF8C (44940) */ - 3343, /* AF8D (44941) */ - 3343, /* AF8E (44942) */ - 3343, /* AF8F (44943) */ - 3343, /* AF90 (44944) */ - 3343, /* AF91 (44945) */ - 3343, /* AF92 (44946) */ - 3343, /* AF93 (44947) */ - 3343, /* AF94 (44948) */ - 3343, /* AF95 (44949) */ - 3343, /* AF96 (44950) */ - 3343, /* AF97 (44951) */ - 3343, /* AF98 (44952) */ - 3343, /* AF99 (44953) */ - 3343, /* AF9A (44954) */ - 3343, /* AF9B (44955) */ - 3343, /* AF9C (44956) */ - 3343, /* AF9D (44957) */ - 3343, /* AF9E (44958) */ - 3343, /* AF9F (44959) */ - 3343, /* AFA0 (44960) */ - 3343, /* AFA1 (44961) */ - 3343, /* AFA2 (44962) */ - 3343, /* AFA3 (44963) */ - 3343, /* AFA4 (44964) */ - 3343, /* AFA5 (44965) */ - 3343, /* AFA6 (44966) */ - 3343, /* AFA7 (44967) */ - 3343, /* AFA8 (44968) */ - 3343, /* AFA9 (44969) */ - 3343, /* AFAA (44970) */ - 3343, /* AFAB (44971) */ - 3343, /* AFAC (44972) */ - 3343, /* AFAD (44973) */ - 3343, /* AFAE (44974) */ - 3343, /* AFAF (44975) */ - 3343, /* AFB0 (44976) */ - 3343, /* AFB1 (44977) */ - 3343, /* AFB2 (44978) */ - 3343, /* AFB3 (44979) */ - 3343, /* AFB4 (44980) */ - 3343, /* AFB5 (44981) */ - 3343, /* AFB6 (44982) */ - 3343, /* AFB7 (44983) */ - 3343, /* AFB8 (44984) */ - 3343, /* AFB9 (44985) */ - 3343, /* AFBA (44986) */ - 3343, /* AFBB (44987) */ - 3343, /* AFBC (44988) */ - 3343, /* AFBD (44989) */ - 3343, /* AFBE (44990) */ - 3343, /* AFBF (44991) */ - 3343, /* AFC0 (44992) */ - 3343, /* AFC1 (44993) */ - 3343, /* AFC2 (44994) */ - 3343, /* AFC3 (44995) */ - 3343, /* AFC4 (44996) */ - 3343, /* AFC5 (44997) */ - 3343, /* AFC6 (44998) */ - 3343, /* AFC7 (44999) */ - 3343, /* AFC8 (45000) */ - 3343, /* AFC9 (45001) */ - 3343, /* AFCA (45002) */ - 3343, /* AFCB (45003) */ - 3343, /* AFCC (45004) */ - 3343, /* AFCD (45005) */ - 3343, /* AFCE (45006) */ - 3343, /* AFCF (45007) */ - 3343, /* AFD0 (45008) */ - 3343, /* AFD1 (45009) */ - 3343, /* AFD2 (45010) */ - 3343, /* AFD3 (45011) */ - 3343, /* AFD4 (45012) */ - 3343, /* AFD5 (45013) */ - 3343, /* AFD6 (45014) */ - 3343, /* AFD7 (45015) */ - 3343, /* AFD8 (45016) */ - 3343, /* AFD9 (45017) */ - 3343, /* AFDA (45018) */ - 3343, /* AFDB (45019) */ - 3343, /* AFDC (45020) */ - 3343, /* AFDD (45021) */ - 3343, /* AFDE (45022) */ - 3343, /* AFDF (45023) */ - 3343, /* AFE0 (45024) */ - 3343, /* AFE1 (45025) */ - 3343, /* AFE2 (45026) */ - 3343, /* AFE3 (45027) */ - 3343, /* AFE4 (45028) */ - 3343, /* AFE5 (45029) */ - 3343, /* AFE6 (45030) */ - 3343, /* AFE7 (45031) */ - 3343, /* AFE8 (45032) */ - 3343, /* AFE9 (45033) */ - 3343, /* AFEA (45034) */ - 3343, /* AFEB (45035) */ - 3343, /* AFEC (45036) */ - 3343, /* AFED (45037) */ - 3343, /* AFEE (45038) */ - 3343, /* AFEF (45039) */ - 3343, /* AFF0 (45040) */ - 3343, /* AFF1 (45041) */ - 3343, /* AFF2 (45042) */ - 3343, /* AFF3 (45043) */ - 3343, /* AFF4 (45044) */ - 3343, /* AFF5 (45045) */ - 3343, /* AFF6 (45046) */ - 3343, /* AFF7 (45047) */ - 3343, /* AFF8 (45048) */ - 3343, /* AFF9 (45049) */ - 3343, /* AFFA (45050) */ - 3343, /* AFFB (45051) */ - 3343, /* AFFC (45052) */ - 3343, /* AFFD (45053) */ - 3343, /* AFFE (45054) */ - 3343, /* AFFF (45055) */ - 3343, /* B000 (45056) */ - 3343, /* B001 (45057) */ - 3343, /* B002 (45058) */ - 3343, /* B003 (45059) */ - 3343, /* B004 (45060) */ - 3343, /* B005 (45061) */ - 3343, /* B006 (45062) */ - 3343, /* B007 (45063) */ - 3343, /* B008 (45064) */ - 3343, /* B009 (45065) */ - 3343, /* B00A (45066) */ - 3343, /* B00B (45067) */ - 3343, /* B00C (45068) */ - 3343, /* B00D (45069) */ - 3343, /* B00E (45070) */ - 3343, /* B00F (45071) */ - 3343, /* B010 (45072) */ - 3343, /* B011 (45073) */ - 3343, /* B012 (45074) */ - 3343, /* B013 (45075) */ - 3343, /* B014 (45076) */ - 3343, /* B015 (45077) */ - 3343, /* B016 (45078) */ - 3343, /* B017 (45079) */ - 3343, /* B018 (45080) */ - 3343, /* B019 (45081) */ - 3343, /* B01A (45082) */ - 3343, /* B01B (45083) */ - 3343, /* B01C (45084) */ - 3343, /* B01D (45085) */ - 3343, /* B01E (45086) */ - 3343, /* B01F (45087) */ - 3343, /* B020 (45088) */ - 3343, /* B021 (45089) */ - 3343, /* B022 (45090) */ - 3343, /* B023 (45091) */ - 3343, /* B024 (45092) */ - 3343, /* B025 (45093) */ - 3343, /* B026 (45094) */ - 3343, /* B027 (45095) */ - 3343, /* B028 (45096) */ - 3343, /* B029 (45097) */ - 3343, /* B02A (45098) */ - 3343, /* B02B (45099) */ - 3343, /* B02C (45100) */ - 3343, /* B02D (45101) */ - 3343, /* B02E (45102) */ - 3343, /* B02F (45103) */ - 3343, /* B030 (45104) */ - 3343, /* B031 (45105) */ - 3343, /* B032 (45106) */ - 3343, /* B033 (45107) */ - 3343, /* B034 (45108) */ - 3343, /* B035 (45109) */ - 3343, /* B036 (45110) */ - 3343, /* B037 (45111) */ - 3343, /* B038 (45112) */ - 3343, /* B039 (45113) */ - 3343, /* B03A (45114) */ - 3343, /* B03B (45115) */ - 3343, /* B03C (45116) */ - 3343, /* B03D (45117) */ - 3343, /* B03E (45118) */ - 3343, /* B03F (45119) */ - 3343, /* B040 (45120) */ - 3343, /* B041 (45121) */ - 3343, /* B042 (45122) */ - 3343, /* B043 (45123) */ - 3343, /* B044 (45124) */ - 3343, /* B045 (45125) */ - 3343, /* B046 (45126) */ - 3343, /* B047 (45127) */ - 3343, /* B048 (45128) */ - 3343, /* B049 (45129) */ - 3343, /* B04A (45130) */ - 3343, /* B04B (45131) */ - 3343, /* B04C (45132) */ - 3343, /* B04D (45133) */ - 3343, /* B04E (45134) */ - 3343, /* B04F (45135) */ - 3343, /* B050 (45136) */ - 3343, /* B051 (45137) */ - 3343, /* B052 (45138) */ - 3343, /* B053 (45139) */ - 3343, /* B054 (45140) */ - 3343, /* B055 (45141) */ - 3343, /* B056 (45142) */ - 3343, /* B057 (45143) */ - 3343, /* B058 (45144) */ - 3343, /* B059 (45145) */ - 3343, /* B05A (45146) */ - 3343, /* B05B (45147) */ - 3343, /* B05C (45148) */ - 3343, /* B05D (45149) */ - 3343, /* B05E (45150) */ - 3343, /* B05F (45151) */ - 3343, /* B060 (45152) */ - 3343, /* B061 (45153) */ - 3343, /* B062 (45154) */ - 3343, /* B063 (45155) */ - 3343, /* B064 (45156) */ - 3343, /* B065 (45157) */ - 3343, /* B066 (45158) */ - 3343, /* B067 (45159) */ - 3343, /* B068 (45160) */ - 3343, /* B069 (45161) */ - 3343, /* B06A (45162) */ - 3343, /* B06B (45163) */ - 3343, /* B06C (45164) */ - 3343, /* B06D (45165) */ - 3343, /* B06E (45166) */ - 3343, /* B06F (45167) */ - 3343, /* B070 (45168) */ - 3343, /* B071 (45169) */ - 3343, /* B072 (45170) */ - 3343, /* B073 (45171) */ - 3343, /* B074 (45172) */ - 3343, /* B075 (45173) */ - 3343, /* B076 (45174) */ - 3343, /* B077 (45175) */ - 3343, /* B078 (45176) */ - 3343, /* B079 (45177) */ - 3343, /* B07A (45178) */ - 3343, /* B07B (45179) */ - 3343, /* B07C (45180) */ - 3343, /* B07D (45181) */ - 3343, /* B07E (45182) */ - 3343, /* B07F (45183) */ - 3343, /* B080 (45184) */ - 3343, /* B081 (45185) */ - 3343, /* B082 (45186) */ - 3343, /* B083 (45187) */ - 3343, /* B084 (45188) */ - 3343, /* B085 (45189) */ - 3343, /* B086 (45190) */ - 3343, /* B087 (45191) */ - 3343, /* B088 (45192) */ - 3343, /* B089 (45193) */ - 3343, /* B08A (45194) */ - 3343, /* B08B (45195) */ - 3343, /* B08C (45196) */ - 3343, /* B08D (45197) */ - 3343, /* B08E (45198) */ - 3343, /* B08F (45199) */ - 3343, /* B090 (45200) */ - 3343, /* B091 (45201) */ - 3343, /* B092 (45202) */ - 3343, /* B093 (45203) */ - 3343, /* B094 (45204) */ - 3343, /* B095 (45205) */ - 3343, /* B096 (45206) */ - 3343, /* B097 (45207) */ - 3343, /* B098 (45208) */ - 3343, /* B099 (45209) */ - 3343, /* B09A (45210) */ - 3343, /* B09B (45211) */ - 3343, /* B09C (45212) */ - 3343, /* B09D (45213) */ - 3343, /* B09E (45214) */ - 3343, /* B09F (45215) */ - 3343, /* B0A0 (45216) */ - 3343, /* B0A1 (45217) */ - 3343, /* B0A2 (45218) */ - 3343, /* B0A3 (45219) */ - 3343, /* B0A4 (45220) */ - 3343, /* B0A5 (45221) */ - 3343, /* B0A6 (45222) */ - 3343, /* B0A7 (45223) */ - 3343, /* B0A8 (45224) */ - 3343, /* B0A9 (45225) */ - 3343, /* B0AA (45226) */ - 3343, /* B0AB (45227) */ - 3343, /* B0AC (45228) */ - 3343, /* B0AD (45229) */ - 3343, /* B0AE (45230) */ - 3343, /* B0AF (45231) */ - 3343, /* B0B0 (45232) */ - 3343, /* B0B1 (45233) */ - 3343, /* B0B2 (45234) */ - 3343, /* B0B3 (45235) */ - 3343, /* B0B4 (45236) */ - 3343, /* B0B5 (45237) */ - 3343, /* B0B6 (45238) */ - 3343, /* B0B7 (45239) */ - 3343, /* B0B8 (45240) */ - 3343, /* B0B9 (45241) */ - 3343, /* B0BA (45242) */ - 3343, /* B0BB (45243) */ - 3343, /* B0BC (45244) */ - 3343, /* B0BD (45245) */ - 3343, /* B0BE (45246) */ - 3343, /* B0BF (45247) */ - 3343, /* B0C0 (45248) */ - 3343, /* B0C1 (45249) */ - 3343, /* B0C2 (45250) */ - 3343, /* B0C3 (45251) */ - 3343, /* B0C4 (45252) */ - 3343, /* B0C5 (45253) */ - 3343, /* B0C6 (45254) */ - 3343, /* B0C7 (45255) */ - 3343, /* B0C8 (45256) */ - 3343, /* B0C9 (45257) */ - 3343, /* B0CA (45258) */ - 3343, /* B0CB (45259) */ - 3343, /* B0CC (45260) */ - 3343, /* B0CD (45261) */ - 3343, /* B0CE (45262) */ - 3343, /* B0CF (45263) */ - 3343, /* B0D0 (45264) */ - 3343, /* B0D1 (45265) */ - 3343, /* B0D2 (45266) */ - 3343, /* B0D3 (45267) */ - 3343, /* B0D4 (45268) */ - 3343, /* B0D5 (45269) */ - 3343, /* B0D6 (45270) */ - 3343, /* B0D7 (45271) */ - 3343, /* B0D8 (45272) */ - 3343, /* B0D9 (45273) */ - 3343, /* B0DA (45274) */ - 3343, /* B0DB (45275) */ - 3343, /* B0DC (45276) */ - 3343, /* B0DD (45277) */ - 3343, /* B0DE (45278) */ - 3343, /* B0DF (45279) */ - 3343, /* B0E0 (45280) */ - 3343, /* B0E1 (45281) */ - 3343, /* B0E2 (45282) */ - 3343, /* B0E3 (45283) */ - 3343, /* B0E4 (45284) */ - 3343, /* B0E5 (45285) */ - 3343, /* B0E6 (45286) */ - 3343, /* B0E7 (45287) */ - 3343, /* B0E8 (45288) */ - 3343, /* B0E9 (45289) */ - 3343, /* B0EA (45290) */ - 3343, /* B0EB (45291) */ - 3343, /* B0EC (45292) */ - 3343, /* B0ED (45293) */ - 3343, /* B0EE (45294) */ - 3343, /* B0EF (45295) */ - 3343, /* B0F0 (45296) */ - 3343, /* B0F1 (45297) */ - 3343, /* B0F2 (45298) */ - 3343, /* B0F3 (45299) */ - 3343, /* B0F4 (45300) */ - 3343, /* B0F5 (45301) */ - 3343, /* B0F6 (45302) */ - 3343, /* B0F7 (45303) */ - 3343, /* B0F8 (45304) */ - 3343, /* B0F9 (45305) */ - 3343, /* B0FA (45306) */ - 3343, /* B0FB (45307) */ - 3343, /* B0FC (45308) */ - 3343, /* B0FD (45309) */ - 3343, /* B0FE (45310) */ - 3343, /* B0FF (45311) */ - 3343, /* B100 (45312) */ - 3343, /* B101 (45313) */ - 3343, /* B102 (45314) */ - 3343, /* B103 (45315) */ - 3343, /* B104 (45316) */ - 3343, /* B105 (45317) */ - 3343, /* B106 (45318) */ - 3343, /* B107 (45319) */ - 3343, /* B108 (45320) */ - 3343, /* B109 (45321) */ - 3343, /* B10A (45322) */ - 3343, /* B10B (45323) */ - 3343, /* B10C (45324) */ - 3343, /* B10D (45325) */ - 3343, /* B10E (45326) */ - 3343, /* B10F (45327) */ - 3343, /* B110 (45328) */ - 3343, /* B111 (45329) */ - 3343, /* B112 (45330) */ - 3343, /* B113 (45331) */ - 3343, /* B114 (45332) */ - 3343, /* B115 (45333) */ - 3343, /* B116 (45334) */ - 3343, /* B117 (45335) */ - 3343, /* B118 (45336) */ - 3343, /* B119 (45337) */ - 3343, /* B11A (45338) */ - 3343, /* B11B (45339) */ - 3343, /* B11C (45340) */ - 3343, /* B11D (45341) */ - 3343, /* B11E (45342) */ - 3343, /* B11F (45343) */ - 3343, /* B120 (45344) */ - 3343, /* B121 (45345) */ - 3343, /* B122 (45346) */ - 3343, /* B123 (45347) */ - 3343, /* B124 (45348) */ - 3343, /* B125 (45349) */ - 3343, /* B126 (45350) */ - 3343, /* B127 (45351) */ - 3343, /* B128 (45352) */ - 3343, /* B129 (45353) */ - 3343, /* B12A (45354) */ - 3343, /* B12B (45355) */ - 3343, /* B12C (45356) */ - 3343, /* B12D (45357) */ - 3343, /* B12E (45358) */ - 3343, /* B12F (45359) */ - 3343, /* B130 (45360) */ - 3343, /* B131 (45361) */ - 3343, /* B132 (45362) */ - 3343, /* B133 (45363) */ - 3343, /* B134 (45364) */ - 3343, /* B135 (45365) */ - 3343, /* B136 (45366) */ - 3343, /* B137 (45367) */ - 3343, /* B138 (45368) */ - 3343, /* B139 (45369) */ - 3343, /* B13A (45370) */ - 3343, /* B13B (45371) */ - 3343, /* B13C (45372) */ - 3343, /* B13D (45373) */ - 3343, /* B13E (45374) */ - 3343, /* B13F (45375) */ - 3343, /* B140 (45376) */ - 3343, /* B141 (45377) */ - 3343, /* B142 (45378) */ - 3343, /* B143 (45379) */ - 3343, /* B144 (45380) */ - 3343, /* B145 (45381) */ - 3343, /* B146 (45382) */ - 3343, /* B147 (45383) */ - 3343, /* B148 (45384) */ - 3343, /* B149 (45385) */ - 3343, /* B14A (45386) */ - 3343, /* B14B (45387) */ - 3343, /* B14C (45388) */ - 3343, /* B14D (45389) */ - 3343, /* B14E (45390) */ - 3343, /* B14F (45391) */ - 3343, /* B150 (45392) */ - 3343, /* B151 (45393) */ - 3343, /* B152 (45394) */ - 3343, /* B153 (45395) */ - 3343, /* B154 (45396) */ - 3343, /* B155 (45397) */ - 3343, /* B156 (45398) */ - 3343, /* B157 (45399) */ - 3343, /* B158 (45400) */ - 3343, /* B159 (45401) */ - 3343, /* B15A (45402) */ - 3343, /* B15B (45403) */ - 3343, /* B15C (45404) */ - 3343, /* B15D (45405) */ - 3343, /* B15E (45406) */ - 3343, /* B15F (45407) */ - 3343, /* B160 (45408) */ - 3343, /* B161 (45409) */ - 3343, /* B162 (45410) */ - 3343, /* B163 (45411) */ - 3343, /* B164 (45412) */ - 3343, /* B165 (45413) */ - 3343, /* B166 (45414) */ - 3343, /* B167 (45415) */ - 3343, /* B168 (45416) */ - 3343, /* B169 (45417) */ - 3343, /* B16A (45418) */ - 3343, /* B16B (45419) */ - 3343, /* B16C (45420) */ - 3343, /* B16D (45421) */ - 3343, /* B16E (45422) */ - 3343, /* B16F (45423) */ - 3343, /* B170 (45424) */ - 3343, /* B171 (45425) */ - 3343, /* B172 (45426) */ - 3343, /* B173 (45427) */ - 3343, /* B174 (45428) */ - 3343, /* B175 (45429) */ - 3343, /* B176 (45430) */ - 3343, /* B177 (45431) */ - 3343, /* B178 (45432) */ - 3343, /* B179 (45433) */ - 3343, /* B17A (45434) */ - 3343, /* B17B (45435) */ - 3343, /* B17C (45436) */ - 3343, /* B17D (45437) */ - 3343, /* B17E (45438) */ - 3343, /* B17F (45439) */ - 3343, /* B180 (45440) */ - 3343, /* B181 (45441) */ - 3343, /* B182 (45442) */ - 3343, /* B183 (45443) */ - 3343, /* B184 (45444) */ - 3343, /* B185 (45445) */ - 3343, /* B186 (45446) */ - 3343, /* B187 (45447) */ - 3343, /* B188 (45448) */ - 3343, /* B189 (45449) */ - 3343, /* B18A (45450) */ - 3343, /* B18B (45451) */ - 3343, /* B18C (45452) */ - 3343, /* B18D (45453) */ - 3343, /* B18E (45454) */ - 3343, /* B18F (45455) */ - 3343, /* B190 (45456) */ - 3343, /* B191 (45457) */ - 3343, /* B192 (45458) */ - 3343, /* B193 (45459) */ - 3343, /* B194 (45460) */ - 3343, /* B195 (45461) */ - 3343, /* B196 (45462) */ - 3343, /* B197 (45463) */ - 3343, /* B198 (45464) */ - 3343, /* B199 (45465) */ - 3343, /* B19A (45466) */ - 3343, /* B19B (45467) */ - 3343, /* B19C (45468) */ - 3343, /* B19D (45469) */ - 3343, /* B19E (45470) */ - 3343, /* B19F (45471) */ - 3343, /* B1A0 (45472) */ - 3343, /* B1A1 (45473) */ - 3343, /* B1A2 (45474) */ - 3343, /* B1A3 (45475) */ - 3343, /* B1A4 (45476) */ - 3343, /* B1A5 (45477) */ - 3343, /* B1A6 (45478) */ - 3343, /* B1A7 (45479) */ - 3343, /* B1A8 (45480) */ - 3343, /* B1A9 (45481) */ - 3343, /* B1AA (45482) */ - 3343, /* B1AB (45483) */ - 3343, /* B1AC (45484) */ - 3343, /* B1AD (45485) */ - 3343, /* B1AE (45486) */ - 3343, /* B1AF (45487) */ - 3343, /* B1B0 (45488) */ - 3343, /* B1B1 (45489) */ - 3343, /* B1B2 (45490) */ - 3343, /* B1B3 (45491) */ - 3343, /* B1B4 (45492) */ - 3343, /* B1B5 (45493) */ - 3343, /* B1B6 (45494) */ - 3343, /* B1B7 (45495) */ - 3343, /* B1B8 (45496) */ - 3343, /* B1B9 (45497) */ - 3343, /* B1BA (45498) */ - 3343, /* B1BB (45499) */ - 3343, /* B1BC (45500) */ - 3343, /* B1BD (45501) */ - 3343, /* B1BE (45502) */ - 3343, /* B1BF (45503) */ - 3343, /* B1C0 (45504) */ - 3343, /* B1C1 (45505) */ - 3343, /* B1C2 (45506) */ - 3343, /* B1C3 (45507) */ - 3343, /* B1C4 (45508) */ - 3343, /* B1C5 (45509) */ - 3343, /* B1C6 (45510) */ - 3343, /* B1C7 (45511) */ - 3343, /* B1C8 (45512) */ - 3343, /* B1C9 (45513) */ - 3343, /* B1CA (45514) */ - 3343, /* B1CB (45515) */ - 3343, /* B1CC (45516) */ - 3343, /* B1CD (45517) */ - 3343, /* B1CE (45518) */ - 3343, /* B1CF (45519) */ - 3343, /* B1D0 (45520) */ - 3343, /* B1D1 (45521) */ - 3343, /* B1D2 (45522) */ - 3343, /* B1D3 (45523) */ - 3343, /* B1D4 (45524) */ - 3343, /* B1D5 (45525) */ - 3343, /* B1D6 (45526) */ - 3343, /* B1D7 (45527) */ - 3343, /* B1D8 (45528) */ - 3343, /* B1D9 (45529) */ - 3343, /* B1DA (45530) */ - 3343, /* B1DB (45531) */ - 3343, /* B1DC (45532) */ - 3343, /* B1DD (45533) */ - 3343, /* B1DE (45534) */ - 3343, /* B1DF (45535) */ - 3343, /* B1E0 (45536) */ - 3343, /* B1E1 (45537) */ - 3343, /* B1E2 (45538) */ - 3343, /* B1E3 (45539) */ - 3343, /* B1E4 (45540) */ - 3343, /* B1E5 (45541) */ - 3343, /* B1E6 (45542) */ - 3343, /* B1E7 (45543) */ - 3343, /* B1E8 (45544) */ - 3343, /* B1E9 (45545) */ - 3343, /* B1EA (45546) */ - 3343, /* B1EB (45547) */ - 3343, /* B1EC (45548) */ - 3343, /* B1ED (45549) */ - 3343, /* B1EE (45550) */ - 3343, /* B1EF (45551) */ - 3343, /* B1F0 (45552) */ - 3343, /* B1F1 (45553) */ - 3343, /* B1F2 (45554) */ - 3343, /* B1F3 (45555) */ - 3343, /* B1F4 (45556) */ - 3343, /* B1F5 (45557) */ - 3343, /* B1F6 (45558) */ - 3343, /* B1F7 (45559) */ - 3343, /* B1F8 (45560) */ - 3343, /* B1F9 (45561) */ - 3343, /* B1FA (45562) */ - 3343, /* B1FB (45563) */ - 3343, /* B1FC (45564) */ - 3343, /* B1FD (45565) */ - 3343, /* B1FE (45566) */ - 3343, /* B1FF (45567) */ - 3343, /* B200 (45568) */ - 3343, /* B201 (45569) */ - 3343, /* B202 (45570) */ - 3343, /* B203 (45571) */ - 3343, /* B204 (45572) */ - 3343, /* B205 (45573) */ - 3343, /* B206 (45574) */ - 3343, /* B207 (45575) */ - 3343, /* B208 (45576) */ - 3343, /* B209 (45577) */ - 3343, /* B20A (45578) */ - 3343, /* B20B (45579) */ - 3343, /* B20C (45580) */ - 3343, /* B20D (45581) */ - 3343, /* B20E (45582) */ - 3343, /* B20F (45583) */ - 3343, /* B210 (45584) */ - 3343, /* B211 (45585) */ - 3343, /* B212 (45586) */ - 3343, /* B213 (45587) */ - 3343, /* B214 (45588) */ - 3343, /* B215 (45589) */ - 3343, /* B216 (45590) */ - 3343, /* B217 (45591) */ - 3343, /* B218 (45592) */ - 3343, /* B219 (45593) */ - 3343, /* B21A (45594) */ - 3343, /* B21B (45595) */ - 3343, /* B21C (45596) */ - 3343, /* B21D (45597) */ - 3343, /* B21E (45598) */ - 3343, /* B21F (45599) */ - 3343, /* B220 (45600) */ - 3343, /* B221 (45601) */ - 3343, /* B222 (45602) */ - 3343, /* B223 (45603) */ - 3343, /* B224 (45604) */ - 3343, /* B225 (45605) */ - 3343, /* B226 (45606) */ - 3343, /* B227 (45607) */ - 3343, /* B228 (45608) */ - 3343, /* B229 (45609) */ - 3343, /* B22A (45610) */ - 3343, /* B22B (45611) */ - 3343, /* B22C (45612) */ - 3343, /* B22D (45613) */ - 3343, /* B22E (45614) */ - 3343, /* B22F (45615) */ - 3343, /* B230 (45616) */ - 3343, /* B231 (45617) */ - 3343, /* B232 (45618) */ - 3343, /* B233 (45619) */ - 3343, /* B234 (45620) */ - 3343, /* B235 (45621) */ - 3343, /* B236 (45622) */ - 3343, /* B237 (45623) */ - 3343, /* B238 (45624) */ - 3343, /* B239 (45625) */ - 3343, /* B23A (45626) */ - 3343, /* B23B (45627) */ - 3343, /* B23C (45628) */ - 3343, /* B23D (45629) */ - 3343, /* B23E (45630) */ - 3343, /* B23F (45631) */ - 3343, /* B240 (45632) */ - 3343, /* B241 (45633) */ - 3343, /* B242 (45634) */ - 3343, /* B243 (45635) */ - 3343, /* B244 (45636) */ - 3343, /* B245 (45637) */ - 3343, /* B246 (45638) */ - 3343, /* B247 (45639) */ - 3343, /* B248 (45640) */ - 3343, /* B249 (45641) */ - 3343, /* B24A (45642) */ - 3343, /* B24B (45643) */ - 3343, /* B24C (45644) */ - 3343, /* B24D (45645) */ - 3343, /* B24E (45646) */ - 3343, /* B24F (45647) */ - 3343, /* B250 (45648) */ - 3343, /* B251 (45649) */ - 3343, /* B252 (45650) */ - 3343, /* B253 (45651) */ - 3343, /* B254 (45652) */ - 3343, /* B255 (45653) */ - 3343, /* B256 (45654) */ - 3343, /* B257 (45655) */ - 3343, /* B258 (45656) */ - 3343, /* B259 (45657) */ - 3343, /* B25A (45658) */ - 3343, /* B25B (45659) */ - 3343, /* B25C (45660) */ - 3343, /* B25D (45661) */ - 3343, /* B25E (45662) */ - 3343, /* B25F (45663) */ - 3343, /* B260 (45664) */ - 3343, /* B261 (45665) */ - 3343, /* B262 (45666) */ - 3343, /* B263 (45667) */ - 3343, /* B264 (45668) */ - 3343, /* B265 (45669) */ - 3343, /* B266 (45670) */ - 3343, /* B267 (45671) */ - 3343, /* B268 (45672) */ - 3343, /* B269 (45673) */ - 3343, /* B26A (45674) */ - 3343, /* B26B (45675) */ - 3343, /* B26C (45676) */ - 3343, /* B26D (45677) */ - 3343, /* B26E (45678) */ - 3343, /* B26F (45679) */ - 3343, /* B270 (45680) */ - 3343, /* B271 (45681) */ - 3343, /* B272 (45682) */ - 3343, /* B273 (45683) */ - 3343, /* B274 (45684) */ - 3343, /* B275 (45685) */ - 3343, /* B276 (45686) */ - 3343, /* B277 (45687) */ - 3343, /* B278 (45688) */ - 3343, /* B279 (45689) */ - 3343, /* B27A (45690) */ - 3343, /* B27B (45691) */ - 3343, /* B27C (45692) */ - 3343, /* B27D (45693) */ - 3343, /* B27E (45694) */ - 3343, /* B27F (45695) */ - 3343, /* B280 (45696) */ - 3343, /* B281 (45697) */ - 3343, /* B282 (45698) */ - 3343, /* B283 (45699) */ - 3343, /* B284 (45700) */ - 3343, /* B285 (45701) */ - 3343, /* B286 (45702) */ - 3343, /* B287 (45703) */ - 3343, /* B288 (45704) */ - 3343, /* B289 (45705) */ - 3343, /* B28A (45706) */ - 3343, /* B28B (45707) */ - 3343, /* B28C (45708) */ - 3343, /* B28D (45709) */ - 3343, /* B28E (45710) */ - 3343, /* B28F (45711) */ - 3343, /* B290 (45712) */ - 3343, /* B291 (45713) */ - 3343, /* B292 (45714) */ - 3343, /* B293 (45715) */ - 3343, /* B294 (45716) */ - 3343, /* B295 (45717) */ - 3343, /* B296 (45718) */ - 3343, /* B297 (45719) */ - 3343, /* B298 (45720) */ - 3343, /* B299 (45721) */ - 3343, /* B29A (45722) */ - 3343, /* B29B (45723) */ - 3343, /* B29C (45724) */ - 3343, /* B29D (45725) */ - 3343, /* B29E (45726) */ - 3343, /* B29F (45727) */ - 3343, /* B2A0 (45728) */ - 3343, /* B2A1 (45729) */ - 3343, /* B2A2 (45730) */ - 3343, /* B2A3 (45731) */ - 3343, /* B2A4 (45732) */ - 3343, /* B2A5 (45733) */ - 3343, /* B2A6 (45734) */ - 3343, /* B2A7 (45735) */ - 3343, /* B2A8 (45736) */ - 3343, /* B2A9 (45737) */ - 3343, /* B2AA (45738) */ - 3343, /* B2AB (45739) */ - 3343, /* B2AC (45740) */ - 3343, /* B2AD (45741) */ - 3343, /* B2AE (45742) */ - 3343, /* B2AF (45743) */ - 3343, /* B2B0 (45744) */ - 3343, /* B2B1 (45745) */ - 3343, /* B2B2 (45746) */ - 3343, /* B2B3 (45747) */ - 3343, /* B2B4 (45748) */ - 3343, /* B2B5 (45749) */ - 3343, /* B2B6 (45750) */ - 3343, /* B2B7 (45751) */ - 3343, /* B2B8 (45752) */ - 3343, /* B2B9 (45753) */ - 3343, /* B2BA (45754) */ - 3343, /* B2BB (45755) */ - 3343, /* B2BC (45756) */ - 3343, /* B2BD (45757) */ - 3343, /* B2BE (45758) */ - 3343, /* B2BF (45759) */ - 3343, /* B2C0 (45760) */ - 3343, /* B2C1 (45761) */ - 3343, /* B2C2 (45762) */ - 3343, /* B2C3 (45763) */ - 3343, /* B2C4 (45764) */ - 3343, /* B2C5 (45765) */ - 3343, /* B2C6 (45766) */ - 3343, /* B2C7 (45767) */ - 3343, /* B2C8 (45768) */ - 3343, /* B2C9 (45769) */ - 3343, /* B2CA (45770) */ - 3343, /* B2CB (45771) */ - 3343, /* B2CC (45772) */ - 3343, /* B2CD (45773) */ - 3343, /* B2CE (45774) */ - 3343, /* B2CF (45775) */ - 3343, /* B2D0 (45776) */ - 3343, /* B2D1 (45777) */ - 3343, /* B2D2 (45778) */ - 3343, /* B2D3 (45779) */ - 3343, /* B2D4 (45780) */ - 3343, /* B2D5 (45781) */ - 3343, /* B2D6 (45782) */ - 3343, /* B2D7 (45783) */ - 3343, /* B2D8 (45784) */ - 3343, /* B2D9 (45785) */ - 3343, /* B2DA (45786) */ - 3343, /* B2DB (45787) */ - 3343, /* B2DC (45788) */ - 3343, /* B2DD (45789) */ - 3343, /* B2DE (45790) */ - 3343, /* B2DF (45791) */ - 3343, /* B2E0 (45792) */ - 3343, /* B2E1 (45793) */ - 3343, /* B2E2 (45794) */ - 3343, /* B2E3 (45795) */ - 3343, /* B2E4 (45796) */ - 3343, /* B2E5 (45797) */ - 3343, /* B2E6 (45798) */ - 3343, /* B2E7 (45799) */ - 3343, /* B2E8 (45800) */ - 3343, /* B2E9 (45801) */ - 3343, /* B2EA (45802) */ - 3343, /* B2EB (45803) */ - 3343, /* B2EC (45804) */ - 3343, /* B2ED (45805) */ - 3343, /* B2EE (45806) */ - 3343, /* B2EF (45807) */ - 3343, /* B2F0 (45808) */ - 3343, /* B2F1 (45809) */ - 3343, /* B2F2 (45810) */ - 3343, /* B2F3 (45811) */ - 3343, /* B2F4 (45812) */ - 3343, /* B2F5 (45813) */ - 3343, /* B2F6 (45814) */ - 3343, /* B2F7 (45815) */ - 3343, /* B2F8 (45816) */ - 3343, /* B2F9 (45817) */ - 3343, /* B2FA (45818) */ - 3343, /* B2FB (45819) */ - 3343, /* B2FC (45820) */ - 3343, /* B2FD (45821) */ - 3343, /* B2FE (45822) */ - 3343, /* B2FF (45823) */ - 3343, /* B300 (45824) */ - 3343, /* B301 (45825) */ - 3343, /* B302 (45826) */ - 3343, /* B303 (45827) */ - 3343, /* B304 (45828) */ - 3343, /* B305 (45829) */ - 3343, /* B306 (45830) */ - 3343, /* B307 (45831) */ - 3343, /* B308 (45832) */ - 3343, /* B309 (45833) */ - 3343, /* B30A (45834) */ - 3343, /* B30B (45835) */ - 3343, /* B30C (45836) */ - 3343, /* B30D (45837) */ - 3343, /* B30E (45838) */ - 3343, /* B30F (45839) */ - 3343, /* B310 (45840) */ - 3343, /* B311 (45841) */ - 3343, /* B312 (45842) */ - 3343, /* B313 (45843) */ - 3343, /* B314 (45844) */ - 3343, /* B315 (45845) */ - 3343, /* B316 (45846) */ - 3343, /* B317 (45847) */ - 3343, /* B318 (45848) */ - 3343, /* B319 (45849) */ - 3343, /* B31A (45850) */ - 3343, /* B31B (45851) */ - 3343, /* B31C (45852) */ - 3343, /* B31D (45853) */ - 3343, /* B31E (45854) */ - 3343, /* B31F (45855) */ - 3343, /* B320 (45856) */ - 3343, /* B321 (45857) */ - 3343, /* B322 (45858) */ - 3343, /* B323 (45859) */ - 3343, /* B324 (45860) */ - 3343, /* B325 (45861) */ - 3343, /* B326 (45862) */ - 3343, /* B327 (45863) */ - 3343, /* B328 (45864) */ - 3343, /* B329 (45865) */ - 3343, /* B32A (45866) */ - 3343, /* B32B (45867) */ - 3343, /* B32C (45868) */ - 3343, /* B32D (45869) */ - 3343, /* B32E (45870) */ - 3343, /* B32F (45871) */ - 3343, /* B330 (45872) */ - 3343, /* B331 (45873) */ - 3343, /* B332 (45874) */ - 3343, /* B333 (45875) */ - 3343, /* B334 (45876) */ - 3343, /* B335 (45877) */ - 3343, /* B336 (45878) */ - 3343, /* B337 (45879) */ - 3343, /* B338 (45880) */ - 3343, /* B339 (45881) */ - 3343, /* B33A (45882) */ - 3343, /* B33B (45883) */ - 3343, /* B33C (45884) */ - 3343, /* B33D (45885) */ - 3343, /* B33E (45886) */ - 3343, /* B33F (45887) */ - 3343, /* B340 (45888) */ - 3343, /* B341 (45889) */ - 3343, /* B342 (45890) */ - 3343, /* B343 (45891) */ - 3343, /* B344 (45892) */ - 3343, /* B345 (45893) */ - 3343, /* B346 (45894) */ - 3343, /* B347 (45895) */ - 3343, /* B348 (45896) */ - 3343, /* B349 (45897) */ - 3343, /* B34A (45898) */ - 3343, /* B34B (45899) */ - 3343, /* B34C (45900) */ - 3343, /* B34D (45901) */ - 3343, /* B34E (45902) */ - 3343, /* B34F (45903) */ - 3343, /* B350 (45904) */ - 3343, /* B351 (45905) */ - 3343, /* B352 (45906) */ - 3343, /* B353 (45907) */ - 3343, /* B354 (45908) */ - 3343, /* B355 (45909) */ - 3343, /* B356 (45910) */ - 3343, /* B357 (45911) */ - 3343, /* B358 (45912) */ - 3343, /* B359 (45913) */ - 3343, /* B35A (45914) */ - 3343, /* B35B (45915) */ - 3343, /* B35C (45916) */ - 3343, /* B35D (45917) */ - 3343, /* B35E (45918) */ - 3343, /* B35F (45919) */ - 3343, /* B360 (45920) */ - 3343, /* B361 (45921) */ - 3343, /* B362 (45922) */ - 3343, /* B363 (45923) */ - 3343, /* B364 (45924) */ - 3343, /* B365 (45925) */ - 3343, /* B366 (45926) */ - 3343, /* B367 (45927) */ - 3343, /* B368 (45928) */ - 3343, /* B369 (45929) */ - 3343, /* B36A (45930) */ - 3343, /* B36B (45931) */ - 3343, /* B36C (45932) */ - 3343, /* B36D (45933) */ - 3343, /* B36E (45934) */ - 3343, /* B36F (45935) */ - 3343, /* B370 (45936) */ - 3343, /* B371 (45937) */ - 3343, /* B372 (45938) */ - 3343, /* B373 (45939) */ - 3343, /* B374 (45940) */ - 3343, /* B375 (45941) */ - 3343, /* B376 (45942) */ - 3343, /* B377 (45943) */ - 3343, /* B378 (45944) */ - 3343, /* B379 (45945) */ - 3343, /* B37A (45946) */ - 3343, /* B37B (45947) */ - 3343, /* B37C (45948) */ - 3343, /* B37D (45949) */ - 3343, /* B37E (45950) */ - 3343, /* B37F (45951) */ - 3343, /* B380 (45952) */ - 3343, /* B381 (45953) */ - 3343, /* B382 (45954) */ - 3343, /* B383 (45955) */ - 3343, /* B384 (45956) */ - 3343, /* B385 (45957) */ - 3343, /* B386 (45958) */ - 3343, /* B387 (45959) */ - 3343, /* B388 (45960) */ - 3343, /* B389 (45961) */ - 3343, /* B38A (45962) */ - 3343, /* B38B (45963) */ - 3343, /* B38C (45964) */ - 3343, /* B38D (45965) */ - 3343, /* B38E (45966) */ - 3343, /* B38F (45967) */ - 3343, /* B390 (45968) */ - 3343, /* B391 (45969) */ - 3343, /* B392 (45970) */ - 3343, /* B393 (45971) */ - 3343, /* B394 (45972) */ - 3343, /* B395 (45973) */ - 3343, /* B396 (45974) */ - 3343, /* B397 (45975) */ - 3343, /* B398 (45976) */ - 3343, /* B399 (45977) */ - 3343, /* B39A (45978) */ - 3343, /* B39B (45979) */ - 3343, /* B39C (45980) */ - 3343, /* B39D (45981) */ - 3343, /* B39E (45982) */ - 3343, /* B39F (45983) */ - 3343, /* B3A0 (45984) */ - 3343, /* B3A1 (45985) */ - 3343, /* B3A2 (45986) */ - 3343, /* B3A3 (45987) */ - 3343, /* B3A4 (45988) */ - 3343, /* B3A5 (45989) */ - 3343, /* B3A6 (45990) */ - 3343, /* B3A7 (45991) */ - 3343, /* B3A8 (45992) */ - 3343, /* B3A9 (45993) */ - 3343, /* B3AA (45994) */ - 3343, /* B3AB (45995) */ - 3343, /* B3AC (45996) */ - 3343, /* B3AD (45997) */ - 3343, /* B3AE (45998) */ - 3343, /* B3AF (45999) */ - 3343, /* B3B0 (46000) */ - 3343, /* B3B1 (46001) */ - 3343, /* B3B2 (46002) */ - 3343, /* B3B3 (46003) */ - 3343, /* B3B4 (46004) */ - 3343, /* B3B5 (46005) */ - 3343, /* B3B6 (46006) */ - 3343, /* B3B7 (46007) */ - 3343, /* B3B8 (46008) */ - 3343, /* B3B9 (46009) */ - 3343, /* B3BA (46010) */ - 3343, /* B3BB (46011) */ - 3343, /* B3BC (46012) */ - 3343, /* B3BD (46013) */ - 3343, /* B3BE (46014) */ - 3343, /* B3BF (46015) */ - 3343, /* B3C0 (46016) */ - 3343, /* B3C1 (46017) */ - 3343, /* B3C2 (46018) */ - 3343, /* B3C3 (46019) */ - 3343, /* B3C4 (46020) */ - 3343, /* B3C5 (46021) */ - 3343, /* B3C6 (46022) */ - 3343, /* B3C7 (46023) */ - 3343, /* B3C8 (46024) */ - 3343, /* B3C9 (46025) */ - 3343, /* B3CA (46026) */ - 3343, /* B3CB (46027) */ - 3343, /* B3CC (46028) */ - 3343, /* B3CD (46029) */ - 3343, /* B3CE (46030) */ - 3343, /* B3CF (46031) */ - 3343, /* B3D0 (46032) */ - 3343, /* B3D1 (46033) */ - 3343, /* B3D2 (46034) */ - 3343, /* B3D3 (46035) */ - 3343, /* B3D4 (46036) */ - 3343, /* B3D5 (46037) */ - 3343, /* B3D6 (46038) */ - 3343, /* B3D7 (46039) */ - 3343, /* B3D8 (46040) */ - 3343, /* B3D9 (46041) */ - 3343, /* B3DA (46042) */ - 3343, /* B3DB (46043) */ - 3343, /* B3DC (46044) */ - 3343, /* B3DD (46045) */ - 3343, /* B3DE (46046) */ - 3343, /* B3DF (46047) */ - 3343, /* B3E0 (46048) */ - 3343, /* B3E1 (46049) */ - 3343, /* B3E2 (46050) */ - 3343, /* B3E3 (46051) */ - 3343, /* B3E4 (46052) */ - 3343, /* B3E5 (46053) */ - 3343, /* B3E6 (46054) */ - 3343, /* B3E7 (46055) */ - 3343, /* B3E8 (46056) */ - 3343, /* B3E9 (46057) */ - 3343, /* B3EA (46058) */ - 3343, /* B3EB (46059) */ - 3343, /* B3EC (46060) */ - 3343, /* B3ED (46061) */ - 3343, /* B3EE (46062) */ - 3343, /* B3EF (46063) */ - 3343, /* B3F0 (46064) */ - 3343, /* B3F1 (46065) */ - 3343, /* B3F2 (46066) */ - 3343, /* B3F3 (46067) */ - 3343, /* B3F4 (46068) */ - 3343, /* B3F5 (46069) */ - 3343, /* B3F6 (46070) */ - 3343, /* B3F7 (46071) */ - 3343, /* B3F8 (46072) */ - 3343, /* B3F9 (46073) */ - 3343, /* B3FA (46074) */ - 3343, /* B3FB (46075) */ - 3343, /* B3FC (46076) */ - 3343, /* B3FD (46077) */ - 3343, /* B3FE (46078) */ - 3343, /* B3FF (46079) */ - 3343, /* B400 (46080) */ - 3343, /* B401 (46081) */ - 3343, /* B402 (46082) */ - 3343, /* B403 (46083) */ - 3343, /* B404 (46084) */ - 3343, /* B405 (46085) */ - 3343, /* B406 (46086) */ - 3343, /* B407 (46087) */ - 3343, /* B408 (46088) */ - 3343, /* B409 (46089) */ - 3343, /* B40A (46090) */ - 3343, /* B40B (46091) */ - 3343, /* B40C (46092) */ - 3343, /* B40D (46093) */ - 3343, /* B40E (46094) */ - 3343, /* B40F (46095) */ - 3343, /* B410 (46096) */ - 3343, /* B411 (46097) */ - 3343, /* B412 (46098) */ - 3343, /* B413 (46099) */ - 3343, /* B414 (46100) */ - 3343, /* B415 (46101) */ - 3343, /* B416 (46102) */ - 3343, /* B417 (46103) */ - 3343, /* B418 (46104) */ - 3343, /* B419 (46105) */ - 3343, /* B41A (46106) */ - 3343, /* B41B (46107) */ - 3343, /* B41C (46108) */ - 3343, /* B41D (46109) */ - 3343, /* B41E (46110) */ - 3343, /* B41F (46111) */ - 3343, /* B420 (46112) */ - 3343, /* B421 (46113) */ - 3343, /* B422 (46114) */ - 3343, /* B423 (46115) */ - 3343, /* B424 (46116) */ - 3343, /* B425 (46117) */ - 3343, /* B426 (46118) */ - 3343, /* B427 (46119) */ - 3343, /* B428 (46120) */ - 3343, /* B429 (46121) */ - 3343, /* B42A (46122) */ - 3343, /* B42B (46123) */ - 3343, /* B42C (46124) */ - 3343, /* B42D (46125) */ - 3343, /* B42E (46126) */ - 3343, /* B42F (46127) */ - 3343, /* B430 (46128) */ - 3343, /* B431 (46129) */ - 3343, /* B432 (46130) */ - 3343, /* B433 (46131) */ - 3343, /* B434 (46132) */ - 3343, /* B435 (46133) */ - 3343, /* B436 (46134) */ - 3343, /* B437 (46135) */ - 3343, /* B438 (46136) */ - 3343, /* B439 (46137) */ - 3343, /* B43A (46138) */ - 3343, /* B43B (46139) */ - 3343, /* B43C (46140) */ - 3343, /* B43D (46141) */ - 3343, /* B43E (46142) */ - 3343, /* B43F (46143) */ - 3343, /* B440 (46144) */ - 3343, /* B441 (46145) */ - 3343, /* B442 (46146) */ - 3343, /* B443 (46147) */ - 3343, /* B444 (46148) */ - 3343, /* B445 (46149) */ - 3343, /* B446 (46150) */ - 3343, /* B447 (46151) */ - 3343, /* B448 (46152) */ - 3343, /* B449 (46153) */ - 3343, /* B44A (46154) */ - 3343, /* B44B (46155) */ - 3343, /* B44C (46156) */ - 3343, /* B44D (46157) */ - 3343, /* B44E (46158) */ - 3343, /* B44F (46159) */ - 3343, /* B450 (46160) */ - 3343, /* B451 (46161) */ - 3343, /* B452 (46162) */ - 3343, /* B453 (46163) */ - 3343, /* B454 (46164) */ - 3343, /* B455 (46165) */ - 3343, /* B456 (46166) */ - 3343, /* B457 (46167) */ - 3343, /* B458 (46168) */ - 3343, /* B459 (46169) */ - 3343, /* B45A (46170) */ - 3343, /* B45B (46171) */ - 3343, /* B45C (46172) */ - 3343, /* B45D (46173) */ - 3343, /* B45E (46174) */ - 3343, /* B45F (46175) */ - 3343, /* B460 (46176) */ - 3343, /* B461 (46177) */ - 3343, /* B462 (46178) */ - 3343, /* B463 (46179) */ - 3343, /* B464 (46180) */ - 3343, /* B465 (46181) */ - 3343, /* B466 (46182) */ - 3343, /* B467 (46183) */ - 3343, /* B468 (46184) */ - 3343, /* B469 (46185) */ - 3343, /* B46A (46186) */ - 3343, /* B46B (46187) */ - 3343, /* B46C (46188) */ - 3343, /* B46D (46189) */ - 3343, /* B46E (46190) */ - 3343, /* B46F (46191) */ - 3343, /* B470 (46192) */ - 3343, /* B471 (46193) */ - 3343, /* B472 (46194) */ - 3343, /* B473 (46195) */ - 3343, /* B474 (46196) */ - 3343, /* B475 (46197) */ - 3343, /* B476 (46198) */ - 3343, /* B477 (46199) */ - 3343, /* B478 (46200) */ - 3343, /* B479 (46201) */ - 3343, /* B47A (46202) */ - 3343, /* B47B (46203) */ - 3343, /* B47C (46204) */ - 3343, /* B47D (46205) */ - 3343, /* B47E (46206) */ - 3343, /* B47F (46207) */ - 3343, /* B480 (46208) */ - 3343, /* B481 (46209) */ - 3343, /* B482 (46210) */ - 3343, /* B483 (46211) */ - 3343, /* B484 (46212) */ - 3343, /* B485 (46213) */ - 3343, /* B486 (46214) */ - 3343, /* B487 (46215) */ - 3343, /* B488 (46216) */ - 3343, /* B489 (46217) */ - 3343, /* B48A (46218) */ - 3343, /* B48B (46219) */ - 3343, /* B48C (46220) */ - 3343, /* B48D (46221) */ - 3343, /* B48E (46222) */ - 3343, /* B48F (46223) */ - 3343, /* B490 (46224) */ - 3343, /* B491 (46225) */ - 3343, /* B492 (46226) */ - 3343, /* B493 (46227) */ - 3343, /* B494 (46228) */ - 3343, /* B495 (46229) */ - 3343, /* B496 (46230) */ - 3343, /* B497 (46231) */ - 3343, /* B498 (46232) */ - 3343, /* B499 (46233) */ - 3343, /* B49A (46234) */ - 3343, /* B49B (46235) */ - 3343, /* B49C (46236) */ - 3343, /* B49D (46237) */ - 3343, /* B49E (46238) */ - 3343, /* B49F (46239) */ - 3343, /* B4A0 (46240) */ - 3343, /* B4A1 (46241) */ - 3343, /* B4A2 (46242) */ - 3343, /* B4A3 (46243) */ - 3343, /* B4A4 (46244) */ - 3343, /* B4A5 (46245) */ - 3343, /* B4A6 (46246) */ - 3343, /* B4A7 (46247) */ - 3343, /* B4A8 (46248) */ - 3343, /* B4A9 (46249) */ - 3343, /* B4AA (46250) */ - 3343, /* B4AB (46251) */ - 3343, /* B4AC (46252) */ - 3343, /* B4AD (46253) */ - 3343, /* B4AE (46254) */ - 3343, /* B4AF (46255) */ - 3343, /* B4B0 (46256) */ - 3343, /* B4B1 (46257) */ - 3343, /* B4B2 (46258) */ - 3343, /* B4B3 (46259) */ - 3343, /* B4B4 (46260) */ - 3343, /* B4B5 (46261) */ - 3343, /* B4B6 (46262) */ - 3343, /* B4B7 (46263) */ - 3343, /* B4B8 (46264) */ - 3343, /* B4B9 (46265) */ - 3343, /* B4BA (46266) */ - 3343, /* B4BB (46267) */ - 3343, /* B4BC (46268) */ - 3343, /* B4BD (46269) */ - 3343, /* B4BE (46270) */ - 3343, /* B4BF (46271) */ - 3343, /* B4C0 (46272) */ - 3343, /* B4C1 (46273) */ - 3343, /* B4C2 (46274) */ - 3343, /* B4C3 (46275) */ - 3343, /* B4C4 (46276) */ - 3343, /* B4C5 (46277) */ - 3343, /* B4C6 (46278) */ - 3343, /* B4C7 (46279) */ - 3343, /* B4C8 (46280) */ - 3343, /* B4C9 (46281) */ - 3343, /* B4CA (46282) */ - 3343, /* B4CB (46283) */ - 3343, /* B4CC (46284) */ - 3343, /* B4CD (46285) */ - 3343, /* B4CE (46286) */ - 3343, /* B4CF (46287) */ - 3343, /* B4D0 (46288) */ - 3343, /* B4D1 (46289) */ - 3343, /* B4D2 (46290) */ - 3343, /* B4D3 (46291) */ - 3343, /* B4D4 (46292) */ - 3343, /* B4D5 (46293) */ - 3343, /* B4D6 (46294) */ - 3343, /* B4D7 (46295) */ - 3343, /* B4D8 (46296) */ - 3343, /* B4D9 (46297) */ - 3343, /* B4DA (46298) */ - 3343, /* B4DB (46299) */ - 3343, /* B4DC (46300) */ - 3343, /* B4DD (46301) */ - 3343, /* B4DE (46302) */ - 3343, /* B4DF (46303) */ - 3343, /* B4E0 (46304) */ - 3343, /* B4E1 (46305) */ - 3343, /* B4E2 (46306) */ - 3343, /* B4E3 (46307) */ - 3343, /* B4E4 (46308) */ - 3343, /* B4E5 (46309) */ - 3343, /* B4E6 (46310) */ - 3343, /* B4E7 (46311) */ - 3343, /* B4E8 (46312) */ - 3343, /* B4E9 (46313) */ - 3343, /* B4EA (46314) */ - 3343, /* B4EB (46315) */ - 3343, /* B4EC (46316) */ - 3343, /* B4ED (46317) */ - 3343, /* B4EE (46318) */ - 3343, /* B4EF (46319) */ - 3343, /* B4F0 (46320) */ - 3343, /* B4F1 (46321) */ - 3343, /* B4F2 (46322) */ - 3343, /* B4F3 (46323) */ - 3343, /* B4F4 (46324) */ - 3343, /* B4F5 (46325) */ - 3343, /* B4F6 (46326) */ - 3343, /* B4F7 (46327) */ - 3343, /* B4F8 (46328) */ - 3343, /* B4F9 (46329) */ - 3343, /* B4FA (46330) */ - 3343, /* B4FB (46331) */ - 3343, /* B4FC (46332) */ - 3343, /* B4FD (46333) */ - 3343, /* B4FE (46334) */ - 3343, /* B4FF (46335) */ - 3343, /* B500 (46336) */ - 3343, /* B501 (46337) */ - 3343, /* B502 (46338) */ - 3343, /* B503 (46339) */ - 3343, /* B504 (46340) */ - 3343, /* B505 (46341) */ - 3343, /* B506 (46342) */ - 3343, /* B507 (46343) */ - 3343, /* B508 (46344) */ - 3343, /* B509 (46345) */ - 3343, /* B50A (46346) */ - 3343, /* B50B (46347) */ - 3343, /* B50C (46348) */ - 3343, /* B50D (46349) */ - 3343, /* B50E (46350) */ - 3343, /* B50F (46351) */ - 3343, /* B510 (46352) */ - 3343, /* B511 (46353) */ - 3343, /* B512 (46354) */ - 3343, /* B513 (46355) */ - 3343, /* B514 (46356) */ - 3343, /* B515 (46357) */ - 3343, /* B516 (46358) */ - 3343, /* B517 (46359) */ - 3343, /* B518 (46360) */ - 3343, /* B519 (46361) */ - 3343, /* B51A (46362) */ - 3343, /* B51B (46363) */ - 3343, /* B51C (46364) */ - 3343, /* B51D (46365) */ - 3343, /* B51E (46366) */ - 3343, /* B51F (46367) */ - 3343, /* B520 (46368) */ - 3343, /* B521 (46369) */ - 3343, /* B522 (46370) */ - 3343, /* B523 (46371) */ - 3343, /* B524 (46372) */ - 3343, /* B525 (46373) */ - 3343, /* B526 (46374) */ - 3343, /* B527 (46375) */ - 3343, /* B528 (46376) */ - 3343, /* B529 (46377) */ - 3343, /* B52A (46378) */ - 3343, /* B52B (46379) */ - 3343, /* B52C (46380) */ - 3343, /* B52D (46381) */ - 3343, /* B52E (46382) */ - 3343, /* B52F (46383) */ - 3343, /* B530 (46384) */ - 3343, /* B531 (46385) */ - 3343, /* B532 (46386) */ - 3343, /* B533 (46387) */ - 3343, /* B534 (46388) */ - 3343, /* B535 (46389) */ - 3343, /* B536 (46390) */ - 3343, /* B537 (46391) */ - 3343, /* B538 (46392) */ - 3343, /* B539 (46393) */ - 3343, /* B53A (46394) */ - 3343, /* B53B (46395) */ - 3343, /* B53C (46396) */ - 3343, /* B53D (46397) */ - 3343, /* B53E (46398) */ - 3343, /* B53F (46399) */ - 3343, /* B540 (46400) */ - 3343, /* B541 (46401) */ - 3343, /* B542 (46402) */ - 3343, /* B543 (46403) */ - 3343, /* B544 (46404) */ - 3343, /* B545 (46405) */ - 3343, /* B546 (46406) */ - 3343, /* B547 (46407) */ - 3343, /* B548 (46408) */ - 3343, /* B549 (46409) */ - 3343, /* B54A (46410) */ - 3343, /* B54B (46411) */ - 3343, /* B54C (46412) */ - 3343, /* B54D (46413) */ - 3343, /* B54E (46414) */ - 3343, /* B54F (46415) */ - 3343, /* B550 (46416) */ - 3343, /* B551 (46417) */ - 3343, /* B552 (46418) */ - 3343, /* B553 (46419) */ - 3343, /* B554 (46420) */ - 3343, /* B555 (46421) */ - 3343, /* B556 (46422) */ - 3343, /* B557 (46423) */ - 3343, /* B558 (46424) */ - 3343, /* B559 (46425) */ - 3343, /* B55A (46426) */ - 3343, /* B55B (46427) */ - 3343, /* B55C (46428) */ - 3343, /* B55D (46429) */ - 3343, /* B55E (46430) */ - 3343, /* B55F (46431) */ - 3343, /* B560 (46432) */ - 3343, /* B561 (46433) */ - 3343, /* B562 (46434) */ - 3343, /* B563 (46435) */ - 3343, /* B564 (46436) */ - 3343, /* B565 (46437) */ - 3343, /* B566 (46438) */ - 3343, /* B567 (46439) */ - 3343, /* B568 (46440) */ - 3343, /* B569 (46441) */ - 3343, /* B56A (46442) */ - 3343, /* B56B (46443) */ - 3343, /* B56C (46444) */ - 3343, /* B56D (46445) */ - 3343, /* B56E (46446) */ - 3343, /* B56F (46447) */ - 3343, /* B570 (46448) */ - 3343, /* B571 (46449) */ - 3343, /* B572 (46450) */ - 3343, /* B573 (46451) */ - 3343, /* B574 (46452) */ - 3343, /* B575 (46453) */ - 3343, /* B576 (46454) */ - 3343, /* B577 (46455) */ - 3343, /* B578 (46456) */ - 3343, /* B579 (46457) */ - 3343, /* B57A (46458) */ - 3343, /* B57B (46459) */ - 3343, /* B57C (46460) */ - 3343, /* B57D (46461) */ - 3343, /* B57E (46462) */ - 3343, /* B57F (46463) */ - 3343, /* B580 (46464) */ - 3343, /* B581 (46465) */ - 3343, /* B582 (46466) */ - 3343, /* B583 (46467) */ - 3343, /* B584 (46468) */ - 3343, /* B585 (46469) */ - 3343, /* B586 (46470) */ - 3343, /* B587 (46471) */ - 3343, /* B588 (46472) */ - 3343, /* B589 (46473) */ - 3343, /* B58A (46474) */ - 3343, /* B58B (46475) */ - 3343, /* B58C (46476) */ - 3343, /* B58D (46477) */ - 3343, /* B58E (46478) */ - 3343, /* B58F (46479) */ - 3343, /* B590 (46480) */ - 3343, /* B591 (46481) */ - 3343, /* B592 (46482) */ - 3343, /* B593 (46483) */ - 3343, /* B594 (46484) */ - 3343, /* B595 (46485) */ - 3343, /* B596 (46486) */ - 3343, /* B597 (46487) */ - 3343, /* B598 (46488) */ - 3343, /* B599 (46489) */ - 3343, /* B59A (46490) */ - 3343, /* B59B (46491) */ - 3343, /* B59C (46492) */ - 3343, /* B59D (46493) */ - 3343, /* B59E (46494) */ - 3343, /* B59F (46495) */ - 3343, /* B5A0 (46496) */ - 3343, /* B5A1 (46497) */ - 3343, /* B5A2 (46498) */ - 3343, /* B5A3 (46499) */ - 3343, /* B5A4 (46500) */ - 3343, /* B5A5 (46501) */ - 3343, /* B5A6 (46502) */ - 3343, /* B5A7 (46503) */ - 3343, /* B5A8 (46504) */ - 3343, /* B5A9 (46505) */ - 3343, /* B5AA (46506) */ - 3343, /* B5AB (46507) */ - 3343, /* B5AC (46508) */ - 3343, /* B5AD (46509) */ - 3343, /* B5AE (46510) */ - 3343, /* B5AF (46511) */ - 3343, /* B5B0 (46512) */ - 3343, /* B5B1 (46513) */ - 3343, /* B5B2 (46514) */ - 3343, /* B5B3 (46515) */ - 3343, /* B5B4 (46516) */ - 3343, /* B5B5 (46517) */ - 3343, /* B5B6 (46518) */ - 3343, /* B5B7 (46519) */ - 3343, /* B5B8 (46520) */ - 3343, /* B5B9 (46521) */ - 3343, /* B5BA (46522) */ - 3343, /* B5BB (46523) */ - 3343, /* B5BC (46524) */ - 3343, /* B5BD (46525) */ - 3343, /* B5BE (46526) */ - 3343, /* B5BF (46527) */ - 3343, /* B5C0 (46528) */ - 3343, /* B5C1 (46529) */ - 3343, /* B5C2 (46530) */ - 3343, /* B5C3 (46531) */ - 3343, /* B5C4 (46532) */ - 3343, /* B5C5 (46533) */ - 3343, /* B5C6 (46534) */ - 3343, /* B5C7 (46535) */ - 3343, /* B5C8 (46536) */ - 3343, /* B5C9 (46537) */ - 3343, /* B5CA (46538) */ - 3343, /* B5CB (46539) */ - 3343, /* B5CC (46540) */ - 3343, /* B5CD (46541) */ - 3343, /* B5CE (46542) */ - 3343, /* B5CF (46543) */ - 3343, /* B5D0 (46544) */ - 3343, /* B5D1 (46545) */ - 3343, /* B5D2 (46546) */ - 3343, /* B5D3 (46547) */ - 3343, /* B5D4 (46548) */ - 3343, /* B5D5 (46549) */ - 3343, /* B5D6 (46550) */ - 3343, /* B5D7 (46551) */ - 3343, /* B5D8 (46552) */ - 3343, /* B5D9 (46553) */ - 3343, /* B5DA (46554) */ - 3343, /* B5DB (46555) */ - 3343, /* B5DC (46556) */ - 3343, /* B5DD (46557) */ - 3343, /* B5DE (46558) */ - 3343, /* B5DF (46559) */ - 3343, /* B5E0 (46560) */ - 3343, /* B5E1 (46561) */ - 3343, /* B5E2 (46562) */ - 3343, /* B5E3 (46563) */ - 3343, /* B5E4 (46564) */ - 3343, /* B5E5 (46565) */ - 3343, /* B5E6 (46566) */ - 3343, /* B5E7 (46567) */ - 3343, /* B5E8 (46568) */ - 3343, /* B5E9 (46569) */ - 3343, /* B5EA (46570) */ - 3343, /* B5EB (46571) */ - 3343, /* B5EC (46572) */ - 3343, /* B5ED (46573) */ - 3343, /* B5EE (46574) */ - 3343, /* B5EF (46575) */ - 3343, /* B5F0 (46576) */ - 3343, /* B5F1 (46577) */ - 3343, /* B5F2 (46578) */ - 3343, /* B5F3 (46579) */ - 3343, /* B5F4 (46580) */ - 3343, /* B5F5 (46581) */ - 3343, /* B5F6 (46582) */ - 3343, /* B5F7 (46583) */ - 3343, /* B5F8 (46584) */ - 3343, /* B5F9 (46585) */ - 3343, /* B5FA (46586) */ - 3343, /* B5FB (46587) */ - 3343, /* B5FC (46588) */ - 3343, /* B5FD (46589) */ - 3343, /* B5FE (46590) */ - 3343, /* B5FF (46591) */ - 3343, /* B600 (46592) */ - 3343, /* B601 (46593) */ - 3343, /* B602 (46594) */ - 3343, /* B603 (46595) */ - 3343, /* B604 (46596) */ - 3343, /* B605 (46597) */ - 3343, /* B606 (46598) */ - 3343, /* B607 (46599) */ - 3343, /* B608 (46600) */ - 3343, /* B609 (46601) */ - 3343, /* B60A (46602) */ - 3343, /* B60B (46603) */ - 3343, /* B60C (46604) */ - 3343, /* B60D (46605) */ - 3343, /* B60E (46606) */ - 3343, /* B60F (46607) */ - 3343, /* B610 (46608) */ - 3343, /* B611 (46609) */ - 3343, /* B612 (46610) */ - 3343, /* B613 (46611) */ - 3343, /* B614 (46612) */ - 3343, /* B615 (46613) */ - 3343, /* B616 (46614) */ - 3343, /* B617 (46615) */ - 3343, /* B618 (46616) */ - 3343, /* B619 (46617) */ - 3343, /* B61A (46618) */ - 3343, /* B61B (46619) */ - 3343, /* B61C (46620) */ - 3343, /* B61D (46621) */ - 3343, /* B61E (46622) */ - 3343, /* B61F (46623) */ - 3343, /* B620 (46624) */ - 3343, /* B621 (46625) */ - 3343, /* B622 (46626) */ - 3343, /* B623 (46627) */ - 3343, /* B624 (46628) */ - 3343, /* B625 (46629) */ - 3343, /* B626 (46630) */ - 3343, /* B627 (46631) */ - 3343, /* B628 (46632) */ - 3343, /* B629 (46633) */ - 3343, /* B62A (46634) */ - 3343, /* B62B (46635) */ - 3343, /* B62C (46636) */ - 3343, /* B62D (46637) */ - 3343, /* B62E (46638) */ - 3343, /* B62F (46639) */ - 3343, /* B630 (46640) */ - 3343, /* B631 (46641) */ - 3343, /* B632 (46642) */ - 3343, /* B633 (46643) */ - 3343, /* B634 (46644) */ - 3343, /* B635 (46645) */ - 3343, /* B636 (46646) */ - 3343, /* B637 (46647) */ - 3343, /* B638 (46648) */ - 3343, /* B639 (46649) */ - 3343, /* B63A (46650) */ - 3343, /* B63B (46651) */ - 3343, /* B63C (46652) */ - 3343, /* B63D (46653) */ - 3343, /* B63E (46654) */ - 3343, /* B63F (46655) */ - 3343, /* B640 (46656) */ - 3343, /* B641 (46657) */ - 3343, /* B642 (46658) */ - 3343, /* B643 (46659) */ - 3343, /* B644 (46660) */ - 3343, /* B645 (46661) */ - 3343, /* B646 (46662) */ - 3343, /* B647 (46663) */ - 3343, /* B648 (46664) */ - 3343, /* B649 (46665) */ - 3343, /* B64A (46666) */ - 3343, /* B64B (46667) */ - 3343, /* B64C (46668) */ - 3343, /* B64D (46669) */ - 3343, /* B64E (46670) */ - 3343, /* B64F (46671) */ - 3343, /* B650 (46672) */ - 3343, /* B651 (46673) */ - 3343, /* B652 (46674) */ - 3343, /* B653 (46675) */ - 3343, /* B654 (46676) */ - 3343, /* B655 (46677) */ - 3343, /* B656 (46678) */ - 3343, /* B657 (46679) */ - 3343, /* B658 (46680) */ - 3343, /* B659 (46681) */ - 3343, /* B65A (46682) */ - 3343, /* B65B (46683) */ - 3343, /* B65C (46684) */ - 3343, /* B65D (46685) */ - 3343, /* B65E (46686) */ - 3343, /* B65F (46687) */ - 3343, /* B660 (46688) */ - 3343, /* B661 (46689) */ - 3343, /* B662 (46690) */ - 3343, /* B663 (46691) */ - 3343, /* B664 (46692) */ - 3343, /* B665 (46693) */ - 3343, /* B666 (46694) */ - 3343, /* B667 (46695) */ - 3343, /* B668 (46696) */ - 3343, /* B669 (46697) */ - 3343, /* B66A (46698) */ - 3343, /* B66B (46699) */ - 3343, /* B66C (46700) */ - 3343, /* B66D (46701) */ - 3343, /* B66E (46702) */ - 3343, /* B66F (46703) */ - 3343, /* B670 (46704) */ - 3343, /* B671 (46705) */ - 3343, /* B672 (46706) */ - 3343, /* B673 (46707) */ - 3343, /* B674 (46708) */ - 3343, /* B675 (46709) */ - 3343, /* B676 (46710) */ - 3343, /* B677 (46711) */ - 3343, /* B678 (46712) */ - 3343, /* B679 (46713) */ - 3343, /* B67A (46714) */ - 3343, /* B67B (46715) */ - 3343, /* B67C (46716) */ - 3343, /* B67D (46717) */ - 3343, /* B67E (46718) */ - 3343, /* B67F (46719) */ - 3343, /* B680 (46720) */ - 3343, /* B681 (46721) */ - 3343, /* B682 (46722) */ - 3343, /* B683 (46723) */ - 3343, /* B684 (46724) */ - 3343, /* B685 (46725) */ - 3343, /* B686 (46726) */ - 3343, /* B687 (46727) */ - 3343, /* B688 (46728) */ - 3343, /* B689 (46729) */ - 3343, /* B68A (46730) */ - 3343, /* B68B (46731) */ - 3343, /* B68C (46732) */ - 3343, /* B68D (46733) */ - 3343, /* B68E (46734) */ - 3343, /* B68F (46735) */ - 3343, /* B690 (46736) */ - 3343, /* B691 (46737) */ - 3343, /* B692 (46738) */ - 3343, /* B693 (46739) */ - 3343, /* B694 (46740) */ - 3343, /* B695 (46741) */ - 3343, /* B696 (46742) */ - 3343, /* B697 (46743) */ - 3343, /* B698 (46744) */ - 3343, /* B699 (46745) */ - 3343, /* B69A (46746) */ - 3343, /* B69B (46747) */ - 3343, /* B69C (46748) */ - 3343, /* B69D (46749) */ - 3343, /* B69E (46750) */ - 3343, /* B69F (46751) */ - 3343, /* B6A0 (46752) */ - 3343, /* B6A1 (46753) */ - 3343, /* B6A2 (46754) */ - 3343, /* B6A3 (46755) */ - 3343, /* B6A4 (46756) */ - 3343, /* B6A5 (46757) */ - 3343, /* B6A6 (46758) */ - 3343, /* B6A7 (46759) */ - 3343, /* B6A8 (46760) */ - 3343, /* B6A9 (46761) */ - 3343, /* B6AA (46762) */ - 3343, /* B6AB (46763) */ - 3343, /* B6AC (46764) */ - 3343, /* B6AD (46765) */ - 3343, /* B6AE (46766) */ - 3343, /* B6AF (46767) */ - 3343, /* B6B0 (46768) */ - 3343, /* B6B1 (46769) */ - 3343, /* B6B2 (46770) */ - 3343, /* B6B3 (46771) */ - 3343, /* B6B4 (46772) */ - 3343, /* B6B5 (46773) */ - 3343, /* B6B6 (46774) */ - 3343, /* B6B7 (46775) */ - 3343, /* B6B8 (46776) */ - 3343, /* B6B9 (46777) */ - 3343, /* B6BA (46778) */ - 3343, /* B6BB (46779) */ - 3343, /* B6BC (46780) */ - 3343, /* B6BD (46781) */ - 3343, /* B6BE (46782) */ - 3343, /* B6BF (46783) */ - 3343, /* B6C0 (46784) */ - 3343, /* B6C1 (46785) */ - 3343, /* B6C2 (46786) */ - 3343, /* B6C3 (46787) */ - 3343, /* B6C4 (46788) */ - 3343, /* B6C5 (46789) */ - 3343, /* B6C6 (46790) */ - 3343, /* B6C7 (46791) */ - 3343, /* B6C8 (46792) */ - 3343, /* B6C9 (46793) */ - 3343, /* B6CA (46794) */ - 3343, /* B6CB (46795) */ - 3343, /* B6CC (46796) */ - 3343, /* B6CD (46797) */ - 3343, /* B6CE (46798) */ - 3343, /* B6CF (46799) */ - 3343, /* B6D0 (46800) */ - 3343, /* B6D1 (46801) */ - 3343, /* B6D2 (46802) */ - 3343, /* B6D3 (46803) */ - 3343, /* B6D4 (46804) */ - 3343, /* B6D5 (46805) */ - 3343, /* B6D6 (46806) */ - 3343, /* B6D7 (46807) */ - 3343, /* B6D8 (46808) */ - 3343, /* B6D9 (46809) */ - 3343, /* B6DA (46810) */ - 3343, /* B6DB (46811) */ - 3343, /* B6DC (46812) */ - 3343, /* B6DD (46813) */ - 3343, /* B6DE (46814) */ - 3343, /* B6DF (46815) */ - 3343, /* B6E0 (46816) */ - 3343, /* B6E1 (46817) */ - 3343, /* B6E2 (46818) */ - 3343, /* B6E3 (46819) */ - 3343, /* B6E4 (46820) */ - 3343, /* B6E5 (46821) */ - 3343, /* B6E6 (46822) */ - 3343, /* B6E7 (46823) */ - 3343, /* B6E8 (46824) */ - 3343, /* B6E9 (46825) */ - 3343, /* B6EA (46826) */ - 3343, /* B6EB (46827) */ - 3343, /* B6EC (46828) */ - 3343, /* B6ED (46829) */ - 3343, /* B6EE (46830) */ - 3343, /* B6EF (46831) */ - 3343, /* B6F0 (46832) */ - 3343, /* B6F1 (46833) */ - 3343, /* B6F2 (46834) */ - 3343, /* B6F3 (46835) */ - 3343, /* B6F4 (46836) */ - 3343, /* B6F5 (46837) */ - 3343, /* B6F6 (46838) */ - 3343, /* B6F7 (46839) */ - 3343, /* B6F8 (46840) */ - 3343, /* B6F9 (46841) */ - 3343, /* B6FA (46842) */ - 3343, /* B6FB (46843) */ - 3343, /* B6FC (46844) */ - 3343, /* B6FD (46845) */ - 3343, /* B6FE (46846) */ - 3343, /* B6FF (46847) */ - 3343, /* B700 (46848) */ - 3343, /* B701 (46849) */ - 3343, /* B702 (46850) */ - 3343, /* B703 (46851) */ - 3343, /* B704 (46852) */ - 3343, /* B705 (46853) */ - 3343, /* B706 (46854) */ - 3343, /* B707 (46855) */ - 3343, /* B708 (46856) */ - 3343, /* B709 (46857) */ - 3343, /* B70A (46858) */ - 3343, /* B70B (46859) */ - 3343, /* B70C (46860) */ - 3343, /* B70D (46861) */ - 3343, /* B70E (46862) */ - 3343, /* B70F (46863) */ - 3343, /* B710 (46864) */ - 3343, /* B711 (46865) */ - 3343, /* B712 (46866) */ - 3343, /* B713 (46867) */ - 3343, /* B714 (46868) */ - 3343, /* B715 (46869) */ - 3343, /* B716 (46870) */ - 3343, /* B717 (46871) */ - 3343, /* B718 (46872) */ - 3343, /* B719 (46873) */ - 3343, /* B71A (46874) */ - 3343, /* B71B (46875) */ - 3343, /* B71C (46876) */ - 3343, /* B71D (46877) */ - 3343, /* B71E (46878) */ - 3343, /* B71F (46879) */ - 3343, /* B720 (46880) */ - 3343, /* B721 (46881) */ - 3343, /* B722 (46882) */ - 3343, /* B723 (46883) */ - 3343, /* B724 (46884) */ - 3343, /* B725 (46885) */ - 3343, /* B726 (46886) */ - 3343, /* B727 (46887) */ - 3343, /* B728 (46888) */ - 3343, /* B729 (46889) */ - 3343, /* B72A (46890) */ - 3343, /* B72B (46891) */ - 3343, /* B72C (46892) */ - 3343, /* B72D (46893) */ - 3343, /* B72E (46894) */ - 3343, /* B72F (46895) */ - 3343, /* B730 (46896) */ - 3343, /* B731 (46897) */ - 3343, /* B732 (46898) */ - 3343, /* B733 (46899) */ - 3343, /* B734 (46900) */ - 3343, /* B735 (46901) */ - 3343, /* B736 (46902) */ - 3343, /* B737 (46903) */ - 3343, /* B738 (46904) */ - 3343, /* B739 (46905) */ - 3343, /* B73A (46906) */ - 3343, /* B73B (46907) */ - 3343, /* B73C (46908) */ - 3343, /* B73D (46909) */ - 3343, /* B73E (46910) */ - 3343, /* B73F (46911) */ - 3343, /* B740 (46912) */ - 3343, /* B741 (46913) */ - 3343, /* B742 (46914) */ - 3343, /* B743 (46915) */ - 3343, /* B744 (46916) */ - 3343, /* B745 (46917) */ - 3343, /* B746 (46918) */ - 3343, /* B747 (46919) */ - 3343, /* B748 (46920) */ - 3343, /* B749 (46921) */ - 3343, /* B74A (46922) */ - 3343, /* B74B (46923) */ - 3343, /* B74C (46924) */ - 3343, /* B74D (46925) */ - 3343, /* B74E (46926) */ - 3343, /* B74F (46927) */ - 3343, /* B750 (46928) */ - 3343, /* B751 (46929) */ - 3343, /* B752 (46930) */ - 3343, /* B753 (46931) */ - 3343, /* B754 (46932) */ - 3343, /* B755 (46933) */ - 3343, /* B756 (46934) */ - 3343, /* B757 (46935) */ - 3343, /* B758 (46936) */ - 3343, /* B759 (46937) */ - 3343, /* B75A (46938) */ - 3343, /* B75B (46939) */ - 3343, /* B75C (46940) */ - 3343, /* B75D (46941) */ - 3343, /* B75E (46942) */ - 3343, /* B75F (46943) */ - 3343, /* B760 (46944) */ - 3343, /* B761 (46945) */ - 3343, /* B762 (46946) */ - 3343, /* B763 (46947) */ - 3343, /* B764 (46948) */ - 3343, /* B765 (46949) */ - 3343, /* B766 (46950) */ - 3343, /* B767 (46951) */ - 3343, /* B768 (46952) */ - 3343, /* B769 (46953) */ - 3343, /* B76A (46954) */ - 3343, /* B76B (46955) */ - 3343, /* B76C (46956) */ - 3343, /* B76D (46957) */ - 3343, /* B76E (46958) */ - 3343, /* B76F (46959) */ - 3343, /* B770 (46960) */ - 3343, /* B771 (46961) */ - 3343, /* B772 (46962) */ - 3343, /* B773 (46963) */ - 3343, /* B774 (46964) */ - 3343, /* B775 (46965) */ - 3343, /* B776 (46966) */ - 3343, /* B777 (46967) */ - 3343, /* B778 (46968) */ - 3343, /* B779 (46969) */ - 3343, /* B77A (46970) */ - 3343, /* B77B (46971) */ - 3343, /* B77C (46972) */ - 3343, /* B77D (46973) */ - 3343, /* B77E (46974) */ - 3343, /* B77F (46975) */ - 3343, /* B780 (46976) */ - 3343, /* B781 (46977) */ - 3343, /* B782 (46978) */ - 3343, /* B783 (46979) */ - 3343, /* B784 (46980) */ - 3343, /* B785 (46981) */ - 3343, /* B786 (46982) */ - 3343, /* B787 (46983) */ - 3343, /* B788 (46984) */ - 3343, /* B789 (46985) */ - 3343, /* B78A (46986) */ - 3343, /* B78B (46987) */ - 3343, /* B78C (46988) */ - 3343, /* B78D (46989) */ - 3343, /* B78E (46990) */ - 3343, /* B78F (46991) */ - 3343, /* B790 (46992) */ - 3343, /* B791 (46993) */ - 3343, /* B792 (46994) */ - 3343, /* B793 (46995) */ - 3343, /* B794 (46996) */ - 3343, /* B795 (46997) */ - 3343, /* B796 (46998) */ - 3343, /* B797 (46999) */ - 3343, /* B798 (47000) */ - 3343, /* B799 (47001) */ - 3343, /* B79A (47002) */ - 3343, /* B79B (47003) */ - 3343, /* B79C (47004) */ - 3343, /* B79D (47005) */ - 3343, /* B79E (47006) */ - 3343, /* B79F (47007) */ - 3343, /* B7A0 (47008) */ - 3343, /* B7A1 (47009) */ - 3343, /* B7A2 (47010) */ - 3343, /* B7A3 (47011) */ - 3343, /* B7A4 (47012) */ - 3343, /* B7A5 (47013) */ - 3343, /* B7A6 (47014) */ - 3343, /* B7A7 (47015) */ - 3343, /* B7A8 (47016) */ - 3343, /* B7A9 (47017) */ - 3343, /* B7AA (47018) */ - 3343, /* B7AB (47019) */ - 3343, /* B7AC (47020) */ - 3343, /* B7AD (47021) */ - 3343, /* B7AE (47022) */ - 3343, /* B7AF (47023) */ - 3343, /* B7B0 (47024) */ - 3343, /* B7B1 (47025) */ - 3343, /* B7B2 (47026) */ - 3343, /* B7B3 (47027) */ - 3343, /* B7B4 (47028) */ - 3343, /* B7B5 (47029) */ - 3343, /* B7B6 (47030) */ - 3343, /* B7B7 (47031) */ - 3343, /* B7B8 (47032) */ - 3343, /* B7B9 (47033) */ - 3343, /* B7BA (47034) */ - 3343, /* B7BB (47035) */ - 3343, /* B7BC (47036) */ - 3343, /* B7BD (47037) */ - 3343, /* B7BE (47038) */ - 3343, /* B7BF (47039) */ - 3343, /* B7C0 (47040) */ - 3343, /* B7C1 (47041) */ - 3343, /* B7C2 (47042) */ - 3343, /* B7C3 (47043) */ - 3343, /* B7C4 (47044) */ - 3343, /* B7C5 (47045) */ - 3343, /* B7C6 (47046) */ - 3343, /* B7C7 (47047) */ - 3343, /* B7C8 (47048) */ - 3343, /* B7C9 (47049) */ - 3343, /* B7CA (47050) */ - 3343, /* B7CB (47051) */ - 3343, /* B7CC (47052) */ - 3343, /* B7CD (47053) */ - 3343, /* B7CE (47054) */ - 3343, /* B7CF (47055) */ - 3343, /* B7D0 (47056) */ - 3343, /* B7D1 (47057) */ - 3343, /* B7D2 (47058) */ - 3343, /* B7D3 (47059) */ - 3343, /* B7D4 (47060) */ - 3343, /* B7D5 (47061) */ - 3343, /* B7D6 (47062) */ - 3343, /* B7D7 (47063) */ - 3343, /* B7D8 (47064) */ - 3343, /* B7D9 (47065) */ - 3343, /* B7DA (47066) */ - 3343, /* B7DB (47067) */ - 3343, /* B7DC (47068) */ - 3343, /* B7DD (47069) */ - 3343, /* B7DE (47070) */ - 3343, /* B7DF (47071) */ - 3343, /* B7E0 (47072) */ - 3343, /* B7E1 (47073) */ - 3343, /* B7E2 (47074) */ - 3343, /* B7E3 (47075) */ - 3343, /* B7E4 (47076) */ - 3343, /* B7E5 (47077) */ - 3343, /* B7E6 (47078) */ - 3343, /* B7E7 (47079) */ - 3343, /* B7E8 (47080) */ - 3343, /* B7E9 (47081) */ - 3343, /* B7EA (47082) */ - 3343, /* B7EB (47083) */ - 3343, /* B7EC (47084) */ - 3343, /* B7ED (47085) */ - 3343, /* B7EE (47086) */ - 3343, /* B7EF (47087) */ - 3343, /* B7F0 (47088) */ - 3343, /* B7F1 (47089) */ - 3343, /* B7F2 (47090) */ - 3343, /* B7F3 (47091) */ - 3343, /* B7F4 (47092) */ - 3343, /* B7F5 (47093) */ - 3343, /* B7F6 (47094) */ - 3343, /* B7F7 (47095) */ - 3343, /* B7F8 (47096) */ - 3343, /* B7F9 (47097) */ - 3343, /* B7FA (47098) */ - 3343, /* B7FB (47099) */ - 3343, /* B7FC (47100) */ - 3343, /* B7FD (47101) */ - 3343, /* B7FE (47102) */ - 3343, /* B7FF (47103) */ - 3343, /* B800 (47104) */ - 3343, /* B801 (47105) */ - 3343, /* B802 (47106) */ - 3343, /* B803 (47107) */ - 3343, /* B804 (47108) */ - 3343, /* B805 (47109) */ - 3343, /* B806 (47110) */ - 3343, /* B807 (47111) */ - 3343, /* B808 (47112) */ - 3343, /* B809 (47113) */ - 3343, /* B80A (47114) */ - 3343, /* B80B (47115) */ - 3343, /* B80C (47116) */ - 3343, /* B80D (47117) */ - 3343, /* B80E (47118) */ - 3343, /* B80F (47119) */ - 3343, /* B810 (47120) */ - 3343, /* B811 (47121) */ - 3343, /* B812 (47122) */ - 3343, /* B813 (47123) */ - 3343, /* B814 (47124) */ - 3343, /* B815 (47125) */ - 3343, /* B816 (47126) */ - 3343, /* B817 (47127) */ - 3343, /* B818 (47128) */ - 3343, /* B819 (47129) */ - 3343, /* B81A (47130) */ - 3343, /* B81B (47131) */ - 3343, /* B81C (47132) */ - 3343, /* B81D (47133) */ - 3343, /* B81E (47134) */ - 3343, /* B81F (47135) */ - 3343, /* B820 (47136) */ - 3343, /* B821 (47137) */ - 3343, /* B822 (47138) */ - 3343, /* B823 (47139) */ - 3343, /* B824 (47140) */ - 3343, /* B825 (47141) */ - 3343, /* B826 (47142) */ - 3343, /* B827 (47143) */ - 3343, /* B828 (47144) */ - 3343, /* B829 (47145) */ - 3343, /* B82A (47146) */ - 3343, /* B82B (47147) */ - 3343, /* B82C (47148) */ - 3343, /* B82D (47149) */ - 3343, /* B82E (47150) */ - 3343, /* B82F (47151) */ - 3343, /* B830 (47152) */ - 3343, /* B831 (47153) */ - 3343, /* B832 (47154) */ - 3343, /* B833 (47155) */ - 3343, /* B834 (47156) */ - 3343, /* B835 (47157) */ - 3343, /* B836 (47158) */ - 3343, /* B837 (47159) */ - 3343, /* B838 (47160) */ - 3343, /* B839 (47161) */ - 3343, /* B83A (47162) */ - 3343, /* B83B (47163) */ - 3343, /* B83C (47164) */ - 3343, /* B83D (47165) */ - 3343, /* B83E (47166) */ - 3343, /* B83F (47167) */ - 3343, /* B840 (47168) */ - 3343, /* B841 (47169) */ - 3343, /* B842 (47170) */ - 3343, /* B843 (47171) */ - 3343, /* B844 (47172) */ - 3343, /* B845 (47173) */ - 3343, /* B846 (47174) */ - 3343, /* B847 (47175) */ - 3343, /* B848 (47176) */ - 3343, /* B849 (47177) */ - 3343, /* B84A (47178) */ - 3343, /* B84B (47179) */ - 3343, /* B84C (47180) */ - 3343, /* B84D (47181) */ - 3343, /* B84E (47182) */ - 3343, /* B84F (47183) */ - 3343, /* B850 (47184) */ - 3343, /* B851 (47185) */ - 3343, /* B852 (47186) */ - 3343, /* B853 (47187) */ - 3343, /* B854 (47188) */ - 3343, /* B855 (47189) */ - 3343, /* B856 (47190) */ - 3343, /* B857 (47191) */ - 3343, /* B858 (47192) */ - 3343, /* B859 (47193) */ - 3343, /* B85A (47194) */ - 3343, /* B85B (47195) */ - 3343, /* B85C (47196) */ - 3343, /* B85D (47197) */ - 3343, /* B85E (47198) */ - 3343, /* B85F (47199) */ - 3343, /* B860 (47200) */ - 3343, /* B861 (47201) */ - 3343, /* B862 (47202) */ - 3343, /* B863 (47203) */ - 3343, /* B864 (47204) */ - 3343, /* B865 (47205) */ - 3343, /* B866 (47206) */ - 3343, /* B867 (47207) */ - 3343, /* B868 (47208) */ - 3343, /* B869 (47209) */ - 3343, /* B86A (47210) */ - 3343, /* B86B (47211) */ - 3343, /* B86C (47212) */ - 3343, /* B86D (47213) */ - 3343, /* B86E (47214) */ - 3343, /* B86F (47215) */ - 3343, /* B870 (47216) */ - 3343, /* B871 (47217) */ - 3343, /* B872 (47218) */ - 3343, /* B873 (47219) */ - 3343, /* B874 (47220) */ - 3343, /* B875 (47221) */ - 3343, /* B876 (47222) */ - 3343, /* B877 (47223) */ - 3343, /* B878 (47224) */ - 3343, /* B879 (47225) */ - 3343, /* B87A (47226) */ - 3343, /* B87B (47227) */ - 3343, /* B87C (47228) */ - 3343, /* B87D (47229) */ - 3343, /* B87E (47230) */ - 3343, /* B87F (47231) */ - 3343, /* B880 (47232) */ - 3343, /* B881 (47233) */ - 3343, /* B882 (47234) */ - 3343, /* B883 (47235) */ - 3343, /* B884 (47236) */ - 3343, /* B885 (47237) */ - 3343, /* B886 (47238) */ - 3343, /* B887 (47239) */ - 3343, /* B888 (47240) */ - 3343, /* B889 (47241) */ - 3343, /* B88A (47242) */ - 3343, /* B88B (47243) */ - 3343, /* B88C (47244) */ - 3343, /* B88D (47245) */ - 3343, /* B88E (47246) */ - 3343, /* B88F (47247) */ - 3343, /* B890 (47248) */ - 3343, /* B891 (47249) */ - 3343, /* B892 (47250) */ - 3343, /* B893 (47251) */ - 3343, /* B894 (47252) */ - 3343, /* B895 (47253) */ - 3343, /* B896 (47254) */ - 3343, /* B897 (47255) */ - 3343, /* B898 (47256) */ - 3343, /* B899 (47257) */ - 3343, /* B89A (47258) */ - 3343, /* B89B (47259) */ - 3343, /* B89C (47260) */ - 3343, /* B89D (47261) */ - 3343, /* B89E (47262) */ - 3343, /* B89F (47263) */ - 3343, /* B8A0 (47264) */ - 3343, /* B8A1 (47265) */ - 3343, /* B8A2 (47266) */ - 3343, /* B8A3 (47267) */ - 3343, /* B8A4 (47268) */ - 3343, /* B8A5 (47269) */ - 3343, /* B8A6 (47270) */ - 3343, /* B8A7 (47271) */ - 3343, /* B8A8 (47272) */ - 3343, /* B8A9 (47273) */ - 3343, /* B8AA (47274) */ - 3343, /* B8AB (47275) */ - 3343, /* B8AC (47276) */ - 3343, /* B8AD (47277) */ - 3343, /* B8AE (47278) */ - 3343, /* B8AF (47279) */ - 3343, /* B8B0 (47280) */ - 3343, /* B8B1 (47281) */ - 3343, /* B8B2 (47282) */ - 3343, /* B8B3 (47283) */ - 3343, /* B8B4 (47284) */ - 3343, /* B8B5 (47285) */ - 3343, /* B8B6 (47286) */ - 3343, /* B8B7 (47287) */ - 3343, /* B8B8 (47288) */ - 3343, /* B8B9 (47289) */ - 3343, /* B8BA (47290) */ - 3343, /* B8BB (47291) */ - 3343, /* B8BC (47292) */ - 3343, /* B8BD (47293) */ - 3343, /* B8BE (47294) */ - 3343, /* B8BF (47295) */ - 3343, /* B8C0 (47296) */ - 3343, /* B8C1 (47297) */ - 3343, /* B8C2 (47298) */ - 3343, /* B8C3 (47299) */ - 3343, /* B8C4 (47300) */ - 3343, /* B8C5 (47301) */ - 3343, /* B8C6 (47302) */ - 3343, /* B8C7 (47303) */ - 3343, /* B8C8 (47304) */ - 3343, /* B8C9 (47305) */ - 3343, /* B8CA (47306) */ - 3343, /* B8CB (47307) */ - 3343, /* B8CC (47308) */ - 3343, /* B8CD (47309) */ - 3343, /* B8CE (47310) */ - 3343, /* B8CF (47311) */ - 3343, /* B8D0 (47312) */ - 3343, /* B8D1 (47313) */ - 3343, /* B8D2 (47314) */ - 3343, /* B8D3 (47315) */ - 3343, /* B8D4 (47316) */ - 3343, /* B8D5 (47317) */ - 3343, /* B8D6 (47318) */ - 3343, /* B8D7 (47319) */ - 3343, /* B8D8 (47320) */ - 3343, /* B8D9 (47321) */ - 3343, /* B8DA (47322) */ - 3343, /* B8DB (47323) */ - 3343, /* B8DC (47324) */ - 3343, /* B8DD (47325) */ - 3343, /* B8DE (47326) */ - 3343, /* B8DF (47327) */ - 3343, /* B8E0 (47328) */ - 3343, /* B8E1 (47329) */ - 3343, /* B8E2 (47330) */ - 3343, /* B8E3 (47331) */ - 3343, /* B8E4 (47332) */ - 3343, /* B8E5 (47333) */ - 3343, /* B8E6 (47334) */ - 3343, /* B8E7 (47335) */ - 3343, /* B8E8 (47336) */ - 3343, /* B8E9 (47337) */ - 3343, /* B8EA (47338) */ - 3343, /* B8EB (47339) */ - 3343, /* B8EC (47340) */ - 3343, /* B8ED (47341) */ - 3343, /* B8EE (47342) */ - 3343, /* B8EF (47343) */ - 3343, /* B8F0 (47344) */ - 3343, /* B8F1 (47345) */ - 3343, /* B8F2 (47346) */ - 3343, /* B8F3 (47347) */ - 3343, /* B8F4 (47348) */ - 3343, /* B8F5 (47349) */ - 3343, /* B8F6 (47350) */ - 3343, /* B8F7 (47351) */ - 3343, /* B8F8 (47352) */ - 3343, /* B8F9 (47353) */ - 3343, /* B8FA (47354) */ - 3343, /* B8FB (47355) */ - 3343, /* B8FC (47356) */ - 3343, /* B8FD (47357) */ - 3343, /* B8FE (47358) */ - 3343, /* B8FF (47359) */ - 3343, /* B900 (47360) */ - 3343, /* B901 (47361) */ - 3343, /* B902 (47362) */ - 3343, /* B903 (47363) */ - 3343, /* B904 (47364) */ - 3343, /* B905 (47365) */ - 3343, /* B906 (47366) */ - 3343, /* B907 (47367) */ - 3343, /* B908 (47368) */ - 3343, /* B909 (47369) */ - 3343, /* B90A (47370) */ - 3343, /* B90B (47371) */ - 3343, /* B90C (47372) */ - 3343, /* B90D (47373) */ - 3343, /* B90E (47374) */ - 3343, /* B90F (47375) */ - 3343, /* B910 (47376) */ - 3343, /* B911 (47377) */ - 3343, /* B912 (47378) */ - 3343, /* B913 (47379) */ - 3343, /* B914 (47380) */ - 3343, /* B915 (47381) */ - 3343, /* B916 (47382) */ - 3343, /* B917 (47383) */ - 3343, /* B918 (47384) */ - 3343, /* B919 (47385) */ - 3343, /* B91A (47386) */ - 3343, /* B91B (47387) */ - 3343, /* B91C (47388) */ - 3343, /* B91D (47389) */ - 3343, /* B91E (47390) */ - 3343, /* B91F (47391) */ - 3343, /* B920 (47392) */ - 3343, /* B921 (47393) */ - 3343, /* B922 (47394) */ - 3343, /* B923 (47395) */ - 3343, /* B924 (47396) */ - 3343, /* B925 (47397) */ - 3343, /* B926 (47398) */ - 3343, /* B927 (47399) */ - 3343, /* B928 (47400) */ - 3343, /* B929 (47401) */ - 3343, /* B92A (47402) */ - 3343, /* B92B (47403) */ - 3343, /* B92C (47404) */ - 3343, /* B92D (47405) */ - 3343, /* B92E (47406) */ - 3343, /* B92F (47407) */ - 3343, /* B930 (47408) */ - 3343, /* B931 (47409) */ - 3343, /* B932 (47410) */ - 3343, /* B933 (47411) */ - 3343, /* B934 (47412) */ - 3343, /* B935 (47413) */ - 3343, /* B936 (47414) */ - 3343, /* B937 (47415) */ - 3343, /* B938 (47416) */ - 3343, /* B939 (47417) */ - 3343, /* B93A (47418) */ - 3343, /* B93B (47419) */ - 3343, /* B93C (47420) */ - 3343, /* B93D (47421) */ - 3343, /* B93E (47422) */ - 3343, /* B93F (47423) */ - 3343, /* B940 (47424) */ - 3343, /* B941 (47425) */ - 3343, /* B942 (47426) */ - 3343, /* B943 (47427) */ - 3343, /* B944 (47428) */ - 3343, /* B945 (47429) */ - 3343, /* B946 (47430) */ - 3343, /* B947 (47431) */ - 3343, /* B948 (47432) */ - 3343, /* B949 (47433) */ - 3343, /* B94A (47434) */ - 3343, /* B94B (47435) */ - 3343, /* B94C (47436) */ - 3343, /* B94D (47437) */ - 3343, /* B94E (47438) */ - 3343, /* B94F (47439) */ - 3343, /* B950 (47440) */ - 3343, /* B951 (47441) */ - 3343, /* B952 (47442) */ - 3343, /* B953 (47443) */ - 3343, /* B954 (47444) */ - 3343, /* B955 (47445) */ - 3343, /* B956 (47446) */ - 3343, /* B957 (47447) */ - 3343, /* B958 (47448) */ - 3343, /* B959 (47449) */ - 3343, /* B95A (47450) */ - 3343, /* B95B (47451) */ - 3343, /* B95C (47452) */ - 3343, /* B95D (47453) */ - 3343, /* B95E (47454) */ - 3343, /* B95F (47455) */ - 3343, /* B960 (47456) */ - 3343, /* B961 (47457) */ - 3343, /* B962 (47458) */ - 3343, /* B963 (47459) */ - 3343, /* B964 (47460) */ - 3343, /* B965 (47461) */ - 3343, /* B966 (47462) */ - 3343, /* B967 (47463) */ - 3343, /* B968 (47464) */ - 3343, /* B969 (47465) */ - 3343, /* B96A (47466) */ - 3343, /* B96B (47467) */ - 3343, /* B96C (47468) */ - 3343, /* B96D (47469) */ - 3343, /* B96E (47470) */ - 3343, /* B96F (47471) */ - 3343, /* B970 (47472) */ - 3343, /* B971 (47473) */ - 3343, /* B972 (47474) */ - 3343, /* B973 (47475) */ - 3343, /* B974 (47476) */ - 3343, /* B975 (47477) */ - 3343, /* B976 (47478) */ - 3343, /* B977 (47479) */ - 3343, /* B978 (47480) */ - 3343, /* B979 (47481) */ - 3343, /* B97A (47482) */ - 3343, /* B97B (47483) */ - 3343, /* B97C (47484) */ - 3343, /* B97D (47485) */ - 3343, /* B97E (47486) */ - 3343, /* B97F (47487) */ - 3343, /* B980 (47488) */ - 3343, /* B981 (47489) */ - 3343, /* B982 (47490) */ - 3343, /* B983 (47491) */ - 3343, /* B984 (47492) */ - 3343, /* B985 (47493) */ - 3343, /* B986 (47494) */ - 3343, /* B987 (47495) */ - 3343, /* B988 (47496) */ - 3343, /* B989 (47497) */ - 3343, /* B98A (47498) */ - 3343, /* B98B (47499) */ - 3343, /* B98C (47500) */ - 3343, /* B98D (47501) */ - 3343, /* B98E (47502) */ - 3343, /* B98F (47503) */ - 3343, /* B990 (47504) */ - 3343, /* B991 (47505) */ - 3343, /* B992 (47506) */ - 3343, /* B993 (47507) */ - 3343, /* B994 (47508) */ - 3343, /* B995 (47509) */ - 3343, /* B996 (47510) */ - 3343, /* B997 (47511) */ - 3343, /* B998 (47512) */ - 3343, /* B999 (47513) */ - 3343, /* B99A (47514) */ - 3343, /* B99B (47515) */ - 3343, /* B99C (47516) */ - 3343, /* B99D (47517) */ - 3343, /* B99E (47518) */ - 3343, /* B99F (47519) */ - 3343, /* B9A0 (47520) */ - 3343, /* B9A1 (47521) */ - 3343, /* B9A2 (47522) */ - 3343, /* B9A3 (47523) */ - 3343, /* B9A4 (47524) */ - 3343, /* B9A5 (47525) */ - 3343, /* B9A6 (47526) */ - 3343, /* B9A7 (47527) */ - 3343, /* B9A8 (47528) */ - 3343, /* B9A9 (47529) */ - 3343, /* B9AA (47530) */ - 3343, /* B9AB (47531) */ - 3343, /* B9AC (47532) */ - 3343, /* B9AD (47533) */ - 3343, /* B9AE (47534) */ - 3343, /* B9AF (47535) */ - 3343, /* B9B0 (47536) */ - 3343, /* B9B1 (47537) */ - 3343, /* B9B2 (47538) */ - 3343, /* B9B3 (47539) */ - 3343, /* B9B4 (47540) */ - 3343, /* B9B5 (47541) */ - 3343, /* B9B6 (47542) */ - 3343, /* B9B7 (47543) */ - 3343, /* B9B8 (47544) */ - 3343, /* B9B9 (47545) */ - 3343, /* B9BA (47546) */ - 3343, /* B9BB (47547) */ - 3343, /* B9BC (47548) */ - 3343, /* B9BD (47549) */ - 3343, /* B9BE (47550) */ - 3343, /* B9BF (47551) */ - 3343, /* B9C0 (47552) */ - 3343, /* B9C1 (47553) */ - 3343, /* B9C2 (47554) */ - 3343, /* B9C3 (47555) */ - 3343, /* B9C4 (47556) */ - 3343, /* B9C5 (47557) */ - 3343, /* B9C6 (47558) */ - 3343, /* B9C7 (47559) */ - 3343, /* B9C8 (47560) */ - 3343, /* B9C9 (47561) */ - 3343, /* B9CA (47562) */ - 3343, /* B9CB (47563) */ - 3343, /* B9CC (47564) */ - 3343, /* B9CD (47565) */ - 3343, /* B9CE (47566) */ - 3343, /* B9CF (47567) */ - 3343, /* B9D0 (47568) */ - 3343, /* B9D1 (47569) */ - 3343, /* B9D2 (47570) */ - 3343, /* B9D3 (47571) */ - 3343, /* B9D4 (47572) */ - 3343, /* B9D5 (47573) */ - 3343, /* B9D6 (47574) */ - 3343, /* B9D7 (47575) */ - 3343, /* B9D8 (47576) */ - 3343, /* B9D9 (47577) */ - 3343, /* B9DA (47578) */ - 3343, /* B9DB (47579) */ - 3343, /* B9DC (47580) */ - 3343, /* B9DD (47581) */ - 3343, /* B9DE (47582) */ - 3343, /* B9DF (47583) */ - 3343, /* B9E0 (47584) */ - 3343, /* B9E1 (47585) */ - 3343, /* B9E2 (47586) */ - 3343, /* B9E3 (47587) */ - 3343, /* B9E4 (47588) */ - 3343, /* B9E5 (47589) */ - 3343, /* B9E6 (47590) */ - 3343, /* B9E7 (47591) */ - 3343, /* B9E8 (47592) */ - 3343, /* B9E9 (47593) */ - 3343, /* B9EA (47594) */ - 3343, /* B9EB (47595) */ - 3343, /* B9EC (47596) */ - 3343, /* B9ED (47597) */ - 3343, /* B9EE (47598) */ - 3343, /* B9EF (47599) */ - 3343, /* B9F0 (47600) */ - 3343, /* B9F1 (47601) */ - 3343, /* B9F2 (47602) */ - 3343, /* B9F3 (47603) */ - 3343, /* B9F4 (47604) */ - 3343, /* B9F5 (47605) */ - 3343, /* B9F6 (47606) */ - 3343, /* B9F7 (47607) */ - 3343, /* B9F8 (47608) */ - 3343, /* B9F9 (47609) */ - 3343, /* B9FA (47610) */ - 3343, /* B9FB (47611) */ - 3343, /* B9FC (47612) */ - 3343, /* B9FD (47613) */ - 3343, /* B9FE (47614) */ - 3343, /* B9FF (47615) */ - 3343, /* BA00 (47616) */ - 3343, /* BA01 (47617) */ - 3343, /* BA02 (47618) */ - 3343, /* BA03 (47619) */ - 3343, /* BA04 (47620) */ - 3343, /* BA05 (47621) */ - 3343, /* BA06 (47622) */ - 3343, /* BA07 (47623) */ - 3343, /* BA08 (47624) */ - 3343, /* BA09 (47625) */ - 3343, /* BA0A (47626) */ - 3343, /* BA0B (47627) */ - 3343, /* BA0C (47628) */ - 3343, /* BA0D (47629) */ - 3343, /* BA0E (47630) */ - 3343, /* BA0F (47631) */ - 3343, /* BA10 (47632) */ - 3343, /* BA11 (47633) */ - 3343, /* BA12 (47634) */ - 3343, /* BA13 (47635) */ - 3343, /* BA14 (47636) */ - 3343, /* BA15 (47637) */ - 3343, /* BA16 (47638) */ - 3343, /* BA17 (47639) */ - 3343, /* BA18 (47640) */ - 3343, /* BA19 (47641) */ - 3343, /* BA1A (47642) */ - 3343, /* BA1B (47643) */ - 3343, /* BA1C (47644) */ - 3343, /* BA1D (47645) */ - 3343, /* BA1E (47646) */ - 3343, /* BA1F (47647) */ - 3343, /* BA20 (47648) */ - 3343, /* BA21 (47649) */ - 3343, /* BA22 (47650) */ - 3343, /* BA23 (47651) */ - 3343, /* BA24 (47652) */ - 3343, /* BA25 (47653) */ - 3343, /* BA26 (47654) */ - 3343, /* BA27 (47655) */ - 3343, /* BA28 (47656) */ - 3343, /* BA29 (47657) */ - 3343, /* BA2A (47658) */ - 3343, /* BA2B (47659) */ - 3343, /* BA2C (47660) */ - 3343, /* BA2D (47661) */ - 3343, /* BA2E (47662) */ - 3343, /* BA2F (47663) */ - 3343, /* BA30 (47664) */ - 3343, /* BA31 (47665) */ - 3343, /* BA32 (47666) */ - 3343, /* BA33 (47667) */ - 3343, /* BA34 (47668) */ - 3343, /* BA35 (47669) */ - 3343, /* BA36 (47670) */ - 3343, /* BA37 (47671) */ - 3343, /* BA38 (47672) */ - 3343, /* BA39 (47673) */ - 3343, /* BA3A (47674) */ - 3343, /* BA3B (47675) */ - 3343, /* BA3C (47676) */ - 3343, /* BA3D (47677) */ - 3343, /* BA3E (47678) */ - 3343, /* BA3F (47679) */ - 3343, /* BA40 (47680) */ - 3343, /* BA41 (47681) */ - 3343, /* BA42 (47682) */ - 3343, /* BA43 (47683) */ - 3343, /* BA44 (47684) */ - 3343, /* BA45 (47685) */ - 3343, /* BA46 (47686) */ - 3343, /* BA47 (47687) */ - 3343, /* BA48 (47688) */ - 3343, /* BA49 (47689) */ - 3343, /* BA4A (47690) */ - 3343, /* BA4B (47691) */ - 3343, /* BA4C (47692) */ - 3343, /* BA4D (47693) */ - 3343, /* BA4E (47694) */ - 3343, /* BA4F (47695) */ - 3343, /* BA50 (47696) */ - 3343, /* BA51 (47697) */ - 3343, /* BA52 (47698) */ - 3343, /* BA53 (47699) */ - 3343, /* BA54 (47700) */ - 3343, /* BA55 (47701) */ - 3343, /* BA56 (47702) */ - 3343, /* BA57 (47703) */ - 3343, /* BA58 (47704) */ - 3343, /* BA59 (47705) */ - 3343, /* BA5A (47706) */ - 3343, /* BA5B (47707) */ - 3343, /* BA5C (47708) */ - 3343, /* BA5D (47709) */ - 3343, /* BA5E (47710) */ - 3343, /* BA5F (47711) */ - 3343, /* BA60 (47712) */ - 3343, /* BA61 (47713) */ - 3343, /* BA62 (47714) */ - 3343, /* BA63 (47715) */ - 3343, /* BA64 (47716) */ - 3343, /* BA65 (47717) */ - 3343, /* BA66 (47718) */ - 3343, /* BA67 (47719) */ - 3343, /* BA68 (47720) */ - 3343, /* BA69 (47721) */ - 3343, /* BA6A (47722) */ - 3343, /* BA6B (47723) */ - 3343, /* BA6C (47724) */ - 3343, /* BA6D (47725) */ - 3343, /* BA6E (47726) */ - 3343, /* BA6F (47727) */ - 3343, /* BA70 (47728) */ - 3343, /* BA71 (47729) */ - 3343, /* BA72 (47730) */ - 3343, /* BA73 (47731) */ - 3343, /* BA74 (47732) */ - 3343, /* BA75 (47733) */ - 3343, /* BA76 (47734) */ - 3343, /* BA77 (47735) */ - 3343, /* BA78 (47736) */ - 3343, /* BA79 (47737) */ - 3343, /* BA7A (47738) */ - 3343, /* BA7B (47739) */ - 3343, /* BA7C (47740) */ - 3343, /* BA7D (47741) */ - 3343, /* BA7E (47742) */ - 3343, /* BA7F (47743) */ - 3343, /* BA80 (47744) */ - 3343, /* BA81 (47745) */ - 3343, /* BA82 (47746) */ - 3343, /* BA83 (47747) */ - 3343, /* BA84 (47748) */ - 3343, /* BA85 (47749) */ - 3343, /* BA86 (47750) */ - 3343, /* BA87 (47751) */ - 3343, /* BA88 (47752) */ - 3343, /* BA89 (47753) */ - 3343, /* BA8A (47754) */ - 3343, /* BA8B (47755) */ - 3343, /* BA8C (47756) */ - 3343, /* BA8D (47757) */ - 3343, /* BA8E (47758) */ - 3343, /* BA8F (47759) */ - 3343, /* BA90 (47760) */ - 3343, /* BA91 (47761) */ - 3343, /* BA92 (47762) */ - 3343, /* BA93 (47763) */ - 3343, /* BA94 (47764) */ - 3343, /* BA95 (47765) */ - 3343, /* BA96 (47766) */ - 3343, /* BA97 (47767) */ - 3343, /* BA98 (47768) */ - 3343, /* BA99 (47769) */ - 3343, /* BA9A (47770) */ - 3343, /* BA9B (47771) */ - 3343, /* BA9C (47772) */ - 3343, /* BA9D (47773) */ - 3343, /* BA9E (47774) */ - 3343, /* BA9F (47775) */ - 3343, /* BAA0 (47776) */ - 3343, /* BAA1 (47777) */ - 3343, /* BAA2 (47778) */ - 3343, /* BAA3 (47779) */ - 3343, /* BAA4 (47780) */ - 3343, /* BAA5 (47781) */ - 3343, /* BAA6 (47782) */ - 3343, /* BAA7 (47783) */ - 3343, /* BAA8 (47784) */ - 3343, /* BAA9 (47785) */ - 3343, /* BAAA (47786) */ - 3343, /* BAAB (47787) */ - 3343, /* BAAC (47788) */ - 3343, /* BAAD (47789) */ - 3343, /* BAAE (47790) */ - 3343, /* BAAF (47791) */ - 3343, /* BAB0 (47792) */ - 3343, /* BAB1 (47793) */ - 3343, /* BAB2 (47794) */ - 3343, /* BAB3 (47795) */ - 3343, /* BAB4 (47796) */ - 3343, /* BAB5 (47797) */ - 3343, /* BAB6 (47798) */ - 3343, /* BAB7 (47799) */ - 3343, /* BAB8 (47800) */ - 3343, /* BAB9 (47801) */ - 3343, /* BABA (47802) */ - 3343, /* BABB (47803) */ - 3343, /* BABC (47804) */ - 3343, /* BABD (47805) */ - 3343, /* BABE (47806) */ - 3343, /* BABF (47807) */ - 3343, /* BAC0 (47808) */ - 3343, /* BAC1 (47809) */ - 3343, /* BAC2 (47810) */ - 3343, /* BAC3 (47811) */ - 3343, /* BAC4 (47812) */ - 3343, /* BAC5 (47813) */ - 3343, /* BAC6 (47814) */ - 3343, /* BAC7 (47815) */ - 3343, /* BAC8 (47816) */ - 3343, /* BAC9 (47817) */ - 3343, /* BACA (47818) */ - 3343, /* BACB (47819) */ - 3343, /* BACC (47820) */ - 3343, /* BACD (47821) */ - 3343, /* BACE (47822) */ - 3343, /* BACF (47823) */ - 3343, /* BAD0 (47824) */ - 3343, /* BAD1 (47825) */ - 3343, /* BAD2 (47826) */ - 3343, /* BAD3 (47827) */ - 3343, /* BAD4 (47828) */ - 3343, /* BAD5 (47829) */ - 3343, /* BAD6 (47830) */ - 3343, /* BAD7 (47831) */ - 3343, /* BAD8 (47832) */ - 3343, /* BAD9 (47833) */ - 3343, /* BADA (47834) */ - 3343, /* BADB (47835) */ - 3343, /* BADC (47836) */ - 3343, /* BADD (47837) */ - 3343, /* BADE (47838) */ - 3343, /* BADF (47839) */ - 3343, /* BAE0 (47840) */ - 3343, /* BAE1 (47841) */ - 3343, /* BAE2 (47842) */ - 3343, /* BAE3 (47843) */ - 3343, /* BAE4 (47844) */ - 3343, /* BAE5 (47845) */ - 3343, /* BAE6 (47846) */ - 3343, /* BAE7 (47847) */ - 3343, /* BAE8 (47848) */ - 3343, /* BAE9 (47849) */ - 3343, /* BAEA (47850) */ - 3343, /* BAEB (47851) */ - 3343, /* BAEC (47852) */ - 3343, /* BAED (47853) */ - 3343, /* BAEE (47854) */ - 3343, /* BAEF (47855) */ - 3343, /* BAF0 (47856) */ - 3343, /* BAF1 (47857) */ - 3343, /* BAF2 (47858) */ - 3343, /* BAF3 (47859) */ - 3343, /* BAF4 (47860) */ - 3343, /* BAF5 (47861) */ - 3343, /* BAF6 (47862) */ - 3343, /* BAF7 (47863) */ - 3343, /* BAF8 (47864) */ - 3343, /* BAF9 (47865) */ - 3343, /* BAFA (47866) */ - 3343, /* BAFB (47867) */ - 3343, /* BAFC (47868) */ - 3343, /* BAFD (47869) */ - 3343, /* BAFE (47870) */ - 3343, /* BAFF (47871) */ - 3343, /* BB00 (47872) */ - 3343, /* BB01 (47873) */ - 3343, /* BB02 (47874) */ - 3343, /* BB03 (47875) */ - 3343, /* BB04 (47876) */ - 3343, /* BB05 (47877) */ - 3343, /* BB06 (47878) */ - 3343, /* BB07 (47879) */ - 3343, /* BB08 (47880) */ - 3343, /* BB09 (47881) */ - 3343, /* BB0A (47882) */ - 3343, /* BB0B (47883) */ - 3343, /* BB0C (47884) */ - 3343, /* BB0D (47885) */ - 3343, /* BB0E (47886) */ - 3343, /* BB0F (47887) */ - 3343, /* BB10 (47888) */ - 3343, /* BB11 (47889) */ - 3343, /* BB12 (47890) */ - 3343, /* BB13 (47891) */ - 3343, /* BB14 (47892) */ - 3343, /* BB15 (47893) */ - 3343, /* BB16 (47894) */ - 3343, /* BB17 (47895) */ - 3343, /* BB18 (47896) */ - 3343, /* BB19 (47897) */ - 3343, /* BB1A (47898) */ - 3343, /* BB1B (47899) */ - 3343, /* BB1C (47900) */ - 3343, /* BB1D (47901) */ - 3343, /* BB1E (47902) */ - 3343, /* BB1F (47903) */ - 3343, /* BB20 (47904) */ - 3343, /* BB21 (47905) */ - 3343, /* BB22 (47906) */ - 3343, /* BB23 (47907) */ - 3343, /* BB24 (47908) */ - 3343, /* BB25 (47909) */ - 3343, /* BB26 (47910) */ - 3343, /* BB27 (47911) */ - 3343, /* BB28 (47912) */ - 3343, /* BB29 (47913) */ - 3343, /* BB2A (47914) */ - 3343, /* BB2B (47915) */ - 3343, /* BB2C (47916) */ - 3343, /* BB2D (47917) */ - 3343, /* BB2E (47918) */ - 3343, /* BB2F (47919) */ - 3343, /* BB30 (47920) */ - 3343, /* BB31 (47921) */ - 3343, /* BB32 (47922) */ - 3343, /* BB33 (47923) */ - 3343, /* BB34 (47924) */ - 3343, /* BB35 (47925) */ - 3343, /* BB36 (47926) */ - 3343, /* BB37 (47927) */ - 3343, /* BB38 (47928) */ - 3343, /* BB39 (47929) */ - 3343, /* BB3A (47930) */ - 3343, /* BB3B (47931) */ - 3343, /* BB3C (47932) */ - 3343, /* BB3D (47933) */ - 3343, /* BB3E (47934) */ - 3343, /* BB3F (47935) */ - 3343, /* BB40 (47936) */ - 3343, /* BB41 (47937) */ - 3343, /* BB42 (47938) */ - 3343, /* BB43 (47939) */ - 3343, /* BB44 (47940) */ - 3343, /* BB45 (47941) */ - 3343, /* BB46 (47942) */ - 3343, /* BB47 (47943) */ - 3343, /* BB48 (47944) */ - 3343, /* BB49 (47945) */ - 3343, /* BB4A (47946) */ - 3343, /* BB4B (47947) */ - 3343, /* BB4C (47948) */ - 3343, /* BB4D (47949) */ - 3343, /* BB4E (47950) */ - 3343, /* BB4F (47951) */ - 3343, /* BB50 (47952) */ - 3343, /* BB51 (47953) */ - 3343, /* BB52 (47954) */ - 3343, /* BB53 (47955) */ - 3343, /* BB54 (47956) */ - 3343, /* BB55 (47957) */ - 3343, /* BB56 (47958) */ - 3343, /* BB57 (47959) */ - 3343, /* BB58 (47960) */ - 3343, /* BB59 (47961) */ - 3343, /* BB5A (47962) */ - 3343, /* BB5B (47963) */ - 3343, /* BB5C (47964) */ - 3343, /* BB5D (47965) */ - 3343, /* BB5E (47966) */ - 3343, /* BB5F (47967) */ - 3343, /* BB60 (47968) */ - 3343, /* BB61 (47969) */ - 3343, /* BB62 (47970) */ - 3343, /* BB63 (47971) */ - 3343, /* BB64 (47972) */ - 3343, /* BB65 (47973) */ - 3343, /* BB66 (47974) */ - 3343, /* BB67 (47975) */ - 3343, /* BB68 (47976) */ - 3343, /* BB69 (47977) */ - 3343, /* BB6A (47978) */ - 3343, /* BB6B (47979) */ - 3343, /* BB6C (47980) */ - 3343, /* BB6D (47981) */ - 3343, /* BB6E (47982) */ - 3343, /* BB6F (47983) */ - 3343, /* BB70 (47984) */ - 3343, /* BB71 (47985) */ - 3343, /* BB72 (47986) */ - 3343, /* BB73 (47987) */ - 3343, /* BB74 (47988) */ - 3343, /* BB75 (47989) */ - 3343, /* BB76 (47990) */ - 3343, /* BB77 (47991) */ - 3343, /* BB78 (47992) */ - 3343, /* BB79 (47993) */ - 3343, /* BB7A (47994) */ - 3343, /* BB7B (47995) */ - 3343, /* BB7C (47996) */ - 3343, /* BB7D (47997) */ - 3343, /* BB7E (47998) */ - 3343, /* BB7F (47999) */ - 3343, /* BB80 (48000) */ - 3343, /* BB81 (48001) */ - 3343, /* BB82 (48002) */ - 3343, /* BB83 (48003) */ - 3343, /* BB84 (48004) */ - 3343, /* BB85 (48005) */ - 3343, /* BB86 (48006) */ - 3343, /* BB87 (48007) */ - 3343, /* BB88 (48008) */ - 3343, /* BB89 (48009) */ - 3343, /* BB8A (48010) */ - 3343, /* BB8B (48011) */ - 3343, /* BB8C (48012) */ - 3343, /* BB8D (48013) */ - 3343, /* BB8E (48014) */ - 3343, /* BB8F (48015) */ - 3343, /* BB90 (48016) */ - 3343, /* BB91 (48017) */ - 3343, /* BB92 (48018) */ - 3343, /* BB93 (48019) */ - 3343, /* BB94 (48020) */ - 3343, /* BB95 (48021) */ - 3343, /* BB96 (48022) */ - 3343, /* BB97 (48023) */ - 3343, /* BB98 (48024) */ - 3343, /* BB99 (48025) */ - 3343, /* BB9A (48026) */ - 3343, /* BB9B (48027) */ - 3343, /* BB9C (48028) */ - 3343, /* BB9D (48029) */ - 3343, /* BB9E (48030) */ - 3343, /* BB9F (48031) */ - 3343, /* BBA0 (48032) */ - 3343, /* BBA1 (48033) */ - 3343, /* BBA2 (48034) */ - 3343, /* BBA3 (48035) */ - 3343, /* BBA4 (48036) */ - 3343, /* BBA5 (48037) */ - 3343, /* BBA6 (48038) */ - 3343, /* BBA7 (48039) */ - 3343, /* BBA8 (48040) */ - 3343, /* BBA9 (48041) */ - 3343, /* BBAA (48042) */ - 3343, /* BBAB (48043) */ - 3343, /* BBAC (48044) */ - 3343, /* BBAD (48045) */ - 3343, /* BBAE (48046) */ - 3343, /* BBAF (48047) */ - 3343, /* BBB0 (48048) */ - 3343, /* BBB1 (48049) */ - 3343, /* BBB2 (48050) */ - 3343, /* BBB3 (48051) */ - 3343, /* BBB4 (48052) */ - 3343, /* BBB5 (48053) */ - 3343, /* BBB6 (48054) */ - 3343, /* BBB7 (48055) */ - 3343, /* BBB8 (48056) */ - 3343, /* BBB9 (48057) */ - 3343, /* BBBA (48058) */ - 3343, /* BBBB (48059) */ - 3343, /* BBBC (48060) */ - 3343, /* BBBD (48061) */ - 3343, /* BBBE (48062) */ - 3343, /* BBBF (48063) */ - 3343, /* BBC0 (48064) */ - 3343, /* BBC1 (48065) */ - 3343, /* BBC2 (48066) */ - 3343, /* BBC3 (48067) */ - 3343, /* BBC4 (48068) */ - 3343, /* BBC5 (48069) */ - 3343, /* BBC6 (48070) */ - 3343, /* BBC7 (48071) */ - 3343, /* BBC8 (48072) */ - 3343, /* BBC9 (48073) */ - 3343, /* BBCA (48074) */ - 3343, /* BBCB (48075) */ - 3343, /* BBCC (48076) */ - 3343, /* BBCD (48077) */ - 3343, /* BBCE (48078) */ - 3343, /* BBCF (48079) */ - 3343, /* BBD0 (48080) */ - 3343, /* BBD1 (48081) */ - 3343, /* BBD2 (48082) */ - 3343, /* BBD3 (48083) */ - 3343, /* BBD4 (48084) */ - 3343, /* BBD5 (48085) */ - 3343, /* BBD6 (48086) */ - 3343, /* BBD7 (48087) */ - 3343, /* BBD8 (48088) */ - 3343, /* BBD9 (48089) */ - 3343, /* BBDA (48090) */ - 3343, /* BBDB (48091) */ - 3343, /* BBDC (48092) */ - 3343, /* BBDD (48093) */ - 3343, /* BBDE (48094) */ - 3343, /* BBDF (48095) */ - 3343, /* BBE0 (48096) */ - 3343, /* BBE1 (48097) */ - 3343, /* BBE2 (48098) */ - 3343, /* BBE3 (48099) */ - 3343, /* BBE4 (48100) */ - 3343, /* BBE5 (48101) */ - 3343, /* BBE6 (48102) */ - 3343, /* BBE7 (48103) */ - 3343, /* BBE8 (48104) */ - 3343, /* BBE9 (48105) */ - 3343, /* BBEA (48106) */ - 3343, /* BBEB (48107) */ - 3343, /* BBEC (48108) */ - 3343, /* BBED (48109) */ - 3343, /* BBEE (48110) */ - 3343, /* BBEF (48111) */ - 3343, /* BBF0 (48112) */ - 3343, /* BBF1 (48113) */ - 3343, /* BBF2 (48114) */ - 3343, /* BBF3 (48115) */ - 3343, /* BBF4 (48116) */ - 3343, /* BBF5 (48117) */ - 3343, /* BBF6 (48118) */ - 3343, /* BBF7 (48119) */ - 3343, /* BBF8 (48120) */ - 3343, /* BBF9 (48121) */ - 3343, /* BBFA (48122) */ - 3343, /* BBFB (48123) */ - 3343, /* BBFC (48124) */ - 3343, /* BBFD (48125) */ - 3343, /* BBFE (48126) */ - 3343, /* BBFF (48127) */ - 3343, /* BC00 (48128) */ - 3343, /* BC01 (48129) */ - 3343, /* BC02 (48130) */ - 3343, /* BC03 (48131) */ - 3343, /* BC04 (48132) */ - 3343, /* BC05 (48133) */ - 3343, /* BC06 (48134) */ - 3343, /* BC07 (48135) */ - 3343, /* BC08 (48136) */ - 3343, /* BC09 (48137) */ - 3343, /* BC0A (48138) */ - 3343, /* BC0B (48139) */ - 3343, /* BC0C (48140) */ - 3343, /* BC0D (48141) */ - 3343, /* BC0E (48142) */ - 3343, /* BC0F (48143) */ - 3343, /* BC10 (48144) */ - 3343, /* BC11 (48145) */ - 3343, /* BC12 (48146) */ - 3343, /* BC13 (48147) */ - 3343, /* BC14 (48148) */ - 3343, /* BC15 (48149) */ - 3343, /* BC16 (48150) */ - 3343, /* BC17 (48151) */ - 3343, /* BC18 (48152) */ - 3343, /* BC19 (48153) */ - 3343, /* BC1A (48154) */ - 3343, /* BC1B (48155) */ - 3343, /* BC1C (48156) */ - 3343, /* BC1D (48157) */ - 3343, /* BC1E (48158) */ - 3343, /* BC1F (48159) */ - 3343, /* BC20 (48160) */ - 3343, /* BC21 (48161) */ - 3343, /* BC22 (48162) */ - 3343, /* BC23 (48163) */ - 3343, /* BC24 (48164) */ - 3343, /* BC25 (48165) */ - 3343, /* BC26 (48166) */ - 3343, /* BC27 (48167) */ - 3343, /* BC28 (48168) */ - 3343, /* BC29 (48169) */ - 3343, /* BC2A (48170) */ - 3343, /* BC2B (48171) */ - 3343, /* BC2C (48172) */ - 3343, /* BC2D (48173) */ - 3343, /* BC2E (48174) */ - 3343, /* BC2F (48175) */ - 3343, /* BC30 (48176) */ - 3343, /* BC31 (48177) */ - 3343, /* BC32 (48178) */ - 3343, /* BC33 (48179) */ - 3343, /* BC34 (48180) */ - 3343, /* BC35 (48181) */ - 3343, /* BC36 (48182) */ - 3343, /* BC37 (48183) */ - 3343, /* BC38 (48184) */ - 3343, /* BC39 (48185) */ - 3343, /* BC3A (48186) */ - 3343, /* BC3B (48187) */ - 3343, /* BC3C (48188) */ - 3343, /* BC3D (48189) */ - 3343, /* BC3E (48190) */ - 3343, /* BC3F (48191) */ - 3343, /* BC40 (48192) */ - 3343, /* BC41 (48193) */ - 3343, /* BC42 (48194) */ - 3343, /* BC43 (48195) */ - 3343, /* BC44 (48196) */ - 3343, /* BC45 (48197) */ - 3343, /* BC46 (48198) */ - 3343, /* BC47 (48199) */ - 3343, /* BC48 (48200) */ - 3343, /* BC49 (48201) */ - 3343, /* BC4A (48202) */ - 3343, /* BC4B (48203) */ - 3343, /* BC4C (48204) */ - 3343, /* BC4D (48205) */ - 3343, /* BC4E (48206) */ - 3343, /* BC4F (48207) */ - 3343, /* BC50 (48208) */ - 3343, /* BC51 (48209) */ - 3343, /* BC52 (48210) */ - 3343, /* BC53 (48211) */ - 3343, /* BC54 (48212) */ - 3343, /* BC55 (48213) */ - 3343, /* BC56 (48214) */ - 3343, /* BC57 (48215) */ - 3343, /* BC58 (48216) */ - 3343, /* BC59 (48217) */ - 3343, /* BC5A (48218) */ - 3343, /* BC5B (48219) */ - 3343, /* BC5C (48220) */ - 3343, /* BC5D (48221) */ - 3343, /* BC5E (48222) */ - 3343, /* BC5F (48223) */ - 3343, /* BC60 (48224) */ - 3343, /* BC61 (48225) */ - 3343, /* BC62 (48226) */ - 3343, /* BC63 (48227) */ - 3343, /* BC64 (48228) */ - 3343, /* BC65 (48229) */ - 3343, /* BC66 (48230) */ - 3343, /* BC67 (48231) */ - 3343, /* BC68 (48232) */ - 3343, /* BC69 (48233) */ - 3343, /* BC6A (48234) */ - 3343, /* BC6B (48235) */ - 3343, /* BC6C (48236) */ - 3343, /* BC6D (48237) */ - 3343, /* BC6E (48238) */ - 3343, /* BC6F (48239) */ - 3343, /* BC70 (48240) */ - 3343, /* BC71 (48241) */ - 3343, /* BC72 (48242) */ - 3343, /* BC73 (48243) */ - 3343, /* BC74 (48244) */ - 3343, /* BC75 (48245) */ - 3343, /* BC76 (48246) */ - 3343, /* BC77 (48247) */ - 3343, /* BC78 (48248) */ - 3343, /* BC79 (48249) */ - 3343, /* BC7A (48250) */ - 3343, /* BC7B (48251) */ - 3343, /* BC7C (48252) */ - 3343, /* BC7D (48253) */ - 3343, /* BC7E (48254) */ - 3343, /* BC7F (48255) */ - 3343, /* BC80 (48256) */ - 3343, /* BC81 (48257) */ - 3343, /* BC82 (48258) */ - 3343, /* BC83 (48259) */ - 3343, /* BC84 (48260) */ - 3343, /* BC85 (48261) */ - 3343, /* BC86 (48262) */ - 3343, /* BC87 (48263) */ - 3343, /* BC88 (48264) */ - 3343, /* BC89 (48265) */ - 3343, /* BC8A (48266) */ - 3343, /* BC8B (48267) */ - 3343, /* BC8C (48268) */ - 3343, /* BC8D (48269) */ - 3343, /* BC8E (48270) */ - 3343, /* BC8F (48271) */ - 3343, /* BC90 (48272) */ - 3343, /* BC91 (48273) */ - 3343, /* BC92 (48274) */ - 3343, /* BC93 (48275) */ - 3343, /* BC94 (48276) */ - 3343, /* BC95 (48277) */ - 3343, /* BC96 (48278) */ - 3343, /* BC97 (48279) */ - 3343, /* BC98 (48280) */ - 3343, /* BC99 (48281) */ - 3343, /* BC9A (48282) */ - 3343, /* BC9B (48283) */ - 3343, /* BC9C (48284) */ - 3343, /* BC9D (48285) */ - 3343, /* BC9E (48286) */ - 3343, /* BC9F (48287) */ - 3343, /* BCA0 (48288) */ - 3343, /* BCA1 (48289) */ - 3343, /* BCA2 (48290) */ - 3343, /* BCA3 (48291) */ - 3343, /* BCA4 (48292) */ - 3343, /* BCA5 (48293) */ - 3343, /* BCA6 (48294) */ - 3343, /* BCA7 (48295) */ - 3343, /* BCA8 (48296) */ - 3343, /* BCA9 (48297) */ - 3343, /* BCAA (48298) */ - 3343, /* BCAB (48299) */ - 3343, /* BCAC (48300) */ - 3343, /* BCAD (48301) */ - 3343, /* BCAE (48302) */ - 3343, /* BCAF (48303) */ - 3343, /* BCB0 (48304) */ - 3343, /* BCB1 (48305) */ - 3343, /* BCB2 (48306) */ - 3343, /* BCB3 (48307) */ - 3343, /* BCB4 (48308) */ - 3343, /* BCB5 (48309) */ - 3343, /* BCB6 (48310) */ - 3343, /* BCB7 (48311) */ - 3343, /* BCB8 (48312) */ - 3343, /* BCB9 (48313) */ - 3343, /* BCBA (48314) */ - 3343, /* BCBB (48315) */ - 3343, /* BCBC (48316) */ - 3343, /* BCBD (48317) */ - 3343, /* BCBE (48318) */ - 3343, /* BCBF (48319) */ - 3343, /* BCC0 (48320) */ - 3343, /* BCC1 (48321) */ - 3343, /* BCC2 (48322) */ - 3343, /* BCC3 (48323) */ - 3343, /* BCC4 (48324) */ - 3343, /* BCC5 (48325) */ - 3343, /* BCC6 (48326) */ - 3343, /* BCC7 (48327) */ - 3343, /* BCC8 (48328) */ - 3343, /* BCC9 (48329) */ - 3343, /* BCCA (48330) */ - 3343, /* BCCB (48331) */ - 3343, /* BCCC (48332) */ - 3343, /* BCCD (48333) */ - 3343, /* BCCE (48334) */ - 3343, /* BCCF (48335) */ - 3343, /* BCD0 (48336) */ - 3343, /* BCD1 (48337) */ - 3343, /* BCD2 (48338) */ - 3343, /* BCD3 (48339) */ - 3343, /* BCD4 (48340) */ - 3343, /* BCD5 (48341) */ - 3343, /* BCD6 (48342) */ - 3343, /* BCD7 (48343) */ - 3343, /* BCD8 (48344) */ - 3343, /* BCD9 (48345) */ - 3343, /* BCDA (48346) */ - 3343, /* BCDB (48347) */ - 3343, /* BCDC (48348) */ - 3343, /* BCDD (48349) */ - 3343, /* BCDE (48350) */ - 3343, /* BCDF (48351) */ - 3343, /* BCE0 (48352) */ - 3343, /* BCE1 (48353) */ - 3343, /* BCE2 (48354) */ - 3343, /* BCE3 (48355) */ - 3343, /* BCE4 (48356) */ - 3343, /* BCE5 (48357) */ - 3343, /* BCE6 (48358) */ - 3343, /* BCE7 (48359) */ - 3343, /* BCE8 (48360) */ - 3343, /* BCE9 (48361) */ - 3343, /* BCEA (48362) */ - 3343, /* BCEB (48363) */ - 3343, /* BCEC (48364) */ - 3343, /* BCED (48365) */ - 3343, /* BCEE (48366) */ - 3343, /* BCEF (48367) */ - 3343, /* BCF0 (48368) */ - 3343, /* BCF1 (48369) */ - 3343, /* BCF2 (48370) */ - 3343, /* BCF3 (48371) */ - 3343, /* BCF4 (48372) */ - 3343, /* BCF5 (48373) */ - 3343, /* BCF6 (48374) */ - 3343, /* BCF7 (48375) */ - 3343, /* BCF8 (48376) */ - 3343, /* BCF9 (48377) */ - 3343, /* BCFA (48378) */ - 3343, /* BCFB (48379) */ - 3343, /* BCFC (48380) */ - 3343, /* BCFD (48381) */ - 3343, /* BCFE (48382) */ - 3343, /* BCFF (48383) */ - 3343, /* BD00 (48384) */ - 3343, /* BD01 (48385) */ - 3343, /* BD02 (48386) */ - 3343, /* BD03 (48387) */ - 3343, /* BD04 (48388) */ - 3343, /* BD05 (48389) */ - 3343, /* BD06 (48390) */ - 3343, /* BD07 (48391) */ - 3343, /* BD08 (48392) */ - 3343, /* BD09 (48393) */ - 3343, /* BD0A (48394) */ - 3343, /* BD0B (48395) */ - 3343, /* BD0C (48396) */ - 3343, /* BD0D (48397) */ - 3343, /* BD0E (48398) */ - 3343, /* BD0F (48399) */ - 3343, /* BD10 (48400) */ - 3343, /* BD11 (48401) */ - 3343, /* BD12 (48402) */ - 3343, /* BD13 (48403) */ - 3343, /* BD14 (48404) */ - 3343, /* BD15 (48405) */ - 3343, /* BD16 (48406) */ - 3343, /* BD17 (48407) */ - 3343, /* BD18 (48408) */ - 3343, /* BD19 (48409) */ - 3343, /* BD1A (48410) */ - 3343, /* BD1B (48411) */ - 3343, /* BD1C (48412) */ - 3343, /* BD1D (48413) */ - 3343, /* BD1E (48414) */ - 3343, /* BD1F (48415) */ - 3343, /* BD20 (48416) */ - 3343, /* BD21 (48417) */ - 3343, /* BD22 (48418) */ - 3343, /* BD23 (48419) */ - 3343, /* BD24 (48420) */ - 3343, /* BD25 (48421) */ - 3343, /* BD26 (48422) */ - 3343, /* BD27 (48423) */ - 3343, /* BD28 (48424) */ - 3343, /* BD29 (48425) */ - 3343, /* BD2A (48426) */ - 3343, /* BD2B (48427) */ - 3343, /* BD2C (48428) */ - 3343, /* BD2D (48429) */ - 3343, /* BD2E (48430) */ - 3343, /* BD2F (48431) */ - 3343, /* BD30 (48432) */ - 3343, /* BD31 (48433) */ - 3343, /* BD32 (48434) */ - 3343, /* BD33 (48435) */ - 3343, /* BD34 (48436) */ - 3343, /* BD35 (48437) */ - 3343, /* BD36 (48438) */ - 3343, /* BD37 (48439) */ - 3343, /* BD38 (48440) */ - 3343, /* BD39 (48441) */ - 3343, /* BD3A (48442) */ - 3343, /* BD3B (48443) */ - 3343, /* BD3C (48444) */ - 3343, /* BD3D (48445) */ - 3343, /* BD3E (48446) */ - 3343, /* BD3F (48447) */ - 3343, /* BD40 (48448) */ - 3343, /* BD41 (48449) */ - 3343, /* BD42 (48450) */ - 3343, /* BD43 (48451) */ - 3343, /* BD44 (48452) */ - 3343, /* BD45 (48453) */ - 3343, /* BD46 (48454) */ - 3343, /* BD47 (48455) */ - 3343, /* BD48 (48456) */ - 3343, /* BD49 (48457) */ - 3343, /* BD4A (48458) */ - 3343, /* BD4B (48459) */ - 3343, /* BD4C (48460) */ - 3343, /* BD4D (48461) */ - 3343, /* BD4E (48462) */ - 3343, /* BD4F (48463) */ - 3343, /* BD50 (48464) */ - 3343, /* BD51 (48465) */ - 3343, /* BD52 (48466) */ - 3343, /* BD53 (48467) */ - 3343, /* BD54 (48468) */ - 3343, /* BD55 (48469) */ - 3343, /* BD56 (48470) */ - 3343, /* BD57 (48471) */ - 3343, /* BD58 (48472) */ - 3343, /* BD59 (48473) */ - 3343, /* BD5A (48474) */ - 3343, /* BD5B (48475) */ - 3343, /* BD5C (48476) */ - 3343, /* BD5D (48477) */ - 3343, /* BD5E (48478) */ - 3343, /* BD5F (48479) */ - 3343, /* BD60 (48480) */ - 3343, /* BD61 (48481) */ - 3343, /* BD62 (48482) */ - 3343, /* BD63 (48483) */ - 3343, /* BD64 (48484) */ - 3343, /* BD65 (48485) */ - 3343, /* BD66 (48486) */ - 3343, /* BD67 (48487) */ - 3343, /* BD68 (48488) */ - 3343, /* BD69 (48489) */ - 3343, /* BD6A (48490) */ - 3343, /* BD6B (48491) */ - 3343, /* BD6C (48492) */ - 3343, /* BD6D (48493) */ - 3343, /* BD6E (48494) */ - 3343, /* BD6F (48495) */ - 3343, /* BD70 (48496) */ - 3343, /* BD71 (48497) */ - 3343, /* BD72 (48498) */ - 3343, /* BD73 (48499) */ - 3343, /* BD74 (48500) */ - 3343, /* BD75 (48501) */ - 3343, /* BD76 (48502) */ - 3343, /* BD77 (48503) */ - 3343, /* BD78 (48504) */ - 3343, /* BD79 (48505) */ - 3343, /* BD7A (48506) */ - 3343, /* BD7B (48507) */ - 3343, /* BD7C (48508) */ - 3343, /* BD7D (48509) */ - 3343, /* BD7E (48510) */ - 3343, /* BD7F (48511) */ - 3343, /* BD80 (48512) */ - 3343, /* BD81 (48513) */ - 3343, /* BD82 (48514) */ - 3343, /* BD83 (48515) */ - 3343, /* BD84 (48516) */ - 3343, /* BD85 (48517) */ - 3343, /* BD86 (48518) */ - 3343, /* BD87 (48519) */ - 3343, /* BD88 (48520) */ - 3343, /* BD89 (48521) */ - 3343, /* BD8A (48522) */ - 3343, /* BD8B (48523) */ - 3343, /* BD8C (48524) */ - 3343, /* BD8D (48525) */ - 3343, /* BD8E (48526) */ - 3343, /* BD8F (48527) */ - 3343, /* BD90 (48528) */ - 3343, /* BD91 (48529) */ - 3343, /* BD92 (48530) */ - 3343, /* BD93 (48531) */ - 3343, /* BD94 (48532) */ - 3343, /* BD95 (48533) */ - 3343, /* BD96 (48534) */ - 3343, /* BD97 (48535) */ - 3343, /* BD98 (48536) */ - 3343, /* BD99 (48537) */ - 3343, /* BD9A (48538) */ - 3343, /* BD9B (48539) */ - 3343, /* BD9C (48540) */ - 3343, /* BD9D (48541) */ - 3343, /* BD9E (48542) */ - 3343, /* BD9F (48543) */ - 3343, /* BDA0 (48544) */ - 3343, /* BDA1 (48545) */ - 3343, /* BDA2 (48546) */ - 3343, /* BDA3 (48547) */ - 3343, /* BDA4 (48548) */ - 3343, /* BDA5 (48549) */ - 3343, /* BDA6 (48550) */ - 3343, /* BDA7 (48551) */ - 3343, /* BDA8 (48552) */ - 3343, /* BDA9 (48553) */ - 3343, /* BDAA (48554) */ - 3343, /* BDAB (48555) */ - 3343, /* BDAC (48556) */ - 3343, /* BDAD (48557) */ - 3343, /* BDAE (48558) */ - 3343, /* BDAF (48559) */ - 3343, /* BDB0 (48560) */ - 3343, /* BDB1 (48561) */ - 3343, /* BDB2 (48562) */ - 3343, /* BDB3 (48563) */ - 3343, /* BDB4 (48564) */ - 3343, /* BDB5 (48565) */ - 3343, /* BDB6 (48566) */ - 3343, /* BDB7 (48567) */ - 3343, /* BDB8 (48568) */ - 3343, /* BDB9 (48569) */ - 3343, /* BDBA (48570) */ - 3343, /* BDBB (48571) */ - 3343, /* BDBC (48572) */ - 3343, /* BDBD (48573) */ - 3343, /* BDBE (48574) */ - 3343, /* BDBF (48575) */ - 3343, /* BDC0 (48576) */ - 3343, /* BDC1 (48577) */ - 3343, /* BDC2 (48578) */ - 3343, /* BDC3 (48579) */ - 3343, /* BDC4 (48580) */ - 3343, /* BDC5 (48581) */ - 3343, /* BDC6 (48582) */ - 3343, /* BDC7 (48583) */ - 3343, /* BDC8 (48584) */ - 3343, /* BDC9 (48585) */ - 3343, /* BDCA (48586) */ - 3343, /* BDCB (48587) */ - 3343, /* BDCC (48588) */ - 3343, /* BDCD (48589) */ - 3343, /* BDCE (48590) */ - 3343, /* BDCF (48591) */ - 3343, /* BDD0 (48592) */ - 3343, /* BDD1 (48593) */ - 3343, /* BDD2 (48594) */ - 3343, /* BDD3 (48595) */ - 3343, /* BDD4 (48596) */ - 3343, /* BDD5 (48597) */ - 3343, /* BDD6 (48598) */ - 3343, /* BDD7 (48599) */ - 3343, /* BDD8 (48600) */ - 3343, /* BDD9 (48601) */ - 3343, /* BDDA (48602) */ - 3343, /* BDDB (48603) */ - 3343, /* BDDC (48604) */ - 3343, /* BDDD (48605) */ - 3343, /* BDDE (48606) */ - 3343, /* BDDF (48607) */ - 3343, /* BDE0 (48608) */ - 3343, /* BDE1 (48609) */ - 3343, /* BDE2 (48610) */ - 3343, /* BDE3 (48611) */ - 3343, /* BDE4 (48612) */ - 3343, /* BDE5 (48613) */ - 3343, /* BDE6 (48614) */ - 3343, /* BDE7 (48615) */ - 3343, /* BDE8 (48616) */ - 3343, /* BDE9 (48617) */ - 3343, /* BDEA (48618) */ - 3343, /* BDEB (48619) */ - 3343, /* BDEC (48620) */ - 3343, /* BDED (48621) */ - 3343, /* BDEE (48622) */ - 3343, /* BDEF (48623) */ - 3343, /* BDF0 (48624) */ - 3343, /* BDF1 (48625) */ - 3343, /* BDF2 (48626) */ - 3343, /* BDF3 (48627) */ - 3343, /* BDF4 (48628) */ - 3343, /* BDF5 (48629) */ - 3343, /* BDF6 (48630) */ - 3343, /* BDF7 (48631) */ - 3343, /* BDF8 (48632) */ - 3343, /* BDF9 (48633) */ - 3343, /* BDFA (48634) */ - 3343, /* BDFB (48635) */ - 3343, /* BDFC (48636) */ - 3343, /* BDFD (48637) */ - 3343, /* BDFE (48638) */ - 3343, /* BDFF (48639) */ - 3343, /* BE00 (48640) */ - 3343, /* BE01 (48641) */ - 3343, /* BE02 (48642) */ - 3343, /* BE03 (48643) */ - 3343, /* BE04 (48644) */ - 3343, /* BE05 (48645) */ - 3343, /* BE06 (48646) */ - 3343, /* BE07 (48647) */ - 3343, /* BE08 (48648) */ - 3343, /* BE09 (48649) */ - 3343, /* BE0A (48650) */ - 3343, /* BE0B (48651) */ - 3343, /* BE0C (48652) */ - 3343, /* BE0D (48653) */ - 3343, /* BE0E (48654) */ - 3343, /* BE0F (48655) */ - 3343, /* BE10 (48656) */ - 3343, /* BE11 (48657) */ - 3343, /* BE12 (48658) */ - 3343, /* BE13 (48659) */ - 3343, /* BE14 (48660) */ - 3343, /* BE15 (48661) */ - 3343, /* BE16 (48662) */ - 3343, /* BE17 (48663) */ - 3343, /* BE18 (48664) */ - 3343, /* BE19 (48665) */ - 3343, /* BE1A (48666) */ - 3343, /* BE1B (48667) */ - 3343, /* BE1C (48668) */ - 3343, /* BE1D (48669) */ - 3343, /* BE1E (48670) */ - 3343, /* BE1F (48671) */ - 3343, /* BE20 (48672) */ - 3343, /* BE21 (48673) */ - 3343, /* BE22 (48674) */ - 3343, /* BE23 (48675) */ - 3343, /* BE24 (48676) */ - 3343, /* BE25 (48677) */ - 3343, /* BE26 (48678) */ - 3343, /* BE27 (48679) */ - 3343, /* BE28 (48680) */ - 3343, /* BE29 (48681) */ - 3343, /* BE2A (48682) */ - 3343, /* BE2B (48683) */ - 3343, /* BE2C (48684) */ - 3343, /* BE2D (48685) */ - 3343, /* BE2E (48686) */ - 3343, /* BE2F (48687) */ - 3343, /* BE30 (48688) */ - 3343, /* BE31 (48689) */ - 3343, /* BE32 (48690) */ - 3343, /* BE33 (48691) */ - 3343, /* BE34 (48692) */ - 3343, /* BE35 (48693) */ - 3343, /* BE36 (48694) */ - 3343, /* BE37 (48695) */ - 3343, /* BE38 (48696) */ - 3343, /* BE39 (48697) */ - 3343, /* BE3A (48698) */ - 3343, /* BE3B (48699) */ - 3343, /* BE3C (48700) */ - 3343, /* BE3D (48701) */ - 3343, /* BE3E (48702) */ - 3343, /* BE3F (48703) */ - 3343, /* BE40 (48704) */ - 3343, /* BE41 (48705) */ - 3343, /* BE42 (48706) */ - 3343, /* BE43 (48707) */ - 3343, /* BE44 (48708) */ - 3343, /* BE45 (48709) */ - 3343, /* BE46 (48710) */ - 3343, /* BE47 (48711) */ - 3343, /* BE48 (48712) */ - 3343, /* BE49 (48713) */ - 3343, /* BE4A (48714) */ - 3343, /* BE4B (48715) */ - 3343, /* BE4C (48716) */ - 3343, /* BE4D (48717) */ - 3343, /* BE4E (48718) */ - 3343, /* BE4F (48719) */ - 3343, /* BE50 (48720) */ - 3343, /* BE51 (48721) */ - 3343, /* BE52 (48722) */ - 3343, /* BE53 (48723) */ - 3343, /* BE54 (48724) */ - 3343, /* BE55 (48725) */ - 3343, /* BE56 (48726) */ - 3343, /* BE57 (48727) */ - 3343, /* BE58 (48728) */ - 3343, /* BE59 (48729) */ - 3343, /* BE5A (48730) */ - 3343, /* BE5B (48731) */ - 3343, /* BE5C (48732) */ - 3343, /* BE5D (48733) */ - 3343, /* BE5E (48734) */ - 3343, /* BE5F (48735) */ - 3343, /* BE60 (48736) */ - 3343, /* BE61 (48737) */ - 3343, /* BE62 (48738) */ - 3343, /* BE63 (48739) */ - 3343, /* BE64 (48740) */ - 3343, /* BE65 (48741) */ - 3343, /* BE66 (48742) */ - 3343, /* BE67 (48743) */ - 3343, /* BE68 (48744) */ - 3343, /* BE69 (48745) */ - 3343, /* BE6A (48746) */ - 3343, /* BE6B (48747) */ - 3343, /* BE6C (48748) */ - 3343, /* BE6D (48749) */ - 3343, /* BE6E (48750) */ - 3343, /* BE6F (48751) */ - 3343, /* BE70 (48752) */ - 3343, /* BE71 (48753) */ - 3343, /* BE72 (48754) */ - 3343, /* BE73 (48755) */ - 3343, /* BE74 (48756) */ - 3343, /* BE75 (48757) */ - 3343, /* BE76 (48758) */ - 3343, /* BE77 (48759) */ - 3343, /* BE78 (48760) */ - 3343, /* BE79 (48761) */ - 3343, /* BE7A (48762) */ - 3343, /* BE7B (48763) */ - 3343, /* BE7C (48764) */ - 3343, /* BE7D (48765) */ - 3343, /* BE7E (48766) */ - 3343, /* BE7F (48767) */ - 3343, /* BE80 (48768) */ - 3343, /* BE81 (48769) */ - 3343, /* BE82 (48770) */ - 3343, /* BE83 (48771) */ - 3343, /* BE84 (48772) */ - 3343, /* BE85 (48773) */ - 3343, /* BE86 (48774) */ - 3343, /* BE87 (48775) */ - 3343, /* BE88 (48776) */ - 3343, /* BE89 (48777) */ - 3343, /* BE8A (48778) */ - 3343, /* BE8B (48779) */ - 3343, /* BE8C (48780) */ - 3343, /* BE8D (48781) */ - 3343, /* BE8E (48782) */ - 3343, /* BE8F (48783) */ - 3343, /* BE90 (48784) */ - 3343, /* BE91 (48785) */ - 3343, /* BE92 (48786) */ - 3343, /* BE93 (48787) */ - 3343, /* BE94 (48788) */ - 3343, /* BE95 (48789) */ - 3343, /* BE96 (48790) */ - 3343, /* BE97 (48791) */ - 3343, /* BE98 (48792) */ - 3343, /* BE99 (48793) */ - 3343, /* BE9A (48794) */ - 3343, /* BE9B (48795) */ - 3343, /* BE9C (48796) */ - 3343, /* BE9D (48797) */ - 3343, /* BE9E (48798) */ - 3343, /* BE9F (48799) */ - 3343, /* BEA0 (48800) */ - 3343, /* BEA1 (48801) */ - 3343, /* BEA2 (48802) */ - 3343, /* BEA3 (48803) */ - 3343, /* BEA4 (48804) */ - 3343, /* BEA5 (48805) */ - 3343, /* BEA6 (48806) */ - 3343, /* BEA7 (48807) */ - 3343, /* BEA8 (48808) */ - 3343, /* BEA9 (48809) */ - 3343, /* BEAA (48810) */ - 3343, /* BEAB (48811) */ - 3343, /* BEAC (48812) */ - 3343, /* BEAD (48813) */ - 3343, /* BEAE (48814) */ - 3343, /* BEAF (48815) */ - 3343, /* BEB0 (48816) */ - 3343, /* BEB1 (48817) */ - 3343, /* BEB2 (48818) */ - 3343, /* BEB3 (48819) */ - 3343, /* BEB4 (48820) */ - 3343, /* BEB5 (48821) */ - 3343, /* BEB6 (48822) */ - 3343, /* BEB7 (48823) */ - 3343, /* BEB8 (48824) */ - 3343, /* BEB9 (48825) */ - 3343, /* BEBA (48826) */ - 3343, /* BEBB (48827) */ - 3343, /* BEBC (48828) */ - 3343, /* BEBD (48829) */ - 3343, /* BEBE (48830) */ - 3343, /* BEBF (48831) */ - 3343, /* BEC0 (48832) */ - 3343, /* BEC1 (48833) */ - 3343, /* BEC2 (48834) */ - 3343, /* BEC3 (48835) */ - 3343, /* BEC4 (48836) */ - 3343, /* BEC5 (48837) */ - 3343, /* BEC6 (48838) */ - 3343, /* BEC7 (48839) */ - 3343, /* BEC8 (48840) */ - 3343, /* BEC9 (48841) */ - 3343, /* BECA (48842) */ - 3343, /* BECB (48843) */ - 3343, /* BECC (48844) */ - 3343, /* BECD (48845) */ - 3343, /* BECE (48846) */ - 3343, /* BECF (48847) */ - 3343, /* BED0 (48848) */ - 3343, /* BED1 (48849) */ - 3343, /* BED2 (48850) */ - 3343, /* BED3 (48851) */ - 3343, /* BED4 (48852) */ - 3343, /* BED5 (48853) */ - 3343, /* BED6 (48854) */ - 3343, /* BED7 (48855) */ - 3343, /* BED8 (48856) */ - 3343, /* BED9 (48857) */ - 3343, /* BEDA (48858) */ - 3343, /* BEDB (48859) */ - 3343, /* BEDC (48860) */ - 3343, /* BEDD (48861) */ - 3343, /* BEDE (48862) */ - 3343, /* BEDF (48863) */ - 3343, /* BEE0 (48864) */ - 3343, /* BEE1 (48865) */ - 3343, /* BEE2 (48866) */ - 3343, /* BEE3 (48867) */ - 3343, /* BEE4 (48868) */ - 3343, /* BEE5 (48869) */ - 3343, /* BEE6 (48870) */ - 3343, /* BEE7 (48871) */ - 3343, /* BEE8 (48872) */ - 3343, /* BEE9 (48873) */ - 3343, /* BEEA (48874) */ - 3343, /* BEEB (48875) */ - 3343, /* BEEC (48876) */ - 3343, /* BEED (48877) */ - 3343, /* BEEE (48878) */ - 3343, /* BEEF (48879) */ - 3343, /* BEF0 (48880) */ - 3343, /* BEF1 (48881) */ - 3343, /* BEF2 (48882) */ - 3343, /* BEF3 (48883) */ - 3343, /* BEF4 (48884) */ - 3343, /* BEF5 (48885) */ - 3343, /* BEF6 (48886) */ - 3343, /* BEF7 (48887) */ - 3343, /* BEF8 (48888) */ - 3343, /* BEF9 (48889) */ - 3343, /* BEFA (48890) */ - 3343, /* BEFB (48891) */ - 3343, /* BEFC (48892) */ - 3343, /* BEFD (48893) */ - 3343, /* BEFE (48894) */ - 3343, /* BEFF (48895) */ - 3343, /* BF00 (48896) */ - 3343, /* BF01 (48897) */ - 3343, /* BF02 (48898) */ - 3343, /* BF03 (48899) */ - 3343, /* BF04 (48900) */ - 3343, /* BF05 (48901) */ - 3343, /* BF06 (48902) */ - 3343, /* BF07 (48903) */ - 3343, /* BF08 (48904) */ - 3343, /* BF09 (48905) */ - 3343, /* BF0A (48906) */ - 3343, /* BF0B (48907) */ - 3343, /* BF0C (48908) */ - 3343, /* BF0D (48909) */ - 3343, /* BF0E (48910) */ - 3343, /* BF0F (48911) */ - 3343, /* BF10 (48912) */ - 3343, /* BF11 (48913) */ - 3343, /* BF12 (48914) */ - 3343, /* BF13 (48915) */ - 3343, /* BF14 (48916) */ - 3343, /* BF15 (48917) */ - 3343, /* BF16 (48918) */ - 3343, /* BF17 (48919) */ - 3343, /* BF18 (48920) */ - 3343, /* BF19 (48921) */ - 3343, /* BF1A (48922) */ - 3343, /* BF1B (48923) */ - 3343, /* BF1C (48924) */ - 3343, /* BF1D (48925) */ - 3343, /* BF1E (48926) */ - 3343, /* BF1F (48927) */ - 3343, /* BF20 (48928) */ - 3343, /* BF21 (48929) */ - 3343, /* BF22 (48930) */ - 3343, /* BF23 (48931) */ - 3343, /* BF24 (48932) */ - 3343, /* BF25 (48933) */ - 3343, /* BF26 (48934) */ - 3343, /* BF27 (48935) */ - 3343, /* BF28 (48936) */ - 3343, /* BF29 (48937) */ - 3343, /* BF2A (48938) */ - 3343, /* BF2B (48939) */ - 3343, /* BF2C (48940) */ - 3343, /* BF2D (48941) */ - 3343, /* BF2E (48942) */ - 3343, /* BF2F (48943) */ - 3343, /* BF30 (48944) */ - 3343, /* BF31 (48945) */ - 3343, /* BF32 (48946) */ - 3343, /* BF33 (48947) */ - 3343, /* BF34 (48948) */ - 3343, /* BF35 (48949) */ - 3343, /* BF36 (48950) */ - 3343, /* BF37 (48951) */ - 3343, /* BF38 (48952) */ - 3343, /* BF39 (48953) */ - 3343, /* BF3A (48954) */ - 3343, /* BF3B (48955) */ - 3343, /* BF3C (48956) */ - 3343, /* BF3D (48957) */ - 3343, /* BF3E (48958) */ - 3343, /* BF3F (48959) */ - 3343, /* BF40 (48960) */ - 3343, /* BF41 (48961) */ - 3343, /* BF42 (48962) */ - 3343, /* BF43 (48963) */ - 3343, /* BF44 (48964) */ - 3343, /* BF45 (48965) */ - 3343, /* BF46 (48966) */ - 3343, /* BF47 (48967) */ - 3343, /* BF48 (48968) */ - 3343, /* BF49 (48969) */ - 3343, /* BF4A (48970) */ - 3343, /* BF4B (48971) */ - 3343, /* BF4C (48972) */ - 3343, /* BF4D (48973) */ - 3343, /* BF4E (48974) */ - 3343, /* BF4F (48975) */ - 3343, /* BF50 (48976) */ - 3343, /* BF51 (48977) */ - 3343, /* BF52 (48978) */ - 3343, /* BF53 (48979) */ - 3343, /* BF54 (48980) */ - 3343, /* BF55 (48981) */ - 3343, /* BF56 (48982) */ - 3343, /* BF57 (48983) */ - 3343, /* BF58 (48984) */ - 3343, /* BF59 (48985) */ - 3343, /* BF5A (48986) */ - 3343, /* BF5B (48987) */ - 3343, /* BF5C (48988) */ - 3343, /* BF5D (48989) */ - 3343, /* BF5E (48990) */ - 3343, /* BF5F (48991) */ - 3343, /* BF60 (48992) */ - 3343, /* BF61 (48993) */ - 3343, /* BF62 (48994) */ - 3343, /* BF63 (48995) */ - 3343, /* BF64 (48996) */ - 3343, /* BF65 (48997) */ - 3343, /* BF66 (48998) */ - 3343, /* BF67 (48999) */ - 3343, /* BF68 (49000) */ - 3343, /* BF69 (49001) */ - 3343, /* BF6A (49002) */ - 3343, /* BF6B (49003) */ - 3343, /* BF6C (49004) */ - 3343, /* BF6D (49005) */ - 3343, /* BF6E (49006) */ - 3343, /* BF6F (49007) */ - 3343, /* BF70 (49008) */ - 3343, /* BF71 (49009) */ - 3343, /* BF72 (49010) */ - 3343, /* BF73 (49011) */ - 3343, /* BF74 (49012) */ - 3343, /* BF75 (49013) */ - 3343, /* BF76 (49014) */ - 3343, /* BF77 (49015) */ - 3343, /* BF78 (49016) */ - 3343, /* BF79 (49017) */ - 3343, /* BF7A (49018) */ - 3343, /* BF7B (49019) */ - 3343, /* BF7C (49020) */ - 3343, /* BF7D (49021) */ - 3343, /* BF7E (49022) */ - 3343, /* BF7F (49023) */ - 3343, /* BF80 (49024) */ - 3343, /* BF81 (49025) */ - 3343, /* BF82 (49026) */ - 3343, /* BF83 (49027) */ - 3343, /* BF84 (49028) */ - 3343, /* BF85 (49029) */ - 3343, /* BF86 (49030) */ - 3343, /* BF87 (49031) */ - 3343, /* BF88 (49032) */ - 3343, /* BF89 (49033) */ - 3343, /* BF8A (49034) */ - 3343, /* BF8B (49035) */ - 3343, /* BF8C (49036) */ - 3343, /* BF8D (49037) */ - 3343, /* BF8E (49038) */ - 3343, /* BF8F (49039) */ - 3343, /* BF90 (49040) */ - 3343, /* BF91 (49041) */ - 3343, /* BF92 (49042) */ - 3343, /* BF93 (49043) */ - 3343, /* BF94 (49044) */ - 3343, /* BF95 (49045) */ - 3343, /* BF96 (49046) */ - 3343, /* BF97 (49047) */ - 3343, /* BF98 (49048) */ - 3343, /* BF99 (49049) */ - 3343, /* BF9A (49050) */ - 3343, /* BF9B (49051) */ - 3343, /* BF9C (49052) */ - 3343, /* BF9D (49053) */ - 3343, /* BF9E (49054) */ - 3343, /* BF9F (49055) */ - 3343, /* BFA0 (49056) */ - 3343, /* BFA1 (49057) */ - 3343, /* BFA2 (49058) */ - 3343, /* BFA3 (49059) */ - 3343, /* BFA4 (49060) */ - 3343, /* BFA5 (49061) */ - 3343, /* BFA6 (49062) */ - 3343, /* BFA7 (49063) */ - 3343, /* BFA8 (49064) */ - 3343, /* BFA9 (49065) */ - 3343, /* BFAA (49066) */ - 3343, /* BFAB (49067) */ - 3343, /* BFAC (49068) */ - 3343, /* BFAD (49069) */ - 3343, /* BFAE (49070) */ - 3343, /* BFAF (49071) */ - 3343, /* BFB0 (49072) */ - 3343, /* BFB1 (49073) */ - 3343, /* BFB2 (49074) */ - 3343, /* BFB3 (49075) */ - 3343, /* BFB4 (49076) */ - 3343, /* BFB5 (49077) */ - 3343, /* BFB6 (49078) */ - 3343, /* BFB7 (49079) */ - 3343, /* BFB8 (49080) */ - 3343, /* BFB9 (49081) */ - 3343, /* BFBA (49082) */ - 3343, /* BFBB (49083) */ - 3343, /* BFBC (49084) */ - 3343, /* BFBD (49085) */ - 3343, /* BFBE (49086) */ - 3343, /* BFBF (49087) */ - 3343, /* BFC0 (49088) */ - 3343, /* BFC1 (49089) */ - 3343, /* BFC2 (49090) */ - 3343, /* BFC3 (49091) */ - 3343, /* BFC4 (49092) */ - 3343, /* BFC5 (49093) */ - 3343, /* BFC6 (49094) */ - 3343, /* BFC7 (49095) */ - 3343, /* BFC8 (49096) */ - 3343, /* BFC9 (49097) */ - 3343, /* BFCA (49098) */ - 3343, /* BFCB (49099) */ - 3343, /* BFCC (49100) */ - 3343, /* BFCD (49101) */ - 3343, /* BFCE (49102) */ - 3343, /* BFCF (49103) */ - 3343, /* BFD0 (49104) */ - 3343, /* BFD1 (49105) */ - 3343, /* BFD2 (49106) */ - 3343, /* BFD3 (49107) */ - 3343, /* BFD4 (49108) */ - 3343, /* BFD5 (49109) */ - 3343, /* BFD6 (49110) */ - 3343, /* BFD7 (49111) */ - 3343, /* BFD8 (49112) */ - 3343, /* BFD9 (49113) */ - 3343, /* BFDA (49114) */ - 3343, /* BFDB (49115) */ - 3343, /* BFDC (49116) */ - 3343, /* BFDD (49117) */ - 3343, /* BFDE (49118) */ - 3343, /* BFDF (49119) */ - 3343, /* BFE0 (49120) */ - 3343, /* BFE1 (49121) */ - 3343, /* BFE2 (49122) */ - 3343, /* BFE3 (49123) */ - 3343, /* BFE4 (49124) */ - 3343, /* BFE5 (49125) */ - 3343, /* BFE6 (49126) */ - 3343, /* BFE7 (49127) */ - 3343, /* BFE8 (49128) */ - 3343, /* BFE9 (49129) */ - 3343, /* BFEA (49130) */ - 3343, /* BFEB (49131) */ - 3343, /* BFEC (49132) */ - 3343, /* BFED (49133) */ - 3343, /* BFEE (49134) */ - 3343, /* BFEF (49135) */ - 3343, /* BFF0 (49136) */ - 3343, /* BFF1 (49137) */ - 3343, /* BFF2 (49138) */ - 3343, /* BFF3 (49139) */ - 3343, /* BFF4 (49140) */ - 3343, /* BFF5 (49141) */ - 3343, /* BFF6 (49142) */ - 3343, /* BFF7 (49143) */ - 3343, /* BFF8 (49144) */ - 3343, /* BFF9 (49145) */ - 3343, /* BFFA (49146) */ - 3343, /* BFFB (49147) */ - 3343, /* BFFC (49148) */ - 3343, /* BFFD (49149) */ - 3343, /* BFFE (49150) */ - 3343, /* BFFF (49151) */ - 3343, /* C000 (49152) */ - 3343, /* C001 (49153) */ - 3343, /* C002 (49154) */ - 3343, /* C003 (49155) */ - 3343, /* C004 (49156) */ - 3343, /* C005 (49157) */ - 3343, /* C006 (49158) */ - 3343, /* C007 (49159) */ - 3343, /* C008 (49160) */ - 3343, /* C009 (49161) */ - 3343, /* C00A (49162) */ - 3343, /* C00B (49163) */ - 3343, /* C00C (49164) */ - 3343, /* C00D (49165) */ - 3343, /* C00E (49166) */ - 3343, /* C00F (49167) */ - 3343, /* C010 (49168) */ - 3343, /* C011 (49169) */ - 3343, /* C012 (49170) */ - 3343, /* C013 (49171) */ - 3343, /* C014 (49172) */ - 3343, /* C015 (49173) */ - 3343, /* C016 (49174) */ - 3343, /* C017 (49175) */ - 3343, /* C018 (49176) */ - 3343, /* C019 (49177) */ - 3343, /* C01A (49178) */ - 3343, /* C01B (49179) */ - 3343, /* C01C (49180) */ - 3343, /* C01D (49181) */ - 3343, /* C01E (49182) */ - 3343, /* C01F (49183) */ - 3343, /* C020 (49184) */ - 3343, /* C021 (49185) */ - 3343, /* C022 (49186) */ - 3343, /* C023 (49187) */ - 3343, /* C024 (49188) */ - 3343, /* C025 (49189) */ - 3343, /* C026 (49190) */ - 3343, /* C027 (49191) */ - 3343, /* C028 (49192) */ - 3343, /* C029 (49193) */ - 3343, /* C02A (49194) */ - 3343, /* C02B (49195) */ - 3343, /* C02C (49196) */ - 3343, /* C02D (49197) */ - 3343, /* C02E (49198) */ - 3343, /* C02F (49199) */ - 3343, /* C030 (49200) */ - 3343, /* C031 (49201) */ - 3343, /* C032 (49202) */ - 3343, /* C033 (49203) */ - 3343, /* C034 (49204) */ - 3343, /* C035 (49205) */ - 3343, /* C036 (49206) */ - 3343, /* C037 (49207) */ - 3343, /* C038 (49208) */ - 3343, /* C039 (49209) */ - 3343, /* C03A (49210) */ - 3343, /* C03B (49211) */ - 3343, /* C03C (49212) */ - 3343, /* C03D (49213) */ - 3343, /* C03E (49214) */ - 3343, /* C03F (49215) */ - 3343, /* C040 (49216) */ - 3343, /* C041 (49217) */ - 3343, /* C042 (49218) */ - 3343, /* C043 (49219) */ - 3343, /* C044 (49220) */ - 3343, /* C045 (49221) */ - 3343, /* C046 (49222) */ - 3343, /* C047 (49223) */ - 3343, /* C048 (49224) */ - 3343, /* C049 (49225) */ - 3343, /* C04A (49226) */ - 3343, /* C04B (49227) */ - 3343, /* C04C (49228) */ - 3343, /* C04D (49229) */ - 3343, /* C04E (49230) */ - 3343, /* C04F (49231) */ - 3343, /* C050 (49232) */ - 3343, /* C051 (49233) */ - 3343, /* C052 (49234) */ - 3343, /* C053 (49235) */ - 3343, /* C054 (49236) */ - 3343, /* C055 (49237) */ - 3343, /* C056 (49238) */ - 3343, /* C057 (49239) */ - 3343, /* C058 (49240) */ - 3343, /* C059 (49241) */ - 3343, /* C05A (49242) */ - 3343, /* C05B (49243) */ - 3343, /* C05C (49244) */ - 3343, /* C05D (49245) */ - 3343, /* C05E (49246) */ - 3343, /* C05F (49247) */ - 3343, /* C060 (49248) */ - 3343, /* C061 (49249) */ - 3343, /* C062 (49250) */ - 3343, /* C063 (49251) */ - 3343, /* C064 (49252) */ - 3343, /* C065 (49253) */ - 3343, /* C066 (49254) */ - 3343, /* C067 (49255) */ - 3343, /* C068 (49256) */ - 3343, /* C069 (49257) */ - 3343, /* C06A (49258) */ - 3343, /* C06B (49259) */ - 3343, /* C06C (49260) */ - 3343, /* C06D (49261) */ - 3343, /* C06E (49262) */ - 3343, /* C06F (49263) */ - 3343, /* C070 (49264) */ - 3343, /* C071 (49265) */ - 3343, /* C072 (49266) */ - 3343, /* C073 (49267) */ - 3343, /* C074 (49268) */ - 3343, /* C075 (49269) */ - 3343, /* C076 (49270) */ - 3343, /* C077 (49271) */ - 3343, /* C078 (49272) */ - 3343, /* C079 (49273) */ - 3343, /* C07A (49274) */ - 3343, /* C07B (49275) */ - 3343, /* C07C (49276) */ - 3343, /* C07D (49277) */ - 3343, /* C07E (49278) */ - 3343, /* C07F (49279) */ - 3343, /* C080 (49280) */ - 3343, /* C081 (49281) */ - 3343, /* C082 (49282) */ - 3343, /* C083 (49283) */ - 3343, /* C084 (49284) */ - 3343, /* C085 (49285) */ - 3343, /* C086 (49286) */ - 3343, /* C087 (49287) */ - 3343, /* C088 (49288) */ - 3343, /* C089 (49289) */ - 3343, /* C08A (49290) */ - 3343, /* C08B (49291) */ - 3343, /* C08C (49292) */ - 3343, /* C08D (49293) */ - 3343, /* C08E (49294) */ - 3343, /* C08F (49295) */ - 3343, /* C090 (49296) */ - 3343, /* C091 (49297) */ - 3343, /* C092 (49298) */ - 3343, /* C093 (49299) */ - 3343, /* C094 (49300) */ - 3343, /* C095 (49301) */ - 3343, /* C096 (49302) */ - 3343, /* C097 (49303) */ - 3343, /* C098 (49304) */ - 3343, /* C099 (49305) */ - 3343, /* C09A (49306) */ - 3343, /* C09B (49307) */ - 3343, /* C09C (49308) */ - 3343, /* C09D (49309) */ - 3343, /* C09E (49310) */ - 3343, /* C09F (49311) */ - 3343, /* C0A0 (49312) */ - 3343, /* C0A1 (49313) */ - 3343, /* C0A2 (49314) */ - 3343, /* C0A3 (49315) */ - 3343, /* C0A4 (49316) */ - 3343, /* C0A5 (49317) */ - 3343, /* C0A6 (49318) */ - 3343, /* C0A7 (49319) */ - 3343, /* C0A8 (49320) */ - 3343, /* C0A9 (49321) */ - 3343, /* C0AA (49322) */ - 3343, /* C0AB (49323) */ - 3343, /* C0AC (49324) */ - 3343, /* C0AD (49325) */ - 3343, /* C0AE (49326) */ - 3343, /* C0AF (49327) */ - 3343, /* C0B0 (49328) */ - 3343, /* C0B1 (49329) */ - 3343, /* C0B2 (49330) */ - 3343, /* C0B3 (49331) */ - 3343, /* C0B4 (49332) */ - 3343, /* C0B5 (49333) */ - 3343, /* C0B6 (49334) */ - 3343, /* C0B7 (49335) */ - 3343, /* C0B8 (49336) */ - 3343, /* C0B9 (49337) */ - 3343, /* C0BA (49338) */ - 3343, /* C0BB (49339) */ - 3343, /* C0BC (49340) */ - 3343, /* C0BD (49341) */ - 3343, /* C0BE (49342) */ - 3343, /* C0BF (49343) */ - 3343, /* C0C0 (49344) */ - 3343, /* C0C1 (49345) */ - 3343, /* C0C2 (49346) */ - 3343, /* C0C3 (49347) */ - 3343, /* C0C4 (49348) */ - 3343, /* C0C5 (49349) */ - 3343, /* C0C6 (49350) */ - 3343, /* C0C7 (49351) */ - 3343, /* C0C8 (49352) */ - 3343, /* C0C9 (49353) */ - 3343, /* C0CA (49354) */ - 3343, /* C0CB (49355) */ - 3343, /* C0CC (49356) */ - 3343, /* C0CD (49357) */ - 3343, /* C0CE (49358) */ - 3343, /* C0CF (49359) */ - 3343, /* C0D0 (49360) */ - 3343, /* C0D1 (49361) */ - 3343, /* C0D2 (49362) */ - 3343, /* C0D3 (49363) */ - 3343, /* C0D4 (49364) */ - 3343, /* C0D5 (49365) */ - 3343, /* C0D6 (49366) */ - 3343, /* C0D7 (49367) */ - 3343, /* C0D8 (49368) */ - 3343, /* C0D9 (49369) */ - 3343, /* C0DA (49370) */ - 3343, /* C0DB (49371) */ - 3343, /* C0DC (49372) */ - 3343, /* C0DD (49373) */ - 3343, /* C0DE (49374) */ - 3343, /* C0DF (49375) */ - 3343, /* C0E0 (49376) */ - 3343, /* C0E1 (49377) */ - 3343, /* C0E2 (49378) */ - 3343, /* C0E3 (49379) */ - 3343, /* C0E4 (49380) */ - 3343, /* C0E5 (49381) */ - 3343, /* C0E6 (49382) */ - 3343, /* C0E7 (49383) */ - 3343, /* C0E8 (49384) */ - 3343, /* C0E9 (49385) */ - 3343, /* C0EA (49386) */ - 3343, /* C0EB (49387) */ - 3343, /* C0EC (49388) */ - 3343, /* C0ED (49389) */ - 3343, /* C0EE (49390) */ - 3343, /* C0EF (49391) */ - 3343, /* C0F0 (49392) */ - 3343, /* C0F1 (49393) */ - 3343, /* C0F2 (49394) */ - 3343, /* C0F3 (49395) */ - 3343, /* C0F4 (49396) */ - 3343, /* C0F5 (49397) */ - 3343, /* C0F6 (49398) */ - 3343, /* C0F7 (49399) */ - 3343, /* C0F8 (49400) */ - 3343, /* C0F9 (49401) */ - 3343, /* C0FA (49402) */ - 3343, /* C0FB (49403) */ - 3343, /* C0FC (49404) */ - 3343, /* C0FD (49405) */ - 3343, /* C0FE (49406) */ - 3343, /* C0FF (49407) */ - 3343, /* C100 (49408) */ - 3343, /* C101 (49409) */ - 3343, /* C102 (49410) */ - 3343, /* C103 (49411) */ - 3343, /* C104 (49412) */ - 3343, /* C105 (49413) */ - 3343, /* C106 (49414) */ - 3343, /* C107 (49415) */ - 3343, /* C108 (49416) */ - 3343, /* C109 (49417) */ - 3343, /* C10A (49418) */ - 3343, /* C10B (49419) */ - 3343, /* C10C (49420) */ - 3343, /* C10D (49421) */ - 3343, /* C10E (49422) */ - 3343, /* C10F (49423) */ - 3343, /* C110 (49424) */ - 3343, /* C111 (49425) */ - 3343, /* C112 (49426) */ - 3343, /* C113 (49427) */ - 3343, /* C114 (49428) */ - 3343, /* C115 (49429) */ - 3343, /* C116 (49430) */ - 3343, /* C117 (49431) */ - 3343, /* C118 (49432) */ - 3343, /* C119 (49433) */ - 3343, /* C11A (49434) */ - 3343, /* C11B (49435) */ - 3343, /* C11C (49436) */ - 3343, /* C11D (49437) */ - 3343, /* C11E (49438) */ - 3343, /* C11F (49439) */ - 3343, /* C120 (49440) */ - 3343, /* C121 (49441) */ - 3343, /* C122 (49442) */ - 3343, /* C123 (49443) */ - 3343, /* C124 (49444) */ - 3343, /* C125 (49445) */ - 3343, /* C126 (49446) */ - 3343, /* C127 (49447) */ - 3343, /* C128 (49448) */ - 3343, /* C129 (49449) */ - 3343, /* C12A (49450) */ - 3343, /* C12B (49451) */ - 3343, /* C12C (49452) */ - 3343, /* C12D (49453) */ - 3343, /* C12E (49454) */ - 3343, /* C12F (49455) */ - 3343, /* C130 (49456) */ - 3343, /* C131 (49457) */ - 3343, /* C132 (49458) */ - 3343, /* C133 (49459) */ - 3343, /* C134 (49460) */ - 3343, /* C135 (49461) */ - 3343, /* C136 (49462) */ - 3343, /* C137 (49463) */ - 3343, /* C138 (49464) */ - 3343, /* C139 (49465) */ - 3343, /* C13A (49466) */ - 3343, /* C13B (49467) */ - 3343, /* C13C (49468) */ - 3343, /* C13D (49469) */ - 3343, /* C13E (49470) */ - 3343, /* C13F (49471) */ - 3343, /* C140 (49472) */ - 3343, /* C141 (49473) */ - 3343, /* C142 (49474) */ - 3343, /* C143 (49475) */ - 3343, /* C144 (49476) */ - 3343, /* C145 (49477) */ - 3343, /* C146 (49478) */ - 3343, /* C147 (49479) */ - 3343, /* C148 (49480) */ - 3343, /* C149 (49481) */ - 3343, /* C14A (49482) */ - 3343, /* C14B (49483) */ - 3343, /* C14C (49484) */ - 3343, /* C14D (49485) */ - 3343, /* C14E (49486) */ - 3343, /* C14F (49487) */ - 3343, /* C150 (49488) */ - 3343, /* C151 (49489) */ - 3343, /* C152 (49490) */ - 3343, /* C153 (49491) */ - 3343, /* C154 (49492) */ - 3343, /* C155 (49493) */ - 3343, /* C156 (49494) */ - 3343, /* C157 (49495) */ - 3343, /* C158 (49496) */ - 3343, /* C159 (49497) */ - 3343, /* C15A (49498) */ - 3343, /* C15B (49499) */ - 3343, /* C15C (49500) */ - 3343, /* C15D (49501) */ - 3343, /* C15E (49502) */ - 3343, /* C15F (49503) */ - 3343, /* C160 (49504) */ - 3343, /* C161 (49505) */ - 3343, /* C162 (49506) */ - 3343, /* C163 (49507) */ - 3343, /* C164 (49508) */ - 3343, /* C165 (49509) */ - 3343, /* C166 (49510) */ - 3343, /* C167 (49511) */ - 3343, /* C168 (49512) */ - 3343, /* C169 (49513) */ - 3343, /* C16A (49514) */ - 3343, /* C16B (49515) */ - 3343, /* C16C (49516) */ - 3343, /* C16D (49517) */ - 3343, /* C16E (49518) */ - 3343, /* C16F (49519) */ - 3343, /* C170 (49520) */ - 3343, /* C171 (49521) */ - 3343, /* C172 (49522) */ - 3343, /* C173 (49523) */ - 3343, /* C174 (49524) */ - 3343, /* C175 (49525) */ - 3343, /* C176 (49526) */ - 3343, /* C177 (49527) */ - 3343, /* C178 (49528) */ - 3343, /* C179 (49529) */ - 3343, /* C17A (49530) */ - 3343, /* C17B (49531) */ - 3343, /* C17C (49532) */ - 3343, /* C17D (49533) */ - 3343, /* C17E (49534) */ - 3343, /* C17F (49535) */ - 3343, /* C180 (49536) */ - 3343, /* C181 (49537) */ - 3343, /* C182 (49538) */ - 3343, /* C183 (49539) */ - 3343, /* C184 (49540) */ - 3343, /* C185 (49541) */ - 3343, /* C186 (49542) */ - 3343, /* C187 (49543) */ - 3343, /* C188 (49544) */ - 3343, /* C189 (49545) */ - 3343, /* C18A (49546) */ - 3343, /* C18B (49547) */ - 3343, /* C18C (49548) */ - 3343, /* C18D (49549) */ - 3343, /* C18E (49550) */ - 3343, /* C18F (49551) */ - 3343, /* C190 (49552) */ - 3343, /* C191 (49553) */ - 3343, /* C192 (49554) */ - 3343, /* C193 (49555) */ - 3343, /* C194 (49556) */ - 3343, /* C195 (49557) */ - 3343, /* C196 (49558) */ - 3343, /* C197 (49559) */ - 3343, /* C198 (49560) */ - 3343, /* C199 (49561) */ - 3343, /* C19A (49562) */ - 3343, /* C19B (49563) */ - 3343, /* C19C (49564) */ - 3343, /* C19D (49565) */ - 3343, /* C19E (49566) */ - 3343, /* C19F (49567) */ - 3343, /* C1A0 (49568) */ - 3343, /* C1A1 (49569) */ - 3343, /* C1A2 (49570) */ - 3343, /* C1A3 (49571) */ - 3343, /* C1A4 (49572) */ - 3343, /* C1A5 (49573) */ - 3343, /* C1A6 (49574) */ - 3343, /* C1A7 (49575) */ - 3343, /* C1A8 (49576) */ - 3343, /* C1A9 (49577) */ - 3343, /* C1AA (49578) */ - 3343, /* C1AB (49579) */ - 3343, /* C1AC (49580) */ - 3343, /* C1AD (49581) */ - 3343, /* C1AE (49582) */ - 3343, /* C1AF (49583) */ - 3343, /* C1B0 (49584) */ - 3343, /* C1B1 (49585) */ - 3343, /* C1B2 (49586) */ - 3343, /* C1B3 (49587) */ - 3343, /* C1B4 (49588) */ - 3343, /* C1B5 (49589) */ - 3343, /* C1B6 (49590) */ - 3343, /* C1B7 (49591) */ - 3343, /* C1B8 (49592) */ - 3343, /* C1B9 (49593) */ - 3343, /* C1BA (49594) */ - 3343, /* C1BB (49595) */ - 3343, /* C1BC (49596) */ - 3343, /* C1BD (49597) */ - 3343, /* C1BE (49598) */ - 3343, /* C1BF (49599) */ - 3343, /* C1C0 (49600) */ - 3343, /* C1C1 (49601) */ - 3343, /* C1C2 (49602) */ - 3343, /* C1C3 (49603) */ - 3343, /* C1C4 (49604) */ - 3343, /* C1C5 (49605) */ - 3343, /* C1C6 (49606) */ - 3343, /* C1C7 (49607) */ - 3343, /* C1C8 (49608) */ - 3343, /* C1C9 (49609) */ - 3343, /* C1CA (49610) */ - 3343, /* C1CB (49611) */ - 3343, /* C1CC (49612) */ - 3343, /* C1CD (49613) */ - 3343, /* C1CE (49614) */ - 3343, /* C1CF (49615) */ - 3343, /* C1D0 (49616) */ - 3343, /* C1D1 (49617) */ - 3343, /* C1D2 (49618) */ - 3343, /* C1D3 (49619) */ - 3343, /* C1D4 (49620) */ - 3343, /* C1D5 (49621) */ - 3343, /* C1D6 (49622) */ - 3343, /* C1D7 (49623) */ - 3343, /* C1D8 (49624) */ - 3343, /* C1D9 (49625) */ - 3343, /* C1DA (49626) */ - 3343, /* C1DB (49627) */ - 3343, /* C1DC (49628) */ - 3343, /* C1DD (49629) */ - 3343, /* C1DE (49630) */ - 3343, /* C1DF (49631) */ - 3343, /* C1E0 (49632) */ - 3343, /* C1E1 (49633) */ - 3343, /* C1E2 (49634) */ - 3343, /* C1E3 (49635) */ - 3343, /* C1E4 (49636) */ - 3343, /* C1E5 (49637) */ - 3343, /* C1E6 (49638) */ - 3343, /* C1E7 (49639) */ - 3343, /* C1E8 (49640) */ - 3343, /* C1E9 (49641) */ - 3343, /* C1EA (49642) */ - 3343, /* C1EB (49643) */ - 3343, /* C1EC (49644) */ - 3343, /* C1ED (49645) */ - 3343, /* C1EE (49646) */ - 3343, /* C1EF (49647) */ - 3343, /* C1F0 (49648) */ - 3343, /* C1F1 (49649) */ - 3343, /* C1F2 (49650) */ - 3343, /* C1F3 (49651) */ - 3343, /* C1F4 (49652) */ - 3343, /* C1F5 (49653) */ - 3343, /* C1F6 (49654) */ - 3343, /* C1F7 (49655) */ - 3343, /* C1F8 (49656) */ - 3343, /* C1F9 (49657) */ - 3343, /* C1FA (49658) */ - 3343, /* C1FB (49659) */ - 3343, /* C1FC (49660) */ - 3343, /* C1FD (49661) */ - 3343, /* C1FE (49662) */ - 3343, /* C1FF (49663) */ - 3343, /* C200 (49664) */ - 3343, /* C201 (49665) */ - 3343, /* C202 (49666) */ - 3343, /* C203 (49667) */ - 3343, /* C204 (49668) */ - 3343, /* C205 (49669) */ - 3343, /* C206 (49670) */ - 3343, /* C207 (49671) */ - 3343, /* C208 (49672) */ - 3343, /* C209 (49673) */ - 3343, /* C20A (49674) */ - 3343, /* C20B (49675) */ - 3343, /* C20C (49676) */ - 3343, /* C20D (49677) */ - 3343, /* C20E (49678) */ - 3343, /* C20F (49679) */ - 3343, /* C210 (49680) */ - 3343, /* C211 (49681) */ - 3343, /* C212 (49682) */ - 3343, /* C213 (49683) */ - 3343, /* C214 (49684) */ - 3343, /* C215 (49685) */ - 3343, /* C216 (49686) */ - 3343, /* C217 (49687) */ - 3343, /* C218 (49688) */ - 3343, /* C219 (49689) */ - 3343, /* C21A (49690) */ - 3343, /* C21B (49691) */ - 3343, /* C21C (49692) */ - 3343, /* C21D (49693) */ - 3343, /* C21E (49694) */ - 3343, /* C21F (49695) */ - 3343, /* C220 (49696) */ - 3343, /* C221 (49697) */ - 3343, /* C222 (49698) */ - 3343, /* C223 (49699) */ - 3343, /* C224 (49700) */ - 3343, /* C225 (49701) */ - 3343, /* C226 (49702) */ - 3343, /* C227 (49703) */ - 3343, /* C228 (49704) */ - 3343, /* C229 (49705) */ - 3343, /* C22A (49706) */ - 3343, /* C22B (49707) */ - 3343, /* C22C (49708) */ - 3343, /* C22D (49709) */ - 3343, /* C22E (49710) */ - 3343, /* C22F (49711) */ - 3343, /* C230 (49712) */ - 3343, /* C231 (49713) */ - 3343, /* C232 (49714) */ - 3343, /* C233 (49715) */ - 3343, /* C234 (49716) */ - 3343, /* C235 (49717) */ - 3343, /* C236 (49718) */ - 3343, /* C237 (49719) */ - 3343, /* C238 (49720) */ - 3343, /* C239 (49721) */ - 3343, /* C23A (49722) */ - 3343, /* C23B (49723) */ - 3343, /* C23C (49724) */ - 3343, /* C23D (49725) */ - 3343, /* C23E (49726) */ - 3343, /* C23F (49727) */ - 3343, /* C240 (49728) */ - 3343, /* C241 (49729) */ - 3343, /* C242 (49730) */ - 3343, /* C243 (49731) */ - 3343, /* C244 (49732) */ - 3343, /* C245 (49733) */ - 3343, /* C246 (49734) */ - 3343, /* C247 (49735) */ - 3343, /* C248 (49736) */ - 3343, /* C249 (49737) */ - 3343, /* C24A (49738) */ - 3343, /* C24B (49739) */ - 3343, /* C24C (49740) */ - 3343, /* C24D (49741) */ - 3343, /* C24E (49742) */ - 3343, /* C24F (49743) */ - 3343, /* C250 (49744) */ - 3343, /* C251 (49745) */ - 3343, /* C252 (49746) */ - 3343, /* C253 (49747) */ - 3343, /* C254 (49748) */ - 3343, /* C255 (49749) */ - 3343, /* C256 (49750) */ - 3343, /* C257 (49751) */ - 3343, /* C258 (49752) */ - 3343, /* C259 (49753) */ - 3343, /* C25A (49754) */ - 3343, /* C25B (49755) */ - 3343, /* C25C (49756) */ - 3343, /* C25D (49757) */ - 3343, /* C25E (49758) */ - 3343, /* C25F (49759) */ - 3343, /* C260 (49760) */ - 3343, /* C261 (49761) */ - 3343, /* C262 (49762) */ - 3343, /* C263 (49763) */ - 3343, /* C264 (49764) */ - 3343, /* C265 (49765) */ - 3343, /* C266 (49766) */ - 3343, /* C267 (49767) */ - 3343, /* C268 (49768) */ - 3343, /* C269 (49769) */ - 3343, /* C26A (49770) */ - 3343, /* C26B (49771) */ - 3343, /* C26C (49772) */ - 3343, /* C26D (49773) */ - 3343, /* C26E (49774) */ - 3343, /* C26F (49775) */ - 3343, /* C270 (49776) */ - 3343, /* C271 (49777) */ - 3343, /* C272 (49778) */ - 3343, /* C273 (49779) */ - 3343, /* C274 (49780) */ - 3343, /* C275 (49781) */ - 3343, /* C276 (49782) */ - 3343, /* C277 (49783) */ - 3343, /* C278 (49784) */ - 3343, /* C279 (49785) */ - 3343, /* C27A (49786) */ - 3343, /* C27B (49787) */ - 3343, /* C27C (49788) */ - 3343, /* C27D (49789) */ - 3343, /* C27E (49790) */ - 3343, /* C27F (49791) */ - 3343, /* C280 (49792) */ - 3343, /* C281 (49793) */ - 3343, /* C282 (49794) */ - 3343, /* C283 (49795) */ - 3343, /* C284 (49796) */ - 3343, /* C285 (49797) */ - 3343, /* C286 (49798) */ - 3343, /* C287 (49799) */ - 3343, /* C288 (49800) */ - 3343, /* C289 (49801) */ - 3343, /* C28A (49802) */ - 3343, /* C28B (49803) */ - 3343, /* C28C (49804) */ - 3343, /* C28D (49805) */ - 3343, /* C28E (49806) */ - 3343, /* C28F (49807) */ - 3343, /* C290 (49808) */ - 3343, /* C291 (49809) */ - 3343, /* C292 (49810) */ - 3343, /* C293 (49811) */ - 3343, /* C294 (49812) */ - 3343, /* C295 (49813) */ - 3343, /* C296 (49814) */ - 3343, /* C297 (49815) */ - 3343, /* C298 (49816) */ - 3343, /* C299 (49817) */ - 3343, /* C29A (49818) */ - 3343, /* C29B (49819) */ - 3343, /* C29C (49820) */ - 3343, /* C29D (49821) */ - 3343, /* C29E (49822) */ - 3343, /* C29F (49823) */ - 3343, /* C2A0 (49824) */ - 3343, /* C2A1 (49825) */ - 3343, /* C2A2 (49826) */ - 3343, /* C2A3 (49827) */ - 3343, /* C2A4 (49828) */ - 3343, /* C2A5 (49829) */ - 3343, /* C2A6 (49830) */ - 3343, /* C2A7 (49831) */ - 3343, /* C2A8 (49832) */ - 3343, /* C2A9 (49833) */ - 3343, /* C2AA (49834) */ - 3343, /* C2AB (49835) */ - 3343, /* C2AC (49836) */ - 3343, /* C2AD (49837) */ - 3343, /* C2AE (49838) */ - 3343, /* C2AF (49839) */ - 3343, /* C2B0 (49840) */ - 3343, /* C2B1 (49841) */ - 3343, /* C2B2 (49842) */ - 3343, /* C2B3 (49843) */ - 3343, /* C2B4 (49844) */ - 3343, /* C2B5 (49845) */ - 3343, /* C2B6 (49846) */ - 3343, /* C2B7 (49847) */ - 3343, /* C2B8 (49848) */ - 3343, /* C2B9 (49849) */ - 3343, /* C2BA (49850) */ - 3343, /* C2BB (49851) */ - 3343, /* C2BC (49852) */ - 3343, /* C2BD (49853) */ - 3343, /* C2BE (49854) */ - 3343, /* C2BF (49855) */ - 3343, /* C2C0 (49856) */ - 3343, /* C2C1 (49857) */ - 3343, /* C2C2 (49858) */ - 3343, /* C2C3 (49859) */ - 3343, /* C2C4 (49860) */ - 3343, /* C2C5 (49861) */ - 3343, /* C2C6 (49862) */ - 3343, /* C2C7 (49863) */ - 3343, /* C2C8 (49864) */ - 3343, /* C2C9 (49865) */ - 3343, /* C2CA (49866) */ - 3343, /* C2CB (49867) */ - 3343, /* C2CC (49868) */ - 3343, /* C2CD (49869) */ - 3343, /* C2CE (49870) */ - 3343, /* C2CF (49871) */ - 3343, /* C2D0 (49872) */ - 3343, /* C2D1 (49873) */ - 3343, /* C2D2 (49874) */ - 3343, /* C2D3 (49875) */ - 3343, /* C2D4 (49876) */ - 3343, /* C2D5 (49877) */ - 3343, /* C2D6 (49878) */ - 3343, /* C2D7 (49879) */ - 3343, /* C2D8 (49880) */ - 3343, /* C2D9 (49881) */ - 3343, /* C2DA (49882) */ - 3343, /* C2DB (49883) */ - 3343, /* C2DC (49884) */ - 3343, /* C2DD (49885) */ - 3343, /* C2DE (49886) */ - 3343, /* C2DF (49887) */ - 3343, /* C2E0 (49888) */ - 3343, /* C2E1 (49889) */ - 3343, /* C2E2 (49890) */ - 3343, /* C2E3 (49891) */ - 3343, /* C2E4 (49892) */ - 3343, /* C2E5 (49893) */ - 3343, /* C2E6 (49894) */ - 3343, /* C2E7 (49895) */ - 3343, /* C2E8 (49896) */ - 3343, /* C2E9 (49897) */ - 3343, /* C2EA (49898) */ - 3343, /* C2EB (49899) */ - 3343, /* C2EC (49900) */ - 3343, /* C2ED (49901) */ - 3343, /* C2EE (49902) */ - 3343, /* C2EF (49903) */ - 3343, /* C2F0 (49904) */ - 3343, /* C2F1 (49905) */ - 3343, /* C2F2 (49906) */ - 3343, /* C2F3 (49907) */ - 3343, /* C2F4 (49908) */ - 3343, /* C2F5 (49909) */ - 3343, /* C2F6 (49910) */ - 3343, /* C2F7 (49911) */ - 3343, /* C2F8 (49912) */ - 3343, /* C2F9 (49913) */ - 3343, /* C2FA (49914) */ - 3343, /* C2FB (49915) */ - 3343, /* C2FC (49916) */ - 3343, /* C2FD (49917) */ - 3343, /* C2FE (49918) */ - 3343, /* C2FF (49919) */ - 3343, /* C300 (49920) */ - 3343, /* C301 (49921) */ - 3343, /* C302 (49922) */ - 3343, /* C303 (49923) */ - 3343, /* C304 (49924) */ - 3343, /* C305 (49925) */ - 3343, /* C306 (49926) */ - 3343, /* C307 (49927) */ - 3343, /* C308 (49928) */ - 3343, /* C309 (49929) */ - 3343, /* C30A (49930) */ - 3343, /* C30B (49931) */ - 3343, /* C30C (49932) */ - 3343, /* C30D (49933) */ - 3343, /* C30E (49934) */ - 3343, /* C30F (49935) */ - 3343, /* C310 (49936) */ - 3343, /* C311 (49937) */ - 3343, /* C312 (49938) */ - 3343, /* C313 (49939) */ - 3343, /* C314 (49940) */ - 3343, /* C315 (49941) */ - 3343, /* C316 (49942) */ - 3343, /* C317 (49943) */ - 3343, /* C318 (49944) */ - 3343, /* C319 (49945) */ - 3343, /* C31A (49946) */ - 3343, /* C31B (49947) */ - 3343, /* C31C (49948) */ - 3343, /* C31D (49949) */ - 3343, /* C31E (49950) */ - 3343, /* C31F (49951) */ - 3343, /* C320 (49952) */ - 3343, /* C321 (49953) */ - 3343, /* C322 (49954) */ - 3343, /* C323 (49955) */ - 3343, /* C324 (49956) */ - 3343, /* C325 (49957) */ - 3343, /* C326 (49958) */ - 3343, /* C327 (49959) */ - 3343, /* C328 (49960) */ - 3343, /* C329 (49961) */ - 3343, /* C32A (49962) */ - 3343, /* C32B (49963) */ - 3343, /* C32C (49964) */ - 3343, /* C32D (49965) */ - 3343, /* C32E (49966) */ - 3343, /* C32F (49967) */ - 3343, /* C330 (49968) */ - 3343, /* C331 (49969) */ - 3343, /* C332 (49970) */ - 3343, /* C333 (49971) */ - 3343, /* C334 (49972) */ - 3343, /* C335 (49973) */ - 3343, /* C336 (49974) */ - 3343, /* C337 (49975) */ - 3343, /* C338 (49976) */ - 3343, /* C339 (49977) */ - 3343, /* C33A (49978) */ - 3343, /* C33B (49979) */ - 3343, /* C33C (49980) */ - 3343, /* C33D (49981) */ - 3343, /* C33E (49982) */ - 3343, /* C33F (49983) */ - 3343, /* C340 (49984) */ - 3343, /* C341 (49985) */ - 3343, /* C342 (49986) */ - 3343, /* C343 (49987) */ - 3343, /* C344 (49988) */ - 3343, /* C345 (49989) */ - 3343, /* C346 (49990) */ - 3343, /* C347 (49991) */ - 3343, /* C348 (49992) */ - 3343, /* C349 (49993) */ - 3343, /* C34A (49994) */ - 3343, /* C34B (49995) */ - 3343, /* C34C (49996) */ - 3343, /* C34D (49997) */ - 3343, /* C34E (49998) */ - 3343, /* C34F (49999) */ - 3343, /* C350 (50000) */ - 3343, /* C351 (50001) */ - 3343, /* C352 (50002) */ - 3343, /* C353 (50003) */ - 3343, /* C354 (50004) */ - 3343, /* C355 (50005) */ - 3343, /* C356 (50006) */ - 3343, /* C357 (50007) */ - 3343, /* C358 (50008) */ - 3343, /* C359 (50009) */ - 3343, /* C35A (50010) */ - 3343, /* C35B (50011) */ - 3343, /* C35C (50012) */ - 3343, /* C35D (50013) */ - 3343, /* C35E (50014) */ - 3343, /* C35F (50015) */ - 3343, /* C360 (50016) */ - 3343, /* C361 (50017) */ - 3343, /* C362 (50018) */ - 3343, /* C363 (50019) */ - 3343, /* C364 (50020) */ - 3343, /* C365 (50021) */ - 3343, /* C366 (50022) */ - 3343, /* C367 (50023) */ - 3343, /* C368 (50024) */ - 3343, /* C369 (50025) */ - 3343, /* C36A (50026) */ - 3343, /* C36B (50027) */ - 3343, /* C36C (50028) */ - 3343, /* C36D (50029) */ - 3343, /* C36E (50030) */ - 3343, /* C36F (50031) */ - 3343, /* C370 (50032) */ - 3343, /* C371 (50033) */ - 3343, /* C372 (50034) */ - 3343, /* C373 (50035) */ - 3343, /* C374 (50036) */ - 3343, /* C375 (50037) */ - 3343, /* C376 (50038) */ - 3343, /* C377 (50039) */ - 3343, /* C378 (50040) */ - 3343, /* C379 (50041) */ - 3343, /* C37A (50042) */ - 3343, /* C37B (50043) */ - 3343, /* C37C (50044) */ - 3343, /* C37D (50045) */ - 3343, /* C37E (50046) */ - 3343, /* C37F (50047) */ - 3343, /* C380 (50048) */ - 3343, /* C381 (50049) */ - 3343, /* C382 (50050) */ - 3343, /* C383 (50051) */ - 3343, /* C384 (50052) */ - 3343, /* C385 (50053) */ - 3343, /* C386 (50054) */ - 3343, /* C387 (50055) */ - 3343, /* C388 (50056) */ - 3343, /* C389 (50057) */ - 3343, /* C38A (50058) */ - 3343, /* C38B (50059) */ - 3343, /* C38C (50060) */ - 3343, /* C38D (50061) */ - 3343, /* C38E (50062) */ - 3343, /* C38F (50063) */ - 3343, /* C390 (50064) */ - 3343, /* C391 (50065) */ - 3343, /* C392 (50066) */ - 3343, /* C393 (50067) */ - 3343, /* C394 (50068) */ - 3343, /* C395 (50069) */ - 3343, /* C396 (50070) */ - 3343, /* C397 (50071) */ - 3343, /* C398 (50072) */ - 3343, /* C399 (50073) */ - 3343, /* C39A (50074) */ - 3343, /* C39B (50075) */ - 3343, /* C39C (50076) */ - 3343, /* C39D (50077) */ - 3343, /* C39E (50078) */ - 3343, /* C39F (50079) */ - 3343, /* C3A0 (50080) */ - 3343, /* C3A1 (50081) */ - 3343, /* C3A2 (50082) */ - 3343, /* C3A3 (50083) */ - 3343, /* C3A4 (50084) */ - 3343, /* C3A5 (50085) */ - 3343, /* C3A6 (50086) */ - 3343, /* C3A7 (50087) */ - 3343, /* C3A8 (50088) */ - 3343, /* C3A9 (50089) */ - 3343, /* C3AA (50090) */ - 3343, /* C3AB (50091) */ - 3343, /* C3AC (50092) */ - 3343, /* C3AD (50093) */ - 3343, /* C3AE (50094) */ - 3343, /* C3AF (50095) */ - 3343, /* C3B0 (50096) */ - 3343, /* C3B1 (50097) */ - 3343, /* C3B2 (50098) */ - 3343, /* C3B3 (50099) */ - 3343, /* C3B4 (50100) */ - 3343, /* C3B5 (50101) */ - 3343, /* C3B6 (50102) */ - 3343, /* C3B7 (50103) */ - 3343, /* C3B8 (50104) */ - 3343, /* C3B9 (50105) */ - 3343, /* C3BA (50106) */ - 3343, /* C3BB (50107) */ - 3343, /* C3BC (50108) */ - 3343, /* C3BD (50109) */ - 3343, /* C3BE (50110) */ - 3343, /* C3BF (50111) */ - 3343, /* C3C0 (50112) */ - 3343, /* C3C1 (50113) */ - 3343, /* C3C2 (50114) */ - 3343, /* C3C3 (50115) */ - 3343, /* C3C4 (50116) */ - 3343, /* C3C5 (50117) */ - 3343, /* C3C6 (50118) */ - 3343, /* C3C7 (50119) */ - 3343, /* C3C8 (50120) */ - 3343, /* C3C9 (50121) */ - 3343, /* C3CA (50122) */ - 3343, /* C3CB (50123) */ - 3343, /* C3CC (50124) */ - 3343, /* C3CD (50125) */ - 3343, /* C3CE (50126) */ - 3343, /* C3CF (50127) */ - 3343, /* C3D0 (50128) */ - 3343, /* C3D1 (50129) */ - 3343, /* C3D2 (50130) */ - 3343, /* C3D3 (50131) */ - 3343, /* C3D4 (50132) */ - 3343, /* C3D5 (50133) */ - 3343, /* C3D6 (50134) */ - 3343, /* C3D7 (50135) */ - 3343, /* C3D8 (50136) */ - 3343, /* C3D9 (50137) */ - 3343, /* C3DA (50138) */ - 3343, /* C3DB (50139) */ - 3343, /* C3DC (50140) */ - 3343, /* C3DD (50141) */ - 3343, /* C3DE (50142) */ - 3343, /* C3DF (50143) */ - 3343, /* C3E0 (50144) */ - 3343, /* C3E1 (50145) */ - 3343, /* C3E2 (50146) */ - 3343, /* C3E3 (50147) */ - 3343, /* C3E4 (50148) */ - 3343, /* C3E5 (50149) */ - 3343, /* C3E6 (50150) */ - 3343, /* C3E7 (50151) */ - 3343, /* C3E8 (50152) */ - 3343, /* C3E9 (50153) */ - 3343, /* C3EA (50154) */ - 3343, /* C3EB (50155) */ - 3343, /* C3EC (50156) */ - 3343, /* C3ED (50157) */ - 3343, /* C3EE (50158) */ - 3343, /* C3EF (50159) */ - 3343, /* C3F0 (50160) */ - 3343, /* C3F1 (50161) */ - 3343, /* C3F2 (50162) */ - 3343, /* C3F3 (50163) */ - 3343, /* C3F4 (50164) */ - 3343, /* C3F5 (50165) */ - 3343, /* C3F6 (50166) */ - 3343, /* C3F7 (50167) */ - 3343, /* C3F8 (50168) */ - 3343, /* C3F9 (50169) */ - 3343, /* C3FA (50170) */ - 3343, /* C3FB (50171) */ - 3343, /* C3FC (50172) */ - 3343, /* C3FD (50173) */ - 3343, /* C3FE (50174) */ - 3343, /* C3FF (50175) */ - 3343, /* C400 (50176) */ - 3343, /* C401 (50177) */ - 3343, /* C402 (50178) */ - 3343, /* C403 (50179) */ - 3343, /* C404 (50180) */ - 3343, /* C405 (50181) */ - 3343, /* C406 (50182) */ - 3343, /* C407 (50183) */ - 3343, /* C408 (50184) */ - 3343, /* C409 (50185) */ - 3343, /* C40A (50186) */ - 3343, /* C40B (50187) */ - 3343, /* C40C (50188) */ - 3343, /* C40D (50189) */ - 3343, /* C40E (50190) */ - 3343, /* C40F (50191) */ - 3343, /* C410 (50192) */ - 3343, /* C411 (50193) */ - 3343, /* C412 (50194) */ - 3343, /* C413 (50195) */ - 3343, /* C414 (50196) */ - 3343, /* C415 (50197) */ - 3343, /* C416 (50198) */ - 3343, /* C417 (50199) */ - 3343, /* C418 (50200) */ - 3343, /* C419 (50201) */ - 3343, /* C41A (50202) */ - 3343, /* C41B (50203) */ - 3343, /* C41C (50204) */ - 3343, /* C41D (50205) */ - 3343, /* C41E (50206) */ - 3343, /* C41F (50207) */ - 3343, /* C420 (50208) */ - 3343, /* C421 (50209) */ - 3343, /* C422 (50210) */ - 3343, /* C423 (50211) */ - 3343, /* C424 (50212) */ - 3343, /* C425 (50213) */ - 3343, /* C426 (50214) */ - 3343, /* C427 (50215) */ - 3343, /* C428 (50216) */ - 3343, /* C429 (50217) */ - 3343, /* C42A (50218) */ - 3343, /* C42B (50219) */ - 3343, /* C42C (50220) */ - 3343, /* C42D (50221) */ - 3343, /* C42E (50222) */ - 3343, /* C42F (50223) */ - 3343, /* C430 (50224) */ - 3343, /* C431 (50225) */ - 3343, /* C432 (50226) */ - 3343, /* C433 (50227) */ - 3343, /* C434 (50228) */ - 3343, /* C435 (50229) */ - 3343, /* C436 (50230) */ - 3343, /* C437 (50231) */ - 3343, /* C438 (50232) */ - 3343, /* C439 (50233) */ - 3343, /* C43A (50234) */ - 3343, /* C43B (50235) */ - 3343, /* C43C (50236) */ - 3343, /* C43D (50237) */ - 3343, /* C43E (50238) */ - 3343, /* C43F (50239) */ - 3343, /* C440 (50240) */ - 3343, /* C441 (50241) */ - 3343, /* C442 (50242) */ - 3343, /* C443 (50243) */ - 3343, /* C444 (50244) */ - 3343, /* C445 (50245) */ - 3343, /* C446 (50246) */ - 3343, /* C447 (50247) */ - 3343, /* C448 (50248) */ - 3343, /* C449 (50249) */ - 3343, /* C44A (50250) */ - 3343, /* C44B (50251) */ - 3343, /* C44C (50252) */ - 3343, /* C44D (50253) */ - 3343, /* C44E (50254) */ - 3343, /* C44F (50255) */ - 3343, /* C450 (50256) */ - 3343, /* C451 (50257) */ - 3343, /* C452 (50258) */ - 3343, /* C453 (50259) */ - 3343, /* C454 (50260) */ - 3343, /* C455 (50261) */ - 3343, /* C456 (50262) */ - 3343, /* C457 (50263) */ - 3343, /* C458 (50264) */ - 3343, /* C459 (50265) */ - 3343, /* C45A (50266) */ - 3343, /* C45B (50267) */ - 3343, /* C45C (50268) */ - 3343, /* C45D (50269) */ - 3343, /* C45E (50270) */ - 3343, /* C45F (50271) */ - 3343, /* C460 (50272) */ - 3343, /* C461 (50273) */ - 3343, /* C462 (50274) */ - 3343, /* C463 (50275) */ - 3343, /* C464 (50276) */ - 3343, /* C465 (50277) */ - 3343, /* C466 (50278) */ - 3343, /* C467 (50279) */ - 3343, /* C468 (50280) */ - 3343, /* C469 (50281) */ - 3343, /* C46A (50282) */ - 3343, /* C46B (50283) */ - 3343, /* C46C (50284) */ - 3343, /* C46D (50285) */ - 3343, /* C46E (50286) */ - 3343, /* C46F (50287) */ - 3343, /* C470 (50288) */ - 3343, /* C471 (50289) */ - 3343, /* C472 (50290) */ - 3343, /* C473 (50291) */ - 3343, /* C474 (50292) */ - 3343, /* C475 (50293) */ - 3343, /* C476 (50294) */ - 3343, /* C477 (50295) */ - 3343, /* C478 (50296) */ - 3343, /* C479 (50297) */ - 3343, /* C47A (50298) */ - 3343, /* C47B (50299) */ - 3343, /* C47C (50300) */ - 3343, /* C47D (50301) */ - 3343, /* C47E (50302) */ - 3343, /* C47F (50303) */ - 3343, /* C480 (50304) */ - 3343, /* C481 (50305) */ - 3343, /* C482 (50306) */ - 3343, /* C483 (50307) */ - 3343, /* C484 (50308) */ - 3343, /* C485 (50309) */ - 3343, /* C486 (50310) */ - 3343, /* C487 (50311) */ - 3343, /* C488 (50312) */ - 3343, /* C489 (50313) */ - 3343, /* C48A (50314) */ - 3343, /* C48B (50315) */ - 3343, /* C48C (50316) */ - 3343, /* C48D (50317) */ - 3343, /* C48E (50318) */ - 3343, /* C48F (50319) */ - 3343, /* C490 (50320) */ - 3343, /* C491 (50321) */ - 3343, /* C492 (50322) */ - 3343, /* C493 (50323) */ - 3343, /* C494 (50324) */ - 3343, /* C495 (50325) */ - 3343, /* C496 (50326) */ - 3343, /* C497 (50327) */ - 3343, /* C498 (50328) */ - 3343, /* C499 (50329) */ - 3343, /* C49A (50330) */ - 3343, /* C49B (50331) */ - 3343, /* C49C (50332) */ - 3343, /* C49D (50333) */ - 3343, /* C49E (50334) */ - 3343, /* C49F (50335) */ - 3343, /* C4A0 (50336) */ - 3343, /* C4A1 (50337) */ - 3343, /* C4A2 (50338) */ - 3343, /* C4A3 (50339) */ - 3343, /* C4A4 (50340) */ - 3343, /* C4A5 (50341) */ - 3343, /* C4A6 (50342) */ - 3343, /* C4A7 (50343) */ - 3343, /* C4A8 (50344) */ - 3343, /* C4A9 (50345) */ - 3343, /* C4AA (50346) */ - 3343, /* C4AB (50347) */ - 3343, /* C4AC (50348) */ - 3343, /* C4AD (50349) */ - 3343, /* C4AE (50350) */ - 3343, /* C4AF (50351) */ - 3343, /* C4B0 (50352) */ - 3343, /* C4B1 (50353) */ - 3343, /* C4B2 (50354) */ - 3343, /* C4B3 (50355) */ - 3343, /* C4B4 (50356) */ - 3343, /* C4B5 (50357) */ - 3343, /* C4B6 (50358) */ - 3343, /* C4B7 (50359) */ - 3343, /* C4B8 (50360) */ - 3343, /* C4B9 (50361) */ - 3343, /* C4BA (50362) */ - 3343, /* C4BB (50363) */ - 3343, /* C4BC (50364) */ - 3343, /* C4BD (50365) */ - 3343, /* C4BE (50366) */ - 3343, /* C4BF (50367) */ - 3343, /* C4C0 (50368) */ - 3343, /* C4C1 (50369) */ - 3343, /* C4C2 (50370) */ - 3343, /* C4C3 (50371) */ - 3343, /* C4C4 (50372) */ - 3343, /* C4C5 (50373) */ - 3343, /* C4C6 (50374) */ - 3343, /* C4C7 (50375) */ - 3343, /* C4C8 (50376) */ - 3343, /* C4C9 (50377) */ - 3343, /* C4CA (50378) */ - 3343, /* C4CB (50379) */ - 3343, /* C4CC (50380) */ - 3343, /* C4CD (50381) */ - 3343, /* C4CE (50382) */ - 3343, /* C4CF (50383) */ - 3343, /* C4D0 (50384) */ - 3343, /* C4D1 (50385) */ - 3343, /* C4D2 (50386) */ - 3343, /* C4D3 (50387) */ - 3343, /* C4D4 (50388) */ - 3343, /* C4D5 (50389) */ - 3343, /* C4D6 (50390) */ - 3343, /* C4D7 (50391) */ - 3343, /* C4D8 (50392) */ - 3343, /* C4D9 (50393) */ - 3343, /* C4DA (50394) */ - 3343, /* C4DB (50395) */ - 3343, /* C4DC (50396) */ - 3343, /* C4DD (50397) */ - 3343, /* C4DE (50398) */ - 3343, /* C4DF (50399) */ - 3343, /* C4E0 (50400) */ - 3343, /* C4E1 (50401) */ - 3343, /* C4E2 (50402) */ - 3343, /* C4E3 (50403) */ - 3343, /* C4E4 (50404) */ - 3343, /* C4E5 (50405) */ - 3343, /* C4E6 (50406) */ - 3343, /* C4E7 (50407) */ - 3343, /* C4E8 (50408) */ - 3343, /* C4E9 (50409) */ - 3343, /* C4EA (50410) */ - 3343, /* C4EB (50411) */ - 3343, /* C4EC (50412) */ - 3343, /* C4ED (50413) */ - 3343, /* C4EE (50414) */ - 3343, /* C4EF (50415) */ - 3343, /* C4F0 (50416) */ - 3343, /* C4F1 (50417) */ - 3343, /* C4F2 (50418) */ - 3343, /* C4F3 (50419) */ - 3343, /* C4F4 (50420) */ - 3343, /* C4F5 (50421) */ - 3343, /* C4F6 (50422) */ - 3343, /* C4F7 (50423) */ - 3343, /* C4F8 (50424) */ - 3343, /* C4F9 (50425) */ - 3343, /* C4FA (50426) */ - 3343, /* C4FB (50427) */ - 3343, /* C4FC (50428) */ - 3343, /* C4FD (50429) */ - 3343, /* C4FE (50430) */ - 3343, /* C4FF (50431) */ - 3343, /* C500 (50432) */ - 3343, /* C501 (50433) */ - 3343, /* C502 (50434) */ - 3343, /* C503 (50435) */ - 3343, /* C504 (50436) */ - 3343, /* C505 (50437) */ - 3343, /* C506 (50438) */ - 3343, /* C507 (50439) */ - 3343, /* C508 (50440) */ - 3343, /* C509 (50441) */ - 3343, /* C50A (50442) */ - 3343, /* C50B (50443) */ - 3343, /* C50C (50444) */ - 3343, /* C50D (50445) */ - 3343, /* C50E (50446) */ - 3343, /* C50F (50447) */ - 3343, /* C510 (50448) */ - 3343, /* C511 (50449) */ - 3343, /* C512 (50450) */ - 3343, /* C513 (50451) */ - 3343, /* C514 (50452) */ - 3343, /* C515 (50453) */ - 3343, /* C516 (50454) */ - 3343, /* C517 (50455) */ - 3343, /* C518 (50456) */ - 3343, /* C519 (50457) */ - 3343, /* C51A (50458) */ - 3343, /* C51B (50459) */ - 3343, /* C51C (50460) */ - 3343, /* C51D (50461) */ - 3343, /* C51E (50462) */ - 3343, /* C51F (50463) */ - 3343, /* C520 (50464) */ - 3343, /* C521 (50465) */ - 3343, /* C522 (50466) */ - 3343, /* C523 (50467) */ - 3343, /* C524 (50468) */ - 3343, /* C525 (50469) */ - 3343, /* C526 (50470) */ - 3343, /* C527 (50471) */ - 3343, /* C528 (50472) */ - 3343, /* C529 (50473) */ - 3343, /* C52A (50474) */ - 3343, /* C52B (50475) */ - 3343, /* C52C (50476) */ - 3343, /* C52D (50477) */ - 3343, /* C52E (50478) */ - 3343, /* C52F (50479) */ - 3343, /* C530 (50480) */ - 3343, /* C531 (50481) */ - 3343, /* C532 (50482) */ - 3343, /* C533 (50483) */ - 3343, /* C534 (50484) */ - 3343, /* C535 (50485) */ - 3343, /* C536 (50486) */ - 3343, /* C537 (50487) */ - 3343, /* C538 (50488) */ - 3343, /* C539 (50489) */ - 3343, /* C53A (50490) */ - 3343, /* C53B (50491) */ - 3343, /* C53C (50492) */ - 3343, /* C53D (50493) */ - 3343, /* C53E (50494) */ - 3343, /* C53F (50495) */ - 3343, /* C540 (50496) */ - 3343, /* C541 (50497) */ - 3343, /* C542 (50498) */ - 3343, /* C543 (50499) */ - 3343, /* C544 (50500) */ - 3343, /* C545 (50501) */ - 3343, /* C546 (50502) */ - 3343, /* C547 (50503) */ - 3343, /* C548 (50504) */ - 3343, /* C549 (50505) */ - 3343, /* C54A (50506) */ - 3343, /* C54B (50507) */ - 3343, /* C54C (50508) */ - 3343, /* C54D (50509) */ - 3343, /* C54E (50510) */ - 3343, /* C54F (50511) */ - 3343, /* C550 (50512) */ - 3343, /* C551 (50513) */ - 3343, /* C552 (50514) */ - 3343, /* C553 (50515) */ - 3343, /* C554 (50516) */ - 3343, /* C555 (50517) */ - 3343, /* C556 (50518) */ - 3343, /* C557 (50519) */ - 3343, /* C558 (50520) */ - 3343, /* C559 (50521) */ - 3343, /* C55A (50522) */ - 3343, /* C55B (50523) */ - 3343, /* C55C (50524) */ - 3343, /* C55D (50525) */ - 3343, /* C55E (50526) */ - 3343, /* C55F (50527) */ - 3343, /* C560 (50528) */ - 3343, /* C561 (50529) */ - 3343, /* C562 (50530) */ - 3343, /* C563 (50531) */ - 3343, /* C564 (50532) */ - 3343, /* C565 (50533) */ - 3343, /* C566 (50534) */ - 3343, /* C567 (50535) */ - 3343, /* C568 (50536) */ - 3343, /* C569 (50537) */ - 3343, /* C56A (50538) */ - 3343, /* C56B (50539) */ - 3343, /* C56C (50540) */ - 3343, /* C56D (50541) */ - 3343, /* C56E (50542) */ - 3343, /* C56F (50543) */ - 3343, /* C570 (50544) */ - 3343, /* C571 (50545) */ - 3343, /* C572 (50546) */ - 3343, /* C573 (50547) */ - 3343, /* C574 (50548) */ - 3343, /* C575 (50549) */ - 3343, /* C576 (50550) */ - 3343, /* C577 (50551) */ - 3343, /* C578 (50552) */ - 3343, /* C579 (50553) */ - 3343, /* C57A (50554) */ - 3343, /* C57B (50555) */ - 3343, /* C57C (50556) */ - 3343, /* C57D (50557) */ - 3343, /* C57E (50558) */ - 3343, /* C57F (50559) */ - 3343, /* C580 (50560) */ - 3343, /* C581 (50561) */ - 3343, /* C582 (50562) */ - 3343, /* C583 (50563) */ - 3343, /* C584 (50564) */ - 3343, /* C585 (50565) */ - 3343, /* C586 (50566) */ - 3343, /* C587 (50567) */ - 3343, /* C588 (50568) */ - 3343, /* C589 (50569) */ - 3343, /* C58A (50570) */ - 3343, /* C58B (50571) */ - 3343, /* C58C (50572) */ - 3343, /* C58D (50573) */ - 3343, /* C58E (50574) */ - 3343, /* C58F (50575) */ - 3343, /* C590 (50576) */ - 3343, /* C591 (50577) */ - 3343, /* C592 (50578) */ - 3343, /* C593 (50579) */ - 3343, /* C594 (50580) */ - 3343, /* C595 (50581) */ - 3343, /* C596 (50582) */ - 3343, /* C597 (50583) */ - 3343, /* C598 (50584) */ - 3343, /* C599 (50585) */ - 3343, /* C59A (50586) */ - 3343, /* C59B (50587) */ - 3343, /* C59C (50588) */ - 3343, /* C59D (50589) */ - 3343, /* C59E (50590) */ - 3343, /* C59F (50591) */ - 3343, /* C5A0 (50592) */ - 3343, /* C5A1 (50593) */ - 3343, /* C5A2 (50594) */ - 3343, /* C5A3 (50595) */ - 3343, /* C5A4 (50596) */ - 3343, /* C5A5 (50597) */ - 3343, /* C5A6 (50598) */ - 3343, /* C5A7 (50599) */ - 3343, /* C5A8 (50600) */ - 3343, /* C5A9 (50601) */ - 3343, /* C5AA (50602) */ - 3343, /* C5AB (50603) */ - 3343, /* C5AC (50604) */ - 3343, /* C5AD (50605) */ - 3343, /* C5AE (50606) */ - 3343, /* C5AF (50607) */ - 3343, /* C5B0 (50608) */ - 3343, /* C5B1 (50609) */ - 3343, /* C5B2 (50610) */ - 3343, /* C5B3 (50611) */ - 3343, /* C5B4 (50612) */ - 3343, /* C5B5 (50613) */ - 3343, /* C5B6 (50614) */ - 3343, /* C5B7 (50615) */ - 3343, /* C5B8 (50616) */ - 3343, /* C5B9 (50617) */ - 3343, /* C5BA (50618) */ - 3343, /* C5BB (50619) */ - 3343, /* C5BC (50620) */ - 3343, /* C5BD (50621) */ - 3343, /* C5BE (50622) */ - 3343, /* C5BF (50623) */ - 3343, /* C5C0 (50624) */ - 3343, /* C5C1 (50625) */ - 3343, /* C5C2 (50626) */ - 3343, /* C5C3 (50627) */ - 3343, /* C5C4 (50628) */ - 3343, /* C5C5 (50629) */ - 3343, /* C5C6 (50630) */ - 3343, /* C5C7 (50631) */ - 3343, /* C5C8 (50632) */ - 3343, /* C5C9 (50633) */ - 3343, /* C5CA (50634) */ - 3343, /* C5CB (50635) */ - 3343, /* C5CC (50636) */ - 3343, /* C5CD (50637) */ - 3343, /* C5CE (50638) */ - 3343, /* C5CF (50639) */ - 3343, /* C5D0 (50640) */ - 3343, /* C5D1 (50641) */ - 3343, /* C5D2 (50642) */ - 3343, /* C5D3 (50643) */ - 3343, /* C5D4 (50644) */ - 3343, /* C5D5 (50645) */ - 3343, /* C5D6 (50646) */ - 3343, /* C5D7 (50647) */ - 3343, /* C5D8 (50648) */ - 3343, /* C5D9 (50649) */ - 3343, /* C5DA (50650) */ - 3343, /* C5DB (50651) */ - 3343, /* C5DC (50652) */ - 3343, /* C5DD (50653) */ - 3343, /* C5DE (50654) */ - 3343, /* C5DF (50655) */ - 3343, /* C5E0 (50656) */ - 3343, /* C5E1 (50657) */ - 3343, /* C5E2 (50658) */ - 3343, /* C5E3 (50659) */ - 3343, /* C5E4 (50660) */ - 3343, /* C5E5 (50661) */ - 3343, /* C5E6 (50662) */ - 3343, /* C5E7 (50663) */ - 3343, /* C5E8 (50664) */ - 3343, /* C5E9 (50665) */ - 3343, /* C5EA (50666) */ - 3343, /* C5EB (50667) */ - 3343, /* C5EC (50668) */ - 3343, /* C5ED (50669) */ - 3343, /* C5EE (50670) */ - 3343, /* C5EF (50671) */ - 3343, /* C5F0 (50672) */ - 3343, /* C5F1 (50673) */ - 3343, /* C5F2 (50674) */ - 3343, /* C5F3 (50675) */ - 3343, /* C5F4 (50676) */ - 3343, /* C5F5 (50677) */ - 3343, /* C5F6 (50678) */ - 3343, /* C5F7 (50679) */ - 3343, /* C5F8 (50680) */ - 3343, /* C5F9 (50681) */ - 3343, /* C5FA (50682) */ - 3343, /* C5FB (50683) */ - 3343, /* C5FC (50684) */ - 3343, /* C5FD (50685) */ - 3343, /* C5FE (50686) */ - 3343, /* C5FF (50687) */ - 3343, /* C600 (50688) */ - 3343, /* C601 (50689) */ - 3343, /* C602 (50690) */ - 3343, /* C603 (50691) */ - 3343, /* C604 (50692) */ - 3343, /* C605 (50693) */ - 3343, /* C606 (50694) */ - 3343, /* C607 (50695) */ - 3343, /* C608 (50696) */ - 3343, /* C609 (50697) */ - 3343, /* C60A (50698) */ - 3343, /* C60B (50699) */ - 3343, /* C60C (50700) */ - 3343, /* C60D (50701) */ - 3343, /* C60E (50702) */ - 3343, /* C60F (50703) */ - 3343, /* C610 (50704) */ - 3343, /* C611 (50705) */ - 3343, /* C612 (50706) */ - 3343, /* C613 (50707) */ - 3343, /* C614 (50708) */ - 3343, /* C615 (50709) */ - 3343, /* C616 (50710) */ - 3343, /* C617 (50711) */ - 3343, /* C618 (50712) */ - 3343, /* C619 (50713) */ - 3343, /* C61A (50714) */ - 3343, /* C61B (50715) */ - 3343, /* C61C (50716) */ - 3343, /* C61D (50717) */ - 3343, /* C61E (50718) */ - 3343, /* C61F (50719) */ - 3343, /* C620 (50720) */ - 3343, /* C621 (50721) */ - 3343, /* C622 (50722) */ - 3343, /* C623 (50723) */ - 3343, /* C624 (50724) */ - 3343, /* C625 (50725) */ - 3343, /* C626 (50726) */ - 3343, /* C627 (50727) */ - 3343, /* C628 (50728) */ - 3343, /* C629 (50729) */ - 3343, /* C62A (50730) */ - 3343, /* C62B (50731) */ - 3343, /* C62C (50732) */ - 3343, /* C62D (50733) */ - 3343, /* C62E (50734) */ - 3343, /* C62F (50735) */ - 3343, /* C630 (50736) */ - 3343, /* C631 (50737) */ - 3343, /* C632 (50738) */ - 3343, /* C633 (50739) */ - 3343, /* C634 (50740) */ - 3343, /* C635 (50741) */ - 3343, /* C636 (50742) */ - 3343, /* C637 (50743) */ - 3343, /* C638 (50744) */ - 3343, /* C639 (50745) */ - 3343, /* C63A (50746) */ - 3343, /* C63B (50747) */ - 3343, /* C63C (50748) */ - 3343, /* C63D (50749) */ - 3343, /* C63E (50750) */ - 3343, /* C63F (50751) */ - 3343, /* C640 (50752) */ - 3343, /* C641 (50753) */ - 3343, /* C642 (50754) */ - 3343, /* C643 (50755) */ - 3343, /* C644 (50756) */ - 3343, /* C645 (50757) */ - 3343, /* C646 (50758) */ - 3343, /* C647 (50759) */ - 3343, /* C648 (50760) */ - 3343, /* C649 (50761) */ - 3343, /* C64A (50762) */ - 3343, /* C64B (50763) */ - 3343, /* C64C (50764) */ - 3343, /* C64D (50765) */ - 3343, /* C64E (50766) */ - 3343, /* C64F (50767) */ - 3343, /* C650 (50768) */ - 3343, /* C651 (50769) */ - 3343, /* C652 (50770) */ - 3343, /* C653 (50771) */ - 3343, /* C654 (50772) */ - 3343, /* C655 (50773) */ - 3343, /* C656 (50774) */ - 3343, /* C657 (50775) */ - 3343, /* C658 (50776) */ - 3343, /* C659 (50777) */ - 3343, /* C65A (50778) */ - 3343, /* C65B (50779) */ - 3343, /* C65C (50780) */ - 3343, /* C65D (50781) */ - 3343, /* C65E (50782) */ - 3343, /* C65F (50783) */ - 3343, /* C660 (50784) */ - 3343, /* C661 (50785) */ - 3343, /* C662 (50786) */ - 3343, /* C663 (50787) */ - 3343, /* C664 (50788) */ - 3343, /* C665 (50789) */ - 3343, /* C666 (50790) */ - 3343, /* C667 (50791) */ - 3343, /* C668 (50792) */ - 3343, /* C669 (50793) */ - 3343, /* C66A (50794) */ - 3343, /* C66B (50795) */ - 3343, /* C66C (50796) */ - 3343, /* C66D (50797) */ - 3343, /* C66E (50798) */ - 3343, /* C66F (50799) */ - 3343, /* C670 (50800) */ - 3343, /* C671 (50801) */ - 3343, /* C672 (50802) */ - 3343, /* C673 (50803) */ - 3343, /* C674 (50804) */ - 3343, /* C675 (50805) */ - 3343, /* C676 (50806) */ - 3343, /* C677 (50807) */ - 3343, /* C678 (50808) */ - 3343, /* C679 (50809) */ - 3343, /* C67A (50810) */ - 3343, /* C67B (50811) */ - 3343, /* C67C (50812) */ - 3343, /* C67D (50813) */ - 3343, /* C67E (50814) */ - 3343, /* C67F (50815) */ - 3343, /* C680 (50816) */ - 3343, /* C681 (50817) */ - 3343, /* C682 (50818) */ - 3343, /* C683 (50819) */ - 3343, /* C684 (50820) */ - 3343, /* C685 (50821) */ - 3343, /* C686 (50822) */ - 3343, /* C687 (50823) */ - 3343, /* C688 (50824) */ - 3343, /* C689 (50825) */ - 3343, /* C68A (50826) */ - 3343, /* C68B (50827) */ - 3343, /* C68C (50828) */ - 3343, /* C68D (50829) */ - 3343, /* C68E (50830) */ - 3343, /* C68F (50831) */ - 3343, /* C690 (50832) */ - 3343, /* C691 (50833) */ - 3343, /* C692 (50834) */ - 3343, /* C693 (50835) */ - 3343, /* C694 (50836) */ - 3343, /* C695 (50837) */ - 3343, /* C696 (50838) */ - 3343, /* C697 (50839) */ - 3343, /* C698 (50840) */ - 3343, /* C699 (50841) */ - 3343, /* C69A (50842) */ - 3343, /* C69B (50843) */ - 3343, /* C69C (50844) */ - 3343, /* C69D (50845) */ - 3343, /* C69E (50846) */ - 3343, /* C69F (50847) */ - 3343, /* C6A0 (50848) */ - 3343, /* C6A1 (50849) */ - 3343, /* C6A2 (50850) */ - 3343, /* C6A3 (50851) */ - 3343, /* C6A4 (50852) */ - 3343, /* C6A5 (50853) */ - 3343, /* C6A6 (50854) */ - 3343, /* C6A7 (50855) */ - 3343, /* C6A8 (50856) */ - 3343, /* C6A9 (50857) */ - 3343, /* C6AA (50858) */ - 3343, /* C6AB (50859) */ - 3343, /* C6AC (50860) */ - 3343, /* C6AD (50861) */ - 3343, /* C6AE (50862) */ - 3343, /* C6AF (50863) */ - 3343, /* C6B0 (50864) */ - 3343, /* C6B1 (50865) */ - 3343, /* C6B2 (50866) */ - 3343, /* C6B3 (50867) */ - 3343, /* C6B4 (50868) */ - 3343, /* C6B5 (50869) */ - 3343, /* C6B6 (50870) */ - 3343, /* C6B7 (50871) */ - 3343, /* C6B8 (50872) */ - 3343, /* C6B9 (50873) */ - 3343, /* C6BA (50874) */ - 3343, /* C6BB (50875) */ - 3343, /* C6BC (50876) */ - 3343, /* C6BD (50877) */ - 3343, /* C6BE (50878) */ - 3343, /* C6BF (50879) */ - 3343, /* C6C0 (50880) */ - 3343, /* C6C1 (50881) */ - 3343, /* C6C2 (50882) */ - 3343, /* C6C3 (50883) */ - 3343, /* C6C4 (50884) */ - 3343, /* C6C5 (50885) */ - 3343, /* C6C6 (50886) */ - 3343, /* C6C7 (50887) */ - 3343, /* C6C8 (50888) */ - 3343, /* C6C9 (50889) */ - 3343, /* C6CA (50890) */ - 3343, /* C6CB (50891) */ - 3343, /* C6CC (50892) */ - 3343, /* C6CD (50893) */ - 3343, /* C6CE (50894) */ - 3343, /* C6CF (50895) */ - 3343, /* C6D0 (50896) */ - 3343, /* C6D1 (50897) */ - 3343, /* C6D2 (50898) */ - 3343, /* C6D3 (50899) */ - 3343, /* C6D4 (50900) */ - 3343, /* C6D5 (50901) */ - 3343, /* C6D6 (50902) */ - 3343, /* C6D7 (50903) */ - 3343, /* C6D8 (50904) */ - 3343, /* C6D9 (50905) */ - 3343, /* C6DA (50906) */ - 3343, /* C6DB (50907) */ - 3343, /* C6DC (50908) */ - 3343, /* C6DD (50909) */ - 3343, /* C6DE (50910) */ - 3343, /* C6DF (50911) */ - 3343, /* C6E0 (50912) */ - 3343, /* C6E1 (50913) */ - 3343, /* C6E2 (50914) */ - 3343, /* C6E3 (50915) */ - 3343, /* C6E4 (50916) */ - 3343, /* C6E5 (50917) */ - 3343, /* C6E6 (50918) */ - 3343, /* C6E7 (50919) */ - 3343, /* C6E8 (50920) */ - 3343, /* C6E9 (50921) */ - 3343, /* C6EA (50922) */ - 3343, /* C6EB (50923) */ - 3343, /* C6EC (50924) */ - 3343, /* C6ED (50925) */ - 3343, /* C6EE (50926) */ - 3343, /* C6EF (50927) */ - 3343, /* C6F0 (50928) */ - 3343, /* C6F1 (50929) */ - 3343, /* C6F2 (50930) */ - 3343, /* C6F3 (50931) */ - 3343, /* C6F4 (50932) */ - 3343, /* C6F5 (50933) */ - 3343, /* C6F6 (50934) */ - 3343, /* C6F7 (50935) */ - 3343, /* C6F8 (50936) */ - 3343, /* C6F9 (50937) */ - 3343, /* C6FA (50938) */ - 3343, /* C6FB (50939) */ - 3343, /* C6FC (50940) */ - 3343, /* C6FD (50941) */ - 3343, /* C6FE (50942) */ - 3343, /* C6FF (50943) */ - 3343, /* C700 (50944) */ - 3343, /* C701 (50945) */ - 3343, /* C702 (50946) */ - 3343, /* C703 (50947) */ - 3343, /* C704 (50948) */ - 3343, /* C705 (50949) */ - 3343, /* C706 (50950) */ - 3343, /* C707 (50951) */ - 3343, /* C708 (50952) */ - 3343, /* C709 (50953) */ - 3343, /* C70A (50954) */ - 3343, /* C70B (50955) */ - 3343, /* C70C (50956) */ - 3343, /* C70D (50957) */ - 3343, /* C70E (50958) */ - 3343, /* C70F (50959) */ - 3343, /* C710 (50960) */ - 3343, /* C711 (50961) */ - 3343, /* C712 (50962) */ - 3343, /* C713 (50963) */ - 3343, /* C714 (50964) */ - 3343, /* C715 (50965) */ - 3343, /* C716 (50966) */ - 3343, /* C717 (50967) */ - 3343, /* C718 (50968) */ - 3343, /* C719 (50969) */ - 3343, /* C71A (50970) */ - 3343, /* C71B (50971) */ - 3343, /* C71C (50972) */ - 3343, /* C71D (50973) */ - 3343, /* C71E (50974) */ - 3343, /* C71F (50975) */ - 3343, /* C720 (50976) */ - 3343, /* C721 (50977) */ - 3343, /* C722 (50978) */ - 3343, /* C723 (50979) */ - 3343, /* C724 (50980) */ - 3343, /* C725 (50981) */ - 3343, /* C726 (50982) */ - 3343, /* C727 (50983) */ - 3343, /* C728 (50984) */ - 3343, /* C729 (50985) */ - 3343, /* C72A (50986) */ - 3343, /* C72B (50987) */ - 3343, /* C72C (50988) */ - 3343, /* C72D (50989) */ - 3343, /* C72E (50990) */ - 3343, /* C72F (50991) */ - 3343, /* C730 (50992) */ - 3343, /* C731 (50993) */ - 3343, /* C732 (50994) */ - 3343, /* C733 (50995) */ - 3343, /* C734 (50996) */ - 3343, /* C735 (50997) */ - 3343, /* C736 (50998) */ - 3343, /* C737 (50999) */ - 3343, /* C738 (51000) */ - 3343, /* C739 (51001) */ - 3343, /* C73A (51002) */ - 3343, /* C73B (51003) */ - 3343, /* C73C (51004) */ - 3343, /* C73D (51005) */ - 3343, /* C73E (51006) */ - 3343, /* C73F (51007) */ - 3343, /* C740 (51008) */ - 3343, /* C741 (51009) */ - 3343, /* C742 (51010) */ - 3343, /* C743 (51011) */ - 3343, /* C744 (51012) */ - 3343, /* C745 (51013) */ - 3343, /* C746 (51014) */ - 3343, /* C747 (51015) */ - 3343, /* C748 (51016) */ - 3343, /* C749 (51017) */ - 3343, /* C74A (51018) */ - 3343, /* C74B (51019) */ - 3343, /* C74C (51020) */ - 3343, /* C74D (51021) */ - 3343, /* C74E (51022) */ - 3343, /* C74F (51023) */ - 3343, /* C750 (51024) */ - 3343, /* C751 (51025) */ - 3343, /* C752 (51026) */ - 3343, /* C753 (51027) */ - 3343, /* C754 (51028) */ - 3343, /* C755 (51029) */ - 3343, /* C756 (51030) */ - 3343, /* C757 (51031) */ - 3343, /* C758 (51032) */ - 3343, /* C759 (51033) */ - 3343, /* C75A (51034) */ - 3343, /* C75B (51035) */ - 3343, /* C75C (51036) */ - 3343, /* C75D (51037) */ - 3343, /* C75E (51038) */ - 3343, /* C75F (51039) */ - 3343, /* C760 (51040) */ - 3343, /* C761 (51041) */ - 3343, /* C762 (51042) */ - 3343, /* C763 (51043) */ - 3343, /* C764 (51044) */ - 3343, /* C765 (51045) */ - 3343, /* C766 (51046) */ - 3343, /* C767 (51047) */ - 3343, /* C768 (51048) */ - 3343, /* C769 (51049) */ - 3343, /* C76A (51050) */ - 3343, /* C76B (51051) */ - 3343, /* C76C (51052) */ - 3343, /* C76D (51053) */ - 3343, /* C76E (51054) */ - 3343, /* C76F (51055) */ - 3343, /* C770 (51056) */ - 3343, /* C771 (51057) */ - 3343, /* C772 (51058) */ - 3343, /* C773 (51059) */ - 3343, /* C774 (51060) */ - 3343, /* C775 (51061) */ - 3343, /* C776 (51062) */ - 3343, /* C777 (51063) */ - 3343, /* C778 (51064) */ - 3343, /* C779 (51065) */ - 3343, /* C77A (51066) */ - 3343, /* C77B (51067) */ - 3343, /* C77C (51068) */ - 3343, /* C77D (51069) */ - 3343, /* C77E (51070) */ - 3343, /* C77F (51071) */ - 3343, /* C780 (51072) */ - 3343, /* C781 (51073) */ - 3343, /* C782 (51074) */ - 3343, /* C783 (51075) */ - 3343, /* C784 (51076) */ - 3343, /* C785 (51077) */ - 3343, /* C786 (51078) */ - 3343, /* C787 (51079) */ - 3343, /* C788 (51080) */ - 3343, /* C789 (51081) */ - 3343, /* C78A (51082) */ - 3343, /* C78B (51083) */ - 3343, /* C78C (51084) */ - 3343, /* C78D (51085) */ - 3343, /* C78E (51086) */ - 3343, /* C78F (51087) */ - 3343, /* C790 (51088) */ - 3343, /* C791 (51089) */ - 3343, /* C792 (51090) */ - 3343, /* C793 (51091) */ - 3343, /* C794 (51092) */ - 3343, /* C795 (51093) */ - 3343, /* C796 (51094) */ - 3343, /* C797 (51095) */ - 3343, /* C798 (51096) */ - 3343, /* C799 (51097) */ - 3343, /* C79A (51098) */ - 3343, /* C79B (51099) */ - 3343, /* C79C (51100) */ - 3343, /* C79D (51101) */ - 3343, /* C79E (51102) */ - 3343, /* C79F (51103) */ - 3343, /* C7A0 (51104) */ - 3343, /* C7A1 (51105) */ - 3343, /* C7A2 (51106) */ - 3343, /* C7A3 (51107) */ - 3343, /* C7A4 (51108) */ - 3343, /* C7A5 (51109) */ - 3343, /* C7A6 (51110) */ - 3343, /* C7A7 (51111) */ - 3343, /* C7A8 (51112) */ - 3343, /* C7A9 (51113) */ - 3343, /* C7AA (51114) */ - 3343, /* C7AB (51115) */ - 3343, /* C7AC (51116) */ - 3343, /* C7AD (51117) */ - 3343, /* C7AE (51118) */ - 3343, /* C7AF (51119) */ - 3343, /* C7B0 (51120) */ - 3343, /* C7B1 (51121) */ - 3343, /* C7B2 (51122) */ - 3343, /* C7B3 (51123) */ - 3343, /* C7B4 (51124) */ - 3343, /* C7B5 (51125) */ - 3343, /* C7B6 (51126) */ - 3343, /* C7B7 (51127) */ - 3343, /* C7B8 (51128) */ - 3343, /* C7B9 (51129) */ - 3343, /* C7BA (51130) */ - 3343, /* C7BB (51131) */ - 3343, /* C7BC (51132) */ - 3343, /* C7BD (51133) */ - 3343, /* C7BE (51134) */ - 3343, /* C7BF (51135) */ - 3343, /* C7C0 (51136) */ - 3343, /* C7C1 (51137) */ - 3343, /* C7C2 (51138) */ - 3343, /* C7C3 (51139) */ - 3343, /* C7C4 (51140) */ - 3343, /* C7C5 (51141) */ - 3343, /* C7C6 (51142) */ - 3343, /* C7C7 (51143) */ - 3343, /* C7C8 (51144) */ - 3343, /* C7C9 (51145) */ - 3343, /* C7CA (51146) */ - 3343, /* C7CB (51147) */ - 3343, /* C7CC (51148) */ - 3343, /* C7CD (51149) */ - 3343, /* C7CE (51150) */ - 3343, /* C7CF (51151) */ - 3343, /* C7D0 (51152) */ - 3343, /* C7D1 (51153) */ - 3343, /* C7D2 (51154) */ - 3343, /* C7D3 (51155) */ - 3343, /* C7D4 (51156) */ - 3343, /* C7D5 (51157) */ - 3343, /* C7D6 (51158) */ - 3343, /* C7D7 (51159) */ - 3343, /* C7D8 (51160) */ - 3343, /* C7D9 (51161) */ - 3343, /* C7DA (51162) */ - 3343, /* C7DB (51163) */ - 3343, /* C7DC (51164) */ - 3343, /* C7DD (51165) */ - 3343, /* C7DE (51166) */ - 3343, /* C7DF (51167) */ - 3343, /* C7E0 (51168) */ - 3343, /* C7E1 (51169) */ - 3343, /* C7E2 (51170) */ - 3343, /* C7E3 (51171) */ - 3343, /* C7E4 (51172) */ - 3343, /* C7E5 (51173) */ - 3343, /* C7E6 (51174) */ - 3343, /* C7E7 (51175) */ - 3343, /* C7E8 (51176) */ - 3343, /* C7E9 (51177) */ - 3343, /* C7EA (51178) */ - 3343, /* C7EB (51179) */ - 3343, /* C7EC (51180) */ - 3343, /* C7ED (51181) */ - 3343, /* C7EE (51182) */ - 3343, /* C7EF (51183) */ - 3343, /* C7F0 (51184) */ - 3343, /* C7F1 (51185) */ - 3343, /* C7F2 (51186) */ - 3343, /* C7F3 (51187) */ - 3343, /* C7F4 (51188) */ - 3343, /* C7F5 (51189) */ - 3343, /* C7F6 (51190) */ - 3343, /* C7F7 (51191) */ - 3343, /* C7F8 (51192) */ - 3343, /* C7F9 (51193) */ - 3343, /* C7FA (51194) */ - 3343, /* C7FB (51195) */ - 3343, /* C7FC (51196) */ - 3343, /* C7FD (51197) */ - 3343, /* C7FE (51198) */ - 3343, /* C7FF (51199) */ - 3343, /* C800 (51200) */ - 3343, /* C801 (51201) */ - 3343, /* C802 (51202) */ - 3343, /* C803 (51203) */ - 3343, /* C804 (51204) */ - 3343, /* C805 (51205) */ - 3343, /* C806 (51206) */ - 3343, /* C807 (51207) */ - 3343, /* C808 (51208) */ - 3343, /* C809 (51209) */ - 3343, /* C80A (51210) */ - 3343, /* C80B (51211) */ - 3343, /* C80C (51212) */ - 3343, /* C80D (51213) */ - 3343, /* C80E (51214) */ - 3343, /* C80F (51215) */ - 3343, /* C810 (51216) */ - 3343, /* C811 (51217) */ - 3343, /* C812 (51218) */ - 3343, /* C813 (51219) */ - 3343, /* C814 (51220) */ - 3343, /* C815 (51221) */ - 3343, /* C816 (51222) */ - 3343, /* C817 (51223) */ - 3343, /* C818 (51224) */ - 3343, /* C819 (51225) */ - 3343, /* C81A (51226) */ - 3343, /* C81B (51227) */ - 3343, /* C81C (51228) */ - 3343, /* C81D (51229) */ - 3343, /* C81E (51230) */ - 3343, /* C81F (51231) */ - 3343, /* C820 (51232) */ - 3343, /* C821 (51233) */ - 3343, /* C822 (51234) */ - 3343, /* C823 (51235) */ - 3343, /* C824 (51236) */ - 3343, /* C825 (51237) */ - 3343, /* C826 (51238) */ - 3343, /* C827 (51239) */ - 3343, /* C828 (51240) */ - 3343, /* C829 (51241) */ - 3343, /* C82A (51242) */ - 3343, /* C82B (51243) */ - 3343, /* C82C (51244) */ - 3343, /* C82D (51245) */ - 3343, /* C82E (51246) */ - 3343, /* C82F (51247) */ - 3343, /* C830 (51248) */ - 3343, /* C831 (51249) */ - 3343, /* C832 (51250) */ - 3343, /* C833 (51251) */ - 3343, /* C834 (51252) */ - 3343, /* C835 (51253) */ - 3343, /* C836 (51254) */ - 3343, /* C837 (51255) */ - 3343, /* C838 (51256) */ - 3343, /* C839 (51257) */ - 3343, /* C83A (51258) */ - 3343, /* C83B (51259) */ - 3343, /* C83C (51260) */ - 3343, /* C83D (51261) */ - 3343, /* C83E (51262) */ - 3343, /* C83F (51263) */ - 3343, /* C840 (51264) */ - 3343, /* C841 (51265) */ - 3343, /* C842 (51266) */ - 3343, /* C843 (51267) */ - 3343, /* C844 (51268) */ - 3343, /* C845 (51269) */ - 3343, /* C846 (51270) */ - 3343, /* C847 (51271) */ - 3343, /* C848 (51272) */ - 3343, /* C849 (51273) */ - 3343, /* C84A (51274) */ - 3343, /* C84B (51275) */ - 3343, /* C84C (51276) */ - 3343, /* C84D (51277) */ - 3343, /* C84E (51278) */ - 3343, /* C84F (51279) */ - 3343, /* C850 (51280) */ - 3343, /* C851 (51281) */ - 3343, /* C852 (51282) */ - 3343, /* C853 (51283) */ - 3343, /* C854 (51284) */ - 3343, /* C855 (51285) */ - 3343, /* C856 (51286) */ - 3343, /* C857 (51287) */ - 3343, /* C858 (51288) */ - 3343, /* C859 (51289) */ - 3343, /* C85A (51290) */ - 3343, /* C85B (51291) */ - 3343, /* C85C (51292) */ - 3343, /* C85D (51293) */ - 3343, /* C85E (51294) */ - 3343, /* C85F (51295) */ - 3343, /* C860 (51296) */ - 3343, /* C861 (51297) */ - 3343, /* C862 (51298) */ - 3343, /* C863 (51299) */ - 3343, /* C864 (51300) */ - 3343, /* C865 (51301) */ - 3343, /* C866 (51302) */ - 3343, /* C867 (51303) */ - 3343, /* C868 (51304) */ - 3343, /* C869 (51305) */ - 3343, /* C86A (51306) */ - 3343, /* C86B (51307) */ - 3343, /* C86C (51308) */ - 3343, /* C86D (51309) */ - 3343, /* C86E (51310) */ - 3343, /* C86F (51311) */ - 3343, /* C870 (51312) */ - 3343, /* C871 (51313) */ - 3343, /* C872 (51314) */ - 3343, /* C873 (51315) */ - 3343, /* C874 (51316) */ - 3343, /* C875 (51317) */ - 3343, /* C876 (51318) */ - 3343, /* C877 (51319) */ - 3343, /* C878 (51320) */ - 3343, /* C879 (51321) */ - 3343, /* C87A (51322) */ - 3343, /* C87B (51323) */ - 3343, /* C87C (51324) */ - 3343, /* C87D (51325) */ - 3343, /* C87E (51326) */ - 3343, /* C87F (51327) */ - 3343, /* C880 (51328) */ - 3343, /* C881 (51329) */ - 3343, /* C882 (51330) */ - 3343, /* C883 (51331) */ - 3343, /* C884 (51332) */ - 3343, /* C885 (51333) */ - 3343, /* C886 (51334) */ - 3343, /* C887 (51335) */ - 3343, /* C888 (51336) */ - 3343, /* C889 (51337) */ - 3343, /* C88A (51338) */ - 3343, /* C88B (51339) */ - 3343, /* C88C (51340) */ - 3343, /* C88D (51341) */ - 3343, /* C88E (51342) */ - 3343, /* C88F (51343) */ - 3343, /* C890 (51344) */ - 3343, /* C891 (51345) */ - 3343, /* C892 (51346) */ - 3343, /* C893 (51347) */ - 3343, /* C894 (51348) */ - 3343, /* C895 (51349) */ - 3343, /* C896 (51350) */ - 3343, /* C897 (51351) */ - 3343, /* C898 (51352) */ - 3343, /* C899 (51353) */ - 3343, /* C89A (51354) */ - 3343, /* C89B (51355) */ - 3343, /* C89C (51356) */ - 3343, /* C89D (51357) */ - 3343, /* C89E (51358) */ - 3343, /* C89F (51359) */ - 3343, /* C8A0 (51360) */ - 3343, /* C8A1 (51361) */ - 3343, /* C8A2 (51362) */ - 3343, /* C8A3 (51363) */ - 3343, /* C8A4 (51364) */ - 3343, /* C8A5 (51365) */ - 3343, /* C8A6 (51366) */ - 3343, /* C8A7 (51367) */ - 3343, /* C8A8 (51368) */ - 3343, /* C8A9 (51369) */ - 3343, /* C8AA (51370) */ - 3343, /* C8AB (51371) */ - 3343, /* C8AC (51372) */ - 3343, /* C8AD (51373) */ - 3343, /* C8AE (51374) */ - 3343, /* C8AF (51375) */ - 3343, /* C8B0 (51376) */ - 3343, /* C8B1 (51377) */ - 3343, /* C8B2 (51378) */ - 3343, /* C8B3 (51379) */ - 3343, /* C8B4 (51380) */ - 3343, /* C8B5 (51381) */ - 3343, /* C8B6 (51382) */ - 3343, /* C8B7 (51383) */ - 3343, /* C8B8 (51384) */ - 3343, /* C8B9 (51385) */ - 3343, /* C8BA (51386) */ - 3343, /* C8BB (51387) */ - 3343, /* C8BC (51388) */ - 3343, /* C8BD (51389) */ - 3343, /* C8BE (51390) */ - 3343, /* C8BF (51391) */ - 3343, /* C8C0 (51392) */ - 3343, /* C8C1 (51393) */ - 3343, /* C8C2 (51394) */ - 3343, /* C8C3 (51395) */ - 3343, /* C8C4 (51396) */ - 3343, /* C8C5 (51397) */ - 3343, /* C8C6 (51398) */ - 3343, /* C8C7 (51399) */ - 3343, /* C8C8 (51400) */ - 3343, /* C8C9 (51401) */ - 3343, /* C8CA (51402) */ - 3343, /* C8CB (51403) */ - 3343, /* C8CC (51404) */ - 3343, /* C8CD (51405) */ - 3343, /* C8CE (51406) */ - 3343, /* C8CF (51407) */ - 3343, /* C8D0 (51408) */ - 3343, /* C8D1 (51409) */ - 3343, /* C8D2 (51410) */ - 3343, /* C8D3 (51411) */ - 3343, /* C8D4 (51412) */ - 3343, /* C8D5 (51413) */ - 3343, /* C8D6 (51414) */ - 3343, /* C8D7 (51415) */ - 3343, /* C8D8 (51416) */ - 3343, /* C8D9 (51417) */ - 3343, /* C8DA (51418) */ - 3343, /* C8DB (51419) */ - 3343, /* C8DC (51420) */ - 3343, /* C8DD (51421) */ - 3343, /* C8DE (51422) */ - 3343, /* C8DF (51423) */ - 3343, /* C8E0 (51424) */ - 3343, /* C8E1 (51425) */ - 3343, /* C8E2 (51426) */ - 3343, /* C8E3 (51427) */ - 3343, /* C8E4 (51428) */ - 3343, /* C8E5 (51429) */ - 3343, /* C8E6 (51430) */ - 3343, /* C8E7 (51431) */ - 3343, /* C8E8 (51432) */ - 3343, /* C8E9 (51433) */ - 3343, /* C8EA (51434) */ - 3343, /* C8EB (51435) */ - 3343, /* C8EC (51436) */ - 3343, /* C8ED (51437) */ - 3343, /* C8EE (51438) */ - 3343, /* C8EF (51439) */ - 3343, /* C8F0 (51440) */ - 3343, /* C8F1 (51441) */ - 3343, /* C8F2 (51442) */ - 3343, /* C8F3 (51443) */ - 3343, /* C8F4 (51444) */ - 3343, /* C8F5 (51445) */ - 3343, /* C8F6 (51446) */ - 3343, /* C8F7 (51447) */ - 3343, /* C8F8 (51448) */ - 3343, /* C8F9 (51449) */ - 3343, /* C8FA (51450) */ - 3343, /* C8FB (51451) */ - 3343, /* C8FC (51452) */ - 3343, /* C8FD (51453) */ - 3343, /* C8FE (51454) */ - 3343, /* C8FF (51455) */ - 3343, /* C900 (51456) */ - 3343, /* C901 (51457) */ - 3343, /* C902 (51458) */ - 3343, /* C903 (51459) */ - 3343, /* C904 (51460) */ - 3343, /* C905 (51461) */ - 3343, /* C906 (51462) */ - 3343, /* C907 (51463) */ - 3343, /* C908 (51464) */ - 3343, /* C909 (51465) */ - 3343, /* C90A (51466) */ - 3343, /* C90B (51467) */ - 3343, /* C90C (51468) */ - 3343, /* C90D (51469) */ - 3343, /* C90E (51470) */ - 3343, /* C90F (51471) */ - 3343, /* C910 (51472) */ - 3343, /* C911 (51473) */ - 3343, /* C912 (51474) */ - 3343, /* C913 (51475) */ - 3343, /* C914 (51476) */ - 3343, /* C915 (51477) */ - 3343, /* C916 (51478) */ - 3343, /* C917 (51479) */ - 3343, /* C918 (51480) */ - 3343, /* C919 (51481) */ - 3343, /* C91A (51482) */ - 3343, /* C91B (51483) */ - 3343, /* C91C (51484) */ - 3343, /* C91D (51485) */ - 3343, /* C91E (51486) */ - 3343, /* C91F (51487) */ - 3343, /* C920 (51488) */ - 3343, /* C921 (51489) */ - 3343, /* C922 (51490) */ - 3343, /* C923 (51491) */ - 3343, /* C924 (51492) */ - 3343, /* C925 (51493) */ - 3343, /* C926 (51494) */ - 3343, /* C927 (51495) */ - 3343, /* C928 (51496) */ - 3343, /* C929 (51497) */ - 3343, /* C92A (51498) */ - 3343, /* C92B (51499) */ - 3343, /* C92C (51500) */ - 3343, /* C92D (51501) */ - 3343, /* C92E (51502) */ - 3343, /* C92F (51503) */ - 3343, /* C930 (51504) */ - 3343, /* C931 (51505) */ - 3343, /* C932 (51506) */ - 3343, /* C933 (51507) */ - 3343, /* C934 (51508) */ - 3343, /* C935 (51509) */ - 3343, /* C936 (51510) */ - 3343, /* C937 (51511) */ - 3343, /* C938 (51512) */ - 3343, /* C939 (51513) */ - 3343, /* C93A (51514) */ - 3343, /* C93B (51515) */ - 3343, /* C93C (51516) */ - 3343, /* C93D (51517) */ - 3343, /* C93E (51518) */ - 3343, /* C93F (51519) */ - 3343, /* C940 (51520) */ - 3343, /* C941 (51521) */ - 3343, /* C942 (51522) */ - 3343, /* C943 (51523) */ - 3343, /* C944 (51524) */ - 3343, /* C945 (51525) */ - 3343, /* C946 (51526) */ - 3343, /* C947 (51527) */ - 3343, /* C948 (51528) */ - 3343, /* C949 (51529) */ - 3343, /* C94A (51530) */ - 3343, /* C94B (51531) */ - 3343, /* C94C (51532) */ - 3343, /* C94D (51533) */ - 3343, /* C94E (51534) */ - 3343, /* C94F (51535) */ - 3343, /* C950 (51536) */ - 3343, /* C951 (51537) */ - 3343, /* C952 (51538) */ - 3343, /* C953 (51539) */ - 3343, /* C954 (51540) */ - 3343, /* C955 (51541) */ - 3343, /* C956 (51542) */ - 3343, /* C957 (51543) */ - 3343, /* C958 (51544) */ - 3343, /* C959 (51545) */ - 3343, /* C95A (51546) */ - 3343, /* C95B (51547) */ - 3343, /* C95C (51548) */ - 3343, /* C95D (51549) */ - 3343, /* C95E (51550) */ - 3343, /* C95F (51551) */ - 3343, /* C960 (51552) */ - 3343, /* C961 (51553) */ - 3343, /* C962 (51554) */ - 3343, /* C963 (51555) */ - 3343, /* C964 (51556) */ - 3343, /* C965 (51557) */ - 3343, /* C966 (51558) */ - 3343, /* C967 (51559) */ - 3343, /* C968 (51560) */ - 3343, /* C969 (51561) */ - 3343, /* C96A (51562) */ - 3343, /* C96B (51563) */ - 3343, /* C96C (51564) */ - 3343, /* C96D (51565) */ - 3343, /* C96E (51566) */ - 3343, /* C96F (51567) */ - 3343, /* C970 (51568) */ - 3343, /* C971 (51569) */ - 3343, /* C972 (51570) */ - 3343, /* C973 (51571) */ - 3343, /* C974 (51572) */ - 3343, /* C975 (51573) */ - 3343, /* C976 (51574) */ - 3343, /* C977 (51575) */ - 3343, /* C978 (51576) */ - 3343, /* C979 (51577) */ - 3343, /* C97A (51578) */ - 3343, /* C97B (51579) */ - 3343, /* C97C (51580) */ - 3343, /* C97D (51581) */ - 3343, /* C97E (51582) */ - 3343, /* C97F (51583) */ - 3343, /* C980 (51584) */ - 3343, /* C981 (51585) */ - 3343, /* C982 (51586) */ - 3343, /* C983 (51587) */ - 3343, /* C984 (51588) */ - 3343, /* C985 (51589) */ - 3343, /* C986 (51590) */ - 3343, /* C987 (51591) */ - 3343, /* C988 (51592) */ - 3343, /* C989 (51593) */ - 3343, /* C98A (51594) */ - 3343, /* C98B (51595) */ - 3343, /* C98C (51596) */ - 3343, /* C98D (51597) */ - 3343, /* C98E (51598) */ - 3343, /* C98F (51599) */ - 3343, /* C990 (51600) */ - 3343, /* C991 (51601) */ - 3343, /* C992 (51602) */ - 3343, /* C993 (51603) */ - 3343, /* C994 (51604) */ - 3343, /* C995 (51605) */ - 3343, /* C996 (51606) */ - 3343, /* C997 (51607) */ - 3343, /* C998 (51608) */ - 3343, /* C999 (51609) */ - 3343, /* C99A (51610) */ - 3343, /* C99B (51611) */ - 3343, /* C99C (51612) */ - 3343, /* C99D (51613) */ - 3343, /* C99E (51614) */ - 3343, /* C99F (51615) */ - 3343, /* C9A0 (51616) */ - 3343, /* C9A1 (51617) */ - 3343, /* C9A2 (51618) */ - 3343, /* C9A3 (51619) */ - 3343, /* C9A4 (51620) */ - 3343, /* C9A5 (51621) */ - 3343, /* C9A6 (51622) */ - 3343, /* C9A7 (51623) */ - 3343, /* C9A8 (51624) */ - 3343, /* C9A9 (51625) */ - 3343, /* C9AA (51626) */ - 3343, /* C9AB (51627) */ - 3343, /* C9AC (51628) */ - 3343, /* C9AD (51629) */ - 3343, /* C9AE (51630) */ - 3343, /* C9AF (51631) */ - 3343, /* C9B0 (51632) */ - 3343, /* C9B1 (51633) */ - 3343, /* C9B2 (51634) */ - 3343, /* C9B3 (51635) */ - 3343, /* C9B4 (51636) */ - 3343, /* C9B5 (51637) */ - 3343, /* C9B6 (51638) */ - 3343, /* C9B7 (51639) */ - 3343, /* C9B8 (51640) */ - 3343, /* C9B9 (51641) */ - 3343, /* C9BA (51642) */ - 3343, /* C9BB (51643) */ - 3343, /* C9BC (51644) */ - 3343, /* C9BD (51645) */ - 3343, /* C9BE (51646) */ - 3343, /* C9BF (51647) */ - 3343, /* C9C0 (51648) */ - 3343, /* C9C1 (51649) */ - 3343, /* C9C2 (51650) */ - 3343, /* C9C3 (51651) */ - 3343, /* C9C4 (51652) */ - 3343, /* C9C5 (51653) */ - 3343, /* C9C6 (51654) */ - 3343, /* C9C7 (51655) */ - 3343, /* C9C8 (51656) */ - 3343, /* C9C9 (51657) */ - 3343, /* C9CA (51658) */ - 3343, /* C9CB (51659) */ - 3343, /* C9CC (51660) */ - 3343, /* C9CD (51661) */ - 3343, /* C9CE (51662) */ - 3343, /* C9CF (51663) */ - 3343, /* C9D0 (51664) */ - 3343, /* C9D1 (51665) */ - 3343, /* C9D2 (51666) */ - 3343, /* C9D3 (51667) */ - 3343, /* C9D4 (51668) */ - 3343, /* C9D5 (51669) */ - 3343, /* C9D6 (51670) */ - 3343, /* C9D7 (51671) */ - 3343, /* C9D8 (51672) */ - 3343, /* C9D9 (51673) */ - 3343, /* C9DA (51674) */ - 3343, /* C9DB (51675) */ - 3343, /* C9DC (51676) */ - 3343, /* C9DD (51677) */ - 3343, /* C9DE (51678) */ - 3343, /* C9DF (51679) */ - 3343, /* C9E0 (51680) */ - 3343, /* C9E1 (51681) */ - 3343, /* C9E2 (51682) */ - 3343, /* C9E3 (51683) */ - 3343, /* C9E4 (51684) */ - 3343, /* C9E5 (51685) */ - 3343, /* C9E6 (51686) */ - 3343, /* C9E7 (51687) */ - 3343, /* C9E8 (51688) */ - 3343, /* C9E9 (51689) */ - 3343, /* C9EA (51690) */ - 3343, /* C9EB (51691) */ - 3343, /* C9EC (51692) */ - 3343, /* C9ED (51693) */ - 3343, /* C9EE (51694) */ - 3343, /* C9EF (51695) */ - 3343, /* C9F0 (51696) */ - 3343, /* C9F1 (51697) */ - 3343, /* C9F2 (51698) */ - 3343, /* C9F3 (51699) */ - 3343, /* C9F4 (51700) */ - 3343, /* C9F5 (51701) */ - 3343, /* C9F6 (51702) */ - 3343, /* C9F7 (51703) */ - 3343, /* C9F8 (51704) */ - 3343, /* C9F9 (51705) */ - 3343, /* C9FA (51706) */ - 3343, /* C9FB (51707) */ - 3343, /* C9FC (51708) */ - 3343, /* C9FD (51709) */ - 3343, /* C9FE (51710) */ - 3343, /* C9FF (51711) */ - 3343, /* CA00 (51712) */ - 3343, /* CA01 (51713) */ - 3343, /* CA02 (51714) */ - 3343, /* CA03 (51715) */ - 3343, /* CA04 (51716) */ - 3343, /* CA05 (51717) */ - 3343, /* CA06 (51718) */ - 3343, /* CA07 (51719) */ - 3343, /* CA08 (51720) */ - 3343, /* CA09 (51721) */ - 3343, /* CA0A (51722) */ - 3343, /* CA0B (51723) */ - 3343, /* CA0C (51724) */ - 3343, /* CA0D (51725) */ - 3343, /* CA0E (51726) */ - 3343, /* CA0F (51727) */ - 3343, /* CA10 (51728) */ - 3343, /* CA11 (51729) */ - 3343, /* CA12 (51730) */ - 3343, /* CA13 (51731) */ - 3343, /* CA14 (51732) */ - 3343, /* CA15 (51733) */ - 3343, /* CA16 (51734) */ - 3343, /* CA17 (51735) */ - 3343, /* CA18 (51736) */ - 3343, /* CA19 (51737) */ - 3343, /* CA1A (51738) */ - 3343, /* CA1B (51739) */ - 3343, /* CA1C (51740) */ - 3343, /* CA1D (51741) */ - 3343, /* CA1E (51742) */ - 3343, /* CA1F (51743) */ - 3343, /* CA20 (51744) */ - 3343, /* CA21 (51745) */ - 3343, /* CA22 (51746) */ - 3343, /* CA23 (51747) */ - 3343, /* CA24 (51748) */ - 3343, /* CA25 (51749) */ - 3343, /* CA26 (51750) */ - 3343, /* CA27 (51751) */ - 3343, /* CA28 (51752) */ - 3343, /* CA29 (51753) */ - 3343, /* CA2A (51754) */ - 3343, /* CA2B (51755) */ - 3343, /* CA2C (51756) */ - 3343, /* CA2D (51757) */ - 3343, /* CA2E (51758) */ - 3343, /* CA2F (51759) */ - 3343, /* CA30 (51760) */ - 3343, /* CA31 (51761) */ - 3343, /* CA32 (51762) */ - 3343, /* CA33 (51763) */ - 3343, /* CA34 (51764) */ - 3343, /* CA35 (51765) */ - 3343, /* CA36 (51766) */ - 3343, /* CA37 (51767) */ - 3343, /* CA38 (51768) */ - 3343, /* CA39 (51769) */ - 3343, /* CA3A (51770) */ - 3343, /* CA3B (51771) */ - 3343, /* CA3C (51772) */ - 3343, /* CA3D (51773) */ - 3343, /* CA3E (51774) */ - 3343, /* CA3F (51775) */ - 3343, /* CA40 (51776) */ - 3343, /* CA41 (51777) */ - 3343, /* CA42 (51778) */ - 3343, /* CA43 (51779) */ - 3343, /* CA44 (51780) */ - 3343, /* CA45 (51781) */ - 3343, /* CA46 (51782) */ - 3343, /* CA47 (51783) */ - 3343, /* CA48 (51784) */ - 3343, /* CA49 (51785) */ - 3343, /* CA4A (51786) */ - 3343, /* CA4B (51787) */ - 3343, /* CA4C (51788) */ - 3343, /* CA4D (51789) */ - 3343, /* CA4E (51790) */ - 3343, /* CA4F (51791) */ - 3343, /* CA50 (51792) */ - 3343, /* CA51 (51793) */ - 3343, /* CA52 (51794) */ - 3343, /* CA53 (51795) */ - 3343, /* CA54 (51796) */ - 3343, /* CA55 (51797) */ - 3343, /* CA56 (51798) */ - 3343, /* CA57 (51799) */ - 3343, /* CA58 (51800) */ - 3343, /* CA59 (51801) */ - 3343, /* CA5A (51802) */ - 3343, /* CA5B (51803) */ - 3343, /* CA5C (51804) */ - 3343, /* CA5D (51805) */ - 3343, /* CA5E (51806) */ - 3343, /* CA5F (51807) */ - 3343, /* CA60 (51808) */ - 3343, /* CA61 (51809) */ - 3343, /* CA62 (51810) */ - 3343, /* CA63 (51811) */ - 3343, /* CA64 (51812) */ - 3343, /* CA65 (51813) */ - 3343, /* CA66 (51814) */ - 3343, /* CA67 (51815) */ - 3343, /* CA68 (51816) */ - 3343, /* CA69 (51817) */ - 3343, /* CA6A (51818) */ - 3343, /* CA6B (51819) */ - 3343, /* CA6C (51820) */ - 3343, /* CA6D (51821) */ - 3343, /* CA6E (51822) */ - 3343, /* CA6F (51823) */ - 3343, /* CA70 (51824) */ - 3343, /* CA71 (51825) */ - 3343, /* CA72 (51826) */ - 3343, /* CA73 (51827) */ - 3343, /* CA74 (51828) */ - 3343, /* CA75 (51829) */ - 3343, /* CA76 (51830) */ - 3343, /* CA77 (51831) */ - 3343, /* CA78 (51832) */ - 3343, /* CA79 (51833) */ - 3343, /* CA7A (51834) */ - 3343, /* CA7B (51835) */ - 3343, /* CA7C (51836) */ - 3343, /* CA7D (51837) */ - 3343, /* CA7E (51838) */ - 3343, /* CA7F (51839) */ - 3343, /* CA80 (51840) */ - 3343, /* CA81 (51841) */ - 3343, /* CA82 (51842) */ - 3343, /* CA83 (51843) */ - 3343, /* CA84 (51844) */ - 3343, /* CA85 (51845) */ - 3343, /* CA86 (51846) */ - 3343, /* CA87 (51847) */ - 3343, /* CA88 (51848) */ - 3343, /* CA89 (51849) */ - 3343, /* CA8A (51850) */ - 3343, /* CA8B (51851) */ - 3343, /* CA8C (51852) */ - 3343, /* CA8D (51853) */ - 3343, /* CA8E (51854) */ - 3343, /* CA8F (51855) */ - 3343, /* CA90 (51856) */ - 3343, /* CA91 (51857) */ - 3343, /* CA92 (51858) */ - 3343, /* CA93 (51859) */ - 3343, /* CA94 (51860) */ - 3343, /* CA95 (51861) */ - 3343, /* CA96 (51862) */ - 3343, /* CA97 (51863) */ - 3343, /* CA98 (51864) */ - 3343, /* CA99 (51865) */ - 3343, /* CA9A (51866) */ - 3343, /* CA9B (51867) */ - 3343, /* CA9C (51868) */ - 3343, /* CA9D (51869) */ - 3343, /* CA9E (51870) */ - 3343, /* CA9F (51871) */ - 3343, /* CAA0 (51872) */ - 3343, /* CAA1 (51873) */ - 3343, /* CAA2 (51874) */ - 3343, /* CAA3 (51875) */ - 3343, /* CAA4 (51876) */ - 3343, /* CAA5 (51877) */ - 3343, /* CAA6 (51878) */ - 3343, /* CAA7 (51879) */ - 3343, /* CAA8 (51880) */ - 3343, /* CAA9 (51881) */ - 3343, /* CAAA (51882) */ - 3343, /* CAAB (51883) */ - 3343, /* CAAC (51884) */ - 3343, /* CAAD (51885) */ - 3343, /* CAAE (51886) */ - 3343, /* CAAF (51887) */ - 3343, /* CAB0 (51888) */ - 3343, /* CAB1 (51889) */ - 3343, /* CAB2 (51890) */ - 3343, /* CAB3 (51891) */ - 3343, /* CAB4 (51892) */ - 3343, /* CAB5 (51893) */ - 3343, /* CAB6 (51894) */ - 3343, /* CAB7 (51895) */ - 3343, /* CAB8 (51896) */ - 3343, /* CAB9 (51897) */ - 3343, /* CABA (51898) */ - 3343, /* CABB (51899) */ - 3343, /* CABC (51900) */ - 3343, /* CABD (51901) */ - 3343, /* CABE (51902) */ - 3343, /* CABF (51903) */ - 3343, /* CAC0 (51904) */ - 3343, /* CAC1 (51905) */ - 3343, /* CAC2 (51906) */ - 3343, /* CAC3 (51907) */ - 3343, /* CAC4 (51908) */ - 3343, /* CAC5 (51909) */ - 3343, /* CAC6 (51910) */ - 3343, /* CAC7 (51911) */ - 3343, /* CAC8 (51912) */ - 3343, /* CAC9 (51913) */ - 3343, /* CACA (51914) */ - 3343, /* CACB (51915) */ - 3343, /* CACC (51916) */ - 3343, /* CACD (51917) */ - 3343, /* CACE (51918) */ - 3343, /* CACF (51919) */ - 3343, /* CAD0 (51920) */ - 3343, /* CAD1 (51921) */ - 3343, /* CAD2 (51922) */ - 3343, /* CAD3 (51923) */ - 3343, /* CAD4 (51924) */ - 3343, /* CAD5 (51925) */ - 3343, /* CAD6 (51926) */ - 3343, /* CAD7 (51927) */ - 3343, /* CAD8 (51928) */ - 3343, /* CAD9 (51929) */ - 3343, /* CADA (51930) */ - 3343, /* CADB (51931) */ - 3343, /* CADC (51932) */ - 3343, /* CADD (51933) */ - 3343, /* CADE (51934) */ - 3343, /* CADF (51935) */ - 3343, /* CAE0 (51936) */ - 3343, /* CAE1 (51937) */ - 3343, /* CAE2 (51938) */ - 3343, /* CAE3 (51939) */ - 3343, /* CAE4 (51940) */ - 3343, /* CAE5 (51941) */ - 3343, /* CAE6 (51942) */ - 3343, /* CAE7 (51943) */ - 3343, /* CAE8 (51944) */ - 3343, /* CAE9 (51945) */ - 3343, /* CAEA (51946) */ - 3343, /* CAEB (51947) */ - 3343, /* CAEC (51948) */ - 3343, /* CAED (51949) */ - 3343, /* CAEE (51950) */ - 3343, /* CAEF (51951) */ - 3343, /* CAF0 (51952) */ - 3343, /* CAF1 (51953) */ - 3343, /* CAF2 (51954) */ - 3343, /* CAF3 (51955) */ - 3343, /* CAF4 (51956) */ - 3343, /* CAF5 (51957) */ - 3343, /* CAF6 (51958) */ - 3343, /* CAF7 (51959) */ - 3343, /* CAF8 (51960) */ - 3343, /* CAF9 (51961) */ - 3343, /* CAFA (51962) */ - 3343, /* CAFB (51963) */ - 3343, /* CAFC (51964) */ - 3343, /* CAFD (51965) */ - 3343, /* CAFE (51966) */ - 3343, /* CAFF (51967) */ - 3343, /* CB00 (51968) */ - 3343, /* CB01 (51969) */ - 3343, /* CB02 (51970) */ - 3343, /* CB03 (51971) */ - 3343, /* CB04 (51972) */ - 3343, /* CB05 (51973) */ - 3343, /* CB06 (51974) */ - 3343, /* CB07 (51975) */ - 3343, /* CB08 (51976) */ - 3343, /* CB09 (51977) */ - 3343, /* CB0A (51978) */ - 3343, /* CB0B (51979) */ - 3343, /* CB0C (51980) */ - 3343, /* CB0D (51981) */ - 3343, /* CB0E (51982) */ - 3343, /* CB0F (51983) */ - 3343, /* CB10 (51984) */ - 3343, /* CB11 (51985) */ - 3343, /* CB12 (51986) */ - 3343, /* CB13 (51987) */ - 3343, /* CB14 (51988) */ - 3343, /* CB15 (51989) */ - 3343, /* CB16 (51990) */ - 3343, /* CB17 (51991) */ - 3343, /* CB18 (51992) */ - 3343, /* CB19 (51993) */ - 3343, /* CB1A (51994) */ - 3343, /* CB1B (51995) */ - 3343, /* CB1C (51996) */ - 3343, /* CB1D (51997) */ - 3343, /* CB1E (51998) */ - 3343, /* CB1F (51999) */ - 3343, /* CB20 (52000) */ - 3343, /* CB21 (52001) */ - 3343, /* CB22 (52002) */ - 3343, /* CB23 (52003) */ - 3343, /* CB24 (52004) */ - 3343, /* CB25 (52005) */ - 3343, /* CB26 (52006) */ - 3343, /* CB27 (52007) */ - 3343, /* CB28 (52008) */ - 3343, /* CB29 (52009) */ - 3343, /* CB2A (52010) */ - 3343, /* CB2B (52011) */ - 3343, /* CB2C (52012) */ - 3343, /* CB2D (52013) */ - 3343, /* CB2E (52014) */ - 3343, /* CB2F (52015) */ - 3343, /* CB30 (52016) */ - 3343, /* CB31 (52017) */ - 3343, /* CB32 (52018) */ - 3343, /* CB33 (52019) */ - 3343, /* CB34 (52020) */ - 3343, /* CB35 (52021) */ - 3343, /* CB36 (52022) */ - 3343, /* CB37 (52023) */ - 3343, /* CB38 (52024) */ - 3343, /* CB39 (52025) */ - 3343, /* CB3A (52026) */ - 3343, /* CB3B (52027) */ - 3343, /* CB3C (52028) */ - 3343, /* CB3D (52029) */ - 3343, /* CB3E (52030) */ - 3343, /* CB3F (52031) */ - 3343, /* CB40 (52032) */ - 3343, /* CB41 (52033) */ - 3343, /* CB42 (52034) */ - 3343, /* CB43 (52035) */ - 3343, /* CB44 (52036) */ - 3343, /* CB45 (52037) */ - 3343, /* CB46 (52038) */ - 3343, /* CB47 (52039) */ - 3343, /* CB48 (52040) */ - 3343, /* CB49 (52041) */ - 3343, /* CB4A (52042) */ - 3343, /* CB4B (52043) */ - 3343, /* CB4C (52044) */ - 3343, /* CB4D (52045) */ - 3343, /* CB4E (52046) */ - 3343, /* CB4F (52047) */ - 3343, /* CB50 (52048) */ - 3343, /* CB51 (52049) */ - 3343, /* CB52 (52050) */ - 3343, /* CB53 (52051) */ - 3343, /* CB54 (52052) */ - 3343, /* CB55 (52053) */ - 3343, /* CB56 (52054) */ - 3343, /* CB57 (52055) */ - 3343, /* CB58 (52056) */ - 3343, /* CB59 (52057) */ - 3343, /* CB5A (52058) */ - 3343, /* CB5B (52059) */ - 3343, /* CB5C (52060) */ - 3343, /* CB5D (52061) */ - 3343, /* CB5E (52062) */ - 3343, /* CB5F (52063) */ - 3343, /* CB60 (52064) */ - 3343, /* CB61 (52065) */ - 3343, /* CB62 (52066) */ - 3343, /* CB63 (52067) */ - 3343, /* CB64 (52068) */ - 3343, /* CB65 (52069) */ - 3343, /* CB66 (52070) */ - 3343, /* CB67 (52071) */ - 3343, /* CB68 (52072) */ - 3343, /* CB69 (52073) */ - 3343, /* CB6A (52074) */ - 3343, /* CB6B (52075) */ - 3343, /* CB6C (52076) */ - 3343, /* CB6D (52077) */ - 3343, /* CB6E (52078) */ - 3343, /* CB6F (52079) */ - 3343, /* CB70 (52080) */ - 3343, /* CB71 (52081) */ - 3343, /* CB72 (52082) */ - 3343, /* CB73 (52083) */ - 3343, /* CB74 (52084) */ - 3343, /* CB75 (52085) */ - 3343, /* CB76 (52086) */ - 3343, /* CB77 (52087) */ - 3343, /* CB78 (52088) */ - 3343, /* CB79 (52089) */ - 3343, /* CB7A (52090) */ - 3343, /* CB7B (52091) */ - 3343, /* CB7C (52092) */ - 3343, /* CB7D (52093) */ - 3343, /* CB7E (52094) */ - 3343, /* CB7F (52095) */ - 3343, /* CB80 (52096) */ - 3343, /* CB81 (52097) */ - 3343, /* CB82 (52098) */ - 3343, /* CB83 (52099) */ - 3343, /* CB84 (52100) */ - 3343, /* CB85 (52101) */ - 3343, /* CB86 (52102) */ - 3343, /* CB87 (52103) */ - 3343, /* CB88 (52104) */ - 3343, /* CB89 (52105) */ - 3343, /* CB8A (52106) */ - 3343, /* CB8B (52107) */ - 3343, /* CB8C (52108) */ - 3343, /* CB8D (52109) */ - 3343, /* CB8E (52110) */ - 3343, /* CB8F (52111) */ - 3343, /* CB90 (52112) */ - 3343, /* CB91 (52113) */ - 3343, /* CB92 (52114) */ - 3343, /* CB93 (52115) */ - 3343, /* CB94 (52116) */ - 3343, /* CB95 (52117) */ - 3343, /* CB96 (52118) */ - 3343, /* CB97 (52119) */ - 3343, /* CB98 (52120) */ - 3343, /* CB99 (52121) */ - 3343, /* CB9A (52122) */ - 3343, /* CB9B (52123) */ - 3343, /* CB9C (52124) */ - 3343, /* CB9D (52125) */ - 3343, /* CB9E (52126) */ - 3343, /* CB9F (52127) */ - 3343, /* CBA0 (52128) */ - 3343, /* CBA1 (52129) */ - 3343, /* CBA2 (52130) */ - 3343, /* CBA3 (52131) */ - 3343, /* CBA4 (52132) */ - 3343, /* CBA5 (52133) */ - 3343, /* CBA6 (52134) */ - 3343, /* CBA7 (52135) */ - 3343, /* CBA8 (52136) */ - 3343, /* CBA9 (52137) */ - 3343, /* CBAA (52138) */ - 3343, /* CBAB (52139) */ - 3343, /* CBAC (52140) */ - 3343, /* CBAD (52141) */ - 3343, /* CBAE (52142) */ - 3343, /* CBAF (52143) */ - 3343, /* CBB0 (52144) */ - 3343, /* CBB1 (52145) */ - 3343, /* CBB2 (52146) */ - 3343, /* CBB3 (52147) */ - 3343, /* CBB4 (52148) */ - 3343, /* CBB5 (52149) */ - 3343, /* CBB6 (52150) */ - 3343, /* CBB7 (52151) */ - 3343, /* CBB8 (52152) */ - 3343, /* CBB9 (52153) */ - 3343, /* CBBA (52154) */ - 3343, /* CBBB (52155) */ - 3343, /* CBBC (52156) */ - 3343, /* CBBD (52157) */ - 3343, /* CBBE (52158) */ - 3343, /* CBBF (52159) */ - 3343, /* CBC0 (52160) */ - 3343, /* CBC1 (52161) */ - 3343, /* CBC2 (52162) */ - 3343, /* CBC3 (52163) */ - 3343, /* CBC4 (52164) */ - 3343, /* CBC5 (52165) */ - 3343, /* CBC6 (52166) */ - 3343, /* CBC7 (52167) */ - 3343, /* CBC8 (52168) */ - 3343, /* CBC9 (52169) */ - 3343, /* CBCA (52170) */ - 3343, /* CBCB (52171) */ - 3343, /* CBCC (52172) */ - 3343, /* CBCD (52173) */ - 3343, /* CBCE (52174) */ - 3343, /* CBCF (52175) */ - 3343, /* CBD0 (52176) */ - 3343, /* CBD1 (52177) */ - 3343, /* CBD2 (52178) */ - 3343, /* CBD3 (52179) */ - 3343, /* CBD4 (52180) */ - 3343, /* CBD5 (52181) */ - 3343, /* CBD6 (52182) */ - 3343, /* CBD7 (52183) */ - 3343, /* CBD8 (52184) */ - 3343, /* CBD9 (52185) */ - 3343, /* CBDA (52186) */ - 3343, /* CBDB (52187) */ - 3343, /* CBDC (52188) */ - 3343, /* CBDD (52189) */ - 3343, /* CBDE (52190) */ - 3343, /* CBDF (52191) */ - 3343, /* CBE0 (52192) */ - 3343, /* CBE1 (52193) */ - 3343, /* CBE2 (52194) */ - 3343, /* CBE3 (52195) */ - 3343, /* CBE4 (52196) */ - 3343, /* CBE5 (52197) */ - 3343, /* CBE6 (52198) */ - 3343, /* CBE7 (52199) */ - 3343, /* CBE8 (52200) */ - 3343, /* CBE9 (52201) */ - 3343, /* CBEA (52202) */ - 3343, /* CBEB (52203) */ - 3343, /* CBEC (52204) */ - 3343, /* CBED (52205) */ - 3343, /* CBEE (52206) */ - 3343, /* CBEF (52207) */ - 3343, /* CBF0 (52208) */ - 3343, /* CBF1 (52209) */ - 3343, /* CBF2 (52210) */ - 3343, /* CBF3 (52211) */ - 3343, /* CBF4 (52212) */ - 3343, /* CBF5 (52213) */ - 3343, /* CBF6 (52214) */ - 3343, /* CBF7 (52215) */ - 3343, /* CBF8 (52216) */ - 3343, /* CBF9 (52217) */ - 3343, /* CBFA (52218) */ - 3343, /* CBFB (52219) */ - 3343, /* CBFC (52220) */ - 3343, /* CBFD (52221) */ - 3343, /* CBFE (52222) */ - 3343, /* CBFF (52223) */ - 3343, /* CC00 (52224) */ - 3343, /* CC01 (52225) */ - 3343, /* CC02 (52226) */ - 3343, /* CC03 (52227) */ - 3343, /* CC04 (52228) */ - 3343, /* CC05 (52229) */ - 3343, /* CC06 (52230) */ - 3343, /* CC07 (52231) */ - 3343, /* CC08 (52232) */ - 3343, /* CC09 (52233) */ - 3343, /* CC0A (52234) */ - 3343, /* CC0B (52235) */ - 3343, /* CC0C (52236) */ - 3343, /* CC0D (52237) */ - 3343, /* CC0E (52238) */ - 3343, /* CC0F (52239) */ - 3343, /* CC10 (52240) */ - 3343, /* CC11 (52241) */ - 3343, /* CC12 (52242) */ - 3343, /* CC13 (52243) */ - 3343, /* CC14 (52244) */ - 3343, /* CC15 (52245) */ - 3343, /* CC16 (52246) */ - 3343, /* CC17 (52247) */ - 3343, /* CC18 (52248) */ - 3343, /* CC19 (52249) */ - 3343, /* CC1A (52250) */ - 3343, /* CC1B (52251) */ - 3343, /* CC1C (52252) */ - 3343, /* CC1D (52253) */ - 3343, /* CC1E (52254) */ - 3343, /* CC1F (52255) */ - 3343, /* CC20 (52256) */ - 3343, /* CC21 (52257) */ - 3343, /* CC22 (52258) */ - 3343, /* CC23 (52259) */ - 3343, /* CC24 (52260) */ - 3343, /* CC25 (52261) */ - 3343, /* CC26 (52262) */ - 3343, /* CC27 (52263) */ - 3343, /* CC28 (52264) */ - 3343, /* CC29 (52265) */ - 3343, /* CC2A (52266) */ - 3343, /* CC2B (52267) */ - 3343, /* CC2C (52268) */ - 3343, /* CC2D (52269) */ - 3343, /* CC2E (52270) */ - 3343, /* CC2F (52271) */ - 3343, /* CC30 (52272) */ - 3343, /* CC31 (52273) */ - 3343, /* CC32 (52274) */ - 3343, /* CC33 (52275) */ - 3343, /* CC34 (52276) */ - 3343, /* CC35 (52277) */ - 3343, /* CC36 (52278) */ - 3343, /* CC37 (52279) */ - 3343, /* CC38 (52280) */ - 3343, /* CC39 (52281) */ - 3343, /* CC3A (52282) */ - 3343, /* CC3B (52283) */ - 3343, /* CC3C (52284) */ - 3343, /* CC3D (52285) */ - 3343, /* CC3E (52286) */ - 3343, /* CC3F (52287) */ - 3343, /* CC40 (52288) */ - 3343, /* CC41 (52289) */ - 3343, /* CC42 (52290) */ - 3343, /* CC43 (52291) */ - 3343, /* CC44 (52292) */ - 3343, /* CC45 (52293) */ - 3343, /* CC46 (52294) */ - 3343, /* CC47 (52295) */ - 3343, /* CC48 (52296) */ - 3343, /* CC49 (52297) */ - 3343, /* CC4A (52298) */ - 3343, /* CC4B (52299) */ - 3343, /* CC4C (52300) */ - 3343, /* CC4D (52301) */ - 3343, /* CC4E (52302) */ - 3343, /* CC4F (52303) */ - 3343, /* CC50 (52304) */ - 3343, /* CC51 (52305) */ - 3343, /* CC52 (52306) */ - 3343, /* CC53 (52307) */ - 3343, /* CC54 (52308) */ - 3343, /* CC55 (52309) */ - 3343, /* CC56 (52310) */ - 3343, /* CC57 (52311) */ - 3343, /* CC58 (52312) */ - 3343, /* CC59 (52313) */ - 3343, /* CC5A (52314) */ - 3343, /* CC5B (52315) */ - 3343, /* CC5C (52316) */ - 3343, /* CC5D (52317) */ - 3343, /* CC5E (52318) */ - 3343, /* CC5F (52319) */ - 3343, /* CC60 (52320) */ - 3343, /* CC61 (52321) */ - 3343, /* CC62 (52322) */ - 3343, /* CC63 (52323) */ - 3343, /* CC64 (52324) */ - 3343, /* CC65 (52325) */ - 3343, /* CC66 (52326) */ - 3343, /* CC67 (52327) */ - 3343, /* CC68 (52328) */ - 3343, /* CC69 (52329) */ - 3343, /* CC6A (52330) */ - 3343, /* CC6B (52331) */ - 3343, /* CC6C (52332) */ - 3343, /* CC6D (52333) */ - 3343, /* CC6E (52334) */ - 3343, /* CC6F (52335) */ - 3343, /* CC70 (52336) */ - 3343, /* CC71 (52337) */ - 3343, /* CC72 (52338) */ - 3343, /* CC73 (52339) */ - 3343, /* CC74 (52340) */ - 3343, /* CC75 (52341) */ - 3343, /* CC76 (52342) */ - 3343, /* CC77 (52343) */ - 3343, /* CC78 (52344) */ - 3343, /* CC79 (52345) */ - 3343, /* CC7A (52346) */ - 3343, /* CC7B (52347) */ - 3343, /* CC7C (52348) */ - 3343, /* CC7D (52349) */ - 3343, /* CC7E (52350) */ - 3343, /* CC7F (52351) */ - 3343, /* CC80 (52352) */ - 3343, /* CC81 (52353) */ - 3343, /* CC82 (52354) */ - 3343, /* CC83 (52355) */ - 3343, /* CC84 (52356) */ - 3343, /* CC85 (52357) */ - 3343, /* CC86 (52358) */ - 3343, /* CC87 (52359) */ - 3343, /* CC88 (52360) */ - 3343, /* CC89 (52361) */ - 3343, /* CC8A (52362) */ - 3343, /* CC8B (52363) */ - 3343, /* CC8C (52364) */ - 3343, /* CC8D (52365) */ - 3343, /* CC8E (52366) */ - 3343, /* CC8F (52367) */ - 3343, /* CC90 (52368) */ - 3343, /* CC91 (52369) */ - 3343, /* CC92 (52370) */ - 3343, /* CC93 (52371) */ - 3343, /* CC94 (52372) */ - 3343, /* CC95 (52373) */ - 3343, /* CC96 (52374) */ - 3343, /* CC97 (52375) */ - 3343, /* CC98 (52376) */ - 3343, /* CC99 (52377) */ - 3343, /* CC9A (52378) */ - 3343, /* CC9B (52379) */ - 3343, /* CC9C (52380) */ - 3343, /* CC9D (52381) */ - 3343, /* CC9E (52382) */ - 3343, /* CC9F (52383) */ - 3343, /* CCA0 (52384) */ - 3343, /* CCA1 (52385) */ - 3343, /* CCA2 (52386) */ - 3343, /* CCA3 (52387) */ - 3343, /* CCA4 (52388) */ - 3343, /* CCA5 (52389) */ - 3343, /* CCA6 (52390) */ - 3343, /* CCA7 (52391) */ - 3343, /* CCA8 (52392) */ - 3343, /* CCA9 (52393) */ - 3343, /* CCAA (52394) */ - 3343, /* CCAB (52395) */ - 3343, /* CCAC (52396) */ - 3343, /* CCAD (52397) */ - 3343, /* CCAE (52398) */ - 3343, /* CCAF (52399) */ - 3343, /* CCB0 (52400) */ - 3343, /* CCB1 (52401) */ - 3343, /* CCB2 (52402) */ - 3343, /* CCB3 (52403) */ - 3343, /* CCB4 (52404) */ - 3343, /* CCB5 (52405) */ - 3343, /* CCB6 (52406) */ - 3343, /* CCB7 (52407) */ - 3343, /* CCB8 (52408) */ - 3343, /* CCB9 (52409) */ - 3343, /* CCBA (52410) */ - 3343, /* CCBB (52411) */ - 3343, /* CCBC (52412) */ - 3343, /* CCBD (52413) */ - 3343, /* CCBE (52414) */ - 3343, /* CCBF (52415) */ - 3343, /* CCC0 (52416) */ - 3343, /* CCC1 (52417) */ - 3343, /* CCC2 (52418) */ - 3343, /* CCC3 (52419) */ - 3343, /* CCC4 (52420) */ - 3343, /* CCC5 (52421) */ - 3343, /* CCC6 (52422) */ - 3343, /* CCC7 (52423) */ - 3343, /* CCC8 (52424) */ - 3343, /* CCC9 (52425) */ - 3343, /* CCCA (52426) */ - 3343, /* CCCB (52427) */ - 3343, /* CCCC (52428) */ - 3343, /* CCCD (52429) */ - 3343, /* CCCE (52430) */ - 3343, /* CCCF (52431) */ - 3343, /* CCD0 (52432) */ - 3343, /* CCD1 (52433) */ - 3343, /* CCD2 (52434) */ - 3343, /* CCD3 (52435) */ - 3343, /* CCD4 (52436) */ - 3343, /* CCD5 (52437) */ - 3343, /* CCD6 (52438) */ - 3343, /* CCD7 (52439) */ - 3343, /* CCD8 (52440) */ - 3343, /* CCD9 (52441) */ - 3343, /* CCDA (52442) */ - 3343, /* CCDB (52443) */ - 3343, /* CCDC (52444) */ - 3343, /* CCDD (52445) */ - 3343, /* CCDE (52446) */ - 3343, /* CCDF (52447) */ - 3343, /* CCE0 (52448) */ - 3343, /* CCE1 (52449) */ - 3343, /* CCE2 (52450) */ - 3343, /* CCE3 (52451) */ - 3343, /* CCE4 (52452) */ - 3343, /* CCE5 (52453) */ - 3343, /* CCE6 (52454) */ - 3343, /* CCE7 (52455) */ - 3343, /* CCE8 (52456) */ - 3343, /* CCE9 (52457) */ - 3343, /* CCEA (52458) */ - 3343, /* CCEB (52459) */ - 3343, /* CCEC (52460) */ - 3343, /* CCED (52461) */ - 3343, /* CCEE (52462) */ - 3343, /* CCEF (52463) */ - 3343, /* CCF0 (52464) */ - 3343, /* CCF1 (52465) */ - 3343, /* CCF2 (52466) */ - 3343, /* CCF3 (52467) */ - 3343, /* CCF4 (52468) */ - 3343, /* CCF5 (52469) */ - 3343, /* CCF6 (52470) */ - 3343, /* CCF7 (52471) */ - 3343, /* CCF8 (52472) */ - 3343, /* CCF9 (52473) */ - 3343, /* CCFA (52474) */ - 3343, /* CCFB (52475) */ - 3343, /* CCFC (52476) */ - 3343, /* CCFD (52477) */ - 3343, /* CCFE (52478) */ - 3343, /* CCFF (52479) */ - 3343, /* CD00 (52480) */ - 3343, /* CD01 (52481) */ - 3343, /* CD02 (52482) */ - 3343, /* CD03 (52483) */ - 3343, /* CD04 (52484) */ - 3343, /* CD05 (52485) */ - 3343, /* CD06 (52486) */ - 3343, /* CD07 (52487) */ - 3343, /* CD08 (52488) */ - 3343, /* CD09 (52489) */ - 3343, /* CD0A (52490) */ - 3343, /* CD0B (52491) */ - 3343, /* CD0C (52492) */ - 3343, /* CD0D (52493) */ - 3343, /* CD0E (52494) */ - 3343, /* CD0F (52495) */ - 3343, /* CD10 (52496) */ - 3343, /* CD11 (52497) */ - 3343, /* CD12 (52498) */ - 3343, /* CD13 (52499) */ - 3343, /* CD14 (52500) */ - 3343, /* CD15 (52501) */ - 3343, /* CD16 (52502) */ - 3343, /* CD17 (52503) */ - 3343, /* CD18 (52504) */ - 3343, /* CD19 (52505) */ - 3343, /* CD1A (52506) */ - 3343, /* CD1B (52507) */ - 3343, /* CD1C (52508) */ - 3343, /* CD1D (52509) */ - 3343, /* CD1E (52510) */ - 3343, /* CD1F (52511) */ - 3343, /* CD20 (52512) */ - 3343, /* CD21 (52513) */ - 3343, /* CD22 (52514) */ - 3343, /* CD23 (52515) */ - 3343, /* CD24 (52516) */ - 3343, /* CD25 (52517) */ - 3343, /* CD26 (52518) */ - 3343, /* CD27 (52519) */ - 3343, /* CD28 (52520) */ - 3343, /* CD29 (52521) */ - 3343, /* CD2A (52522) */ - 3343, /* CD2B (52523) */ - 3343, /* CD2C (52524) */ - 3343, /* CD2D (52525) */ - 3343, /* CD2E (52526) */ - 3343, /* CD2F (52527) */ - 3343, /* CD30 (52528) */ - 3343, /* CD31 (52529) */ - 3343, /* CD32 (52530) */ - 3343, /* CD33 (52531) */ - 3343, /* CD34 (52532) */ - 3343, /* CD35 (52533) */ - 3343, /* CD36 (52534) */ - 3343, /* CD37 (52535) */ - 3343, /* CD38 (52536) */ - 3343, /* CD39 (52537) */ - 3343, /* CD3A (52538) */ - 3343, /* CD3B (52539) */ - 3343, /* CD3C (52540) */ - 3343, /* CD3D (52541) */ - 3343, /* CD3E (52542) */ - 3343, /* CD3F (52543) */ - 3343, /* CD40 (52544) */ - 3343, /* CD41 (52545) */ - 3343, /* CD42 (52546) */ - 3343, /* CD43 (52547) */ - 3343, /* CD44 (52548) */ - 3343, /* CD45 (52549) */ - 3343, /* CD46 (52550) */ - 3343, /* CD47 (52551) */ - 3343, /* CD48 (52552) */ - 3343, /* CD49 (52553) */ - 3343, /* CD4A (52554) */ - 3343, /* CD4B (52555) */ - 3343, /* CD4C (52556) */ - 3343, /* CD4D (52557) */ - 3343, /* CD4E (52558) */ - 3343, /* CD4F (52559) */ - 3343, /* CD50 (52560) */ - 3343, /* CD51 (52561) */ - 3343, /* CD52 (52562) */ - 3343, /* CD53 (52563) */ - 3343, /* CD54 (52564) */ - 3343, /* CD55 (52565) */ - 3343, /* CD56 (52566) */ - 3343, /* CD57 (52567) */ - 3343, /* CD58 (52568) */ - 3343, /* CD59 (52569) */ - 3343, /* CD5A (52570) */ - 3343, /* CD5B (52571) */ - 3343, /* CD5C (52572) */ - 3343, /* CD5D (52573) */ - 3343, /* CD5E (52574) */ - 3343, /* CD5F (52575) */ - 3343, /* CD60 (52576) */ - 3343, /* CD61 (52577) */ - 3343, /* CD62 (52578) */ - 3343, /* CD63 (52579) */ - 3343, /* CD64 (52580) */ - 3343, /* CD65 (52581) */ - 3343, /* CD66 (52582) */ - 3343, /* CD67 (52583) */ - 3343, /* CD68 (52584) */ - 3343, /* CD69 (52585) */ - 3343, /* CD6A (52586) */ - 3343, /* CD6B (52587) */ - 3343, /* CD6C (52588) */ - 3343, /* CD6D (52589) */ - 3343, /* CD6E (52590) */ - 3343, /* CD6F (52591) */ - 3343, /* CD70 (52592) */ - 3343, /* CD71 (52593) */ - 3343, /* CD72 (52594) */ - 3343, /* CD73 (52595) */ - 3343, /* CD74 (52596) */ - 3343, /* CD75 (52597) */ - 3343, /* CD76 (52598) */ - 3343, /* CD77 (52599) */ - 3343, /* CD78 (52600) */ - 3343, /* CD79 (52601) */ - 3343, /* CD7A (52602) */ - 3343, /* CD7B (52603) */ - 3343, /* CD7C (52604) */ - 3343, /* CD7D (52605) */ - 3343, /* CD7E (52606) */ - 3343, /* CD7F (52607) */ - 3343, /* CD80 (52608) */ - 3343, /* CD81 (52609) */ - 3343, /* CD82 (52610) */ - 3343, /* CD83 (52611) */ - 3343, /* CD84 (52612) */ - 3343, /* CD85 (52613) */ - 3343, /* CD86 (52614) */ - 3343, /* CD87 (52615) */ - 3343, /* CD88 (52616) */ - 3343, /* CD89 (52617) */ - 3343, /* CD8A (52618) */ - 3343, /* CD8B (52619) */ - 3343, /* CD8C (52620) */ - 3343, /* CD8D (52621) */ - 3343, /* CD8E (52622) */ - 3343, /* CD8F (52623) */ - 3343, /* CD90 (52624) */ - 3343, /* CD91 (52625) */ - 3343, /* CD92 (52626) */ - 3343, /* CD93 (52627) */ - 3343, /* CD94 (52628) */ - 3343, /* CD95 (52629) */ - 3343, /* CD96 (52630) */ - 3343, /* CD97 (52631) */ - 3343, /* CD98 (52632) */ - 3343, /* CD99 (52633) */ - 3343, /* CD9A (52634) */ - 3343, /* CD9B (52635) */ - 3343, /* CD9C (52636) */ - 3343, /* CD9D (52637) */ - 3343, /* CD9E (52638) */ - 3343, /* CD9F (52639) */ - 3343, /* CDA0 (52640) */ - 3343, /* CDA1 (52641) */ - 3343, /* CDA2 (52642) */ - 3343, /* CDA3 (52643) */ - 3343, /* CDA4 (52644) */ - 3343, /* CDA5 (52645) */ - 3343, /* CDA6 (52646) */ - 3343, /* CDA7 (52647) */ - 3343, /* CDA8 (52648) */ - 3343, /* CDA9 (52649) */ - 3343, /* CDAA (52650) */ - 3343, /* CDAB (52651) */ - 3343, /* CDAC (52652) */ - 3343, /* CDAD (52653) */ - 3343, /* CDAE (52654) */ - 3343, /* CDAF (52655) */ - 3343, /* CDB0 (52656) */ - 3343, /* CDB1 (52657) */ - 3343, /* CDB2 (52658) */ - 3343, /* CDB3 (52659) */ - 3343, /* CDB4 (52660) */ - 3343, /* CDB5 (52661) */ - 3343, /* CDB6 (52662) */ - 3343, /* CDB7 (52663) */ - 3343, /* CDB8 (52664) */ - 3343, /* CDB9 (52665) */ - 3343, /* CDBA (52666) */ - 3343, /* CDBB (52667) */ - 3343, /* CDBC (52668) */ - 3343, /* CDBD (52669) */ - 3343, /* CDBE (52670) */ - 3343, /* CDBF (52671) */ - 3343, /* CDC0 (52672) */ - 3343, /* CDC1 (52673) */ - 3343, /* CDC2 (52674) */ - 3343, /* CDC3 (52675) */ - 3343, /* CDC4 (52676) */ - 3343, /* CDC5 (52677) */ - 3343, /* CDC6 (52678) */ - 3343, /* CDC7 (52679) */ - 3343, /* CDC8 (52680) */ - 3343, /* CDC9 (52681) */ - 3343, /* CDCA (52682) */ - 3343, /* CDCB (52683) */ - 3343, /* CDCC (52684) */ - 3343, /* CDCD (52685) */ - 3343, /* CDCE (52686) */ - 3343, /* CDCF (52687) */ - 3343, /* CDD0 (52688) */ - 3343, /* CDD1 (52689) */ - 3343, /* CDD2 (52690) */ - 3343, /* CDD3 (52691) */ - 3343, /* CDD4 (52692) */ - 3343, /* CDD5 (52693) */ - 3343, /* CDD6 (52694) */ - 3343, /* CDD7 (52695) */ - 3343, /* CDD8 (52696) */ - 3343, /* CDD9 (52697) */ - 3343, /* CDDA (52698) */ - 3343, /* CDDB (52699) */ - 3343, /* CDDC (52700) */ - 3343, /* CDDD (52701) */ - 3343, /* CDDE (52702) */ - 3343, /* CDDF (52703) */ - 3343, /* CDE0 (52704) */ - 3343, /* CDE1 (52705) */ - 3343, /* CDE2 (52706) */ - 3343, /* CDE3 (52707) */ - 3343, /* CDE4 (52708) */ - 3343, /* CDE5 (52709) */ - 3343, /* CDE6 (52710) */ - 3343, /* CDE7 (52711) */ - 3343, /* CDE8 (52712) */ - 3343, /* CDE9 (52713) */ - 3343, /* CDEA (52714) */ - 3343, /* CDEB (52715) */ - 3343, /* CDEC (52716) */ - 3343, /* CDED (52717) */ - 3343, /* CDEE (52718) */ - 3343, /* CDEF (52719) */ - 3343, /* CDF0 (52720) */ - 3343, /* CDF1 (52721) */ - 3343, /* CDF2 (52722) */ - 3343, /* CDF3 (52723) */ - 3343, /* CDF4 (52724) */ - 3343, /* CDF5 (52725) */ - 3343, /* CDF6 (52726) */ - 3343, /* CDF7 (52727) */ - 3343, /* CDF8 (52728) */ - 3343, /* CDF9 (52729) */ - 3343, /* CDFA (52730) */ - 3343, /* CDFB (52731) */ - 3343, /* CDFC (52732) */ - 3343, /* CDFD (52733) */ - 3343, /* CDFE (52734) */ - 3343, /* CDFF (52735) */ - 3343, /* CE00 (52736) */ - 3343, /* CE01 (52737) */ - 3343, /* CE02 (52738) */ - 3343, /* CE03 (52739) */ - 3343, /* CE04 (52740) */ - 3343, /* CE05 (52741) */ - 3343, /* CE06 (52742) */ - 3343, /* CE07 (52743) */ - 3343, /* CE08 (52744) */ - 3343, /* CE09 (52745) */ - 3343, /* CE0A (52746) */ - 3343, /* CE0B (52747) */ - 3343, /* CE0C (52748) */ - 3343, /* CE0D (52749) */ - 3343, /* CE0E (52750) */ - 3343, /* CE0F (52751) */ - 3343, /* CE10 (52752) */ - 3343, /* CE11 (52753) */ - 3343, /* CE12 (52754) */ - 3343, /* CE13 (52755) */ - 3343, /* CE14 (52756) */ - 3343, /* CE15 (52757) */ - 3343, /* CE16 (52758) */ - 3343, /* CE17 (52759) */ - 3343, /* CE18 (52760) */ - 3343, /* CE19 (52761) */ - 3343, /* CE1A (52762) */ - 3343, /* CE1B (52763) */ - 3343, /* CE1C (52764) */ - 3343, /* CE1D (52765) */ - 3343, /* CE1E (52766) */ - 3343, /* CE1F (52767) */ - 3343, /* CE20 (52768) */ - 3343, /* CE21 (52769) */ - 3343, /* CE22 (52770) */ - 3343, /* CE23 (52771) */ - 3343, /* CE24 (52772) */ - 3343, /* CE25 (52773) */ - 3343, /* CE26 (52774) */ - 3343, /* CE27 (52775) */ - 3343, /* CE28 (52776) */ - 3343, /* CE29 (52777) */ - 3343, /* CE2A (52778) */ - 3343, /* CE2B (52779) */ - 3343, /* CE2C (52780) */ - 3343, /* CE2D (52781) */ - 3343, /* CE2E (52782) */ - 3343, /* CE2F (52783) */ - 3343, /* CE30 (52784) */ - 3343, /* CE31 (52785) */ - 3343, /* CE32 (52786) */ - 3343, /* CE33 (52787) */ - 3343, /* CE34 (52788) */ - 3343, /* CE35 (52789) */ - 3343, /* CE36 (52790) */ - 3343, /* CE37 (52791) */ - 3343, /* CE38 (52792) */ - 3343, /* CE39 (52793) */ - 3343, /* CE3A (52794) */ - 3343, /* CE3B (52795) */ - 3343, /* CE3C (52796) */ - 3343, /* CE3D (52797) */ - 3343, /* CE3E (52798) */ - 3343, /* CE3F (52799) */ - 3343, /* CE40 (52800) */ - 3343, /* CE41 (52801) */ - 3343, /* CE42 (52802) */ - 3343, /* CE43 (52803) */ - 3343, /* CE44 (52804) */ - 3343, /* CE45 (52805) */ - 3343, /* CE46 (52806) */ - 3343, /* CE47 (52807) */ - 3343, /* CE48 (52808) */ - 3343, /* CE49 (52809) */ - 3343, /* CE4A (52810) */ - 3343, /* CE4B (52811) */ - 3343, /* CE4C (52812) */ - 3343, /* CE4D (52813) */ - 3343, /* CE4E (52814) */ - 3343, /* CE4F (52815) */ - 3343, /* CE50 (52816) */ - 3343, /* CE51 (52817) */ - 3343, /* CE52 (52818) */ - 3343, /* CE53 (52819) */ - 3343, /* CE54 (52820) */ - 3343, /* CE55 (52821) */ - 3343, /* CE56 (52822) */ - 3343, /* CE57 (52823) */ - 3343, /* CE58 (52824) */ - 3343, /* CE59 (52825) */ - 3343, /* CE5A (52826) */ - 3343, /* CE5B (52827) */ - 3343, /* CE5C (52828) */ - 3343, /* CE5D (52829) */ - 3343, /* CE5E (52830) */ - 3343, /* CE5F (52831) */ - 3343, /* CE60 (52832) */ - 3343, /* CE61 (52833) */ - 3343, /* CE62 (52834) */ - 3343, /* CE63 (52835) */ - 3343, /* CE64 (52836) */ - 3343, /* CE65 (52837) */ - 3343, /* CE66 (52838) */ - 3343, /* CE67 (52839) */ - 3343, /* CE68 (52840) */ - 3343, /* CE69 (52841) */ - 3343, /* CE6A (52842) */ - 3343, /* CE6B (52843) */ - 3343, /* CE6C (52844) */ - 3343, /* CE6D (52845) */ - 3343, /* CE6E (52846) */ - 3343, /* CE6F (52847) */ - 3343, /* CE70 (52848) */ - 3343, /* CE71 (52849) */ - 3343, /* CE72 (52850) */ - 3343, /* CE73 (52851) */ - 3343, /* CE74 (52852) */ - 3343, /* CE75 (52853) */ - 3343, /* CE76 (52854) */ - 3343, /* CE77 (52855) */ - 3343, /* CE78 (52856) */ - 3343, /* CE79 (52857) */ - 3343, /* CE7A (52858) */ - 3343, /* CE7B (52859) */ - 3343, /* CE7C (52860) */ - 3343, /* CE7D (52861) */ - 3343, /* CE7E (52862) */ - 3343, /* CE7F (52863) */ - 3343, /* CE80 (52864) */ - 3343, /* CE81 (52865) */ - 3343, /* CE82 (52866) */ - 3343, /* CE83 (52867) */ - 3343, /* CE84 (52868) */ - 3343, /* CE85 (52869) */ - 3343, /* CE86 (52870) */ - 3343, /* CE87 (52871) */ - 3343, /* CE88 (52872) */ - 3343, /* CE89 (52873) */ - 3343, /* CE8A (52874) */ - 3343, /* CE8B (52875) */ - 3343, /* CE8C (52876) */ - 3343, /* CE8D (52877) */ - 3343, /* CE8E (52878) */ - 3343, /* CE8F (52879) */ - 3343, /* CE90 (52880) */ - 3343, /* CE91 (52881) */ - 3343, /* CE92 (52882) */ - 3343, /* CE93 (52883) */ - 3343, /* CE94 (52884) */ - 3343, /* CE95 (52885) */ - 3343, /* CE96 (52886) */ - 3343, /* CE97 (52887) */ - 3343, /* CE98 (52888) */ - 3343, /* CE99 (52889) */ - 3343, /* CE9A (52890) */ - 3343, /* CE9B (52891) */ - 3343, /* CE9C (52892) */ - 3343, /* CE9D (52893) */ - 3343, /* CE9E (52894) */ - 3343, /* CE9F (52895) */ - 3343, /* CEA0 (52896) */ - 3343, /* CEA1 (52897) */ - 3343, /* CEA2 (52898) */ - 3343, /* CEA3 (52899) */ - 3343, /* CEA4 (52900) */ - 3343, /* CEA5 (52901) */ - 3343, /* CEA6 (52902) */ - 3343, /* CEA7 (52903) */ - 3343, /* CEA8 (52904) */ - 3343, /* CEA9 (52905) */ - 3343, /* CEAA (52906) */ - 3343, /* CEAB (52907) */ - 3343, /* CEAC (52908) */ - 3343, /* CEAD (52909) */ - 3343, /* CEAE (52910) */ - 3343, /* CEAF (52911) */ - 3343, /* CEB0 (52912) */ - 3343, /* CEB1 (52913) */ - 3343, /* CEB2 (52914) */ - 3343, /* CEB3 (52915) */ - 3343, /* CEB4 (52916) */ - 3343, /* CEB5 (52917) */ - 3343, /* CEB6 (52918) */ - 3343, /* CEB7 (52919) */ - 3343, /* CEB8 (52920) */ - 3343, /* CEB9 (52921) */ - 3343, /* CEBA (52922) */ - 3343, /* CEBB (52923) */ - 3343, /* CEBC (52924) */ - 3343, /* CEBD (52925) */ - 3343, /* CEBE (52926) */ - 3343, /* CEBF (52927) */ - 3343, /* CEC0 (52928) */ - 3343, /* CEC1 (52929) */ - 3343, /* CEC2 (52930) */ - 3343, /* CEC3 (52931) */ - 3343, /* CEC4 (52932) */ - 3343, /* CEC5 (52933) */ - 3343, /* CEC6 (52934) */ - 3343, /* CEC7 (52935) */ - 3343, /* CEC8 (52936) */ - 3343, /* CEC9 (52937) */ - 3343, /* CECA (52938) */ - 3343, /* CECB (52939) */ - 3343, /* CECC (52940) */ - 3343, /* CECD (52941) */ - 3343, /* CECE (52942) */ - 3343, /* CECF (52943) */ - 3343, /* CED0 (52944) */ - 3343, /* CED1 (52945) */ - 3343, /* CED2 (52946) */ - 3343, /* CED3 (52947) */ - 3343, /* CED4 (52948) */ - 3343, /* CED5 (52949) */ - 3343, /* CED6 (52950) */ - 3343, /* CED7 (52951) */ - 3343, /* CED8 (52952) */ - 3343, /* CED9 (52953) */ - 3343, /* CEDA (52954) */ - 3343, /* CEDB (52955) */ - 3343, /* CEDC (52956) */ - 3343, /* CEDD (52957) */ - 3343, /* CEDE (52958) */ - 3343, /* CEDF (52959) */ - 3343, /* CEE0 (52960) */ - 3343, /* CEE1 (52961) */ - 3343, /* CEE2 (52962) */ - 3343, /* CEE3 (52963) */ - 3343, /* CEE4 (52964) */ - 3343, /* CEE5 (52965) */ - 3343, /* CEE6 (52966) */ - 3343, /* CEE7 (52967) */ - 3343, /* CEE8 (52968) */ - 3343, /* CEE9 (52969) */ - 3343, /* CEEA (52970) */ - 3343, /* CEEB (52971) */ - 3343, /* CEEC (52972) */ - 3343, /* CEED (52973) */ - 3343, /* CEEE (52974) */ - 3343, /* CEEF (52975) */ - 3343, /* CEF0 (52976) */ - 3343, /* CEF1 (52977) */ - 3343, /* CEF2 (52978) */ - 3343, /* CEF3 (52979) */ - 3343, /* CEF4 (52980) */ - 3343, /* CEF5 (52981) */ - 3343, /* CEF6 (52982) */ - 3343, /* CEF7 (52983) */ - 3343, /* CEF8 (52984) */ - 3343, /* CEF9 (52985) */ - 3343, /* CEFA (52986) */ - 3343, /* CEFB (52987) */ - 3343, /* CEFC (52988) */ - 3343, /* CEFD (52989) */ - 3343, /* CEFE (52990) */ - 3343, /* CEFF (52991) */ - 3343, /* CF00 (52992) */ - 3343, /* CF01 (52993) */ - 3343, /* CF02 (52994) */ - 3343, /* CF03 (52995) */ - 3343, /* CF04 (52996) */ - 3343, /* CF05 (52997) */ - 3343, /* CF06 (52998) */ - 3343, /* CF07 (52999) */ - 3343, /* CF08 (53000) */ - 3343, /* CF09 (53001) */ - 3343, /* CF0A (53002) */ - 3343, /* CF0B (53003) */ - 3343, /* CF0C (53004) */ - 3343, /* CF0D (53005) */ - 3343, /* CF0E (53006) */ - 3343, /* CF0F (53007) */ - 3343, /* CF10 (53008) */ - 3343, /* CF11 (53009) */ - 3343, /* CF12 (53010) */ - 3343, /* CF13 (53011) */ - 3343, /* CF14 (53012) */ - 3343, /* CF15 (53013) */ - 3343, /* CF16 (53014) */ - 3343, /* CF17 (53015) */ - 3343, /* CF18 (53016) */ - 3343, /* CF19 (53017) */ - 3343, /* CF1A (53018) */ - 3343, /* CF1B (53019) */ - 3343, /* CF1C (53020) */ - 3343, /* CF1D (53021) */ - 3343, /* CF1E (53022) */ - 3343, /* CF1F (53023) */ - 3343, /* CF20 (53024) */ - 3343, /* CF21 (53025) */ - 3343, /* CF22 (53026) */ - 3343, /* CF23 (53027) */ - 3343, /* CF24 (53028) */ - 3343, /* CF25 (53029) */ - 3343, /* CF26 (53030) */ - 3343, /* CF27 (53031) */ - 3343, /* CF28 (53032) */ - 3343, /* CF29 (53033) */ - 3343, /* CF2A (53034) */ - 3343, /* CF2B (53035) */ - 3343, /* CF2C (53036) */ - 3343, /* CF2D (53037) */ - 3343, /* CF2E (53038) */ - 3343, /* CF2F (53039) */ - 3343, /* CF30 (53040) */ - 3343, /* CF31 (53041) */ - 3343, /* CF32 (53042) */ - 3343, /* CF33 (53043) */ - 3343, /* CF34 (53044) */ - 3343, /* CF35 (53045) */ - 3343, /* CF36 (53046) */ - 3343, /* CF37 (53047) */ - 3343, /* CF38 (53048) */ - 3343, /* CF39 (53049) */ - 3343, /* CF3A (53050) */ - 3343, /* CF3B (53051) */ - 3343, /* CF3C (53052) */ - 3343, /* CF3D (53053) */ - 3343, /* CF3E (53054) */ - 3343, /* CF3F (53055) */ - 3343, /* CF40 (53056) */ - 3343, /* CF41 (53057) */ - 3343, /* CF42 (53058) */ - 3343, /* CF43 (53059) */ - 3343, /* CF44 (53060) */ - 3343, /* CF45 (53061) */ - 3343, /* CF46 (53062) */ - 3343, /* CF47 (53063) */ - 3343, /* CF48 (53064) */ - 3343, /* CF49 (53065) */ - 3343, /* CF4A (53066) */ - 3343, /* CF4B (53067) */ - 3343, /* CF4C (53068) */ - 3343, /* CF4D (53069) */ - 3343, /* CF4E (53070) */ - 3343, /* CF4F (53071) */ - 3343, /* CF50 (53072) */ - 3343, /* CF51 (53073) */ - 3343, /* CF52 (53074) */ - 3343, /* CF53 (53075) */ - 3343, /* CF54 (53076) */ - 3343, /* CF55 (53077) */ - 3343, /* CF56 (53078) */ - 3343, /* CF57 (53079) */ - 3343, /* CF58 (53080) */ - 3343, /* CF59 (53081) */ - 3343, /* CF5A (53082) */ - 3343, /* CF5B (53083) */ - 3343, /* CF5C (53084) */ - 3343, /* CF5D (53085) */ - 3343, /* CF5E (53086) */ - 3343, /* CF5F (53087) */ - 3343, /* CF60 (53088) */ - 3343, /* CF61 (53089) */ - 3343, /* CF62 (53090) */ - 3343, /* CF63 (53091) */ - 3343, /* CF64 (53092) */ - 3343, /* CF65 (53093) */ - 3343, /* CF66 (53094) */ - 3343, /* CF67 (53095) */ - 3343, /* CF68 (53096) */ - 3343, /* CF69 (53097) */ - 3343, /* CF6A (53098) */ - 3343, /* CF6B (53099) */ - 3343, /* CF6C (53100) */ - 3343, /* CF6D (53101) */ - 3343, /* CF6E (53102) */ - 3343, /* CF6F (53103) */ - 3343, /* CF70 (53104) */ - 3343, /* CF71 (53105) */ - 3343, /* CF72 (53106) */ - 3343, /* CF73 (53107) */ - 3343, /* CF74 (53108) */ - 3343, /* CF75 (53109) */ - 3343, /* CF76 (53110) */ - 3343, /* CF77 (53111) */ - 3343, /* CF78 (53112) */ - 3343, /* CF79 (53113) */ - 3343, /* CF7A (53114) */ - 3343, /* CF7B (53115) */ - 3343, /* CF7C (53116) */ - 3343, /* CF7D (53117) */ - 3343, /* CF7E (53118) */ - 3343, /* CF7F (53119) */ - 3343, /* CF80 (53120) */ - 3343, /* CF81 (53121) */ - 3343, /* CF82 (53122) */ - 3343, /* CF83 (53123) */ - 3343, /* CF84 (53124) */ - 3343, /* CF85 (53125) */ - 3343, /* CF86 (53126) */ - 3343, /* CF87 (53127) */ - 3343, /* CF88 (53128) */ - 3343, /* CF89 (53129) */ - 3343, /* CF8A (53130) */ - 3343, /* CF8B (53131) */ - 3343, /* CF8C (53132) */ - 3343, /* CF8D (53133) */ - 3343, /* CF8E (53134) */ - 3343, /* CF8F (53135) */ - 3343, /* CF90 (53136) */ - 3343, /* CF91 (53137) */ - 3343, /* CF92 (53138) */ - 3343, /* CF93 (53139) */ - 3343, /* CF94 (53140) */ - 3343, /* CF95 (53141) */ - 3343, /* CF96 (53142) */ - 3343, /* CF97 (53143) */ - 3343, /* CF98 (53144) */ - 3343, /* CF99 (53145) */ - 3343, /* CF9A (53146) */ - 3343, /* CF9B (53147) */ - 3343, /* CF9C (53148) */ - 3343, /* CF9D (53149) */ - 3343, /* CF9E (53150) */ - 3343, /* CF9F (53151) */ - 3343, /* CFA0 (53152) */ - 3343, /* CFA1 (53153) */ - 3343, /* CFA2 (53154) */ - 3343, /* CFA3 (53155) */ - 3343, /* CFA4 (53156) */ - 3343, /* CFA5 (53157) */ - 3343, /* CFA6 (53158) */ - 3343, /* CFA7 (53159) */ - 3343, /* CFA8 (53160) */ - 3343, /* CFA9 (53161) */ - 3343, /* CFAA (53162) */ - 3343, /* CFAB (53163) */ - 3343, /* CFAC (53164) */ - 3343, /* CFAD (53165) */ - 3343, /* CFAE (53166) */ - 3343, /* CFAF (53167) */ - 3343, /* CFB0 (53168) */ - 3343, /* CFB1 (53169) */ - 3343, /* CFB2 (53170) */ - 3343, /* CFB3 (53171) */ - 3343, /* CFB4 (53172) */ - 3343, /* CFB5 (53173) */ - 3343, /* CFB6 (53174) */ - 3343, /* CFB7 (53175) */ - 3343, /* CFB8 (53176) */ - 3343, /* CFB9 (53177) */ - 3343, /* CFBA (53178) */ - 3343, /* CFBB (53179) */ - 3343, /* CFBC (53180) */ - 3343, /* CFBD (53181) */ - 3343, /* CFBE (53182) */ - 3343, /* CFBF (53183) */ - 3343, /* CFC0 (53184) */ - 3343, /* CFC1 (53185) */ - 3343, /* CFC2 (53186) */ - 3343, /* CFC3 (53187) */ - 3343, /* CFC4 (53188) */ - 3343, /* CFC5 (53189) */ - 3343, /* CFC6 (53190) */ - 3343, /* CFC7 (53191) */ - 3343, /* CFC8 (53192) */ - 3343, /* CFC9 (53193) */ - 3343, /* CFCA (53194) */ - 3343, /* CFCB (53195) */ - 3343, /* CFCC (53196) */ - 3343, /* CFCD (53197) */ - 3343, /* CFCE (53198) */ - 3343, /* CFCF (53199) */ - 3343, /* CFD0 (53200) */ - 3343, /* CFD1 (53201) */ - 3343, /* CFD2 (53202) */ - 3343, /* CFD3 (53203) */ - 3343, /* CFD4 (53204) */ - 3343, /* CFD5 (53205) */ - 3343, /* CFD6 (53206) */ - 3343, /* CFD7 (53207) */ - 3343, /* CFD8 (53208) */ - 3343, /* CFD9 (53209) */ - 3343, /* CFDA (53210) */ - 3343, /* CFDB (53211) */ - 3343, /* CFDC (53212) */ - 3343, /* CFDD (53213) */ - 3343, /* CFDE (53214) */ - 3343, /* CFDF (53215) */ - 3343, /* CFE0 (53216) */ - 3343, /* CFE1 (53217) */ - 3343, /* CFE2 (53218) */ - 3343, /* CFE3 (53219) */ - 3343, /* CFE4 (53220) */ - 3343, /* CFE5 (53221) */ - 3343, /* CFE6 (53222) */ - 3343, /* CFE7 (53223) */ - 3343, /* CFE8 (53224) */ - 3343, /* CFE9 (53225) */ - 3343, /* CFEA (53226) */ - 3343, /* CFEB (53227) */ - 3343, /* CFEC (53228) */ - 3343, /* CFED (53229) */ - 3343, /* CFEE (53230) */ - 3343, /* CFEF (53231) */ - 3343, /* CFF0 (53232) */ - 3343, /* CFF1 (53233) */ - 3343, /* CFF2 (53234) */ - 3343, /* CFF3 (53235) */ - 3343, /* CFF4 (53236) */ - 3343, /* CFF5 (53237) */ - 3343, /* CFF6 (53238) */ - 3343, /* CFF7 (53239) */ - 3343, /* CFF8 (53240) */ - 3343, /* CFF9 (53241) */ - 3343, /* CFFA (53242) */ - 3343, /* CFFB (53243) */ - 3343, /* CFFC (53244) */ - 3343, /* CFFD (53245) */ - 3343, /* CFFE (53246) */ - 3343, /* CFFF (53247) */ - 3343, /* D000 (53248) */ - 3343, /* D001 (53249) */ - 3343, /* D002 (53250) */ - 3343, /* D003 (53251) */ - 3343, /* D004 (53252) */ - 3343, /* D005 (53253) */ - 3343, /* D006 (53254) */ - 3343, /* D007 (53255) */ - 3343, /* D008 (53256) */ - 3343, /* D009 (53257) */ - 3343, /* D00A (53258) */ - 3343, /* D00B (53259) */ - 3343, /* D00C (53260) */ - 3343, /* D00D (53261) */ - 3343, /* D00E (53262) */ - 3343, /* D00F (53263) */ - 3343, /* D010 (53264) */ - 3343, /* D011 (53265) */ - 3343, /* D012 (53266) */ - 3343, /* D013 (53267) */ - 3343, /* D014 (53268) */ - 3343, /* D015 (53269) */ - 3343, /* D016 (53270) */ - 3343, /* D017 (53271) */ - 3343, /* D018 (53272) */ - 3343, /* D019 (53273) */ - 3343, /* D01A (53274) */ - 3343, /* D01B (53275) */ - 3343, /* D01C (53276) */ - 3343, /* D01D (53277) */ - 3343, /* D01E (53278) */ - 3343, /* D01F (53279) */ - 3343, /* D020 (53280) */ - 3343, /* D021 (53281) */ - 3343, /* D022 (53282) */ - 3343, /* D023 (53283) */ - 3343, /* D024 (53284) */ - 3343, /* D025 (53285) */ - 3343, /* D026 (53286) */ - 3343, /* D027 (53287) */ - 3343, /* D028 (53288) */ - 3343, /* D029 (53289) */ - 3343, /* D02A (53290) */ - 3343, /* D02B (53291) */ - 3343, /* D02C (53292) */ - 3343, /* D02D (53293) */ - 3343, /* D02E (53294) */ - 3343, /* D02F (53295) */ - 3343, /* D030 (53296) */ - 3343, /* D031 (53297) */ - 3343, /* D032 (53298) */ - 3343, /* D033 (53299) */ - 3343, /* D034 (53300) */ - 3343, /* D035 (53301) */ - 3343, /* D036 (53302) */ - 3343, /* D037 (53303) */ - 3343, /* D038 (53304) */ - 3343, /* D039 (53305) */ - 3343, /* D03A (53306) */ - 3343, /* D03B (53307) */ - 3343, /* D03C (53308) */ - 3343, /* D03D (53309) */ - 3343, /* D03E (53310) */ - 3343, /* D03F (53311) */ - 3343, /* D040 (53312) */ - 3343, /* D041 (53313) */ - 3343, /* D042 (53314) */ - 3343, /* D043 (53315) */ - 3343, /* D044 (53316) */ - 3343, /* D045 (53317) */ - 3343, /* D046 (53318) */ - 3343, /* D047 (53319) */ - 3343, /* D048 (53320) */ - 3343, /* D049 (53321) */ - 3343, /* D04A (53322) */ - 3343, /* D04B (53323) */ - 3343, /* D04C (53324) */ - 3343, /* D04D (53325) */ - 3343, /* D04E (53326) */ - 3343, /* D04F (53327) */ - 3343, /* D050 (53328) */ - 3343, /* D051 (53329) */ - 3343, /* D052 (53330) */ - 3343, /* D053 (53331) */ - 3343, /* D054 (53332) */ - 3343, /* D055 (53333) */ - 3343, /* D056 (53334) */ - 3343, /* D057 (53335) */ - 3343, /* D058 (53336) */ - 3343, /* D059 (53337) */ - 3343, /* D05A (53338) */ - 3343, /* D05B (53339) */ - 3343, /* D05C (53340) */ - 3343, /* D05D (53341) */ - 3343, /* D05E (53342) */ - 3343, /* D05F (53343) */ - 3343, /* D060 (53344) */ - 3343, /* D061 (53345) */ - 3343, /* D062 (53346) */ - 3343, /* D063 (53347) */ - 3343, /* D064 (53348) */ - 3343, /* D065 (53349) */ - 3343, /* D066 (53350) */ - 3343, /* D067 (53351) */ - 3343, /* D068 (53352) */ - 3343, /* D069 (53353) */ - 3343, /* D06A (53354) */ - 3343, /* D06B (53355) */ - 3343, /* D06C (53356) */ - 3343, /* D06D (53357) */ - 3343, /* D06E (53358) */ - 3343, /* D06F (53359) */ - 3343, /* D070 (53360) */ - 3343, /* D071 (53361) */ - 3343, /* D072 (53362) */ - 3343, /* D073 (53363) */ - 3343, /* D074 (53364) */ - 3343, /* D075 (53365) */ - 3343, /* D076 (53366) */ - 3343, /* D077 (53367) */ - 3343, /* D078 (53368) */ - 3343, /* D079 (53369) */ - 3343, /* D07A (53370) */ - 3343, /* D07B (53371) */ - 3343, /* D07C (53372) */ - 3343, /* D07D (53373) */ - 3343, /* D07E (53374) */ - 3343, /* D07F (53375) */ - 3343, /* D080 (53376) */ - 3343, /* D081 (53377) */ - 3343, /* D082 (53378) */ - 3343, /* D083 (53379) */ - 3343, /* D084 (53380) */ - 3343, /* D085 (53381) */ - 3343, /* D086 (53382) */ - 3343, /* D087 (53383) */ - 3343, /* D088 (53384) */ - 3343, /* D089 (53385) */ - 3343, /* D08A (53386) */ - 3343, /* D08B (53387) */ - 3343, /* D08C (53388) */ - 3343, /* D08D (53389) */ - 3343, /* D08E (53390) */ - 3343, /* D08F (53391) */ - 3343, /* D090 (53392) */ - 3343, /* D091 (53393) */ - 3343, /* D092 (53394) */ - 3343, /* D093 (53395) */ - 3343, /* D094 (53396) */ - 3343, /* D095 (53397) */ - 3343, /* D096 (53398) */ - 3343, /* D097 (53399) */ - 3343, /* D098 (53400) */ - 3343, /* D099 (53401) */ - 3343, /* D09A (53402) */ - 3343, /* D09B (53403) */ - 3343, /* D09C (53404) */ - 3343, /* D09D (53405) */ - 3343, /* D09E (53406) */ - 3343, /* D09F (53407) */ - 3343, /* D0A0 (53408) */ - 3343, /* D0A1 (53409) */ - 3343, /* D0A2 (53410) */ - 3343, /* D0A3 (53411) */ - 3343, /* D0A4 (53412) */ - 3343, /* D0A5 (53413) */ - 3343, /* D0A6 (53414) */ - 3343, /* D0A7 (53415) */ - 3343, /* D0A8 (53416) */ - 3343, /* D0A9 (53417) */ - 3343, /* D0AA (53418) */ - 3343, /* D0AB (53419) */ - 3343, /* D0AC (53420) */ - 3343, /* D0AD (53421) */ - 3343, /* D0AE (53422) */ - 3343, /* D0AF (53423) */ - 3343, /* D0B0 (53424) */ - 3343, /* D0B1 (53425) */ - 3343, /* D0B2 (53426) */ - 3343, /* D0B3 (53427) */ - 3343, /* D0B4 (53428) */ - 3343, /* D0B5 (53429) */ - 3343, /* D0B6 (53430) */ - 3343, /* D0B7 (53431) */ - 3343, /* D0B8 (53432) */ - 3343, /* D0B9 (53433) */ - 3343, /* D0BA (53434) */ - 3343, /* D0BB (53435) */ - 3343, /* D0BC (53436) */ - 3343, /* D0BD (53437) */ - 3343, /* D0BE (53438) */ - 3343, /* D0BF (53439) */ - 3343, /* D0C0 (53440) */ - 3343, /* D0C1 (53441) */ - 3343, /* D0C2 (53442) */ - 3343, /* D0C3 (53443) */ - 3343, /* D0C4 (53444) */ - 3343, /* D0C5 (53445) */ - 3343, /* D0C6 (53446) */ - 3343, /* D0C7 (53447) */ - 3343, /* D0C8 (53448) */ - 3343, /* D0C9 (53449) */ - 3343, /* D0CA (53450) */ - 3343, /* D0CB (53451) */ - 3343, /* D0CC (53452) */ - 3343, /* D0CD (53453) */ - 3343, /* D0CE (53454) */ - 3343, /* D0CF (53455) */ - 3343, /* D0D0 (53456) */ - 3343, /* D0D1 (53457) */ - 3343, /* D0D2 (53458) */ - 3343, /* D0D3 (53459) */ - 3343, /* D0D4 (53460) */ - 3343, /* D0D5 (53461) */ - 3343, /* D0D6 (53462) */ - 3343, /* D0D7 (53463) */ - 3343, /* D0D8 (53464) */ - 3343, /* D0D9 (53465) */ - 3343, /* D0DA (53466) */ - 3343, /* D0DB (53467) */ - 3343, /* D0DC (53468) */ - 3343, /* D0DD (53469) */ - 3343, /* D0DE (53470) */ - 3343, /* D0DF (53471) */ - 3343, /* D0E0 (53472) */ - 3343, /* D0E1 (53473) */ - 3343, /* D0E2 (53474) */ - 3343, /* D0E3 (53475) */ - 3343, /* D0E4 (53476) */ - 3343, /* D0E5 (53477) */ - 3343, /* D0E6 (53478) */ - 3343, /* D0E7 (53479) */ - 3343, /* D0E8 (53480) */ - 3343, /* D0E9 (53481) */ - 3343, /* D0EA (53482) */ - 3343, /* D0EB (53483) */ - 3343, /* D0EC (53484) */ - 3343, /* D0ED (53485) */ - 3343, /* D0EE (53486) */ - 3343, /* D0EF (53487) */ - 3343, /* D0F0 (53488) */ - 3343, /* D0F1 (53489) */ - 3343, /* D0F2 (53490) */ - 3343, /* D0F3 (53491) */ - 3343, /* D0F4 (53492) */ - 3343, /* D0F5 (53493) */ - 3343, /* D0F6 (53494) */ - 3343, /* D0F7 (53495) */ - 3343, /* D0F8 (53496) */ - 3343, /* D0F9 (53497) */ - 3343, /* D0FA (53498) */ - 3343, /* D0FB (53499) */ - 3343, /* D0FC (53500) */ - 3343, /* D0FD (53501) */ - 3343, /* D0FE (53502) */ - 3343, /* D0FF (53503) */ - 3343, /* D100 (53504) */ - 3343, /* D101 (53505) */ - 3343, /* D102 (53506) */ - 3343, /* D103 (53507) */ - 3343, /* D104 (53508) */ - 3343, /* D105 (53509) */ - 3343, /* D106 (53510) */ - 3343, /* D107 (53511) */ - 3343, /* D108 (53512) */ - 3343, /* D109 (53513) */ - 3343, /* D10A (53514) */ - 3343, /* D10B (53515) */ - 3343, /* D10C (53516) */ - 3343, /* D10D (53517) */ - 3343, /* D10E (53518) */ - 3343, /* D10F (53519) */ - 3343, /* D110 (53520) */ - 3343, /* D111 (53521) */ - 3343, /* D112 (53522) */ - 3343, /* D113 (53523) */ - 3343, /* D114 (53524) */ - 3343, /* D115 (53525) */ - 3343, /* D116 (53526) */ - 3343, /* D117 (53527) */ - 3343, /* D118 (53528) */ - 3343, /* D119 (53529) */ - 3343, /* D11A (53530) */ - 3343, /* D11B (53531) */ - 3343, /* D11C (53532) */ - 3343, /* D11D (53533) */ - 3343, /* D11E (53534) */ - 3343, /* D11F (53535) */ - 3343, /* D120 (53536) */ - 3343, /* D121 (53537) */ - 3343, /* D122 (53538) */ - 3343, /* D123 (53539) */ - 3343, /* D124 (53540) */ - 3343, /* D125 (53541) */ - 3343, /* D126 (53542) */ - 3343, /* D127 (53543) */ - 3343, /* D128 (53544) */ - 3343, /* D129 (53545) */ - 3343, /* D12A (53546) */ - 3343, /* D12B (53547) */ - 3343, /* D12C (53548) */ - 3343, /* D12D (53549) */ - 3343, /* D12E (53550) */ - 3343, /* D12F (53551) */ - 3343, /* D130 (53552) */ - 3343, /* D131 (53553) */ - 3343, /* D132 (53554) */ - 3343, /* D133 (53555) */ - 3343, /* D134 (53556) */ - 3343, /* D135 (53557) */ - 3343, /* D136 (53558) */ - 3343, /* D137 (53559) */ - 3343, /* D138 (53560) */ - 3343, /* D139 (53561) */ - 3343, /* D13A (53562) */ - 3343, /* D13B (53563) */ - 3343, /* D13C (53564) */ - 3343, /* D13D (53565) */ - 3343, /* D13E (53566) */ - 3343, /* D13F (53567) */ - 3343, /* D140 (53568) */ - 3343, /* D141 (53569) */ - 3343, /* D142 (53570) */ - 3343, /* D143 (53571) */ - 3343, /* D144 (53572) */ - 3343, /* D145 (53573) */ - 3343, /* D146 (53574) */ - 3343, /* D147 (53575) */ - 3343, /* D148 (53576) */ - 3343, /* D149 (53577) */ - 3343, /* D14A (53578) */ - 3343, /* D14B (53579) */ - 3343, /* D14C (53580) */ - 3343, /* D14D (53581) */ - 3343, /* D14E (53582) */ - 3343, /* D14F (53583) */ - 3343, /* D150 (53584) */ - 3343, /* D151 (53585) */ - 3343, /* D152 (53586) */ - 3343, /* D153 (53587) */ - 3343, /* D154 (53588) */ - 3343, /* D155 (53589) */ - 3343, /* D156 (53590) */ - 3343, /* D157 (53591) */ - 3343, /* D158 (53592) */ - 3343, /* D159 (53593) */ - 3343, /* D15A (53594) */ - 3343, /* D15B (53595) */ - 3343, /* D15C (53596) */ - 3343, /* D15D (53597) */ - 3343, /* D15E (53598) */ - 3343, /* D15F (53599) */ - 3343, /* D160 (53600) */ - 3343, /* D161 (53601) */ - 3343, /* D162 (53602) */ - 3343, /* D163 (53603) */ - 3343, /* D164 (53604) */ - 3343, /* D165 (53605) */ - 3343, /* D166 (53606) */ - 3343, /* D167 (53607) */ - 3343, /* D168 (53608) */ - 3343, /* D169 (53609) */ - 3343, /* D16A (53610) */ - 3343, /* D16B (53611) */ - 3343, /* D16C (53612) */ - 3343, /* D16D (53613) */ - 3343, /* D16E (53614) */ - 3343, /* D16F (53615) */ - 3343, /* D170 (53616) */ - 3343, /* D171 (53617) */ - 3343, /* D172 (53618) */ - 3343, /* D173 (53619) */ - 3343, /* D174 (53620) */ - 3343, /* D175 (53621) */ - 3343, /* D176 (53622) */ - 3343, /* D177 (53623) */ - 3343, /* D178 (53624) */ - 3343, /* D179 (53625) */ - 3343, /* D17A (53626) */ - 3343, /* D17B (53627) */ - 3343, /* D17C (53628) */ - 3343, /* D17D (53629) */ - 3343, /* D17E (53630) */ - 3343, /* D17F (53631) */ - 3343, /* D180 (53632) */ - 3343, /* D181 (53633) */ - 3343, /* D182 (53634) */ - 3343, /* D183 (53635) */ - 3343, /* D184 (53636) */ - 3343, /* D185 (53637) */ - 3343, /* D186 (53638) */ - 3343, /* D187 (53639) */ - 3343, /* D188 (53640) */ - 3343, /* D189 (53641) */ - 3343, /* D18A (53642) */ - 3343, /* D18B (53643) */ - 3343, /* D18C (53644) */ - 3343, /* D18D (53645) */ - 3343, /* D18E (53646) */ - 3343, /* D18F (53647) */ - 3343, /* D190 (53648) */ - 3343, /* D191 (53649) */ - 3343, /* D192 (53650) */ - 3343, /* D193 (53651) */ - 3343, /* D194 (53652) */ - 3343, /* D195 (53653) */ - 3343, /* D196 (53654) */ - 3343, /* D197 (53655) */ - 3343, /* D198 (53656) */ - 3343, /* D199 (53657) */ - 3343, /* D19A (53658) */ - 3343, /* D19B (53659) */ - 3343, /* D19C (53660) */ - 3343, /* D19D (53661) */ - 3343, /* D19E (53662) */ - 3343, /* D19F (53663) */ - 3343, /* D1A0 (53664) */ - 3343, /* D1A1 (53665) */ - 3343, /* D1A2 (53666) */ - 3343, /* D1A3 (53667) */ - 3343, /* D1A4 (53668) */ - 3343, /* D1A5 (53669) */ - 3343, /* D1A6 (53670) */ - 3343, /* D1A7 (53671) */ - 3343, /* D1A8 (53672) */ - 3343, /* D1A9 (53673) */ - 3343, /* D1AA (53674) */ - 3343, /* D1AB (53675) */ - 3343, /* D1AC (53676) */ - 3343, /* D1AD (53677) */ - 3343, /* D1AE (53678) */ - 3343, /* D1AF (53679) */ - 3343, /* D1B0 (53680) */ - 3343, /* D1B1 (53681) */ - 3343, /* D1B2 (53682) */ - 3343, /* D1B3 (53683) */ - 3343, /* D1B4 (53684) */ - 3343, /* D1B5 (53685) */ - 3343, /* D1B6 (53686) */ - 3343, /* D1B7 (53687) */ - 3343, /* D1B8 (53688) */ - 3343, /* D1B9 (53689) */ - 3343, /* D1BA (53690) */ - 3343, /* D1BB (53691) */ - 3343, /* D1BC (53692) */ - 3343, /* D1BD (53693) */ - 3343, /* D1BE (53694) */ - 3343, /* D1BF (53695) */ - 3343, /* D1C0 (53696) */ - 3343, /* D1C1 (53697) */ - 3343, /* D1C2 (53698) */ - 3343, /* D1C3 (53699) */ - 3343, /* D1C4 (53700) */ - 3343, /* D1C5 (53701) */ - 3343, /* D1C6 (53702) */ - 3343, /* D1C7 (53703) */ - 3343, /* D1C8 (53704) */ - 3343, /* D1C9 (53705) */ - 3343, /* D1CA (53706) */ - 3343, /* D1CB (53707) */ - 3343, /* D1CC (53708) */ - 3343, /* D1CD (53709) */ - 3343, /* D1CE (53710) */ - 3343, /* D1CF (53711) */ - 3343, /* D1D0 (53712) */ - 3343, /* D1D1 (53713) */ - 3343, /* D1D2 (53714) */ - 3343, /* D1D3 (53715) */ - 3343, /* D1D4 (53716) */ - 3343, /* D1D5 (53717) */ - 3343, /* D1D6 (53718) */ - 3343, /* D1D7 (53719) */ - 3343, /* D1D8 (53720) */ - 3343, /* D1D9 (53721) */ - 3343, /* D1DA (53722) */ - 3343, /* D1DB (53723) */ - 3343, /* D1DC (53724) */ - 3343, /* D1DD (53725) */ - 3343, /* D1DE (53726) */ - 3343, /* D1DF (53727) */ - 3343, /* D1E0 (53728) */ - 3343, /* D1E1 (53729) */ - 3343, /* D1E2 (53730) */ - 3343, /* D1E3 (53731) */ - 3343, /* D1E4 (53732) */ - 3343, /* D1E5 (53733) */ - 3343, /* D1E6 (53734) */ - 3343, /* D1E7 (53735) */ - 3343, /* D1E8 (53736) */ - 3343, /* D1E9 (53737) */ - 3343, /* D1EA (53738) */ - 3343, /* D1EB (53739) */ - 3343, /* D1EC (53740) */ - 3343, /* D1ED (53741) */ - 3343, /* D1EE (53742) */ - 3343, /* D1EF (53743) */ - 3343, /* D1F0 (53744) */ - 3343, /* D1F1 (53745) */ - 3343, /* D1F2 (53746) */ - 3343, /* D1F3 (53747) */ - 3343, /* D1F4 (53748) */ - 3343, /* D1F5 (53749) */ - 3343, /* D1F6 (53750) */ - 3343, /* D1F7 (53751) */ - 3343, /* D1F8 (53752) */ - 3343, /* D1F9 (53753) */ - 3343, /* D1FA (53754) */ - 3343, /* D1FB (53755) */ - 3343, /* D1FC (53756) */ - 3343, /* D1FD (53757) */ - 3343, /* D1FE (53758) */ - 3343, /* D1FF (53759) */ - 3343, /* D200 (53760) */ - 3343, /* D201 (53761) */ - 3343, /* D202 (53762) */ - 3343, /* D203 (53763) */ - 3343, /* D204 (53764) */ - 3343, /* D205 (53765) */ - 3343, /* D206 (53766) */ - 3343, /* D207 (53767) */ - 3343, /* D208 (53768) */ - 3343, /* D209 (53769) */ - 3343, /* D20A (53770) */ - 3343, /* D20B (53771) */ - 3343, /* D20C (53772) */ - 3343, /* D20D (53773) */ - 3343, /* D20E (53774) */ - 3343, /* D20F (53775) */ - 3343, /* D210 (53776) */ - 3343, /* D211 (53777) */ - 3343, /* D212 (53778) */ - 3343, /* D213 (53779) */ - 3343, /* D214 (53780) */ - 3343, /* D215 (53781) */ - 3343, /* D216 (53782) */ - 3343, /* D217 (53783) */ - 3343, /* D218 (53784) */ - 3343, /* D219 (53785) */ - 3343, /* D21A (53786) */ - 3343, /* D21B (53787) */ - 3343, /* D21C (53788) */ - 3343, /* D21D (53789) */ - 3343, /* D21E (53790) */ - 3343, /* D21F (53791) */ - 3343, /* D220 (53792) */ - 3343, /* D221 (53793) */ - 3343, /* D222 (53794) */ - 3343, /* D223 (53795) */ - 3343, /* D224 (53796) */ - 3343, /* D225 (53797) */ - 3343, /* D226 (53798) */ - 3343, /* D227 (53799) */ - 3343, /* D228 (53800) */ - 3343, /* D229 (53801) */ - 3343, /* D22A (53802) */ - 3343, /* D22B (53803) */ - 3343, /* D22C (53804) */ - 3343, /* D22D (53805) */ - 3343, /* D22E (53806) */ - 3343, /* D22F (53807) */ - 3343, /* D230 (53808) */ - 3343, /* D231 (53809) */ - 3343, /* D232 (53810) */ - 3343, /* D233 (53811) */ - 3343, /* D234 (53812) */ - 3343, /* D235 (53813) */ - 3343, /* D236 (53814) */ - 3343, /* D237 (53815) */ - 3343, /* D238 (53816) */ - 3343, /* D239 (53817) */ - 3343, /* D23A (53818) */ - 3343, /* D23B (53819) */ - 3343, /* D23C (53820) */ - 3343, /* D23D (53821) */ - 3343, /* D23E (53822) */ - 3343, /* D23F (53823) */ - 3343, /* D240 (53824) */ - 3343, /* D241 (53825) */ - 3343, /* D242 (53826) */ - 3343, /* D243 (53827) */ - 3343, /* D244 (53828) */ - 3343, /* D245 (53829) */ - 3343, /* D246 (53830) */ - 3343, /* D247 (53831) */ - 3343, /* D248 (53832) */ - 3343, /* D249 (53833) */ - 3343, /* D24A (53834) */ - 3343, /* D24B (53835) */ - 3343, /* D24C (53836) */ - 3343, /* D24D (53837) */ - 3343, /* D24E (53838) */ - 3343, /* D24F (53839) */ - 3343, /* D250 (53840) */ - 3343, /* D251 (53841) */ - 3343, /* D252 (53842) */ - 3343, /* D253 (53843) */ - 3343, /* D254 (53844) */ - 3343, /* D255 (53845) */ - 3343, /* D256 (53846) */ - 3343, /* D257 (53847) */ - 3343, /* D258 (53848) */ - 3343, /* D259 (53849) */ - 3343, /* D25A (53850) */ - 3343, /* D25B (53851) */ - 3343, /* D25C (53852) */ - 3343, /* D25D (53853) */ - 3343, /* D25E (53854) */ - 3343, /* D25F (53855) */ - 3343, /* D260 (53856) */ - 3343, /* D261 (53857) */ - 3343, /* D262 (53858) */ - 3343, /* D263 (53859) */ - 3343, /* D264 (53860) */ - 3343, /* D265 (53861) */ - 3343, /* D266 (53862) */ - 3343, /* D267 (53863) */ - 3343, /* D268 (53864) */ - 3343, /* D269 (53865) */ - 3343, /* D26A (53866) */ - 3343, /* D26B (53867) */ - 3343, /* D26C (53868) */ - 3343, /* D26D (53869) */ - 3343, /* D26E (53870) */ - 3343, /* D26F (53871) */ - 3343, /* D270 (53872) */ - 3343, /* D271 (53873) */ - 3343, /* D272 (53874) */ - 3343, /* D273 (53875) */ - 3343, /* D274 (53876) */ - 3343, /* D275 (53877) */ - 3343, /* D276 (53878) */ - 3343, /* D277 (53879) */ - 3343, /* D278 (53880) */ - 3343, /* D279 (53881) */ - 3343, /* D27A (53882) */ - 3343, /* D27B (53883) */ - 3343, /* D27C (53884) */ - 3343, /* D27D (53885) */ - 3343, /* D27E (53886) */ - 3343, /* D27F (53887) */ - 3343, /* D280 (53888) */ - 3343, /* D281 (53889) */ - 3343, /* D282 (53890) */ - 3343, /* D283 (53891) */ - 3343, /* D284 (53892) */ - 3343, /* D285 (53893) */ - 3343, /* D286 (53894) */ - 3343, /* D287 (53895) */ - 3343, /* D288 (53896) */ - 3343, /* D289 (53897) */ - 3343, /* D28A (53898) */ - 3343, /* D28B (53899) */ - 3343, /* D28C (53900) */ - 3343, /* D28D (53901) */ - 3343, /* D28E (53902) */ - 3343, /* D28F (53903) */ - 3343, /* D290 (53904) */ - 3343, /* D291 (53905) */ - 3343, /* D292 (53906) */ - 3343, /* D293 (53907) */ - 3343, /* D294 (53908) */ - 3343, /* D295 (53909) */ - 3343, /* D296 (53910) */ - 3343, /* D297 (53911) */ - 3343, /* D298 (53912) */ - 3343, /* D299 (53913) */ - 3343, /* D29A (53914) */ - 3343, /* D29B (53915) */ - 3343, /* D29C (53916) */ - 3343, /* D29D (53917) */ - 3343, /* D29E (53918) */ - 3343, /* D29F (53919) */ - 3343, /* D2A0 (53920) */ - 3343, /* D2A1 (53921) */ - 3343, /* D2A2 (53922) */ - 3343, /* D2A3 (53923) */ - 3343, /* D2A4 (53924) */ - 3343, /* D2A5 (53925) */ - 3343, /* D2A6 (53926) */ - 3343, /* D2A7 (53927) */ - 3343, /* D2A8 (53928) */ - 3343, /* D2A9 (53929) */ - 3343, /* D2AA (53930) */ - 3343, /* D2AB (53931) */ - 3343, /* D2AC (53932) */ - 3343, /* D2AD (53933) */ - 3343, /* D2AE (53934) */ - 3343, /* D2AF (53935) */ - 3343, /* D2B0 (53936) */ - 3343, /* D2B1 (53937) */ - 3343, /* D2B2 (53938) */ - 3343, /* D2B3 (53939) */ - 3343, /* D2B4 (53940) */ - 3343, /* D2B5 (53941) */ - 3343, /* D2B6 (53942) */ - 3343, /* D2B7 (53943) */ - 3343, /* D2B8 (53944) */ - 3343, /* D2B9 (53945) */ - 3343, /* D2BA (53946) */ - 3343, /* D2BB (53947) */ - 3343, /* D2BC (53948) */ - 3343, /* D2BD (53949) */ - 3343, /* D2BE (53950) */ - 3343, /* D2BF (53951) */ - 3343, /* D2C0 (53952) */ - 3343, /* D2C1 (53953) */ - 3343, /* D2C2 (53954) */ - 3343, /* D2C3 (53955) */ - 3343, /* D2C4 (53956) */ - 3343, /* D2C5 (53957) */ - 3343, /* D2C6 (53958) */ - 3343, /* D2C7 (53959) */ - 3343, /* D2C8 (53960) */ - 3343, /* D2C9 (53961) */ - 3343, /* D2CA (53962) */ - 3343, /* D2CB (53963) */ - 3343, /* D2CC (53964) */ - 3343, /* D2CD (53965) */ - 3343, /* D2CE (53966) */ - 3343, /* D2CF (53967) */ - 3343, /* D2D0 (53968) */ - 3343, /* D2D1 (53969) */ - 3343, /* D2D2 (53970) */ - 3343, /* D2D3 (53971) */ - 3343, /* D2D4 (53972) */ - 3343, /* D2D5 (53973) */ - 3343, /* D2D6 (53974) */ - 3343, /* D2D7 (53975) */ - 3343, /* D2D8 (53976) */ - 3343, /* D2D9 (53977) */ - 3343, /* D2DA (53978) */ - 3343, /* D2DB (53979) */ - 3343, /* D2DC (53980) */ - 3343, /* D2DD (53981) */ - 3343, /* D2DE (53982) */ - 3343, /* D2DF (53983) */ - 3343, /* D2E0 (53984) */ - 3343, /* D2E1 (53985) */ - 3343, /* D2E2 (53986) */ - 3343, /* D2E3 (53987) */ - 3343, /* D2E4 (53988) */ - 3343, /* D2E5 (53989) */ - 3343, /* D2E6 (53990) */ - 3343, /* D2E7 (53991) */ - 3343, /* D2E8 (53992) */ - 3343, /* D2E9 (53993) */ - 3343, /* D2EA (53994) */ - 3343, /* D2EB (53995) */ - 3343, /* D2EC (53996) */ - 3343, /* D2ED (53997) */ - 3343, /* D2EE (53998) */ - 3343, /* D2EF (53999) */ - 3343, /* D2F0 (54000) */ - 3343, /* D2F1 (54001) */ - 3343, /* D2F2 (54002) */ - 3343, /* D2F3 (54003) */ - 3343, /* D2F4 (54004) */ - 3343, /* D2F5 (54005) */ - 3343, /* D2F6 (54006) */ - 3343, /* D2F7 (54007) */ - 3343, /* D2F8 (54008) */ - 3343, /* D2F9 (54009) */ - 3343, /* D2FA (54010) */ - 3343, /* D2FB (54011) */ - 3343, /* D2FC (54012) */ - 3343, /* D2FD (54013) */ - 3343, /* D2FE (54014) */ - 3343, /* D2FF (54015) */ - 3343, /* D300 (54016) */ - 3343, /* D301 (54017) */ - 3343, /* D302 (54018) */ - 3343, /* D303 (54019) */ - 3343, /* D304 (54020) */ - 3343, /* D305 (54021) */ - 3343, /* D306 (54022) */ - 3343, /* D307 (54023) */ - 3343, /* D308 (54024) */ - 3343, /* D309 (54025) */ - 3343, /* D30A (54026) */ - 3343, /* D30B (54027) */ - 3343, /* D30C (54028) */ - 3343, /* D30D (54029) */ - 3343, /* D30E (54030) */ - 3343, /* D30F (54031) */ - 3343, /* D310 (54032) */ - 3343, /* D311 (54033) */ - 3343, /* D312 (54034) */ - 3343, /* D313 (54035) */ - 3343, /* D314 (54036) */ - 3343, /* D315 (54037) */ - 3343, /* D316 (54038) */ - 3343, /* D317 (54039) */ - 3343, /* D318 (54040) */ - 3343, /* D319 (54041) */ - 3343, /* D31A (54042) */ - 3343, /* D31B (54043) */ - 3343, /* D31C (54044) */ - 3343, /* D31D (54045) */ - 3343, /* D31E (54046) */ - 3343, /* D31F (54047) */ - 3343, /* D320 (54048) */ - 3343, /* D321 (54049) */ - 3343, /* D322 (54050) */ - 3343, /* D323 (54051) */ - 3343, /* D324 (54052) */ - 3343, /* D325 (54053) */ - 3343, /* D326 (54054) */ - 3343, /* D327 (54055) */ - 3343, /* D328 (54056) */ - 3343, /* D329 (54057) */ - 3343, /* D32A (54058) */ - 3343, /* D32B (54059) */ - 3343, /* D32C (54060) */ - 3343, /* D32D (54061) */ - 3343, /* D32E (54062) */ - 3343, /* D32F (54063) */ - 3343, /* D330 (54064) */ - 3343, /* D331 (54065) */ - 3343, /* D332 (54066) */ - 3343, /* D333 (54067) */ - 3343, /* D334 (54068) */ - 3343, /* D335 (54069) */ - 3343, /* D336 (54070) */ - 3343, /* D337 (54071) */ - 3343, /* D338 (54072) */ - 3343, /* D339 (54073) */ - 3343, /* D33A (54074) */ - 3343, /* D33B (54075) */ - 3343, /* D33C (54076) */ - 3343, /* D33D (54077) */ - 3343, /* D33E (54078) */ - 3343, /* D33F (54079) */ - 3343, /* D340 (54080) */ - 3343, /* D341 (54081) */ - 3343, /* D342 (54082) */ - 3343, /* D343 (54083) */ - 3343, /* D344 (54084) */ - 3343, /* D345 (54085) */ - 3343, /* D346 (54086) */ - 3343, /* D347 (54087) */ - 3343, /* D348 (54088) */ - 3343, /* D349 (54089) */ - 3343, /* D34A (54090) */ - 3343, /* D34B (54091) */ - 3343, /* D34C (54092) */ - 3343, /* D34D (54093) */ - 3343, /* D34E (54094) */ - 3343, /* D34F (54095) */ - 3343, /* D350 (54096) */ - 3343, /* D351 (54097) */ - 3343, /* D352 (54098) */ - 3343, /* D353 (54099) */ - 3343, /* D354 (54100) */ - 3343, /* D355 (54101) */ - 3343, /* D356 (54102) */ - 3343, /* D357 (54103) */ - 3343, /* D358 (54104) */ - 3343, /* D359 (54105) */ - 3343, /* D35A (54106) */ - 3343, /* D35B (54107) */ - 3343, /* D35C (54108) */ - 3343, /* D35D (54109) */ - 3343, /* D35E (54110) */ - 3343, /* D35F (54111) */ - 3343, /* D360 (54112) */ - 3343, /* D361 (54113) */ - 3343, /* D362 (54114) */ - 3343, /* D363 (54115) */ - 3343, /* D364 (54116) */ - 3343, /* D365 (54117) */ - 3343, /* D366 (54118) */ - 3343, /* D367 (54119) */ - 3343, /* D368 (54120) */ - 3343, /* D369 (54121) */ - 3343, /* D36A (54122) */ - 3343, /* D36B (54123) */ - 3343, /* D36C (54124) */ - 3343, /* D36D (54125) */ - 3343, /* D36E (54126) */ - 3343, /* D36F (54127) */ - 3343, /* D370 (54128) */ - 3343, /* D371 (54129) */ - 3343, /* D372 (54130) */ - 3343, /* D373 (54131) */ - 3343, /* D374 (54132) */ - 3343, /* D375 (54133) */ - 3343, /* D376 (54134) */ - 3343, /* D377 (54135) */ - 3343, /* D378 (54136) */ - 3343, /* D379 (54137) */ - 3343, /* D37A (54138) */ - 3343, /* D37B (54139) */ - 3343, /* D37C (54140) */ - 3343, /* D37D (54141) */ - 3343, /* D37E (54142) */ - 3343, /* D37F (54143) */ - 3343, /* D380 (54144) */ - 3343, /* D381 (54145) */ - 3343, /* D382 (54146) */ - 3343, /* D383 (54147) */ - 3343, /* D384 (54148) */ - 3343, /* D385 (54149) */ - 3343, /* D386 (54150) */ - 3343, /* D387 (54151) */ - 3343, /* D388 (54152) */ - 3343, /* D389 (54153) */ - 3343, /* D38A (54154) */ - 3343, /* D38B (54155) */ - 3343, /* D38C (54156) */ - 3343, /* D38D (54157) */ - 3343, /* D38E (54158) */ - 3343, /* D38F (54159) */ - 3343, /* D390 (54160) */ - 3343, /* D391 (54161) */ - 3343, /* D392 (54162) */ - 3343, /* D393 (54163) */ - 3343, /* D394 (54164) */ - 3343, /* D395 (54165) */ - 3343, /* D396 (54166) */ - 3343, /* D397 (54167) */ - 3343, /* D398 (54168) */ - 3343, /* D399 (54169) */ - 3343, /* D39A (54170) */ - 3343, /* D39B (54171) */ - 3343, /* D39C (54172) */ - 3343, /* D39D (54173) */ - 3343, /* D39E (54174) */ - 3343, /* D39F (54175) */ - 3343, /* D3A0 (54176) */ - 3343, /* D3A1 (54177) */ - 3343, /* D3A2 (54178) */ - 3343, /* D3A3 (54179) */ - 3343, /* D3A4 (54180) */ - 3343, /* D3A5 (54181) */ - 3343, /* D3A6 (54182) */ - 3343, /* D3A7 (54183) */ - 3343, /* D3A8 (54184) */ - 3343, /* D3A9 (54185) */ - 3343, /* D3AA (54186) */ - 3343, /* D3AB (54187) */ - 3343, /* D3AC (54188) */ - 3343, /* D3AD (54189) */ - 3343, /* D3AE (54190) */ - 3343, /* D3AF (54191) */ - 3343, /* D3B0 (54192) */ - 3343, /* D3B1 (54193) */ - 3343, /* D3B2 (54194) */ - 3343, /* D3B3 (54195) */ - 3343, /* D3B4 (54196) */ - 3343, /* D3B5 (54197) */ - 3343, /* D3B6 (54198) */ - 3343, /* D3B7 (54199) */ - 3343, /* D3B8 (54200) */ - 3343, /* D3B9 (54201) */ - 3343, /* D3BA (54202) */ - 3343, /* D3BB (54203) */ - 3343, /* D3BC (54204) */ - 3343, /* D3BD (54205) */ - 3343, /* D3BE (54206) */ - 3343, /* D3BF (54207) */ - 3343, /* D3C0 (54208) */ - 3343, /* D3C1 (54209) */ - 3343, /* D3C2 (54210) */ - 3343, /* D3C3 (54211) */ - 3343, /* D3C4 (54212) */ - 3343, /* D3C5 (54213) */ - 3343, /* D3C6 (54214) */ - 3343, /* D3C7 (54215) */ - 3343, /* D3C8 (54216) */ - 3343, /* D3C9 (54217) */ - 3343, /* D3CA (54218) */ - 3343, /* D3CB (54219) */ - 3343, /* D3CC (54220) */ - 3343, /* D3CD (54221) */ - 3343, /* D3CE (54222) */ - 3343, /* D3CF (54223) */ - 3343, /* D3D0 (54224) */ - 3343, /* D3D1 (54225) */ - 3343, /* D3D2 (54226) */ - 3343, /* D3D3 (54227) */ - 3343, /* D3D4 (54228) */ - 3343, /* D3D5 (54229) */ - 3343, /* D3D6 (54230) */ - 3343, /* D3D7 (54231) */ - 3343, /* D3D8 (54232) */ - 3343, /* D3D9 (54233) */ - 3343, /* D3DA (54234) */ - 3343, /* D3DB (54235) */ - 3343, /* D3DC (54236) */ - 3343, /* D3DD (54237) */ - 3343, /* D3DE (54238) */ - 3343, /* D3DF (54239) */ - 3343, /* D3E0 (54240) */ - 3343, /* D3E1 (54241) */ - 3343, /* D3E2 (54242) */ - 3343, /* D3E3 (54243) */ - 3343, /* D3E4 (54244) */ - 3343, /* D3E5 (54245) */ - 3343, /* D3E6 (54246) */ - 3343, /* D3E7 (54247) */ - 3343, /* D3E8 (54248) */ - 3343, /* D3E9 (54249) */ - 3343, /* D3EA (54250) */ - 3343, /* D3EB (54251) */ - 3343, /* D3EC (54252) */ - 3343, /* D3ED (54253) */ - 3343, /* D3EE (54254) */ - 3343, /* D3EF (54255) */ - 3343, /* D3F0 (54256) */ - 3343, /* D3F1 (54257) */ - 3343, /* D3F2 (54258) */ - 3343, /* D3F3 (54259) */ - 3343, /* D3F4 (54260) */ - 3343, /* D3F5 (54261) */ - 3343, /* D3F6 (54262) */ - 3343, /* D3F7 (54263) */ - 3343, /* D3F8 (54264) */ - 3343, /* D3F9 (54265) */ - 3343, /* D3FA (54266) */ - 3343, /* D3FB (54267) */ - 3343, /* D3FC (54268) */ - 3343, /* D3FD (54269) */ - 3343, /* D3FE (54270) */ - 3343, /* D3FF (54271) */ - 3343, /* D400 (54272) */ - 3343, /* D401 (54273) */ - 3343, /* D402 (54274) */ - 3343, /* D403 (54275) */ - 3343, /* D404 (54276) */ - 3343, /* D405 (54277) */ - 3343, /* D406 (54278) */ - 3343, /* D407 (54279) */ - 3343, /* D408 (54280) */ - 3343, /* D409 (54281) */ - 3343, /* D40A (54282) */ - 3343, /* D40B (54283) */ - 3343, /* D40C (54284) */ - 3343, /* D40D (54285) */ - 3343, /* D40E (54286) */ - 3343, /* D40F (54287) */ - 3343, /* D410 (54288) */ - 3343, /* D411 (54289) */ - 3343, /* D412 (54290) */ - 3343, /* D413 (54291) */ - 3343, /* D414 (54292) */ - 3343, /* D415 (54293) */ - 3343, /* D416 (54294) */ - 3343, /* D417 (54295) */ - 3343, /* D418 (54296) */ - 3343, /* D419 (54297) */ - 3343, /* D41A (54298) */ - 3343, /* D41B (54299) */ - 3343, /* D41C (54300) */ - 3343, /* D41D (54301) */ - 3343, /* D41E (54302) */ - 3343, /* D41F (54303) */ - 3343, /* D420 (54304) */ - 3343, /* D421 (54305) */ - 3343, /* D422 (54306) */ - 3343, /* D423 (54307) */ - 3343, /* D424 (54308) */ - 3343, /* D425 (54309) */ - 3343, /* D426 (54310) */ - 3343, /* D427 (54311) */ - 3343, /* D428 (54312) */ - 3343, /* D429 (54313) */ - 3343, /* D42A (54314) */ - 3343, /* D42B (54315) */ - 3343, /* D42C (54316) */ - 3343, /* D42D (54317) */ - 3343, /* D42E (54318) */ - 3343, /* D42F (54319) */ - 3343, /* D430 (54320) */ - 3343, /* D431 (54321) */ - 3343, /* D432 (54322) */ - 3343, /* D433 (54323) */ - 3343, /* D434 (54324) */ - 3343, /* D435 (54325) */ - 3343, /* D436 (54326) */ - 3343, /* D437 (54327) */ - 3343, /* D438 (54328) */ - 3343, /* D439 (54329) */ - 3343, /* D43A (54330) */ - 3343, /* D43B (54331) */ - 3343, /* D43C (54332) */ - 3343, /* D43D (54333) */ - 3343, /* D43E (54334) */ - 3343, /* D43F (54335) */ - 3343, /* D440 (54336) */ - 3343, /* D441 (54337) */ - 3343, /* D442 (54338) */ - 3343, /* D443 (54339) */ - 3343, /* D444 (54340) */ - 3343, /* D445 (54341) */ - 3343, /* D446 (54342) */ - 3343, /* D447 (54343) */ - 3343, /* D448 (54344) */ - 3343, /* D449 (54345) */ - 3343, /* D44A (54346) */ - 3343, /* D44B (54347) */ - 3343, /* D44C (54348) */ - 3343, /* D44D (54349) */ - 3343, /* D44E (54350) */ - 3343, /* D44F (54351) */ - 3343, /* D450 (54352) */ - 3343, /* D451 (54353) */ - 3343, /* D452 (54354) */ - 3343, /* D453 (54355) */ - 3343, /* D454 (54356) */ - 3343, /* D455 (54357) */ - 3343, /* D456 (54358) */ - 3343, /* D457 (54359) */ - 3343, /* D458 (54360) */ - 3343, /* D459 (54361) */ - 3343, /* D45A (54362) */ - 3343, /* D45B (54363) */ - 3343, /* D45C (54364) */ - 3343, /* D45D (54365) */ - 3343, /* D45E (54366) */ - 3343, /* D45F (54367) */ - 3343, /* D460 (54368) */ - 3343, /* D461 (54369) */ - 3343, /* D462 (54370) */ - 3343, /* D463 (54371) */ - 3343, /* D464 (54372) */ - 3343, /* D465 (54373) */ - 3343, /* D466 (54374) */ - 3343, /* D467 (54375) */ - 3343, /* D468 (54376) */ - 3343, /* D469 (54377) */ - 3343, /* D46A (54378) */ - 3343, /* D46B (54379) */ - 3343, /* D46C (54380) */ - 3343, /* D46D (54381) */ - 3343, /* D46E (54382) */ - 3343, /* D46F (54383) */ - 3343, /* D470 (54384) */ - 3343, /* D471 (54385) */ - 3343, /* D472 (54386) */ - 3343, /* D473 (54387) */ - 3343, /* D474 (54388) */ - 3343, /* D475 (54389) */ - 3343, /* D476 (54390) */ - 3343, /* D477 (54391) */ - 3343, /* D478 (54392) */ - 3343, /* D479 (54393) */ - 3343, /* D47A (54394) */ - 3343, /* D47B (54395) */ - 3343, /* D47C (54396) */ - 3343, /* D47D (54397) */ - 3343, /* D47E (54398) */ - 3343, /* D47F (54399) */ - 3343, /* D480 (54400) */ - 3343, /* D481 (54401) */ - 3343, /* D482 (54402) */ - 3343, /* D483 (54403) */ - 3343, /* D484 (54404) */ - 3343, /* D485 (54405) */ - 3343, /* D486 (54406) */ - 3343, /* D487 (54407) */ - 3343, /* D488 (54408) */ - 3343, /* D489 (54409) */ - 3343, /* D48A (54410) */ - 3343, /* D48B (54411) */ - 3343, /* D48C (54412) */ - 3343, /* D48D (54413) */ - 3343, /* D48E (54414) */ - 3343, /* D48F (54415) */ - 3343, /* D490 (54416) */ - 3343, /* D491 (54417) */ - 3343, /* D492 (54418) */ - 3343, /* D493 (54419) */ - 3343, /* D494 (54420) */ - 3343, /* D495 (54421) */ - 3343, /* D496 (54422) */ - 3343, /* D497 (54423) */ - 3343, /* D498 (54424) */ - 3343, /* D499 (54425) */ - 3343, /* D49A (54426) */ - 3343, /* D49B (54427) */ - 3343, /* D49C (54428) */ - 3343, /* D49D (54429) */ - 3343, /* D49E (54430) */ - 3343, /* D49F (54431) */ - 3343, /* D4A0 (54432) */ - 3343, /* D4A1 (54433) */ - 3343, /* D4A2 (54434) */ - 3343, /* D4A3 (54435) */ - 3343, /* D4A4 (54436) */ - 3343, /* D4A5 (54437) */ - 3343, /* D4A6 (54438) */ - 3343, /* D4A7 (54439) */ - 3343, /* D4A8 (54440) */ - 3343, /* D4A9 (54441) */ - 3343, /* D4AA (54442) */ - 3343, /* D4AB (54443) */ - 3343, /* D4AC (54444) */ - 3343, /* D4AD (54445) */ - 3343, /* D4AE (54446) */ - 3343, /* D4AF (54447) */ - 3343, /* D4B0 (54448) */ - 3343, /* D4B1 (54449) */ - 3343, /* D4B2 (54450) */ - 3343, /* D4B3 (54451) */ - 3343, /* D4B4 (54452) */ - 3343, /* D4B5 (54453) */ - 3343, /* D4B6 (54454) */ - 3343, /* D4B7 (54455) */ - 3343, /* D4B8 (54456) */ - 3343, /* D4B9 (54457) */ - 3343, /* D4BA (54458) */ - 3343, /* D4BB (54459) */ - 3343, /* D4BC (54460) */ - 3343, /* D4BD (54461) */ - 3343, /* D4BE (54462) */ - 3343, /* D4BF (54463) */ - 3343, /* D4C0 (54464) */ - 3343, /* D4C1 (54465) */ - 3343, /* D4C2 (54466) */ - 3343, /* D4C3 (54467) */ - 3343, /* D4C4 (54468) */ - 3343, /* D4C5 (54469) */ - 3343, /* D4C6 (54470) */ - 3343, /* D4C7 (54471) */ - 3343, /* D4C8 (54472) */ - 3343, /* D4C9 (54473) */ - 3343, /* D4CA (54474) */ - 3343, /* D4CB (54475) */ - 3343, /* D4CC (54476) */ - 3343, /* D4CD (54477) */ - 3343, /* D4CE (54478) */ - 3343, /* D4CF (54479) */ - 3343, /* D4D0 (54480) */ - 3343, /* D4D1 (54481) */ - 3343, /* D4D2 (54482) */ - 3343, /* D4D3 (54483) */ - 3343, /* D4D4 (54484) */ - 3343, /* D4D5 (54485) */ - 3343, /* D4D6 (54486) */ - 3343, /* D4D7 (54487) */ - 3343, /* D4D8 (54488) */ - 3343, /* D4D9 (54489) */ - 3343, /* D4DA (54490) */ - 3343, /* D4DB (54491) */ - 3343, /* D4DC (54492) */ - 3343, /* D4DD (54493) */ - 3343, /* D4DE (54494) */ - 3343, /* D4DF (54495) */ - 3343, /* D4E0 (54496) */ - 3343, /* D4E1 (54497) */ - 3343, /* D4E2 (54498) */ - 3343, /* D4E3 (54499) */ - 3343, /* D4E4 (54500) */ - 3343, /* D4E5 (54501) */ - 3343, /* D4E6 (54502) */ - 3343, /* D4E7 (54503) */ - 3343, /* D4E8 (54504) */ - 3343, /* D4E9 (54505) */ - 3343, /* D4EA (54506) */ - 3343, /* D4EB (54507) */ - 3343, /* D4EC (54508) */ - 3343, /* D4ED (54509) */ - 3343, /* D4EE (54510) */ - 3343, /* D4EF (54511) */ - 3343, /* D4F0 (54512) */ - 3343, /* D4F1 (54513) */ - 3343, /* D4F2 (54514) */ - 3343, /* D4F3 (54515) */ - 3343, /* D4F4 (54516) */ - 3343, /* D4F5 (54517) */ - 3343, /* D4F6 (54518) */ - 3343, /* D4F7 (54519) */ - 3343, /* D4F8 (54520) */ - 3343, /* D4F9 (54521) */ - 3343, /* D4FA (54522) */ - 3343, /* D4FB (54523) */ - 3343, /* D4FC (54524) */ - 3343, /* D4FD (54525) */ - 3343, /* D4FE (54526) */ - 3343, /* D4FF (54527) */ - 3343, /* D500 (54528) */ - 3343, /* D501 (54529) */ - 3343, /* D502 (54530) */ - 3343, /* D503 (54531) */ - 3343, /* D504 (54532) */ - 3343, /* D505 (54533) */ - 3343, /* D506 (54534) */ - 3343, /* D507 (54535) */ - 3343, /* D508 (54536) */ - 3343, /* D509 (54537) */ - 3343, /* D50A (54538) */ - 3343, /* D50B (54539) */ - 3343, /* D50C (54540) */ - 3343, /* D50D (54541) */ - 3343, /* D50E (54542) */ - 3343, /* D50F (54543) */ - 3343, /* D510 (54544) */ - 3343, /* D511 (54545) */ - 3343, /* D512 (54546) */ - 3343, /* D513 (54547) */ - 3343, /* D514 (54548) */ - 3343, /* D515 (54549) */ - 3343, /* D516 (54550) */ - 3343, /* D517 (54551) */ - 3343, /* D518 (54552) */ - 3343, /* D519 (54553) */ - 3343, /* D51A (54554) */ - 3343, /* D51B (54555) */ - 3343, /* D51C (54556) */ - 3343, /* D51D (54557) */ - 3343, /* D51E (54558) */ - 3343, /* D51F (54559) */ - 3343, /* D520 (54560) */ - 3343, /* D521 (54561) */ - 3343, /* D522 (54562) */ - 3343, /* D523 (54563) */ - 3343, /* D524 (54564) */ - 3343, /* D525 (54565) */ - 3343, /* D526 (54566) */ - 3343, /* D527 (54567) */ - 3343, /* D528 (54568) */ - 3343, /* D529 (54569) */ - 3343, /* D52A (54570) */ - 3343, /* D52B (54571) */ - 3343, /* D52C (54572) */ - 3343, /* D52D (54573) */ - 3343, /* D52E (54574) */ - 3343, /* D52F (54575) */ - 3343, /* D530 (54576) */ - 3343, /* D531 (54577) */ - 3343, /* D532 (54578) */ - 3343, /* D533 (54579) */ - 3343, /* D534 (54580) */ - 3343, /* D535 (54581) */ - 3343, /* D536 (54582) */ - 3343, /* D537 (54583) */ - 3343, /* D538 (54584) */ - 3343, /* D539 (54585) */ - 3343, /* D53A (54586) */ - 3343, /* D53B (54587) */ - 3343, /* D53C (54588) */ - 3343, /* D53D (54589) */ - 3343, /* D53E (54590) */ - 3343, /* D53F (54591) */ - 3343, /* D540 (54592) */ - 3343, /* D541 (54593) */ - 3343, /* D542 (54594) */ - 3343, /* D543 (54595) */ - 3343, /* D544 (54596) */ - 3343, /* D545 (54597) */ - 3343, /* D546 (54598) */ - 3343, /* D547 (54599) */ - 3343, /* D548 (54600) */ - 3343, /* D549 (54601) */ - 3343, /* D54A (54602) */ - 3343, /* D54B (54603) */ - 3343, /* D54C (54604) */ - 3343, /* D54D (54605) */ - 3343, /* D54E (54606) */ - 3343, /* D54F (54607) */ - 3343, /* D550 (54608) */ - 3343, /* D551 (54609) */ - 3343, /* D552 (54610) */ - 3343, /* D553 (54611) */ - 3343, /* D554 (54612) */ - 3343, /* D555 (54613) */ - 3343, /* D556 (54614) */ - 3343, /* D557 (54615) */ - 3343, /* D558 (54616) */ - 3343, /* D559 (54617) */ - 3343, /* D55A (54618) */ - 3343, /* D55B (54619) */ - 3343, /* D55C (54620) */ - 3343, /* D55D (54621) */ - 3343, /* D55E (54622) */ - 3343, /* D55F (54623) */ - 3343, /* D560 (54624) */ - 3343, /* D561 (54625) */ - 3343, /* D562 (54626) */ - 3343, /* D563 (54627) */ - 3343, /* D564 (54628) */ - 3343, /* D565 (54629) */ - 3343, /* D566 (54630) */ - 3343, /* D567 (54631) */ - 3343, /* D568 (54632) */ - 3343, /* D569 (54633) */ - 3343, /* D56A (54634) */ - 3343, /* D56B (54635) */ - 3343, /* D56C (54636) */ - 3343, /* D56D (54637) */ - 3343, /* D56E (54638) */ - 3343, /* D56F (54639) */ - 3343, /* D570 (54640) */ - 3343, /* D571 (54641) */ - 3343, /* D572 (54642) */ - 3343, /* D573 (54643) */ - 3343, /* D574 (54644) */ - 3343, /* D575 (54645) */ - 3343, /* D576 (54646) */ - 3343, /* D577 (54647) */ - 3343, /* D578 (54648) */ - 3343, /* D579 (54649) */ - 3343, /* D57A (54650) */ - 3343, /* D57B (54651) */ - 3343, /* D57C (54652) */ - 3343, /* D57D (54653) */ - 3343, /* D57E (54654) */ - 3343, /* D57F (54655) */ - 3343, /* D580 (54656) */ - 3343, /* D581 (54657) */ - 3343, /* D582 (54658) */ - 3343, /* D583 (54659) */ - 3343, /* D584 (54660) */ - 3343, /* D585 (54661) */ - 3343, /* D586 (54662) */ - 3343, /* D587 (54663) */ - 3343, /* D588 (54664) */ - 3343, /* D589 (54665) */ - 3343, /* D58A (54666) */ - 3343, /* D58B (54667) */ - 3343, /* D58C (54668) */ - 3343, /* D58D (54669) */ - 3343, /* D58E (54670) */ - 3343, /* D58F (54671) */ - 3343, /* D590 (54672) */ - 3343, /* D591 (54673) */ - 3343, /* D592 (54674) */ - 3343, /* D593 (54675) */ - 3343, /* D594 (54676) */ - 3343, /* D595 (54677) */ - 3343, /* D596 (54678) */ - 3343, /* D597 (54679) */ - 3343, /* D598 (54680) */ - 3343, /* D599 (54681) */ - 3343, /* D59A (54682) */ - 3343, /* D59B (54683) */ - 3343, /* D59C (54684) */ - 3343, /* D59D (54685) */ - 3343, /* D59E (54686) */ - 3343, /* D59F (54687) */ - 3343, /* D5A0 (54688) */ - 3343, /* D5A1 (54689) */ - 3343, /* D5A2 (54690) */ - 3343, /* D5A3 (54691) */ - 3343, /* D5A4 (54692) */ - 3343, /* D5A5 (54693) */ - 3343, /* D5A6 (54694) */ - 3343, /* D5A7 (54695) */ - 3343, /* D5A8 (54696) */ - 3343, /* D5A9 (54697) */ - 3343, /* D5AA (54698) */ - 3343, /* D5AB (54699) */ - 3343, /* D5AC (54700) */ - 3343, /* D5AD (54701) */ - 3343, /* D5AE (54702) */ - 3343, /* D5AF (54703) */ - 3343, /* D5B0 (54704) */ - 3343, /* D5B1 (54705) */ - 3343, /* D5B2 (54706) */ - 3343, /* D5B3 (54707) */ - 3343, /* D5B4 (54708) */ - 3343, /* D5B5 (54709) */ - 3343, /* D5B6 (54710) */ - 3343, /* D5B7 (54711) */ - 3343, /* D5B8 (54712) */ - 3343, /* D5B9 (54713) */ - 3343, /* D5BA (54714) */ - 3343, /* D5BB (54715) */ - 3343, /* D5BC (54716) */ - 3343, /* D5BD (54717) */ - 3343, /* D5BE (54718) */ - 3343, /* D5BF (54719) */ - 3343, /* D5C0 (54720) */ - 3343, /* D5C1 (54721) */ - 3343, /* D5C2 (54722) */ - 3343, /* D5C3 (54723) */ - 3343, /* D5C4 (54724) */ - 3343, /* D5C5 (54725) */ - 3343, /* D5C6 (54726) */ - 3343, /* D5C7 (54727) */ - 3343, /* D5C8 (54728) */ - 3343, /* D5C9 (54729) */ - 3343, /* D5CA (54730) */ - 3343, /* D5CB (54731) */ - 3343, /* D5CC (54732) */ - 3343, /* D5CD (54733) */ - 3343, /* D5CE (54734) */ - 3343, /* D5CF (54735) */ - 3343, /* D5D0 (54736) */ - 3343, /* D5D1 (54737) */ - 3343, /* D5D2 (54738) */ - 3343, /* D5D3 (54739) */ - 3343, /* D5D4 (54740) */ - 3343, /* D5D5 (54741) */ - 3343, /* D5D6 (54742) */ - 3343, /* D5D7 (54743) */ - 3343, /* D5D8 (54744) */ - 3343, /* D5D9 (54745) */ - 3343, /* D5DA (54746) */ - 3343, /* D5DB (54747) */ - 3343, /* D5DC (54748) */ - 3343, /* D5DD (54749) */ - 3343, /* D5DE (54750) */ - 3343, /* D5DF (54751) */ - 3343, /* D5E0 (54752) */ - 3343, /* D5E1 (54753) */ - 3343, /* D5E2 (54754) */ - 3343, /* D5E3 (54755) */ - 3343, /* D5E4 (54756) */ - 3343, /* D5E5 (54757) */ - 3343, /* D5E6 (54758) */ - 3343, /* D5E7 (54759) */ - 3343, /* D5E8 (54760) */ - 3343, /* D5E9 (54761) */ - 3343, /* D5EA (54762) */ - 3343, /* D5EB (54763) */ - 3343, /* D5EC (54764) */ - 3343, /* D5ED (54765) */ - 3343, /* D5EE (54766) */ - 3343, /* D5EF (54767) */ - 3343, /* D5F0 (54768) */ - 3343, /* D5F1 (54769) */ - 3343, /* D5F2 (54770) */ - 3343, /* D5F3 (54771) */ - 3343, /* D5F4 (54772) */ - 3343, /* D5F5 (54773) */ - 3343, /* D5F6 (54774) */ - 3343, /* D5F7 (54775) */ - 3343, /* D5F8 (54776) */ - 3343, /* D5F9 (54777) */ - 3343, /* D5FA (54778) */ - 3343, /* D5FB (54779) */ - 3343, /* D5FC (54780) */ - 3343, /* D5FD (54781) */ - 3343, /* D5FE (54782) */ - 3343, /* D5FF (54783) */ - 3343, /* D600 (54784) */ - 3343, /* D601 (54785) */ - 3343, /* D602 (54786) */ - 3343, /* D603 (54787) */ - 3343, /* D604 (54788) */ - 3343, /* D605 (54789) */ - 3343, /* D606 (54790) */ - 3343, /* D607 (54791) */ - 3343, /* D608 (54792) */ - 3343, /* D609 (54793) */ - 3343, /* D60A (54794) */ - 3343, /* D60B (54795) */ - 3343, /* D60C (54796) */ - 3343, /* D60D (54797) */ - 3343, /* D60E (54798) */ - 3343, /* D60F (54799) */ - 3343, /* D610 (54800) */ - 3343, /* D611 (54801) */ - 3343, /* D612 (54802) */ - 3343, /* D613 (54803) */ - 3343, /* D614 (54804) */ - 3343, /* D615 (54805) */ - 3343, /* D616 (54806) */ - 3343, /* D617 (54807) */ - 3343, /* D618 (54808) */ - 3343, /* D619 (54809) */ - 3343, /* D61A (54810) */ - 3343, /* D61B (54811) */ - 3343, /* D61C (54812) */ - 3343, /* D61D (54813) */ - 3343, /* D61E (54814) */ - 3343, /* D61F (54815) */ - 3343, /* D620 (54816) */ - 3343, /* D621 (54817) */ - 3343, /* D622 (54818) */ - 3343, /* D623 (54819) */ - 3343, /* D624 (54820) */ - 3343, /* D625 (54821) */ - 3343, /* D626 (54822) */ - 3343, /* D627 (54823) */ - 3343, /* D628 (54824) */ - 3343, /* D629 (54825) */ - 3343, /* D62A (54826) */ - 3343, /* D62B (54827) */ - 3343, /* D62C (54828) */ - 3343, /* D62D (54829) */ - 3343, /* D62E (54830) */ - 3343, /* D62F (54831) */ - 3343, /* D630 (54832) */ - 3343, /* D631 (54833) */ - 3343, /* D632 (54834) */ - 3343, /* D633 (54835) */ - 3343, /* D634 (54836) */ - 3343, /* D635 (54837) */ - 3343, /* D636 (54838) */ - 3343, /* D637 (54839) */ - 3343, /* D638 (54840) */ - 3343, /* D639 (54841) */ - 3343, /* D63A (54842) */ - 3343, /* D63B (54843) */ - 3343, /* D63C (54844) */ - 3343, /* D63D (54845) */ - 3343, /* D63E (54846) */ - 3343, /* D63F (54847) */ - 3343, /* D640 (54848) */ - 3343, /* D641 (54849) */ - 3343, /* D642 (54850) */ - 3343, /* D643 (54851) */ - 3343, /* D644 (54852) */ - 3343, /* D645 (54853) */ - 3343, /* D646 (54854) */ - 3343, /* D647 (54855) */ - 3343, /* D648 (54856) */ - 3343, /* D649 (54857) */ - 3343, /* D64A (54858) */ - 3343, /* D64B (54859) */ - 3343, /* D64C (54860) */ - 3343, /* D64D (54861) */ - 3343, /* D64E (54862) */ - 3343, /* D64F (54863) */ - 3343, /* D650 (54864) */ - 3343, /* D651 (54865) */ - 3343, /* D652 (54866) */ - 3343, /* D653 (54867) */ - 3343, /* D654 (54868) */ - 3343, /* D655 (54869) */ - 3343, /* D656 (54870) */ - 3343, /* D657 (54871) */ - 3343, /* D658 (54872) */ - 3343, /* D659 (54873) */ - 3343, /* D65A (54874) */ - 3343, /* D65B (54875) */ - 3343, /* D65C (54876) */ - 3343, /* D65D (54877) */ - 3343, /* D65E (54878) */ - 3343, /* D65F (54879) */ - 3343, /* D660 (54880) */ - 3343, /* D661 (54881) */ - 3343, /* D662 (54882) */ - 3343, /* D663 (54883) */ - 3343, /* D664 (54884) */ - 3343, /* D665 (54885) */ - 3343, /* D666 (54886) */ - 3343, /* D667 (54887) */ - 3343, /* D668 (54888) */ - 3343, /* D669 (54889) */ - 3343, /* D66A (54890) */ - 3343, /* D66B (54891) */ - 3343, /* D66C (54892) */ - 3343, /* D66D (54893) */ - 3343, /* D66E (54894) */ - 3343, /* D66F (54895) */ - 3343, /* D670 (54896) */ - 3343, /* D671 (54897) */ - 3343, /* D672 (54898) */ - 3343, /* D673 (54899) */ - 3343, /* D674 (54900) */ - 3343, /* D675 (54901) */ - 3343, /* D676 (54902) */ - 3343, /* D677 (54903) */ - 3343, /* D678 (54904) */ - 3343, /* D679 (54905) */ - 3343, /* D67A (54906) */ - 3343, /* D67B (54907) */ - 3343, /* D67C (54908) */ - 3343, /* D67D (54909) */ - 3343, /* D67E (54910) */ - 3343, /* D67F (54911) */ - 3343, /* D680 (54912) */ - 3343, /* D681 (54913) */ - 3343, /* D682 (54914) */ - 3343, /* D683 (54915) */ - 3343, /* D684 (54916) */ - 3343, /* D685 (54917) */ - 3343, /* D686 (54918) */ - 3343, /* D687 (54919) */ - 3343, /* D688 (54920) */ - 3343, /* D689 (54921) */ - 3343, /* D68A (54922) */ - 3343, /* D68B (54923) */ - 3343, /* D68C (54924) */ - 3343, /* D68D (54925) */ - 3343, /* D68E (54926) */ - 3343, /* D68F (54927) */ - 3343, /* D690 (54928) */ - 3343, /* D691 (54929) */ - 3343, /* D692 (54930) */ - 3343, /* D693 (54931) */ - 3343, /* D694 (54932) */ - 3343, /* D695 (54933) */ - 3343, /* D696 (54934) */ - 3343, /* D697 (54935) */ - 3343, /* D698 (54936) */ - 3343, /* D699 (54937) */ - 3343, /* D69A (54938) */ - 3343, /* D69B (54939) */ - 3343, /* D69C (54940) */ - 3343, /* D69D (54941) */ - 3343, /* D69E (54942) */ - 3343, /* D69F (54943) */ - 3343, /* D6A0 (54944) */ - 3343, /* D6A1 (54945) */ - 3343, /* D6A2 (54946) */ - 3343, /* D6A3 (54947) */ - 3343, /* D6A4 (54948) */ - 3343, /* D6A5 (54949) */ - 3343, /* D6A6 (54950) */ - 3343, /* D6A7 (54951) */ - 3343, /* D6A8 (54952) */ - 3343, /* D6A9 (54953) */ - 3343, /* D6AA (54954) */ - 3343, /* D6AB (54955) */ - 3343, /* D6AC (54956) */ - 3343, /* D6AD (54957) */ - 3343, /* D6AE (54958) */ - 3343, /* D6AF (54959) */ - 3343, /* D6B0 (54960) */ - 3343, /* D6B1 (54961) */ - 3343, /* D6B2 (54962) */ - 3343, /* D6B3 (54963) */ - 3343, /* D6B4 (54964) */ - 3343, /* D6B5 (54965) */ - 3343, /* D6B6 (54966) */ - 3343, /* D6B7 (54967) */ - 3343, /* D6B8 (54968) */ - 3343, /* D6B9 (54969) */ - 3343, /* D6BA (54970) */ - 3343, /* D6BB (54971) */ - 3343, /* D6BC (54972) */ - 3343, /* D6BD (54973) */ - 3343, /* D6BE (54974) */ - 3343, /* D6BF (54975) */ - 3343, /* D6C0 (54976) */ - 3343, /* D6C1 (54977) */ - 3343, /* D6C2 (54978) */ - 3343, /* D6C3 (54979) */ - 3343, /* D6C4 (54980) */ - 3343, /* D6C5 (54981) */ - 3343, /* D6C6 (54982) */ - 3343, /* D6C7 (54983) */ - 3343, /* D6C8 (54984) */ - 3343, /* D6C9 (54985) */ - 3343, /* D6CA (54986) */ - 3343, /* D6CB (54987) */ - 3343, /* D6CC (54988) */ - 3343, /* D6CD (54989) */ - 3343, /* D6CE (54990) */ - 3343, /* D6CF (54991) */ - 3343, /* D6D0 (54992) */ - 3343, /* D6D1 (54993) */ - 3343, /* D6D2 (54994) */ - 3343, /* D6D3 (54995) */ - 3343, /* D6D4 (54996) */ - 3343, /* D6D5 (54997) */ - 3343, /* D6D6 (54998) */ - 3343, /* D6D7 (54999) */ - 3343, /* D6D8 (55000) */ - 3343, /* D6D9 (55001) */ - 3343, /* D6DA (55002) */ - 3343, /* D6DB (55003) */ - 3343, /* D6DC (55004) */ - 3343, /* D6DD (55005) */ - 3343, /* D6DE (55006) */ - 3343, /* D6DF (55007) */ - 3343, /* D6E0 (55008) */ - 3343, /* D6E1 (55009) */ - 3343, /* D6E2 (55010) */ - 3343, /* D6E3 (55011) */ - 3343, /* D6E4 (55012) */ - 3343, /* D6E5 (55013) */ - 3343, /* D6E6 (55014) */ - 3343, /* D6E7 (55015) */ - 3343, /* D6E8 (55016) */ - 3343, /* D6E9 (55017) */ - 3343, /* D6EA (55018) */ - 3343, /* D6EB (55019) */ - 3343, /* D6EC (55020) */ - 3343, /* D6ED (55021) */ - 3343, /* D6EE (55022) */ - 3343, /* D6EF (55023) */ - 3343, /* D6F0 (55024) */ - 3343, /* D6F1 (55025) */ - 3343, /* D6F2 (55026) */ - 3343, /* D6F3 (55027) */ - 3343, /* D6F4 (55028) */ - 3343, /* D6F5 (55029) */ - 3343, /* D6F6 (55030) */ - 3343, /* D6F7 (55031) */ - 3343, /* D6F8 (55032) */ - 3343, /* D6F9 (55033) */ - 3343, /* D6FA (55034) */ - 3343, /* D6FB (55035) */ - 3343, /* D6FC (55036) */ - 3343, /* D6FD (55037) */ - 3343, /* D6FE (55038) */ - 3343, /* D6FF (55039) */ - 3343, /* D700 (55040) */ - 3343, /* D701 (55041) */ - 3343, /* D702 (55042) */ - 3343, /* D703 (55043) */ - 3343, /* D704 (55044) */ - 3343, /* D705 (55045) */ - 3343, /* D706 (55046) */ - 3343, /* D707 (55047) */ - 3343, /* D708 (55048) */ - 3343, /* D709 (55049) */ - 3343, /* D70A (55050) */ - 3343, /* D70B (55051) */ - 3343, /* D70C (55052) */ - 3343, /* D70D (55053) */ - 3343, /* D70E (55054) */ - 3343, /* D70F (55055) */ - 3343, /* D710 (55056) */ - 3343, /* D711 (55057) */ - 3343, /* D712 (55058) */ - 3343, /* D713 (55059) */ - 3343, /* D714 (55060) */ - 3343, /* D715 (55061) */ - 3343, /* D716 (55062) */ - 3343, /* D717 (55063) */ - 3343, /* D718 (55064) */ - 3343, /* D719 (55065) */ - 3343, /* D71A (55066) */ - 3343, /* D71B (55067) */ - 3343, /* D71C (55068) */ - 3343, /* D71D (55069) */ - 3343, /* D71E (55070) */ - 3343, /* D71F (55071) */ - 3343, /* D720 (55072) */ - 3343, /* D721 (55073) */ - 3343, /* D722 (55074) */ - 3343, /* D723 (55075) */ - 3343, /* D724 (55076) */ - 3343, /* D725 (55077) */ - 3343, /* D726 (55078) */ - 3343, /* D727 (55079) */ - 3343, /* D728 (55080) */ - 3343, /* D729 (55081) */ - 3343, /* D72A (55082) */ - 3343, /* D72B (55083) */ - 3343, /* D72C (55084) */ - 3343, /* D72D (55085) */ - 3343, /* D72E (55086) */ - 3343, /* D72F (55087) */ - 3343, /* D730 (55088) */ - 3343, /* D731 (55089) */ - 3343, /* D732 (55090) */ - 3343, /* D733 (55091) */ - 3343, /* D734 (55092) */ - 3343, /* D735 (55093) */ - 3343, /* D736 (55094) */ - 3343, /* D737 (55095) */ - 3343, /* D738 (55096) */ - 3343, /* D739 (55097) */ - 3343, /* D73A (55098) */ - 3343, /* D73B (55099) */ - 3343, /* D73C (55100) */ - 3343, /* D73D (55101) */ - 3343, /* D73E (55102) */ - 3343, /* D73F (55103) */ - 3343, /* D740 (55104) */ - 3343, /* D741 (55105) */ - 3343, /* D742 (55106) */ - 3343, /* D743 (55107) */ - 3343, /* D744 (55108) */ - 3343, /* D745 (55109) */ - 3343, /* D746 (55110) */ - 3343, /* D747 (55111) */ - 3343, /* D748 (55112) */ - 3343, /* D749 (55113) */ - 3343, /* D74A (55114) */ - 3343, /* D74B (55115) */ - 3343, /* D74C (55116) */ - 3343, /* D74D (55117) */ - 3343, /* D74E (55118) */ - 3343, /* D74F (55119) */ - 3343, /* D750 (55120) */ - 3343, /* D751 (55121) */ - 3343, /* D752 (55122) */ - 3343, /* D753 (55123) */ - 3343, /* D754 (55124) */ - 3343, /* D755 (55125) */ - 3343, /* D756 (55126) */ - 3343, /* D757 (55127) */ - 3343, /* D758 (55128) */ - 3343, /* D759 (55129) */ - 3343, /* D75A (55130) */ - 3343, /* D75B (55131) */ - 3343, /* D75C (55132) */ - 3343, /* D75D (55133) */ - 3343, /* D75E (55134) */ - 3343, /* D75F (55135) */ - 3343, /* D760 (55136) */ - 3343, /* D761 (55137) */ - 3343, /* D762 (55138) */ - 3343, /* D763 (55139) */ - 3343, /* D764 (55140) */ - 3343, /* D765 (55141) */ - 3343, /* D766 (55142) */ - 3343, /* D767 (55143) */ - 3343, /* D768 (55144) */ - 3343, /* D769 (55145) */ - 3343, /* D76A (55146) */ - 3343, /* D76B (55147) */ - 3343, /* D76C (55148) */ - 3343, /* D76D (55149) */ - 3343, /* D76E (55150) */ - 3343, /* D76F (55151) */ - 3343, /* D770 (55152) */ - 3343, /* D771 (55153) */ - 3343, /* D772 (55154) */ - 3343, /* D773 (55155) */ - 3343, /* D774 (55156) */ - 3343, /* D775 (55157) */ - 3343, /* D776 (55158) */ - 3343, /* D777 (55159) */ - 3343, /* D778 (55160) */ - 3343, /* D779 (55161) */ - 3343, /* D77A (55162) */ - 3343, /* D77B (55163) */ - 3343, /* D77C (55164) */ - 3343, /* D77D (55165) */ - 3343, /* D77E (55166) */ - 3343, /* D77F (55167) */ - 3343, /* D780 (55168) */ - 3343, /* D781 (55169) */ - 3343, /* D782 (55170) */ - 3343, /* D783 (55171) */ - 3343, /* D784 (55172) */ - 3343, /* D785 (55173) */ - 3343, /* D786 (55174) */ - 3343, /* D787 (55175) */ - 3343, /* D788 (55176) */ - 3343, /* D789 (55177) */ - 3343, /* D78A (55178) */ - 3343, /* D78B (55179) */ - 3343, /* D78C (55180) */ - 3343, /* D78D (55181) */ - 3343, /* D78E (55182) */ - 3343, /* D78F (55183) */ - 3343, /* D790 (55184) */ - 3343, /* D791 (55185) */ - 3343, /* D792 (55186) */ - 3343, /* D793 (55187) */ - 3343, /* D794 (55188) */ - 3343, /* D795 (55189) */ - 3343, /* D796 (55190) */ - 3343, /* D797 (55191) */ - 3343, /* D798 (55192) */ - 3343, /* D799 (55193) */ - 3343, /* D79A (55194) */ - 3343, /* D79B (55195) */ - 3343, /* D79C (55196) */ - 3343, /* D79D (55197) */ - 3343, /* D79E (55198) */ - 3343, /* D79F (55199) */ - 3343, /* D7A0 (55200) */ - 3343, /* D7A1 (55201) */ - 3343, /* D7A2 (55202) */ - 3343, /* D7A3 (55203) */ + 3347, /* AC00 (44032) */ + 3347, /* AC01 (44033) */ + 3347, /* AC02 (44034) */ + 3347, /* AC03 (44035) */ + 3347, /* AC04 (44036) */ + 3347, /* AC05 (44037) */ + 3347, /* AC06 (44038) */ + 3347, /* AC07 (44039) */ + 3347, /* AC08 (44040) */ + 3347, /* AC09 (44041) */ + 3347, /* AC0A (44042) */ + 3347, /* AC0B (44043) */ + 3347, /* AC0C (44044) */ + 3347, /* AC0D (44045) */ + 3347, /* AC0E (44046) */ + 3347, /* AC0F (44047) */ + 3347, /* AC10 (44048) */ + 3347, /* AC11 (44049) */ + 3347, /* AC12 (44050) */ + 3347, /* AC13 (44051) */ + 3347, /* AC14 (44052) */ + 3347, /* AC15 (44053) */ + 3347, /* AC16 (44054) */ + 3347, /* AC17 (44055) */ + 3347, /* AC18 (44056) */ + 3347, /* AC19 (44057) */ + 3347, /* AC1A (44058) */ + 3347, /* AC1B (44059) */ + 3347, /* AC1C (44060) */ + 3347, /* AC1D (44061) */ + 3347, /* AC1E (44062) */ + 3347, /* AC1F (44063) */ + 3347, /* AC20 (44064) */ + 3347, /* AC21 (44065) */ + 3347, /* AC22 (44066) */ + 3347, /* AC23 (44067) */ + 3347, /* AC24 (44068) */ + 3347, /* AC25 (44069) */ + 3347, /* AC26 (44070) */ + 3347, /* AC27 (44071) */ + 3347, /* AC28 (44072) */ + 3347, /* AC29 (44073) */ + 3347, /* AC2A (44074) */ + 3347, /* AC2B (44075) */ + 3347, /* AC2C (44076) */ + 3347, /* AC2D (44077) */ + 3347, /* AC2E (44078) */ + 3347, /* AC2F (44079) */ + 3347, /* AC30 (44080) */ + 3347, /* AC31 (44081) */ + 3347, /* AC32 (44082) */ + 3347, /* AC33 (44083) */ + 3347, /* AC34 (44084) */ + 3347, /* AC35 (44085) */ + 3347, /* AC36 (44086) */ + 3347, /* AC37 (44087) */ + 3347, /* AC38 (44088) */ + 3347, /* AC39 (44089) */ + 3347, /* AC3A (44090) */ + 3347, /* AC3B (44091) */ + 3347, /* AC3C (44092) */ + 3347, /* AC3D (44093) */ + 3347, /* AC3E (44094) */ + 3347, /* AC3F (44095) */ + 3347, /* AC40 (44096) */ + 3347, /* AC41 (44097) */ + 3347, /* AC42 (44098) */ + 3347, /* AC43 (44099) */ + 3347, /* AC44 (44100) */ + 3347, /* AC45 (44101) */ + 3347, /* AC46 (44102) */ + 3347, /* AC47 (44103) */ + 3347, /* AC48 (44104) */ + 3347, /* AC49 (44105) */ + 3347, /* AC4A (44106) */ + 3347, /* AC4B (44107) */ + 3347, /* AC4C (44108) */ + 3347, /* AC4D (44109) */ + 3347, /* AC4E (44110) */ + 3347, /* AC4F (44111) */ + 3347, /* AC50 (44112) */ + 3347, /* AC51 (44113) */ + 3347, /* AC52 (44114) */ + 3347, /* AC53 (44115) */ + 3347, /* AC54 (44116) */ + 3347, /* AC55 (44117) */ + 3347, /* AC56 (44118) */ + 3347, /* AC57 (44119) */ + 3347, /* AC58 (44120) */ + 3347, /* AC59 (44121) */ + 3347, /* AC5A (44122) */ + 3347, /* AC5B (44123) */ + 3347, /* AC5C (44124) */ + 3347, /* AC5D (44125) */ + 3347, /* AC5E (44126) */ + 3347, /* AC5F (44127) */ + 3347, /* AC60 (44128) */ + 3347, /* AC61 (44129) */ + 3347, /* AC62 (44130) */ + 3347, /* AC63 (44131) */ + 3347, /* AC64 (44132) */ + 3347, /* AC65 (44133) */ + 3347, /* AC66 (44134) */ + 3347, /* AC67 (44135) */ + 3347, /* AC68 (44136) */ + 3347, /* AC69 (44137) */ + 3347, /* AC6A (44138) */ + 3347, /* AC6B (44139) */ + 3347, /* AC6C (44140) */ + 3347, /* AC6D (44141) */ + 3347, /* AC6E (44142) */ + 3347, /* AC6F (44143) */ + 3347, /* AC70 (44144) */ + 3347, /* AC71 (44145) */ + 3347, /* AC72 (44146) */ + 3347, /* AC73 (44147) */ + 3347, /* AC74 (44148) */ + 3347, /* AC75 (44149) */ + 3347, /* AC76 (44150) */ + 3347, /* AC77 (44151) */ + 3347, /* AC78 (44152) */ + 3347, /* AC79 (44153) */ + 3347, /* AC7A (44154) */ + 3347, /* AC7B (44155) */ + 3347, /* AC7C (44156) */ + 3347, /* AC7D (44157) */ + 3347, /* AC7E (44158) */ + 3347, /* AC7F (44159) */ + 3347, /* AC80 (44160) */ + 3347, /* AC81 (44161) */ + 3347, /* AC82 (44162) */ + 3347, /* AC83 (44163) */ + 3347, /* AC84 (44164) */ + 3347, /* AC85 (44165) */ + 3347, /* AC86 (44166) */ + 3347, /* AC87 (44167) */ + 3347, /* AC88 (44168) */ + 3347, /* AC89 (44169) */ + 3347, /* AC8A (44170) */ + 3347, /* AC8B (44171) */ + 3347, /* AC8C (44172) */ + 3347, /* AC8D (44173) */ + 3347, /* AC8E (44174) */ + 3347, /* AC8F (44175) */ + 3347, /* AC90 (44176) */ + 3347, /* AC91 (44177) */ + 3347, /* AC92 (44178) */ + 3347, /* AC93 (44179) */ + 3347, /* AC94 (44180) */ + 3347, /* AC95 (44181) */ + 3347, /* AC96 (44182) */ + 3347, /* AC97 (44183) */ + 3347, /* AC98 (44184) */ + 3347, /* AC99 (44185) */ + 3347, /* AC9A (44186) */ + 3347, /* AC9B (44187) */ + 3347, /* AC9C (44188) */ + 3347, /* AC9D (44189) */ + 3347, /* AC9E (44190) */ + 3347, /* AC9F (44191) */ + 3347, /* ACA0 (44192) */ + 3347, /* ACA1 (44193) */ + 3347, /* ACA2 (44194) */ + 3347, /* ACA3 (44195) */ + 3347, /* ACA4 (44196) */ + 3347, /* ACA5 (44197) */ + 3347, /* ACA6 (44198) */ + 3347, /* ACA7 (44199) */ + 3347, /* ACA8 (44200) */ + 3347, /* ACA9 (44201) */ + 3347, /* ACAA (44202) */ + 3347, /* ACAB (44203) */ + 3347, /* ACAC (44204) */ + 3347, /* ACAD (44205) */ + 3347, /* ACAE (44206) */ + 3347, /* ACAF (44207) */ + 3347, /* ACB0 (44208) */ + 3347, /* ACB1 (44209) */ + 3347, /* ACB2 (44210) */ + 3347, /* ACB3 (44211) */ + 3347, /* ACB4 (44212) */ + 3347, /* ACB5 (44213) */ + 3347, /* ACB6 (44214) */ + 3347, /* ACB7 (44215) */ + 3347, /* ACB8 (44216) */ + 3347, /* ACB9 (44217) */ + 3347, /* ACBA (44218) */ + 3347, /* ACBB (44219) */ + 3347, /* ACBC (44220) */ + 3347, /* ACBD (44221) */ + 3347, /* ACBE (44222) */ + 3347, /* ACBF (44223) */ + 3347, /* ACC0 (44224) */ + 3347, /* ACC1 (44225) */ + 3347, /* ACC2 (44226) */ + 3347, /* ACC3 (44227) */ + 3347, /* ACC4 (44228) */ + 3347, /* ACC5 (44229) */ + 3347, /* ACC6 (44230) */ + 3347, /* ACC7 (44231) */ + 3347, /* ACC8 (44232) */ + 3347, /* ACC9 (44233) */ + 3347, /* ACCA (44234) */ + 3347, /* ACCB (44235) */ + 3347, /* ACCC (44236) */ + 3347, /* ACCD (44237) */ + 3347, /* ACCE (44238) */ + 3347, /* ACCF (44239) */ + 3347, /* ACD0 (44240) */ + 3347, /* ACD1 (44241) */ + 3347, /* ACD2 (44242) */ + 3347, /* ACD3 (44243) */ + 3347, /* ACD4 (44244) */ + 3347, /* ACD5 (44245) */ + 3347, /* ACD6 (44246) */ + 3347, /* ACD7 (44247) */ + 3347, /* ACD8 (44248) */ + 3347, /* ACD9 (44249) */ + 3347, /* ACDA (44250) */ + 3347, /* ACDB (44251) */ + 3347, /* ACDC (44252) */ + 3347, /* ACDD (44253) */ + 3347, /* ACDE (44254) */ + 3347, /* ACDF (44255) */ + 3347, /* ACE0 (44256) */ + 3347, /* ACE1 (44257) */ + 3347, /* ACE2 (44258) */ + 3347, /* ACE3 (44259) */ + 3347, /* ACE4 (44260) */ + 3347, /* ACE5 (44261) */ + 3347, /* ACE6 (44262) */ + 3347, /* ACE7 (44263) */ + 3347, /* ACE8 (44264) */ + 3347, /* ACE9 (44265) */ + 3347, /* ACEA (44266) */ + 3347, /* ACEB (44267) */ + 3347, /* ACEC (44268) */ + 3347, /* ACED (44269) */ + 3347, /* ACEE (44270) */ + 3347, /* ACEF (44271) */ + 3347, /* ACF0 (44272) */ + 3347, /* ACF1 (44273) */ + 3347, /* ACF2 (44274) */ + 3347, /* ACF3 (44275) */ + 3347, /* ACF4 (44276) */ + 3347, /* ACF5 (44277) */ + 3347, /* ACF6 (44278) */ + 3347, /* ACF7 (44279) */ + 3347, /* ACF8 (44280) */ + 3347, /* ACF9 (44281) */ + 3347, /* ACFA (44282) */ + 3347, /* ACFB (44283) */ + 3347, /* ACFC (44284) */ + 3347, /* ACFD (44285) */ + 3347, /* ACFE (44286) */ + 3347, /* ACFF (44287) */ + 3347, /* AD00 (44288) */ + 3347, /* AD01 (44289) */ + 3347, /* AD02 (44290) */ + 3347, /* AD03 (44291) */ + 3347, /* AD04 (44292) */ + 3347, /* AD05 (44293) */ + 3347, /* AD06 (44294) */ + 3347, /* AD07 (44295) */ + 3347, /* AD08 (44296) */ + 3347, /* AD09 (44297) */ + 3347, /* AD0A (44298) */ + 3347, /* AD0B (44299) */ + 3347, /* AD0C (44300) */ + 3347, /* AD0D (44301) */ + 3347, /* AD0E (44302) */ + 3347, /* AD0F (44303) */ + 3347, /* AD10 (44304) */ + 3347, /* AD11 (44305) */ + 3347, /* AD12 (44306) */ + 3347, /* AD13 (44307) */ + 3347, /* AD14 (44308) */ + 3347, /* AD15 (44309) */ + 3347, /* AD16 (44310) */ + 3347, /* AD17 (44311) */ + 3347, /* AD18 (44312) */ + 3347, /* AD19 (44313) */ + 3347, /* AD1A (44314) */ + 3347, /* AD1B (44315) */ + 3347, /* AD1C (44316) */ + 3347, /* AD1D (44317) */ + 3347, /* AD1E (44318) */ + 3347, /* AD1F (44319) */ + 3347, /* AD20 (44320) */ + 3347, /* AD21 (44321) */ + 3347, /* AD22 (44322) */ + 3347, /* AD23 (44323) */ + 3347, /* AD24 (44324) */ + 3347, /* AD25 (44325) */ + 3347, /* AD26 (44326) */ + 3347, /* AD27 (44327) */ + 3347, /* AD28 (44328) */ + 3347, /* AD29 (44329) */ + 3347, /* AD2A (44330) */ + 3347, /* AD2B (44331) */ + 3347, /* AD2C (44332) */ + 3347, /* AD2D (44333) */ + 3347, /* AD2E (44334) */ + 3347, /* AD2F (44335) */ + 3347, /* AD30 (44336) */ + 3347, /* AD31 (44337) */ + 3347, /* AD32 (44338) */ + 3347, /* AD33 (44339) */ + 3347, /* AD34 (44340) */ + 3347, /* AD35 (44341) */ + 3347, /* AD36 (44342) */ + 3347, /* AD37 (44343) */ + 3347, /* AD38 (44344) */ + 3347, /* AD39 (44345) */ + 3347, /* AD3A (44346) */ + 3347, /* AD3B (44347) */ + 3347, /* AD3C (44348) */ + 3347, /* AD3D (44349) */ + 3347, /* AD3E (44350) */ + 3347, /* AD3F (44351) */ + 3347, /* AD40 (44352) */ + 3347, /* AD41 (44353) */ + 3347, /* AD42 (44354) */ + 3347, /* AD43 (44355) */ + 3347, /* AD44 (44356) */ + 3347, /* AD45 (44357) */ + 3347, /* AD46 (44358) */ + 3347, /* AD47 (44359) */ + 3347, /* AD48 (44360) */ + 3347, /* AD49 (44361) */ + 3347, /* AD4A (44362) */ + 3347, /* AD4B (44363) */ + 3347, /* AD4C (44364) */ + 3347, /* AD4D (44365) */ + 3347, /* AD4E (44366) */ + 3347, /* AD4F (44367) */ + 3347, /* AD50 (44368) */ + 3347, /* AD51 (44369) */ + 3347, /* AD52 (44370) */ + 3347, /* AD53 (44371) */ + 3347, /* AD54 (44372) */ + 3347, /* AD55 (44373) */ + 3347, /* AD56 (44374) */ + 3347, /* AD57 (44375) */ + 3347, /* AD58 (44376) */ + 3347, /* AD59 (44377) */ + 3347, /* AD5A (44378) */ + 3347, /* AD5B (44379) */ + 3347, /* AD5C (44380) */ + 3347, /* AD5D (44381) */ + 3347, /* AD5E (44382) */ + 3347, /* AD5F (44383) */ + 3347, /* AD60 (44384) */ + 3347, /* AD61 (44385) */ + 3347, /* AD62 (44386) */ + 3347, /* AD63 (44387) */ + 3347, /* AD64 (44388) */ + 3347, /* AD65 (44389) */ + 3347, /* AD66 (44390) */ + 3347, /* AD67 (44391) */ + 3347, /* AD68 (44392) */ + 3347, /* AD69 (44393) */ + 3347, /* AD6A (44394) */ + 3347, /* AD6B (44395) */ + 3347, /* AD6C (44396) */ + 3347, /* AD6D (44397) */ + 3347, /* AD6E (44398) */ + 3347, /* AD6F (44399) */ + 3347, /* AD70 (44400) */ + 3347, /* AD71 (44401) */ + 3347, /* AD72 (44402) */ + 3347, /* AD73 (44403) */ + 3347, /* AD74 (44404) */ + 3347, /* AD75 (44405) */ + 3347, /* AD76 (44406) */ + 3347, /* AD77 (44407) */ + 3347, /* AD78 (44408) */ + 3347, /* AD79 (44409) */ + 3347, /* AD7A (44410) */ + 3347, /* AD7B (44411) */ + 3347, /* AD7C (44412) */ + 3347, /* AD7D (44413) */ + 3347, /* AD7E (44414) */ + 3347, /* AD7F (44415) */ + 3347, /* AD80 (44416) */ + 3347, /* AD81 (44417) */ + 3347, /* AD82 (44418) */ + 3347, /* AD83 (44419) */ + 3347, /* AD84 (44420) */ + 3347, /* AD85 (44421) */ + 3347, /* AD86 (44422) */ + 3347, /* AD87 (44423) */ + 3347, /* AD88 (44424) */ + 3347, /* AD89 (44425) */ + 3347, /* AD8A (44426) */ + 3347, /* AD8B (44427) */ + 3347, /* AD8C (44428) */ + 3347, /* AD8D (44429) */ + 3347, /* AD8E (44430) */ + 3347, /* AD8F (44431) */ + 3347, /* AD90 (44432) */ + 3347, /* AD91 (44433) */ + 3347, /* AD92 (44434) */ + 3347, /* AD93 (44435) */ + 3347, /* AD94 (44436) */ + 3347, /* AD95 (44437) */ + 3347, /* AD96 (44438) */ + 3347, /* AD97 (44439) */ + 3347, /* AD98 (44440) */ + 3347, /* AD99 (44441) */ + 3347, /* AD9A (44442) */ + 3347, /* AD9B (44443) */ + 3347, /* AD9C (44444) */ + 3347, /* AD9D (44445) */ + 3347, /* AD9E (44446) */ + 3347, /* AD9F (44447) */ + 3347, /* ADA0 (44448) */ + 3347, /* ADA1 (44449) */ + 3347, /* ADA2 (44450) */ + 3347, /* ADA3 (44451) */ + 3347, /* ADA4 (44452) */ + 3347, /* ADA5 (44453) */ + 3347, /* ADA6 (44454) */ + 3347, /* ADA7 (44455) */ + 3347, /* ADA8 (44456) */ + 3347, /* ADA9 (44457) */ + 3347, /* ADAA (44458) */ + 3347, /* ADAB (44459) */ + 3347, /* ADAC (44460) */ + 3347, /* ADAD (44461) */ + 3347, /* ADAE (44462) */ + 3347, /* ADAF (44463) */ + 3347, /* ADB0 (44464) */ + 3347, /* ADB1 (44465) */ + 3347, /* ADB2 (44466) */ + 3347, /* ADB3 (44467) */ + 3347, /* ADB4 (44468) */ + 3347, /* ADB5 (44469) */ + 3347, /* ADB6 (44470) */ + 3347, /* ADB7 (44471) */ + 3347, /* ADB8 (44472) */ + 3347, /* ADB9 (44473) */ + 3347, /* ADBA (44474) */ + 3347, /* ADBB (44475) */ + 3347, /* ADBC (44476) */ + 3347, /* ADBD (44477) */ + 3347, /* ADBE (44478) */ + 3347, /* ADBF (44479) */ + 3347, /* ADC0 (44480) */ + 3347, /* ADC1 (44481) */ + 3347, /* ADC2 (44482) */ + 3347, /* ADC3 (44483) */ + 3347, /* ADC4 (44484) */ + 3347, /* ADC5 (44485) */ + 3347, /* ADC6 (44486) */ + 3347, /* ADC7 (44487) */ + 3347, /* ADC8 (44488) */ + 3347, /* ADC9 (44489) */ + 3347, /* ADCA (44490) */ + 3347, /* ADCB (44491) */ + 3347, /* ADCC (44492) */ + 3347, /* ADCD (44493) */ + 3347, /* ADCE (44494) */ + 3347, /* ADCF (44495) */ + 3347, /* ADD0 (44496) */ + 3347, /* ADD1 (44497) */ + 3347, /* ADD2 (44498) */ + 3347, /* ADD3 (44499) */ + 3347, /* ADD4 (44500) */ + 3347, /* ADD5 (44501) */ + 3347, /* ADD6 (44502) */ + 3347, /* ADD7 (44503) */ + 3347, /* ADD8 (44504) */ + 3347, /* ADD9 (44505) */ + 3347, /* ADDA (44506) */ + 3347, /* ADDB (44507) */ + 3347, /* ADDC (44508) */ + 3347, /* ADDD (44509) */ + 3347, /* ADDE (44510) */ + 3347, /* ADDF (44511) */ + 3347, /* ADE0 (44512) */ + 3347, /* ADE1 (44513) */ + 3347, /* ADE2 (44514) */ + 3347, /* ADE3 (44515) */ + 3347, /* ADE4 (44516) */ + 3347, /* ADE5 (44517) */ + 3347, /* ADE6 (44518) */ + 3347, /* ADE7 (44519) */ + 3347, /* ADE8 (44520) */ + 3347, /* ADE9 (44521) */ + 3347, /* ADEA (44522) */ + 3347, /* ADEB (44523) */ + 3347, /* ADEC (44524) */ + 3347, /* ADED (44525) */ + 3347, /* ADEE (44526) */ + 3347, /* ADEF (44527) */ + 3347, /* ADF0 (44528) */ + 3347, /* ADF1 (44529) */ + 3347, /* ADF2 (44530) */ + 3347, /* ADF3 (44531) */ + 3347, /* ADF4 (44532) */ + 3347, /* ADF5 (44533) */ + 3347, /* ADF6 (44534) */ + 3347, /* ADF7 (44535) */ + 3347, /* ADF8 (44536) */ + 3347, /* ADF9 (44537) */ + 3347, /* ADFA (44538) */ + 3347, /* ADFB (44539) */ + 3347, /* ADFC (44540) */ + 3347, /* ADFD (44541) */ + 3347, /* ADFE (44542) */ + 3347, /* ADFF (44543) */ + 3347, /* AE00 (44544) */ + 3347, /* AE01 (44545) */ + 3347, /* AE02 (44546) */ + 3347, /* AE03 (44547) */ + 3347, /* AE04 (44548) */ + 3347, /* AE05 (44549) */ + 3347, /* AE06 (44550) */ + 3347, /* AE07 (44551) */ + 3347, /* AE08 (44552) */ + 3347, /* AE09 (44553) */ + 3347, /* AE0A (44554) */ + 3347, /* AE0B (44555) */ + 3347, /* AE0C (44556) */ + 3347, /* AE0D (44557) */ + 3347, /* AE0E (44558) */ + 3347, /* AE0F (44559) */ + 3347, /* AE10 (44560) */ + 3347, /* AE11 (44561) */ + 3347, /* AE12 (44562) */ + 3347, /* AE13 (44563) */ + 3347, /* AE14 (44564) */ + 3347, /* AE15 (44565) */ + 3347, /* AE16 (44566) */ + 3347, /* AE17 (44567) */ + 3347, /* AE18 (44568) */ + 3347, /* AE19 (44569) */ + 3347, /* AE1A (44570) */ + 3347, /* AE1B (44571) */ + 3347, /* AE1C (44572) */ + 3347, /* AE1D (44573) */ + 3347, /* AE1E (44574) */ + 3347, /* AE1F (44575) */ + 3347, /* AE20 (44576) */ + 3347, /* AE21 (44577) */ + 3347, /* AE22 (44578) */ + 3347, /* AE23 (44579) */ + 3347, /* AE24 (44580) */ + 3347, /* AE25 (44581) */ + 3347, /* AE26 (44582) */ + 3347, /* AE27 (44583) */ + 3347, /* AE28 (44584) */ + 3347, /* AE29 (44585) */ + 3347, /* AE2A (44586) */ + 3347, /* AE2B (44587) */ + 3347, /* AE2C (44588) */ + 3347, /* AE2D (44589) */ + 3347, /* AE2E (44590) */ + 3347, /* AE2F (44591) */ + 3347, /* AE30 (44592) */ + 3347, /* AE31 (44593) */ + 3347, /* AE32 (44594) */ + 3347, /* AE33 (44595) */ + 3347, /* AE34 (44596) */ + 3347, /* AE35 (44597) */ + 3347, /* AE36 (44598) */ + 3347, /* AE37 (44599) */ + 3347, /* AE38 (44600) */ + 3347, /* AE39 (44601) */ + 3347, /* AE3A (44602) */ + 3347, /* AE3B (44603) */ + 3347, /* AE3C (44604) */ + 3347, /* AE3D (44605) */ + 3347, /* AE3E (44606) */ + 3347, /* AE3F (44607) */ + 3347, /* AE40 (44608) */ + 3347, /* AE41 (44609) */ + 3347, /* AE42 (44610) */ + 3347, /* AE43 (44611) */ + 3347, /* AE44 (44612) */ + 3347, /* AE45 (44613) */ + 3347, /* AE46 (44614) */ + 3347, /* AE47 (44615) */ + 3347, /* AE48 (44616) */ + 3347, /* AE49 (44617) */ + 3347, /* AE4A (44618) */ + 3347, /* AE4B (44619) */ + 3347, /* AE4C (44620) */ + 3347, /* AE4D (44621) */ + 3347, /* AE4E (44622) */ + 3347, /* AE4F (44623) */ + 3347, /* AE50 (44624) */ + 3347, /* AE51 (44625) */ + 3347, /* AE52 (44626) */ + 3347, /* AE53 (44627) */ + 3347, /* AE54 (44628) */ + 3347, /* AE55 (44629) */ + 3347, /* AE56 (44630) */ + 3347, /* AE57 (44631) */ + 3347, /* AE58 (44632) */ + 3347, /* AE59 (44633) */ + 3347, /* AE5A (44634) */ + 3347, /* AE5B (44635) */ + 3347, /* AE5C (44636) */ + 3347, /* AE5D (44637) */ + 3347, /* AE5E (44638) */ + 3347, /* AE5F (44639) */ + 3347, /* AE60 (44640) */ + 3347, /* AE61 (44641) */ + 3347, /* AE62 (44642) */ + 3347, /* AE63 (44643) */ + 3347, /* AE64 (44644) */ + 3347, /* AE65 (44645) */ + 3347, /* AE66 (44646) */ + 3347, /* AE67 (44647) */ + 3347, /* AE68 (44648) */ + 3347, /* AE69 (44649) */ + 3347, /* AE6A (44650) */ + 3347, /* AE6B (44651) */ + 3347, /* AE6C (44652) */ + 3347, /* AE6D (44653) */ + 3347, /* AE6E (44654) */ + 3347, /* AE6F (44655) */ + 3347, /* AE70 (44656) */ + 3347, /* AE71 (44657) */ + 3347, /* AE72 (44658) */ + 3347, /* AE73 (44659) */ + 3347, /* AE74 (44660) */ + 3347, /* AE75 (44661) */ + 3347, /* AE76 (44662) */ + 3347, /* AE77 (44663) */ + 3347, /* AE78 (44664) */ + 3347, /* AE79 (44665) */ + 3347, /* AE7A (44666) */ + 3347, /* AE7B (44667) */ + 3347, /* AE7C (44668) */ + 3347, /* AE7D (44669) */ + 3347, /* AE7E (44670) */ + 3347, /* AE7F (44671) */ + 3347, /* AE80 (44672) */ + 3347, /* AE81 (44673) */ + 3347, /* AE82 (44674) */ + 3347, /* AE83 (44675) */ + 3347, /* AE84 (44676) */ + 3347, /* AE85 (44677) */ + 3347, /* AE86 (44678) */ + 3347, /* AE87 (44679) */ + 3347, /* AE88 (44680) */ + 3347, /* AE89 (44681) */ + 3347, /* AE8A (44682) */ + 3347, /* AE8B (44683) */ + 3347, /* AE8C (44684) */ + 3347, /* AE8D (44685) */ + 3347, /* AE8E (44686) */ + 3347, /* AE8F (44687) */ + 3347, /* AE90 (44688) */ + 3347, /* AE91 (44689) */ + 3347, /* AE92 (44690) */ + 3347, /* AE93 (44691) */ + 3347, /* AE94 (44692) */ + 3347, /* AE95 (44693) */ + 3347, /* AE96 (44694) */ + 3347, /* AE97 (44695) */ + 3347, /* AE98 (44696) */ + 3347, /* AE99 (44697) */ + 3347, /* AE9A (44698) */ + 3347, /* AE9B (44699) */ + 3347, /* AE9C (44700) */ + 3347, /* AE9D (44701) */ + 3347, /* AE9E (44702) */ + 3347, /* AE9F (44703) */ + 3347, /* AEA0 (44704) */ + 3347, /* AEA1 (44705) */ + 3347, /* AEA2 (44706) */ + 3347, /* AEA3 (44707) */ + 3347, /* AEA4 (44708) */ + 3347, /* AEA5 (44709) */ + 3347, /* AEA6 (44710) */ + 3347, /* AEA7 (44711) */ + 3347, /* AEA8 (44712) */ + 3347, /* AEA9 (44713) */ + 3347, /* AEAA (44714) */ + 3347, /* AEAB (44715) */ + 3347, /* AEAC (44716) */ + 3347, /* AEAD (44717) */ + 3347, /* AEAE (44718) */ + 3347, /* AEAF (44719) */ + 3347, /* AEB0 (44720) */ + 3347, /* AEB1 (44721) */ + 3347, /* AEB2 (44722) */ + 3347, /* AEB3 (44723) */ + 3347, /* AEB4 (44724) */ + 3347, /* AEB5 (44725) */ + 3347, /* AEB6 (44726) */ + 3347, /* AEB7 (44727) */ + 3347, /* AEB8 (44728) */ + 3347, /* AEB9 (44729) */ + 3347, /* AEBA (44730) */ + 3347, /* AEBB (44731) */ + 3347, /* AEBC (44732) */ + 3347, /* AEBD (44733) */ + 3347, /* AEBE (44734) */ + 3347, /* AEBF (44735) */ + 3347, /* AEC0 (44736) */ + 3347, /* AEC1 (44737) */ + 3347, /* AEC2 (44738) */ + 3347, /* AEC3 (44739) */ + 3347, /* AEC4 (44740) */ + 3347, /* AEC5 (44741) */ + 3347, /* AEC6 (44742) */ + 3347, /* AEC7 (44743) */ + 3347, /* AEC8 (44744) */ + 3347, /* AEC9 (44745) */ + 3347, /* AECA (44746) */ + 3347, /* AECB (44747) */ + 3347, /* AECC (44748) */ + 3347, /* AECD (44749) */ + 3347, /* AECE (44750) */ + 3347, /* AECF (44751) */ + 3347, /* AED0 (44752) */ + 3347, /* AED1 (44753) */ + 3347, /* AED2 (44754) */ + 3347, /* AED3 (44755) */ + 3347, /* AED4 (44756) */ + 3347, /* AED5 (44757) */ + 3347, /* AED6 (44758) */ + 3347, /* AED7 (44759) */ + 3347, /* AED8 (44760) */ + 3347, /* AED9 (44761) */ + 3347, /* AEDA (44762) */ + 3347, /* AEDB (44763) */ + 3347, /* AEDC (44764) */ + 3347, /* AEDD (44765) */ + 3347, /* AEDE (44766) */ + 3347, /* AEDF (44767) */ + 3347, /* AEE0 (44768) */ + 3347, /* AEE1 (44769) */ + 3347, /* AEE2 (44770) */ + 3347, /* AEE3 (44771) */ + 3347, /* AEE4 (44772) */ + 3347, /* AEE5 (44773) */ + 3347, /* AEE6 (44774) */ + 3347, /* AEE7 (44775) */ + 3347, /* AEE8 (44776) */ + 3347, /* AEE9 (44777) */ + 3347, /* AEEA (44778) */ + 3347, /* AEEB (44779) */ + 3347, /* AEEC (44780) */ + 3347, /* AEED (44781) */ + 3347, /* AEEE (44782) */ + 3347, /* AEEF (44783) */ + 3347, /* AEF0 (44784) */ + 3347, /* AEF1 (44785) */ + 3347, /* AEF2 (44786) */ + 3347, /* AEF3 (44787) */ + 3347, /* AEF4 (44788) */ + 3347, /* AEF5 (44789) */ + 3347, /* AEF6 (44790) */ + 3347, /* AEF7 (44791) */ + 3347, /* AEF8 (44792) */ + 3347, /* AEF9 (44793) */ + 3347, /* AEFA (44794) */ + 3347, /* AEFB (44795) */ + 3347, /* AEFC (44796) */ + 3347, /* AEFD (44797) */ + 3347, /* AEFE (44798) */ + 3347, /* AEFF (44799) */ + 3347, /* AF00 (44800) */ + 3347, /* AF01 (44801) */ + 3347, /* AF02 (44802) */ + 3347, /* AF03 (44803) */ + 3347, /* AF04 (44804) */ + 3347, /* AF05 (44805) */ + 3347, /* AF06 (44806) */ + 3347, /* AF07 (44807) */ + 3347, /* AF08 (44808) */ + 3347, /* AF09 (44809) */ + 3347, /* AF0A (44810) */ + 3347, /* AF0B (44811) */ + 3347, /* AF0C (44812) */ + 3347, /* AF0D (44813) */ + 3347, /* AF0E (44814) */ + 3347, /* AF0F (44815) */ + 3347, /* AF10 (44816) */ + 3347, /* AF11 (44817) */ + 3347, /* AF12 (44818) */ + 3347, /* AF13 (44819) */ + 3347, /* AF14 (44820) */ + 3347, /* AF15 (44821) */ + 3347, /* AF16 (44822) */ + 3347, /* AF17 (44823) */ + 3347, /* AF18 (44824) */ + 3347, /* AF19 (44825) */ + 3347, /* AF1A (44826) */ + 3347, /* AF1B (44827) */ + 3347, /* AF1C (44828) */ + 3347, /* AF1D (44829) */ + 3347, /* AF1E (44830) */ + 3347, /* AF1F (44831) */ + 3347, /* AF20 (44832) */ + 3347, /* AF21 (44833) */ + 3347, /* AF22 (44834) */ + 3347, /* AF23 (44835) */ + 3347, /* AF24 (44836) */ + 3347, /* AF25 (44837) */ + 3347, /* AF26 (44838) */ + 3347, /* AF27 (44839) */ + 3347, /* AF28 (44840) */ + 3347, /* AF29 (44841) */ + 3347, /* AF2A (44842) */ + 3347, /* AF2B (44843) */ + 3347, /* AF2C (44844) */ + 3347, /* AF2D (44845) */ + 3347, /* AF2E (44846) */ + 3347, /* AF2F (44847) */ + 3347, /* AF30 (44848) */ + 3347, /* AF31 (44849) */ + 3347, /* AF32 (44850) */ + 3347, /* AF33 (44851) */ + 3347, /* AF34 (44852) */ + 3347, /* AF35 (44853) */ + 3347, /* AF36 (44854) */ + 3347, /* AF37 (44855) */ + 3347, /* AF38 (44856) */ + 3347, /* AF39 (44857) */ + 3347, /* AF3A (44858) */ + 3347, /* AF3B (44859) */ + 3347, /* AF3C (44860) */ + 3347, /* AF3D (44861) */ + 3347, /* AF3E (44862) */ + 3347, /* AF3F (44863) */ + 3347, /* AF40 (44864) */ + 3347, /* AF41 (44865) */ + 3347, /* AF42 (44866) */ + 3347, /* AF43 (44867) */ + 3347, /* AF44 (44868) */ + 3347, /* AF45 (44869) */ + 3347, /* AF46 (44870) */ + 3347, /* AF47 (44871) */ + 3347, /* AF48 (44872) */ + 3347, /* AF49 (44873) */ + 3347, /* AF4A (44874) */ + 3347, /* AF4B (44875) */ + 3347, /* AF4C (44876) */ + 3347, /* AF4D (44877) */ + 3347, /* AF4E (44878) */ + 3347, /* AF4F (44879) */ + 3347, /* AF50 (44880) */ + 3347, /* AF51 (44881) */ + 3347, /* AF52 (44882) */ + 3347, /* AF53 (44883) */ + 3347, /* AF54 (44884) */ + 3347, /* AF55 (44885) */ + 3347, /* AF56 (44886) */ + 3347, /* AF57 (44887) */ + 3347, /* AF58 (44888) */ + 3347, /* AF59 (44889) */ + 3347, /* AF5A (44890) */ + 3347, /* AF5B (44891) */ + 3347, /* AF5C (44892) */ + 3347, /* AF5D (44893) */ + 3347, /* AF5E (44894) */ + 3347, /* AF5F (44895) */ + 3347, /* AF60 (44896) */ + 3347, /* AF61 (44897) */ + 3347, /* AF62 (44898) */ + 3347, /* AF63 (44899) */ + 3347, /* AF64 (44900) */ + 3347, /* AF65 (44901) */ + 3347, /* AF66 (44902) */ + 3347, /* AF67 (44903) */ + 3347, /* AF68 (44904) */ + 3347, /* AF69 (44905) */ + 3347, /* AF6A (44906) */ + 3347, /* AF6B (44907) */ + 3347, /* AF6C (44908) */ + 3347, /* AF6D (44909) */ + 3347, /* AF6E (44910) */ + 3347, /* AF6F (44911) */ + 3347, /* AF70 (44912) */ + 3347, /* AF71 (44913) */ + 3347, /* AF72 (44914) */ + 3347, /* AF73 (44915) */ + 3347, /* AF74 (44916) */ + 3347, /* AF75 (44917) */ + 3347, /* AF76 (44918) */ + 3347, /* AF77 (44919) */ + 3347, /* AF78 (44920) */ + 3347, /* AF79 (44921) */ + 3347, /* AF7A (44922) */ + 3347, /* AF7B (44923) */ + 3347, /* AF7C (44924) */ + 3347, /* AF7D (44925) */ + 3347, /* AF7E (44926) */ + 3347, /* AF7F (44927) */ + 3347, /* AF80 (44928) */ + 3347, /* AF81 (44929) */ + 3347, /* AF82 (44930) */ + 3347, /* AF83 (44931) */ + 3347, /* AF84 (44932) */ + 3347, /* AF85 (44933) */ + 3347, /* AF86 (44934) */ + 3347, /* AF87 (44935) */ + 3347, /* AF88 (44936) */ + 3347, /* AF89 (44937) */ + 3347, /* AF8A (44938) */ + 3347, /* AF8B (44939) */ + 3347, /* AF8C (44940) */ + 3347, /* AF8D (44941) */ + 3347, /* AF8E (44942) */ + 3347, /* AF8F (44943) */ + 3347, /* AF90 (44944) */ + 3347, /* AF91 (44945) */ + 3347, /* AF92 (44946) */ + 3347, /* AF93 (44947) */ + 3347, /* AF94 (44948) */ + 3347, /* AF95 (44949) */ + 3347, /* AF96 (44950) */ + 3347, /* AF97 (44951) */ + 3347, /* AF98 (44952) */ + 3347, /* AF99 (44953) */ + 3347, /* AF9A (44954) */ + 3347, /* AF9B (44955) */ + 3347, /* AF9C (44956) */ + 3347, /* AF9D (44957) */ + 3347, /* AF9E (44958) */ + 3347, /* AF9F (44959) */ + 3347, /* AFA0 (44960) */ + 3347, /* AFA1 (44961) */ + 3347, /* AFA2 (44962) */ + 3347, /* AFA3 (44963) */ + 3347, /* AFA4 (44964) */ + 3347, /* AFA5 (44965) */ + 3347, /* AFA6 (44966) */ + 3347, /* AFA7 (44967) */ + 3347, /* AFA8 (44968) */ + 3347, /* AFA9 (44969) */ + 3347, /* AFAA (44970) */ + 3347, /* AFAB (44971) */ + 3347, /* AFAC (44972) */ + 3347, /* AFAD (44973) */ + 3347, /* AFAE (44974) */ + 3347, /* AFAF (44975) */ + 3347, /* AFB0 (44976) */ + 3347, /* AFB1 (44977) */ + 3347, /* AFB2 (44978) */ + 3347, /* AFB3 (44979) */ + 3347, /* AFB4 (44980) */ + 3347, /* AFB5 (44981) */ + 3347, /* AFB6 (44982) */ + 3347, /* AFB7 (44983) */ + 3347, /* AFB8 (44984) */ + 3347, /* AFB9 (44985) */ + 3347, /* AFBA (44986) */ + 3347, /* AFBB (44987) */ + 3347, /* AFBC (44988) */ + 3347, /* AFBD (44989) */ + 3347, /* AFBE (44990) */ + 3347, /* AFBF (44991) */ + 3347, /* AFC0 (44992) */ + 3347, /* AFC1 (44993) */ + 3347, /* AFC2 (44994) */ + 3347, /* AFC3 (44995) */ + 3347, /* AFC4 (44996) */ + 3347, /* AFC5 (44997) */ + 3347, /* AFC6 (44998) */ + 3347, /* AFC7 (44999) */ + 3347, /* AFC8 (45000) */ + 3347, /* AFC9 (45001) */ + 3347, /* AFCA (45002) */ + 3347, /* AFCB (45003) */ + 3347, /* AFCC (45004) */ + 3347, /* AFCD (45005) */ + 3347, /* AFCE (45006) */ + 3347, /* AFCF (45007) */ + 3347, /* AFD0 (45008) */ + 3347, /* AFD1 (45009) */ + 3347, /* AFD2 (45010) */ + 3347, /* AFD3 (45011) */ + 3347, /* AFD4 (45012) */ + 3347, /* AFD5 (45013) */ + 3347, /* AFD6 (45014) */ + 3347, /* AFD7 (45015) */ + 3347, /* AFD8 (45016) */ + 3347, /* AFD9 (45017) */ + 3347, /* AFDA (45018) */ + 3347, /* AFDB (45019) */ + 3347, /* AFDC (45020) */ + 3347, /* AFDD (45021) */ + 3347, /* AFDE (45022) */ + 3347, /* AFDF (45023) */ + 3347, /* AFE0 (45024) */ + 3347, /* AFE1 (45025) */ + 3347, /* AFE2 (45026) */ + 3347, /* AFE3 (45027) */ + 3347, /* AFE4 (45028) */ + 3347, /* AFE5 (45029) */ + 3347, /* AFE6 (45030) */ + 3347, /* AFE7 (45031) */ + 3347, /* AFE8 (45032) */ + 3347, /* AFE9 (45033) */ + 3347, /* AFEA (45034) */ + 3347, /* AFEB (45035) */ + 3347, /* AFEC (45036) */ + 3347, /* AFED (45037) */ + 3347, /* AFEE (45038) */ + 3347, /* AFEF (45039) */ + 3347, /* AFF0 (45040) */ + 3347, /* AFF1 (45041) */ + 3347, /* AFF2 (45042) */ + 3347, /* AFF3 (45043) */ + 3347, /* AFF4 (45044) */ + 3347, /* AFF5 (45045) */ + 3347, /* AFF6 (45046) */ + 3347, /* AFF7 (45047) */ + 3347, /* AFF8 (45048) */ + 3347, /* AFF9 (45049) */ + 3347, /* AFFA (45050) */ + 3347, /* AFFB (45051) */ + 3347, /* AFFC (45052) */ + 3347, /* AFFD (45053) */ + 3347, /* AFFE (45054) */ + 3347, /* AFFF (45055) */ + 3347, /* B000 (45056) */ + 3347, /* B001 (45057) */ + 3347, /* B002 (45058) */ + 3347, /* B003 (45059) */ + 3347, /* B004 (45060) */ + 3347, /* B005 (45061) */ + 3347, /* B006 (45062) */ + 3347, /* B007 (45063) */ + 3347, /* B008 (45064) */ + 3347, /* B009 (45065) */ + 3347, /* B00A (45066) */ + 3347, /* B00B (45067) */ + 3347, /* B00C (45068) */ + 3347, /* B00D (45069) */ + 3347, /* B00E (45070) */ + 3347, /* B00F (45071) */ + 3347, /* B010 (45072) */ + 3347, /* B011 (45073) */ + 3347, /* B012 (45074) */ + 3347, /* B013 (45075) */ + 3347, /* B014 (45076) */ + 3347, /* B015 (45077) */ + 3347, /* B016 (45078) */ + 3347, /* B017 (45079) */ + 3347, /* B018 (45080) */ + 3347, /* B019 (45081) */ + 3347, /* B01A (45082) */ + 3347, /* B01B (45083) */ + 3347, /* B01C (45084) */ + 3347, /* B01D (45085) */ + 3347, /* B01E (45086) */ + 3347, /* B01F (45087) */ + 3347, /* B020 (45088) */ + 3347, /* B021 (45089) */ + 3347, /* B022 (45090) */ + 3347, /* B023 (45091) */ + 3347, /* B024 (45092) */ + 3347, /* B025 (45093) */ + 3347, /* B026 (45094) */ + 3347, /* B027 (45095) */ + 3347, /* B028 (45096) */ + 3347, /* B029 (45097) */ + 3347, /* B02A (45098) */ + 3347, /* B02B (45099) */ + 3347, /* B02C (45100) */ + 3347, /* B02D (45101) */ + 3347, /* B02E (45102) */ + 3347, /* B02F (45103) */ + 3347, /* B030 (45104) */ + 3347, /* B031 (45105) */ + 3347, /* B032 (45106) */ + 3347, /* B033 (45107) */ + 3347, /* B034 (45108) */ + 3347, /* B035 (45109) */ + 3347, /* B036 (45110) */ + 3347, /* B037 (45111) */ + 3347, /* B038 (45112) */ + 3347, /* B039 (45113) */ + 3347, /* B03A (45114) */ + 3347, /* B03B (45115) */ + 3347, /* B03C (45116) */ + 3347, /* B03D (45117) */ + 3347, /* B03E (45118) */ + 3347, /* B03F (45119) */ + 3347, /* B040 (45120) */ + 3347, /* B041 (45121) */ + 3347, /* B042 (45122) */ + 3347, /* B043 (45123) */ + 3347, /* B044 (45124) */ + 3347, /* B045 (45125) */ + 3347, /* B046 (45126) */ + 3347, /* B047 (45127) */ + 3347, /* B048 (45128) */ + 3347, /* B049 (45129) */ + 3347, /* B04A (45130) */ + 3347, /* B04B (45131) */ + 3347, /* B04C (45132) */ + 3347, /* B04D (45133) */ + 3347, /* B04E (45134) */ + 3347, /* B04F (45135) */ + 3347, /* B050 (45136) */ + 3347, /* B051 (45137) */ + 3347, /* B052 (45138) */ + 3347, /* B053 (45139) */ + 3347, /* B054 (45140) */ + 3347, /* B055 (45141) */ + 3347, /* B056 (45142) */ + 3347, /* B057 (45143) */ + 3347, /* B058 (45144) */ + 3347, /* B059 (45145) */ + 3347, /* B05A (45146) */ + 3347, /* B05B (45147) */ + 3347, /* B05C (45148) */ + 3347, /* B05D (45149) */ + 3347, /* B05E (45150) */ + 3347, /* B05F (45151) */ + 3347, /* B060 (45152) */ + 3347, /* B061 (45153) */ + 3347, /* B062 (45154) */ + 3347, /* B063 (45155) */ + 3347, /* B064 (45156) */ + 3347, /* B065 (45157) */ + 3347, /* B066 (45158) */ + 3347, /* B067 (45159) */ + 3347, /* B068 (45160) */ + 3347, /* B069 (45161) */ + 3347, /* B06A (45162) */ + 3347, /* B06B (45163) */ + 3347, /* B06C (45164) */ + 3347, /* B06D (45165) */ + 3347, /* B06E (45166) */ + 3347, /* B06F (45167) */ + 3347, /* B070 (45168) */ + 3347, /* B071 (45169) */ + 3347, /* B072 (45170) */ + 3347, /* B073 (45171) */ + 3347, /* B074 (45172) */ + 3347, /* B075 (45173) */ + 3347, /* B076 (45174) */ + 3347, /* B077 (45175) */ + 3347, /* B078 (45176) */ + 3347, /* B079 (45177) */ + 3347, /* B07A (45178) */ + 3347, /* B07B (45179) */ + 3347, /* B07C (45180) */ + 3347, /* B07D (45181) */ + 3347, /* B07E (45182) */ + 3347, /* B07F (45183) */ + 3347, /* B080 (45184) */ + 3347, /* B081 (45185) */ + 3347, /* B082 (45186) */ + 3347, /* B083 (45187) */ + 3347, /* B084 (45188) */ + 3347, /* B085 (45189) */ + 3347, /* B086 (45190) */ + 3347, /* B087 (45191) */ + 3347, /* B088 (45192) */ + 3347, /* B089 (45193) */ + 3347, /* B08A (45194) */ + 3347, /* B08B (45195) */ + 3347, /* B08C (45196) */ + 3347, /* B08D (45197) */ + 3347, /* B08E (45198) */ + 3347, /* B08F (45199) */ + 3347, /* B090 (45200) */ + 3347, /* B091 (45201) */ + 3347, /* B092 (45202) */ + 3347, /* B093 (45203) */ + 3347, /* B094 (45204) */ + 3347, /* B095 (45205) */ + 3347, /* B096 (45206) */ + 3347, /* B097 (45207) */ + 3347, /* B098 (45208) */ + 3347, /* B099 (45209) */ + 3347, /* B09A (45210) */ + 3347, /* B09B (45211) */ + 3347, /* B09C (45212) */ + 3347, /* B09D (45213) */ + 3347, /* B09E (45214) */ + 3347, /* B09F (45215) */ + 3347, /* B0A0 (45216) */ + 3347, /* B0A1 (45217) */ + 3347, /* B0A2 (45218) */ + 3347, /* B0A3 (45219) */ + 3347, /* B0A4 (45220) */ + 3347, /* B0A5 (45221) */ + 3347, /* B0A6 (45222) */ + 3347, /* B0A7 (45223) */ + 3347, /* B0A8 (45224) */ + 3347, /* B0A9 (45225) */ + 3347, /* B0AA (45226) */ + 3347, /* B0AB (45227) */ + 3347, /* B0AC (45228) */ + 3347, /* B0AD (45229) */ + 3347, /* B0AE (45230) */ + 3347, /* B0AF (45231) */ + 3347, /* B0B0 (45232) */ + 3347, /* B0B1 (45233) */ + 3347, /* B0B2 (45234) */ + 3347, /* B0B3 (45235) */ + 3347, /* B0B4 (45236) */ + 3347, /* B0B5 (45237) */ + 3347, /* B0B6 (45238) */ + 3347, /* B0B7 (45239) */ + 3347, /* B0B8 (45240) */ + 3347, /* B0B9 (45241) */ + 3347, /* B0BA (45242) */ + 3347, /* B0BB (45243) */ + 3347, /* B0BC (45244) */ + 3347, /* B0BD (45245) */ + 3347, /* B0BE (45246) */ + 3347, /* B0BF (45247) */ + 3347, /* B0C0 (45248) */ + 3347, /* B0C1 (45249) */ + 3347, /* B0C2 (45250) */ + 3347, /* B0C3 (45251) */ + 3347, /* B0C4 (45252) */ + 3347, /* B0C5 (45253) */ + 3347, /* B0C6 (45254) */ + 3347, /* B0C7 (45255) */ + 3347, /* B0C8 (45256) */ + 3347, /* B0C9 (45257) */ + 3347, /* B0CA (45258) */ + 3347, /* B0CB (45259) */ + 3347, /* B0CC (45260) */ + 3347, /* B0CD (45261) */ + 3347, /* B0CE (45262) */ + 3347, /* B0CF (45263) */ + 3347, /* B0D0 (45264) */ + 3347, /* B0D1 (45265) */ + 3347, /* B0D2 (45266) */ + 3347, /* B0D3 (45267) */ + 3347, /* B0D4 (45268) */ + 3347, /* B0D5 (45269) */ + 3347, /* B0D6 (45270) */ + 3347, /* B0D7 (45271) */ + 3347, /* B0D8 (45272) */ + 3347, /* B0D9 (45273) */ + 3347, /* B0DA (45274) */ + 3347, /* B0DB (45275) */ + 3347, /* B0DC (45276) */ + 3347, /* B0DD (45277) */ + 3347, /* B0DE (45278) */ + 3347, /* B0DF (45279) */ + 3347, /* B0E0 (45280) */ + 3347, /* B0E1 (45281) */ + 3347, /* B0E2 (45282) */ + 3347, /* B0E3 (45283) */ + 3347, /* B0E4 (45284) */ + 3347, /* B0E5 (45285) */ + 3347, /* B0E6 (45286) */ + 3347, /* B0E7 (45287) */ + 3347, /* B0E8 (45288) */ + 3347, /* B0E9 (45289) */ + 3347, /* B0EA (45290) */ + 3347, /* B0EB (45291) */ + 3347, /* B0EC (45292) */ + 3347, /* B0ED (45293) */ + 3347, /* B0EE (45294) */ + 3347, /* B0EF (45295) */ + 3347, /* B0F0 (45296) */ + 3347, /* B0F1 (45297) */ + 3347, /* B0F2 (45298) */ + 3347, /* B0F3 (45299) */ + 3347, /* B0F4 (45300) */ + 3347, /* B0F5 (45301) */ + 3347, /* B0F6 (45302) */ + 3347, /* B0F7 (45303) */ + 3347, /* B0F8 (45304) */ + 3347, /* B0F9 (45305) */ + 3347, /* B0FA (45306) */ + 3347, /* B0FB (45307) */ + 3347, /* B0FC (45308) */ + 3347, /* B0FD (45309) */ + 3347, /* B0FE (45310) */ + 3347, /* B0FF (45311) */ + 3347, /* B100 (45312) */ + 3347, /* B101 (45313) */ + 3347, /* B102 (45314) */ + 3347, /* B103 (45315) */ + 3347, /* B104 (45316) */ + 3347, /* B105 (45317) */ + 3347, /* B106 (45318) */ + 3347, /* B107 (45319) */ + 3347, /* B108 (45320) */ + 3347, /* B109 (45321) */ + 3347, /* B10A (45322) */ + 3347, /* B10B (45323) */ + 3347, /* B10C (45324) */ + 3347, /* B10D (45325) */ + 3347, /* B10E (45326) */ + 3347, /* B10F (45327) */ + 3347, /* B110 (45328) */ + 3347, /* B111 (45329) */ + 3347, /* B112 (45330) */ + 3347, /* B113 (45331) */ + 3347, /* B114 (45332) */ + 3347, /* B115 (45333) */ + 3347, /* B116 (45334) */ + 3347, /* B117 (45335) */ + 3347, /* B118 (45336) */ + 3347, /* B119 (45337) */ + 3347, /* B11A (45338) */ + 3347, /* B11B (45339) */ + 3347, /* B11C (45340) */ + 3347, /* B11D (45341) */ + 3347, /* B11E (45342) */ + 3347, /* B11F (45343) */ + 3347, /* B120 (45344) */ + 3347, /* B121 (45345) */ + 3347, /* B122 (45346) */ + 3347, /* B123 (45347) */ + 3347, /* B124 (45348) */ + 3347, /* B125 (45349) */ + 3347, /* B126 (45350) */ + 3347, /* B127 (45351) */ + 3347, /* B128 (45352) */ + 3347, /* B129 (45353) */ + 3347, /* B12A (45354) */ + 3347, /* B12B (45355) */ + 3347, /* B12C (45356) */ + 3347, /* B12D (45357) */ + 3347, /* B12E (45358) */ + 3347, /* B12F (45359) */ + 3347, /* B130 (45360) */ + 3347, /* B131 (45361) */ + 3347, /* B132 (45362) */ + 3347, /* B133 (45363) */ + 3347, /* B134 (45364) */ + 3347, /* B135 (45365) */ + 3347, /* B136 (45366) */ + 3347, /* B137 (45367) */ + 3347, /* B138 (45368) */ + 3347, /* B139 (45369) */ + 3347, /* B13A (45370) */ + 3347, /* B13B (45371) */ + 3347, /* B13C (45372) */ + 3347, /* B13D (45373) */ + 3347, /* B13E (45374) */ + 3347, /* B13F (45375) */ + 3347, /* B140 (45376) */ + 3347, /* B141 (45377) */ + 3347, /* B142 (45378) */ + 3347, /* B143 (45379) */ + 3347, /* B144 (45380) */ + 3347, /* B145 (45381) */ + 3347, /* B146 (45382) */ + 3347, /* B147 (45383) */ + 3347, /* B148 (45384) */ + 3347, /* B149 (45385) */ + 3347, /* B14A (45386) */ + 3347, /* B14B (45387) */ + 3347, /* B14C (45388) */ + 3347, /* B14D (45389) */ + 3347, /* B14E (45390) */ + 3347, /* B14F (45391) */ + 3347, /* B150 (45392) */ + 3347, /* B151 (45393) */ + 3347, /* B152 (45394) */ + 3347, /* B153 (45395) */ + 3347, /* B154 (45396) */ + 3347, /* B155 (45397) */ + 3347, /* B156 (45398) */ + 3347, /* B157 (45399) */ + 3347, /* B158 (45400) */ + 3347, /* B159 (45401) */ + 3347, /* B15A (45402) */ + 3347, /* B15B (45403) */ + 3347, /* B15C (45404) */ + 3347, /* B15D (45405) */ + 3347, /* B15E (45406) */ + 3347, /* B15F (45407) */ + 3347, /* B160 (45408) */ + 3347, /* B161 (45409) */ + 3347, /* B162 (45410) */ + 3347, /* B163 (45411) */ + 3347, /* B164 (45412) */ + 3347, /* B165 (45413) */ + 3347, /* B166 (45414) */ + 3347, /* B167 (45415) */ + 3347, /* B168 (45416) */ + 3347, /* B169 (45417) */ + 3347, /* B16A (45418) */ + 3347, /* B16B (45419) */ + 3347, /* B16C (45420) */ + 3347, /* B16D (45421) */ + 3347, /* B16E (45422) */ + 3347, /* B16F (45423) */ + 3347, /* B170 (45424) */ + 3347, /* B171 (45425) */ + 3347, /* B172 (45426) */ + 3347, /* B173 (45427) */ + 3347, /* B174 (45428) */ + 3347, /* B175 (45429) */ + 3347, /* B176 (45430) */ + 3347, /* B177 (45431) */ + 3347, /* B178 (45432) */ + 3347, /* B179 (45433) */ + 3347, /* B17A (45434) */ + 3347, /* B17B (45435) */ + 3347, /* B17C (45436) */ + 3347, /* B17D (45437) */ + 3347, /* B17E (45438) */ + 3347, /* B17F (45439) */ + 3347, /* B180 (45440) */ + 3347, /* B181 (45441) */ + 3347, /* B182 (45442) */ + 3347, /* B183 (45443) */ + 3347, /* B184 (45444) */ + 3347, /* B185 (45445) */ + 3347, /* B186 (45446) */ + 3347, /* B187 (45447) */ + 3347, /* B188 (45448) */ + 3347, /* B189 (45449) */ + 3347, /* B18A (45450) */ + 3347, /* B18B (45451) */ + 3347, /* B18C (45452) */ + 3347, /* B18D (45453) */ + 3347, /* B18E (45454) */ + 3347, /* B18F (45455) */ + 3347, /* B190 (45456) */ + 3347, /* B191 (45457) */ + 3347, /* B192 (45458) */ + 3347, /* B193 (45459) */ + 3347, /* B194 (45460) */ + 3347, /* B195 (45461) */ + 3347, /* B196 (45462) */ + 3347, /* B197 (45463) */ + 3347, /* B198 (45464) */ + 3347, /* B199 (45465) */ + 3347, /* B19A (45466) */ + 3347, /* B19B (45467) */ + 3347, /* B19C (45468) */ + 3347, /* B19D (45469) */ + 3347, /* B19E (45470) */ + 3347, /* B19F (45471) */ + 3347, /* B1A0 (45472) */ + 3347, /* B1A1 (45473) */ + 3347, /* B1A2 (45474) */ + 3347, /* B1A3 (45475) */ + 3347, /* B1A4 (45476) */ + 3347, /* B1A5 (45477) */ + 3347, /* B1A6 (45478) */ + 3347, /* B1A7 (45479) */ + 3347, /* B1A8 (45480) */ + 3347, /* B1A9 (45481) */ + 3347, /* B1AA (45482) */ + 3347, /* B1AB (45483) */ + 3347, /* B1AC (45484) */ + 3347, /* B1AD (45485) */ + 3347, /* B1AE (45486) */ + 3347, /* B1AF (45487) */ + 3347, /* B1B0 (45488) */ + 3347, /* B1B1 (45489) */ + 3347, /* B1B2 (45490) */ + 3347, /* B1B3 (45491) */ + 3347, /* B1B4 (45492) */ + 3347, /* B1B5 (45493) */ + 3347, /* B1B6 (45494) */ + 3347, /* B1B7 (45495) */ + 3347, /* B1B8 (45496) */ + 3347, /* B1B9 (45497) */ + 3347, /* B1BA (45498) */ + 3347, /* B1BB (45499) */ + 3347, /* B1BC (45500) */ + 3347, /* B1BD (45501) */ + 3347, /* B1BE (45502) */ + 3347, /* B1BF (45503) */ + 3347, /* B1C0 (45504) */ + 3347, /* B1C1 (45505) */ + 3347, /* B1C2 (45506) */ + 3347, /* B1C3 (45507) */ + 3347, /* B1C4 (45508) */ + 3347, /* B1C5 (45509) */ + 3347, /* B1C6 (45510) */ + 3347, /* B1C7 (45511) */ + 3347, /* B1C8 (45512) */ + 3347, /* B1C9 (45513) */ + 3347, /* B1CA (45514) */ + 3347, /* B1CB (45515) */ + 3347, /* B1CC (45516) */ + 3347, /* B1CD (45517) */ + 3347, /* B1CE (45518) */ + 3347, /* B1CF (45519) */ + 3347, /* B1D0 (45520) */ + 3347, /* B1D1 (45521) */ + 3347, /* B1D2 (45522) */ + 3347, /* B1D3 (45523) */ + 3347, /* B1D4 (45524) */ + 3347, /* B1D5 (45525) */ + 3347, /* B1D6 (45526) */ + 3347, /* B1D7 (45527) */ + 3347, /* B1D8 (45528) */ + 3347, /* B1D9 (45529) */ + 3347, /* B1DA (45530) */ + 3347, /* B1DB (45531) */ + 3347, /* B1DC (45532) */ + 3347, /* B1DD (45533) */ + 3347, /* B1DE (45534) */ + 3347, /* B1DF (45535) */ + 3347, /* B1E0 (45536) */ + 3347, /* B1E1 (45537) */ + 3347, /* B1E2 (45538) */ + 3347, /* B1E3 (45539) */ + 3347, /* B1E4 (45540) */ + 3347, /* B1E5 (45541) */ + 3347, /* B1E6 (45542) */ + 3347, /* B1E7 (45543) */ + 3347, /* B1E8 (45544) */ + 3347, /* B1E9 (45545) */ + 3347, /* B1EA (45546) */ + 3347, /* B1EB (45547) */ + 3347, /* B1EC (45548) */ + 3347, /* B1ED (45549) */ + 3347, /* B1EE (45550) */ + 3347, /* B1EF (45551) */ + 3347, /* B1F0 (45552) */ + 3347, /* B1F1 (45553) */ + 3347, /* B1F2 (45554) */ + 3347, /* B1F3 (45555) */ + 3347, /* B1F4 (45556) */ + 3347, /* B1F5 (45557) */ + 3347, /* B1F6 (45558) */ + 3347, /* B1F7 (45559) */ + 3347, /* B1F8 (45560) */ + 3347, /* B1F9 (45561) */ + 3347, /* B1FA (45562) */ + 3347, /* B1FB (45563) */ + 3347, /* B1FC (45564) */ + 3347, /* B1FD (45565) */ + 3347, /* B1FE (45566) */ + 3347, /* B1FF (45567) */ + 3347, /* B200 (45568) */ + 3347, /* B201 (45569) */ + 3347, /* B202 (45570) */ + 3347, /* B203 (45571) */ + 3347, /* B204 (45572) */ + 3347, /* B205 (45573) */ + 3347, /* B206 (45574) */ + 3347, /* B207 (45575) */ + 3347, /* B208 (45576) */ + 3347, /* B209 (45577) */ + 3347, /* B20A (45578) */ + 3347, /* B20B (45579) */ + 3347, /* B20C (45580) */ + 3347, /* B20D (45581) */ + 3347, /* B20E (45582) */ + 3347, /* B20F (45583) */ + 3347, /* B210 (45584) */ + 3347, /* B211 (45585) */ + 3347, /* B212 (45586) */ + 3347, /* B213 (45587) */ + 3347, /* B214 (45588) */ + 3347, /* B215 (45589) */ + 3347, /* B216 (45590) */ + 3347, /* B217 (45591) */ + 3347, /* B218 (45592) */ + 3347, /* B219 (45593) */ + 3347, /* B21A (45594) */ + 3347, /* B21B (45595) */ + 3347, /* B21C (45596) */ + 3347, /* B21D (45597) */ + 3347, /* B21E (45598) */ + 3347, /* B21F (45599) */ + 3347, /* B220 (45600) */ + 3347, /* B221 (45601) */ + 3347, /* B222 (45602) */ + 3347, /* B223 (45603) */ + 3347, /* B224 (45604) */ + 3347, /* B225 (45605) */ + 3347, /* B226 (45606) */ + 3347, /* B227 (45607) */ + 3347, /* B228 (45608) */ + 3347, /* B229 (45609) */ + 3347, /* B22A (45610) */ + 3347, /* B22B (45611) */ + 3347, /* B22C (45612) */ + 3347, /* B22D (45613) */ + 3347, /* B22E (45614) */ + 3347, /* B22F (45615) */ + 3347, /* B230 (45616) */ + 3347, /* B231 (45617) */ + 3347, /* B232 (45618) */ + 3347, /* B233 (45619) */ + 3347, /* B234 (45620) */ + 3347, /* B235 (45621) */ + 3347, /* B236 (45622) */ + 3347, /* B237 (45623) */ + 3347, /* B238 (45624) */ + 3347, /* B239 (45625) */ + 3347, /* B23A (45626) */ + 3347, /* B23B (45627) */ + 3347, /* B23C (45628) */ + 3347, /* B23D (45629) */ + 3347, /* B23E (45630) */ + 3347, /* B23F (45631) */ + 3347, /* B240 (45632) */ + 3347, /* B241 (45633) */ + 3347, /* B242 (45634) */ + 3347, /* B243 (45635) */ + 3347, /* B244 (45636) */ + 3347, /* B245 (45637) */ + 3347, /* B246 (45638) */ + 3347, /* B247 (45639) */ + 3347, /* B248 (45640) */ + 3347, /* B249 (45641) */ + 3347, /* B24A (45642) */ + 3347, /* B24B (45643) */ + 3347, /* B24C (45644) */ + 3347, /* B24D (45645) */ + 3347, /* B24E (45646) */ + 3347, /* B24F (45647) */ + 3347, /* B250 (45648) */ + 3347, /* B251 (45649) */ + 3347, /* B252 (45650) */ + 3347, /* B253 (45651) */ + 3347, /* B254 (45652) */ + 3347, /* B255 (45653) */ + 3347, /* B256 (45654) */ + 3347, /* B257 (45655) */ + 3347, /* B258 (45656) */ + 3347, /* B259 (45657) */ + 3347, /* B25A (45658) */ + 3347, /* B25B (45659) */ + 3347, /* B25C (45660) */ + 3347, /* B25D (45661) */ + 3347, /* B25E (45662) */ + 3347, /* B25F (45663) */ + 3347, /* B260 (45664) */ + 3347, /* B261 (45665) */ + 3347, /* B262 (45666) */ + 3347, /* B263 (45667) */ + 3347, /* B264 (45668) */ + 3347, /* B265 (45669) */ + 3347, /* B266 (45670) */ + 3347, /* B267 (45671) */ + 3347, /* B268 (45672) */ + 3347, /* B269 (45673) */ + 3347, /* B26A (45674) */ + 3347, /* B26B (45675) */ + 3347, /* B26C (45676) */ + 3347, /* B26D (45677) */ + 3347, /* B26E (45678) */ + 3347, /* B26F (45679) */ + 3347, /* B270 (45680) */ + 3347, /* B271 (45681) */ + 3347, /* B272 (45682) */ + 3347, /* B273 (45683) */ + 3347, /* B274 (45684) */ + 3347, /* B275 (45685) */ + 3347, /* B276 (45686) */ + 3347, /* B277 (45687) */ + 3347, /* B278 (45688) */ + 3347, /* B279 (45689) */ + 3347, /* B27A (45690) */ + 3347, /* B27B (45691) */ + 3347, /* B27C (45692) */ + 3347, /* B27D (45693) */ + 3347, /* B27E (45694) */ + 3347, /* B27F (45695) */ + 3347, /* B280 (45696) */ + 3347, /* B281 (45697) */ + 3347, /* B282 (45698) */ + 3347, /* B283 (45699) */ + 3347, /* B284 (45700) */ + 3347, /* B285 (45701) */ + 3347, /* B286 (45702) */ + 3347, /* B287 (45703) */ + 3347, /* B288 (45704) */ + 3347, /* B289 (45705) */ + 3347, /* B28A (45706) */ + 3347, /* B28B (45707) */ + 3347, /* B28C (45708) */ + 3347, /* B28D (45709) */ + 3347, /* B28E (45710) */ + 3347, /* B28F (45711) */ + 3347, /* B290 (45712) */ + 3347, /* B291 (45713) */ + 3347, /* B292 (45714) */ + 3347, /* B293 (45715) */ + 3347, /* B294 (45716) */ + 3347, /* B295 (45717) */ + 3347, /* B296 (45718) */ + 3347, /* B297 (45719) */ + 3347, /* B298 (45720) */ + 3347, /* B299 (45721) */ + 3347, /* B29A (45722) */ + 3347, /* B29B (45723) */ + 3347, /* B29C (45724) */ + 3347, /* B29D (45725) */ + 3347, /* B29E (45726) */ + 3347, /* B29F (45727) */ + 3347, /* B2A0 (45728) */ + 3347, /* B2A1 (45729) */ + 3347, /* B2A2 (45730) */ + 3347, /* B2A3 (45731) */ + 3347, /* B2A4 (45732) */ + 3347, /* B2A5 (45733) */ + 3347, /* B2A6 (45734) */ + 3347, /* B2A7 (45735) */ + 3347, /* B2A8 (45736) */ + 3347, /* B2A9 (45737) */ + 3347, /* B2AA (45738) */ + 3347, /* B2AB (45739) */ + 3347, /* B2AC (45740) */ + 3347, /* B2AD (45741) */ + 3347, /* B2AE (45742) */ + 3347, /* B2AF (45743) */ + 3347, /* B2B0 (45744) */ + 3347, /* B2B1 (45745) */ + 3347, /* B2B2 (45746) */ + 3347, /* B2B3 (45747) */ + 3347, /* B2B4 (45748) */ + 3347, /* B2B5 (45749) */ + 3347, /* B2B6 (45750) */ + 3347, /* B2B7 (45751) */ + 3347, /* B2B8 (45752) */ + 3347, /* B2B9 (45753) */ + 3347, /* B2BA (45754) */ + 3347, /* B2BB (45755) */ + 3347, /* B2BC (45756) */ + 3347, /* B2BD (45757) */ + 3347, /* B2BE (45758) */ + 3347, /* B2BF (45759) */ + 3347, /* B2C0 (45760) */ + 3347, /* B2C1 (45761) */ + 3347, /* B2C2 (45762) */ + 3347, /* B2C3 (45763) */ + 3347, /* B2C4 (45764) */ + 3347, /* B2C5 (45765) */ + 3347, /* B2C6 (45766) */ + 3347, /* B2C7 (45767) */ + 3347, /* B2C8 (45768) */ + 3347, /* B2C9 (45769) */ + 3347, /* B2CA (45770) */ + 3347, /* B2CB (45771) */ + 3347, /* B2CC (45772) */ + 3347, /* B2CD (45773) */ + 3347, /* B2CE (45774) */ + 3347, /* B2CF (45775) */ + 3347, /* B2D0 (45776) */ + 3347, /* B2D1 (45777) */ + 3347, /* B2D2 (45778) */ + 3347, /* B2D3 (45779) */ + 3347, /* B2D4 (45780) */ + 3347, /* B2D5 (45781) */ + 3347, /* B2D6 (45782) */ + 3347, /* B2D7 (45783) */ + 3347, /* B2D8 (45784) */ + 3347, /* B2D9 (45785) */ + 3347, /* B2DA (45786) */ + 3347, /* B2DB (45787) */ + 3347, /* B2DC (45788) */ + 3347, /* B2DD (45789) */ + 3347, /* B2DE (45790) */ + 3347, /* B2DF (45791) */ + 3347, /* B2E0 (45792) */ + 3347, /* B2E1 (45793) */ + 3347, /* B2E2 (45794) */ + 3347, /* B2E3 (45795) */ + 3347, /* B2E4 (45796) */ + 3347, /* B2E5 (45797) */ + 3347, /* B2E6 (45798) */ + 3347, /* B2E7 (45799) */ + 3347, /* B2E8 (45800) */ + 3347, /* B2E9 (45801) */ + 3347, /* B2EA (45802) */ + 3347, /* B2EB (45803) */ + 3347, /* B2EC (45804) */ + 3347, /* B2ED (45805) */ + 3347, /* B2EE (45806) */ + 3347, /* B2EF (45807) */ + 3347, /* B2F0 (45808) */ + 3347, /* B2F1 (45809) */ + 3347, /* B2F2 (45810) */ + 3347, /* B2F3 (45811) */ + 3347, /* B2F4 (45812) */ + 3347, /* B2F5 (45813) */ + 3347, /* B2F6 (45814) */ + 3347, /* B2F7 (45815) */ + 3347, /* B2F8 (45816) */ + 3347, /* B2F9 (45817) */ + 3347, /* B2FA (45818) */ + 3347, /* B2FB (45819) */ + 3347, /* B2FC (45820) */ + 3347, /* B2FD (45821) */ + 3347, /* B2FE (45822) */ + 3347, /* B2FF (45823) */ + 3347, /* B300 (45824) */ + 3347, /* B301 (45825) */ + 3347, /* B302 (45826) */ + 3347, /* B303 (45827) */ + 3347, /* B304 (45828) */ + 3347, /* B305 (45829) */ + 3347, /* B306 (45830) */ + 3347, /* B307 (45831) */ + 3347, /* B308 (45832) */ + 3347, /* B309 (45833) */ + 3347, /* B30A (45834) */ + 3347, /* B30B (45835) */ + 3347, /* B30C (45836) */ + 3347, /* B30D (45837) */ + 3347, /* B30E (45838) */ + 3347, /* B30F (45839) */ + 3347, /* B310 (45840) */ + 3347, /* B311 (45841) */ + 3347, /* B312 (45842) */ + 3347, /* B313 (45843) */ + 3347, /* B314 (45844) */ + 3347, /* B315 (45845) */ + 3347, /* B316 (45846) */ + 3347, /* B317 (45847) */ + 3347, /* B318 (45848) */ + 3347, /* B319 (45849) */ + 3347, /* B31A (45850) */ + 3347, /* B31B (45851) */ + 3347, /* B31C (45852) */ + 3347, /* B31D (45853) */ + 3347, /* B31E (45854) */ + 3347, /* B31F (45855) */ + 3347, /* B320 (45856) */ + 3347, /* B321 (45857) */ + 3347, /* B322 (45858) */ + 3347, /* B323 (45859) */ + 3347, /* B324 (45860) */ + 3347, /* B325 (45861) */ + 3347, /* B326 (45862) */ + 3347, /* B327 (45863) */ + 3347, /* B328 (45864) */ + 3347, /* B329 (45865) */ + 3347, /* B32A (45866) */ + 3347, /* B32B (45867) */ + 3347, /* B32C (45868) */ + 3347, /* B32D (45869) */ + 3347, /* B32E (45870) */ + 3347, /* B32F (45871) */ + 3347, /* B330 (45872) */ + 3347, /* B331 (45873) */ + 3347, /* B332 (45874) */ + 3347, /* B333 (45875) */ + 3347, /* B334 (45876) */ + 3347, /* B335 (45877) */ + 3347, /* B336 (45878) */ + 3347, /* B337 (45879) */ + 3347, /* B338 (45880) */ + 3347, /* B339 (45881) */ + 3347, /* B33A (45882) */ + 3347, /* B33B (45883) */ + 3347, /* B33C (45884) */ + 3347, /* B33D (45885) */ + 3347, /* B33E (45886) */ + 3347, /* B33F (45887) */ + 3347, /* B340 (45888) */ + 3347, /* B341 (45889) */ + 3347, /* B342 (45890) */ + 3347, /* B343 (45891) */ + 3347, /* B344 (45892) */ + 3347, /* B345 (45893) */ + 3347, /* B346 (45894) */ + 3347, /* B347 (45895) */ + 3347, /* B348 (45896) */ + 3347, /* B349 (45897) */ + 3347, /* B34A (45898) */ + 3347, /* B34B (45899) */ + 3347, /* B34C (45900) */ + 3347, /* B34D (45901) */ + 3347, /* B34E (45902) */ + 3347, /* B34F (45903) */ + 3347, /* B350 (45904) */ + 3347, /* B351 (45905) */ + 3347, /* B352 (45906) */ + 3347, /* B353 (45907) */ + 3347, /* B354 (45908) */ + 3347, /* B355 (45909) */ + 3347, /* B356 (45910) */ + 3347, /* B357 (45911) */ + 3347, /* B358 (45912) */ + 3347, /* B359 (45913) */ + 3347, /* B35A (45914) */ + 3347, /* B35B (45915) */ + 3347, /* B35C (45916) */ + 3347, /* B35D (45917) */ + 3347, /* B35E (45918) */ + 3347, /* B35F (45919) */ + 3347, /* B360 (45920) */ + 3347, /* B361 (45921) */ + 3347, /* B362 (45922) */ + 3347, /* B363 (45923) */ + 3347, /* B364 (45924) */ + 3347, /* B365 (45925) */ + 3347, /* B366 (45926) */ + 3347, /* B367 (45927) */ + 3347, /* B368 (45928) */ + 3347, /* B369 (45929) */ + 3347, /* B36A (45930) */ + 3347, /* B36B (45931) */ + 3347, /* B36C (45932) */ + 3347, /* B36D (45933) */ + 3347, /* B36E (45934) */ + 3347, /* B36F (45935) */ + 3347, /* B370 (45936) */ + 3347, /* B371 (45937) */ + 3347, /* B372 (45938) */ + 3347, /* B373 (45939) */ + 3347, /* B374 (45940) */ + 3347, /* B375 (45941) */ + 3347, /* B376 (45942) */ + 3347, /* B377 (45943) */ + 3347, /* B378 (45944) */ + 3347, /* B379 (45945) */ + 3347, /* B37A (45946) */ + 3347, /* B37B (45947) */ + 3347, /* B37C (45948) */ + 3347, /* B37D (45949) */ + 3347, /* B37E (45950) */ + 3347, /* B37F (45951) */ + 3347, /* B380 (45952) */ + 3347, /* B381 (45953) */ + 3347, /* B382 (45954) */ + 3347, /* B383 (45955) */ + 3347, /* B384 (45956) */ + 3347, /* B385 (45957) */ + 3347, /* B386 (45958) */ + 3347, /* B387 (45959) */ + 3347, /* B388 (45960) */ + 3347, /* B389 (45961) */ + 3347, /* B38A (45962) */ + 3347, /* B38B (45963) */ + 3347, /* B38C (45964) */ + 3347, /* B38D (45965) */ + 3347, /* B38E (45966) */ + 3347, /* B38F (45967) */ + 3347, /* B390 (45968) */ + 3347, /* B391 (45969) */ + 3347, /* B392 (45970) */ + 3347, /* B393 (45971) */ + 3347, /* B394 (45972) */ + 3347, /* B395 (45973) */ + 3347, /* B396 (45974) */ + 3347, /* B397 (45975) */ + 3347, /* B398 (45976) */ + 3347, /* B399 (45977) */ + 3347, /* B39A (45978) */ + 3347, /* B39B (45979) */ + 3347, /* B39C (45980) */ + 3347, /* B39D (45981) */ + 3347, /* B39E (45982) */ + 3347, /* B39F (45983) */ + 3347, /* B3A0 (45984) */ + 3347, /* B3A1 (45985) */ + 3347, /* B3A2 (45986) */ + 3347, /* B3A3 (45987) */ + 3347, /* B3A4 (45988) */ + 3347, /* B3A5 (45989) */ + 3347, /* B3A6 (45990) */ + 3347, /* B3A7 (45991) */ + 3347, /* B3A8 (45992) */ + 3347, /* B3A9 (45993) */ + 3347, /* B3AA (45994) */ + 3347, /* B3AB (45995) */ + 3347, /* B3AC (45996) */ + 3347, /* B3AD (45997) */ + 3347, /* B3AE (45998) */ + 3347, /* B3AF (45999) */ + 3347, /* B3B0 (46000) */ + 3347, /* B3B1 (46001) */ + 3347, /* B3B2 (46002) */ + 3347, /* B3B3 (46003) */ + 3347, /* B3B4 (46004) */ + 3347, /* B3B5 (46005) */ + 3347, /* B3B6 (46006) */ + 3347, /* B3B7 (46007) */ + 3347, /* B3B8 (46008) */ + 3347, /* B3B9 (46009) */ + 3347, /* B3BA (46010) */ + 3347, /* B3BB (46011) */ + 3347, /* B3BC (46012) */ + 3347, /* B3BD (46013) */ + 3347, /* B3BE (46014) */ + 3347, /* B3BF (46015) */ + 3347, /* B3C0 (46016) */ + 3347, /* B3C1 (46017) */ + 3347, /* B3C2 (46018) */ + 3347, /* B3C3 (46019) */ + 3347, /* B3C4 (46020) */ + 3347, /* B3C5 (46021) */ + 3347, /* B3C6 (46022) */ + 3347, /* B3C7 (46023) */ + 3347, /* B3C8 (46024) */ + 3347, /* B3C9 (46025) */ + 3347, /* B3CA (46026) */ + 3347, /* B3CB (46027) */ + 3347, /* B3CC (46028) */ + 3347, /* B3CD (46029) */ + 3347, /* B3CE (46030) */ + 3347, /* B3CF (46031) */ + 3347, /* B3D0 (46032) */ + 3347, /* B3D1 (46033) */ + 3347, /* B3D2 (46034) */ + 3347, /* B3D3 (46035) */ + 3347, /* B3D4 (46036) */ + 3347, /* B3D5 (46037) */ + 3347, /* B3D6 (46038) */ + 3347, /* B3D7 (46039) */ + 3347, /* B3D8 (46040) */ + 3347, /* B3D9 (46041) */ + 3347, /* B3DA (46042) */ + 3347, /* B3DB (46043) */ + 3347, /* B3DC (46044) */ + 3347, /* B3DD (46045) */ + 3347, /* B3DE (46046) */ + 3347, /* B3DF (46047) */ + 3347, /* B3E0 (46048) */ + 3347, /* B3E1 (46049) */ + 3347, /* B3E2 (46050) */ + 3347, /* B3E3 (46051) */ + 3347, /* B3E4 (46052) */ + 3347, /* B3E5 (46053) */ + 3347, /* B3E6 (46054) */ + 3347, /* B3E7 (46055) */ + 3347, /* B3E8 (46056) */ + 3347, /* B3E9 (46057) */ + 3347, /* B3EA (46058) */ + 3347, /* B3EB (46059) */ + 3347, /* B3EC (46060) */ + 3347, /* B3ED (46061) */ + 3347, /* B3EE (46062) */ + 3347, /* B3EF (46063) */ + 3347, /* B3F0 (46064) */ + 3347, /* B3F1 (46065) */ + 3347, /* B3F2 (46066) */ + 3347, /* B3F3 (46067) */ + 3347, /* B3F4 (46068) */ + 3347, /* B3F5 (46069) */ + 3347, /* B3F6 (46070) */ + 3347, /* B3F7 (46071) */ + 3347, /* B3F8 (46072) */ + 3347, /* B3F9 (46073) */ + 3347, /* B3FA (46074) */ + 3347, /* B3FB (46075) */ + 3347, /* B3FC (46076) */ + 3347, /* B3FD (46077) */ + 3347, /* B3FE (46078) */ + 3347, /* B3FF (46079) */ + 3347, /* B400 (46080) */ + 3347, /* B401 (46081) */ + 3347, /* B402 (46082) */ + 3347, /* B403 (46083) */ + 3347, /* B404 (46084) */ + 3347, /* B405 (46085) */ + 3347, /* B406 (46086) */ + 3347, /* B407 (46087) */ + 3347, /* B408 (46088) */ + 3347, /* B409 (46089) */ + 3347, /* B40A (46090) */ + 3347, /* B40B (46091) */ + 3347, /* B40C (46092) */ + 3347, /* B40D (46093) */ + 3347, /* B40E (46094) */ + 3347, /* B40F (46095) */ + 3347, /* B410 (46096) */ + 3347, /* B411 (46097) */ + 3347, /* B412 (46098) */ + 3347, /* B413 (46099) */ + 3347, /* B414 (46100) */ + 3347, /* B415 (46101) */ + 3347, /* B416 (46102) */ + 3347, /* B417 (46103) */ + 3347, /* B418 (46104) */ + 3347, /* B419 (46105) */ + 3347, /* B41A (46106) */ + 3347, /* B41B (46107) */ + 3347, /* B41C (46108) */ + 3347, /* B41D (46109) */ + 3347, /* B41E (46110) */ + 3347, /* B41F (46111) */ + 3347, /* B420 (46112) */ + 3347, /* B421 (46113) */ + 3347, /* B422 (46114) */ + 3347, /* B423 (46115) */ + 3347, /* B424 (46116) */ + 3347, /* B425 (46117) */ + 3347, /* B426 (46118) */ + 3347, /* B427 (46119) */ + 3347, /* B428 (46120) */ + 3347, /* B429 (46121) */ + 3347, /* B42A (46122) */ + 3347, /* B42B (46123) */ + 3347, /* B42C (46124) */ + 3347, /* B42D (46125) */ + 3347, /* B42E (46126) */ + 3347, /* B42F (46127) */ + 3347, /* B430 (46128) */ + 3347, /* B431 (46129) */ + 3347, /* B432 (46130) */ + 3347, /* B433 (46131) */ + 3347, /* B434 (46132) */ + 3347, /* B435 (46133) */ + 3347, /* B436 (46134) */ + 3347, /* B437 (46135) */ + 3347, /* B438 (46136) */ + 3347, /* B439 (46137) */ + 3347, /* B43A (46138) */ + 3347, /* B43B (46139) */ + 3347, /* B43C (46140) */ + 3347, /* B43D (46141) */ + 3347, /* B43E (46142) */ + 3347, /* B43F (46143) */ + 3347, /* B440 (46144) */ + 3347, /* B441 (46145) */ + 3347, /* B442 (46146) */ + 3347, /* B443 (46147) */ + 3347, /* B444 (46148) */ + 3347, /* B445 (46149) */ + 3347, /* B446 (46150) */ + 3347, /* B447 (46151) */ + 3347, /* B448 (46152) */ + 3347, /* B449 (46153) */ + 3347, /* B44A (46154) */ + 3347, /* B44B (46155) */ + 3347, /* B44C (46156) */ + 3347, /* B44D (46157) */ + 3347, /* B44E (46158) */ + 3347, /* B44F (46159) */ + 3347, /* B450 (46160) */ + 3347, /* B451 (46161) */ + 3347, /* B452 (46162) */ + 3347, /* B453 (46163) */ + 3347, /* B454 (46164) */ + 3347, /* B455 (46165) */ + 3347, /* B456 (46166) */ + 3347, /* B457 (46167) */ + 3347, /* B458 (46168) */ + 3347, /* B459 (46169) */ + 3347, /* B45A (46170) */ + 3347, /* B45B (46171) */ + 3347, /* B45C (46172) */ + 3347, /* B45D (46173) */ + 3347, /* B45E (46174) */ + 3347, /* B45F (46175) */ + 3347, /* B460 (46176) */ + 3347, /* B461 (46177) */ + 3347, /* B462 (46178) */ + 3347, /* B463 (46179) */ + 3347, /* B464 (46180) */ + 3347, /* B465 (46181) */ + 3347, /* B466 (46182) */ + 3347, /* B467 (46183) */ + 3347, /* B468 (46184) */ + 3347, /* B469 (46185) */ + 3347, /* B46A (46186) */ + 3347, /* B46B (46187) */ + 3347, /* B46C (46188) */ + 3347, /* B46D (46189) */ + 3347, /* B46E (46190) */ + 3347, /* B46F (46191) */ + 3347, /* B470 (46192) */ + 3347, /* B471 (46193) */ + 3347, /* B472 (46194) */ + 3347, /* B473 (46195) */ + 3347, /* B474 (46196) */ + 3347, /* B475 (46197) */ + 3347, /* B476 (46198) */ + 3347, /* B477 (46199) */ + 3347, /* B478 (46200) */ + 3347, /* B479 (46201) */ + 3347, /* B47A (46202) */ + 3347, /* B47B (46203) */ + 3347, /* B47C (46204) */ + 3347, /* B47D (46205) */ + 3347, /* B47E (46206) */ + 3347, /* B47F (46207) */ + 3347, /* B480 (46208) */ + 3347, /* B481 (46209) */ + 3347, /* B482 (46210) */ + 3347, /* B483 (46211) */ + 3347, /* B484 (46212) */ + 3347, /* B485 (46213) */ + 3347, /* B486 (46214) */ + 3347, /* B487 (46215) */ + 3347, /* B488 (46216) */ + 3347, /* B489 (46217) */ + 3347, /* B48A (46218) */ + 3347, /* B48B (46219) */ + 3347, /* B48C (46220) */ + 3347, /* B48D (46221) */ + 3347, /* B48E (46222) */ + 3347, /* B48F (46223) */ + 3347, /* B490 (46224) */ + 3347, /* B491 (46225) */ + 3347, /* B492 (46226) */ + 3347, /* B493 (46227) */ + 3347, /* B494 (46228) */ + 3347, /* B495 (46229) */ + 3347, /* B496 (46230) */ + 3347, /* B497 (46231) */ + 3347, /* B498 (46232) */ + 3347, /* B499 (46233) */ + 3347, /* B49A (46234) */ + 3347, /* B49B (46235) */ + 3347, /* B49C (46236) */ + 3347, /* B49D (46237) */ + 3347, /* B49E (46238) */ + 3347, /* B49F (46239) */ + 3347, /* B4A0 (46240) */ + 3347, /* B4A1 (46241) */ + 3347, /* B4A2 (46242) */ + 3347, /* B4A3 (46243) */ + 3347, /* B4A4 (46244) */ + 3347, /* B4A5 (46245) */ + 3347, /* B4A6 (46246) */ + 3347, /* B4A7 (46247) */ + 3347, /* B4A8 (46248) */ + 3347, /* B4A9 (46249) */ + 3347, /* B4AA (46250) */ + 3347, /* B4AB (46251) */ + 3347, /* B4AC (46252) */ + 3347, /* B4AD (46253) */ + 3347, /* B4AE (46254) */ + 3347, /* B4AF (46255) */ + 3347, /* B4B0 (46256) */ + 3347, /* B4B1 (46257) */ + 3347, /* B4B2 (46258) */ + 3347, /* B4B3 (46259) */ + 3347, /* B4B4 (46260) */ + 3347, /* B4B5 (46261) */ + 3347, /* B4B6 (46262) */ + 3347, /* B4B7 (46263) */ + 3347, /* B4B8 (46264) */ + 3347, /* B4B9 (46265) */ + 3347, /* B4BA (46266) */ + 3347, /* B4BB (46267) */ + 3347, /* B4BC (46268) */ + 3347, /* B4BD (46269) */ + 3347, /* B4BE (46270) */ + 3347, /* B4BF (46271) */ + 3347, /* B4C0 (46272) */ + 3347, /* B4C1 (46273) */ + 3347, /* B4C2 (46274) */ + 3347, /* B4C3 (46275) */ + 3347, /* B4C4 (46276) */ + 3347, /* B4C5 (46277) */ + 3347, /* B4C6 (46278) */ + 3347, /* B4C7 (46279) */ + 3347, /* B4C8 (46280) */ + 3347, /* B4C9 (46281) */ + 3347, /* B4CA (46282) */ + 3347, /* B4CB (46283) */ + 3347, /* B4CC (46284) */ + 3347, /* B4CD (46285) */ + 3347, /* B4CE (46286) */ + 3347, /* B4CF (46287) */ + 3347, /* B4D0 (46288) */ + 3347, /* B4D1 (46289) */ + 3347, /* B4D2 (46290) */ + 3347, /* B4D3 (46291) */ + 3347, /* B4D4 (46292) */ + 3347, /* B4D5 (46293) */ + 3347, /* B4D6 (46294) */ + 3347, /* B4D7 (46295) */ + 3347, /* B4D8 (46296) */ + 3347, /* B4D9 (46297) */ + 3347, /* B4DA (46298) */ + 3347, /* B4DB (46299) */ + 3347, /* B4DC (46300) */ + 3347, /* B4DD (46301) */ + 3347, /* B4DE (46302) */ + 3347, /* B4DF (46303) */ + 3347, /* B4E0 (46304) */ + 3347, /* B4E1 (46305) */ + 3347, /* B4E2 (46306) */ + 3347, /* B4E3 (46307) */ + 3347, /* B4E4 (46308) */ + 3347, /* B4E5 (46309) */ + 3347, /* B4E6 (46310) */ + 3347, /* B4E7 (46311) */ + 3347, /* B4E8 (46312) */ + 3347, /* B4E9 (46313) */ + 3347, /* B4EA (46314) */ + 3347, /* B4EB (46315) */ + 3347, /* B4EC (46316) */ + 3347, /* B4ED (46317) */ + 3347, /* B4EE (46318) */ + 3347, /* B4EF (46319) */ + 3347, /* B4F0 (46320) */ + 3347, /* B4F1 (46321) */ + 3347, /* B4F2 (46322) */ + 3347, /* B4F3 (46323) */ + 3347, /* B4F4 (46324) */ + 3347, /* B4F5 (46325) */ + 3347, /* B4F6 (46326) */ + 3347, /* B4F7 (46327) */ + 3347, /* B4F8 (46328) */ + 3347, /* B4F9 (46329) */ + 3347, /* B4FA (46330) */ + 3347, /* B4FB (46331) */ + 3347, /* B4FC (46332) */ + 3347, /* B4FD (46333) */ + 3347, /* B4FE (46334) */ + 3347, /* B4FF (46335) */ + 3347, /* B500 (46336) */ + 3347, /* B501 (46337) */ + 3347, /* B502 (46338) */ + 3347, /* B503 (46339) */ + 3347, /* B504 (46340) */ + 3347, /* B505 (46341) */ + 3347, /* B506 (46342) */ + 3347, /* B507 (46343) */ + 3347, /* B508 (46344) */ + 3347, /* B509 (46345) */ + 3347, /* B50A (46346) */ + 3347, /* B50B (46347) */ + 3347, /* B50C (46348) */ + 3347, /* B50D (46349) */ + 3347, /* B50E (46350) */ + 3347, /* B50F (46351) */ + 3347, /* B510 (46352) */ + 3347, /* B511 (46353) */ + 3347, /* B512 (46354) */ + 3347, /* B513 (46355) */ + 3347, /* B514 (46356) */ + 3347, /* B515 (46357) */ + 3347, /* B516 (46358) */ + 3347, /* B517 (46359) */ + 3347, /* B518 (46360) */ + 3347, /* B519 (46361) */ + 3347, /* B51A (46362) */ + 3347, /* B51B (46363) */ + 3347, /* B51C (46364) */ + 3347, /* B51D (46365) */ + 3347, /* B51E (46366) */ + 3347, /* B51F (46367) */ + 3347, /* B520 (46368) */ + 3347, /* B521 (46369) */ + 3347, /* B522 (46370) */ + 3347, /* B523 (46371) */ + 3347, /* B524 (46372) */ + 3347, /* B525 (46373) */ + 3347, /* B526 (46374) */ + 3347, /* B527 (46375) */ + 3347, /* B528 (46376) */ + 3347, /* B529 (46377) */ + 3347, /* B52A (46378) */ + 3347, /* B52B (46379) */ + 3347, /* B52C (46380) */ + 3347, /* B52D (46381) */ + 3347, /* B52E (46382) */ + 3347, /* B52F (46383) */ + 3347, /* B530 (46384) */ + 3347, /* B531 (46385) */ + 3347, /* B532 (46386) */ + 3347, /* B533 (46387) */ + 3347, /* B534 (46388) */ + 3347, /* B535 (46389) */ + 3347, /* B536 (46390) */ + 3347, /* B537 (46391) */ + 3347, /* B538 (46392) */ + 3347, /* B539 (46393) */ + 3347, /* B53A (46394) */ + 3347, /* B53B (46395) */ + 3347, /* B53C (46396) */ + 3347, /* B53D (46397) */ + 3347, /* B53E (46398) */ + 3347, /* B53F (46399) */ + 3347, /* B540 (46400) */ + 3347, /* B541 (46401) */ + 3347, /* B542 (46402) */ + 3347, /* B543 (46403) */ + 3347, /* B544 (46404) */ + 3347, /* B545 (46405) */ + 3347, /* B546 (46406) */ + 3347, /* B547 (46407) */ + 3347, /* B548 (46408) */ + 3347, /* B549 (46409) */ + 3347, /* B54A (46410) */ + 3347, /* B54B (46411) */ + 3347, /* B54C (46412) */ + 3347, /* B54D (46413) */ + 3347, /* B54E (46414) */ + 3347, /* B54F (46415) */ + 3347, /* B550 (46416) */ + 3347, /* B551 (46417) */ + 3347, /* B552 (46418) */ + 3347, /* B553 (46419) */ + 3347, /* B554 (46420) */ + 3347, /* B555 (46421) */ + 3347, /* B556 (46422) */ + 3347, /* B557 (46423) */ + 3347, /* B558 (46424) */ + 3347, /* B559 (46425) */ + 3347, /* B55A (46426) */ + 3347, /* B55B (46427) */ + 3347, /* B55C (46428) */ + 3347, /* B55D (46429) */ + 3347, /* B55E (46430) */ + 3347, /* B55F (46431) */ + 3347, /* B560 (46432) */ + 3347, /* B561 (46433) */ + 3347, /* B562 (46434) */ + 3347, /* B563 (46435) */ + 3347, /* B564 (46436) */ + 3347, /* B565 (46437) */ + 3347, /* B566 (46438) */ + 3347, /* B567 (46439) */ + 3347, /* B568 (46440) */ + 3347, /* B569 (46441) */ + 3347, /* B56A (46442) */ + 3347, /* B56B (46443) */ + 3347, /* B56C (46444) */ + 3347, /* B56D (46445) */ + 3347, /* B56E (46446) */ + 3347, /* B56F (46447) */ + 3347, /* B570 (46448) */ + 3347, /* B571 (46449) */ + 3347, /* B572 (46450) */ + 3347, /* B573 (46451) */ + 3347, /* B574 (46452) */ + 3347, /* B575 (46453) */ + 3347, /* B576 (46454) */ + 3347, /* B577 (46455) */ + 3347, /* B578 (46456) */ + 3347, /* B579 (46457) */ + 3347, /* B57A (46458) */ + 3347, /* B57B (46459) */ + 3347, /* B57C (46460) */ + 3347, /* B57D (46461) */ + 3347, /* B57E (46462) */ + 3347, /* B57F (46463) */ + 3347, /* B580 (46464) */ + 3347, /* B581 (46465) */ + 3347, /* B582 (46466) */ + 3347, /* B583 (46467) */ + 3347, /* B584 (46468) */ + 3347, /* B585 (46469) */ + 3347, /* B586 (46470) */ + 3347, /* B587 (46471) */ + 3347, /* B588 (46472) */ + 3347, /* B589 (46473) */ + 3347, /* B58A (46474) */ + 3347, /* B58B (46475) */ + 3347, /* B58C (46476) */ + 3347, /* B58D (46477) */ + 3347, /* B58E (46478) */ + 3347, /* B58F (46479) */ + 3347, /* B590 (46480) */ + 3347, /* B591 (46481) */ + 3347, /* B592 (46482) */ + 3347, /* B593 (46483) */ + 3347, /* B594 (46484) */ + 3347, /* B595 (46485) */ + 3347, /* B596 (46486) */ + 3347, /* B597 (46487) */ + 3347, /* B598 (46488) */ + 3347, /* B599 (46489) */ + 3347, /* B59A (46490) */ + 3347, /* B59B (46491) */ + 3347, /* B59C (46492) */ + 3347, /* B59D (46493) */ + 3347, /* B59E (46494) */ + 3347, /* B59F (46495) */ + 3347, /* B5A0 (46496) */ + 3347, /* B5A1 (46497) */ + 3347, /* B5A2 (46498) */ + 3347, /* B5A3 (46499) */ + 3347, /* B5A4 (46500) */ + 3347, /* B5A5 (46501) */ + 3347, /* B5A6 (46502) */ + 3347, /* B5A7 (46503) */ + 3347, /* B5A8 (46504) */ + 3347, /* B5A9 (46505) */ + 3347, /* B5AA (46506) */ + 3347, /* B5AB (46507) */ + 3347, /* B5AC (46508) */ + 3347, /* B5AD (46509) */ + 3347, /* B5AE (46510) */ + 3347, /* B5AF (46511) */ + 3347, /* B5B0 (46512) */ + 3347, /* B5B1 (46513) */ + 3347, /* B5B2 (46514) */ + 3347, /* B5B3 (46515) */ + 3347, /* B5B4 (46516) */ + 3347, /* B5B5 (46517) */ + 3347, /* B5B6 (46518) */ + 3347, /* B5B7 (46519) */ + 3347, /* B5B8 (46520) */ + 3347, /* B5B9 (46521) */ + 3347, /* B5BA (46522) */ + 3347, /* B5BB (46523) */ + 3347, /* B5BC (46524) */ + 3347, /* B5BD (46525) */ + 3347, /* B5BE (46526) */ + 3347, /* B5BF (46527) */ + 3347, /* B5C0 (46528) */ + 3347, /* B5C1 (46529) */ + 3347, /* B5C2 (46530) */ + 3347, /* B5C3 (46531) */ + 3347, /* B5C4 (46532) */ + 3347, /* B5C5 (46533) */ + 3347, /* B5C6 (46534) */ + 3347, /* B5C7 (46535) */ + 3347, /* B5C8 (46536) */ + 3347, /* B5C9 (46537) */ + 3347, /* B5CA (46538) */ + 3347, /* B5CB (46539) */ + 3347, /* B5CC (46540) */ + 3347, /* B5CD (46541) */ + 3347, /* B5CE (46542) */ + 3347, /* B5CF (46543) */ + 3347, /* B5D0 (46544) */ + 3347, /* B5D1 (46545) */ + 3347, /* B5D2 (46546) */ + 3347, /* B5D3 (46547) */ + 3347, /* B5D4 (46548) */ + 3347, /* B5D5 (46549) */ + 3347, /* B5D6 (46550) */ + 3347, /* B5D7 (46551) */ + 3347, /* B5D8 (46552) */ + 3347, /* B5D9 (46553) */ + 3347, /* B5DA (46554) */ + 3347, /* B5DB (46555) */ + 3347, /* B5DC (46556) */ + 3347, /* B5DD (46557) */ + 3347, /* B5DE (46558) */ + 3347, /* B5DF (46559) */ + 3347, /* B5E0 (46560) */ + 3347, /* B5E1 (46561) */ + 3347, /* B5E2 (46562) */ + 3347, /* B5E3 (46563) */ + 3347, /* B5E4 (46564) */ + 3347, /* B5E5 (46565) */ + 3347, /* B5E6 (46566) */ + 3347, /* B5E7 (46567) */ + 3347, /* B5E8 (46568) */ + 3347, /* B5E9 (46569) */ + 3347, /* B5EA (46570) */ + 3347, /* B5EB (46571) */ + 3347, /* B5EC (46572) */ + 3347, /* B5ED (46573) */ + 3347, /* B5EE (46574) */ + 3347, /* B5EF (46575) */ + 3347, /* B5F0 (46576) */ + 3347, /* B5F1 (46577) */ + 3347, /* B5F2 (46578) */ + 3347, /* B5F3 (46579) */ + 3347, /* B5F4 (46580) */ + 3347, /* B5F5 (46581) */ + 3347, /* B5F6 (46582) */ + 3347, /* B5F7 (46583) */ + 3347, /* B5F8 (46584) */ + 3347, /* B5F9 (46585) */ + 3347, /* B5FA (46586) */ + 3347, /* B5FB (46587) */ + 3347, /* B5FC (46588) */ + 3347, /* B5FD (46589) */ + 3347, /* B5FE (46590) */ + 3347, /* B5FF (46591) */ + 3347, /* B600 (46592) */ + 3347, /* B601 (46593) */ + 3347, /* B602 (46594) */ + 3347, /* B603 (46595) */ + 3347, /* B604 (46596) */ + 3347, /* B605 (46597) */ + 3347, /* B606 (46598) */ + 3347, /* B607 (46599) */ + 3347, /* B608 (46600) */ + 3347, /* B609 (46601) */ + 3347, /* B60A (46602) */ + 3347, /* B60B (46603) */ + 3347, /* B60C (46604) */ + 3347, /* B60D (46605) */ + 3347, /* B60E (46606) */ + 3347, /* B60F (46607) */ + 3347, /* B610 (46608) */ + 3347, /* B611 (46609) */ + 3347, /* B612 (46610) */ + 3347, /* B613 (46611) */ + 3347, /* B614 (46612) */ + 3347, /* B615 (46613) */ + 3347, /* B616 (46614) */ + 3347, /* B617 (46615) */ + 3347, /* B618 (46616) */ + 3347, /* B619 (46617) */ + 3347, /* B61A (46618) */ + 3347, /* B61B (46619) */ + 3347, /* B61C (46620) */ + 3347, /* B61D (46621) */ + 3347, /* B61E (46622) */ + 3347, /* B61F (46623) */ + 3347, /* B620 (46624) */ + 3347, /* B621 (46625) */ + 3347, /* B622 (46626) */ + 3347, /* B623 (46627) */ + 3347, /* B624 (46628) */ + 3347, /* B625 (46629) */ + 3347, /* B626 (46630) */ + 3347, /* B627 (46631) */ + 3347, /* B628 (46632) */ + 3347, /* B629 (46633) */ + 3347, /* B62A (46634) */ + 3347, /* B62B (46635) */ + 3347, /* B62C (46636) */ + 3347, /* B62D (46637) */ + 3347, /* B62E (46638) */ + 3347, /* B62F (46639) */ + 3347, /* B630 (46640) */ + 3347, /* B631 (46641) */ + 3347, /* B632 (46642) */ + 3347, /* B633 (46643) */ + 3347, /* B634 (46644) */ + 3347, /* B635 (46645) */ + 3347, /* B636 (46646) */ + 3347, /* B637 (46647) */ + 3347, /* B638 (46648) */ + 3347, /* B639 (46649) */ + 3347, /* B63A (46650) */ + 3347, /* B63B (46651) */ + 3347, /* B63C (46652) */ + 3347, /* B63D (46653) */ + 3347, /* B63E (46654) */ + 3347, /* B63F (46655) */ + 3347, /* B640 (46656) */ + 3347, /* B641 (46657) */ + 3347, /* B642 (46658) */ + 3347, /* B643 (46659) */ + 3347, /* B644 (46660) */ + 3347, /* B645 (46661) */ + 3347, /* B646 (46662) */ + 3347, /* B647 (46663) */ + 3347, /* B648 (46664) */ + 3347, /* B649 (46665) */ + 3347, /* B64A (46666) */ + 3347, /* B64B (46667) */ + 3347, /* B64C (46668) */ + 3347, /* B64D (46669) */ + 3347, /* B64E (46670) */ + 3347, /* B64F (46671) */ + 3347, /* B650 (46672) */ + 3347, /* B651 (46673) */ + 3347, /* B652 (46674) */ + 3347, /* B653 (46675) */ + 3347, /* B654 (46676) */ + 3347, /* B655 (46677) */ + 3347, /* B656 (46678) */ + 3347, /* B657 (46679) */ + 3347, /* B658 (46680) */ + 3347, /* B659 (46681) */ + 3347, /* B65A (46682) */ + 3347, /* B65B (46683) */ + 3347, /* B65C (46684) */ + 3347, /* B65D (46685) */ + 3347, /* B65E (46686) */ + 3347, /* B65F (46687) */ + 3347, /* B660 (46688) */ + 3347, /* B661 (46689) */ + 3347, /* B662 (46690) */ + 3347, /* B663 (46691) */ + 3347, /* B664 (46692) */ + 3347, /* B665 (46693) */ + 3347, /* B666 (46694) */ + 3347, /* B667 (46695) */ + 3347, /* B668 (46696) */ + 3347, /* B669 (46697) */ + 3347, /* B66A (46698) */ + 3347, /* B66B (46699) */ + 3347, /* B66C (46700) */ + 3347, /* B66D (46701) */ + 3347, /* B66E (46702) */ + 3347, /* B66F (46703) */ + 3347, /* B670 (46704) */ + 3347, /* B671 (46705) */ + 3347, /* B672 (46706) */ + 3347, /* B673 (46707) */ + 3347, /* B674 (46708) */ + 3347, /* B675 (46709) */ + 3347, /* B676 (46710) */ + 3347, /* B677 (46711) */ + 3347, /* B678 (46712) */ + 3347, /* B679 (46713) */ + 3347, /* B67A (46714) */ + 3347, /* B67B (46715) */ + 3347, /* B67C (46716) */ + 3347, /* B67D (46717) */ + 3347, /* B67E (46718) */ + 3347, /* B67F (46719) */ + 3347, /* B680 (46720) */ + 3347, /* B681 (46721) */ + 3347, /* B682 (46722) */ + 3347, /* B683 (46723) */ + 3347, /* B684 (46724) */ + 3347, /* B685 (46725) */ + 3347, /* B686 (46726) */ + 3347, /* B687 (46727) */ + 3347, /* B688 (46728) */ + 3347, /* B689 (46729) */ + 3347, /* B68A (46730) */ + 3347, /* B68B (46731) */ + 3347, /* B68C (46732) */ + 3347, /* B68D (46733) */ + 3347, /* B68E (46734) */ + 3347, /* B68F (46735) */ + 3347, /* B690 (46736) */ + 3347, /* B691 (46737) */ + 3347, /* B692 (46738) */ + 3347, /* B693 (46739) */ + 3347, /* B694 (46740) */ + 3347, /* B695 (46741) */ + 3347, /* B696 (46742) */ + 3347, /* B697 (46743) */ + 3347, /* B698 (46744) */ + 3347, /* B699 (46745) */ + 3347, /* B69A (46746) */ + 3347, /* B69B (46747) */ + 3347, /* B69C (46748) */ + 3347, /* B69D (46749) */ + 3347, /* B69E (46750) */ + 3347, /* B69F (46751) */ + 3347, /* B6A0 (46752) */ + 3347, /* B6A1 (46753) */ + 3347, /* B6A2 (46754) */ + 3347, /* B6A3 (46755) */ + 3347, /* B6A4 (46756) */ + 3347, /* B6A5 (46757) */ + 3347, /* B6A6 (46758) */ + 3347, /* B6A7 (46759) */ + 3347, /* B6A8 (46760) */ + 3347, /* B6A9 (46761) */ + 3347, /* B6AA (46762) */ + 3347, /* B6AB (46763) */ + 3347, /* B6AC (46764) */ + 3347, /* B6AD (46765) */ + 3347, /* B6AE (46766) */ + 3347, /* B6AF (46767) */ + 3347, /* B6B0 (46768) */ + 3347, /* B6B1 (46769) */ + 3347, /* B6B2 (46770) */ + 3347, /* B6B3 (46771) */ + 3347, /* B6B4 (46772) */ + 3347, /* B6B5 (46773) */ + 3347, /* B6B6 (46774) */ + 3347, /* B6B7 (46775) */ + 3347, /* B6B8 (46776) */ + 3347, /* B6B9 (46777) */ + 3347, /* B6BA (46778) */ + 3347, /* B6BB (46779) */ + 3347, /* B6BC (46780) */ + 3347, /* B6BD (46781) */ + 3347, /* B6BE (46782) */ + 3347, /* B6BF (46783) */ + 3347, /* B6C0 (46784) */ + 3347, /* B6C1 (46785) */ + 3347, /* B6C2 (46786) */ + 3347, /* B6C3 (46787) */ + 3347, /* B6C4 (46788) */ + 3347, /* B6C5 (46789) */ + 3347, /* B6C6 (46790) */ + 3347, /* B6C7 (46791) */ + 3347, /* B6C8 (46792) */ + 3347, /* B6C9 (46793) */ + 3347, /* B6CA (46794) */ + 3347, /* B6CB (46795) */ + 3347, /* B6CC (46796) */ + 3347, /* B6CD (46797) */ + 3347, /* B6CE (46798) */ + 3347, /* B6CF (46799) */ + 3347, /* B6D0 (46800) */ + 3347, /* B6D1 (46801) */ + 3347, /* B6D2 (46802) */ + 3347, /* B6D3 (46803) */ + 3347, /* B6D4 (46804) */ + 3347, /* B6D5 (46805) */ + 3347, /* B6D6 (46806) */ + 3347, /* B6D7 (46807) */ + 3347, /* B6D8 (46808) */ + 3347, /* B6D9 (46809) */ + 3347, /* B6DA (46810) */ + 3347, /* B6DB (46811) */ + 3347, /* B6DC (46812) */ + 3347, /* B6DD (46813) */ + 3347, /* B6DE (46814) */ + 3347, /* B6DF (46815) */ + 3347, /* B6E0 (46816) */ + 3347, /* B6E1 (46817) */ + 3347, /* B6E2 (46818) */ + 3347, /* B6E3 (46819) */ + 3347, /* B6E4 (46820) */ + 3347, /* B6E5 (46821) */ + 3347, /* B6E6 (46822) */ + 3347, /* B6E7 (46823) */ + 3347, /* B6E8 (46824) */ + 3347, /* B6E9 (46825) */ + 3347, /* B6EA (46826) */ + 3347, /* B6EB (46827) */ + 3347, /* B6EC (46828) */ + 3347, /* B6ED (46829) */ + 3347, /* B6EE (46830) */ + 3347, /* B6EF (46831) */ + 3347, /* B6F0 (46832) */ + 3347, /* B6F1 (46833) */ + 3347, /* B6F2 (46834) */ + 3347, /* B6F3 (46835) */ + 3347, /* B6F4 (46836) */ + 3347, /* B6F5 (46837) */ + 3347, /* B6F6 (46838) */ + 3347, /* B6F7 (46839) */ + 3347, /* B6F8 (46840) */ + 3347, /* B6F9 (46841) */ + 3347, /* B6FA (46842) */ + 3347, /* B6FB (46843) */ + 3347, /* B6FC (46844) */ + 3347, /* B6FD (46845) */ + 3347, /* B6FE (46846) */ + 3347, /* B6FF (46847) */ + 3347, /* B700 (46848) */ + 3347, /* B701 (46849) */ + 3347, /* B702 (46850) */ + 3347, /* B703 (46851) */ + 3347, /* B704 (46852) */ + 3347, /* B705 (46853) */ + 3347, /* B706 (46854) */ + 3347, /* B707 (46855) */ + 3347, /* B708 (46856) */ + 3347, /* B709 (46857) */ + 3347, /* B70A (46858) */ + 3347, /* B70B (46859) */ + 3347, /* B70C (46860) */ + 3347, /* B70D (46861) */ + 3347, /* B70E (46862) */ + 3347, /* B70F (46863) */ + 3347, /* B710 (46864) */ + 3347, /* B711 (46865) */ + 3347, /* B712 (46866) */ + 3347, /* B713 (46867) */ + 3347, /* B714 (46868) */ + 3347, /* B715 (46869) */ + 3347, /* B716 (46870) */ + 3347, /* B717 (46871) */ + 3347, /* B718 (46872) */ + 3347, /* B719 (46873) */ + 3347, /* B71A (46874) */ + 3347, /* B71B (46875) */ + 3347, /* B71C (46876) */ + 3347, /* B71D (46877) */ + 3347, /* B71E (46878) */ + 3347, /* B71F (46879) */ + 3347, /* B720 (46880) */ + 3347, /* B721 (46881) */ + 3347, /* B722 (46882) */ + 3347, /* B723 (46883) */ + 3347, /* B724 (46884) */ + 3347, /* B725 (46885) */ + 3347, /* B726 (46886) */ + 3347, /* B727 (46887) */ + 3347, /* B728 (46888) */ + 3347, /* B729 (46889) */ + 3347, /* B72A (46890) */ + 3347, /* B72B (46891) */ + 3347, /* B72C (46892) */ + 3347, /* B72D (46893) */ + 3347, /* B72E (46894) */ + 3347, /* B72F (46895) */ + 3347, /* B730 (46896) */ + 3347, /* B731 (46897) */ + 3347, /* B732 (46898) */ + 3347, /* B733 (46899) */ + 3347, /* B734 (46900) */ + 3347, /* B735 (46901) */ + 3347, /* B736 (46902) */ + 3347, /* B737 (46903) */ + 3347, /* B738 (46904) */ + 3347, /* B739 (46905) */ + 3347, /* B73A (46906) */ + 3347, /* B73B (46907) */ + 3347, /* B73C (46908) */ + 3347, /* B73D (46909) */ + 3347, /* B73E (46910) */ + 3347, /* B73F (46911) */ + 3347, /* B740 (46912) */ + 3347, /* B741 (46913) */ + 3347, /* B742 (46914) */ + 3347, /* B743 (46915) */ + 3347, /* B744 (46916) */ + 3347, /* B745 (46917) */ + 3347, /* B746 (46918) */ + 3347, /* B747 (46919) */ + 3347, /* B748 (46920) */ + 3347, /* B749 (46921) */ + 3347, /* B74A (46922) */ + 3347, /* B74B (46923) */ + 3347, /* B74C (46924) */ + 3347, /* B74D (46925) */ + 3347, /* B74E (46926) */ + 3347, /* B74F (46927) */ + 3347, /* B750 (46928) */ + 3347, /* B751 (46929) */ + 3347, /* B752 (46930) */ + 3347, /* B753 (46931) */ + 3347, /* B754 (46932) */ + 3347, /* B755 (46933) */ + 3347, /* B756 (46934) */ + 3347, /* B757 (46935) */ + 3347, /* B758 (46936) */ + 3347, /* B759 (46937) */ + 3347, /* B75A (46938) */ + 3347, /* B75B (46939) */ + 3347, /* B75C (46940) */ + 3347, /* B75D (46941) */ + 3347, /* B75E (46942) */ + 3347, /* B75F (46943) */ + 3347, /* B760 (46944) */ + 3347, /* B761 (46945) */ + 3347, /* B762 (46946) */ + 3347, /* B763 (46947) */ + 3347, /* B764 (46948) */ + 3347, /* B765 (46949) */ + 3347, /* B766 (46950) */ + 3347, /* B767 (46951) */ + 3347, /* B768 (46952) */ + 3347, /* B769 (46953) */ + 3347, /* B76A (46954) */ + 3347, /* B76B (46955) */ + 3347, /* B76C (46956) */ + 3347, /* B76D (46957) */ + 3347, /* B76E (46958) */ + 3347, /* B76F (46959) */ + 3347, /* B770 (46960) */ + 3347, /* B771 (46961) */ + 3347, /* B772 (46962) */ + 3347, /* B773 (46963) */ + 3347, /* B774 (46964) */ + 3347, /* B775 (46965) */ + 3347, /* B776 (46966) */ + 3347, /* B777 (46967) */ + 3347, /* B778 (46968) */ + 3347, /* B779 (46969) */ + 3347, /* B77A (46970) */ + 3347, /* B77B (46971) */ + 3347, /* B77C (46972) */ + 3347, /* B77D (46973) */ + 3347, /* B77E (46974) */ + 3347, /* B77F (46975) */ + 3347, /* B780 (46976) */ + 3347, /* B781 (46977) */ + 3347, /* B782 (46978) */ + 3347, /* B783 (46979) */ + 3347, /* B784 (46980) */ + 3347, /* B785 (46981) */ + 3347, /* B786 (46982) */ + 3347, /* B787 (46983) */ + 3347, /* B788 (46984) */ + 3347, /* B789 (46985) */ + 3347, /* B78A (46986) */ + 3347, /* B78B (46987) */ + 3347, /* B78C (46988) */ + 3347, /* B78D (46989) */ + 3347, /* B78E (46990) */ + 3347, /* B78F (46991) */ + 3347, /* B790 (46992) */ + 3347, /* B791 (46993) */ + 3347, /* B792 (46994) */ + 3347, /* B793 (46995) */ + 3347, /* B794 (46996) */ + 3347, /* B795 (46997) */ + 3347, /* B796 (46998) */ + 3347, /* B797 (46999) */ + 3347, /* B798 (47000) */ + 3347, /* B799 (47001) */ + 3347, /* B79A (47002) */ + 3347, /* B79B (47003) */ + 3347, /* B79C (47004) */ + 3347, /* B79D (47005) */ + 3347, /* B79E (47006) */ + 3347, /* B79F (47007) */ + 3347, /* B7A0 (47008) */ + 3347, /* B7A1 (47009) */ + 3347, /* B7A2 (47010) */ + 3347, /* B7A3 (47011) */ + 3347, /* B7A4 (47012) */ + 3347, /* B7A5 (47013) */ + 3347, /* B7A6 (47014) */ + 3347, /* B7A7 (47015) */ + 3347, /* B7A8 (47016) */ + 3347, /* B7A9 (47017) */ + 3347, /* B7AA (47018) */ + 3347, /* B7AB (47019) */ + 3347, /* B7AC (47020) */ + 3347, /* B7AD (47021) */ + 3347, /* B7AE (47022) */ + 3347, /* B7AF (47023) */ + 3347, /* B7B0 (47024) */ + 3347, /* B7B1 (47025) */ + 3347, /* B7B2 (47026) */ + 3347, /* B7B3 (47027) */ + 3347, /* B7B4 (47028) */ + 3347, /* B7B5 (47029) */ + 3347, /* B7B6 (47030) */ + 3347, /* B7B7 (47031) */ + 3347, /* B7B8 (47032) */ + 3347, /* B7B9 (47033) */ + 3347, /* B7BA (47034) */ + 3347, /* B7BB (47035) */ + 3347, /* B7BC (47036) */ + 3347, /* B7BD (47037) */ + 3347, /* B7BE (47038) */ + 3347, /* B7BF (47039) */ + 3347, /* B7C0 (47040) */ + 3347, /* B7C1 (47041) */ + 3347, /* B7C2 (47042) */ + 3347, /* B7C3 (47043) */ + 3347, /* B7C4 (47044) */ + 3347, /* B7C5 (47045) */ + 3347, /* B7C6 (47046) */ + 3347, /* B7C7 (47047) */ + 3347, /* B7C8 (47048) */ + 3347, /* B7C9 (47049) */ + 3347, /* B7CA (47050) */ + 3347, /* B7CB (47051) */ + 3347, /* B7CC (47052) */ + 3347, /* B7CD (47053) */ + 3347, /* B7CE (47054) */ + 3347, /* B7CF (47055) */ + 3347, /* B7D0 (47056) */ + 3347, /* B7D1 (47057) */ + 3347, /* B7D2 (47058) */ + 3347, /* B7D3 (47059) */ + 3347, /* B7D4 (47060) */ + 3347, /* B7D5 (47061) */ + 3347, /* B7D6 (47062) */ + 3347, /* B7D7 (47063) */ + 3347, /* B7D8 (47064) */ + 3347, /* B7D9 (47065) */ + 3347, /* B7DA (47066) */ + 3347, /* B7DB (47067) */ + 3347, /* B7DC (47068) */ + 3347, /* B7DD (47069) */ + 3347, /* B7DE (47070) */ + 3347, /* B7DF (47071) */ + 3347, /* B7E0 (47072) */ + 3347, /* B7E1 (47073) */ + 3347, /* B7E2 (47074) */ + 3347, /* B7E3 (47075) */ + 3347, /* B7E4 (47076) */ + 3347, /* B7E5 (47077) */ + 3347, /* B7E6 (47078) */ + 3347, /* B7E7 (47079) */ + 3347, /* B7E8 (47080) */ + 3347, /* B7E9 (47081) */ + 3347, /* B7EA (47082) */ + 3347, /* B7EB (47083) */ + 3347, /* B7EC (47084) */ + 3347, /* B7ED (47085) */ + 3347, /* B7EE (47086) */ + 3347, /* B7EF (47087) */ + 3347, /* B7F0 (47088) */ + 3347, /* B7F1 (47089) */ + 3347, /* B7F2 (47090) */ + 3347, /* B7F3 (47091) */ + 3347, /* B7F4 (47092) */ + 3347, /* B7F5 (47093) */ + 3347, /* B7F6 (47094) */ + 3347, /* B7F7 (47095) */ + 3347, /* B7F8 (47096) */ + 3347, /* B7F9 (47097) */ + 3347, /* B7FA (47098) */ + 3347, /* B7FB (47099) */ + 3347, /* B7FC (47100) */ + 3347, /* B7FD (47101) */ + 3347, /* B7FE (47102) */ + 3347, /* B7FF (47103) */ + 3347, /* B800 (47104) */ + 3347, /* B801 (47105) */ + 3347, /* B802 (47106) */ + 3347, /* B803 (47107) */ + 3347, /* B804 (47108) */ + 3347, /* B805 (47109) */ + 3347, /* B806 (47110) */ + 3347, /* B807 (47111) */ + 3347, /* B808 (47112) */ + 3347, /* B809 (47113) */ + 3347, /* B80A (47114) */ + 3347, /* B80B (47115) */ + 3347, /* B80C (47116) */ + 3347, /* B80D (47117) */ + 3347, /* B80E (47118) */ + 3347, /* B80F (47119) */ + 3347, /* B810 (47120) */ + 3347, /* B811 (47121) */ + 3347, /* B812 (47122) */ + 3347, /* B813 (47123) */ + 3347, /* B814 (47124) */ + 3347, /* B815 (47125) */ + 3347, /* B816 (47126) */ + 3347, /* B817 (47127) */ + 3347, /* B818 (47128) */ + 3347, /* B819 (47129) */ + 3347, /* B81A (47130) */ + 3347, /* B81B (47131) */ + 3347, /* B81C (47132) */ + 3347, /* B81D (47133) */ + 3347, /* B81E (47134) */ + 3347, /* B81F (47135) */ + 3347, /* B820 (47136) */ + 3347, /* B821 (47137) */ + 3347, /* B822 (47138) */ + 3347, /* B823 (47139) */ + 3347, /* B824 (47140) */ + 3347, /* B825 (47141) */ + 3347, /* B826 (47142) */ + 3347, /* B827 (47143) */ + 3347, /* B828 (47144) */ + 3347, /* B829 (47145) */ + 3347, /* B82A (47146) */ + 3347, /* B82B (47147) */ + 3347, /* B82C (47148) */ + 3347, /* B82D (47149) */ + 3347, /* B82E (47150) */ + 3347, /* B82F (47151) */ + 3347, /* B830 (47152) */ + 3347, /* B831 (47153) */ + 3347, /* B832 (47154) */ + 3347, /* B833 (47155) */ + 3347, /* B834 (47156) */ + 3347, /* B835 (47157) */ + 3347, /* B836 (47158) */ + 3347, /* B837 (47159) */ + 3347, /* B838 (47160) */ + 3347, /* B839 (47161) */ + 3347, /* B83A (47162) */ + 3347, /* B83B (47163) */ + 3347, /* B83C (47164) */ + 3347, /* B83D (47165) */ + 3347, /* B83E (47166) */ + 3347, /* B83F (47167) */ + 3347, /* B840 (47168) */ + 3347, /* B841 (47169) */ + 3347, /* B842 (47170) */ + 3347, /* B843 (47171) */ + 3347, /* B844 (47172) */ + 3347, /* B845 (47173) */ + 3347, /* B846 (47174) */ + 3347, /* B847 (47175) */ + 3347, /* B848 (47176) */ + 3347, /* B849 (47177) */ + 3347, /* B84A (47178) */ + 3347, /* B84B (47179) */ + 3347, /* B84C (47180) */ + 3347, /* B84D (47181) */ + 3347, /* B84E (47182) */ + 3347, /* B84F (47183) */ + 3347, /* B850 (47184) */ + 3347, /* B851 (47185) */ + 3347, /* B852 (47186) */ + 3347, /* B853 (47187) */ + 3347, /* B854 (47188) */ + 3347, /* B855 (47189) */ + 3347, /* B856 (47190) */ + 3347, /* B857 (47191) */ + 3347, /* B858 (47192) */ + 3347, /* B859 (47193) */ + 3347, /* B85A (47194) */ + 3347, /* B85B (47195) */ + 3347, /* B85C (47196) */ + 3347, /* B85D (47197) */ + 3347, /* B85E (47198) */ + 3347, /* B85F (47199) */ + 3347, /* B860 (47200) */ + 3347, /* B861 (47201) */ + 3347, /* B862 (47202) */ + 3347, /* B863 (47203) */ + 3347, /* B864 (47204) */ + 3347, /* B865 (47205) */ + 3347, /* B866 (47206) */ + 3347, /* B867 (47207) */ + 3347, /* B868 (47208) */ + 3347, /* B869 (47209) */ + 3347, /* B86A (47210) */ + 3347, /* B86B (47211) */ + 3347, /* B86C (47212) */ + 3347, /* B86D (47213) */ + 3347, /* B86E (47214) */ + 3347, /* B86F (47215) */ + 3347, /* B870 (47216) */ + 3347, /* B871 (47217) */ + 3347, /* B872 (47218) */ + 3347, /* B873 (47219) */ + 3347, /* B874 (47220) */ + 3347, /* B875 (47221) */ + 3347, /* B876 (47222) */ + 3347, /* B877 (47223) */ + 3347, /* B878 (47224) */ + 3347, /* B879 (47225) */ + 3347, /* B87A (47226) */ + 3347, /* B87B (47227) */ + 3347, /* B87C (47228) */ + 3347, /* B87D (47229) */ + 3347, /* B87E (47230) */ + 3347, /* B87F (47231) */ + 3347, /* B880 (47232) */ + 3347, /* B881 (47233) */ + 3347, /* B882 (47234) */ + 3347, /* B883 (47235) */ + 3347, /* B884 (47236) */ + 3347, /* B885 (47237) */ + 3347, /* B886 (47238) */ + 3347, /* B887 (47239) */ + 3347, /* B888 (47240) */ + 3347, /* B889 (47241) */ + 3347, /* B88A (47242) */ + 3347, /* B88B (47243) */ + 3347, /* B88C (47244) */ + 3347, /* B88D (47245) */ + 3347, /* B88E (47246) */ + 3347, /* B88F (47247) */ + 3347, /* B890 (47248) */ + 3347, /* B891 (47249) */ + 3347, /* B892 (47250) */ + 3347, /* B893 (47251) */ + 3347, /* B894 (47252) */ + 3347, /* B895 (47253) */ + 3347, /* B896 (47254) */ + 3347, /* B897 (47255) */ + 3347, /* B898 (47256) */ + 3347, /* B899 (47257) */ + 3347, /* B89A (47258) */ + 3347, /* B89B (47259) */ + 3347, /* B89C (47260) */ + 3347, /* B89D (47261) */ + 3347, /* B89E (47262) */ + 3347, /* B89F (47263) */ + 3347, /* B8A0 (47264) */ + 3347, /* B8A1 (47265) */ + 3347, /* B8A2 (47266) */ + 3347, /* B8A3 (47267) */ + 3347, /* B8A4 (47268) */ + 3347, /* B8A5 (47269) */ + 3347, /* B8A6 (47270) */ + 3347, /* B8A7 (47271) */ + 3347, /* B8A8 (47272) */ + 3347, /* B8A9 (47273) */ + 3347, /* B8AA (47274) */ + 3347, /* B8AB (47275) */ + 3347, /* B8AC (47276) */ + 3347, /* B8AD (47277) */ + 3347, /* B8AE (47278) */ + 3347, /* B8AF (47279) */ + 3347, /* B8B0 (47280) */ + 3347, /* B8B1 (47281) */ + 3347, /* B8B2 (47282) */ + 3347, /* B8B3 (47283) */ + 3347, /* B8B4 (47284) */ + 3347, /* B8B5 (47285) */ + 3347, /* B8B6 (47286) */ + 3347, /* B8B7 (47287) */ + 3347, /* B8B8 (47288) */ + 3347, /* B8B9 (47289) */ + 3347, /* B8BA (47290) */ + 3347, /* B8BB (47291) */ + 3347, /* B8BC (47292) */ + 3347, /* B8BD (47293) */ + 3347, /* B8BE (47294) */ + 3347, /* B8BF (47295) */ + 3347, /* B8C0 (47296) */ + 3347, /* B8C1 (47297) */ + 3347, /* B8C2 (47298) */ + 3347, /* B8C3 (47299) */ + 3347, /* B8C4 (47300) */ + 3347, /* B8C5 (47301) */ + 3347, /* B8C6 (47302) */ + 3347, /* B8C7 (47303) */ + 3347, /* B8C8 (47304) */ + 3347, /* B8C9 (47305) */ + 3347, /* B8CA (47306) */ + 3347, /* B8CB (47307) */ + 3347, /* B8CC (47308) */ + 3347, /* B8CD (47309) */ + 3347, /* B8CE (47310) */ + 3347, /* B8CF (47311) */ + 3347, /* B8D0 (47312) */ + 3347, /* B8D1 (47313) */ + 3347, /* B8D2 (47314) */ + 3347, /* B8D3 (47315) */ + 3347, /* B8D4 (47316) */ + 3347, /* B8D5 (47317) */ + 3347, /* B8D6 (47318) */ + 3347, /* B8D7 (47319) */ + 3347, /* B8D8 (47320) */ + 3347, /* B8D9 (47321) */ + 3347, /* B8DA (47322) */ + 3347, /* B8DB (47323) */ + 3347, /* B8DC (47324) */ + 3347, /* B8DD (47325) */ + 3347, /* B8DE (47326) */ + 3347, /* B8DF (47327) */ + 3347, /* B8E0 (47328) */ + 3347, /* B8E1 (47329) */ + 3347, /* B8E2 (47330) */ + 3347, /* B8E3 (47331) */ + 3347, /* B8E4 (47332) */ + 3347, /* B8E5 (47333) */ + 3347, /* B8E6 (47334) */ + 3347, /* B8E7 (47335) */ + 3347, /* B8E8 (47336) */ + 3347, /* B8E9 (47337) */ + 3347, /* B8EA (47338) */ + 3347, /* B8EB (47339) */ + 3347, /* B8EC (47340) */ + 3347, /* B8ED (47341) */ + 3347, /* B8EE (47342) */ + 3347, /* B8EF (47343) */ + 3347, /* B8F0 (47344) */ + 3347, /* B8F1 (47345) */ + 3347, /* B8F2 (47346) */ + 3347, /* B8F3 (47347) */ + 3347, /* B8F4 (47348) */ + 3347, /* B8F5 (47349) */ + 3347, /* B8F6 (47350) */ + 3347, /* B8F7 (47351) */ + 3347, /* B8F8 (47352) */ + 3347, /* B8F9 (47353) */ + 3347, /* B8FA (47354) */ + 3347, /* B8FB (47355) */ + 3347, /* B8FC (47356) */ + 3347, /* B8FD (47357) */ + 3347, /* B8FE (47358) */ + 3347, /* B8FF (47359) */ + 3347, /* B900 (47360) */ + 3347, /* B901 (47361) */ + 3347, /* B902 (47362) */ + 3347, /* B903 (47363) */ + 3347, /* B904 (47364) */ + 3347, /* B905 (47365) */ + 3347, /* B906 (47366) */ + 3347, /* B907 (47367) */ + 3347, /* B908 (47368) */ + 3347, /* B909 (47369) */ + 3347, /* B90A (47370) */ + 3347, /* B90B (47371) */ + 3347, /* B90C (47372) */ + 3347, /* B90D (47373) */ + 3347, /* B90E (47374) */ + 3347, /* B90F (47375) */ + 3347, /* B910 (47376) */ + 3347, /* B911 (47377) */ + 3347, /* B912 (47378) */ + 3347, /* B913 (47379) */ + 3347, /* B914 (47380) */ + 3347, /* B915 (47381) */ + 3347, /* B916 (47382) */ + 3347, /* B917 (47383) */ + 3347, /* B918 (47384) */ + 3347, /* B919 (47385) */ + 3347, /* B91A (47386) */ + 3347, /* B91B (47387) */ + 3347, /* B91C (47388) */ + 3347, /* B91D (47389) */ + 3347, /* B91E (47390) */ + 3347, /* B91F (47391) */ + 3347, /* B920 (47392) */ + 3347, /* B921 (47393) */ + 3347, /* B922 (47394) */ + 3347, /* B923 (47395) */ + 3347, /* B924 (47396) */ + 3347, /* B925 (47397) */ + 3347, /* B926 (47398) */ + 3347, /* B927 (47399) */ + 3347, /* B928 (47400) */ + 3347, /* B929 (47401) */ + 3347, /* B92A (47402) */ + 3347, /* B92B (47403) */ + 3347, /* B92C (47404) */ + 3347, /* B92D (47405) */ + 3347, /* B92E (47406) */ + 3347, /* B92F (47407) */ + 3347, /* B930 (47408) */ + 3347, /* B931 (47409) */ + 3347, /* B932 (47410) */ + 3347, /* B933 (47411) */ + 3347, /* B934 (47412) */ + 3347, /* B935 (47413) */ + 3347, /* B936 (47414) */ + 3347, /* B937 (47415) */ + 3347, /* B938 (47416) */ + 3347, /* B939 (47417) */ + 3347, /* B93A (47418) */ + 3347, /* B93B (47419) */ + 3347, /* B93C (47420) */ + 3347, /* B93D (47421) */ + 3347, /* B93E (47422) */ + 3347, /* B93F (47423) */ + 3347, /* B940 (47424) */ + 3347, /* B941 (47425) */ + 3347, /* B942 (47426) */ + 3347, /* B943 (47427) */ + 3347, /* B944 (47428) */ + 3347, /* B945 (47429) */ + 3347, /* B946 (47430) */ + 3347, /* B947 (47431) */ + 3347, /* B948 (47432) */ + 3347, /* B949 (47433) */ + 3347, /* B94A (47434) */ + 3347, /* B94B (47435) */ + 3347, /* B94C (47436) */ + 3347, /* B94D (47437) */ + 3347, /* B94E (47438) */ + 3347, /* B94F (47439) */ + 3347, /* B950 (47440) */ + 3347, /* B951 (47441) */ + 3347, /* B952 (47442) */ + 3347, /* B953 (47443) */ + 3347, /* B954 (47444) */ + 3347, /* B955 (47445) */ + 3347, /* B956 (47446) */ + 3347, /* B957 (47447) */ + 3347, /* B958 (47448) */ + 3347, /* B959 (47449) */ + 3347, /* B95A (47450) */ + 3347, /* B95B (47451) */ + 3347, /* B95C (47452) */ + 3347, /* B95D (47453) */ + 3347, /* B95E (47454) */ + 3347, /* B95F (47455) */ + 3347, /* B960 (47456) */ + 3347, /* B961 (47457) */ + 3347, /* B962 (47458) */ + 3347, /* B963 (47459) */ + 3347, /* B964 (47460) */ + 3347, /* B965 (47461) */ + 3347, /* B966 (47462) */ + 3347, /* B967 (47463) */ + 3347, /* B968 (47464) */ + 3347, /* B969 (47465) */ + 3347, /* B96A (47466) */ + 3347, /* B96B (47467) */ + 3347, /* B96C (47468) */ + 3347, /* B96D (47469) */ + 3347, /* B96E (47470) */ + 3347, /* B96F (47471) */ + 3347, /* B970 (47472) */ + 3347, /* B971 (47473) */ + 3347, /* B972 (47474) */ + 3347, /* B973 (47475) */ + 3347, /* B974 (47476) */ + 3347, /* B975 (47477) */ + 3347, /* B976 (47478) */ + 3347, /* B977 (47479) */ + 3347, /* B978 (47480) */ + 3347, /* B979 (47481) */ + 3347, /* B97A (47482) */ + 3347, /* B97B (47483) */ + 3347, /* B97C (47484) */ + 3347, /* B97D (47485) */ + 3347, /* B97E (47486) */ + 3347, /* B97F (47487) */ + 3347, /* B980 (47488) */ + 3347, /* B981 (47489) */ + 3347, /* B982 (47490) */ + 3347, /* B983 (47491) */ + 3347, /* B984 (47492) */ + 3347, /* B985 (47493) */ + 3347, /* B986 (47494) */ + 3347, /* B987 (47495) */ + 3347, /* B988 (47496) */ + 3347, /* B989 (47497) */ + 3347, /* B98A (47498) */ + 3347, /* B98B (47499) */ + 3347, /* B98C (47500) */ + 3347, /* B98D (47501) */ + 3347, /* B98E (47502) */ + 3347, /* B98F (47503) */ + 3347, /* B990 (47504) */ + 3347, /* B991 (47505) */ + 3347, /* B992 (47506) */ + 3347, /* B993 (47507) */ + 3347, /* B994 (47508) */ + 3347, /* B995 (47509) */ + 3347, /* B996 (47510) */ + 3347, /* B997 (47511) */ + 3347, /* B998 (47512) */ + 3347, /* B999 (47513) */ + 3347, /* B99A (47514) */ + 3347, /* B99B (47515) */ + 3347, /* B99C (47516) */ + 3347, /* B99D (47517) */ + 3347, /* B99E (47518) */ + 3347, /* B99F (47519) */ + 3347, /* B9A0 (47520) */ + 3347, /* B9A1 (47521) */ + 3347, /* B9A2 (47522) */ + 3347, /* B9A3 (47523) */ + 3347, /* B9A4 (47524) */ + 3347, /* B9A5 (47525) */ + 3347, /* B9A6 (47526) */ + 3347, /* B9A7 (47527) */ + 3347, /* B9A8 (47528) */ + 3347, /* B9A9 (47529) */ + 3347, /* B9AA (47530) */ + 3347, /* B9AB (47531) */ + 3347, /* B9AC (47532) */ + 3347, /* B9AD (47533) */ + 3347, /* B9AE (47534) */ + 3347, /* B9AF (47535) */ + 3347, /* B9B0 (47536) */ + 3347, /* B9B1 (47537) */ + 3347, /* B9B2 (47538) */ + 3347, /* B9B3 (47539) */ + 3347, /* B9B4 (47540) */ + 3347, /* B9B5 (47541) */ + 3347, /* B9B6 (47542) */ + 3347, /* B9B7 (47543) */ + 3347, /* B9B8 (47544) */ + 3347, /* B9B9 (47545) */ + 3347, /* B9BA (47546) */ + 3347, /* B9BB (47547) */ + 3347, /* B9BC (47548) */ + 3347, /* B9BD (47549) */ + 3347, /* B9BE (47550) */ + 3347, /* B9BF (47551) */ + 3347, /* B9C0 (47552) */ + 3347, /* B9C1 (47553) */ + 3347, /* B9C2 (47554) */ + 3347, /* B9C3 (47555) */ + 3347, /* B9C4 (47556) */ + 3347, /* B9C5 (47557) */ + 3347, /* B9C6 (47558) */ + 3347, /* B9C7 (47559) */ + 3347, /* B9C8 (47560) */ + 3347, /* B9C9 (47561) */ + 3347, /* B9CA (47562) */ + 3347, /* B9CB (47563) */ + 3347, /* B9CC (47564) */ + 3347, /* B9CD (47565) */ + 3347, /* B9CE (47566) */ + 3347, /* B9CF (47567) */ + 3347, /* B9D0 (47568) */ + 3347, /* B9D1 (47569) */ + 3347, /* B9D2 (47570) */ + 3347, /* B9D3 (47571) */ + 3347, /* B9D4 (47572) */ + 3347, /* B9D5 (47573) */ + 3347, /* B9D6 (47574) */ + 3347, /* B9D7 (47575) */ + 3347, /* B9D8 (47576) */ + 3347, /* B9D9 (47577) */ + 3347, /* B9DA (47578) */ + 3347, /* B9DB (47579) */ + 3347, /* B9DC (47580) */ + 3347, /* B9DD (47581) */ + 3347, /* B9DE (47582) */ + 3347, /* B9DF (47583) */ + 3347, /* B9E0 (47584) */ + 3347, /* B9E1 (47585) */ + 3347, /* B9E2 (47586) */ + 3347, /* B9E3 (47587) */ + 3347, /* B9E4 (47588) */ + 3347, /* B9E5 (47589) */ + 3347, /* B9E6 (47590) */ + 3347, /* B9E7 (47591) */ + 3347, /* B9E8 (47592) */ + 3347, /* B9E9 (47593) */ + 3347, /* B9EA (47594) */ + 3347, /* B9EB (47595) */ + 3347, /* B9EC (47596) */ + 3347, /* B9ED (47597) */ + 3347, /* B9EE (47598) */ + 3347, /* B9EF (47599) */ + 3347, /* B9F0 (47600) */ + 3347, /* B9F1 (47601) */ + 3347, /* B9F2 (47602) */ + 3347, /* B9F3 (47603) */ + 3347, /* B9F4 (47604) */ + 3347, /* B9F5 (47605) */ + 3347, /* B9F6 (47606) */ + 3347, /* B9F7 (47607) */ + 3347, /* B9F8 (47608) */ + 3347, /* B9F9 (47609) */ + 3347, /* B9FA (47610) */ + 3347, /* B9FB (47611) */ + 3347, /* B9FC (47612) */ + 3347, /* B9FD (47613) */ + 3347, /* B9FE (47614) */ + 3347, /* B9FF (47615) */ + 3347, /* BA00 (47616) */ + 3347, /* BA01 (47617) */ + 3347, /* BA02 (47618) */ + 3347, /* BA03 (47619) */ + 3347, /* BA04 (47620) */ + 3347, /* BA05 (47621) */ + 3347, /* BA06 (47622) */ + 3347, /* BA07 (47623) */ + 3347, /* BA08 (47624) */ + 3347, /* BA09 (47625) */ + 3347, /* BA0A (47626) */ + 3347, /* BA0B (47627) */ + 3347, /* BA0C (47628) */ + 3347, /* BA0D (47629) */ + 3347, /* BA0E (47630) */ + 3347, /* BA0F (47631) */ + 3347, /* BA10 (47632) */ + 3347, /* BA11 (47633) */ + 3347, /* BA12 (47634) */ + 3347, /* BA13 (47635) */ + 3347, /* BA14 (47636) */ + 3347, /* BA15 (47637) */ + 3347, /* BA16 (47638) */ + 3347, /* BA17 (47639) */ + 3347, /* BA18 (47640) */ + 3347, /* BA19 (47641) */ + 3347, /* BA1A (47642) */ + 3347, /* BA1B (47643) */ + 3347, /* BA1C (47644) */ + 3347, /* BA1D (47645) */ + 3347, /* BA1E (47646) */ + 3347, /* BA1F (47647) */ + 3347, /* BA20 (47648) */ + 3347, /* BA21 (47649) */ + 3347, /* BA22 (47650) */ + 3347, /* BA23 (47651) */ + 3347, /* BA24 (47652) */ + 3347, /* BA25 (47653) */ + 3347, /* BA26 (47654) */ + 3347, /* BA27 (47655) */ + 3347, /* BA28 (47656) */ + 3347, /* BA29 (47657) */ + 3347, /* BA2A (47658) */ + 3347, /* BA2B (47659) */ + 3347, /* BA2C (47660) */ + 3347, /* BA2D (47661) */ + 3347, /* BA2E (47662) */ + 3347, /* BA2F (47663) */ + 3347, /* BA30 (47664) */ + 3347, /* BA31 (47665) */ + 3347, /* BA32 (47666) */ + 3347, /* BA33 (47667) */ + 3347, /* BA34 (47668) */ + 3347, /* BA35 (47669) */ + 3347, /* BA36 (47670) */ + 3347, /* BA37 (47671) */ + 3347, /* BA38 (47672) */ + 3347, /* BA39 (47673) */ + 3347, /* BA3A (47674) */ + 3347, /* BA3B (47675) */ + 3347, /* BA3C (47676) */ + 3347, /* BA3D (47677) */ + 3347, /* BA3E (47678) */ + 3347, /* BA3F (47679) */ + 3347, /* BA40 (47680) */ + 3347, /* BA41 (47681) */ + 3347, /* BA42 (47682) */ + 3347, /* BA43 (47683) */ + 3347, /* BA44 (47684) */ + 3347, /* BA45 (47685) */ + 3347, /* BA46 (47686) */ + 3347, /* BA47 (47687) */ + 3347, /* BA48 (47688) */ + 3347, /* BA49 (47689) */ + 3347, /* BA4A (47690) */ + 3347, /* BA4B (47691) */ + 3347, /* BA4C (47692) */ + 3347, /* BA4D (47693) */ + 3347, /* BA4E (47694) */ + 3347, /* BA4F (47695) */ + 3347, /* BA50 (47696) */ + 3347, /* BA51 (47697) */ + 3347, /* BA52 (47698) */ + 3347, /* BA53 (47699) */ + 3347, /* BA54 (47700) */ + 3347, /* BA55 (47701) */ + 3347, /* BA56 (47702) */ + 3347, /* BA57 (47703) */ + 3347, /* BA58 (47704) */ + 3347, /* BA59 (47705) */ + 3347, /* BA5A (47706) */ + 3347, /* BA5B (47707) */ + 3347, /* BA5C (47708) */ + 3347, /* BA5D (47709) */ + 3347, /* BA5E (47710) */ + 3347, /* BA5F (47711) */ + 3347, /* BA60 (47712) */ + 3347, /* BA61 (47713) */ + 3347, /* BA62 (47714) */ + 3347, /* BA63 (47715) */ + 3347, /* BA64 (47716) */ + 3347, /* BA65 (47717) */ + 3347, /* BA66 (47718) */ + 3347, /* BA67 (47719) */ + 3347, /* BA68 (47720) */ + 3347, /* BA69 (47721) */ + 3347, /* BA6A (47722) */ + 3347, /* BA6B (47723) */ + 3347, /* BA6C (47724) */ + 3347, /* BA6D (47725) */ + 3347, /* BA6E (47726) */ + 3347, /* BA6F (47727) */ + 3347, /* BA70 (47728) */ + 3347, /* BA71 (47729) */ + 3347, /* BA72 (47730) */ + 3347, /* BA73 (47731) */ + 3347, /* BA74 (47732) */ + 3347, /* BA75 (47733) */ + 3347, /* BA76 (47734) */ + 3347, /* BA77 (47735) */ + 3347, /* BA78 (47736) */ + 3347, /* BA79 (47737) */ + 3347, /* BA7A (47738) */ + 3347, /* BA7B (47739) */ + 3347, /* BA7C (47740) */ + 3347, /* BA7D (47741) */ + 3347, /* BA7E (47742) */ + 3347, /* BA7F (47743) */ + 3347, /* BA80 (47744) */ + 3347, /* BA81 (47745) */ + 3347, /* BA82 (47746) */ + 3347, /* BA83 (47747) */ + 3347, /* BA84 (47748) */ + 3347, /* BA85 (47749) */ + 3347, /* BA86 (47750) */ + 3347, /* BA87 (47751) */ + 3347, /* BA88 (47752) */ + 3347, /* BA89 (47753) */ + 3347, /* BA8A (47754) */ + 3347, /* BA8B (47755) */ + 3347, /* BA8C (47756) */ + 3347, /* BA8D (47757) */ + 3347, /* BA8E (47758) */ + 3347, /* BA8F (47759) */ + 3347, /* BA90 (47760) */ + 3347, /* BA91 (47761) */ + 3347, /* BA92 (47762) */ + 3347, /* BA93 (47763) */ + 3347, /* BA94 (47764) */ + 3347, /* BA95 (47765) */ + 3347, /* BA96 (47766) */ + 3347, /* BA97 (47767) */ + 3347, /* BA98 (47768) */ + 3347, /* BA99 (47769) */ + 3347, /* BA9A (47770) */ + 3347, /* BA9B (47771) */ + 3347, /* BA9C (47772) */ + 3347, /* BA9D (47773) */ + 3347, /* BA9E (47774) */ + 3347, /* BA9F (47775) */ + 3347, /* BAA0 (47776) */ + 3347, /* BAA1 (47777) */ + 3347, /* BAA2 (47778) */ + 3347, /* BAA3 (47779) */ + 3347, /* BAA4 (47780) */ + 3347, /* BAA5 (47781) */ + 3347, /* BAA6 (47782) */ + 3347, /* BAA7 (47783) */ + 3347, /* BAA8 (47784) */ + 3347, /* BAA9 (47785) */ + 3347, /* BAAA (47786) */ + 3347, /* BAAB (47787) */ + 3347, /* BAAC (47788) */ + 3347, /* BAAD (47789) */ + 3347, /* BAAE (47790) */ + 3347, /* BAAF (47791) */ + 3347, /* BAB0 (47792) */ + 3347, /* BAB1 (47793) */ + 3347, /* BAB2 (47794) */ + 3347, /* BAB3 (47795) */ + 3347, /* BAB4 (47796) */ + 3347, /* BAB5 (47797) */ + 3347, /* BAB6 (47798) */ + 3347, /* BAB7 (47799) */ + 3347, /* BAB8 (47800) */ + 3347, /* BAB9 (47801) */ + 3347, /* BABA (47802) */ + 3347, /* BABB (47803) */ + 3347, /* BABC (47804) */ + 3347, /* BABD (47805) */ + 3347, /* BABE (47806) */ + 3347, /* BABF (47807) */ + 3347, /* BAC0 (47808) */ + 3347, /* BAC1 (47809) */ + 3347, /* BAC2 (47810) */ + 3347, /* BAC3 (47811) */ + 3347, /* BAC4 (47812) */ + 3347, /* BAC5 (47813) */ + 3347, /* BAC6 (47814) */ + 3347, /* BAC7 (47815) */ + 3347, /* BAC8 (47816) */ + 3347, /* BAC9 (47817) */ + 3347, /* BACA (47818) */ + 3347, /* BACB (47819) */ + 3347, /* BACC (47820) */ + 3347, /* BACD (47821) */ + 3347, /* BACE (47822) */ + 3347, /* BACF (47823) */ + 3347, /* BAD0 (47824) */ + 3347, /* BAD1 (47825) */ + 3347, /* BAD2 (47826) */ + 3347, /* BAD3 (47827) */ + 3347, /* BAD4 (47828) */ + 3347, /* BAD5 (47829) */ + 3347, /* BAD6 (47830) */ + 3347, /* BAD7 (47831) */ + 3347, /* BAD8 (47832) */ + 3347, /* BAD9 (47833) */ + 3347, /* BADA (47834) */ + 3347, /* BADB (47835) */ + 3347, /* BADC (47836) */ + 3347, /* BADD (47837) */ + 3347, /* BADE (47838) */ + 3347, /* BADF (47839) */ + 3347, /* BAE0 (47840) */ + 3347, /* BAE1 (47841) */ + 3347, /* BAE2 (47842) */ + 3347, /* BAE3 (47843) */ + 3347, /* BAE4 (47844) */ + 3347, /* BAE5 (47845) */ + 3347, /* BAE6 (47846) */ + 3347, /* BAE7 (47847) */ + 3347, /* BAE8 (47848) */ + 3347, /* BAE9 (47849) */ + 3347, /* BAEA (47850) */ + 3347, /* BAEB (47851) */ + 3347, /* BAEC (47852) */ + 3347, /* BAED (47853) */ + 3347, /* BAEE (47854) */ + 3347, /* BAEF (47855) */ + 3347, /* BAF0 (47856) */ + 3347, /* BAF1 (47857) */ + 3347, /* BAF2 (47858) */ + 3347, /* BAF3 (47859) */ + 3347, /* BAF4 (47860) */ + 3347, /* BAF5 (47861) */ + 3347, /* BAF6 (47862) */ + 3347, /* BAF7 (47863) */ + 3347, /* BAF8 (47864) */ + 3347, /* BAF9 (47865) */ + 3347, /* BAFA (47866) */ + 3347, /* BAFB (47867) */ + 3347, /* BAFC (47868) */ + 3347, /* BAFD (47869) */ + 3347, /* BAFE (47870) */ + 3347, /* BAFF (47871) */ + 3347, /* BB00 (47872) */ + 3347, /* BB01 (47873) */ + 3347, /* BB02 (47874) */ + 3347, /* BB03 (47875) */ + 3347, /* BB04 (47876) */ + 3347, /* BB05 (47877) */ + 3347, /* BB06 (47878) */ + 3347, /* BB07 (47879) */ + 3347, /* BB08 (47880) */ + 3347, /* BB09 (47881) */ + 3347, /* BB0A (47882) */ + 3347, /* BB0B (47883) */ + 3347, /* BB0C (47884) */ + 3347, /* BB0D (47885) */ + 3347, /* BB0E (47886) */ + 3347, /* BB0F (47887) */ + 3347, /* BB10 (47888) */ + 3347, /* BB11 (47889) */ + 3347, /* BB12 (47890) */ + 3347, /* BB13 (47891) */ + 3347, /* BB14 (47892) */ + 3347, /* BB15 (47893) */ + 3347, /* BB16 (47894) */ + 3347, /* BB17 (47895) */ + 3347, /* BB18 (47896) */ + 3347, /* BB19 (47897) */ + 3347, /* BB1A (47898) */ + 3347, /* BB1B (47899) */ + 3347, /* BB1C (47900) */ + 3347, /* BB1D (47901) */ + 3347, /* BB1E (47902) */ + 3347, /* BB1F (47903) */ + 3347, /* BB20 (47904) */ + 3347, /* BB21 (47905) */ + 3347, /* BB22 (47906) */ + 3347, /* BB23 (47907) */ + 3347, /* BB24 (47908) */ + 3347, /* BB25 (47909) */ + 3347, /* BB26 (47910) */ + 3347, /* BB27 (47911) */ + 3347, /* BB28 (47912) */ + 3347, /* BB29 (47913) */ + 3347, /* BB2A (47914) */ + 3347, /* BB2B (47915) */ + 3347, /* BB2C (47916) */ + 3347, /* BB2D (47917) */ + 3347, /* BB2E (47918) */ + 3347, /* BB2F (47919) */ + 3347, /* BB30 (47920) */ + 3347, /* BB31 (47921) */ + 3347, /* BB32 (47922) */ + 3347, /* BB33 (47923) */ + 3347, /* BB34 (47924) */ + 3347, /* BB35 (47925) */ + 3347, /* BB36 (47926) */ + 3347, /* BB37 (47927) */ + 3347, /* BB38 (47928) */ + 3347, /* BB39 (47929) */ + 3347, /* BB3A (47930) */ + 3347, /* BB3B (47931) */ + 3347, /* BB3C (47932) */ + 3347, /* BB3D (47933) */ + 3347, /* BB3E (47934) */ + 3347, /* BB3F (47935) */ + 3347, /* BB40 (47936) */ + 3347, /* BB41 (47937) */ + 3347, /* BB42 (47938) */ + 3347, /* BB43 (47939) */ + 3347, /* BB44 (47940) */ + 3347, /* BB45 (47941) */ + 3347, /* BB46 (47942) */ + 3347, /* BB47 (47943) */ + 3347, /* BB48 (47944) */ + 3347, /* BB49 (47945) */ + 3347, /* BB4A (47946) */ + 3347, /* BB4B (47947) */ + 3347, /* BB4C (47948) */ + 3347, /* BB4D (47949) */ + 3347, /* BB4E (47950) */ + 3347, /* BB4F (47951) */ + 3347, /* BB50 (47952) */ + 3347, /* BB51 (47953) */ + 3347, /* BB52 (47954) */ + 3347, /* BB53 (47955) */ + 3347, /* BB54 (47956) */ + 3347, /* BB55 (47957) */ + 3347, /* BB56 (47958) */ + 3347, /* BB57 (47959) */ + 3347, /* BB58 (47960) */ + 3347, /* BB59 (47961) */ + 3347, /* BB5A (47962) */ + 3347, /* BB5B (47963) */ + 3347, /* BB5C (47964) */ + 3347, /* BB5D (47965) */ + 3347, /* BB5E (47966) */ + 3347, /* BB5F (47967) */ + 3347, /* BB60 (47968) */ + 3347, /* BB61 (47969) */ + 3347, /* BB62 (47970) */ + 3347, /* BB63 (47971) */ + 3347, /* BB64 (47972) */ + 3347, /* BB65 (47973) */ + 3347, /* BB66 (47974) */ + 3347, /* BB67 (47975) */ + 3347, /* BB68 (47976) */ + 3347, /* BB69 (47977) */ + 3347, /* BB6A (47978) */ + 3347, /* BB6B (47979) */ + 3347, /* BB6C (47980) */ + 3347, /* BB6D (47981) */ + 3347, /* BB6E (47982) */ + 3347, /* BB6F (47983) */ + 3347, /* BB70 (47984) */ + 3347, /* BB71 (47985) */ + 3347, /* BB72 (47986) */ + 3347, /* BB73 (47987) */ + 3347, /* BB74 (47988) */ + 3347, /* BB75 (47989) */ + 3347, /* BB76 (47990) */ + 3347, /* BB77 (47991) */ + 3347, /* BB78 (47992) */ + 3347, /* BB79 (47993) */ + 3347, /* BB7A (47994) */ + 3347, /* BB7B (47995) */ + 3347, /* BB7C (47996) */ + 3347, /* BB7D (47997) */ + 3347, /* BB7E (47998) */ + 3347, /* BB7F (47999) */ + 3347, /* BB80 (48000) */ + 3347, /* BB81 (48001) */ + 3347, /* BB82 (48002) */ + 3347, /* BB83 (48003) */ + 3347, /* BB84 (48004) */ + 3347, /* BB85 (48005) */ + 3347, /* BB86 (48006) */ + 3347, /* BB87 (48007) */ + 3347, /* BB88 (48008) */ + 3347, /* BB89 (48009) */ + 3347, /* BB8A (48010) */ + 3347, /* BB8B (48011) */ + 3347, /* BB8C (48012) */ + 3347, /* BB8D (48013) */ + 3347, /* BB8E (48014) */ + 3347, /* BB8F (48015) */ + 3347, /* BB90 (48016) */ + 3347, /* BB91 (48017) */ + 3347, /* BB92 (48018) */ + 3347, /* BB93 (48019) */ + 3347, /* BB94 (48020) */ + 3347, /* BB95 (48021) */ + 3347, /* BB96 (48022) */ + 3347, /* BB97 (48023) */ + 3347, /* BB98 (48024) */ + 3347, /* BB99 (48025) */ + 3347, /* BB9A (48026) */ + 3347, /* BB9B (48027) */ + 3347, /* BB9C (48028) */ + 3347, /* BB9D (48029) */ + 3347, /* BB9E (48030) */ + 3347, /* BB9F (48031) */ + 3347, /* BBA0 (48032) */ + 3347, /* BBA1 (48033) */ + 3347, /* BBA2 (48034) */ + 3347, /* BBA3 (48035) */ + 3347, /* BBA4 (48036) */ + 3347, /* BBA5 (48037) */ + 3347, /* BBA6 (48038) */ + 3347, /* BBA7 (48039) */ + 3347, /* BBA8 (48040) */ + 3347, /* BBA9 (48041) */ + 3347, /* BBAA (48042) */ + 3347, /* BBAB (48043) */ + 3347, /* BBAC (48044) */ + 3347, /* BBAD (48045) */ + 3347, /* BBAE (48046) */ + 3347, /* BBAF (48047) */ + 3347, /* BBB0 (48048) */ + 3347, /* BBB1 (48049) */ + 3347, /* BBB2 (48050) */ + 3347, /* BBB3 (48051) */ + 3347, /* BBB4 (48052) */ + 3347, /* BBB5 (48053) */ + 3347, /* BBB6 (48054) */ + 3347, /* BBB7 (48055) */ + 3347, /* BBB8 (48056) */ + 3347, /* BBB9 (48057) */ + 3347, /* BBBA (48058) */ + 3347, /* BBBB (48059) */ + 3347, /* BBBC (48060) */ + 3347, /* BBBD (48061) */ + 3347, /* BBBE (48062) */ + 3347, /* BBBF (48063) */ + 3347, /* BBC0 (48064) */ + 3347, /* BBC1 (48065) */ + 3347, /* BBC2 (48066) */ + 3347, /* BBC3 (48067) */ + 3347, /* BBC4 (48068) */ + 3347, /* BBC5 (48069) */ + 3347, /* BBC6 (48070) */ + 3347, /* BBC7 (48071) */ + 3347, /* BBC8 (48072) */ + 3347, /* BBC9 (48073) */ + 3347, /* BBCA (48074) */ + 3347, /* BBCB (48075) */ + 3347, /* BBCC (48076) */ + 3347, /* BBCD (48077) */ + 3347, /* BBCE (48078) */ + 3347, /* BBCF (48079) */ + 3347, /* BBD0 (48080) */ + 3347, /* BBD1 (48081) */ + 3347, /* BBD2 (48082) */ + 3347, /* BBD3 (48083) */ + 3347, /* BBD4 (48084) */ + 3347, /* BBD5 (48085) */ + 3347, /* BBD6 (48086) */ + 3347, /* BBD7 (48087) */ + 3347, /* BBD8 (48088) */ + 3347, /* BBD9 (48089) */ + 3347, /* BBDA (48090) */ + 3347, /* BBDB (48091) */ + 3347, /* BBDC (48092) */ + 3347, /* BBDD (48093) */ + 3347, /* BBDE (48094) */ + 3347, /* BBDF (48095) */ + 3347, /* BBE0 (48096) */ + 3347, /* BBE1 (48097) */ + 3347, /* BBE2 (48098) */ + 3347, /* BBE3 (48099) */ + 3347, /* BBE4 (48100) */ + 3347, /* BBE5 (48101) */ + 3347, /* BBE6 (48102) */ + 3347, /* BBE7 (48103) */ + 3347, /* BBE8 (48104) */ + 3347, /* BBE9 (48105) */ + 3347, /* BBEA (48106) */ + 3347, /* BBEB (48107) */ + 3347, /* BBEC (48108) */ + 3347, /* BBED (48109) */ + 3347, /* BBEE (48110) */ + 3347, /* BBEF (48111) */ + 3347, /* BBF0 (48112) */ + 3347, /* BBF1 (48113) */ + 3347, /* BBF2 (48114) */ + 3347, /* BBF3 (48115) */ + 3347, /* BBF4 (48116) */ + 3347, /* BBF5 (48117) */ + 3347, /* BBF6 (48118) */ + 3347, /* BBF7 (48119) */ + 3347, /* BBF8 (48120) */ + 3347, /* BBF9 (48121) */ + 3347, /* BBFA (48122) */ + 3347, /* BBFB (48123) */ + 3347, /* BBFC (48124) */ + 3347, /* BBFD (48125) */ + 3347, /* BBFE (48126) */ + 3347, /* BBFF (48127) */ + 3347, /* BC00 (48128) */ + 3347, /* BC01 (48129) */ + 3347, /* BC02 (48130) */ + 3347, /* BC03 (48131) */ + 3347, /* BC04 (48132) */ + 3347, /* BC05 (48133) */ + 3347, /* BC06 (48134) */ + 3347, /* BC07 (48135) */ + 3347, /* BC08 (48136) */ + 3347, /* BC09 (48137) */ + 3347, /* BC0A (48138) */ + 3347, /* BC0B (48139) */ + 3347, /* BC0C (48140) */ + 3347, /* BC0D (48141) */ + 3347, /* BC0E (48142) */ + 3347, /* BC0F (48143) */ + 3347, /* BC10 (48144) */ + 3347, /* BC11 (48145) */ + 3347, /* BC12 (48146) */ + 3347, /* BC13 (48147) */ + 3347, /* BC14 (48148) */ + 3347, /* BC15 (48149) */ + 3347, /* BC16 (48150) */ + 3347, /* BC17 (48151) */ + 3347, /* BC18 (48152) */ + 3347, /* BC19 (48153) */ + 3347, /* BC1A (48154) */ + 3347, /* BC1B (48155) */ + 3347, /* BC1C (48156) */ + 3347, /* BC1D (48157) */ + 3347, /* BC1E (48158) */ + 3347, /* BC1F (48159) */ + 3347, /* BC20 (48160) */ + 3347, /* BC21 (48161) */ + 3347, /* BC22 (48162) */ + 3347, /* BC23 (48163) */ + 3347, /* BC24 (48164) */ + 3347, /* BC25 (48165) */ + 3347, /* BC26 (48166) */ + 3347, /* BC27 (48167) */ + 3347, /* BC28 (48168) */ + 3347, /* BC29 (48169) */ + 3347, /* BC2A (48170) */ + 3347, /* BC2B (48171) */ + 3347, /* BC2C (48172) */ + 3347, /* BC2D (48173) */ + 3347, /* BC2E (48174) */ + 3347, /* BC2F (48175) */ + 3347, /* BC30 (48176) */ + 3347, /* BC31 (48177) */ + 3347, /* BC32 (48178) */ + 3347, /* BC33 (48179) */ + 3347, /* BC34 (48180) */ + 3347, /* BC35 (48181) */ + 3347, /* BC36 (48182) */ + 3347, /* BC37 (48183) */ + 3347, /* BC38 (48184) */ + 3347, /* BC39 (48185) */ + 3347, /* BC3A (48186) */ + 3347, /* BC3B (48187) */ + 3347, /* BC3C (48188) */ + 3347, /* BC3D (48189) */ + 3347, /* BC3E (48190) */ + 3347, /* BC3F (48191) */ + 3347, /* BC40 (48192) */ + 3347, /* BC41 (48193) */ + 3347, /* BC42 (48194) */ + 3347, /* BC43 (48195) */ + 3347, /* BC44 (48196) */ + 3347, /* BC45 (48197) */ + 3347, /* BC46 (48198) */ + 3347, /* BC47 (48199) */ + 3347, /* BC48 (48200) */ + 3347, /* BC49 (48201) */ + 3347, /* BC4A (48202) */ + 3347, /* BC4B (48203) */ + 3347, /* BC4C (48204) */ + 3347, /* BC4D (48205) */ + 3347, /* BC4E (48206) */ + 3347, /* BC4F (48207) */ + 3347, /* BC50 (48208) */ + 3347, /* BC51 (48209) */ + 3347, /* BC52 (48210) */ + 3347, /* BC53 (48211) */ + 3347, /* BC54 (48212) */ + 3347, /* BC55 (48213) */ + 3347, /* BC56 (48214) */ + 3347, /* BC57 (48215) */ + 3347, /* BC58 (48216) */ + 3347, /* BC59 (48217) */ + 3347, /* BC5A (48218) */ + 3347, /* BC5B (48219) */ + 3347, /* BC5C (48220) */ + 3347, /* BC5D (48221) */ + 3347, /* BC5E (48222) */ + 3347, /* BC5F (48223) */ + 3347, /* BC60 (48224) */ + 3347, /* BC61 (48225) */ + 3347, /* BC62 (48226) */ + 3347, /* BC63 (48227) */ + 3347, /* BC64 (48228) */ + 3347, /* BC65 (48229) */ + 3347, /* BC66 (48230) */ + 3347, /* BC67 (48231) */ + 3347, /* BC68 (48232) */ + 3347, /* BC69 (48233) */ + 3347, /* BC6A (48234) */ + 3347, /* BC6B (48235) */ + 3347, /* BC6C (48236) */ + 3347, /* BC6D (48237) */ + 3347, /* BC6E (48238) */ + 3347, /* BC6F (48239) */ + 3347, /* BC70 (48240) */ + 3347, /* BC71 (48241) */ + 3347, /* BC72 (48242) */ + 3347, /* BC73 (48243) */ + 3347, /* BC74 (48244) */ + 3347, /* BC75 (48245) */ + 3347, /* BC76 (48246) */ + 3347, /* BC77 (48247) */ + 3347, /* BC78 (48248) */ + 3347, /* BC79 (48249) */ + 3347, /* BC7A (48250) */ + 3347, /* BC7B (48251) */ + 3347, /* BC7C (48252) */ + 3347, /* BC7D (48253) */ + 3347, /* BC7E (48254) */ + 3347, /* BC7F (48255) */ + 3347, /* BC80 (48256) */ + 3347, /* BC81 (48257) */ + 3347, /* BC82 (48258) */ + 3347, /* BC83 (48259) */ + 3347, /* BC84 (48260) */ + 3347, /* BC85 (48261) */ + 3347, /* BC86 (48262) */ + 3347, /* BC87 (48263) */ + 3347, /* BC88 (48264) */ + 3347, /* BC89 (48265) */ + 3347, /* BC8A (48266) */ + 3347, /* BC8B (48267) */ + 3347, /* BC8C (48268) */ + 3347, /* BC8D (48269) */ + 3347, /* BC8E (48270) */ + 3347, /* BC8F (48271) */ + 3347, /* BC90 (48272) */ + 3347, /* BC91 (48273) */ + 3347, /* BC92 (48274) */ + 3347, /* BC93 (48275) */ + 3347, /* BC94 (48276) */ + 3347, /* BC95 (48277) */ + 3347, /* BC96 (48278) */ + 3347, /* BC97 (48279) */ + 3347, /* BC98 (48280) */ + 3347, /* BC99 (48281) */ + 3347, /* BC9A (48282) */ + 3347, /* BC9B (48283) */ + 3347, /* BC9C (48284) */ + 3347, /* BC9D (48285) */ + 3347, /* BC9E (48286) */ + 3347, /* BC9F (48287) */ + 3347, /* BCA0 (48288) */ + 3347, /* BCA1 (48289) */ + 3347, /* BCA2 (48290) */ + 3347, /* BCA3 (48291) */ + 3347, /* BCA4 (48292) */ + 3347, /* BCA5 (48293) */ + 3347, /* BCA6 (48294) */ + 3347, /* BCA7 (48295) */ + 3347, /* BCA8 (48296) */ + 3347, /* BCA9 (48297) */ + 3347, /* BCAA (48298) */ + 3347, /* BCAB (48299) */ + 3347, /* BCAC (48300) */ + 3347, /* BCAD (48301) */ + 3347, /* BCAE (48302) */ + 3347, /* BCAF (48303) */ + 3347, /* BCB0 (48304) */ + 3347, /* BCB1 (48305) */ + 3347, /* BCB2 (48306) */ + 3347, /* BCB3 (48307) */ + 3347, /* BCB4 (48308) */ + 3347, /* BCB5 (48309) */ + 3347, /* BCB6 (48310) */ + 3347, /* BCB7 (48311) */ + 3347, /* BCB8 (48312) */ + 3347, /* BCB9 (48313) */ + 3347, /* BCBA (48314) */ + 3347, /* BCBB (48315) */ + 3347, /* BCBC (48316) */ + 3347, /* BCBD (48317) */ + 3347, /* BCBE (48318) */ + 3347, /* BCBF (48319) */ + 3347, /* BCC0 (48320) */ + 3347, /* BCC1 (48321) */ + 3347, /* BCC2 (48322) */ + 3347, /* BCC3 (48323) */ + 3347, /* BCC4 (48324) */ + 3347, /* BCC5 (48325) */ + 3347, /* BCC6 (48326) */ + 3347, /* BCC7 (48327) */ + 3347, /* BCC8 (48328) */ + 3347, /* BCC9 (48329) */ + 3347, /* BCCA (48330) */ + 3347, /* BCCB (48331) */ + 3347, /* BCCC (48332) */ + 3347, /* BCCD (48333) */ + 3347, /* BCCE (48334) */ + 3347, /* BCCF (48335) */ + 3347, /* BCD0 (48336) */ + 3347, /* BCD1 (48337) */ + 3347, /* BCD2 (48338) */ + 3347, /* BCD3 (48339) */ + 3347, /* BCD4 (48340) */ + 3347, /* BCD5 (48341) */ + 3347, /* BCD6 (48342) */ + 3347, /* BCD7 (48343) */ + 3347, /* BCD8 (48344) */ + 3347, /* BCD9 (48345) */ + 3347, /* BCDA (48346) */ + 3347, /* BCDB (48347) */ + 3347, /* BCDC (48348) */ + 3347, /* BCDD (48349) */ + 3347, /* BCDE (48350) */ + 3347, /* BCDF (48351) */ + 3347, /* BCE0 (48352) */ + 3347, /* BCE1 (48353) */ + 3347, /* BCE2 (48354) */ + 3347, /* BCE3 (48355) */ + 3347, /* BCE4 (48356) */ + 3347, /* BCE5 (48357) */ + 3347, /* BCE6 (48358) */ + 3347, /* BCE7 (48359) */ + 3347, /* BCE8 (48360) */ + 3347, /* BCE9 (48361) */ + 3347, /* BCEA (48362) */ + 3347, /* BCEB (48363) */ + 3347, /* BCEC (48364) */ + 3347, /* BCED (48365) */ + 3347, /* BCEE (48366) */ + 3347, /* BCEF (48367) */ + 3347, /* BCF0 (48368) */ + 3347, /* BCF1 (48369) */ + 3347, /* BCF2 (48370) */ + 3347, /* BCF3 (48371) */ + 3347, /* BCF4 (48372) */ + 3347, /* BCF5 (48373) */ + 3347, /* BCF6 (48374) */ + 3347, /* BCF7 (48375) */ + 3347, /* BCF8 (48376) */ + 3347, /* BCF9 (48377) */ + 3347, /* BCFA (48378) */ + 3347, /* BCFB (48379) */ + 3347, /* BCFC (48380) */ + 3347, /* BCFD (48381) */ + 3347, /* BCFE (48382) */ + 3347, /* BCFF (48383) */ + 3347, /* BD00 (48384) */ + 3347, /* BD01 (48385) */ + 3347, /* BD02 (48386) */ + 3347, /* BD03 (48387) */ + 3347, /* BD04 (48388) */ + 3347, /* BD05 (48389) */ + 3347, /* BD06 (48390) */ + 3347, /* BD07 (48391) */ + 3347, /* BD08 (48392) */ + 3347, /* BD09 (48393) */ + 3347, /* BD0A (48394) */ + 3347, /* BD0B (48395) */ + 3347, /* BD0C (48396) */ + 3347, /* BD0D (48397) */ + 3347, /* BD0E (48398) */ + 3347, /* BD0F (48399) */ + 3347, /* BD10 (48400) */ + 3347, /* BD11 (48401) */ + 3347, /* BD12 (48402) */ + 3347, /* BD13 (48403) */ + 3347, /* BD14 (48404) */ + 3347, /* BD15 (48405) */ + 3347, /* BD16 (48406) */ + 3347, /* BD17 (48407) */ + 3347, /* BD18 (48408) */ + 3347, /* BD19 (48409) */ + 3347, /* BD1A (48410) */ + 3347, /* BD1B (48411) */ + 3347, /* BD1C (48412) */ + 3347, /* BD1D (48413) */ + 3347, /* BD1E (48414) */ + 3347, /* BD1F (48415) */ + 3347, /* BD20 (48416) */ + 3347, /* BD21 (48417) */ + 3347, /* BD22 (48418) */ + 3347, /* BD23 (48419) */ + 3347, /* BD24 (48420) */ + 3347, /* BD25 (48421) */ + 3347, /* BD26 (48422) */ + 3347, /* BD27 (48423) */ + 3347, /* BD28 (48424) */ + 3347, /* BD29 (48425) */ + 3347, /* BD2A (48426) */ + 3347, /* BD2B (48427) */ + 3347, /* BD2C (48428) */ + 3347, /* BD2D (48429) */ + 3347, /* BD2E (48430) */ + 3347, /* BD2F (48431) */ + 3347, /* BD30 (48432) */ + 3347, /* BD31 (48433) */ + 3347, /* BD32 (48434) */ + 3347, /* BD33 (48435) */ + 3347, /* BD34 (48436) */ + 3347, /* BD35 (48437) */ + 3347, /* BD36 (48438) */ + 3347, /* BD37 (48439) */ + 3347, /* BD38 (48440) */ + 3347, /* BD39 (48441) */ + 3347, /* BD3A (48442) */ + 3347, /* BD3B (48443) */ + 3347, /* BD3C (48444) */ + 3347, /* BD3D (48445) */ + 3347, /* BD3E (48446) */ + 3347, /* BD3F (48447) */ + 3347, /* BD40 (48448) */ + 3347, /* BD41 (48449) */ + 3347, /* BD42 (48450) */ + 3347, /* BD43 (48451) */ + 3347, /* BD44 (48452) */ + 3347, /* BD45 (48453) */ + 3347, /* BD46 (48454) */ + 3347, /* BD47 (48455) */ + 3347, /* BD48 (48456) */ + 3347, /* BD49 (48457) */ + 3347, /* BD4A (48458) */ + 3347, /* BD4B (48459) */ + 3347, /* BD4C (48460) */ + 3347, /* BD4D (48461) */ + 3347, /* BD4E (48462) */ + 3347, /* BD4F (48463) */ + 3347, /* BD50 (48464) */ + 3347, /* BD51 (48465) */ + 3347, /* BD52 (48466) */ + 3347, /* BD53 (48467) */ + 3347, /* BD54 (48468) */ + 3347, /* BD55 (48469) */ + 3347, /* BD56 (48470) */ + 3347, /* BD57 (48471) */ + 3347, /* BD58 (48472) */ + 3347, /* BD59 (48473) */ + 3347, /* BD5A (48474) */ + 3347, /* BD5B (48475) */ + 3347, /* BD5C (48476) */ + 3347, /* BD5D (48477) */ + 3347, /* BD5E (48478) */ + 3347, /* BD5F (48479) */ + 3347, /* BD60 (48480) */ + 3347, /* BD61 (48481) */ + 3347, /* BD62 (48482) */ + 3347, /* BD63 (48483) */ + 3347, /* BD64 (48484) */ + 3347, /* BD65 (48485) */ + 3347, /* BD66 (48486) */ + 3347, /* BD67 (48487) */ + 3347, /* BD68 (48488) */ + 3347, /* BD69 (48489) */ + 3347, /* BD6A (48490) */ + 3347, /* BD6B (48491) */ + 3347, /* BD6C (48492) */ + 3347, /* BD6D (48493) */ + 3347, /* BD6E (48494) */ + 3347, /* BD6F (48495) */ + 3347, /* BD70 (48496) */ + 3347, /* BD71 (48497) */ + 3347, /* BD72 (48498) */ + 3347, /* BD73 (48499) */ + 3347, /* BD74 (48500) */ + 3347, /* BD75 (48501) */ + 3347, /* BD76 (48502) */ + 3347, /* BD77 (48503) */ + 3347, /* BD78 (48504) */ + 3347, /* BD79 (48505) */ + 3347, /* BD7A (48506) */ + 3347, /* BD7B (48507) */ + 3347, /* BD7C (48508) */ + 3347, /* BD7D (48509) */ + 3347, /* BD7E (48510) */ + 3347, /* BD7F (48511) */ + 3347, /* BD80 (48512) */ + 3347, /* BD81 (48513) */ + 3347, /* BD82 (48514) */ + 3347, /* BD83 (48515) */ + 3347, /* BD84 (48516) */ + 3347, /* BD85 (48517) */ + 3347, /* BD86 (48518) */ + 3347, /* BD87 (48519) */ + 3347, /* BD88 (48520) */ + 3347, /* BD89 (48521) */ + 3347, /* BD8A (48522) */ + 3347, /* BD8B (48523) */ + 3347, /* BD8C (48524) */ + 3347, /* BD8D (48525) */ + 3347, /* BD8E (48526) */ + 3347, /* BD8F (48527) */ + 3347, /* BD90 (48528) */ + 3347, /* BD91 (48529) */ + 3347, /* BD92 (48530) */ + 3347, /* BD93 (48531) */ + 3347, /* BD94 (48532) */ + 3347, /* BD95 (48533) */ + 3347, /* BD96 (48534) */ + 3347, /* BD97 (48535) */ + 3347, /* BD98 (48536) */ + 3347, /* BD99 (48537) */ + 3347, /* BD9A (48538) */ + 3347, /* BD9B (48539) */ + 3347, /* BD9C (48540) */ + 3347, /* BD9D (48541) */ + 3347, /* BD9E (48542) */ + 3347, /* BD9F (48543) */ + 3347, /* BDA0 (48544) */ + 3347, /* BDA1 (48545) */ + 3347, /* BDA2 (48546) */ + 3347, /* BDA3 (48547) */ + 3347, /* BDA4 (48548) */ + 3347, /* BDA5 (48549) */ + 3347, /* BDA6 (48550) */ + 3347, /* BDA7 (48551) */ + 3347, /* BDA8 (48552) */ + 3347, /* BDA9 (48553) */ + 3347, /* BDAA (48554) */ + 3347, /* BDAB (48555) */ + 3347, /* BDAC (48556) */ + 3347, /* BDAD (48557) */ + 3347, /* BDAE (48558) */ + 3347, /* BDAF (48559) */ + 3347, /* BDB0 (48560) */ + 3347, /* BDB1 (48561) */ + 3347, /* BDB2 (48562) */ + 3347, /* BDB3 (48563) */ + 3347, /* BDB4 (48564) */ + 3347, /* BDB5 (48565) */ + 3347, /* BDB6 (48566) */ + 3347, /* BDB7 (48567) */ + 3347, /* BDB8 (48568) */ + 3347, /* BDB9 (48569) */ + 3347, /* BDBA (48570) */ + 3347, /* BDBB (48571) */ + 3347, /* BDBC (48572) */ + 3347, /* BDBD (48573) */ + 3347, /* BDBE (48574) */ + 3347, /* BDBF (48575) */ + 3347, /* BDC0 (48576) */ + 3347, /* BDC1 (48577) */ + 3347, /* BDC2 (48578) */ + 3347, /* BDC3 (48579) */ + 3347, /* BDC4 (48580) */ + 3347, /* BDC5 (48581) */ + 3347, /* BDC6 (48582) */ + 3347, /* BDC7 (48583) */ + 3347, /* BDC8 (48584) */ + 3347, /* BDC9 (48585) */ + 3347, /* BDCA (48586) */ + 3347, /* BDCB (48587) */ + 3347, /* BDCC (48588) */ + 3347, /* BDCD (48589) */ + 3347, /* BDCE (48590) */ + 3347, /* BDCF (48591) */ + 3347, /* BDD0 (48592) */ + 3347, /* BDD1 (48593) */ + 3347, /* BDD2 (48594) */ + 3347, /* BDD3 (48595) */ + 3347, /* BDD4 (48596) */ + 3347, /* BDD5 (48597) */ + 3347, /* BDD6 (48598) */ + 3347, /* BDD7 (48599) */ + 3347, /* BDD8 (48600) */ + 3347, /* BDD9 (48601) */ + 3347, /* BDDA (48602) */ + 3347, /* BDDB (48603) */ + 3347, /* BDDC (48604) */ + 3347, /* BDDD (48605) */ + 3347, /* BDDE (48606) */ + 3347, /* BDDF (48607) */ + 3347, /* BDE0 (48608) */ + 3347, /* BDE1 (48609) */ + 3347, /* BDE2 (48610) */ + 3347, /* BDE3 (48611) */ + 3347, /* BDE4 (48612) */ + 3347, /* BDE5 (48613) */ + 3347, /* BDE6 (48614) */ + 3347, /* BDE7 (48615) */ + 3347, /* BDE8 (48616) */ + 3347, /* BDE9 (48617) */ + 3347, /* BDEA (48618) */ + 3347, /* BDEB (48619) */ + 3347, /* BDEC (48620) */ + 3347, /* BDED (48621) */ + 3347, /* BDEE (48622) */ + 3347, /* BDEF (48623) */ + 3347, /* BDF0 (48624) */ + 3347, /* BDF1 (48625) */ + 3347, /* BDF2 (48626) */ + 3347, /* BDF3 (48627) */ + 3347, /* BDF4 (48628) */ + 3347, /* BDF5 (48629) */ + 3347, /* BDF6 (48630) */ + 3347, /* BDF7 (48631) */ + 3347, /* BDF8 (48632) */ + 3347, /* BDF9 (48633) */ + 3347, /* BDFA (48634) */ + 3347, /* BDFB (48635) */ + 3347, /* BDFC (48636) */ + 3347, /* BDFD (48637) */ + 3347, /* BDFE (48638) */ + 3347, /* BDFF (48639) */ + 3347, /* BE00 (48640) */ + 3347, /* BE01 (48641) */ + 3347, /* BE02 (48642) */ + 3347, /* BE03 (48643) */ + 3347, /* BE04 (48644) */ + 3347, /* BE05 (48645) */ + 3347, /* BE06 (48646) */ + 3347, /* BE07 (48647) */ + 3347, /* BE08 (48648) */ + 3347, /* BE09 (48649) */ + 3347, /* BE0A (48650) */ + 3347, /* BE0B (48651) */ + 3347, /* BE0C (48652) */ + 3347, /* BE0D (48653) */ + 3347, /* BE0E (48654) */ + 3347, /* BE0F (48655) */ + 3347, /* BE10 (48656) */ + 3347, /* BE11 (48657) */ + 3347, /* BE12 (48658) */ + 3347, /* BE13 (48659) */ + 3347, /* BE14 (48660) */ + 3347, /* BE15 (48661) */ + 3347, /* BE16 (48662) */ + 3347, /* BE17 (48663) */ + 3347, /* BE18 (48664) */ + 3347, /* BE19 (48665) */ + 3347, /* BE1A (48666) */ + 3347, /* BE1B (48667) */ + 3347, /* BE1C (48668) */ + 3347, /* BE1D (48669) */ + 3347, /* BE1E (48670) */ + 3347, /* BE1F (48671) */ + 3347, /* BE20 (48672) */ + 3347, /* BE21 (48673) */ + 3347, /* BE22 (48674) */ + 3347, /* BE23 (48675) */ + 3347, /* BE24 (48676) */ + 3347, /* BE25 (48677) */ + 3347, /* BE26 (48678) */ + 3347, /* BE27 (48679) */ + 3347, /* BE28 (48680) */ + 3347, /* BE29 (48681) */ + 3347, /* BE2A (48682) */ + 3347, /* BE2B (48683) */ + 3347, /* BE2C (48684) */ + 3347, /* BE2D (48685) */ + 3347, /* BE2E (48686) */ + 3347, /* BE2F (48687) */ + 3347, /* BE30 (48688) */ + 3347, /* BE31 (48689) */ + 3347, /* BE32 (48690) */ + 3347, /* BE33 (48691) */ + 3347, /* BE34 (48692) */ + 3347, /* BE35 (48693) */ + 3347, /* BE36 (48694) */ + 3347, /* BE37 (48695) */ + 3347, /* BE38 (48696) */ + 3347, /* BE39 (48697) */ + 3347, /* BE3A (48698) */ + 3347, /* BE3B (48699) */ + 3347, /* BE3C (48700) */ + 3347, /* BE3D (48701) */ + 3347, /* BE3E (48702) */ + 3347, /* BE3F (48703) */ + 3347, /* BE40 (48704) */ + 3347, /* BE41 (48705) */ + 3347, /* BE42 (48706) */ + 3347, /* BE43 (48707) */ + 3347, /* BE44 (48708) */ + 3347, /* BE45 (48709) */ + 3347, /* BE46 (48710) */ + 3347, /* BE47 (48711) */ + 3347, /* BE48 (48712) */ + 3347, /* BE49 (48713) */ + 3347, /* BE4A (48714) */ + 3347, /* BE4B (48715) */ + 3347, /* BE4C (48716) */ + 3347, /* BE4D (48717) */ + 3347, /* BE4E (48718) */ + 3347, /* BE4F (48719) */ + 3347, /* BE50 (48720) */ + 3347, /* BE51 (48721) */ + 3347, /* BE52 (48722) */ + 3347, /* BE53 (48723) */ + 3347, /* BE54 (48724) */ + 3347, /* BE55 (48725) */ + 3347, /* BE56 (48726) */ + 3347, /* BE57 (48727) */ + 3347, /* BE58 (48728) */ + 3347, /* BE59 (48729) */ + 3347, /* BE5A (48730) */ + 3347, /* BE5B (48731) */ + 3347, /* BE5C (48732) */ + 3347, /* BE5D (48733) */ + 3347, /* BE5E (48734) */ + 3347, /* BE5F (48735) */ + 3347, /* BE60 (48736) */ + 3347, /* BE61 (48737) */ + 3347, /* BE62 (48738) */ + 3347, /* BE63 (48739) */ + 3347, /* BE64 (48740) */ + 3347, /* BE65 (48741) */ + 3347, /* BE66 (48742) */ + 3347, /* BE67 (48743) */ + 3347, /* BE68 (48744) */ + 3347, /* BE69 (48745) */ + 3347, /* BE6A (48746) */ + 3347, /* BE6B (48747) */ + 3347, /* BE6C (48748) */ + 3347, /* BE6D (48749) */ + 3347, /* BE6E (48750) */ + 3347, /* BE6F (48751) */ + 3347, /* BE70 (48752) */ + 3347, /* BE71 (48753) */ + 3347, /* BE72 (48754) */ + 3347, /* BE73 (48755) */ + 3347, /* BE74 (48756) */ + 3347, /* BE75 (48757) */ + 3347, /* BE76 (48758) */ + 3347, /* BE77 (48759) */ + 3347, /* BE78 (48760) */ + 3347, /* BE79 (48761) */ + 3347, /* BE7A (48762) */ + 3347, /* BE7B (48763) */ + 3347, /* BE7C (48764) */ + 3347, /* BE7D (48765) */ + 3347, /* BE7E (48766) */ + 3347, /* BE7F (48767) */ + 3347, /* BE80 (48768) */ + 3347, /* BE81 (48769) */ + 3347, /* BE82 (48770) */ + 3347, /* BE83 (48771) */ + 3347, /* BE84 (48772) */ + 3347, /* BE85 (48773) */ + 3347, /* BE86 (48774) */ + 3347, /* BE87 (48775) */ + 3347, /* BE88 (48776) */ + 3347, /* BE89 (48777) */ + 3347, /* BE8A (48778) */ + 3347, /* BE8B (48779) */ + 3347, /* BE8C (48780) */ + 3347, /* BE8D (48781) */ + 3347, /* BE8E (48782) */ + 3347, /* BE8F (48783) */ + 3347, /* BE90 (48784) */ + 3347, /* BE91 (48785) */ + 3347, /* BE92 (48786) */ + 3347, /* BE93 (48787) */ + 3347, /* BE94 (48788) */ + 3347, /* BE95 (48789) */ + 3347, /* BE96 (48790) */ + 3347, /* BE97 (48791) */ + 3347, /* BE98 (48792) */ + 3347, /* BE99 (48793) */ + 3347, /* BE9A (48794) */ + 3347, /* BE9B (48795) */ + 3347, /* BE9C (48796) */ + 3347, /* BE9D (48797) */ + 3347, /* BE9E (48798) */ + 3347, /* BE9F (48799) */ + 3347, /* BEA0 (48800) */ + 3347, /* BEA1 (48801) */ + 3347, /* BEA2 (48802) */ + 3347, /* BEA3 (48803) */ + 3347, /* BEA4 (48804) */ + 3347, /* BEA5 (48805) */ + 3347, /* BEA6 (48806) */ + 3347, /* BEA7 (48807) */ + 3347, /* BEA8 (48808) */ + 3347, /* BEA9 (48809) */ + 3347, /* BEAA (48810) */ + 3347, /* BEAB (48811) */ + 3347, /* BEAC (48812) */ + 3347, /* BEAD (48813) */ + 3347, /* BEAE (48814) */ + 3347, /* BEAF (48815) */ + 3347, /* BEB0 (48816) */ + 3347, /* BEB1 (48817) */ + 3347, /* BEB2 (48818) */ + 3347, /* BEB3 (48819) */ + 3347, /* BEB4 (48820) */ + 3347, /* BEB5 (48821) */ + 3347, /* BEB6 (48822) */ + 3347, /* BEB7 (48823) */ + 3347, /* BEB8 (48824) */ + 3347, /* BEB9 (48825) */ + 3347, /* BEBA (48826) */ + 3347, /* BEBB (48827) */ + 3347, /* BEBC (48828) */ + 3347, /* BEBD (48829) */ + 3347, /* BEBE (48830) */ + 3347, /* BEBF (48831) */ + 3347, /* BEC0 (48832) */ + 3347, /* BEC1 (48833) */ + 3347, /* BEC2 (48834) */ + 3347, /* BEC3 (48835) */ + 3347, /* BEC4 (48836) */ + 3347, /* BEC5 (48837) */ + 3347, /* BEC6 (48838) */ + 3347, /* BEC7 (48839) */ + 3347, /* BEC8 (48840) */ + 3347, /* BEC9 (48841) */ + 3347, /* BECA (48842) */ + 3347, /* BECB (48843) */ + 3347, /* BECC (48844) */ + 3347, /* BECD (48845) */ + 3347, /* BECE (48846) */ + 3347, /* BECF (48847) */ + 3347, /* BED0 (48848) */ + 3347, /* BED1 (48849) */ + 3347, /* BED2 (48850) */ + 3347, /* BED3 (48851) */ + 3347, /* BED4 (48852) */ + 3347, /* BED5 (48853) */ + 3347, /* BED6 (48854) */ + 3347, /* BED7 (48855) */ + 3347, /* BED8 (48856) */ + 3347, /* BED9 (48857) */ + 3347, /* BEDA (48858) */ + 3347, /* BEDB (48859) */ + 3347, /* BEDC (48860) */ + 3347, /* BEDD (48861) */ + 3347, /* BEDE (48862) */ + 3347, /* BEDF (48863) */ + 3347, /* BEE0 (48864) */ + 3347, /* BEE1 (48865) */ + 3347, /* BEE2 (48866) */ + 3347, /* BEE3 (48867) */ + 3347, /* BEE4 (48868) */ + 3347, /* BEE5 (48869) */ + 3347, /* BEE6 (48870) */ + 3347, /* BEE7 (48871) */ + 3347, /* BEE8 (48872) */ + 3347, /* BEE9 (48873) */ + 3347, /* BEEA (48874) */ + 3347, /* BEEB (48875) */ + 3347, /* BEEC (48876) */ + 3347, /* BEED (48877) */ + 3347, /* BEEE (48878) */ + 3347, /* BEEF (48879) */ + 3347, /* BEF0 (48880) */ + 3347, /* BEF1 (48881) */ + 3347, /* BEF2 (48882) */ + 3347, /* BEF3 (48883) */ + 3347, /* BEF4 (48884) */ + 3347, /* BEF5 (48885) */ + 3347, /* BEF6 (48886) */ + 3347, /* BEF7 (48887) */ + 3347, /* BEF8 (48888) */ + 3347, /* BEF9 (48889) */ + 3347, /* BEFA (48890) */ + 3347, /* BEFB (48891) */ + 3347, /* BEFC (48892) */ + 3347, /* BEFD (48893) */ + 3347, /* BEFE (48894) */ + 3347, /* BEFF (48895) */ + 3347, /* BF00 (48896) */ + 3347, /* BF01 (48897) */ + 3347, /* BF02 (48898) */ + 3347, /* BF03 (48899) */ + 3347, /* BF04 (48900) */ + 3347, /* BF05 (48901) */ + 3347, /* BF06 (48902) */ + 3347, /* BF07 (48903) */ + 3347, /* BF08 (48904) */ + 3347, /* BF09 (48905) */ + 3347, /* BF0A (48906) */ + 3347, /* BF0B (48907) */ + 3347, /* BF0C (48908) */ + 3347, /* BF0D (48909) */ + 3347, /* BF0E (48910) */ + 3347, /* BF0F (48911) */ + 3347, /* BF10 (48912) */ + 3347, /* BF11 (48913) */ + 3347, /* BF12 (48914) */ + 3347, /* BF13 (48915) */ + 3347, /* BF14 (48916) */ + 3347, /* BF15 (48917) */ + 3347, /* BF16 (48918) */ + 3347, /* BF17 (48919) */ + 3347, /* BF18 (48920) */ + 3347, /* BF19 (48921) */ + 3347, /* BF1A (48922) */ + 3347, /* BF1B (48923) */ + 3347, /* BF1C (48924) */ + 3347, /* BF1D (48925) */ + 3347, /* BF1E (48926) */ + 3347, /* BF1F (48927) */ + 3347, /* BF20 (48928) */ + 3347, /* BF21 (48929) */ + 3347, /* BF22 (48930) */ + 3347, /* BF23 (48931) */ + 3347, /* BF24 (48932) */ + 3347, /* BF25 (48933) */ + 3347, /* BF26 (48934) */ + 3347, /* BF27 (48935) */ + 3347, /* BF28 (48936) */ + 3347, /* BF29 (48937) */ + 3347, /* BF2A (48938) */ + 3347, /* BF2B (48939) */ + 3347, /* BF2C (48940) */ + 3347, /* BF2D (48941) */ + 3347, /* BF2E (48942) */ + 3347, /* BF2F (48943) */ + 3347, /* BF30 (48944) */ + 3347, /* BF31 (48945) */ + 3347, /* BF32 (48946) */ + 3347, /* BF33 (48947) */ + 3347, /* BF34 (48948) */ + 3347, /* BF35 (48949) */ + 3347, /* BF36 (48950) */ + 3347, /* BF37 (48951) */ + 3347, /* BF38 (48952) */ + 3347, /* BF39 (48953) */ + 3347, /* BF3A (48954) */ + 3347, /* BF3B (48955) */ + 3347, /* BF3C (48956) */ + 3347, /* BF3D (48957) */ + 3347, /* BF3E (48958) */ + 3347, /* BF3F (48959) */ + 3347, /* BF40 (48960) */ + 3347, /* BF41 (48961) */ + 3347, /* BF42 (48962) */ + 3347, /* BF43 (48963) */ + 3347, /* BF44 (48964) */ + 3347, /* BF45 (48965) */ + 3347, /* BF46 (48966) */ + 3347, /* BF47 (48967) */ + 3347, /* BF48 (48968) */ + 3347, /* BF49 (48969) */ + 3347, /* BF4A (48970) */ + 3347, /* BF4B (48971) */ + 3347, /* BF4C (48972) */ + 3347, /* BF4D (48973) */ + 3347, /* BF4E (48974) */ + 3347, /* BF4F (48975) */ + 3347, /* BF50 (48976) */ + 3347, /* BF51 (48977) */ + 3347, /* BF52 (48978) */ + 3347, /* BF53 (48979) */ + 3347, /* BF54 (48980) */ + 3347, /* BF55 (48981) */ + 3347, /* BF56 (48982) */ + 3347, /* BF57 (48983) */ + 3347, /* BF58 (48984) */ + 3347, /* BF59 (48985) */ + 3347, /* BF5A (48986) */ + 3347, /* BF5B (48987) */ + 3347, /* BF5C (48988) */ + 3347, /* BF5D (48989) */ + 3347, /* BF5E (48990) */ + 3347, /* BF5F (48991) */ + 3347, /* BF60 (48992) */ + 3347, /* BF61 (48993) */ + 3347, /* BF62 (48994) */ + 3347, /* BF63 (48995) */ + 3347, /* BF64 (48996) */ + 3347, /* BF65 (48997) */ + 3347, /* BF66 (48998) */ + 3347, /* BF67 (48999) */ + 3347, /* BF68 (49000) */ + 3347, /* BF69 (49001) */ + 3347, /* BF6A (49002) */ + 3347, /* BF6B (49003) */ + 3347, /* BF6C (49004) */ + 3347, /* BF6D (49005) */ + 3347, /* BF6E (49006) */ + 3347, /* BF6F (49007) */ + 3347, /* BF70 (49008) */ + 3347, /* BF71 (49009) */ + 3347, /* BF72 (49010) */ + 3347, /* BF73 (49011) */ + 3347, /* BF74 (49012) */ + 3347, /* BF75 (49013) */ + 3347, /* BF76 (49014) */ + 3347, /* BF77 (49015) */ + 3347, /* BF78 (49016) */ + 3347, /* BF79 (49017) */ + 3347, /* BF7A (49018) */ + 3347, /* BF7B (49019) */ + 3347, /* BF7C (49020) */ + 3347, /* BF7D (49021) */ + 3347, /* BF7E (49022) */ + 3347, /* BF7F (49023) */ + 3347, /* BF80 (49024) */ + 3347, /* BF81 (49025) */ + 3347, /* BF82 (49026) */ + 3347, /* BF83 (49027) */ + 3347, /* BF84 (49028) */ + 3347, /* BF85 (49029) */ + 3347, /* BF86 (49030) */ + 3347, /* BF87 (49031) */ + 3347, /* BF88 (49032) */ + 3347, /* BF89 (49033) */ + 3347, /* BF8A (49034) */ + 3347, /* BF8B (49035) */ + 3347, /* BF8C (49036) */ + 3347, /* BF8D (49037) */ + 3347, /* BF8E (49038) */ + 3347, /* BF8F (49039) */ + 3347, /* BF90 (49040) */ + 3347, /* BF91 (49041) */ + 3347, /* BF92 (49042) */ + 3347, /* BF93 (49043) */ + 3347, /* BF94 (49044) */ + 3347, /* BF95 (49045) */ + 3347, /* BF96 (49046) */ + 3347, /* BF97 (49047) */ + 3347, /* BF98 (49048) */ + 3347, /* BF99 (49049) */ + 3347, /* BF9A (49050) */ + 3347, /* BF9B (49051) */ + 3347, /* BF9C (49052) */ + 3347, /* BF9D (49053) */ + 3347, /* BF9E (49054) */ + 3347, /* BF9F (49055) */ + 3347, /* BFA0 (49056) */ + 3347, /* BFA1 (49057) */ + 3347, /* BFA2 (49058) */ + 3347, /* BFA3 (49059) */ + 3347, /* BFA4 (49060) */ + 3347, /* BFA5 (49061) */ + 3347, /* BFA6 (49062) */ + 3347, /* BFA7 (49063) */ + 3347, /* BFA8 (49064) */ + 3347, /* BFA9 (49065) */ + 3347, /* BFAA (49066) */ + 3347, /* BFAB (49067) */ + 3347, /* BFAC (49068) */ + 3347, /* BFAD (49069) */ + 3347, /* BFAE (49070) */ + 3347, /* BFAF (49071) */ + 3347, /* BFB0 (49072) */ + 3347, /* BFB1 (49073) */ + 3347, /* BFB2 (49074) */ + 3347, /* BFB3 (49075) */ + 3347, /* BFB4 (49076) */ + 3347, /* BFB5 (49077) */ + 3347, /* BFB6 (49078) */ + 3347, /* BFB7 (49079) */ + 3347, /* BFB8 (49080) */ + 3347, /* BFB9 (49081) */ + 3347, /* BFBA (49082) */ + 3347, /* BFBB (49083) */ + 3347, /* BFBC (49084) */ + 3347, /* BFBD (49085) */ + 3347, /* BFBE (49086) */ + 3347, /* BFBF (49087) */ + 3347, /* BFC0 (49088) */ + 3347, /* BFC1 (49089) */ + 3347, /* BFC2 (49090) */ + 3347, /* BFC3 (49091) */ + 3347, /* BFC4 (49092) */ + 3347, /* BFC5 (49093) */ + 3347, /* BFC6 (49094) */ + 3347, /* BFC7 (49095) */ + 3347, /* BFC8 (49096) */ + 3347, /* BFC9 (49097) */ + 3347, /* BFCA (49098) */ + 3347, /* BFCB (49099) */ + 3347, /* BFCC (49100) */ + 3347, /* BFCD (49101) */ + 3347, /* BFCE (49102) */ + 3347, /* BFCF (49103) */ + 3347, /* BFD0 (49104) */ + 3347, /* BFD1 (49105) */ + 3347, /* BFD2 (49106) */ + 3347, /* BFD3 (49107) */ + 3347, /* BFD4 (49108) */ + 3347, /* BFD5 (49109) */ + 3347, /* BFD6 (49110) */ + 3347, /* BFD7 (49111) */ + 3347, /* BFD8 (49112) */ + 3347, /* BFD9 (49113) */ + 3347, /* BFDA (49114) */ + 3347, /* BFDB (49115) */ + 3347, /* BFDC (49116) */ + 3347, /* BFDD (49117) */ + 3347, /* BFDE (49118) */ + 3347, /* BFDF (49119) */ + 3347, /* BFE0 (49120) */ + 3347, /* BFE1 (49121) */ + 3347, /* BFE2 (49122) */ + 3347, /* BFE3 (49123) */ + 3347, /* BFE4 (49124) */ + 3347, /* BFE5 (49125) */ + 3347, /* BFE6 (49126) */ + 3347, /* BFE7 (49127) */ + 3347, /* BFE8 (49128) */ + 3347, /* BFE9 (49129) */ + 3347, /* BFEA (49130) */ + 3347, /* BFEB (49131) */ + 3347, /* BFEC (49132) */ + 3347, /* BFED (49133) */ + 3347, /* BFEE (49134) */ + 3347, /* BFEF (49135) */ + 3347, /* BFF0 (49136) */ + 3347, /* BFF1 (49137) */ + 3347, /* BFF2 (49138) */ + 3347, /* BFF3 (49139) */ + 3347, /* BFF4 (49140) */ + 3347, /* BFF5 (49141) */ + 3347, /* BFF6 (49142) */ + 3347, /* BFF7 (49143) */ + 3347, /* BFF8 (49144) */ + 3347, /* BFF9 (49145) */ + 3347, /* BFFA (49146) */ + 3347, /* BFFB (49147) */ + 3347, /* BFFC (49148) */ + 3347, /* BFFD (49149) */ + 3347, /* BFFE (49150) */ + 3347, /* BFFF (49151) */ + 3347, /* C000 (49152) */ + 3347, /* C001 (49153) */ + 3347, /* C002 (49154) */ + 3347, /* C003 (49155) */ + 3347, /* C004 (49156) */ + 3347, /* C005 (49157) */ + 3347, /* C006 (49158) */ + 3347, /* C007 (49159) */ + 3347, /* C008 (49160) */ + 3347, /* C009 (49161) */ + 3347, /* C00A (49162) */ + 3347, /* C00B (49163) */ + 3347, /* C00C (49164) */ + 3347, /* C00D (49165) */ + 3347, /* C00E (49166) */ + 3347, /* C00F (49167) */ + 3347, /* C010 (49168) */ + 3347, /* C011 (49169) */ + 3347, /* C012 (49170) */ + 3347, /* C013 (49171) */ + 3347, /* C014 (49172) */ + 3347, /* C015 (49173) */ + 3347, /* C016 (49174) */ + 3347, /* C017 (49175) */ + 3347, /* C018 (49176) */ + 3347, /* C019 (49177) */ + 3347, /* C01A (49178) */ + 3347, /* C01B (49179) */ + 3347, /* C01C (49180) */ + 3347, /* C01D (49181) */ + 3347, /* C01E (49182) */ + 3347, /* C01F (49183) */ + 3347, /* C020 (49184) */ + 3347, /* C021 (49185) */ + 3347, /* C022 (49186) */ + 3347, /* C023 (49187) */ + 3347, /* C024 (49188) */ + 3347, /* C025 (49189) */ + 3347, /* C026 (49190) */ + 3347, /* C027 (49191) */ + 3347, /* C028 (49192) */ + 3347, /* C029 (49193) */ + 3347, /* C02A (49194) */ + 3347, /* C02B (49195) */ + 3347, /* C02C (49196) */ + 3347, /* C02D (49197) */ + 3347, /* C02E (49198) */ + 3347, /* C02F (49199) */ + 3347, /* C030 (49200) */ + 3347, /* C031 (49201) */ + 3347, /* C032 (49202) */ + 3347, /* C033 (49203) */ + 3347, /* C034 (49204) */ + 3347, /* C035 (49205) */ + 3347, /* C036 (49206) */ + 3347, /* C037 (49207) */ + 3347, /* C038 (49208) */ + 3347, /* C039 (49209) */ + 3347, /* C03A (49210) */ + 3347, /* C03B (49211) */ + 3347, /* C03C (49212) */ + 3347, /* C03D (49213) */ + 3347, /* C03E (49214) */ + 3347, /* C03F (49215) */ + 3347, /* C040 (49216) */ + 3347, /* C041 (49217) */ + 3347, /* C042 (49218) */ + 3347, /* C043 (49219) */ + 3347, /* C044 (49220) */ + 3347, /* C045 (49221) */ + 3347, /* C046 (49222) */ + 3347, /* C047 (49223) */ + 3347, /* C048 (49224) */ + 3347, /* C049 (49225) */ + 3347, /* C04A (49226) */ + 3347, /* C04B (49227) */ + 3347, /* C04C (49228) */ + 3347, /* C04D (49229) */ + 3347, /* C04E (49230) */ + 3347, /* C04F (49231) */ + 3347, /* C050 (49232) */ + 3347, /* C051 (49233) */ + 3347, /* C052 (49234) */ + 3347, /* C053 (49235) */ + 3347, /* C054 (49236) */ + 3347, /* C055 (49237) */ + 3347, /* C056 (49238) */ + 3347, /* C057 (49239) */ + 3347, /* C058 (49240) */ + 3347, /* C059 (49241) */ + 3347, /* C05A (49242) */ + 3347, /* C05B (49243) */ + 3347, /* C05C (49244) */ + 3347, /* C05D (49245) */ + 3347, /* C05E (49246) */ + 3347, /* C05F (49247) */ + 3347, /* C060 (49248) */ + 3347, /* C061 (49249) */ + 3347, /* C062 (49250) */ + 3347, /* C063 (49251) */ + 3347, /* C064 (49252) */ + 3347, /* C065 (49253) */ + 3347, /* C066 (49254) */ + 3347, /* C067 (49255) */ + 3347, /* C068 (49256) */ + 3347, /* C069 (49257) */ + 3347, /* C06A (49258) */ + 3347, /* C06B (49259) */ + 3347, /* C06C (49260) */ + 3347, /* C06D (49261) */ + 3347, /* C06E (49262) */ + 3347, /* C06F (49263) */ + 3347, /* C070 (49264) */ + 3347, /* C071 (49265) */ + 3347, /* C072 (49266) */ + 3347, /* C073 (49267) */ + 3347, /* C074 (49268) */ + 3347, /* C075 (49269) */ + 3347, /* C076 (49270) */ + 3347, /* C077 (49271) */ + 3347, /* C078 (49272) */ + 3347, /* C079 (49273) */ + 3347, /* C07A (49274) */ + 3347, /* C07B (49275) */ + 3347, /* C07C (49276) */ + 3347, /* C07D (49277) */ + 3347, /* C07E (49278) */ + 3347, /* C07F (49279) */ + 3347, /* C080 (49280) */ + 3347, /* C081 (49281) */ + 3347, /* C082 (49282) */ + 3347, /* C083 (49283) */ + 3347, /* C084 (49284) */ + 3347, /* C085 (49285) */ + 3347, /* C086 (49286) */ + 3347, /* C087 (49287) */ + 3347, /* C088 (49288) */ + 3347, /* C089 (49289) */ + 3347, /* C08A (49290) */ + 3347, /* C08B (49291) */ + 3347, /* C08C (49292) */ + 3347, /* C08D (49293) */ + 3347, /* C08E (49294) */ + 3347, /* C08F (49295) */ + 3347, /* C090 (49296) */ + 3347, /* C091 (49297) */ + 3347, /* C092 (49298) */ + 3347, /* C093 (49299) */ + 3347, /* C094 (49300) */ + 3347, /* C095 (49301) */ + 3347, /* C096 (49302) */ + 3347, /* C097 (49303) */ + 3347, /* C098 (49304) */ + 3347, /* C099 (49305) */ + 3347, /* C09A (49306) */ + 3347, /* C09B (49307) */ + 3347, /* C09C (49308) */ + 3347, /* C09D (49309) */ + 3347, /* C09E (49310) */ + 3347, /* C09F (49311) */ + 3347, /* C0A0 (49312) */ + 3347, /* C0A1 (49313) */ + 3347, /* C0A2 (49314) */ + 3347, /* C0A3 (49315) */ + 3347, /* C0A4 (49316) */ + 3347, /* C0A5 (49317) */ + 3347, /* C0A6 (49318) */ + 3347, /* C0A7 (49319) */ + 3347, /* C0A8 (49320) */ + 3347, /* C0A9 (49321) */ + 3347, /* C0AA (49322) */ + 3347, /* C0AB (49323) */ + 3347, /* C0AC (49324) */ + 3347, /* C0AD (49325) */ + 3347, /* C0AE (49326) */ + 3347, /* C0AF (49327) */ + 3347, /* C0B0 (49328) */ + 3347, /* C0B1 (49329) */ + 3347, /* C0B2 (49330) */ + 3347, /* C0B3 (49331) */ + 3347, /* C0B4 (49332) */ + 3347, /* C0B5 (49333) */ + 3347, /* C0B6 (49334) */ + 3347, /* C0B7 (49335) */ + 3347, /* C0B8 (49336) */ + 3347, /* C0B9 (49337) */ + 3347, /* C0BA (49338) */ + 3347, /* C0BB (49339) */ + 3347, /* C0BC (49340) */ + 3347, /* C0BD (49341) */ + 3347, /* C0BE (49342) */ + 3347, /* C0BF (49343) */ + 3347, /* C0C0 (49344) */ + 3347, /* C0C1 (49345) */ + 3347, /* C0C2 (49346) */ + 3347, /* C0C3 (49347) */ + 3347, /* C0C4 (49348) */ + 3347, /* C0C5 (49349) */ + 3347, /* C0C6 (49350) */ + 3347, /* C0C7 (49351) */ + 3347, /* C0C8 (49352) */ + 3347, /* C0C9 (49353) */ + 3347, /* C0CA (49354) */ + 3347, /* C0CB (49355) */ + 3347, /* C0CC (49356) */ + 3347, /* C0CD (49357) */ + 3347, /* C0CE (49358) */ + 3347, /* C0CF (49359) */ + 3347, /* C0D0 (49360) */ + 3347, /* C0D1 (49361) */ + 3347, /* C0D2 (49362) */ + 3347, /* C0D3 (49363) */ + 3347, /* C0D4 (49364) */ + 3347, /* C0D5 (49365) */ + 3347, /* C0D6 (49366) */ + 3347, /* C0D7 (49367) */ + 3347, /* C0D8 (49368) */ + 3347, /* C0D9 (49369) */ + 3347, /* C0DA (49370) */ + 3347, /* C0DB (49371) */ + 3347, /* C0DC (49372) */ + 3347, /* C0DD (49373) */ + 3347, /* C0DE (49374) */ + 3347, /* C0DF (49375) */ + 3347, /* C0E0 (49376) */ + 3347, /* C0E1 (49377) */ + 3347, /* C0E2 (49378) */ + 3347, /* C0E3 (49379) */ + 3347, /* C0E4 (49380) */ + 3347, /* C0E5 (49381) */ + 3347, /* C0E6 (49382) */ + 3347, /* C0E7 (49383) */ + 3347, /* C0E8 (49384) */ + 3347, /* C0E9 (49385) */ + 3347, /* C0EA (49386) */ + 3347, /* C0EB (49387) */ + 3347, /* C0EC (49388) */ + 3347, /* C0ED (49389) */ + 3347, /* C0EE (49390) */ + 3347, /* C0EF (49391) */ + 3347, /* C0F0 (49392) */ + 3347, /* C0F1 (49393) */ + 3347, /* C0F2 (49394) */ + 3347, /* C0F3 (49395) */ + 3347, /* C0F4 (49396) */ + 3347, /* C0F5 (49397) */ + 3347, /* C0F6 (49398) */ + 3347, /* C0F7 (49399) */ + 3347, /* C0F8 (49400) */ + 3347, /* C0F9 (49401) */ + 3347, /* C0FA (49402) */ + 3347, /* C0FB (49403) */ + 3347, /* C0FC (49404) */ + 3347, /* C0FD (49405) */ + 3347, /* C0FE (49406) */ + 3347, /* C0FF (49407) */ + 3347, /* C100 (49408) */ + 3347, /* C101 (49409) */ + 3347, /* C102 (49410) */ + 3347, /* C103 (49411) */ + 3347, /* C104 (49412) */ + 3347, /* C105 (49413) */ + 3347, /* C106 (49414) */ + 3347, /* C107 (49415) */ + 3347, /* C108 (49416) */ + 3347, /* C109 (49417) */ + 3347, /* C10A (49418) */ + 3347, /* C10B (49419) */ + 3347, /* C10C (49420) */ + 3347, /* C10D (49421) */ + 3347, /* C10E (49422) */ + 3347, /* C10F (49423) */ + 3347, /* C110 (49424) */ + 3347, /* C111 (49425) */ + 3347, /* C112 (49426) */ + 3347, /* C113 (49427) */ + 3347, /* C114 (49428) */ + 3347, /* C115 (49429) */ + 3347, /* C116 (49430) */ + 3347, /* C117 (49431) */ + 3347, /* C118 (49432) */ + 3347, /* C119 (49433) */ + 3347, /* C11A (49434) */ + 3347, /* C11B (49435) */ + 3347, /* C11C (49436) */ + 3347, /* C11D (49437) */ + 3347, /* C11E (49438) */ + 3347, /* C11F (49439) */ + 3347, /* C120 (49440) */ + 3347, /* C121 (49441) */ + 3347, /* C122 (49442) */ + 3347, /* C123 (49443) */ + 3347, /* C124 (49444) */ + 3347, /* C125 (49445) */ + 3347, /* C126 (49446) */ + 3347, /* C127 (49447) */ + 3347, /* C128 (49448) */ + 3347, /* C129 (49449) */ + 3347, /* C12A (49450) */ + 3347, /* C12B (49451) */ + 3347, /* C12C (49452) */ + 3347, /* C12D (49453) */ + 3347, /* C12E (49454) */ + 3347, /* C12F (49455) */ + 3347, /* C130 (49456) */ + 3347, /* C131 (49457) */ + 3347, /* C132 (49458) */ + 3347, /* C133 (49459) */ + 3347, /* C134 (49460) */ + 3347, /* C135 (49461) */ + 3347, /* C136 (49462) */ + 3347, /* C137 (49463) */ + 3347, /* C138 (49464) */ + 3347, /* C139 (49465) */ + 3347, /* C13A (49466) */ + 3347, /* C13B (49467) */ + 3347, /* C13C (49468) */ + 3347, /* C13D (49469) */ + 3347, /* C13E (49470) */ + 3347, /* C13F (49471) */ + 3347, /* C140 (49472) */ + 3347, /* C141 (49473) */ + 3347, /* C142 (49474) */ + 3347, /* C143 (49475) */ + 3347, /* C144 (49476) */ + 3347, /* C145 (49477) */ + 3347, /* C146 (49478) */ + 3347, /* C147 (49479) */ + 3347, /* C148 (49480) */ + 3347, /* C149 (49481) */ + 3347, /* C14A (49482) */ + 3347, /* C14B (49483) */ + 3347, /* C14C (49484) */ + 3347, /* C14D (49485) */ + 3347, /* C14E (49486) */ + 3347, /* C14F (49487) */ + 3347, /* C150 (49488) */ + 3347, /* C151 (49489) */ + 3347, /* C152 (49490) */ + 3347, /* C153 (49491) */ + 3347, /* C154 (49492) */ + 3347, /* C155 (49493) */ + 3347, /* C156 (49494) */ + 3347, /* C157 (49495) */ + 3347, /* C158 (49496) */ + 3347, /* C159 (49497) */ + 3347, /* C15A (49498) */ + 3347, /* C15B (49499) */ + 3347, /* C15C (49500) */ + 3347, /* C15D (49501) */ + 3347, /* C15E (49502) */ + 3347, /* C15F (49503) */ + 3347, /* C160 (49504) */ + 3347, /* C161 (49505) */ + 3347, /* C162 (49506) */ + 3347, /* C163 (49507) */ + 3347, /* C164 (49508) */ + 3347, /* C165 (49509) */ + 3347, /* C166 (49510) */ + 3347, /* C167 (49511) */ + 3347, /* C168 (49512) */ + 3347, /* C169 (49513) */ + 3347, /* C16A (49514) */ + 3347, /* C16B (49515) */ + 3347, /* C16C (49516) */ + 3347, /* C16D (49517) */ + 3347, /* C16E (49518) */ + 3347, /* C16F (49519) */ + 3347, /* C170 (49520) */ + 3347, /* C171 (49521) */ + 3347, /* C172 (49522) */ + 3347, /* C173 (49523) */ + 3347, /* C174 (49524) */ + 3347, /* C175 (49525) */ + 3347, /* C176 (49526) */ + 3347, /* C177 (49527) */ + 3347, /* C178 (49528) */ + 3347, /* C179 (49529) */ + 3347, /* C17A (49530) */ + 3347, /* C17B (49531) */ + 3347, /* C17C (49532) */ + 3347, /* C17D (49533) */ + 3347, /* C17E (49534) */ + 3347, /* C17F (49535) */ + 3347, /* C180 (49536) */ + 3347, /* C181 (49537) */ + 3347, /* C182 (49538) */ + 3347, /* C183 (49539) */ + 3347, /* C184 (49540) */ + 3347, /* C185 (49541) */ + 3347, /* C186 (49542) */ + 3347, /* C187 (49543) */ + 3347, /* C188 (49544) */ + 3347, /* C189 (49545) */ + 3347, /* C18A (49546) */ + 3347, /* C18B (49547) */ + 3347, /* C18C (49548) */ + 3347, /* C18D (49549) */ + 3347, /* C18E (49550) */ + 3347, /* C18F (49551) */ + 3347, /* C190 (49552) */ + 3347, /* C191 (49553) */ + 3347, /* C192 (49554) */ + 3347, /* C193 (49555) */ + 3347, /* C194 (49556) */ + 3347, /* C195 (49557) */ + 3347, /* C196 (49558) */ + 3347, /* C197 (49559) */ + 3347, /* C198 (49560) */ + 3347, /* C199 (49561) */ + 3347, /* C19A (49562) */ + 3347, /* C19B (49563) */ + 3347, /* C19C (49564) */ + 3347, /* C19D (49565) */ + 3347, /* C19E (49566) */ + 3347, /* C19F (49567) */ + 3347, /* C1A0 (49568) */ + 3347, /* C1A1 (49569) */ + 3347, /* C1A2 (49570) */ + 3347, /* C1A3 (49571) */ + 3347, /* C1A4 (49572) */ + 3347, /* C1A5 (49573) */ + 3347, /* C1A6 (49574) */ + 3347, /* C1A7 (49575) */ + 3347, /* C1A8 (49576) */ + 3347, /* C1A9 (49577) */ + 3347, /* C1AA (49578) */ + 3347, /* C1AB (49579) */ + 3347, /* C1AC (49580) */ + 3347, /* C1AD (49581) */ + 3347, /* C1AE (49582) */ + 3347, /* C1AF (49583) */ + 3347, /* C1B0 (49584) */ + 3347, /* C1B1 (49585) */ + 3347, /* C1B2 (49586) */ + 3347, /* C1B3 (49587) */ + 3347, /* C1B4 (49588) */ + 3347, /* C1B5 (49589) */ + 3347, /* C1B6 (49590) */ + 3347, /* C1B7 (49591) */ + 3347, /* C1B8 (49592) */ + 3347, /* C1B9 (49593) */ + 3347, /* C1BA (49594) */ + 3347, /* C1BB (49595) */ + 3347, /* C1BC (49596) */ + 3347, /* C1BD (49597) */ + 3347, /* C1BE (49598) */ + 3347, /* C1BF (49599) */ + 3347, /* C1C0 (49600) */ + 3347, /* C1C1 (49601) */ + 3347, /* C1C2 (49602) */ + 3347, /* C1C3 (49603) */ + 3347, /* C1C4 (49604) */ + 3347, /* C1C5 (49605) */ + 3347, /* C1C6 (49606) */ + 3347, /* C1C7 (49607) */ + 3347, /* C1C8 (49608) */ + 3347, /* C1C9 (49609) */ + 3347, /* C1CA (49610) */ + 3347, /* C1CB (49611) */ + 3347, /* C1CC (49612) */ + 3347, /* C1CD (49613) */ + 3347, /* C1CE (49614) */ + 3347, /* C1CF (49615) */ + 3347, /* C1D0 (49616) */ + 3347, /* C1D1 (49617) */ + 3347, /* C1D2 (49618) */ + 3347, /* C1D3 (49619) */ + 3347, /* C1D4 (49620) */ + 3347, /* C1D5 (49621) */ + 3347, /* C1D6 (49622) */ + 3347, /* C1D7 (49623) */ + 3347, /* C1D8 (49624) */ + 3347, /* C1D9 (49625) */ + 3347, /* C1DA (49626) */ + 3347, /* C1DB (49627) */ + 3347, /* C1DC (49628) */ + 3347, /* C1DD (49629) */ + 3347, /* C1DE (49630) */ + 3347, /* C1DF (49631) */ + 3347, /* C1E0 (49632) */ + 3347, /* C1E1 (49633) */ + 3347, /* C1E2 (49634) */ + 3347, /* C1E3 (49635) */ + 3347, /* C1E4 (49636) */ + 3347, /* C1E5 (49637) */ + 3347, /* C1E6 (49638) */ + 3347, /* C1E7 (49639) */ + 3347, /* C1E8 (49640) */ + 3347, /* C1E9 (49641) */ + 3347, /* C1EA (49642) */ + 3347, /* C1EB (49643) */ + 3347, /* C1EC (49644) */ + 3347, /* C1ED (49645) */ + 3347, /* C1EE (49646) */ + 3347, /* C1EF (49647) */ + 3347, /* C1F0 (49648) */ + 3347, /* C1F1 (49649) */ + 3347, /* C1F2 (49650) */ + 3347, /* C1F3 (49651) */ + 3347, /* C1F4 (49652) */ + 3347, /* C1F5 (49653) */ + 3347, /* C1F6 (49654) */ + 3347, /* C1F7 (49655) */ + 3347, /* C1F8 (49656) */ + 3347, /* C1F9 (49657) */ + 3347, /* C1FA (49658) */ + 3347, /* C1FB (49659) */ + 3347, /* C1FC (49660) */ + 3347, /* C1FD (49661) */ + 3347, /* C1FE (49662) */ + 3347, /* C1FF (49663) */ + 3347, /* C200 (49664) */ + 3347, /* C201 (49665) */ + 3347, /* C202 (49666) */ + 3347, /* C203 (49667) */ + 3347, /* C204 (49668) */ + 3347, /* C205 (49669) */ + 3347, /* C206 (49670) */ + 3347, /* C207 (49671) */ + 3347, /* C208 (49672) */ + 3347, /* C209 (49673) */ + 3347, /* C20A (49674) */ + 3347, /* C20B (49675) */ + 3347, /* C20C (49676) */ + 3347, /* C20D (49677) */ + 3347, /* C20E (49678) */ + 3347, /* C20F (49679) */ + 3347, /* C210 (49680) */ + 3347, /* C211 (49681) */ + 3347, /* C212 (49682) */ + 3347, /* C213 (49683) */ + 3347, /* C214 (49684) */ + 3347, /* C215 (49685) */ + 3347, /* C216 (49686) */ + 3347, /* C217 (49687) */ + 3347, /* C218 (49688) */ + 3347, /* C219 (49689) */ + 3347, /* C21A (49690) */ + 3347, /* C21B (49691) */ + 3347, /* C21C (49692) */ + 3347, /* C21D (49693) */ + 3347, /* C21E (49694) */ + 3347, /* C21F (49695) */ + 3347, /* C220 (49696) */ + 3347, /* C221 (49697) */ + 3347, /* C222 (49698) */ + 3347, /* C223 (49699) */ + 3347, /* C224 (49700) */ + 3347, /* C225 (49701) */ + 3347, /* C226 (49702) */ + 3347, /* C227 (49703) */ + 3347, /* C228 (49704) */ + 3347, /* C229 (49705) */ + 3347, /* C22A (49706) */ + 3347, /* C22B (49707) */ + 3347, /* C22C (49708) */ + 3347, /* C22D (49709) */ + 3347, /* C22E (49710) */ + 3347, /* C22F (49711) */ + 3347, /* C230 (49712) */ + 3347, /* C231 (49713) */ + 3347, /* C232 (49714) */ + 3347, /* C233 (49715) */ + 3347, /* C234 (49716) */ + 3347, /* C235 (49717) */ + 3347, /* C236 (49718) */ + 3347, /* C237 (49719) */ + 3347, /* C238 (49720) */ + 3347, /* C239 (49721) */ + 3347, /* C23A (49722) */ + 3347, /* C23B (49723) */ + 3347, /* C23C (49724) */ + 3347, /* C23D (49725) */ + 3347, /* C23E (49726) */ + 3347, /* C23F (49727) */ + 3347, /* C240 (49728) */ + 3347, /* C241 (49729) */ + 3347, /* C242 (49730) */ + 3347, /* C243 (49731) */ + 3347, /* C244 (49732) */ + 3347, /* C245 (49733) */ + 3347, /* C246 (49734) */ + 3347, /* C247 (49735) */ + 3347, /* C248 (49736) */ + 3347, /* C249 (49737) */ + 3347, /* C24A (49738) */ + 3347, /* C24B (49739) */ + 3347, /* C24C (49740) */ + 3347, /* C24D (49741) */ + 3347, /* C24E (49742) */ + 3347, /* C24F (49743) */ + 3347, /* C250 (49744) */ + 3347, /* C251 (49745) */ + 3347, /* C252 (49746) */ + 3347, /* C253 (49747) */ + 3347, /* C254 (49748) */ + 3347, /* C255 (49749) */ + 3347, /* C256 (49750) */ + 3347, /* C257 (49751) */ + 3347, /* C258 (49752) */ + 3347, /* C259 (49753) */ + 3347, /* C25A (49754) */ + 3347, /* C25B (49755) */ + 3347, /* C25C (49756) */ + 3347, /* C25D (49757) */ + 3347, /* C25E (49758) */ + 3347, /* C25F (49759) */ + 3347, /* C260 (49760) */ + 3347, /* C261 (49761) */ + 3347, /* C262 (49762) */ + 3347, /* C263 (49763) */ + 3347, /* C264 (49764) */ + 3347, /* C265 (49765) */ + 3347, /* C266 (49766) */ + 3347, /* C267 (49767) */ + 3347, /* C268 (49768) */ + 3347, /* C269 (49769) */ + 3347, /* C26A (49770) */ + 3347, /* C26B (49771) */ + 3347, /* C26C (49772) */ + 3347, /* C26D (49773) */ + 3347, /* C26E (49774) */ + 3347, /* C26F (49775) */ + 3347, /* C270 (49776) */ + 3347, /* C271 (49777) */ + 3347, /* C272 (49778) */ + 3347, /* C273 (49779) */ + 3347, /* C274 (49780) */ + 3347, /* C275 (49781) */ + 3347, /* C276 (49782) */ + 3347, /* C277 (49783) */ + 3347, /* C278 (49784) */ + 3347, /* C279 (49785) */ + 3347, /* C27A (49786) */ + 3347, /* C27B (49787) */ + 3347, /* C27C (49788) */ + 3347, /* C27D (49789) */ + 3347, /* C27E (49790) */ + 3347, /* C27F (49791) */ + 3347, /* C280 (49792) */ + 3347, /* C281 (49793) */ + 3347, /* C282 (49794) */ + 3347, /* C283 (49795) */ + 3347, /* C284 (49796) */ + 3347, /* C285 (49797) */ + 3347, /* C286 (49798) */ + 3347, /* C287 (49799) */ + 3347, /* C288 (49800) */ + 3347, /* C289 (49801) */ + 3347, /* C28A (49802) */ + 3347, /* C28B (49803) */ + 3347, /* C28C (49804) */ + 3347, /* C28D (49805) */ + 3347, /* C28E (49806) */ + 3347, /* C28F (49807) */ + 3347, /* C290 (49808) */ + 3347, /* C291 (49809) */ + 3347, /* C292 (49810) */ + 3347, /* C293 (49811) */ + 3347, /* C294 (49812) */ + 3347, /* C295 (49813) */ + 3347, /* C296 (49814) */ + 3347, /* C297 (49815) */ + 3347, /* C298 (49816) */ + 3347, /* C299 (49817) */ + 3347, /* C29A (49818) */ + 3347, /* C29B (49819) */ + 3347, /* C29C (49820) */ + 3347, /* C29D (49821) */ + 3347, /* C29E (49822) */ + 3347, /* C29F (49823) */ + 3347, /* C2A0 (49824) */ + 3347, /* C2A1 (49825) */ + 3347, /* C2A2 (49826) */ + 3347, /* C2A3 (49827) */ + 3347, /* C2A4 (49828) */ + 3347, /* C2A5 (49829) */ + 3347, /* C2A6 (49830) */ + 3347, /* C2A7 (49831) */ + 3347, /* C2A8 (49832) */ + 3347, /* C2A9 (49833) */ + 3347, /* C2AA (49834) */ + 3347, /* C2AB (49835) */ + 3347, /* C2AC (49836) */ + 3347, /* C2AD (49837) */ + 3347, /* C2AE (49838) */ + 3347, /* C2AF (49839) */ + 3347, /* C2B0 (49840) */ + 3347, /* C2B1 (49841) */ + 3347, /* C2B2 (49842) */ + 3347, /* C2B3 (49843) */ + 3347, /* C2B4 (49844) */ + 3347, /* C2B5 (49845) */ + 3347, /* C2B6 (49846) */ + 3347, /* C2B7 (49847) */ + 3347, /* C2B8 (49848) */ + 3347, /* C2B9 (49849) */ + 3347, /* C2BA (49850) */ + 3347, /* C2BB (49851) */ + 3347, /* C2BC (49852) */ + 3347, /* C2BD (49853) */ + 3347, /* C2BE (49854) */ + 3347, /* C2BF (49855) */ + 3347, /* C2C0 (49856) */ + 3347, /* C2C1 (49857) */ + 3347, /* C2C2 (49858) */ + 3347, /* C2C3 (49859) */ + 3347, /* C2C4 (49860) */ + 3347, /* C2C5 (49861) */ + 3347, /* C2C6 (49862) */ + 3347, /* C2C7 (49863) */ + 3347, /* C2C8 (49864) */ + 3347, /* C2C9 (49865) */ + 3347, /* C2CA (49866) */ + 3347, /* C2CB (49867) */ + 3347, /* C2CC (49868) */ + 3347, /* C2CD (49869) */ + 3347, /* C2CE (49870) */ + 3347, /* C2CF (49871) */ + 3347, /* C2D0 (49872) */ + 3347, /* C2D1 (49873) */ + 3347, /* C2D2 (49874) */ + 3347, /* C2D3 (49875) */ + 3347, /* C2D4 (49876) */ + 3347, /* C2D5 (49877) */ + 3347, /* C2D6 (49878) */ + 3347, /* C2D7 (49879) */ + 3347, /* C2D8 (49880) */ + 3347, /* C2D9 (49881) */ + 3347, /* C2DA (49882) */ + 3347, /* C2DB (49883) */ + 3347, /* C2DC (49884) */ + 3347, /* C2DD (49885) */ + 3347, /* C2DE (49886) */ + 3347, /* C2DF (49887) */ + 3347, /* C2E0 (49888) */ + 3347, /* C2E1 (49889) */ + 3347, /* C2E2 (49890) */ + 3347, /* C2E3 (49891) */ + 3347, /* C2E4 (49892) */ + 3347, /* C2E5 (49893) */ + 3347, /* C2E6 (49894) */ + 3347, /* C2E7 (49895) */ + 3347, /* C2E8 (49896) */ + 3347, /* C2E9 (49897) */ + 3347, /* C2EA (49898) */ + 3347, /* C2EB (49899) */ + 3347, /* C2EC (49900) */ + 3347, /* C2ED (49901) */ + 3347, /* C2EE (49902) */ + 3347, /* C2EF (49903) */ + 3347, /* C2F0 (49904) */ + 3347, /* C2F1 (49905) */ + 3347, /* C2F2 (49906) */ + 3347, /* C2F3 (49907) */ + 3347, /* C2F4 (49908) */ + 3347, /* C2F5 (49909) */ + 3347, /* C2F6 (49910) */ + 3347, /* C2F7 (49911) */ + 3347, /* C2F8 (49912) */ + 3347, /* C2F9 (49913) */ + 3347, /* C2FA (49914) */ + 3347, /* C2FB (49915) */ + 3347, /* C2FC (49916) */ + 3347, /* C2FD (49917) */ + 3347, /* C2FE (49918) */ + 3347, /* C2FF (49919) */ + 3347, /* C300 (49920) */ + 3347, /* C301 (49921) */ + 3347, /* C302 (49922) */ + 3347, /* C303 (49923) */ + 3347, /* C304 (49924) */ + 3347, /* C305 (49925) */ + 3347, /* C306 (49926) */ + 3347, /* C307 (49927) */ + 3347, /* C308 (49928) */ + 3347, /* C309 (49929) */ + 3347, /* C30A (49930) */ + 3347, /* C30B (49931) */ + 3347, /* C30C (49932) */ + 3347, /* C30D (49933) */ + 3347, /* C30E (49934) */ + 3347, /* C30F (49935) */ + 3347, /* C310 (49936) */ + 3347, /* C311 (49937) */ + 3347, /* C312 (49938) */ + 3347, /* C313 (49939) */ + 3347, /* C314 (49940) */ + 3347, /* C315 (49941) */ + 3347, /* C316 (49942) */ + 3347, /* C317 (49943) */ + 3347, /* C318 (49944) */ + 3347, /* C319 (49945) */ + 3347, /* C31A (49946) */ + 3347, /* C31B (49947) */ + 3347, /* C31C (49948) */ + 3347, /* C31D (49949) */ + 3347, /* C31E (49950) */ + 3347, /* C31F (49951) */ + 3347, /* C320 (49952) */ + 3347, /* C321 (49953) */ + 3347, /* C322 (49954) */ + 3347, /* C323 (49955) */ + 3347, /* C324 (49956) */ + 3347, /* C325 (49957) */ + 3347, /* C326 (49958) */ + 3347, /* C327 (49959) */ + 3347, /* C328 (49960) */ + 3347, /* C329 (49961) */ + 3347, /* C32A (49962) */ + 3347, /* C32B (49963) */ + 3347, /* C32C (49964) */ + 3347, /* C32D (49965) */ + 3347, /* C32E (49966) */ + 3347, /* C32F (49967) */ + 3347, /* C330 (49968) */ + 3347, /* C331 (49969) */ + 3347, /* C332 (49970) */ + 3347, /* C333 (49971) */ + 3347, /* C334 (49972) */ + 3347, /* C335 (49973) */ + 3347, /* C336 (49974) */ + 3347, /* C337 (49975) */ + 3347, /* C338 (49976) */ + 3347, /* C339 (49977) */ + 3347, /* C33A (49978) */ + 3347, /* C33B (49979) */ + 3347, /* C33C (49980) */ + 3347, /* C33D (49981) */ + 3347, /* C33E (49982) */ + 3347, /* C33F (49983) */ + 3347, /* C340 (49984) */ + 3347, /* C341 (49985) */ + 3347, /* C342 (49986) */ + 3347, /* C343 (49987) */ + 3347, /* C344 (49988) */ + 3347, /* C345 (49989) */ + 3347, /* C346 (49990) */ + 3347, /* C347 (49991) */ + 3347, /* C348 (49992) */ + 3347, /* C349 (49993) */ + 3347, /* C34A (49994) */ + 3347, /* C34B (49995) */ + 3347, /* C34C (49996) */ + 3347, /* C34D (49997) */ + 3347, /* C34E (49998) */ + 3347, /* C34F (49999) */ + 3347, /* C350 (50000) */ + 3347, /* C351 (50001) */ + 3347, /* C352 (50002) */ + 3347, /* C353 (50003) */ + 3347, /* C354 (50004) */ + 3347, /* C355 (50005) */ + 3347, /* C356 (50006) */ + 3347, /* C357 (50007) */ + 3347, /* C358 (50008) */ + 3347, /* C359 (50009) */ + 3347, /* C35A (50010) */ + 3347, /* C35B (50011) */ + 3347, /* C35C (50012) */ + 3347, /* C35D (50013) */ + 3347, /* C35E (50014) */ + 3347, /* C35F (50015) */ + 3347, /* C360 (50016) */ + 3347, /* C361 (50017) */ + 3347, /* C362 (50018) */ + 3347, /* C363 (50019) */ + 3347, /* C364 (50020) */ + 3347, /* C365 (50021) */ + 3347, /* C366 (50022) */ + 3347, /* C367 (50023) */ + 3347, /* C368 (50024) */ + 3347, /* C369 (50025) */ + 3347, /* C36A (50026) */ + 3347, /* C36B (50027) */ + 3347, /* C36C (50028) */ + 3347, /* C36D (50029) */ + 3347, /* C36E (50030) */ + 3347, /* C36F (50031) */ + 3347, /* C370 (50032) */ + 3347, /* C371 (50033) */ + 3347, /* C372 (50034) */ + 3347, /* C373 (50035) */ + 3347, /* C374 (50036) */ + 3347, /* C375 (50037) */ + 3347, /* C376 (50038) */ + 3347, /* C377 (50039) */ + 3347, /* C378 (50040) */ + 3347, /* C379 (50041) */ + 3347, /* C37A (50042) */ + 3347, /* C37B (50043) */ + 3347, /* C37C (50044) */ + 3347, /* C37D (50045) */ + 3347, /* C37E (50046) */ + 3347, /* C37F (50047) */ + 3347, /* C380 (50048) */ + 3347, /* C381 (50049) */ + 3347, /* C382 (50050) */ + 3347, /* C383 (50051) */ + 3347, /* C384 (50052) */ + 3347, /* C385 (50053) */ + 3347, /* C386 (50054) */ + 3347, /* C387 (50055) */ + 3347, /* C388 (50056) */ + 3347, /* C389 (50057) */ + 3347, /* C38A (50058) */ + 3347, /* C38B (50059) */ + 3347, /* C38C (50060) */ + 3347, /* C38D (50061) */ + 3347, /* C38E (50062) */ + 3347, /* C38F (50063) */ + 3347, /* C390 (50064) */ + 3347, /* C391 (50065) */ + 3347, /* C392 (50066) */ + 3347, /* C393 (50067) */ + 3347, /* C394 (50068) */ + 3347, /* C395 (50069) */ + 3347, /* C396 (50070) */ + 3347, /* C397 (50071) */ + 3347, /* C398 (50072) */ + 3347, /* C399 (50073) */ + 3347, /* C39A (50074) */ + 3347, /* C39B (50075) */ + 3347, /* C39C (50076) */ + 3347, /* C39D (50077) */ + 3347, /* C39E (50078) */ + 3347, /* C39F (50079) */ + 3347, /* C3A0 (50080) */ + 3347, /* C3A1 (50081) */ + 3347, /* C3A2 (50082) */ + 3347, /* C3A3 (50083) */ + 3347, /* C3A4 (50084) */ + 3347, /* C3A5 (50085) */ + 3347, /* C3A6 (50086) */ + 3347, /* C3A7 (50087) */ + 3347, /* C3A8 (50088) */ + 3347, /* C3A9 (50089) */ + 3347, /* C3AA (50090) */ + 3347, /* C3AB (50091) */ + 3347, /* C3AC (50092) */ + 3347, /* C3AD (50093) */ + 3347, /* C3AE (50094) */ + 3347, /* C3AF (50095) */ + 3347, /* C3B0 (50096) */ + 3347, /* C3B1 (50097) */ + 3347, /* C3B2 (50098) */ + 3347, /* C3B3 (50099) */ + 3347, /* C3B4 (50100) */ + 3347, /* C3B5 (50101) */ + 3347, /* C3B6 (50102) */ + 3347, /* C3B7 (50103) */ + 3347, /* C3B8 (50104) */ + 3347, /* C3B9 (50105) */ + 3347, /* C3BA (50106) */ + 3347, /* C3BB (50107) */ + 3347, /* C3BC (50108) */ + 3347, /* C3BD (50109) */ + 3347, /* C3BE (50110) */ + 3347, /* C3BF (50111) */ + 3347, /* C3C0 (50112) */ + 3347, /* C3C1 (50113) */ + 3347, /* C3C2 (50114) */ + 3347, /* C3C3 (50115) */ + 3347, /* C3C4 (50116) */ + 3347, /* C3C5 (50117) */ + 3347, /* C3C6 (50118) */ + 3347, /* C3C7 (50119) */ + 3347, /* C3C8 (50120) */ + 3347, /* C3C9 (50121) */ + 3347, /* C3CA (50122) */ + 3347, /* C3CB (50123) */ + 3347, /* C3CC (50124) */ + 3347, /* C3CD (50125) */ + 3347, /* C3CE (50126) */ + 3347, /* C3CF (50127) */ + 3347, /* C3D0 (50128) */ + 3347, /* C3D1 (50129) */ + 3347, /* C3D2 (50130) */ + 3347, /* C3D3 (50131) */ + 3347, /* C3D4 (50132) */ + 3347, /* C3D5 (50133) */ + 3347, /* C3D6 (50134) */ + 3347, /* C3D7 (50135) */ + 3347, /* C3D8 (50136) */ + 3347, /* C3D9 (50137) */ + 3347, /* C3DA (50138) */ + 3347, /* C3DB (50139) */ + 3347, /* C3DC (50140) */ + 3347, /* C3DD (50141) */ + 3347, /* C3DE (50142) */ + 3347, /* C3DF (50143) */ + 3347, /* C3E0 (50144) */ + 3347, /* C3E1 (50145) */ + 3347, /* C3E2 (50146) */ + 3347, /* C3E3 (50147) */ + 3347, /* C3E4 (50148) */ + 3347, /* C3E5 (50149) */ + 3347, /* C3E6 (50150) */ + 3347, /* C3E7 (50151) */ + 3347, /* C3E8 (50152) */ + 3347, /* C3E9 (50153) */ + 3347, /* C3EA (50154) */ + 3347, /* C3EB (50155) */ + 3347, /* C3EC (50156) */ + 3347, /* C3ED (50157) */ + 3347, /* C3EE (50158) */ + 3347, /* C3EF (50159) */ + 3347, /* C3F0 (50160) */ + 3347, /* C3F1 (50161) */ + 3347, /* C3F2 (50162) */ + 3347, /* C3F3 (50163) */ + 3347, /* C3F4 (50164) */ + 3347, /* C3F5 (50165) */ + 3347, /* C3F6 (50166) */ + 3347, /* C3F7 (50167) */ + 3347, /* C3F8 (50168) */ + 3347, /* C3F9 (50169) */ + 3347, /* C3FA (50170) */ + 3347, /* C3FB (50171) */ + 3347, /* C3FC (50172) */ + 3347, /* C3FD (50173) */ + 3347, /* C3FE (50174) */ + 3347, /* C3FF (50175) */ + 3347, /* C400 (50176) */ + 3347, /* C401 (50177) */ + 3347, /* C402 (50178) */ + 3347, /* C403 (50179) */ + 3347, /* C404 (50180) */ + 3347, /* C405 (50181) */ + 3347, /* C406 (50182) */ + 3347, /* C407 (50183) */ + 3347, /* C408 (50184) */ + 3347, /* C409 (50185) */ + 3347, /* C40A (50186) */ + 3347, /* C40B (50187) */ + 3347, /* C40C (50188) */ + 3347, /* C40D (50189) */ + 3347, /* C40E (50190) */ + 3347, /* C40F (50191) */ + 3347, /* C410 (50192) */ + 3347, /* C411 (50193) */ + 3347, /* C412 (50194) */ + 3347, /* C413 (50195) */ + 3347, /* C414 (50196) */ + 3347, /* C415 (50197) */ + 3347, /* C416 (50198) */ + 3347, /* C417 (50199) */ + 3347, /* C418 (50200) */ + 3347, /* C419 (50201) */ + 3347, /* C41A (50202) */ + 3347, /* C41B (50203) */ + 3347, /* C41C (50204) */ + 3347, /* C41D (50205) */ + 3347, /* C41E (50206) */ + 3347, /* C41F (50207) */ + 3347, /* C420 (50208) */ + 3347, /* C421 (50209) */ + 3347, /* C422 (50210) */ + 3347, /* C423 (50211) */ + 3347, /* C424 (50212) */ + 3347, /* C425 (50213) */ + 3347, /* C426 (50214) */ + 3347, /* C427 (50215) */ + 3347, /* C428 (50216) */ + 3347, /* C429 (50217) */ + 3347, /* C42A (50218) */ + 3347, /* C42B (50219) */ + 3347, /* C42C (50220) */ + 3347, /* C42D (50221) */ + 3347, /* C42E (50222) */ + 3347, /* C42F (50223) */ + 3347, /* C430 (50224) */ + 3347, /* C431 (50225) */ + 3347, /* C432 (50226) */ + 3347, /* C433 (50227) */ + 3347, /* C434 (50228) */ + 3347, /* C435 (50229) */ + 3347, /* C436 (50230) */ + 3347, /* C437 (50231) */ + 3347, /* C438 (50232) */ + 3347, /* C439 (50233) */ + 3347, /* C43A (50234) */ + 3347, /* C43B (50235) */ + 3347, /* C43C (50236) */ + 3347, /* C43D (50237) */ + 3347, /* C43E (50238) */ + 3347, /* C43F (50239) */ + 3347, /* C440 (50240) */ + 3347, /* C441 (50241) */ + 3347, /* C442 (50242) */ + 3347, /* C443 (50243) */ + 3347, /* C444 (50244) */ + 3347, /* C445 (50245) */ + 3347, /* C446 (50246) */ + 3347, /* C447 (50247) */ + 3347, /* C448 (50248) */ + 3347, /* C449 (50249) */ + 3347, /* C44A (50250) */ + 3347, /* C44B (50251) */ + 3347, /* C44C (50252) */ + 3347, /* C44D (50253) */ + 3347, /* C44E (50254) */ + 3347, /* C44F (50255) */ + 3347, /* C450 (50256) */ + 3347, /* C451 (50257) */ + 3347, /* C452 (50258) */ + 3347, /* C453 (50259) */ + 3347, /* C454 (50260) */ + 3347, /* C455 (50261) */ + 3347, /* C456 (50262) */ + 3347, /* C457 (50263) */ + 3347, /* C458 (50264) */ + 3347, /* C459 (50265) */ + 3347, /* C45A (50266) */ + 3347, /* C45B (50267) */ + 3347, /* C45C (50268) */ + 3347, /* C45D (50269) */ + 3347, /* C45E (50270) */ + 3347, /* C45F (50271) */ + 3347, /* C460 (50272) */ + 3347, /* C461 (50273) */ + 3347, /* C462 (50274) */ + 3347, /* C463 (50275) */ + 3347, /* C464 (50276) */ + 3347, /* C465 (50277) */ + 3347, /* C466 (50278) */ + 3347, /* C467 (50279) */ + 3347, /* C468 (50280) */ + 3347, /* C469 (50281) */ + 3347, /* C46A (50282) */ + 3347, /* C46B (50283) */ + 3347, /* C46C (50284) */ + 3347, /* C46D (50285) */ + 3347, /* C46E (50286) */ + 3347, /* C46F (50287) */ + 3347, /* C470 (50288) */ + 3347, /* C471 (50289) */ + 3347, /* C472 (50290) */ + 3347, /* C473 (50291) */ + 3347, /* C474 (50292) */ + 3347, /* C475 (50293) */ + 3347, /* C476 (50294) */ + 3347, /* C477 (50295) */ + 3347, /* C478 (50296) */ + 3347, /* C479 (50297) */ + 3347, /* C47A (50298) */ + 3347, /* C47B (50299) */ + 3347, /* C47C (50300) */ + 3347, /* C47D (50301) */ + 3347, /* C47E (50302) */ + 3347, /* C47F (50303) */ + 3347, /* C480 (50304) */ + 3347, /* C481 (50305) */ + 3347, /* C482 (50306) */ + 3347, /* C483 (50307) */ + 3347, /* C484 (50308) */ + 3347, /* C485 (50309) */ + 3347, /* C486 (50310) */ + 3347, /* C487 (50311) */ + 3347, /* C488 (50312) */ + 3347, /* C489 (50313) */ + 3347, /* C48A (50314) */ + 3347, /* C48B (50315) */ + 3347, /* C48C (50316) */ + 3347, /* C48D (50317) */ + 3347, /* C48E (50318) */ + 3347, /* C48F (50319) */ + 3347, /* C490 (50320) */ + 3347, /* C491 (50321) */ + 3347, /* C492 (50322) */ + 3347, /* C493 (50323) */ + 3347, /* C494 (50324) */ + 3347, /* C495 (50325) */ + 3347, /* C496 (50326) */ + 3347, /* C497 (50327) */ + 3347, /* C498 (50328) */ + 3347, /* C499 (50329) */ + 3347, /* C49A (50330) */ + 3347, /* C49B (50331) */ + 3347, /* C49C (50332) */ + 3347, /* C49D (50333) */ + 3347, /* C49E (50334) */ + 3347, /* C49F (50335) */ + 3347, /* C4A0 (50336) */ + 3347, /* C4A1 (50337) */ + 3347, /* C4A2 (50338) */ + 3347, /* C4A3 (50339) */ + 3347, /* C4A4 (50340) */ + 3347, /* C4A5 (50341) */ + 3347, /* C4A6 (50342) */ + 3347, /* C4A7 (50343) */ + 3347, /* C4A8 (50344) */ + 3347, /* C4A9 (50345) */ + 3347, /* C4AA (50346) */ + 3347, /* C4AB (50347) */ + 3347, /* C4AC (50348) */ + 3347, /* C4AD (50349) */ + 3347, /* C4AE (50350) */ + 3347, /* C4AF (50351) */ + 3347, /* C4B0 (50352) */ + 3347, /* C4B1 (50353) */ + 3347, /* C4B2 (50354) */ + 3347, /* C4B3 (50355) */ + 3347, /* C4B4 (50356) */ + 3347, /* C4B5 (50357) */ + 3347, /* C4B6 (50358) */ + 3347, /* C4B7 (50359) */ + 3347, /* C4B8 (50360) */ + 3347, /* C4B9 (50361) */ + 3347, /* C4BA (50362) */ + 3347, /* C4BB (50363) */ + 3347, /* C4BC (50364) */ + 3347, /* C4BD (50365) */ + 3347, /* C4BE (50366) */ + 3347, /* C4BF (50367) */ + 3347, /* C4C0 (50368) */ + 3347, /* C4C1 (50369) */ + 3347, /* C4C2 (50370) */ + 3347, /* C4C3 (50371) */ + 3347, /* C4C4 (50372) */ + 3347, /* C4C5 (50373) */ + 3347, /* C4C6 (50374) */ + 3347, /* C4C7 (50375) */ + 3347, /* C4C8 (50376) */ + 3347, /* C4C9 (50377) */ + 3347, /* C4CA (50378) */ + 3347, /* C4CB (50379) */ + 3347, /* C4CC (50380) */ + 3347, /* C4CD (50381) */ + 3347, /* C4CE (50382) */ + 3347, /* C4CF (50383) */ + 3347, /* C4D0 (50384) */ + 3347, /* C4D1 (50385) */ + 3347, /* C4D2 (50386) */ + 3347, /* C4D3 (50387) */ + 3347, /* C4D4 (50388) */ + 3347, /* C4D5 (50389) */ + 3347, /* C4D6 (50390) */ + 3347, /* C4D7 (50391) */ + 3347, /* C4D8 (50392) */ + 3347, /* C4D9 (50393) */ + 3347, /* C4DA (50394) */ + 3347, /* C4DB (50395) */ + 3347, /* C4DC (50396) */ + 3347, /* C4DD (50397) */ + 3347, /* C4DE (50398) */ + 3347, /* C4DF (50399) */ + 3347, /* C4E0 (50400) */ + 3347, /* C4E1 (50401) */ + 3347, /* C4E2 (50402) */ + 3347, /* C4E3 (50403) */ + 3347, /* C4E4 (50404) */ + 3347, /* C4E5 (50405) */ + 3347, /* C4E6 (50406) */ + 3347, /* C4E7 (50407) */ + 3347, /* C4E8 (50408) */ + 3347, /* C4E9 (50409) */ + 3347, /* C4EA (50410) */ + 3347, /* C4EB (50411) */ + 3347, /* C4EC (50412) */ + 3347, /* C4ED (50413) */ + 3347, /* C4EE (50414) */ + 3347, /* C4EF (50415) */ + 3347, /* C4F0 (50416) */ + 3347, /* C4F1 (50417) */ + 3347, /* C4F2 (50418) */ + 3347, /* C4F3 (50419) */ + 3347, /* C4F4 (50420) */ + 3347, /* C4F5 (50421) */ + 3347, /* C4F6 (50422) */ + 3347, /* C4F7 (50423) */ + 3347, /* C4F8 (50424) */ + 3347, /* C4F9 (50425) */ + 3347, /* C4FA (50426) */ + 3347, /* C4FB (50427) */ + 3347, /* C4FC (50428) */ + 3347, /* C4FD (50429) */ + 3347, /* C4FE (50430) */ + 3347, /* C4FF (50431) */ + 3347, /* C500 (50432) */ + 3347, /* C501 (50433) */ + 3347, /* C502 (50434) */ + 3347, /* C503 (50435) */ + 3347, /* C504 (50436) */ + 3347, /* C505 (50437) */ + 3347, /* C506 (50438) */ + 3347, /* C507 (50439) */ + 3347, /* C508 (50440) */ + 3347, /* C509 (50441) */ + 3347, /* C50A (50442) */ + 3347, /* C50B (50443) */ + 3347, /* C50C (50444) */ + 3347, /* C50D (50445) */ + 3347, /* C50E (50446) */ + 3347, /* C50F (50447) */ + 3347, /* C510 (50448) */ + 3347, /* C511 (50449) */ + 3347, /* C512 (50450) */ + 3347, /* C513 (50451) */ + 3347, /* C514 (50452) */ + 3347, /* C515 (50453) */ + 3347, /* C516 (50454) */ + 3347, /* C517 (50455) */ + 3347, /* C518 (50456) */ + 3347, /* C519 (50457) */ + 3347, /* C51A (50458) */ + 3347, /* C51B (50459) */ + 3347, /* C51C (50460) */ + 3347, /* C51D (50461) */ + 3347, /* C51E (50462) */ + 3347, /* C51F (50463) */ + 3347, /* C520 (50464) */ + 3347, /* C521 (50465) */ + 3347, /* C522 (50466) */ + 3347, /* C523 (50467) */ + 3347, /* C524 (50468) */ + 3347, /* C525 (50469) */ + 3347, /* C526 (50470) */ + 3347, /* C527 (50471) */ + 3347, /* C528 (50472) */ + 3347, /* C529 (50473) */ + 3347, /* C52A (50474) */ + 3347, /* C52B (50475) */ + 3347, /* C52C (50476) */ + 3347, /* C52D (50477) */ + 3347, /* C52E (50478) */ + 3347, /* C52F (50479) */ + 3347, /* C530 (50480) */ + 3347, /* C531 (50481) */ + 3347, /* C532 (50482) */ + 3347, /* C533 (50483) */ + 3347, /* C534 (50484) */ + 3347, /* C535 (50485) */ + 3347, /* C536 (50486) */ + 3347, /* C537 (50487) */ + 3347, /* C538 (50488) */ + 3347, /* C539 (50489) */ + 3347, /* C53A (50490) */ + 3347, /* C53B (50491) */ + 3347, /* C53C (50492) */ + 3347, /* C53D (50493) */ + 3347, /* C53E (50494) */ + 3347, /* C53F (50495) */ + 3347, /* C540 (50496) */ + 3347, /* C541 (50497) */ + 3347, /* C542 (50498) */ + 3347, /* C543 (50499) */ + 3347, /* C544 (50500) */ + 3347, /* C545 (50501) */ + 3347, /* C546 (50502) */ + 3347, /* C547 (50503) */ + 3347, /* C548 (50504) */ + 3347, /* C549 (50505) */ + 3347, /* C54A (50506) */ + 3347, /* C54B (50507) */ + 3347, /* C54C (50508) */ + 3347, /* C54D (50509) */ + 3347, /* C54E (50510) */ + 3347, /* C54F (50511) */ + 3347, /* C550 (50512) */ + 3347, /* C551 (50513) */ + 3347, /* C552 (50514) */ + 3347, /* C553 (50515) */ + 3347, /* C554 (50516) */ + 3347, /* C555 (50517) */ + 3347, /* C556 (50518) */ + 3347, /* C557 (50519) */ + 3347, /* C558 (50520) */ + 3347, /* C559 (50521) */ + 3347, /* C55A (50522) */ + 3347, /* C55B (50523) */ + 3347, /* C55C (50524) */ + 3347, /* C55D (50525) */ + 3347, /* C55E (50526) */ + 3347, /* C55F (50527) */ + 3347, /* C560 (50528) */ + 3347, /* C561 (50529) */ + 3347, /* C562 (50530) */ + 3347, /* C563 (50531) */ + 3347, /* C564 (50532) */ + 3347, /* C565 (50533) */ + 3347, /* C566 (50534) */ + 3347, /* C567 (50535) */ + 3347, /* C568 (50536) */ + 3347, /* C569 (50537) */ + 3347, /* C56A (50538) */ + 3347, /* C56B (50539) */ + 3347, /* C56C (50540) */ + 3347, /* C56D (50541) */ + 3347, /* C56E (50542) */ + 3347, /* C56F (50543) */ + 3347, /* C570 (50544) */ + 3347, /* C571 (50545) */ + 3347, /* C572 (50546) */ + 3347, /* C573 (50547) */ + 3347, /* C574 (50548) */ + 3347, /* C575 (50549) */ + 3347, /* C576 (50550) */ + 3347, /* C577 (50551) */ + 3347, /* C578 (50552) */ + 3347, /* C579 (50553) */ + 3347, /* C57A (50554) */ + 3347, /* C57B (50555) */ + 3347, /* C57C (50556) */ + 3347, /* C57D (50557) */ + 3347, /* C57E (50558) */ + 3347, /* C57F (50559) */ + 3347, /* C580 (50560) */ + 3347, /* C581 (50561) */ + 3347, /* C582 (50562) */ + 3347, /* C583 (50563) */ + 3347, /* C584 (50564) */ + 3347, /* C585 (50565) */ + 3347, /* C586 (50566) */ + 3347, /* C587 (50567) */ + 3347, /* C588 (50568) */ + 3347, /* C589 (50569) */ + 3347, /* C58A (50570) */ + 3347, /* C58B (50571) */ + 3347, /* C58C (50572) */ + 3347, /* C58D (50573) */ + 3347, /* C58E (50574) */ + 3347, /* C58F (50575) */ + 3347, /* C590 (50576) */ + 3347, /* C591 (50577) */ + 3347, /* C592 (50578) */ + 3347, /* C593 (50579) */ + 3347, /* C594 (50580) */ + 3347, /* C595 (50581) */ + 3347, /* C596 (50582) */ + 3347, /* C597 (50583) */ + 3347, /* C598 (50584) */ + 3347, /* C599 (50585) */ + 3347, /* C59A (50586) */ + 3347, /* C59B (50587) */ + 3347, /* C59C (50588) */ + 3347, /* C59D (50589) */ + 3347, /* C59E (50590) */ + 3347, /* C59F (50591) */ + 3347, /* C5A0 (50592) */ + 3347, /* C5A1 (50593) */ + 3347, /* C5A2 (50594) */ + 3347, /* C5A3 (50595) */ + 3347, /* C5A4 (50596) */ + 3347, /* C5A5 (50597) */ + 3347, /* C5A6 (50598) */ + 3347, /* C5A7 (50599) */ + 3347, /* C5A8 (50600) */ + 3347, /* C5A9 (50601) */ + 3347, /* C5AA (50602) */ + 3347, /* C5AB (50603) */ + 3347, /* C5AC (50604) */ + 3347, /* C5AD (50605) */ + 3347, /* C5AE (50606) */ + 3347, /* C5AF (50607) */ + 3347, /* C5B0 (50608) */ + 3347, /* C5B1 (50609) */ + 3347, /* C5B2 (50610) */ + 3347, /* C5B3 (50611) */ + 3347, /* C5B4 (50612) */ + 3347, /* C5B5 (50613) */ + 3347, /* C5B6 (50614) */ + 3347, /* C5B7 (50615) */ + 3347, /* C5B8 (50616) */ + 3347, /* C5B9 (50617) */ + 3347, /* C5BA (50618) */ + 3347, /* C5BB (50619) */ + 3347, /* C5BC (50620) */ + 3347, /* C5BD (50621) */ + 3347, /* C5BE (50622) */ + 3347, /* C5BF (50623) */ + 3347, /* C5C0 (50624) */ + 3347, /* C5C1 (50625) */ + 3347, /* C5C2 (50626) */ + 3347, /* C5C3 (50627) */ + 3347, /* C5C4 (50628) */ + 3347, /* C5C5 (50629) */ + 3347, /* C5C6 (50630) */ + 3347, /* C5C7 (50631) */ + 3347, /* C5C8 (50632) */ + 3347, /* C5C9 (50633) */ + 3347, /* C5CA (50634) */ + 3347, /* C5CB (50635) */ + 3347, /* C5CC (50636) */ + 3347, /* C5CD (50637) */ + 3347, /* C5CE (50638) */ + 3347, /* C5CF (50639) */ + 3347, /* C5D0 (50640) */ + 3347, /* C5D1 (50641) */ + 3347, /* C5D2 (50642) */ + 3347, /* C5D3 (50643) */ + 3347, /* C5D4 (50644) */ + 3347, /* C5D5 (50645) */ + 3347, /* C5D6 (50646) */ + 3347, /* C5D7 (50647) */ + 3347, /* C5D8 (50648) */ + 3347, /* C5D9 (50649) */ + 3347, /* C5DA (50650) */ + 3347, /* C5DB (50651) */ + 3347, /* C5DC (50652) */ + 3347, /* C5DD (50653) */ + 3347, /* C5DE (50654) */ + 3347, /* C5DF (50655) */ + 3347, /* C5E0 (50656) */ + 3347, /* C5E1 (50657) */ + 3347, /* C5E2 (50658) */ + 3347, /* C5E3 (50659) */ + 3347, /* C5E4 (50660) */ + 3347, /* C5E5 (50661) */ + 3347, /* C5E6 (50662) */ + 3347, /* C5E7 (50663) */ + 3347, /* C5E8 (50664) */ + 3347, /* C5E9 (50665) */ + 3347, /* C5EA (50666) */ + 3347, /* C5EB (50667) */ + 3347, /* C5EC (50668) */ + 3347, /* C5ED (50669) */ + 3347, /* C5EE (50670) */ + 3347, /* C5EF (50671) */ + 3347, /* C5F0 (50672) */ + 3347, /* C5F1 (50673) */ + 3347, /* C5F2 (50674) */ + 3347, /* C5F3 (50675) */ + 3347, /* C5F4 (50676) */ + 3347, /* C5F5 (50677) */ + 3347, /* C5F6 (50678) */ + 3347, /* C5F7 (50679) */ + 3347, /* C5F8 (50680) */ + 3347, /* C5F9 (50681) */ + 3347, /* C5FA (50682) */ + 3347, /* C5FB (50683) */ + 3347, /* C5FC (50684) */ + 3347, /* C5FD (50685) */ + 3347, /* C5FE (50686) */ + 3347, /* C5FF (50687) */ + 3347, /* C600 (50688) */ + 3347, /* C601 (50689) */ + 3347, /* C602 (50690) */ + 3347, /* C603 (50691) */ + 3347, /* C604 (50692) */ + 3347, /* C605 (50693) */ + 3347, /* C606 (50694) */ + 3347, /* C607 (50695) */ + 3347, /* C608 (50696) */ + 3347, /* C609 (50697) */ + 3347, /* C60A (50698) */ + 3347, /* C60B (50699) */ + 3347, /* C60C (50700) */ + 3347, /* C60D (50701) */ + 3347, /* C60E (50702) */ + 3347, /* C60F (50703) */ + 3347, /* C610 (50704) */ + 3347, /* C611 (50705) */ + 3347, /* C612 (50706) */ + 3347, /* C613 (50707) */ + 3347, /* C614 (50708) */ + 3347, /* C615 (50709) */ + 3347, /* C616 (50710) */ + 3347, /* C617 (50711) */ + 3347, /* C618 (50712) */ + 3347, /* C619 (50713) */ + 3347, /* C61A (50714) */ + 3347, /* C61B (50715) */ + 3347, /* C61C (50716) */ + 3347, /* C61D (50717) */ + 3347, /* C61E (50718) */ + 3347, /* C61F (50719) */ + 3347, /* C620 (50720) */ + 3347, /* C621 (50721) */ + 3347, /* C622 (50722) */ + 3347, /* C623 (50723) */ + 3347, /* C624 (50724) */ + 3347, /* C625 (50725) */ + 3347, /* C626 (50726) */ + 3347, /* C627 (50727) */ + 3347, /* C628 (50728) */ + 3347, /* C629 (50729) */ + 3347, /* C62A (50730) */ + 3347, /* C62B (50731) */ + 3347, /* C62C (50732) */ + 3347, /* C62D (50733) */ + 3347, /* C62E (50734) */ + 3347, /* C62F (50735) */ + 3347, /* C630 (50736) */ + 3347, /* C631 (50737) */ + 3347, /* C632 (50738) */ + 3347, /* C633 (50739) */ + 3347, /* C634 (50740) */ + 3347, /* C635 (50741) */ + 3347, /* C636 (50742) */ + 3347, /* C637 (50743) */ + 3347, /* C638 (50744) */ + 3347, /* C639 (50745) */ + 3347, /* C63A (50746) */ + 3347, /* C63B (50747) */ + 3347, /* C63C (50748) */ + 3347, /* C63D (50749) */ + 3347, /* C63E (50750) */ + 3347, /* C63F (50751) */ + 3347, /* C640 (50752) */ + 3347, /* C641 (50753) */ + 3347, /* C642 (50754) */ + 3347, /* C643 (50755) */ + 3347, /* C644 (50756) */ + 3347, /* C645 (50757) */ + 3347, /* C646 (50758) */ + 3347, /* C647 (50759) */ + 3347, /* C648 (50760) */ + 3347, /* C649 (50761) */ + 3347, /* C64A (50762) */ + 3347, /* C64B (50763) */ + 3347, /* C64C (50764) */ + 3347, /* C64D (50765) */ + 3347, /* C64E (50766) */ + 3347, /* C64F (50767) */ + 3347, /* C650 (50768) */ + 3347, /* C651 (50769) */ + 3347, /* C652 (50770) */ + 3347, /* C653 (50771) */ + 3347, /* C654 (50772) */ + 3347, /* C655 (50773) */ + 3347, /* C656 (50774) */ + 3347, /* C657 (50775) */ + 3347, /* C658 (50776) */ + 3347, /* C659 (50777) */ + 3347, /* C65A (50778) */ + 3347, /* C65B (50779) */ + 3347, /* C65C (50780) */ + 3347, /* C65D (50781) */ + 3347, /* C65E (50782) */ + 3347, /* C65F (50783) */ + 3347, /* C660 (50784) */ + 3347, /* C661 (50785) */ + 3347, /* C662 (50786) */ + 3347, /* C663 (50787) */ + 3347, /* C664 (50788) */ + 3347, /* C665 (50789) */ + 3347, /* C666 (50790) */ + 3347, /* C667 (50791) */ + 3347, /* C668 (50792) */ + 3347, /* C669 (50793) */ + 3347, /* C66A (50794) */ + 3347, /* C66B (50795) */ + 3347, /* C66C (50796) */ + 3347, /* C66D (50797) */ + 3347, /* C66E (50798) */ + 3347, /* C66F (50799) */ + 3347, /* C670 (50800) */ + 3347, /* C671 (50801) */ + 3347, /* C672 (50802) */ + 3347, /* C673 (50803) */ + 3347, /* C674 (50804) */ + 3347, /* C675 (50805) */ + 3347, /* C676 (50806) */ + 3347, /* C677 (50807) */ + 3347, /* C678 (50808) */ + 3347, /* C679 (50809) */ + 3347, /* C67A (50810) */ + 3347, /* C67B (50811) */ + 3347, /* C67C (50812) */ + 3347, /* C67D (50813) */ + 3347, /* C67E (50814) */ + 3347, /* C67F (50815) */ + 3347, /* C680 (50816) */ + 3347, /* C681 (50817) */ + 3347, /* C682 (50818) */ + 3347, /* C683 (50819) */ + 3347, /* C684 (50820) */ + 3347, /* C685 (50821) */ + 3347, /* C686 (50822) */ + 3347, /* C687 (50823) */ + 3347, /* C688 (50824) */ + 3347, /* C689 (50825) */ + 3347, /* C68A (50826) */ + 3347, /* C68B (50827) */ + 3347, /* C68C (50828) */ + 3347, /* C68D (50829) */ + 3347, /* C68E (50830) */ + 3347, /* C68F (50831) */ + 3347, /* C690 (50832) */ + 3347, /* C691 (50833) */ + 3347, /* C692 (50834) */ + 3347, /* C693 (50835) */ + 3347, /* C694 (50836) */ + 3347, /* C695 (50837) */ + 3347, /* C696 (50838) */ + 3347, /* C697 (50839) */ + 3347, /* C698 (50840) */ + 3347, /* C699 (50841) */ + 3347, /* C69A (50842) */ + 3347, /* C69B (50843) */ + 3347, /* C69C (50844) */ + 3347, /* C69D (50845) */ + 3347, /* C69E (50846) */ + 3347, /* C69F (50847) */ + 3347, /* C6A0 (50848) */ + 3347, /* C6A1 (50849) */ + 3347, /* C6A2 (50850) */ + 3347, /* C6A3 (50851) */ + 3347, /* C6A4 (50852) */ + 3347, /* C6A5 (50853) */ + 3347, /* C6A6 (50854) */ + 3347, /* C6A7 (50855) */ + 3347, /* C6A8 (50856) */ + 3347, /* C6A9 (50857) */ + 3347, /* C6AA (50858) */ + 3347, /* C6AB (50859) */ + 3347, /* C6AC (50860) */ + 3347, /* C6AD (50861) */ + 3347, /* C6AE (50862) */ + 3347, /* C6AF (50863) */ + 3347, /* C6B0 (50864) */ + 3347, /* C6B1 (50865) */ + 3347, /* C6B2 (50866) */ + 3347, /* C6B3 (50867) */ + 3347, /* C6B4 (50868) */ + 3347, /* C6B5 (50869) */ + 3347, /* C6B6 (50870) */ + 3347, /* C6B7 (50871) */ + 3347, /* C6B8 (50872) */ + 3347, /* C6B9 (50873) */ + 3347, /* C6BA (50874) */ + 3347, /* C6BB (50875) */ + 3347, /* C6BC (50876) */ + 3347, /* C6BD (50877) */ + 3347, /* C6BE (50878) */ + 3347, /* C6BF (50879) */ + 3347, /* C6C0 (50880) */ + 3347, /* C6C1 (50881) */ + 3347, /* C6C2 (50882) */ + 3347, /* C6C3 (50883) */ + 3347, /* C6C4 (50884) */ + 3347, /* C6C5 (50885) */ + 3347, /* C6C6 (50886) */ + 3347, /* C6C7 (50887) */ + 3347, /* C6C8 (50888) */ + 3347, /* C6C9 (50889) */ + 3347, /* C6CA (50890) */ + 3347, /* C6CB (50891) */ + 3347, /* C6CC (50892) */ + 3347, /* C6CD (50893) */ + 3347, /* C6CE (50894) */ + 3347, /* C6CF (50895) */ + 3347, /* C6D0 (50896) */ + 3347, /* C6D1 (50897) */ + 3347, /* C6D2 (50898) */ + 3347, /* C6D3 (50899) */ + 3347, /* C6D4 (50900) */ + 3347, /* C6D5 (50901) */ + 3347, /* C6D6 (50902) */ + 3347, /* C6D7 (50903) */ + 3347, /* C6D8 (50904) */ + 3347, /* C6D9 (50905) */ + 3347, /* C6DA (50906) */ + 3347, /* C6DB (50907) */ + 3347, /* C6DC (50908) */ + 3347, /* C6DD (50909) */ + 3347, /* C6DE (50910) */ + 3347, /* C6DF (50911) */ + 3347, /* C6E0 (50912) */ + 3347, /* C6E1 (50913) */ + 3347, /* C6E2 (50914) */ + 3347, /* C6E3 (50915) */ + 3347, /* C6E4 (50916) */ + 3347, /* C6E5 (50917) */ + 3347, /* C6E6 (50918) */ + 3347, /* C6E7 (50919) */ + 3347, /* C6E8 (50920) */ + 3347, /* C6E9 (50921) */ + 3347, /* C6EA (50922) */ + 3347, /* C6EB (50923) */ + 3347, /* C6EC (50924) */ + 3347, /* C6ED (50925) */ + 3347, /* C6EE (50926) */ + 3347, /* C6EF (50927) */ + 3347, /* C6F0 (50928) */ + 3347, /* C6F1 (50929) */ + 3347, /* C6F2 (50930) */ + 3347, /* C6F3 (50931) */ + 3347, /* C6F4 (50932) */ + 3347, /* C6F5 (50933) */ + 3347, /* C6F6 (50934) */ + 3347, /* C6F7 (50935) */ + 3347, /* C6F8 (50936) */ + 3347, /* C6F9 (50937) */ + 3347, /* C6FA (50938) */ + 3347, /* C6FB (50939) */ + 3347, /* C6FC (50940) */ + 3347, /* C6FD (50941) */ + 3347, /* C6FE (50942) */ + 3347, /* C6FF (50943) */ + 3347, /* C700 (50944) */ + 3347, /* C701 (50945) */ + 3347, /* C702 (50946) */ + 3347, /* C703 (50947) */ + 3347, /* C704 (50948) */ + 3347, /* C705 (50949) */ + 3347, /* C706 (50950) */ + 3347, /* C707 (50951) */ + 3347, /* C708 (50952) */ + 3347, /* C709 (50953) */ + 3347, /* C70A (50954) */ + 3347, /* C70B (50955) */ + 3347, /* C70C (50956) */ + 3347, /* C70D (50957) */ + 3347, /* C70E (50958) */ + 3347, /* C70F (50959) */ + 3347, /* C710 (50960) */ + 3347, /* C711 (50961) */ + 3347, /* C712 (50962) */ + 3347, /* C713 (50963) */ + 3347, /* C714 (50964) */ + 3347, /* C715 (50965) */ + 3347, /* C716 (50966) */ + 3347, /* C717 (50967) */ + 3347, /* C718 (50968) */ + 3347, /* C719 (50969) */ + 3347, /* C71A (50970) */ + 3347, /* C71B (50971) */ + 3347, /* C71C (50972) */ + 3347, /* C71D (50973) */ + 3347, /* C71E (50974) */ + 3347, /* C71F (50975) */ + 3347, /* C720 (50976) */ + 3347, /* C721 (50977) */ + 3347, /* C722 (50978) */ + 3347, /* C723 (50979) */ + 3347, /* C724 (50980) */ + 3347, /* C725 (50981) */ + 3347, /* C726 (50982) */ + 3347, /* C727 (50983) */ + 3347, /* C728 (50984) */ + 3347, /* C729 (50985) */ + 3347, /* C72A (50986) */ + 3347, /* C72B (50987) */ + 3347, /* C72C (50988) */ + 3347, /* C72D (50989) */ + 3347, /* C72E (50990) */ + 3347, /* C72F (50991) */ + 3347, /* C730 (50992) */ + 3347, /* C731 (50993) */ + 3347, /* C732 (50994) */ + 3347, /* C733 (50995) */ + 3347, /* C734 (50996) */ + 3347, /* C735 (50997) */ + 3347, /* C736 (50998) */ + 3347, /* C737 (50999) */ + 3347, /* C738 (51000) */ + 3347, /* C739 (51001) */ + 3347, /* C73A (51002) */ + 3347, /* C73B (51003) */ + 3347, /* C73C (51004) */ + 3347, /* C73D (51005) */ + 3347, /* C73E (51006) */ + 3347, /* C73F (51007) */ + 3347, /* C740 (51008) */ + 3347, /* C741 (51009) */ + 3347, /* C742 (51010) */ + 3347, /* C743 (51011) */ + 3347, /* C744 (51012) */ + 3347, /* C745 (51013) */ + 3347, /* C746 (51014) */ + 3347, /* C747 (51015) */ + 3347, /* C748 (51016) */ + 3347, /* C749 (51017) */ + 3347, /* C74A (51018) */ + 3347, /* C74B (51019) */ + 3347, /* C74C (51020) */ + 3347, /* C74D (51021) */ + 3347, /* C74E (51022) */ + 3347, /* C74F (51023) */ + 3347, /* C750 (51024) */ + 3347, /* C751 (51025) */ + 3347, /* C752 (51026) */ + 3347, /* C753 (51027) */ + 3347, /* C754 (51028) */ + 3347, /* C755 (51029) */ + 3347, /* C756 (51030) */ + 3347, /* C757 (51031) */ + 3347, /* C758 (51032) */ + 3347, /* C759 (51033) */ + 3347, /* C75A (51034) */ + 3347, /* C75B (51035) */ + 3347, /* C75C (51036) */ + 3347, /* C75D (51037) */ + 3347, /* C75E (51038) */ + 3347, /* C75F (51039) */ + 3347, /* C760 (51040) */ + 3347, /* C761 (51041) */ + 3347, /* C762 (51042) */ + 3347, /* C763 (51043) */ + 3347, /* C764 (51044) */ + 3347, /* C765 (51045) */ + 3347, /* C766 (51046) */ + 3347, /* C767 (51047) */ + 3347, /* C768 (51048) */ + 3347, /* C769 (51049) */ + 3347, /* C76A (51050) */ + 3347, /* C76B (51051) */ + 3347, /* C76C (51052) */ + 3347, /* C76D (51053) */ + 3347, /* C76E (51054) */ + 3347, /* C76F (51055) */ + 3347, /* C770 (51056) */ + 3347, /* C771 (51057) */ + 3347, /* C772 (51058) */ + 3347, /* C773 (51059) */ + 3347, /* C774 (51060) */ + 3347, /* C775 (51061) */ + 3347, /* C776 (51062) */ + 3347, /* C777 (51063) */ + 3347, /* C778 (51064) */ + 3347, /* C779 (51065) */ + 3347, /* C77A (51066) */ + 3347, /* C77B (51067) */ + 3347, /* C77C (51068) */ + 3347, /* C77D (51069) */ + 3347, /* C77E (51070) */ + 3347, /* C77F (51071) */ + 3347, /* C780 (51072) */ + 3347, /* C781 (51073) */ + 3347, /* C782 (51074) */ + 3347, /* C783 (51075) */ + 3347, /* C784 (51076) */ + 3347, /* C785 (51077) */ + 3347, /* C786 (51078) */ + 3347, /* C787 (51079) */ + 3347, /* C788 (51080) */ + 3347, /* C789 (51081) */ + 3347, /* C78A (51082) */ + 3347, /* C78B (51083) */ + 3347, /* C78C (51084) */ + 3347, /* C78D (51085) */ + 3347, /* C78E (51086) */ + 3347, /* C78F (51087) */ + 3347, /* C790 (51088) */ + 3347, /* C791 (51089) */ + 3347, /* C792 (51090) */ + 3347, /* C793 (51091) */ + 3347, /* C794 (51092) */ + 3347, /* C795 (51093) */ + 3347, /* C796 (51094) */ + 3347, /* C797 (51095) */ + 3347, /* C798 (51096) */ + 3347, /* C799 (51097) */ + 3347, /* C79A (51098) */ + 3347, /* C79B (51099) */ + 3347, /* C79C (51100) */ + 3347, /* C79D (51101) */ + 3347, /* C79E (51102) */ + 3347, /* C79F (51103) */ + 3347, /* C7A0 (51104) */ + 3347, /* C7A1 (51105) */ + 3347, /* C7A2 (51106) */ + 3347, /* C7A3 (51107) */ + 3347, /* C7A4 (51108) */ + 3347, /* C7A5 (51109) */ + 3347, /* C7A6 (51110) */ + 3347, /* C7A7 (51111) */ + 3347, /* C7A8 (51112) */ + 3347, /* C7A9 (51113) */ + 3347, /* C7AA (51114) */ + 3347, /* C7AB (51115) */ + 3347, /* C7AC (51116) */ + 3347, /* C7AD (51117) */ + 3347, /* C7AE (51118) */ + 3347, /* C7AF (51119) */ + 3347, /* C7B0 (51120) */ + 3347, /* C7B1 (51121) */ + 3347, /* C7B2 (51122) */ + 3347, /* C7B3 (51123) */ + 3347, /* C7B4 (51124) */ + 3347, /* C7B5 (51125) */ + 3347, /* C7B6 (51126) */ + 3347, /* C7B7 (51127) */ + 3347, /* C7B8 (51128) */ + 3347, /* C7B9 (51129) */ + 3347, /* C7BA (51130) */ + 3347, /* C7BB (51131) */ + 3347, /* C7BC (51132) */ + 3347, /* C7BD (51133) */ + 3347, /* C7BE (51134) */ + 3347, /* C7BF (51135) */ + 3347, /* C7C0 (51136) */ + 3347, /* C7C1 (51137) */ + 3347, /* C7C2 (51138) */ + 3347, /* C7C3 (51139) */ + 3347, /* C7C4 (51140) */ + 3347, /* C7C5 (51141) */ + 3347, /* C7C6 (51142) */ + 3347, /* C7C7 (51143) */ + 3347, /* C7C8 (51144) */ + 3347, /* C7C9 (51145) */ + 3347, /* C7CA (51146) */ + 3347, /* C7CB (51147) */ + 3347, /* C7CC (51148) */ + 3347, /* C7CD (51149) */ + 3347, /* C7CE (51150) */ + 3347, /* C7CF (51151) */ + 3347, /* C7D0 (51152) */ + 3347, /* C7D1 (51153) */ + 3347, /* C7D2 (51154) */ + 3347, /* C7D3 (51155) */ + 3347, /* C7D4 (51156) */ + 3347, /* C7D5 (51157) */ + 3347, /* C7D6 (51158) */ + 3347, /* C7D7 (51159) */ + 3347, /* C7D8 (51160) */ + 3347, /* C7D9 (51161) */ + 3347, /* C7DA (51162) */ + 3347, /* C7DB (51163) */ + 3347, /* C7DC (51164) */ + 3347, /* C7DD (51165) */ + 3347, /* C7DE (51166) */ + 3347, /* C7DF (51167) */ + 3347, /* C7E0 (51168) */ + 3347, /* C7E1 (51169) */ + 3347, /* C7E2 (51170) */ + 3347, /* C7E3 (51171) */ + 3347, /* C7E4 (51172) */ + 3347, /* C7E5 (51173) */ + 3347, /* C7E6 (51174) */ + 3347, /* C7E7 (51175) */ + 3347, /* C7E8 (51176) */ + 3347, /* C7E9 (51177) */ + 3347, /* C7EA (51178) */ + 3347, /* C7EB (51179) */ + 3347, /* C7EC (51180) */ + 3347, /* C7ED (51181) */ + 3347, /* C7EE (51182) */ + 3347, /* C7EF (51183) */ + 3347, /* C7F0 (51184) */ + 3347, /* C7F1 (51185) */ + 3347, /* C7F2 (51186) */ + 3347, /* C7F3 (51187) */ + 3347, /* C7F4 (51188) */ + 3347, /* C7F5 (51189) */ + 3347, /* C7F6 (51190) */ + 3347, /* C7F7 (51191) */ + 3347, /* C7F8 (51192) */ + 3347, /* C7F9 (51193) */ + 3347, /* C7FA (51194) */ + 3347, /* C7FB (51195) */ + 3347, /* C7FC (51196) */ + 3347, /* C7FD (51197) */ + 3347, /* C7FE (51198) */ + 3347, /* C7FF (51199) */ + 3347, /* C800 (51200) */ + 3347, /* C801 (51201) */ + 3347, /* C802 (51202) */ + 3347, /* C803 (51203) */ + 3347, /* C804 (51204) */ + 3347, /* C805 (51205) */ + 3347, /* C806 (51206) */ + 3347, /* C807 (51207) */ + 3347, /* C808 (51208) */ + 3347, /* C809 (51209) */ + 3347, /* C80A (51210) */ + 3347, /* C80B (51211) */ + 3347, /* C80C (51212) */ + 3347, /* C80D (51213) */ + 3347, /* C80E (51214) */ + 3347, /* C80F (51215) */ + 3347, /* C810 (51216) */ + 3347, /* C811 (51217) */ + 3347, /* C812 (51218) */ + 3347, /* C813 (51219) */ + 3347, /* C814 (51220) */ + 3347, /* C815 (51221) */ + 3347, /* C816 (51222) */ + 3347, /* C817 (51223) */ + 3347, /* C818 (51224) */ + 3347, /* C819 (51225) */ + 3347, /* C81A (51226) */ + 3347, /* C81B (51227) */ + 3347, /* C81C (51228) */ + 3347, /* C81D (51229) */ + 3347, /* C81E (51230) */ + 3347, /* C81F (51231) */ + 3347, /* C820 (51232) */ + 3347, /* C821 (51233) */ + 3347, /* C822 (51234) */ + 3347, /* C823 (51235) */ + 3347, /* C824 (51236) */ + 3347, /* C825 (51237) */ + 3347, /* C826 (51238) */ + 3347, /* C827 (51239) */ + 3347, /* C828 (51240) */ + 3347, /* C829 (51241) */ + 3347, /* C82A (51242) */ + 3347, /* C82B (51243) */ + 3347, /* C82C (51244) */ + 3347, /* C82D (51245) */ + 3347, /* C82E (51246) */ + 3347, /* C82F (51247) */ + 3347, /* C830 (51248) */ + 3347, /* C831 (51249) */ + 3347, /* C832 (51250) */ + 3347, /* C833 (51251) */ + 3347, /* C834 (51252) */ + 3347, /* C835 (51253) */ + 3347, /* C836 (51254) */ + 3347, /* C837 (51255) */ + 3347, /* C838 (51256) */ + 3347, /* C839 (51257) */ + 3347, /* C83A (51258) */ + 3347, /* C83B (51259) */ + 3347, /* C83C (51260) */ + 3347, /* C83D (51261) */ + 3347, /* C83E (51262) */ + 3347, /* C83F (51263) */ + 3347, /* C840 (51264) */ + 3347, /* C841 (51265) */ + 3347, /* C842 (51266) */ + 3347, /* C843 (51267) */ + 3347, /* C844 (51268) */ + 3347, /* C845 (51269) */ + 3347, /* C846 (51270) */ + 3347, /* C847 (51271) */ + 3347, /* C848 (51272) */ + 3347, /* C849 (51273) */ + 3347, /* C84A (51274) */ + 3347, /* C84B (51275) */ + 3347, /* C84C (51276) */ + 3347, /* C84D (51277) */ + 3347, /* C84E (51278) */ + 3347, /* C84F (51279) */ + 3347, /* C850 (51280) */ + 3347, /* C851 (51281) */ + 3347, /* C852 (51282) */ + 3347, /* C853 (51283) */ + 3347, /* C854 (51284) */ + 3347, /* C855 (51285) */ + 3347, /* C856 (51286) */ + 3347, /* C857 (51287) */ + 3347, /* C858 (51288) */ + 3347, /* C859 (51289) */ + 3347, /* C85A (51290) */ + 3347, /* C85B (51291) */ + 3347, /* C85C (51292) */ + 3347, /* C85D (51293) */ + 3347, /* C85E (51294) */ + 3347, /* C85F (51295) */ + 3347, /* C860 (51296) */ + 3347, /* C861 (51297) */ + 3347, /* C862 (51298) */ + 3347, /* C863 (51299) */ + 3347, /* C864 (51300) */ + 3347, /* C865 (51301) */ + 3347, /* C866 (51302) */ + 3347, /* C867 (51303) */ + 3347, /* C868 (51304) */ + 3347, /* C869 (51305) */ + 3347, /* C86A (51306) */ + 3347, /* C86B (51307) */ + 3347, /* C86C (51308) */ + 3347, /* C86D (51309) */ + 3347, /* C86E (51310) */ + 3347, /* C86F (51311) */ + 3347, /* C870 (51312) */ + 3347, /* C871 (51313) */ + 3347, /* C872 (51314) */ + 3347, /* C873 (51315) */ + 3347, /* C874 (51316) */ + 3347, /* C875 (51317) */ + 3347, /* C876 (51318) */ + 3347, /* C877 (51319) */ + 3347, /* C878 (51320) */ + 3347, /* C879 (51321) */ + 3347, /* C87A (51322) */ + 3347, /* C87B (51323) */ + 3347, /* C87C (51324) */ + 3347, /* C87D (51325) */ + 3347, /* C87E (51326) */ + 3347, /* C87F (51327) */ + 3347, /* C880 (51328) */ + 3347, /* C881 (51329) */ + 3347, /* C882 (51330) */ + 3347, /* C883 (51331) */ + 3347, /* C884 (51332) */ + 3347, /* C885 (51333) */ + 3347, /* C886 (51334) */ + 3347, /* C887 (51335) */ + 3347, /* C888 (51336) */ + 3347, /* C889 (51337) */ + 3347, /* C88A (51338) */ + 3347, /* C88B (51339) */ + 3347, /* C88C (51340) */ + 3347, /* C88D (51341) */ + 3347, /* C88E (51342) */ + 3347, /* C88F (51343) */ + 3347, /* C890 (51344) */ + 3347, /* C891 (51345) */ + 3347, /* C892 (51346) */ + 3347, /* C893 (51347) */ + 3347, /* C894 (51348) */ + 3347, /* C895 (51349) */ + 3347, /* C896 (51350) */ + 3347, /* C897 (51351) */ + 3347, /* C898 (51352) */ + 3347, /* C899 (51353) */ + 3347, /* C89A (51354) */ + 3347, /* C89B (51355) */ + 3347, /* C89C (51356) */ + 3347, /* C89D (51357) */ + 3347, /* C89E (51358) */ + 3347, /* C89F (51359) */ + 3347, /* C8A0 (51360) */ + 3347, /* C8A1 (51361) */ + 3347, /* C8A2 (51362) */ + 3347, /* C8A3 (51363) */ + 3347, /* C8A4 (51364) */ + 3347, /* C8A5 (51365) */ + 3347, /* C8A6 (51366) */ + 3347, /* C8A7 (51367) */ + 3347, /* C8A8 (51368) */ + 3347, /* C8A9 (51369) */ + 3347, /* C8AA (51370) */ + 3347, /* C8AB (51371) */ + 3347, /* C8AC (51372) */ + 3347, /* C8AD (51373) */ + 3347, /* C8AE (51374) */ + 3347, /* C8AF (51375) */ + 3347, /* C8B0 (51376) */ + 3347, /* C8B1 (51377) */ + 3347, /* C8B2 (51378) */ + 3347, /* C8B3 (51379) */ + 3347, /* C8B4 (51380) */ + 3347, /* C8B5 (51381) */ + 3347, /* C8B6 (51382) */ + 3347, /* C8B7 (51383) */ + 3347, /* C8B8 (51384) */ + 3347, /* C8B9 (51385) */ + 3347, /* C8BA (51386) */ + 3347, /* C8BB (51387) */ + 3347, /* C8BC (51388) */ + 3347, /* C8BD (51389) */ + 3347, /* C8BE (51390) */ + 3347, /* C8BF (51391) */ + 3347, /* C8C0 (51392) */ + 3347, /* C8C1 (51393) */ + 3347, /* C8C2 (51394) */ + 3347, /* C8C3 (51395) */ + 3347, /* C8C4 (51396) */ + 3347, /* C8C5 (51397) */ + 3347, /* C8C6 (51398) */ + 3347, /* C8C7 (51399) */ + 3347, /* C8C8 (51400) */ + 3347, /* C8C9 (51401) */ + 3347, /* C8CA (51402) */ + 3347, /* C8CB (51403) */ + 3347, /* C8CC (51404) */ + 3347, /* C8CD (51405) */ + 3347, /* C8CE (51406) */ + 3347, /* C8CF (51407) */ + 3347, /* C8D0 (51408) */ + 3347, /* C8D1 (51409) */ + 3347, /* C8D2 (51410) */ + 3347, /* C8D3 (51411) */ + 3347, /* C8D4 (51412) */ + 3347, /* C8D5 (51413) */ + 3347, /* C8D6 (51414) */ + 3347, /* C8D7 (51415) */ + 3347, /* C8D8 (51416) */ + 3347, /* C8D9 (51417) */ + 3347, /* C8DA (51418) */ + 3347, /* C8DB (51419) */ + 3347, /* C8DC (51420) */ + 3347, /* C8DD (51421) */ + 3347, /* C8DE (51422) */ + 3347, /* C8DF (51423) */ + 3347, /* C8E0 (51424) */ + 3347, /* C8E1 (51425) */ + 3347, /* C8E2 (51426) */ + 3347, /* C8E3 (51427) */ + 3347, /* C8E4 (51428) */ + 3347, /* C8E5 (51429) */ + 3347, /* C8E6 (51430) */ + 3347, /* C8E7 (51431) */ + 3347, /* C8E8 (51432) */ + 3347, /* C8E9 (51433) */ + 3347, /* C8EA (51434) */ + 3347, /* C8EB (51435) */ + 3347, /* C8EC (51436) */ + 3347, /* C8ED (51437) */ + 3347, /* C8EE (51438) */ + 3347, /* C8EF (51439) */ + 3347, /* C8F0 (51440) */ + 3347, /* C8F1 (51441) */ + 3347, /* C8F2 (51442) */ + 3347, /* C8F3 (51443) */ + 3347, /* C8F4 (51444) */ + 3347, /* C8F5 (51445) */ + 3347, /* C8F6 (51446) */ + 3347, /* C8F7 (51447) */ + 3347, /* C8F8 (51448) */ + 3347, /* C8F9 (51449) */ + 3347, /* C8FA (51450) */ + 3347, /* C8FB (51451) */ + 3347, /* C8FC (51452) */ + 3347, /* C8FD (51453) */ + 3347, /* C8FE (51454) */ + 3347, /* C8FF (51455) */ + 3347, /* C900 (51456) */ + 3347, /* C901 (51457) */ + 3347, /* C902 (51458) */ + 3347, /* C903 (51459) */ + 3347, /* C904 (51460) */ + 3347, /* C905 (51461) */ + 3347, /* C906 (51462) */ + 3347, /* C907 (51463) */ + 3347, /* C908 (51464) */ + 3347, /* C909 (51465) */ + 3347, /* C90A (51466) */ + 3347, /* C90B (51467) */ + 3347, /* C90C (51468) */ + 3347, /* C90D (51469) */ + 3347, /* C90E (51470) */ + 3347, /* C90F (51471) */ + 3347, /* C910 (51472) */ + 3347, /* C911 (51473) */ + 3347, /* C912 (51474) */ + 3347, /* C913 (51475) */ + 3347, /* C914 (51476) */ + 3347, /* C915 (51477) */ + 3347, /* C916 (51478) */ + 3347, /* C917 (51479) */ + 3347, /* C918 (51480) */ + 3347, /* C919 (51481) */ + 3347, /* C91A (51482) */ + 3347, /* C91B (51483) */ + 3347, /* C91C (51484) */ + 3347, /* C91D (51485) */ + 3347, /* C91E (51486) */ + 3347, /* C91F (51487) */ + 3347, /* C920 (51488) */ + 3347, /* C921 (51489) */ + 3347, /* C922 (51490) */ + 3347, /* C923 (51491) */ + 3347, /* C924 (51492) */ + 3347, /* C925 (51493) */ + 3347, /* C926 (51494) */ + 3347, /* C927 (51495) */ + 3347, /* C928 (51496) */ + 3347, /* C929 (51497) */ + 3347, /* C92A (51498) */ + 3347, /* C92B (51499) */ + 3347, /* C92C (51500) */ + 3347, /* C92D (51501) */ + 3347, /* C92E (51502) */ + 3347, /* C92F (51503) */ + 3347, /* C930 (51504) */ + 3347, /* C931 (51505) */ + 3347, /* C932 (51506) */ + 3347, /* C933 (51507) */ + 3347, /* C934 (51508) */ + 3347, /* C935 (51509) */ + 3347, /* C936 (51510) */ + 3347, /* C937 (51511) */ + 3347, /* C938 (51512) */ + 3347, /* C939 (51513) */ + 3347, /* C93A (51514) */ + 3347, /* C93B (51515) */ + 3347, /* C93C (51516) */ + 3347, /* C93D (51517) */ + 3347, /* C93E (51518) */ + 3347, /* C93F (51519) */ + 3347, /* C940 (51520) */ + 3347, /* C941 (51521) */ + 3347, /* C942 (51522) */ + 3347, /* C943 (51523) */ + 3347, /* C944 (51524) */ + 3347, /* C945 (51525) */ + 3347, /* C946 (51526) */ + 3347, /* C947 (51527) */ + 3347, /* C948 (51528) */ + 3347, /* C949 (51529) */ + 3347, /* C94A (51530) */ + 3347, /* C94B (51531) */ + 3347, /* C94C (51532) */ + 3347, /* C94D (51533) */ + 3347, /* C94E (51534) */ + 3347, /* C94F (51535) */ + 3347, /* C950 (51536) */ + 3347, /* C951 (51537) */ + 3347, /* C952 (51538) */ + 3347, /* C953 (51539) */ + 3347, /* C954 (51540) */ + 3347, /* C955 (51541) */ + 3347, /* C956 (51542) */ + 3347, /* C957 (51543) */ + 3347, /* C958 (51544) */ + 3347, /* C959 (51545) */ + 3347, /* C95A (51546) */ + 3347, /* C95B (51547) */ + 3347, /* C95C (51548) */ + 3347, /* C95D (51549) */ + 3347, /* C95E (51550) */ + 3347, /* C95F (51551) */ + 3347, /* C960 (51552) */ + 3347, /* C961 (51553) */ + 3347, /* C962 (51554) */ + 3347, /* C963 (51555) */ + 3347, /* C964 (51556) */ + 3347, /* C965 (51557) */ + 3347, /* C966 (51558) */ + 3347, /* C967 (51559) */ + 3347, /* C968 (51560) */ + 3347, /* C969 (51561) */ + 3347, /* C96A (51562) */ + 3347, /* C96B (51563) */ + 3347, /* C96C (51564) */ + 3347, /* C96D (51565) */ + 3347, /* C96E (51566) */ + 3347, /* C96F (51567) */ + 3347, /* C970 (51568) */ + 3347, /* C971 (51569) */ + 3347, /* C972 (51570) */ + 3347, /* C973 (51571) */ + 3347, /* C974 (51572) */ + 3347, /* C975 (51573) */ + 3347, /* C976 (51574) */ + 3347, /* C977 (51575) */ + 3347, /* C978 (51576) */ + 3347, /* C979 (51577) */ + 3347, /* C97A (51578) */ + 3347, /* C97B (51579) */ + 3347, /* C97C (51580) */ + 3347, /* C97D (51581) */ + 3347, /* C97E (51582) */ + 3347, /* C97F (51583) */ + 3347, /* C980 (51584) */ + 3347, /* C981 (51585) */ + 3347, /* C982 (51586) */ + 3347, /* C983 (51587) */ + 3347, /* C984 (51588) */ + 3347, /* C985 (51589) */ + 3347, /* C986 (51590) */ + 3347, /* C987 (51591) */ + 3347, /* C988 (51592) */ + 3347, /* C989 (51593) */ + 3347, /* C98A (51594) */ + 3347, /* C98B (51595) */ + 3347, /* C98C (51596) */ + 3347, /* C98D (51597) */ + 3347, /* C98E (51598) */ + 3347, /* C98F (51599) */ + 3347, /* C990 (51600) */ + 3347, /* C991 (51601) */ + 3347, /* C992 (51602) */ + 3347, /* C993 (51603) */ + 3347, /* C994 (51604) */ + 3347, /* C995 (51605) */ + 3347, /* C996 (51606) */ + 3347, /* C997 (51607) */ + 3347, /* C998 (51608) */ + 3347, /* C999 (51609) */ + 3347, /* C99A (51610) */ + 3347, /* C99B (51611) */ + 3347, /* C99C (51612) */ + 3347, /* C99D (51613) */ + 3347, /* C99E (51614) */ + 3347, /* C99F (51615) */ + 3347, /* C9A0 (51616) */ + 3347, /* C9A1 (51617) */ + 3347, /* C9A2 (51618) */ + 3347, /* C9A3 (51619) */ + 3347, /* C9A4 (51620) */ + 3347, /* C9A5 (51621) */ + 3347, /* C9A6 (51622) */ + 3347, /* C9A7 (51623) */ + 3347, /* C9A8 (51624) */ + 3347, /* C9A9 (51625) */ + 3347, /* C9AA (51626) */ + 3347, /* C9AB (51627) */ + 3347, /* C9AC (51628) */ + 3347, /* C9AD (51629) */ + 3347, /* C9AE (51630) */ + 3347, /* C9AF (51631) */ + 3347, /* C9B0 (51632) */ + 3347, /* C9B1 (51633) */ + 3347, /* C9B2 (51634) */ + 3347, /* C9B3 (51635) */ + 3347, /* C9B4 (51636) */ + 3347, /* C9B5 (51637) */ + 3347, /* C9B6 (51638) */ + 3347, /* C9B7 (51639) */ + 3347, /* C9B8 (51640) */ + 3347, /* C9B9 (51641) */ + 3347, /* C9BA (51642) */ + 3347, /* C9BB (51643) */ + 3347, /* C9BC (51644) */ + 3347, /* C9BD (51645) */ + 3347, /* C9BE (51646) */ + 3347, /* C9BF (51647) */ + 3347, /* C9C0 (51648) */ + 3347, /* C9C1 (51649) */ + 3347, /* C9C2 (51650) */ + 3347, /* C9C3 (51651) */ + 3347, /* C9C4 (51652) */ + 3347, /* C9C5 (51653) */ + 3347, /* C9C6 (51654) */ + 3347, /* C9C7 (51655) */ + 3347, /* C9C8 (51656) */ + 3347, /* C9C9 (51657) */ + 3347, /* C9CA (51658) */ + 3347, /* C9CB (51659) */ + 3347, /* C9CC (51660) */ + 3347, /* C9CD (51661) */ + 3347, /* C9CE (51662) */ + 3347, /* C9CF (51663) */ + 3347, /* C9D0 (51664) */ + 3347, /* C9D1 (51665) */ + 3347, /* C9D2 (51666) */ + 3347, /* C9D3 (51667) */ + 3347, /* C9D4 (51668) */ + 3347, /* C9D5 (51669) */ + 3347, /* C9D6 (51670) */ + 3347, /* C9D7 (51671) */ + 3347, /* C9D8 (51672) */ + 3347, /* C9D9 (51673) */ + 3347, /* C9DA (51674) */ + 3347, /* C9DB (51675) */ + 3347, /* C9DC (51676) */ + 3347, /* C9DD (51677) */ + 3347, /* C9DE (51678) */ + 3347, /* C9DF (51679) */ + 3347, /* C9E0 (51680) */ + 3347, /* C9E1 (51681) */ + 3347, /* C9E2 (51682) */ + 3347, /* C9E3 (51683) */ + 3347, /* C9E4 (51684) */ + 3347, /* C9E5 (51685) */ + 3347, /* C9E6 (51686) */ + 3347, /* C9E7 (51687) */ + 3347, /* C9E8 (51688) */ + 3347, /* C9E9 (51689) */ + 3347, /* C9EA (51690) */ + 3347, /* C9EB (51691) */ + 3347, /* C9EC (51692) */ + 3347, /* C9ED (51693) */ + 3347, /* C9EE (51694) */ + 3347, /* C9EF (51695) */ + 3347, /* C9F0 (51696) */ + 3347, /* C9F1 (51697) */ + 3347, /* C9F2 (51698) */ + 3347, /* C9F3 (51699) */ + 3347, /* C9F4 (51700) */ + 3347, /* C9F5 (51701) */ + 3347, /* C9F6 (51702) */ + 3347, /* C9F7 (51703) */ + 3347, /* C9F8 (51704) */ + 3347, /* C9F9 (51705) */ + 3347, /* C9FA (51706) */ + 3347, /* C9FB (51707) */ + 3347, /* C9FC (51708) */ + 3347, /* C9FD (51709) */ + 3347, /* C9FE (51710) */ + 3347, /* C9FF (51711) */ + 3347, /* CA00 (51712) */ + 3347, /* CA01 (51713) */ + 3347, /* CA02 (51714) */ + 3347, /* CA03 (51715) */ + 3347, /* CA04 (51716) */ + 3347, /* CA05 (51717) */ + 3347, /* CA06 (51718) */ + 3347, /* CA07 (51719) */ + 3347, /* CA08 (51720) */ + 3347, /* CA09 (51721) */ + 3347, /* CA0A (51722) */ + 3347, /* CA0B (51723) */ + 3347, /* CA0C (51724) */ + 3347, /* CA0D (51725) */ + 3347, /* CA0E (51726) */ + 3347, /* CA0F (51727) */ + 3347, /* CA10 (51728) */ + 3347, /* CA11 (51729) */ + 3347, /* CA12 (51730) */ + 3347, /* CA13 (51731) */ + 3347, /* CA14 (51732) */ + 3347, /* CA15 (51733) */ + 3347, /* CA16 (51734) */ + 3347, /* CA17 (51735) */ + 3347, /* CA18 (51736) */ + 3347, /* CA19 (51737) */ + 3347, /* CA1A (51738) */ + 3347, /* CA1B (51739) */ + 3347, /* CA1C (51740) */ + 3347, /* CA1D (51741) */ + 3347, /* CA1E (51742) */ + 3347, /* CA1F (51743) */ + 3347, /* CA20 (51744) */ + 3347, /* CA21 (51745) */ + 3347, /* CA22 (51746) */ + 3347, /* CA23 (51747) */ + 3347, /* CA24 (51748) */ + 3347, /* CA25 (51749) */ + 3347, /* CA26 (51750) */ + 3347, /* CA27 (51751) */ + 3347, /* CA28 (51752) */ + 3347, /* CA29 (51753) */ + 3347, /* CA2A (51754) */ + 3347, /* CA2B (51755) */ + 3347, /* CA2C (51756) */ + 3347, /* CA2D (51757) */ + 3347, /* CA2E (51758) */ + 3347, /* CA2F (51759) */ + 3347, /* CA30 (51760) */ + 3347, /* CA31 (51761) */ + 3347, /* CA32 (51762) */ + 3347, /* CA33 (51763) */ + 3347, /* CA34 (51764) */ + 3347, /* CA35 (51765) */ + 3347, /* CA36 (51766) */ + 3347, /* CA37 (51767) */ + 3347, /* CA38 (51768) */ + 3347, /* CA39 (51769) */ + 3347, /* CA3A (51770) */ + 3347, /* CA3B (51771) */ + 3347, /* CA3C (51772) */ + 3347, /* CA3D (51773) */ + 3347, /* CA3E (51774) */ + 3347, /* CA3F (51775) */ + 3347, /* CA40 (51776) */ + 3347, /* CA41 (51777) */ + 3347, /* CA42 (51778) */ + 3347, /* CA43 (51779) */ + 3347, /* CA44 (51780) */ + 3347, /* CA45 (51781) */ + 3347, /* CA46 (51782) */ + 3347, /* CA47 (51783) */ + 3347, /* CA48 (51784) */ + 3347, /* CA49 (51785) */ + 3347, /* CA4A (51786) */ + 3347, /* CA4B (51787) */ + 3347, /* CA4C (51788) */ + 3347, /* CA4D (51789) */ + 3347, /* CA4E (51790) */ + 3347, /* CA4F (51791) */ + 3347, /* CA50 (51792) */ + 3347, /* CA51 (51793) */ + 3347, /* CA52 (51794) */ + 3347, /* CA53 (51795) */ + 3347, /* CA54 (51796) */ + 3347, /* CA55 (51797) */ + 3347, /* CA56 (51798) */ + 3347, /* CA57 (51799) */ + 3347, /* CA58 (51800) */ + 3347, /* CA59 (51801) */ + 3347, /* CA5A (51802) */ + 3347, /* CA5B (51803) */ + 3347, /* CA5C (51804) */ + 3347, /* CA5D (51805) */ + 3347, /* CA5E (51806) */ + 3347, /* CA5F (51807) */ + 3347, /* CA60 (51808) */ + 3347, /* CA61 (51809) */ + 3347, /* CA62 (51810) */ + 3347, /* CA63 (51811) */ + 3347, /* CA64 (51812) */ + 3347, /* CA65 (51813) */ + 3347, /* CA66 (51814) */ + 3347, /* CA67 (51815) */ + 3347, /* CA68 (51816) */ + 3347, /* CA69 (51817) */ + 3347, /* CA6A (51818) */ + 3347, /* CA6B (51819) */ + 3347, /* CA6C (51820) */ + 3347, /* CA6D (51821) */ + 3347, /* CA6E (51822) */ + 3347, /* CA6F (51823) */ + 3347, /* CA70 (51824) */ + 3347, /* CA71 (51825) */ + 3347, /* CA72 (51826) */ + 3347, /* CA73 (51827) */ + 3347, /* CA74 (51828) */ + 3347, /* CA75 (51829) */ + 3347, /* CA76 (51830) */ + 3347, /* CA77 (51831) */ + 3347, /* CA78 (51832) */ + 3347, /* CA79 (51833) */ + 3347, /* CA7A (51834) */ + 3347, /* CA7B (51835) */ + 3347, /* CA7C (51836) */ + 3347, /* CA7D (51837) */ + 3347, /* CA7E (51838) */ + 3347, /* CA7F (51839) */ + 3347, /* CA80 (51840) */ + 3347, /* CA81 (51841) */ + 3347, /* CA82 (51842) */ + 3347, /* CA83 (51843) */ + 3347, /* CA84 (51844) */ + 3347, /* CA85 (51845) */ + 3347, /* CA86 (51846) */ + 3347, /* CA87 (51847) */ + 3347, /* CA88 (51848) */ + 3347, /* CA89 (51849) */ + 3347, /* CA8A (51850) */ + 3347, /* CA8B (51851) */ + 3347, /* CA8C (51852) */ + 3347, /* CA8D (51853) */ + 3347, /* CA8E (51854) */ + 3347, /* CA8F (51855) */ + 3347, /* CA90 (51856) */ + 3347, /* CA91 (51857) */ + 3347, /* CA92 (51858) */ + 3347, /* CA93 (51859) */ + 3347, /* CA94 (51860) */ + 3347, /* CA95 (51861) */ + 3347, /* CA96 (51862) */ + 3347, /* CA97 (51863) */ + 3347, /* CA98 (51864) */ + 3347, /* CA99 (51865) */ + 3347, /* CA9A (51866) */ + 3347, /* CA9B (51867) */ + 3347, /* CA9C (51868) */ + 3347, /* CA9D (51869) */ + 3347, /* CA9E (51870) */ + 3347, /* CA9F (51871) */ + 3347, /* CAA0 (51872) */ + 3347, /* CAA1 (51873) */ + 3347, /* CAA2 (51874) */ + 3347, /* CAA3 (51875) */ + 3347, /* CAA4 (51876) */ + 3347, /* CAA5 (51877) */ + 3347, /* CAA6 (51878) */ + 3347, /* CAA7 (51879) */ + 3347, /* CAA8 (51880) */ + 3347, /* CAA9 (51881) */ + 3347, /* CAAA (51882) */ + 3347, /* CAAB (51883) */ + 3347, /* CAAC (51884) */ + 3347, /* CAAD (51885) */ + 3347, /* CAAE (51886) */ + 3347, /* CAAF (51887) */ + 3347, /* CAB0 (51888) */ + 3347, /* CAB1 (51889) */ + 3347, /* CAB2 (51890) */ + 3347, /* CAB3 (51891) */ + 3347, /* CAB4 (51892) */ + 3347, /* CAB5 (51893) */ + 3347, /* CAB6 (51894) */ + 3347, /* CAB7 (51895) */ + 3347, /* CAB8 (51896) */ + 3347, /* CAB9 (51897) */ + 3347, /* CABA (51898) */ + 3347, /* CABB (51899) */ + 3347, /* CABC (51900) */ + 3347, /* CABD (51901) */ + 3347, /* CABE (51902) */ + 3347, /* CABF (51903) */ + 3347, /* CAC0 (51904) */ + 3347, /* CAC1 (51905) */ + 3347, /* CAC2 (51906) */ + 3347, /* CAC3 (51907) */ + 3347, /* CAC4 (51908) */ + 3347, /* CAC5 (51909) */ + 3347, /* CAC6 (51910) */ + 3347, /* CAC7 (51911) */ + 3347, /* CAC8 (51912) */ + 3347, /* CAC9 (51913) */ + 3347, /* CACA (51914) */ + 3347, /* CACB (51915) */ + 3347, /* CACC (51916) */ + 3347, /* CACD (51917) */ + 3347, /* CACE (51918) */ + 3347, /* CACF (51919) */ + 3347, /* CAD0 (51920) */ + 3347, /* CAD1 (51921) */ + 3347, /* CAD2 (51922) */ + 3347, /* CAD3 (51923) */ + 3347, /* CAD4 (51924) */ + 3347, /* CAD5 (51925) */ + 3347, /* CAD6 (51926) */ + 3347, /* CAD7 (51927) */ + 3347, /* CAD8 (51928) */ + 3347, /* CAD9 (51929) */ + 3347, /* CADA (51930) */ + 3347, /* CADB (51931) */ + 3347, /* CADC (51932) */ + 3347, /* CADD (51933) */ + 3347, /* CADE (51934) */ + 3347, /* CADF (51935) */ + 3347, /* CAE0 (51936) */ + 3347, /* CAE1 (51937) */ + 3347, /* CAE2 (51938) */ + 3347, /* CAE3 (51939) */ + 3347, /* CAE4 (51940) */ + 3347, /* CAE5 (51941) */ + 3347, /* CAE6 (51942) */ + 3347, /* CAE7 (51943) */ + 3347, /* CAE8 (51944) */ + 3347, /* CAE9 (51945) */ + 3347, /* CAEA (51946) */ + 3347, /* CAEB (51947) */ + 3347, /* CAEC (51948) */ + 3347, /* CAED (51949) */ + 3347, /* CAEE (51950) */ + 3347, /* CAEF (51951) */ + 3347, /* CAF0 (51952) */ + 3347, /* CAF1 (51953) */ + 3347, /* CAF2 (51954) */ + 3347, /* CAF3 (51955) */ + 3347, /* CAF4 (51956) */ + 3347, /* CAF5 (51957) */ + 3347, /* CAF6 (51958) */ + 3347, /* CAF7 (51959) */ + 3347, /* CAF8 (51960) */ + 3347, /* CAF9 (51961) */ + 3347, /* CAFA (51962) */ + 3347, /* CAFB (51963) */ + 3347, /* CAFC (51964) */ + 3347, /* CAFD (51965) */ + 3347, /* CAFE (51966) */ + 3347, /* CAFF (51967) */ + 3347, /* CB00 (51968) */ + 3347, /* CB01 (51969) */ + 3347, /* CB02 (51970) */ + 3347, /* CB03 (51971) */ + 3347, /* CB04 (51972) */ + 3347, /* CB05 (51973) */ + 3347, /* CB06 (51974) */ + 3347, /* CB07 (51975) */ + 3347, /* CB08 (51976) */ + 3347, /* CB09 (51977) */ + 3347, /* CB0A (51978) */ + 3347, /* CB0B (51979) */ + 3347, /* CB0C (51980) */ + 3347, /* CB0D (51981) */ + 3347, /* CB0E (51982) */ + 3347, /* CB0F (51983) */ + 3347, /* CB10 (51984) */ + 3347, /* CB11 (51985) */ + 3347, /* CB12 (51986) */ + 3347, /* CB13 (51987) */ + 3347, /* CB14 (51988) */ + 3347, /* CB15 (51989) */ + 3347, /* CB16 (51990) */ + 3347, /* CB17 (51991) */ + 3347, /* CB18 (51992) */ + 3347, /* CB19 (51993) */ + 3347, /* CB1A (51994) */ + 3347, /* CB1B (51995) */ + 3347, /* CB1C (51996) */ + 3347, /* CB1D (51997) */ + 3347, /* CB1E (51998) */ + 3347, /* CB1F (51999) */ + 3347, /* CB20 (52000) */ + 3347, /* CB21 (52001) */ + 3347, /* CB22 (52002) */ + 3347, /* CB23 (52003) */ + 3347, /* CB24 (52004) */ + 3347, /* CB25 (52005) */ + 3347, /* CB26 (52006) */ + 3347, /* CB27 (52007) */ + 3347, /* CB28 (52008) */ + 3347, /* CB29 (52009) */ + 3347, /* CB2A (52010) */ + 3347, /* CB2B (52011) */ + 3347, /* CB2C (52012) */ + 3347, /* CB2D (52013) */ + 3347, /* CB2E (52014) */ + 3347, /* CB2F (52015) */ + 3347, /* CB30 (52016) */ + 3347, /* CB31 (52017) */ + 3347, /* CB32 (52018) */ + 3347, /* CB33 (52019) */ + 3347, /* CB34 (52020) */ + 3347, /* CB35 (52021) */ + 3347, /* CB36 (52022) */ + 3347, /* CB37 (52023) */ + 3347, /* CB38 (52024) */ + 3347, /* CB39 (52025) */ + 3347, /* CB3A (52026) */ + 3347, /* CB3B (52027) */ + 3347, /* CB3C (52028) */ + 3347, /* CB3D (52029) */ + 3347, /* CB3E (52030) */ + 3347, /* CB3F (52031) */ + 3347, /* CB40 (52032) */ + 3347, /* CB41 (52033) */ + 3347, /* CB42 (52034) */ + 3347, /* CB43 (52035) */ + 3347, /* CB44 (52036) */ + 3347, /* CB45 (52037) */ + 3347, /* CB46 (52038) */ + 3347, /* CB47 (52039) */ + 3347, /* CB48 (52040) */ + 3347, /* CB49 (52041) */ + 3347, /* CB4A (52042) */ + 3347, /* CB4B (52043) */ + 3347, /* CB4C (52044) */ + 3347, /* CB4D (52045) */ + 3347, /* CB4E (52046) */ + 3347, /* CB4F (52047) */ + 3347, /* CB50 (52048) */ + 3347, /* CB51 (52049) */ + 3347, /* CB52 (52050) */ + 3347, /* CB53 (52051) */ + 3347, /* CB54 (52052) */ + 3347, /* CB55 (52053) */ + 3347, /* CB56 (52054) */ + 3347, /* CB57 (52055) */ + 3347, /* CB58 (52056) */ + 3347, /* CB59 (52057) */ + 3347, /* CB5A (52058) */ + 3347, /* CB5B (52059) */ + 3347, /* CB5C (52060) */ + 3347, /* CB5D (52061) */ + 3347, /* CB5E (52062) */ + 3347, /* CB5F (52063) */ + 3347, /* CB60 (52064) */ + 3347, /* CB61 (52065) */ + 3347, /* CB62 (52066) */ + 3347, /* CB63 (52067) */ + 3347, /* CB64 (52068) */ + 3347, /* CB65 (52069) */ + 3347, /* CB66 (52070) */ + 3347, /* CB67 (52071) */ + 3347, /* CB68 (52072) */ + 3347, /* CB69 (52073) */ + 3347, /* CB6A (52074) */ + 3347, /* CB6B (52075) */ + 3347, /* CB6C (52076) */ + 3347, /* CB6D (52077) */ + 3347, /* CB6E (52078) */ + 3347, /* CB6F (52079) */ + 3347, /* CB70 (52080) */ + 3347, /* CB71 (52081) */ + 3347, /* CB72 (52082) */ + 3347, /* CB73 (52083) */ + 3347, /* CB74 (52084) */ + 3347, /* CB75 (52085) */ + 3347, /* CB76 (52086) */ + 3347, /* CB77 (52087) */ + 3347, /* CB78 (52088) */ + 3347, /* CB79 (52089) */ + 3347, /* CB7A (52090) */ + 3347, /* CB7B (52091) */ + 3347, /* CB7C (52092) */ + 3347, /* CB7D (52093) */ + 3347, /* CB7E (52094) */ + 3347, /* CB7F (52095) */ + 3347, /* CB80 (52096) */ + 3347, /* CB81 (52097) */ + 3347, /* CB82 (52098) */ + 3347, /* CB83 (52099) */ + 3347, /* CB84 (52100) */ + 3347, /* CB85 (52101) */ + 3347, /* CB86 (52102) */ + 3347, /* CB87 (52103) */ + 3347, /* CB88 (52104) */ + 3347, /* CB89 (52105) */ + 3347, /* CB8A (52106) */ + 3347, /* CB8B (52107) */ + 3347, /* CB8C (52108) */ + 3347, /* CB8D (52109) */ + 3347, /* CB8E (52110) */ + 3347, /* CB8F (52111) */ + 3347, /* CB90 (52112) */ + 3347, /* CB91 (52113) */ + 3347, /* CB92 (52114) */ + 3347, /* CB93 (52115) */ + 3347, /* CB94 (52116) */ + 3347, /* CB95 (52117) */ + 3347, /* CB96 (52118) */ + 3347, /* CB97 (52119) */ + 3347, /* CB98 (52120) */ + 3347, /* CB99 (52121) */ + 3347, /* CB9A (52122) */ + 3347, /* CB9B (52123) */ + 3347, /* CB9C (52124) */ + 3347, /* CB9D (52125) */ + 3347, /* CB9E (52126) */ + 3347, /* CB9F (52127) */ + 3347, /* CBA0 (52128) */ + 3347, /* CBA1 (52129) */ + 3347, /* CBA2 (52130) */ + 3347, /* CBA3 (52131) */ + 3347, /* CBA4 (52132) */ + 3347, /* CBA5 (52133) */ + 3347, /* CBA6 (52134) */ + 3347, /* CBA7 (52135) */ + 3347, /* CBA8 (52136) */ + 3347, /* CBA9 (52137) */ + 3347, /* CBAA (52138) */ + 3347, /* CBAB (52139) */ + 3347, /* CBAC (52140) */ + 3347, /* CBAD (52141) */ + 3347, /* CBAE (52142) */ + 3347, /* CBAF (52143) */ + 3347, /* CBB0 (52144) */ + 3347, /* CBB1 (52145) */ + 3347, /* CBB2 (52146) */ + 3347, /* CBB3 (52147) */ + 3347, /* CBB4 (52148) */ + 3347, /* CBB5 (52149) */ + 3347, /* CBB6 (52150) */ + 3347, /* CBB7 (52151) */ + 3347, /* CBB8 (52152) */ + 3347, /* CBB9 (52153) */ + 3347, /* CBBA (52154) */ + 3347, /* CBBB (52155) */ + 3347, /* CBBC (52156) */ + 3347, /* CBBD (52157) */ + 3347, /* CBBE (52158) */ + 3347, /* CBBF (52159) */ + 3347, /* CBC0 (52160) */ + 3347, /* CBC1 (52161) */ + 3347, /* CBC2 (52162) */ + 3347, /* CBC3 (52163) */ + 3347, /* CBC4 (52164) */ + 3347, /* CBC5 (52165) */ + 3347, /* CBC6 (52166) */ + 3347, /* CBC7 (52167) */ + 3347, /* CBC8 (52168) */ + 3347, /* CBC9 (52169) */ + 3347, /* CBCA (52170) */ + 3347, /* CBCB (52171) */ + 3347, /* CBCC (52172) */ + 3347, /* CBCD (52173) */ + 3347, /* CBCE (52174) */ + 3347, /* CBCF (52175) */ + 3347, /* CBD0 (52176) */ + 3347, /* CBD1 (52177) */ + 3347, /* CBD2 (52178) */ + 3347, /* CBD3 (52179) */ + 3347, /* CBD4 (52180) */ + 3347, /* CBD5 (52181) */ + 3347, /* CBD6 (52182) */ + 3347, /* CBD7 (52183) */ + 3347, /* CBD8 (52184) */ + 3347, /* CBD9 (52185) */ + 3347, /* CBDA (52186) */ + 3347, /* CBDB (52187) */ + 3347, /* CBDC (52188) */ + 3347, /* CBDD (52189) */ + 3347, /* CBDE (52190) */ + 3347, /* CBDF (52191) */ + 3347, /* CBE0 (52192) */ + 3347, /* CBE1 (52193) */ + 3347, /* CBE2 (52194) */ + 3347, /* CBE3 (52195) */ + 3347, /* CBE4 (52196) */ + 3347, /* CBE5 (52197) */ + 3347, /* CBE6 (52198) */ + 3347, /* CBE7 (52199) */ + 3347, /* CBE8 (52200) */ + 3347, /* CBE9 (52201) */ + 3347, /* CBEA (52202) */ + 3347, /* CBEB (52203) */ + 3347, /* CBEC (52204) */ + 3347, /* CBED (52205) */ + 3347, /* CBEE (52206) */ + 3347, /* CBEF (52207) */ + 3347, /* CBF0 (52208) */ + 3347, /* CBF1 (52209) */ + 3347, /* CBF2 (52210) */ + 3347, /* CBF3 (52211) */ + 3347, /* CBF4 (52212) */ + 3347, /* CBF5 (52213) */ + 3347, /* CBF6 (52214) */ + 3347, /* CBF7 (52215) */ + 3347, /* CBF8 (52216) */ + 3347, /* CBF9 (52217) */ + 3347, /* CBFA (52218) */ + 3347, /* CBFB (52219) */ + 3347, /* CBFC (52220) */ + 3347, /* CBFD (52221) */ + 3347, /* CBFE (52222) */ + 3347, /* CBFF (52223) */ + 3347, /* CC00 (52224) */ + 3347, /* CC01 (52225) */ + 3347, /* CC02 (52226) */ + 3347, /* CC03 (52227) */ + 3347, /* CC04 (52228) */ + 3347, /* CC05 (52229) */ + 3347, /* CC06 (52230) */ + 3347, /* CC07 (52231) */ + 3347, /* CC08 (52232) */ + 3347, /* CC09 (52233) */ + 3347, /* CC0A (52234) */ + 3347, /* CC0B (52235) */ + 3347, /* CC0C (52236) */ + 3347, /* CC0D (52237) */ + 3347, /* CC0E (52238) */ + 3347, /* CC0F (52239) */ + 3347, /* CC10 (52240) */ + 3347, /* CC11 (52241) */ + 3347, /* CC12 (52242) */ + 3347, /* CC13 (52243) */ + 3347, /* CC14 (52244) */ + 3347, /* CC15 (52245) */ + 3347, /* CC16 (52246) */ + 3347, /* CC17 (52247) */ + 3347, /* CC18 (52248) */ + 3347, /* CC19 (52249) */ + 3347, /* CC1A (52250) */ + 3347, /* CC1B (52251) */ + 3347, /* CC1C (52252) */ + 3347, /* CC1D (52253) */ + 3347, /* CC1E (52254) */ + 3347, /* CC1F (52255) */ + 3347, /* CC20 (52256) */ + 3347, /* CC21 (52257) */ + 3347, /* CC22 (52258) */ + 3347, /* CC23 (52259) */ + 3347, /* CC24 (52260) */ + 3347, /* CC25 (52261) */ + 3347, /* CC26 (52262) */ + 3347, /* CC27 (52263) */ + 3347, /* CC28 (52264) */ + 3347, /* CC29 (52265) */ + 3347, /* CC2A (52266) */ + 3347, /* CC2B (52267) */ + 3347, /* CC2C (52268) */ + 3347, /* CC2D (52269) */ + 3347, /* CC2E (52270) */ + 3347, /* CC2F (52271) */ + 3347, /* CC30 (52272) */ + 3347, /* CC31 (52273) */ + 3347, /* CC32 (52274) */ + 3347, /* CC33 (52275) */ + 3347, /* CC34 (52276) */ + 3347, /* CC35 (52277) */ + 3347, /* CC36 (52278) */ + 3347, /* CC37 (52279) */ + 3347, /* CC38 (52280) */ + 3347, /* CC39 (52281) */ + 3347, /* CC3A (52282) */ + 3347, /* CC3B (52283) */ + 3347, /* CC3C (52284) */ + 3347, /* CC3D (52285) */ + 3347, /* CC3E (52286) */ + 3347, /* CC3F (52287) */ + 3347, /* CC40 (52288) */ + 3347, /* CC41 (52289) */ + 3347, /* CC42 (52290) */ + 3347, /* CC43 (52291) */ + 3347, /* CC44 (52292) */ + 3347, /* CC45 (52293) */ + 3347, /* CC46 (52294) */ + 3347, /* CC47 (52295) */ + 3347, /* CC48 (52296) */ + 3347, /* CC49 (52297) */ + 3347, /* CC4A (52298) */ + 3347, /* CC4B (52299) */ + 3347, /* CC4C (52300) */ + 3347, /* CC4D (52301) */ + 3347, /* CC4E (52302) */ + 3347, /* CC4F (52303) */ + 3347, /* CC50 (52304) */ + 3347, /* CC51 (52305) */ + 3347, /* CC52 (52306) */ + 3347, /* CC53 (52307) */ + 3347, /* CC54 (52308) */ + 3347, /* CC55 (52309) */ + 3347, /* CC56 (52310) */ + 3347, /* CC57 (52311) */ + 3347, /* CC58 (52312) */ + 3347, /* CC59 (52313) */ + 3347, /* CC5A (52314) */ + 3347, /* CC5B (52315) */ + 3347, /* CC5C (52316) */ + 3347, /* CC5D (52317) */ + 3347, /* CC5E (52318) */ + 3347, /* CC5F (52319) */ + 3347, /* CC60 (52320) */ + 3347, /* CC61 (52321) */ + 3347, /* CC62 (52322) */ + 3347, /* CC63 (52323) */ + 3347, /* CC64 (52324) */ + 3347, /* CC65 (52325) */ + 3347, /* CC66 (52326) */ + 3347, /* CC67 (52327) */ + 3347, /* CC68 (52328) */ + 3347, /* CC69 (52329) */ + 3347, /* CC6A (52330) */ + 3347, /* CC6B (52331) */ + 3347, /* CC6C (52332) */ + 3347, /* CC6D (52333) */ + 3347, /* CC6E (52334) */ + 3347, /* CC6F (52335) */ + 3347, /* CC70 (52336) */ + 3347, /* CC71 (52337) */ + 3347, /* CC72 (52338) */ + 3347, /* CC73 (52339) */ + 3347, /* CC74 (52340) */ + 3347, /* CC75 (52341) */ + 3347, /* CC76 (52342) */ + 3347, /* CC77 (52343) */ + 3347, /* CC78 (52344) */ + 3347, /* CC79 (52345) */ + 3347, /* CC7A (52346) */ + 3347, /* CC7B (52347) */ + 3347, /* CC7C (52348) */ + 3347, /* CC7D (52349) */ + 3347, /* CC7E (52350) */ + 3347, /* CC7F (52351) */ + 3347, /* CC80 (52352) */ + 3347, /* CC81 (52353) */ + 3347, /* CC82 (52354) */ + 3347, /* CC83 (52355) */ + 3347, /* CC84 (52356) */ + 3347, /* CC85 (52357) */ + 3347, /* CC86 (52358) */ + 3347, /* CC87 (52359) */ + 3347, /* CC88 (52360) */ + 3347, /* CC89 (52361) */ + 3347, /* CC8A (52362) */ + 3347, /* CC8B (52363) */ + 3347, /* CC8C (52364) */ + 3347, /* CC8D (52365) */ + 3347, /* CC8E (52366) */ + 3347, /* CC8F (52367) */ + 3347, /* CC90 (52368) */ + 3347, /* CC91 (52369) */ + 3347, /* CC92 (52370) */ + 3347, /* CC93 (52371) */ + 3347, /* CC94 (52372) */ + 3347, /* CC95 (52373) */ + 3347, /* CC96 (52374) */ + 3347, /* CC97 (52375) */ + 3347, /* CC98 (52376) */ + 3347, /* CC99 (52377) */ + 3347, /* CC9A (52378) */ + 3347, /* CC9B (52379) */ + 3347, /* CC9C (52380) */ + 3347, /* CC9D (52381) */ + 3347, /* CC9E (52382) */ + 3347, /* CC9F (52383) */ + 3347, /* CCA0 (52384) */ + 3347, /* CCA1 (52385) */ + 3347, /* CCA2 (52386) */ + 3347, /* CCA3 (52387) */ + 3347, /* CCA4 (52388) */ + 3347, /* CCA5 (52389) */ + 3347, /* CCA6 (52390) */ + 3347, /* CCA7 (52391) */ + 3347, /* CCA8 (52392) */ + 3347, /* CCA9 (52393) */ + 3347, /* CCAA (52394) */ + 3347, /* CCAB (52395) */ + 3347, /* CCAC (52396) */ + 3347, /* CCAD (52397) */ + 3347, /* CCAE (52398) */ + 3347, /* CCAF (52399) */ + 3347, /* CCB0 (52400) */ + 3347, /* CCB1 (52401) */ + 3347, /* CCB2 (52402) */ + 3347, /* CCB3 (52403) */ + 3347, /* CCB4 (52404) */ + 3347, /* CCB5 (52405) */ + 3347, /* CCB6 (52406) */ + 3347, /* CCB7 (52407) */ + 3347, /* CCB8 (52408) */ + 3347, /* CCB9 (52409) */ + 3347, /* CCBA (52410) */ + 3347, /* CCBB (52411) */ + 3347, /* CCBC (52412) */ + 3347, /* CCBD (52413) */ + 3347, /* CCBE (52414) */ + 3347, /* CCBF (52415) */ + 3347, /* CCC0 (52416) */ + 3347, /* CCC1 (52417) */ + 3347, /* CCC2 (52418) */ + 3347, /* CCC3 (52419) */ + 3347, /* CCC4 (52420) */ + 3347, /* CCC5 (52421) */ + 3347, /* CCC6 (52422) */ + 3347, /* CCC7 (52423) */ + 3347, /* CCC8 (52424) */ + 3347, /* CCC9 (52425) */ + 3347, /* CCCA (52426) */ + 3347, /* CCCB (52427) */ + 3347, /* CCCC (52428) */ + 3347, /* CCCD (52429) */ + 3347, /* CCCE (52430) */ + 3347, /* CCCF (52431) */ + 3347, /* CCD0 (52432) */ + 3347, /* CCD1 (52433) */ + 3347, /* CCD2 (52434) */ + 3347, /* CCD3 (52435) */ + 3347, /* CCD4 (52436) */ + 3347, /* CCD5 (52437) */ + 3347, /* CCD6 (52438) */ + 3347, /* CCD7 (52439) */ + 3347, /* CCD8 (52440) */ + 3347, /* CCD9 (52441) */ + 3347, /* CCDA (52442) */ + 3347, /* CCDB (52443) */ + 3347, /* CCDC (52444) */ + 3347, /* CCDD (52445) */ + 3347, /* CCDE (52446) */ + 3347, /* CCDF (52447) */ + 3347, /* CCE0 (52448) */ + 3347, /* CCE1 (52449) */ + 3347, /* CCE2 (52450) */ + 3347, /* CCE3 (52451) */ + 3347, /* CCE4 (52452) */ + 3347, /* CCE5 (52453) */ + 3347, /* CCE6 (52454) */ + 3347, /* CCE7 (52455) */ + 3347, /* CCE8 (52456) */ + 3347, /* CCE9 (52457) */ + 3347, /* CCEA (52458) */ + 3347, /* CCEB (52459) */ + 3347, /* CCEC (52460) */ + 3347, /* CCED (52461) */ + 3347, /* CCEE (52462) */ + 3347, /* CCEF (52463) */ + 3347, /* CCF0 (52464) */ + 3347, /* CCF1 (52465) */ + 3347, /* CCF2 (52466) */ + 3347, /* CCF3 (52467) */ + 3347, /* CCF4 (52468) */ + 3347, /* CCF5 (52469) */ + 3347, /* CCF6 (52470) */ + 3347, /* CCF7 (52471) */ + 3347, /* CCF8 (52472) */ + 3347, /* CCF9 (52473) */ + 3347, /* CCFA (52474) */ + 3347, /* CCFB (52475) */ + 3347, /* CCFC (52476) */ + 3347, /* CCFD (52477) */ + 3347, /* CCFE (52478) */ + 3347, /* CCFF (52479) */ + 3347, /* CD00 (52480) */ + 3347, /* CD01 (52481) */ + 3347, /* CD02 (52482) */ + 3347, /* CD03 (52483) */ + 3347, /* CD04 (52484) */ + 3347, /* CD05 (52485) */ + 3347, /* CD06 (52486) */ + 3347, /* CD07 (52487) */ + 3347, /* CD08 (52488) */ + 3347, /* CD09 (52489) */ + 3347, /* CD0A (52490) */ + 3347, /* CD0B (52491) */ + 3347, /* CD0C (52492) */ + 3347, /* CD0D (52493) */ + 3347, /* CD0E (52494) */ + 3347, /* CD0F (52495) */ + 3347, /* CD10 (52496) */ + 3347, /* CD11 (52497) */ + 3347, /* CD12 (52498) */ + 3347, /* CD13 (52499) */ + 3347, /* CD14 (52500) */ + 3347, /* CD15 (52501) */ + 3347, /* CD16 (52502) */ + 3347, /* CD17 (52503) */ + 3347, /* CD18 (52504) */ + 3347, /* CD19 (52505) */ + 3347, /* CD1A (52506) */ + 3347, /* CD1B (52507) */ + 3347, /* CD1C (52508) */ + 3347, /* CD1D (52509) */ + 3347, /* CD1E (52510) */ + 3347, /* CD1F (52511) */ + 3347, /* CD20 (52512) */ + 3347, /* CD21 (52513) */ + 3347, /* CD22 (52514) */ + 3347, /* CD23 (52515) */ + 3347, /* CD24 (52516) */ + 3347, /* CD25 (52517) */ + 3347, /* CD26 (52518) */ + 3347, /* CD27 (52519) */ + 3347, /* CD28 (52520) */ + 3347, /* CD29 (52521) */ + 3347, /* CD2A (52522) */ + 3347, /* CD2B (52523) */ + 3347, /* CD2C (52524) */ + 3347, /* CD2D (52525) */ + 3347, /* CD2E (52526) */ + 3347, /* CD2F (52527) */ + 3347, /* CD30 (52528) */ + 3347, /* CD31 (52529) */ + 3347, /* CD32 (52530) */ + 3347, /* CD33 (52531) */ + 3347, /* CD34 (52532) */ + 3347, /* CD35 (52533) */ + 3347, /* CD36 (52534) */ + 3347, /* CD37 (52535) */ + 3347, /* CD38 (52536) */ + 3347, /* CD39 (52537) */ + 3347, /* CD3A (52538) */ + 3347, /* CD3B (52539) */ + 3347, /* CD3C (52540) */ + 3347, /* CD3D (52541) */ + 3347, /* CD3E (52542) */ + 3347, /* CD3F (52543) */ + 3347, /* CD40 (52544) */ + 3347, /* CD41 (52545) */ + 3347, /* CD42 (52546) */ + 3347, /* CD43 (52547) */ + 3347, /* CD44 (52548) */ + 3347, /* CD45 (52549) */ + 3347, /* CD46 (52550) */ + 3347, /* CD47 (52551) */ + 3347, /* CD48 (52552) */ + 3347, /* CD49 (52553) */ + 3347, /* CD4A (52554) */ + 3347, /* CD4B (52555) */ + 3347, /* CD4C (52556) */ + 3347, /* CD4D (52557) */ + 3347, /* CD4E (52558) */ + 3347, /* CD4F (52559) */ + 3347, /* CD50 (52560) */ + 3347, /* CD51 (52561) */ + 3347, /* CD52 (52562) */ + 3347, /* CD53 (52563) */ + 3347, /* CD54 (52564) */ + 3347, /* CD55 (52565) */ + 3347, /* CD56 (52566) */ + 3347, /* CD57 (52567) */ + 3347, /* CD58 (52568) */ + 3347, /* CD59 (52569) */ + 3347, /* CD5A (52570) */ + 3347, /* CD5B (52571) */ + 3347, /* CD5C (52572) */ + 3347, /* CD5D (52573) */ + 3347, /* CD5E (52574) */ + 3347, /* CD5F (52575) */ + 3347, /* CD60 (52576) */ + 3347, /* CD61 (52577) */ + 3347, /* CD62 (52578) */ + 3347, /* CD63 (52579) */ + 3347, /* CD64 (52580) */ + 3347, /* CD65 (52581) */ + 3347, /* CD66 (52582) */ + 3347, /* CD67 (52583) */ + 3347, /* CD68 (52584) */ + 3347, /* CD69 (52585) */ + 3347, /* CD6A (52586) */ + 3347, /* CD6B (52587) */ + 3347, /* CD6C (52588) */ + 3347, /* CD6D (52589) */ + 3347, /* CD6E (52590) */ + 3347, /* CD6F (52591) */ + 3347, /* CD70 (52592) */ + 3347, /* CD71 (52593) */ + 3347, /* CD72 (52594) */ + 3347, /* CD73 (52595) */ + 3347, /* CD74 (52596) */ + 3347, /* CD75 (52597) */ + 3347, /* CD76 (52598) */ + 3347, /* CD77 (52599) */ + 3347, /* CD78 (52600) */ + 3347, /* CD79 (52601) */ + 3347, /* CD7A (52602) */ + 3347, /* CD7B (52603) */ + 3347, /* CD7C (52604) */ + 3347, /* CD7D (52605) */ + 3347, /* CD7E (52606) */ + 3347, /* CD7F (52607) */ + 3347, /* CD80 (52608) */ + 3347, /* CD81 (52609) */ + 3347, /* CD82 (52610) */ + 3347, /* CD83 (52611) */ + 3347, /* CD84 (52612) */ + 3347, /* CD85 (52613) */ + 3347, /* CD86 (52614) */ + 3347, /* CD87 (52615) */ + 3347, /* CD88 (52616) */ + 3347, /* CD89 (52617) */ + 3347, /* CD8A (52618) */ + 3347, /* CD8B (52619) */ + 3347, /* CD8C (52620) */ + 3347, /* CD8D (52621) */ + 3347, /* CD8E (52622) */ + 3347, /* CD8F (52623) */ + 3347, /* CD90 (52624) */ + 3347, /* CD91 (52625) */ + 3347, /* CD92 (52626) */ + 3347, /* CD93 (52627) */ + 3347, /* CD94 (52628) */ + 3347, /* CD95 (52629) */ + 3347, /* CD96 (52630) */ + 3347, /* CD97 (52631) */ + 3347, /* CD98 (52632) */ + 3347, /* CD99 (52633) */ + 3347, /* CD9A (52634) */ + 3347, /* CD9B (52635) */ + 3347, /* CD9C (52636) */ + 3347, /* CD9D (52637) */ + 3347, /* CD9E (52638) */ + 3347, /* CD9F (52639) */ + 3347, /* CDA0 (52640) */ + 3347, /* CDA1 (52641) */ + 3347, /* CDA2 (52642) */ + 3347, /* CDA3 (52643) */ + 3347, /* CDA4 (52644) */ + 3347, /* CDA5 (52645) */ + 3347, /* CDA6 (52646) */ + 3347, /* CDA7 (52647) */ + 3347, /* CDA8 (52648) */ + 3347, /* CDA9 (52649) */ + 3347, /* CDAA (52650) */ + 3347, /* CDAB (52651) */ + 3347, /* CDAC (52652) */ + 3347, /* CDAD (52653) */ + 3347, /* CDAE (52654) */ + 3347, /* CDAF (52655) */ + 3347, /* CDB0 (52656) */ + 3347, /* CDB1 (52657) */ + 3347, /* CDB2 (52658) */ + 3347, /* CDB3 (52659) */ + 3347, /* CDB4 (52660) */ + 3347, /* CDB5 (52661) */ + 3347, /* CDB6 (52662) */ + 3347, /* CDB7 (52663) */ + 3347, /* CDB8 (52664) */ + 3347, /* CDB9 (52665) */ + 3347, /* CDBA (52666) */ + 3347, /* CDBB (52667) */ + 3347, /* CDBC (52668) */ + 3347, /* CDBD (52669) */ + 3347, /* CDBE (52670) */ + 3347, /* CDBF (52671) */ + 3347, /* CDC0 (52672) */ + 3347, /* CDC1 (52673) */ + 3347, /* CDC2 (52674) */ + 3347, /* CDC3 (52675) */ + 3347, /* CDC4 (52676) */ + 3347, /* CDC5 (52677) */ + 3347, /* CDC6 (52678) */ + 3347, /* CDC7 (52679) */ + 3347, /* CDC8 (52680) */ + 3347, /* CDC9 (52681) */ + 3347, /* CDCA (52682) */ + 3347, /* CDCB (52683) */ + 3347, /* CDCC (52684) */ + 3347, /* CDCD (52685) */ + 3347, /* CDCE (52686) */ + 3347, /* CDCF (52687) */ + 3347, /* CDD0 (52688) */ + 3347, /* CDD1 (52689) */ + 3347, /* CDD2 (52690) */ + 3347, /* CDD3 (52691) */ + 3347, /* CDD4 (52692) */ + 3347, /* CDD5 (52693) */ + 3347, /* CDD6 (52694) */ + 3347, /* CDD7 (52695) */ + 3347, /* CDD8 (52696) */ + 3347, /* CDD9 (52697) */ + 3347, /* CDDA (52698) */ + 3347, /* CDDB (52699) */ + 3347, /* CDDC (52700) */ + 3347, /* CDDD (52701) */ + 3347, /* CDDE (52702) */ + 3347, /* CDDF (52703) */ + 3347, /* CDE0 (52704) */ + 3347, /* CDE1 (52705) */ + 3347, /* CDE2 (52706) */ + 3347, /* CDE3 (52707) */ + 3347, /* CDE4 (52708) */ + 3347, /* CDE5 (52709) */ + 3347, /* CDE6 (52710) */ + 3347, /* CDE7 (52711) */ + 3347, /* CDE8 (52712) */ + 3347, /* CDE9 (52713) */ + 3347, /* CDEA (52714) */ + 3347, /* CDEB (52715) */ + 3347, /* CDEC (52716) */ + 3347, /* CDED (52717) */ + 3347, /* CDEE (52718) */ + 3347, /* CDEF (52719) */ + 3347, /* CDF0 (52720) */ + 3347, /* CDF1 (52721) */ + 3347, /* CDF2 (52722) */ + 3347, /* CDF3 (52723) */ + 3347, /* CDF4 (52724) */ + 3347, /* CDF5 (52725) */ + 3347, /* CDF6 (52726) */ + 3347, /* CDF7 (52727) */ + 3347, /* CDF8 (52728) */ + 3347, /* CDF9 (52729) */ + 3347, /* CDFA (52730) */ + 3347, /* CDFB (52731) */ + 3347, /* CDFC (52732) */ + 3347, /* CDFD (52733) */ + 3347, /* CDFE (52734) */ + 3347, /* CDFF (52735) */ + 3347, /* CE00 (52736) */ + 3347, /* CE01 (52737) */ + 3347, /* CE02 (52738) */ + 3347, /* CE03 (52739) */ + 3347, /* CE04 (52740) */ + 3347, /* CE05 (52741) */ + 3347, /* CE06 (52742) */ + 3347, /* CE07 (52743) */ + 3347, /* CE08 (52744) */ + 3347, /* CE09 (52745) */ + 3347, /* CE0A (52746) */ + 3347, /* CE0B (52747) */ + 3347, /* CE0C (52748) */ + 3347, /* CE0D (52749) */ + 3347, /* CE0E (52750) */ + 3347, /* CE0F (52751) */ + 3347, /* CE10 (52752) */ + 3347, /* CE11 (52753) */ + 3347, /* CE12 (52754) */ + 3347, /* CE13 (52755) */ + 3347, /* CE14 (52756) */ + 3347, /* CE15 (52757) */ + 3347, /* CE16 (52758) */ + 3347, /* CE17 (52759) */ + 3347, /* CE18 (52760) */ + 3347, /* CE19 (52761) */ + 3347, /* CE1A (52762) */ + 3347, /* CE1B (52763) */ + 3347, /* CE1C (52764) */ + 3347, /* CE1D (52765) */ + 3347, /* CE1E (52766) */ + 3347, /* CE1F (52767) */ + 3347, /* CE20 (52768) */ + 3347, /* CE21 (52769) */ + 3347, /* CE22 (52770) */ + 3347, /* CE23 (52771) */ + 3347, /* CE24 (52772) */ + 3347, /* CE25 (52773) */ + 3347, /* CE26 (52774) */ + 3347, /* CE27 (52775) */ + 3347, /* CE28 (52776) */ + 3347, /* CE29 (52777) */ + 3347, /* CE2A (52778) */ + 3347, /* CE2B (52779) */ + 3347, /* CE2C (52780) */ + 3347, /* CE2D (52781) */ + 3347, /* CE2E (52782) */ + 3347, /* CE2F (52783) */ + 3347, /* CE30 (52784) */ + 3347, /* CE31 (52785) */ + 3347, /* CE32 (52786) */ + 3347, /* CE33 (52787) */ + 3347, /* CE34 (52788) */ + 3347, /* CE35 (52789) */ + 3347, /* CE36 (52790) */ + 3347, /* CE37 (52791) */ + 3347, /* CE38 (52792) */ + 3347, /* CE39 (52793) */ + 3347, /* CE3A (52794) */ + 3347, /* CE3B (52795) */ + 3347, /* CE3C (52796) */ + 3347, /* CE3D (52797) */ + 3347, /* CE3E (52798) */ + 3347, /* CE3F (52799) */ + 3347, /* CE40 (52800) */ + 3347, /* CE41 (52801) */ + 3347, /* CE42 (52802) */ + 3347, /* CE43 (52803) */ + 3347, /* CE44 (52804) */ + 3347, /* CE45 (52805) */ + 3347, /* CE46 (52806) */ + 3347, /* CE47 (52807) */ + 3347, /* CE48 (52808) */ + 3347, /* CE49 (52809) */ + 3347, /* CE4A (52810) */ + 3347, /* CE4B (52811) */ + 3347, /* CE4C (52812) */ + 3347, /* CE4D (52813) */ + 3347, /* CE4E (52814) */ + 3347, /* CE4F (52815) */ + 3347, /* CE50 (52816) */ + 3347, /* CE51 (52817) */ + 3347, /* CE52 (52818) */ + 3347, /* CE53 (52819) */ + 3347, /* CE54 (52820) */ + 3347, /* CE55 (52821) */ + 3347, /* CE56 (52822) */ + 3347, /* CE57 (52823) */ + 3347, /* CE58 (52824) */ + 3347, /* CE59 (52825) */ + 3347, /* CE5A (52826) */ + 3347, /* CE5B (52827) */ + 3347, /* CE5C (52828) */ + 3347, /* CE5D (52829) */ + 3347, /* CE5E (52830) */ + 3347, /* CE5F (52831) */ + 3347, /* CE60 (52832) */ + 3347, /* CE61 (52833) */ + 3347, /* CE62 (52834) */ + 3347, /* CE63 (52835) */ + 3347, /* CE64 (52836) */ + 3347, /* CE65 (52837) */ + 3347, /* CE66 (52838) */ + 3347, /* CE67 (52839) */ + 3347, /* CE68 (52840) */ + 3347, /* CE69 (52841) */ + 3347, /* CE6A (52842) */ + 3347, /* CE6B (52843) */ + 3347, /* CE6C (52844) */ + 3347, /* CE6D (52845) */ + 3347, /* CE6E (52846) */ + 3347, /* CE6F (52847) */ + 3347, /* CE70 (52848) */ + 3347, /* CE71 (52849) */ + 3347, /* CE72 (52850) */ + 3347, /* CE73 (52851) */ + 3347, /* CE74 (52852) */ + 3347, /* CE75 (52853) */ + 3347, /* CE76 (52854) */ + 3347, /* CE77 (52855) */ + 3347, /* CE78 (52856) */ + 3347, /* CE79 (52857) */ + 3347, /* CE7A (52858) */ + 3347, /* CE7B (52859) */ + 3347, /* CE7C (52860) */ + 3347, /* CE7D (52861) */ + 3347, /* CE7E (52862) */ + 3347, /* CE7F (52863) */ + 3347, /* CE80 (52864) */ + 3347, /* CE81 (52865) */ + 3347, /* CE82 (52866) */ + 3347, /* CE83 (52867) */ + 3347, /* CE84 (52868) */ + 3347, /* CE85 (52869) */ + 3347, /* CE86 (52870) */ + 3347, /* CE87 (52871) */ + 3347, /* CE88 (52872) */ + 3347, /* CE89 (52873) */ + 3347, /* CE8A (52874) */ + 3347, /* CE8B (52875) */ + 3347, /* CE8C (52876) */ + 3347, /* CE8D (52877) */ + 3347, /* CE8E (52878) */ + 3347, /* CE8F (52879) */ + 3347, /* CE90 (52880) */ + 3347, /* CE91 (52881) */ + 3347, /* CE92 (52882) */ + 3347, /* CE93 (52883) */ + 3347, /* CE94 (52884) */ + 3347, /* CE95 (52885) */ + 3347, /* CE96 (52886) */ + 3347, /* CE97 (52887) */ + 3347, /* CE98 (52888) */ + 3347, /* CE99 (52889) */ + 3347, /* CE9A (52890) */ + 3347, /* CE9B (52891) */ + 3347, /* CE9C (52892) */ + 3347, /* CE9D (52893) */ + 3347, /* CE9E (52894) */ + 3347, /* CE9F (52895) */ + 3347, /* CEA0 (52896) */ + 3347, /* CEA1 (52897) */ + 3347, /* CEA2 (52898) */ + 3347, /* CEA3 (52899) */ + 3347, /* CEA4 (52900) */ + 3347, /* CEA5 (52901) */ + 3347, /* CEA6 (52902) */ + 3347, /* CEA7 (52903) */ + 3347, /* CEA8 (52904) */ + 3347, /* CEA9 (52905) */ + 3347, /* CEAA (52906) */ + 3347, /* CEAB (52907) */ + 3347, /* CEAC (52908) */ + 3347, /* CEAD (52909) */ + 3347, /* CEAE (52910) */ + 3347, /* CEAF (52911) */ + 3347, /* CEB0 (52912) */ + 3347, /* CEB1 (52913) */ + 3347, /* CEB2 (52914) */ + 3347, /* CEB3 (52915) */ + 3347, /* CEB4 (52916) */ + 3347, /* CEB5 (52917) */ + 3347, /* CEB6 (52918) */ + 3347, /* CEB7 (52919) */ + 3347, /* CEB8 (52920) */ + 3347, /* CEB9 (52921) */ + 3347, /* CEBA (52922) */ + 3347, /* CEBB (52923) */ + 3347, /* CEBC (52924) */ + 3347, /* CEBD (52925) */ + 3347, /* CEBE (52926) */ + 3347, /* CEBF (52927) */ + 3347, /* CEC0 (52928) */ + 3347, /* CEC1 (52929) */ + 3347, /* CEC2 (52930) */ + 3347, /* CEC3 (52931) */ + 3347, /* CEC4 (52932) */ + 3347, /* CEC5 (52933) */ + 3347, /* CEC6 (52934) */ + 3347, /* CEC7 (52935) */ + 3347, /* CEC8 (52936) */ + 3347, /* CEC9 (52937) */ + 3347, /* CECA (52938) */ + 3347, /* CECB (52939) */ + 3347, /* CECC (52940) */ + 3347, /* CECD (52941) */ + 3347, /* CECE (52942) */ + 3347, /* CECF (52943) */ + 3347, /* CED0 (52944) */ + 3347, /* CED1 (52945) */ + 3347, /* CED2 (52946) */ + 3347, /* CED3 (52947) */ + 3347, /* CED4 (52948) */ + 3347, /* CED5 (52949) */ + 3347, /* CED6 (52950) */ + 3347, /* CED7 (52951) */ + 3347, /* CED8 (52952) */ + 3347, /* CED9 (52953) */ + 3347, /* CEDA (52954) */ + 3347, /* CEDB (52955) */ + 3347, /* CEDC (52956) */ + 3347, /* CEDD (52957) */ + 3347, /* CEDE (52958) */ + 3347, /* CEDF (52959) */ + 3347, /* CEE0 (52960) */ + 3347, /* CEE1 (52961) */ + 3347, /* CEE2 (52962) */ + 3347, /* CEE3 (52963) */ + 3347, /* CEE4 (52964) */ + 3347, /* CEE5 (52965) */ + 3347, /* CEE6 (52966) */ + 3347, /* CEE7 (52967) */ + 3347, /* CEE8 (52968) */ + 3347, /* CEE9 (52969) */ + 3347, /* CEEA (52970) */ + 3347, /* CEEB (52971) */ + 3347, /* CEEC (52972) */ + 3347, /* CEED (52973) */ + 3347, /* CEEE (52974) */ + 3347, /* CEEF (52975) */ + 3347, /* CEF0 (52976) */ + 3347, /* CEF1 (52977) */ + 3347, /* CEF2 (52978) */ + 3347, /* CEF3 (52979) */ + 3347, /* CEF4 (52980) */ + 3347, /* CEF5 (52981) */ + 3347, /* CEF6 (52982) */ + 3347, /* CEF7 (52983) */ + 3347, /* CEF8 (52984) */ + 3347, /* CEF9 (52985) */ + 3347, /* CEFA (52986) */ + 3347, /* CEFB (52987) */ + 3347, /* CEFC (52988) */ + 3347, /* CEFD (52989) */ + 3347, /* CEFE (52990) */ + 3347, /* CEFF (52991) */ + 3347, /* CF00 (52992) */ + 3347, /* CF01 (52993) */ + 3347, /* CF02 (52994) */ + 3347, /* CF03 (52995) */ + 3347, /* CF04 (52996) */ + 3347, /* CF05 (52997) */ + 3347, /* CF06 (52998) */ + 3347, /* CF07 (52999) */ + 3347, /* CF08 (53000) */ + 3347, /* CF09 (53001) */ + 3347, /* CF0A (53002) */ + 3347, /* CF0B (53003) */ + 3347, /* CF0C (53004) */ + 3347, /* CF0D (53005) */ + 3347, /* CF0E (53006) */ + 3347, /* CF0F (53007) */ + 3347, /* CF10 (53008) */ + 3347, /* CF11 (53009) */ + 3347, /* CF12 (53010) */ + 3347, /* CF13 (53011) */ + 3347, /* CF14 (53012) */ + 3347, /* CF15 (53013) */ + 3347, /* CF16 (53014) */ + 3347, /* CF17 (53015) */ + 3347, /* CF18 (53016) */ + 3347, /* CF19 (53017) */ + 3347, /* CF1A (53018) */ + 3347, /* CF1B (53019) */ + 3347, /* CF1C (53020) */ + 3347, /* CF1D (53021) */ + 3347, /* CF1E (53022) */ + 3347, /* CF1F (53023) */ + 3347, /* CF20 (53024) */ + 3347, /* CF21 (53025) */ + 3347, /* CF22 (53026) */ + 3347, /* CF23 (53027) */ + 3347, /* CF24 (53028) */ + 3347, /* CF25 (53029) */ + 3347, /* CF26 (53030) */ + 3347, /* CF27 (53031) */ + 3347, /* CF28 (53032) */ + 3347, /* CF29 (53033) */ + 3347, /* CF2A (53034) */ + 3347, /* CF2B (53035) */ + 3347, /* CF2C (53036) */ + 3347, /* CF2D (53037) */ + 3347, /* CF2E (53038) */ + 3347, /* CF2F (53039) */ + 3347, /* CF30 (53040) */ + 3347, /* CF31 (53041) */ + 3347, /* CF32 (53042) */ + 3347, /* CF33 (53043) */ + 3347, /* CF34 (53044) */ + 3347, /* CF35 (53045) */ + 3347, /* CF36 (53046) */ + 3347, /* CF37 (53047) */ + 3347, /* CF38 (53048) */ + 3347, /* CF39 (53049) */ + 3347, /* CF3A (53050) */ + 3347, /* CF3B (53051) */ + 3347, /* CF3C (53052) */ + 3347, /* CF3D (53053) */ + 3347, /* CF3E (53054) */ + 3347, /* CF3F (53055) */ + 3347, /* CF40 (53056) */ + 3347, /* CF41 (53057) */ + 3347, /* CF42 (53058) */ + 3347, /* CF43 (53059) */ + 3347, /* CF44 (53060) */ + 3347, /* CF45 (53061) */ + 3347, /* CF46 (53062) */ + 3347, /* CF47 (53063) */ + 3347, /* CF48 (53064) */ + 3347, /* CF49 (53065) */ + 3347, /* CF4A (53066) */ + 3347, /* CF4B (53067) */ + 3347, /* CF4C (53068) */ + 3347, /* CF4D (53069) */ + 3347, /* CF4E (53070) */ + 3347, /* CF4F (53071) */ + 3347, /* CF50 (53072) */ + 3347, /* CF51 (53073) */ + 3347, /* CF52 (53074) */ + 3347, /* CF53 (53075) */ + 3347, /* CF54 (53076) */ + 3347, /* CF55 (53077) */ + 3347, /* CF56 (53078) */ + 3347, /* CF57 (53079) */ + 3347, /* CF58 (53080) */ + 3347, /* CF59 (53081) */ + 3347, /* CF5A (53082) */ + 3347, /* CF5B (53083) */ + 3347, /* CF5C (53084) */ + 3347, /* CF5D (53085) */ + 3347, /* CF5E (53086) */ + 3347, /* CF5F (53087) */ + 3347, /* CF60 (53088) */ + 3347, /* CF61 (53089) */ + 3347, /* CF62 (53090) */ + 3347, /* CF63 (53091) */ + 3347, /* CF64 (53092) */ + 3347, /* CF65 (53093) */ + 3347, /* CF66 (53094) */ + 3347, /* CF67 (53095) */ + 3347, /* CF68 (53096) */ + 3347, /* CF69 (53097) */ + 3347, /* CF6A (53098) */ + 3347, /* CF6B (53099) */ + 3347, /* CF6C (53100) */ + 3347, /* CF6D (53101) */ + 3347, /* CF6E (53102) */ + 3347, /* CF6F (53103) */ + 3347, /* CF70 (53104) */ + 3347, /* CF71 (53105) */ + 3347, /* CF72 (53106) */ + 3347, /* CF73 (53107) */ + 3347, /* CF74 (53108) */ + 3347, /* CF75 (53109) */ + 3347, /* CF76 (53110) */ + 3347, /* CF77 (53111) */ + 3347, /* CF78 (53112) */ + 3347, /* CF79 (53113) */ + 3347, /* CF7A (53114) */ + 3347, /* CF7B (53115) */ + 3347, /* CF7C (53116) */ + 3347, /* CF7D (53117) */ + 3347, /* CF7E (53118) */ + 3347, /* CF7F (53119) */ + 3347, /* CF80 (53120) */ + 3347, /* CF81 (53121) */ + 3347, /* CF82 (53122) */ + 3347, /* CF83 (53123) */ + 3347, /* CF84 (53124) */ + 3347, /* CF85 (53125) */ + 3347, /* CF86 (53126) */ + 3347, /* CF87 (53127) */ + 3347, /* CF88 (53128) */ + 3347, /* CF89 (53129) */ + 3347, /* CF8A (53130) */ + 3347, /* CF8B (53131) */ + 3347, /* CF8C (53132) */ + 3347, /* CF8D (53133) */ + 3347, /* CF8E (53134) */ + 3347, /* CF8F (53135) */ + 3347, /* CF90 (53136) */ + 3347, /* CF91 (53137) */ + 3347, /* CF92 (53138) */ + 3347, /* CF93 (53139) */ + 3347, /* CF94 (53140) */ + 3347, /* CF95 (53141) */ + 3347, /* CF96 (53142) */ + 3347, /* CF97 (53143) */ + 3347, /* CF98 (53144) */ + 3347, /* CF99 (53145) */ + 3347, /* CF9A (53146) */ + 3347, /* CF9B (53147) */ + 3347, /* CF9C (53148) */ + 3347, /* CF9D (53149) */ + 3347, /* CF9E (53150) */ + 3347, /* CF9F (53151) */ + 3347, /* CFA0 (53152) */ + 3347, /* CFA1 (53153) */ + 3347, /* CFA2 (53154) */ + 3347, /* CFA3 (53155) */ + 3347, /* CFA4 (53156) */ + 3347, /* CFA5 (53157) */ + 3347, /* CFA6 (53158) */ + 3347, /* CFA7 (53159) */ + 3347, /* CFA8 (53160) */ + 3347, /* CFA9 (53161) */ + 3347, /* CFAA (53162) */ + 3347, /* CFAB (53163) */ + 3347, /* CFAC (53164) */ + 3347, /* CFAD (53165) */ + 3347, /* CFAE (53166) */ + 3347, /* CFAF (53167) */ + 3347, /* CFB0 (53168) */ + 3347, /* CFB1 (53169) */ + 3347, /* CFB2 (53170) */ + 3347, /* CFB3 (53171) */ + 3347, /* CFB4 (53172) */ + 3347, /* CFB5 (53173) */ + 3347, /* CFB6 (53174) */ + 3347, /* CFB7 (53175) */ + 3347, /* CFB8 (53176) */ + 3347, /* CFB9 (53177) */ + 3347, /* CFBA (53178) */ + 3347, /* CFBB (53179) */ + 3347, /* CFBC (53180) */ + 3347, /* CFBD (53181) */ + 3347, /* CFBE (53182) */ + 3347, /* CFBF (53183) */ + 3347, /* CFC0 (53184) */ + 3347, /* CFC1 (53185) */ + 3347, /* CFC2 (53186) */ + 3347, /* CFC3 (53187) */ + 3347, /* CFC4 (53188) */ + 3347, /* CFC5 (53189) */ + 3347, /* CFC6 (53190) */ + 3347, /* CFC7 (53191) */ + 3347, /* CFC8 (53192) */ + 3347, /* CFC9 (53193) */ + 3347, /* CFCA (53194) */ + 3347, /* CFCB (53195) */ + 3347, /* CFCC (53196) */ + 3347, /* CFCD (53197) */ + 3347, /* CFCE (53198) */ + 3347, /* CFCF (53199) */ + 3347, /* CFD0 (53200) */ + 3347, /* CFD1 (53201) */ + 3347, /* CFD2 (53202) */ + 3347, /* CFD3 (53203) */ + 3347, /* CFD4 (53204) */ + 3347, /* CFD5 (53205) */ + 3347, /* CFD6 (53206) */ + 3347, /* CFD7 (53207) */ + 3347, /* CFD8 (53208) */ + 3347, /* CFD9 (53209) */ + 3347, /* CFDA (53210) */ + 3347, /* CFDB (53211) */ + 3347, /* CFDC (53212) */ + 3347, /* CFDD (53213) */ + 3347, /* CFDE (53214) */ + 3347, /* CFDF (53215) */ + 3347, /* CFE0 (53216) */ + 3347, /* CFE1 (53217) */ + 3347, /* CFE2 (53218) */ + 3347, /* CFE3 (53219) */ + 3347, /* CFE4 (53220) */ + 3347, /* CFE5 (53221) */ + 3347, /* CFE6 (53222) */ + 3347, /* CFE7 (53223) */ + 3347, /* CFE8 (53224) */ + 3347, /* CFE9 (53225) */ + 3347, /* CFEA (53226) */ + 3347, /* CFEB (53227) */ + 3347, /* CFEC (53228) */ + 3347, /* CFED (53229) */ + 3347, /* CFEE (53230) */ + 3347, /* CFEF (53231) */ + 3347, /* CFF0 (53232) */ + 3347, /* CFF1 (53233) */ + 3347, /* CFF2 (53234) */ + 3347, /* CFF3 (53235) */ + 3347, /* CFF4 (53236) */ + 3347, /* CFF5 (53237) */ + 3347, /* CFF6 (53238) */ + 3347, /* CFF7 (53239) */ + 3347, /* CFF8 (53240) */ + 3347, /* CFF9 (53241) */ + 3347, /* CFFA (53242) */ + 3347, /* CFFB (53243) */ + 3347, /* CFFC (53244) */ + 3347, /* CFFD (53245) */ + 3347, /* CFFE (53246) */ + 3347, /* CFFF (53247) */ + 3347, /* D000 (53248) */ + 3347, /* D001 (53249) */ + 3347, /* D002 (53250) */ + 3347, /* D003 (53251) */ + 3347, /* D004 (53252) */ + 3347, /* D005 (53253) */ + 3347, /* D006 (53254) */ + 3347, /* D007 (53255) */ + 3347, /* D008 (53256) */ + 3347, /* D009 (53257) */ + 3347, /* D00A (53258) */ + 3347, /* D00B (53259) */ + 3347, /* D00C (53260) */ + 3347, /* D00D (53261) */ + 3347, /* D00E (53262) */ + 3347, /* D00F (53263) */ + 3347, /* D010 (53264) */ + 3347, /* D011 (53265) */ + 3347, /* D012 (53266) */ + 3347, /* D013 (53267) */ + 3347, /* D014 (53268) */ + 3347, /* D015 (53269) */ + 3347, /* D016 (53270) */ + 3347, /* D017 (53271) */ + 3347, /* D018 (53272) */ + 3347, /* D019 (53273) */ + 3347, /* D01A (53274) */ + 3347, /* D01B (53275) */ + 3347, /* D01C (53276) */ + 3347, /* D01D (53277) */ + 3347, /* D01E (53278) */ + 3347, /* D01F (53279) */ + 3347, /* D020 (53280) */ + 3347, /* D021 (53281) */ + 3347, /* D022 (53282) */ + 3347, /* D023 (53283) */ + 3347, /* D024 (53284) */ + 3347, /* D025 (53285) */ + 3347, /* D026 (53286) */ + 3347, /* D027 (53287) */ + 3347, /* D028 (53288) */ + 3347, /* D029 (53289) */ + 3347, /* D02A (53290) */ + 3347, /* D02B (53291) */ + 3347, /* D02C (53292) */ + 3347, /* D02D (53293) */ + 3347, /* D02E (53294) */ + 3347, /* D02F (53295) */ + 3347, /* D030 (53296) */ + 3347, /* D031 (53297) */ + 3347, /* D032 (53298) */ + 3347, /* D033 (53299) */ + 3347, /* D034 (53300) */ + 3347, /* D035 (53301) */ + 3347, /* D036 (53302) */ + 3347, /* D037 (53303) */ + 3347, /* D038 (53304) */ + 3347, /* D039 (53305) */ + 3347, /* D03A (53306) */ + 3347, /* D03B (53307) */ + 3347, /* D03C (53308) */ + 3347, /* D03D (53309) */ + 3347, /* D03E (53310) */ + 3347, /* D03F (53311) */ + 3347, /* D040 (53312) */ + 3347, /* D041 (53313) */ + 3347, /* D042 (53314) */ + 3347, /* D043 (53315) */ + 3347, /* D044 (53316) */ + 3347, /* D045 (53317) */ + 3347, /* D046 (53318) */ + 3347, /* D047 (53319) */ + 3347, /* D048 (53320) */ + 3347, /* D049 (53321) */ + 3347, /* D04A (53322) */ + 3347, /* D04B (53323) */ + 3347, /* D04C (53324) */ + 3347, /* D04D (53325) */ + 3347, /* D04E (53326) */ + 3347, /* D04F (53327) */ + 3347, /* D050 (53328) */ + 3347, /* D051 (53329) */ + 3347, /* D052 (53330) */ + 3347, /* D053 (53331) */ + 3347, /* D054 (53332) */ + 3347, /* D055 (53333) */ + 3347, /* D056 (53334) */ + 3347, /* D057 (53335) */ + 3347, /* D058 (53336) */ + 3347, /* D059 (53337) */ + 3347, /* D05A (53338) */ + 3347, /* D05B (53339) */ + 3347, /* D05C (53340) */ + 3347, /* D05D (53341) */ + 3347, /* D05E (53342) */ + 3347, /* D05F (53343) */ + 3347, /* D060 (53344) */ + 3347, /* D061 (53345) */ + 3347, /* D062 (53346) */ + 3347, /* D063 (53347) */ + 3347, /* D064 (53348) */ + 3347, /* D065 (53349) */ + 3347, /* D066 (53350) */ + 3347, /* D067 (53351) */ + 3347, /* D068 (53352) */ + 3347, /* D069 (53353) */ + 3347, /* D06A (53354) */ + 3347, /* D06B (53355) */ + 3347, /* D06C (53356) */ + 3347, /* D06D (53357) */ + 3347, /* D06E (53358) */ + 3347, /* D06F (53359) */ + 3347, /* D070 (53360) */ + 3347, /* D071 (53361) */ + 3347, /* D072 (53362) */ + 3347, /* D073 (53363) */ + 3347, /* D074 (53364) */ + 3347, /* D075 (53365) */ + 3347, /* D076 (53366) */ + 3347, /* D077 (53367) */ + 3347, /* D078 (53368) */ + 3347, /* D079 (53369) */ + 3347, /* D07A (53370) */ + 3347, /* D07B (53371) */ + 3347, /* D07C (53372) */ + 3347, /* D07D (53373) */ + 3347, /* D07E (53374) */ + 3347, /* D07F (53375) */ + 3347, /* D080 (53376) */ + 3347, /* D081 (53377) */ + 3347, /* D082 (53378) */ + 3347, /* D083 (53379) */ + 3347, /* D084 (53380) */ + 3347, /* D085 (53381) */ + 3347, /* D086 (53382) */ + 3347, /* D087 (53383) */ + 3347, /* D088 (53384) */ + 3347, /* D089 (53385) */ + 3347, /* D08A (53386) */ + 3347, /* D08B (53387) */ + 3347, /* D08C (53388) */ + 3347, /* D08D (53389) */ + 3347, /* D08E (53390) */ + 3347, /* D08F (53391) */ + 3347, /* D090 (53392) */ + 3347, /* D091 (53393) */ + 3347, /* D092 (53394) */ + 3347, /* D093 (53395) */ + 3347, /* D094 (53396) */ + 3347, /* D095 (53397) */ + 3347, /* D096 (53398) */ + 3347, /* D097 (53399) */ + 3347, /* D098 (53400) */ + 3347, /* D099 (53401) */ + 3347, /* D09A (53402) */ + 3347, /* D09B (53403) */ + 3347, /* D09C (53404) */ + 3347, /* D09D (53405) */ + 3347, /* D09E (53406) */ + 3347, /* D09F (53407) */ + 3347, /* D0A0 (53408) */ + 3347, /* D0A1 (53409) */ + 3347, /* D0A2 (53410) */ + 3347, /* D0A3 (53411) */ + 3347, /* D0A4 (53412) */ + 3347, /* D0A5 (53413) */ + 3347, /* D0A6 (53414) */ + 3347, /* D0A7 (53415) */ + 3347, /* D0A8 (53416) */ + 3347, /* D0A9 (53417) */ + 3347, /* D0AA (53418) */ + 3347, /* D0AB (53419) */ + 3347, /* D0AC (53420) */ + 3347, /* D0AD (53421) */ + 3347, /* D0AE (53422) */ + 3347, /* D0AF (53423) */ + 3347, /* D0B0 (53424) */ + 3347, /* D0B1 (53425) */ + 3347, /* D0B2 (53426) */ + 3347, /* D0B3 (53427) */ + 3347, /* D0B4 (53428) */ + 3347, /* D0B5 (53429) */ + 3347, /* D0B6 (53430) */ + 3347, /* D0B7 (53431) */ + 3347, /* D0B8 (53432) */ + 3347, /* D0B9 (53433) */ + 3347, /* D0BA (53434) */ + 3347, /* D0BB (53435) */ + 3347, /* D0BC (53436) */ + 3347, /* D0BD (53437) */ + 3347, /* D0BE (53438) */ + 3347, /* D0BF (53439) */ + 3347, /* D0C0 (53440) */ + 3347, /* D0C1 (53441) */ + 3347, /* D0C2 (53442) */ + 3347, /* D0C3 (53443) */ + 3347, /* D0C4 (53444) */ + 3347, /* D0C5 (53445) */ + 3347, /* D0C6 (53446) */ + 3347, /* D0C7 (53447) */ + 3347, /* D0C8 (53448) */ + 3347, /* D0C9 (53449) */ + 3347, /* D0CA (53450) */ + 3347, /* D0CB (53451) */ + 3347, /* D0CC (53452) */ + 3347, /* D0CD (53453) */ + 3347, /* D0CE (53454) */ + 3347, /* D0CF (53455) */ + 3347, /* D0D0 (53456) */ + 3347, /* D0D1 (53457) */ + 3347, /* D0D2 (53458) */ + 3347, /* D0D3 (53459) */ + 3347, /* D0D4 (53460) */ + 3347, /* D0D5 (53461) */ + 3347, /* D0D6 (53462) */ + 3347, /* D0D7 (53463) */ + 3347, /* D0D8 (53464) */ + 3347, /* D0D9 (53465) */ + 3347, /* D0DA (53466) */ + 3347, /* D0DB (53467) */ + 3347, /* D0DC (53468) */ + 3347, /* D0DD (53469) */ + 3347, /* D0DE (53470) */ + 3347, /* D0DF (53471) */ + 3347, /* D0E0 (53472) */ + 3347, /* D0E1 (53473) */ + 3347, /* D0E2 (53474) */ + 3347, /* D0E3 (53475) */ + 3347, /* D0E4 (53476) */ + 3347, /* D0E5 (53477) */ + 3347, /* D0E6 (53478) */ + 3347, /* D0E7 (53479) */ + 3347, /* D0E8 (53480) */ + 3347, /* D0E9 (53481) */ + 3347, /* D0EA (53482) */ + 3347, /* D0EB (53483) */ + 3347, /* D0EC (53484) */ + 3347, /* D0ED (53485) */ + 3347, /* D0EE (53486) */ + 3347, /* D0EF (53487) */ + 3347, /* D0F0 (53488) */ + 3347, /* D0F1 (53489) */ + 3347, /* D0F2 (53490) */ + 3347, /* D0F3 (53491) */ + 3347, /* D0F4 (53492) */ + 3347, /* D0F5 (53493) */ + 3347, /* D0F6 (53494) */ + 3347, /* D0F7 (53495) */ + 3347, /* D0F8 (53496) */ + 3347, /* D0F9 (53497) */ + 3347, /* D0FA (53498) */ + 3347, /* D0FB (53499) */ + 3347, /* D0FC (53500) */ + 3347, /* D0FD (53501) */ + 3347, /* D0FE (53502) */ + 3347, /* D0FF (53503) */ + 3347, /* D100 (53504) */ + 3347, /* D101 (53505) */ + 3347, /* D102 (53506) */ + 3347, /* D103 (53507) */ + 3347, /* D104 (53508) */ + 3347, /* D105 (53509) */ + 3347, /* D106 (53510) */ + 3347, /* D107 (53511) */ + 3347, /* D108 (53512) */ + 3347, /* D109 (53513) */ + 3347, /* D10A (53514) */ + 3347, /* D10B (53515) */ + 3347, /* D10C (53516) */ + 3347, /* D10D (53517) */ + 3347, /* D10E (53518) */ + 3347, /* D10F (53519) */ + 3347, /* D110 (53520) */ + 3347, /* D111 (53521) */ + 3347, /* D112 (53522) */ + 3347, /* D113 (53523) */ + 3347, /* D114 (53524) */ + 3347, /* D115 (53525) */ + 3347, /* D116 (53526) */ + 3347, /* D117 (53527) */ + 3347, /* D118 (53528) */ + 3347, /* D119 (53529) */ + 3347, /* D11A (53530) */ + 3347, /* D11B (53531) */ + 3347, /* D11C (53532) */ + 3347, /* D11D (53533) */ + 3347, /* D11E (53534) */ + 3347, /* D11F (53535) */ + 3347, /* D120 (53536) */ + 3347, /* D121 (53537) */ + 3347, /* D122 (53538) */ + 3347, /* D123 (53539) */ + 3347, /* D124 (53540) */ + 3347, /* D125 (53541) */ + 3347, /* D126 (53542) */ + 3347, /* D127 (53543) */ + 3347, /* D128 (53544) */ + 3347, /* D129 (53545) */ + 3347, /* D12A (53546) */ + 3347, /* D12B (53547) */ + 3347, /* D12C (53548) */ + 3347, /* D12D (53549) */ + 3347, /* D12E (53550) */ + 3347, /* D12F (53551) */ + 3347, /* D130 (53552) */ + 3347, /* D131 (53553) */ + 3347, /* D132 (53554) */ + 3347, /* D133 (53555) */ + 3347, /* D134 (53556) */ + 3347, /* D135 (53557) */ + 3347, /* D136 (53558) */ + 3347, /* D137 (53559) */ + 3347, /* D138 (53560) */ + 3347, /* D139 (53561) */ + 3347, /* D13A (53562) */ + 3347, /* D13B (53563) */ + 3347, /* D13C (53564) */ + 3347, /* D13D (53565) */ + 3347, /* D13E (53566) */ + 3347, /* D13F (53567) */ + 3347, /* D140 (53568) */ + 3347, /* D141 (53569) */ + 3347, /* D142 (53570) */ + 3347, /* D143 (53571) */ + 3347, /* D144 (53572) */ + 3347, /* D145 (53573) */ + 3347, /* D146 (53574) */ + 3347, /* D147 (53575) */ + 3347, /* D148 (53576) */ + 3347, /* D149 (53577) */ + 3347, /* D14A (53578) */ + 3347, /* D14B (53579) */ + 3347, /* D14C (53580) */ + 3347, /* D14D (53581) */ + 3347, /* D14E (53582) */ + 3347, /* D14F (53583) */ + 3347, /* D150 (53584) */ + 3347, /* D151 (53585) */ + 3347, /* D152 (53586) */ + 3347, /* D153 (53587) */ + 3347, /* D154 (53588) */ + 3347, /* D155 (53589) */ + 3347, /* D156 (53590) */ + 3347, /* D157 (53591) */ + 3347, /* D158 (53592) */ + 3347, /* D159 (53593) */ + 3347, /* D15A (53594) */ + 3347, /* D15B (53595) */ + 3347, /* D15C (53596) */ + 3347, /* D15D (53597) */ + 3347, /* D15E (53598) */ + 3347, /* D15F (53599) */ + 3347, /* D160 (53600) */ + 3347, /* D161 (53601) */ + 3347, /* D162 (53602) */ + 3347, /* D163 (53603) */ + 3347, /* D164 (53604) */ + 3347, /* D165 (53605) */ + 3347, /* D166 (53606) */ + 3347, /* D167 (53607) */ + 3347, /* D168 (53608) */ + 3347, /* D169 (53609) */ + 3347, /* D16A (53610) */ + 3347, /* D16B (53611) */ + 3347, /* D16C (53612) */ + 3347, /* D16D (53613) */ + 3347, /* D16E (53614) */ + 3347, /* D16F (53615) */ + 3347, /* D170 (53616) */ + 3347, /* D171 (53617) */ + 3347, /* D172 (53618) */ + 3347, /* D173 (53619) */ + 3347, /* D174 (53620) */ + 3347, /* D175 (53621) */ + 3347, /* D176 (53622) */ + 3347, /* D177 (53623) */ + 3347, /* D178 (53624) */ + 3347, /* D179 (53625) */ + 3347, /* D17A (53626) */ + 3347, /* D17B (53627) */ + 3347, /* D17C (53628) */ + 3347, /* D17D (53629) */ + 3347, /* D17E (53630) */ + 3347, /* D17F (53631) */ + 3347, /* D180 (53632) */ + 3347, /* D181 (53633) */ + 3347, /* D182 (53634) */ + 3347, /* D183 (53635) */ + 3347, /* D184 (53636) */ + 3347, /* D185 (53637) */ + 3347, /* D186 (53638) */ + 3347, /* D187 (53639) */ + 3347, /* D188 (53640) */ + 3347, /* D189 (53641) */ + 3347, /* D18A (53642) */ + 3347, /* D18B (53643) */ + 3347, /* D18C (53644) */ + 3347, /* D18D (53645) */ + 3347, /* D18E (53646) */ + 3347, /* D18F (53647) */ + 3347, /* D190 (53648) */ + 3347, /* D191 (53649) */ + 3347, /* D192 (53650) */ + 3347, /* D193 (53651) */ + 3347, /* D194 (53652) */ + 3347, /* D195 (53653) */ + 3347, /* D196 (53654) */ + 3347, /* D197 (53655) */ + 3347, /* D198 (53656) */ + 3347, /* D199 (53657) */ + 3347, /* D19A (53658) */ + 3347, /* D19B (53659) */ + 3347, /* D19C (53660) */ + 3347, /* D19D (53661) */ + 3347, /* D19E (53662) */ + 3347, /* D19F (53663) */ + 3347, /* D1A0 (53664) */ + 3347, /* D1A1 (53665) */ + 3347, /* D1A2 (53666) */ + 3347, /* D1A3 (53667) */ + 3347, /* D1A4 (53668) */ + 3347, /* D1A5 (53669) */ + 3347, /* D1A6 (53670) */ + 3347, /* D1A7 (53671) */ + 3347, /* D1A8 (53672) */ + 3347, /* D1A9 (53673) */ + 3347, /* D1AA (53674) */ + 3347, /* D1AB (53675) */ + 3347, /* D1AC (53676) */ + 3347, /* D1AD (53677) */ + 3347, /* D1AE (53678) */ + 3347, /* D1AF (53679) */ + 3347, /* D1B0 (53680) */ + 3347, /* D1B1 (53681) */ + 3347, /* D1B2 (53682) */ + 3347, /* D1B3 (53683) */ + 3347, /* D1B4 (53684) */ + 3347, /* D1B5 (53685) */ + 3347, /* D1B6 (53686) */ + 3347, /* D1B7 (53687) */ + 3347, /* D1B8 (53688) */ + 3347, /* D1B9 (53689) */ + 3347, /* D1BA (53690) */ + 3347, /* D1BB (53691) */ + 3347, /* D1BC (53692) */ + 3347, /* D1BD (53693) */ + 3347, /* D1BE (53694) */ + 3347, /* D1BF (53695) */ + 3347, /* D1C0 (53696) */ + 3347, /* D1C1 (53697) */ + 3347, /* D1C2 (53698) */ + 3347, /* D1C3 (53699) */ + 3347, /* D1C4 (53700) */ + 3347, /* D1C5 (53701) */ + 3347, /* D1C6 (53702) */ + 3347, /* D1C7 (53703) */ + 3347, /* D1C8 (53704) */ + 3347, /* D1C9 (53705) */ + 3347, /* D1CA (53706) */ + 3347, /* D1CB (53707) */ + 3347, /* D1CC (53708) */ + 3347, /* D1CD (53709) */ + 3347, /* D1CE (53710) */ + 3347, /* D1CF (53711) */ + 3347, /* D1D0 (53712) */ + 3347, /* D1D1 (53713) */ + 3347, /* D1D2 (53714) */ + 3347, /* D1D3 (53715) */ + 3347, /* D1D4 (53716) */ + 3347, /* D1D5 (53717) */ + 3347, /* D1D6 (53718) */ + 3347, /* D1D7 (53719) */ + 3347, /* D1D8 (53720) */ + 3347, /* D1D9 (53721) */ + 3347, /* D1DA (53722) */ + 3347, /* D1DB (53723) */ + 3347, /* D1DC (53724) */ + 3347, /* D1DD (53725) */ + 3347, /* D1DE (53726) */ + 3347, /* D1DF (53727) */ + 3347, /* D1E0 (53728) */ + 3347, /* D1E1 (53729) */ + 3347, /* D1E2 (53730) */ + 3347, /* D1E3 (53731) */ + 3347, /* D1E4 (53732) */ + 3347, /* D1E5 (53733) */ + 3347, /* D1E6 (53734) */ + 3347, /* D1E7 (53735) */ + 3347, /* D1E8 (53736) */ + 3347, /* D1E9 (53737) */ + 3347, /* D1EA (53738) */ + 3347, /* D1EB (53739) */ + 3347, /* D1EC (53740) */ + 3347, /* D1ED (53741) */ + 3347, /* D1EE (53742) */ + 3347, /* D1EF (53743) */ + 3347, /* D1F0 (53744) */ + 3347, /* D1F1 (53745) */ + 3347, /* D1F2 (53746) */ + 3347, /* D1F3 (53747) */ + 3347, /* D1F4 (53748) */ + 3347, /* D1F5 (53749) */ + 3347, /* D1F6 (53750) */ + 3347, /* D1F7 (53751) */ + 3347, /* D1F8 (53752) */ + 3347, /* D1F9 (53753) */ + 3347, /* D1FA (53754) */ + 3347, /* D1FB (53755) */ + 3347, /* D1FC (53756) */ + 3347, /* D1FD (53757) */ + 3347, /* D1FE (53758) */ + 3347, /* D1FF (53759) */ + 3347, /* D200 (53760) */ + 3347, /* D201 (53761) */ + 3347, /* D202 (53762) */ + 3347, /* D203 (53763) */ + 3347, /* D204 (53764) */ + 3347, /* D205 (53765) */ + 3347, /* D206 (53766) */ + 3347, /* D207 (53767) */ + 3347, /* D208 (53768) */ + 3347, /* D209 (53769) */ + 3347, /* D20A (53770) */ + 3347, /* D20B (53771) */ + 3347, /* D20C (53772) */ + 3347, /* D20D (53773) */ + 3347, /* D20E (53774) */ + 3347, /* D20F (53775) */ + 3347, /* D210 (53776) */ + 3347, /* D211 (53777) */ + 3347, /* D212 (53778) */ + 3347, /* D213 (53779) */ + 3347, /* D214 (53780) */ + 3347, /* D215 (53781) */ + 3347, /* D216 (53782) */ + 3347, /* D217 (53783) */ + 3347, /* D218 (53784) */ + 3347, /* D219 (53785) */ + 3347, /* D21A (53786) */ + 3347, /* D21B (53787) */ + 3347, /* D21C (53788) */ + 3347, /* D21D (53789) */ + 3347, /* D21E (53790) */ + 3347, /* D21F (53791) */ + 3347, /* D220 (53792) */ + 3347, /* D221 (53793) */ + 3347, /* D222 (53794) */ + 3347, /* D223 (53795) */ + 3347, /* D224 (53796) */ + 3347, /* D225 (53797) */ + 3347, /* D226 (53798) */ + 3347, /* D227 (53799) */ + 3347, /* D228 (53800) */ + 3347, /* D229 (53801) */ + 3347, /* D22A (53802) */ + 3347, /* D22B (53803) */ + 3347, /* D22C (53804) */ + 3347, /* D22D (53805) */ + 3347, /* D22E (53806) */ + 3347, /* D22F (53807) */ + 3347, /* D230 (53808) */ + 3347, /* D231 (53809) */ + 3347, /* D232 (53810) */ + 3347, /* D233 (53811) */ + 3347, /* D234 (53812) */ + 3347, /* D235 (53813) */ + 3347, /* D236 (53814) */ + 3347, /* D237 (53815) */ + 3347, /* D238 (53816) */ + 3347, /* D239 (53817) */ + 3347, /* D23A (53818) */ + 3347, /* D23B (53819) */ + 3347, /* D23C (53820) */ + 3347, /* D23D (53821) */ + 3347, /* D23E (53822) */ + 3347, /* D23F (53823) */ + 3347, /* D240 (53824) */ + 3347, /* D241 (53825) */ + 3347, /* D242 (53826) */ + 3347, /* D243 (53827) */ + 3347, /* D244 (53828) */ + 3347, /* D245 (53829) */ + 3347, /* D246 (53830) */ + 3347, /* D247 (53831) */ + 3347, /* D248 (53832) */ + 3347, /* D249 (53833) */ + 3347, /* D24A (53834) */ + 3347, /* D24B (53835) */ + 3347, /* D24C (53836) */ + 3347, /* D24D (53837) */ + 3347, /* D24E (53838) */ + 3347, /* D24F (53839) */ + 3347, /* D250 (53840) */ + 3347, /* D251 (53841) */ + 3347, /* D252 (53842) */ + 3347, /* D253 (53843) */ + 3347, /* D254 (53844) */ + 3347, /* D255 (53845) */ + 3347, /* D256 (53846) */ + 3347, /* D257 (53847) */ + 3347, /* D258 (53848) */ + 3347, /* D259 (53849) */ + 3347, /* D25A (53850) */ + 3347, /* D25B (53851) */ + 3347, /* D25C (53852) */ + 3347, /* D25D (53853) */ + 3347, /* D25E (53854) */ + 3347, /* D25F (53855) */ + 3347, /* D260 (53856) */ + 3347, /* D261 (53857) */ + 3347, /* D262 (53858) */ + 3347, /* D263 (53859) */ + 3347, /* D264 (53860) */ + 3347, /* D265 (53861) */ + 3347, /* D266 (53862) */ + 3347, /* D267 (53863) */ + 3347, /* D268 (53864) */ + 3347, /* D269 (53865) */ + 3347, /* D26A (53866) */ + 3347, /* D26B (53867) */ + 3347, /* D26C (53868) */ + 3347, /* D26D (53869) */ + 3347, /* D26E (53870) */ + 3347, /* D26F (53871) */ + 3347, /* D270 (53872) */ + 3347, /* D271 (53873) */ + 3347, /* D272 (53874) */ + 3347, /* D273 (53875) */ + 3347, /* D274 (53876) */ + 3347, /* D275 (53877) */ + 3347, /* D276 (53878) */ + 3347, /* D277 (53879) */ + 3347, /* D278 (53880) */ + 3347, /* D279 (53881) */ + 3347, /* D27A (53882) */ + 3347, /* D27B (53883) */ + 3347, /* D27C (53884) */ + 3347, /* D27D (53885) */ + 3347, /* D27E (53886) */ + 3347, /* D27F (53887) */ + 3347, /* D280 (53888) */ + 3347, /* D281 (53889) */ + 3347, /* D282 (53890) */ + 3347, /* D283 (53891) */ + 3347, /* D284 (53892) */ + 3347, /* D285 (53893) */ + 3347, /* D286 (53894) */ + 3347, /* D287 (53895) */ + 3347, /* D288 (53896) */ + 3347, /* D289 (53897) */ + 3347, /* D28A (53898) */ + 3347, /* D28B (53899) */ + 3347, /* D28C (53900) */ + 3347, /* D28D (53901) */ + 3347, /* D28E (53902) */ + 3347, /* D28F (53903) */ + 3347, /* D290 (53904) */ + 3347, /* D291 (53905) */ + 3347, /* D292 (53906) */ + 3347, /* D293 (53907) */ + 3347, /* D294 (53908) */ + 3347, /* D295 (53909) */ + 3347, /* D296 (53910) */ + 3347, /* D297 (53911) */ + 3347, /* D298 (53912) */ + 3347, /* D299 (53913) */ + 3347, /* D29A (53914) */ + 3347, /* D29B (53915) */ + 3347, /* D29C (53916) */ + 3347, /* D29D (53917) */ + 3347, /* D29E (53918) */ + 3347, /* D29F (53919) */ + 3347, /* D2A0 (53920) */ + 3347, /* D2A1 (53921) */ + 3347, /* D2A2 (53922) */ + 3347, /* D2A3 (53923) */ + 3347, /* D2A4 (53924) */ + 3347, /* D2A5 (53925) */ + 3347, /* D2A6 (53926) */ + 3347, /* D2A7 (53927) */ + 3347, /* D2A8 (53928) */ + 3347, /* D2A9 (53929) */ + 3347, /* D2AA (53930) */ + 3347, /* D2AB (53931) */ + 3347, /* D2AC (53932) */ + 3347, /* D2AD (53933) */ + 3347, /* D2AE (53934) */ + 3347, /* D2AF (53935) */ + 3347, /* D2B0 (53936) */ + 3347, /* D2B1 (53937) */ + 3347, /* D2B2 (53938) */ + 3347, /* D2B3 (53939) */ + 3347, /* D2B4 (53940) */ + 3347, /* D2B5 (53941) */ + 3347, /* D2B6 (53942) */ + 3347, /* D2B7 (53943) */ + 3347, /* D2B8 (53944) */ + 3347, /* D2B9 (53945) */ + 3347, /* D2BA (53946) */ + 3347, /* D2BB (53947) */ + 3347, /* D2BC (53948) */ + 3347, /* D2BD (53949) */ + 3347, /* D2BE (53950) */ + 3347, /* D2BF (53951) */ + 3347, /* D2C0 (53952) */ + 3347, /* D2C1 (53953) */ + 3347, /* D2C2 (53954) */ + 3347, /* D2C3 (53955) */ + 3347, /* D2C4 (53956) */ + 3347, /* D2C5 (53957) */ + 3347, /* D2C6 (53958) */ + 3347, /* D2C7 (53959) */ + 3347, /* D2C8 (53960) */ + 3347, /* D2C9 (53961) */ + 3347, /* D2CA (53962) */ + 3347, /* D2CB (53963) */ + 3347, /* D2CC (53964) */ + 3347, /* D2CD (53965) */ + 3347, /* D2CE (53966) */ + 3347, /* D2CF (53967) */ + 3347, /* D2D0 (53968) */ + 3347, /* D2D1 (53969) */ + 3347, /* D2D2 (53970) */ + 3347, /* D2D3 (53971) */ + 3347, /* D2D4 (53972) */ + 3347, /* D2D5 (53973) */ + 3347, /* D2D6 (53974) */ + 3347, /* D2D7 (53975) */ + 3347, /* D2D8 (53976) */ + 3347, /* D2D9 (53977) */ + 3347, /* D2DA (53978) */ + 3347, /* D2DB (53979) */ + 3347, /* D2DC (53980) */ + 3347, /* D2DD (53981) */ + 3347, /* D2DE (53982) */ + 3347, /* D2DF (53983) */ + 3347, /* D2E0 (53984) */ + 3347, /* D2E1 (53985) */ + 3347, /* D2E2 (53986) */ + 3347, /* D2E3 (53987) */ + 3347, /* D2E4 (53988) */ + 3347, /* D2E5 (53989) */ + 3347, /* D2E6 (53990) */ + 3347, /* D2E7 (53991) */ + 3347, /* D2E8 (53992) */ + 3347, /* D2E9 (53993) */ + 3347, /* D2EA (53994) */ + 3347, /* D2EB (53995) */ + 3347, /* D2EC (53996) */ + 3347, /* D2ED (53997) */ + 3347, /* D2EE (53998) */ + 3347, /* D2EF (53999) */ + 3347, /* D2F0 (54000) */ + 3347, /* D2F1 (54001) */ + 3347, /* D2F2 (54002) */ + 3347, /* D2F3 (54003) */ + 3347, /* D2F4 (54004) */ + 3347, /* D2F5 (54005) */ + 3347, /* D2F6 (54006) */ + 3347, /* D2F7 (54007) */ + 3347, /* D2F8 (54008) */ + 3347, /* D2F9 (54009) */ + 3347, /* D2FA (54010) */ + 3347, /* D2FB (54011) */ + 3347, /* D2FC (54012) */ + 3347, /* D2FD (54013) */ + 3347, /* D2FE (54014) */ + 3347, /* D2FF (54015) */ + 3347, /* D300 (54016) */ + 3347, /* D301 (54017) */ + 3347, /* D302 (54018) */ + 3347, /* D303 (54019) */ + 3347, /* D304 (54020) */ + 3347, /* D305 (54021) */ + 3347, /* D306 (54022) */ + 3347, /* D307 (54023) */ + 3347, /* D308 (54024) */ + 3347, /* D309 (54025) */ + 3347, /* D30A (54026) */ + 3347, /* D30B (54027) */ + 3347, /* D30C (54028) */ + 3347, /* D30D (54029) */ + 3347, /* D30E (54030) */ + 3347, /* D30F (54031) */ + 3347, /* D310 (54032) */ + 3347, /* D311 (54033) */ + 3347, /* D312 (54034) */ + 3347, /* D313 (54035) */ + 3347, /* D314 (54036) */ + 3347, /* D315 (54037) */ + 3347, /* D316 (54038) */ + 3347, /* D317 (54039) */ + 3347, /* D318 (54040) */ + 3347, /* D319 (54041) */ + 3347, /* D31A (54042) */ + 3347, /* D31B (54043) */ + 3347, /* D31C (54044) */ + 3347, /* D31D (54045) */ + 3347, /* D31E (54046) */ + 3347, /* D31F (54047) */ + 3347, /* D320 (54048) */ + 3347, /* D321 (54049) */ + 3347, /* D322 (54050) */ + 3347, /* D323 (54051) */ + 3347, /* D324 (54052) */ + 3347, /* D325 (54053) */ + 3347, /* D326 (54054) */ + 3347, /* D327 (54055) */ + 3347, /* D328 (54056) */ + 3347, /* D329 (54057) */ + 3347, /* D32A (54058) */ + 3347, /* D32B (54059) */ + 3347, /* D32C (54060) */ + 3347, /* D32D (54061) */ + 3347, /* D32E (54062) */ + 3347, /* D32F (54063) */ + 3347, /* D330 (54064) */ + 3347, /* D331 (54065) */ + 3347, /* D332 (54066) */ + 3347, /* D333 (54067) */ + 3347, /* D334 (54068) */ + 3347, /* D335 (54069) */ + 3347, /* D336 (54070) */ + 3347, /* D337 (54071) */ + 3347, /* D338 (54072) */ + 3347, /* D339 (54073) */ + 3347, /* D33A (54074) */ + 3347, /* D33B (54075) */ + 3347, /* D33C (54076) */ + 3347, /* D33D (54077) */ + 3347, /* D33E (54078) */ + 3347, /* D33F (54079) */ + 3347, /* D340 (54080) */ + 3347, /* D341 (54081) */ + 3347, /* D342 (54082) */ + 3347, /* D343 (54083) */ + 3347, /* D344 (54084) */ + 3347, /* D345 (54085) */ + 3347, /* D346 (54086) */ + 3347, /* D347 (54087) */ + 3347, /* D348 (54088) */ + 3347, /* D349 (54089) */ + 3347, /* D34A (54090) */ + 3347, /* D34B (54091) */ + 3347, /* D34C (54092) */ + 3347, /* D34D (54093) */ + 3347, /* D34E (54094) */ + 3347, /* D34F (54095) */ + 3347, /* D350 (54096) */ + 3347, /* D351 (54097) */ + 3347, /* D352 (54098) */ + 3347, /* D353 (54099) */ + 3347, /* D354 (54100) */ + 3347, /* D355 (54101) */ + 3347, /* D356 (54102) */ + 3347, /* D357 (54103) */ + 3347, /* D358 (54104) */ + 3347, /* D359 (54105) */ + 3347, /* D35A (54106) */ + 3347, /* D35B (54107) */ + 3347, /* D35C (54108) */ + 3347, /* D35D (54109) */ + 3347, /* D35E (54110) */ + 3347, /* D35F (54111) */ + 3347, /* D360 (54112) */ + 3347, /* D361 (54113) */ + 3347, /* D362 (54114) */ + 3347, /* D363 (54115) */ + 3347, /* D364 (54116) */ + 3347, /* D365 (54117) */ + 3347, /* D366 (54118) */ + 3347, /* D367 (54119) */ + 3347, /* D368 (54120) */ + 3347, /* D369 (54121) */ + 3347, /* D36A (54122) */ + 3347, /* D36B (54123) */ + 3347, /* D36C (54124) */ + 3347, /* D36D (54125) */ + 3347, /* D36E (54126) */ + 3347, /* D36F (54127) */ + 3347, /* D370 (54128) */ + 3347, /* D371 (54129) */ + 3347, /* D372 (54130) */ + 3347, /* D373 (54131) */ + 3347, /* D374 (54132) */ + 3347, /* D375 (54133) */ + 3347, /* D376 (54134) */ + 3347, /* D377 (54135) */ + 3347, /* D378 (54136) */ + 3347, /* D379 (54137) */ + 3347, /* D37A (54138) */ + 3347, /* D37B (54139) */ + 3347, /* D37C (54140) */ + 3347, /* D37D (54141) */ + 3347, /* D37E (54142) */ + 3347, /* D37F (54143) */ + 3347, /* D380 (54144) */ + 3347, /* D381 (54145) */ + 3347, /* D382 (54146) */ + 3347, /* D383 (54147) */ + 3347, /* D384 (54148) */ + 3347, /* D385 (54149) */ + 3347, /* D386 (54150) */ + 3347, /* D387 (54151) */ + 3347, /* D388 (54152) */ + 3347, /* D389 (54153) */ + 3347, /* D38A (54154) */ + 3347, /* D38B (54155) */ + 3347, /* D38C (54156) */ + 3347, /* D38D (54157) */ + 3347, /* D38E (54158) */ + 3347, /* D38F (54159) */ + 3347, /* D390 (54160) */ + 3347, /* D391 (54161) */ + 3347, /* D392 (54162) */ + 3347, /* D393 (54163) */ + 3347, /* D394 (54164) */ + 3347, /* D395 (54165) */ + 3347, /* D396 (54166) */ + 3347, /* D397 (54167) */ + 3347, /* D398 (54168) */ + 3347, /* D399 (54169) */ + 3347, /* D39A (54170) */ + 3347, /* D39B (54171) */ + 3347, /* D39C (54172) */ + 3347, /* D39D (54173) */ + 3347, /* D39E (54174) */ + 3347, /* D39F (54175) */ + 3347, /* D3A0 (54176) */ + 3347, /* D3A1 (54177) */ + 3347, /* D3A2 (54178) */ + 3347, /* D3A3 (54179) */ + 3347, /* D3A4 (54180) */ + 3347, /* D3A5 (54181) */ + 3347, /* D3A6 (54182) */ + 3347, /* D3A7 (54183) */ + 3347, /* D3A8 (54184) */ + 3347, /* D3A9 (54185) */ + 3347, /* D3AA (54186) */ + 3347, /* D3AB (54187) */ + 3347, /* D3AC (54188) */ + 3347, /* D3AD (54189) */ + 3347, /* D3AE (54190) */ + 3347, /* D3AF (54191) */ + 3347, /* D3B0 (54192) */ + 3347, /* D3B1 (54193) */ + 3347, /* D3B2 (54194) */ + 3347, /* D3B3 (54195) */ + 3347, /* D3B4 (54196) */ + 3347, /* D3B5 (54197) */ + 3347, /* D3B6 (54198) */ + 3347, /* D3B7 (54199) */ + 3347, /* D3B8 (54200) */ + 3347, /* D3B9 (54201) */ + 3347, /* D3BA (54202) */ + 3347, /* D3BB (54203) */ + 3347, /* D3BC (54204) */ + 3347, /* D3BD (54205) */ + 3347, /* D3BE (54206) */ + 3347, /* D3BF (54207) */ + 3347, /* D3C0 (54208) */ + 3347, /* D3C1 (54209) */ + 3347, /* D3C2 (54210) */ + 3347, /* D3C3 (54211) */ + 3347, /* D3C4 (54212) */ + 3347, /* D3C5 (54213) */ + 3347, /* D3C6 (54214) */ + 3347, /* D3C7 (54215) */ + 3347, /* D3C8 (54216) */ + 3347, /* D3C9 (54217) */ + 3347, /* D3CA (54218) */ + 3347, /* D3CB (54219) */ + 3347, /* D3CC (54220) */ + 3347, /* D3CD (54221) */ + 3347, /* D3CE (54222) */ + 3347, /* D3CF (54223) */ + 3347, /* D3D0 (54224) */ + 3347, /* D3D1 (54225) */ + 3347, /* D3D2 (54226) */ + 3347, /* D3D3 (54227) */ + 3347, /* D3D4 (54228) */ + 3347, /* D3D5 (54229) */ + 3347, /* D3D6 (54230) */ + 3347, /* D3D7 (54231) */ + 3347, /* D3D8 (54232) */ + 3347, /* D3D9 (54233) */ + 3347, /* D3DA (54234) */ + 3347, /* D3DB (54235) */ + 3347, /* D3DC (54236) */ + 3347, /* D3DD (54237) */ + 3347, /* D3DE (54238) */ + 3347, /* D3DF (54239) */ + 3347, /* D3E0 (54240) */ + 3347, /* D3E1 (54241) */ + 3347, /* D3E2 (54242) */ + 3347, /* D3E3 (54243) */ + 3347, /* D3E4 (54244) */ + 3347, /* D3E5 (54245) */ + 3347, /* D3E6 (54246) */ + 3347, /* D3E7 (54247) */ + 3347, /* D3E8 (54248) */ + 3347, /* D3E9 (54249) */ + 3347, /* D3EA (54250) */ + 3347, /* D3EB (54251) */ + 3347, /* D3EC (54252) */ + 3347, /* D3ED (54253) */ + 3347, /* D3EE (54254) */ + 3347, /* D3EF (54255) */ + 3347, /* D3F0 (54256) */ + 3347, /* D3F1 (54257) */ + 3347, /* D3F2 (54258) */ + 3347, /* D3F3 (54259) */ + 3347, /* D3F4 (54260) */ + 3347, /* D3F5 (54261) */ + 3347, /* D3F6 (54262) */ + 3347, /* D3F7 (54263) */ + 3347, /* D3F8 (54264) */ + 3347, /* D3F9 (54265) */ + 3347, /* D3FA (54266) */ + 3347, /* D3FB (54267) */ + 3347, /* D3FC (54268) */ + 3347, /* D3FD (54269) */ + 3347, /* D3FE (54270) */ + 3347, /* D3FF (54271) */ + 3347, /* D400 (54272) */ + 3347, /* D401 (54273) */ + 3347, /* D402 (54274) */ + 3347, /* D403 (54275) */ + 3347, /* D404 (54276) */ + 3347, /* D405 (54277) */ + 3347, /* D406 (54278) */ + 3347, /* D407 (54279) */ + 3347, /* D408 (54280) */ + 3347, /* D409 (54281) */ + 3347, /* D40A (54282) */ + 3347, /* D40B (54283) */ + 3347, /* D40C (54284) */ + 3347, /* D40D (54285) */ + 3347, /* D40E (54286) */ + 3347, /* D40F (54287) */ + 3347, /* D410 (54288) */ + 3347, /* D411 (54289) */ + 3347, /* D412 (54290) */ + 3347, /* D413 (54291) */ + 3347, /* D414 (54292) */ + 3347, /* D415 (54293) */ + 3347, /* D416 (54294) */ + 3347, /* D417 (54295) */ + 3347, /* D418 (54296) */ + 3347, /* D419 (54297) */ + 3347, /* D41A (54298) */ + 3347, /* D41B (54299) */ + 3347, /* D41C (54300) */ + 3347, /* D41D (54301) */ + 3347, /* D41E (54302) */ + 3347, /* D41F (54303) */ + 3347, /* D420 (54304) */ + 3347, /* D421 (54305) */ + 3347, /* D422 (54306) */ + 3347, /* D423 (54307) */ + 3347, /* D424 (54308) */ + 3347, /* D425 (54309) */ + 3347, /* D426 (54310) */ + 3347, /* D427 (54311) */ + 3347, /* D428 (54312) */ + 3347, /* D429 (54313) */ + 3347, /* D42A (54314) */ + 3347, /* D42B (54315) */ + 3347, /* D42C (54316) */ + 3347, /* D42D (54317) */ + 3347, /* D42E (54318) */ + 3347, /* D42F (54319) */ + 3347, /* D430 (54320) */ + 3347, /* D431 (54321) */ + 3347, /* D432 (54322) */ + 3347, /* D433 (54323) */ + 3347, /* D434 (54324) */ + 3347, /* D435 (54325) */ + 3347, /* D436 (54326) */ + 3347, /* D437 (54327) */ + 3347, /* D438 (54328) */ + 3347, /* D439 (54329) */ + 3347, /* D43A (54330) */ + 3347, /* D43B (54331) */ + 3347, /* D43C (54332) */ + 3347, /* D43D (54333) */ + 3347, /* D43E (54334) */ + 3347, /* D43F (54335) */ + 3347, /* D440 (54336) */ + 3347, /* D441 (54337) */ + 3347, /* D442 (54338) */ + 3347, /* D443 (54339) */ + 3347, /* D444 (54340) */ + 3347, /* D445 (54341) */ + 3347, /* D446 (54342) */ + 3347, /* D447 (54343) */ + 3347, /* D448 (54344) */ + 3347, /* D449 (54345) */ + 3347, /* D44A (54346) */ + 3347, /* D44B (54347) */ + 3347, /* D44C (54348) */ + 3347, /* D44D (54349) */ + 3347, /* D44E (54350) */ + 3347, /* D44F (54351) */ + 3347, /* D450 (54352) */ + 3347, /* D451 (54353) */ + 3347, /* D452 (54354) */ + 3347, /* D453 (54355) */ + 3347, /* D454 (54356) */ + 3347, /* D455 (54357) */ + 3347, /* D456 (54358) */ + 3347, /* D457 (54359) */ + 3347, /* D458 (54360) */ + 3347, /* D459 (54361) */ + 3347, /* D45A (54362) */ + 3347, /* D45B (54363) */ + 3347, /* D45C (54364) */ + 3347, /* D45D (54365) */ + 3347, /* D45E (54366) */ + 3347, /* D45F (54367) */ + 3347, /* D460 (54368) */ + 3347, /* D461 (54369) */ + 3347, /* D462 (54370) */ + 3347, /* D463 (54371) */ + 3347, /* D464 (54372) */ + 3347, /* D465 (54373) */ + 3347, /* D466 (54374) */ + 3347, /* D467 (54375) */ + 3347, /* D468 (54376) */ + 3347, /* D469 (54377) */ + 3347, /* D46A (54378) */ + 3347, /* D46B (54379) */ + 3347, /* D46C (54380) */ + 3347, /* D46D (54381) */ + 3347, /* D46E (54382) */ + 3347, /* D46F (54383) */ + 3347, /* D470 (54384) */ + 3347, /* D471 (54385) */ + 3347, /* D472 (54386) */ + 3347, /* D473 (54387) */ + 3347, /* D474 (54388) */ + 3347, /* D475 (54389) */ + 3347, /* D476 (54390) */ + 3347, /* D477 (54391) */ + 3347, /* D478 (54392) */ + 3347, /* D479 (54393) */ + 3347, /* D47A (54394) */ + 3347, /* D47B (54395) */ + 3347, /* D47C (54396) */ + 3347, /* D47D (54397) */ + 3347, /* D47E (54398) */ + 3347, /* D47F (54399) */ + 3347, /* D480 (54400) */ + 3347, /* D481 (54401) */ + 3347, /* D482 (54402) */ + 3347, /* D483 (54403) */ + 3347, /* D484 (54404) */ + 3347, /* D485 (54405) */ + 3347, /* D486 (54406) */ + 3347, /* D487 (54407) */ + 3347, /* D488 (54408) */ + 3347, /* D489 (54409) */ + 3347, /* D48A (54410) */ + 3347, /* D48B (54411) */ + 3347, /* D48C (54412) */ + 3347, /* D48D (54413) */ + 3347, /* D48E (54414) */ + 3347, /* D48F (54415) */ + 3347, /* D490 (54416) */ + 3347, /* D491 (54417) */ + 3347, /* D492 (54418) */ + 3347, /* D493 (54419) */ + 3347, /* D494 (54420) */ + 3347, /* D495 (54421) */ + 3347, /* D496 (54422) */ + 3347, /* D497 (54423) */ + 3347, /* D498 (54424) */ + 3347, /* D499 (54425) */ + 3347, /* D49A (54426) */ + 3347, /* D49B (54427) */ + 3347, /* D49C (54428) */ + 3347, /* D49D (54429) */ + 3347, /* D49E (54430) */ + 3347, /* D49F (54431) */ + 3347, /* D4A0 (54432) */ + 3347, /* D4A1 (54433) */ + 3347, /* D4A2 (54434) */ + 3347, /* D4A3 (54435) */ + 3347, /* D4A4 (54436) */ + 3347, /* D4A5 (54437) */ + 3347, /* D4A6 (54438) */ + 3347, /* D4A7 (54439) */ + 3347, /* D4A8 (54440) */ + 3347, /* D4A9 (54441) */ + 3347, /* D4AA (54442) */ + 3347, /* D4AB (54443) */ + 3347, /* D4AC (54444) */ + 3347, /* D4AD (54445) */ + 3347, /* D4AE (54446) */ + 3347, /* D4AF (54447) */ + 3347, /* D4B0 (54448) */ + 3347, /* D4B1 (54449) */ + 3347, /* D4B2 (54450) */ + 3347, /* D4B3 (54451) */ + 3347, /* D4B4 (54452) */ + 3347, /* D4B5 (54453) */ + 3347, /* D4B6 (54454) */ + 3347, /* D4B7 (54455) */ + 3347, /* D4B8 (54456) */ + 3347, /* D4B9 (54457) */ + 3347, /* D4BA (54458) */ + 3347, /* D4BB (54459) */ + 3347, /* D4BC (54460) */ + 3347, /* D4BD (54461) */ + 3347, /* D4BE (54462) */ + 3347, /* D4BF (54463) */ + 3347, /* D4C0 (54464) */ + 3347, /* D4C1 (54465) */ + 3347, /* D4C2 (54466) */ + 3347, /* D4C3 (54467) */ + 3347, /* D4C4 (54468) */ + 3347, /* D4C5 (54469) */ + 3347, /* D4C6 (54470) */ + 3347, /* D4C7 (54471) */ + 3347, /* D4C8 (54472) */ + 3347, /* D4C9 (54473) */ + 3347, /* D4CA (54474) */ + 3347, /* D4CB (54475) */ + 3347, /* D4CC (54476) */ + 3347, /* D4CD (54477) */ + 3347, /* D4CE (54478) */ + 3347, /* D4CF (54479) */ + 3347, /* D4D0 (54480) */ + 3347, /* D4D1 (54481) */ + 3347, /* D4D2 (54482) */ + 3347, /* D4D3 (54483) */ + 3347, /* D4D4 (54484) */ + 3347, /* D4D5 (54485) */ + 3347, /* D4D6 (54486) */ + 3347, /* D4D7 (54487) */ + 3347, /* D4D8 (54488) */ + 3347, /* D4D9 (54489) */ + 3347, /* D4DA (54490) */ + 3347, /* D4DB (54491) */ + 3347, /* D4DC (54492) */ + 3347, /* D4DD (54493) */ + 3347, /* D4DE (54494) */ + 3347, /* D4DF (54495) */ + 3347, /* D4E0 (54496) */ + 3347, /* D4E1 (54497) */ + 3347, /* D4E2 (54498) */ + 3347, /* D4E3 (54499) */ + 3347, /* D4E4 (54500) */ + 3347, /* D4E5 (54501) */ + 3347, /* D4E6 (54502) */ + 3347, /* D4E7 (54503) */ + 3347, /* D4E8 (54504) */ + 3347, /* D4E9 (54505) */ + 3347, /* D4EA (54506) */ + 3347, /* D4EB (54507) */ + 3347, /* D4EC (54508) */ + 3347, /* D4ED (54509) */ + 3347, /* D4EE (54510) */ + 3347, /* D4EF (54511) */ + 3347, /* D4F0 (54512) */ + 3347, /* D4F1 (54513) */ + 3347, /* D4F2 (54514) */ + 3347, /* D4F3 (54515) */ + 3347, /* D4F4 (54516) */ + 3347, /* D4F5 (54517) */ + 3347, /* D4F6 (54518) */ + 3347, /* D4F7 (54519) */ + 3347, /* D4F8 (54520) */ + 3347, /* D4F9 (54521) */ + 3347, /* D4FA (54522) */ + 3347, /* D4FB (54523) */ + 3347, /* D4FC (54524) */ + 3347, /* D4FD (54525) */ + 3347, /* D4FE (54526) */ + 3347, /* D4FF (54527) */ + 3347, /* D500 (54528) */ + 3347, /* D501 (54529) */ + 3347, /* D502 (54530) */ + 3347, /* D503 (54531) */ + 3347, /* D504 (54532) */ + 3347, /* D505 (54533) */ + 3347, /* D506 (54534) */ + 3347, /* D507 (54535) */ + 3347, /* D508 (54536) */ + 3347, /* D509 (54537) */ + 3347, /* D50A (54538) */ + 3347, /* D50B (54539) */ + 3347, /* D50C (54540) */ + 3347, /* D50D (54541) */ + 3347, /* D50E (54542) */ + 3347, /* D50F (54543) */ + 3347, /* D510 (54544) */ + 3347, /* D511 (54545) */ + 3347, /* D512 (54546) */ + 3347, /* D513 (54547) */ + 3347, /* D514 (54548) */ + 3347, /* D515 (54549) */ + 3347, /* D516 (54550) */ + 3347, /* D517 (54551) */ + 3347, /* D518 (54552) */ + 3347, /* D519 (54553) */ + 3347, /* D51A (54554) */ + 3347, /* D51B (54555) */ + 3347, /* D51C (54556) */ + 3347, /* D51D (54557) */ + 3347, /* D51E (54558) */ + 3347, /* D51F (54559) */ + 3347, /* D520 (54560) */ + 3347, /* D521 (54561) */ + 3347, /* D522 (54562) */ + 3347, /* D523 (54563) */ + 3347, /* D524 (54564) */ + 3347, /* D525 (54565) */ + 3347, /* D526 (54566) */ + 3347, /* D527 (54567) */ + 3347, /* D528 (54568) */ + 3347, /* D529 (54569) */ + 3347, /* D52A (54570) */ + 3347, /* D52B (54571) */ + 3347, /* D52C (54572) */ + 3347, /* D52D (54573) */ + 3347, /* D52E (54574) */ + 3347, /* D52F (54575) */ + 3347, /* D530 (54576) */ + 3347, /* D531 (54577) */ + 3347, /* D532 (54578) */ + 3347, /* D533 (54579) */ + 3347, /* D534 (54580) */ + 3347, /* D535 (54581) */ + 3347, /* D536 (54582) */ + 3347, /* D537 (54583) */ + 3347, /* D538 (54584) */ + 3347, /* D539 (54585) */ + 3347, /* D53A (54586) */ + 3347, /* D53B (54587) */ + 3347, /* D53C (54588) */ + 3347, /* D53D (54589) */ + 3347, /* D53E (54590) */ + 3347, /* D53F (54591) */ + 3347, /* D540 (54592) */ + 3347, /* D541 (54593) */ + 3347, /* D542 (54594) */ + 3347, /* D543 (54595) */ + 3347, /* D544 (54596) */ + 3347, /* D545 (54597) */ + 3347, /* D546 (54598) */ + 3347, /* D547 (54599) */ + 3347, /* D548 (54600) */ + 3347, /* D549 (54601) */ + 3347, /* D54A (54602) */ + 3347, /* D54B (54603) */ + 3347, /* D54C (54604) */ + 3347, /* D54D (54605) */ + 3347, /* D54E (54606) */ + 3347, /* D54F (54607) */ + 3347, /* D550 (54608) */ + 3347, /* D551 (54609) */ + 3347, /* D552 (54610) */ + 3347, /* D553 (54611) */ + 3347, /* D554 (54612) */ + 3347, /* D555 (54613) */ + 3347, /* D556 (54614) */ + 3347, /* D557 (54615) */ + 3347, /* D558 (54616) */ + 3347, /* D559 (54617) */ + 3347, /* D55A (54618) */ + 3347, /* D55B (54619) */ + 3347, /* D55C (54620) */ + 3347, /* D55D (54621) */ + 3347, /* D55E (54622) */ + 3347, /* D55F (54623) */ + 3347, /* D560 (54624) */ + 3347, /* D561 (54625) */ + 3347, /* D562 (54626) */ + 3347, /* D563 (54627) */ + 3347, /* D564 (54628) */ + 3347, /* D565 (54629) */ + 3347, /* D566 (54630) */ + 3347, /* D567 (54631) */ + 3347, /* D568 (54632) */ + 3347, /* D569 (54633) */ + 3347, /* D56A (54634) */ + 3347, /* D56B (54635) */ + 3347, /* D56C (54636) */ + 3347, /* D56D (54637) */ + 3347, /* D56E (54638) */ + 3347, /* D56F (54639) */ + 3347, /* D570 (54640) */ + 3347, /* D571 (54641) */ + 3347, /* D572 (54642) */ + 3347, /* D573 (54643) */ + 3347, /* D574 (54644) */ + 3347, /* D575 (54645) */ + 3347, /* D576 (54646) */ + 3347, /* D577 (54647) */ + 3347, /* D578 (54648) */ + 3347, /* D579 (54649) */ + 3347, /* D57A (54650) */ + 3347, /* D57B (54651) */ + 3347, /* D57C (54652) */ + 3347, /* D57D (54653) */ + 3347, /* D57E (54654) */ + 3347, /* D57F (54655) */ + 3347, /* D580 (54656) */ + 3347, /* D581 (54657) */ + 3347, /* D582 (54658) */ + 3347, /* D583 (54659) */ + 3347, /* D584 (54660) */ + 3347, /* D585 (54661) */ + 3347, /* D586 (54662) */ + 3347, /* D587 (54663) */ + 3347, /* D588 (54664) */ + 3347, /* D589 (54665) */ + 3347, /* D58A (54666) */ + 3347, /* D58B (54667) */ + 3347, /* D58C (54668) */ + 3347, /* D58D (54669) */ + 3347, /* D58E (54670) */ + 3347, /* D58F (54671) */ + 3347, /* D590 (54672) */ + 3347, /* D591 (54673) */ + 3347, /* D592 (54674) */ + 3347, /* D593 (54675) */ + 3347, /* D594 (54676) */ + 3347, /* D595 (54677) */ + 3347, /* D596 (54678) */ + 3347, /* D597 (54679) */ + 3347, /* D598 (54680) */ + 3347, /* D599 (54681) */ + 3347, /* D59A (54682) */ + 3347, /* D59B (54683) */ + 3347, /* D59C (54684) */ + 3347, /* D59D (54685) */ + 3347, /* D59E (54686) */ + 3347, /* D59F (54687) */ + 3347, /* D5A0 (54688) */ + 3347, /* D5A1 (54689) */ + 3347, /* D5A2 (54690) */ + 3347, /* D5A3 (54691) */ + 3347, /* D5A4 (54692) */ + 3347, /* D5A5 (54693) */ + 3347, /* D5A6 (54694) */ + 3347, /* D5A7 (54695) */ + 3347, /* D5A8 (54696) */ + 3347, /* D5A9 (54697) */ + 3347, /* D5AA (54698) */ + 3347, /* D5AB (54699) */ + 3347, /* D5AC (54700) */ + 3347, /* D5AD (54701) */ + 3347, /* D5AE (54702) */ + 3347, /* D5AF (54703) */ + 3347, /* D5B0 (54704) */ + 3347, /* D5B1 (54705) */ + 3347, /* D5B2 (54706) */ + 3347, /* D5B3 (54707) */ + 3347, /* D5B4 (54708) */ + 3347, /* D5B5 (54709) */ + 3347, /* D5B6 (54710) */ + 3347, /* D5B7 (54711) */ + 3347, /* D5B8 (54712) */ + 3347, /* D5B9 (54713) */ + 3347, /* D5BA (54714) */ + 3347, /* D5BB (54715) */ + 3347, /* D5BC (54716) */ + 3347, /* D5BD (54717) */ + 3347, /* D5BE (54718) */ + 3347, /* D5BF (54719) */ + 3347, /* D5C0 (54720) */ + 3347, /* D5C1 (54721) */ + 3347, /* D5C2 (54722) */ + 3347, /* D5C3 (54723) */ + 3347, /* D5C4 (54724) */ + 3347, /* D5C5 (54725) */ + 3347, /* D5C6 (54726) */ + 3347, /* D5C7 (54727) */ + 3347, /* D5C8 (54728) */ + 3347, /* D5C9 (54729) */ + 3347, /* D5CA (54730) */ + 3347, /* D5CB (54731) */ + 3347, /* D5CC (54732) */ + 3347, /* D5CD (54733) */ + 3347, /* D5CE (54734) */ + 3347, /* D5CF (54735) */ + 3347, /* D5D0 (54736) */ + 3347, /* D5D1 (54737) */ + 3347, /* D5D2 (54738) */ + 3347, /* D5D3 (54739) */ + 3347, /* D5D4 (54740) */ + 3347, /* D5D5 (54741) */ + 3347, /* D5D6 (54742) */ + 3347, /* D5D7 (54743) */ + 3347, /* D5D8 (54744) */ + 3347, /* D5D9 (54745) */ + 3347, /* D5DA (54746) */ + 3347, /* D5DB (54747) */ + 3347, /* D5DC (54748) */ + 3347, /* D5DD (54749) */ + 3347, /* D5DE (54750) */ + 3347, /* D5DF (54751) */ + 3347, /* D5E0 (54752) */ + 3347, /* D5E1 (54753) */ + 3347, /* D5E2 (54754) */ + 3347, /* D5E3 (54755) */ + 3347, /* D5E4 (54756) */ + 3347, /* D5E5 (54757) */ + 3347, /* D5E6 (54758) */ + 3347, /* D5E7 (54759) */ + 3347, /* D5E8 (54760) */ + 3347, /* D5E9 (54761) */ + 3347, /* D5EA (54762) */ + 3347, /* D5EB (54763) */ + 3347, /* D5EC (54764) */ + 3347, /* D5ED (54765) */ + 3347, /* D5EE (54766) */ + 3347, /* D5EF (54767) */ + 3347, /* D5F0 (54768) */ + 3347, /* D5F1 (54769) */ + 3347, /* D5F2 (54770) */ + 3347, /* D5F3 (54771) */ + 3347, /* D5F4 (54772) */ + 3347, /* D5F5 (54773) */ + 3347, /* D5F6 (54774) */ + 3347, /* D5F7 (54775) */ + 3347, /* D5F8 (54776) */ + 3347, /* D5F9 (54777) */ + 3347, /* D5FA (54778) */ + 3347, /* D5FB (54779) */ + 3347, /* D5FC (54780) */ + 3347, /* D5FD (54781) */ + 3347, /* D5FE (54782) */ + 3347, /* D5FF (54783) */ + 3347, /* D600 (54784) */ + 3347, /* D601 (54785) */ + 3347, /* D602 (54786) */ + 3347, /* D603 (54787) */ + 3347, /* D604 (54788) */ + 3347, /* D605 (54789) */ + 3347, /* D606 (54790) */ + 3347, /* D607 (54791) */ + 3347, /* D608 (54792) */ + 3347, /* D609 (54793) */ + 3347, /* D60A (54794) */ + 3347, /* D60B (54795) */ + 3347, /* D60C (54796) */ + 3347, /* D60D (54797) */ + 3347, /* D60E (54798) */ + 3347, /* D60F (54799) */ + 3347, /* D610 (54800) */ + 3347, /* D611 (54801) */ + 3347, /* D612 (54802) */ + 3347, /* D613 (54803) */ + 3347, /* D614 (54804) */ + 3347, /* D615 (54805) */ + 3347, /* D616 (54806) */ + 3347, /* D617 (54807) */ + 3347, /* D618 (54808) */ + 3347, /* D619 (54809) */ + 3347, /* D61A (54810) */ + 3347, /* D61B (54811) */ + 3347, /* D61C (54812) */ + 3347, /* D61D (54813) */ + 3347, /* D61E (54814) */ + 3347, /* D61F (54815) */ + 3347, /* D620 (54816) */ + 3347, /* D621 (54817) */ + 3347, /* D622 (54818) */ + 3347, /* D623 (54819) */ + 3347, /* D624 (54820) */ + 3347, /* D625 (54821) */ + 3347, /* D626 (54822) */ + 3347, /* D627 (54823) */ + 3347, /* D628 (54824) */ + 3347, /* D629 (54825) */ + 3347, /* D62A (54826) */ + 3347, /* D62B (54827) */ + 3347, /* D62C (54828) */ + 3347, /* D62D (54829) */ + 3347, /* D62E (54830) */ + 3347, /* D62F (54831) */ + 3347, /* D630 (54832) */ + 3347, /* D631 (54833) */ + 3347, /* D632 (54834) */ + 3347, /* D633 (54835) */ + 3347, /* D634 (54836) */ + 3347, /* D635 (54837) */ + 3347, /* D636 (54838) */ + 3347, /* D637 (54839) */ + 3347, /* D638 (54840) */ + 3347, /* D639 (54841) */ + 3347, /* D63A (54842) */ + 3347, /* D63B (54843) */ + 3347, /* D63C (54844) */ + 3347, /* D63D (54845) */ + 3347, /* D63E (54846) */ + 3347, /* D63F (54847) */ + 3347, /* D640 (54848) */ + 3347, /* D641 (54849) */ + 3347, /* D642 (54850) */ + 3347, /* D643 (54851) */ + 3347, /* D644 (54852) */ + 3347, /* D645 (54853) */ + 3347, /* D646 (54854) */ + 3347, /* D647 (54855) */ + 3347, /* D648 (54856) */ + 3347, /* D649 (54857) */ + 3347, /* D64A (54858) */ + 3347, /* D64B (54859) */ + 3347, /* D64C (54860) */ + 3347, /* D64D (54861) */ + 3347, /* D64E (54862) */ + 3347, /* D64F (54863) */ + 3347, /* D650 (54864) */ + 3347, /* D651 (54865) */ + 3347, /* D652 (54866) */ + 3347, /* D653 (54867) */ + 3347, /* D654 (54868) */ + 3347, /* D655 (54869) */ + 3347, /* D656 (54870) */ + 3347, /* D657 (54871) */ + 3347, /* D658 (54872) */ + 3347, /* D659 (54873) */ + 3347, /* D65A (54874) */ + 3347, /* D65B (54875) */ + 3347, /* D65C (54876) */ + 3347, /* D65D (54877) */ + 3347, /* D65E (54878) */ + 3347, /* D65F (54879) */ + 3347, /* D660 (54880) */ + 3347, /* D661 (54881) */ + 3347, /* D662 (54882) */ + 3347, /* D663 (54883) */ + 3347, /* D664 (54884) */ + 3347, /* D665 (54885) */ + 3347, /* D666 (54886) */ + 3347, /* D667 (54887) */ + 3347, /* D668 (54888) */ + 3347, /* D669 (54889) */ + 3347, /* D66A (54890) */ + 3347, /* D66B (54891) */ + 3347, /* D66C (54892) */ + 3347, /* D66D (54893) */ + 3347, /* D66E (54894) */ + 3347, /* D66F (54895) */ + 3347, /* D670 (54896) */ + 3347, /* D671 (54897) */ + 3347, /* D672 (54898) */ + 3347, /* D673 (54899) */ + 3347, /* D674 (54900) */ + 3347, /* D675 (54901) */ + 3347, /* D676 (54902) */ + 3347, /* D677 (54903) */ + 3347, /* D678 (54904) */ + 3347, /* D679 (54905) */ + 3347, /* D67A (54906) */ + 3347, /* D67B (54907) */ + 3347, /* D67C (54908) */ + 3347, /* D67D (54909) */ + 3347, /* D67E (54910) */ + 3347, /* D67F (54911) */ + 3347, /* D680 (54912) */ + 3347, /* D681 (54913) */ + 3347, /* D682 (54914) */ + 3347, /* D683 (54915) */ + 3347, /* D684 (54916) */ + 3347, /* D685 (54917) */ + 3347, /* D686 (54918) */ + 3347, /* D687 (54919) */ + 3347, /* D688 (54920) */ + 3347, /* D689 (54921) */ + 3347, /* D68A (54922) */ + 3347, /* D68B (54923) */ + 3347, /* D68C (54924) */ + 3347, /* D68D (54925) */ + 3347, /* D68E (54926) */ + 3347, /* D68F (54927) */ + 3347, /* D690 (54928) */ + 3347, /* D691 (54929) */ + 3347, /* D692 (54930) */ + 3347, /* D693 (54931) */ + 3347, /* D694 (54932) */ + 3347, /* D695 (54933) */ + 3347, /* D696 (54934) */ + 3347, /* D697 (54935) */ + 3347, /* D698 (54936) */ + 3347, /* D699 (54937) */ + 3347, /* D69A (54938) */ + 3347, /* D69B (54939) */ + 3347, /* D69C (54940) */ + 3347, /* D69D (54941) */ + 3347, /* D69E (54942) */ + 3347, /* D69F (54943) */ + 3347, /* D6A0 (54944) */ + 3347, /* D6A1 (54945) */ + 3347, /* D6A2 (54946) */ + 3347, /* D6A3 (54947) */ + 3347, /* D6A4 (54948) */ + 3347, /* D6A5 (54949) */ + 3347, /* D6A6 (54950) */ + 3347, /* D6A7 (54951) */ + 3347, /* D6A8 (54952) */ + 3347, /* D6A9 (54953) */ + 3347, /* D6AA (54954) */ + 3347, /* D6AB (54955) */ + 3347, /* D6AC (54956) */ + 3347, /* D6AD (54957) */ + 3347, /* D6AE (54958) */ + 3347, /* D6AF (54959) */ + 3347, /* D6B0 (54960) */ + 3347, /* D6B1 (54961) */ + 3347, /* D6B2 (54962) */ + 3347, /* D6B3 (54963) */ + 3347, /* D6B4 (54964) */ + 3347, /* D6B5 (54965) */ + 3347, /* D6B6 (54966) */ + 3347, /* D6B7 (54967) */ + 3347, /* D6B8 (54968) */ + 3347, /* D6B9 (54969) */ + 3347, /* D6BA (54970) */ + 3347, /* D6BB (54971) */ + 3347, /* D6BC (54972) */ + 3347, /* D6BD (54973) */ + 3347, /* D6BE (54974) */ + 3347, /* D6BF (54975) */ + 3347, /* D6C0 (54976) */ + 3347, /* D6C1 (54977) */ + 3347, /* D6C2 (54978) */ + 3347, /* D6C3 (54979) */ + 3347, /* D6C4 (54980) */ + 3347, /* D6C5 (54981) */ + 3347, /* D6C6 (54982) */ + 3347, /* D6C7 (54983) */ + 3347, /* D6C8 (54984) */ + 3347, /* D6C9 (54985) */ + 3347, /* D6CA (54986) */ + 3347, /* D6CB (54987) */ + 3347, /* D6CC (54988) */ + 3347, /* D6CD (54989) */ + 3347, /* D6CE (54990) */ + 3347, /* D6CF (54991) */ + 3347, /* D6D0 (54992) */ + 3347, /* D6D1 (54993) */ + 3347, /* D6D2 (54994) */ + 3347, /* D6D3 (54995) */ + 3347, /* D6D4 (54996) */ + 3347, /* D6D5 (54997) */ + 3347, /* D6D6 (54998) */ + 3347, /* D6D7 (54999) */ + 3347, /* D6D8 (55000) */ + 3347, /* D6D9 (55001) */ + 3347, /* D6DA (55002) */ + 3347, /* D6DB (55003) */ + 3347, /* D6DC (55004) */ + 3347, /* D6DD (55005) */ + 3347, /* D6DE (55006) */ + 3347, /* D6DF (55007) */ + 3347, /* D6E0 (55008) */ + 3347, /* D6E1 (55009) */ + 3347, /* D6E2 (55010) */ + 3347, /* D6E3 (55011) */ + 3347, /* D6E4 (55012) */ + 3347, /* D6E5 (55013) */ + 3347, /* D6E6 (55014) */ + 3347, /* D6E7 (55015) */ + 3347, /* D6E8 (55016) */ + 3347, /* D6E9 (55017) */ + 3347, /* D6EA (55018) */ + 3347, /* D6EB (55019) */ + 3347, /* D6EC (55020) */ + 3347, /* D6ED (55021) */ + 3347, /* D6EE (55022) */ + 3347, /* D6EF (55023) */ + 3347, /* D6F0 (55024) */ + 3347, /* D6F1 (55025) */ + 3347, /* D6F2 (55026) */ + 3347, /* D6F3 (55027) */ + 3347, /* D6F4 (55028) */ + 3347, /* D6F5 (55029) */ + 3347, /* D6F6 (55030) */ + 3347, /* D6F7 (55031) */ + 3347, /* D6F8 (55032) */ + 3347, /* D6F9 (55033) */ + 3347, /* D6FA (55034) */ + 3347, /* D6FB (55035) */ + 3347, /* D6FC (55036) */ + 3347, /* D6FD (55037) */ + 3347, /* D6FE (55038) */ + 3347, /* D6FF (55039) */ + 3347, /* D700 (55040) */ + 3347, /* D701 (55041) */ + 3347, /* D702 (55042) */ + 3347, /* D703 (55043) */ + 3347, /* D704 (55044) */ + 3347, /* D705 (55045) */ + 3347, /* D706 (55046) */ + 3347, /* D707 (55047) */ + 3347, /* D708 (55048) */ + 3347, /* D709 (55049) */ + 3347, /* D70A (55050) */ + 3347, /* D70B (55051) */ + 3347, /* D70C (55052) */ + 3347, /* D70D (55053) */ + 3347, /* D70E (55054) */ + 3347, /* D70F (55055) */ + 3347, /* D710 (55056) */ + 3347, /* D711 (55057) */ + 3347, /* D712 (55058) */ + 3347, /* D713 (55059) */ + 3347, /* D714 (55060) */ + 3347, /* D715 (55061) */ + 3347, /* D716 (55062) */ + 3347, /* D717 (55063) */ + 3347, /* D718 (55064) */ + 3347, /* D719 (55065) */ + 3347, /* D71A (55066) */ + 3347, /* D71B (55067) */ + 3347, /* D71C (55068) */ + 3347, /* D71D (55069) */ + 3347, /* D71E (55070) */ + 3347, /* D71F (55071) */ + 3347, /* D720 (55072) */ + 3347, /* D721 (55073) */ + 3347, /* D722 (55074) */ + 3347, /* D723 (55075) */ + 3347, /* D724 (55076) */ + 3347, /* D725 (55077) */ + 3347, /* D726 (55078) */ + 3347, /* D727 (55079) */ + 3347, /* D728 (55080) */ + 3347, /* D729 (55081) */ + 3347, /* D72A (55082) */ + 3347, /* D72B (55083) */ + 3347, /* D72C (55084) */ + 3347, /* D72D (55085) */ + 3347, /* D72E (55086) */ + 3347, /* D72F (55087) */ + 3347, /* D730 (55088) */ + 3347, /* D731 (55089) */ + 3347, /* D732 (55090) */ + 3347, /* D733 (55091) */ + 3347, /* D734 (55092) */ + 3347, /* D735 (55093) */ + 3347, /* D736 (55094) */ + 3347, /* D737 (55095) */ + 3347, /* D738 (55096) */ + 3347, /* D739 (55097) */ + 3347, /* D73A (55098) */ + 3347, /* D73B (55099) */ + 3347, /* D73C (55100) */ + 3347, /* D73D (55101) */ + 3347, /* D73E (55102) */ + 3347, /* D73F (55103) */ + 3347, /* D740 (55104) */ + 3347, /* D741 (55105) */ + 3347, /* D742 (55106) */ + 3347, /* D743 (55107) */ + 3347, /* D744 (55108) */ + 3347, /* D745 (55109) */ + 3347, /* D746 (55110) */ + 3347, /* D747 (55111) */ + 3347, /* D748 (55112) */ + 3347, /* D749 (55113) */ + 3347, /* D74A (55114) */ + 3347, /* D74B (55115) */ + 3347, /* D74C (55116) */ + 3347, /* D74D (55117) */ + 3347, /* D74E (55118) */ + 3347, /* D74F (55119) */ + 3347, /* D750 (55120) */ + 3347, /* D751 (55121) */ + 3347, /* D752 (55122) */ + 3347, /* D753 (55123) */ + 3347, /* D754 (55124) */ + 3347, /* D755 (55125) */ + 3347, /* D756 (55126) */ + 3347, /* D757 (55127) */ + 3347, /* D758 (55128) */ + 3347, /* D759 (55129) */ + 3347, /* D75A (55130) */ + 3347, /* D75B (55131) */ + 3347, /* D75C (55132) */ + 3347, /* D75D (55133) */ + 3347, /* D75E (55134) */ + 3347, /* D75F (55135) */ + 3347, /* D760 (55136) */ + 3347, /* D761 (55137) */ + 3347, /* D762 (55138) */ + 3347, /* D763 (55139) */ + 3347, /* D764 (55140) */ + 3347, /* D765 (55141) */ + 3347, /* D766 (55142) */ + 3347, /* D767 (55143) */ + 3347, /* D768 (55144) */ + 3347, /* D769 (55145) */ + 3347, /* D76A (55146) */ + 3347, /* D76B (55147) */ + 3347, /* D76C (55148) */ + 3347, /* D76D (55149) */ + 3347, /* D76E (55150) */ + 3347, /* D76F (55151) */ + 3347, /* D770 (55152) */ + 3347, /* D771 (55153) */ + 3347, /* D772 (55154) */ + 3347, /* D773 (55155) */ + 3347, /* D774 (55156) */ + 3347, /* D775 (55157) */ + 3347, /* D776 (55158) */ + 3347, /* D777 (55159) */ + 3347, /* D778 (55160) */ + 3347, /* D779 (55161) */ + 3347, /* D77A (55162) */ + 3347, /* D77B (55163) */ + 3347, /* D77C (55164) */ + 3347, /* D77D (55165) */ + 3347, /* D77E (55166) */ + 3347, /* D77F (55167) */ + 3347, /* D780 (55168) */ + 3347, /* D781 (55169) */ + 3347, /* D782 (55170) */ + 3347, /* D783 (55171) */ + 3347, /* D784 (55172) */ + 3347, /* D785 (55173) */ + 3347, /* D786 (55174) */ + 3347, /* D787 (55175) */ + 3347, /* D788 (55176) */ + 3347, /* D789 (55177) */ + 3347, /* D78A (55178) */ + 3347, /* D78B (55179) */ + 3347, /* D78C (55180) */ + 3347, /* D78D (55181) */ + 3347, /* D78E (55182) */ + 3347, /* D78F (55183) */ + 3347, /* D790 (55184) */ + 3347, /* D791 (55185) */ + 3347, /* D792 (55186) */ + 3347, /* D793 (55187) */ + 3347, /* D794 (55188) */ + 3347, /* D795 (55189) */ + 3347, /* D796 (55190) */ + 3347, /* D797 (55191) */ + 3347, /* D798 (55192) */ + 3347, /* D799 (55193) */ + 3347, /* D79A (55194) */ + 3347, /* D79B (55195) */ + 3347, /* D79C (55196) */ + 3347, /* D79D (55197) */ + 3347, /* D79E (55198) */ + 3347, /* D79F (55199) */ + 3347, /* D7A0 (55200) */ + 3347, /* D7A1 (55201) */ + 3347, /* D7A2 (55202) */ + 3347, /* D7A3 (55203) */ 56, /* D7A4 (55204) */ 56, /* D7A5 (55205) */ 56, /* D7A6 (55206) */ @@ -57372,480 +57372,480 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = static const uint16_t lxb_unicode_table_map_63743_83527[19784] = { 56, /* F8FF (63743) */ - 3344, /* F900 (63744) */ - 3345, /* F901 (63745) */ - 3346, /* F902 (63746) */ - 3347, /* F903 (63747) */ - 3348, /* F904 (63748) */ - 3349, /* F905 (63749) */ - 3350, /* F906 (63750) */ - 3351, /* F907 (63751) */ - 3351, /* F908 (63752) */ - 3352, /* F909 (63753) */ - 3353, /* F90A (63754) */ - 3354, /* F90B (63755) */ - 3355, /* F90C (63756) */ - 3356, /* F90D (63757) */ - 3357, /* F90E (63758) */ - 3358, /* F90F (63759) */ - 3359, /* F910 (63760) */ - 3360, /* F911 (63761) */ - 3361, /* F912 (63762) */ - 3362, /* F913 (63763) */ - 3363, /* F914 (63764) */ - 3364, /* F915 (63765) */ - 3365, /* F916 (63766) */ - 3366, /* F917 (63767) */ - 3367, /* F918 (63768) */ - 3368, /* F919 (63769) */ - 3369, /* F91A (63770) */ - 3370, /* F91B (63771) */ - 3371, /* F91C (63772) */ - 3372, /* F91D (63773) */ - 3373, /* F91E (63774) */ - 3374, /* F91F (63775) */ - 3375, /* F920 (63776) */ - 3376, /* F921 (63777) */ - 3377, /* F922 (63778) */ - 3378, /* F923 (63779) */ - 3379, /* F924 (63780) */ - 3380, /* F925 (63781) */ - 3381, /* F926 (63782) */ - 3382, /* F927 (63783) */ - 3383, /* F928 (63784) */ - 3384, /* F929 (63785) */ - 3385, /* F92A (63786) */ - 3386, /* F92B (63787) */ - 3387, /* F92C (63788) */ - 3388, /* F92D (63789) */ - 3389, /* F92E (63790) */ - 3390, /* F92F (63791) */ - 3391, /* F930 (63792) */ - 3392, /* F931 (63793) */ - 3393, /* F932 (63794) */ - 3394, /* F933 (63795) */ - 3395, /* F934 (63796) */ - 3396, /* F935 (63797) */ - 3397, /* F936 (63798) */ - 3398, /* F937 (63799) */ - 3399, /* F938 (63800) */ - 3400, /* F939 (63801) */ - 3401, /* F93A (63802) */ - 3402, /* F93B (63803) */ - 3403, /* F93C (63804) */ - 3404, /* F93D (63805) */ - 3405, /* F93E (63806) */ - 3406, /* F93F (63807) */ - 3407, /* F940 (63808) */ - 3408, /* F941 (63809) */ - 3409, /* F942 (63810) */ - 3410, /* F943 (63811) */ - 3411, /* F944 (63812) */ - 3412, /* F945 (63813) */ - 3413, /* F946 (63814) */ - 3414, /* F947 (63815) */ - 3415, /* F948 (63816) */ - 3416, /* F949 (63817) */ - 3417, /* F94A (63818) */ - 3418, /* F94B (63819) */ - 3419, /* F94C (63820) */ - 3420, /* F94D (63821) */ - 3421, /* F94E (63822) */ - 3422, /* F94F (63823) */ - 3423, /* F950 (63824) */ - 3424, /* F951 (63825) */ - 3425, /* F952 (63826) */ - 3426, /* F953 (63827) */ - 3427, /* F954 (63828) */ - 3428, /* F955 (63829) */ - 3429, /* F956 (63830) */ - 3430, /* F957 (63831) */ - 3431, /* F958 (63832) */ - 3432, /* F959 (63833) */ - 3433, /* F95A (63834) */ - 3434, /* F95B (63835) */ - 3363, /* F95C (63836) */ - 3435, /* F95D (63837) */ - 3436, /* F95E (63838) */ - 3437, /* F95F (63839) */ - 3438, /* F960 (63840) */ - 3439, /* F961 (63841) */ - 3440, /* F962 (63842) */ - 3441, /* F963 (63843) */ - 3442, /* F964 (63844) */ - 3443, /* F965 (63845) */ - 3444, /* F966 (63846) */ - 3445, /* F967 (63847) */ - 3446, /* F968 (63848) */ - 3447, /* F969 (63849) */ - 3448, /* F96A (63850) */ - 3449, /* F96B (63851) */ - 3450, /* F96C (63852) */ - 3451, /* F96D (63853) */ - 3452, /* F96E (63854) */ - 3453, /* F96F (63855) */ - 3454, /* F970 (63856) */ - 3455, /* F971 (63857) */ - 3456, /* F972 (63858) */ - 3457, /* F973 (63859) */ - 3458, /* F974 (63860) */ - 3459, /* F975 (63861) */ - 3460, /* F976 (63862) */ - 3461, /* F977 (63863) */ - 3462, /* F978 (63864) */ - 3463, /* F979 (63865) */ - 3464, /* F97A (63866) */ - 3465, /* F97B (63867) */ - 3466, /* F97C (63868) */ - 3467, /* F97D (63869) */ - 3468, /* F97E (63870) */ - 3469, /* F97F (63871) */ - 3470, /* F980 (63872) */ - 3471, /* F981 (63873) */ - 3472, /* F982 (63874) */ - 3473, /* F983 (63875) */ - 3474, /* F984 (63876) */ - 3475, /* F985 (63877) */ - 3476, /* F986 (63878) */ - 3477, /* F987 (63879) */ - 3478, /* F988 (63880) */ - 3479, /* F989 (63881) */ - 3480, /* F98A (63882) */ - 3481, /* F98B (63883) */ - 3482, /* F98C (63884) */ - 3483, /* F98D (63885) */ - 3484, /* F98E (63886) */ - 3485, /* F98F (63887) */ - 3486, /* F990 (63888) */ - 3487, /* F991 (63889) */ - 3488, /* F992 (63890) */ - 3489, /* F993 (63891) */ - 3490, /* F994 (63892) */ - 3491, /* F995 (63893) */ - 3492, /* F996 (63894) */ - 3493, /* F997 (63895) */ - 3494, /* F998 (63896) */ - 3495, /* F999 (63897) */ - 3496, /* F99A (63898) */ - 3497, /* F99B (63899) */ - 3498, /* F99C (63900) */ - 3499, /* F99D (63901) */ - 3500, /* F99E (63902) */ - 3501, /* F99F (63903) */ - 3502, /* F9A0 (63904) */ - 3453, /* F9A1 (63905) */ - 3503, /* F9A2 (63906) */ - 3504, /* F9A3 (63907) */ - 3505, /* F9A4 (63908) */ - 3506, /* F9A5 (63909) */ - 3507, /* F9A6 (63910) */ - 3508, /* F9A7 (63911) */ - 3509, /* F9A8 (63912) */ - 3510, /* F9A9 (63913) */ - 3437, /* F9AA (63914) */ - 3511, /* F9AB (63915) */ - 3512, /* F9AC (63916) */ - 3513, /* F9AD (63917) */ - 3514, /* F9AE (63918) */ - 3515, /* F9AF (63919) */ - 3516, /* F9B0 (63920) */ - 3517, /* F9B1 (63921) */ - 3518, /* F9B2 (63922) */ - 3519, /* F9B3 (63923) */ - 3520, /* F9B4 (63924) */ - 3521, /* F9B5 (63925) */ - 3522, /* F9B6 (63926) */ - 3523, /* F9B7 (63927) */ - 3524, /* F9B8 (63928) */ - 3525, /* F9B9 (63929) */ - 3526, /* F9BA (63930) */ - 3527, /* F9BB (63931) */ - 3528, /* F9BC (63932) */ - 3529, /* F9BD (63933) */ - 3530, /* F9BE (63934) */ - 3363, /* F9BF (63935) */ - 3531, /* F9C0 (63936) */ - 3532, /* F9C1 (63937) */ - 3533, /* F9C2 (63938) */ - 3534, /* F9C3 (63939) */ - 3535, /* F9C4 (63940) */ - 3536, /* F9C5 (63941) */ - 3537, /* F9C6 (63942) */ - 3538, /* F9C7 (63943) */ - 3539, /* F9C8 (63944) */ - 3540, /* F9C9 (63945) */ - 3541, /* F9CA (63946) */ - 3542, /* F9CB (63947) */ - 3543, /* F9CC (63948) */ - 3544, /* F9CD (63949) */ - 3545, /* F9CE (63950) */ - 3546, /* F9CF (63951) */ - 3547, /* F9D0 (63952) */ - 3548, /* F9D1 (63953) */ - 3549, /* F9D2 (63954) */ - 3550, /* F9D3 (63955) */ - 3551, /* F9D4 (63956) */ - 3552, /* F9D5 (63957) */ - 3553, /* F9D6 (63958) */ - 3554, /* F9D7 (63959) */ - 3555, /* F9D8 (63960) */ - 3556, /* F9D9 (63961) */ - 3557, /* F9DA (63962) */ - 3439, /* F9DB (63963) */ - 3558, /* F9DC (63964) */ - 3559, /* F9DD (63965) */ - 3560, /* F9DE (63966) */ - 3561, /* F9DF (63967) */ - 3562, /* F9E0 (63968) */ - 3563, /* F9E1 (63969) */ - 3564, /* F9E2 (63970) */ - 3565, /* F9E3 (63971) */ - 3566, /* F9E4 (63972) */ - 3567, /* F9E5 (63973) */ - 3568, /* F9E6 (63974) */ - 3569, /* F9E7 (63975) */ - 3570, /* F9E8 (63976) */ - 3571, /* F9E9 (63977) */ - 3572, /* F9EA (63978) */ - 3573, /* F9EB (63979) */ - 3574, /* F9EC (63980) */ - 3575, /* F9ED (63981) */ - 3576, /* F9EE (63982) */ - 3577, /* F9EF (63983) */ - 3578, /* F9F0 (63984) */ - 3579, /* F9F1 (63985) */ - 3580, /* F9F2 (63986) */ - 3581, /* F9F3 (63987) */ - 3582, /* F9F4 (63988) */ - 3583, /* F9F5 (63989) */ - 3584, /* F9F6 (63990) */ - 3585, /* F9F7 (63991) */ - 3586, /* F9F8 (63992) */ - 3587, /* F9F9 (63993) */ - 3588, /* F9FA (63994) */ - 3589, /* F9FB (63995) */ - 3590, /* F9FC (63996) */ - 3591, /* F9FD (63997) */ - 3592, /* F9FE (63998) */ - 3593, /* F9FF (63999) */ - 3594, /* FA00 (64000) */ - 3595, /* FA01 (64001) */ - 3596, /* FA02 (64002) */ - 3597, /* FA03 (64003) */ - 3598, /* FA04 (64004) */ - 3599, /* FA05 (64005) */ - 3600, /* FA06 (64006) */ - 3601, /* FA07 (64007) */ - 3602, /* FA08 (64008) */ - 3603, /* FA09 (64009) */ - 3604, /* FA0A (64010) */ - 3605, /* FA0B (64011) */ - 3606, /* FA0C (64012) */ - 3607, /* FA0D (64013) */ + 3348, /* F900 (63744) */ + 3349, /* F901 (63745) */ + 3350, /* F902 (63746) */ + 3351, /* F903 (63747) */ + 3352, /* F904 (63748) */ + 3353, /* F905 (63749) */ + 3354, /* F906 (63750) */ + 3355, /* F907 (63751) */ + 3355, /* F908 (63752) */ + 3356, /* F909 (63753) */ + 3357, /* F90A (63754) */ + 3358, /* F90B (63755) */ + 3359, /* F90C (63756) */ + 3360, /* F90D (63757) */ + 3361, /* F90E (63758) */ + 3362, /* F90F (63759) */ + 3363, /* F910 (63760) */ + 3364, /* F911 (63761) */ + 3365, /* F912 (63762) */ + 3366, /* F913 (63763) */ + 3367, /* F914 (63764) */ + 3368, /* F915 (63765) */ + 3369, /* F916 (63766) */ + 3370, /* F917 (63767) */ + 3371, /* F918 (63768) */ + 3372, /* F919 (63769) */ + 3373, /* F91A (63770) */ + 3374, /* F91B (63771) */ + 3375, /* F91C (63772) */ + 3376, /* F91D (63773) */ + 3377, /* F91E (63774) */ + 3378, /* F91F (63775) */ + 3379, /* F920 (63776) */ + 3380, /* F921 (63777) */ + 3381, /* F922 (63778) */ + 3382, /* F923 (63779) */ + 3383, /* F924 (63780) */ + 3384, /* F925 (63781) */ + 3385, /* F926 (63782) */ + 3386, /* F927 (63783) */ + 3387, /* F928 (63784) */ + 3388, /* F929 (63785) */ + 3389, /* F92A (63786) */ + 3390, /* F92B (63787) */ + 3391, /* F92C (63788) */ + 3392, /* F92D (63789) */ + 3393, /* F92E (63790) */ + 3394, /* F92F (63791) */ + 3395, /* F930 (63792) */ + 3396, /* F931 (63793) */ + 3397, /* F932 (63794) */ + 3398, /* F933 (63795) */ + 3399, /* F934 (63796) */ + 3400, /* F935 (63797) */ + 3401, /* F936 (63798) */ + 3402, /* F937 (63799) */ + 3403, /* F938 (63800) */ + 3404, /* F939 (63801) */ + 3405, /* F93A (63802) */ + 3406, /* F93B (63803) */ + 3407, /* F93C (63804) */ + 3408, /* F93D (63805) */ + 3409, /* F93E (63806) */ + 3410, /* F93F (63807) */ + 3411, /* F940 (63808) */ + 3412, /* F941 (63809) */ + 3413, /* F942 (63810) */ + 3414, /* F943 (63811) */ + 3415, /* F944 (63812) */ + 3416, /* F945 (63813) */ + 3417, /* F946 (63814) */ + 3418, /* F947 (63815) */ + 3419, /* F948 (63816) */ + 3420, /* F949 (63817) */ + 3421, /* F94A (63818) */ + 3422, /* F94B (63819) */ + 3423, /* F94C (63820) */ + 3424, /* F94D (63821) */ + 3425, /* F94E (63822) */ + 3426, /* F94F (63823) */ + 3427, /* F950 (63824) */ + 3428, /* F951 (63825) */ + 3429, /* F952 (63826) */ + 3430, /* F953 (63827) */ + 3431, /* F954 (63828) */ + 3432, /* F955 (63829) */ + 3433, /* F956 (63830) */ + 3434, /* F957 (63831) */ + 3435, /* F958 (63832) */ + 3436, /* F959 (63833) */ + 3437, /* F95A (63834) */ + 3438, /* F95B (63835) */ + 3367, /* F95C (63836) */ + 3439, /* F95D (63837) */ + 3440, /* F95E (63838) */ + 3441, /* F95F (63839) */ + 3442, /* F960 (63840) */ + 3443, /* F961 (63841) */ + 3444, /* F962 (63842) */ + 3445, /* F963 (63843) */ + 3446, /* F964 (63844) */ + 3447, /* F965 (63845) */ + 3448, /* F966 (63846) */ + 3449, /* F967 (63847) */ + 3450, /* F968 (63848) */ + 3451, /* F969 (63849) */ + 3452, /* F96A (63850) */ + 3453, /* F96B (63851) */ + 3454, /* F96C (63852) */ + 3455, /* F96D (63853) */ + 3456, /* F96E (63854) */ + 3457, /* F96F (63855) */ + 3458, /* F970 (63856) */ + 3459, /* F971 (63857) */ + 3460, /* F972 (63858) */ + 3461, /* F973 (63859) */ + 3462, /* F974 (63860) */ + 3463, /* F975 (63861) */ + 3464, /* F976 (63862) */ + 3465, /* F977 (63863) */ + 3466, /* F978 (63864) */ + 3467, /* F979 (63865) */ + 3468, /* F97A (63866) */ + 3469, /* F97B (63867) */ + 3470, /* F97C (63868) */ + 3471, /* F97D (63869) */ + 3472, /* F97E (63870) */ + 3473, /* F97F (63871) */ + 3474, /* F980 (63872) */ + 3475, /* F981 (63873) */ + 3476, /* F982 (63874) */ + 3477, /* F983 (63875) */ + 3478, /* F984 (63876) */ + 3479, /* F985 (63877) */ + 3480, /* F986 (63878) */ + 3481, /* F987 (63879) */ + 3482, /* F988 (63880) */ + 3483, /* F989 (63881) */ + 3484, /* F98A (63882) */ + 3485, /* F98B (63883) */ + 3486, /* F98C (63884) */ + 3487, /* F98D (63885) */ + 3488, /* F98E (63886) */ + 3489, /* F98F (63887) */ + 3490, /* F990 (63888) */ + 3491, /* F991 (63889) */ + 3492, /* F992 (63890) */ + 3493, /* F993 (63891) */ + 3494, /* F994 (63892) */ + 3495, /* F995 (63893) */ + 3496, /* F996 (63894) */ + 3497, /* F997 (63895) */ + 3498, /* F998 (63896) */ + 3499, /* F999 (63897) */ + 3500, /* F99A (63898) */ + 3501, /* F99B (63899) */ + 3502, /* F99C (63900) */ + 3503, /* F99D (63901) */ + 3504, /* F99E (63902) */ + 3505, /* F99F (63903) */ + 3506, /* F9A0 (63904) */ + 3457, /* F9A1 (63905) */ + 3507, /* F9A2 (63906) */ + 3508, /* F9A3 (63907) */ + 3509, /* F9A4 (63908) */ + 3510, /* F9A5 (63909) */ + 3511, /* F9A6 (63910) */ + 3512, /* F9A7 (63911) */ + 3513, /* F9A8 (63912) */ + 3514, /* F9A9 (63913) */ + 3441, /* F9AA (63914) */ + 3515, /* F9AB (63915) */ + 3516, /* F9AC (63916) */ + 3517, /* F9AD (63917) */ + 3518, /* F9AE (63918) */ + 3519, /* F9AF (63919) */ + 3520, /* F9B0 (63920) */ + 3521, /* F9B1 (63921) */ + 3522, /* F9B2 (63922) */ + 3523, /* F9B3 (63923) */ + 3524, /* F9B4 (63924) */ + 3525, /* F9B5 (63925) */ + 3526, /* F9B6 (63926) */ + 3527, /* F9B7 (63927) */ + 3528, /* F9B8 (63928) */ + 3529, /* F9B9 (63929) */ + 3530, /* F9BA (63930) */ + 3531, /* F9BB (63931) */ + 3532, /* F9BC (63932) */ + 3533, /* F9BD (63933) */ + 3534, /* F9BE (63934) */ + 3367, /* F9BF (63935) */ + 3535, /* F9C0 (63936) */ + 3536, /* F9C1 (63937) */ + 3537, /* F9C2 (63938) */ + 3538, /* F9C3 (63939) */ + 3539, /* F9C4 (63940) */ + 3540, /* F9C5 (63941) */ + 3541, /* F9C6 (63942) */ + 3542, /* F9C7 (63943) */ + 3543, /* F9C8 (63944) */ + 3544, /* F9C9 (63945) */ + 3545, /* F9CA (63946) */ + 3546, /* F9CB (63947) */ + 3547, /* F9CC (63948) */ + 3548, /* F9CD (63949) */ + 3549, /* F9CE (63950) */ + 3550, /* F9CF (63951) */ + 3551, /* F9D0 (63952) */ + 3552, /* F9D1 (63953) */ + 3553, /* F9D2 (63954) */ + 3554, /* F9D3 (63955) */ + 3555, /* F9D4 (63956) */ + 3556, /* F9D5 (63957) */ + 3557, /* F9D6 (63958) */ + 3558, /* F9D7 (63959) */ + 3559, /* F9D8 (63960) */ + 3560, /* F9D9 (63961) */ + 3561, /* F9DA (63962) */ + 3443, /* F9DB (63963) */ + 3562, /* F9DC (63964) */ + 3563, /* F9DD (63965) */ + 3564, /* F9DE (63966) */ + 3565, /* F9DF (63967) */ + 3566, /* F9E0 (63968) */ + 3567, /* F9E1 (63969) */ + 3568, /* F9E2 (63970) */ + 3569, /* F9E3 (63971) */ + 3570, /* F9E4 (63972) */ + 3571, /* F9E5 (63973) */ + 3572, /* F9E6 (63974) */ + 3573, /* F9E7 (63975) */ + 3574, /* F9E8 (63976) */ + 3575, /* F9E9 (63977) */ + 3576, /* F9EA (63978) */ + 3577, /* F9EB (63979) */ + 3578, /* F9EC (63980) */ + 3579, /* F9ED (63981) */ + 3580, /* F9EE (63982) */ + 3581, /* F9EF (63983) */ + 3582, /* F9F0 (63984) */ + 3583, /* F9F1 (63985) */ + 3584, /* F9F2 (63986) */ + 3585, /* F9F3 (63987) */ + 3586, /* F9F4 (63988) */ + 3587, /* F9F5 (63989) */ + 3588, /* F9F6 (63990) */ + 3589, /* F9F7 (63991) */ + 3590, /* F9F8 (63992) */ + 3591, /* F9F9 (63993) */ + 3592, /* F9FA (63994) */ + 3593, /* F9FB (63995) */ + 3594, /* F9FC (63996) */ + 3595, /* F9FD (63997) */ + 3596, /* F9FE (63998) */ + 3597, /* F9FF (63999) */ + 3598, /* FA00 (64000) */ + 3599, /* FA01 (64001) */ + 3600, /* FA02 (64002) */ + 3601, /* FA03 (64003) */ + 3602, /* FA04 (64004) */ + 3603, /* FA05 (64005) */ + 3604, /* FA06 (64006) */ + 3605, /* FA07 (64007) */ + 3606, /* FA08 (64008) */ + 3607, /* FA09 (64009) */ + 3608, /* FA0A (64010) */ + 3609, /* FA0B (64011) */ + 3610, /* FA0C (64012) */ + 3611, /* FA0D (64013) */ 1, /* FA0E (64014) */ 1, /* FA0F (64015) */ - 3608, /* FA10 (64016) */ + 3612, /* FA10 (64016) */ 1, /* FA11 (64017) */ - 3609, /* FA12 (64018) */ + 3613, /* FA12 (64018) */ 1, /* FA13 (64019) */ 1, /* FA14 (64020) */ - 3610, /* FA15 (64021) */ - 3611, /* FA16 (64022) */ - 3612, /* FA17 (64023) */ - 3613, /* FA18 (64024) */ - 3614, /* FA19 (64025) */ - 3615, /* FA1A (64026) */ - 3616, /* FA1B (64027) */ - 3617, /* FA1C (64028) */ - 3618, /* FA1D (64029) */ - 3619, /* FA1E (64030) */ + 3614, /* FA15 (64021) */ + 3615, /* FA16 (64022) */ + 3616, /* FA17 (64023) */ + 3617, /* FA18 (64024) */ + 3618, /* FA19 (64025) */ + 3619, /* FA1A (64026) */ + 3620, /* FA1B (64027) */ + 3621, /* FA1C (64028) */ + 3622, /* FA1D (64029) */ + 3623, /* FA1E (64030) */ 1, /* FA1F (64031) */ - 3620, /* FA20 (64032) */ + 3624, /* FA20 (64032) */ 1, /* FA21 (64033) */ - 3621, /* FA22 (64034) */ + 3625, /* FA22 (64034) */ 1, /* FA23 (64035) */ 1, /* FA24 (64036) */ - 3622, /* FA25 (64037) */ - 3623, /* FA26 (64038) */ + 3626, /* FA25 (64037) */ + 3627, /* FA26 (64038) */ 1, /* FA27 (64039) */ 1, /* FA28 (64040) */ 1, /* FA29 (64041) */ - 3624, /* FA2A (64042) */ - 3625, /* FA2B (64043) */ - 3626, /* FA2C (64044) */ - 3627, /* FA2D (64045) */ - 3628, /* FA2E (64046) */ - 3629, /* FA2F (64047) */ - 3630, /* FA30 (64048) */ - 3631, /* FA31 (64049) */ - 3632, /* FA32 (64050) */ - 3633, /* FA33 (64051) */ - 3634, /* FA34 (64052) */ - 3635, /* FA35 (64053) */ - 3636, /* FA36 (64054) */ - 3637, /* FA37 (64055) */ - 3638, /* FA38 (64056) */ - 3639, /* FA39 (64057) */ - 3640, /* FA3A (64058) */ - 3641, /* FA3B (64059) */ - 3642, /* FA3C (64060) */ - 3643, /* FA3D (64061) */ - 3644, /* FA3E (64062) */ - 3645, /* FA3F (64063) */ - 3646, /* FA40 (64064) */ - 3647, /* FA41 (64065) */ - 3648, /* FA42 (64066) */ - 3649, /* FA43 (64067) */ - 3650, /* FA44 (64068) */ - 3651, /* FA45 (64069) */ - 3652, /* FA46 (64070) */ - 3653, /* FA47 (64071) */ - 3654, /* FA48 (64072) */ - 3655, /* FA49 (64073) */ - 3656, /* FA4A (64074) */ - 3657, /* FA4B (64075) */ - 3658, /* FA4C (64076) */ - 3659, /* FA4D (64077) */ - 3660, /* FA4E (64078) */ - 3661, /* FA4F (64079) */ - 3662, /* FA50 (64080) */ - 3663, /* FA51 (64081) */ - 3664, /* FA52 (64082) */ - 3665, /* FA53 (64083) */ - 3666, /* FA54 (64084) */ - 3667, /* FA55 (64085) */ - 3668, /* FA56 (64086) */ - 3492, /* FA57 (64087) */ - 3669, /* FA58 (64088) */ - 3670, /* FA59 (64089) */ - 3671, /* FA5A (64090) */ - 3672, /* FA5B (64091) */ - 3673, /* FA5C (64092) */ - 3674, /* FA5D (64093) */ - 3674, /* FA5E (64094) */ - 3675, /* FA5F (64095) */ - 3676, /* FA60 (64096) */ - 3677, /* FA61 (64097) */ - 3678, /* FA62 (64098) */ - 3679, /* FA63 (64099) */ - 3680, /* FA64 (64100) */ - 3681, /* FA65 (64101) */ - 3682, /* FA66 (64102) */ - 3622, /* FA67 (64103) */ - 3683, /* FA68 (64104) */ - 3684, /* FA69 (64105) */ - 3685, /* FA6A (64106) */ - 3686, /* FA6B (64107) */ - 3687, /* FA6C (64108) */ - 3688, /* FA6D (64109) */ + 3628, /* FA2A (64042) */ + 3629, /* FA2B (64043) */ + 3630, /* FA2C (64044) */ + 3631, /* FA2D (64045) */ + 3632, /* FA2E (64046) */ + 3633, /* FA2F (64047) */ + 3634, /* FA30 (64048) */ + 3635, /* FA31 (64049) */ + 3636, /* FA32 (64050) */ + 3637, /* FA33 (64051) */ + 3638, /* FA34 (64052) */ + 3639, /* FA35 (64053) */ + 3640, /* FA36 (64054) */ + 3641, /* FA37 (64055) */ + 3642, /* FA38 (64056) */ + 3643, /* FA39 (64057) */ + 3644, /* FA3A (64058) */ + 3645, /* FA3B (64059) */ + 3646, /* FA3C (64060) */ + 3647, /* FA3D (64061) */ + 3648, /* FA3E (64062) */ + 3649, /* FA3F (64063) */ + 3650, /* FA40 (64064) */ + 3651, /* FA41 (64065) */ + 3652, /* FA42 (64066) */ + 3653, /* FA43 (64067) */ + 3654, /* FA44 (64068) */ + 3655, /* FA45 (64069) */ + 3656, /* FA46 (64070) */ + 3657, /* FA47 (64071) */ + 3658, /* FA48 (64072) */ + 3659, /* FA49 (64073) */ + 3660, /* FA4A (64074) */ + 3661, /* FA4B (64075) */ + 3662, /* FA4C (64076) */ + 3663, /* FA4D (64077) */ + 3664, /* FA4E (64078) */ + 3665, /* FA4F (64079) */ + 3666, /* FA50 (64080) */ + 3667, /* FA51 (64081) */ + 3668, /* FA52 (64082) */ + 3669, /* FA53 (64083) */ + 3670, /* FA54 (64084) */ + 3671, /* FA55 (64085) */ + 3672, /* FA56 (64086) */ + 3496, /* FA57 (64087) */ + 3673, /* FA58 (64088) */ + 3674, /* FA59 (64089) */ + 3675, /* FA5A (64090) */ + 3676, /* FA5B (64091) */ + 3677, /* FA5C (64092) */ + 3678, /* FA5D (64093) */ + 3678, /* FA5E (64094) */ + 3679, /* FA5F (64095) */ + 3680, /* FA60 (64096) */ + 3681, /* FA61 (64097) */ + 3682, /* FA62 (64098) */ + 3683, /* FA63 (64099) */ + 3684, /* FA64 (64100) */ + 3685, /* FA65 (64101) */ + 3686, /* FA66 (64102) */ + 3626, /* FA67 (64103) */ + 3687, /* FA68 (64104) */ + 3688, /* FA69 (64105) */ + 3689, /* FA6A (64106) */ + 3690, /* FA6B (64107) */ + 3691, /* FA6C (64108) */ + 3692, /* FA6D (64109) */ 56, /* FA6E (64110) */ 56, /* FA6F (64111) */ - 3689, /* FA70 (64112) */ - 3690, /* FA71 (64113) */ - 3691, /* FA72 (64114) */ - 3692, /* FA73 (64115) */ - 3693, /* FA74 (64116) */ - 3694, /* FA75 (64117) */ - 3695, /* FA76 (64118) */ - 3696, /* FA77 (64119) */ - 3636, /* FA78 (64120) */ - 3697, /* FA79 (64121) */ - 3698, /* FA7A (64122) */ - 3699, /* FA7B (64123) */ - 3608, /* FA7C (64124) */ - 3700, /* FA7D (64125) */ - 3701, /* FA7E (64126) */ - 3702, /* FA7F (64127) */ - 3703, /* FA80 (64128) */ - 3704, /* FA81 (64129) */ - 3705, /* FA82 (64130) */ - 3706, /* FA83 (64131) */ - 3707, /* FA84 (64132) */ - 3708, /* FA85 (64133) */ - 3709, /* FA86 (64134) */ - 3710, /* FA87 (64135) */ - 3711, /* FA88 (64136) */ - 3645, /* FA89 (64137) */ - 3712, /* FA8A (64138) */ - 3646, /* FA8B (64139) */ - 3713, /* FA8C (64140) */ - 3714, /* FA8D (64141) */ - 3715, /* FA8E (64142) */ - 3716, /* FA8F (64143) */ - 3717, /* FA90 (64144) */ - 3609, /* FA91 (64145) */ - 3384, /* FA92 (64146) */ - 3718, /* FA93 (64147) */ - 3719, /* FA94 (64148) */ - 3720, /* FA95 (64149) */ - 3454, /* FA96 (64150) */ - 3541, /* FA97 (64151) */ - 3721, /* FA98 (64152) */ - 3722, /* FA99 (64153) */ - 3653, /* FA9A (64154) */ - 3723, /* FA9B (64155) */ - 3654, /* FA9C (64156) */ - 3724, /* FA9D (64157) */ - 3725, /* FA9E (64158) */ - 3726, /* FA9F (64159) */ - 3611, /* FAA0 (64160) */ - 3727, /* FAA1 (64161) */ - 3728, /* FAA2 (64162) */ - 3729, /* FAA3 (64163) */ - 3730, /* FAA4 (64164) */ - 3731, /* FAA5 (64165) */ - 3612, /* FAA6 (64166) */ - 3732, /* FAA7 (64167) */ - 3733, /* FAA8 (64168) */ - 3734, /* FAA9 (64169) */ - 3735, /* FAAA (64170) */ - 3736, /* FAAB (64171) */ - 3737, /* FAAC (64172) */ - 3668, /* FAAD (64173) */ - 3738, /* FAAE (64174) */ - 3739, /* FAAF (64175) */ - 3492, /* FAB0 (64176) */ - 3740, /* FAB1 (64177) */ - 3672, /* FAB2 (64178) */ - 3741, /* FAB3 (64179) */ - 3742, /* FAB4 (64180) */ - 3743, /* FAB5 (64181) */ - 3744, /* FAB6 (64182) */ - 3745, /* FAB7 (64183) */ - 3677, /* FAB8 (64184) */ - 3746, /* FAB9 (64185) */ - 3621, /* FABA (64186) */ - 3747, /* FABB (64187) */ - 3678, /* FABC (64188) */ - 3435, /* FABD (64189) */ - 3748, /* FABE (64190) */ - 3679, /* FABF (64191) */ - 3749, /* FAC0 (64192) */ - 3681, /* FAC1 (64193) */ - 3750, /* FAC2 (64194) */ - 3751, /* FAC3 (64195) */ - 3752, /* FAC4 (64196) */ - 3753, /* FAC5 (64197) */ - 3754, /* FAC6 (64198) */ - 3683, /* FAC7 (64199) */ - 3617, /* FAC8 (64200) */ - 3755, /* FAC9 (64201) */ - 3684, /* FACA (64202) */ - 3756, /* FACB (64203) */ - 3685, /* FACC (64204) */ - 3757, /* FACD (64205) */ - 3351, /* FACE (64206) */ - 3758, /* FACF (64207) */ - 3759, /* FAD0 (64208) */ - 3760, /* FAD1 (64209) */ - 3761, /* FAD2 (64210) */ - 3762, /* FAD3 (64211) */ - 3763, /* FAD4 (64212) */ - 3764, /* FAD5 (64213) */ - 3765, /* FAD6 (64214) */ - 3766, /* FAD7 (64215) */ - 3767, /* FAD8 (64216) */ - 3768, /* FAD9 (64217) */ + 3693, /* FA70 (64112) */ + 3694, /* FA71 (64113) */ + 3695, /* FA72 (64114) */ + 3696, /* FA73 (64115) */ + 3697, /* FA74 (64116) */ + 3698, /* FA75 (64117) */ + 3699, /* FA76 (64118) */ + 3700, /* FA77 (64119) */ + 3640, /* FA78 (64120) */ + 3701, /* FA79 (64121) */ + 3702, /* FA7A (64122) */ + 3703, /* FA7B (64123) */ + 3612, /* FA7C (64124) */ + 3704, /* FA7D (64125) */ + 3705, /* FA7E (64126) */ + 3706, /* FA7F (64127) */ + 3707, /* FA80 (64128) */ + 3708, /* FA81 (64129) */ + 3709, /* FA82 (64130) */ + 3710, /* FA83 (64131) */ + 3711, /* FA84 (64132) */ + 3712, /* FA85 (64133) */ + 3713, /* FA86 (64134) */ + 3714, /* FA87 (64135) */ + 3715, /* FA88 (64136) */ + 3649, /* FA89 (64137) */ + 3716, /* FA8A (64138) */ + 3650, /* FA8B (64139) */ + 3717, /* FA8C (64140) */ + 3718, /* FA8D (64141) */ + 3719, /* FA8E (64142) */ + 3720, /* FA8F (64143) */ + 3721, /* FA90 (64144) */ + 3613, /* FA91 (64145) */ + 3388, /* FA92 (64146) */ + 3722, /* FA93 (64147) */ + 3723, /* FA94 (64148) */ + 3724, /* FA95 (64149) */ + 3458, /* FA96 (64150) */ + 3545, /* FA97 (64151) */ + 3725, /* FA98 (64152) */ + 3726, /* FA99 (64153) */ + 3657, /* FA9A (64154) */ + 3727, /* FA9B (64155) */ + 3658, /* FA9C (64156) */ + 3728, /* FA9D (64157) */ + 3729, /* FA9E (64158) */ + 3730, /* FA9F (64159) */ + 3615, /* FAA0 (64160) */ + 3731, /* FAA1 (64161) */ + 3732, /* FAA2 (64162) */ + 3733, /* FAA3 (64163) */ + 3734, /* FAA4 (64164) */ + 3735, /* FAA5 (64165) */ + 3616, /* FAA6 (64166) */ + 3736, /* FAA7 (64167) */ + 3737, /* FAA8 (64168) */ + 3738, /* FAA9 (64169) */ + 3739, /* FAAA (64170) */ + 3740, /* FAAB (64171) */ + 3741, /* FAAC (64172) */ + 3672, /* FAAD (64173) */ + 3742, /* FAAE (64174) */ + 3743, /* FAAF (64175) */ + 3496, /* FAB0 (64176) */ + 3744, /* FAB1 (64177) */ + 3676, /* FAB2 (64178) */ + 3745, /* FAB3 (64179) */ + 3746, /* FAB4 (64180) */ + 3747, /* FAB5 (64181) */ + 3748, /* FAB6 (64182) */ + 3749, /* FAB7 (64183) */ + 3681, /* FAB8 (64184) */ + 3750, /* FAB9 (64185) */ + 3625, /* FABA (64186) */ + 3751, /* FABB (64187) */ + 3682, /* FABC (64188) */ + 3439, /* FABD (64189) */ + 3752, /* FABE (64190) */ + 3683, /* FABF (64191) */ + 3753, /* FAC0 (64192) */ + 3685, /* FAC1 (64193) */ + 3754, /* FAC2 (64194) */ + 3755, /* FAC3 (64195) */ + 3756, /* FAC4 (64196) */ + 3757, /* FAC5 (64197) */ + 3758, /* FAC6 (64198) */ + 3687, /* FAC7 (64199) */ + 3621, /* FAC8 (64200) */ + 3759, /* FAC9 (64201) */ + 3688, /* FACA (64202) */ + 3760, /* FACB (64203) */ + 3689, /* FACC (64204) */ + 3761, /* FACD (64205) */ + 3355, /* FACE (64206) */ + 3762, /* FACF (64207) */ + 3763, /* FAD0 (64208) */ + 3764, /* FAD1 (64209) */ + 3765, /* FAD2 (64210) */ + 3766, /* FAD3 (64211) */ + 3767, /* FAD4 (64212) */ + 3768, /* FAD5 (64213) */ + 3769, /* FAD6 (64214) */ + 3770, /* FAD7 (64215) */ + 3771, /* FAD8 (64216) */ + 3772, /* FAD9 (64217) */ 56, /* FADA (64218) */ 56, /* FADB (64219) */ 56, /* FADC (64220) */ @@ -57884,13 +57884,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FAFD (64253) */ 56, /* FAFE (64254) */ 56, /* FAFF (64255) */ - 3769, /* FB00 (64256) */ - 3770, /* FB01 (64257) */ - 3771, /* FB02 (64258) */ - 3772, /* FB03 (64259) */ - 3773, /* FB04 (64260) */ - 3774, /* FB05 (64261) */ - 3775, /* FB06 (64262) */ + 3773, /* FB00 (64256) */ + 3774, /* FB01 (64257) */ + 3775, /* FB02 (64258) */ + 3776, /* FB03 (64259) */ + 3777, /* FB04 (64260) */ + 3778, /* FB05 (64261) */ + 3779, /* FB06 (64262) */ 56, /* FB07 (64263) */ 56, /* FB08 (64264) */ 56, /* FB09 (64265) */ @@ -57903,165 +57903,165 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FB10 (64272) */ 56, /* FB11 (64273) */ 56, /* FB12 (64274) */ - 3776, /* FB13 (64275) */ - 3777, /* FB14 (64276) */ - 3778, /* FB15 (64277) */ - 3779, /* FB16 (64278) */ - 3780, /* FB17 (64279) */ + 3780, /* FB13 (64275) */ + 3781, /* FB14 (64276) */ + 3782, /* FB15 (64277) */ + 3783, /* FB16 (64278) */ + 3784, /* FB17 (64279) */ 56, /* FB18 (64280) */ 56, /* FB19 (64281) */ 56, /* FB1A (64282) */ 56, /* FB1B (64283) */ 56, /* FB1C (64284) */ - 3781, /* FB1D (64285) */ - 3782, /* FB1E (64286) */ - 3783, /* FB1F (64287) */ - 3784, /* FB20 (64288) */ - 3785, /* FB21 (64289) */ - 3786, /* FB22 (64290) */ - 3787, /* FB23 (64291) */ - 3788, /* FB24 (64292) */ - 3789, /* FB25 (64293) */ - 3790, /* FB26 (64294) */ - 3791, /* FB27 (64295) */ - 3792, /* FB28 (64296) */ - 3793, /* FB29 (64297) */ - 3794, /* FB2A (64298) */ - 3795, /* FB2B (64299) */ - 3796, /* FB2C (64300) */ - 3797, /* FB2D (64301) */ - 3798, /* FB2E (64302) */ - 3799, /* FB2F (64303) */ - 3800, /* FB30 (64304) */ - 3801, /* FB31 (64305) */ - 3802, /* FB32 (64306) */ - 3803, /* FB33 (64307) */ - 3804, /* FB34 (64308) */ - 3805, /* FB35 (64309) */ - 3806, /* FB36 (64310) */ + 3785, /* FB1D (64285) */ + 3786, /* FB1E (64286) */ + 3787, /* FB1F (64287) */ + 3788, /* FB20 (64288) */ + 3789, /* FB21 (64289) */ + 3790, /* FB22 (64290) */ + 3791, /* FB23 (64291) */ + 3792, /* FB24 (64292) */ + 3793, /* FB25 (64293) */ + 3794, /* FB26 (64294) */ + 3795, /* FB27 (64295) */ + 3796, /* FB28 (64296) */ + 3797, /* FB29 (64297) */ + 3798, /* FB2A (64298) */ + 3799, /* FB2B (64299) */ + 3800, /* FB2C (64300) */ + 3801, /* FB2D (64301) */ + 3802, /* FB2E (64302) */ + 3803, /* FB2F (64303) */ + 3804, /* FB30 (64304) */ + 3805, /* FB31 (64305) */ + 3806, /* FB32 (64306) */ + 3807, /* FB33 (64307) */ + 3808, /* FB34 (64308) */ + 3809, /* FB35 (64309) */ + 3810, /* FB36 (64310) */ 56, /* FB37 (64311) */ - 3807, /* FB38 (64312) */ - 3808, /* FB39 (64313) */ - 3809, /* FB3A (64314) */ - 3810, /* FB3B (64315) */ - 3811, /* FB3C (64316) */ + 3811, /* FB38 (64312) */ + 3812, /* FB39 (64313) */ + 3813, /* FB3A (64314) */ + 3814, /* FB3B (64315) */ + 3815, /* FB3C (64316) */ 56, /* FB3D (64317) */ - 3812, /* FB3E (64318) */ + 3816, /* FB3E (64318) */ 56, /* FB3F (64319) */ - 3813, /* FB40 (64320) */ - 3814, /* FB41 (64321) */ + 3817, /* FB40 (64320) */ + 3818, /* FB41 (64321) */ 56, /* FB42 (64322) */ - 3815, /* FB43 (64323) */ - 3816, /* FB44 (64324) */ + 3819, /* FB43 (64323) */ + 3820, /* FB44 (64324) */ 56, /* FB45 (64325) */ - 3817, /* FB46 (64326) */ - 3818, /* FB47 (64327) */ - 3819, /* FB48 (64328) */ - 3820, /* FB49 (64329) */ - 3821, /* FB4A (64330) */ - 3822, /* FB4B (64331) */ - 3823, /* FB4C (64332) */ - 3824, /* FB4D (64333) */ - 3825, /* FB4E (64334) */ - 3826, /* FB4F (64335) */ - 3827, /* FB50 (64336) */ - 3828, /* FB51 (64337) */ - 3829, /* FB52 (64338) */ - 3830, /* FB53 (64339) */ - 3831, /* FB54 (64340) */ - 3832, /* FB55 (64341) */ - 3833, /* FB56 (64342) */ - 3834, /* FB57 (64343) */ - 3835, /* FB58 (64344) */ - 3836, /* FB59 (64345) */ - 3837, /* FB5A (64346) */ - 3838, /* FB5B (64347) */ - 3839, /* FB5C (64348) */ - 3840, /* FB5D (64349) */ - 3841, /* FB5E (64350) */ - 3842, /* FB5F (64351) */ - 3843, /* FB60 (64352) */ - 3844, /* FB61 (64353) */ - 3845, /* FB62 (64354) */ - 3846, /* FB63 (64355) */ - 3847, /* FB64 (64356) */ - 3848, /* FB65 (64357) */ - 3849, /* FB66 (64358) */ - 3850, /* FB67 (64359) */ - 3851, /* FB68 (64360) */ - 3852, /* FB69 (64361) */ - 3853, /* FB6A (64362) */ - 3854, /* FB6B (64363) */ - 3855, /* FB6C (64364) */ - 3856, /* FB6D (64365) */ - 3857, /* FB6E (64366) */ - 3858, /* FB6F (64367) */ - 3859, /* FB70 (64368) */ - 3860, /* FB71 (64369) */ - 3861, /* FB72 (64370) */ - 3862, /* FB73 (64371) */ - 3863, /* FB74 (64372) */ - 3864, /* FB75 (64373) */ - 3865, /* FB76 (64374) */ - 3866, /* FB77 (64375) */ - 3867, /* FB78 (64376) */ - 3868, /* FB79 (64377) */ - 3869, /* FB7A (64378) */ - 3870, /* FB7B (64379) */ - 3871, /* FB7C (64380) */ - 3872, /* FB7D (64381) */ - 3873, /* FB7E (64382) */ - 3874, /* FB7F (64383) */ - 3875, /* FB80 (64384) */ - 3876, /* FB81 (64385) */ - 3877, /* FB82 (64386) */ - 3878, /* FB83 (64387) */ - 3879, /* FB84 (64388) */ - 3880, /* FB85 (64389) */ - 3881, /* FB86 (64390) */ - 3882, /* FB87 (64391) */ - 3883, /* FB88 (64392) */ - 3884, /* FB89 (64393) */ - 3885, /* FB8A (64394) */ - 3886, /* FB8B (64395) */ - 3887, /* FB8C (64396) */ - 3888, /* FB8D (64397) */ - 3889, /* FB8E (64398) */ - 3890, /* FB8F (64399) */ - 3891, /* FB90 (64400) */ - 3892, /* FB91 (64401) */ - 3893, /* FB92 (64402) */ - 3894, /* FB93 (64403) */ - 3895, /* FB94 (64404) */ - 3896, /* FB95 (64405) */ - 3897, /* FB96 (64406) */ - 3898, /* FB97 (64407) */ - 3899, /* FB98 (64408) */ - 3900, /* FB99 (64409) */ - 3901, /* FB9A (64410) */ - 3902, /* FB9B (64411) */ - 3903, /* FB9C (64412) */ - 3904, /* FB9D (64413) */ - 3905, /* FB9E (64414) */ - 3906, /* FB9F (64415) */ - 3907, /* FBA0 (64416) */ - 3908, /* FBA1 (64417) */ - 3909, /* FBA2 (64418) */ - 3910, /* FBA3 (64419) */ - 3911, /* FBA4 (64420) */ - 3912, /* FBA5 (64421) */ - 3913, /* FBA6 (64422) */ - 3914, /* FBA7 (64423) */ - 3915, /* FBA8 (64424) */ - 3916, /* FBA9 (64425) */ - 3917, /* FBAA (64426) */ - 3918, /* FBAB (64427) */ - 3919, /* FBAC (64428) */ - 3920, /* FBAD (64429) */ - 3921, /* FBAE (64430) */ - 3922, /* FBAF (64431) */ - 3923, /* FBB0 (64432) */ - 3924, /* FBB1 (64433) */ + 3821, /* FB46 (64326) */ + 3822, /* FB47 (64327) */ + 3823, /* FB48 (64328) */ + 3824, /* FB49 (64329) */ + 3825, /* FB4A (64330) */ + 3826, /* FB4B (64331) */ + 3827, /* FB4C (64332) */ + 3828, /* FB4D (64333) */ + 3829, /* FB4E (64334) */ + 3830, /* FB4F (64335) */ + 3831, /* FB50 (64336) */ + 3832, /* FB51 (64337) */ + 3833, /* FB52 (64338) */ + 3834, /* FB53 (64339) */ + 3835, /* FB54 (64340) */ + 3836, /* FB55 (64341) */ + 3837, /* FB56 (64342) */ + 3838, /* FB57 (64343) */ + 3839, /* FB58 (64344) */ + 3840, /* FB59 (64345) */ + 3841, /* FB5A (64346) */ + 3842, /* FB5B (64347) */ + 3843, /* FB5C (64348) */ + 3844, /* FB5D (64349) */ + 3845, /* FB5E (64350) */ + 3846, /* FB5F (64351) */ + 3847, /* FB60 (64352) */ + 3848, /* FB61 (64353) */ + 3849, /* FB62 (64354) */ + 3850, /* FB63 (64355) */ + 3851, /* FB64 (64356) */ + 3852, /* FB65 (64357) */ + 3853, /* FB66 (64358) */ + 3854, /* FB67 (64359) */ + 3855, /* FB68 (64360) */ + 3856, /* FB69 (64361) */ + 3857, /* FB6A (64362) */ + 3858, /* FB6B (64363) */ + 3859, /* FB6C (64364) */ + 3860, /* FB6D (64365) */ + 3861, /* FB6E (64366) */ + 3862, /* FB6F (64367) */ + 3863, /* FB70 (64368) */ + 3864, /* FB71 (64369) */ + 3865, /* FB72 (64370) */ + 3866, /* FB73 (64371) */ + 3867, /* FB74 (64372) */ + 3868, /* FB75 (64373) */ + 3869, /* FB76 (64374) */ + 3870, /* FB77 (64375) */ + 3871, /* FB78 (64376) */ + 3872, /* FB79 (64377) */ + 3873, /* FB7A (64378) */ + 3874, /* FB7B (64379) */ + 3875, /* FB7C (64380) */ + 3876, /* FB7D (64381) */ + 3877, /* FB7E (64382) */ + 3878, /* FB7F (64383) */ + 3879, /* FB80 (64384) */ + 3880, /* FB81 (64385) */ + 3881, /* FB82 (64386) */ + 3882, /* FB83 (64387) */ + 3883, /* FB84 (64388) */ + 3884, /* FB85 (64389) */ + 3885, /* FB86 (64390) */ + 3886, /* FB87 (64391) */ + 3887, /* FB88 (64392) */ + 3888, /* FB89 (64393) */ + 3889, /* FB8A (64394) */ + 3890, /* FB8B (64395) */ + 3891, /* FB8C (64396) */ + 3892, /* FB8D (64397) */ + 3893, /* FB8E (64398) */ + 3894, /* FB8F (64399) */ + 3895, /* FB90 (64400) */ + 3896, /* FB91 (64401) */ + 3897, /* FB92 (64402) */ + 3898, /* FB93 (64403) */ + 3899, /* FB94 (64404) */ + 3900, /* FB95 (64405) */ + 3901, /* FB96 (64406) */ + 3902, /* FB97 (64407) */ + 3903, /* FB98 (64408) */ + 3904, /* FB99 (64409) */ + 3905, /* FB9A (64410) */ + 3906, /* FB9B (64411) */ + 3907, /* FB9C (64412) */ + 3908, /* FB9D (64413) */ + 3909, /* FB9E (64414) */ + 3910, /* FB9F (64415) */ + 3911, /* FBA0 (64416) */ + 3912, /* FBA1 (64417) */ + 3913, /* FBA2 (64418) */ + 3914, /* FBA3 (64419) */ + 3915, /* FBA4 (64420) */ + 3916, /* FBA5 (64421) */ + 3917, /* FBA6 (64422) */ + 3918, /* FBA7 (64423) */ + 3919, /* FBA8 (64424) */ + 3920, /* FBA9 (64425) */ + 3921, /* FBAA (64426) */ + 3922, /* FBAB (64427) */ + 3923, /* FBAC (64428) */ + 3924, /* FBAD (64429) */ + 3925, /* FBAE (64430) */ + 3926, /* FBAF (64431) */ + 3927, /* FBB0 (64432) */ + 3928, /* FBB1 (64433) */ 1, /* FBB2 (64434) */ 1, /* FBB3 (64435) */ 1, /* FBB4 (64436) */ @@ -58079,385 +58079,385 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* FBC0 (64448) */ 1, /* FBC1 (64449) */ 1, /* FBC2 (64450) */ - 56, /* FBC3 (64451) */ - 56, /* FBC4 (64452) */ - 56, /* FBC5 (64453) */ - 56, /* FBC6 (64454) */ - 56, /* FBC7 (64455) */ - 56, /* FBC8 (64456) */ - 56, /* FBC9 (64457) */ - 56, /* FBCA (64458) */ - 56, /* FBCB (64459) */ - 56, /* FBCC (64460) */ - 56, /* FBCD (64461) */ - 56, /* FBCE (64462) */ - 56, /* FBCF (64463) */ - 56, /* FBD0 (64464) */ - 56, /* FBD1 (64465) */ - 56, /* FBD2 (64466) */ - 3925, /* FBD3 (64467) */ - 3926, /* FBD4 (64468) */ - 3927, /* FBD5 (64469) */ - 3928, /* FBD6 (64470) */ - 3929, /* FBD7 (64471) */ - 3930, /* FBD8 (64472) */ - 3931, /* FBD9 (64473) */ - 3932, /* FBDA (64474) */ - 3933, /* FBDB (64475) */ - 3934, /* FBDC (64476) */ - 3935, /* FBDD (64477) */ - 3936, /* FBDE (64478) */ - 3937, /* FBDF (64479) */ - 3938, /* FBE0 (64480) */ - 3939, /* FBE1 (64481) */ - 3940, /* FBE2 (64482) */ - 3941, /* FBE3 (64483) */ - 3942, /* FBE4 (64484) */ - 3943, /* FBE5 (64485) */ - 3944, /* FBE6 (64486) */ - 3945, /* FBE7 (64487) */ - 3946, /* FBE8 (64488) */ - 3947, /* FBE9 (64489) */ - 3948, /* FBEA (64490) */ - 3949, /* FBEB (64491) */ - 3950, /* FBEC (64492) */ - 3951, /* FBED (64493) */ - 3952, /* FBEE (64494) */ - 3953, /* FBEF (64495) */ - 3954, /* FBF0 (64496) */ - 3955, /* FBF1 (64497) */ - 3956, /* FBF2 (64498) */ - 3957, /* FBF3 (64499) */ - 3958, /* FBF4 (64500) */ - 3959, /* FBF5 (64501) */ - 3960, /* FBF6 (64502) */ - 3961, /* FBF7 (64503) */ - 3962, /* FBF8 (64504) */ - 3963, /* FBF9 (64505) */ - 3964, /* FBFA (64506) */ - 3965, /* FBFB (64507) */ - 3966, /* FBFC (64508) */ - 3967, /* FBFD (64509) */ - 3968, /* FBFE (64510) */ - 3969, /* FBFF (64511) */ - 3970, /* FC00 (64512) */ - 3971, /* FC01 (64513) */ - 3972, /* FC02 (64514) */ - 3963, /* FC03 (64515) */ - 3973, /* FC04 (64516) */ - 3974, /* FC05 (64517) */ - 3975, /* FC06 (64518) */ - 3976, /* FC07 (64519) */ - 3977, /* FC08 (64520) */ - 3978, /* FC09 (64521) */ - 3979, /* FC0A (64522) */ - 3980, /* FC0B (64523) */ - 3981, /* FC0C (64524) */ - 3982, /* FC0D (64525) */ - 3983, /* FC0E (64526) */ - 3984, /* FC0F (64527) */ - 3985, /* FC10 (64528) */ - 3986, /* FC11 (64529) */ - 3987, /* FC12 (64530) */ - 3988, /* FC13 (64531) */ - 3989, /* FC14 (64532) */ - 3990, /* FC15 (64533) */ - 3991, /* FC16 (64534) */ - 3992, /* FC17 (64535) */ - 3993, /* FC18 (64536) */ - 3994, /* FC19 (64537) */ - 3995, /* FC1A (64538) */ - 3996, /* FC1B (64539) */ - 3997, /* FC1C (64540) */ - 3998, /* FC1D (64541) */ - 3999, /* FC1E (64542) */ - 4000, /* FC1F (64543) */ - 4001, /* FC20 (64544) */ - 4002, /* FC21 (64545) */ - 4003, /* FC22 (64546) */ - 4004, /* FC23 (64547) */ - 4005, /* FC24 (64548) */ - 4006, /* FC25 (64549) */ - 4007, /* FC26 (64550) */ - 4008, /* FC27 (64551) */ - 4009, /* FC28 (64552) */ - 4010, /* FC29 (64553) */ - 4011, /* FC2A (64554) */ - 4012, /* FC2B (64555) */ - 4013, /* FC2C (64556) */ - 4014, /* FC2D (64557) */ - 4015, /* FC2E (64558) */ - 4016, /* FC2F (64559) */ - 4017, /* FC30 (64560) */ - 4018, /* FC31 (64561) */ - 4019, /* FC32 (64562) */ - 4020, /* FC33 (64563) */ - 4021, /* FC34 (64564) */ - 4022, /* FC35 (64565) */ - 4023, /* FC36 (64566) */ - 4024, /* FC37 (64567) */ - 4025, /* FC38 (64568) */ - 4026, /* FC39 (64569) */ - 4027, /* FC3A (64570) */ - 4028, /* FC3B (64571) */ - 4029, /* FC3C (64572) */ - 4030, /* FC3D (64573) */ - 4031, /* FC3E (64574) */ - 4032, /* FC3F (64575) */ - 4033, /* FC40 (64576) */ - 4034, /* FC41 (64577) */ - 4035, /* FC42 (64578) */ - 4036, /* FC43 (64579) */ - 4037, /* FC44 (64580) */ - 4038, /* FC45 (64581) */ - 4039, /* FC46 (64582) */ - 4040, /* FC47 (64583) */ - 4041, /* FC48 (64584) */ - 4042, /* FC49 (64585) */ - 4043, /* FC4A (64586) */ - 4044, /* FC4B (64587) */ - 4045, /* FC4C (64588) */ - 4046, /* FC4D (64589) */ - 4047, /* FC4E (64590) */ - 4048, /* FC4F (64591) */ - 4049, /* FC50 (64592) */ - 4050, /* FC51 (64593) */ - 4051, /* FC52 (64594) */ - 4052, /* FC53 (64595) */ - 4053, /* FC54 (64596) */ - 4054, /* FC55 (64597) */ - 4055, /* FC56 (64598) */ - 4056, /* FC57 (64599) */ - 4057, /* FC58 (64600) */ - 4058, /* FC59 (64601) */ - 4059, /* FC5A (64602) */ - 4060, /* FC5B (64603) */ - 4061, /* FC5C (64604) */ - 4062, /* FC5D (64605) */ - 4063, /* FC5E (64606) */ - 4064, /* FC5F (64607) */ - 4065, /* FC60 (64608) */ - 4066, /* FC61 (64609) */ - 4067, /* FC62 (64610) */ - 4068, /* FC63 (64611) */ - 4069, /* FC64 (64612) */ - 4070, /* FC65 (64613) */ - 4071, /* FC66 (64614) */ - 4072, /* FC67 (64615) */ - 3964, /* FC68 (64616) */ - 4073, /* FC69 (64617) */ - 4074, /* FC6A (64618) */ - 4075, /* FC6B (64619) */ - 4076, /* FC6C (64620) */ - 4077, /* FC6D (64621) */ - 4078, /* FC6E (64622) */ - 4079, /* FC6F (64623) */ - 4080, /* FC70 (64624) */ - 4081, /* FC71 (64625) */ - 4082, /* FC72 (64626) */ - 4083, /* FC73 (64627) */ - 4084, /* FC74 (64628) */ - 4085, /* FC75 (64629) */ - 4086, /* FC76 (64630) */ - 4087, /* FC77 (64631) */ - 4088, /* FC78 (64632) */ - 4089, /* FC79 (64633) */ - 4090, /* FC7A (64634) */ - 4091, /* FC7B (64635) */ - 4092, /* FC7C (64636) */ - 4093, /* FC7D (64637) */ - 4094, /* FC7E (64638) */ - 4095, /* FC7F (64639) */ - 4096, /* FC80 (64640) */ - 4097, /* FC81 (64641) */ - 4098, /* FC82 (64642) */ - 4099, /* FC83 (64643) */ - 4100, /* FC84 (64644) */ - 4101, /* FC85 (64645) */ - 4102, /* FC86 (64646) */ - 4103, /* FC87 (64647) */ - 4104, /* FC88 (64648) */ - 4105, /* FC89 (64649) */ - 4106, /* FC8A (64650) */ - 4107, /* FC8B (64651) */ - 4108, /* FC8C (64652) */ - 4109, /* FC8D (64653) */ - 4110, /* FC8E (64654) */ - 4111, /* FC8F (64655) */ - 4112, /* FC90 (64656) */ - 4113, /* FC91 (64657) */ - 4114, /* FC92 (64658) */ - 4115, /* FC93 (64659) */ - 4116, /* FC94 (64660) */ - 4117, /* FC95 (64661) */ - 4118, /* FC96 (64662) */ - 4119, /* FC97 (64663) */ - 4120, /* FC98 (64664) */ - 4121, /* FC99 (64665) */ - 4122, /* FC9A (64666) */ - 4123, /* FC9B (64667) */ - 4124, /* FC9C (64668) */ - 4125, /* FC9D (64669) */ - 4126, /* FC9E (64670) */ - 4127, /* FC9F (64671) */ - 4128, /* FCA0 (64672) */ - 4129, /* FCA1 (64673) */ - 4130, /* FCA2 (64674) */ - 4131, /* FCA3 (64675) */ - 4132, /* FCA4 (64676) */ - 4133, /* FCA5 (64677) */ - 4134, /* FCA6 (64678) */ - 4135, /* FCA7 (64679) */ - 4136, /* FCA8 (64680) */ - 4137, /* FCA9 (64681) */ - 4138, /* FCAA (64682) */ - 4139, /* FCAB (64683) */ - 4140, /* FCAC (64684) */ - 4141, /* FCAD (64685) */ - 4142, /* FCAE (64686) */ - 4143, /* FCAF (64687) */ - 4144, /* FCB0 (64688) */ - 4145, /* FCB1 (64689) */ - 4146, /* FCB2 (64690) */ - 4147, /* FCB3 (64691) */ - 4148, /* FCB4 (64692) */ - 4149, /* FCB5 (64693) */ - 4150, /* FCB6 (64694) */ - 4151, /* FCB7 (64695) */ - 4152, /* FCB8 (64696) */ - 4153, /* FCB9 (64697) */ - 4154, /* FCBA (64698) */ - 4155, /* FCBB (64699) */ - 4156, /* FCBC (64700) */ - 4157, /* FCBD (64701) */ - 4158, /* FCBE (64702) */ - 4159, /* FCBF (64703) */ - 4160, /* FCC0 (64704) */ - 4161, /* FCC1 (64705) */ - 4162, /* FCC2 (64706) */ - 4163, /* FCC3 (64707) */ - 4164, /* FCC4 (64708) */ - 4165, /* FCC5 (64709) */ - 4166, /* FCC6 (64710) */ - 4167, /* FCC7 (64711) */ - 4168, /* FCC8 (64712) */ - 4169, /* FCC9 (64713) */ - 4170, /* FCCA (64714) */ - 4171, /* FCCB (64715) */ - 4172, /* FCCC (64716) */ - 4173, /* FCCD (64717) */ - 4174, /* FCCE (64718) */ - 4175, /* FCCF (64719) */ - 4176, /* FCD0 (64720) */ - 4177, /* FCD1 (64721) */ - 4178, /* FCD2 (64722) */ - 4179, /* FCD3 (64723) */ - 4180, /* FCD4 (64724) */ - 4181, /* FCD5 (64725) */ - 4182, /* FCD6 (64726) */ - 4183, /* FCD7 (64727) */ - 4184, /* FCD8 (64728) */ - 4185, /* FCD9 (64729) */ - 4186, /* FCDA (64730) */ - 4187, /* FCDB (64731) */ - 4188, /* FCDC (64732) */ - 4189, /* FCDD (64733) */ - 4190, /* FCDE (64734) */ - 4191, /* FCDF (64735) */ - 4192, /* FCE0 (64736) */ - 4193, /* FCE1 (64737) */ - 4194, /* FCE2 (64738) */ - 4195, /* FCE3 (64739) */ - 4196, /* FCE4 (64740) */ - 4197, /* FCE5 (64741) */ - 4198, /* FCE6 (64742) */ - 4199, /* FCE7 (64743) */ - 4200, /* FCE8 (64744) */ - 4201, /* FCE9 (64745) */ - 4202, /* FCEA (64746) */ - 4203, /* FCEB (64747) */ - 4204, /* FCEC (64748) */ - 4205, /* FCED (64749) */ - 4206, /* FCEE (64750) */ - 4207, /* FCEF (64751) */ - 4208, /* FCF0 (64752) */ - 4209, /* FCF1 (64753) */ - 4210, /* FCF2 (64754) */ - 4211, /* FCF3 (64755) */ - 4212, /* FCF4 (64756) */ - 4213, /* FCF5 (64757) */ - 4214, /* FCF6 (64758) */ - 4215, /* FCF7 (64759) */ - 4216, /* FCF8 (64760) */ - 4217, /* FCF9 (64761) */ - 4218, /* FCFA (64762) */ - 4219, /* FCFB (64763) */ - 4220, /* FCFC (64764) */ - 4221, /* FCFD (64765) */ - 4222, /* FCFE (64766) */ - 4223, /* FCFF (64767) */ - 4224, /* FD00 (64768) */ - 4225, /* FD01 (64769) */ - 4226, /* FD02 (64770) */ - 4227, /* FD03 (64771) */ - 4228, /* FD04 (64772) */ - 4229, /* FD05 (64773) */ - 4230, /* FD06 (64774) */ - 4231, /* FD07 (64775) */ - 4232, /* FD08 (64776) */ - 4233, /* FD09 (64777) */ - 4234, /* FD0A (64778) */ - 4235, /* FD0B (64779) */ - 4236, /* FD0C (64780) */ - 4237, /* FD0D (64781) */ - 4238, /* FD0E (64782) */ - 4239, /* FD0F (64783) */ - 4240, /* FD10 (64784) */ - 4241, /* FD11 (64785) */ - 4242, /* FD12 (64786) */ - 4243, /* FD13 (64787) */ - 4244, /* FD14 (64788) */ - 4245, /* FD15 (64789) */ - 4246, /* FD16 (64790) */ - 4247, /* FD17 (64791) */ - 4248, /* FD18 (64792) */ - 4249, /* FD19 (64793) */ - 4250, /* FD1A (64794) */ - 4251, /* FD1B (64795) */ - 4252, /* FD1C (64796) */ - 4253, /* FD1D (64797) */ - 4254, /* FD1E (64798) */ - 4255, /* FD1F (64799) */ - 4256, /* FD20 (64800) */ - 4257, /* FD21 (64801) */ - 4258, /* FD22 (64802) */ - 4259, /* FD23 (64803) */ - 4260, /* FD24 (64804) */ - 4261, /* FD25 (64805) */ - 4262, /* FD26 (64806) */ - 4263, /* FD27 (64807) */ - 4264, /* FD28 (64808) */ - 4265, /* FD29 (64809) */ - 4266, /* FD2A (64810) */ - 4267, /* FD2B (64811) */ - 4268, /* FD2C (64812) */ - 4269, /* FD2D (64813) */ - 4270, /* FD2E (64814) */ - 4271, /* FD2F (64815) */ - 4272, /* FD30 (64816) */ - 4273, /* FD31 (64817) */ - 4274, /* FD32 (64818) */ - 4275, /* FD33 (64819) */ - 4276, /* FD34 (64820) */ - 4277, /* FD35 (64821) */ - 4278, /* FD36 (64822) */ - 4279, /* FD37 (64823) */ - 4280, /* FD38 (64824) */ - 4281, /* FD39 (64825) */ - 4282, /* FD3A (64826) */ - 4283, /* FD3B (64827) */ - 4284, /* FD3C (64828) */ - 4285, /* FD3D (64829) */ + 1, /* FBC3 (64451) */ + 1, /* FBC4 (64452) */ + 1, /* FBC5 (64453) */ + 1, /* FBC6 (64454) */ + 1, /* FBC7 (64455) */ + 1, /* FBC8 (64456) */ + 1, /* FBC9 (64457) */ + 1, /* FBCA (64458) */ + 1, /* FBCB (64459) */ + 1, /* FBCC (64460) */ + 1, /* FBCD (64461) */ + 1, /* FBCE (64462) */ + 1, /* FBCF (64463) */ + 1, /* FBD0 (64464) */ + 1, /* FBD1 (64465) */ + 1, /* FBD2 (64466) */ + 3929, /* FBD3 (64467) */ + 3930, /* FBD4 (64468) */ + 3931, /* FBD5 (64469) */ + 3932, /* FBD6 (64470) */ + 3933, /* FBD7 (64471) */ + 3934, /* FBD8 (64472) */ + 3935, /* FBD9 (64473) */ + 3936, /* FBDA (64474) */ + 3937, /* FBDB (64475) */ + 3938, /* FBDC (64476) */ + 3939, /* FBDD (64477) */ + 3940, /* FBDE (64478) */ + 3941, /* FBDF (64479) */ + 3942, /* FBE0 (64480) */ + 3943, /* FBE1 (64481) */ + 3944, /* FBE2 (64482) */ + 3945, /* FBE3 (64483) */ + 3946, /* FBE4 (64484) */ + 3947, /* FBE5 (64485) */ + 3948, /* FBE6 (64486) */ + 3949, /* FBE7 (64487) */ + 3950, /* FBE8 (64488) */ + 3951, /* FBE9 (64489) */ + 3952, /* FBEA (64490) */ + 3953, /* FBEB (64491) */ + 3954, /* FBEC (64492) */ + 3955, /* FBED (64493) */ + 3956, /* FBEE (64494) */ + 3957, /* FBEF (64495) */ + 3958, /* FBF0 (64496) */ + 3959, /* FBF1 (64497) */ + 3960, /* FBF2 (64498) */ + 3961, /* FBF3 (64499) */ + 3962, /* FBF4 (64500) */ + 3963, /* FBF5 (64501) */ + 3964, /* FBF6 (64502) */ + 3965, /* FBF7 (64503) */ + 3966, /* FBF8 (64504) */ + 3967, /* FBF9 (64505) */ + 3968, /* FBFA (64506) */ + 3969, /* FBFB (64507) */ + 3970, /* FBFC (64508) */ + 3971, /* FBFD (64509) */ + 3972, /* FBFE (64510) */ + 3973, /* FBFF (64511) */ + 3974, /* FC00 (64512) */ + 3975, /* FC01 (64513) */ + 3976, /* FC02 (64514) */ + 3967, /* FC03 (64515) */ + 3977, /* FC04 (64516) */ + 3978, /* FC05 (64517) */ + 3979, /* FC06 (64518) */ + 3980, /* FC07 (64519) */ + 3981, /* FC08 (64520) */ + 3982, /* FC09 (64521) */ + 3983, /* FC0A (64522) */ + 3984, /* FC0B (64523) */ + 3985, /* FC0C (64524) */ + 3986, /* FC0D (64525) */ + 3987, /* FC0E (64526) */ + 3988, /* FC0F (64527) */ + 3989, /* FC10 (64528) */ + 3990, /* FC11 (64529) */ + 3991, /* FC12 (64530) */ + 3992, /* FC13 (64531) */ + 3993, /* FC14 (64532) */ + 3994, /* FC15 (64533) */ + 3995, /* FC16 (64534) */ + 3996, /* FC17 (64535) */ + 3997, /* FC18 (64536) */ + 3998, /* FC19 (64537) */ + 3999, /* FC1A (64538) */ + 4000, /* FC1B (64539) */ + 4001, /* FC1C (64540) */ + 4002, /* FC1D (64541) */ + 4003, /* FC1E (64542) */ + 4004, /* FC1F (64543) */ + 4005, /* FC20 (64544) */ + 4006, /* FC21 (64545) */ + 4007, /* FC22 (64546) */ + 4008, /* FC23 (64547) */ + 4009, /* FC24 (64548) */ + 4010, /* FC25 (64549) */ + 4011, /* FC26 (64550) */ + 4012, /* FC27 (64551) */ + 4013, /* FC28 (64552) */ + 4014, /* FC29 (64553) */ + 4015, /* FC2A (64554) */ + 4016, /* FC2B (64555) */ + 4017, /* FC2C (64556) */ + 4018, /* FC2D (64557) */ + 4019, /* FC2E (64558) */ + 4020, /* FC2F (64559) */ + 4021, /* FC30 (64560) */ + 4022, /* FC31 (64561) */ + 4023, /* FC32 (64562) */ + 4024, /* FC33 (64563) */ + 4025, /* FC34 (64564) */ + 4026, /* FC35 (64565) */ + 4027, /* FC36 (64566) */ + 4028, /* FC37 (64567) */ + 4029, /* FC38 (64568) */ + 4030, /* FC39 (64569) */ + 4031, /* FC3A (64570) */ + 4032, /* FC3B (64571) */ + 4033, /* FC3C (64572) */ + 4034, /* FC3D (64573) */ + 4035, /* FC3E (64574) */ + 4036, /* FC3F (64575) */ + 4037, /* FC40 (64576) */ + 4038, /* FC41 (64577) */ + 4039, /* FC42 (64578) */ + 4040, /* FC43 (64579) */ + 4041, /* FC44 (64580) */ + 4042, /* FC45 (64581) */ + 4043, /* FC46 (64582) */ + 4044, /* FC47 (64583) */ + 4045, /* FC48 (64584) */ + 4046, /* FC49 (64585) */ + 4047, /* FC4A (64586) */ + 4048, /* FC4B (64587) */ + 4049, /* FC4C (64588) */ + 4050, /* FC4D (64589) */ + 4051, /* FC4E (64590) */ + 4052, /* FC4F (64591) */ + 4053, /* FC50 (64592) */ + 4054, /* FC51 (64593) */ + 4055, /* FC52 (64594) */ + 4056, /* FC53 (64595) */ + 4057, /* FC54 (64596) */ + 4058, /* FC55 (64597) */ + 4059, /* FC56 (64598) */ + 4060, /* FC57 (64599) */ + 4061, /* FC58 (64600) */ + 4062, /* FC59 (64601) */ + 4063, /* FC5A (64602) */ + 4064, /* FC5B (64603) */ + 4065, /* FC5C (64604) */ + 4066, /* FC5D (64605) */ + 4067, /* FC5E (64606) */ + 4068, /* FC5F (64607) */ + 4069, /* FC60 (64608) */ + 4070, /* FC61 (64609) */ + 4071, /* FC62 (64610) */ + 4072, /* FC63 (64611) */ + 4073, /* FC64 (64612) */ + 4074, /* FC65 (64613) */ + 4075, /* FC66 (64614) */ + 4076, /* FC67 (64615) */ + 3968, /* FC68 (64616) */ + 4077, /* FC69 (64617) */ + 4078, /* FC6A (64618) */ + 4079, /* FC6B (64619) */ + 4080, /* FC6C (64620) */ + 4081, /* FC6D (64621) */ + 4082, /* FC6E (64622) */ + 4083, /* FC6F (64623) */ + 4084, /* FC70 (64624) */ + 4085, /* FC71 (64625) */ + 4086, /* FC72 (64626) */ + 4087, /* FC73 (64627) */ + 4088, /* FC74 (64628) */ + 4089, /* FC75 (64629) */ + 4090, /* FC76 (64630) */ + 4091, /* FC77 (64631) */ + 4092, /* FC78 (64632) */ + 4093, /* FC79 (64633) */ + 4094, /* FC7A (64634) */ + 4095, /* FC7B (64635) */ + 4096, /* FC7C (64636) */ + 4097, /* FC7D (64637) */ + 4098, /* FC7E (64638) */ + 4099, /* FC7F (64639) */ + 4100, /* FC80 (64640) */ + 4101, /* FC81 (64641) */ + 4102, /* FC82 (64642) */ + 4103, /* FC83 (64643) */ + 4104, /* FC84 (64644) */ + 4105, /* FC85 (64645) */ + 4106, /* FC86 (64646) */ + 4107, /* FC87 (64647) */ + 4108, /* FC88 (64648) */ + 4109, /* FC89 (64649) */ + 4110, /* FC8A (64650) */ + 4111, /* FC8B (64651) */ + 4112, /* FC8C (64652) */ + 4113, /* FC8D (64653) */ + 4114, /* FC8E (64654) */ + 4115, /* FC8F (64655) */ + 4116, /* FC90 (64656) */ + 4117, /* FC91 (64657) */ + 4118, /* FC92 (64658) */ + 4119, /* FC93 (64659) */ + 4120, /* FC94 (64660) */ + 4121, /* FC95 (64661) */ + 4122, /* FC96 (64662) */ + 4123, /* FC97 (64663) */ + 4124, /* FC98 (64664) */ + 4125, /* FC99 (64665) */ + 4126, /* FC9A (64666) */ + 4127, /* FC9B (64667) */ + 4128, /* FC9C (64668) */ + 4129, /* FC9D (64669) */ + 4130, /* FC9E (64670) */ + 4131, /* FC9F (64671) */ + 4132, /* FCA0 (64672) */ + 4133, /* FCA1 (64673) */ + 4134, /* FCA2 (64674) */ + 4135, /* FCA3 (64675) */ + 4136, /* FCA4 (64676) */ + 4137, /* FCA5 (64677) */ + 4138, /* FCA6 (64678) */ + 4139, /* FCA7 (64679) */ + 4140, /* FCA8 (64680) */ + 4141, /* FCA9 (64681) */ + 4142, /* FCAA (64682) */ + 4143, /* FCAB (64683) */ + 4144, /* FCAC (64684) */ + 4145, /* FCAD (64685) */ + 4146, /* FCAE (64686) */ + 4147, /* FCAF (64687) */ + 4148, /* FCB0 (64688) */ + 4149, /* FCB1 (64689) */ + 4150, /* FCB2 (64690) */ + 4151, /* FCB3 (64691) */ + 4152, /* FCB4 (64692) */ + 4153, /* FCB5 (64693) */ + 4154, /* FCB6 (64694) */ + 4155, /* FCB7 (64695) */ + 4156, /* FCB8 (64696) */ + 4157, /* FCB9 (64697) */ + 4158, /* FCBA (64698) */ + 4159, /* FCBB (64699) */ + 4160, /* FCBC (64700) */ + 4161, /* FCBD (64701) */ + 4162, /* FCBE (64702) */ + 4163, /* FCBF (64703) */ + 4164, /* FCC0 (64704) */ + 4165, /* FCC1 (64705) */ + 4166, /* FCC2 (64706) */ + 4167, /* FCC3 (64707) */ + 4168, /* FCC4 (64708) */ + 4169, /* FCC5 (64709) */ + 4170, /* FCC6 (64710) */ + 4171, /* FCC7 (64711) */ + 4172, /* FCC8 (64712) */ + 4173, /* FCC9 (64713) */ + 4174, /* FCCA (64714) */ + 4175, /* FCCB (64715) */ + 4176, /* FCCC (64716) */ + 4177, /* FCCD (64717) */ + 4178, /* FCCE (64718) */ + 4179, /* FCCF (64719) */ + 4180, /* FCD0 (64720) */ + 4181, /* FCD1 (64721) */ + 4182, /* FCD2 (64722) */ + 4183, /* FCD3 (64723) */ + 4184, /* FCD4 (64724) */ + 4185, /* FCD5 (64725) */ + 4186, /* FCD6 (64726) */ + 4187, /* FCD7 (64727) */ + 4188, /* FCD8 (64728) */ + 4189, /* FCD9 (64729) */ + 4190, /* FCDA (64730) */ + 4191, /* FCDB (64731) */ + 4192, /* FCDC (64732) */ + 4193, /* FCDD (64733) */ + 4194, /* FCDE (64734) */ + 4195, /* FCDF (64735) */ + 4196, /* FCE0 (64736) */ + 4197, /* FCE1 (64737) */ + 4198, /* FCE2 (64738) */ + 4199, /* FCE3 (64739) */ + 4200, /* FCE4 (64740) */ + 4201, /* FCE5 (64741) */ + 4202, /* FCE6 (64742) */ + 4203, /* FCE7 (64743) */ + 4204, /* FCE8 (64744) */ + 4205, /* FCE9 (64745) */ + 4206, /* FCEA (64746) */ + 4207, /* FCEB (64747) */ + 4208, /* FCEC (64748) */ + 4209, /* FCED (64749) */ + 4210, /* FCEE (64750) */ + 4211, /* FCEF (64751) */ + 4212, /* FCF0 (64752) */ + 4213, /* FCF1 (64753) */ + 4214, /* FCF2 (64754) */ + 4215, /* FCF3 (64755) */ + 4216, /* FCF4 (64756) */ + 4217, /* FCF5 (64757) */ + 4218, /* FCF6 (64758) */ + 4219, /* FCF7 (64759) */ + 4220, /* FCF8 (64760) */ + 4221, /* FCF9 (64761) */ + 4222, /* FCFA (64762) */ + 4223, /* FCFB (64763) */ + 4224, /* FCFC (64764) */ + 4225, /* FCFD (64765) */ + 4226, /* FCFE (64766) */ + 4227, /* FCFF (64767) */ + 4228, /* FD00 (64768) */ + 4229, /* FD01 (64769) */ + 4230, /* FD02 (64770) */ + 4231, /* FD03 (64771) */ + 4232, /* FD04 (64772) */ + 4233, /* FD05 (64773) */ + 4234, /* FD06 (64774) */ + 4235, /* FD07 (64775) */ + 4236, /* FD08 (64776) */ + 4237, /* FD09 (64777) */ + 4238, /* FD0A (64778) */ + 4239, /* FD0B (64779) */ + 4240, /* FD0C (64780) */ + 4241, /* FD0D (64781) */ + 4242, /* FD0E (64782) */ + 4243, /* FD0F (64783) */ + 4244, /* FD10 (64784) */ + 4245, /* FD11 (64785) */ + 4246, /* FD12 (64786) */ + 4247, /* FD13 (64787) */ + 4248, /* FD14 (64788) */ + 4249, /* FD15 (64789) */ + 4250, /* FD16 (64790) */ + 4251, /* FD17 (64791) */ + 4252, /* FD18 (64792) */ + 4253, /* FD19 (64793) */ + 4254, /* FD1A (64794) */ + 4255, /* FD1B (64795) */ + 4256, /* FD1C (64796) */ + 4257, /* FD1D (64797) */ + 4258, /* FD1E (64798) */ + 4259, /* FD1F (64799) */ + 4260, /* FD20 (64800) */ + 4261, /* FD21 (64801) */ + 4262, /* FD22 (64802) */ + 4263, /* FD23 (64803) */ + 4264, /* FD24 (64804) */ + 4265, /* FD25 (64805) */ + 4266, /* FD26 (64806) */ + 4267, /* FD27 (64807) */ + 4268, /* FD28 (64808) */ + 4269, /* FD29 (64809) */ + 4270, /* FD2A (64810) */ + 4271, /* FD2B (64811) */ + 4272, /* FD2C (64812) */ + 4273, /* FD2D (64813) */ + 4274, /* FD2E (64814) */ + 4275, /* FD2F (64815) */ + 4276, /* FD30 (64816) */ + 4277, /* FD31 (64817) */ + 4278, /* FD32 (64818) */ + 4279, /* FD33 (64819) */ + 4280, /* FD34 (64820) */ + 4281, /* FD35 (64821) */ + 4282, /* FD36 (64822) */ + 4283, /* FD37 (64823) */ + 4284, /* FD38 (64824) */ + 4285, /* FD39 (64825) */ + 4286, /* FD3A (64826) */ + 4287, /* FD3B (64827) */ + 4288, /* FD3C (64828) */ + 4289, /* FD3D (64829) */ 1, /* FD3E (64830) */ 1, /* FD3F (64831) */ 1, /* FD40 (64832) */ @@ -58476,133 +58476,133 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* FD4D (64845) */ 1, /* FD4E (64846) */ 1, /* FD4F (64847) */ - 4286, /* FD50 (64848) */ - 4287, /* FD51 (64849) */ - 4288, /* FD52 (64850) */ - 4289, /* FD53 (64851) */ - 4290, /* FD54 (64852) */ - 4291, /* FD55 (64853) */ - 4292, /* FD56 (64854) */ - 4293, /* FD57 (64855) */ - 4294, /* FD58 (64856) */ - 4295, /* FD59 (64857) */ - 4296, /* FD5A (64858) */ - 4297, /* FD5B (64859) */ - 4298, /* FD5C (64860) */ - 4299, /* FD5D (64861) */ - 4300, /* FD5E (64862) */ - 4301, /* FD5F (64863) */ - 4302, /* FD60 (64864) */ - 4303, /* FD61 (64865) */ - 4304, /* FD62 (64866) */ - 4305, /* FD63 (64867) */ - 4306, /* FD64 (64868) */ - 4307, /* FD65 (64869) */ - 4308, /* FD66 (64870) */ - 4309, /* FD67 (64871) */ - 4310, /* FD68 (64872) */ - 4311, /* FD69 (64873) */ - 4312, /* FD6A (64874) */ - 4313, /* FD6B (64875) */ - 4314, /* FD6C (64876) */ - 4315, /* FD6D (64877) */ - 4316, /* FD6E (64878) */ - 4317, /* FD6F (64879) */ - 4318, /* FD70 (64880) */ - 4319, /* FD71 (64881) */ - 4320, /* FD72 (64882) */ - 4321, /* FD73 (64883) */ - 4322, /* FD74 (64884) */ - 4323, /* FD75 (64885) */ - 4324, /* FD76 (64886) */ - 4325, /* FD77 (64887) */ - 4326, /* FD78 (64888) */ - 4327, /* FD79 (64889) */ - 4328, /* FD7A (64890) */ - 4329, /* FD7B (64891) */ - 4330, /* FD7C (64892) */ - 4331, /* FD7D (64893) */ - 4332, /* FD7E (64894) */ - 4333, /* FD7F (64895) */ - 4334, /* FD80 (64896) */ - 4335, /* FD81 (64897) */ - 4336, /* FD82 (64898) */ - 4337, /* FD83 (64899) */ - 4338, /* FD84 (64900) */ - 4339, /* FD85 (64901) */ - 4340, /* FD86 (64902) */ - 4341, /* FD87 (64903) */ - 4342, /* FD88 (64904) */ - 4343, /* FD89 (64905) */ - 4344, /* FD8A (64906) */ - 4345, /* FD8B (64907) */ - 4346, /* FD8C (64908) */ - 4347, /* FD8D (64909) */ - 4348, /* FD8E (64910) */ - 4349, /* FD8F (64911) */ - 56, /* FD90 (64912) */ - 56, /* FD91 (64913) */ - 4350, /* FD92 (64914) */ - 4351, /* FD93 (64915) */ - 4352, /* FD94 (64916) */ - 4353, /* FD95 (64917) */ - 4354, /* FD96 (64918) */ - 4355, /* FD97 (64919) */ - 4356, /* FD98 (64920) */ - 4357, /* FD99 (64921) */ - 4358, /* FD9A (64922) */ - 4359, /* FD9B (64923) */ - 4360, /* FD9C (64924) */ - 4361, /* FD9D (64925) */ - 4362, /* FD9E (64926) */ - 4363, /* FD9F (64927) */ - 4364, /* FDA0 (64928) */ - 4365, /* FDA1 (64929) */ - 4366, /* FDA2 (64930) */ - 4367, /* FDA3 (64931) */ - 4368, /* FDA4 (64932) */ - 4369, /* FDA5 (64933) */ - 4370, /* FDA6 (64934) */ - 4371, /* FDA7 (64935) */ - 4372, /* FDA8 (64936) */ - 4373, /* FDA9 (64937) */ - 4374, /* FDAA (64938) */ - 4375, /* FDAB (64939) */ - 4376, /* FDAC (64940) */ - 4377, /* FDAD (64941) */ - 4378, /* FDAE (64942) */ - 4379, /* FDAF (64943) */ - 4380, /* FDB0 (64944) */ - 4381, /* FDB1 (64945) */ - 4382, /* FDB2 (64946) */ - 4383, /* FDB3 (64947) */ - 4384, /* FDB4 (64948) */ - 4385, /* FDB5 (64949) */ - 4386, /* FDB6 (64950) */ - 4387, /* FDB7 (64951) */ - 4388, /* FDB8 (64952) */ - 4389, /* FDB9 (64953) */ - 4390, /* FDBA (64954) */ - 4391, /* FDBB (64955) */ - 4392, /* FDBC (64956) */ - 4393, /* FDBD (64957) */ - 4394, /* FDBE (64958) */ - 4395, /* FDBF (64959) */ - 4396, /* FDC0 (64960) */ - 4397, /* FDC1 (64961) */ - 4398, /* FDC2 (64962) */ - 4399, /* FDC3 (64963) */ - 4400, /* FDC4 (64964) */ - 4401, /* FDC5 (64965) */ - 4402, /* FDC6 (64966) */ - 4403, /* FDC7 (64967) */ - 56, /* FDC8 (64968) */ - 56, /* FDC9 (64969) */ - 56, /* FDCA (64970) */ - 56, /* FDCB (64971) */ - 56, /* FDCC (64972) */ - 56, /* FDCD (64973) */ - 56, /* FDCE (64974) */ + 4290, /* FD50 (64848) */ + 4291, /* FD51 (64849) */ + 4292, /* FD52 (64850) */ + 4293, /* FD53 (64851) */ + 4294, /* FD54 (64852) */ + 4295, /* FD55 (64853) */ + 4296, /* FD56 (64854) */ + 4297, /* FD57 (64855) */ + 4298, /* FD58 (64856) */ + 4299, /* FD59 (64857) */ + 4300, /* FD5A (64858) */ + 4301, /* FD5B (64859) */ + 4302, /* FD5C (64860) */ + 4303, /* FD5D (64861) */ + 4304, /* FD5E (64862) */ + 4305, /* FD5F (64863) */ + 4306, /* FD60 (64864) */ + 4307, /* FD61 (64865) */ + 4308, /* FD62 (64866) */ + 4309, /* FD63 (64867) */ + 4310, /* FD64 (64868) */ + 4311, /* FD65 (64869) */ + 4312, /* FD66 (64870) */ + 4313, /* FD67 (64871) */ + 4314, /* FD68 (64872) */ + 4315, /* FD69 (64873) */ + 4316, /* FD6A (64874) */ + 4317, /* FD6B (64875) */ + 4318, /* FD6C (64876) */ + 4319, /* FD6D (64877) */ + 4320, /* FD6E (64878) */ + 4321, /* FD6F (64879) */ + 4322, /* FD70 (64880) */ + 4323, /* FD71 (64881) */ + 4324, /* FD72 (64882) */ + 4325, /* FD73 (64883) */ + 4326, /* FD74 (64884) */ + 4327, /* FD75 (64885) */ + 4328, /* FD76 (64886) */ + 4329, /* FD77 (64887) */ + 4330, /* FD78 (64888) */ + 4331, /* FD79 (64889) */ + 4332, /* FD7A (64890) */ + 4333, /* FD7B (64891) */ + 4334, /* FD7C (64892) */ + 4335, /* FD7D (64893) */ + 4336, /* FD7E (64894) */ + 4337, /* FD7F (64895) */ + 4338, /* FD80 (64896) */ + 4339, /* FD81 (64897) */ + 4340, /* FD82 (64898) */ + 4341, /* FD83 (64899) */ + 4342, /* FD84 (64900) */ + 4343, /* FD85 (64901) */ + 4344, /* FD86 (64902) */ + 4345, /* FD87 (64903) */ + 4346, /* FD88 (64904) */ + 4347, /* FD89 (64905) */ + 4348, /* FD8A (64906) */ + 4349, /* FD8B (64907) */ + 4350, /* FD8C (64908) */ + 4351, /* FD8D (64909) */ + 4352, /* FD8E (64910) */ + 4353, /* FD8F (64911) */ + 1, /* FD90 (64912) */ + 1, /* FD91 (64913) */ + 4354, /* FD92 (64914) */ + 4355, /* FD93 (64915) */ + 4356, /* FD94 (64916) */ + 4357, /* FD95 (64917) */ + 4358, /* FD96 (64918) */ + 4359, /* FD97 (64919) */ + 4360, /* FD98 (64920) */ + 4361, /* FD99 (64921) */ + 4362, /* FD9A (64922) */ + 4363, /* FD9B (64923) */ + 4364, /* FD9C (64924) */ + 4365, /* FD9D (64925) */ + 4366, /* FD9E (64926) */ + 4367, /* FD9F (64927) */ + 4368, /* FDA0 (64928) */ + 4369, /* FDA1 (64929) */ + 4370, /* FDA2 (64930) */ + 4371, /* FDA3 (64931) */ + 4372, /* FDA4 (64932) */ + 4373, /* FDA5 (64933) */ + 4374, /* FDA6 (64934) */ + 4375, /* FDA7 (64935) */ + 4376, /* FDA8 (64936) */ + 4377, /* FDA9 (64937) */ + 4378, /* FDAA (64938) */ + 4379, /* FDAB (64939) */ + 4380, /* FDAC (64940) */ + 4381, /* FDAD (64941) */ + 4382, /* FDAE (64942) */ + 4383, /* FDAF (64943) */ + 4384, /* FDB0 (64944) */ + 4385, /* FDB1 (64945) */ + 4386, /* FDB2 (64946) */ + 4387, /* FDB3 (64947) */ + 4388, /* FDB4 (64948) */ + 4389, /* FDB5 (64949) */ + 4390, /* FDB6 (64950) */ + 4391, /* FDB7 (64951) */ + 4392, /* FDB8 (64952) */ + 4393, /* FDB9 (64953) */ + 4394, /* FDBA (64954) */ + 4395, /* FDBB (64955) */ + 4396, /* FDBC (64956) */ + 4397, /* FDBD (64957) */ + 4398, /* FDBE (64958) */ + 4399, /* FDBF (64959) */ + 4400, /* FDC0 (64960) */ + 4401, /* FDC1 (64961) */ + 4402, /* FDC2 (64962) */ + 4403, /* FDC3 (64963) */ + 4404, /* FDC4 (64964) */ + 4405, /* FDC5 (64965) */ + 4406, /* FDC6 (64966) */ + 4407, /* FDC7 (64967) */ + 1, /* FDC8 (64968) */ + 1, /* FDC9 (64969) */ + 1, /* FDCA (64970) */ + 1, /* FDCB (64971) */ + 1, /* FDCC (64972) */ + 1, /* FDCD (64973) */ + 1, /* FDCE (64974) */ 1, /* FDCF (64975) */ 56, /* FDD0 (64976) */ 56, /* FDD1 (64977) */ @@ -58636,19 +58636,19 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FDED (65005) */ 56, /* FDEE (65006) */ 56, /* FDEF (65007) */ - 4404, /* FDF0 (65008) */ - 4405, /* FDF1 (65009) */ - 4406, /* FDF2 (65010) */ - 4407, /* FDF3 (65011) */ - 4408, /* FDF4 (65012) */ - 4409, /* FDF5 (65013) */ - 4410, /* FDF6 (65014) */ - 4411, /* FDF7 (65015) */ - 4412, /* FDF8 (65016) */ - 4413, /* FDF9 (65017) */ - 4414, /* FDFA (65018) */ - 4415, /* FDFB (65019) */ - 4416, /* FDFC (65020) */ + 4408, /* FDF0 (65008) */ + 4409, /* FDF1 (65009) */ + 4410, /* FDF2 (65010) */ + 4411, /* FDF3 (65011) */ + 4412, /* FDF4 (65012) */ + 4413, /* FDF5 (65013) */ + 4414, /* FDF6 (65014) */ + 4415, /* FDF7 (65015) */ + 4416, /* FDF8 (65016) */ + 4417, /* FDF9 (65017) */ + 4418, /* FDFA (65018) */ + 4419, /* FDFB (65019) */ + 4420, /* FDFC (65020) */ 1, /* FDFD (65021) */ 1, /* FDFE (65022) */ 1, /* FDFF (65023) */ @@ -58668,16 +58668,16 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 60, /* FE0D (65037) */ 60, /* FE0E (65038) */ 60, /* FE0F (65039) */ - 4417, /* FE10 (65040) */ - 4418, /* FE11 (65041) */ - 4419, /* FE12 (65042) */ - 4420, /* FE13 (65043) */ - 4421, /* FE14 (65044) */ - 4422, /* FE15 (65045) */ - 4423, /* FE16 (65046) */ - 4424, /* FE17 (65047) */ - 4425, /* FE18 (65048) */ - 4426, /* FE19 (65049) */ + 4421, /* FE10 (65040) */ + 4422, /* FE11 (65041) */ + 4423, /* FE12 (65042) */ + 4424, /* FE13 (65043) */ + 4425, /* FE14 (65044) */ + 4426, /* FE15 (65045) */ + 4427, /* FE16 (65046) */ + 4428, /* FE17 (65047) */ + 4429, /* FE18 (65048) */ + 4430, /* FE19 (65049) */ 56, /* FE1A (65050) */ 56, /* FE1B (65051) */ 56, /* FE1C (65052) */ @@ -58700,453 +58700,453 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 433, /* FE2D (65069) */ 431, /* FE2E (65070) */ 431, /* FE2F (65071) */ - 4427, /* FE30 (65072) */ - 4428, /* FE31 (65073) */ - 4429, /* FE32 (65074) */ - 4430, /* FE33 (65075) */ - 4430, /* FE34 (65076) */ - 4431, /* FE35 (65077) */ - 4432, /* FE36 (65078) */ - 4433, /* FE37 (65079) */ - 4434, /* FE38 (65080) */ - 4435, /* FE39 (65081) */ - 4436, /* FE3A (65082) */ - 4437, /* FE3B (65083) */ - 4438, /* FE3C (65084) */ - 4439, /* FE3D (65085) */ - 4440, /* FE3E (65086) */ - 4441, /* FE3F (65087) */ - 4442, /* FE40 (65088) */ - 4443, /* FE41 (65089) */ - 4444, /* FE42 (65090) */ - 4445, /* FE43 (65091) */ - 4446, /* FE44 (65092) */ + 4431, /* FE30 (65072) */ + 4432, /* FE31 (65073) */ + 4433, /* FE32 (65074) */ + 4434, /* FE33 (65075) */ + 4434, /* FE34 (65076) */ + 4435, /* FE35 (65077) */ + 4436, /* FE36 (65078) */ + 4437, /* FE37 (65079) */ + 4438, /* FE38 (65080) */ + 4439, /* FE39 (65081) */ + 4440, /* FE3A (65082) */ + 4441, /* FE3B (65083) */ + 4442, /* FE3C (65084) */ + 4443, /* FE3D (65085) */ + 4444, /* FE3E (65086) */ + 4445, /* FE3F (65087) */ + 4446, /* FE40 (65088) */ + 4447, /* FE41 (65089) */ + 4448, /* FE42 (65090) */ + 4449, /* FE43 (65091) */ + 4450, /* FE44 (65092) */ 1, /* FE45 (65093) */ 1, /* FE46 (65094) */ - 4447, /* FE47 (65095) */ - 4448, /* FE48 (65096) */ - 4449, /* FE49 (65097) */ - 4450, /* FE4A (65098) */ - 4451, /* FE4B (65099) */ - 4452, /* FE4C (65100) */ - 4453, /* FE4D (65101) */ - 4453, /* FE4E (65102) */ - 4453, /* FE4F (65103) */ - 4454, /* FE50 (65104) */ - 4455, /* FE51 (65105) */ - 4456, /* FE52 (65106) */ + 4451, /* FE47 (65095) */ + 4452, /* FE48 (65096) */ + 4453, /* FE49 (65097) */ + 4454, /* FE4A (65098) */ + 4455, /* FE4B (65099) */ + 4456, /* FE4C (65100) */ + 4457, /* FE4D (65101) */ + 4457, /* FE4E (65102) */ + 4457, /* FE4F (65103) */ + 4458, /* FE50 (65104) */ + 4459, /* FE51 (65105) */ + 4460, /* FE52 (65106) */ 56, /* FE53 (65107) */ - 4457, /* FE54 (65108) */ - 4458, /* FE55 (65109) */ - 4459, /* FE56 (65110) */ - 4460, /* FE57 (65111) */ - 4461, /* FE58 (65112) */ - 4462, /* FE59 (65113) */ - 4463, /* FE5A (65114) */ - 4464, /* FE5B (65115) */ - 4465, /* FE5C (65116) */ - 4466, /* FE5D (65117) */ - 4467, /* FE5E (65118) */ - 4468, /* FE5F (65119) */ - 4469, /* FE60 (65120) */ - 4470, /* FE61 (65121) */ - 4471, /* FE62 (65122) */ - 4472, /* FE63 (65123) */ - 4473, /* FE64 (65124) */ - 4474, /* FE65 (65125) */ - 4475, /* FE66 (65126) */ + 4461, /* FE54 (65108) */ + 4462, /* FE55 (65109) */ + 4463, /* FE56 (65110) */ + 4464, /* FE57 (65111) */ + 4465, /* FE58 (65112) */ + 4466, /* FE59 (65113) */ + 4467, /* FE5A (65114) */ + 4468, /* FE5B (65115) */ + 4469, /* FE5C (65116) */ + 4470, /* FE5D (65117) */ + 4471, /* FE5E (65118) */ + 4472, /* FE5F (65119) */ + 4473, /* FE60 (65120) */ + 4474, /* FE61 (65121) */ + 4475, /* FE62 (65122) */ + 4476, /* FE63 (65123) */ + 4477, /* FE64 (65124) */ + 4478, /* FE65 (65125) */ + 4479, /* FE66 (65126) */ 56, /* FE67 (65127) */ - 4476, /* FE68 (65128) */ - 4477, /* FE69 (65129) */ - 4478, /* FE6A (65130) */ - 4479, /* FE6B (65131) */ + 4480, /* FE68 (65128) */ + 4481, /* FE69 (65129) */ + 4482, /* FE6A (65130) */ + 4483, /* FE6B (65131) */ 56, /* FE6C (65132) */ 56, /* FE6D (65133) */ 56, /* FE6E (65134) */ 56, /* FE6F (65135) */ - 4480, /* FE70 (65136) */ - 4481, /* FE71 (65137) */ - 4482, /* FE72 (65138) */ + 4484, /* FE70 (65136) */ + 4485, /* FE71 (65137) */ + 4486, /* FE72 (65138) */ 1, /* FE73 (65139) */ - 4483, /* FE74 (65140) */ + 4487, /* FE74 (65140) */ 56, /* FE75 (65141) */ - 4484, /* FE76 (65142) */ - 4485, /* FE77 (65143) */ - 4486, /* FE78 (65144) */ - 4487, /* FE79 (65145) */ - 4488, /* FE7A (65146) */ - 4489, /* FE7B (65147) */ - 4490, /* FE7C (65148) */ - 4491, /* FE7D (65149) */ - 4492, /* FE7E (65150) */ - 4493, /* FE7F (65151) */ - 4494, /* FE80 (65152) */ - 4495, /* FE81 (65153) */ - 4496, /* FE82 (65154) */ - 4497, /* FE83 (65155) */ - 4498, /* FE84 (65156) */ - 4499, /* FE85 (65157) */ - 4500, /* FE86 (65158) */ - 4501, /* FE87 (65159) */ - 4502, /* FE88 (65160) */ - 4503, /* FE89 (65161) */ - 4504, /* FE8A (65162) */ - 4505, /* FE8B (65163) */ - 4506, /* FE8C (65164) */ - 4507, /* FE8D (65165) */ - 4508, /* FE8E (65166) */ - 4509, /* FE8F (65167) */ - 4510, /* FE90 (65168) */ - 4511, /* FE91 (65169) */ - 4512, /* FE92 (65170) */ - 4513, /* FE93 (65171) */ - 4514, /* FE94 (65172) */ - 4515, /* FE95 (65173) */ - 4516, /* FE96 (65174) */ - 4517, /* FE97 (65175) */ - 4518, /* FE98 (65176) */ - 4519, /* FE99 (65177) */ - 4520, /* FE9A (65178) */ - 4521, /* FE9B (65179) */ - 4522, /* FE9C (65180) */ - 4523, /* FE9D (65181) */ - 4524, /* FE9E (65182) */ - 4525, /* FE9F (65183) */ - 4526, /* FEA0 (65184) */ - 4527, /* FEA1 (65185) */ - 4528, /* FEA2 (65186) */ - 4529, /* FEA3 (65187) */ - 4530, /* FEA4 (65188) */ - 4531, /* FEA5 (65189) */ - 4532, /* FEA6 (65190) */ - 4533, /* FEA7 (65191) */ - 4534, /* FEA8 (65192) */ - 4535, /* FEA9 (65193) */ - 4536, /* FEAA (65194) */ - 4537, /* FEAB (65195) */ - 4538, /* FEAC (65196) */ - 4539, /* FEAD (65197) */ - 4540, /* FEAE (65198) */ - 4541, /* FEAF (65199) */ - 4542, /* FEB0 (65200) */ - 4543, /* FEB1 (65201) */ - 4544, /* FEB2 (65202) */ - 4545, /* FEB3 (65203) */ - 4546, /* FEB4 (65204) */ - 4547, /* FEB5 (65205) */ - 4548, /* FEB6 (65206) */ - 4549, /* FEB7 (65207) */ - 4550, /* FEB8 (65208) */ - 4551, /* FEB9 (65209) */ - 4552, /* FEBA (65210) */ - 4553, /* FEBB (65211) */ - 4554, /* FEBC (65212) */ - 4555, /* FEBD (65213) */ - 4556, /* FEBE (65214) */ - 4557, /* FEBF (65215) */ - 4558, /* FEC0 (65216) */ - 4559, /* FEC1 (65217) */ - 4560, /* FEC2 (65218) */ - 4561, /* FEC3 (65219) */ - 4562, /* FEC4 (65220) */ - 4563, /* FEC5 (65221) */ - 4564, /* FEC6 (65222) */ - 4565, /* FEC7 (65223) */ - 4566, /* FEC8 (65224) */ - 4567, /* FEC9 (65225) */ - 4568, /* FECA (65226) */ - 4569, /* FECB (65227) */ - 4570, /* FECC (65228) */ - 4571, /* FECD (65229) */ - 4572, /* FECE (65230) */ - 4573, /* FECF (65231) */ - 4574, /* FED0 (65232) */ - 4575, /* FED1 (65233) */ - 4576, /* FED2 (65234) */ - 4577, /* FED3 (65235) */ - 4578, /* FED4 (65236) */ - 4579, /* FED5 (65237) */ - 4580, /* FED6 (65238) */ - 4581, /* FED7 (65239) */ - 4582, /* FED8 (65240) */ - 4583, /* FED9 (65241) */ - 4584, /* FEDA (65242) */ - 4585, /* FEDB (65243) */ - 4586, /* FEDC (65244) */ - 4587, /* FEDD (65245) */ - 4588, /* FEDE (65246) */ - 4589, /* FEDF (65247) */ - 4590, /* FEE0 (65248) */ - 4591, /* FEE1 (65249) */ - 4592, /* FEE2 (65250) */ - 4593, /* FEE3 (65251) */ - 4594, /* FEE4 (65252) */ - 4595, /* FEE5 (65253) */ - 4596, /* FEE6 (65254) */ - 4597, /* FEE7 (65255) */ - 4598, /* FEE8 (65256) */ - 4599, /* FEE9 (65257) */ - 4600, /* FEEA (65258) */ - 4601, /* FEEB (65259) */ - 4602, /* FEEC (65260) */ - 4603, /* FEED (65261) */ - 4604, /* FEEE (65262) */ - 4605, /* FEEF (65263) */ - 4606, /* FEF0 (65264) */ - 4607, /* FEF1 (65265) */ - 4608, /* FEF2 (65266) */ - 4609, /* FEF3 (65267) */ - 4610, /* FEF4 (65268) */ - 4611, /* FEF5 (65269) */ - 4612, /* FEF6 (65270) */ - 4613, /* FEF7 (65271) */ - 4614, /* FEF8 (65272) */ - 4615, /* FEF9 (65273) */ - 4616, /* FEFA (65274) */ - 4617, /* FEFB (65275) */ - 4618, /* FEFC (65276) */ + 4488, /* FE76 (65142) */ + 4489, /* FE77 (65143) */ + 4490, /* FE78 (65144) */ + 4491, /* FE79 (65145) */ + 4492, /* FE7A (65146) */ + 4493, /* FE7B (65147) */ + 4494, /* FE7C (65148) */ + 4495, /* FE7D (65149) */ + 4496, /* FE7E (65150) */ + 4497, /* FE7F (65151) */ + 4498, /* FE80 (65152) */ + 4499, /* FE81 (65153) */ + 4500, /* FE82 (65154) */ + 4501, /* FE83 (65155) */ + 4502, /* FE84 (65156) */ + 4503, /* FE85 (65157) */ + 4504, /* FE86 (65158) */ + 4505, /* FE87 (65159) */ + 4506, /* FE88 (65160) */ + 4507, /* FE89 (65161) */ + 4508, /* FE8A (65162) */ + 4509, /* FE8B (65163) */ + 4510, /* FE8C (65164) */ + 4511, /* FE8D (65165) */ + 4512, /* FE8E (65166) */ + 4513, /* FE8F (65167) */ + 4514, /* FE90 (65168) */ + 4515, /* FE91 (65169) */ + 4516, /* FE92 (65170) */ + 4517, /* FE93 (65171) */ + 4518, /* FE94 (65172) */ + 4519, /* FE95 (65173) */ + 4520, /* FE96 (65174) */ + 4521, /* FE97 (65175) */ + 4522, /* FE98 (65176) */ + 4523, /* FE99 (65177) */ + 4524, /* FE9A (65178) */ + 4525, /* FE9B (65179) */ + 4526, /* FE9C (65180) */ + 4527, /* FE9D (65181) */ + 4528, /* FE9E (65182) */ + 4529, /* FE9F (65183) */ + 4530, /* FEA0 (65184) */ + 4531, /* FEA1 (65185) */ + 4532, /* FEA2 (65186) */ + 4533, /* FEA3 (65187) */ + 4534, /* FEA4 (65188) */ + 4535, /* FEA5 (65189) */ + 4536, /* FEA6 (65190) */ + 4537, /* FEA7 (65191) */ + 4538, /* FEA8 (65192) */ + 4539, /* FEA9 (65193) */ + 4540, /* FEAA (65194) */ + 4541, /* FEAB (65195) */ + 4542, /* FEAC (65196) */ + 4543, /* FEAD (65197) */ + 4544, /* FEAE (65198) */ + 4545, /* FEAF (65199) */ + 4546, /* FEB0 (65200) */ + 4547, /* FEB1 (65201) */ + 4548, /* FEB2 (65202) */ + 4549, /* FEB3 (65203) */ + 4550, /* FEB4 (65204) */ + 4551, /* FEB5 (65205) */ + 4552, /* FEB6 (65206) */ + 4553, /* FEB7 (65207) */ + 4554, /* FEB8 (65208) */ + 4555, /* FEB9 (65209) */ + 4556, /* FEBA (65210) */ + 4557, /* FEBB (65211) */ + 4558, /* FEBC (65212) */ + 4559, /* FEBD (65213) */ + 4560, /* FEBE (65214) */ + 4561, /* FEBF (65215) */ + 4562, /* FEC0 (65216) */ + 4563, /* FEC1 (65217) */ + 4564, /* FEC2 (65218) */ + 4565, /* FEC3 (65219) */ + 4566, /* FEC4 (65220) */ + 4567, /* FEC5 (65221) */ + 4568, /* FEC6 (65222) */ + 4569, /* FEC7 (65223) */ + 4570, /* FEC8 (65224) */ + 4571, /* FEC9 (65225) */ + 4572, /* FECA (65226) */ + 4573, /* FECB (65227) */ + 4574, /* FECC (65228) */ + 4575, /* FECD (65229) */ + 4576, /* FECE (65230) */ + 4577, /* FECF (65231) */ + 4578, /* FED0 (65232) */ + 4579, /* FED1 (65233) */ + 4580, /* FED2 (65234) */ + 4581, /* FED3 (65235) */ + 4582, /* FED4 (65236) */ + 4583, /* FED5 (65237) */ + 4584, /* FED6 (65238) */ + 4585, /* FED7 (65239) */ + 4586, /* FED8 (65240) */ + 4587, /* FED9 (65241) */ + 4588, /* FEDA (65242) */ + 4589, /* FEDB (65243) */ + 4590, /* FEDC (65244) */ + 4591, /* FEDD (65245) */ + 4592, /* FEDE (65246) */ + 4593, /* FEDF (65247) */ + 4594, /* FEE0 (65248) */ + 4595, /* FEE1 (65249) */ + 4596, /* FEE2 (65250) */ + 4597, /* FEE3 (65251) */ + 4598, /* FEE4 (65252) */ + 4599, /* FEE5 (65253) */ + 4600, /* FEE6 (65254) */ + 4601, /* FEE7 (65255) */ + 4602, /* FEE8 (65256) */ + 4603, /* FEE9 (65257) */ + 4604, /* FEEA (65258) */ + 4605, /* FEEB (65259) */ + 4606, /* FEEC (65260) */ + 4607, /* FEED (65261) */ + 4608, /* FEEE (65262) */ + 4609, /* FEEF (65263) */ + 4610, /* FEF0 (65264) */ + 4611, /* FEF1 (65265) */ + 4612, /* FEF2 (65266) */ + 4613, /* FEF3 (65267) */ + 4614, /* FEF4 (65268) */ + 4615, /* FEF5 (65269) */ + 4616, /* FEF6 (65270) */ + 4617, /* FEF7 (65271) */ + 4618, /* FEF8 (65272) */ + 4619, /* FEF9 (65273) */ + 4620, /* FEFA (65274) */ + 4621, /* FEFB (65275) */ + 4622, /* FEFC (65276) */ 56, /* FEFD (65277) */ 56, /* FEFE (65278) */ 60, /* FEFF (65279) */ 56, /* FF00 (65280) */ - 4619, /* FF01 (65281) */ - 4620, /* FF02 (65282) */ - 4621, /* FF03 (65283) */ - 4622, /* FF04 (65284) */ - 4623, /* FF05 (65285) */ - 4624, /* FF06 (65286) */ - 4625, /* FF07 (65287) */ - 4626, /* FF08 (65288) */ - 4627, /* FF09 (65289) */ - 4628, /* FF0A (65290) */ - 4629, /* FF0B (65291) */ - 4630, /* FF0C (65292) */ - 4631, /* FF0D (65293) */ - 4632, /* FF0E (65294) */ - 4633, /* FF0F (65295) */ - 4634, /* FF10 (65296) */ - 4635, /* FF11 (65297) */ - 4636, /* FF12 (65298) */ - 4637, /* FF13 (65299) */ - 4638, /* FF14 (65300) */ - 4639, /* FF15 (65301) */ - 4640, /* FF16 (65302) */ - 4641, /* FF17 (65303) */ - 4642, /* FF18 (65304) */ - 4643, /* FF19 (65305) */ - 4644, /* FF1A (65306) */ - 4645, /* FF1B (65307) */ - 4646, /* FF1C (65308) */ - 4647, /* FF1D (65309) */ - 4648, /* FF1E (65310) */ - 4649, /* FF1F (65311) */ - 4650, /* FF20 (65312) */ - 4651, /* FF21 (65313) */ - 4652, /* FF22 (65314) */ - 4653, /* FF23 (65315) */ - 4654, /* FF24 (65316) */ - 4655, /* FF25 (65317) */ - 4656, /* FF26 (65318) */ - 4657, /* FF27 (65319) */ - 4658, /* FF28 (65320) */ - 4659, /* FF29 (65321) */ - 4660, /* FF2A (65322) */ - 4661, /* FF2B (65323) */ - 4662, /* FF2C (65324) */ - 4663, /* FF2D (65325) */ - 4664, /* FF2E (65326) */ - 4665, /* FF2F (65327) */ - 4666, /* FF30 (65328) */ - 4667, /* FF31 (65329) */ - 4668, /* FF32 (65330) */ - 4669, /* FF33 (65331) */ - 4670, /* FF34 (65332) */ - 4671, /* FF35 (65333) */ - 4672, /* FF36 (65334) */ - 4673, /* FF37 (65335) */ - 4674, /* FF38 (65336) */ - 4675, /* FF39 (65337) */ - 4676, /* FF3A (65338) */ - 4677, /* FF3B (65339) */ - 4678, /* FF3C (65340) */ - 4679, /* FF3D (65341) */ - 4680, /* FF3E (65342) */ - 4681, /* FF3F (65343) */ - 4682, /* FF40 (65344) */ - 4683, /* FF41 (65345) */ - 4684, /* FF42 (65346) */ - 4685, /* FF43 (65347) */ - 4686, /* FF44 (65348) */ - 4687, /* FF45 (65349) */ - 4688, /* FF46 (65350) */ - 4689, /* FF47 (65351) */ - 4690, /* FF48 (65352) */ - 4691, /* FF49 (65353) */ - 4692, /* FF4A (65354) */ - 4693, /* FF4B (65355) */ - 4694, /* FF4C (65356) */ - 4695, /* FF4D (65357) */ - 4696, /* FF4E (65358) */ - 4697, /* FF4F (65359) */ - 4698, /* FF50 (65360) */ - 4699, /* FF51 (65361) */ - 4700, /* FF52 (65362) */ - 4701, /* FF53 (65363) */ - 4702, /* FF54 (65364) */ - 4703, /* FF55 (65365) */ - 4704, /* FF56 (65366) */ - 4705, /* FF57 (65367) */ - 4706, /* FF58 (65368) */ - 4707, /* FF59 (65369) */ - 4708, /* FF5A (65370) */ - 4709, /* FF5B (65371) */ - 4710, /* FF5C (65372) */ - 4711, /* FF5D (65373) */ - 4712, /* FF5E (65374) */ - 4713, /* FF5F (65375) */ - 4714, /* FF60 (65376) */ - 4715, /* FF61 (65377) */ - 4716, /* FF62 (65378) */ - 4717, /* FF63 (65379) */ - 4718, /* FF64 (65380) */ - 4719, /* FF65 (65381) */ - 4720, /* FF66 (65382) */ - 4721, /* FF67 (65383) */ - 4722, /* FF68 (65384) */ - 4723, /* FF69 (65385) */ - 4724, /* FF6A (65386) */ - 4725, /* FF6B (65387) */ - 4726, /* FF6C (65388) */ - 4727, /* FF6D (65389) */ - 4728, /* FF6E (65390) */ - 4729, /* FF6F (65391) */ - 4730, /* FF70 (65392) */ - 4731, /* FF71 (65393) */ - 4732, /* FF72 (65394) */ - 4733, /* FF73 (65395) */ - 4734, /* FF74 (65396) */ - 4735, /* FF75 (65397) */ - 4736, /* FF76 (65398) */ - 4737, /* FF77 (65399) */ - 4738, /* FF78 (65400) */ - 4739, /* FF79 (65401) */ - 4740, /* FF7A (65402) */ - 4741, /* FF7B (65403) */ - 4742, /* FF7C (65404) */ - 4743, /* FF7D (65405) */ - 4744, /* FF7E (65406) */ - 4745, /* FF7F (65407) */ - 4746, /* FF80 (65408) */ - 4747, /* FF81 (65409) */ - 4748, /* FF82 (65410) */ - 4749, /* FF83 (65411) */ - 4750, /* FF84 (65412) */ - 4751, /* FF85 (65413) */ - 4752, /* FF86 (65414) */ - 4753, /* FF87 (65415) */ - 4754, /* FF88 (65416) */ - 4755, /* FF89 (65417) */ - 4756, /* FF8A (65418) */ - 4757, /* FF8B (65419) */ - 4758, /* FF8C (65420) */ - 4759, /* FF8D (65421) */ - 4760, /* FF8E (65422) */ - 4761, /* FF8F (65423) */ - 4762, /* FF90 (65424) */ - 4763, /* FF91 (65425) */ - 4764, /* FF92 (65426) */ - 4765, /* FF93 (65427) */ - 4766, /* FF94 (65428) */ - 4767, /* FF95 (65429) */ - 4768, /* FF96 (65430) */ - 4769, /* FF97 (65431) */ - 4770, /* FF98 (65432) */ - 4771, /* FF99 (65433) */ - 4772, /* FF9A (65434) */ - 4773, /* FF9B (65435) */ - 4774, /* FF9C (65436) */ - 4775, /* FF9D (65437) */ - 4776, /* FF9E (65438) */ - 4777, /* FF9F (65439) */ - 4778, /* FFA0 (65440) */ - 4779, /* FFA1 (65441) */ - 4780, /* FFA2 (65442) */ - 4781, /* FFA3 (65443) */ - 4782, /* FFA4 (65444) */ - 4783, /* FFA5 (65445) */ - 4784, /* FFA6 (65446) */ - 4785, /* FFA7 (65447) */ - 4786, /* FFA8 (65448) */ - 4787, /* FFA9 (65449) */ - 4788, /* FFAA (65450) */ - 4789, /* FFAB (65451) */ - 4790, /* FFAC (65452) */ - 4791, /* FFAD (65453) */ - 4792, /* FFAE (65454) */ - 4793, /* FFAF (65455) */ - 4794, /* FFB0 (65456) */ - 4795, /* FFB1 (65457) */ - 4796, /* FFB2 (65458) */ - 4797, /* FFB3 (65459) */ - 4798, /* FFB4 (65460) */ - 4799, /* FFB5 (65461) */ - 4800, /* FFB6 (65462) */ - 4801, /* FFB7 (65463) */ - 4802, /* FFB8 (65464) */ - 4803, /* FFB9 (65465) */ - 4804, /* FFBA (65466) */ - 4805, /* FFBB (65467) */ - 4806, /* FFBC (65468) */ - 4807, /* FFBD (65469) */ - 4808, /* FFBE (65470) */ + 4623, /* FF01 (65281) */ + 4624, /* FF02 (65282) */ + 4625, /* FF03 (65283) */ + 4626, /* FF04 (65284) */ + 4627, /* FF05 (65285) */ + 4628, /* FF06 (65286) */ + 4629, /* FF07 (65287) */ + 4630, /* FF08 (65288) */ + 4631, /* FF09 (65289) */ + 4632, /* FF0A (65290) */ + 4633, /* FF0B (65291) */ + 4634, /* FF0C (65292) */ + 4635, /* FF0D (65293) */ + 4636, /* FF0E (65294) */ + 4637, /* FF0F (65295) */ + 4638, /* FF10 (65296) */ + 4639, /* FF11 (65297) */ + 4640, /* FF12 (65298) */ + 4641, /* FF13 (65299) */ + 4642, /* FF14 (65300) */ + 4643, /* FF15 (65301) */ + 4644, /* FF16 (65302) */ + 4645, /* FF17 (65303) */ + 4646, /* FF18 (65304) */ + 4647, /* FF19 (65305) */ + 4648, /* FF1A (65306) */ + 4649, /* FF1B (65307) */ + 4650, /* FF1C (65308) */ + 4651, /* FF1D (65309) */ + 4652, /* FF1E (65310) */ + 4653, /* FF1F (65311) */ + 4654, /* FF20 (65312) */ + 4655, /* FF21 (65313) */ + 4656, /* FF22 (65314) */ + 4657, /* FF23 (65315) */ + 4658, /* FF24 (65316) */ + 4659, /* FF25 (65317) */ + 4660, /* FF26 (65318) */ + 4661, /* FF27 (65319) */ + 4662, /* FF28 (65320) */ + 4663, /* FF29 (65321) */ + 4664, /* FF2A (65322) */ + 4665, /* FF2B (65323) */ + 4666, /* FF2C (65324) */ + 4667, /* FF2D (65325) */ + 4668, /* FF2E (65326) */ + 4669, /* FF2F (65327) */ + 4670, /* FF30 (65328) */ + 4671, /* FF31 (65329) */ + 4672, /* FF32 (65330) */ + 4673, /* FF33 (65331) */ + 4674, /* FF34 (65332) */ + 4675, /* FF35 (65333) */ + 4676, /* FF36 (65334) */ + 4677, /* FF37 (65335) */ + 4678, /* FF38 (65336) */ + 4679, /* FF39 (65337) */ + 4680, /* FF3A (65338) */ + 4681, /* FF3B (65339) */ + 4682, /* FF3C (65340) */ + 4683, /* FF3D (65341) */ + 4684, /* FF3E (65342) */ + 4685, /* FF3F (65343) */ + 4686, /* FF40 (65344) */ + 4687, /* FF41 (65345) */ + 4688, /* FF42 (65346) */ + 4689, /* FF43 (65347) */ + 4690, /* FF44 (65348) */ + 4691, /* FF45 (65349) */ + 4692, /* FF46 (65350) */ + 4693, /* FF47 (65351) */ + 4694, /* FF48 (65352) */ + 4695, /* FF49 (65353) */ + 4696, /* FF4A (65354) */ + 4697, /* FF4B (65355) */ + 4698, /* FF4C (65356) */ + 4699, /* FF4D (65357) */ + 4700, /* FF4E (65358) */ + 4701, /* FF4F (65359) */ + 4702, /* FF50 (65360) */ + 4703, /* FF51 (65361) */ + 4704, /* FF52 (65362) */ + 4705, /* FF53 (65363) */ + 4706, /* FF54 (65364) */ + 4707, /* FF55 (65365) */ + 4708, /* FF56 (65366) */ + 4709, /* FF57 (65367) */ + 4710, /* FF58 (65368) */ + 4711, /* FF59 (65369) */ + 4712, /* FF5A (65370) */ + 4713, /* FF5B (65371) */ + 4714, /* FF5C (65372) */ + 4715, /* FF5D (65373) */ + 4716, /* FF5E (65374) */ + 4717, /* FF5F (65375) */ + 4718, /* FF60 (65376) */ + 4719, /* FF61 (65377) */ + 4720, /* FF62 (65378) */ + 4721, /* FF63 (65379) */ + 4722, /* FF64 (65380) */ + 4723, /* FF65 (65381) */ + 4724, /* FF66 (65382) */ + 4725, /* FF67 (65383) */ + 4726, /* FF68 (65384) */ + 4727, /* FF69 (65385) */ + 4728, /* FF6A (65386) */ + 4729, /* FF6B (65387) */ + 4730, /* FF6C (65388) */ + 4731, /* FF6D (65389) */ + 4732, /* FF6E (65390) */ + 4733, /* FF6F (65391) */ + 4734, /* FF70 (65392) */ + 4735, /* FF71 (65393) */ + 4736, /* FF72 (65394) */ + 4737, /* FF73 (65395) */ + 4738, /* FF74 (65396) */ + 4739, /* FF75 (65397) */ + 4740, /* FF76 (65398) */ + 4741, /* FF77 (65399) */ + 4742, /* FF78 (65400) */ + 4743, /* FF79 (65401) */ + 4744, /* FF7A (65402) */ + 4745, /* FF7B (65403) */ + 4746, /* FF7C (65404) */ + 4747, /* FF7D (65405) */ + 4748, /* FF7E (65406) */ + 4749, /* FF7F (65407) */ + 4750, /* FF80 (65408) */ + 4751, /* FF81 (65409) */ + 4752, /* FF82 (65410) */ + 4753, /* FF83 (65411) */ + 4754, /* FF84 (65412) */ + 4755, /* FF85 (65413) */ + 4756, /* FF86 (65414) */ + 4757, /* FF87 (65415) */ + 4758, /* FF88 (65416) */ + 4759, /* FF89 (65417) */ + 4760, /* FF8A (65418) */ + 4761, /* FF8B (65419) */ + 4762, /* FF8C (65420) */ + 4763, /* FF8D (65421) */ + 4764, /* FF8E (65422) */ + 4765, /* FF8F (65423) */ + 4766, /* FF90 (65424) */ + 4767, /* FF91 (65425) */ + 4768, /* FF92 (65426) */ + 4769, /* FF93 (65427) */ + 4770, /* FF94 (65428) */ + 4771, /* FF95 (65429) */ + 4772, /* FF96 (65430) */ + 4773, /* FF97 (65431) */ + 4774, /* FF98 (65432) */ + 4775, /* FF99 (65433) */ + 4776, /* FF9A (65434) */ + 4777, /* FF9B (65435) */ + 4778, /* FF9C (65436) */ + 4779, /* FF9D (65437) */ + 4780, /* FF9E (65438) */ + 4781, /* FF9F (65439) */ + 4782, /* FFA0 (65440) */ + 4783, /* FFA1 (65441) */ + 4784, /* FFA2 (65442) */ + 4785, /* FFA3 (65443) */ + 4786, /* FFA4 (65444) */ + 4787, /* FFA5 (65445) */ + 4788, /* FFA6 (65446) */ + 4789, /* FFA7 (65447) */ + 4790, /* FFA8 (65448) */ + 4791, /* FFA9 (65449) */ + 4792, /* FFAA (65450) */ + 4793, /* FFAB (65451) */ + 4794, /* FFAC (65452) */ + 4795, /* FFAD (65453) */ + 4796, /* FFAE (65454) */ + 4797, /* FFAF (65455) */ + 4798, /* FFB0 (65456) */ + 4799, /* FFB1 (65457) */ + 4800, /* FFB2 (65458) */ + 4801, /* FFB3 (65459) */ + 4802, /* FFB4 (65460) */ + 4803, /* FFB5 (65461) */ + 4804, /* FFB6 (65462) */ + 4805, /* FFB7 (65463) */ + 4806, /* FFB8 (65464) */ + 4807, /* FFB9 (65465) */ + 4808, /* FFBA (65466) */ + 4809, /* FFBB (65467) */ + 4810, /* FFBC (65468) */ + 4811, /* FFBD (65469) */ + 4812, /* FFBE (65470) */ 56, /* FFBF (65471) */ 56, /* FFC0 (65472) */ 56, /* FFC1 (65473) */ - 4809, /* FFC2 (65474) */ - 4810, /* FFC3 (65475) */ - 4811, /* FFC4 (65476) */ - 4812, /* FFC5 (65477) */ - 4813, /* FFC6 (65478) */ - 4814, /* FFC7 (65479) */ + 4813, /* FFC2 (65474) */ + 4814, /* FFC3 (65475) */ + 4815, /* FFC4 (65476) */ + 4816, /* FFC5 (65477) */ + 4817, /* FFC6 (65478) */ + 4818, /* FFC7 (65479) */ 56, /* FFC8 (65480) */ 56, /* FFC9 (65481) */ - 4815, /* FFCA (65482) */ - 4816, /* FFCB (65483) */ - 4817, /* FFCC (65484) */ - 4818, /* FFCD (65485) */ - 4819, /* FFCE (65486) */ - 4820, /* FFCF (65487) */ + 4819, /* FFCA (65482) */ + 4820, /* FFCB (65483) */ + 4821, /* FFCC (65484) */ + 4822, /* FFCD (65485) */ + 4823, /* FFCE (65486) */ + 4824, /* FFCF (65487) */ 56, /* FFD0 (65488) */ 56, /* FFD1 (65489) */ - 4821, /* FFD2 (65490) */ - 4822, /* FFD3 (65491) */ - 4823, /* FFD4 (65492) */ - 4824, /* FFD5 (65493) */ - 4825, /* FFD6 (65494) */ - 4826, /* FFD7 (65495) */ + 4825, /* FFD2 (65490) */ + 4826, /* FFD3 (65491) */ + 4827, /* FFD4 (65492) */ + 4828, /* FFD5 (65493) */ + 4829, /* FFD6 (65494) */ + 4830, /* FFD7 (65495) */ 56, /* FFD8 (65496) */ 56, /* FFD9 (65497) */ - 4827, /* FFDA (65498) */ - 4828, /* FFDB (65499) */ - 4829, /* FFDC (65500) */ + 4831, /* FFDA (65498) */ + 4832, /* FFDB (65499) */ + 4833, /* FFDC (65500) */ 56, /* FFDD (65501) */ 56, /* FFDE (65502) */ 56, /* FFDF (65503) */ - 4830, /* FFE0 (65504) */ - 4831, /* FFE1 (65505) */ - 4832, /* FFE2 (65506) */ - 4833, /* FFE3 (65507) */ - 4834, /* FFE4 (65508) */ - 4835, /* FFE5 (65509) */ - 4836, /* FFE6 (65510) */ + 4834, /* FFE0 (65504) */ + 4835, /* FFE1 (65505) */ + 4836, /* FFE2 (65506) */ + 4837, /* FFE3 (65507) */ + 4838, /* FFE4 (65508) */ + 4839, /* FFE5 (65509) */ + 4840, /* FFE6 (65510) */ 56, /* FFE7 (65511) */ - 4837, /* FFE8 (65512) */ - 4838, /* FFE9 (65513) */ - 4839, /* FFEA (65514) */ - 4840, /* FFEB (65515) */ - 4841, /* FFEC (65516) */ - 4842, /* FFED (65517) */ - 4843, /* FFEE (65518) */ + 4841, /* FFE8 (65512) */ + 4842, /* FFE9 (65513) */ + 4843, /* FFEA (65514) */ + 4844, /* FFEB (65515) */ + 4845, /* FFEC (65516) */ + 4846, /* FFED (65517) */ + 4847, /* FFEE (65518) */ 56, /* FFEF (65519) */ 56, /* FFF0 (65520) */ 56, /* FFF1 (65521) */ @@ -60188,46 +60188,46 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 103FD (66557) */ 56, /* 103FE (66558) */ 56, /* 103FF (66559) */ - 4844, /* 10400 (66560) */ - 4845, /* 10401 (66561) */ - 4846, /* 10402 (66562) */ - 4847, /* 10403 (66563) */ - 4848, /* 10404 (66564) */ - 4849, /* 10405 (66565) */ - 4850, /* 10406 (66566) */ - 4851, /* 10407 (66567) */ - 4852, /* 10408 (66568) */ - 4853, /* 10409 (66569) */ - 4854, /* 1040A (66570) */ - 4855, /* 1040B (66571) */ - 4856, /* 1040C (66572) */ - 4857, /* 1040D (66573) */ - 4858, /* 1040E (66574) */ - 4859, /* 1040F (66575) */ - 4860, /* 10410 (66576) */ - 4861, /* 10411 (66577) */ - 4862, /* 10412 (66578) */ - 4863, /* 10413 (66579) */ - 4864, /* 10414 (66580) */ - 4865, /* 10415 (66581) */ - 4866, /* 10416 (66582) */ - 4867, /* 10417 (66583) */ - 4868, /* 10418 (66584) */ - 4869, /* 10419 (66585) */ - 4870, /* 1041A (66586) */ - 4871, /* 1041B (66587) */ - 4872, /* 1041C (66588) */ - 4873, /* 1041D (66589) */ - 4874, /* 1041E (66590) */ - 4875, /* 1041F (66591) */ - 4876, /* 10420 (66592) */ - 4877, /* 10421 (66593) */ - 4878, /* 10422 (66594) */ - 4879, /* 10423 (66595) */ - 4880, /* 10424 (66596) */ - 4881, /* 10425 (66597) */ - 4882, /* 10426 (66598) */ - 4883, /* 10427 (66599) */ + 4848, /* 10400 (66560) */ + 4849, /* 10401 (66561) */ + 4850, /* 10402 (66562) */ + 4851, /* 10403 (66563) */ + 4852, /* 10404 (66564) */ + 4853, /* 10405 (66565) */ + 4854, /* 10406 (66566) */ + 4855, /* 10407 (66567) */ + 4856, /* 10408 (66568) */ + 4857, /* 10409 (66569) */ + 4858, /* 1040A (66570) */ + 4859, /* 1040B (66571) */ + 4860, /* 1040C (66572) */ + 4861, /* 1040D (66573) */ + 4862, /* 1040E (66574) */ + 4863, /* 1040F (66575) */ + 4864, /* 10410 (66576) */ + 4865, /* 10411 (66577) */ + 4866, /* 10412 (66578) */ + 4867, /* 10413 (66579) */ + 4868, /* 10414 (66580) */ + 4869, /* 10415 (66581) */ + 4870, /* 10416 (66582) */ + 4871, /* 10417 (66583) */ + 4872, /* 10418 (66584) */ + 4873, /* 10419 (66585) */ + 4874, /* 1041A (66586) */ + 4875, /* 1041B (66587) */ + 4876, /* 1041C (66588) */ + 4877, /* 1041D (66589) */ + 4878, /* 1041E (66590) */ + 4879, /* 1041F (66591) */ + 4880, /* 10420 (66592) */ + 4881, /* 10421 (66593) */ + 4882, /* 10422 (66594) */ + 4883, /* 10423 (66595) */ + 4884, /* 10424 (66596) */ + 4885, /* 10425 (66597) */ + 4886, /* 10426 (66598) */ + 4887, /* 10427 (66599) */ 1, /* 10428 (66600) */ 1, /* 10429 (66601) */ 1, /* 1042A (66602) */ @@ -60364,42 +60364,42 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 104AD (66733) */ 56, /* 104AE (66734) */ 56, /* 104AF (66735) */ - 4884, /* 104B0 (66736) */ - 4885, /* 104B1 (66737) */ - 4886, /* 104B2 (66738) */ - 4887, /* 104B3 (66739) */ - 4888, /* 104B4 (66740) */ - 4889, /* 104B5 (66741) */ - 4890, /* 104B6 (66742) */ - 4891, /* 104B7 (66743) */ - 4892, /* 104B8 (66744) */ - 4893, /* 104B9 (66745) */ - 4894, /* 104BA (66746) */ - 4895, /* 104BB (66747) */ - 4896, /* 104BC (66748) */ - 4897, /* 104BD (66749) */ - 4898, /* 104BE (66750) */ - 4899, /* 104BF (66751) */ - 4900, /* 104C0 (66752) */ - 4901, /* 104C1 (66753) */ - 4902, /* 104C2 (66754) */ - 4903, /* 104C3 (66755) */ - 4904, /* 104C4 (66756) */ - 4905, /* 104C5 (66757) */ - 4906, /* 104C6 (66758) */ - 4907, /* 104C7 (66759) */ - 4908, /* 104C8 (66760) */ - 4909, /* 104C9 (66761) */ - 4910, /* 104CA (66762) */ - 4911, /* 104CB (66763) */ - 4912, /* 104CC (66764) */ - 4913, /* 104CD (66765) */ - 4914, /* 104CE (66766) */ - 4915, /* 104CF (66767) */ - 4916, /* 104D0 (66768) */ - 4917, /* 104D1 (66769) */ - 4918, /* 104D2 (66770) */ - 4919, /* 104D3 (66771) */ + 4888, /* 104B0 (66736) */ + 4889, /* 104B1 (66737) */ + 4890, /* 104B2 (66738) */ + 4891, /* 104B3 (66739) */ + 4892, /* 104B4 (66740) */ + 4893, /* 104B5 (66741) */ + 4894, /* 104B6 (66742) */ + 4895, /* 104B7 (66743) */ + 4896, /* 104B8 (66744) */ + 4897, /* 104B9 (66745) */ + 4898, /* 104BA (66746) */ + 4899, /* 104BB (66747) */ + 4900, /* 104BC (66748) */ + 4901, /* 104BD (66749) */ + 4902, /* 104BE (66750) */ + 4903, /* 104BF (66751) */ + 4904, /* 104C0 (66752) */ + 4905, /* 104C1 (66753) */ + 4906, /* 104C2 (66754) */ + 4907, /* 104C3 (66755) */ + 4908, /* 104C4 (66756) */ + 4909, /* 104C5 (66757) */ + 4910, /* 104C6 (66758) */ + 4911, /* 104C7 (66759) */ + 4912, /* 104C8 (66760) */ + 4913, /* 104C9 (66761) */ + 4914, /* 104CA (66762) */ + 4915, /* 104CB (66763) */ + 4916, /* 104CC (66764) */ + 4917, /* 104CD (66765) */ + 4918, /* 104CE (66766) */ + 4919, /* 104CF (66767) */ + 4920, /* 104D0 (66768) */ + 4921, /* 104D1 (66769) */ + 4922, /* 104D2 (66770) */ + 4923, /* 104D3 (66771) */ 56, /* 104D4 (66772) */ 56, /* 104D5 (66773) */ 56, /* 104D6 (66774) */ @@ -60556,44 +60556,44 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1056D (66925) */ 56, /* 1056E (66926) */ 1, /* 1056F (66927) */ - 4920, /* 10570 (66928) */ - 4921, /* 10571 (66929) */ - 4922, /* 10572 (66930) */ - 4923, /* 10573 (66931) */ - 4924, /* 10574 (66932) */ - 4925, /* 10575 (66933) */ - 4926, /* 10576 (66934) */ - 4927, /* 10577 (66935) */ - 4928, /* 10578 (66936) */ - 4929, /* 10579 (66937) */ - 4930, /* 1057A (66938) */ + 4924, /* 10570 (66928) */ + 4925, /* 10571 (66929) */ + 4926, /* 10572 (66930) */ + 4927, /* 10573 (66931) */ + 4928, /* 10574 (66932) */ + 4929, /* 10575 (66933) */ + 4930, /* 10576 (66934) */ + 4931, /* 10577 (66935) */ + 4932, /* 10578 (66936) */ + 4933, /* 10579 (66937) */ + 4934, /* 1057A (66938) */ 56, /* 1057B (66939) */ - 4931, /* 1057C (66940) */ - 4932, /* 1057D (66941) */ - 4933, /* 1057E (66942) */ - 4934, /* 1057F (66943) */ - 4935, /* 10580 (66944) */ - 4936, /* 10581 (66945) */ - 4937, /* 10582 (66946) */ - 4938, /* 10583 (66947) */ - 4939, /* 10584 (66948) */ - 4940, /* 10585 (66949) */ - 4941, /* 10586 (66950) */ - 4942, /* 10587 (66951) */ - 4943, /* 10588 (66952) */ - 4944, /* 10589 (66953) */ - 4945, /* 1058A (66954) */ + 4935, /* 1057C (66940) */ + 4936, /* 1057D (66941) */ + 4937, /* 1057E (66942) */ + 4938, /* 1057F (66943) */ + 4939, /* 10580 (66944) */ + 4940, /* 10581 (66945) */ + 4941, /* 10582 (66946) */ + 4942, /* 10583 (66947) */ + 4943, /* 10584 (66948) */ + 4944, /* 10585 (66949) */ + 4945, /* 10586 (66950) */ + 4946, /* 10587 (66951) */ + 4947, /* 10588 (66952) */ + 4948, /* 10589 (66953) */ + 4949, /* 1058A (66954) */ 56, /* 1058B (66955) */ - 4946, /* 1058C (66956) */ - 4947, /* 1058D (66957) */ - 4948, /* 1058E (66958) */ - 4949, /* 1058F (66959) */ - 4950, /* 10590 (66960) */ - 4951, /* 10591 (66961) */ - 4952, /* 10592 (66962) */ + 4950, /* 1058C (66956) */ + 4951, /* 1058D (66957) */ + 4952, /* 1058E (66958) */ + 4953, /* 1058F (66959) */ + 4954, /* 10590 (66960) */ + 4955, /* 10591 (66961) */ + 4956, /* 10592 (66962) */ 56, /* 10593 (66963) */ - 4953, /* 10594 (66964) */ - 4954, /* 10595 (66965) */ + 4957, /* 10594 (66964) */ + 4958, /* 10595 (66965) */ 56, /* 10596 (66966) */ 1, /* 10597 (66967) */ 1, /* 10598 (66968) */ @@ -60645,7 +60645,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105C6 (67014) */ 1, /* 105C7 (67015) */ 1, /* 105C8 (67016) */ - 4955, /* 105C9 (67017) */ + 4959, /* 105C9 (67017) */ 1, /* 105CA (67018) */ 1, /* 105CB (67019) */ 1, /* 105CC (67020) */ @@ -60654,7 +60654,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105CF (67023) */ 1, /* 105D0 (67024) */ 1, /* 105D1 (67025) */ - 4956, /* 105D2 (67026) */ + 4960, /* 105D2 (67026) */ 1, /* 105D3 (67027) */ 1, /* 105D4 (67028) */ 1, /* 105D5 (67029) */ @@ -60662,7 +60662,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105D7 (67031) */ 1, /* 105D8 (67032) */ 1, /* 105D9 (67033) */ - 4957, /* 105DA (67034) */ + 4961, /* 105DA (67034) */ 1, /* 105DB (67035) */ 1, /* 105DC (67036) */ 1, /* 105DD (67037) */ @@ -60672,7 +60672,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105E1 (67041) */ 1, /* 105E2 (67042) */ 1, /* 105E3 (67043) */ - 4958, /* 105E4 (67044) */ + 4962, /* 105E4 (67044) */ 1, /* 105E5 (67045) */ 1, /* 105E6 (67046) */ 1, /* 105E7 (67047) */ @@ -61085,64 +61085,64 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1077E (67454) */ 56, /* 1077F (67455) */ 1, /* 10780 (67456) */ - 4959, /* 10781 (67457) */ - 4960, /* 10782 (67458) */ - 4961, /* 10783 (67459) */ - 4962, /* 10784 (67460) */ - 4963, /* 10785 (67461) */ + 4963, /* 10781 (67457) */ + 4964, /* 10782 (67458) */ + 4965, /* 10783 (67459) */ + 4966, /* 10784 (67460) */ + 4967, /* 10785 (67461) */ 56, /* 10786 (67462) */ - 4964, /* 10787 (67463) */ - 4965, /* 10788 (67464) */ - 4966, /* 10789 (67465) */ - 4967, /* 1078A (67466) */ - 4968, /* 1078B (67467) */ - 4969, /* 1078C (67468) */ - 4970, /* 1078D (67469) */ - 4971, /* 1078E (67470) */ - 4972, /* 1078F (67471) */ - 4973, /* 10790 (67472) */ - 4974, /* 10791 (67473) */ - 4975, /* 10792 (67474) */ - 4976, /* 10793 (67475) */ - 4977, /* 10794 (67476) */ - 4978, /* 10795 (67477) */ - 4979, /* 10796 (67478) */ - 4980, /* 10797 (67479) */ - 4981, /* 10798 (67480) */ - 4982, /* 10799 (67481) */ - 4983, /* 1079A (67482) */ - 4984, /* 1079B (67483) */ - 4985, /* 1079C (67484) */ - 4986, /* 1079D (67485) */ - 4987, /* 1079E (67486) */ - 4988, /* 1079F (67487) */ - 4989, /* 107A0 (67488) */ - 4990, /* 107A1 (67489) */ - 4991, /* 107A2 (67490) */ - 4992, /* 107A3 (67491) */ - 4993, /* 107A4 (67492) */ - 4994, /* 107A5 (67493) */ - 4995, /* 107A6 (67494) */ - 4996, /* 107A7 (67495) */ - 4997, /* 107A8 (67496) */ - 4998, /* 107A9 (67497) */ - 4999, /* 107AA (67498) */ - 5000, /* 107AB (67499) */ - 5001, /* 107AC (67500) */ - 5002, /* 107AD (67501) */ - 5003, /* 107AE (67502) */ - 5004, /* 107AF (67503) */ - 5005, /* 107B0 (67504) */ + 4968, /* 10787 (67463) */ + 4969, /* 10788 (67464) */ + 4970, /* 10789 (67465) */ + 4971, /* 1078A (67466) */ + 4972, /* 1078B (67467) */ + 4973, /* 1078C (67468) */ + 4974, /* 1078D (67469) */ + 4975, /* 1078E (67470) */ + 4976, /* 1078F (67471) */ + 4977, /* 10790 (67472) */ + 4978, /* 10791 (67473) */ + 4979, /* 10792 (67474) */ + 4980, /* 10793 (67475) */ + 4981, /* 10794 (67476) */ + 4982, /* 10795 (67477) */ + 4983, /* 10796 (67478) */ + 4984, /* 10797 (67479) */ + 4985, /* 10798 (67480) */ + 4986, /* 10799 (67481) */ + 4987, /* 1079A (67482) */ + 4988, /* 1079B (67483) */ + 4989, /* 1079C (67484) */ + 4990, /* 1079D (67485) */ + 4991, /* 1079E (67486) */ + 4992, /* 1079F (67487) */ + 4993, /* 107A0 (67488) */ + 4994, /* 107A1 (67489) */ + 4995, /* 107A2 (67490) */ + 4996, /* 107A3 (67491) */ + 4997, /* 107A4 (67492) */ + 4998, /* 107A5 (67493) */ + 4999, /* 107A6 (67494) */ + 5000, /* 107A7 (67495) */ + 5001, /* 107A8 (67496) */ + 5002, /* 107A9 (67497) */ + 5003, /* 107AA (67498) */ + 5004, /* 107AB (67499) */ + 5005, /* 107AC (67500) */ + 5006, /* 107AD (67501) */ + 5007, /* 107AE (67502) */ + 5008, /* 107AF (67503) */ + 5009, /* 107B0 (67504) */ 56, /* 107B1 (67505) */ - 5006, /* 107B2 (67506) */ - 5007, /* 107B3 (67507) */ - 5008, /* 107B4 (67508) */ - 5009, /* 107B5 (67509) */ - 5010, /* 107B6 (67510) */ - 5011, /* 107B7 (67511) */ - 5012, /* 107B8 (67512) */ - 5013, /* 107B9 (67513) */ - 5014, /* 107BA (67514) */ + 5010, /* 107B2 (67506) */ + 5011, /* 107B3 (67507) */ + 5012, /* 107B4 (67508) */ + 5013, /* 107B5 (67509) */ + 5014, /* 107B6 (67510) */ + 5015, /* 107B7 (67511) */ + 5016, /* 107B8 (67512) */ + 5017, /* 107B9 (67513) */ + 5018, /* 107BA (67514) */ 56, /* 107BB (67515) */ 56, /* 107BC (67516) */ 56, /* 107BD (67517) */ @@ -61532,32 +61532,32 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1093D (67901) */ 56, /* 1093E (67902) */ 1, /* 1093F (67903) */ - 56, /* 10940 (67904) */ - 56, /* 10941 (67905) */ - 56, /* 10942 (67906) */ - 56, /* 10943 (67907) */ - 56, /* 10944 (67908) */ - 56, /* 10945 (67909) */ - 56, /* 10946 (67910) */ - 56, /* 10947 (67911) */ - 56, /* 10948 (67912) */ - 56, /* 10949 (67913) */ - 56, /* 1094A (67914) */ - 56, /* 1094B (67915) */ - 56, /* 1094C (67916) */ - 56, /* 1094D (67917) */ - 56, /* 1094E (67918) */ - 56, /* 1094F (67919) */ - 56, /* 10950 (67920) */ - 56, /* 10951 (67921) */ - 56, /* 10952 (67922) */ - 56, /* 10953 (67923) */ - 56, /* 10954 (67924) */ - 56, /* 10955 (67925) */ - 56, /* 10956 (67926) */ - 56, /* 10957 (67927) */ - 56, /* 10958 (67928) */ - 56, /* 10959 (67929) */ + 1, /* 10940 (67904) */ + 1, /* 10941 (67905) */ + 1, /* 10942 (67906) */ + 1, /* 10943 (67907) */ + 1, /* 10944 (67908) */ + 1, /* 10945 (67909) */ + 1, /* 10946 (67910) */ + 1, /* 10947 (67911) */ + 1, /* 10948 (67912) */ + 1, /* 10949 (67913) */ + 1, /* 1094A (67914) */ + 1, /* 1094B (67915) */ + 1, /* 1094C (67916) */ + 1, /* 1094D (67917) */ + 1, /* 1094E (67918) */ + 1, /* 1094F (67919) */ + 1, /* 10950 (67920) */ + 1, /* 10951 (67921) */ + 1, /* 10952 (67922) */ + 1, /* 10953 (67923) */ + 1, /* 10954 (67924) */ + 1, /* 10955 (67925) */ + 1, /* 10956 (67926) */ + 1, /* 10957 (67927) */ + 1, /* 10958 (67928) */ + 1, /* 10959 (67929) */ 56, /* 1095A (67930) */ 56, /* 1095B (67931) */ 56, /* 1095C (67932) */ @@ -62364,57 +62364,57 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10C7D (68733) */ 56, /* 10C7E (68734) */ 56, /* 10C7F (68735) */ - 5015, /* 10C80 (68736) */ - 5016, /* 10C81 (68737) */ - 5017, /* 10C82 (68738) */ - 5018, /* 10C83 (68739) */ - 5019, /* 10C84 (68740) */ - 5020, /* 10C85 (68741) */ - 5021, /* 10C86 (68742) */ - 5022, /* 10C87 (68743) */ - 5023, /* 10C88 (68744) */ - 5024, /* 10C89 (68745) */ - 5025, /* 10C8A (68746) */ - 5026, /* 10C8B (68747) */ - 5027, /* 10C8C (68748) */ - 5028, /* 10C8D (68749) */ - 5029, /* 10C8E (68750) */ - 5030, /* 10C8F (68751) */ - 5031, /* 10C90 (68752) */ - 5032, /* 10C91 (68753) */ - 5033, /* 10C92 (68754) */ - 5034, /* 10C93 (68755) */ - 5035, /* 10C94 (68756) */ - 5036, /* 10C95 (68757) */ - 5037, /* 10C96 (68758) */ - 5038, /* 10C97 (68759) */ - 5039, /* 10C98 (68760) */ - 5040, /* 10C99 (68761) */ - 5041, /* 10C9A (68762) */ - 5042, /* 10C9B (68763) */ - 5043, /* 10C9C (68764) */ - 5044, /* 10C9D (68765) */ - 5045, /* 10C9E (68766) */ - 5046, /* 10C9F (68767) */ - 5047, /* 10CA0 (68768) */ - 5048, /* 10CA1 (68769) */ - 5049, /* 10CA2 (68770) */ - 5050, /* 10CA3 (68771) */ - 5051, /* 10CA4 (68772) */ - 5052, /* 10CA5 (68773) */ - 5053, /* 10CA6 (68774) */ - 5054, /* 10CA7 (68775) */ - 5055, /* 10CA8 (68776) */ - 5056, /* 10CA9 (68777) */ - 5057, /* 10CAA (68778) */ - 5058, /* 10CAB (68779) */ - 5059, /* 10CAC (68780) */ - 5060, /* 10CAD (68781) */ - 5061, /* 10CAE (68782) */ - 5062, /* 10CAF (68783) */ - 5063, /* 10CB0 (68784) */ - 5064, /* 10CB1 (68785) */ - 5065, /* 10CB2 (68786) */ + 5019, /* 10C80 (68736) */ + 5020, /* 10C81 (68737) */ + 5021, /* 10C82 (68738) */ + 5022, /* 10C83 (68739) */ + 5023, /* 10C84 (68740) */ + 5024, /* 10C85 (68741) */ + 5025, /* 10C86 (68742) */ + 5026, /* 10C87 (68743) */ + 5027, /* 10C88 (68744) */ + 5028, /* 10C89 (68745) */ + 5029, /* 10C8A (68746) */ + 5030, /* 10C8B (68747) */ + 5031, /* 10C8C (68748) */ + 5032, /* 10C8D (68749) */ + 5033, /* 10C8E (68750) */ + 5034, /* 10C8F (68751) */ + 5035, /* 10C90 (68752) */ + 5036, /* 10C91 (68753) */ + 5037, /* 10C92 (68754) */ + 5038, /* 10C93 (68755) */ + 5039, /* 10C94 (68756) */ + 5040, /* 10C95 (68757) */ + 5041, /* 10C96 (68758) */ + 5042, /* 10C97 (68759) */ + 5043, /* 10C98 (68760) */ + 5044, /* 10C99 (68761) */ + 5045, /* 10C9A (68762) */ + 5046, /* 10C9B (68763) */ + 5047, /* 10C9C (68764) */ + 5048, /* 10C9D (68765) */ + 5049, /* 10C9E (68766) */ + 5050, /* 10C9F (68767) */ + 5051, /* 10CA0 (68768) */ + 5052, /* 10CA1 (68769) */ + 5053, /* 10CA2 (68770) */ + 5054, /* 10CA3 (68771) */ + 5055, /* 10CA4 (68772) */ + 5056, /* 10CA5 (68773) */ + 5057, /* 10CA6 (68774) */ + 5058, /* 10CA7 (68775) */ + 5059, /* 10CA8 (68776) */ + 5060, /* 10CA9 (68777) */ + 5061, /* 10CAA (68778) */ + 5062, /* 10CAB (68779) */ + 5063, /* 10CAC (68780) */ + 5064, /* 10CAD (68781) */ + 5065, /* 10CAE (68782) */ + 5066, /* 10CAF (68783) */ + 5067, /* 10CB0 (68784) */ + 5068, /* 10CB1 (68785) */ + 5069, /* 10CB2 (68786) */ 56, /* 10CB3 (68787) */ 56, /* 10CB4 (68788) */ 56, /* 10CB5 (68789) */ @@ -62572,28 +62572,28 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 10D4D (68941) */ 1, /* 10D4E (68942) */ 1, /* 10D4F (68943) */ - 5066, /* 10D50 (68944) */ - 5067, /* 10D51 (68945) */ - 5068, /* 10D52 (68946) */ - 5069, /* 10D53 (68947) */ - 5070, /* 10D54 (68948) */ - 5071, /* 10D55 (68949) */ - 5072, /* 10D56 (68950) */ - 5073, /* 10D57 (68951) */ - 5074, /* 10D58 (68952) */ - 5075, /* 10D59 (68953) */ - 5076, /* 10D5A (68954) */ - 5077, /* 10D5B (68955) */ - 5078, /* 10D5C (68956) */ - 5079, /* 10D5D (68957) */ - 5080, /* 10D5E (68958) */ - 5081, /* 10D5F (68959) */ - 5082, /* 10D60 (68960) */ - 5083, /* 10D61 (68961) */ - 5084, /* 10D62 (68962) */ - 5085, /* 10D63 (68963) */ - 5086, /* 10D64 (68964) */ - 5087, /* 10D65 (68965) */ + 5070, /* 10D50 (68944) */ + 5071, /* 10D51 (68945) */ + 5072, /* 10D52 (68946) */ + 5073, /* 10D53 (68947) */ + 5074, /* 10D54 (68948) */ + 5075, /* 10D55 (68949) */ + 5076, /* 10D56 (68950) */ + 5077, /* 10D57 (68951) */ + 5078, /* 10D58 (68952) */ + 5079, /* 10D59 (68953) */ + 5080, /* 10D5A (68954) */ + 5081, /* 10D5B (68955) */ + 5082, /* 10D5C (68956) */ + 5083, /* 10D5D (68957) */ + 5084, /* 10D5E (68958) */ + 5085, /* 10D5F (68959) */ + 5086, /* 10D60 (68960) */ + 5087, /* 10D61 (68961) */ + 5088, /* 10D62 (68962) */ + 5089, /* 10D63 (68963) */ + 5090, /* 10D64 (68964) */ + 5091, /* 10D65 (68965) */ 56, /* 10D66 (68966) */ 56, /* 10D67 (68967) */ 56, /* 10D68 (68968) */ @@ -62945,9 +62945,9 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 10EC2 (69314) */ 1, /* 10EC3 (69315) */ 1, /* 10EC4 (69316) */ - 56, /* 10EC5 (69317) */ - 56, /* 10EC6 (69318) */ - 56, /* 10EC7 (69319) */ + 1, /* 10EC5 (69317) */ + 1, /* 10EC6 (69318) */ + 1, /* 10EC7 (69319) */ 56, /* 10EC8 (69320) */ 56, /* 10EC9 (69321) */ 56, /* 10ECA (69322) */ @@ -62956,15 +62956,15 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10ECD (69325) */ 56, /* 10ECE (69326) */ 56, /* 10ECF (69327) */ - 56, /* 10ED0 (69328) */ - 56, /* 10ED1 (69329) */ - 56, /* 10ED2 (69330) */ - 56, /* 10ED3 (69331) */ - 56, /* 10ED4 (69332) */ - 56, /* 10ED5 (69333) */ - 56, /* 10ED6 (69334) */ - 56, /* 10ED7 (69335) */ - 56, /* 10ED8 (69336) */ + 1, /* 10ED0 (69328) */ + 1, /* 10ED1 (69329) */ + 1, /* 10ED2 (69330) */ + 1, /* 10ED3 (69331) */ + 1, /* 10ED4 (69332) */ + 1, /* 10ED5 (69333) */ + 1, /* 10ED6 (69334) */ + 1, /* 10ED7 (69335) */ + 1, /* 10ED8 (69336) */ 56, /* 10ED9 (69337) */ 56, /* 10EDA (69338) */ 56, /* 10EDB (69339) */ @@ -62998,8 +62998,8 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10EF7 (69367) */ 56, /* 10EF8 (69368) */ 56, /* 10EF9 (69369) */ - 56, /* 10EFA (69370) */ - 56, /* 10EFB (69371) */ + 433, /* 10EFA (69370) */ + 433, /* 10EFB (69371) */ 1, /* 10EFC (69372) */ 433, /* 10EFD (69373) */ 433, /* 10EFE (69374) */ @@ -63413,10 +63413,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11096 (69782) */ 1, /* 11097 (69783) */ 1, /* 11098 (69784) */ - 5088, /* 11099 (69785) */ - 5089, /* 1109A (69786) */ - 5090, /* 1109B (69787) */ - 5091, /* 1109C (69788) */ + 5092, /* 11099 (69785) */ + 5093, /* 1109A (69786) */ + 5094, /* 1109B (69787) */ + 5095, /* 1109C (69788) */ 1, /* 1109D (69789) */ 1, /* 1109E (69790) */ 1, /* 1109F (69791) */ @@ -63425,13 +63425,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 110A2 (69794) */ 1, /* 110A3 (69795) */ 1, /* 110A4 (69796) */ - 5092, /* 110A5 (69797) */ + 5096, /* 110A5 (69797) */ 1, /* 110A6 (69798) */ 1, /* 110A7 (69799) */ 1, /* 110A8 (69800) */ 1, /* 110A9 (69801) */ 1, /* 110AA (69802) */ - 5093, /* 110AB (69803) */ + 5097, /* 110AB (69803) */ 1, /* 110AC (69804) */ 1, /* 110AD (69805) */ 1, /* 110AE (69806) */ @@ -63562,11 +63562,11 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 1112B (69931) */ 1, /* 1112C (69932) */ 1, /* 1112D (69933) */ - 5094, /* 1112E (69934) */ - 5095, /* 1112F (69935) */ + 5098, /* 1112E (69934) */ + 5099, /* 1112F (69935) */ 1, /* 11130 (69936) */ - 5096, /* 11131 (69937) */ - 5097, /* 11132 (69938) */ + 5100, /* 11131 (69937) */ + 5101, /* 11132 (69938) */ 852, /* 11133 (69939) */ 852, /* 11134 (69940) */ 56, /* 11135 (69941) */ @@ -64099,12 +64099,12 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11344 (70468) */ 56, /* 11345 (70469) */ 56, /* 11346 (70470) */ - 5098, /* 11347 (70471) */ + 5102, /* 11347 (70471) */ 1, /* 11348 (70472) */ 56, /* 11349 (70473) */ 56, /* 1134A (70474) */ - 5099, /* 1134B (70475) */ - 5100, /* 1134C (70476) */ + 5103, /* 1134B (70475) */ + 5104, /* 1134C (70476) */ 852, /* 1134D (70477) */ 56, /* 1134E (70478) */ 56, /* 1134F (70479) */ @@ -64158,22 +64158,22 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1137F (70527) */ 1, /* 11380 (70528) */ 1, /* 11381 (70529) */ - 5101, /* 11382 (70530) */ - 5102, /* 11383 (70531) */ - 5103, /* 11384 (70532) */ - 5104, /* 11385 (70533) */ + 5105, /* 11382 (70530) */ + 5106, /* 11383 (70531) */ + 5107, /* 11384 (70532) */ + 5108, /* 11385 (70533) */ 1, /* 11386 (70534) */ 1, /* 11387 (70535) */ 1, /* 11388 (70536) */ 1, /* 11389 (70537) */ 56, /* 1138A (70538) */ - 5105, /* 1138B (70539) */ + 5109, /* 1138B (70539) */ 56, /* 1138C (70540) */ 56, /* 1138D (70541) */ - 5106, /* 1138E (70542) */ + 5110, /* 1138E (70542) */ 56, /* 1138F (70543) */ - 5107, /* 11390 (70544) */ - 5108, /* 11391 (70545) */ + 5111, /* 11390 (70544) */ + 5112, /* 11391 (70545) */ 1, /* 11392 (70546) */ 1, /* 11393 (70547) */ 1, /* 11394 (70548) */ @@ -64222,13 +64222,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 113BF (70591) */ 1, /* 113C0 (70592) */ 56, /* 113C1 (70593) */ - 5109, /* 113C2 (70594) */ + 5113, /* 113C2 (70594) */ 56, /* 113C3 (70595) */ 56, /* 113C4 (70596) */ - 5110, /* 113C5 (70597) */ + 5114, /* 113C5 (70597) */ 56, /* 113C6 (70598) */ - 5111, /* 113C7 (70599) */ - 5112, /* 113C8 (70600) */ + 5115, /* 113C7 (70599) */ + 5116, /* 113C8 (70600) */ 865, /* 113C9 (70601) */ 1, /* 113CA (70602) */ 56, /* 113CB (70603) */ @@ -64469,12 +64469,12 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 114B6 (70838) */ 1, /* 114B7 (70839) */ 1, /* 114B8 (70840) */ - 5113, /* 114B9 (70841) */ + 5117, /* 114B9 (70841) */ 865, /* 114BA (70842) */ - 5114, /* 114BB (70843) */ - 5115, /* 114BC (70844) */ + 5118, /* 114BB (70843) */ + 5119, /* 114BC (70844) */ 865, /* 114BD (70845) */ - 5116, /* 114BE (70846) */ + 5120, /* 114BE (70846) */ 1, /* 114BF (70847) */ 1, /* 114C0 (70848) */ 1, /* 114C1 (70849) */ @@ -64724,10 +64724,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 115B5 (71093) */ 56, /* 115B6 (71094) */ 56, /* 115B7 (71095) */ - 5117, /* 115B8 (71096) */ - 5118, /* 115B9 (71097) */ - 5119, /* 115BA (71098) */ - 5120, /* 115BB (71099) */ + 5121, /* 115B8 (71096) */ + 5122, /* 115B9 (71097) */ + 5123, /* 115BA (71098) */ + 5124, /* 115BB (71099) */ 1, /* 115BC (71100) */ 1, /* 115BD (71101) */ 1, /* 115BE (71102) */ @@ -65468,38 +65468,38 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1189D (71837) */ 56, /* 1189E (71838) */ 56, /* 1189F (71839) */ - 5121, /* 118A0 (71840) */ - 5122, /* 118A1 (71841) */ - 5123, /* 118A2 (71842) */ - 5124, /* 118A3 (71843) */ - 5125, /* 118A4 (71844) */ - 5126, /* 118A5 (71845) */ - 5127, /* 118A6 (71846) */ - 5128, /* 118A7 (71847) */ - 5129, /* 118A8 (71848) */ - 5130, /* 118A9 (71849) */ - 5131, /* 118AA (71850) */ - 5132, /* 118AB (71851) */ - 5133, /* 118AC (71852) */ - 5134, /* 118AD (71853) */ - 5135, /* 118AE (71854) */ - 5136, /* 118AF (71855) */ - 5137, /* 118B0 (71856) */ - 5138, /* 118B1 (71857) */ - 5139, /* 118B2 (71858) */ - 5140, /* 118B3 (71859) */ - 5141, /* 118B4 (71860) */ - 5142, /* 118B5 (71861) */ - 5143, /* 118B6 (71862) */ - 5144, /* 118B7 (71863) */ - 5145, /* 118B8 (71864) */ - 5146, /* 118B9 (71865) */ - 5147, /* 118BA (71866) */ - 5148, /* 118BB (71867) */ - 5149, /* 118BC (71868) */ - 5150, /* 118BD (71869) */ - 5151, /* 118BE (71870) */ - 5152, /* 118BF (71871) */ + 5125, /* 118A0 (71840) */ + 5126, /* 118A1 (71841) */ + 5127, /* 118A2 (71842) */ + 5128, /* 118A3 (71843) */ + 5129, /* 118A4 (71844) */ + 5130, /* 118A5 (71845) */ + 5131, /* 118A6 (71846) */ + 5132, /* 118A7 (71847) */ + 5133, /* 118A8 (71848) */ + 5134, /* 118A9 (71849) */ + 5135, /* 118AA (71850) */ + 5136, /* 118AB (71851) */ + 5137, /* 118AC (71852) */ + 5138, /* 118AD (71853) */ + 5139, /* 118AE (71854) */ + 5140, /* 118AF (71855) */ + 5141, /* 118B0 (71856) */ + 5142, /* 118B1 (71857) */ + 5143, /* 118B2 (71858) */ + 5144, /* 118B3 (71859) */ + 5145, /* 118B4 (71860) */ + 5146, /* 118B5 (71861) */ + 5147, /* 118B6 (71862) */ + 5148, /* 118B7 (71863) */ + 5149, /* 118B8 (71864) */ + 5150, /* 118B9 (71865) */ + 5151, /* 118BA (71866) */ + 5152, /* 118BB (71867) */ + 5153, /* 118BC (71868) */ + 5154, /* 118BD (71869) */ + 5155, /* 118BE (71870) */ + 5156, /* 118BF (71871) */ 1, /* 118C0 (71872) */ 1, /* 118C1 (71873) */ 1, /* 118C2 (71874) */ @@ -65617,10 +65617,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11932 (71986) */ 1, /* 11933 (71987) */ 1, /* 11934 (71988) */ - 5153, /* 11935 (71989) */ + 5157, /* 11935 (71989) */ 56, /* 11936 (71990) */ 1, /* 11937 (71991) */ - 5154, /* 11938 (71992) */ + 5158, /* 11938 (71992) */ 56, /* 11939 (71993) */ 56, /* 1193A (71994) */ 1, /* 1193B (71995) */ @@ -66172,14 +66172,14 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 11B5D (72541) */ 56, /* 11B5E (72542) */ 56, /* 11B5F (72543) */ - 56, /* 11B60 (72544) */ - 56, /* 11B61 (72545) */ - 56, /* 11B62 (72546) */ - 56, /* 11B63 (72547) */ - 56, /* 11B64 (72548) */ - 56, /* 11B65 (72549) */ - 56, /* 11B66 (72550) */ - 56, /* 11B67 (72551) */ + 1, /* 11B60 (72544) */ + 1, /* 11B61 (72545) */ + 1, /* 11B62 (72546) */ + 1, /* 11B63 (72547) */ + 1, /* 11B64 (72548) */ + 1, /* 11B65 (72549) */ + 1, /* 11B66 (72550) */ + 1, /* 11B67 (72551) */ 56, /* 11B68 (72552) */ 56, /* 11B69 (72553) */ 56, /* 11B6A (72554) */ @@ -66764,64 +66764,64 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 11DAD (73133) */ 56, /* 11DAE (73134) */ 56, /* 11DAF (73135) */ - 56, /* 11DB0 (73136) */ - 56, /* 11DB1 (73137) */ - 56, /* 11DB2 (73138) */ - 56, /* 11DB3 (73139) */ - 56, /* 11DB4 (73140) */ - 56, /* 11DB5 (73141) */ - 56, /* 11DB6 (73142) */ - 56, /* 11DB7 (73143) */ - 56, /* 11DB8 (73144) */ - 56, /* 11DB9 (73145) */ - 56, /* 11DBA (73146) */ - 56, /* 11DBB (73147) */ - 56, /* 11DBC (73148) */ - 56, /* 11DBD (73149) */ - 56, /* 11DBE (73150) */ - 56, /* 11DBF (73151) */ - 56, /* 11DC0 (73152) */ - 56, /* 11DC1 (73153) */ - 56, /* 11DC2 (73154) */ - 56, /* 11DC3 (73155) */ - 56, /* 11DC4 (73156) */ - 56, /* 11DC5 (73157) */ - 56, /* 11DC6 (73158) */ - 56, /* 11DC7 (73159) */ - 56, /* 11DC8 (73160) */ - 56, /* 11DC9 (73161) */ - 56, /* 11DCA (73162) */ - 56, /* 11DCB (73163) */ - 56, /* 11DCC (73164) */ - 56, /* 11DCD (73165) */ - 56, /* 11DCE (73166) */ - 56, /* 11DCF (73167) */ - 56, /* 11DD0 (73168) */ - 56, /* 11DD1 (73169) */ - 56, /* 11DD2 (73170) */ - 56, /* 11DD3 (73171) */ - 56, /* 11DD4 (73172) */ - 56, /* 11DD5 (73173) */ - 56, /* 11DD6 (73174) */ - 56, /* 11DD7 (73175) */ - 56, /* 11DD8 (73176) */ - 56, /* 11DD9 (73177) */ - 56, /* 11DDA (73178) */ - 56, /* 11DDB (73179) */ + 1, /* 11DB0 (73136) */ + 1, /* 11DB1 (73137) */ + 1, /* 11DB2 (73138) */ + 1, /* 11DB3 (73139) */ + 1, /* 11DB4 (73140) */ + 1, /* 11DB5 (73141) */ + 1, /* 11DB6 (73142) */ + 1, /* 11DB7 (73143) */ + 1, /* 11DB8 (73144) */ + 1, /* 11DB9 (73145) */ + 1, /* 11DBA (73146) */ + 1, /* 11DBB (73147) */ + 1, /* 11DBC (73148) */ + 1, /* 11DBD (73149) */ + 1, /* 11DBE (73150) */ + 1, /* 11DBF (73151) */ + 1, /* 11DC0 (73152) */ + 1, /* 11DC1 (73153) */ + 1, /* 11DC2 (73154) */ + 1, /* 11DC3 (73155) */ + 1, /* 11DC4 (73156) */ + 1, /* 11DC5 (73157) */ + 1, /* 11DC6 (73158) */ + 1, /* 11DC7 (73159) */ + 1, /* 11DC8 (73160) */ + 1, /* 11DC9 (73161) */ + 1, /* 11DCA (73162) */ + 1, /* 11DCB (73163) */ + 1, /* 11DCC (73164) */ + 1, /* 11DCD (73165) */ + 1, /* 11DCE (73166) */ + 1, /* 11DCF (73167) */ + 1, /* 11DD0 (73168) */ + 1, /* 11DD1 (73169) */ + 1, /* 11DD2 (73170) */ + 1, /* 11DD3 (73171) */ + 1, /* 11DD4 (73172) */ + 1, /* 11DD5 (73173) */ + 1, /* 11DD6 (73174) */ + 1, /* 11DD7 (73175) */ + 1, /* 11DD8 (73176) */ + 1, /* 11DD9 (73177) */ + 1, /* 11DDA (73178) */ + 1, /* 11DDB (73179) */ 56, /* 11DDC (73180) */ 56, /* 11DDD (73181) */ 56, /* 11DDE (73182) */ 56, /* 11DDF (73183) */ - 56, /* 11DE0 (73184) */ - 56, /* 11DE1 (73185) */ - 56, /* 11DE2 (73186) */ - 56, /* 11DE3 (73187) */ - 56, /* 11DE4 (73188) */ - 56, /* 11DE5 (73189) */ - 56, /* 11DE6 (73190) */ - 56, /* 11DE7 (73191) */ - 56, /* 11DE8 (73192) */ - 56, /* 11DE9 (73193) */ + 1, /* 11DE0 (73184) */ + 1, /* 11DE1 (73185) */ + 1, /* 11DE2 (73186) */ + 1, /* 11DE3 (73187) */ + 1, /* 11DE4 (73188) */ + 1, /* 11DE5 (73189) */ + 1, /* 11DE6 (73190) */ + 1, /* 11DE7 (73191) */ + 1, /* 11DE8 (73192) */ + 1, /* 11DE9 (73193) */ 56, /* 11DEA (73194) */ 56, /* 11DEB (73195) */ 56, /* 11DEC (73196) */ @@ -77157,8 +77157,8 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 14646 (83526) */ }; -/* From: 16100; To: 18D08 */ -static const uint16_t lxb_unicode_table_map_90368_101641[11273] = +/* From: 16100; To: 18DF2 */ +static const uint16_t lxb_unicode_table_map_90368_101875[11507] = { 1, /* 16100 (90368) */ 1, /* 16101 (90369) */ @@ -77190,18 +77190,18 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 1611B (90395) */ 1, /* 1611C (90396) */ 1, /* 1611D (90397) */ - 5155, /* 1611E (90398) */ + 5159, /* 1611E (90398) */ 865, /* 1611F (90399) */ 865, /* 16120 (90400) */ - 5156, /* 16121 (90401) */ - 5157, /* 16122 (90402) */ - 5158, /* 16123 (90403) */ - 5159, /* 16124 (90404) */ - 5160, /* 16125 (90405) */ - 5161, /* 16126 (90406) */ - 5162, /* 16127 (90407) */ - 5163, /* 16128 (90408) */ - 5164, /* 16129 (90409) */ + 5160, /* 16121 (90401) */ + 5161, /* 16122 (90402) */ + 5162, /* 16123 (90403) */ + 5163, /* 16124 (90404) */ + 5164, /* 16125 (90405) */ + 5165, /* 16126 (90406) */ + 5166, /* 16127 (90407) */ + 5167, /* 16128 (90408) */ + 5168, /* 16129 (90409) */ 1, /* 1612A (90410) */ 1, /* 1612B (90411) */ 1, /* 1612C (90412) */ @@ -80331,14 +80331,14 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 16D60 (93536) */ 1, /* 16D61 (93537) */ 1, /* 16D62 (93538) */ - 5165, /* 16D63 (93539) */ + 5169, /* 16D63 (93539) */ 1, /* 16D64 (93540) */ 1, /* 16D65 (93541) */ 1, /* 16D66 (93542) */ - 5166, /* 16D67 (93543) */ - 5167, /* 16D68 (93544) */ - 5168, /* 16D69 (93545) */ - 5169, /* 16D6A (93546) */ + 5170, /* 16D67 (93543) */ + 5171, /* 16D68 (93544) */ + 5172, /* 16D69 (93545) */ + 5173, /* 16D6A (93546) */ 1, /* 16D6B (93547) */ 1, /* 16D6C (93548) */ 1, /* 16D6D (93549) */ @@ -80552,38 +80552,38 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16E3D (93757) */ 56, /* 16E3E (93758) */ 56, /* 16E3F (93759) */ - 5170, /* 16E40 (93760) */ - 5171, /* 16E41 (93761) */ - 5172, /* 16E42 (93762) */ - 5173, /* 16E43 (93763) */ - 5174, /* 16E44 (93764) */ - 5175, /* 16E45 (93765) */ - 5176, /* 16E46 (93766) */ - 5177, /* 16E47 (93767) */ - 5178, /* 16E48 (93768) */ - 5179, /* 16E49 (93769) */ - 5180, /* 16E4A (93770) */ - 5181, /* 16E4B (93771) */ - 5182, /* 16E4C (93772) */ - 5183, /* 16E4D (93773) */ - 5184, /* 16E4E (93774) */ - 5185, /* 16E4F (93775) */ - 5186, /* 16E50 (93776) */ - 5187, /* 16E51 (93777) */ - 5188, /* 16E52 (93778) */ - 5189, /* 16E53 (93779) */ - 5190, /* 16E54 (93780) */ - 5191, /* 16E55 (93781) */ - 5192, /* 16E56 (93782) */ - 5193, /* 16E57 (93783) */ - 5194, /* 16E58 (93784) */ - 5195, /* 16E59 (93785) */ - 5196, /* 16E5A (93786) */ - 5197, /* 16E5B (93787) */ - 5198, /* 16E5C (93788) */ - 5199, /* 16E5D (93789) */ - 5200, /* 16E5E (93790) */ - 5201, /* 16E5F (93791) */ + 5174, /* 16E40 (93760) */ + 5175, /* 16E41 (93761) */ + 5176, /* 16E42 (93762) */ + 5177, /* 16E43 (93763) */ + 5178, /* 16E44 (93764) */ + 5179, /* 16E45 (93765) */ + 5180, /* 16E46 (93766) */ + 5181, /* 16E47 (93767) */ + 5182, /* 16E48 (93768) */ + 5183, /* 16E49 (93769) */ + 5184, /* 16E4A (93770) */ + 5185, /* 16E4B (93771) */ + 5186, /* 16E4C (93772) */ + 5187, /* 16E4D (93773) */ + 5188, /* 16E4E (93774) */ + 5189, /* 16E4F (93775) */ + 5190, /* 16E50 (93776) */ + 5191, /* 16E51 (93777) */ + 5192, /* 16E52 (93778) */ + 5193, /* 16E53 (93779) */ + 5194, /* 16E54 (93780) */ + 5195, /* 16E55 (93781) */ + 5196, /* 16E56 (93782) */ + 5197, /* 16E57 (93783) */ + 5198, /* 16E58 (93784) */ + 5199, /* 16E59 (93785) */ + 5200, /* 16E5A (93786) */ + 5201, /* 16E5B (93787) */ + 5202, /* 16E5C (93788) */ + 5203, /* 16E5D (93789) */ + 5204, /* 16E5E (93790) */ + 5205, /* 16E5F (93791) */ 1, /* 16E60 (93792) */ 1, /* 16E61 (93793) */ 1, /* 16E62 (93794) */ @@ -80648,58 +80648,58 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16E9D (93853) */ 56, /* 16E9E (93854) */ 56, /* 16E9F (93855) */ - 56, /* 16EA0 (93856) */ - 56, /* 16EA1 (93857) */ - 56, /* 16EA2 (93858) */ - 56, /* 16EA3 (93859) */ - 56, /* 16EA4 (93860) */ - 56, /* 16EA5 (93861) */ - 56, /* 16EA6 (93862) */ - 56, /* 16EA7 (93863) */ - 56, /* 16EA8 (93864) */ - 56, /* 16EA9 (93865) */ - 56, /* 16EAA (93866) */ - 56, /* 16EAB (93867) */ - 56, /* 16EAC (93868) */ - 56, /* 16EAD (93869) */ - 56, /* 16EAE (93870) */ - 56, /* 16EAF (93871) */ - 56, /* 16EB0 (93872) */ - 56, /* 16EB1 (93873) */ - 56, /* 16EB2 (93874) */ - 56, /* 16EB3 (93875) */ - 56, /* 16EB4 (93876) */ - 56, /* 16EB5 (93877) */ - 56, /* 16EB6 (93878) */ - 56, /* 16EB7 (93879) */ - 56, /* 16EB8 (93880) */ + 5206, /* 16EA0 (93856) */ + 5207, /* 16EA1 (93857) */ + 5208, /* 16EA2 (93858) */ + 5209, /* 16EA3 (93859) */ + 5210, /* 16EA4 (93860) */ + 5211, /* 16EA5 (93861) */ + 5212, /* 16EA6 (93862) */ + 5213, /* 16EA7 (93863) */ + 5214, /* 16EA8 (93864) */ + 5215, /* 16EA9 (93865) */ + 5216, /* 16EAA (93866) */ + 5217, /* 16EAB (93867) */ + 5218, /* 16EAC (93868) */ + 5219, /* 16EAD (93869) */ + 5220, /* 16EAE (93870) */ + 5221, /* 16EAF (93871) */ + 5222, /* 16EB0 (93872) */ + 5223, /* 16EB1 (93873) */ + 5224, /* 16EB2 (93874) */ + 5225, /* 16EB3 (93875) */ + 5226, /* 16EB4 (93876) */ + 5227, /* 16EB5 (93877) */ + 5228, /* 16EB6 (93878) */ + 5229, /* 16EB7 (93879) */ + 5230, /* 16EB8 (93880) */ 56, /* 16EB9 (93881) */ 56, /* 16EBA (93882) */ - 56, /* 16EBB (93883) */ - 56, /* 16EBC (93884) */ - 56, /* 16EBD (93885) */ - 56, /* 16EBE (93886) */ - 56, /* 16EBF (93887) */ - 56, /* 16EC0 (93888) */ - 56, /* 16EC1 (93889) */ - 56, /* 16EC2 (93890) */ - 56, /* 16EC3 (93891) */ - 56, /* 16EC4 (93892) */ - 56, /* 16EC5 (93893) */ - 56, /* 16EC6 (93894) */ - 56, /* 16EC7 (93895) */ - 56, /* 16EC8 (93896) */ - 56, /* 16EC9 (93897) */ - 56, /* 16ECA (93898) */ - 56, /* 16ECB (93899) */ - 56, /* 16ECC (93900) */ - 56, /* 16ECD (93901) */ - 56, /* 16ECE (93902) */ - 56, /* 16ECF (93903) */ - 56, /* 16ED0 (93904) */ - 56, /* 16ED1 (93905) */ - 56, /* 16ED2 (93906) */ - 56, /* 16ED3 (93907) */ + 1, /* 16EBB (93883) */ + 1, /* 16EBC (93884) */ + 1, /* 16EBD (93885) */ + 1, /* 16EBE (93886) */ + 1, /* 16EBF (93887) */ + 1, /* 16EC0 (93888) */ + 1, /* 16EC1 (93889) */ + 1, /* 16EC2 (93890) */ + 1, /* 16EC3 (93891) */ + 1, /* 16EC4 (93892) */ + 1, /* 16EC5 (93893) */ + 1, /* 16EC6 (93894) */ + 1, /* 16EC7 (93895) */ + 1, /* 16EC8 (93896) */ + 1, /* 16EC9 (93897) */ + 1, /* 16ECA (93898) */ + 1, /* 16ECB (93899) */ + 1, /* 16ECC (93900) */ + 1, /* 16ECD (93901) */ + 1, /* 16ECE (93902) */ + 1, /* 16ECF (93903) */ + 1, /* 16ED0 (93904) */ + 1, /* 16ED1 (93905) */ + 1, /* 16ED2 (93906) */ + 1, /* 16ED3 (93907) */ 56, /* 16ED4 (93908) */ 56, /* 16ED5 (93909) */ 56, /* 16ED6 (93910) */ @@ -80984,13 +80984,13 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16FED (94189) */ 56, /* 16FEE (94190) */ 56, /* 16FEF (94191) */ - 5202, /* 16FF0 (94192) */ - 5202, /* 16FF1 (94193) */ - 56, /* 16FF2 (94194) */ - 56, /* 16FF3 (94195) */ - 56, /* 16FF4 (94196) */ - 56, /* 16FF5 (94197) */ - 56, /* 16FF6 (94198) */ + 5231, /* 16FF0 (94192) */ + 5231, /* 16FF1 (94193) */ + 1, /* 16FF2 (94194) */ + 1, /* 16FF3 (94195) */ + 1, /* 16FF4 (94196) */ + 1, /* 16FF5 (94197) */ + 1, /* 16FF6 (94198) */ 56, /* 16FF7 (94199) */ 56, /* 16FF8 (94200) */ 56, /* 16FF9 (94201) */ @@ -87136,14 +87136,14 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 187F5 (100341) */ 1, /* 187F6 (100342) */ 1, /* 187F7 (100343) */ - 56, /* 187F8 (100344) */ - 56, /* 187F9 (100345) */ - 56, /* 187FA (100346) */ - 56, /* 187FB (100347) */ - 56, /* 187FC (100348) */ - 56, /* 187FD (100349) */ - 56, /* 187FE (100350) */ - 56, /* 187FF (100351) */ + 1, /* 187F8 (100344) */ + 1, /* 187F9 (100345) */ + 1, /* 187FA (100346) */ + 1, /* 187FB (100347) */ + 1, /* 187FC (100348) */ + 1, /* 187FD (100349) */ + 1, /* 187FE (100350) */ + 1, /* 187FF (100351) */ 1, /* 18800 (100352) */ 1, /* 18801 (100353) */ 1, /* 18802 (100354) */ @@ -88433,10 +88433,244 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 18D06 (101638) */ 1, /* 18D07 (101639) */ 1, /* 18D08 (101640) */ + 1, /* 18D09 (101641) */ + 1, /* 18D0A (101642) */ + 1, /* 18D0B (101643) */ + 1, /* 18D0C (101644) */ + 1, /* 18D0D (101645) */ + 1, /* 18D0E (101646) */ + 1, /* 18D0F (101647) */ + 1, /* 18D10 (101648) */ + 1, /* 18D11 (101649) */ + 1, /* 18D12 (101650) */ + 1, /* 18D13 (101651) */ + 1, /* 18D14 (101652) */ + 1, /* 18D15 (101653) */ + 1, /* 18D16 (101654) */ + 1, /* 18D17 (101655) */ + 1, /* 18D18 (101656) */ + 1, /* 18D19 (101657) */ + 1, /* 18D1A (101658) */ + 1, /* 18D1B (101659) */ + 1, /* 18D1C (101660) */ + 1, /* 18D1D (101661) */ + 1, /* 18D1E (101662) */ + 56, /* 18D1F (101663) */ + 56, /* 18D20 (101664) */ + 56, /* 18D21 (101665) */ + 56, /* 18D22 (101666) */ + 56, /* 18D23 (101667) */ + 56, /* 18D24 (101668) */ + 56, /* 18D25 (101669) */ + 56, /* 18D26 (101670) */ + 56, /* 18D27 (101671) */ + 56, /* 18D28 (101672) */ + 56, /* 18D29 (101673) */ + 56, /* 18D2A (101674) */ + 56, /* 18D2B (101675) */ + 56, /* 18D2C (101676) */ + 56, /* 18D2D (101677) */ + 56, /* 18D2E (101678) */ + 56, /* 18D2F (101679) */ + 56, /* 18D30 (101680) */ + 56, /* 18D31 (101681) */ + 56, /* 18D32 (101682) */ + 56, /* 18D33 (101683) */ + 56, /* 18D34 (101684) */ + 56, /* 18D35 (101685) */ + 56, /* 18D36 (101686) */ + 56, /* 18D37 (101687) */ + 56, /* 18D38 (101688) */ + 56, /* 18D39 (101689) */ + 56, /* 18D3A (101690) */ + 56, /* 18D3B (101691) */ + 56, /* 18D3C (101692) */ + 56, /* 18D3D (101693) */ + 56, /* 18D3E (101694) */ + 56, /* 18D3F (101695) */ + 56, /* 18D40 (101696) */ + 56, /* 18D41 (101697) */ + 56, /* 18D42 (101698) */ + 56, /* 18D43 (101699) */ + 56, /* 18D44 (101700) */ + 56, /* 18D45 (101701) */ + 56, /* 18D46 (101702) */ + 56, /* 18D47 (101703) */ + 56, /* 18D48 (101704) */ + 56, /* 18D49 (101705) */ + 56, /* 18D4A (101706) */ + 56, /* 18D4B (101707) */ + 56, /* 18D4C (101708) */ + 56, /* 18D4D (101709) */ + 56, /* 18D4E (101710) */ + 56, /* 18D4F (101711) */ + 56, /* 18D50 (101712) */ + 56, /* 18D51 (101713) */ + 56, /* 18D52 (101714) */ + 56, /* 18D53 (101715) */ + 56, /* 18D54 (101716) */ + 56, /* 18D55 (101717) */ + 56, /* 18D56 (101718) */ + 56, /* 18D57 (101719) */ + 56, /* 18D58 (101720) */ + 56, /* 18D59 (101721) */ + 56, /* 18D5A (101722) */ + 56, /* 18D5B (101723) */ + 56, /* 18D5C (101724) */ + 56, /* 18D5D (101725) */ + 56, /* 18D5E (101726) */ + 56, /* 18D5F (101727) */ + 56, /* 18D60 (101728) */ + 56, /* 18D61 (101729) */ + 56, /* 18D62 (101730) */ + 56, /* 18D63 (101731) */ + 56, /* 18D64 (101732) */ + 56, /* 18D65 (101733) */ + 56, /* 18D66 (101734) */ + 56, /* 18D67 (101735) */ + 56, /* 18D68 (101736) */ + 56, /* 18D69 (101737) */ + 56, /* 18D6A (101738) */ + 56, /* 18D6B (101739) */ + 56, /* 18D6C (101740) */ + 56, /* 18D6D (101741) */ + 56, /* 18D6E (101742) */ + 56, /* 18D6F (101743) */ + 56, /* 18D70 (101744) */ + 56, /* 18D71 (101745) */ + 56, /* 18D72 (101746) */ + 56, /* 18D73 (101747) */ + 56, /* 18D74 (101748) */ + 56, /* 18D75 (101749) */ + 56, /* 18D76 (101750) */ + 56, /* 18D77 (101751) */ + 56, /* 18D78 (101752) */ + 56, /* 18D79 (101753) */ + 56, /* 18D7A (101754) */ + 56, /* 18D7B (101755) */ + 56, /* 18D7C (101756) */ + 56, /* 18D7D (101757) */ + 56, /* 18D7E (101758) */ + 56, /* 18D7F (101759) */ + 1, /* 18D80 (101760) */ + 1, /* 18D81 (101761) */ + 1, /* 18D82 (101762) */ + 1, /* 18D83 (101763) */ + 1, /* 18D84 (101764) */ + 1, /* 18D85 (101765) */ + 1, /* 18D86 (101766) */ + 1, /* 18D87 (101767) */ + 1, /* 18D88 (101768) */ + 1, /* 18D89 (101769) */ + 1, /* 18D8A (101770) */ + 1, /* 18D8B (101771) */ + 1, /* 18D8C (101772) */ + 1, /* 18D8D (101773) */ + 1, /* 18D8E (101774) */ + 1, /* 18D8F (101775) */ + 1, /* 18D90 (101776) */ + 1, /* 18D91 (101777) */ + 1, /* 18D92 (101778) */ + 1, /* 18D93 (101779) */ + 1, /* 18D94 (101780) */ + 1, /* 18D95 (101781) */ + 1, /* 18D96 (101782) */ + 1, /* 18D97 (101783) */ + 1, /* 18D98 (101784) */ + 1, /* 18D99 (101785) */ + 1, /* 18D9A (101786) */ + 1, /* 18D9B (101787) */ + 1, /* 18D9C (101788) */ + 1, /* 18D9D (101789) */ + 1, /* 18D9E (101790) */ + 1, /* 18D9F (101791) */ + 1, /* 18DA0 (101792) */ + 1, /* 18DA1 (101793) */ + 1, /* 18DA2 (101794) */ + 1, /* 18DA3 (101795) */ + 1, /* 18DA4 (101796) */ + 1, /* 18DA5 (101797) */ + 1, /* 18DA6 (101798) */ + 1, /* 18DA7 (101799) */ + 1, /* 18DA8 (101800) */ + 1, /* 18DA9 (101801) */ + 1, /* 18DAA (101802) */ + 1, /* 18DAB (101803) */ + 1, /* 18DAC (101804) */ + 1, /* 18DAD (101805) */ + 1, /* 18DAE (101806) */ + 1, /* 18DAF (101807) */ + 1, /* 18DB0 (101808) */ + 1, /* 18DB1 (101809) */ + 1, /* 18DB2 (101810) */ + 1, /* 18DB3 (101811) */ + 1, /* 18DB4 (101812) */ + 1, /* 18DB5 (101813) */ + 1, /* 18DB6 (101814) */ + 1, /* 18DB7 (101815) */ + 1, /* 18DB8 (101816) */ + 1, /* 18DB9 (101817) */ + 1, /* 18DBA (101818) */ + 1, /* 18DBB (101819) */ + 1, /* 18DBC (101820) */ + 1, /* 18DBD (101821) */ + 1, /* 18DBE (101822) */ + 1, /* 18DBF (101823) */ + 1, /* 18DC0 (101824) */ + 1, /* 18DC1 (101825) */ + 1, /* 18DC2 (101826) */ + 1, /* 18DC3 (101827) */ + 1, /* 18DC4 (101828) */ + 1, /* 18DC5 (101829) */ + 1, /* 18DC6 (101830) */ + 1, /* 18DC7 (101831) */ + 1, /* 18DC8 (101832) */ + 1, /* 18DC9 (101833) */ + 1, /* 18DCA (101834) */ + 1, /* 18DCB (101835) */ + 1, /* 18DCC (101836) */ + 1, /* 18DCD (101837) */ + 1, /* 18DCE (101838) */ + 1, /* 18DCF (101839) */ + 1, /* 18DD0 (101840) */ + 1, /* 18DD1 (101841) */ + 1, /* 18DD2 (101842) */ + 1, /* 18DD3 (101843) */ + 1, /* 18DD4 (101844) */ + 1, /* 18DD5 (101845) */ + 1, /* 18DD6 (101846) */ + 1, /* 18DD7 (101847) */ + 1, /* 18DD8 (101848) */ + 1, /* 18DD9 (101849) */ + 1, /* 18DDA (101850) */ + 1, /* 18DDB (101851) */ + 1, /* 18DDC (101852) */ + 1, /* 18DDD (101853) */ + 1, /* 18DDE (101854) */ + 1, /* 18DDF (101855) */ + 1, /* 18DE0 (101856) */ + 1, /* 18DE1 (101857) */ + 1, /* 18DE2 (101858) */ + 1, /* 18DE3 (101859) */ + 1, /* 18DE4 (101860) */ + 1, /* 18DE5 (101861) */ + 1, /* 18DE6 (101862) */ + 1, /* 18DE7 (101863) */ + 1, /* 18DE8 (101864) */ + 1, /* 18DE9 (101865) */ + 1, /* 18DEA (101866) */ + 1, /* 18DEB (101867) */ + 1, /* 18DEC (101868) */ + 1, /* 18DED (101869) */ + 1, /* 18DEE (101870) */ + 1, /* 18DEF (101871) */ + 1, /* 18DF0 (101872) */ + 1, /* 18DF1 (101873) */ + 1, /* 18DF2 (101874) */ }; -/* From: 1AFF0; To: 323AF */ -static const uint32_t lxb_unicode_table_map_110576_205744[95168] = +/* From: 1AFF0; To: 33479 */ +static const uint32_t lxb_unicode_table_map_110576_210042[99466] = { 1, /* 1AFF0 (110576) */ 1, /* 1AFF1 (110577) */ @@ -95836,45 +96070,45 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1CCD3 (117971) */ 1, /* 1CCD4 (117972) */ 1, /* 1CCD5 (117973) */ - 5203, /* 1CCD6 (117974) */ + 5232, /* 1CCD6 (117974) */ 1755, /* 1CCD7 (117975) */ 1730, /* 1CCD8 (117976) */ 1773, /* 1CCD9 (117977) */ 1757, /* 1CCDA (117978) */ 1758, /* 1CCDB (117979) */ - 5204, /* 1CCDC (117980) */ + 5233, /* 1CCDC (117980) */ 1737, /* 1CCDD (117981) */ 1740, /* 1CCDE (117982) */ - 5205, /* 1CCDF (117983) */ - 5206, /* 1CCE0 (117984) */ + 5234, /* 1CCDF (117983) */ + 5235, /* 1CCE0 (117984) */ 1741, /* 1CCE1 (117985) */ 1760, /* 1CCE2 (117986) */ 1743, /* 1CCE3 (117987) */ - 5207, /* 1CCE4 (117988) */ + 5236, /* 1CCE4 (117988) */ 1745, /* 1CCE5 (117989) */ 1746, /* 1CCE6 (117990) */ 1747, /* 1CCE7 (117991) */ - 5208, /* 1CCE8 (117992) */ - 5209, /* 1CCE9 (117993) */ - 5210, /* 1CCEA (117994) */ - 5211, /* 1CCEB (117995) */ - 5212, /* 1CCEC (117996) */ - 5213, /* 1CCED (117997) */ - 5214, /* 1CCEE (117998) */ + 5237, /* 1CCE8 (117992) */ + 5238, /* 1CCE9 (117993) */ + 5239, /* 1CCEA (117994) */ + 5240, /* 1CCEB (117995) */ + 5241, /* 1CCEC (117996) */ + 5242, /* 1CCED (117997) */ + 5243, /* 1CCEE (117998) */ 1751, /* 1CCEF (117999) */ - 5215, /* 1CCF0 (118000) */ - 5216, /* 1CCF1 (118001) */ - 5217, /* 1CCF2 (118002) */ - 5218, /* 1CCF3 (118003) */ - 5219, /* 1CCF4 (118004) */ - 5220, /* 1CCF5 (118005) */ - 5221, /* 1CCF6 (118006) */ - 5222, /* 1CCF7 (118007) */ - 5223, /* 1CCF8 (118008) */ - 5224, /* 1CCF9 (118009) */ - 56, /* 1CCFA (118010) */ - 56, /* 1CCFB (118011) */ - 56, /* 1CCFC (118012) */ + 5244, /* 1CCF0 (118000) */ + 5245, /* 1CCF1 (118001) */ + 5246, /* 1CCF2 (118002) */ + 5247, /* 1CCF3 (118003) */ + 5248, /* 1CCF4 (118004) */ + 5249, /* 1CCF5 (118005) */ + 5250, /* 1CCF6 (118006) */ + 5251, /* 1CCF7 (118007) */ + 5252, /* 1CCF8 (118008) */ + 5253, /* 1CCF9 (118009) */ + 1, /* 1CCFA (118010) */ + 1, /* 1CCFB (118011) */ + 1, /* 1CCFC (118012) */ 56, /* 1CCFD (118013) */ 56, /* 1CCFE (118014) */ 56, /* 1CCFF (118015) */ @@ -96320,29 +96554,29 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1CEB7 (118455) */ 56, /* 1CEB8 (118456) */ 56, /* 1CEB9 (118457) */ - 56, /* 1CEBA (118458) */ - 56, /* 1CEBB (118459) */ - 56, /* 1CEBC (118460) */ - 56, /* 1CEBD (118461) */ - 56, /* 1CEBE (118462) */ - 56, /* 1CEBF (118463) */ - 56, /* 1CEC0 (118464) */ - 56, /* 1CEC1 (118465) */ - 56, /* 1CEC2 (118466) */ - 56, /* 1CEC3 (118467) */ - 56, /* 1CEC4 (118468) */ - 56, /* 1CEC5 (118469) */ - 56, /* 1CEC6 (118470) */ - 56, /* 1CEC7 (118471) */ - 56, /* 1CEC8 (118472) */ - 56, /* 1CEC9 (118473) */ - 56, /* 1CECA (118474) */ - 56, /* 1CECB (118475) */ - 56, /* 1CECC (118476) */ - 56, /* 1CECD (118477) */ - 56, /* 1CECE (118478) */ - 56, /* 1CECF (118479) */ - 56, /* 1CED0 (118480) */ + 1, /* 1CEBA (118458) */ + 1, /* 1CEBB (118459) */ + 1, /* 1CEBC (118460) */ + 1, /* 1CEBD (118461) */ + 1, /* 1CEBE (118462) */ + 1, /* 1CEBF (118463) */ + 1, /* 1CEC0 (118464) */ + 1, /* 1CEC1 (118465) */ + 1, /* 1CEC2 (118466) */ + 1, /* 1CEC3 (118467) */ + 1, /* 1CEC4 (118468) */ + 1, /* 1CEC5 (118469) */ + 1, /* 1CEC6 (118470) */ + 1, /* 1CEC7 (118471) */ + 1, /* 1CEC8 (118472) */ + 1, /* 1CEC9 (118473) */ + 1, /* 1CECA (118474) */ + 1, /* 1CECB (118475) */ + 1, /* 1CECC (118476) */ + 1, /* 1CECD (118477) */ + 1, /* 1CECE (118478) */ + 1, /* 1CECF (118479) */ + 1, /* 1CED0 (118480) */ 56, /* 1CED1 (118481) */ 56, /* 1CED2 (118482) */ 56, /* 1CED3 (118483) */ @@ -96358,23 +96592,23 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1CEDD (118493) */ 56, /* 1CEDE (118494) */ 56, /* 1CEDF (118495) */ - 56, /* 1CEE0 (118496) */ - 56, /* 1CEE1 (118497) */ - 56, /* 1CEE2 (118498) */ - 56, /* 1CEE3 (118499) */ - 56, /* 1CEE4 (118500) */ - 56, /* 1CEE5 (118501) */ - 56, /* 1CEE6 (118502) */ - 56, /* 1CEE7 (118503) */ - 56, /* 1CEE8 (118504) */ - 56, /* 1CEE9 (118505) */ - 56, /* 1CEEA (118506) */ - 56, /* 1CEEB (118507) */ - 56, /* 1CEEC (118508) */ - 56, /* 1CEED (118509) */ - 56, /* 1CEEE (118510) */ - 56, /* 1CEEF (118511) */ - 56, /* 1CEF0 (118512) */ + 1, /* 1CEE0 (118496) */ + 1, /* 1CEE1 (118497) */ + 1, /* 1CEE2 (118498) */ + 1, /* 1CEE3 (118499) */ + 1, /* 1CEE4 (118500) */ + 1, /* 1CEE5 (118501) */ + 1, /* 1CEE6 (118502) */ + 1, /* 1CEE7 (118503) */ + 1, /* 1CEE8 (118504) */ + 1, /* 1CEE9 (118505) */ + 1, /* 1CEEA (118506) */ + 1, /* 1CEEB (118507) */ + 1, /* 1CEEC (118508) */ + 1, /* 1CEED (118509) */ + 1, /* 1CEEE (118510) */ + 1, /* 1CEEF (118511) */ + 1, /* 1CEF0 (118512) */ 56, /* 1CEF1 (118513) */ 56, /* 1CEF2 (118514) */ 56, /* 1CEF3 (118515) */ @@ -96989,20 +97223,20 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D154 (119124) */ 1, /* 1D155 (119125) */ 1, /* 1D156 (119126) */ - 5225, /* 1D157 (119127) */ - 5226, /* 1D158 (119128) */ + 5254, /* 1D157 (119127) */ + 5255, /* 1D158 (119128) */ 1, /* 1D159 (119129) */ 1, /* 1D15A (119130) */ 1, /* 1D15B (119131) */ 1, /* 1D15C (119132) */ 1, /* 1D15D (119133) */ - 5227, /* 1D15E (119134) */ - 5228, /* 1D15F (119135) */ - 5229, /* 1D160 (119136) */ - 5230, /* 1D161 (119137) */ - 5231, /* 1D162 (119138) */ - 5232, /* 1D163 (119139) */ - 5233, /* 1D164 (119140) */ + 5256, /* 1D15E (119134) */ + 5257, /* 1D15F (119135) */ + 5258, /* 1D160 (119136) */ + 5259, /* 1D161 (119137) */ + 5260, /* 1D162 (119138) */ + 5261, /* 1D163 (119139) */ + 5262, /* 1D164 (119140) */ 930, /* 1D165 (119141) */ 930, /* 1D166 (119142) */ 438, /* 1D167 (119143) */ @@ -97011,7 +97245,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D16A (119146) */ 1, /* 1D16B (119147) */ 1, /* 1D16C (119148) */ - 5234, /* 1D16D (119149) */ + 5263, /* 1D16D (119149) */ 930, /* 1D16E (119150) */ 930, /* 1D16F (119151) */ 930, /* 1D170 (119152) */ @@ -97087,14 +97321,14 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D1B6 (119222) */ 1, /* 1D1B7 (119223) */ 1, /* 1D1B8 (119224) */ - 5235, /* 1D1B9 (119225) */ - 5236, /* 1D1BA (119226) */ - 5237, /* 1D1BB (119227) */ - 5238, /* 1D1BC (119228) */ - 5239, /* 1D1BD (119229) */ - 5240, /* 1D1BE (119230) */ - 5241, /* 1D1BF (119231) */ - 5242, /* 1D1C0 (119232) */ + 5264, /* 1D1B9 (119225) */ + 5265, /* 1D1BA (119226) */ + 5266, /* 1D1BB (119227) */ + 5267, /* 1D1BC (119228) */ + 5268, /* 1D1BD (119229) */ + 5269, /* 1D1BE (119230) */ + 5270, /* 1D1BF (119231) */ + 5271, /* 1D1C0 (119232) */ 1, /* 1D1C1 (119233) */ 1, /* 1D1C2 (119234) */ 1, /* 1D1C3 (119235) */ @@ -97670,1030 +97904,1030 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1D3FD (119805) */ 56, /* 1D3FE (119806) */ 56, /* 1D3FF (119807) */ - 5203, /* 1D400 (119808) */ + 5232, /* 1D400 (119808) */ 1755, /* 1D401 (119809) */ 1730, /* 1D402 (119810) */ 1773, /* 1D403 (119811) */ 1757, /* 1D404 (119812) */ 1758, /* 1D405 (119813) */ - 5204, /* 1D406 (119814) */ + 5233, /* 1D406 (119814) */ 1737, /* 1D407 (119815) */ 1740, /* 1D408 (119816) */ - 5205, /* 1D409 (119817) */ - 5206, /* 1D40A (119818) */ + 5234, /* 1D409 (119817) */ + 5235, /* 1D40A (119818) */ 1741, /* 1D40B (119819) */ 1760, /* 1D40C (119820) */ 1743, /* 1D40D (119821) */ - 5207, /* 1D40E (119822) */ + 5236, /* 1D40E (119822) */ 1745, /* 1D40F (119823) */ 1746, /* 1D410 (119824) */ 1747, /* 1D411 (119825) */ - 5208, /* 1D412 (119826) */ - 5209, /* 1D413 (119827) */ - 5210, /* 1D414 (119828) */ - 5211, /* 1D415 (119829) */ - 5212, /* 1D416 (119830) */ - 5213, /* 1D417 (119831) */ - 5214, /* 1D418 (119832) */ + 5237, /* 1D412 (119826) */ + 5238, /* 1D413 (119827) */ + 5239, /* 1D414 (119828) */ + 5240, /* 1D415 (119829) */ + 5241, /* 1D416 (119830) */ + 5242, /* 1D417 (119831) */ + 5243, /* 1D418 (119832) */ 1751, /* 1D419 (119833) */ - 5243, /* 1D41A (119834) */ - 5244, /* 1D41B (119835) */ - 5245, /* 1D41C (119836) */ + 5272, /* 1D41A (119834) */ + 5273, /* 1D41B (119835) */ + 5274, /* 1D41C (119836) */ 1774, /* 1D41D (119837) */ 1756, /* 1D41E (119838) */ - 5246, /* 1D41F (119839) */ + 5275, /* 1D41F (119839) */ 1736, /* 1D420 (119840) */ 1738, /* 1D421 (119841) */ 1766, /* 1D422 (119842) */ 1775, /* 1D423 (119843) */ - 5247, /* 1D424 (119844) */ + 5276, /* 1D424 (119844) */ 1742, /* 1D425 (119845) */ - 5248, /* 1D426 (119846) */ - 5249, /* 1D427 (119847) */ + 5277, /* 1D426 (119846) */ + 5278, /* 1D427 (119847) */ 1761, /* 1D428 (119848) */ - 5250, /* 1D429 (119849) */ - 5251, /* 1D42A (119850) */ - 5252, /* 1D42B (119851) */ - 5253, /* 1D42C (119852) */ - 5254, /* 1D42D (119853) */ - 5255, /* 1D42E (119854) */ - 5256, /* 1D42F (119855) */ - 5257, /* 1D430 (119856) */ - 5258, /* 1D431 (119857) */ - 5259, /* 1D432 (119858) */ - 5260, /* 1D433 (119859) */ - 5203, /* 1D434 (119860) */ + 5279, /* 1D429 (119849) */ + 5280, /* 1D42A (119850) */ + 5281, /* 1D42B (119851) */ + 5282, /* 1D42C (119852) */ + 5283, /* 1D42D (119853) */ + 5284, /* 1D42E (119854) */ + 5285, /* 1D42F (119855) */ + 5286, /* 1D430 (119856) */ + 5287, /* 1D431 (119857) */ + 5288, /* 1D432 (119858) */ + 5289, /* 1D433 (119859) */ + 5232, /* 1D434 (119860) */ 1755, /* 1D435 (119861) */ 1730, /* 1D436 (119862) */ 1773, /* 1D437 (119863) */ 1757, /* 1D438 (119864) */ 1758, /* 1D439 (119865) */ - 5204, /* 1D43A (119866) */ + 5233, /* 1D43A (119866) */ 1737, /* 1D43B (119867) */ 1740, /* 1D43C (119868) */ - 5205, /* 1D43D (119869) */ - 5206, /* 1D43E (119870) */ + 5234, /* 1D43D (119869) */ + 5235, /* 1D43E (119870) */ 1741, /* 1D43F (119871) */ 1760, /* 1D440 (119872) */ 1743, /* 1D441 (119873) */ - 5207, /* 1D442 (119874) */ + 5236, /* 1D442 (119874) */ 1745, /* 1D443 (119875) */ 1746, /* 1D444 (119876) */ 1747, /* 1D445 (119877) */ - 5208, /* 1D446 (119878) */ - 5209, /* 1D447 (119879) */ - 5210, /* 1D448 (119880) */ - 5211, /* 1D449 (119881) */ - 5212, /* 1D44A (119882) */ - 5213, /* 1D44B (119883) */ - 5214, /* 1D44C (119884) */ + 5237, /* 1D446 (119878) */ + 5238, /* 1D447 (119879) */ + 5239, /* 1D448 (119880) */ + 5240, /* 1D449 (119881) */ + 5241, /* 1D44A (119882) */ + 5242, /* 1D44B (119883) */ + 5243, /* 1D44C (119884) */ 1751, /* 1D44D (119885) */ - 5243, /* 1D44E (119886) */ - 5244, /* 1D44F (119887) */ - 5245, /* 1D450 (119888) */ + 5272, /* 1D44E (119886) */ + 5273, /* 1D44F (119887) */ + 5274, /* 1D450 (119888) */ 1774, /* 1D451 (119889) */ 1756, /* 1D452 (119890) */ - 5246, /* 1D453 (119891) */ + 5275, /* 1D453 (119891) */ 1736, /* 1D454 (119892) */ 56, /* 1D455 (119893) */ 1766, /* 1D456 (119894) */ 1775, /* 1D457 (119895) */ - 5247, /* 1D458 (119896) */ + 5276, /* 1D458 (119896) */ 1742, /* 1D459 (119897) */ - 5248, /* 1D45A (119898) */ - 5249, /* 1D45B (119899) */ + 5277, /* 1D45A (119898) */ + 5278, /* 1D45B (119899) */ 1761, /* 1D45C (119900) */ - 5250, /* 1D45D (119901) */ - 5251, /* 1D45E (119902) */ - 5252, /* 1D45F (119903) */ - 5253, /* 1D460 (119904) */ - 5254, /* 1D461 (119905) */ - 5255, /* 1D462 (119906) */ - 5256, /* 1D463 (119907) */ - 5257, /* 1D464 (119908) */ - 5258, /* 1D465 (119909) */ - 5259, /* 1D466 (119910) */ - 5260, /* 1D467 (119911) */ - 5203, /* 1D468 (119912) */ + 5279, /* 1D45D (119901) */ + 5280, /* 1D45E (119902) */ + 5281, /* 1D45F (119903) */ + 5282, /* 1D460 (119904) */ + 5283, /* 1D461 (119905) */ + 5284, /* 1D462 (119906) */ + 5285, /* 1D463 (119907) */ + 5286, /* 1D464 (119908) */ + 5287, /* 1D465 (119909) */ + 5288, /* 1D466 (119910) */ + 5289, /* 1D467 (119911) */ + 5232, /* 1D468 (119912) */ 1755, /* 1D469 (119913) */ 1730, /* 1D46A (119914) */ 1773, /* 1D46B (119915) */ 1757, /* 1D46C (119916) */ 1758, /* 1D46D (119917) */ - 5204, /* 1D46E (119918) */ + 5233, /* 1D46E (119918) */ 1737, /* 1D46F (119919) */ 1740, /* 1D470 (119920) */ - 5205, /* 1D471 (119921) */ - 5206, /* 1D472 (119922) */ + 5234, /* 1D471 (119921) */ + 5235, /* 1D472 (119922) */ 1741, /* 1D473 (119923) */ 1760, /* 1D474 (119924) */ 1743, /* 1D475 (119925) */ - 5207, /* 1D476 (119926) */ + 5236, /* 1D476 (119926) */ 1745, /* 1D477 (119927) */ 1746, /* 1D478 (119928) */ 1747, /* 1D479 (119929) */ - 5208, /* 1D47A (119930) */ - 5209, /* 1D47B (119931) */ - 5210, /* 1D47C (119932) */ - 5211, /* 1D47D (119933) */ - 5212, /* 1D47E (119934) */ - 5213, /* 1D47F (119935) */ - 5214, /* 1D480 (119936) */ + 5237, /* 1D47A (119930) */ + 5238, /* 1D47B (119931) */ + 5239, /* 1D47C (119932) */ + 5240, /* 1D47D (119933) */ + 5241, /* 1D47E (119934) */ + 5242, /* 1D47F (119935) */ + 5243, /* 1D480 (119936) */ 1751, /* 1D481 (119937) */ - 5243, /* 1D482 (119938) */ - 5244, /* 1D483 (119939) */ - 5245, /* 1D484 (119940) */ + 5272, /* 1D482 (119938) */ + 5273, /* 1D483 (119939) */ + 5274, /* 1D484 (119940) */ 1774, /* 1D485 (119941) */ 1756, /* 1D486 (119942) */ - 5246, /* 1D487 (119943) */ + 5275, /* 1D487 (119943) */ 1736, /* 1D488 (119944) */ 1738, /* 1D489 (119945) */ 1766, /* 1D48A (119946) */ 1775, /* 1D48B (119947) */ - 5247, /* 1D48C (119948) */ + 5276, /* 1D48C (119948) */ 1742, /* 1D48D (119949) */ - 5248, /* 1D48E (119950) */ - 5249, /* 1D48F (119951) */ + 5277, /* 1D48E (119950) */ + 5278, /* 1D48F (119951) */ 1761, /* 1D490 (119952) */ - 5250, /* 1D491 (119953) */ - 5251, /* 1D492 (119954) */ - 5252, /* 1D493 (119955) */ - 5253, /* 1D494 (119956) */ - 5254, /* 1D495 (119957) */ - 5255, /* 1D496 (119958) */ - 5256, /* 1D497 (119959) */ - 5257, /* 1D498 (119960) */ - 5258, /* 1D499 (119961) */ - 5259, /* 1D49A (119962) */ - 5260, /* 1D49B (119963) */ - 5203, /* 1D49C (119964) */ + 5279, /* 1D491 (119953) */ + 5280, /* 1D492 (119954) */ + 5281, /* 1D493 (119955) */ + 5282, /* 1D494 (119956) */ + 5283, /* 1D495 (119957) */ + 5284, /* 1D496 (119958) */ + 5285, /* 1D497 (119959) */ + 5286, /* 1D498 (119960) */ + 5287, /* 1D499 (119961) */ + 5288, /* 1D49A (119962) */ + 5289, /* 1D49B (119963) */ + 5232, /* 1D49C (119964) */ 56, /* 1D49D (119965) */ 1730, /* 1D49E (119966) */ 1773, /* 1D49F (119967) */ 56, /* 1D4A0 (119968) */ 56, /* 1D4A1 (119969) */ - 5204, /* 1D4A2 (119970) */ + 5233, /* 1D4A2 (119970) */ 56, /* 1D4A3 (119971) */ 56, /* 1D4A4 (119972) */ - 5205, /* 1D4A5 (119973) */ - 5206, /* 1D4A6 (119974) */ + 5234, /* 1D4A5 (119973) */ + 5235, /* 1D4A6 (119974) */ 56, /* 1D4A7 (119975) */ 56, /* 1D4A8 (119976) */ 1743, /* 1D4A9 (119977) */ - 5207, /* 1D4AA (119978) */ + 5236, /* 1D4AA (119978) */ 1745, /* 1D4AB (119979) */ 1746, /* 1D4AC (119980) */ 56, /* 1D4AD (119981) */ - 5208, /* 1D4AE (119982) */ - 5209, /* 1D4AF (119983) */ - 5210, /* 1D4B0 (119984) */ - 5211, /* 1D4B1 (119985) */ - 5212, /* 1D4B2 (119986) */ - 5213, /* 1D4B3 (119987) */ - 5214, /* 1D4B4 (119988) */ + 5237, /* 1D4AE (119982) */ + 5238, /* 1D4AF (119983) */ + 5239, /* 1D4B0 (119984) */ + 5240, /* 1D4B1 (119985) */ + 5241, /* 1D4B2 (119986) */ + 5242, /* 1D4B3 (119987) */ + 5243, /* 1D4B4 (119988) */ 1751, /* 1D4B5 (119989) */ - 5243, /* 1D4B6 (119990) */ - 5244, /* 1D4B7 (119991) */ - 5245, /* 1D4B8 (119992) */ + 5272, /* 1D4B6 (119990) */ + 5273, /* 1D4B7 (119991) */ + 5274, /* 1D4B8 (119992) */ 1774, /* 1D4B9 (119993) */ 56, /* 1D4BA (119994) */ - 5246, /* 1D4BB (119995) */ + 5275, /* 1D4BB (119995) */ 56, /* 1D4BC (119996) */ 1738, /* 1D4BD (119997) */ 1766, /* 1D4BE (119998) */ 1775, /* 1D4BF (119999) */ - 5247, /* 1D4C0 (120000) */ + 5276, /* 1D4C0 (120000) */ 1742, /* 1D4C1 (120001) */ - 5248, /* 1D4C2 (120002) */ - 5249, /* 1D4C3 (120003) */ + 5277, /* 1D4C2 (120002) */ + 5278, /* 1D4C3 (120003) */ 56, /* 1D4C4 (120004) */ - 5250, /* 1D4C5 (120005) */ - 5251, /* 1D4C6 (120006) */ - 5252, /* 1D4C7 (120007) */ - 5253, /* 1D4C8 (120008) */ - 5254, /* 1D4C9 (120009) */ - 5255, /* 1D4CA (120010) */ - 5256, /* 1D4CB (120011) */ - 5257, /* 1D4CC (120012) */ - 5258, /* 1D4CD (120013) */ - 5259, /* 1D4CE (120014) */ - 5260, /* 1D4CF (120015) */ - 5203, /* 1D4D0 (120016) */ + 5279, /* 1D4C5 (120005) */ + 5280, /* 1D4C6 (120006) */ + 5281, /* 1D4C7 (120007) */ + 5282, /* 1D4C8 (120008) */ + 5283, /* 1D4C9 (120009) */ + 5284, /* 1D4CA (120010) */ + 5285, /* 1D4CB (120011) */ + 5286, /* 1D4CC (120012) */ + 5287, /* 1D4CD (120013) */ + 5288, /* 1D4CE (120014) */ + 5289, /* 1D4CF (120015) */ + 5232, /* 1D4D0 (120016) */ 1755, /* 1D4D1 (120017) */ 1730, /* 1D4D2 (120018) */ 1773, /* 1D4D3 (120019) */ 1757, /* 1D4D4 (120020) */ 1758, /* 1D4D5 (120021) */ - 5204, /* 1D4D6 (120022) */ + 5233, /* 1D4D6 (120022) */ 1737, /* 1D4D7 (120023) */ 1740, /* 1D4D8 (120024) */ - 5205, /* 1D4D9 (120025) */ - 5206, /* 1D4DA (120026) */ + 5234, /* 1D4D9 (120025) */ + 5235, /* 1D4DA (120026) */ 1741, /* 1D4DB (120027) */ 1760, /* 1D4DC (120028) */ 1743, /* 1D4DD (120029) */ - 5207, /* 1D4DE (120030) */ + 5236, /* 1D4DE (120030) */ 1745, /* 1D4DF (120031) */ 1746, /* 1D4E0 (120032) */ 1747, /* 1D4E1 (120033) */ - 5208, /* 1D4E2 (120034) */ - 5209, /* 1D4E3 (120035) */ - 5210, /* 1D4E4 (120036) */ - 5211, /* 1D4E5 (120037) */ - 5212, /* 1D4E6 (120038) */ - 5213, /* 1D4E7 (120039) */ - 5214, /* 1D4E8 (120040) */ + 5237, /* 1D4E2 (120034) */ + 5238, /* 1D4E3 (120035) */ + 5239, /* 1D4E4 (120036) */ + 5240, /* 1D4E5 (120037) */ + 5241, /* 1D4E6 (120038) */ + 5242, /* 1D4E7 (120039) */ + 5243, /* 1D4E8 (120040) */ 1751, /* 1D4E9 (120041) */ - 5243, /* 1D4EA (120042) */ - 5244, /* 1D4EB (120043) */ - 5245, /* 1D4EC (120044) */ + 5272, /* 1D4EA (120042) */ + 5273, /* 1D4EB (120043) */ + 5274, /* 1D4EC (120044) */ 1774, /* 1D4ED (120045) */ 1756, /* 1D4EE (120046) */ - 5246, /* 1D4EF (120047) */ + 5275, /* 1D4EF (120047) */ 1736, /* 1D4F0 (120048) */ 1738, /* 1D4F1 (120049) */ 1766, /* 1D4F2 (120050) */ 1775, /* 1D4F3 (120051) */ - 5247, /* 1D4F4 (120052) */ + 5276, /* 1D4F4 (120052) */ 1742, /* 1D4F5 (120053) */ - 5248, /* 1D4F6 (120054) */ - 5249, /* 1D4F7 (120055) */ + 5277, /* 1D4F6 (120054) */ + 5278, /* 1D4F7 (120055) */ 1761, /* 1D4F8 (120056) */ - 5250, /* 1D4F9 (120057) */ - 5251, /* 1D4FA (120058) */ - 5252, /* 1D4FB (120059) */ - 5253, /* 1D4FC (120060) */ - 5254, /* 1D4FD (120061) */ - 5255, /* 1D4FE (120062) */ - 5256, /* 1D4FF (120063) */ - 5257, /* 1D500 (120064) */ - 5258, /* 1D501 (120065) */ - 5259, /* 1D502 (120066) */ - 5260, /* 1D503 (120067) */ - 5203, /* 1D504 (120068) */ + 5279, /* 1D4F9 (120057) */ + 5280, /* 1D4FA (120058) */ + 5281, /* 1D4FB (120059) */ + 5282, /* 1D4FC (120060) */ + 5283, /* 1D4FD (120061) */ + 5284, /* 1D4FE (120062) */ + 5285, /* 1D4FF (120063) */ + 5286, /* 1D500 (120064) */ + 5287, /* 1D501 (120065) */ + 5288, /* 1D502 (120066) */ + 5289, /* 1D503 (120067) */ + 5232, /* 1D504 (120068) */ 1755, /* 1D505 (120069) */ 56, /* 1D506 (120070) */ 1773, /* 1D507 (120071) */ 1757, /* 1D508 (120072) */ 1758, /* 1D509 (120073) */ - 5204, /* 1D50A (120074) */ + 5233, /* 1D50A (120074) */ 56, /* 1D50B (120075) */ 56, /* 1D50C (120076) */ - 5205, /* 1D50D (120077) */ - 5206, /* 1D50E (120078) */ + 5234, /* 1D50D (120077) */ + 5235, /* 1D50E (120078) */ 1741, /* 1D50F (120079) */ 1760, /* 1D510 (120080) */ 1743, /* 1D511 (120081) */ - 5207, /* 1D512 (120082) */ + 5236, /* 1D512 (120082) */ 1745, /* 1D513 (120083) */ 1746, /* 1D514 (120084) */ 56, /* 1D515 (120085) */ - 5208, /* 1D516 (120086) */ - 5209, /* 1D517 (120087) */ - 5210, /* 1D518 (120088) */ - 5211, /* 1D519 (120089) */ - 5212, /* 1D51A (120090) */ - 5213, /* 1D51B (120091) */ - 5214, /* 1D51C (120092) */ + 5237, /* 1D516 (120086) */ + 5238, /* 1D517 (120087) */ + 5239, /* 1D518 (120088) */ + 5240, /* 1D519 (120089) */ + 5241, /* 1D51A (120090) */ + 5242, /* 1D51B (120091) */ + 5243, /* 1D51C (120092) */ 56, /* 1D51D (120093) */ - 5243, /* 1D51E (120094) */ - 5244, /* 1D51F (120095) */ - 5245, /* 1D520 (120096) */ + 5272, /* 1D51E (120094) */ + 5273, /* 1D51F (120095) */ + 5274, /* 1D520 (120096) */ 1774, /* 1D521 (120097) */ 1756, /* 1D522 (120098) */ - 5246, /* 1D523 (120099) */ + 5275, /* 1D523 (120099) */ 1736, /* 1D524 (120100) */ 1738, /* 1D525 (120101) */ 1766, /* 1D526 (120102) */ 1775, /* 1D527 (120103) */ - 5247, /* 1D528 (120104) */ + 5276, /* 1D528 (120104) */ 1742, /* 1D529 (120105) */ - 5248, /* 1D52A (120106) */ - 5249, /* 1D52B (120107) */ + 5277, /* 1D52A (120106) */ + 5278, /* 1D52B (120107) */ 1761, /* 1D52C (120108) */ - 5250, /* 1D52D (120109) */ - 5251, /* 1D52E (120110) */ - 5252, /* 1D52F (120111) */ - 5253, /* 1D530 (120112) */ - 5254, /* 1D531 (120113) */ - 5255, /* 1D532 (120114) */ - 5256, /* 1D533 (120115) */ - 5257, /* 1D534 (120116) */ - 5258, /* 1D535 (120117) */ - 5259, /* 1D536 (120118) */ - 5260, /* 1D537 (120119) */ - 5203, /* 1D538 (120120) */ + 5279, /* 1D52D (120109) */ + 5280, /* 1D52E (120110) */ + 5281, /* 1D52F (120111) */ + 5282, /* 1D530 (120112) */ + 5283, /* 1D531 (120113) */ + 5284, /* 1D532 (120114) */ + 5285, /* 1D533 (120115) */ + 5286, /* 1D534 (120116) */ + 5287, /* 1D535 (120117) */ + 5288, /* 1D536 (120118) */ + 5289, /* 1D537 (120119) */ + 5232, /* 1D538 (120120) */ 1755, /* 1D539 (120121) */ 56, /* 1D53A (120122) */ 1773, /* 1D53B (120123) */ 1757, /* 1D53C (120124) */ 1758, /* 1D53D (120125) */ - 5204, /* 1D53E (120126) */ + 5233, /* 1D53E (120126) */ 56, /* 1D53F (120127) */ 1740, /* 1D540 (120128) */ - 5205, /* 1D541 (120129) */ - 5206, /* 1D542 (120130) */ + 5234, /* 1D541 (120129) */ + 5235, /* 1D542 (120130) */ 1741, /* 1D543 (120131) */ 1760, /* 1D544 (120132) */ 56, /* 1D545 (120133) */ - 5207, /* 1D546 (120134) */ + 5236, /* 1D546 (120134) */ 56, /* 1D547 (120135) */ 56, /* 1D548 (120136) */ 56, /* 1D549 (120137) */ - 5208, /* 1D54A (120138) */ - 5209, /* 1D54B (120139) */ - 5210, /* 1D54C (120140) */ - 5211, /* 1D54D (120141) */ - 5212, /* 1D54E (120142) */ - 5213, /* 1D54F (120143) */ - 5214, /* 1D550 (120144) */ + 5237, /* 1D54A (120138) */ + 5238, /* 1D54B (120139) */ + 5239, /* 1D54C (120140) */ + 5240, /* 1D54D (120141) */ + 5241, /* 1D54E (120142) */ + 5242, /* 1D54F (120143) */ + 5243, /* 1D550 (120144) */ 56, /* 1D551 (120145) */ - 5243, /* 1D552 (120146) */ - 5244, /* 1D553 (120147) */ - 5245, /* 1D554 (120148) */ + 5272, /* 1D552 (120146) */ + 5273, /* 1D553 (120147) */ + 5274, /* 1D554 (120148) */ 1774, /* 1D555 (120149) */ 1756, /* 1D556 (120150) */ - 5246, /* 1D557 (120151) */ + 5275, /* 1D557 (120151) */ 1736, /* 1D558 (120152) */ 1738, /* 1D559 (120153) */ 1766, /* 1D55A (120154) */ 1775, /* 1D55B (120155) */ - 5247, /* 1D55C (120156) */ + 5276, /* 1D55C (120156) */ 1742, /* 1D55D (120157) */ - 5248, /* 1D55E (120158) */ - 5249, /* 1D55F (120159) */ + 5277, /* 1D55E (120158) */ + 5278, /* 1D55F (120159) */ 1761, /* 1D560 (120160) */ - 5250, /* 1D561 (120161) */ - 5251, /* 1D562 (120162) */ - 5252, /* 1D563 (120163) */ - 5253, /* 1D564 (120164) */ - 5254, /* 1D565 (120165) */ - 5255, /* 1D566 (120166) */ - 5256, /* 1D567 (120167) */ - 5257, /* 1D568 (120168) */ - 5258, /* 1D569 (120169) */ - 5259, /* 1D56A (120170) */ - 5260, /* 1D56B (120171) */ - 5203, /* 1D56C (120172) */ + 5279, /* 1D561 (120161) */ + 5280, /* 1D562 (120162) */ + 5281, /* 1D563 (120163) */ + 5282, /* 1D564 (120164) */ + 5283, /* 1D565 (120165) */ + 5284, /* 1D566 (120166) */ + 5285, /* 1D567 (120167) */ + 5286, /* 1D568 (120168) */ + 5287, /* 1D569 (120169) */ + 5288, /* 1D56A (120170) */ + 5289, /* 1D56B (120171) */ + 5232, /* 1D56C (120172) */ 1755, /* 1D56D (120173) */ 1730, /* 1D56E (120174) */ 1773, /* 1D56F (120175) */ 1757, /* 1D570 (120176) */ 1758, /* 1D571 (120177) */ - 5204, /* 1D572 (120178) */ + 5233, /* 1D572 (120178) */ 1737, /* 1D573 (120179) */ 1740, /* 1D574 (120180) */ - 5205, /* 1D575 (120181) */ - 5206, /* 1D576 (120182) */ + 5234, /* 1D575 (120181) */ + 5235, /* 1D576 (120182) */ 1741, /* 1D577 (120183) */ 1760, /* 1D578 (120184) */ 1743, /* 1D579 (120185) */ - 5207, /* 1D57A (120186) */ + 5236, /* 1D57A (120186) */ 1745, /* 1D57B (120187) */ 1746, /* 1D57C (120188) */ 1747, /* 1D57D (120189) */ - 5208, /* 1D57E (120190) */ - 5209, /* 1D57F (120191) */ - 5210, /* 1D580 (120192) */ - 5211, /* 1D581 (120193) */ - 5212, /* 1D582 (120194) */ - 5213, /* 1D583 (120195) */ - 5214, /* 1D584 (120196) */ + 5237, /* 1D57E (120190) */ + 5238, /* 1D57F (120191) */ + 5239, /* 1D580 (120192) */ + 5240, /* 1D581 (120193) */ + 5241, /* 1D582 (120194) */ + 5242, /* 1D583 (120195) */ + 5243, /* 1D584 (120196) */ 1751, /* 1D585 (120197) */ - 5243, /* 1D586 (120198) */ - 5244, /* 1D587 (120199) */ - 5245, /* 1D588 (120200) */ + 5272, /* 1D586 (120198) */ + 5273, /* 1D587 (120199) */ + 5274, /* 1D588 (120200) */ 1774, /* 1D589 (120201) */ 1756, /* 1D58A (120202) */ - 5246, /* 1D58B (120203) */ + 5275, /* 1D58B (120203) */ 1736, /* 1D58C (120204) */ 1738, /* 1D58D (120205) */ 1766, /* 1D58E (120206) */ 1775, /* 1D58F (120207) */ - 5247, /* 1D590 (120208) */ + 5276, /* 1D590 (120208) */ 1742, /* 1D591 (120209) */ - 5248, /* 1D592 (120210) */ - 5249, /* 1D593 (120211) */ + 5277, /* 1D592 (120210) */ + 5278, /* 1D593 (120211) */ 1761, /* 1D594 (120212) */ - 5250, /* 1D595 (120213) */ - 5251, /* 1D596 (120214) */ - 5252, /* 1D597 (120215) */ - 5253, /* 1D598 (120216) */ - 5254, /* 1D599 (120217) */ - 5255, /* 1D59A (120218) */ - 5256, /* 1D59B (120219) */ - 5257, /* 1D59C (120220) */ - 5258, /* 1D59D (120221) */ - 5259, /* 1D59E (120222) */ - 5260, /* 1D59F (120223) */ - 5203, /* 1D5A0 (120224) */ + 5279, /* 1D595 (120213) */ + 5280, /* 1D596 (120214) */ + 5281, /* 1D597 (120215) */ + 5282, /* 1D598 (120216) */ + 5283, /* 1D599 (120217) */ + 5284, /* 1D59A (120218) */ + 5285, /* 1D59B (120219) */ + 5286, /* 1D59C (120220) */ + 5287, /* 1D59D (120221) */ + 5288, /* 1D59E (120222) */ + 5289, /* 1D59F (120223) */ + 5232, /* 1D5A0 (120224) */ 1755, /* 1D5A1 (120225) */ 1730, /* 1D5A2 (120226) */ 1773, /* 1D5A3 (120227) */ 1757, /* 1D5A4 (120228) */ 1758, /* 1D5A5 (120229) */ - 5204, /* 1D5A6 (120230) */ + 5233, /* 1D5A6 (120230) */ 1737, /* 1D5A7 (120231) */ 1740, /* 1D5A8 (120232) */ - 5205, /* 1D5A9 (120233) */ - 5206, /* 1D5AA (120234) */ + 5234, /* 1D5A9 (120233) */ + 5235, /* 1D5AA (120234) */ 1741, /* 1D5AB (120235) */ 1760, /* 1D5AC (120236) */ 1743, /* 1D5AD (120237) */ - 5207, /* 1D5AE (120238) */ + 5236, /* 1D5AE (120238) */ 1745, /* 1D5AF (120239) */ 1746, /* 1D5B0 (120240) */ 1747, /* 1D5B1 (120241) */ - 5208, /* 1D5B2 (120242) */ - 5209, /* 1D5B3 (120243) */ - 5210, /* 1D5B4 (120244) */ - 5211, /* 1D5B5 (120245) */ - 5212, /* 1D5B6 (120246) */ - 5213, /* 1D5B7 (120247) */ - 5214, /* 1D5B8 (120248) */ + 5237, /* 1D5B2 (120242) */ + 5238, /* 1D5B3 (120243) */ + 5239, /* 1D5B4 (120244) */ + 5240, /* 1D5B5 (120245) */ + 5241, /* 1D5B6 (120246) */ + 5242, /* 1D5B7 (120247) */ + 5243, /* 1D5B8 (120248) */ 1751, /* 1D5B9 (120249) */ - 5243, /* 1D5BA (120250) */ - 5244, /* 1D5BB (120251) */ - 5245, /* 1D5BC (120252) */ + 5272, /* 1D5BA (120250) */ + 5273, /* 1D5BB (120251) */ + 5274, /* 1D5BC (120252) */ 1774, /* 1D5BD (120253) */ 1756, /* 1D5BE (120254) */ - 5246, /* 1D5BF (120255) */ + 5275, /* 1D5BF (120255) */ 1736, /* 1D5C0 (120256) */ 1738, /* 1D5C1 (120257) */ 1766, /* 1D5C2 (120258) */ 1775, /* 1D5C3 (120259) */ - 5247, /* 1D5C4 (120260) */ + 5276, /* 1D5C4 (120260) */ 1742, /* 1D5C5 (120261) */ - 5248, /* 1D5C6 (120262) */ - 5249, /* 1D5C7 (120263) */ + 5277, /* 1D5C6 (120262) */ + 5278, /* 1D5C7 (120263) */ 1761, /* 1D5C8 (120264) */ - 5250, /* 1D5C9 (120265) */ - 5251, /* 1D5CA (120266) */ - 5252, /* 1D5CB (120267) */ - 5253, /* 1D5CC (120268) */ - 5254, /* 1D5CD (120269) */ - 5255, /* 1D5CE (120270) */ - 5256, /* 1D5CF (120271) */ - 5257, /* 1D5D0 (120272) */ - 5258, /* 1D5D1 (120273) */ - 5259, /* 1D5D2 (120274) */ - 5260, /* 1D5D3 (120275) */ - 5203, /* 1D5D4 (120276) */ + 5279, /* 1D5C9 (120265) */ + 5280, /* 1D5CA (120266) */ + 5281, /* 1D5CB (120267) */ + 5282, /* 1D5CC (120268) */ + 5283, /* 1D5CD (120269) */ + 5284, /* 1D5CE (120270) */ + 5285, /* 1D5CF (120271) */ + 5286, /* 1D5D0 (120272) */ + 5287, /* 1D5D1 (120273) */ + 5288, /* 1D5D2 (120274) */ + 5289, /* 1D5D3 (120275) */ + 5232, /* 1D5D4 (120276) */ 1755, /* 1D5D5 (120277) */ 1730, /* 1D5D6 (120278) */ 1773, /* 1D5D7 (120279) */ 1757, /* 1D5D8 (120280) */ 1758, /* 1D5D9 (120281) */ - 5204, /* 1D5DA (120282) */ + 5233, /* 1D5DA (120282) */ 1737, /* 1D5DB (120283) */ 1740, /* 1D5DC (120284) */ - 5205, /* 1D5DD (120285) */ - 5206, /* 1D5DE (120286) */ + 5234, /* 1D5DD (120285) */ + 5235, /* 1D5DE (120286) */ 1741, /* 1D5DF (120287) */ 1760, /* 1D5E0 (120288) */ 1743, /* 1D5E1 (120289) */ - 5207, /* 1D5E2 (120290) */ + 5236, /* 1D5E2 (120290) */ 1745, /* 1D5E3 (120291) */ 1746, /* 1D5E4 (120292) */ 1747, /* 1D5E5 (120293) */ - 5208, /* 1D5E6 (120294) */ - 5209, /* 1D5E7 (120295) */ - 5210, /* 1D5E8 (120296) */ - 5211, /* 1D5E9 (120297) */ - 5212, /* 1D5EA (120298) */ - 5213, /* 1D5EB (120299) */ - 5214, /* 1D5EC (120300) */ + 5237, /* 1D5E6 (120294) */ + 5238, /* 1D5E7 (120295) */ + 5239, /* 1D5E8 (120296) */ + 5240, /* 1D5E9 (120297) */ + 5241, /* 1D5EA (120298) */ + 5242, /* 1D5EB (120299) */ + 5243, /* 1D5EC (120300) */ 1751, /* 1D5ED (120301) */ - 5243, /* 1D5EE (120302) */ - 5244, /* 1D5EF (120303) */ - 5245, /* 1D5F0 (120304) */ + 5272, /* 1D5EE (120302) */ + 5273, /* 1D5EF (120303) */ + 5274, /* 1D5F0 (120304) */ 1774, /* 1D5F1 (120305) */ 1756, /* 1D5F2 (120306) */ - 5246, /* 1D5F3 (120307) */ + 5275, /* 1D5F3 (120307) */ 1736, /* 1D5F4 (120308) */ 1738, /* 1D5F5 (120309) */ 1766, /* 1D5F6 (120310) */ 1775, /* 1D5F7 (120311) */ - 5247, /* 1D5F8 (120312) */ + 5276, /* 1D5F8 (120312) */ 1742, /* 1D5F9 (120313) */ - 5248, /* 1D5FA (120314) */ - 5249, /* 1D5FB (120315) */ + 5277, /* 1D5FA (120314) */ + 5278, /* 1D5FB (120315) */ 1761, /* 1D5FC (120316) */ - 5250, /* 1D5FD (120317) */ - 5251, /* 1D5FE (120318) */ - 5252, /* 1D5FF (120319) */ - 5253, /* 1D600 (120320) */ - 5254, /* 1D601 (120321) */ - 5255, /* 1D602 (120322) */ - 5256, /* 1D603 (120323) */ - 5257, /* 1D604 (120324) */ - 5258, /* 1D605 (120325) */ - 5259, /* 1D606 (120326) */ - 5260, /* 1D607 (120327) */ - 5203, /* 1D608 (120328) */ + 5279, /* 1D5FD (120317) */ + 5280, /* 1D5FE (120318) */ + 5281, /* 1D5FF (120319) */ + 5282, /* 1D600 (120320) */ + 5283, /* 1D601 (120321) */ + 5284, /* 1D602 (120322) */ + 5285, /* 1D603 (120323) */ + 5286, /* 1D604 (120324) */ + 5287, /* 1D605 (120325) */ + 5288, /* 1D606 (120326) */ + 5289, /* 1D607 (120327) */ + 5232, /* 1D608 (120328) */ 1755, /* 1D609 (120329) */ 1730, /* 1D60A (120330) */ 1773, /* 1D60B (120331) */ 1757, /* 1D60C (120332) */ 1758, /* 1D60D (120333) */ - 5204, /* 1D60E (120334) */ + 5233, /* 1D60E (120334) */ 1737, /* 1D60F (120335) */ 1740, /* 1D610 (120336) */ - 5205, /* 1D611 (120337) */ - 5206, /* 1D612 (120338) */ + 5234, /* 1D611 (120337) */ + 5235, /* 1D612 (120338) */ 1741, /* 1D613 (120339) */ 1760, /* 1D614 (120340) */ 1743, /* 1D615 (120341) */ - 5207, /* 1D616 (120342) */ + 5236, /* 1D616 (120342) */ 1745, /* 1D617 (120343) */ 1746, /* 1D618 (120344) */ 1747, /* 1D619 (120345) */ - 5208, /* 1D61A (120346) */ - 5209, /* 1D61B (120347) */ - 5210, /* 1D61C (120348) */ - 5211, /* 1D61D (120349) */ - 5212, /* 1D61E (120350) */ - 5213, /* 1D61F (120351) */ - 5214, /* 1D620 (120352) */ + 5237, /* 1D61A (120346) */ + 5238, /* 1D61B (120347) */ + 5239, /* 1D61C (120348) */ + 5240, /* 1D61D (120349) */ + 5241, /* 1D61E (120350) */ + 5242, /* 1D61F (120351) */ + 5243, /* 1D620 (120352) */ 1751, /* 1D621 (120353) */ - 5243, /* 1D622 (120354) */ - 5244, /* 1D623 (120355) */ - 5245, /* 1D624 (120356) */ + 5272, /* 1D622 (120354) */ + 5273, /* 1D623 (120355) */ + 5274, /* 1D624 (120356) */ 1774, /* 1D625 (120357) */ 1756, /* 1D626 (120358) */ - 5246, /* 1D627 (120359) */ + 5275, /* 1D627 (120359) */ 1736, /* 1D628 (120360) */ 1738, /* 1D629 (120361) */ 1766, /* 1D62A (120362) */ 1775, /* 1D62B (120363) */ - 5247, /* 1D62C (120364) */ + 5276, /* 1D62C (120364) */ 1742, /* 1D62D (120365) */ - 5248, /* 1D62E (120366) */ - 5249, /* 1D62F (120367) */ + 5277, /* 1D62E (120366) */ + 5278, /* 1D62F (120367) */ 1761, /* 1D630 (120368) */ - 5250, /* 1D631 (120369) */ - 5251, /* 1D632 (120370) */ - 5252, /* 1D633 (120371) */ - 5253, /* 1D634 (120372) */ - 5254, /* 1D635 (120373) */ - 5255, /* 1D636 (120374) */ - 5256, /* 1D637 (120375) */ - 5257, /* 1D638 (120376) */ - 5258, /* 1D639 (120377) */ - 5259, /* 1D63A (120378) */ - 5260, /* 1D63B (120379) */ - 5203, /* 1D63C (120380) */ + 5279, /* 1D631 (120369) */ + 5280, /* 1D632 (120370) */ + 5281, /* 1D633 (120371) */ + 5282, /* 1D634 (120372) */ + 5283, /* 1D635 (120373) */ + 5284, /* 1D636 (120374) */ + 5285, /* 1D637 (120375) */ + 5286, /* 1D638 (120376) */ + 5287, /* 1D639 (120377) */ + 5288, /* 1D63A (120378) */ + 5289, /* 1D63B (120379) */ + 5232, /* 1D63C (120380) */ 1755, /* 1D63D (120381) */ 1730, /* 1D63E (120382) */ 1773, /* 1D63F (120383) */ 1757, /* 1D640 (120384) */ 1758, /* 1D641 (120385) */ - 5204, /* 1D642 (120386) */ + 5233, /* 1D642 (120386) */ 1737, /* 1D643 (120387) */ 1740, /* 1D644 (120388) */ - 5205, /* 1D645 (120389) */ - 5206, /* 1D646 (120390) */ + 5234, /* 1D645 (120389) */ + 5235, /* 1D646 (120390) */ 1741, /* 1D647 (120391) */ 1760, /* 1D648 (120392) */ 1743, /* 1D649 (120393) */ - 5207, /* 1D64A (120394) */ + 5236, /* 1D64A (120394) */ 1745, /* 1D64B (120395) */ 1746, /* 1D64C (120396) */ 1747, /* 1D64D (120397) */ - 5208, /* 1D64E (120398) */ - 5209, /* 1D64F (120399) */ - 5210, /* 1D650 (120400) */ - 5211, /* 1D651 (120401) */ - 5212, /* 1D652 (120402) */ - 5213, /* 1D653 (120403) */ - 5214, /* 1D654 (120404) */ + 5237, /* 1D64E (120398) */ + 5238, /* 1D64F (120399) */ + 5239, /* 1D650 (120400) */ + 5240, /* 1D651 (120401) */ + 5241, /* 1D652 (120402) */ + 5242, /* 1D653 (120403) */ + 5243, /* 1D654 (120404) */ 1751, /* 1D655 (120405) */ - 5243, /* 1D656 (120406) */ - 5244, /* 1D657 (120407) */ - 5245, /* 1D658 (120408) */ + 5272, /* 1D656 (120406) */ + 5273, /* 1D657 (120407) */ + 5274, /* 1D658 (120408) */ 1774, /* 1D659 (120409) */ 1756, /* 1D65A (120410) */ - 5246, /* 1D65B (120411) */ + 5275, /* 1D65B (120411) */ 1736, /* 1D65C (120412) */ 1738, /* 1D65D (120413) */ 1766, /* 1D65E (120414) */ 1775, /* 1D65F (120415) */ - 5247, /* 1D660 (120416) */ + 5276, /* 1D660 (120416) */ 1742, /* 1D661 (120417) */ - 5248, /* 1D662 (120418) */ - 5249, /* 1D663 (120419) */ + 5277, /* 1D662 (120418) */ + 5278, /* 1D663 (120419) */ 1761, /* 1D664 (120420) */ - 5250, /* 1D665 (120421) */ - 5251, /* 1D666 (120422) */ - 5252, /* 1D667 (120423) */ - 5253, /* 1D668 (120424) */ - 5254, /* 1D669 (120425) */ - 5255, /* 1D66A (120426) */ - 5256, /* 1D66B (120427) */ - 5257, /* 1D66C (120428) */ - 5258, /* 1D66D (120429) */ - 5259, /* 1D66E (120430) */ - 5260, /* 1D66F (120431) */ - 5203, /* 1D670 (120432) */ + 5279, /* 1D665 (120421) */ + 5280, /* 1D666 (120422) */ + 5281, /* 1D667 (120423) */ + 5282, /* 1D668 (120424) */ + 5283, /* 1D669 (120425) */ + 5284, /* 1D66A (120426) */ + 5285, /* 1D66B (120427) */ + 5286, /* 1D66C (120428) */ + 5287, /* 1D66D (120429) */ + 5288, /* 1D66E (120430) */ + 5289, /* 1D66F (120431) */ + 5232, /* 1D670 (120432) */ 1755, /* 1D671 (120433) */ 1730, /* 1D672 (120434) */ 1773, /* 1D673 (120435) */ 1757, /* 1D674 (120436) */ 1758, /* 1D675 (120437) */ - 5204, /* 1D676 (120438) */ + 5233, /* 1D676 (120438) */ 1737, /* 1D677 (120439) */ 1740, /* 1D678 (120440) */ - 5205, /* 1D679 (120441) */ - 5206, /* 1D67A (120442) */ + 5234, /* 1D679 (120441) */ + 5235, /* 1D67A (120442) */ 1741, /* 1D67B (120443) */ 1760, /* 1D67C (120444) */ 1743, /* 1D67D (120445) */ - 5207, /* 1D67E (120446) */ + 5236, /* 1D67E (120446) */ 1745, /* 1D67F (120447) */ 1746, /* 1D680 (120448) */ 1747, /* 1D681 (120449) */ - 5208, /* 1D682 (120450) */ - 5209, /* 1D683 (120451) */ - 5210, /* 1D684 (120452) */ - 5211, /* 1D685 (120453) */ - 5212, /* 1D686 (120454) */ - 5213, /* 1D687 (120455) */ - 5214, /* 1D688 (120456) */ + 5237, /* 1D682 (120450) */ + 5238, /* 1D683 (120451) */ + 5239, /* 1D684 (120452) */ + 5240, /* 1D685 (120453) */ + 5241, /* 1D686 (120454) */ + 5242, /* 1D687 (120455) */ + 5243, /* 1D688 (120456) */ 1751, /* 1D689 (120457) */ - 5243, /* 1D68A (120458) */ - 5244, /* 1D68B (120459) */ - 5245, /* 1D68C (120460) */ + 5272, /* 1D68A (120458) */ + 5273, /* 1D68B (120459) */ + 5274, /* 1D68C (120460) */ 1774, /* 1D68D (120461) */ 1756, /* 1D68E (120462) */ - 5246, /* 1D68F (120463) */ + 5275, /* 1D68F (120463) */ 1736, /* 1D690 (120464) */ 1738, /* 1D691 (120465) */ 1766, /* 1D692 (120466) */ 1775, /* 1D693 (120467) */ - 5247, /* 1D694 (120468) */ + 5276, /* 1D694 (120468) */ 1742, /* 1D695 (120469) */ - 5248, /* 1D696 (120470) */ - 5249, /* 1D697 (120471) */ + 5277, /* 1D696 (120470) */ + 5278, /* 1D697 (120471) */ 1761, /* 1D698 (120472) */ - 5250, /* 1D699 (120473) */ - 5251, /* 1D69A (120474) */ - 5252, /* 1D69B (120475) */ - 5253, /* 1D69C (120476) */ - 5254, /* 1D69D (120477) */ - 5255, /* 1D69E (120478) */ - 5256, /* 1D69F (120479) */ - 5257, /* 1D6A0 (120480) */ - 5258, /* 1D6A1 (120481) */ - 5259, /* 1D6A2 (120482) */ - 5260, /* 1D6A3 (120483) */ - 5261, /* 1D6A4 (120484) */ - 5262, /* 1D6A5 (120485) */ + 5279, /* 1D699 (120473) */ + 5280, /* 1D69A (120474) */ + 5281, /* 1D69B (120475) */ + 5282, /* 1D69C (120476) */ + 5283, /* 1D69D (120477) */ + 5284, /* 1D69E (120478) */ + 5285, /* 1D69F (120479) */ + 5286, /* 1D6A0 (120480) */ + 5287, /* 1D6A1 (120481) */ + 5288, /* 1D6A2 (120482) */ + 5289, /* 1D6A3 (120483) */ + 5290, /* 1D6A4 (120484) */ + 5291, /* 1D6A5 (120485) */ 56, /* 1D6A6 (120486) */ 56, /* 1D6A7 (120487) */ - 5263, /* 1D6A8 (120488) */ - 5264, /* 1D6A9 (120489) */ + 5292, /* 1D6A8 (120488) */ + 5293, /* 1D6A9 (120489) */ 1770, /* 1D6AA (120490) */ - 5265, /* 1D6AB (120491) */ - 5266, /* 1D6AC (120492) */ - 5267, /* 1D6AD (120493) */ - 5268, /* 1D6AE (120494) */ - 5269, /* 1D6AF (120495) */ - 5270, /* 1D6B0 (120496) */ - 5271, /* 1D6B1 (120497) */ - 5272, /* 1D6B2 (120498) */ - 5273, /* 1D6B3 (120499) */ - 5274, /* 1D6B4 (120500) */ - 5275, /* 1D6B5 (120501) */ - 5276, /* 1D6B6 (120502) */ + 5294, /* 1D6AB (120491) */ + 5295, /* 1D6AC (120492) */ + 5296, /* 1D6AD (120493) */ + 5297, /* 1D6AE (120494) */ + 5298, /* 1D6AF (120495) */ + 5299, /* 1D6B0 (120496) */ + 5300, /* 1D6B1 (120497) */ + 5301, /* 1D6B2 (120498) */ + 5302, /* 1D6B3 (120499) */ + 5303, /* 1D6B4 (120500) */ + 5304, /* 1D6B5 (120501) */ + 5305, /* 1D6B6 (120502) */ 1771, /* 1D6B7 (120503) */ - 5277, /* 1D6B8 (120504) */ - 5278, /* 1D6B9 (120505) */ - 5279, /* 1D6BA (120506) */ - 5280, /* 1D6BB (120507) */ - 5281, /* 1D6BC (120508) */ - 5282, /* 1D6BD (120509) */ - 5283, /* 1D6BE (120510) */ - 5284, /* 1D6BF (120511) */ - 5285, /* 1D6C0 (120512) */ - 5286, /* 1D6C1 (120513) */ - 5287, /* 1D6C2 (120514) */ - 5288, /* 1D6C3 (120515) */ + 5306, /* 1D6B8 (120504) */ + 5307, /* 1D6B9 (120505) */ + 5308, /* 1D6BA (120506) */ + 5309, /* 1D6BB (120507) */ + 5310, /* 1D6BC (120508) */ + 5311, /* 1D6BD (120509) */ + 5312, /* 1D6BE (120510) */ + 5313, /* 1D6BF (120511) */ + 5314, /* 1D6C0 (120512) */ + 5315, /* 1D6C1 (120513) */ + 5316, /* 1D6C2 (120514) */ + 5317, /* 1D6C3 (120515) */ 1769, /* 1D6C4 (120516) */ - 5289, /* 1D6C5 (120517) */ - 5290, /* 1D6C6 (120518) */ - 5291, /* 1D6C7 (120519) */ - 5292, /* 1D6C8 (120520) */ - 5293, /* 1D6C9 (120521) */ - 5294, /* 1D6CA (120522) */ - 5295, /* 1D6CB (120523) */ - 5296, /* 1D6CC (120524) */ - 5297, /* 1D6CD (120525) */ - 5298, /* 1D6CE (120526) */ - 5299, /* 1D6CF (120527) */ - 5300, /* 1D6D0 (120528) */ + 5318, /* 1D6C5 (120517) */ + 5319, /* 1D6C6 (120518) */ + 5320, /* 1D6C7 (120519) */ + 5321, /* 1D6C8 (120520) */ + 5322, /* 1D6C9 (120521) */ + 5323, /* 1D6CA (120522) */ + 5324, /* 1D6CB (120523) */ + 5325, /* 1D6CC (120524) */ + 5326, /* 1D6CD (120525) */ + 5327, /* 1D6CE (120526) */ + 5328, /* 1D6CF (120527) */ + 5329, /* 1D6D0 (120528) */ 1768, /* 1D6D1 (120529) */ - 5301, /* 1D6D2 (120530) */ - 5302, /* 1D6D3 (120531) */ - 5303, /* 1D6D4 (120532) */ - 5304, /* 1D6D5 (120533) */ - 5305, /* 1D6D6 (120534) */ - 5306, /* 1D6D7 (120535) */ - 5307, /* 1D6D8 (120536) */ - 5308, /* 1D6D9 (120537) */ - 5309, /* 1D6DA (120538) */ - 5310, /* 1D6DB (120539) */ - 5311, /* 1D6DC (120540) */ - 5312, /* 1D6DD (120541) */ - 5313, /* 1D6DE (120542) */ - 5314, /* 1D6DF (120543) */ - 5315, /* 1D6E0 (120544) */ - 5316, /* 1D6E1 (120545) */ - 5263, /* 1D6E2 (120546) */ - 5264, /* 1D6E3 (120547) */ + 5330, /* 1D6D2 (120530) */ + 5331, /* 1D6D3 (120531) */ + 5332, /* 1D6D4 (120532) */ + 5333, /* 1D6D5 (120533) */ + 5334, /* 1D6D6 (120534) */ + 5335, /* 1D6D7 (120535) */ + 5336, /* 1D6D8 (120536) */ + 5337, /* 1D6D9 (120537) */ + 5338, /* 1D6DA (120538) */ + 5339, /* 1D6DB (120539) */ + 5340, /* 1D6DC (120540) */ + 5341, /* 1D6DD (120541) */ + 5342, /* 1D6DE (120542) */ + 5343, /* 1D6DF (120543) */ + 5344, /* 1D6E0 (120544) */ + 5345, /* 1D6E1 (120545) */ + 5292, /* 1D6E2 (120546) */ + 5293, /* 1D6E3 (120547) */ 1770, /* 1D6E4 (120548) */ - 5265, /* 1D6E5 (120549) */ - 5266, /* 1D6E6 (120550) */ - 5267, /* 1D6E7 (120551) */ - 5268, /* 1D6E8 (120552) */ - 5269, /* 1D6E9 (120553) */ - 5270, /* 1D6EA (120554) */ - 5271, /* 1D6EB (120555) */ - 5272, /* 1D6EC (120556) */ - 5273, /* 1D6ED (120557) */ - 5274, /* 1D6EE (120558) */ - 5275, /* 1D6EF (120559) */ - 5276, /* 1D6F0 (120560) */ + 5294, /* 1D6E5 (120549) */ + 5295, /* 1D6E6 (120550) */ + 5296, /* 1D6E7 (120551) */ + 5297, /* 1D6E8 (120552) */ + 5298, /* 1D6E9 (120553) */ + 5299, /* 1D6EA (120554) */ + 5300, /* 1D6EB (120555) */ + 5301, /* 1D6EC (120556) */ + 5302, /* 1D6ED (120557) */ + 5303, /* 1D6EE (120558) */ + 5304, /* 1D6EF (120559) */ + 5305, /* 1D6F0 (120560) */ 1771, /* 1D6F1 (120561) */ - 5277, /* 1D6F2 (120562) */ - 5317, /* 1D6F3 (120563) */ - 5279, /* 1D6F4 (120564) */ - 5280, /* 1D6F5 (120565) */ - 5281, /* 1D6F6 (120566) */ - 5282, /* 1D6F7 (120567) */ - 5283, /* 1D6F8 (120568) */ - 5284, /* 1D6F9 (120569) */ - 5285, /* 1D6FA (120570) */ - 5286, /* 1D6FB (120571) */ - 5287, /* 1D6FC (120572) */ - 5288, /* 1D6FD (120573) */ + 5306, /* 1D6F2 (120562) */ + 5346, /* 1D6F3 (120563) */ + 5308, /* 1D6F4 (120564) */ + 5309, /* 1D6F5 (120565) */ + 5310, /* 1D6F6 (120566) */ + 5311, /* 1D6F7 (120567) */ + 5312, /* 1D6F8 (120568) */ + 5313, /* 1D6F9 (120569) */ + 5314, /* 1D6FA (120570) */ + 5315, /* 1D6FB (120571) */ + 5316, /* 1D6FC (120572) */ + 5317, /* 1D6FD (120573) */ 1769, /* 1D6FE (120574) */ - 5289, /* 1D6FF (120575) */ - 5290, /* 1D700 (120576) */ - 5291, /* 1D701 (120577) */ - 5292, /* 1D702 (120578) */ - 5293, /* 1D703 (120579) */ - 5294, /* 1D704 (120580) */ - 5295, /* 1D705 (120581) */ - 5296, /* 1D706 (120582) */ - 5297, /* 1D707 (120583) */ - 5298, /* 1D708 (120584) */ - 5299, /* 1D709 (120585) */ - 5300, /* 1D70A (120586) */ + 5318, /* 1D6FF (120575) */ + 5319, /* 1D700 (120576) */ + 5320, /* 1D701 (120577) */ + 5321, /* 1D702 (120578) */ + 5322, /* 1D703 (120579) */ + 5323, /* 1D704 (120580) */ + 5324, /* 1D705 (120581) */ + 5325, /* 1D706 (120582) */ + 5326, /* 1D707 (120583) */ + 5327, /* 1D708 (120584) */ + 5328, /* 1D709 (120585) */ + 5329, /* 1D70A (120586) */ 1768, /* 1D70B (120587) */ - 5301, /* 1D70C (120588) */ - 5302, /* 1D70D (120589) */ - 5303, /* 1D70E (120590) */ - 5304, /* 1D70F (120591) */ - 5305, /* 1D710 (120592) */ - 5306, /* 1D711 (120593) */ - 5307, /* 1D712 (120594) */ - 5308, /* 1D713 (120595) */ - 5309, /* 1D714 (120596) */ - 5310, /* 1D715 (120597) */ - 5318, /* 1D716 (120598) */ - 5319, /* 1D717 (120599) */ - 5320, /* 1D718 (120600) */ - 5321, /* 1D719 (120601) */ - 5322, /* 1D71A (120602) */ - 5323, /* 1D71B (120603) */ - 5263, /* 1D71C (120604) */ - 5264, /* 1D71D (120605) */ + 5330, /* 1D70C (120588) */ + 5331, /* 1D70D (120589) */ + 5332, /* 1D70E (120590) */ + 5333, /* 1D70F (120591) */ + 5334, /* 1D710 (120592) */ + 5335, /* 1D711 (120593) */ + 5336, /* 1D712 (120594) */ + 5337, /* 1D713 (120595) */ + 5338, /* 1D714 (120596) */ + 5339, /* 1D715 (120597) */ + 5347, /* 1D716 (120598) */ + 5348, /* 1D717 (120599) */ + 5349, /* 1D718 (120600) */ + 5350, /* 1D719 (120601) */ + 5351, /* 1D71A (120602) */ + 5352, /* 1D71B (120603) */ + 5292, /* 1D71C (120604) */ + 5293, /* 1D71D (120605) */ 1770, /* 1D71E (120606) */ - 5265, /* 1D71F (120607) */ - 5266, /* 1D720 (120608) */ - 5267, /* 1D721 (120609) */ - 5268, /* 1D722 (120610) */ - 5269, /* 1D723 (120611) */ - 5270, /* 1D724 (120612) */ - 5271, /* 1D725 (120613) */ - 5272, /* 1D726 (120614) */ - 5273, /* 1D727 (120615) */ - 5274, /* 1D728 (120616) */ - 5275, /* 1D729 (120617) */ - 5276, /* 1D72A (120618) */ + 5294, /* 1D71F (120607) */ + 5295, /* 1D720 (120608) */ + 5296, /* 1D721 (120609) */ + 5297, /* 1D722 (120610) */ + 5298, /* 1D723 (120611) */ + 5299, /* 1D724 (120612) */ + 5300, /* 1D725 (120613) */ + 5301, /* 1D726 (120614) */ + 5302, /* 1D727 (120615) */ + 5303, /* 1D728 (120616) */ + 5304, /* 1D729 (120617) */ + 5305, /* 1D72A (120618) */ 1771, /* 1D72B (120619) */ - 5277, /* 1D72C (120620) */ - 5324, /* 1D72D (120621) */ - 5279, /* 1D72E (120622) */ - 5280, /* 1D72F (120623) */ - 5281, /* 1D730 (120624) */ - 5282, /* 1D731 (120625) */ - 5283, /* 1D732 (120626) */ - 5284, /* 1D733 (120627) */ - 5285, /* 1D734 (120628) */ - 5286, /* 1D735 (120629) */ - 5287, /* 1D736 (120630) */ - 5288, /* 1D737 (120631) */ + 5306, /* 1D72C (120620) */ + 5353, /* 1D72D (120621) */ + 5308, /* 1D72E (120622) */ + 5309, /* 1D72F (120623) */ + 5310, /* 1D730 (120624) */ + 5311, /* 1D731 (120625) */ + 5312, /* 1D732 (120626) */ + 5313, /* 1D733 (120627) */ + 5314, /* 1D734 (120628) */ + 5315, /* 1D735 (120629) */ + 5316, /* 1D736 (120630) */ + 5317, /* 1D737 (120631) */ 1769, /* 1D738 (120632) */ - 5289, /* 1D739 (120633) */ - 5290, /* 1D73A (120634) */ - 5291, /* 1D73B (120635) */ - 5292, /* 1D73C (120636) */ - 5293, /* 1D73D (120637) */ - 5294, /* 1D73E (120638) */ - 5295, /* 1D73F (120639) */ - 5296, /* 1D740 (120640) */ - 5297, /* 1D741 (120641) */ - 5298, /* 1D742 (120642) */ - 5299, /* 1D743 (120643) */ - 5300, /* 1D744 (120644) */ + 5318, /* 1D739 (120633) */ + 5319, /* 1D73A (120634) */ + 5320, /* 1D73B (120635) */ + 5321, /* 1D73C (120636) */ + 5322, /* 1D73D (120637) */ + 5323, /* 1D73E (120638) */ + 5324, /* 1D73F (120639) */ + 5325, /* 1D740 (120640) */ + 5326, /* 1D741 (120641) */ + 5327, /* 1D742 (120642) */ + 5328, /* 1D743 (120643) */ + 5329, /* 1D744 (120644) */ 1768, /* 1D745 (120645) */ - 5301, /* 1D746 (120646) */ - 5302, /* 1D747 (120647) */ - 5303, /* 1D748 (120648) */ - 5304, /* 1D749 (120649) */ - 5305, /* 1D74A (120650) */ - 5306, /* 1D74B (120651) */ - 5307, /* 1D74C (120652) */ - 5308, /* 1D74D (120653) */ - 5309, /* 1D74E (120654) */ - 5310, /* 1D74F (120655) */ - 5325, /* 1D750 (120656) */ - 5326, /* 1D751 (120657) */ - 5327, /* 1D752 (120658) */ - 5328, /* 1D753 (120659) */ - 5329, /* 1D754 (120660) */ - 5330, /* 1D755 (120661) */ - 5263, /* 1D756 (120662) */ - 5264, /* 1D757 (120663) */ + 5330, /* 1D746 (120646) */ + 5331, /* 1D747 (120647) */ + 5332, /* 1D748 (120648) */ + 5333, /* 1D749 (120649) */ + 5334, /* 1D74A (120650) */ + 5335, /* 1D74B (120651) */ + 5336, /* 1D74C (120652) */ + 5337, /* 1D74D (120653) */ + 5338, /* 1D74E (120654) */ + 5339, /* 1D74F (120655) */ + 5354, /* 1D750 (120656) */ + 5355, /* 1D751 (120657) */ + 5356, /* 1D752 (120658) */ + 5357, /* 1D753 (120659) */ + 5358, /* 1D754 (120660) */ + 5359, /* 1D755 (120661) */ + 5292, /* 1D756 (120662) */ + 5293, /* 1D757 (120663) */ 1770, /* 1D758 (120664) */ - 5265, /* 1D759 (120665) */ - 5266, /* 1D75A (120666) */ - 5267, /* 1D75B (120667) */ - 5268, /* 1D75C (120668) */ - 5269, /* 1D75D (120669) */ - 5270, /* 1D75E (120670) */ - 5271, /* 1D75F (120671) */ - 5272, /* 1D760 (120672) */ - 5273, /* 1D761 (120673) */ - 5274, /* 1D762 (120674) */ - 5275, /* 1D763 (120675) */ - 5276, /* 1D764 (120676) */ + 5294, /* 1D759 (120665) */ + 5295, /* 1D75A (120666) */ + 5296, /* 1D75B (120667) */ + 5297, /* 1D75C (120668) */ + 5298, /* 1D75D (120669) */ + 5299, /* 1D75E (120670) */ + 5300, /* 1D75F (120671) */ + 5301, /* 1D760 (120672) */ + 5302, /* 1D761 (120673) */ + 5303, /* 1D762 (120674) */ + 5304, /* 1D763 (120675) */ + 5305, /* 1D764 (120676) */ 1771, /* 1D765 (120677) */ - 5277, /* 1D766 (120678) */ - 5331, /* 1D767 (120679) */ - 5279, /* 1D768 (120680) */ - 5280, /* 1D769 (120681) */ - 5281, /* 1D76A (120682) */ - 5282, /* 1D76B (120683) */ - 5283, /* 1D76C (120684) */ - 5284, /* 1D76D (120685) */ - 5285, /* 1D76E (120686) */ - 5286, /* 1D76F (120687) */ - 5287, /* 1D770 (120688) */ - 5288, /* 1D771 (120689) */ + 5306, /* 1D766 (120678) */ + 5360, /* 1D767 (120679) */ + 5308, /* 1D768 (120680) */ + 5309, /* 1D769 (120681) */ + 5310, /* 1D76A (120682) */ + 5311, /* 1D76B (120683) */ + 5312, /* 1D76C (120684) */ + 5313, /* 1D76D (120685) */ + 5314, /* 1D76E (120686) */ + 5315, /* 1D76F (120687) */ + 5316, /* 1D770 (120688) */ + 5317, /* 1D771 (120689) */ 1769, /* 1D772 (120690) */ - 5289, /* 1D773 (120691) */ - 5290, /* 1D774 (120692) */ - 5291, /* 1D775 (120693) */ - 5292, /* 1D776 (120694) */ - 5293, /* 1D777 (120695) */ - 5294, /* 1D778 (120696) */ - 5295, /* 1D779 (120697) */ - 5296, /* 1D77A (120698) */ - 5297, /* 1D77B (120699) */ - 5298, /* 1D77C (120700) */ - 5299, /* 1D77D (120701) */ - 5300, /* 1D77E (120702) */ + 5318, /* 1D773 (120691) */ + 5319, /* 1D774 (120692) */ + 5320, /* 1D775 (120693) */ + 5321, /* 1D776 (120694) */ + 5322, /* 1D777 (120695) */ + 5323, /* 1D778 (120696) */ + 5324, /* 1D779 (120697) */ + 5325, /* 1D77A (120698) */ + 5326, /* 1D77B (120699) */ + 5327, /* 1D77C (120700) */ + 5328, /* 1D77D (120701) */ + 5329, /* 1D77E (120702) */ 1768, /* 1D77F (120703) */ - 5301, /* 1D780 (120704) */ - 5302, /* 1D781 (120705) */ - 5303, /* 1D782 (120706) */ - 5304, /* 1D783 (120707) */ - 5305, /* 1D784 (120708) */ - 5306, /* 1D785 (120709) */ - 5307, /* 1D786 (120710) */ - 5308, /* 1D787 (120711) */ - 5309, /* 1D788 (120712) */ - 5310, /* 1D789 (120713) */ - 5332, /* 1D78A (120714) */ - 5333, /* 1D78B (120715) */ - 5334, /* 1D78C (120716) */ - 5335, /* 1D78D (120717) */ - 5336, /* 1D78E (120718) */ - 5337, /* 1D78F (120719) */ - 5263, /* 1D790 (120720) */ - 5264, /* 1D791 (120721) */ + 5330, /* 1D780 (120704) */ + 5331, /* 1D781 (120705) */ + 5332, /* 1D782 (120706) */ + 5333, /* 1D783 (120707) */ + 5334, /* 1D784 (120708) */ + 5335, /* 1D785 (120709) */ + 5336, /* 1D786 (120710) */ + 5337, /* 1D787 (120711) */ + 5338, /* 1D788 (120712) */ + 5339, /* 1D789 (120713) */ + 5361, /* 1D78A (120714) */ + 5362, /* 1D78B (120715) */ + 5363, /* 1D78C (120716) */ + 5364, /* 1D78D (120717) */ + 5365, /* 1D78E (120718) */ + 5366, /* 1D78F (120719) */ + 5292, /* 1D790 (120720) */ + 5293, /* 1D791 (120721) */ 1770, /* 1D792 (120722) */ - 5265, /* 1D793 (120723) */ - 5266, /* 1D794 (120724) */ - 5267, /* 1D795 (120725) */ - 5268, /* 1D796 (120726) */ - 5269, /* 1D797 (120727) */ - 5270, /* 1D798 (120728) */ - 5271, /* 1D799 (120729) */ - 5272, /* 1D79A (120730) */ - 5273, /* 1D79B (120731) */ - 5274, /* 1D79C (120732) */ - 5275, /* 1D79D (120733) */ - 5276, /* 1D79E (120734) */ + 5294, /* 1D793 (120723) */ + 5295, /* 1D794 (120724) */ + 5296, /* 1D795 (120725) */ + 5297, /* 1D796 (120726) */ + 5298, /* 1D797 (120727) */ + 5299, /* 1D798 (120728) */ + 5300, /* 1D799 (120729) */ + 5301, /* 1D79A (120730) */ + 5302, /* 1D79B (120731) */ + 5303, /* 1D79C (120732) */ + 5304, /* 1D79D (120733) */ + 5305, /* 1D79E (120734) */ 1771, /* 1D79F (120735) */ - 5277, /* 1D7A0 (120736) */ - 5338, /* 1D7A1 (120737) */ - 5279, /* 1D7A2 (120738) */ - 5280, /* 1D7A3 (120739) */ - 5281, /* 1D7A4 (120740) */ - 5282, /* 1D7A5 (120741) */ - 5283, /* 1D7A6 (120742) */ - 5284, /* 1D7A7 (120743) */ - 5285, /* 1D7A8 (120744) */ - 5286, /* 1D7A9 (120745) */ - 5287, /* 1D7AA (120746) */ - 5288, /* 1D7AB (120747) */ + 5306, /* 1D7A0 (120736) */ + 5367, /* 1D7A1 (120737) */ + 5308, /* 1D7A2 (120738) */ + 5309, /* 1D7A3 (120739) */ + 5310, /* 1D7A4 (120740) */ + 5311, /* 1D7A5 (120741) */ + 5312, /* 1D7A6 (120742) */ + 5313, /* 1D7A7 (120743) */ + 5314, /* 1D7A8 (120744) */ + 5315, /* 1D7A9 (120745) */ + 5316, /* 1D7AA (120746) */ + 5317, /* 1D7AB (120747) */ 1769, /* 1D7AC (120748) */ - 5289, /* 1D7AD (120749) */ - 5290, /* 1D7AE (120750) */ - 5291, /* 1D7AF (120751) */ - 5292, /* 1D7B0 (120752) */ - 5293, /* 1D7B1 (120753) */ - 5294, /* 1D7B2 (120754) */ - 5295, /* 1D7B3 (120755) */ - 5296, /* 1D7B4 (120756) */ - 5297, /* 1D7B5 (120757) */ - 5298, /* 1D7B6 (120758) */ - 5299, /* 1D7B7 (120759) */ - 5300, /* 1D7B8 (120760) */ + 5318, /* 1D7AD (120749) */ + 5319, /* 1D7AE (120750) */ + 5320, /* 1D7AF (120751) */ + 5321, /* 1D7B0 (120752) */ + 5322, /* 1D7B1 (120753) */ + 5323, /* 1D7B2 (120754) */ + 5324, /* 1D7B3 (120755) */ + 5325, /* 1D7B4 (120756) */ + 5326, /* 1D7B5 (120757) */ + 5327, /* 1D7B6 (120758) */ + 5328, /* 1D7B7 (120759) */ + 5329, /* 1D7B8 (120760) */ 1768, /* 1D7B9 (120761) */ - 5301, /* 1D7BA (120762) */ - 5302, /* 1D7BB (120763) */ - 5303, /* 1D7BC (120764) */ - 5304, /* 1D7BD (120765) */ - 5305, /* 1D7BE (120766) */ - 5306, /* 1D7BF (120767) */ - 5307, /* 1D7C0 (120768) */ - 5308, /* 1D7C1 (120769) */ - 5309, /* 1D7C2 (120770) */ - 5310, /* 1D7C3 (120771) */ - 5339, /* 1D7C4 (120772) */ - 5340, /* 1D7C5 (120773) */ - 5341, /* 1D7C6 (120774) */ - 5342, /* 1D7C7 (120775) */ - 5343, /* 1D7C8 (120776) */ - 5344, /* 1D7C9 (120777) */ - 5345, /* 1D7CA (120778) */ - 5346, /* 1D7CB (120779) */ + 5330, /* 1D7BA (120762) */ + 5331, /* 1D7BB (120763) */ + 5332, /* 1D7BC (120764) */ + 5333, /* 1D7BD (120765) */ + 5334, /* 1D7BE (120766) */ + 5335, /* 1D7BF (120767) */ + 5336, /* 1D7C0 (120768) */ + 5337, /* 1D7C1 (120769) */ + 5338, /* 1D7C2 (120770) */ + 5339, /* 1D7C3 (120771) */ + 5368, /* 1D7C4 (120772) */ + 5369, /* 1D7C5 (120773) */ + 5370, /* 1D7C6 (120774) */ + 5371, /* 1D7C7 (120775) */ + 5372, /* 1D7C8 (120776) */ + 5373, /* 1D7C9 (120777) */ + 5374, /* 1D7CA (120778) */ + 5375, /* 1D7CB (120779) */ 56, /* 1D7CC (120780) */ 56, /* 1D7CD (120781) */ - 5215, /* 1D7CE (120782) */ - 5216, /* 1D7CF (120783) */ - 5217, /* 1D7D0 (120784) */ - 5218, /* 1D7D1 (120785) */ - 5219, /* 1D7D2 (120786) */ - 5220, /* 1D7D3 (120787) */ - 5221, /* 1D7D4 (120788) */ - 5222, /* 1D7D5 (120789) */ - 5223, /* 1D7D6 (120790) */ - 5224, /* 1D7D7 (120791) */ - 5215, /* 1D7D8 (120792) */ - 5216, /* 1D7D9 (120793) */ - 5217, /* 1D7DA (120794) */ - 5218, /* 1D7DB (120795) */ - 5219, /* 1D7DC (120796) */ - 5220, /* 1D7DD (120797) */ - 5221, /* 1D7DE (120798) */ - 5222, /* 1D7DF (120799) */ - 5223, /* 1D7E0 (120800) */ - 5224, /* 1D7E1 (120801) */ - 5215, /* 1D7E2 (120802) */ - 5216, /* 1D7E3 (120803) */ - 5217, /* 1D7E4 (120804) */ - 5218, /* 1D7E5 (120805) */ - 5219, /* 1D7E6 (120806) */ - 5220, /* 1D7E7 (120807) */ - 5221, /* 1D7E8 (120808) */ - 5222, /* 1D7E9 (120809) */ - 5223, /* 1D7EA (120810) */ - 5224, /* 1D7EB (120811) */ - 5215, /* 1D7EC (120812) */ - 5216, /* 1D7ED (120813) */ - 5217, /* 1D7EE (120814) */ - 5218, /* 1D7EF (120815) */ - 5219, /* 1D7F0 (120816) */ - 5220, /* 1D7F1 (120817) */ - 5221, /* 1D7F2 (120818) */ - 5222, /* 1D7F3 (120819) */ - 5223, /* 1D7F4 (120820) */ - 5224, /* 1D7F5 (120821) */ - 5215, /* 1D7F6 (120822) */ - 5216, /* 1D7F7 (120823) */ - 5217, /* 1D7F8 (120824) */ - 5218, /* 1D7F9 (120825) */ - 5219, /* 1D7FA (120826) */ - 5220, /* 1D7FB (120827) */ - 5221, /* 1D7FC (120828) */ - 5222, /* 1D7FD (120829) */ - 5223, /* 1D7FE (120830) */ - 5224, /* 1D7FF (120831) */ + 5244, /* 1D7CE (120782) */ + 5245, /* 1D7CF (120783) */ + 5246, /* 1D7D0 (120784) */ + 5247, /* 1D7D1 (120785) */ + 5248, /* 1D7D2 (120786) */ + 5249, /* 1D7D3 (120787) */ + 5250, /* 1D7D4 (120788) */ + 5251, /* 1D7D5 (120789) */ + 5252, /* 1D7D6 (120790) */ + 5253, /* 1D7D7 (120791) */ + 5244, /* 1D7D8 (120792) */ + 5245, /* 1D7D9 (120793) */ + 5246, /* 1D7DA (120794) */ + 5247, /* 1D7DB (120795) */ + 5248, /* 1D7DC (120796) */ + 5249, /* 1D7DD (120797) */ + 5250, /* 1D7DE (120798) */ + 5251, /* 1D7DF (120799) */ + 5252, /* 1D7E0 (120800) */ + 5253, /* 1D7E1 (120801) */ + 5244, /* 1D7E2 (120802) */ + 5245, /* 1D7E3 (120803) */ + 5246, /* 1D7E4 (120804) */ + 5247, /* 1D7E5 (120805) */ + 5248, /* 1D7E6 (120806) */ + 5249, /* 1D7E7 (120807) */ + 5250, /* 1D7E8 (120808) */ + 5251, /* 1D7E9 (120809) */ + 5252, /* 1D7EA (120810) */ + 5253, /* 1D7EB (120811) */ + 5244, /* 1D7EC (120812) */ + 5245, /* 1D7ED (120813) */ + 5246, /* 1D7EE (120814) */ + 5247, /* 1D7EF (120815) */ + 5248, /* 1D7F0 (120816) */ + 5249, /* 1D7F1 (120817) */ + 5250, /* 1D7F2 (120818) */ + 5251, /* 1D7F3 (120819) */ + 5252, /* 1D7F4 (120820) */ + 5253, /* 1D7F5 (120821) */ + 5244, /* 1D7F6 (120822) */ + 5245, /* 1D7F7 (120823) */ + 5246, /* 1D7F8 (120824) */ + 5247, /* 1D7F9 (120825) */ + 5248, /* 1D7FA (120826) */ + 5249, /* 1D7FB (120827) */ + 5250, /* 1D7FC (120828) */ + 5251, /* 1D7FD (120829) */ + 5252, /* 1D7FE (120830) */ + 5253, /* 1D7FF (120831) */ 1, /* 1D800 (120832) */ 1, /* 1D801 (120833) */ 1, /* 1D802 (120834) */ @@ -100790,68 +101024,68 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E02D (122925) */ 56, /* 1E02E (122926) */ 56, /* 1E02F (122927) */ - 5347, /* 1E030 (122928) */ - 5348, /* 1E031 (122929) */ - 5349, /* 1E032 (122930) */ - 5350, /* 1E033 (122931) */ - 5351, /* 1E034 (122932) */ - 5352, /* 1E035 (122933) */ - 5353, /* 1E036 (122934) */ - 5354, /* 1E037 (122935) */ - 5355, /* 1E038 (122936) */ - 5356, /* 1E039 (122937) */ - 5357, /* 1E03A (122938) */ - 5358, /* 1E03B (122939) */ - 5359, /* 1E03C (122940) */ - 5360, /* 1E03D (122941) */ - 5361, /* 1E03E (122942) */ - 5362, /* 1E03F (122943) */ - 5363, /* 1E040 (122944) */ - 5364, /* 1E041 (122945) */ - 5365, /* 1E042 (122946) */ - 5366, /* 1E043 (122947) */ - 5367, /* 1E044 (122948) */ - 5368, /* 1E045 (122949) */ - 5369, /* 1E046 (122950) */ - 5370, /* 1E047 (122951) */ - 5371, /* 1E048 (122952) */ - 5372, /* 1E049 (122953) */ - 5373, /* 1E04A (122954) */ - 5374, /* 1E04B (122955) */ - 5375, /* 1E04C (122956) */ - 5376, /* 1E04D (122957) */ - 5377, /* 1E04E (122958) */ - 5378, /* 1E04F (122959) */ - 5379, /* 1E050 (122960) */ - 5380, /* 1E051 (122961) */ - 5381, /* 1E052 (122962) */ - 5382, /* 1E053 (122963) */ - 5383, /* 1E054 (122964) */ - 5384, /* 1E055 (122965) */ - 5385, /* 1E056 (122966) */ - 5386, /* 1E057 (122967) */ - 5387, /* 1E058 (122968) */ - 5388, /* 1E059 (122969) */ - 5389, /* 1E05A (122970) */ - 5390, /* 1E05B (122971) */ - 5391, /* 1E05C (122972) */ - 5392, /* 1E05D (122973) */ - 5393, /* 1E05E (122974) */ - 5394, /* 1E05F (122975) */ - 5395, /* 1E060 (122976) */ - 5396, /* 1E061 (122977) */ - 5397, /* 1E062 (122978) */ - 5398, /* 1E063 (122979) */ - 5399, /* 1E064 (122980) */ - 5400, /* 1E065 (122981) */ - 5401, /* 1E066 (122982) */ - 5402, /* 1E067 (122983) */ - 5403, /* 1E068 (122984) */ - 5404, /* 1E069 (122985) */ - 5405, /* 1E06A (122986) */ - 5406, /* 1E06B (122987) */ - 5407, /* 1E06C (122988) */ - 5408, /* 1E06D (122989) */ + 5376, /* 1E030 (122928) */ + 5377, /* 1E031 (122929) */ + 5378, /* 1E032 (122930) */ + 5379, /* 1E033 (122931) */ + 5380, /* 1E034 (122932) */ + 5381, /* 1E035 (122933) */ + 5382, /* 1E036 (122934) */ + 5383, /* 1E037 (122935) */ + 5384, /* 1E038 (122936) */ + 5385, /* 1E039 (122937) */ + 5386, /* 1E03A (122938) */ + 5387, /* 1E03B (122939) */ + 5388, /* 1E03C (122940) */ + 5389, /* 1E03D (122941) */ + 5390, /* 1E03E (122942) */ + 5391, /* 1E03F (122943) */ + 5392, /* 1E040 (122944) */ + 5393, /* 1E041 (122945) */ + 5394, /* 1E042 (122946) */ + 5395, /* 1E043 (122947) */ + 5396, /* 1E044 (122948) */ + 5397, /* 1E045 (122949) */ + 5398, /* 1E046 (122950) */ + 5399, /* 1E047 (122951) */ + 5400, /* 1E048 (122952) */ + 5401, /* 1E049 (122953) */ + 5402, /* 1E04A (122954) */ + 5403, /* 1E04B (122955) */ + 5404, /* 1E04C (122956) */ + 5405, /* 1E04D (122957) */ + 5406, /* 1E04E (122958) */ + 5407, /* 1E04F (122959) */ + 5408, /* 1E050 (122960) */ + 5409, /* 1E051 (122961) */ + 5410, /* 1E052 (122962) */ + 5411, /* 1E053 (122963) */ + 5412, /* 1E054 (122964) */ + 5413, /* 1E055 (122965) */ + 5414, /* 1E056 (122966) */ + 5415, /* 1E057 (122967) */ + 5416, /* 1E058 (122968) */ + 5417, /* 1E059 (122969) */ + 5418, /* 1E05A (122970) */ + 5419, /* 1E05B (122971) */ + 5420, /* 1E05C (122972) */ + 5421, /* 1E05D (122973) */ + 5422, /* 1E05E (122974) */ + 5423, /* 1E05F (122975) */ + 5424, /* 1E060 (122976) */ + 5425, /* 1E061 (122977) */ + 5426, /* 1E062 (122978) */ + 5427, /* 1E063 (122979) */ + 5428, /* 1E064 (122980) */ + 5429, /* 1E065 (122981) */ + 5430, /* 1E066 (122982) */ + 5431, /* 1E067 (122983) */ + 5432, /* 1E068 (122984) */ + 5433, /* 1E069 (122985) */ + 5434, /* 1E06A (122986) */ + 5435, /* 1E06B (122987) */ + 5436, /* 1E06C (122988) */ + 5437, /* 1E06D (122989) */ 56, /* 1E06E (122990) */ 56, /* 1E06F (122991) */ 56, /* 1E070 (122992) */ @@ -102470,60 +102704,60 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E6BD (124605) */ 56, /* 1E6BE (124606) */ 56, /* 1E6BF (124607) */ - 56, /* 1E6C0 (124608) */ - 56, /* 1E6C1 (124609) */ - 56, /* 1E6C2 (124610) */ - 56, /* 1E6C3 (124611) */ - 56, /* 1E6C4 (124612) */ - 56, /* 1E6C5 (124613) */ - 56, /* 1E6C6 (124614) */ - 56, /* 1E6C7 (124615) */ - 56, /* 1E6C8 (124616) */ - 56, /* 1E6C9 (124617) */ - 56, /* 1E6CA (124618) */ - 56, /* 1E6CB (124619) */ - 56, /* 1E6CC (124620) */ - 56, /* 1E6CD (124621) */ - 56, /* 1E6CE (124622) */ - 56, /* 1E6CF (124623) */ - 56, /* 1E6D0 (124624) */ - 56, /* 1E6D1 (124625) */ - 56, /* 1E6D2 (124626) */ - 56, /* 1E6D3 (124627) */ - 56, /* 1E6D4 (124628) */ - 56, /* 1E6D5 (124629) */ - 56, /* 1E6D6 (124630) */ - 56, /* 1E6D7 (124631) */ - 56, /* 1E6D8 (124632) */ - 56, /* 1E6D9 (124633) */ - 56, /* 1E6DA (124634) */ - 56, /* 1E6DB (124635) */ - 56, /* 1E6DC (124636) */ - 56, /* 1E6DD (124637) */ - 56, /* 1E6DE (124638) */ + 1, /* 1E6C0 (124608) */ + 1, /* 1E6C1 (124609) */ + 1, /* 1E6C2 (124610) */ + 1, /* 1E6C3 (124611) */ + 1, /* 1E6C4 (124612) */ + 1, /* 1E6C5 (124613) */ + 1, /* 1E6C6 (124614) */ + 1, /* 1E6C7 (124615) */ + 1, /* 1E6C8 (124616) */ + 1, /* 1E6C9 (124617) */ + 1, /* 1E6CA (124618) */ + 1, /* 1E6CB (124619) */ + 1, /* 1E6CC (124620) */ + 1, /* 1E6CD (124621) */ + 1, /* 1E6CE (124622) */ + 1, /* 1E6CF (124623) */ + 1, /* 1E6D0 (124624) */ + 1, /* 1E6D1 (124625) */ + 1, /* 1E6D2 (124626) */ + 1, /* 1E6D3 (124627) */ + 1, /* 1E6D4 (124628) */ + 1, /* 1E6D5 (124629) */ + 1, /* 1E6D6 (124630) */ + 1, /* 1E6D7 (124631) */ + 1, /* 1E6D8 (124632) */ + 1, /* 1E6D9 (124633) */ + 1, /* 1E6DA (124634) */ + 1, /* 1E6DB (124635) */ + 1, /* 1E6DC (124636) */ + 1, /* 1E6DD (124637) */ + 1, /* 1E6DE (124638) */ 56, /* 1E6DF (124639) */ - 56, /* 1E6E0 (124640) */ - 56, /* 1E6E1 (124641) */ - 56, /* 1E6E2 (124642) */ - 56, /* 1E6E3 (124643) */ - 56, /* 1E6E4 (124644) */ - 56, /* 1E6E5 (124645) */ - 56, /* 1E6E6 (124646) */ - 56, /* 1E6E7 (124647) */ - 56, /* 1E6E8 (124648) */ - 56, /* 1E6E9 (124649) */ - 56, /* 1E6EA (124650) */ - 56, /* 1E6EB (124651) */ - 56, /* 1E6EC (124652) */ - 56, /* 1E6ED (124653) */ - 56, /* 1E6EE (124654) */ - 56, /* 1E6EF (124655) */ - 56, /* 1E6F0 (124656) */ - 56, /* 1E6F1 (124657) */ - 56, /* 1E6F2 (124658) */ - 56, /* 1E6F3 (124659) */ - 56, /* 1E6F4 (124660) */ - 56, /* 1E6F5 (124661) */ + 1, /* 1E6E0 (124640) */ + 1, /* 1E6E1 (124641) */ + 1, /* 1E6E2 (124642) */ + 431, /* 1E6E3 (124643) */ + 1, /* 1E6E4 (124644) */ + 1, /* 1E6E5 (124645) */ + 431, /* 1E6E6 (124646) */ + 1, /* 1E6E7 (124647) */ + 1, /* 1E6E8 (124648) */ + 1, /* 1E6E9 (124649) */ + 1, /* 1E6EA (124650) */ + 1, /* 1E6EB (124651) */ + 1, /* 1E6EC (124652) */ + 1, /* 1E6ED (124653) */ + 431, /* 1E6EE (124654) */ + 431, /* 1E6EF (124655) */ + 1, /* 1E6F0 (124656) */ + 1, /* 1E6F1 (124657) */ + 1, /* 1E6F2 (124658) */ + 1, /* 1E6F3 (124659) */ + 1, /* 1E6F4 (124660) */ + 431, /* 1E6F5 (124661) */ 56, /* 1E6F6 (124662) */ 56, /* 1E6F7 (124663) */ 56, /* 1E6F8 (124664) */ @@ -102532,8 +102766,8 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E6FB (124667) */ 56, /* 1E6FC (124668) */ 56, /* 1E6FD (124669) */ - 56, /* 1E6FE (124670) */ - 56, /* 1E6FF (124671) */ + 1, /* 1E6FE (124670) */ + 1, /* 1E6FF (124671) */ 56, /* 1E700 (124672) */ 56, /* 1E701 (124673) */ 56, /* 1E702 (124674) */ @@ -103046,40 +103280,40 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E8FD (125181) */ 56, /* 1E8FE (125182) */ 56, /* 1E8FF (125183) */ - 5409, /* 1E900 (125184) */ - 5410, /* 1E901 (125185) */ - 5411, /* 1E902 (125186) */ - 5412, /* 1E903 (125187) */ - 5413, /* 1E904 (125188) */ - 5414, /* 1E905 (125189) */ - 5415, /* 1E906 (125190) */ - 5416, /* 1E907 (125191) */ - 5417, /* 1E908 (125192) */ - 5418, /* 1E909 (125193) */ - 5419, /* 1E90A (125194) */ - 5420, /* 1E90B (125195) */ - 5421, /* 1E90C (125196) */ - 5422, /* 1E90D (125197) */ - 5423, /* 1E90E (125198) */ - 5424, /* 1E90F (125199) */ - 5425, /* 1E910 (125200) */ - 5426, /* 1E911 (125201) */ - 5427, /* 1E912 (125202) */ - 5428, /* 1E913 (125203) */ - 5429, /* 1E914 (125204) */ - 5430, /* 1E915 (125205) */ - 5431, /* 1E916 (125206) */ - 5432, /* 1E917 (125207) */ - 5433, /* 1E918 (125208) */ - 5434, /* 1E919 (125209) */ - 5435, /* 1E91A (125210) */ - 5436, /* 1E91B (125211) */ - 5437, /* 1E91C (125212) */ - 5438, /* 1E91D (125213) */ - 5439, /* 1E91E (125214) */ - 5440, /* 1E91F (125215) */ - 5441, /* 1E920 (125216) */ - 5442, /* 1E921 (125217) */ + 5438, /* 1E900 (125184) */ + 5439, /* 1E901 (125185) */ + 5440, /* 1E902 (125186) */ + 5441, /* 1E903 (125187) */ + 5442, /* 1E904 (125188) */ + 5443, /* 1E905 (125189) */ + 5444, /* 1E906 (125190) */ + 5445, /* 1E907 (125191) */ + 5446, /* 1E908 (125192) */ + 5447, /* 1E909 (125193) */ + 5448, /* 1E90A (125194) */ + 5449, /* 1E90B (125195) */ + 5450, /* 1E90C (125196) */ + 5451, /* 1E90D (125197) */ + 5452, /* 1E90E (125198) */ + 5453, /* 1E90F (125199) */ + 5454, /* 1E910 (125200) */ + 5455, /* 1E911 (125201) */ + 5456, /* 1E912 (125202) */ + 5457, /* 1E913 (125203) */ + 5458, /* 1E914 (125204) */ + 5459, /* 1E915 (125205) */ + 5460, /* 1E916 (125206) */ + 5461, /* 1E917 (125207) */ + 5462, /* 1E918 (125208) */ + 5463, /* 1E919 (125209) */ + 5464, /* 1E91A (125210) */ + 5465, /* 1E91B (125211) */ + 5466, /* 1E91C (125212) */ + 5467, /* 1E91D (125213) */ + 5468, /* 1E91E (125214) */ + 5469, /* 1E91F (125215) */ + 5470, /* 1E920 (125216) */ + 5471, /* 1E921 (125217) */ 1, /* 1E922 (125218) */ 1, /* 1E923 (125219) */ 1, /* 1E924 (125220) */ @@ -104326,194 +104560,194 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1EDFD (126461) */ 56, /* 1EDFE (126462) */ 56, /* 1EDFF (126463) */ - 5443, /* 1EE00 (126464) */ - 5444, /* 1EE01 (126465) */ - 5445, /* 1EE02 (126466) */ - 5446, /* 1EE03 (126467) */ + 5472, /* 1EE00 (126464) */ + 5473, /* 1EE01 (126465) */ + 5474, /* 1EE02 (126466) */ + 5475, /* 1EE03 (126467) */ 56, /* 1EE04 (126468) */ - 5447, /* 1EE05 (126469) */ - 5448, /* 1EE06 (126470) */ - 5449, /* 1EE07 (126471) */ - 5450, /* 1EE08 (126472) */ - 5451, /* 1EE09 (126473) */ - 5452, /* 1EE0A (126474) */ - 5453, /* 1EE0B (126475) */ - 5454, /* 1EE0C (126476) */ - 5455, /* 1EE0D (126477) */ - 5456, /* 1EE0E (126478) */ - 5457, /* 1EE0F (126479) */ - 5458, /* 1EE10 (126480) */ - 5459, /* 1EE11 (126481) */ - 5460, /* 1EE12 (126482) */ - 5461, /* 1EE13 (126483) */ - 5462, /* 1EE14 (126484) */ - 5463, /* 1EE15 (126485) */ - 5464, /* 1EE16 (126486) */ - 5465, /* 1EE17 (126487) */ - 5466, /* 1EE18 (126488) */ - 5467, /* 1EE19 (126489) */ - 5468, /* 1EE1A (126490) */ - 5469, /* 1EE1B (126491) */ - 5470, /* 1EE1C (126492) */ - 5471, /* 1EE1D (126493) */ - 5472, /* 1EE1E (126494) */ - 5473, /* 1EE1F (126495) */ + 5476, /* 1EE05 (126469) */ + 5477, /* 1EE06 (126470) */ + 5478, /* 1EE07 (126471) */ + 5479, /* 1EE08 (126472) */ + 5480, /* 1EE09 (126473) */ + 5481, /* 1EE0A (126474) */ + 5482, /* 1EE0B (126475) */ + 5483, /* 1EE0C (126476) */ + 5484, /* 1EE0D (126477) */ + 5485, /* 1EE0E (126478) */ + 5486, /* 1EE0F (126479) */ + 5487, /* 1EE10 (126480) */ + 5488, /* 1EE11 (126481) */ + 5489, /* 1EE12 (126482) */ + 5490, /* 1EE13 (126483) */ + 5491, /* 1EE14 (126484) */ + 5492, /* 1EE15 (126485) */ + 5493, /* 1EE16 (126486) */ + 5494, /* 1EE17 (126487) */ + 5495, /* 1EE18 (126488) */ + 5496, /* 1EE19 (126489) */ + 5497, /* 1EE1A (126490) */ + 5498, /* 1EE1B (126491) */ + 5499, /* 1EE1C (126492) */ + 5500, /* 1EE1D (126493) */ + 5501, /* 1EE1E (126494) */ + 5502, /* 1EE1F (126495) */ 56, /* 1EE20 (126496) */ - 5444, /* 1EE21 (126497) */ - 5445, /* 1EE22 (126498) */ + 5473, /* 1EE21 (126497) */ + 5474, /* 1EE22 (126498) */ 56, /* 1EE23 (126499) */ - 5474, /* 1EE24 (126500) */ + 5503, /* 1EE24 (126500) */ 56, /* 1EE25 (126501) */ 56, /* 1EE26 (126502) */ - 5449, /* 1EE27 (126503) */ + 5478, /* 1EE27 (126503) */ 56, /* 1EE28 (126504) */ - 5451, /* 1EE29 (126505) */ - 5452, /* 1EE2A (126506) */ - 5453, /* 1EE2B (126507) */ - 5454, /* 1EE2C (126508) */ - 5455, /* 1EE2D (126509) */ - 5456, /* 1EE2E (126510) */ - 5457, /* 1EE2F (126511) */ - 5458, /* 1EE30 (126512) */ - 5459, /* 1EE31 (126513) */ - 5460, /* 1EE32 (126514) */ + 5480, /* 1EE29 (126505) */ + 5481, /* 1EE2A (126506) */ + 5482, /* 1EE2B (126507) */ + 5483, /* 1EE2C (126508) */ + 5484, /* 1EE2D (126509) */ + 5485, /* 1EE2E (126510) */ + 5486, /* 1EE2F (126511) */ + 5487, /* 1EE30 (126512) */ + 5488, /* 1EE31 (126513) */ + 5489, /* 1EE32 (126514) */ 56, /* 1EE33 (126515) */ - 5462, /* 1EE34 (126516) */ - 5463, /* 1EE35 (126517) */ - 5464, /* 1EE36 (126518) */ - 5465, /* 1EE37 (126519) */ + 5491, /* 1EE34 (126516) */ + 5492, /* 1EE35 (126517) */ + 5493, /* 1EE36 (126518) */ + 5494, /* 1EE37 (126519) */ 56, /* 1EE38 (126520) */ - 5467, /* 1EE39 (126521) */ + 5496, /* 1EE39 (126521) */ 56, /* 1EE3A (126522) */ - 5469, /* 1EE3B (126523) */ + 5498, /* 1EE3B (126523) */ 56, /* 1EE3C (126524) */ 56, /* 1EE3D (126525) */ 56, /* 1EE3E (126526) */ 56, /* 1EE3F (126527) */ 56, /* 1EE40 (126528) */ 56, /* 1EE41 (126529) */ - 5445, /* 1EE42 (126530) */ + 5474, /* 1EE42 (126530) */ 56, /* 1EE43 (126531) */ 56, /* 1EE44 (126532) */ 56, /* 1EE45 (126533) */ 56, /* 1EE46 (126534) */ - 5449, /* 1EE47 (126535) */ + 5478, /* 1EE47 (126535) */ 56, /* 1EE48 (126536) */ - 5451, /* 1EE49 (126537) */ + 5480, /* 1EE49 (126537) */ 56, /* 1EE4A (126538) */ - 5453, /* 1EE4B (126539) */ + 5482, /* 1EE4B (126539) */ 56, /* 1EE4C (126540) */ - 5455, /* 1EE4D (126541) */ - 5456, /* 1EE4E (126542) */ - 5457, /* 1EE4F (126543) */ + 5484, /* 1EE4D (126541) */ + 5485, /* 1EE4E (126542) */ + 5486, /* 1EE4F (126543) */ 56, /* 1EE50 (126544) */ - 5459, /* 1EE51 (126545) */ - 5460, /* 1EE52 (126546) */ + 5488, /* 1EE51 (126545) */ + 5489, /* 1EE52 (126546) */ 56, /* 1EE53 (126547) */ - 5462, /* 1EE54 (126548) */ + 5491, /* 1EE54 (126548) */ 56, /* 1EE55 (126549) */ 56, /* 1EE56 (126550) */ - 5465, /* 1EE57 (126551) */ + 5494, /* 1EE57 (126551) */ 56, /* 1EE58 (126552) */ - 5467, /* 1EE59 (126553) */ + 5496, /* 1EE59 (126553) */ 56, /* 1EE5A (126554) */ - 5469, /* 1EE5B (126555) */ + 5498, /* 1EE5B (126555) */ 56, /* 1EE5C (126556) */ - 5471, /* 1EE5D (126557) */ + 5500, /* 1EE5D (126557) */ 56, /* 1EE5E (126558) */ - 5473, /* 1EE5F (126559) */ + 5502, /* 1EE5F (126559) */ 56, /* 1EE60 (126560) */ - 5444, /* 1EE61 (126561) */ - 5445, /* 1EE62 (126562) */ + 5473, /* 1EE61 (126561) */ + 5474, /* 1EE62 (126562) */ 56, /* 1EE63 (126563) */ - 5474, /* 1EE64 (126564) */ + 5503, /* 1EE64 (126564) */ 56, /* 1EE65 (126565) */ 56, /* 1EE66 (126566) */ - 5449, /* 1EE67 (126567) */ - 5450, /* 1EE68 (126568) */ - 5451, /* 1EE69 (126569) */ - 5452, /* 1EE6A (126570) */ + 5478, /* 1EE67 (126567) */ + 5479, /* 1EE68 (126568) */ + 5480, /* 1EE69 (126569) */ + 5481, /* 1EE6A (126570) */ 56, /* 1EE6B (126571) */ - 5454, /* 1EE6C (126572) */ - 5455, /* 1EE6D (126573) */ - 5456, /* 1EE6E (126574) */ - 5457, /* 1EE6F (126575) */ - 5458, /* 1EE70 (126576) */ - 5459, /* 1EE71 (126577) */ - 5460, /* 1EE72 (126578) */ + 5483, /* 1EE6C (126572) */ + 5484, /* 1EE6D (126573) */ + 5485, /* 1EE6E (126574) */ + 5486, /* 1EE6F (126575) */ + 5487, /* 1EE70 (126576) */ + 5488, /* 1EE71 (126577) */ + 5489, /* 1EE72 (126578) */ 56, /* 1EE73 (126579) */ - 5462, /* 1EE74 (126580) */ - 5463, /* 1EE75 (126581) */ - 5464, /* 1EE76 (126582) */ - 5465, /* 1EE77 (126583) */ + 5491, /* 1EE74 (126580) */ + 5492, /* 1EE75 (126581) */ + 5493, /* 1EE76 (126582) */ + 5494, /* 1EE77 (126583) */ 56, /* 1EE78 (126584) */ - 5467, /* 1EE79 (126585) */ - 5468, /* 1EE7A (126586) */ - 5469, /* 1EE7B (126587) */ - 5470, /* 1EE7C (126588) */ + 5496, /* 1EE79 (126585) */ + 5497, /* 1EE7A (126586) */ + 5498, /* 1EE7B (126587) */ + 5499, /* 1EE7C (126588) */ 56, /* 1EE7D (126589) */ - 5472, /* 1EE7E (126590) */ + 5501, /* 1EE7E (126590) */ 56, /* 1EE7F (126591) */ - 5443, /* 1EE80 (126592) */ - 5444, /* 1EE81 (126593) */ - 5445, /* 1EE82 (126594) */ - 5446, /* 1EE83 (126595) */ - 5474, /* 1EE84 (126596) */ - 5447, /* 1EE85 (126597) */ - 5448, /* 1EE86 (126598) */ - 5449, /* 1EE87 (126599) */ - 5450, /* 1EE88 (126600) */ - 5451, /* 1EE89 (126601) */ + 5472, /* 1EE80 (126592) */ + 5473, /* 1EE81 (126593) */ + 5474, /* 1EE82 (126594) */ + 5475, /* 1EE83 (126595) */ + 5503, /* 1EE84 (126596) */ + 5476, /* 1EE85 (126597) */ + 5477, /* 1EE86 (126598) */ + 5478, /* 1EE87 (126599) */ + 5479, /* 1EE88 (126600) */ + 5480, /* 1EE89 (126601) */ 56, /* 1EE8A (126602) */ - 5453, /* 1EE8B (126603) */ - 5454, /* 1EE8C (126604) */ - 5455, /* 1EE8D (126605) */ - 5456, /* 1EE8E (126606) */ - 5457, /* 1EE8F (126607) */ - 5458, /* 1EE90 (126608) */ - 5459, /* 1EE91 (126609) */ - 5460, /* 1EE92 (126610) */ - 5461, /* 1EE93 (126611) */ - 5462, /* 1EE94 (126612) */ - 5463, /* 1EE95 (126613) */ - 5464, /* 1EE96 (126614) */ - 5465, /* 1EE97 (126615) */ - 5466, /* 1EE98 (126616) */ - 5467, /* 1EE99 (126617) */ - 5468, /* 1EE9A (126618) */ - 5469, /* 1EE9B (126619) */ + 5482, /* 1EE8B (126603) */ + 5483, /* 1EE8C (126604) */ + 5484, /* 1EE8D (126605) */ + 5485, /* 1EE8E (126606) */ + 5486, /* 1EE8F (126607) */ + 5487, /* 1EE90 (126608) */ + 5488, /* 1EE91 (126609) */ + 5489, /* 1EE92 (126610) */ + 5490, /* 1EE93 (126611) */ + 5491, /* 1EE94 (126612) */ + 5492, /* 1EE95 (126613) */ + 5493, /* 1EE96 (126614) */ + 5494, /* 1EE97 (126615) */ + 5495, /* 1EE98 (126616) */ + 5496, /* 1EE99 (126617) */ + 5497, /* 1EE9A (126618) */ + 5498, /* 1EE9B (126619) */ 56, /* 1EE9C (126620) */ 56, /* 1EE9D (126621) */ 56, /* 1EE9E (126622) */ 56, /* 1EE9F (126623) */ 56, /* 1EEA0 (126624) */ - 5444, /* 1EEA1 (126625) */ - 5445, /* 1EEA2 (126626) */ - 5446, /* 1EEA3 (126627) */ + 5473, /* 1EEA1 (126625) */ + 5474, /* 1EEA2 (126626) */ + 5475, /* 1EEA3 (126627) */ 56, /* 1EEA4 (126628) */ - 5447, /* 1EEA5 (126629) */ - 5448, /* 1EEA6 (126630) */ - 5449, /* 1EEA7 (126631) */ - 5450, /* 1EEA8 (126632) */ - 5451, /* 1EEA9 (126633) */ + 5476, /* 1EEA5 (126629) */ + 5477, /* 1EEA6 (126630) */ + 5478, /* 1EEA7 (126631) */ + 5479, /* 1EEA8 (126632) */ + 5480, /* 1EEA9 (126633) */ 56, /* 1EEAA (126634) */ - 5453, /* 1EEAB (126635) */ - 5454, /* 1EEAC (126636) */ - 5455, /* 1EEAD (126637) */ - 5456, /* 1EEAE (126638) */ - 5457, /* 1EEAF (126639) */ - 5458, /* 1EEB0 (126640) */ - 5459, /* 1EEB1 (126641) */ - 5460, /* 1EEB2 (126642) */ - 5461, /* 1EEB3 (126643) */ - 5462, /* 1EEB4 (126644) */ - 5463, /* 1EEB5 (126645) */ - 5464, /* 1EEB6 (126646) */ - 5465, /* 1EEB7 (126647) */ - 5466, /* 1EEB8 (126648) */ - 5467, /* 1EEB9 (126649) */ - 5468, /* 1EEBA (126650) */ - 5469, /* 1EEBB (126651) */ + 5482, /* 1EEAB (126635) */ + 5483, /* 1EEAC (126636) */ + 5484, /* 1EEAD (126637) */ + 5485, /* 1EEAE (126638) */ + 5486, /* 1EEAF (126639) */ + 5487, /* 1EEB0 (126640) */ + 5488, /* 1EEB1 (126641) */ + 5489, /* 1EEB2 (126642) */ + 5490, /* 1EEB3 (126643) */ + 5491, /* 1EEB4 (126644) */ + 5492, /* 1EEB5 (126645) */ + 5493, /* 1EEB6 (126646) */ + 5494, /* 1EEB7 (126647) */ + 5495, /* 1EEB8 (126648) */ + 5496, /* 1EEB9 (126649) */ + 5497, /* 1EEBA (126650) */ + 5498, /* 1EEBB (126651) */ 56, /* 1EEBC (126652) */ 56, /* 1EEBD (126653) */ 56, /* 1EEBE (126654) */ @@ -105094,86 +105328,86 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F0FD (127229) */ 56, /* 1F0FE (127230) */ 56, /* 1F0FF (127231) */ - 5475, /* 1F100 (127232) */ - 5476, /* 1F101 (127233) */ - 5477, /* 1F102 (127234) */ - 5478, /* 1F103 (127235) */ - 5479, /* 1F104 (127236) */ - 5480, /* 1F105 (127237) */ - 5481, /* 1F106 (127238) */ - 5482, /* 1F107 (127239) */ - 5483, /* 1F108 (127240) */ - 5484, /* 1F109 (127241) */ - 5485, /* 1F10A (127242) */ + 5504, /* 1F100 (127232) */ + 5505, /* 1F101 (127233) */ + 5506, /* 1F102 (127234) */ + 5507, /* 1F103 (127235) */ + 5508, /* 1F104 (127236) */ + 5509, /* 1F105 (127237) */ + 5510, /* 1F106 (127238) */ + 5511, /* 1F107 (127239) */ + 5512, /* 1F108 (127240) */ + 5513, /* 1F109 (127241) */ + 5514, /* 1F10A (127242) */ 1, /* 1F10B (127243) */ 1, /* 1F10C (127244) */ 1, /* 1F10D (127245) */ 1, /* 1F10E (127246) */ 1, /* 1F10F (127247) */ - 5486, /* 1F110 (127248) */ - 5487, /* 1F111 (127249) */ - 5488, /* 1F112 (127250) */ - 5489, /* 1F113 (127251) */ - 5490, /* 1F114 (127252) */ - 5491, /* 1F115 (127253) */ - 5492, /* 1F116 (127254) */ - 5493, /* 1F117 (127255) */ - 5494, /* 1F118 (127256) */ - 5495, /* 1F119 (127257) */ - 5496, /* 1F11A (127258) */ - 5497, /* 1F11B (127259) */ - 5498, /* 1F11C (127260) */ - 5499, /* 1F11D (127261) */ - 5500, /* 1F11E (127262) */ - 5501, /* 1F11F (127263) */ - 5502, /* 1F120 (127264) */ - 5503, /* 1F121 (127265) */ - 5504, /* 1F122 (127266) */ - 5505, /* 1F123 (127267) */ - 5506, /* 1F124 (127268) */ - 5507, /* 1F125 (127269) */ - 5508, /* 1F126 (127270) */ - 5509, /* 1F127 (127271) */ - 5510, /* 1F128 (127272) */ - 5511, /* 1F129 (127273) */ - 5512, /* 1F12A (127274) */ + 5515, /* 1F110 (127248) */ + 5516, /* 1F111 (127249) */ + 5517, /* 1F112 (127250) */ + 5518, /* 1F113 (127251) */ + 5519, /* 1F114 (127252) */ + 5520, /* 1F115 (127253) */ + 5521, /* 1F116 (127254) */ + 5522, /* 1F117 (127255) */ + 5523, /* 1F118 (127256) */ + 5524, /* 1F119 (127257) */ + 5525, /* 1F11A (127258) */ + 5526, /* 1F11B (127259) */ + 5527, /* 1F11C (127260) */ + 5528, /* 1F11D (127261) */ + 5529, /* 1F11E (127262) */ + 5530, /* 1F11F (127263) */ + 5531, /* 1F120 (127264) */ + 5532, /* 1F121 (127265) */ + 5533, /* 1F122 (127266) */ + 5534, /* 1F123 (127267) */ + 5535, /* 1F124 (127268) */ + 5536, /* 1F125 (127269) */ + 5537, /* 1F126 (127270) */ + 5538, /* 1F127 (127271) */ + 5539, /* 1F128 (127272) */ + 5540, /* 1F129 (127273) */ + 5541, /* 1F12A (127274) */ 2005, /* 1F12B (127275) */ 2020, /* 1F12C (127276) */ - 5513, /* 1F12D (127277) */ - 5514, /* 1F12E (127278) */ + 5542, /* 1F12D (127277) */ + 5543, /* 1F12E (127278) */ 1, /* 1F12F (127279) */ - 5515, /* 1F130 (127280) */ - 5516, /* 1F131 (127281) */ - 5517, /* 1F132 (127282) */ - 5518, /* 1F133 (127283) */ - 5519, /* 1F134 (127284) */ - 5520, /* 1F135 (127285) */ - 5521, /* 1F136 (127286) */ - 5522, /* 1F137 (127287) */ - 5523, /* 1F138 (127288) */ - 5524, /* 1F139 (127289) */ - 5525, /* 1F13A (127290) */ - 5526, /* 1F13B (127291) */ - 5527, /* 1F13C (127292) */ - 5528, /* 1F13D (127293) */ - 5529, /* 1F13E (127294) */ - 5530, /* 1F13F (127295) */ - 5531, /* 1F140 (127296) */ - 5532, /* 1F141 (127297) */ - 5533, /* 1F142 (127298) */ - 5534, /* 1F143 (127299) */ - 5535, /* 1F144 (127300) */ - 5536, /* 1F145 (127301) */ - 5537, /* 1F146 (127302) */ - 5538, /* 1F147 (127303) */ - 5539, /* 1F148 (127304) */ - 5540, /* 1F149 (127305) */ - 5541, /* 1F14A (127306) */ + 5544, /* 1F130 (127280) */ + 5545, /* 1F131 (127281) */ + 5546, /* 1F132 (127282) */ + 5547, /* 1F133 (127283) */ + 5548, /* 1F134 (127284) */ + 5549, /* 1F135 (127285) */ + 5550, /* 1F136 (127286) */ + 5551, /* 1F137 (127287) */ + 5552, /* 1F138 (127288) */ + 5553, /* 1F139 (127289) */ + 5554, /* 1F13A (127290) */ + 5555, /* 1F13B (127291) */ + 5556, /* 1F13C (127292) */ + 5557, /* 1F13D (127293) */ + 5558, /* 1F13E (127294) */ + 5559, /* 1F13F (127295) */ + 5560, /* 1F140 (127296) */ + 5561, /* 1F141 (127297) */ + 5562, /* 1F142 (127298) */ + 5563, /* 1F143 (127299) */ + 5564, /* 1F144 (127300) */ + 5565, /* 1F145 (127301) */ + 5566, /* 1F146 (127302) */ + 5567, /* 1F147 (127303) */ + 5568, /* 1F148 (127304) */ + 5569, /* 1F149 (127305) */ + 5570, /* 1F14A (127306) */ 3053, /* 1F14B (127307) */ - 5542, /* 1F14C (127308) */ - 5543, /* 1F14D (127309) */ - 5544, /* 1F14E (127310) */ - 5545, /* 1F14F (127311) */ + 5571, /* 1F14C (127308) */ + 5572, /* 1F14D (127309) */ + 5573, /* 1F14E (127310) */ + 5574, /* 1F14F (127311) */ 1, /* 1F150 (127312) */ 1, /* 1F151 (127313) */ 1, /* 1F152 (127314) */ @@ -105200,9 +105434,9 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F167 (127335) */ 1, /* 1F168 (127336) */ 1, /* 1F169 (127337) */ - 5546, /* 1F16A (127338) */ - 5547, /* 1F16B (127339) */ - 5548, /* 1F16C (127340) */ + 5575, /* 1F16A (127338) */ + 5576, /* 1F16B (127339) */ + 5577, /* 1F16C (127340) */ 1, /* 1F16D (127341) */ 1, /* 1F16E (127342) */ 1, /* 1F16F (127343) */ @@ -105238,7 +105472,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F18D (127373) */ 1, /* 1F18E (127374) */ 1, /* 1F18F (127375) */ - 5549, /* 1F190 (127376) */ + 5578, /* 1F190 (127376) */ 1, /* 1F191 (127377) */ 1, /* 1F192 (127378) */ 1, /* 1F193 (127379) */ @@ -105350,9 +105584,9 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F1FD (127485) */ 1, /* 1F1FE (127486) */ 1, /* 1F1FF (127487) */ - 5550, /* 1F200 (127488) */ - 5551, /* 1F201 (127489) */ - 5552, /* 1F202 (127490) */ + 5579, /* 1F200 (127488) */ + 5580, /* 1F201 (127489) */ + 5581, /* 1F202 (127490) */ 56, /* 1F203 (127491) */ 56, /* 1F204 (127492) */ 56, /* 1F205 (127493) */ @@ -105366,63 +105600,63 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F20D (127501) */ 56, /* 1F20E (127502) */ 56, /* 1F20F (127503) */ - 5553, /* 1F210 (127504) */ - 5554, /* 1F211 (127505) */ - 5555, /* 1F212 (127506) */ - 5556, /* 1F213 (127507) */ - 5557, /* 1F214 (127508) */ - 5558, /* 1F215 (127509) */ - 5559, /* 1F216 (127510) */ - 5560, /* 1F217 (127511) */ - 5561, /* 1F218 (127512) */ - 5562, /* 1F219 (127513) */ - 5563, /* 1F21A (127514) */ - 5564, /* 1F21B (127515) */ - 5565, /* 1F21C (127516) */ - 5566, /* 1F21D (127517) */ - 5567, /* 1F21E (127518) */ - 5568, /* 1F21F (127519) */ - 5569, /* 1F220 (127520) */ - 5570, /* 1F221 (127521) */ - 5571, /* 1F222 (127522) */ - 5572, /* 1F223 (127523) */ - 5573, /* 1F224 (127524) */ - 5574, /* 1F225 (127525) */ - 5575, /* 1F226 (127526) */ - 5576, /* 1F227 (127527) */ - 5577, /* 1F228 (127528) */ - 5578, /* 1F229 (127529) */ - 5579, /* 1F22A (127530) */ - 5580, /* 1F22B (127531) */ - 5581, /* 1F22C (127532) */ - 5582, /* 1F22D (127533) */ - 5583, /* 1F22E (127534) */ - 5584, /* 1F22F (127535) */ - 5585, /* 1F230 (127536) */ - 5586, /* 1F231 (127537) */ - 5587, /* 1F232 (127538) */ - 5588, /* 1F233 (127539) */ - 5589, /* 1F234 (127540) */ - 5590, /* 1F235 (127541) */ - 5591, /* 1F236 (127542) */ - 5592, /* 1F237 (127543) */ - 5593, /* 1F238 (127544) */ - 5594, /* 1F239 (127545) */ - 5595, /* 1F23A (127546) */ - 5596, /* 1F23B (127547) */ + 5582, /* 1F210 (127504) */ + 5583, /* 1F211 (127505) */ + 5584, /* 1F212 (127506) */ + 5585, /* 1F213 (127507) */ + 5586, /* 1F214 (127508) */ + 5587, /* 1F215 (127509) */ + 5588, /* 1F216 (127510) */ + 5589, /* 1F217 (127511) */ + 5590, /* 1F218 (127512) */ + 5591, /* 1F219 (127513) */ + 5592, /* 1F21A (127514) */ + 5593, /* 1F21B (127515) */ + 5594, /* 1F21C (127516) */ + 5595, /* 1F21D (127517) */ + 5596, /* 1F21E (127518) */ + 5597, /* 1F21F (127519) */ + 5598, /* 1F220 (127520) */ + 5599, /* 1F221 (127521) */ + 5600, /* 1F222 (127522) */ + 5601, /* 1F223 (127523) */ + 5602, /* 1F224 (127524) */ + 5603, /* 1F225 (127525) */ + 5604, /* 1F226 (127526) */ + 5605, /* 1F227 (127527) */ + 5606, /* 1F228 (127528) */ + 5607, /* 1F229 (127529) */ + 5608, /* 1F22A (127530) */ + 5609, /* 1F22B (127531) */ + 5610, /* 1F22C (127532) */ + 5611, /* 1F22D (127533) */ + 5612, /* 1F22E (127534) */ + 5613, /* 1F22F (127535) */ + 5614, /* 1F230 (127536) */ + 5615, /* 1F231 (127537) */ + 5616, /* 1F232 (127538) */ + 5617, /* 1F233 (127539) */ + 5618, /* 1F234 (127540) */ + 5619, /* 1F235 (127541) */ + 5620, /* 1F236 (127542) */ + 5621, /* 1F237 (127543) */ + 5622, /* 1F238 (127544) */ + 5623, /* 1F239 (127545) */ + 5624, /* 1F23A (127546) */ + 5625, /* 1F23B (127547) */ 56, /* 1F23C (127548) */ 56, /* 1F23D (127549) */ 56, /* 1F23E (127550) */ 56, /* 1F23F (127551) */ - 5597, /* 1F240 (127552) */ - 5598, /* 1F241 (127553) */ - 5599, /* 1F242 (127554) */ - 5600, /* 1F243 (127555) */ - 5601, /* 1F244 (127556) */ - 5602, /* 1F245 (127557) */ - 5603, /* 1F246 (127558) */ - 5604, /* 1F247 (127559) */ - 5605, /* 1F248 (127560) */ + 5626, /* 1F240 (127552) */ + 5627, /* 1F241 (127553) */ + 5628, /* 1F242 (127554) */ + 5629, /* 1F243 (127555) */ + 5630, /* 1F244 (127556) */ + 5631, /* 1F245 (127557) */ + 5632, /* 1F246 (127558) */ + 5633, /* 1F247 (127559) */ + 5634, /* 1F248 (127560) */ 56, /* 1F249 (127561) */ 56, /* 1F24A (127562) */ 56, /* 1F24B (127563) */ @@ -105430,8 +105664,8 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F24D (127565) */ 56, /* 1F24E (127566) */ 56, /* 1F24F (127567) */ - 5606, /* 1F250 (127568) */ - 5607, /* 1F251 (127569) */ + 5635, /* 1F250 (127568) */ + 5636, /* 1F251 (127569) */ 56, /* 1F252 (127570) */ 56, /* 1F253 (127571) */ 56, /* 1F254 (127572) */ @@ -106590,7 +106824,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F6D5 (128725) */ 1, /* 1F6D6 (128726) */ 1, /* 1F6D7 (128727) */ - 56, /* 1F6D8 (128728) */ + 1, /* 1F6D8 (128728) */ 56, /* 1F6D9 (128729) */ 56, /* 1F6DA (128730) */ 56, /* 1F6DB (128731) */ @@ -106749,10 +106983,10 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F774 (128884) */ 1, /* 1F775 (128885) */ 1, /* 1F776 (128886) */ - 56, /* 1F777 (128887) */ - 56, /* 1F778 (128888) */ - 56, /* 1F779 (128889) */ - 56, /* 1F77A (128890) */ + 1, /* 1F777 (128887) */ + 1, /* 1F778 (128888) */ + 1, /* 1F779 (128889) */ + 1, /* 1F77A (128890) */ 1, /* 1F77B (128891) */ 1, /* 1F77C (128892) */ 1, /* 1F77D (128893) */ @@ -107094,15 +107328,15 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F8CD (129229) */ 56, /* 1F8CE (129230) */ 56, /* 1F8CF (129231) */ - 56, /* 1F8D0 (129232) */ - 56, /* 1F8D1 (129233) */ - 56, /* 1F8D2 (129234) */ - 56, /* 1F8D3 (129235) */ - 56, /* 1F8D4 (129236) */ - 56, /* 1F8D5 (129237) */ - 56, /* 1F8D6 (129238) */ - 56, /* 1F8D7 (129239) */ - 56, /* 1F8D8 (129240) */ + 1, /* 1F8D0 (129232) */ + 1, /* 1F8D1 (129233) */ + 1, /* 1F8D2 (129234) */ + 1, /* 1F8D3 (129235) */ + 1, /* 1F8D4 (129236) */ + 1, /* 1F8D5 (129237) */ + 1, /* 1F8D6 (129238) */ + 1, /* 1F8D7 (129239) */ + 1, /* 1F8D8 (129240) */ 56, /* 1F8D9 (129241) */ 56, /* 1F8DA (129242) */ 56, /* 1F8DB (129243) */ @@ -107482,10 +107716,10 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FA51 (129617) */ 1, /* 1FA52 (129618) */ 1, /* 1FA53 (129619) */ - 56, /* 1FA54 (129620) */ - 56, /* 1FA55 (129621) */ - 56, /* 1FA56 (129622) */ - 56, /* 1FA57 (129623) */ + 1, /* 1FA54 (129620) */ + 1, /* 1FA55 (129621) */ + 1, /* 1FA56 (129622) */ + 1, /* 1FA57 (129623) */ 56, /* 1FA58 (129624) */ 56, /* 1FA59 (129625) */ 56, /* 1FA5A (129626) */ @@ -107536,11 +107770,11 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FA87 (129671) */ 1, /* 1FA88 (129672) */ 1, /* 1FA89 (129673) */ - 56, /* 1FA8A (129674) */ + 1, /* 1FA8A (129674) */ 56, /* 1FA8B (129675) */ 56, /* 1FA8C (129676) */ 56, /* 1FA8D (129677) */ - 56, /* 1FA8E (129678) */ + 1, /* 1FA8E (129678) */ 1, /* 1FA8F (129679) */ 1, /* 1FA90 (129680) */ 1, /* 1FA91 (129681) */ @@ -107598,12 +107832,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FAC5 (129733) */ 1, /* 1FAC6 (129734) */ 56, /* 1FAC7 (129735) */ - 56, /* 1FAC8 (129736) */ + 1, /* 1FAC8 (129736) */ 56, /* 1FAC9 (129737) */ 56, /* 1FACA (129738) */ 56, /* 1FACB (129739) */ 56, /* 1FACC (129740) */ - 56, /* 1FACD (129741) */ + 1, /* 1FACD (129741) */ 1, /* 1FACE (129742) */ 1, /* 1FACF (129743) */ 1, /* 1FAD0 (129744) */ @@ -107632,12 +107866,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FAE7 (129767) */ 1, /* 1FAE8 (129768) */ 1, /* 1FAE9 (129769) */ - 56, /* 1FAEA (129770) */ + 1, /* 1FAEA (129770) */ 56, /* 1FAEB (129771) */ 56, /* 1FAEC (129772) */ 56, /* 1FAED (129773) */ 56, /* 1FAEE (129774) */ - 56, /* 1FAEF (129775) */ + 1, /* 1FAEF (129775) */ 1, /* 1FAF0 (129776) */ 1, /* 1FAF1 (129777) */ 1, /* 1FAF2 (129778) */ @@ -107894,17 +108128,17 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FBED (130029) */ 1, /* 1FBEE (130030) */ 1, /* 1FBEF (130031) */ - 5215, /* 1FBF0 (130032) */ - 5216, /* 1FBF1 (130033) */ - 5217, /* 1FBF2 (130034) */ - 5218, /* 1FBF3 (130035) */ - 5219, /* 1FBF4 (130036) */ - 5220, /* 1FBF5 (130037) */ - 5221, /* 1FBF6 (130038) */ - 5222, /* 1FBF7 (130039) */ - 5223, /* 1FBF8 (130040) */ - 5224, /* 1FBF9 (130041) */ - 56, /* 1FBFA (130042) */ + 5244, /* 1FBF0 (130032) */ + 5245, /* 1FBF1 (130033) */ + 5246, /* 1FBF2 (130034) */ + 5247, /* 1FBF3 (130035) */ + 5248, /* 1FBF4 (130036) */ + 5249, /* 1FBF5 (130037) */ + 5250, /* 1FBF6 (130038) */ + 5251, /* 1FBF7 (130039) */ + 5252, /* 1FBF8 (130040) */ + 5253, /* 1FBF9 (130041) */ + 1, /* 1FBFA (130042) */ 56, /* 1FBFB (130043) */ 56, /* 1FBFC (130044) */ 56, /* 1FBFD (130045) */ @@ -155840,12 +156074,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 2B737 (177975) */ 1, /* 2B738 (177976) */ 1, /* 2B739 (177977) */ - 56, /* 2B73A (177978) */ - 56, /* 2B73B (177979) */ - 56, /* 2B73C (177980) */ - 56, /* 2B73D (177981) */ - 56, /* 2B73E (177982) */ - 56, /* 2B73F (177983) */ + 1, /* 2B73A (177978) */ + 1, /* 2B73B (177979) */ + 1, /* 2B73C (177980) */ + 1, /* 2B73D (177981) */ + 1, /* 2B73E (177982) */ + 1, /* 2B73F (177983) */ 1, /* 2B740 (177984) */ 1, /* 2B741 (177985) */ 1, /* 2B742 (177986) */ @@ -161832,18 +162066,18 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 2CE9F (183967) */ 1, /* 2CEA0 (183968) */ 1, /* 2CEA1 (183969) */ - 56, /* 2CEA2 (183970) */ - 56, /* 2CEA3 (183971) */ - 56, /* 2CEA4 (183972) */ - 56, /* 2CEA5 (183973) */ - 56, /* 2CEA6 (183974) */ - 56, /* 2CEA7 (183975) */ - 56, /* 2CEA8 (183976) */ - 56, /* 2CEA9 (183977) */ - 56, /* 2CEAA (183978) */ - 56, /* 2CEAB (183979) */ - 56, /* 2CEAC (183980) */ - 56, /* 2CEAD (183981) */ + 1, /* 2CEA2 (183970) */ + 1, /* 2CEA3 (183971) */ + 1, /* 2CEA4 (183972) */ + 1, /* 2CEA5 (183973) */ + 1, /* 2CEA6 (183974) */ + 1, /* 2CEA7 (183975) */ + 1, /* 2CEA8 (183976) */ + 1, /* 2CEA9 (183977) */ + 1, /* 2CEAA (183978) */ + 1, /* 2CEAB (183979) */ + 1, /* 2CEAC (183980) */ + 1, /* 2CEAD (183981) */ 56, /* 2CEAE (183982) */ 56, /* 2CEAF (183983) */ 1, /* 2CEB0 (183984) */ @@ -172422,548 +172656,548 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 2F7FD (194557) */ 56, /* 2F7FE (194558) */ 56, /* 2F7FF (194559) */ - 5608, /* 2F800 (194560) */ - 5609, /* 2F801 (194561) */ - 5610, /* 2F802 (194562) */ - 5611, /* 2F803 (194563) */ - 5612, /* 2F804 (194564) */ - 3630, /* 2F805 (194565) */ - 5613, /* 2F806 (194566) */ - 5614, /* 2F807 (194567) */ - 5615, /* 2F808 (194568) */ - 5616, /* 2F809 (194569) */ - 3631, /* 2F80A (194570) */ - 5617, /* 2F80B (194571) */ - 5618, /* 2F80C (194572) */ - 5619, /* 2F80D (194573) */ - 3632, /* 2F80E (194574) */ - 5620, /* 2F80F (194575) */ - 5621, /* 2F810 (194576) */ - 5622, /* 2F811 (194577) */ - 5623, /* 2F812 (194578) */ - 5624, /* 2F813 (194579) */ - 5625, /* 2F814 (194580) */ - 5626, /* 2F815 (194581) */ - 5627, /* 2F816 (194582) */ - 5628, /* 2F817 (194583) */ - 5629, /* 2F818 (194584) */ - 5630, /* 2F819 (194585) */ - 5631, /* 2F81A (194586) */ - 3690, /* 2F81B (194587) */ - 5632, /* 2F81C (194588) */ - 5633, /* 2F81D (194589) */ - 5634, /* 2F81E (194590) */ - 5635, /* 2F81F (194591) */ - 5636, /* 2F820 (194592) */ - 5637, /* 2F821 (194593) */ - 5638, /* 2F822 (194594) */ - 5639, /* 2F823 (194595) */ - 5640, /* 2F824 (194596) */ - 3695, /* 2F825 (194597) */ - 3633, /* 2F826 (194598) */ - 3634, /* 2F827 (194599) */ - 3696, /* 2F828 (194600) */ - 5641, /* 2F829 (194601) */ - 5642, /* 2F82A (194602) */ - 3441, /* 2F82B (194603) */ - 5643, /* 2F82C (194604) */ - 3635, /* 2F82D (194605) */ - 5644, /* 2F82E (194606) */ - 5645, /* 2F82F (194607) */ - 5646, /* 2F830 (194608) */ - 5647, /* 2F831 (194609) */ - 5647, /* 2F832 (194610) */ - 5647, /* 2F833 (194611) */ - 5648, /* 2F834 (194612) */ - 5649, /* 2F835 (194613) */ - 5650, /* 2F836 (194614) */ - 5651, /* 2F837 (194615) */ - 5652, /* 2F838 (194616) */ - 5653, /* 2F839 (194617) */ - 5654, /* 2F83A (194618) */ - 5655, /* 2F83B (194619) */ - 5656, /* 2F83C (194620) */ - 5657, /* 2F83D (194621) */ - 5658, /* 2F83E (194622) */ - 5659, /* 2F83F (194623) */ - 5660, /* 2F840 (194624) */ - 5661, /* 2F841 (194625) */ - 5662, /* 2F842 (194626) */ - 5663, /* 2F843 (194627) */ - 5664, /* 2F844 (194628) */ - 5665, /* 2F845 (194629) */ - 5665, /* 2F846 (194630) */ - 3698, /* 2F847 (194631) */ - 5666, /* 2F848 (194632) */ - 5667, /* 2F849 (194633) */ - 5668, /* 2F84A (194634) */ - 5669, /* 2F84B (194635) */ - 3637, /* 2F84C (194636) */ - 5670, /* 2F84D (194637) */ - 5671, /* 2F84E (194638) */ - 5672, /* 2F84F (194639) */ - 3594, /* 2F850 (194640) */ - 5673, /* 2F851 (194641) */ - 5674, /* 2F852 (194642) */ - 5675, /* 2F853 (194643) */ - 5676, /* 2F854 (194644) */ - 5677, /* 2F855 (194645) */ - 5678, /* 2F856 (194646) */ - 5679, /* 2F857 (194647) */ - 5680, /* 2F858 (194648) */ - 5681, /* 2F859 (194649) */ - 5682, /* 2F85A (194650) */ - 5683, /* 2F85B (194651) */ - 5684, /* 2F85C (194652) */ - 5685, /* 2F85D (194653) */ - 5686, /* 2F85E (194654) */ - 5687, /* 2F85F (194655) */ - 5688, /* 2F860 (194656) */ - 5689, /* 2F861 (194657) */ - 5690, /* 2F862 (194658) */ - 5691, /* 2F863 (194659) */ - 5692, /* 2F864 (194660) */ - 5693, /* 2F865 (194661) */ - 5694, /* 2F866 (194662) */ - 5695, /* 2F867 (194663) */ - 5696, /* 2F868 (194664) */ - 5697, /* 2F869 (194665) */ - 5698, /* 2F86A (194666) */ - 5698, /* 2F86B (194667) */ - 5699, /* 2F86C (194668) */ - 5700, /* 2F86D (194669) */ - 5701, /* 2F86E (194670) */ - 3437, /* 2F86F (194671) */ - 5702, /* 2F870 (194672) */ - 5703, /* 2F871 (194673) */ - 5704, /* 2F872 (194674) */ - 5705, /* 2F873 (194675) */ - 5706, /* 2F874 (194676) */ - 5707, /* 2F875 (194677) */ - 5708, /* 2F876 (194678) */ - 5709, /* 2F877 (194679) */ - 3642, /* 2F878 (194680) */ - 5710, /* 2F879 (194681) */ - 5711, /* 2F87A (194682) */ - 5712, /* 2F87B (194683) */ - 5713, /* 2F87C (194684) */ - 5714, /* 2F87D (194685) */ - 5715, /* 2F87E (194686) */ - 5716, /* 2F87F (194687) */ - 5717, /* 2F880 (194688) */ - 5718, /* 2F881 (194689) */ - 5719, /* 2F882 (194690) */ - 5720, /* 2F883 (194691) */ - 5721, /* 2F884 (194692) */ - 5722, /* 2F885 (194693) */ - 5723, /* 2F886 (194694) */ - 5724, /* 2F887 (194695) */ - 5725, /* 2F888 (194696) */ - 5726, /* 2F889 (194697) */ - 5727, /* 2F88A (194698) */ - 5728, /* 2F88B (194699) */ - 5729, /* 2F88C (194700) */ - 5730, /* 2F88D (194701) */ - 3383, /* 2F88E (194702) */ - 5731, /* 2F88F (194703) */ - 5732, /* 2F890 (194704) */ - 5733, /* 2F891 (194705) */ - 5733, /* 2F892 (194706) */ - 5734, /* 2F893 (194707) */ - 5735, /* 2F894 (194708) */ - 5735, /* 2F895 (194709) */ - 5736, /* 2F896 (194710) */ - 5737, /* 2F897 (194711) */ - 5738, /* 2F898 (194712) */ - 5739, /* 2F899 (194713) */ - 5740, /* 2F89A (194714) */ - 5741, /* 2F89B (194715) */ - 5742, /* 2F89C (194716) */ - 5743, /* 2F89D (194717) */ - 5744, /* 2F89E (194718) */ - 5745, /* 2F89F (194719) */ - 5746, /* 2F8A0 (194720) */ - 5747, /* 2F8A1 (194721) */ - 5748, /* 2F8A2 (194722) */ - 3643, /* 2F8A3 (194723) */ - 5749, /* 2F8A4 (194724) */ - 5750, /* 2F8A5 (194725) */ - 5751, /* 2F8A6 (194726) */ - 5752, /* 2F8A7 (194727) */ - 3710, /* 2F8A8 (194728) */ - 5752, /* 2F8A9 (194729) */ - 5753, /* 2F8AA (194730) */ - 3645, /* 2F8AB (194731) */ - 5754, /* 2F8AC (194732) */ - 5755, /* 2F8AD (194733) */ - 5756, /* 2F8AE (194734) */ - 5757, /* 2F8AF (194735) */ - 3646, /* 2F8B0 (194736) */ - 3356, /* 2F8B1 (194737) */ - 5758, /* 2F8B2 (194738) */ - 5759, /* 2F8B3 (194739) */ - 5760, /* 2F8B4 (194740) */ - 5761, /* 2F8B5 (194741) */ - 5762, /* 2F8B6 (194742) */ - 5763, /* 2F8B7 (194743) */ - 5764, /* 2F8B8 (194744) */ - 5765, /* 2F8B9 (194745) */ - 5766, /* 2F8BA (194746) */ - 5767, /* 2F8BB (194747) */ - 5768, /* 2F8BC (194748) */ - 5769, /* 2F8BD (194749) */ - 5770, /* 2F8BE (194750) */ - 5771, /* 2F8BF (194751) */ - 5772, /* 2F8C0 (194752) */ - 5773, /* 2F8C1 (194753) */ - 5774, /* 2F8C2 (194754) */ - 5775, /* 2F8C3 (194755) */ - 5776, /* 2F8C4 (194756) */ - 5777, /* 2F8C5 (194757) */ - 5778, /* 2F8C6 (194758) */ - 5779, /* 2F8C7 (194759) */ - 3647, /* 2F8C8 (194760) */ - 5780, /* 2F8C9 (194761) */ - 5781, /* 2F8CA (194762) */ - 5782, /* 2F8CB (194763) */ - 5783, /* 2F8CC (194764) */ - 5784, /* 2F8CD (194765) */ - 5785, /* 2F8CE (194766) */ - 3649, /* 2F8CF (194767) */ - 5786, /* 2F8D0 (194768) */ - 5787, /* 2F8D1 (194769) */ - 5788, /* 2F8D2 (194770) */ - 5789, /* 2F8D3 (194771) */ - 5790, /* 2F8D4 (194772) */ - 5791, /* 2F8D5 (194773) */ - 5792, /* 2F8D6 (194774) */ - 5793, /* 2F8D7 (194775) */ - 3384, /* 2F8D8 (194776) */ - 3718, /* 2F8D9 (194777) */ - 5794, /* 2F8DA (194778) */ - 5795, /* 2F8DB (194779) */ - 5796, /* 2F8DC (194780) */ - 5797, /* 2F8DD (194781) */ - 5798, /* 2F8DE (194782) */ - 5799, /* 2F8DF (194783) */ - 5800, /* 2F8E0 (194784) */ - 5801, /* 2F8E1 (194785) */ - 3650, /* 2F8E2 (194786) */ - 5802, /* 2F8E3 (194787) */ - 5803, /* 2F8E4 (194788) */ - 5804, /* 2F8E5 (194789) */ - 5805, /* 2F8E6 (194790) */ - 3761, /* 2F8E7 (194791) */ - 5806, /* 2F8E8 (194792) */ - 5807, /* 2F8E9 (194793) */ - 5808, /* 2F8EA (194794) */ - 5809, /* 2F8EB (194795) */ - 5810, /* 2F8EC (194796) */ - 5811, /* 2F8ED (194797) */ - 5812, /* 2F8EE (194798) */ - 5813, /* 2F8EF (194799) */ - 5814, /* 2F8F0 (194800) */ - 5815, /* 2F8F1 (194801) */ - 5816, /* 2F8F2 (194802) */ - 5817, /* 2F8F3 (194803) */ - 5818, /* 2F8F4 (194804) */ - 3454, /* 2F8F5 (194805) */ - 5819, /* 2F8F6 (194806) */ - 5820, /* 2F8F7 (194807) */ - 5821, /* 2F8F8 (194808) */ - 5822, /* 2F8F9 (194809) */ - 5823, /* 2F8FA (194810) */ - 5824, /* 2F8FB (194811) */ - 5825, /* 2F8FC (194812) */ - 5826, /* 2F8FD (194813) */ - 5827, /* 2F8FE (194814) */ - 5828, /* 2F8FF (194815) */ - 5829, /* 2F900 (194816) */ - 3651, /* 2F901 (194817) */ - 3541, /* 2F902 (194818) */ - 5830, /* 2F903 (194819) */ - 5831, /* 2F904 (194820) */ - 5832, /* 2F905 (194821) */ - 5833, /* 2F906 (194822) */ - 5834, /* 2F907 (194823) */ - 5835, /* 2F908 (194824) */ - 5836, /* 2F909 (194825) */ - 5837, /* 2F90A (194826) */ - 3722, /* 2F90B (194827) */ - 5838, /* 2F90C (194828) */ - 5839, /* 2F90D (194829) */ - 5840, /* 2F90E (194830) */ - 5841, /* 2F90F (194831) */ - 5842, /* 2F910 (194832) */ - 5843, /* 2F911 (194833) */ - 5844, /* 2F912 (194834) */ - 5845, /* 2F913 (194835) */ - 3723, /* 2F914 (194836) */ - 5846, /* 2F915 (194837) */ - 5847, /* 2F916 (194838) */ - 5848, /* 2F917 (194839) */ - 5849, /* 2F918 (194840) */ - 5850, /* 2F919 (194841) */ - 5851, /* 2F91A (194842) */ - 5852, /* 2F91B (194843) */ - 5853, /* 2F91C (194844) */ - 5854, /* 2F91D (194845) */ - 5855, /* 2F91E (194846) */ - 5856, /* 2F91F (194847) */ - 5857, /* 2F920 (194848) */ - 3725, /* 2F921 (194849) */ - 5858, /* 2F922 (194850) */ - 5859, /* 2F923 (194851) */ - 5860, /* 2F924 (194852) */ - 5861, /* 2F925 (194853) */ - 5862, /* 2F926 (194854) */ - 5863, /* 2F927 (194855) */ - 5864, /* 2F928 (194856) */ - 5865, /* 2F929 (194857) */ - 5866, /* 2F92A (194858) */ - 5867, /* 2F92B (194859) */ - 5868, /* 2F92C (194860) */ - 5868, /* 2F92D (194861) */ - 5869, /* 2F92E (194862) */ - 5870, /* 2F92F (194863) */ - 3727, /* 2F930 (194864) */ - 5871, /* 2F931 (194865) */ - 5872, /* 2F932 (194866) */ - 5873, /* 2F933 (194867) */ - 5874, /* 2F934 (194868) */ - 5875, /* 2F935 (194869) */ - 5876, /* 2F936 (194870) */ - 5877, /* 2F937 (194871) */ - 3440, /* 2F938 (194872) */ - 5878, /* 2F939 (194873) */ - 5879, /* 2F93A (194874) */ - 5880, /* 2F93B (194875) */ - 5881, /* 2F93C (194876) */ - 5882, /* 2F93D (194877) */ - 5883, /* 2F93E (194878) */ - 5884, /* 2F93F (194879) */ - 3733, /* 2F940 (194880) */ - 5885, /* 2F941 (194881) */ - 5886, /* 2F942 (194882) */ - 5887, /* 2F943 (194883) */ - 5888, /* 2F944 (194884) */ - 5889, /* 2F945 (194885) */ - 5890, /* 2F946 (194886) */ - 5890, /* 2F947 (194887) */ - 3734, /* 2F948 (194888) */ - 3763, /* 2F949 (194889) */ - 5891, /* 2F94A (194890) */ - 5892, /* 2F94B (194891) */ - 5893, /* 2F94C (194892) */ - 5894, /* 2F94D (194893) */ - 5895, /* 2F94E (194894) */ - 3402, /* 2F94F (194895) */ - 3736, /* 2F950 (194896) */ - 5896, /* 2F951 (194897) */ - 5897, /* 2F952 (194898) */ - 3662, /* 2F953 (194899) */ - 5898, /* 2F954 (194900) */ - 5899, /* 2F955 (194901) */ - 3616, /* 2F956 (194902) */ - 5900, /* 2F957 (194903) */ - 5901, /* 2F958 (194904) */ - 3666, /* 2F959 (194905) */ - 5902, /* 2F95A (194906) */ - 5903, /* 2F95B (194907) */ - 5904, /* 2F95C (194908) */ - 5905, /* 2F95D (194909) */ - 5905, /* 2F95E (194910) */ - 5906, /* 2F95F (194911) */ - 5907, /* 2F960 (194912) */ - 5908, /* 2F961 (194913) */ - 5909, /* 2F962 (194914) */ - 5910, /* 2F963 (194915) */ - 5911, /* 2F964 (194916) */ - 5912, /* 2F965 (194917) */ - 5913, /* 2F966 (194918) */ - 5914, /* 2F967 (194919) */ - 5915, /* 2F968 (194920) */ - 5916, /* 2F969 (194921) */ - 5917, /* 2F96A (194922) */ - 5918, /* 2F96B (194923) */ - 5919, /* 2F96C (194924) */ - 5920, /* 2F96D (194925) */ - 5921, /* 2F96E (194926) */ - 5922, /* 2F96F (194927) */ - 5923, /* 2F970 (194928) */ - 5924, /* 2F971 (194929) */ - 5925, /* 2F972 (194930) */ - 5926, /* 2F973 (194931) */ - 5927, /* 2F974 (194932) */ - 5928, /* 2F975 (194933) */ - 5929, /* 2F976 (194934) */ - 5930, /* 2F977 (194935) */ - 5931, /* 2F978 (194936) */ - 5932, /* 2F979 (194937) */ - 3672, /* 2F97A (194938) */ - 5933, /* 2F97B (194939) */ - 5934, /* 2F97C (194940) */ - 5935, /* 2F97D (194941) */ - 5936, /* 2F97E (194942) */ - 5937, /* 2F97F (194943) */ - 5938, /* 2F980 (194944) */ - 5939, /* 2F981 (194945) */ - 5940, /* 2F982 (194946) */ - 5941, /* 2F983 (194947) */ - 5942, /* 2F984 (194948) */ - 5943, /* 2F985 (194949) */ - 5944, /* 2F986 (194950) */ - 5945, /* 2F987 (194951) */ - 5946, /* 2F988 (194952) */ - 5947, /* 2F989 (194953) */ - 5948, /* 2F98A (194954) */ - 5734, /* 2F98B (194955) */ - 5949, /* 2F98C (194956) */ - 5950, /* 2F98D (194957) */ - 5951, /* 2F98E (194958) */ - 5952, /* 2F98F (194959) */ - 5953, /* 2F990 (194960) */ - 5954, /* 2F991 (194961) */ - 5955, /* 2F992 (194962) */ - 5956, /* 2F993 (194963) */ - 5957, /* 2F994 (194964) */ - 5958, /* 2F995 (194965) */ - 5959, /* 2F996 (194966) */ - 5960, /* 2F997 (194967) */ - 3458, /* 2F998 (194968) */ - 5961, /* 2F999 (194969) */ - 5962, /* 2F99A (194970) */ - 5963, /* 2F99B (194971) */ - 5964, /* 2F99C (194972) */ - 5965, /* 2F99D (194973) */ - 5966, /* 2F99E (194974) */ - 3675, /* 2F99F (194975) */ - 5967, /* 2F9A0 (194976) */ - 5968, /* 2F9A1 (194977) */ - 5969, /* 2F9A2 (194978) */ - 5970, /* 2F9A3 (194979) */ - 5971, /* 2F9A4 (194980) */ - 5972, /* 2F9A5 (194981) */ - 5973, /* 2F9A6 (194982) */ - 5974, /* 2F9A7 (194983) */ - 5975, /* 2F9A8 (194984) */ - 5976, /* 2F9A9 (194985) */ - 5977, /* 2F9AA (194986) */ - 5978, /* 2F9AB (194987) */ - 5979, /* 2F9AC (194988) */ - 5980, /* 2F9AD (194989) */ - 5981, /* 2F9AE (194990) */ - 5982, /* 2F9AF (194991) */ - 5983, /* 2F9B0 (194992) */ - 5984, /* 2F9B1 (194993) */ - 5985, /* 2F9B2 (194994) */ - 5986, /* 2F9B3 (194995) */ - 3397, /* 2F9B4 (194996) */ - 5987, /* 2F9B5 (194997) */ - 5988, /* 2F9B6 (194998) */ - 5989, /* 2F9B7 (194999) */ - 5990, /* 2F9B8 (195000) */ - 5991, /* 2F9B9 (195001) */ - 5992, /* 2F9BA (195002) */ - 3743, /* 2F9BB (195003) */ - 5993, /* 2F9BC (195004) */ - 5994, /* 2F9BD (195005) */ - 5995, /* 2F9BE (195006) */ - 5996, /* 2F9BF (195007) */ - 5997, /* 2F9C0 (195008) */ - 5998, /* 2F9C1 (195009) */ - 5999, /* 2F9C2 (195010) */ - 6000, /* 2F9C3 (195011) */ - 6001, /* 2F9C4 (195012) */ - 6002, /* 2F9C5 (195013) */ - 6003, /* 2F9C6 (195014) */ - 6004, /* 2F9C7 (195015) */ - 6005, /* 2F9C8 (195016) */ - 6006, /* 2F9C9 (195017) */ - 6007, /* 2F9CA (195018) */ - 6008, /* 2F9CB (195019) */ - 6009, /* 2F9CC (195020) */ - 6010, /* 2F9CD (195021) */ - 6011, /* 2F9CE (195022) */ - 6012, /* 2F9CF (195023) */ - 3748, /* 2F9D0 (195024) */ - 3749, /* 2F9D1 (195025) */ - 6013, /* 2F9D2 (195026) */ - 6014, /* 2F9D3 (195027) */ - 6015, /* 2F9D4 (195028) */ - 6016, /* 2F9D5 (195029) */ - 6017, /* 2F9D6 (195030) */ - 6018, /* 2F9D7 (195031) */ - 6019, /* 2F9D8 (195032) */ - 6020, /* 2F9D9 (195033) */ - 6021, /* 2F9DA (195034) */ - 6022, /* 2F9DB (195035) */ - 6023, /* 2F9DC (195036) */ - 6024, /* 2F9DD (195037) */ - 6025, /* 2F9DE (195038) */ - 3750, /* 2F9DF (195039) */ - 6026, /* 2F9E0 (195040) */ - 6027, /* 2F9E1 (195041) */ - 6028, /* 2F9E2 (195042) */ - 6029, /* 2F9E3 (195043) */ - 6030, /* 2F9E4 (195044) */ - 6031, /* 2F9E5 (195045) */ - 6032, /* 2F9E6 (195046) */ - 6033, /* 2F9E7 (195047) */ - 6034, /* 2F9E8 (195048) */ - 6035, /* 2F9E9 (195049) */ - 6036, /* 2F9EA (195050) */ - 6037, /* 2F9EB (195051) */ - 6038, /* 2F9EC (195052) */ - 6039, /* 2F9ED (195053) */ - 6040, /* 2F9EE (195054) */ - 6041, /* 2F9EF (195055) */ - 6042, /* 2F9F0 (195056) */ - 6043, /* 2F9F1 (195057) */ - 6044, /* 2F9F2 (195058) */ - 6045, /* 2F9F3 (195059) */ - 6046, /* 2F9F4 (195060) */ - 6047, /* 2F9F5 (195061) */ - 6048, /* 2F9F6 (195062) */ - 6049, /* 2F9F7 (195063) */ - 6050, /* 2F9F8 (195064) */ - 6051, /* 2F9F9 (195065) */ - 6052, /* 2F9FA (195066) */ - 6053, /* 2F9FB (195067) */ - 6054, /* 2F9FC (195068) */ - 6055, /* 2F9FD (195069) */ - 3756, /* 2F9FE (195070) */ - 3756, /* 2F9FF (195071) */ - 6056, /* 2FA00 (195072) */ - 6057, /* 2FA01 (195073) */ - 6058, /* 2FA02 (195074) */ - 6059, /* 2FA03 (195075) */ - 6060, /* 2FA04 (195076) */ - 6061, /* 2FA05 (195077) */ - 6062, /* 2FA06 (195078) */ - 6063, /* 2FA07 (195079) */ - 6064, /* 2FA08 (195080) */ - 6065, /* 2FA09 (195081) */ - 3757, /* 2FA0A (195082) */ - 6066, /* 2FA0B (195083) */ - 6067, /* 2FA0C (195084) */ - 6068, /* 2FA0D (195085) */ - 6069, /* 2FA0E (195086) */ - 6070, /* 2FA0F (195087) */ - 6071, /* 2FA10 (195088) */ - 6072, /* 2FA11 (195089) */ - 6073, /* 2FA12 (195090) */ - 6074, /* 2FA13 (195091) */ - 6075, /* 2FA14 (195092) */ - 6076, /* 2FA15 (195093) */ - 6077, /* 2FA16 (195094) */ - 6078, /* 2FA17 (195095) */ - 6079, /* 2FA18 (195096) */ - 6080, /* 2FA19 (195097) */ - 6081, /* 2FA1A (195098) */ - 6082, /* 2FA1B (195099) */ - 6083, /* 2FA1C (195100) */ - 6084, /* 2FA1D (195101) */ + 5637, /* 2F800 (194560) */ + 5638, /* 2F801 (194561) */ + 5639, /* 2F802 (194562) */ + 5640, /* 2F803 (194563) */ + 5641, /* 2F804 (194564) */ + 3634, /* 2F805 (194565) */ + 5642, /* 2F806 (194566) */ + 5643, /* 2F807 (194567) */ + 5644, /* 2F808 (194568) */ + 5645, /* 2F809 (194569) */ + 3635, /* 2F80A (194570) */ + 5646, /* 2F80B (194571) */ + 5647, /* 2F80C (194572) */ + 5648, /* 2F80D (194573) */ + 3636, /* 2F80E (194574) */ + 5649, /* 2F80F (194575) */ + 5650, /* 2F810 (194576) */ + 5651, /* 2F811 (194577) */ + 5652, /* 2F812 (194578) */ + 5653, /* 2F813 (194579) */ + 5654, /* 2F814 (194580) */ + 5655, /* 2F815 (194581) */ + 5656, /* 2F816 (194582) */ + 5657, /* 2F817 (194583) */ + 5658, /* 2F818 (194584) */ + 5659, /* 2F819 (194585) */ + 5660, /* 2F81A (194586) */ + 3694, /* 2F81B (194587) */ + 5661, /* 2F81C (194588) */ + 5662, /* 2F81D (194589) */ + 5663, /* 2F81E (194590) */ + 5664, /* 2F81F (194591) */ + 5665, /* 2F820 (194592) */ + 5666, /* 2F821 (194593) */ + 5667, /* 2F822 (194594) */ + 5668, /* 2F823 (194595) */ + 5669, /* 2F824 (194596) */ + 3699, /* 2F825 (194597) */ + 3637, /* 2F826 (194598) */ + 3638, /* 2F827 (194599) */ + 3700, /* 2F828 (194600) */ + 5670, /* 2F829 (194601) */ + 5671, /* 2F82A (194602) */ + 3445, /* 2F82B (194603) */ + 5672, /* 2F82C (194604) */ + 3639, /* 2F82D (194605) */ + 5673, /* 2F82E (194606) */ + 5674, /* 2F82F (194607) */ + 5675, /* 2F830 (194608) */ + 5676, /* 2F831 (194609) */ + 5676, /* 2F832 (194610) */ + 5676, /* 2F833 (194611) */ + 5677, /* 2F834 (194612) */ + 5678, /* 2F835 (194613) */ + 5679, /* 2F836 (194614) */ + 5680, /* 2F837 (194615) */ + 5681, /* 2F838 (194616) */ + 5682, /* 2F839 (194617) */ + 5683, /* 2F83A (194618) */ + 5684, /* 2F83B (194619) */ + 5685, /* 2F83C (194620) */ + 5686, /* 2F83D (194621) */ + 5687, /* 2F83E (194622) */ + 5688, /* 2F83F (194623) */ + 5689, /* 2F840 (194624) */ + 5690, /* 2F841 (194625) */ + 5691, /* 2F842 (194626) */ + 5692, /* 2F843 (194627) */ + 5693, /* 2F844 (194628) */ + 5694, /* 2F845 (194629) */ + 5694, /* 2F846 (194630) */ + 3702, /* 2F847 (194631) */ + 5695, /* 2F848 (194632) */ + 5696, /* 2F849 (194633) */ + 5697, /* 2F84A (194634) */ + 5698, /* 2F84B (194635) */ + 3641, /* 2F84C (194636) */ + 5699, /* 2F84D (194637) */ + 5700, /* 2F84E (194638) */ + 5701, /* 2F84F (194639) */ + 3598, /* 2F850 (194640) */ + 5702, /* 2F851 (194641) */ + 5703, /* 2F852 (194642) */ + 5704, /* 2F853 (194643) */ + 5705, /* 2F854 (194644) */ + 5706, /* 2F855 (194645) */ + 5707, /* 2F856 (194646) */ + 5708, /* 2F857 (194647) */ + 5709, /* 2F858 (194648) */ + 5710, /* 2F859 (194649) */ + 5711, /* 2F85A (194650) */ + 5712, /* 2F85B (194651) */ + 5713, /* 2F85C (194652) */ + 5714, /* 2F85D (194653) */ + 5715, /* 2F85E (194654) */ + 5716, /* 2F85F (194655) */ + 5717, /* 2F860 (194656) */ + 5718, /* 2F861 (194657) */ + 5719, /* 2F862 (194658) */ + 5720, /* 2F863 (194659) */ + 5721, /* 2F864 (194660) */ + 5722, /* 2F865 (194661) */ + 5723, /* 2F866 (194662) */ + 5724, /* 2F867 (194663) */ + 5725, /* 2F868 (194664) */ + 5726, /* 2F869 (194665) */ + 5727, /* 2F86A (194666) */ + 5727, /* 2F86B (194667) */ + 5728, /* 2F86C (194668) */ + 5729, /* 2F86D (194669) */ + 5730, /* 2F86E (194670) */ + 3441, /* 2F86F (194671) */ + 5731, /* 2F870 (194672) */ + 5732, /* 2F871 (194673) */ + 5733, /* 2F872 (194674) */ + 5734, /* 2F873 (194675) */ + 5735, /* 2F874 (194676) */ + 5736, /* 2F875 (194677) */ + 5737, /* 2F876 (194678) */ + 5738, /* 2F877 (194679) */ + 3646, /* 2F878 (194680) */ + 5739, /* 2F879 (194681) */ + 5740, /* 2F87A (194682) */ + 5741, /* 2F87B (194683) */ + 5742, /* 2F87C (194684) */ + 5743, /* 2F87D (194685) */ + 5744, /* 2F87E (194686) */ + 5745, /* 2F87F (194687) */ + 5746, /* 2F880 (194688) */ + 5747, /* 2F881 (194689) */ + 5748, /* 2F882 (194690) */ + 5749, /* 2F883 (194691) */ + 5750, /* 2F884 (194692) */ + 5751, /* 2F885 (194693) */ + 5752, /* 2F886 (194694) */ + 5753, /* 2F887 (194695) */ + 5754, /* 2F888 (194696) */ + 5755, /* 2F889 (194697) */ + 5756, /* 2F88A (194698) */ + 5757, /* 2F88B (194699) */ + 5758, /* 2F88C (194700) */ + 5759, /* 2F88D (194701) */ + 3387, /* 2F88E (194702) */ + 5760, /* 2F88F (194703) */ + 5761, /* 2F890 (194704) */ + 5762, /* 2F891 (194705) */ + 5762, /* 2F892 (194706) */ + 5763, /* 2F893 (194707) */ + 5764, /* 2F894 (194708) */ + 5764, /* 2F895 (194709) */ + 5765, /* 2F896 (194710) */ + 5766, /* 2F897 (194711) */ + 5767, /* 2F898 (194712) */ + 5768, /* 2F899 (194713) */ + 5769, /* 2F89A (194714) */ + 5770, /* 2F89B (194715) */ + 5771, /* 2F89C (194716) */ + 5772, /* 2F89D (194717) */ + 5773, /* 2F89E (194718) */ + 5774, /* 2F89F (194719) */ + 5775, /* 2F8A0 (194720) */ + 5776, /* 2F8A1 (194721) */ + 5777, /* 2F8A2 (194722) */ + 3647, /* 2F8A3 (194723) */ + 5778, /* 2F8A4 (194724) */ + 5779, /* 2F8A5 (194725) */ + 5780, /* 2F8A6 (194726) */ + 5781, /* 2F8A7 (194727) */ + 3714, /* 2F8A8 (194728) */ + 5781, /* 2F8A9 (194729) */ + 5782, /* 2F8AA (194730) */ + 3649, /* 2F8AB (194731) */ + 5783, /* 2F8AC (194732) */ + 5784, /* 2F8AD (194733) */ + 5785, /* 2F8AE (194734) */ + 5786, /* 2F8AF (194735) */ + 3650, /* 2F8B0 (194736) */ + 3360, /* 2F8B1 (194737) */ + 5787, /* 2F8B2 (194738) */ + 5788, /* 2F8B3 (194739) */ + 5789, /* 2F8B4 (194740) */ + 5790, /* 2F8B5 (194741) */ + 5791, /* 2F8B6 (194742) */ + 5792, /* 2F8B7 (194743) */ + 5793, /* 2F8B8 (194744) */ + 5794, /* 2F8B9 (194745) */ + 5795, /* 2F8BA (194746) */ + 5796, /* 2F8BB (194747) */ + 5797, /* 2F8BC (194748) */ + 5798, /* 2F8BD (194749) */ + 5799, /* 2F8BE (194750) */ + 5800, /* 2F8BF (194751) */ + 5801, /* 2F8C0 (194752) */ + 5802, /* 2F8C1 (194753) */ + 5803, /* 2F8C2 (194754) */ + 5804, /* 2F8C3 (194755) */ + 5805, /* 2F8C4 (194756) */ + 5806, /* 2F8C5 (194757) */ + 5807, /* 2F8C6 (194758) */ + 5808, /* 2F8C7 (194759) */ + 3651, /* 2F8C8 (194760) */ + 5809, /* 2F8C9 (194761) */ + 5810, /* 2F8CA (194762) */ + 5811, /* 2F8CB (194763) */ + 5812, /* 2F8CC (194764) */ + 5813, /* 2F8CD (194765) */ + 5814, /* 2F8CE (194766) */ + 3653, /* 2F8CF (194767) */ + 5815, /* 2F8D0 (194768) */ + 5816, /* 2F8D1 (194769) */ + 5817, /* 2F8D2 (194770) */ + 5818, /* 2F8D3 (194771) */ + 5819, /* 2F8D4 (194772) */ + 5820, /* 2F8D5 (194773) */ + 5821, /* 2F8D6 (194774) */ + 5822, /* 2F8D7 (194775) */ + 3388, /* 2F8D8 (194776) */ + 3722, /* 2F8D9 (194777) */ + 5823, /* 2F8DA (194778) */ + 5824, /* 2F8DB (194779) */ + 5825, /* 2F8DC (194780) */ + 5826, /* 2F8DD (194781) */ + 5827, /* 2F8DE (194782) */ + 5828, /* 2F8DF (194783) */ + 5829, /* 2F8E0 (194784) */ + 5830, /* 2F8E1 (194785) */ + 3654, /* 2F8E2 (194786) */ + 5831, /* 2F8E3 (194787) */ + 5832, /* 2F8E4 (194788) */ + 5833, /* 2F8E5 (194789) */ + 5834, /* 2F8E6 (194790) */ + 3765, /* 2F8E7 (194791) */ + 5835, /* 2F8E8 (194792) */ + 5836, /* 2F8E9 (194793) */ + 5837, /* 2F8EA (194794) */ + 5838, /* 2F8EB (194795) */ + 5839, /* 2F8EC (194796) */ + 5840, /* 2F8ED (194797) */ + 5841, /* 2F8EE (194798) */ + 5842, /* 2F8EF (194799) */ + 5843, /* 2F8F0 (194800) */ + 5844, /* 2F8F1 (194801) */ + 5845, /* 2F8F2 (194802) */ + 5846, /* 2F8F3 (194803) */ + 5847, /* 2F8F4 (194804) */ + 3458, /* 2F8F5 (194805) */ + 5848, /* 2F8F6 (194806) */ + 5849, /* 2F8F7 (194807) */ + 5850, /* 2F8F8 (194808) */ + 5851, /* 2F8F9 (194809) */ + 5852, /* 2F8FA (194810) */ + 5853, /* 2F8FB (194811) */ + 5854, /* 2F8FC (194812) */ + 5855, /* 2F8FD (194813) */ + 5856, /* 2F8FE (194814) */ + 5857, /* 2F8FF (194815) */ + 5858, /* 2F900 (194816) */ + 3655, /* 2F901 (194817) */ + 3545, /* 2F902 (194818) */ + 5859, /* 2F903 (194819) */ + 5860, /* 2F904 (194820) */ + 5861, /* 2F905 (194821) */ + 5862, /* 2F906 (194822) */ + 5863, /* 2F907 (194823) */ + 5864, /* 2F908 (194824) */ + 5865, /* 2F909 (194825) */ + 5866, /* 2F90A (194826) */ + 3726, /* 2F90B (194827) */ + 5867, /* 2F90C (194828) */ + 5868, /* 2F90D (194829) */ + 5869, /* 2F90E (194830) */ + 5870, /* 2F90F (194831) */ + 5871, /* 2F910 (194832) */ + 5872, /* 2F911 (194833) */ + 5873, /* 2F912 (194834) */ + 5874, /* 2F913 (194835) */ + 3727, /* 2F914 (194836) */ + 5875, /* 2F915 (194837) */ + 5876, /* 2F916 (194838) */ + 5877, /* 2F917 (194839) */ + 5878, /* 2F918 (194840) */ + 5879, /* 2F919 (194841) */ + 5880, /* 2F91A (194842) */ + 5881, /* 2F91B (194843) */ + 5882, /* 2F91C (194844) */ + 5883, /* 2F91D (194845) */ + 5884, /* 2F91E (194846) */ + 5885, /* 2F91F (194847) */ + 5886, /* 2F920 (194848) */ + 3729, /* 2F921 (194849) */ + 5887, /* 2F922 (194850) */ + 5888, /* 2F923 (194851) */ + 5889, /* 2F924 (194852) */ + 5890, /* 2F925 (194853) */ + 5891, /* 2F926 (194854) */ + 5892, /* 2F927 (194855) */ + 5893, /* 2F928 (194856) */ + 5894, /* 2F929 (194857) */ + 5895, /* 2F92A (194858) */ + 5896, /* 2F92B (194859) */ + 5897, /* 2F92C (194860) */ + 5897, /* 2F92D (194861) */ + 5898, /* 2F92E (194862) */ + 5899, /* 2F92F (194863) */ + 3731, /* 2F930 (194864) */ + 5900, /* 2F931 (194865) */ + 5901, /* 2F932 (194866) */ + 5902, /* 2F933 (194867) */ + 5903, /* 2F934 (194868) */ + 5904, /* 2F935 (194869) */ + 5905, /* 2F936 (194870) */ + 5906, /* 2F937 (194871) */ + 3444, /* 2F938 (194872) */ + 5907, /* 2F939 (194873) */ + 5908, /* 2F93A (194874) */ + 5909, /* 2F93B (194875) */ + 5910, /* 2F93C (194876) */ + 5911, /* 2F93D (194877) */ + 5912, /* 2F93E (194878) */ + 5913, /* 2F93F (194879) */ + 3737, /* 2F940 (194880) */ + 5914, /* 2F941 (194881) */ + 5915, /* 2F942 (194882) */ + 5916, /* 2F943 (194883) */ + 5917, /* 2F944 (194884) */ + 5918, /* 2F945 (194885) */ + 5919, /* 2F946 (194886) */ + 5919, /* 2F947 (194887) */ + 3738, /* 2F948 (194888) */ + 3767, /* 2F949 (194889) */ + 5920, /* 2F94A (194890) */ + 5921, /* 2F94B (194891) */ + 5922, /* 2F94C (194892) */ + 5923, /* 2F94D (194893) */ + 5924, /* 2F94E (194894) */ + 3406, /* 2F94F (194895) */ + 3740, /* 2F950 (194896) */ + 5925, /* 2F951 (194897) */ + 5926, /* 2F952 (194898) */ + 3666, /* 2F953 (194899) */ + 5927, /* 2F954 (194900) */ + 5928, /* 2F955 (194901) */ + 3620, /* 2F956 (194902) */ + 5929, /* 2F957 (194903) */ + 5930, /* 2F958 (194904) */ + 3670, /* 2F959 (194905) */ + 5931, /* 2F95A (194906) */ + 5932, /* 2F95B (194907) */ + 5933, /* 2F95C (194908) */ + 5934, /* 2F95D (194909) */ + 5934, /* 2F95E (194910) */ + 5935, /* 2F95F (194911) */ + 5936, /* 2F960 (194912) */ + 5937, /* 2F961 (194913) */ + 5938, /* 2F962 (194914) */ + 5939, /* 2F963 (194915) */ + 5940, /* 2F964 (194916) */ + 5941, /* 2F965 (194917) */ + 5942, /* 2F966 (194918) */ + 5943, /* 2F967 (194919) */ + 5944, /* 2F968 (194920) */ + 5945, /* 2F969 (194921) */ + 5946, /* 2F96A (194922) */ + 5947, /* 2F96B (194923) */ + 5948, /* 2F96C (194924) */ + 5949, /* 2F96D (194925) */ + 5950, /* 2F96E (194926) */ + 5951, /* 2F96F (194927) */ + 5952, /* 2F970 (194928) */ + 5953, /* 2F971 (194929) */ + 5954, /* 2F972 (194930) */ + 5955, /* 2F973 (194931) */ + 5956, /* 2F974 (194932) */ + 5957, /* 2F975 (194933) */ + 5958, /* 2F976 (194934) */ + 5959, /* 2F977 (194935) */ + 5960, /* 2F978 (194936) */ + 5961, /* 2F979 (194937) */ + 3676, /* 2F97A (194938) */ + 5962, /* 2F97B (194939) */ + 5963, /* 2F97C (194940) */ + 5964, /* 2F97D (194941) */ + 5965, /* 2F97E (194942) */ + 5966, /* 2F97F (194943) */ + 5967, /* 2F980 (194944) */ + 5968, /* 2F981 (194945) */ + 5969, /* 2F982 (194946) */ + 5970, /* 2F983 (194947) */ + 5971, /* 2F984 (194948) */ + 5972, /* 2F985 (194949) */ + 5973, /* 2F986 (194950) */ + 5974, /* 2F987 (194951) */ + 5975, /* 2F988 (194952) */ + 5976, /* 2F989 (194953) */ + 5977, /* 2F98A (194954) */ + 5763, /* 2F98B (194955) */ + 5978, /* 2F98C (194956) */ + 5979, /* 2F98D (194957) */ + 5980, /* 2F98E (194958) */ + 5981, /* 2F98F (194959) */ + 5982, /* 2F990 (194960) */ + 5983, /* 2F991 (194961) */ + 5984, /* 2F992 (194962) */ + 5985, /* 2F993 (194963) */ + 5986, /* 2F994 (194964) */ + 5987, /* 2F995 (194965) */ + 5988, /* 2F996 (194966) */ + 5989, /* 2F997 (194967) */ + 3462, /* 2F998 (194968) */ + 5990, /* 2F999 (194969) */ + 5991, /* 2F99A (194970) */ + 5992, /* 2F99B (194971) */ + 5993, /* 2F99C (194972) */ + 5994, /* 2F99D (194973) */ + 5995, /* 2F99E (194974) */ + 3679, /* 2F99F (194975) */ + 5996, /* 2F9A0 (194976) */ + 5997, /* 2F9A1 (194977) */ + 5998, /* 2F9A2 (194978) */ + 5999, /* 2F9A3 (194979) */ + 6000, /* 2F9A4 (194980) */ + 6001, /* 2F9A5 (194981) */ + 6002, /* 2F9A6 (194982) */ + 6003, /* 2F9A7 (194983) */ + 6004, /* 2F9A8 (194984) */ + 6005, /* 2F9A9 (194985) */ + 6006, /* 2F9AA (194986) */ + 6007, /* 2F9AB (194987) */ + 6008, /* 2F9AC (194988) */ + 6009, /* 2F9AD (194989) */ + 6010, /* 2F9AE (194990) */ + 6011, /* 2F9AF (194991) */ + 6012, /* 2F9B0 (194992) */ + 6013, /* 2F9B1 (194993) */ + 6014, /* 2F9B2 (194994) */ + 6015, /* 2F9B3 (194995) */ + 3401, /* 2F9B4 (194996) */ + 6016, /* 2F9B5 (194997) */ + 6017, /* 2F9B6 (194998) */ + 6018, /* 2F9B7 (194999) */ + 6019, /* 2F9B8 (195000) */ + 6020, /* 2F9B9 (195001) */ + 6021, /* 2F9BA (195002) */ + 3747, /* 2F9BB (195003) */ + 6022, /* 2F9BC (195004) */ + 6023, /* 2F9BD (195005) */ + 6024, /* 2F9BE (195006) */ + 6025, /* 2F9BF (195007) */ + 6026, /* 2F9C0 (195008) */ + 6027, /* 2F9C1 (195009) */ + 6028, /* 2F9C2 (195010) */ + 6029, /* 2F9C3 (195011) */ + 6030, /* 2F9C4 (195012) */ + 6031, /* 2F9C5 (195013) */ + 6032, /* 2F9C6 (195014) */ + 6033, /* 2F9C7 (195015) */ + 6034, /* 2F9C8 (195016) */ + 6035, /* 2F9C9 (195017) */ + 6036, /* 2F9CA (195018) */ + 6037, /* 2F9CB (195019) */ + 6038, /* 2F9CC (195020) */ + 6039, /* 2F9CD (195021) */ + 6040, /* 2F9CE (195022) */ + 6041, /* 2F9CF (195023) */ + 3752, /* 2F9D0 (195024) */ + 3753, /* 2F9D1 (195025) */ + 6042, /* 2F9D2 (195026) */ + 6043, /* 2F9D3 (195027) */ + 6044, /* 2F9D4 (195028) */ + 6045, /* 2F9D5 (195029) */ + 6046, /* 2F9D6 (195030) */ + 6047, /* 2F9D7 (195031) */ + 6048, /* 2F9D8 (195032) */ + 6049, /* 2F9D9 (195033) */ + 6050, /* 2F9DA (195034) */ + 6051, /* 2F9DB (195035) */ + 6052, /* 2F9DC (195036) */ + 6053, /* 2F9DD (195037) */ + 6054, /* 2F9DE (195038) */ + 3754, /* 2F9DF (195039) */ + 6055, /* 2F9E0 (195040) */ + 6056, /* 2F9E1 (195041) */ + 6057, /* 2F9E2 (195042) */ + 6058, /* 2F9E3 (195043) */ + 6059, /* 2F9E4 (195044) */ + 6060, /* 2F9E5 (195045) */ + 6061, /* 2F9E6 (195046) */ + 6062, /* 2F9E7 (195047) */ + 6063, /* 2F9E8 (195048) */ + 6064, /* 2F9E9 (195049) */ + 6065, /* 2F9EA (195050) */ + 6066, /* 2F9EB (195051) */ + 6067, /* 2F9EC (195052) */ + 6068, /* 2F9ED (195053) */ + 6069, /* 2F9EE (195054) */ + 6070, /* 2F9EF (195055) */ + 6071, /* 2F9F0 (195056) */ + 6072, /* 2F9F1 (195057) */ + 6073, /* 2F9F2 (195058) */ + 6074, /* 2F9F3 (195059) */ + 6075, /* 2F9F4 (195060) */ + 6076, /* 2F9F5 (195061) */ + 6077, /* 2F9F6 (195062) */ + 6078, /* 2F9F7 (195063) */ + 6079, /* 2F9F8 (195064) */ + 6080, /* 2F9F9 (195065) */ + 6081, /* 2F9FA (195066) */ + 6082, /* 2F9FB (195067) */ + 6083, /* 2F9FC (195068) */ + 6084, /* 2F9FD (195069) */ + 3760, /* 2F9FE (195070) */ + 3760, /* 2F9FF (195071) */ + 6085, /* 2FA00 (195072) */ + 6086, /* 2FA01 (195073) */ + 6087, /* 2FA02 (195074) */ + 6088, /* 2FA03 (195075) */ + 6089, /* 2FA04 (195076) */ + 6090, /* 2FA05 (195077) */ + 6091, /* 2FA06 (195078) */ + 6092, /* 2FA07 (195079) */ + 6093, /* 2FA08 (195080) */ + 6094, /* 2FA09 (195081) */ + 3761, /* 2FA0A (195082) */ + 6095, /* 2FA0B (195083) */ + 6096, /* 2FA0C (195084) */ + 6097, /* 2FA0D (195085) */ + 6098, /* 2FA0E (195086) */ + 6099, /* 2FA0F (195087) */ + 6100, /* 2FA10 (195088) */ + 6101, /* 2FA11 (195089) */ + 6102, /* 2FA12 (195090) */ + 6103, /* 2FA13 (195091) */ + 6104, /* 2FA14 (195092) */ + 6105, /* 2FA15 (195093) */ + 6106, /* 2FA16 (195094) */ + 6107, /* 2FA17 (195095) */ + 6108, /* 2FA18 (195096) */ + 6109, /* 2FA19 (195097) */ + 6110, /* 2FA1A (195098) */ + 6111, /* 2FA1B (195099) */ + 6112, /* 2FA1C (195100) */ + 6113, /* 2FA1D (195101) */ 56, /* 2FA1E (195102) */ 56, /* 2FA1F (195103) */ 56, /* 2FA20 (195104) */ @@ -183606,6 +183840,4304 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 323AD (205741) */ 1, /* 323AE (205742) */ 1, /* 323AF (205743) */ + 1, /* 323B0 (205744) */ + 1, /* 323B1 (205745) */ + 1, /* 323B2 (205746) */ + 1, /* 323B3 (205747) */ + 1, /* 323B4 (205748) */ + 1, /* 323B5 (205749) */ + 1, /* 323B6 (205750) */ + 1, /* 323B7 (205751) */ + 1, /* 323B8 (205752) */ + 1, /* 323B9 (205753) */ + 1, /* 323BA (205754) */ + 1, /* 323BB (205755) */ + 1, /* 323BC (205756) */ + 1, /* 323BD (205757) */ + 1, /* 323BE (205758) */ + 1, /* 323BF (205759) */ + 1, /* 323C0 (205760) */ + 1, /* 323C1 (205761) */ + 1, /* 323C2 (205762) */ + 1, /* 323C3 (205763) */ + 1, /* 323C4 (205764) */ + 1, /* 323C5 (205765) */ + 1, /* 323C6 (205766) */ + 1, /* 323C7 (205767) */ + 1, /* 323C8 (205768) */ + 1, /* 323C9 (205769) */ + 1, /* 323CA (205770) */ + 1, /* 323CB (205771) */ + 1, /* 323CC (205772) */ + 1, /* 323CD (205773) */ + 1, /* 323CE (205774) */ + 1, /* 323CF (205775) */ + 1, /* 323D0 (205776) */ + 1, /* 323D1 (205777) */ + 1, /* 323D2 (205778) */ + 1, /* 323D3 (205779) */ + 1, /* 323D4 (205780) */ + 1, /* 323D5 (205781) */ + 1, /* 323D6 (205782) */ + 1, /* 323D7 (205783) */ + 1, /* 323D8 (205784) */ + 1, /* 323D9 (205785) */ + 1, /* 323DA (205786) */ + 1, /* 323DB (205787) */ + 1, /* 323DC (205788) */ + 1, /* 323DD (205789) */ + 1, /* 323DE (205790) */ + 1, /* 323DF (205791) */ + 1, /* 323E0 (205792) */ + 1, /* 323E1 (205793) */ + 1, /* 323E2 (205794) */ + 1, /* 323E3 (205795) */ + 1, /* 323E4 (205796) */ + 1, /* 323E5 (205797) */ + 1, /* 323E6 (205798) */ + 1, /* 323E7 (205799) */ + 1, /* 323E8 (205800) */ + 1, /* 323E9 (205801) */ + 1, /* 323EA (205802) */ + 1, /* 323EB (205803) */ + 1, /* 323EC (205804) */ + 1, /* 323ED (205805) */ + 1, /* 323EE (205806) */ + 1, /* 323EF (205807) */ + 1, /* 323F0 (205808) */ + 1, /* 323F1 (205809) */ + 1, /* 323F2 (205810) */ + 1, /* 323F3 (205811) */ + 1, /* 323F4 (205812) */ + 1, /* 323F5 (205813) */ + 1, /* 323F6 (205814) */ + 1, /* 323F7 (205815) */ + 1, /* 323F8 (205816) */ + 1, /* 323F9 (205817) */ + 1, /* 323FA (205818) */ + 1, /* 323FB (205819) */ + 1, /* 323FC (205820) */ + 1, /* 323FD (205821) */ + 1, /* 323FE (205822) */ + 1, /* 323FF (205823) */ + 1, /* 32400 (205824) */ + 1, /* 32401 (205825) */ + 1, /* 32402 (205826) */ + 1, /* 32403 (205827) */ + 1, /* 32404 (205828) */ + 1, /* 32405 (205829) */ + 1, /* 32406 (205830) */ + 1, /* 32407 (205831) */ + 1, /* 32408 (205832) */ + 1, /* 32409 (205833) */ + 1, /* 3240A (205834) */ + 1, /* 3240B (205835) */ + 1, /* 3240C (205836) */ + 1, /* 3240D (205837) */ + 1, /* 3240E (205838) */ + 1, /* 3240F (205839) */ + 1, /* 32410 (205840) */ + 1, /* 32411 (205841) */ + 1, /* 32412 (205842) */ + 1, /* 32413 (205843) */ + 1, /* 32414 (205844) */ + 1, /* 32415 (205845) */ + 1, /* 32416 (205846) */ + 1, /* 32417 (205847) */ + 1, /* 32418 (205848) */ + 1, /* 32419 (205849) */ + 1, /* 3241A (205850) */ + 1, /* 3241B (205851) */ + 1, /* 3241C (205852) */ + 1, /* 3241D (205853) */ + 1, /* 3241E (205854) */ + 1, /* 3241F (205855) */ + 1, /* 32420 (205856) */ + 1, /* 32421 (205857) */ + 1, /* 32422 (205858) */ + 1, /* 32423 (205859) */ + 1, /* 32424 (205860) */ + 1, /* 32425 (205861) */ + 1, /* 32426 (205862) */ + 1, /* 32427 (205863) */ + 1, /* 32428 (205864) */ + 1, /* 32429 (205865) */ + 1, /* 3242A (205866) */ + 1, /* 3242B (205867) */ + 1, /* 3242C (205868) */ + 1, /* 3242D (205869) */ + 1, /* 3242E (205870) */ + 1, /* 3242F (205871) */ + 1, /* 32430 (205872) */ + 1, /* 32431 (205873) */ + 1, /* 32432 (205874) */ + 1, /* 32433 (205875) */ + 1, /* 32434 (205876) */ + 1, /* 32435 (205877) */ + 1, /* 32436 (205878) */ + 1, /* 32437 (205879) */ + 1, /* 32438 (205880) */ + 1, /* 32439 (205881) */ + 1, /* 3243A (205882) */ + 1, /* 3243B (205883) */ + 1, /* 3243C (205884) */ + 1, /* 3243D (205885) */ + 1, /* 3243E (205886) */ + 1, /* 3243F (205887) */ + 1, /* 32440 (205888) */ + 1, /* 32441 (205889) */ + 1, /* 32442 (205890) */ + 1, /* 32443 (205891) */ + 1, /* 32444 (205892) */ + 1, /* 32445 (205893) */ + 1, /* 32446 (205894) */ + 1, /* 32447 (205895) */ + 1, /* 32448 (205896) */ + 1, /* 32449 (205897) */ + 1, /* 3244A (205898) */ + 1, /* 3244B (205899) */ + 1, /* 3244C (205900) */ + 1, /* 3244D (205901) */ + 1, /* 3244E (205902) */ + 1, /* 3244F (205903) */ + 1, /* 32450 (205904) */ + 1, /* 32451 (205905) */ + 1, /* 32452 (205906) */ + 1, /* 32453 (205907) */ + 1, /* 32454 (205908) */ + 1, /* 32455 (205909) */ + 1, /* 32456 (205910) */ + 1, /* 32457 (205911) */ + 1, /* 32458 (205912) */ + 1, /* 32459 (205913) */ + 1, /* 3245A (205914) */ + 1, /* 3245B (205915) */ + 1, /* 3245C (205916) */ + 1, /* 3245D (205917) */ + 1, /* 3245E (205918) */ + 1, /* 3245F (205919) */ + 1, /* 32460 (205920) */ + 1, /* 32461 (205921) */ + 1, /* 32462 (205922) */ + 1, /* 32463 (205923) */ + 1, /* 32464 (205924) */ + 1, /* 32465 (205925) */ + 1, /* 32466 (205926) */ + 1, /* 32467 (205927) */ + 1, /* 32468 (205928) */ + 1, /* 32469 (205929) */ + 1, /* 3246A (205930) */ + 1, /* 3246B (205931) */ + 1, /* 3246C (205932) */ + 1, /* 3246D (205933) */ + 1, /* 3246E (205934) */ + 1, /* 3246F (205935) */ + 1, /* 32470 (205936) */ + 1, /* 32471 (205937) */ + 1, /* 32472 (205938) */ + 1, /* 32473 (205939) */ + 1, /* 32474 (205940) */ + 1, /* 32475 (205941) */ + 1, /* 32476 (205942) */ + 1, /* 32477 (205943) */ + 1, /* 32478 (205944) */ + 1, /* 32479 (205945) */ + 1, /* 3247A (205946) */ + 1, /* 3247B (205947) */ + 1, /* 3247C (205948) */ + 1, /* 3247D (205949) */ + 1, /* 3247E (205950) */ + 1, /* 3247F (205951) */ + 1, /* 32480 (205952) */ + 1, /* 32481 (205953) */ + 1, /* 32482 (205954) */ + 1, /* 32483 (205955) */ + 1, /* 32484 (205956) */ + 1, /* 32485 (205957) */ + 1, /* 32486 (205958) */ + 1, /* 32487 (205959) */ + 1, /* 32488 (205960) */ + 1, /* 32489 (205961) */ + 1, /* 3248A (205962) */ + 1, /* 3248B (205963) */ + 1, /* 3248C (205964) */ + 1, /* 3248D (205965) */ + 1, /* 3248E (205966) */ + 1, /* 3248F (205967) */ + 1, /* 32490 (205968) */ + 1, /* 32491 (205969) */ + 1, /* 32492 (205970) */ + 1, /* 32493 (205971) */ + 1, /* 32494 (205972) */ + 1, /* 32495 (205973) */ + 1, /* 32496 (205974) */ + 1, /* 32497 (205975) */ + 1, /* 32498 (205976) */ + 1, /* 32499 (205977) */ + 1, /* 3249A (205978) */ + 1, /* 3249B (205979) */ + 1, /* 3249C (205980) */ + 1, /* 3249D (205981) */ + 1, /* 3249E (205982) */ + 1, /* 3249F (205983) */ + 1, /* 324A0 (205984) */ + 1, /* 324A1 (205985) */ + 1, /* 324A2 (205986) */ + 1, /* 324A3 (205987) */ + 1, /* 324A4 (205988) */ + 1, /* 324A5 (205989) */ + 1, /* 324A6 (205990) */ + 1, /* 324A7 (205991) */ + 1, /* 324A8 (205992) */ + 1, /* 324A9 (205993) */ + 1, /* 324AA (205994) */ + 1, /* 324AB (205995) */ + 1, /* 324AC (205996) */ + 1, /* 324AD (205997) */ + 1, /* 324AE (205998) */ + 1, /* 324AF (205999) */ + 1, /* 324B0 (206000) */ + 1, /* 324B1 (206001) */ + 1, /* 324B2 (206002) */ + 1, /* 324B3 (206003) */ + 1, /* 324B4 (206004) */ + 1, /* 324B5 (206005) */ + 1, /* 324B6 (206006) */ + 1, /* 324B7 (206007) */ + 1, /* 324B8 (206008) */ + 1, /* 324B9 (206009) */ + 1, /* 324BA (206010) */ + 1, /* 324BB (206011) */ + 1, /* 324BC (206012) */ + 1, /* 324BD (206013) */ + 1, /* 324BE (206014) */ + 1, /* 324BF (206015) */ + 1, /* 324C0 (206016) */ + 1, /* 324C1 (206017) */ + 1, /* 324C2 (206018) */ + 1, /* 324C3 (206019) */ + 1, /* 324C4 (206020) */ + 1, /* 324C5 (206021) */ + 1, /* 324C6 (206022) */ + 1, /* 324C7 (206023) */ + 1, /* 324C8 (206024) */ + 1, /* 324C9 (206025) */ + 1, /* 324CA (206026) */ + 1, /* 324CB (206027) */ + 1, /* 324CC (206028) */ + 1, /* 324CD (206029) */ + 1, /* 324CE (206030) */ + 1, /* 324CF (206031) */ + 1, /* 324D0 (206032) */ + 1, /* 324D1 (206033) */ + 1, /* 324D2 (206034) */ + 1, /* 324D3 (206035) */ + 1, /* 324D4 (206036) */ + 1, /* 324D5 (206037) */ + 1, /* 324D6 (206038) */ + 1, /* 324D7 (206039) */ + 1, /* 324D8 (206040) */ + 1, /* 324D9 (206041) */ + 1, /* 324DA (206042) */ + 1, /* 324DB (206043) */ + 1, /* 324DC (206044) */ + 1, /* 324DD (206045) */ + 1, /* 324DE (206046) */ + 1, /* 324DF (206047) */ + 1, /* 324E0 (206048) */ + 1, /* 324E1 (206049) */ + 1, /* 324E2 (206050) */ + 1, /* 324E3 (206051) */ + 1, /* 324E4 (206052) */ + 1, /* 324E5 (206053) */ + 1, /* 324E6 (206054) */ + 1, /* 324E7 (206055) */ + 1, /* 324E8 (206056) */ + 1, /* 324E9 (206057) */ + 1, /* 324EA (206058) */ + 1, /* 324EB (206059) */ + 1, /* 324EC (206060) */ + 1, /* 324ED (206061) */ + 1, /* 324EE (206062) */ + 1, /* 324EF (206063) */ + 1, /* 324F0 (206064) */ + 1, /* 324F1 (206065) */ + 1, /* 324F2 (206066) */ + 1, /* 324F3 (206067) */ + 1, /* 324F4 (206068) */ + 1, /* 324F5 (206069) */ + 1, /* 324F6 (206070) */ + 1, /* 324F7 (206071) */ + 1, /* 324F8 (206072) */ + 1, /* 324F9 (206073) */ + 1, /* 324FA (206074) */ + 1, /* 324FB (206075) */ + 1, /* 324FC (206076) */ + 1, /* 324FD (206077) */ + 1, /* 324FE (206078) */ + 1, /* 324FF (206079) */ + 1, /* 32500 (206080) */ + 1, /* 32501 (206081) */ + 1, /* 32502 (206082) */ + 1, /* 32503 (206083) */ + 1, /* 32504 (206084) */ + 1, /* 32505 (206085) */ + 1, /* 32506 (206086) */ + 1, /* 32507 (206087) */ + 1, /* 32508 (206088) */ + 1, /* 32509 (206089) */ + 1, /* 3250A (206090) */ + 1, /* 3250B (206091) */ + 1, /* 3250C (206092) */ + 1, /* 3250D (206093) */ + 1, /* 3250E (206094) */ + 1, /* 3250F (206095) */ + 1, /* 32510 (206096) */ + 1, /* 32511 (206097) */ + 1, /* 32512 (206098) */ + 1, /* 32513 (206099) */ + 1, /* 32514 (206100) */ + 1, /* 32515 (206101) */ + 1, /* 32516 (206102) */ + 1, /* 32517 (206103) */ + 1, /* 32518 (206104) */ + 1, /* 32519 (206105) */ + 1, /* 3251A (206106) */ + 1, /* 3251B (206107) */ + 1, /* 3251C (206108) */ + 1, /* 3251D (206109) */ + 1, /* 3251E (206110) */ + 1, /* 3251F (206111) */ + 1, /* 32520 (206112) */ + 1, /* 32521 (206113) */ + 1, /* 32522 (206114) */ + 1, /* 32523 (206115) */ + 1, /* 32524 (206116) */ + 1, /* 32525 (206117) */ + 1, /* 32526 (206118) */ + 1, /* 32527 (206119) */ + 1, /* 32528 (206120) */ + 1, /* 32529 (206121) */ + 1, /* 3252A (206122) */ + 1, /* 3252B (206123) */ + 1, /* 3252C (206124) */ + 1, /* 3252D (206125) */ + 1, /* 3252E (206126) */ + 1, /* 3252F (206127) */ + 1, /* 32530 (206128) */ + 1, /* 32531 (206129) */ + 1, /* 32532 (206130) */ + 1, /* 32533 (206131) */ + 1, /* 32534 (206132) */ + 1, /* 32535 (206133) */ + 1, /* 32536 (206134) */ + 1, /* 32537 (206135) */ + 1, /* 32538 (206136) */ + 1, /* 32539 (206137) */ + 1, /* 3253A (206138) */ + 1, /* 3253B (206139) */ + 1, /* 3253C (206140) */ + 1, /* 3253D (206141) */ + 1, /* 3253E (206142) */ + 1, /* 3253F (206143) */ + 1, /* 32540 (206144) */ + 1, /* 32541 (206145) */ + 1, /* 32542 (206146) */ + 1, /* 32543 (206147) */ + 1, /* 32544 (206148) */ + 1, /* 32545 (206149) */ + 1, /* 32546 (206150) */ + 1, /* 32547 (206151) */ + 1, /* 32548 (206152) */ + 1, /* 32549 (206153) */ + 1, /* 3254A (206154) */ + 1, /* 3254B (206155) */ + 1, /* 3254C (206156) */ + 1, /* 3254D (206157) */ + 1, /* 3254E (206158) */ + 1, /* 3254F (206159) */ + 1, /* 32550 (206160) */ + 1, /* 32551 (206161) */ + 1, /* 32552 (206162) */ + 1, /* 32553 (206163) */ + 1, /* 32554 (206164) */ + 1, /* 32555 (206165) */ + 1, /* 32556 (206166) */ + 1, /* 32557 (206167) */ + 1, /* 32558 (206168) */ + 1, /* 32559 (206169) */ + 1, /* 3255A (206170) */ + 1, /* 3255B (206171) */ + 1, /* 3255C (206172) */ + 1, /* 3255D (206173) */ + 1, /* 3255E (206174) */ + 1, /* 3255F (206175) */ + 1, /* 32560 (206176) */ + 1, /* 32561 (206177) */ + 1, /* 32562 (206178) */ + 1, /* 32563 (206179) */ + 1, /* 32564 (206180) */ + 1, /* 32565 (206181) */ + 1, /* 32566 (206182) */ + 1, /* 32567 (206183) */ + 1, /* 32568 (206184) */ + 1, /* 32569 (206185) */ + 1, /* 3256A (206186) */ + 1, /* 3256B (206187) */ + 1, /* 3256C (206188) */ + 1, /* 3256D (206189) */ + 1, /* 3256E (206190) */ + 1, /* 3256F (206191) */ + 1, /* 32570 (206192) */ + 1, /* 32571 (206193) */ + 1, /* 32572 (206194) */ + 1, /* 32573 (206195) */ + 1, /* 32574 (206196) */ + 1, /* 32575 (206197) */ + 1, /* 32576 (206198) */ + 1, /* 32577 (206199) */ + 1, /* 32578 (206200) */ + 1, /* 32579 (206201) */ + 1, /* 3257A (206202) */ + 1, /* 3257B (206203) */ + 1, /* 3257C (206204) */ + 1, /* 3257D (206205) */ + 1, /* 3257E (206206) */ + 1, /* 3257F (206207) */ + 1, /* 32580 (206208) */ + 1, /* 32581 (206209) */ + 1, /* 32582 (206210) */ + 1, /* 32583 (206211) */ + 1, /* 32584 (206212) */ + 1, /* 32585 (206213) */ + 1, /* 32586 (206214) */ + 1, /* 32587 (206215) */ + 1, /* 32588 (206216) */ + 1, /* 32589 (206217) */ + 1, /* 3258A (206218) */ + 1, /* 3258B (206219) */ + 1, /* 3258C (206220) */ + 1, /* 3258D (206221) */ + 1, /* 3258E (206222) */ + 1, /* 3258F (206223) */ + 1, /* 32590 (206224) */ + 1, /* 32591 (206225) */ + 1, /* 32592 (206226) */ + 1, /* 32593 (206227) */ + 1, /* 32594 (206228) */ + 1, /* 32595 (206229) */ + 1, /* 32596 (206230) */ + 1, /* 32597 (206231) */ + 1, /* 32598 (206232) */ + 1, /* 32599 (206233) */ + 1, /* 3259A (206234) */ + 1, /* 3259B (206235) */ + 1, /* 3259C (206236) */ + 1, /* 3259D (206237) */ + 1, /* 3259E (206238) */ + 1, /* 3259F (206239) */ + 1, /* 325A0 (206240) */ + 1, /* 325A1 (206241) */ + 1, /* 325A2 (206242) */ + 1, /* 325A3 (206243) */ + 1, /* 325A4 (206244) */ + 1, /* 325A5 (206245) */ + 1, /* 325A6 (206246) */ + 1, /* 325A7 (206247) */ + 1, /* 325A8 (206248) */ + 1, /* 325A9 (206249) */ + 1, /* 325AA (206250) */ + 1, /* 325AB (206251) */ + 1, /* 325AC (206252) */ + 1, /* 325AD (206253) */ + 1, /* 325AE (206254) */ + 1, /* 325AF (206255) */ + 1, /* 325B0 (206256) */ + 1, /* 325B1 (206257) */ + 1, /* 325B2 (206258) */ + 1, /* 325B3 (206259) */ + 1, /* 325B4 (206260) */ + 1, /* 325B5 (206261) */ + 1, /* 325B6 (206262) */ + 1, /* 325B7 (206263) */ + 1, /* 325B8 (206264) */ + 1, /* 325B9 (206265) */ + 1, /* 325BA (206266) */ + 1, /* 325BB (206267) */ + 1, /* 325BC (206268) */ + 1, /* 325BD (206269) */ + 1, /* 325BE (206270) */ + 1, /* 325BF (206271) */ + 1, /* 325C0 (206272) */ + 1, /* 325C1 (206273) */ + 1, /* 325C2 (206274) */ + 1, /* 325C3 (206275) */ + 1, /* 325C4 (206276) */ + 1, /* 325C5 (206277) */ + 1, /* 325C6 (206278) */ + 1, /* 325C7 (206279) */ + 1, /* 325C8 (206280) */ + 1, /* 325C9 (206281) */ + 1, /* 325CA (206282) */ + 1, /* 325CB (206283) */ + 1, /* 325CC (206284) */ + 1, /* 325CD (206285) */ + 1, /* 325CE (206286) */ + 1, /* 325CF (206287) */ + 1, /* 325D0 (206288) */ + 1, /* 325D1 (206289) */ + 1, /* 325D2 (206290) */ + 1, /* 325D3 (206291) */ + 1, /* 325D4 (206292) */ + 1, /* 325D5 (206293) */ + 1, /* 325D6 (206294) */ + 1, /* 325D7 (206295) */ + 1, /* 325D8 (206296) */ + 1, /* 325D9 (206297) */ + 1, /* 325DA (206298) */ + 1, /* 325DB (206299) */ + 1, /* 325DC (206300) */ + 1, /* 325DD (206301) */ + 1, /* 325DE (206302) */ + 1, /* 325DF (206303) */ + 1, /* 325E0 (206304) */ + 1, /* 325E1 (206305) */ + 1, /* 325E2 (206306) */ + 1, /* 325E3 (206307) */ + 1, /* 325E4 (206308) */ + 1, /* 325E5 (206309) */ + 1, /* 325E6 (206310) */ + 1, /* 325E7 (206311) */ + 1, /* 325E8 (206312) */ + 1, /* 325E9 (206313) */ + 1, /* 325EA (206314) */ + 1, /* 325EB (206315) */ + 1, /* 325EC (206316) */ + 1, /* 325ED (206317) */ + 1, /* 325EE (206318) */ + 1, /* 325EF (206319) */ + 1, /* 325F0 (206320) */ + 1, /* 325F1 (206321) */ + 1, /* 325F2 (206322) */ + 1, /* 325F3 (206323) */ + 1, /* 325F4 (206324) */ + 1, /* 325F5 (206325) */ + 1, /* 325F6 (206326) */ + 1, /* 325F7 (206327) */ + 1, /* 325F8 (206328) */ + 1, /* 325F9 (206329) */ + 1, /* 325FA (206330) */ + 1, /* 325FB (206331) */ + 1, /* 325FC (206332) */ + 1, /* 325FD (206333) */ + 1, /* 325FE (206334) */ + 1, /* 325FF (206335) */ + 1, /* 32600 (206336) */ + 1, /* 32601 (206337) */ + 1, /* 32602 (206338) */ + 1, /* 32603 (206339) */ + 1, /* 32604 (206340) */ + 1, /* 32605 (206341) */ + 1, /* 32606 (206342) */ + 1, /* 32607 (206343) */ + 1, /* 32608 (206344) */ + 1, /* 32609 (206345) */ + 1, /* 3260A (206346) */ + 1, /* 3260B (206347) */ + 1, /* 3260C (206348) */ + 1, /* 3260D (206349) */ + 1, /* 3260E (206350) */ + 1, /* 3260F (206351) */ + 1, /* 32610 (206352) */ + 1, /* 32611 (206353) */ + 1, /* 32612 (206354) */ + 1, /* 32613 (206355) */ + 1, /* 32614 (206356) */ + 1, /* 32615 (206357) */ + 1, /* 32616 (206358) */ + 1, /* 32617 (206359) */ + 1, /* 32618 (206360) */ + 1, /* 32619 (206361) */ + 1, /* 3261A (206362) */ + 1, /* 3261B (206363) */ + 1, /* 3261C (206364) */ + 1, /* 3261D (206365) */ + 1, /* 3261E (206366) */ + 1, /* 3261F (206367) */ + 1, /* 32620 (206368) */ + 1, /* 32621 (206369) */ + 1, /* 32622 (206370) */ + 1, /* 32623 (206371) */ + 1, /* 32624 (206372) */ + 1, /* 32625 (206373) */ + 1, /* 32626 (206374) */ + 1, /* 32627 (206375) */ + 1, /* 32628 (206376) */ + 1, /* 32629 (206377) */ + 1, /* 3262A (206378) */ + 1, /* 3262B (206379) */ + 1, /* 3262C (206380) */ + 1, /* 3262D (206381) */ + 1, /* 3262E (206382) */ + 1, /* 3262F (206383) */ + 1, /* 32630 (206384) */ + 1, /* 32631 (206385) */ + 1, /* 32632 (206386) */ + 1, /* 32633 (206387) */ + 1, /* 32634 (206388) */ + 1, /* 32635 (206389) */ + 1, /* 32636 (206390) */ + 1, /* 32637 (206391) */ + 1, /* 32638 (206392) */ + 1, /* 32639 (206393) */ + 1, /* 3263A (206394) */ + 1, /* 3263B (206395) */ + 1, /* 3263C (206396) */ + 1, /* 3263D (206397) */ + 1, /* 3263E (206398) */ + 1, /* 3263F (206399) */ + 1, /* 32640 (206400) */ + 1, /* 32641 (206401) */ + 1, /* 32642 (206402) */ + 1, /* 32643 (206403) */ + 1, /* 32644 (206404) */ + 1, /* 32645 (206405) */ + 1, /* 32646 (206406) */ + 1, /* 32647 (206407) */ + 1, /* 32648 (206408) */ + 1, /* 32649 (206409) */ + 1, /* 3264A (206410) */ + 1, /* 3264B (206411) */ + 1, /* 3264C (206412) */ + 1, /* 3264D (206413) */ + 1, /* 3264E (206414) */ + 1, /* 3264F (206415) */ + 1, /* 32650 (206416) */ + 1, /* 32651 (206417) */ + 1, /* 32652 (206418) */ + 1, /* 32653 (206419) */ + 1, /* 32654 (206420) */ + 1, /* 32655 (206421) */ + 1, /* 32656 (206422) */ + 1, /* 32657 (206423) */ + 1, /* 32658 (206424) */ + 1, /* 32659 (206425) */ + 1, /* 3265A (206426) */ + 1, /* 3265B (206427) */ + 1, /* 3265C (206428) */ + 1, /* 3265D (206429) */ + 1, /* 3265E (206430) */ + 1, /* 3265F (206431) */ + 1, /* 32660 (206432) */ + 1, /* 32661 (206433) */ + 1, /* 32662 (206434) */ + 1, /* 32663 (206435) */ + 1, /* 32664 (206436) */ + 1, /* 32665 (206437) */ + 1, /* 32666 (206438) */ + 1, /* 32667 (206439) */ + 1, /* 32668 (206440) */ + 1, /* 32669 (206441) */ + 1, /* 3266A (206442) */ + 1, /* 3266B (206443) */ + 1, /* 3266C (206444) */ + 1, /* 3266D (206445) */ + 1, /* 3266E (206446) */ + 1, /* 3266F (206447) */ + 1, /* 32670 (206448) */ + 1, /* 32671 (206449) */ + 1, /* 32672 (206450) */ + 1, /* 32673 (206451) */ + 1, /* 32674 (206452) */ + 1, /* 32675 (206453) */ + 1, /* 32676 (206454) */ + 1, /* 32677 (206455) */ + 1, /* 32678 (206456) */ + 1, /* 32679 (206457) */ + 1, /* 3267A (206458) */ + 1, /* 3267B (206459) */ + 1, /* 3267C (206460) */ + 1, /* 3267D (206461) */ + 1, /* 3267E (206462) */ + 1, /* 3267F (206463) */ + 1, /* 32680 (206464) */ + 1, /* 32681 (206465) */ + 1, /* 32682 (206466) */ + 1, /* 32683 (206467) */ + 1, /* 32684 (206468) */ + 1, /* 32685 (206469) */ + 1, /* 32686 (206470) */ + 1, /* 32687 (206471) */ + 1, /* 32688 (206472) */ + 1, /* 32689 (206473) */ + 1, /* 3268A (206474) */ + 1, /* 3268B (206475) */ + 1, /* 3268C (206476) */ + 1, /* 3268D (206477) */ + 1, /* 3268E (206478) */ + 1, /* 3268F (206479) */ + 1, /* 32690 (206480) */ + 1, /* 32691 (206481) */ + 1, /* 32692 (206482) */ + 1, /* 32693 (206483) */ + 1, /* 32694 (206484) */ + 1, /* 32695 (206485) */ + 1, /* 32696 (206486) */ + 1, /* 32697 (206487) */ + 1, /* 32698 (206488) */ + 1, /* 32699 (206489) */ + 1, /* 3269A (206490) */ + 1, /* 3269B (206491) */ + 1, /* 3269C (206492) */ + 1, /* 3269D (206493) */ + 1, /* 3269E (206494) */ + 1, /* 3269F (206495) */ + 1, /* 326A0 (206496) */ + 1, /* 326A1 (206497) */ + 1, /* 326A2 (206498) */ + 1, /* 326A3 (206499) */ + 1, /* 326A4 (206500) */ + 1, /* 326A5 (206501) */ + 1, /* 326A6 (206502) */ + 1, /* 326A7 (206503) */ + 1, /* 326A8 (206504) */ + 1, /* 326A9 (206505) */ + 1, /* 326AA (206506) */ + 1, /* 326AB (206507) */ + 1, /* 326AC (206508) */ + 1, /* 326AD (206509) */ + 1, /* 326AE (206510) */ + 1, /* 326AF (206511) */ + 1, /* 326B0 (206512) */ + 1, /* 326B1 (206513) */ + 1, /* 326B2 (206514) */ + 1, /* 326B3 (206515) */ + 1, /* 326B4 (206516) */ + 1, /* 326B5 (206517) */ + 1, /* 326B6 (206518) */ + 1, /* 326B7 (206519) */ + 1, /* 326B8 (206520) */ + 1, /* 326B9 (206521) */ + 1, /* 326BA (206522) */ + 1, /* 326BB (206523) */ + 1, /* 326BC (206524) */ + 1, /* 326BD (206525) */ + 1, /* 326BE (206526) */ + 1, /* 326BF (206527) */ + 1, /* 326C0 (206528) */ + 1, /* 326C1 (206529) */ + 1, /* 326C2 (206530) */ + 1, /* 326C3 (206531) */ + 1, /* 326C4 (206532) */ + 1, /* 326C5 (206533) */ + 1, /* 326C6 (206534) */ + 1, /* 326C7 (206535) */ + 1, /* 326C8 (206536) */ + 1, /* 326C9 (206537) */ + 1, /* 326CA (206538) */ + 1, /* 326CB (206539) */ + 1, /* 326CC (206540) */ + 1, /* 326CD (206541) */ + 1, /* 326CE (206542) */ + 1, /* 326CF (206543) */ + 1, /* 326D0 (206544) */ + 1, /* 326D1 (206545) */ + 1, /* 326D2 (206546) */ + 1, /* 326D3 (206547) */ + 1, /* 326D4 (206548) */ + 1, /* 326D5 (206549) */ + 1, /* 326D6 (206550) */ + 1, /* 326D7 (206551) */ + 1, /* 326D8 (206552) */ + 1, /* 326D9 (206553) */ + 1, /* 326DA (206554) */ + 1, /* 326DB (206555) */ + 1, /* 326DC (206556) */ + 1, /* 326DD (206557) */ + 1, /* 326DE (206558) */ + 1, /* 326DF (206559) */ + 1, /* 326E0 (206560) */ + 1, /* 326E1 (206561) */ + 1, /* 326E2 (206562) */ + 1, /* 326E3 (206563) */ + 1, /* 326E4 (206564) */ + 1, /* 326E5 (206565) */ + 1, /* 326E6 (206566) */ + 1, /* 326E7 (206567) */ + 1, /* 326E8 (206568) */ + 1, /* 326E9 (206569) */ + 1, /* 326EA (206570) */ + 1, /* 326EB (206571) */ + 1, /* 326EC (206572) */ + 1, /* 326ED (206573) */ + 1, /* 326EE (206574) */ + 1, /* 326EF (206575) */ + 1, /* 326F0 (206576) */ + 1, /* 326F1 (206577) */ + 1, /* 326F2 (206578) */ + 1, /* 326F3 (206579) */ + 1, /* 326F4 (206580) */ + 1, /* 326F5 (206581) */ + 1, /* 326F6 (206582) */ + 1, /* 326F7 (206583) */ + 1, /* 326F8 (206584) */ + 1, /* 326F9 (206585) */ + 1, /* 326FA (206586) */ + 1, /* 326FB (206587) */ + 1, /* 326FC (206588) */ + 1, /* 326FD (206589) */ + 1, /* 326FE (206590) */ + 1, /* 326FF (206591) */ + 1, /* 32700 (206592) */ + 1, /* 32701 (206593) */ + 1, /* 32702 (206594) */ + 1, /* 32703 (206595) */ + 1, /* 32704 (206596) */ + 1, /* 32705 (206597) */ + 1, /* 32706 (206598) */ + 1, /* 32707 (206599) */ + 1, /* 32708 (206600) */ + 1, /* 32709 (206601) */ + 1, /* 3270A (206602) */ + 1, /* 3270B (206603) */ + 1, /* 3270C (206604) */ + 1, /* 3270D (206605) */ + 1, /* 3270E (206606) */ + 1, /* 3270F (206607) */ + 1, /* 32710 (206608) */ + 1, /* 32711 (206609) */ + 1, /* 32712 (206610) */ + 1, /* 32713 (206611) */ + 1, /* 32714 (206612) */ + 1, /* 32715 (206613) */ + 1, /* 32716 (206614) */ + 1, /* 32717 (206615) */ + 1, /* 32718 (206616) */ + 1, /* 32719 (206617) */ + 1, /* 3271A (206618) */ + 1, /* 3271B (206619) */ + 1, /* 3271C (206620) */ + 1, /* 3271D (206621) */ + 1, /* 3271E (206622) */ + 1, /* 3271F (206623) */ + 1, /* 32720 (206624) */ + 1, /* 32721 (206625) */ + 1, /* 32722 (206626) */ + 1, /* 32723 (206627) */ + 1, /* 32724 (206628) */ + 1, /* 32725 (206629) */ + 1, /* 32726 (206630) */ + 1, /* 32727 (206631) */ + 1, /* 32728 (206632) */ + 1, /* 32729 (206633) */ + 1, /* 3272A (206634) */ + 1, /* 3272B (206635) */ + 1, /* 3272C (206636) */ + 1, /* 3272D (206637) */ + 1, /* 3272E (206638) */ + 1, /* 3272F (206639) */ + 1, /* 32730 (206640) */ + 1, /* 32731 (206641) */ + 1, /* 32732 (206642) */ + 1, /* 32733 (206643) */ + 1, /* 32734 (206644) */ + 1, /* 32735 (206645) */ + 1, /* 32736 (206646) */ + 1, /* 32737 (206647) */ + 1, /* 32738 (206648) */ + 1, /* 32739 (206649) */ + 1, /* 3273A (206650) */ + 1, /* 3273B (206651) */ + 1, /* 3273C (206652) */ + 1, /* 3273D (206653) */ + 1, /* 3273E (206654) */ + 1, /* 3273F (206655) */ + 1, /* 32740 (206656) */ + 1, /* 32741 (206657) */ + 1, /* 32742 (206658) */ + 1, /* 32743 (206659) */ + 1, /* 32744 (206660) */ + 1, /* 32745 (206661) */ + 1, /* 32746 (206662) */ + 1, /* 32747 (206663) */ + 1, /* 32748 (206664) */ + 1, /* 32749 (206665) */ + 1, /* 3274A (206666) */ + 1, /* 3274B (206667) */ + 1, /* 3274C (206668) */ + 1, /* 3274D (206669) */ + 1, /* 3274E (206670) */ + 1, /* 3274F (206671) */ + 1, /* 32750 (206672) */ + 1, /* 32751 (206673) */ + 1, /* 32752 (206674) */ + 1, /* 32753 (206675) */ + 1, /* 32754 (206676) */ + 1, /* 32755 (206677) */ + 1, /* 32756 (206678) */ + 1, /* 32757 (206679) */ + 1, /* 32758 (206680) */ + 1, /* 32759 (206681) */ + 1, /* 3275A (206682) */ + 1, /* 3275B (206683) */ + 1, /* 3275C (206684) */ + 1, /* 3275D (206685) */ + 1, /* 3275E (206686) */ + 1, /* 3275F (206687) */ + 1, /* 32760 (206688) */ + 1, /* 32761 (206689) */ + 1, /* 32762 (206690) */ + 1, /* 32763 (206691) */ + 1, /* 32764 (206692) */ + 1, /* 32765 (206693) */ + 1, /* 32766 (206694) */ + 1, /* 32767 (206695) */ + 1, /* 32768 (206696) */ + 1, /* 32769 (206697) */ + 1, /* 3276A (206698) */ + 1, /* 3276B (206699) */ + 1, /* 3276C (206700) */ + 1, /* 3276D (206701) */ + 1, /* 3276E (206702) */ + 1, /* 3276F (206703) */ + 1, /* 32770 (206704) */ + 1, /* 32771 (206705) */ + 1, /* 32772 (206706) */ + 1, /* 32773 (206707) */ + 1, /* 32774 (206708) */ + 1, /* 32775 (206709) */ + 1, /* 32776 (206710) */ + 1, /* 32777 (206711) */ + 1, /* 32778 (206712) */ + 1, /* 32779 (206713) */ + 1, /* 3277A (206714) */ + 1, /* 3277B (206715) */ + 1, /* 3277C (206716) */ + 1, /* 3277D (206717) */ + 1, /* 3277E (206718) */ + 1, /* 3277F (206719) */ + 1, /* 32780 (206720) */ + 1, /* 32781 (206721) */ + 1, /* 32782 (206722) */ + 1, /* 32783 (206723) */ + 1, /* 32784 (206724) */ + 1, /* 32785 (206725) */ + 1, /* 32786 (206726) */ + 1, /* 32787 (206727) */ + 1, /* 32788 (206728) */ + 1, /* 32789 (206729) */ + 1, /* 3278A (206730) */ + 1, /* 3278B (206731) */ + 1, /* 3278C (206732) */ + 1, /* 3278D (206733) */ + 1, /* 3278E (206734) */ + 1, /* 3278F (206735) */ + 1, /* 32790 (206736) */ + 1, /* 32791 (206737) */ + 1, /* 32792 (206738) */ + 1, /* 32793 (206739) */ + 1, /* 32794 (206740) */ + 1, /* 32795 (206741) */ + 1, /* 32796 (206742) */ + 1, /* 32797 (206743) */ + 1, /* 32798 (206744) */ + 1, /* 32799 (206745) */ + 1, /* 3279A (206746) */ + 1, /* 3279B (206747) */ + 1, /* 3279C (206748) */ + 1, /* 3279D (206749) */ + 1, /* 3279E (206750) */ + 1, /* 3279F (206751) */ + 1, /* 327A0 (206752) */ + 1, /* 327A1 (206753) */ + 1, /* 327A2 (206754) */ + 1, /* 327A3 (206755) */ + 1, /* 327A4 (206756) */ + 1, /* 327A5 (206757) */ + 1, /* 327A6 (206758) */ + 1, /* 327A7 (206759) */ + 1, /* 327A8 (206760) */ + 1, /* 327A9 (206761) */ + 1, /* 327AA (206762) */ + 1, /* 327AB (206763) */ + 1, /* 327AC (206764) */ + 1, /* 327AD (206765) */ + 1, /* 327AE (206766) */ + 1, /* 327AF (206767) */ + 1, /* 327B0 (206768) */ + 1, /* 327B1 (206769) */ + 1, /* 327B2 (206770) */ + 1, /* 327B3 (206771) */ + 1, /* 327B4 (206772) */ + 1, /* 327B5 (206773) */ + 1, /* 327B6 (206774) */ + 1, /* 327B7 (206775) */ + 1, /* 327B8 (206776) */ + 1, /* 327B9 (206777) */ + 1, /* 327BA (206778) */ + 1, /* 327BB (206779) */ + 1, /* 327BC (206780) */ + 1, /* 327BD (206781) */ + 1, /* 327BE (206782) */ + 1, /* 327BF (206783) */ + 1, /* 327C0 (206784) */ + 1, /* 327C1 (206785) */ + 1, /* 327C2 (206786) */ + 1, /* 327C3 (206787) */ + 1, /* 327C4 (206788) */ + 1, /* 327C5 (206789) */ + 1, /* 327C6 (206790) */ + 1, /* 327C7 (206791) */ + 1, /* 327C8 (206792) */ + 1, /* 327C9 (206793) */ + 1, /* 327CA (206794) */ + 1, /* 327CB (206795) */ + 1, /* 327CC (206796) */ + 1, /* 327CD (206797) */ + 1, /* 327CE (206798) */ + 1, /* 327CF (206799) */ + 1, /* 327D0 (206800) */ + 1, /* 327D1 (206801) */ + 1, /* 327D2 (206802) */ + 1, /* 327D3 (206803) */ + 1, /* 327D4 (206804) */ + 1, /* 327D5 (206805) */ + 1, /* 327D6 (206806) */ + 1, /* 327D7 (206807) */ + 1, /* 327D8 (206808) */ + 1, /* 327D9 (206809) */ + 1, /* 327DA (206810) */ + 1, /* 327DB (206811) */ + 1, /* 327DC (206812) */ + 1, /* 327DD (206813) */ + 1, /* 327DE (206814) */ + 1, /* 327DF (206815) */ + 1, /* 327E0 (206816) */ + 1, /* 327E1 (206817) */ + 1, /* 327E2 (206818) */ + 1, /* 327E3 (206819) */ + 1, /* 327E4 (206820) */ + 1, /* 327E5 (206821) */ + 1, /* 327E6 (206822) */ + 1, /* 327E7 (206823) */ + 1, /* 327E8 (206824) */ + 1, /* 327E9 (206825) */ + 1, /* 327EA (206826) */ + 1, /* 327EB (206827) */ + 1, /* 327EC (206828) */ + 1, /* 327ED (206829) */ + 1, /* 327EE (206830) */ + 1, /* 327EF (206831) */ + 1, /* 327F0 (206832) */ + 1, /* 327F1 (206833) */ + 1, /* 327F2 (206834) */ + 1, /* 327F3 (206835) */ + 1, /* 327F4 (206836) */ + 1, /* 327F5 (206837) */ + 1, /* 327F6 (206838) */ + 1, /* 327F7 (206839) */ + 1, /* 327F8 (206840) */ + 1, /* 327F9 (206841) */ + 1, /* 327FA (206842) */ + 1, /* 327FB (206843) */ + 1, /* 327FC (206844) */ + 1, /* 327FD (206845) */ + 1, /* 327FE (206846) */ + 1, /* 327FF (206847) */ + 1, /* 32800 (206848) */ + 1, /* 32801 (206849) */ + 1, /* 32802 (206850) */ + 1, /* 32803 (206851) */ + 1, /* 32804 (206852) */ + 1, /* 32805 (206853) */ + 1, /* 32806 (206854) */ + 1, /* 32807 (206855) */ + 1, /* 32808 (206856) */ + 1, /* 32809 (206857) */ + 1, /* 3280A (206858) */ + 1, /* 3280B (206859) */ + 1, /* 3280C (206860) */ + 1, /* 3280D (206861) */ + 1, /* 3280E (206862) */ + 1, /* 3280F (206863) */ + 1, /* 32810 (206864) */ + 1, /* 32811 (206865) */ + 1, /* 32812 (206866) */ + 1, /* 32813 (206867) */ + 1, /* 32814 (206868) */ + 1, /* 32815 (206869) */ + 1, /* 32816 (206870) */ + 1, /* 32817 (206871) */ + 1, /* 32818 (206872) */ + 1, /* 32819 (206873) */ + 1, /* 3281A (206874) */ + 1, /* 3281B (206875) */ + 1, /* 3281C (206876) */ + 1, /* 3281D (206877) */ + 1, /* 3281E (206878) */ + 1, /* 3281F (206879) */ + 1, /* 32820 (206880) */ + 1, /* 32821 (206881) */ + 1, /* 32822 (206882) */ + 1, /* 32823 (206883) */ + 1, /* 32824 (206884) */ + 1, /* 32825 (206885) */ + 1, /* 32826 (206886) */ + 1, /* 32827 (206887) */ + 1, /* 32828 (206888) */ + 1, /* 32829 (206889) */ + 1, /* 3282A (206890) */ + 1, /* 3282B (206891) */ + 1, /* 3282C (206892) */ + 1, /* 3282D (206893) */ + 1, /* 3282E (206894) */ + 1, /* 3282F (206895) */ + 1, /* 32830 (206896) */ + 1, /* 32831 (206897) */ + 1, /* 32832 (206898) */ + 1, /* 32833 (206899) */ + 1, /* 32834 (206900) */ + 1, /* 32835 (206901) */ + 1, /* 32836 (206902) */ + 1, /* 32837 (206903) */ + 1, /* 32838 (206904) */ + 1, /* 32839 (206905) */ + 1, /* 3283A (206906) */ + 1, /* 3283B (206907) */ + 1, /* 3283C (206908) */ + 1, /* 3283D (206909) */ + 1, /* 3283E (206910) */ + 1, /* 3283F (206911) */ + 1, /* 32840 (206912) */ + 1, /* 32841 (206913) */ + 1, /* 32842 (206914) */ + 1, /* 32843 (206915) */ + 1, /* 32844 (206916) */ + 1, /* 32845 (206917) */ + 1, /* 32846 (206918) */ + 1, /* 32847 (206919) */ + 1, /* 32848 (206920) */ + 1, /* 32849 (206921) */ + 1, /* 3284A (206922) */ + 1, /* 3284B (206923) */ + 1, /* 3284C (206924) */ + 1, /* 3284D (206925) */ + 1, /* 3284E (206926) */ + 1, /* 3284F (206927) */ + 1, /* 32850 (206928) */ + 1, /* 32851 (206929) */ + 1, /* 32852 (206930) */ + 1, /* 32853 (206931) */ + 1, /* 32854 (206932) */ + 1, /* 32855 (206933) */ + 1, /* 32856 (206934) */ + 1, /* 32857 (206935) */ + 1, /* 32858 (206936) */ + 1, /* 32859 (206937) */ + 1, /* 3285A (206938) */ + 1, /* 3285B (206939) */ + 1, /* 3285C (206940) */ + 1, /* 3285D (206941) */ + 1, /* 3285E (206942) */ + 1, /* 3285F (206943) */ + 1, /* 32860 (206944) */ + 1, /* 32861 (206945) */ + 1, /* 32862 (206946) */ + 1, /* 32863 (206947) */ + 1, /* 32864 (206948) */ + 1, /* 32865 (206949) */ + 1, /* 32866 (206950) */ + 1, /* 32867 (206951) */ + 1, /* 32868 (206952) */ + 1, /* 32869 (206953) */ + 1, /* 3286A (206954) */ + 1, /* 3286B (206955) */ + 1, /* 3286C (206956) */ + 1, /* 3286D (206957) */ + 1, /* 3286E (206958) */ + 1, /* 3286F (206959) */ + 1, /* 32870 (206960) */ + 1, /* 32871 (206961) */ + 1, /* 32872 (206962) */ + 1, /* 32873 (206963) */ + 1, /* 32874 (206964) */ + 1, /* 32875 (206965) */ + 1, /* 32876 (206966) */ + 1, /* 32877 (206967) */ + 1, /* 32878 (206968) */ + 1, /* 32879 (206969) */ + 1, /* 3287A (206970) */ + 1, /* 3287B (206971) */ + 1, /* 3287C (206972) */ + 1, /* 3287D (206973) */ + 1, /* 3287E (206974) */ + 1, /* 3287F (206975) */ + 1, /* 32880 (206976) */ + 1, /* 32881 (206977) */ + 1, /* 32882 (206978) */ + 1, /* 32883 (206979) */ + 1, /* 32884 (206980) */ + 1, /* 32885 (206981) */ + 1, /* 32886 (206982) */ + 1, /* 32887 (206983) */ + 1, /* 32888 (206984) */ + 1, /* 32889 (206985) */ + 1, /* 3288A (206986) */ + 1, /* 3288B (206987) */ + 1, /* 3288C (206988) */ + 1, /* 3288D (206989) */ + 1, /* 3288E (206990) */ + 1, /* 3288F (206991) */ + 1, /* 32890 (206992) */ + 1, /* 32891 (206993) */ + 1, /* 32892 (206994) */ + 1, /* 32893 (206995) */ + 1, /* 32894 (206996) */ + 1, /* 32895 (206997) */ + 1, /* 32896 (206998) */ + 1, /* 32897 (206999) */ + 1, /* 32898 (207000) */ + 1, /* 32899 (207001) */ + 1, /* 3289A (207002) */ + 1, /* 3289B (207003) */ + 1, /* 3289C (207004) */ + 1, /* 3289D (207005) */ + 1, /* 3289E (207006) */ + 1, /* 3289F (207007) */ + 1, /* 328A0 (207008) */ + 1, /* 328A1 (207009) */ + 1, /* 328A2 (207010) */ + 1, /* 328A3 (207011) */ + 1, /* 328A4 (207012) */ + 1, /* 328A5 (207013) */ + 1, /* 328A6 (207014) */ + 1, /* 328A7 (207015) */ + 1, /* 328A8 (207016) */ + 1, /* 328A9 (207017) */ + 1, /* 328AA (207018) */ + 1, /* 328AB (207019) */ + 1, /* 328AC (207020) */ + 1, /* 328AD (207021) */ + 1, /* 328AE (207022) */ + 1, /* 328AF (207023) */ + 1, /* 328B0 (207024) */ + 1, /* 328B1 (207025) */ + 1, /* 328B2 (207026) */ + 1, /* 328B3 (207027) */ + 1, /* 328B4 (207028) */ + 1, /* 328B5 (207029) */ + 1, /* 328B6 (207030) */ + 1, /* 328B7 (207031) */ + 1, /* 328B8 (207032) */ + 1, /* 328B9 (207033) */ + 1, /* 328BA (207034) */ + 1, /* 328BB (207035) */ + 1, /* 328BC (207036) */ + 1, /* 328BD (207037) */ + 1, /* 328BE (207038) */ + 1, /* 328BF (207039) */ + 1, /* 328C0 (207040) */ + 1, /* 328C1 (207041) */ + 1, /* 328C2 (207042) */ + 1, /* 328C3 (207043) */ + 1, /* 328C4 (207044) */ + 1, /* 328C5 (207045) */ + 1, /* 328C6 (207046) */ + 1, /* 328C7 (207047) */ + 1, /* 328C8 (207048) */ + 1, /* 328C9 (207049) */ + 1, /* 328CA (207050) */ + 1, /* 328CB (207051) */ + 1, /* 328CC (207052) */ + 1, /* 328CD (207053) */ + 1, /* 328CE (207054) */ + 1, /* 328CF (207055) */ + 1, /* 328D0 (207056) */ + 1, /* 328D1 (207057) */ + 1, /* 328D2 (207058) */ + 1, /* 328D3 (207059) */ + 1, /* 328D4 (207060) */ + 1, /* 328D5 (207061) */ + 1, /* 328D6 (207062) */ + 1, /* 328D7 (207063) */ + 1, /* 328D8 (207064) */ + 1, /* 328D9 (207065) */ + 1, /* 328DA (207066) */ + 1, /* 328DB (207067) */ + 1, /* 328DC (207068) */ + 1, /* 328DD (207069) */ + 1, /* 328DE (207070) */ + 1, /* 328DF (207071) */ + 1, /* 328E0 (207072) */ + 1, /* 328E1 (207073) */ + 1, /* 328E2 (207074) */ + 1, /* 328E3 (207075) */ + 1, /* 328E4 (207076) */ + 1, /* 328E5 (207077) */ + 1, /* 328E6 (207078) */ + 1, /* 328E7 (207079) */ + 1, /* 328E8 (207080) */ + 1, /* 328E9 (207081) */ + 1, /* 328EA (207082) */ + 1, /* 328EB (207083) */ + 1, /* 328EC (207084) */ + 1, /* 328ED (207085) */ + 1, /* 328EE (207086) */ + 1, /* 328EF (207087) */ + 1, /* 328F0 (207088) */ + 1, /* 328F1 (207089) */ + 1, /* 328F2 (207090) */ + 1, /* 328F3 (207091) */ + 1, /* 328F4 (207092) */ + 1, /* 328F5 (207093) */ + 1, /* 328F6 (207094) */ + 1, /* 328F7 (207095) */ + 1, /* 328F8 (207096) */ + 1, /* 328F9 (207097) */ + 1, /* 328FA (207098) */ + 1, /* 328FB (207099) */ + 1, /* 328FC (207100) */ + 1, /* 328FD (207101) */ + 1, /* 328FE (207102) */ + 1, /* 328FF (207103) */ + 1, /* 32900 (207104) */ + 1, /* 32901 (207105) */ + 1, /* 32902 (207106) */ + 1, /* 32903 (207107) */ + 1, /* 32904 (207108) */ + 1, /* 32905 (207109) */ + 1, /* 32906 (207110) */ + 1, /* 32907 (207111) */ + 1, /* 32908 (207112) */ + 1, /* 32909 (207113) */ + 1, /* 3290A (207114) */ + 1, /* 3290B (207115) */ + 1, /* 3290C (207116) */ + 1, /* 3290D (207117) */ + 1, /* 3290E (207118) */ + 1, /* 3290F (207119) */ + 1, /* 32910 (207120) */ + 1, /* 32911 (207121) */ + 1, /* 32912 (207122) */ + 1, /* 32913 (207123) */ + 1, /* 32914 (207124) */ + 1, /* 32915 (207125) */ + 1, /* 32916 (207126) */ + 1, /* 32917 (207127) */ + 1, /* 32918 (207128) */ + 1, /* 32919 (207129) */ + 1, /* 3291A (207130) */ + 1, /* 3291B (207131) */ + 1, /* 3291C (207132) */ + 1, /* 3291D (207133) */ + 1, /* 3291E (207134) */ + 1, /* 3291F (207135) */ + 1, /* 32920 (207136) */ + 1, /* 32921 (207137) */ + 1, /* 32922 (207138) */ + 1, /* 32923 (207139) */ + 1, /* 32924 (207140) */ + 1, /* 32925 (207141) */ + 1, /* 32926 (207142) */ + 1, /* 32927 (207143) */ + 1, /* 32928 (207144) */ + 1, /* 32929 (207145) */ + 1, /* 3292A (207146) */ + 1, /* 3292B (207147) */ + 1, /* 3292C (207148) */ + 1, /* 3292D (207149) */ + 1, /* 3292E (207150) */ + 1, /* 3292F (207151) */ + 1, /* 32930 (207152) */ + 1, /* 32931 (207153) */ + 1, /* 32932 (207154) */ + 1, /* 32933 (207155) */ + 1, /* 32934 (207156) */ + 1, /* 32935 (207157) */ + 1, /* 32936 (207158) */ + 1, /* 32937 (207159) */ + 1, /* 32938 (207160) */ + 1, /* 32939 (207161) */ + 1, /* 3293A (207162) */ + 1, /* 3293B (207163) */ + 1, /* 3293C (207164) */ + 1, /* 3293D (207165) */ + 1, /* 3293E (207166) */ + 1, /* 3293F (207167) */ + 1, /* 32940 (207168) */ + 1, /* 32941 (207169) */ + 1, /* 32942 (207170) */ + 1, /* 32943 (207171) */ + 1, /* 32944 (207172) */ + 1, /* 32945 (207173) */ + 1, /* 32946 (207174) */ + 1, /* 32947 (207175) */ + 1, /* 32948 (207176) */ + 1, /* 32949 (207177) */ + 1, /* 3294A (207178) */ + 1, /* 3294B (207179) */ + 1, /* 3294C (207180) */ + 1, /* 3294D (207181) */ + 1, /* 3294E (207182) */ + 1, /* 3294F (207183) */ + 1, /* 32950 (207184) */ + 1, /* 32951 (207185) */ + 1, /* 32952 (207186) */ + 1, /* 32953 (207187) */ + 1, /* 32954 (207188) */ + 1, /* 32955 (207189) */ + 1, /* 32956 (207190) */ + 1, /* 32957 (207191) */ + 1, /* 32958 (207192) */ + 1, /* 32959 (207193) */ + 1, /* 3295A (207194) */ + 1, /* 3295B (207195) */ + 1, /* 3295C (207196) */ + 1, /* 3295D (207197) */ + 1, /* 3295E (207198) */ + 1, /* 3295F (207199) */ + 1, /* 32960 (207200) */ + 1, /* 32961 (207201) */ + 1, /* 32962 (207202) */ + 1, /* 32963 (207203) */ + 1, /* 32964 (207204) */ + 1, /* 32965 (207205) */ + 1, /* 32966 (207206) */ + 1, /* 32967 (207207) */ + 1, /* 32968 (207208) */ + 1, /* 32969 (207209) */ + 1, /* 3296A (207210) */ + 1, /* 3296B (207211) */ + 1, /* 3296C (207212) */ + 1, /* 3296D (207213) */ + 1, /* 3296E (207214) */ + 1, /* 3296F (207215) */ + 1, /* 32970 (207216) */ + 1, /* 32971 (207217) */ + 1, /* 32972 (207218) */ + 1, /* 32973 (207219) */ + 1, /* 32974 (207220) */ + 1, /* 32975 (207221) */ + 1, /* 32976 (207222) */ + 1, /* 32977 (207223) */ + 1, /* 32978 (207224) */ + 1, /* 32979 (207225) */ + 1, /* 3297A (207226) */ + 1, /* 3297B (207227) */ + 1, /* 3297C (207228) */ + 1, /* 3297D (207229) */ + 1, /* 3297E (207230) */ + 1, /* 3297F (207231) */ + 1, /* 32980 (207232) */ + 1, /* 32981 (207233) */ + 1, /* 32982 (207234) */ + 1, /* 32983 (207235) */ + 1, /* 32984 (207236) */ + 1, /* 32985 (207237) */ + 1, /* 32986 (207238) */ + 1, /* 32987 (207239) */ + 1, /* 32988 (207240) */ + 1, /* 32989 (207241) */ + 1, /* 3298A (207242) */ + 1, /* 3298B (207243) */ + 1, /* 3298C (207244) */ + 1, /* 3298D (207245) */ + 1, /* 3298E (207246) */ + 1, /* 3298F (207247) */ + 1, /* 32990 (207248) */ + 1, /* 32991 (207249) */ + 1, /* 32992 (207250) */ + 1, /* 32993 (207251) */ + 1, /* 32994 (207252) */ + 1, /* 32995 (207253) */ + 1, /* 32996 (207254) */ + 1, /* 32997 (207255) */ + 1, /* 32998 (207256) */ + 1, /* 32999 (207257) */ + 1, /* 3299A (207258) */ + 1, /* 3299B (207259) */ + 1, /* 3299C (207260) */ + 1, /* 3299D (207261) */ + 1, /* 3299E (207262) */ + 1, /* 3299F (207263) */ + 1, /* 329A0 (207264) */ + 1, /* 329A1 (207265) */ + 1, /* 329A2 (207266) */ + 1, /* 329A3 (207267) */ + 1, /* 329A4 (207268) */ + 1, /* 329A5 (207269) */ + 1, /* 329A6 (207270) */ + 1, /* 329A7 (207271) */ + 1, /* 329A8 (207272) */ + 1, /* 329A9 (207273) */ + 1, /* 329AA (207274) */ + 1, /* 329AB (207275) */ + 1, /* 329AC (207276) */ + 1, /* 329AD (207277) */ + 1, /* 329AE (207278) */ + 1, /* 329AF (207279) */ + 1, /* 329B0 (207280) */ + 1, /* 329B1 (207281) */ + 1, /* 329B2 (207282) */ + 1, /* 329B3 (207283) */ + 1, /* 329B4 (207284) */ + 1, /* 329B5 (207285) */ + 1, /* 329B6 (207286) */ + 1, /* 329B7 (207287) */ + 1, /* 329B8 (207288) */ + 1, /* 329B9 (207289) */ + 1, /* 329BA (207290) */ + 1, /* 329BB (207291) */ + 1, /* 329BC (207292) */ + 1, /* 329BD (207293) */ + 1, /* 329BE (207294) */ + 1, /* 329BF (207295) */ + 1, /* 329C0 (207296) */ + 1, /* 329C1 (207297) */ + 1, /* 329C2 (207298) */ + 1, /* 329C3 (207299) */ + 1, /* 329C4 (207300) */ + 1, /* 329C5 (207301) */ + 1, /* 329C6 (207302) */ + 1, /* 329C7 (207303) */ + 1, /* 329C8 (207304) */ + 1, /* 329C9 (207305) */ + 1, /* 329CA (207306) */ + 1, /* 329CB (207307) */ + 1, /* 329CC (207308) */ + 1, /* 329CD (207309) */ + 1, /* 329CE (207310) */ + 1, /* 329CF (207311) */ + 1, /* 329D0 (207312) */ + 1, /* 329D1 (207313) */ + 1, /* 329D2 (207314) */ + 1, /* 329D3 (207315) */ + 1, /* 329D4 (207316) */ + 1, /* 329D5 (207317) */ + 1, /* 329D6 (207318) */ + 1, /* 329D7 (207319) */ + 1, /* 329D8 (207320) */ + 1, /* 329D9 (207321) */ + 1, /* 329DA (207322) */ + 1, /* 329DB (207323) */ + 1, /* 329DC (207324) */ + 1, /* 329DD (207325) */ + 1, /* 329DE (207326) */ + 1, /* 329DF (207327) */ + 1, /* 329E0 (207328) */ + 1, /* 329E1 (207329) */ + 1, /* 329E2 (207330) */ + 1, /* 329E3 (207331) */ + 1, /* 329E4 (207332) */ + 1, /* 329E5 (207333) */ + 1, /* 329E6 (207334) */ + 1, /* 329E7 (207335) */ + 1, /* 329E8 (207336) */ + 1, /* 329E9 (207337) */ + 1, /* 329EA (207338) */ + 1, /* 329EB (207339) */ + 1, /* 329EC (207340) */ + 1, /* 329ED (207341) */ + 1, /* 329EE (207342) */ + 1, /* 329EF (207343) */ + 1, /* 329F0 (207344) */ + 1, /* 329F1 (207345) */ + 1, /* 329F2 (207346) */ + 1, /* 329F3 (207347) */ + 1, /* 329F4 (207348) */ + 1, /* 329F5 (207349) */ + 1, /* 329F6 (207350) */ + 1, /* 329F7 (207351) */ + 1, /* 329F8 (207352) */ + 1, /* 329F9 (207353) */ + 1, /* 329FA (207354) */ + 1, /* 329FB (207355) */ + 1, /* 329FC (207356) */ + 1, /* 329FD (207357) */ + 1, /* 329FE (207358) */ + 1, /* 329FF (207359) */ + 1, /* 32A00 (207360) */ + 1, /* 32A01 (207361) */ + 1, /* 32A02 (207362) */ + 1, /* 32A03 (207363) */ + 1, /* 32A04 (207364) */ + 1, /* 32A05 (207365) */ + 1, /* 32A06 (207366) */ + 1, /* 32A07 (207367) */ + 1, /* 32A08 (207368) */ + 1, /* 32A09 (207369) */ + 1, /* 32A0A (207370) */ + 1, /* 32A0B (207371) */ + 1, /* 32A0C (207372) */ + 1, /* 32A0D (207373) */ + 1, /* 32A0E (207374) */ + 1, /* 32A0F (207375) */ + 1, /* 32A10 (207376) */ + 1, /* 32A11 (207377) */ + 1, /* 32A12 (207378) */ + 1, /* 32A13 (207379) */ + 1, /* 32A14 (207380) */ + 1, /* 32A15 (207381) */ + 1, /* 32A16 (207382) */ + 1, /* 32A17 (207383) */ + 1, /* 32A18 (207384) */ + 1, /* 32A19 (207385) */ + 1, /* 32A1A (207386) */ + 1, /* 32A1B (207387) */ + 1, /* 32A1C (207388) */ + 1, /* 32A1D (207389) */ + 1, /* 32A1E (207390) */ + 1, /* 32A1F (207391) */ + 1, /* 32A20 (207392) */ + 1, /* 32A21 (207393) */ + 1, /* 32A22 (207394) */ + 1, /* 32A23 (207395) */ + 1, /* 32A24 (207396) */ + 1, /* 32A25 (207397) */ + 1, /* 32A26 (207398) */ + 1, /* 32A27 (207399) */ + 1, /* 32A28 (207400) */ + 1, /* 32A29 (207401) */ + 1, /* 32A2A (207402) */ + 1, /* 32A2B (207403) */ + 1, /* 32A2C (207404) */ + 1, /* 32A2D (207405) */ + 1, /* 32A2E (207406) */ + 1, /* 32A2F (207407) */ + 1, /* 32A30 (207408) */ + 1, /* 32A31 (207409) */ + 1, /* 32A32 (207410) */ + 1, /* 32A33 (207411) */ + 1, /* 32A34 (207412) */ + 1, /* 32A35 (207413) */ + 1, /* 32A36 (207414) */ + 1, /* 32A37 (207415) */ + 1, /* 32A38 (207416) */ + 1, /* 32A39 (207417) */ + 1, /* 32A3A (207418) */ + 1, /* 32A3B (207419) */ + 1, /* 32A3C (207420) */ + 1, /* 32A3D (207421) */ + 1, /* 32A3E (207422) */ + 1, /* 32A3F (207423) */ + 1, /* 32A40 (207424) */ + 1, /* 32A41 (207425) */ + 1, /* 32A42 (207426) */ + 1, /* 32A43 (207427) */ + 1, /* 32A44 (207428) */ + 1, /* 32A45 (207429) */ + 1, /* 32A46 (207430) */ + 1, /* 32A47 (207431) */ + 1, /* 32A48 (207432) */ + 1, /* 32A49 (207433) */ + 1, /* 32A4A (207434) */ + 1, /* 32A4B (207435) */ + 1, /* 32A4C (207436) */ + 1, /* 32A4D (207437) */ + 1, /* 32A4E (207438) */ + 1, /* 32A4F (207439) */ + 1, /* 32A50 (207440) */ + 1, /* 32A51 (207441) */ + 1, /* 32A52 (207442) */ + 1, /* 32A53 (207443) */ + 1, /* 32A54 (207444) */ + 1, /* 32A55 (207445) */ + 1, /* 32A56 (207446) */ + 1, /* 32A57 (207447) */ + 1, /* 32A58 (207448) */ + 1, /* 32A59 (207449) */ + 1, /* 32A5A (207450) */ + 1, /* 32A5B (207451) */ + 1, /* 32A5C (207452) */ + 1, /* 32A5D (207453) */ + 1, /* 32A5E (207454) */ + 1, /* 32A5F (207455) */ + 1, /* 32A60 (207456) */ + 1, /* 32A61 (207457) */ + 1, /* 32A62 (207458) */ + 1, /* 32A63 (207459) */ + 1, /* 32A64 (207460) */ + 1, /* 32A65 (207461) */ + 1, /* 32A66 (207462) */ + 1, /* 32A67 (207463) */ + 1, /* 32A68 (207464) */ + 1, /* 32A69 (207465) */ + 1, /* 32A6A (207466) */ + 1, /* 32A6B (207467) */ + 1, /* 32A6C (207468) */ + 1, /* 32A6D (207469) */ + 1, /* 32A6E (207470) */ + 1, /* 32A6F (207471) */ + 1, /* 32A70 (207472) */ + 1, /* 32A71 (207473) */ + 1, /* 32A72 (207474) */ + 1, /* 32A73 (207475) */ + 1, /* 32A74 (207476) */ + 1, /* 32A75 (207477) */ + 1, /* 32A76 (207478) */ + 1, /* 32A77 (207479) */ + 1, /* 32A78 (207480) */ + 1, /* 32A79 (207481) */ + 1, /* 32A7A (207482) */ + 1, /* 32A7B (207483) */ + 1, /* 32A7C (207484) */ + 1, /* 32A7D (207485) */ + 1, /* 32A7E (207486) */ + 1, /* 32A7F (207487) */ + 1, /* 32A80 (207488) */ + 1, /* 32A81 (207489) */ + 1, /* 32A82 (207490) */ + 1, /* 32A83 (207491) */ + 1, /* 32A84 (207492) */ + 1, /* 32A85 (207493) */ + 1, /* 32A86 (207494) */ + 1, /* 32A87 (207495) */ + 1, /* 32A88 (207496) */ + 1, /* 32A89 (207497) */ + 1, /* 32A8A (207498) */ + 1, /* 32A8B (207499) */ + 1, /* 32A8C (207500) */ + 1, /* 32A8D (207501) */ + 1, /* 32A8E (207502) */ + 1, /* 32A8F (207503) */ + 1, /* 32A90 (207504) */ + 1, /* 32A91 (207505) */ + 1, /* 32A92 (207506) */ + 1, /* 32A93 (207507) */ + 1, /* 32A94 (207508) */ + 1, /* 32A95 (207509) */ + 1, /* 32A96 (207510) */ + 1, /* 32A97 (207511) */ + 1, /* 32A98 (207512) */ + 1, /* 32A99 (207513) */ + 1, /* 32A9A (207514) */ + 1, /* 32A9B (207515) */ + 1, /* 32A9C (207516) */ + 1, /* 32A9D (207517) */ + 1, /* 32A9E (207518) */ + 1, /* 32A9F (207519) */ + 1, /* 32AA0 (207520) */ + 1, /* 32AA1 (207521) */ + 1, /* 32AA2 (207522) */ + 1, /* 32AA3 (207523) */ + 1, /* 32AA4 (207524) */ + 1, /* 32AA5 (207525) */ + 1, /* 32AA6 (207526) */ + 1, /* 32AA7 (207527) */ + 1, /* 32AA8 (207528) */ + 1, /* 32AA9 (207529) */ + 1, /* 32AAA (207530) */ + 1, /* 32AAB (207531) */ + 1, /* 32AAC (207532) */ + 1, /* 32AAD (207533) */ + 1, /* 32AAE (207534) */ + 1, /* 32AAF (207535) */ + 1, /* 32AB0 (207536) */ + 1, /* 32AB1 (207537) */ + 1, /* 32AB2 (207538) */ + 1, /* 32AB3 (207539) */ + 1, /* 32AB4 (207540) */ + 1, /* 32AB5 (207541) */ + 1, /* 32AB6 (207542) */ + 1, /* 32AB7 (207543) */ + 1, /* 32AB8 (207544) */ + 1, /* 32AB9 (207545) */ + 1, /* 32ABA (207546) */ + 1, /* 32ABB (207547) */ + 1, /* 32ABC (207548) */ + 1, /* 32ABD (207549) */ + 1, /* 32ABE (207550) */ + 1, /* 32ABF (207551) */ + 1, /* 32AC0 (207552) */ + 1, /* 32AC1 (207553) */ + 1, /* 32AC2 (207554) */ + 1, /* 32AC3 (207555) */ + 1, /* 32AC4 (207556) */ + 1, /* 32AC5 (207557) */ + 1, /* 32AC6 (207558) */ + 1, /* 32AC7 (207559) */ + 1, /* 32AC8 (207560) */ + 1, /* 32AC9 (207561) */ + 1, /* 32ACA (207562) */ + 1, /* 32ACB (207563) */ + 1, /* 32ACC (207564) */ + 1, /* 32ACD (207565) */ + 1, /* 32ACE (207566) */ + 1, /* 32ACF (207567) */ + 1, /* 32AD0 (207568) */ + 1, /* 32AD1 (207569) */ + 1, /* 32AD2 (207570) */ + 1, /* 32AD3 (207571) */ + 1, /* 32AD4 (207572) */ + 1, /* 32AD5 (207573) */ + 1, /* 32AD6 (207574) */ + 1, /* 32AD7 (207575) */ + 1, /* 32AD8 (207576) */ + 1, /* 32AD9 (207577) */ + 1, /* 32ADA (207578) */ + 1, /* 32ADB (207579) */ + 1, /* 32ADC (207580) */ + 1, /* 32ADD (207581) */ + 1, /* 32ADE (207582) */ + 1, /* 32ADF (207583) */ + 1, /* 32AE0 (207584) */ + 1, /* 32AE1 (207585) */ + 1, /* 32AE2 (207586) */ + 1, /* 32AE3 (207587) */ + 1, /* 32AE4 (207588) */ + 1, /* 32AE5 (207589) */ + 1, /* 32AE6 (207590) */ + 1, /* 32AE7 (207591) */ + 1, /* 32AE8 (207592) */ + 1, /* 32AE9 (207593) */ + 1, /* 32AEA (207594) */ + 1, /* 32AEB (207595) */ + 1, /* 32AEC (207596) */ + 1, /* 32AED (207597) */ + 1, /* 32AEE (207598) */ + 1, /* 32AEF (207599) */ + 1, /* 32AF0 (207600) */ + 1, /* 32AF1 (207601) */ + 1, /* 32AF2 (207602) */ + 1, /* 32AF3 (207603) */ + 1, /* 32AF4 (207604) */ + 1, /* 32AF5 (207605) */ + 1, /* 32AF6 (207606) */ + 1, /* 32AF7 (207607) */ + 1, /* 32AF8 (207608) */ + 1, /* 32AF9 (207609) */ + 1, /* 32AFA (207610) */ + 1, /* 32AFB (207611) */ + 1, /* 32AFC (207612) */ + 1, /* 32AFD (207613) */ + 1, /* 32AFE (207614) */ + 1, /* 32AFF (207615) */ + 1, /* 32B00 (207616) */ + 1, /* 32B01 (207617) */ + 1, /* 32B02 (207618) */ + 1, /* 32B03 (207619) */ + 1, /* 32B04 (207620) */ + 1, /* 32B05 (207621) */ + 1, /* 32B06 (207622) */ + 1, /* 32B07 (207623) */ + 1, /* 32B08 (207624) */ + 1, /* 32B09 (207625) */ + 1, /* 32B0A (207626) */ + 1, /* 32B0B (207627) */ + 1, /* 32B0C (207628) */ + 1, /* 32B0D (207629) */ + 1, /* 32B0E (207630) */ + 1, /* 32B0F (207631) */ + 1, /* 32B10 (207632) */ + 1, /* 32B11 (207633) */ + 1, /* 32B12 (207634) */ + 1, /* 32B13 (207635) */ + 1, /* 32B14 (207636) */ + 1, /* 32B15 (207637) */ + 1, /* 32B16 (207638) */ + 1, /* 32B17 (207639) */ + 1, /* 32B18 (207640) */ + 1, /* 32B19 (207641) */ + 1, /* 32B1A (207642) */ + 1, /* 32B1B (207643) */ + 1, /* 32B1C (207644) */ + 1, /* 32B1D (207645) */ + 1, /* 32B1E (207646) */ + 1, /* 32B1F (207647) */ + 1, /* 32B20 (207648) */ + 1, /* 32B21 (207649) */ + 1, /* 32B22 (207650) */ + 1, /* 32B23 (207651) */ + 1, /* 32B24 (207652) */ + 1, /* 32B25 (207653) */ + 1, /* 32B26 (207654) */ + 1, /* 32B27 (207655) */ + 1, /* 32B28 (207656) */ + 1, /* 32B29 (207657) */ + 1, /* 32B2A (207658) */ + 1, /* 32B2B (207659) */ + 1, /* 32B2C (207660) */ + 1, /* 32B2D (207661) */ + 1, /* 32B2E (207662) */ + 1, /* 32B2F (207663) */ + 1, /* 32B30 (207664) */ + 1, /* 32B31 (207665) */ + 1, /* 32B32 (207666) */ + 1, /* 32B33 (207667) */ + 1, /* 32B34 (207668) */ + 1, /* 32B35 (207669) */ + 1, /* 32B36 (207670) */ + 1, /* 32B37 (207671) */ + 1, /* 32B38 (207672) */ + 1, /* 32B39 (207673) */ + 1, /* 32B3A (207674) */ + 1, /* 32B3B (207675) */ + 1, /* 32B3C (207676) */ + 1, /* 32B3D (207677) */ + 1, /* 32B3E (207678) */ + 1, /* 32B3F (207679) */ + 1, /* 32B40 (207680) */ + 1, /* 32B41 (207681) */ + 1, /* 32B42 (207682) */ + 1, /* 32B43 (207683) */ + 1, /* 32B44 (207684) */ + 1, /* 32B45 (207685) */ + 1, /* 32B46 (207686) */ + 1, /* 32B47 (207687) */ + 1, /* 32B48 (207688) */ + 1, /* 32B49 (207689) */ + 1, /* 32B4A (207690) */ + 1, /* 32B4B (207691) */ + 1, /* 32B4C (207692) */ + 1, /* 32B4D (207693) */ + 1, /* 32B4E (207694) */ + 1, /* 32B4F (207695) */ + 1, /* 32B50 (207696) */ + 1, /* 32B51 (207697) */ + 1, /* 32B52 (207698) */ + 1, /* 32B53 (207699) */ + 1, /* 32B54 (207700) */ + 1, /* 32B55 (207701) */ + 1, /* 32B56 (207702) */ + 1, /* 32B57 (207703) */ + 1, /* 32B58 (207704) */ + 1, /* 32B59 (207705) */ + 1, /* 32B5A (207706) */ + 1, /* 32B5B (207707) */ + 1, /* 32B5C (207708) */ + 1, /* 32B5D (207709) */ + 1, /* 32B5E (207710) */ + 1, /* 32B5F (207711) */ + 1, /* 32B60 (207712) */ + 1, /* 32B61 (207713) */ + 1, /* 32B62 (207714) */ + 1, /* 32B63 (207715) */ + 1, /* 32B64 (207716) */ + 1, /* 32B65 (207717) */ + 1, /* 32B66 (207718) */ + 1, /* 32B67 (207719) */ + 1, /* 32B68 (207720) */ + 1, /* 32B69 (207721) */ + 1, /* 32B6A (207722) */ + 1, /* 32B6B (207723) */ + 1, /* 32B6C (207724) */ + 1, /* 32B6D (207725) */ + 1, /* 32B6E (207726) */ + 1, /* 32B6F (207727) */ + 1, /* 32B70 (207728) */ + 1, /* 32B71 (207729) */ + 1, /* 32B72 (207730) */ + 1, /* 32B73 (207731) */ + 1, /* 32B74 (207732) */ + 1, /* 32B75 (207733) */ + 1, /* 32B76 (207734) */ + 1, /* 32B77 (207735) */ + 1, /* 32B78 (207736) */ + 1, /* 32B79 (207737) */ + 1, /* 32B7A (207738) */ + 1, /* 32B7B (207739) */ + 1, /* 32B7C (207740) */ + 1, /* 32B7D (207741) */ + 1, /* 32B7E (207742) */ + 1, /* 32B7F (207743) */ + 1, /* 32B80 (207744) */ + 1, /* 32B81 (207745) */ + 1, /* 32B82 (207746) */ + 1, /* 32B83 (207747) */ + 1, /* 32B84 (207748) */ + 1, /* 32B85 (207749) */ + 1, /* 32B86 (207750) */ + 1, /* 32B87 (207751) */ + 1, /* 32B88 (207752) */ + 1, /* 32B89 (207753) */ + 1, /* 32B8A (207754) */ + 1, /* 32B8B (207755) */ + 1, /* 32B8C (207756) */ + 1, /* 32B8D (207757) */ + 1, /* 32B8E (207758) */ + 1, /* 32B8F (207759) */ + 1, /* 32B90 (207760) */ + 1, /* 32B91 (207761) */ + 1, /* 32B92 (207762) */ + 1, /* 32B93 (207763) */ + 1, /* 32B94 (207764) */ + 1, /* 32B95 (207765) */ + 1, /* 32B96 (207766) */ + 1, /* 32B97 (207767) */ + 1, /* 32B98 (207768) */ + 1, /* 32B99 (207769) */ + 1, /* 32B9A (207770) */ + 1, /* 32B9B (207771) */ + 1, /* 32B9C (207772) */ + 1, /* 32B9D (207773) */ + 1, /* 32B9E (207774) */ + 1, /* 32B9F (207775) */ + 1, /* 32BA0 (207776) */ + 1, /* 32BA1 (207777) */ + 1, /* 32BA2 (207778) */ + 1, /* 32BA3 (207779) */ + 1, /* 32BA4 (207780) */ + 1, /* 32BA5 (207781) */ + 1, /* 32BA6 (207782) */ + 1, /* 32BA7 (207783) */ + 1, /* 32BA8 (207784) */ + 1, /* 32BA9 (207785) */ + 1, /* 32BAA (207786) */ + 1, /* 32BAB (207787) */ + 1, /* 32BAC (207788) */ + 1, /* 32BAD (207789) */ + 1, /* 32BAE (207790) */ + 1, /* 32BAF (207791) */ + 1, /* 32BB0 (207792) */ + 1, /* 32BB1 (207793) */ + 1, /* 32BB2 (207794) */ + 1, /* 32BB3 (207795) */ + 1, /* 32BB4 (207796) */ + 1, /* 32BB5 (207797) */ + 1, /* 32BB6 (207798) */ + 1, /* 32BB7 (207799) */ + 1, /* 32BB8 (207800) */ + 1, /* 32BB9 (207801) */ + 1, /* 32BBA (207802) */ + 1, /* 32BBB (207803) */ + 1, /* 32BBC (207804) */ + 1, /* 32BBD (207805) */ + 1, /* 32BBE (207806) */ + 1, /* 32BBF (207807) */ + 1, /* 32BC0 (207808) */ + 1, /* 32BC1 (207809) */ + 1, /* 32BC2 (207810) */ + 1, /* 32BC3 (207811) */ + 1, /* 32BC4 (207812) */ + 1, /* 32BC5 (207813) */ + 1, /* 32BC6 (207814) */ + 1, /* 32BC7 (207815) */ + 1, /* 32BC8 (207816) */ + 1, /* 32BC9 (207817) */ + 1, /* 32BCA (207818) */ + 1, /* 32BCB (207819) */ + 1, /* 32BCC (207820) */ + 1, /* 32BCD (207821) */ + 1, /* 32BCE (207822) */ + 1, /* 32BCF (207823) */ + 1, /* 32BD0 (207824) */ + 1, /* 32BD1 (207825) */ + 1, /* 32BD2 (207826) */ + 1, /* 32BD3 (207827) */ + 1, /* 32BD4 (207828) */ + 1, /* 32BD5 (207829) */ + 1, /* 32BD6 (207830) */ + 1, /* 32BD7 (207831) */ + 1, /* 32BD8 (207832) */ + 1, /* 32BD9 (207833) */ + 1, /* 32BDA (207834) */ + 1, /* 32BDB (207835) */ + 1, /* 32BDC (207836) */ + 1, /* 32BDD (207837) */ + 1, /* 32BDE (207838) */ + 1, /* 32BDF (207839) */ + 1, /* 32BE0 (207840) */ + 1, /* 32BE1 (207841) */ + 1, /* 32BE2 (207842) */ + 1, /* 32BE3 (207843) */ + 1, /* 32BE4 (207844) */ + 1, /* 32BE5 (207845) */ + 1, /* 32BE6 (207846) */ + 1, /* 32BE7 (207847) */ + 1, /* 32BE8 (207848) */ + 1, /* 32BE9 (207849) */ + 1, /* 32BEA (207850) */ + 1, /* 32BEB (207851) */ + 1, /* 32BEC (207852) */ + 1, /* 32BED (207853) */ + 1, /* 32BEE (207854) */ + 1, /* 32BEF (207855) */ + 1, /* 32BF0 (207856) */ + 1, /* 32BF1 (207857) */ + 1, /* 32BF2 (207858) */ + 1, /* 32BF3 (207859) */ + 1, /* 32BF4 (207860) */ + 1, /* 32BF5 (207861) */ + 1, /* 32BF6 (207862) */ + 1, /* 32BF7 (207863) */ + 1, /* 32BF8 (207864) */ + 1, /* 32BF9 (207865) */ + 1, /* 32BFA (207866) */ + 1, /* 32BFB (207867) */ + 1, /* 32BFC (207868) */ + 1, /* 32BFD (207869) */ + 1, /* 32BFE (207870) */ + 1, /* 32BFF (207871) */ + 1, /* 32C00 (207872) */ + 1, /* 32C01 (207873) */ + 1, /* 32C02 (207874) */ + 1, /* 32C03 (207875) */ + 1, /* 32C04 (207876) */ + 1, /* 32C05 (207877) */ + 1, /* 32C06 (207878) */ + 1, /* 32C07 (207879) */ + 1, /* 32C08 (207880) */ + 1, /* 32C09 (207881) */ + 1, /* 32C0A (207882) */ + 1, /* 32C0B (207883) */ + 1, /* 32C0C (207884) */ + 1, /* 32C0D (207885) */ + 1, /* 32C0E (207886) */ + 1, /* 32C0F (207887) */ + 1, /* 32C10 (207888) */ + 1, /* 32C11 (207889) */ + 1, /* 32C12 (207890) */ + 1, /* 32C13 (207891) */ + 1, /* 32C14 (207892) */ + 1, /* 32C15 (207893) */ + 1, /* 32C16 (207894) */ + 1, /* 32C17 (207895) */ + 1, /* 32C18 (207896) */ + 1, /* 32C19 (207897) */ + 1, /* 32C1A (207898) */ + 1, /* 32C1B (207899) */ + 1, /* 32C1C (207900) */ + 1, /* 32C1D (207901) */ + 1, /* 32C1E (207902) */ + 1, /* 32C1F (207903) */ + 1, /* 32C20 (207904) */ + 1, /* 32C21 (207905) */ + 1, /* 32C22 (207906) */ + 1, /* 32C23 (207907) */ + 1, /* 32C24 (207908) */ + 1, /* 32C25 (207909) */ + 1, /* 32C26 (207910) */ + 1, /* 32C27 (207911) */ + 1, /* 32C28 (207912) */ + 1, /* 32C29 (207913) */ + 1, /* 32C2A (207914) */ + 1, /* 32C2B (207915) */ + 1, /* 32C2C (207916) */ + 1, /* 32C2D (207917) */ + 1, /* 32C2E (207918) */ + 1, /* 32C2F (207919) */ + 1, /* 32C30 (207920) */ + 1, /* 32C31 (207921) */ + 1, /* 32C32 (207922) */ + 1, /* 32C33 (207923) */ + 1, /* 32C34 (207924) */ + 1, /* 32C35 (207925) */ + 1, /* 32C36 (207926) */ + 1, /* 32C37 (207927) */ + 1, /* 32C38 (207928) */ + 1, /* 32C39 (207929) */ + 1, /* 32C3A (207930) */ + 1, /* 32C3B (207931) */ + 1, /* 32C3C (207932) */ + 1, /* 32C3D (207933) */ + 1, /* 32C3E (207934) */ + 1, /* 32C3F (207935) */ + 1, /* 32C40 (207936) */ + 1, /* 32C41 (207937) */ + 1, /* 32C42 (207938) */ + 1, /* 32C43 (207939) */ + 1, /* 32C44 (207940) */ + 1, /* 32C45 (207941) */ + 1, /* 32C46 (207942) */ + 1, /* 32C47 (207943) */ + 1, /* 32C48 (207944) */ + 1, /* 32C49 (207945) */ + 1, /* 32C4A (207946) */ + 1, /* 32C4B (207947) */ + 1, /* 32C4C (207948) */ + 1, /* 32C4D (207949) */ + 1, /* 32C4E (207950) */ + 1, /* 32C4F (207951) */ + 1, /* 32C50 (207952) */ + 1, /* 32C51 (207953) */ + 1, /* 32C52 (207954) */ + 1, /* 32C53 (207955) */ + 1, /* 32C54 (207956) */ + 1, /* 32C55 (207957) */ + 1, /* 32C56 (207958) */ + 1, /* 32C57 (207959) */ + 1, /* 32C58 (207960) */ + 1, /* 32C59 (207961) */ + 1, /* 32C5A (207962) */ + 1, /* 32C5B (207963) */ + 1, /* 32C5C (207964) */ + 1, /* 32C5D (207965) */ + 1, /* 32C5E (207966) */ + 1, /* 32C5F (207967) */ + 1, /* 32C60 (207968) */ + 1, /* 32C61 (207969) */ + 1, /* 32C62 (207970) */ + 1, /* 32C63 (207971) */ + 1, /* 32C64 (207972) */ + 1, /* 32C65 (207973) */ + 1, /* 32C66 (207974) */ + 1, /* 32C67 (207975) */ + 1, /* 32C68 (207976) */ + 1, /* 32C69 (207977) */ + 1, /* 32C6A (207978) */ + 1, /* 32C6B (207979) */ + 1, /* 32C6C (207980) */ + 1, /* 32C6D (207981) */ + 1, /* 32C6E (207982) */ + 1, /* 32C6F (207983) */ + 1, /* 32C70 (207984) */ + 1, /* 32C71 (207985) */ + 1, /* 32C72 (207986) */ + 1, /* 32C73 (207987) */ + 1, /* 32C74 (207988) */ + 1, /* 32C75 (207989) */ + 1, /* 32C76 (207990) */ + 1, /* 32C77 (207991) */ + 1, /* 32C78 (207992) */ + 1, /* 32C79 (207993) */ + 1, /* 32C7A (207994) */ + 1, /* 32C7B (207995) */ + 1, /* 32C7C (207996) */ + 1, /* 32C7D (207997) */ + 1, /* 32C7E (207998) */ + 1, /* 32C7F (207999) */ + 1, /* 32C80 (208000) */ + 1, /* 32C81 (208001) */ + 1, /* 32C82 (208002) */ + 1, /* 32C83 (208003) */ + 1, /* 32C84 (208004) */ + 1, /* 32C85 (208005) */ + 1, /* 32C86 (208006) */ + 1, /* 32C87 (208007) */ + 1, /* 32C88 (208008) */ + 1, /* 32C89 (208009) */ + 1, /* 32C8A (208010) */ + 1, /* 32C8B (208011) */ + 1, /* 32C8C (208012) */ + 1, /* 32C8D (208013) */ + 1, /* 32C8E (208014) */ + 1, /* 32C8F (208015) */ + 1, /* 32C90 (208016) */ + 1, /* 32C91 (208017) */ + 1, /* 32C92 (208018) */ + 1, /* 32C93 (208019) */ + 1, /* 32C94 (208020) */ + 1, /* 32C95 (208021) */ + 1, /* 32C96 (208022) */ + 1, /* 32C97 (208023) */ + 1, /* 32C98 (208024) */ + 1, /* 32C99 (208025) */ + 1, /* 32C9A (208026) */ + 1, /* 32C9B (208027) */ + 1, /* 32C9C (208028) */ + 1, /* 32C9D (208029) */ + 1, /* 32C9E (208030) */ + 1, /* 32C9F (208031) */ + 1, /* 32CA0 (208032) */ + 1, /* 32CA1 (208033) */ + 1, /* 32CA2 (208034) */ + 1, /* 32CA3 (208035) */ + 1, /* 32CA4 (208036) */ + 1, /* 32CA5 (208037) */ + 1, /* 32CA6 (208038) */ + 1, /* 32CA7 (208039) */ + 1, /* 32CA8 (208040) */ + 1, /* 32CA9 (208041) */ + 1, /* 32CAA (208042) */ + 1, /* 32CAB (208043) */ + 1, /* 32CAC (208044) */ + 1, /* 32CAD (208045) */ + 1, /* 32CAE (208046) */ + 1, /* 32CAF (208047) */ + 1, /* 32CB0 (208048) */ + 1, /* 32CB1 (208049) */ + 1, /* 32CB2 (208050) */ + 1, /* 32CB3 (208051) */ + 1, /* 32CB4 (208052) */ + 1, /* 32CB5 (208053) */ + 1, /* 32CB6 (208054) */ + 1, /* 32CB7 (208055) */ + 1, /* 32CB8 (208056) */ + 1, /* 32CB9 (208057) */ + 1, /* 32CBA (208058) */ + 1, /* 32CBB (208059) */ + 1, /* 32CBC (208060) */ + 1, /* 32CBD (208061) */ + 1, /* 32CBE (208062) */ + 1, /* 32CBF (208063) */ + 1, /* 32CC0 (208064) */ + 1, /* 32CC1 (208065) */ + 1, /* 32CC2 (208066) */ + 1, /* 32CC3 (208067) */ + 1, /* 32CC4 (208068) */ + 1, /* 32CC5 (208069) */ + 1, /* 32CC6 (208070) */ + 1, /* 32CC7 (208071) */ + 1, /* 32CC8 (208072) */ + 1, /* 32CC9 (208073) */ + 1, /* 32CCA (208074) */ + 1, /* 32CCB (208075) */ + 1, /* 32CCC (208076) */ + 1, /* 32CCD (208077) */ + 1, /* 32CCE (208078) */ + 1, /* 32CCF (208079) */ + 1, /* 32CD0 (208080) */ + 1, /* 32CD1 (208081) */ + 1, /* 32CD2 (208082) */ + 1, /* 32CD3 (208083) */ + 1, /* 32CD4 (208084) */ + 1, /* 32CD5 (208085) */ + 1, /* 32CD6 (208086) */ + 1, /* 32CD7 (208087) */ + 1, /* 32CD8 (208088) */ + 1, /* 32CD9 (208089) */ + 1, /* 32CDA (208090) */ + 1, /* 32CDB (208091) */ + 1, /* 32CDC (208092) */ + 1, /* 32CDD (208093) */ + 1, /* 32CDE (208094) */ + 1, /* 32CDF (208095) */ + 1, /* 32CE0 (208096) */ + 1, /* 32CE1 (208097) */ + 1, /* 32CE2 (208098) */ + 1, /* 32CE3 (208099) */ + 1, /* 32CE4 (208100) */ + 1, /* 32CE5 (208101) */ + 1, /* 32CE6 (208102) */ + 1, /* 32CE7 (208103) */ + 1, /* 32CE8 (208104) */ + 1, /* 32CE9 (208105) */ + 1, /* 32CEA (208106) */ + 1, /* 32CEB (208107) */ + 1, /* 32CEC (208108) */ + 1, /* 32CED (208109) */ + 1, /* 32CEE (208110) */ + 1, /* 32CEF (208111) */ + 1, /* 32CF0 (208112) */ + 1, /* 32CF1 (208113) */ + 1, /* 32CF2 (208114) */ + 1, /* 32CF3 (208115) */ + 1, /* 32CF4 (208116) */ + 1, /* 32CF5 (208117) */ + 1, /* 32CF6 (208118) */ + 1, /* 32CF7 (208119) */ + 1, /* 32CF8 (208120) */ + 1, /* 32CF9 (208121) */ + 1, /* 32CFA (208122) */ + 1, /* 32CFB (208123) */ + 1, /* 32CFC (208124) */ + 1, /* 32CFD (208125) */ + 1, /* 32CFE (208126) */ + 1, /* 32CFF (208127) */ + 1, /* 32D00 (208128) */ + 1, /* 32D01 (208129) */ + 1, /* 32D02 (208130) */ + 1, /* 32D03 (208131) */ + 1, /* 32D04 (208132) */ + 1, /* 32D05 (208133) */ + 1, /* 32D06 (208134) */ + 1, /* 32D07 (208135) */ + 1, /* 32D08 (208136) */ + 1, /* 32D09 (208137) */ + 1, /* 32D0A (208138) */ + 1, /* 32D0B (208139) */ + 1, /* 32D0C (208140) */ + 1, /* 32D0D (208141) */ + 1, /* 32D0E (208142) */ + 1, /* 32D0F (208143) */ + 1, /* 32D10 (208144) */ + 1, /* 32D11 (208145) */ + 1, /* 32D12 (208146) */ + 1, /* 32D13 (208147) */ + 1, /* 32D14 (208148) */ + 1, /* 32D15 (208149) */ + 1, /* 32D16 (208150) */ + 1, /* 32D17 (208151) */ + 1, /* 32D18 (208152) */ + 1, /* 32D19 (208153) */ + 1, /* 32D1A (208154) */ + 1, /* 32D1B (208155) */ + 1, /* 32D1C (208156) */ + 1, /* 32D1D (208157) */ + 1, /* 32D1E (208158) */ + 1, /* 32D1F (208159) */ + 1, /* 32D20 (208160) */ + 1, /* 32D21 (208161) */ + 1, /* 32D22 (208162) */ + 1, /* 32D23 (208163) */ + 1, /* 32D24 (208164) */ + 1, /* 32D25 (208165) */ + 1, /* 32D26 (208166) */ + 1, /* 32D27 (208167) */ + 1, /* 32D28 (208168) */ + 1, /* 32D29 (208169) */ + 1, /* 32D2A (208170) */ + 1, /* 32D2B (208171) */ + 1, /* 32D2C (208172) */ + 1, /* 32D2D (208173) */ + 1, /* 32D2E (208174) */ + 1, /* 32D2F (208175) */ + 1, /* 32D30 (208176) */ + 1, /* 32D31 (208177) */ + 1, /* 32D32 (208178) */ + 1, /* 32D33 (208179) */ + 1, /* 32D34 (208180) */ + 1, /* 32D35 (208181) */ + 1, /* 32D36 (208182) */ + 1, /* 32D37 (208183) */ + 1, /* 32D38 (208184) */ + 1, /* 32D39 (208185) */ + 1, /* 32D3A (208186) */ + 1, /* 32D3B (208187) */ + 1, /* 32D3C (208188) */ + 1, /* 32D3D (208189) */ + 1, /* 32D3E (208190) */ + 1, /* 32D3F (208191) */ + 1, /* 32D40 (208192) */ + 1, /* 32D41 (208193) */ + 1, /* 32D42 (208194) */ + 1, /* 32D43 (208195) */ + 1, /* 32D44 (208196) */ + 1, /* 32D45 (208197) */ + 1, /* 32D46 (208198) */ + 1, /* 32D47 (208199) */ + 1, /* 32D48 (208200) */ + 1, /* 32D49 (208201) */ + 1, /* 32D4A (208202) */ + 1, /* 32D4B (208203) */ + 1, /* 32D4C (208204) */ + 1, /* 32D4D (208205) */ + 1, /* 32D4E (208206) */ + 1, /* 32D4F (208207) */ + 1, /* 32D50 (208208) */ + 1, /* 32D51 (208209) */ + 1, /* 32D52 (208210) */ + 1, /* 32D53 (208211) */ + 1, /* 32D54 (208212) */ + 1, /* 32D55 (208213) */ + 1, /* 32D56 (208214) */ + 1, /* 32D57 (208215) */ + 1, /* 32D58 (208216) */ + 1, /* 32D59 (208217) */ + 1, /* 32D5A (208218) */ + 1, /* 32D5B (208219) */ + 1, /* 32D5C (208220) */ + 1, /* 32D5D (208221) */ + 1, /* 32D5E (208222) */ + 1, /* 32D5F (208223) */ + 1, /* 32D60 (208224) */ + 1, /* 32D61 (208225) */ + 1, /* 32D62 (208226) */ + 1, /* 32D63 (208227) */ + 1, /* 32D64 (208228) */ + 1, /* 32D65 (208229) */ + 1, /* 32D66 (208230) */ + 1, /* 32D67 (208231) */ + 1, /* 32D68 (208232) */ + 1, /* 32D69 (208233) */ + 1, /* 32D6A (208234) */ + 1, /* 32D6B (208235) */ + 1, /* 32D6C (208236) */ + 1, /* 32D6D (208237) */ + 1, /* 32D6E (208238) */ + 1, /* 32D6F (208239) */ + 1, /* 32D70 (208240) */ + 1, /* 32D71 (208241) */ + 1, /* 32D72 (208242) */ + 1, /* 32D73 (208243) */ + 1, /* 32D74 (208244) */ + 1, /* 32D75 (208245) */ + 1, /* 32D76 (208246) */ + 1, /* 32D77 (208247) */ + 1, /* 32D78 (208248) */ + 1, /* 32D79 (208249) */ + 1, /* 32D7A (208250) */ + 1, /* 32D7B (208251) */ + 1, /* 32D7C (208252) */ + 1, /* 32D7D (208253) */ + 1, /* 32D7E (208254) */ + 1, /* 32D7F (208255) */ + 1, /* 32D80 (208256) */ + 1, /* 32D81 (208257) */ + 1, /* 32D82 (208258) */ + 1, /* 32D83 (208259) */ + 1, /* 32D84 (208260) */ + 1, /* 32D85 (208261) */ + 1, /* 32D86 (208262) */ + 1, /* 32D87 (208263) */ + 1, /* 32D88 (208264) */ + 1, /* 32D89 (208265) */ + 1, /* 32D8A (208266) */ + 1, /* 32D8B (208267) */ + 1, /* 32D8C (208268) */ + 1, /* 32D8D (208269) */ + 1, /* 32D8E (208270) */ + 1, /* 32D8F (208271) */ + 1, /* 32D90 (208272) */ + 1, /* 32D91 (208273) */ + 1, /* 32D92 (208274) */ + 1, /* 32D93 (208275) */ + 1, /* 32D94 (208276) */ + 1, /* 32D95 (208277) */ + 1, /* 32D96 (208278) */ + 1, /* 32D97 (208279) */ + 1, /* 32D98 (208280) */ + 1, /* 32D99 (208281) */ + 1, /* 32D9A (208282) */ + 1, /* 32D9B (208283) */ + 1, /* 32D9C (208284) */ + 1, /* 32D9D (208285) */ + 1, /* 32D9E (208286) */ + 1, /* 32D9F (208287) */ + 1, /* 32DA0 (208288) */ + 1, /* 32DA1 (208289) */ + 1, /* 32DA2 (208290) */ + 1, /* 32DA3 (208291) */ + 1, /* 32DA4 (208292) */ + 1, /* 32DA5 (208293) */ + 1, /* 32DA6 (208294) */ + 1, /* 32DA7 (208295) */ + 1, /* 32DA8 (208296) */ + 1, /* 32DA9 (208297) */ + 1, /* 32DAA (208298) */ + 1, /* 32DAB (208299) */ + 1, /* 32DAC (208300) */ + 1, /* 32DAD (208301) */ + 1, /* 32DAE (208302) */ + 1, /* 32DAF (208303) */ + 1, /* 32DB0 (208304) */ + 1, /* 32DB1 (208305) */ + 1, /* 32DB2 (208306) */ + 1, /* 32DB3 (208307) */ + 1, /* 32DB4 (208308) */ + 1, /* 32DB5 (208309) */ + 1, /* 32DB6 (208310) */ + 1, /* 32DB7 (208311) */ + 1, /* 32DB8 (208312) */ + 1, /* 32DB9 (208313) */ + 1, /* 32DBA (208314) */ + 1, /* 32DBB (208315) */ + 1, /* 32DBC (208316) */ + 1, /* 32DBD (208317) */ + 1, /* 32DBE (208318) */ + 1, /* 32DBF (208319) */ + 1, /* 32DC0 (208320) */ + 1, /* 32DC1 (208321) */ + 1, /* 32DC2 (208322) */ + 1, /* 32DC3 (208323) */ + 1, /* 32DC4 (208324) */ + 1, /* 32DC5 (208325) */ + 1, /* 32DC6 (208326) */ + 1, /* 32DC7 (208327) */ + 1, /* 32DC8 (208328) */ + 1, /* 32DC9 (208329) */ + 1, /* 32DCA (208330) */ + 1, /* 32DCB (208331) */ + 1, /* 32DCC (208332) */ + 1, /* 32DCD (208333) */ + 1, /* 32DCE (208334) */ + 1, /* 32DCF (208335) */ + 1, /* 32DD0 (208336) */ + 1, /* 32DD1 (208337) */ + 1, /* 32DD2 (208338) */ + 1, /* 32DD3 (208339) */ + 1, /* 32DD4 (208340) */ + 1, /* 32DD5 (208341) */ + 1, /* 32DD6 (208342) */ + 1, /* 32DD7 (208343) */ + 1, /* 32DD8 (208344) */ + 1, /* 32DD9 (208345) */ + 1, /* 32DDA (208346) */ + 1, /* 32DDB (208347) */ + 1, /* 32DDC (208348) */ + 1, /* 32DDD (208349) */ + 1, /* 32DDE (208350) */ + 1, /* 32DDF (208351) */ + 1, /* 32DE0 (208352) */ + 1, /* 32DE1 (208353) */ + 1, /* 32DE2 (208354) */ + 1, /* 32DE3 (208355) */ + 1, /* 32DE4 (208356) */ + 1, /* 32DE5 (208357) */ + 1, /* 32DE6 (208358) */ + 1, /* 32DE7 (208359) */ + 1, /* 32DE8 (208360) */ + 1, /* 32DE9 (208361) */ + 1, /* 32DEA (208362) */ + 1, /* 32DEB (208363) */ + 1, /* 32DEC (208364) */ + 1, /* 32DED (208365) */ + 1, /* 32DEE (208366) */ + 1, /* 32DEF (208367) */ + 1, /* 32DF0 (208368) */ + 1, /* 32DF1 (208369) */ + 1, /* 32DF2 (208370) */ + 1, /* 32DF3 (208371) */ + 1, /* 32DF4 (208372) */ + 1, /* 32DF5 (208373) */ + 1, /* 32DF6 (208374) */ + 1, /* 32DF7 (208375) */ + 1, /* 32DF8 (208376) */ + 1, /* 32DF9 (208377) */ + 1, /* 32DFA (208378) */ + 1, /* 32DFB (208379) */ + 1, /* 32DFC (208380) */ + 1, /* 32DFD (208381) */ + 1, /* 32DFE (208382) */ + 1, /* 32DFF (208383) */ + 1, /* 32E00 (208384) */ + 1, /* 32E01 (208385) */ + 1, /* 32E02 (208386) */ + 1, /* 32E03 (208387) */ + 1, /* 32E04 (208388) */ + 1, /* 32E05 (208389) */ + 1, /* 32E06 (208390) */ + 1, /* 32E07 (208391) */ + 1, /* 32E08 (208392) */ + 1, /* 32E09 (208393) */ + 1, /* 32E0A (208394) */ + 1, /* 32E0B (208395) */ + 1, /* 32E0C (208396) */ + 1, /* 32E0D (208397) */ + 1, /* 32E0E (208398) */ + 1, /* 32E0F (208399) */ + 1, /* 32E10 (208400) */ + 1, /* 32E11 (208401) */ + 1, /* 32E12 (208402) */ + 1, /* 32E13 (208403) */ + 1, /* 32E14 (208404) */ + 1, /* 32E15 (208405) */ + 1, /* 32E16 (208406) */ + 1, /* 32E17 (208407) */ + 1, /* 32E18 (208408) */ + 1, /* 32E19 (208409) */ + 1, /* 32E1A (208410) */ + 1, /* 32E1B (208411) */ + 1, /* 32E1C (208412) */ + 1, /* 32E1D (208413) */ + 1, /* 32E1E (208414) */ + 1, /* 32E1F (208415) */ + 1, /* 32E20 (208416) */ + 1, /* 32E21 (208417) */ + 1, /* 32E22 (208418) */ + 1, /* 32E23 (208419) */ + 1, /* 32E24 (208420) */ + 1, /* 32E25 (208421) */ + 1, /* 32E26 (208422) */ + 1, /* 32E27 (208423) */ + 1, /* 32E28 (208424) */ + 1, /* 32E29 (208425) */ + 1, /* 32E2A (208426) */ + 1, /* 32E2B (208427) */ + 1, /* 32E2C (208428) */ + 1, /* 32E2D (208429) */ + 1, /* 32E2E (208430) */ + 1, /* 32E2F (208431) */ + 1, /* 32E30 (208432) */ + 1, /* 32E31 (208433) */ + 1, /* 32E32 (208434) */ + 1, /* 32E33 (208435) */ + 1, /* 32E34 (208436) */ + 1, /* 32E35 (208437) */ + 1, /* 32E36 (208438) */ + 1, /* 32E37 (208439) */ + 1, /* 32E38 (208440) */ + 1, /* 32E39 (208441) */ + 1, /* 32E3A (208442) */ + 1, /* 32E3B (208443) */ + 1, /* 32E3C (208444) */ + 1, /* 32E3D (208445) */ + 1, /* 32E3E (208446) */ + 1, /* 32E3F (208447) */ + 1, /* 32E40 (208448) */ + 1, /* 32E41 (208449) */ + 1, /* 32E42 (208450) */ + 1, /* 32E43 (208451) */ + 1, /* 32E44 (208452) */ + 1, /* 32E45 (208453) */ + 1, /* 32E46 (208454) */ + 1, /* 32E47 (208455) */ + 1, /* 32E48 (208456) */ + 1, /* 32E49 (208457) */ + 1, /* 32E4A (208458) */ + 1, /* 32E4B (208459) */ + 1, /* 32E4C (208460) */ + 1, /* 32E4D (208461) */ + 1, /* 32E4E (208462) */ + 1, /* 32E4F (208463) */ + 1, /* 32E50 (208464) */ + 1, /* 32E51 (208465) */ + 1, /* 32E52 (208466) */ + 1, /* 32E53 (208467) */ + 1, /* 32E54 (208468) */ + 1, /* 32E55 (208469) */ + 1, /* 32E56 (208470) */ + 1, /* 32E57 (208471) */ + 1, /* 32E58 (208472) */ + 1, /* 32E59 (208473) */ + 1, /* 32E5A (208474) */ + 1, /* 32E5B (208475) */ + 1, /* 32E5C (208476) */ + 1, /* 32E5D (208477) */ + 1, /* 32E5E (208478) */ + 1, /* 32E5F (208479) */ + 1, /* 32E60 (208480) */ + 1, /* 32E61 (208481) */ + 1, /* 32E62 (208482) */ + 1, /* 32E63 (208483) */ + 1, /* 32E64 (208484) */ + 1, /* 32E65 (208485) */ + 1, /* 32E66 (208486) */ + 1, /* 32E67 (208487) */ + 1, /* 32E68 (208488) */ + 1, /* 32E69 (208489) */ + 1, /* 32E6A (208490) */ + 1, /* 32E6B (208491) */ + 1, /* 32E6C (208492) */ + 1, /* 32E6D (208493) */ + 1, /* 32E6E (208494) */ + 1, /* 32E6F (208495) */ + 1, /* 32E70 (208496) */ + 1, /* 32E71 (208497) */ + 1, /* 32E72 (208498) */ + 1, /* 32E73 (208499) */ + 1, /* 32E74 (208500) */ + 1, /* 32E75 (208501) */ + 1, /* 32E76 (208502) */ + 1, /* 32E77 (208503) */ + 1, /* 32E78 (208504) */ + 1, /* 32E79 (208505) */ + 1, /* 32E7A (208506) */ + 1, /* 32E7B (208507) */ + 1, /* 32E7C (208508) */ + 1, /* 32E7D (208509) */ + 1, /* 32E7E (208510) */ + 1, /* 32E7F (208511) */ + 1, /* 32E80 (208512) */ + 1, /* 32E81 (208513) */ + 1, /* 32E82 (208514) */ + 1, /* 32E83 (208515) */ + 1, /* 32E84 (208516) */ + 1, /* 32E85 (208517) */ + 1, /* 32E86 (208518) */ + 1, /* 32E87 (208519) */ + 1, /* 32E88 (208520) */ + 1, /* 32E89 (208521) */ + 1, /* 32E8A (208522) */ + 1, /* 32E8B (208523) */ + 1, /* 32E8C (208524) */ + 1, /* 32E8D (208525) */ + 1, /* 32E8E (208526) */ + 1, /* 32E8F (208527) */ + 1, /* 32E90 (208528) */ + 1, /* 32E91 (208529) */ + 1, /* 32E92 (208530) */ + 1, /* 32E93 (208531) */ + 1, /* 32E94 (208532) */ + 1, /* 32E95 (208533) */ + 1, /* 32E96 (208534) */ + 1, /* 32E97 (208535) */ + 1, /* 32E98 (208536) */ + 1, /* 32E99 (208537) */ + 1, /* 32E9A (208538) */ + 1, /* 32E9B (208539) */ + 1, /* 32E9C (208540) */ + 1, /* 32E9D (208541) */ + 1, /* 32E9E (208542) */ + 1, /* 32E9F (208543) */ + 1, /* 32EA0 (208544) */ + 1, /* 32EA1 (208545) */ + 1, /* 32EA2 (208546) */ + 1, /* 32EA3 (208547) */ + 1, /* 32EA4 (208548) */ + 1, /* 32EA5 (208549) */ + 1, /* 32EA6 (208550) */ + 1, /* 32EA7 (208551) */ + 1, /* 32EA8 (208552) */ + 1, /* 32EA9 (208553) */ + 1, /* 32EAA (208554) */ + 1, /* 32EAB (208555) */ + 1, /* 32EAC (208556) */ + 1, /* 32EAD (208557) */ + 1, /* 32EAE (208558) */ + 1, /* 32EAF (208559) */ + 1, /* 32EB0 (208560) */ + 1, /* 32EB1 (208561) */ + 1, /* 32EB2 (208562) */ + 1, /* 32EB3 (208563) */ + 1, /* 32EB4 (208564) */ + 1, /* 32EB5 (208565) */ + 1, /* 32EB6 (208566) */ + 1, /* 32EB7 (208567) */ + 1, /* 32EB8 (208568) */ + 1, /* 32EB9 (208569) */ + 1, /* 32EBA (208570) */ + 1, /* 32EBB (208571) */ + 1, /* 32EBC (208572) */ + 1, /* 32EBD (208573) */ + 1, /* 32EBE (208574) */ + 1, /* 32EBF (208575) */ + 1, /* 32EC0 (208576) */ + 1, /* 32EC1 (208577) */ + 1, /* 32EC2 (208578) */ + 1, /* 32EC3 (208579) */ + 1, /* 32EC4 (208580) */ + 1, /* 32EC5 (208581) */ + 1, /* 32EC6 (208582) */ + 1, /* 32EC7 (208583) */ + 1, /* 32EC8 (208584) */ + 1, /* 32EC9 (208585) */ + 1, /* 32ECA (208586) */ + 1, /* 32ECB (208587) */ + 1, /* 32ECC (208588) */ + 1, /* 32ECD (208589) */ + 1, /* 32ECE (208590) */ + 1, /* 32ECF (208591) */ + 1, /* 32ED0 (208592) */ + 1, /* 32ED1 (208593) */ + 1, /* 32ED2 (208594) */ + 1, /* 32ED3 (208595) */ + 1, /* 32ED4 (208596) */ + 1, /* 32ED5 (208597) */ + 1, /* 32ED6 (208598) */ + 1, /* 32ED7 (208599) */ + 1, /* 32ED8 (208600) */ + 1, /* 32ED9 (208601) */ + 1, /* 32EDA (208602) */ + 1, /* 32EDB (208603) */ + 1, /* 32EDC (208604) */ + 1, /* 32EDD (208605) */ + 1, /* 32EDE (208606) */ + 1, /* 32EDF (208607) */ + 1, /* 32EE0 (208608) */ + 1, /* 32EE1 (208609) */ + 1, /* 32EE2 (208610) */ + 1, /* 32EE3 (208611) */ + 1, /* 32EE4 (208612) */ + 1, /* 32EE5 (208613) */ + 1, /* 32EE6 (208614) */ + 1, /* 32EE7 (208615) */ + 1, /* 32EE8 (208616) */ + 1, /* 32EE9 (208617) */ + 1, /* 32EEA (208618) */ + 1, /* 32EEB (208619) */ + 1, /* 32EEC (208620) */ + 1, /* 32EED (208621) */ + 1, /* 32EEE (208622) */ + 1, /* 32EEF (208623) */ + 1, /* 32EF0 (208624) */ + 1, /* 32EF1 (208625) */ + 1, /* 32EF2 (208626) */ + 1, /* 32EF3 (208627) */ + 1, /* 32EF4 (208628) */ + 1, /* 32EF5 (208629) */ + 1, /* 32EF6 (208630) */ + 1, /* 32EF7 (208631) */ + 1, /* 32EF8 (208632) */ + 1, /* 32EF9 (208633) */ + 1, /* 32EFA (208634) */ + 1, /* 32EFB (208635) */ + 1, /* 32EFC (208636) */ + 1, /* 32EFD (208637) */ + 1, /* 32EFE (208638) */ + 1, /* 32EFF (208639) */ + 1, /* 32F00 (208640) */ + 1, /* 32F01 (208641) */ + 1, /* 32F02 (208642) */ + 1, /* 32F03 (208643) */ + 1, /* 32F04 (208644) */ + 1, /* 32F05 (208645) */ + 1, /* 32F06 (208646) */ + 1, /* 32F07 (208647) */ + 1, /* 32F08 (208648) */ + 1, /* 32F09 (208649) */ + 1, /* 32F0A (208650) */ + 1, /* 32F0B (208651) */ + 1, /* 32F0C (208652) */ + 1, /* 32F0D (208653) */ + 1, /* 32F0E (208654) */ + 1, /* 32F0F (208655) */ + 1, /* 32F10 (208656) */ + 1, /* 32F11 (208657) */ + 1, /* 32F12 (208658) */ + 1, /* 32F13 (208659) */ + 1, /* 32F14 (208660) */ + 1, /* 32F15 (208661) */ + 1, /* 32F16 (208662) */ + 1, /* 32F17 (208663) */ + 1, /* 32F18 (208664) */ + 1, /* 32F19 (208665) */ + 1, /* 32F1A (208666) */ + 1, /* 32F1B (208667) */ + 1, /* 32F1C (208668) */ + 1, /* 32F1D (208669) */ + 1, /* 32F1E (208670) */ + 1, /* 32F1F (208671) */ + 1, /* 32F20 (208672) */ + 1, /* 32F21 (208673) */ + 1, /* 32F22 (208674) */ + 1, /* 32F23 (208675) */ + 1, /* 32F24 (208676) */ + 1, /* 32F25 (208677) */ + 1, /* 32F26 (208678) */ + 1, /* 32F27 (208679) */ + 1, /* 32F28 (208680) */ + 1, /* 32F29 (208681) */ + 1, /* 32F2A (208682) */ + 1, /* 32F2B (208683) */ + 1, /* 32F2C (208684) */ + 1, /* 32F2D (208685) */ + 1, /* 32F2E (208686) */ + 1, /* 32F2F (208687) */ + 1, /* 32F30 (208688) */ + 1, /* 32F31 (208689) */ + 1, /* 32F32 (208690) */ + 1, /* 32F33 (208691) */ + 1, /* 32F34 (208692) */ + 1, /* 32F35 (208693) */ + 1, /* 32F36 (208694) */ + 1, /* 32F37 (208695) */ + 1, /* 32F38 (208696) */ + 1, /* 32F39 (208697) */ + 1, /* 32F3A (208698) */ + 1, /* 32F3B (208699) */ + 1, /* 32F3C (208700) */ + 1, /* 32F3D (208701) */ + 1, /* 32F3E (208702) */ + 1, /* 32F3F (208703) */ + 1, /* 32F40 (208704) */ + 1, /* 32F41 (208705) */ + 1, /* 32F42 (208706) */ + 1, /* 32F43 (208707) */ + 1, /* 32F44 (208708) */ + 1, /* 32F45 (208709) */ + 1, /* 32F46 (208710) */ + 1, /* 32F47 (208711) */ + 1, /* 32F48 (208712) */ + 1, /* 32F49 (208713) */ + 1, /* 32F4A (208714) */ + 1, /* 32F4B (208715) */ + 1, /* 32F4C (208716) */ + 1, /* 32F4D (208717) */ + 1, /* 32F4E (208718) */ + 1, /* 32F4F (208719) */ + 1, /* 32F50 (208720) */ + 1, /* 32F51 (208721) */ + 1, /* 32F52 (208722) */ + 1, /* 32F53 (208723) */ + 1, /* 32F54 (208724) */ + 1, /* 32F55 (208725) */ + 1, /* 32F56 (208726) */ + 1, /* 32F57 (208727) */ + 1, /* 32F58 (208728) */ + 1, /* 32F59 (208729) */ + 1, /* 32F5A (208730) */ + 1, /* 32F5B (208731) */ + 1, /* 32F5C (208732) */ + 1, /* 32F5D (208733) */ + 1, /* 32F5E (208734) */ + 1, /* 32F5F (208735) */ + 1, /* 32F60 (208736) */ + 1, /* 32F61 (208737) */ + 1, /* 32F62 (208738) */ + 1, /* 32F63 (208739) */ + 1, /* 32F64 (208740) */ + 1, /* 32F65 (208741) */ + 1, /* 32F66 (208742) */ + 1, /* 32F67 (208743) */ + 1, /* 32F68 (208744) */ + 1, /* 32F69 (208745) */ + 1, /* 32F6A (208746) */ + 1, /* 32F6B (208747) */ + 1, /* 32F6C (208748) */ + 1, /* 32F6D (208749) */ + 1, /* 32F6E (208750) */ + 1, /* 32F6F (208751) */ + 1, /* 32F70 (208752) */ + 1, /* 32F71 (208753) */ + 1, /* 32F72 (208754) */ + 1, /* 32F73 (208755) */ + 1, /* 32F74 (208756) */ + 1, /* 32F75 (208757) */ + 1, /* 32F76 (208758) */ + 1, /* 32F77 (208759) */ + 1, /* 32F78 (208760) */ + 1, /* 32F79 (208761) */ + 1, /* 32F7A (208762) */ + 1, /* 32F7B (208763) */ + 1, /* 32F7C (208764) */ + 1, /* 32F7D (208765) */ + 1, /* 32F7E (208766) */ + 1, /* 32F7F (208767) */ + 1, /* 32F80 (208768) */ + 1, /* 32F81 (208769) */ + 1, /* 32F82 (208770) */ + 1, /* 32F83 (208771) */ + 1, /* 32F84 (208772) */ + 1, /* 32F85 (208773) */ + 1, /* 32F86 (208774) */ + 1, /* 32F87 (208775) */ + 1, /* 32F88 (208776) */ + 1, /* 32F89 (208777) */ + 1, /* 32F8A (208778) */ + 1, /* 32F8B (208779) */ + 1, /* 32F8C (208780) */ + 1, /* 32F8D (208781) */ + 1, /* 32F8E (208782) */ + 1, /* 32F8F (208783) */ + 1, /* 32F90 (208784) */ + 1, /* 32F91 (208785) */ + 1, /* 32F92 (208786) */ + 1, /* 32F93 (208787) */ + 1, /* 32F94 (208788) */ + 1, /* 32F95 (208789) */ + 1, /* 32F96 (208790) */ + 1, /* 32F97 (208791) */ + 1, /* 32F98 (208792) */ + 1, /* 32F99 (208793) */ + 1, /* 32F9A (208794) */ + 1, /* 32F9B (208795) */ + 1, /* 32F9C (208796) */ + 1, /* 32F9D (208797) */ + 1, /* 32F9E (208798) */ + 1, /* 32F9F (208799) */ + 1, /* 32FA0 (208800) */ + 1, /* 32FA1 (208801) */ + 1, /* 32FA2 (208802) */ + 1, /* 32FA3 (208803) */ + 1, /* 32FA4 (208804) */ + 1, /* 32FA5 (208805) */ + 1, /* 32FA6 (208806) */ + 1, /* 32FA7 (208807) */ + 1, /* 32FA8 (208808) */ + 1, /* 32FA9 (208809) */ + 1, /* 32FAA (208810) */ + 1, /* 32FAB (208811) */ + 1, /* 32FAC (208812) */ + 1, /* 32FAD (208813) */ + 1, /* 32FAE (208814) */ + 1, /* 32FAF (208815) */ + 1, /* 32FB0 (208816) */ + 1, /* 32FB1 (208817) */ + 1, /* 32FB2 (208818) */ + 1, /* 32FB3 (208819) */ + 1, /* 32FB4 (208820) */ + 1, /* 32FB5 (208821) */ + 1, /* 32FB6 (208822) */ + 1, /* 32FB7 (208823) */ + 1, /* 32FB8 (208824) */ + 1, /* 32FB9 (208825) */ + 1, /* 32FBA (208826) */ + 1, /* 32FBB (208827) */ + 1, /* 32FBC (208828) */ + 1, /* 32FBD (208829) */ + 1, /* 32FBE (208830) */ + 1, /* 32FBF (208831) */ + 1, /* 32FC0 (208832) */ + 1, /* 32FC1 (208833) */ + 1, /* 32FC2 (208834) */ + 1, /* 32FC3 (208835) */ + 1, /* 32FC4 (208836) */ + 1, /* 32FC5 (208837) */ + 1, /* 32FC6 (208838) */ + 1, /* 32FC7 (208839) */ + 1, /* 32FC8 (208840) */ + 1, /* 32FC9 (208841) */ + 1, /* 32FCA (208842) */ + 1, /* 32FCB (208843) */ + 1, /* 32FCC (208844) */ + 1, /* 32FCD (208845) */ + 1, /* 32FCE (208846) */ + 1, /* 32FCF (208847) */ + 1, /* 32FD0 (208848) */ + 1, /* 32FD1 (208849) */ + 1, /* 32FD2 (208850) */ + 1, /* 32FD3 (208851) */ + 1, /* 32FD4 (208852) */ + 1, /* 32FD5 (208853) */ + 1, /* 32FD6 (208854) */ + 1, /* 32FD7 (208855) */ + 1, /* 32FD8 (208856) */ + 1, /* 32FD9 (208857) */ + 1, /* 32FDA (208858) */ + 1, /* 32FDB (208859) */ + 1, /* 32FDC (208860) */ + 1, /* 32FDD (208861) */ + 1, /* 32FDE (208862) */ + 1, /* 32FDF (208863) */ + 1, /* 32FE0 (208864) */ + 1, /* 32FE1 (208865) */ + 1, /* 32FE2 (208866) */ + 1, /* 32FE3 (208867) */ + 1, /* 32FE4 (208868) */ + 1, /* 32FE5 (208869) */ + 1, /* 32FE6 (208870) */ + 1, /* 32FE7 (208871) */ + 1, /* 32FE8 (208872) */ + 1, /* 32FE9 (208873) */ + 1, /* 32FEA (208874) */ + 1, /* 32FEB (208875) */ + 1, /* 32FEC (208876) */ + 1, /* 32FED (208877) */ + 1, /* 32FEE (208878) */ + 1, /* 32FEF (208879) */ + 1, /* 32FF0 (208880) */ + 1, /* 32FF1 (208881) */ + 1, /* 32FF2 (208882) */ + 1, /* 32FF3 (208883) */ + 1, /* 32FF4 (208884) */ + 1, /* 32FF5 (208885) */ + 1, /* 32FF6 (208886) */ + 1, /* 32FF7 (208887) */ + 1, /* 32FF8 (208888) */ + 1, /* 32FF9 (208889) */ + 1, /* 32FFA (208890) */ + 1, /* 32FFB (208891) */ + 1, /* 32FFC (208892) */ + 1, /* 32FFD (208893) */ + 1, /* 32FFE (208894) */ + 1, /* 32FFF (208895) */ + 1, /* 33000 (208896) */ + 1, /* 33001 (208897) */ + 1, /* 33002 (208898) */ + 1, /* 33003 (208899) */ + 1, /* 33004 (208900) */ + 1, /* 33005 (208901) */ + 1, /* 33006 (208902) */ + 1, /* 33007 (208903) */ + 1, /* 33008 (208904) */ + 1, /* 33009 (208905) */ + 1, /* 3300A (208906) */ + 1, /* 3300B (208907) */ + 1, /* 3300C (208908) */ + 1, /* 3300D (208909) */ + 1, /* 3300E (208910) */ + 1, /* 3300F (208911) */ + 1, /* 33010 (208912) */ + 1, /* 33011 (208913) */ + 1, /* 33012 (208914) */ + 1, /* 33013 (208915) */ + 1, /* 33014 (208916) */ + 1, /* 33015 (208917) */ + 1, /* 33016 (208918) */ + 1, /* 33017 (208919) */ + 1, /* 33018 (208920) */ + 1, /* 33019 (208921) */ + 1, /* 3301A (208922) */ + 1, /* 3301B (208923) */ + 1, /* 3301C (208924) */ + 1, /* 3301D (208925) */ + 1, /* 3301E (208926) */ + 1, /* 3301F (208927) */ + 1, /* 33020 (208928) */ + 1, /* 33021 (208929) */ + 1, /* 33022 (208930) */ + 1, /* 33023 (208931) */ + 1, /* 33024 (208932) */ + 1, /* 33025 (208933) */ + 1, /* 33026 (208934) */ + 1, /* 33027 (208935) */ + 1, /* 33028 (208936) */ + 1, /* 33029 (208937) */ + 1, /* 3302A (208938) */ + 1, /* 3302B (208939) */ + 1, /* 3302C (208940) */ + 1, /* 3302D (208941) */ + 1, /* 3302E (208942) */ + 1, /* 3302F (208943) */ + 1, /* 33030 (208944) */ + 1, /* 33031 (208945) */ + 1, /* 33032 (208946) */ + 1, /* 33033 (208947) */ + 1, /* 33034 (208948) */ + 1, /* 33035 (208949) */ + 1, /* 33036 (208950) */ + 1, /* 33037 (208951) */ + 1, /* 33038 (208952) */ + 1, /* 33039 (208953) */ + 1, /* 3303A (208954) */ + 1, /* 3303B (208955) */ + 1, /* 3303C (208956) */ + 1, /* 3303D (208957) */ + 1, /* 3303E (208958) */ + 1, /* 3303F (208959) */ + 1, /* 33040 (208960) */ + 1, /* 33041 (208961) */ + 1, /* 33042 (208962) */ + 1, /* 33043 (208963) */ + 1, /* 33044 (208964) */ + 1, /* 33045 (208965) */ + 1, /* 33046 (208966) */ + 1, /* 33047 (208967) */ + 1, /* 33048 (208968) */ + 1, /* 33049 (208969) */ + 1, /* 3304A (208970) */ + 1, /* 3304B (208971) */ + 1, /* 3304C (208972) */ + 1, /* 3304D (208973) */ + 1, /* 3304E (208974) */ + 1, /* 3304F (208975) */ + 1, /* 33050 (208976) */ + 1, /* 33051 (208977) */ + 1, /* 33052 (208978) */ + 1, /* 33053 (208979) */ + 1, /* 33054 (208980) */ + 1, /* 33055 (208981) */ + 1, /* 33056 (208982) */ + 1, /* 33057 (208983) */ + 1, /* 33058 (208984) */ + 1, /* 33059 (208985) */ + 1, /* 3305A (208986) */ + 1, /* 3305B (208987) */ + 1, /* 3305C (208988) */ + 1, /* 3305D (208989) */ + 1, /* 3305E (208990) */ + 1, /* 3305F (208991) */ + 1, /* 33060 (208992) */ + 1, /* 33061 (208993) */ + 1, /* 33062 (208994) */ + 1, /* 33063 (208995) */ + 1, /* 33064 (208996) */ + 1, /* 33065 (208997) */ + 1, /* 33066 (208998) */ + 1, /* 33067 (208999) */ + 1, /* 33068 (209000) */ + 1, /* 33069 (209001) */ + 1, /* 3306A (209002) */ + 1, /* 3306B (209003) */ + 1, /* 3306C (209004) */ + 1, /* 3306D (209005) */ + 1, /* 3306E (209006) */ + 1, /* 3306F (209007) */ + 1, /* 33070 (209008) */ + 1, /* 33071 (209009) */ + 1, /* 33072 (209010) */ + 1, /* 33073 (209011) */ + 1, /* 33074 (209012) */ + 1, /* 33075 (209013) */ + 1, /* 33076 (209014) */ + 1, /* 33077 (209015) */ + 1, /* 33078 (209016) */ + 1, /* 33079 (209017) */ + 1, /* 3307A (209018) */ + 1, /* 3307B (209019) */ + 1, /* 3307C (209020) */ + 1, /* 3307D (209021) */ + 1, /* 3307E (209022) */ + 1, /* 3307F (209023) */ + 1, /* 33080 (209024) */ + 1, /* 33081 (209025) */ + 1, /* 33082 (209026) */ + 1, /* 33083 (209027) */ + 1, /* 33084 (209028) */ + 1, /* 33085 (209029) */ + 1, /* 33086 (209030) */ + 1, /* 33087 (209031) */ + 1, /* 33088 (209032) */ + 1, /* 33089 (209033) */ + 1, /* 3308A (209034) */ + 1, /* 3308B (209035) */ + 1, /* 3308C (209036) */ + 1, /* 3308D (209037) */ + 1, /* 3308E (209038) */ + 1, /* 3308F (209039) */ + 1, /* 33090 (209040) */ + 1, /* 33091 (209041) */ + 1, /* 33092 (209042) */ + 1, /* 33093 (209043) */ + 1, /* 33094 (209044) */ + 1, /* 33095 (209045) */ + 1, /* 33096 (209046) */ + 1, /* 33097 (209047) */ + 1, /* 33098 (209048) */ + 1, /* 33099 (209049) */ + 1, /* 3309A (209050) */ + 1, /* 3309B (209051) */ + 1, /* 3309C (209052) */ + 1, /* 3309D (209053) */ + 1, /* 3309E (209054) */ + 1, /* 3309F (209055) */ + 1, /* 330A0 (209056) */ + 1, /* 330A1 (209057) */ + 1, /* 330A2 (209058) */ + 1, /* 330A3 (209059) */ + 1, /* 330A4 (209060) */ + 1, /* 330A5 (209061) */ + 1, /* 330A6 (209062) */ + 1, /* 330A7 (209063) */ + 1, /* 330A8 (209064) */ + 1, /* 330A9 (209065) */ + 1, /* 330AA (209066) */ + 1, /* 330AB (209067) */ + 1, /* 330AC (209068) */ + 1, /* 330AD (209069) */ + 1, /* 330AE (209070) */ + 1, /* 330AF (209071) */ + 1, /* 330B0 (209072) */ + 1, /* 330B1 (209073) */ + 1, /* 330B2 (209074) */ + 1, /* 330B3 (209075) */ + 1, /* 330B4 (209076) */ + 1, /* 330B5 (209077) */ + 1, /* 330B6 (209078) */ + 1, /* 330B7 (209079) */ + 1, /* 330B8 (209080) */ + 1, /* 330B9 (209081) */ + 1, /* 330BA (209082) */ + 1, /* 330BB (209083) */ + 1, /* 330BC (209084) */ + 1, /* 330BD (209085) */ + 1, /* 330BE (209086) */ + 1, /* 330BF (209087) */ + 1, /* 330C0 (209088) */ + 1, /* 330C1 (209089) */ + 1, /* 330C2 (209090) */ + 1, /* 330C3 (209091) */ + 1, /* 330C4 (209092) */ + 1, /* 330C5 (209093) */ + 1, /* 330C6 (209094) */ + 1, /* 330C7 (209095) */ + 1, /* 330C8 (209096) */ + 1, /* 330C9 (209097) */ + 1, /* 330CA (209098) */ + 1, /* 330CB (209099) */ + 1, /* 330CC (209100) */ + 1, /* 330CD (209101) */ + 1, /* 330CE (209102) */ + 1, /* 330CF (209103) */ + 1, /* 330D0 (209104) */ + 1, /* 330D1 (209105) */ + 1, /* 330D2 (209106) */ + 1, /* 330D3 (209107) */ + 1, /* 330D4 (209108) */ + 1, /* 330D5 (209109) */ + 1, /* 330D6 (209110) */ + 1, /* 330D7 (209111) */ + 1, /* 330D8 (209112) */ + 1, /* 330D9 (209113) */ + 1, /* 330DA (209114) */ + 1, /* 330DB (209115) */ + 1, /* 330DC (209116) */ + 1, /* 330DD (209117) */ + 1, /* 330DE (209118) */ + 1, /* 330DF (209119) */ + 1, /* 330E0 (209120) */ + 1, /* 330E1 (209121) */ + 1, /* 330E2 (209122) */ + 1, /* 330E3 (209123) */ + 1, /* 330E4 (209124) */ + 1, /* 330E5 (209125) */ + 1, /* 330E6 (209126) */ + 1, /* 330E7 (209127) */ + 1, /* 330E8 (209128) */ + 1, /* 330E9 (209129) */ + 1, /* 330EA (209130) */ + 1, /* 330EB (209131) */ + 1, /* 330EC (209132) */ + 1, /* 330ED (209133) */ + 1, /* 330EE (209134) */ + 1, /* 330EF (209135) */ + 1, /* 330F0 (209136) */ + 1, /* 330F1 (209137) */ + 1, /* 330F2 (209138) */ + 1, /* 330F3 (209139) */ + 1, /* 330F4 (209140) */ + 1, /* 330F5 (209141) */ + 1, /* 330F6 (209142) */ + 1, /* 330F7 (209143) */ + 1, /* 330F8 (209144) */ + 1, /* 330F9 (209145) */ + 1, /* 330FA (209146) */ + 1, /* 330FB (209147) */ + 1, /* 330FC (209148) */ + 1, /* 330FD (209149) */ + 1, /* 330FE (209150) */ + 1, /* 330FF (209151) */ + 1, /* 33100 (209152) */ + 1, /* 33101 (209153) */ + 1, /* 33102 (209154) */ + 1, /* 33103 (209155) */ + 1, /* 33104 (209156) */ + 1, /* 33105 (209157) */ + 1, /* 33106 (209158) */ + 1, /* 33107 (209159) */ + 1, /* 33108 (209160) */ + 1, /* 33109 (209161) */ + 1, /* 3310A (209162) */ + 1, /* 3310B (209163) */ + 1, /* 3310C (209164) */ + 1, /* 3310D (209165) */ + 1, /* 3310E (209166) */ + 1, /* 3310F (209167) */ + 1, /* 33110 (209168) */ + 1, /* 33111 (209169) */ + 1, /* 33112 (209170) */ + 1, /* 33113 (209171) */ + 1, /* 33114 (209172) */ + 1, /* 33115 (209173) */ + 1, /* 33116 (209174) */ + 1, /* 33117 (209175) */ + 1, /* 33118 (209176) */ + 1, /* 33119 (209177) */ + 1, /* 3311A (209178) */ + 1, /* 3311B (209179) */ + 1, /* 3311C (209180) */ + 1, /* 3311D (209181) */ + 1, /* 3311E (209182) */ + 1, /* 3311F (209183) */ + 1, /* 33120 (209184) */ + 1, /* 33121 (209185) */ + 1, /* 33122 (209186) */ + 1, /* 33123 (209187) */ + 1, /* 33124 (209188) */ + 1, /* 33125 (209189) */ + 1, /* 33126 (209190) */ + 1, /* 33127 (209191) */ + 1, /* 33128 (209192) */ + 1, /* 33129 (209193) */ + 1, /* 3312A (209194) */ + 1, /* 3312B (209195) */ + 1, /* 3312C (209196) */ + 1, /* 3312D (209197) */ + 1, /* 3312E (209198) */ + 1, /* 3312F (209199) */ + 1, /* 33130 (209200) */ + 1, /* 33131 (209201) */ + 1, /* 33132 (209202) */ + 1, /* 33133 (209203) */ + 1, /* 33134 (209204) */ + 1, /* 33135 (209205) */ + 1, /* 33136 (209206) */ + 1, /* 33137 (209207) */ + 1, /* 33138 (209208) */ + 1, /* 33139 (209209) */ + 1, /* 3313A (209210) */ + 1, /* 3313B (209211) */ + 1, /* 3313C (209212) */ + 1, /* 3313D (209213) */ + 1, /* 3313E (209214) */ + 1, /* 3313F (209215) */ + 1, /* 33140 (209216) */ + 1, /* 33141 (209217) */ + 1, /* 33142 (209218) */ + 1, /* 33143 (209219) */ + 1, /* 33144 (209220) */ + 1, /* 33145 (209221) */ + 1, /* 33146 (209222) */ + 1, /* 33147 (209223) */ + 1, /* 33148 (209224) */ + 1, /* 33149 (209225) */ + 1, /* 3314A (209226) */ + 1, /* 3314B (209227) */ + 1, /* 3314C (209228) */ + 1, /* 3314D (209229) */ + 1, /* 3314E (209230) */ + 1, /* 3314F (209231) */ + 1, /* 33150 (209232) */ + 1, /* 33151 (209233) */ + 1, /* 33152 (209234) */ + 1, /* 33153 (209235) */ + 1, /* 33154 (209236) */ + 1, /* 33155 (209237) */ + 1, /* 33156 (209238) */ + 1, /* 33157 (209239) */ + 1, /* 33158 (209240) */ + 1, /* 33159 (209241) */ + 1, /* 3315A (209242) */ + 1, /* 3315B (209243) */ + 1, /* 3315C (209244) */ + 1, /* 3315D (209245) */ + 1, /* 3315E (209246) */ + 1, /* 3315F (209247) */ + 1, /* 33160 (209248) */ + 1, /* 33161 (209249) */ + 1, /* 33162 (209250) */ + 1, /* 33163 (209251) */ + 1, /* 33164 (209252) */ + 1, /* 33165 (209253) */ + 1, /* 33166 (209254) */ + 1, /* 33167 (209255) */ + 1, /* 33168 (209256) */ + 1, /* 33169 (209257) */ + 1, /* 3316A (209258) */ + 1, /* 3316B (209259) */ + 1, /* 3316C (209260) */ + 1, /* 3316D (209261) */ + 1, /* 3316E (209262) */ + 1, /* 3316F (209263) */ + 1, /* 33170 (209264) */ + 1, /* 33171 (209265) */ + 1, /* 33172 (209266) */ + 1, /* 33173 (209267) */ + 1, /* 33174 (209268) */ + 1, /* 33175 (209269) */ + 1, /* 33176 (209270) */ + 1, /* 33177 (209271) */ + 1, /* 33178 (209272) */ + 1, /* 33179 (209273) */ + 1, /* 3317A (209274) */ + 1, /* 3317B (209275) */ + 1, /* 3317C (209276) */ + 1, /* 3317D (209277) */ + 1, /* 3317E (209278) */ + 1, /* 3317F (209279) */ + 1, /* 33180 (209280) */ + 1, /* 33181 (209281) */ + 1, /* 33182 (209282) */ + 1, /* 33183 (209283) */ + 1, /* 33184 (209284) */ + 1, /* 33185 (209285) */ + 1, /* 33186 (209286) */ + 1, /* 33187 (209287) */ + 1, /* 33188 (209288) */ + 1, /* 33189 (209289) */ + 1, /* 3318A (209290) */ + 1, /* 3318B (209291) */ + 1, /* 3318C (209292) */ + 1, /* 3318D (209293) */ + 1, /* 3318E (209294) */ + 1, /* 3318F (209295) */ + 1, /* 33190 (209296) */ + 1, /* 33191 (209297) */ + 1, /* 33192 (209298) */ + 1, /* 33193 (209299) */ + 1, /* 33194 (209300) */ + 1, /* 33195 (209301) */ + 1, /* 33196 (209302) */ + 1, /* 33197 (209303) */ + 1, /* 33198 (209304) */ + 1, /* 33199 (209305) */ + 1, /* 3319A (209306) */ + 1, /* 3319B (209307) */ + 1, /* 3319C (209308) */ + 1, /* 3319D (209309) */ + 1, /* 3319E (209310) */ + 1, /* 3319F (209311) */ + 1, /* 331A0 (209312) */ + 1, /* 331A1 (209313) */ + 1, /* 331A2 (209314) */ + 1, /* 331A3 (209315) */ + 1, /* 331A4 (209316) */ + 1, /* 331A5 (209317) */ + 1, /* 331A6 (209318) */ + 1, /* 331A7 (209319) */ + 1, /* 331A8 (209320) */ + 1, /* 331A9 (209321) */ + 1, /* 331AA (209322) */ + 1, /* 331AB (209323) */ + 1, /* 331AC (209324) */ + 1, /* 331AD (209325) */ + 1, /* 331AE (209326) */ + 1, /* 331AF (209327) */ + 1, /* 331B0 (209328) */ + 1, /* 331B1 (209329) */ + 1, /* 331B2 (209330) */ + 1, /* 331B3 (209331) */ + 1, /* 331B4 (209332) */ + 1, /* 331B5 (209333) */ + 1, /* 331B6 (209334) */ + 1, /* 331B7 (209335) */ + 1, /* 331B8 (209336) */ + 1, /* 331B9 (209337) */ + 1, /* 331BA (209338) */ + 1, /* 331BB (209339) */ + 1, /* 331BC (209340) */ + 1, /* 331BD (209341) */ + 1, /* 331BE (209342) */ + 1, /* 331BF (209343) */ + 1, /* 331C0 (209344) */ + 1, /* 331C1 (209345) */ + 1, /* 331C2 (209346) */ + 1, /* 331C3 (209347) */ + 1, /* 331C4 (209348) */ + 1, /* 331C5 (209349) */ + 1, /* 331C6 (209350) */ + 1, /* 331C7 (209351) */ + 1, /* 331C8 (209352) */ + 1, /* 331C9 (209353) */ + 1, /* 331CA (209354) */ + 1, /* 331CB (209355) */ + 1, /* 331CC (209356) */ + 1, /* 331CD (209357) */ + 1, /* 331CE (209358) */ + 1, /* 331CF (209359) */ + 1, /* 331D0 (209360) */ + 1, /* 331D1 (209361) */ + 1, /* 331D2 (209362) */ + 1, /* 331D3 (209363) */ + 1, /* 331D4 (209364) */ + 1, /* 331D5 (209365) */ + 1, /* 331D6 (209366) */ + 1, /* 331D7 (209367) */ + 1, /* 331D8 (209368) */ + 1, /* 331D9 (209369) */ + 1, /* 331DA (209370) */ + 1, /* 331DB (209371) */ + 1, /* 331DC (209372) */ + 1, /* 331DD (209373) */ + 1, /* 331DE (209374) */ + 1, /* 331DF (209375) */ + 1, /* 331E0 (209376) */ + 1, /* 331E1 (209377) */ + 1, /* 331E2 (209378) */ + 1, /* 331E3 (209379) */ + 1, /* 331E4 (209380) */ + 1, /* 331E5 (209381) */ + 1, /* 331E6 (209382) */ + 1, /* 331E7 (209383) */ + 1, /* 331E8 (209384) */ + 1, /* 331E9 (209385) */ + 1, /* 331EA (209386) */ + 1, /* 331EB (209387) */ + 1, /* 331EC (209388) */ + 1, /* 331ED (209389) */ + 1, /* 331EE (209390) */ + 1, /* 331EF (209391) */ + 1, /* 331F0 (209392) */ + 1, /* 331F1 (209393) */ + 1, /* 331F2 (209394) */ + 1, /* 331F3 (209395) */ + 1, /* 331F4 (209396) */ + 1, /* 331F5 (209397) */ + 1, /* 331F6 (209398) */ + 1, /* 331F7 (209399) */ + 1, /* 331F8 (209400) */ + 1, /* 331F9 (209401) */ + 1, /* 331FA (209402) */ + 1, /* 331FB (209403) */ + 1, /* 331FC (209404) */ + 1, /* 331FD (209405) */ + 1, /* 331FE (209406) */ + 1, /* 331FF (209407) */ + 1, /* 33200 (209408) */ + 1, /* 33201 (209409) */ + 1, /* 33202 (209410) */ + 1, /* 33203 (209411) */ + 1, /* 33204 (209412) */ + 1, /* 33205 (209413) */ + 1, /* 33206 (209414) */ + 1, /* 33207 (209415) */ + 1, /* 33208 (209416) */ + 1, /* 33209 (209417) */ + 1, /* 3320A (209418) */ + 1, /* 3320B (209419) */ + 1, /* 3320C (209420) */ + 1, /* 3320D (209421) */ + 1, /* 3320E (209422) */ + 1, /* 3320F (209423) */ + 1, /* 33210 (209424) */ + 1, /* 33211 (209425) */ + 1, /* 33212 (209426) */ + 1, /* 33213 (209427) */ + 1, /* 33214 (209428) */ + 1, /* 33215 (209429) */ + 1, /* 33216 (209430) */ + 1, /* 33217 (209431) */ + 1, /* 33218 (209432) */ + 1, /* 33219 (209433) */ + 1, /* 3321A (209434) */ + 1, /* 3321B (209435) */ + 1, /* 3321C (209436) */ + 1, /* 3321D (209437) */ + 1, /* 3321E (209438) */ + 1, /* 3321F (209439) */ + 1, /* 33220 (209440) */ + 1, /* 33221 (209441) */ + 1, /* 33222 (209442) */ + 1, /* 33223 (209443) */ + 1, /* 33224 (209444) */ + 1, /* 33225 (209445) */ + 1, /* 33226 (209446) */ + 1, /* 33227 (209447) */ + 1, /* 33228 (209448) */ + 1, /* 33229 (209449) */ + 1, /* 3322A (209450) */ + 1, /* 3322B (209451) */ + 1, /* 3322C (209452) */ + 1, /* 3322D (209453) */ + 1, /* 3322E (209454) */ + 1, /* 3322F (209455) */ + 1, /* 33230 (209456) */ + 1, /* 33231 (209457) */ + 1, /* 33232 (209458) */ + 1, /* 33233 (209459) */ + 1, /* 33234 (209460) */ + 1, /* 33235 (209461) */ + 1, /* 33236 (209462) */ + 1, /* 33237 (209463) */ + 1, /* 33238 (209464) */ + 1, /* 33239 (209465) */ + 1, /* 3323A (209466) */ + 1, /* 3323B (209467) */ + 1, /* 3323C (209468) */ + 1, /* 3323D (209469) */ + 1, /* 3323E (209470) */ + 1, /* 3323F (209471) */ + 1, /* 33240 (209472) */ + 1, /* 33241 (209473) */ + 1, /* 33242 (209474) */ + 1, /* 33243 (209475) */ + 1, /* 33244 (209476) */ + 1, /* 33245 (209477) */ + 1, /* 33246 (209478) */ + 1, /* 33247 (209479) */ + 1, /* 33248 (209480) */ + 1, /* 33249 (209481) */ + 1, /* 3324A (209482) */ + 1, /* 3324B (209483) */ + 1, /* 3324C (209484) */ + 1, /* 3324D (209485) */ + 1, /* 3324E (209486) */ + 1, /* 3324F (209487) */ + 1, /* 33250 (209488) */ + 1, /* 33251 (209489) */ + 1, /* 33252 (209490) */ + 1, /* 33253 (209491) */ + 1, /* 33254 (209492) */ + 1, /* 33255 (209493) */ + 1, /* 33256 (209494) */ + 1, /* 33257 (209495) */ + 1, /* 33258 (209496) */ + 1, /* 33259 (209497) */ + 1, /* 3325A (209498) */ + 1, /* 3325B (209499) */ + 1, /* 3325C (209500) */ + 1, /* 3325D (209501) */ + 1, /* 3325E (209502) */ + 1, /* 3325F (209503) */ + 1, /* 33260 (209504) */ + 1, /* 33261 (209505) */ + 1, /* 33262 (209506) */ + 1, /* 33263 (209507) */ + 1, /* 33264 (209508) */ + 1, /* 33265 (209509) */ + 1, /* 33266 (209510) */ + 1, /* 33267 (209511) */ + 1, /* 33268 (209512) */ + 1, /* 33269 (209513) */ + 1, /* 3326A (209514) */ + 1, /* 3326B (209515) */ + 1, /* 3326C (209516) */ + 1, /* 3326D (209517) */ + 1, /* 3326E (209518) */ + 1, /* 3326F (209519) */ + 1, /* 33270 (209520) */ + 1, /* 33271 (209521) */ + 1, /* 33272 (209522) */ + 1, /* 33273 (209523) */ + 1, /* 33274 (209524) */ + 1, /* 33275 (209525) */ + 1, /* 33276 (209526) */ + 1, /* 33277 (209527) */ + 1, /* 33278 (209528) */ + 1, /* 33279 (209529) */ + 1, /* 3327A (209530) */ + 1, /* 3327B (209531) */ + 1, /* 3327C (209532) */ + 1, /* 3327D (209533) */ + 1, /* 3327E (209534) */ + 1, /* 3327F (209535) */ + 1, /* 33280 (209536) */ + 1, /* 33281 (209537) */ + 1, /* 33282 (209538) */ + 1, /* 33283 (209539) */ + 1, /* 33284 (209540) */ + 1, /* 33285 (209541) */ + 1, /* 33286 (209542) */ + 1, /* 33287 (209543) */ + 1, /* 33288 (209544) */ + 1, /* 33289 (209545) */ + 1, /* 3328A (209546) */ + 1, /* 3328B (209547) */ + 1, /* 3328C (209548) */ + 1, /* 3328D (209549) */ + 1, /* 3328E (209550) */ + 1, /* 3328F (209551) */ + 1, /* 33290 (209552) */ + 1, /* 33291 (209553) */ + 1, /* 33292 (209554) */ + 1, /* 33293 (209555) */ + 1, /* 33294 (209556) */ + 1, /* 33295 (209557) */ + 1, /* 33296 (209558) */ + 1, /* 33297 (209559) */ + 1, /* 33298 (209560) */ + 1, /* 33299 (209561) */ + 1, /* 3329A (209562) */ + 1, /* 3329B (209563) */ + 1, /* 3329C (209564) */ + 1, /* 3329D (209565) */ + 1, /* 3329E (209566) */ + 1, /* 3329F (209567) */ + 1, /* 332A0 (209568) */ + 1, /* 332A1 (209569) */ + 1, /* 332A2 (209570) */ + 1, /* 332A3 (209571) */ + 1, /* 332A4 (209572) */ + 1, /* 332A5 (209573) */ + 1, /* 332A6 (209574) */ + 1, /* 332A7 (209575) */ + 1, /* 332A8 (209576) */ + 1, /* 332A9 (209577) */ + 1, /* 332AA (209578) */ + 1, /* 332AB (209579) */ + 1, /* 332AC (209580) */ + 1, /* 332AD (209581) */ + 1, /* 332AE (209582) */ + 1, /* 332AF (209583) */ + 1, /* 332B0 (209584) */ + 1, /* 332B1 (209585) */ + 1, /* 332B2 (209586) */ + 1, /* 332B3 (209587) */ + 1, /* 332B4 (209588) */ + 1, /* 332B5 (209589) */ + 1, /* 332B6 (209590) */ + 1, /* 332B7 (209591) */ + 1, /* 332B8 (209592) */ + 1, /* 332B9 (209593) */ + 1, /* 332BA (209594) */ + 1, /* 332BB (209595) */ + 1, /* 332BC (209596) */ + 1, /* 332BD (209597) */ + 1, /* 332BE (209598) */ + 1, /* 332BF (209599) */ + 1, /* 332C0 (209600) */ + 1, /* 332C1 (209601) */ + 1, /* 332C2 (209602) */ + 1, /* 332C3 (209603) */ + 1, /* 332C4 (209604) */ + 1, /* 332C5 (209605) */ + 1, /* 332C6 (209606) */ + 1, /* 332C7 (209607) */ + 1, /* 332C8 (209608) */ + 1, /* 332C9 (209609) */ + 1, /* 332CA (209610) */ + 1, /* 332CB (209611) */ + 1, /* 332CC (209612) */ + 1, /* 332CD (209613) */ + 1, /* 332CE (209614) */ + 1, /* 332CF (209615) */ + 1, /* 332D0 (209616) */ + 1, /* 332D1 (209617) */ + 1, /* 332D2 (209618) */ + 1, /* 332D3 (209619) */ + 1, /* 332D4 (209620) */ + 1, /* 332D5 (209621) */ + 1, /* 332D6 (209622) */ + 1, /* 332D7 (209623) */ + 1, /* 332D8 (209624) */ + 1, /* 332D9 (209625) */ + 1, /* 332DA (209626) */ + 1, /* 332DB (209627) */ + 1, /* 332DC (209628) */ + 1, /* 332DD (209629) */ + 1, /* 332DE (209630) */ + 1, /* 332DF (209631) */ + 1, /* 332E0 (209632) */ + 1, /* 332E1 (209633) */ + 1, /* 332E2 (209634) */ + 1, /* 332E3 (209635) */ + 1, /* 332E4 (209636) */ + 1, /* 332E5 (209637) */ + 1, /* 332E6 (209638) */ + 1, /* 332E7 (209639) */ + 1, /* 332E8 (209640) */ + 1, /* 332E9 (209641) */ + 1, /* 332EA (209642) */ + 1, /* 332EB (209643) */ + 1, /* 332EC (209644) */ + 1, /* 332ED (209645) */ + 1, /* 332EE (209646) */ + 1, /* 332EF (209647) */ + 1, /* 332F0 (209648) */ + 1, /* 332F1 (209649) */ + 1, /* 332F2 (209650) */ + 1, /* 332F3 (209651) */ + 1, /* 332F4 (209652) */ + 1, /* 332F5 (209653) */ + 1, /* 332F6 (209654) */ + 1, /* 332F7 (209655) */ + 1, /* 332F8 (209656) */ + 1, /* 332F9 (209657) */ + 1, /* 332FA (209658) */ + 1, /* 332FB (209659) */ + 1, /* 332FC (209660) */ + 1, /* 332FD (209661) */ + 1, /* 332FE (209662) */ + 1, /* 332FF (209663) */ + 1, /* 33300 (209664) */ + 1, /* 33301 (209665) */ + 1, /* 33302 (209666) */ + 1, /* 33303 (209667) */ + 1, /* 33304 (209668) */ + 1, /* 33305 (209669) */ + 1, /* 33306 (209670) */ + 1, /* 33307 (209671) */ + 1, /* 33308 (209672) */ + 1, /* 33309 (209673) */ + 1, /* 3330A (209674) */ + 1, /* 3330B (209675) */ + 1, /* 3330C (209676) */ + 1, /* 3330D (209677) */ + 1, /* 3330E (209678) */ + 1, /* 3330F (209679) */ + 1, /* 33310 (209680) */ + 1, /* 33311 (209681) */ + 1, /* 33312 (209682) */ + 1, /* 33313 (209683) */ + 1, /* 33314 (209684) */ + 1, /* 33315 (209685) */ + 1, /* 33316 (209686) */ + 1, /* 33317 (209687) */ + 1, /* 33318 (209688) */ + 1, /* 33319 (209689) */ + 1, /* 3331A (209690) */ + 1, /* 3331B (209691) */ + 1, /* 3331C (209692) */ + 1, /* 3331D (209693) */ + 1, /* 3331E (209694) */ + 1, /* 3331F (209695) */ + 1, /* 33320 (209696) */ + 1, /* 33321 (209697) */ + 1, /* 33322 (209698) */ + 1, /* 33323 (209699) */ + 1, /* 33324 (209700) */ + 1, /* 33325 (209701) */ + 1, /* 33326 (209702) */ + 1, /* 33327 (209703) */ + 1, /* 33328 (209704) */ + 1, /* 33329 (209705) */ + 1, /* 3332A (209706) */ + 1, /* 3332B (209707) */ + 1, /* 3332C (209708) */ + 1, /* 3332D (209709) */ + 1, /* 3332E (209710) */ + 1, /* 3332F (209711) */ + 1, /* 33330 (209712) */ + 1, /* 33331 (209713) */ + 1, /* 33332 (209714) */ + 1, /* 33333 (209715) */ + 1, /* 33334 (209716) */ + 1, /* 33335 (209717) */ + 1, /* 33336 (209718) */ + 1, /* 33337 (209719) */ + 1, /* 33338 (209720) */ + 1, /* 33339 (209721) */ + 1, /* 3333A (209722) */ + 1, /* 3333B (209723) */ + 1, /* 3333C (209724) */ + 1, /* 3333D (209725) */ + 1, /* 3333E (209726) */ + 1, /* 3333F (209727) */ + 1, /* 33340 (209728) */ + 1, /* 33341 (209729) */ + 1, /* 33342 (209730) */ + 1, /* 33343 (209731) */ + 1, /* 33344 (209732) */ + 1, /* 33345 (209733) */ + 1, /* 33346 (209734) */ + 1, /* 33347 (209735) */ + 1, /* 33348 (209736) */ + 1, /* 33349 (209737) */ + 1, /* 3334A (209738) */ + 1, /* 3334B (209739) */ + 1, /* 3334C (209740) */ + 1, /* 3334D (209741) */ + 1, /* 3334E (209742) */ + 1, /* 3334F (209743) */ + 1, /* 33350 (209744) */ + 1, /* 33351 (209745) */ + 1, /* 33352 (209746) */ + 1, /* 33353 (209747) */ + 1, /* 33354 (209748) */ + 1, /* 33355 (209749) */ + 1, /* 33356 (209750) */ + 1, /* 33357 (209751) */ + 1, /* 33358 (209752) */ + 1, /* 33359 (209753) */ + 1, /* 3335A (209754) */ + 1, /* 3335B (209755) */ + 1, /* 3335C (209756) */ + 1, /* 3335D (209757) */ + 1, /* 3335E (209758) */ + 1, /* 3335F (209759) */ + 1, /* 33360 (209760) */ + 1, /* 33361 (209761) */ + 1, /* 33362 (209762) */ + 1, /* 33363 (209763) */ + 1, /* 33364 (209764) */ + 1, /* 33365 (209765) */ + 1, /* 33366 (209766) */ + 1, /* 33367 (209767) */ + 1, /* 33368 (209768) */ + 1, /* 33369 (209769) */ + 1, /* 3336A (209770) */ + 1, /* 3336B (209771) */ + 1, /* 3336C (209772) */ + 1, /* 3336D (209773) */ + 1, /* 3336E (209774) */ + 1, /* 3336F (209775) */ + 1, /* 33370 (209776) */ + 1, /* 33371 (209777) */ + 1, /* 33372 (209778) */ + 1, /* 33373 (209779) */ + 1, /* 33374 (209780) */ + 1, /* 33375 (209781) */ + 1, /* 33376 (209782) */ + 1, /* 33377 (209783) */ + 1, /* 33378 (209784) */ + 1, /* 33379 (209785) */ + 1, /* 3337A (209786) */ + 1, /* 3337B (209787) */ + 1, /* 3337C (209788) */ + 1, /* 3337D (209789) */ + 1, /* 3337E (209790) */ + 1, /* 3337F (209791) */ + 1, /* 33380 (209792) */ + 1, /* 33381 (209793) */ + 1, /* 33382 (209794) */ + 1, /* 33383 (209795) */ + 1, /* 33384 (209796) */ + 1, /* 33385 (209797) */ + 1, /* 33386 (209798) */ + 1, /* 33387 (209799) */ + 1, /* 33388 (209800) */ + 1, /* 33389 (209801) */ + 1, /* 3338A (209802) */ + 1, /* 3338B (209803) */ + 1, /* 3338C (209804) */ + 1, /* 3338D (209805) */ + 1, /* 3338E (209806) */ + 1, /* 3338F (209807) */ + 1, /* 33390 (209808) */ + 1, /* 33391 (209809) */ + 1, /* 33392 (209810) */ + 1, /* 33393 (209811) */ + 1, /* 33394 (209812) */ + 1, /* 33395 (209813) */ + 1, /* 33396 (209814) */ + 1, /* 33397 (209815) */ + 1, /* 33398 (209816) */ + 1, /* 33399 (209817) */ + 1, /* 3339A (209818) */ + 1, /* 3339B (209819) */ + 1, /* 3339C (209820) */ + 1, /* 3339D (209821) */ + 1, /* 3339E (209822) */ + 1, /* 3339F (209823) */ + 1, /* 333A0 (209824) */ + 1, /* 333A1 (209825) */ + 1, /* 333A2 (209826) */ + 1, /* 333A3 (209827) */ + 1, /* 333A4 (209828) */ + 1, /* 333A5 (209829) */ + 1, /* 333A6 (209830) */ + 1, /* 333A7 (209831) */ + 1, /* 333A8 (209832) */ + 1, /* 333A9 (209833) */ + 1, /* 333AA (209834) */ + 1, /* 333AB (209835) */ + 1, /* 333AC (209836) */ + 1, /* 333AD (209837) */ + 1, /* 333AE (209838) */ + 1, /* 333AF (209839) */ + 1, /* 333B0 (209840) */ + 1, /* 333B1 (209841) */ + 1, /* 333B2 (209842) */ + 1, /* 333B3 (209843) */ + 1, /* 333B4 (209844) */ + 1, /* 333B5 (209845) */ + 1, /* 333B6 (209846) */ + 1, /* 333B7 (209847) */ + 1, /* 333B8 (209848) */ + 1, /* 333B9 (209849) */ + 1, /* 333BA (209850) */ + 1, /* 333BB (209851) */ + 1, /* 333BC (209852) */ + 1, /* 333BD (209853) */ + 1, /* 333BE (209854) */ + 1, /* 333BF (209855) */ + 1, /* 333C0 (209856) */ + 1, /* 333C1 (209857) */ + 1, /* 333C2 (209858) */ + 1, /* 333C3 (209859) */ + 1, /* 333C4 (209860) */ + 1, /* 333C5 (209861) */ + 1, /* 333C6 (209862) */ + 1, /* 333C7 (209863) */ + 1, /* 333C8 (209864) */ + 1, /* 333C9 (209865) */ + 1, /* 333CA (209866) */ + 1, /* 333CB (209867) */ + 1, /* 333CC (209868) */ + 1, /* 333CD (209869) */ + 1, /* 333CE (209870) */ + 1, /* 333CF (209871) */ + 1, /* 333D0 (209872) */ + 1, /* 333D1 (209873) */ + 1, /* 333D2 (209874) */ + 1, /* 333D3 (209875) */ + 1, /* 333D4 (209876) */ + 1, /* 333D5 (209877) */ + 1, /* 333D6 (209878) */ + 1, /* 333D7 (209879) */ + 1, /* 333D8 (209880) */ + 1, /* 333D9 (209881) */ + 1, /* 333DA (209882) */ + 1, /* 333DB (209883) */ + 1, /* 333DC (209884) */ + 1, /* 333DD (209885) */ + 1, /* 333DE (209886) */ + 1, /* 333DF (209887) */ + 1, /* 333E0 (209888) */ + 1, /* 333E1 (209889) */ + 1, /* 333E2 (209890) */ + 1, /* 333E3 (209891) */ + 1, /* 333E4 (209892) */ + 1, /* 333E5 (209893) */ + 1, /* 333E6 (209894) */ + 1, /* 333E7 (209895) */ + 1, /* 333E8 (209896) */ + 1, /* 333E9 (209897) */ + 1, /* 333EA (209898) */ + 1, /* 333EB (209899) */ + 1, /* 333EC (209900) */ + 1, /* 333ED (209901) */ + 1, /* 333EE (209902) */ + 1, /* 333EF (209903) */ + 1, /* 333F0 (209904) */ + 1, /* 333F1 (209905) */ + 1, /* 333F2 (209906) */ + 1, /* 333F3 (209907) */ + 1, /* 333F4 (209908) */ + 1, /* 333F5 (209909) */ + 1, /* 333F6 (209910) */ + 1, /* 333F7 (209911) */ + 1, /* 333F8 (209912) */ + 1, /* 333F9 (209913) */ + 1, /* 333FA (209914) */ + 1, /* 333FB (209915) */ + 1, /* 333FC (209916) */ + 1, /* 333FD (209917) */ + 1, /* 333FE (209918) */ + 1, /* 333FF (209919) */ + 1, /* 33400 (209920) */ + 1, /* 33401 (209921) */ + 1, /* 33402 (209922) */ + 1, /* 33403 (209923) */ + 1, /* 33404 (209924) */ + 1, /* 33405 (209925) */ + 1, /* 33406 (209926) */ + 1, /* 33407 (209927) */ + 1, /* 33408 (209928) */ + 1, /* 33409 (209929) */ + 1, /* 3340A (209930) */ + 1, /* 3340B (209931) */ + 1, /* 3340C (209932) */ + 1, /* 3340D (209933) */ + 1, /* 3340E (209934) */ + 1, /* 3340F (209935) */ + 1, /* 33410 (209936) */ + 1, /* 33411 (209937) */ + 1, /* 33412 (209938) */ + 1, /* 33413 (209939) */ + 1, /* 33414 (209940) */ + 1, /* 33415 (209941) */ + 1, /* 33416 (209942) */ + 1, /* 33417 (209943) */ + 1, /* 33418 (209944) */ + 1, /* 33419 (209945) */ + 1, /* 3341A (209946) */ + 1, /* 3341B (209947) */ + 1, /* 3341C (209948) */ + 1, /* 3341D (209949) */ + 1, /* 3341E (209950) */ + 1, /* 3341F (209951) */ + 1, /* 33420 (209952) */ + 1, /* 33421 (209953) */ + 1, /* 33422 (209954) */ + 1, /* 33423 (209955) */ + 1, /* 33424 (209956) */ + 1, /* 33425 (209957) */ + 1, /* 33426 (209958) */ + 1, /* 33427 (209959) */ + 1, /* 33428 (209960) */ + 1, /* 33429 (209961) */ + 1, /* 3342A (209962) */ + 1, /* 3342B (209963) */ + 1, /* 3342C (209964) */ + 1, /* 3342D (209965) */ + 1, /* 3342E (209966) */ + 1, /* 3342F (209967) */ + 1, /* 33430 (209968) */ + 1, /* 33431 (209969) */ + 1, /* 33432 (209970) */ + 1, /* 33433 (209971) */ + 1, /* 33434 (209972) */ + 1, /* 33435 (209973) */ + 1, /* 33436 (209974) */ + 1, /* 33437 (209975) */ + 1, /* 33438 (209976) */ + 1, /* 33439 (209977) */ + 1, /* 3343A (209978) */ + 1, /* 3343B (209979) */ + 1, /* 3343C (209980) */ + 1, /* 3343D (209981) */ + 1, /* 3343E (209982) */ + 1, /* 3343F (209983) */ + 1, /* 33440 (209984) */ + 1, /* 33441 (209985) */ + 1, /* 33442 (209986) */ + 1, /* 33443 (209987) */ + 1, /* 33444 (209988) */ + 1, /* 33445 (209989) */ + 1, /* 33446 (209990) */ + 1, /* 33447 (209991) */ + 1, /* 33448 (209992) */ + 1, /* 33449 (209993) */ + 1, /* 3344A (209994) */ + 1, /* 3344B (209995) */ + 1, /* 3344C (209996) */ + 1, /* 3344D (209997) */ + 1, /* 3344E (209998) */ + 1, /* 3344F (209999) */ + 1, /* 33450 (210000) */ + 1, /* 33451 (210001) */ + 1, /* 33452 (210002) */ + 1, /* 33453 (210003) */ + 1, /* 33454 (210004) */ + 1, /* 33455 (210005) */ + 1, /* 33456 (210006) */ + 1, /* 33457 (210007) */ + 1, /* 33458 (210008) */ + 1, /* 33459 (210009) */ + 1, /* 3345A (210010) */ + 1, /* 3345B (210011) */ + 1, /* 3345C (210012) */ + 1, /* 3345D (210013) */ + 1, /* 3345E (210014) */ + 1, /* 3345F (210015) */ + 1, /* 33460 (210016) */ + 1, /* 33461 (210017) */ + 1, /* 33462 (210018) */ + 1, /* 33463 (210019) */ + 1, /* 33464 (210020) */ + 1, /* 33465 (210021) */ + 1, /* 33466 (210022) */ + 1, /* 33467 (210023) */ + 1, /* 33468 (210024) */ + 1, /* 33469 (210025) */ + 1, /* 3346A (210026) */ + 1, /* 3346B (210027) */ + 1, /* 3346C (210028) */ + 1, /* 3346D (210029) */ + 1, /* 3346E (210030) */ + 1, /* 3346F (210031) */ + 1, /* 33470 (210032) */ + 1, /* 33471 (210033) */ + 1, /* 33472 (210034) */ + 1, /* 33473 (210035) */ + 1, /* 33474 (210036) */ + 1, /* 33475 (210037) */ + 1, /* 33476 (210038) */ + 1, /* 33477 (210039) */ + 1, /* 33478 (210040) */ + 1, /* 33479 (210041) */ }; /* From: E0001; To: E01EF */ @@ -184130,6093 +188662,6122 @@ static const uint16_t lxb_unicode_table_map_1114109_1114110[1] = }; -static const lxb_unicode_entry_t lxb_unicode_entries[6085] = +static const lxb_unicode_entry_t lxb_unicode_entries[6114] = { {0, 0}, - {0, 2}, - {4898, 2}, - {4917, 2}, - {5037, 2}, - {4936, 181}, - {5109, 171}, - {4880, 7}, - {5117, 101}, - {4981, 551}, - {5057, 184}, - {5073, 286}, - {4885, 29}, - {4828, 482}, - {5006, 68}, - {5087, 320}, - {4947, 268}, - {5027, 134}, - {4961, 131}, - {4833, 485}, - {4956, 307}, - {0, 191}, - {4980, 37}, - {5042, 544}, - {4877, 198}, - {4950, 57}, - {5095, 107}, - {4859, 44}, - {5053, 162}, - {5039, 120}, - {5065, 5}, - {5016, 2}, - {4970, 2}, - {4840, 2}, - {4957, 2}, - {5002, 2}, - {5041, 2}, - {4995, 2}, - {5059, 2}, - {4983, 2}, - {4899, 2}, - {4962, 2}, - {5101, 2}, - {4901, 2}, - {4978, 2}, - {4997, 2}, - {5046, 2}, - {5072, 2}, - {4987, 2}, - {4914, 2}, - {4974, 2}, - {5105, 2}, - {4913, 2}, - {4986, 2}, - {4949, 2}, - {4900, 2}, {0, 1}, - {1410, 722}, - {3338, 445}, - {1487, 181}, - {0, 13}, - {1069, 444}, - {3139, 731}, - {2328, 432}, - {823, 176}, - {2025, 291}, - {1817, 3783}, - {1733, 222}, - {142, 485}, - {3907, 3840}, - {487, 2642}, - {4501, 2018}, - {2403, 2058}, - {3068, 1844}, - {2696, 2271}, - {2761, 792}, - {3951, 1047}, - {4504, 2692}, - {4865, 487}, - {3694, 3656}, - {3689, 3913}, - {2780, 3113}, - {1519, 3848}, - {3327, 3661}, - {3556, 325}, - {3627, 2809}, - {4265, 3050}, - {3692, 2132}, - {0, 16}, - {4525, 1832}, - {1592, 2219}, - {696, 3128}, - {4180, 2301}, - {1257, 2525}, - {888, 2038}, - {4984, 2826}, - {1589, 172}, - {3513, 2206}, - {1908, 560}, - {1853, 463}, - {377, 1573}, - {0, 404}, - {0, 22}, - {811, 2}, - {729, 2}, - {2410, 2}, - {1844, 2}, - {3506, 2}, - {2132, 2}, - {4965, 2}, - {1932, 2}, - {3125, 2}, - {1299, 2}, - {1680, 2}, - {1622, 2}, - {352, 2}, - {957, 2}, - {3737, 2}, - {675, 2}, - {3547, 2}, - {2309, 2}, - {3008, 2}, - {2784, 2}, - {2710, 2}, - {4062, 2}, - {4954, 2}, - {3777, 2}, - {3652, 2}, - {2778, 2}, - {1497, 2}, - {3357, 2}, - {3637, 2}, - {4280, 2373}, - {3650, 2}, - {873, 951}, - {4541, 2}, - {3562, 1011}, - {4598, 2}, - {1111, 1068}, - {4006, 2}, - {3653, 3135}, - {3727, 2}, - {2940, 2119}, - {3557, 2}, - {1609, 3265}, - {2649, 2}, - {3496, 3664}, - {4648, 2}, - {0, 3703}, - {3852, 540}, - {3791, 2}, - {2878, 2902}, - {3494, 2}, - {1834, 464}, - {2568, 2}, - {4123, 3440}, - {2871, 2}, - {1683, 3477}, - {3468, 2}, - {3121, 857}, - {3169, 2}, - {4643, 2646}, - {4121, 2}, - {1049, 771}, - {4377, 2}, - {329, 2886}, - {1326, 2}, - {2509, 2843}, - {1915, 2}, - {0, 1693}, - {971, 3646}, - {334, 2}, - {4296, 1507}, - {1252, 2}, - {651, 2736}, - {1631, 2}, - {2827, 2790}, - {2216, 2}, - {1991, 1481}, - {1255, 748}, - {653, 748}, - {4568, 1710}, - {974, 2}, - {2739, 3492}, - {3722, 2}, - {4267, 3223}, - {4603, 2}, - {4519, 2377}, - {3331, 2}, - {2738, 1685}, - {1948, 2}, - {3623, 1340}, - {2532, 1340}, - {0, 233}, - {4425, 1705}, - {4642, 2}, - {4726, 652}, - {3123, 2}, - {2530, 3309}, - {2104, 2}, - {3396, 3369}, - {0, 1831}, - {2411, 1754}, - {3059, 2}, - {2705, 2563}, - {2767, 2}, - {3956, 690}, - {4514, 2}, - {0, 571}, - {852, 3172}, - {1994, 2}, - {3149, 3139}, - {1408, 2}, - {1627, 1066}, - {1704, 2}, - {278, 2223}, - {856, 2}, - {3679, 1132}, - {610, 2}, - {627, 2501}, - {1619, 2}, - {2797, 2566}, - {2246, 2}, - {2004, 1753}, - {1925, 2}, - {1263, 3407}, - {626, 2}, - {0, 1952}, - {2007, 1967}, - {877, 2}, - {4397, 1916}, - {215, 2}, - {629, 2641}, - {547, 2}, - {1349, 827}, - {2002, 2}, - {2759, 2479}, - {1648, 2}, - {2085, 2983}, - {808, 2}, - {4335, 2946}, - {136, 2}, - {384, 1296}, - {471, 2}, - {1418, 3760}, - {2081, 946}, - {2522, 2}, - {1721, 882}, - {179, 2}, - {1421, 3166}, - {2707, 2}, - {2035, 544}, - {0, 3052}, - {0, 3127}, - {0, 2153}, - {0, 2659}, - {0, 2957}, - {0, 395}, - {0, 43}, - {0, 2763}, - {0, 298}, - {0, 1041}, - {0, 133}, - {0, 1286}, - {0, 374}, - {0, 2071}, - {0, 1218}, - {0, 175}, - {0, 3866}, - {0, 1950}, - {0, 1803}, - {0, 895}, - {3300, 1192}, - {2786, 2}, - {0, 2276}, - {0, 3723}, - {0, 2097}, - {0, 3861}, - {0, 3027}, - {0, 369}, - {0, 987}, - {3609, 2267}, - {2444, 2}, - {0, 1772}, - {0, 973}, - {0, 2541}, - {0, 1300}, - {5012, 1646}, - {0, 1798}, - {0, 2457}, - {2844, 668}, - {2204, 668}, - {1979, 668}, - {1900, 1788}, - {1228, 1788}, - {672, 1788}, - {4620, 2880}, - {955, 2880}, - {1978, 2880}, - {903, 2337}, - {4376, 2}, - {252, 3479}, - {676, 2}, - {594, 2678}, - {1391, 2}, - {1976, 1449}, - {2733, 2}, - {1685, 1533}, - {2042, 2}, - {831, 1493}, - {4309, 2}, - {174, 132}, - {445, 2}, - {513, 1331}, - {1463, 2}, - {2487, 3722}, - {1763, 2}, - {106, 709}, - {1469, 2}, - {2647, 790}, - {2097, 2}, - {0, 3315}, - {832, 1853}, - {105, 2}, - {4428, 3481}, - {1114, 2}, - {3968, 1585}, - {3050, 2}, - {1867, 1489}, - {3585, 2}, - {3209, 2786}, - {3287, 2}, - {4487, 2}, - {3971, 2818}, - {1177, 2818}, - {4226, 2818}, - {2122, 3421}, - {772, 2}, - {0, 3483}, - {0, 3269}, - {503, 845}, - {439, 2}, - {1535, 2629}, - {2123, 2}, - {2562, 797}, - {1831, 2}, - {4720, 2778}, - {3432, 2}, - {2214, 2730}, - {2835, 2}, - {2610, 1591}, - {2535, 2}, - {4203, 3569}, - {4719, 2}, - {484, 1640}, - {3899, 2}, - {4518, 1001}, - {3591, 2}, - {2418, 1063}, - {3047, 2}, - {2674, 3144}, - {2742, 2}, - {3941, 2109}, - {4515, 2}, - {612, 3271}, - {3681, 2}, - {2498, 661}, - {3918, 2}, - {319, 572}, - {4461, 2}, - {4652, 3679}, - {4735, 2}, - {3129, 1679}, - {2502, 2}, - {2020, 3527}, - {3401, 2}, - {0, 3088}, - {4017, 3059}, - {1107, 2}, - {0, 1422}, - {0, 649}, - {0, 1240}, - {2119, 3620}, - {744, 2}, - {4229, 3676}, - {86, 2}, - {542, 578}, - {460, 2}, - {1558, 2852}, - {2116, 2}, - {2592, 522}, - {1875, 2}, - {544, 477}, - {1737, 2}, - {3000, 418}, - {2317, 2}, - {0, 3270}, - {0, 2397}, - {0, 3425}, - {0, 1170}, - {0, 1393}, - {0, 1605}, - {0, 2230}, - {0, 1266}, - {0, 3865}, - {0, 301}, - {0, 3041}, - {0, 52}, - {0, 2353}, - {5103, 2}, - {4457, 29}, - {1067, 2598}, - {3932, 68}, - {3052, 37}, - {1802, 1532}, - {3636, 1267}, - {3276, 2762}, - {3354, 44}, - {4543, 120}, - {3140, 3571}, - {2329, 2307}, - {1147, 953}, - {2262, 2004}, - {3456, 1052}, - {1696, 742}, - {613, 2071}, - {1149, 268}, - {3943, 544}, - {281, 162}, - {4239, 2467}, - {4764, 2}, - {4773, 2}, - {4785, 2}, - {4774, 2}, - {4765, 2}, - {4793, 2}, - {4759, 2}, - {4767, 2}, - {4776, 2}, - {4758, 2}, - {2458, 1121}, - {3013, 868}, - {2734, 1891}, - {3935, 2159}, - {4760, 480}, - {4805, 2}, - {4779, 2}, - {0, 3508}, - {0, 3469}, - {2454, 874}, - {0, 2602}, - {3988, 2806}, - {3224, 530}, - {0, 3919}, - {4659, 1577}, - {1131, 383}, - {4145, 41}, - {3915, 1045}, - {3838, 1263}, - {2922, 1522}, - {1812, 201}, - {794, 1907}, - {2043, 710}, - {3219, 2}, - {4851, 59}, - {0, 106}, - {0, 215}, - {0, 173}, - {5107, 15}, - {0, 278}, - {5082, 155}, - {0, 72}, - {5125, 480}, - {0, 615}, - {0, 1324}, - {0, 291}, - {0, 205}, - {0, 64}, - {4854, 83}, - {0, 36}, - {4866, 240}, + {5003, 1}, + {4934, 1}, + {5123, 1}, + {5119, 196}, + {5000, 158}, + {5033, 48}, + {5008, 57}, + {4832, 154}, + {5012, 187}, + {4918, 169}, + {5130, 119}, + {4944, 167}, + {4883, 4}, + {5128, 163}, + {4991, 115}, + {5019, 55}, + {5014, 22}, + {4844, 157}, + {4987, 160}, + {0, 397}, + {5081, 54}, + {4904, 80}, + {4851, 139}, + {5075, 213}, + {5028, 76}, + {4996, 150}, + {4985, 212}, + {4869, 19}, + {4850, 67}, + {4843, 1}, + {4855, 1}, + {5029, 1}, + {5038, 1}, + {4990, 1}, + {5027, 1}, + {5085, 1}, + {5015, 1}, + {5084, 1}, + {4865, 1}, + {5031, 1}, + {5099, 1}, + {4984, 1}, + {4906, 1}, + {4964, 1}, + {4916, 1}, + {4926, 1}, + {4866, 1}, + {5080, 1}, + {4902, 1}, + {4859, 1}, + {4974, 1}, + {5107, 1}, + {5079, 1}, + {5093, 1}, + {0, 2}, + {1247, 291}, + {228, 2803}, + {1914, 196}, + {0, 20}, + {1462, 1967}, + {3575, 89}, + {4719, 21}, + {3297, 608}, + {1248, 726}, + {2754, 2344}, + {4654, 206}, + {2054, 157}, + {235, 1136}, + {1548, 3105}, + {2613, 1368}, + {3741, 1427}, + {2830, 2049}, + {4280, 1684}, + {2826, 2739}, + {618, 310}, + {4588, 2563}, + {4901, 1923}, + {833, 1842}, + {3470, 439}, + {2064, 3405}, + {4574, 366}, + {3134, 830}, + {4003, 78}, + {3130, 3842}, + {977, 1488}, + {3749, 3178}, + {0, 888}, + {498, 1031}, + {1206, 3698}, + {4372, 880}, + {2422, 3661}, + {982, 3366}, + {1849, 3891}, + {4969, 2786}, + {1500, 1185}, + {4192, 1378}, + {2949, 3288}, + {1951, 176}, + {3427, 3200}, + {0, 81}, + {0, 658}, + {37, 1}, + {2344, 1}, + {4649, 1}, + {386, 1}, + {2604, 1}, + {3700, 1}, + {5069, 1}, + {2127, 1}, + {4659, 1}, + {3344, 1}, + {4068, 1}, + {3348, 1}, + {722, 1}, + {3811, 1}, + {1877, 1}, + {580, 1}, + {4179, 1}, + {1568, 1}, + {563, 1}, + {2191, 1}, + {565, 1}, + {2879, 1}, + {5078, 1}, + {3354, 1}, + {1044, 1}, + {4254, 1}, + {2225, 1}, + {849, 1}, + {848, 1}, + {3236, 277}, + {1337, 1}, + {4010, 3695}, + {2820, 1}, + {4597, 737}, + {826, 1}, + {3486, 647}, + {4199, 1}, + {2901, 980}, + {4200, 1}, + {2216, 1733}, + {2622, 1}, + {446, 2243}, + {1727, 1}, + {1402, 227}, + {2902, 1}, + {0, 309}, + {825, 628}, + {1665, 1}, + {4146, 1428}, + {1104, 1}, + {3100, 2838}, + {4332, 1}, + {4580, 2985}, + {847, 1}, + {3449, 2920}, + {4257, 1}, + {2850, 2680}, + {4255, 1}, + {2165, 3785}, + {2618, 1}, + {370, 430}, + {1734, 1}, + {3060, 1720}, + {1572, 1}, + {4176, 1776}, + {2688, 1}, + {0, 2056}, + {134, 747}, + {4490, 1}, + {2408, 3191}, + {1237, 1}, + {192, 3700}, + {4125, 1}, + {1460, 3663}, + {667, 1}, + {2110, 3887}, + {2791, 1180}, + {2391, 1180}, + {4441, 1370}, + {3268, 1}, + {2635, 443}, + {1691, 1}, + {2789, 838}, + {4311, 1}, + {2790, 3851}, + {681, 1}, + {4607, 3176}, + {1995, 1}, + {808, 1018}, + {4150, 1018}, + {0, 1207}, + {3861, 3119}, + {3598, 1}, + {3862, 416}, + {1396, 1}, + {3305, 903}, + {1186, 1}, + {2479, 3541}, + {0, 1181}, + {1404, 3348}, + {409, 1}, + {2038, 3157}, + {412, 1}, + {3020, 2453}, + {2301, 1}, + {0, 1953}, + {3384, 1915}, + {1993, 1}, + {4517, 1863}, + {3207, 1}, + {3926, 2103}, + {3209, 1}, + {899, 851}, + {3662, 1}, + {1710, 3282}, + {424, 1}, + {2741, 2890}, + {1919, 1}, + {3881, 2955}, + {2980, 1}, + {4436, 2764}, + {2979, 1}, + {457, 3814}, + {4714, 1}, + {0, 465}, + {1532, 3516}, + {2912, 1}, + {275, 3447}, + {1887, 1}, + {933, 3265}, + {1888, 1}, + {3967, 2565}, + {1228, 1}, + {3324, 2086}, + {4348, 1}, + {4643, 3751}, + {935, 1}, + {3526, 3796}, + {4471, 1}, + {2911, 3620}, + {4472, 1}, + {1955, 2967}, + {2685, 648}, + {625, 1}, + {1837, 3349}, + {1473, 1}, + {2978, 2428}, + {190, 1}, + {1920, 80}, + {0, 663}, + {0, 248}, + {0, 3666}, + {0, 930}, + {0, 1596}, {0, 130}, - {0, 1260}, - {5085, 1418}, - {0, 78}, - {0, 287}, - {0, 216}, - {4864, 297}, - {3382, 908}, - {2084, 1009}, - {2516, 2}, - {3908, 2}, - {325, 2}, - {4450, 2}, - {4666, 2}, - {4910, 2}, - {4992, 2}, - {4850, 2}, - {4825, 2}, - {5068, 2}, - {5015, 2}, - {5051, 2}, - {4976, 2}, - {3706, 2}, - {2726, 2}, - {1545, 2}, - {3303, 2}, - {3534, 2}, - {0, 1620}, - {4254, 106}, - {3707, 72}, - {911, 1418}, - {4510, 1907}, - {3346, 1009}, - {4246, 78}, - {755, 36}, - {0, 3138}, - {0, 2117}, - {0, 1213}, - {0, 1279}, - {0, 1235}, - {0, 2998}, - {0, 12}, - {0, 3065}, - {0, 529}, - {0, 2386}, - {0, 3237}, - {0, 2589}, - {721, 615}, - {2390, 240}, - {1271, 130}, - {3734, 72}, - {3519, 15}, - {0, 370}, - {446, 130}, + {0, 2447}, + {0, 2030}, + {0, 1164}, + {0, 278}, + {0, 1651}, + {0, 2733}, + {0, 958}, + {0, 2020}, + {0, 788}, + {0, 752}, + {0, 3219}, + {0, 1281}, + {0, 2691}, + {0, 743}, + {2785, 3527}, + {2400, 1}, + {0, 1194}, + {0, 1977}, + {0, 1511}, + {0, 1469}, + {0, 2639}, + {0, 3390}, + {0, 279}, + {1813, 2608}, + {3831, 1}, + {0, 1258}, + {0, 677}, + {0, 2983}, + {0, 2378}, + {5076, 915}, + {0, 3555}, + {0, 3840}, + {1386, 42}, + {493, 42}, + {2000, 42}, + {490, 2124}, + {2957, 2124}, + {2285, 2124}, + {4318, 615}, + {3076, 615}, + {3737, 615}, + {494, 2490}, + {2609, 1}, + {3976, 1903}, + {3140, 1}, + {3977, 3089}, + {1885, 1}, + {3453, 2259}, + {724, 1}, + {2059, 2008}, + {2353, 1}, + {3139, 3079}, + {1172, 1}, + {1961, 1245}, + {495, 1}, + {1964, 2491}, + {4470, 1}, + {2812, 3462}, + {4000, 1}, + {3767, 3121}, + {491, 1}, + {2624, 3170}, + {3933, 1}, + {0, 3416}, + {1925, 2308}, + {3480, 1}, + {795, 1779}, + {2045, 1}, + {3294, 470}, + {2497, 1}, + {4427, 413}, + {3557, 1}, + {3890, 26}, + {3559, 1}, + {1122, 1}, + {4139, 1061}, + {1484, 1061}, + {354, 1061}, + {2529, 3142}, + {1662, 1}, + {0, 3211}, + {0, 3900}, + {4196, 3393}, + {2895, 1}, + {536, 2330}, + {4511, 1}, + {2034, 1818}, + {771, 1}, + {335, 1137}, + {4148, 1}, + {1599, 1217}, + {534, 1}, + {2219, 895}, + {535, 1}, + {2907, 2188}, + {2484, 1}, + {4402, 2652}, + {3300, 1}, + {1695, 3350}, + {2647, 1}, + {471, 3402}, + {1369, 1}, + {1130, 3216}, + {1372, 1}, + {3887, 2510}, + {802, 1}, + {3397, 2015}, + {4619, 1}, + {2738, 3867}, + {1917, 1}, + {3875, 3927}, + {2974, 1}, + {4434, 3690}, + {2975, 1}, + {462, 3097}, + {4720, 1}, + {2084, 1699}, + {1006, 1}, + {0, 1238}, + {2375, 1323}, + {1017, 1}, + {0, 1580}, + {0, 106}, + {0, 3602}, + {97, 2667}, + {4044, 1}, + {1412, 2605}, + {417, 1}, + {2043, 2367}, + {415, 1}, + {3017, 3461}, + {2294, 1}, + {4216, 1121}, + {3212, 1}, + {3692, 3776}, + {402, 1}, + {2545, 3821}, + {3995, 1}, + {0, 3542}, + {0, 616}, + {0, 3563}, + {0, 3245}, + {0, 342}, + {0, 3935}, {0, 1725}, - {0, 3101}, - {0, 2432}, - {0, 1280}, - {3726, 3302}, - {3253, 1586}, - {0, 2680}, - {3927, 2204}, - {0, 591}, - {0, 3473}, - {4919, 100}, - {4435, 2888}, - {0, 702}, - {0, 1593}, - {0, 3502}, - {0, 1283}, - {355, 2429}, - {1048, 1974}, - {1539, 249}, - {0, 1784}, - {4836, 319}, - {0, 1364}, - {0, 1146}, - {4955, 2411}, - {0, 1104}, - {4963, 1084}, - {4857, 584}, - {5075, 1661}, - {4826, 2130}, - {187, 433}, - {4903, 1462}, - {0, 2340}, - {0, 1814}, - {0, 516}, - {5076, 1115}, - {0, 170}, - {0, 2392}, - {0, 636}, - {0, 203}, - {5000, 2047}, - {0, 1696}, - {0, 316}, - {0, 1906}, - {5119, 142}, - {0, 1400}, - {0, 475}, - {0, 2535}, - {4930, 425}, - {0, 1665}, - {4928, 2738}, - {0, 2665}, - {0, 1166}, - {4835, 2}, - {5058, 2}, - {4938, 2}, - {5040, 2}, - {4939, 2}, - {4863, 2}, - {2093, 2}, - {4998, 2}, - {4891, 2}, - {5044, 2}, - {5115, 2}, - {4929, 2}, - {4991, 2}, - {4090, 2}, - {3488, 2}, - {3861, 2}, - {4922, 2}, - {1799, 2}, - {3630, 2}, - {2526, 2}, - {4747, 2}, - {0, 1787}, - {0, 1509}, + {0, 2214}, + {0, 1764}, + {0, 2042}, + {0, 763}, + {0, 3183}, + {0, 2975}, + {4874, 1}, + {3985, 119}, + {2875, 2984}, + {1866, 4}, + {2766, 54}, + {638, 382}, + {1504, 863}, + {1265, 83}, + {1503, 150}, + {3747, 19}, + {2056, 1179}, + {712, 3017}, + {1830, 2942}, + {2674, 1986}, + {578, 2996}, + {1550, 2420}, + {3712, 2020}, + {945, 115}, + {3635, 80}, + {4651, 212}, + {4479, 203}, + {4762, 1}, + {4774, 1}, + {4791, 1}, + {4776, 1}, + {4771, 1}, + {4797, 1}, + {4765, 1}, + {4760, 1}, + {4775, 1}, + {4767, 1}, + {4363, 3595}, + {3619, 3523}, + {3618, 283}, + {1060, 2747}, + {4761, 369}, + {4779, 1}, + {4780, 1}, + {0, 2128}, + {0, 2182}, + {2610, 1891}, + {0, 1216}, + {2756, 2840}, + {4485, 2411}, + {0, 1228}, + {2476, 2246}, + {4450, 1305}, + {3562, 2184}, + {3866, 1569}, + {3564, 2212}, + {1116, 137}, + {1467, 1944}, + {772, 1919}, + {4512, 71}, + {1986, 1}, + {4837, 254}, + {0, 341}, + {0, 583}, + {0, 27}, + {4957, 6}, + {0, 112}, + {4917, 927}, + {0, 94}, + {5122, 369}, + {0, 533}, + {0, 186}, + {0, 726}, + {0, 1575}, + {0, 484}, + {5048, 2239}, + {0, 15}, + {5129, 351}, + {0, 123}, + {0, 887}, + {4888, 314}, + {0, 697}, + {0, 258}, + {0, 807}, + {4942, 63}, + {1397, 3518}, + {55, 1606}, + {475, 1}, + {3779, 1}, + {1699, 1}, + {67, 1}, + {2322, 1}, + {4961, 1}, + {4884, 1}, + {5118, 1}, + {5010, 1}, + {5127, 1}, + {5001, 1}, + {5057, 1}, + {4992, 1}, + {1868, 1}, + {2775, 1}, + {608, 1}, + {1515, 1}, + {1272, 1}, {0, 2913}, - {0, 3530}, + {3745, 341}, + {991, 94}, + {3520, 314}, + {4743, 1919}, + {4447, 1606}, + {1291, 697}, + {3307, 15}, + {0, 3799}, + {0, 2783}, + {0, 1350}, + {0, 1012}, + {0, 946}, + {0, 689}, + {0, 1968}, + {0, 2472}, + {0, 3209}, + {0, 1754}, {0, 1825}, - {0, 2051}, - {0, 3531}, - {0, 2720}, - {0, 3756}, - {0, 2080}, - {4846, 2543}, - {4887, 2}, - {1902, 160}, - {654, 2}, - {0, 1338}, - {0, 518}, - {0, 2508}, - {0, 976}, - {0, 2727}, - {0, 2916}, - {0, 3742}, - {0, 2716}, - {0, 763}, - {0, 3544}, - {0, 2040}, - {0, 1006}, - {0, 1804}, - {0, 3617}, - {0, 2574}, - {0, 271}, - {0, 1386}, - {0, 573}, - {0, 2667}, - {0, 3890}, - {0, 1972}, - {0, 926}, - {0, 2202}, - {0, 3873}, - {0, 2154}, - {0, 1770}, - {0, 691}, - {0, 2017}, - {0, 3798}, - {0, 2950}, - {0, 671}, - {0, 1781}, - {0, 971}, - {2752, 3340}, - {4499, 2}, - {0, 1404}, - {0, 1595}, - {0, 2891}, - {0, 3098}, - {0, 2520}, - {0, 334}, - {2362, 2057}, - {178, 2}, - {3521, 1051}, - {4055, 2}, - {0, 1846}, - {3946, 3551}, - {2732, 2}, - {5123, 56}, - {5055, 2}, - {2149, 2483}, - {434, 2}, - {3289, 3366}, - {3699, 2}, - {2571, 2274}, - {3510, 2}, - {0, 187}, - {2811, 2766}, - {1917, 2}, - {2050, 1060}, - {507, 2}, - {3208, 2110}, - {3755, 2}, - {5029, 794}, - {4944, 2}, - {3680, 2740}, - {3021, 2}, - {3867, 3008}, - {1244, 2}, - {1087, 744}, - {1454, 2}, - {4553, 1834}, - {2971, 2}, - {4173, 1044}, - {4227, 2}, - {3044, 2928}, - {3656, 2}, - {0, 2074}, - {492, 3609}, - {2030, 2}, - {0, 2784}, - {0, 3817}, - {0, 2048}, - {0, 303}, - {0, 2682}, - {0, 3503}, - {0, 2435}, - {0, 252}, - {0, 1886}, - {0, 3852}, - {0, 3051}, - {0, 3654}, - {0, 1992}, - {0, 3526}, - {0, 1417}, - {0, 322}, - {0, 1716}, - {0, 3436}, - {0, 2690}, - {0, 292}, - {0, 1433}, - {0, 623}, - {0, 2584}, - {0, 3458}, - {0, 1361}, - {0, 217}, - {0, 1637}, + {0, 216}, + {4528, 533}, + {590, 351}, + {604, 123}, + {2818, 94}, + {1998, 6}, + {0, 491}, + {3715, 123}, + {0, 2818}, + {0, 2771}, + {0, 1812}, + {0, 2401}, + {4226, 1897}, + {1399, 3386}, + {0, 315}, + {1630, 3136}, + {0, 1916}, + {0, 75}, + {5067, 660}, + {2418, 2637}, + {0, 1674}, + {0, 2977}, + {0, 1562}, + {0, 3659}, + {284, 1060}, + {149, 3884}, + {4276, 1543}, + {0, 2598}, + {5007, 402}, {0, 713}, - {0, 3255}, - {0, 1876}, - {0, 1635}, - {0, 2487}, - {0, 539}, - {0, 2265}, - {0, 1363}, - {0, 2805}, - {0, 3279}, - {0, 1000}, - {0, 893}, - {0, 2434}, - {0, 3102}, - {0, 2052}, - {0, 3916}, - {0, 1842}, - {0, 2893}, - {0, 1469}, - {0, 863}, - {0, 3384}, - {0, 2342}, - {0, 842}, - {0, 574}, - {0, 3313}, - {0, 1677}, - {0, 3143}, - {0, 270}, - {0, 3655}, - {0, 2451}, - {0, 2014}, - {0, 2618}, - {0, 1095}, - {0, 210}, - {0, 3154}, - {0, 1373}, - {0, 3359}, - {0, 548}, - {1811, 2094}, - {4784, 2}, - {4791, 2}, - {4813, 2}, - {4795, 2}, - {4814, 2}, - {4794, 2}, - {4817, 2}, - {4800, 2}, - {4786, 2}, - {4823, 2}, - {4775, 2}, - {4796, 2}, - {4811, 2}, - {4798, 2}, - {4812, 2}, - {4799, 2}, - {4821, 2}, - {4788, 2}, - {4973, 2}, - {5031, 2}, - {5084, 2}, - {5110, 2}, - {4948, 2}, - {5030, 2}, - {4911, 2}, - {5062, 2}, - {4844, 2}, - {5092, 2}, - {4845, 2}, - {5024, 2}, - {4856, 2}, - {4888, 2}, - {5081, 2}, - {4977, 2}, - {5033, 2}, - {4909, 2}, - {4953, 2}, - {5120, 2}, - {4883, 2}, - {5080, 2}, - {5097, 2}, - {4787, 2}, - {4804, 2}, - {4801, 2}, - {2185, 2}, - {2556, 2}, - {2718, 2}, - {4625, 2}, - {1439, 2}, - {5089, 2}, - {4862, 2}, - {5122, 2}, - {4797, 2}, - {4778, 2}, - {4820, 2}, - {4815, 2}, - {4803, 2}, - {4822, 2}, - {4542, 3463}, - {1526, 1487}, - {777, 2270}, - {1958, 4}, - {4135, 2}, - {5067, 2}, - {2021, 2}, - {4958, 2}, - {1600, 2}, - {5049, 2}, - {4818, 2}, - {4842, 2}, - {4941, 2}, - {5023, 2}, - {5116, 2}, - {5001, 2}, - {4906, 2}, - {5003, 2}, - {1521, 2}, - {5096, 2}, - {4969, 2}, - {5129, 2}, - {2963, 2}, - {4892, 2}, - {357, 2}, - {4763, 2}, - {4783, 2}, - {3252, 239}, - {4033, 3162}, - {2099, 1345}, - {165, 3357}, - {1323, 532}, - {2453, 3826}, - {59, 2638}, - {1876, 1797}, - {4940, 2}, - {4843, 2}, - {5114, 2}, - {4782, 2}, - {4761, 2}, - {4852, 2}, - {3107, 2}, - {4158, 2}, - {1161, 677}, - {1703, 3043}, - {941, 2460}, - {4905, 2}, - {4982, 2}, - {5118, 2}, - {5018, 2}, - {4896, 2}, - {1458, 3621}, - {2494, 2582}, - {4868, 2}, - {2500, 49}, - {2648, 1715}, - {2370, 3896}, - {3380, 2450}, - {5022, 2}, - {4886, 2}, - {4996, 2}, - {994, 2}, - {1688, 2}, - {1839, 2}, - {419, 2464}, - {1503, 1970}, - {4890, 2}, - {1778, 2}, - {5060, 2}, - {4873, 2}, - {1547, 2}, - {433, 2}, - {4193, 2}, - {5034, 2}, - {2538, 2}, - {4806, 2}, - {4762, 2}, - {4841, 2}, - {4018, 2}, - {4912, 2}, - {1233, 2}, - {1080, 2}, - {4616, 2}, - {2965, 2}, - {4920, 2}, - {5011, 2}, - {3073, 2}, - {4279, 2}, - {1809, 2}, - {4771, 2}, - {4943, 2}, - {1186, 2}, - {2369, 2}, - {814, 2}, - {978, 2}, - {465, 262}, - {4808, 2}, - {4792, 2}, - {2543, 2516}, - {4802, 2}, - {4781, 2}, - {2240, 1968}, - {652, 3789}, - {3900, 2131}, - {4777, 2}, - {5104, 2}, - {4942, 2}, - {3371, 2810}, - {4988, 2}, - {4736, 3628}, - {4990, 2}, - {4391, 1704}, - {5013, 2}, - {1217, 2857}, - {5045, 2}, - {226, 1427}, - {3390, 2025}, - {4819, 2}, - {4789, 2}, - {3477, 3396}, - {4807, 2}, - {3917, 3912}, - {3415, 2619}, - {4472, 1829}, - {3628, 2448}, - {1522, 879}, - {3435, 2114}, - {4975, 2}, - {5112, 2}, - {1747, 1603}, - {4921, 2}, - {2552, 1013}, - {5020, 2}, - {3213, 2897}, - {4993, 2}, - {2425, 1728}, - {4918, 2}, - {4332, 3713}, - {4967, 2}, - {5028, 2}, - {2644, 2029}, - {4855, 2}, - {2889, 2}, - {0, 93}, - {0, 3578}, - {0, 2321}, - {0, 2136}, - {0, 2504}, - {0, 958}, - {0, 27}, - {0, 3234}, - {0, 1238}, - {0, 3467}, - {0, 393}, - {0, 3746}, - {0, 2537}, - {0, 1917}, - {0, 1510}, - {0, 3765}, - {0, 3156}, - {0, 206}, - {0, 2261}, - {0, 556}, - {0, 3363}, - {0, 997}, - {0, 1624}, - {0, 2804}, - {0, 804}, - {0, 2382}, - {0, 3058}, - {0, 2024}, - {0, 3859}, - {0, 1756}, - {0, 2819}, - {0, 1388}, - {0, 915}, - {0, 3323}, - {0, 1439}, - {0, 3708}, - {0, 3509}, - {0, 454}, - {0, 143}, - {0, 1630}, - {2868, 368}, - {0, 1429}, - {0, 2308}, - {0, 313}, - {0, 2560}, - {0, 1706}, - {0, 3077}, - {4927, 2}, - {2525, 2}, - {4926, 2}, - {396, 2}, - {5005, 2}, - {4400, 2}, - {5099, 2}, - {879, 2}, - {5083, 2}, - {35, 2}, - {4972, 2}, - {4536, 2}, - {4952, 2}, - {2169, 2}, - {5093, 2}, - {615, 2}, - {5130, 2}, - {4861, 2}, - {2741, 2}, - {3385, 2}, - {4946, 2}, - {2822, 2}, - {0, 1115}, - {0, 1885}, - {0, 1217}, - {0, 3464}, - {0, 411}, - {0, 2604}, - {0, 3}, - {0, 3243}, - {0, 844}, - {0, 1447}, - {0, 2919}, - {0, 308}, - {0, 2885}, - {0, 2676}, - {0, 1558}, - {0, 368}, - {0, 1305}, - {0, 2437}, - {0, 1987}, - {0, 277}, - {0, 3790}, - {0, 616}, - {0, 3104}, - {0, 2440}, - {0, 1314}, - {0, 3288}, - {0, 1561}, - {0, 2675}, - {0, 2194}, + {0, 488}, + {4915, 1235}, + {0, 1229}, + {4860, 1301}, + {5117, 266}, + {4941, 2173}, + {4968, 633}, + {2416, 2937}, + {5068, 848}, + {0, 925}, + {0, 2449}, + {0, 1762}, + {4847, 2058}, + {0, 1143}, + {0, 612}, + {0, 652}, + {0, 876}, + {5002, 1317}, + {0, 681}, + {0, 1774}, + {0, 417}, + {5049, 2208}, + {0, 890}, + {0, 2480}, + {0, 1421}, + {5066, 1612}, + {0, 928}, + {4952, 1602}, + {0, 476}, + {0, 2004}, + {4933, 1}, + {4838, 1}, + {4909, 1}, + {4946, 1}, + {5131, 1}, + {5102, 1}, + {2680, 1}, + {4830, 1}, + {5036, 1}, + {5020, 1}, + {4882, 1}, + {5043, 1}, + {4963, 1}, + {1000, 1}, + {2707, 1}, + {3048, 1}, + {4970, 1}, + {1033, 1}, + {1432, 1}, + {1561, 1}, + {3338, 1}, + {0, 1138}, + {0, 184}, + {0, 2527}, + {0, 3804}, + {0, 2542}, + {0, 61}, + {0, 2741}, + {0, 2876}, + {0, 3312}, + {0, 2851}, + {4929, 813}, + {4947, 1}, + {3349, 2394}, + {1932, 1}, + {0, 2337}, + {0, 3623}, + {0, 2294}, + {0, 3387}, + {0, 2063}, + {0, 3545}, + {0, 3389}, + {0, 2959}, + {0, 2232}, + {0, 3732}, + {0, 1397}, + {0, 1254}, + {0, 655}, + {0, 1283}, + {0, 2577}, + {0, 1204}, + {0, 1015}, + {0, 1556}, + {0, 1045}, + {0, 622}, + {0, 3046}, + {0, 2640}, + {0, 3345}, + {0, 1087}, + {0, 1080}, + {0, 1952}, + {0, 2143}, {0, 562}, - {0, 3589}, - {0, 3856}, - {0, 1643}, - {0, 1882}, - {0, 2745}, - {0, 807}, - {0, 2936}, - {0, 2127}, - {0, 2572}, - {0, 3881}, - {0, 76}, - {0, 1735}, - {0, 3887}, - {0, 3277}, - {0, 194}, - {0, 2400}, - {0, 1147}, - {0, 1632}, - {0, 2774}, - {4195, 181}, - {2536, 487}, - {3306, 171}, - {1671, 101}, - {889, 551}, - {2872, 298}, - {4651, 286}, - {3593, 29}, - {2472, 482}, - {4714, 68}, - {3084, 320}, - {1355, 268}, - {3498, 134}, - {3638, 131}, - {2407, 485}, - {459, 649}, - {1666, 307}, - {2033, 37}, - {468, 198}, - {1432, 57}, - {3058, 44}, - {1970, 2696}, - {572, 1743}, - {3194, 3552}, - {3812, 171}, - {2787, 101}, - {3425, 551}, - {3882, 1041}, - {2850, 133}, - {2960, 1645}, - {2044, 286}, - {659, 320}, - {3085, 134}, - {3886, 1831}, - {3443, 2659}, - {3806, 3838}, - {2867, 197}, - {4073, 307}, - {792, 198}, - {931, 57}, - {1583, 3601}, - {4458, 1950}, - {2484, 107}, - {3760, 1158}, - {4661, 106}, - {2631, 215}, - {4120, 173}, - {486, 78}, - {4324, 287}, - {4443, 482}, - {2838, 37}, - {919, 57}, - {1303, 107}, - {125, 106}, - {1138, 215}, - {1373, 240}, - {557, 78}, - {4611, 287}, - {4132, 516}, - {2869, 2243}, - {2175, 7}, - {2542, 2746}, - {2709, 16}, - {1433, 184}, - {830, 1353}, - {1903, 673}, - {1815, 1796}, - {712, 175}, - {2406, 1218}, - {3257, 376}, - {1739, 3194}, - {1584, 2673}, - {950, 1144}, - {2851, 3016}, - {4707, 894}, - {3573, 3615}, - {2622, 196}, - {4656, 1803}, - {3192, 2657}, - {4263, 85}, - {408, 895}, - {576, 2463}, - {1965, 1657}, - {4134, 3027}, - {3466, 1409}, - {4548, 2230}, - {3903, 1772}, - {3403, 149}, - {4463, 973}, - {3296, 1266}, - {1879, 5}, - {1706, 3320}, - {913, 565}, - {2899, 1646}, - {4678, 72}, - {4810, 2}, - {4790, 2}, - {269, 3883}, - {4630, 2}, - {4482, 1983}, - {2727, 2}, - {1038, 922}, - {1791, 2}, - {601, 2195}, - {820, 2}, - {1776, 3849}, - {172, 2}, - {3937, 2581}, - {746, 2}, - {884, 254}, - {1677, 2}, - {4347, 1397}, - {2598, 2}, - {3666, 588}, - {4692, 2}, - {2503, 2695}, - {4154, 2}, - {4449, 3460}, - {643, 2}, - {490, 1359}, - {2032, 2}, - {4067, 238}, - {3528, 2}, - {4752, 1644}, - {3712, 2}, - {3620, 3491}, - {4275, 2}, - {3092, 2616}, - {1639, 2}, - {1777, 212}, - {851, 2}, - {2966, 1374}, - {4618, 2}, - {3384, 553}, - {2750, 2}, - {4498, 2647}, - {3318, 2}, - {1905, 3496}, - {2817, 2}, - {2956, 1445}, - {4305, 2}, - {1770, 288}, - {1076, 2}, - {2242, 1692}, - {1554, 2}, - {1041, 3428}, - {2165, 2}, - {2518, 3308}, - {2218, 2}, - {2361, 1689}, - {181, 2}, - {3523, 630}, - {4056, 2}, - {2799, 1446}, - {3295, 2}, - {3945, 3226}, - {2729, 2}, - {2892, 824}, - {1981, 2}, - {2150, 3038}, - {432, 2}, - {3288, 3869}, - {3697, 2}, - {2570, 2844}, - {3511, 2}, - {3741, 931}, - {2935, 2}, - {2812, 2413}, - {1916, 2}, - {2047, 633}, - {508, 2}, - {3211, 1741}, - {3758, 2}, - {2491, 364}, - {3580, 2}, - {3676, 2379}, - {3019, 2}, - {3868, 2685}, - {1241, 2}, - {1086, 300}, - {1457, 2}, - {4555, 1440}, - {2972, 2}, - {4174, 626}, - {4225, 2}, - {3042, 2587}, - {3655, 2}, - {4448, 1707}, - {644, 2}, - {491, 3293}, - {2031, 2}, - {4065, 2445}, - {3533, 2}, - {4750, 2979}, - {3713, 2}, - {3618, 1682}, - {4277, 2}, - {189, 747}, - {4557, 2}, - {4686, 3006}, - {2481, 2}, - {1240, 3812}, - {1563, 2}, - {524, 2777}, - {887, 2}, - {1701, 704}, - {248, 2}, - {4181, 1237}, - {967, 2}, - {813, 3352}, - {1760, 2}, - {4291, 2506}, - {2691, 2}, - {3865, 3159}, - {4486, 2}, - {2744, 1343}, - {3926, 2}, - {2550, 3639}, - {2195, 2}, - {2321, 2140}, - {133, 2}, - {3551, 1137}, - {4001, 2}, - {2840, 1936}, - {3333, 2}, - {3990, 3717}, - {2773, 2}, - {3873, 2802}, - {1238, 2}, - {1089, 1125}, - {1450, 2}, - {4562, 2155}, - {2980, 2}, - {4166, 855}, - {4220, 2}, - {3035, 2900}, - {3645, 2}, - {370, 3670}, - {4695, 2}, - {4572, 2201}, - {2658, 2}, - {1102, 1183}, - {1731, 2}, - {658, 1979}, - {748, 2}, - {1869, 3643}, - {61, 2}, - {4409, 2}, - {685, 2}, - {528, 2}, - {2090, 2}, - {4021, 935}, - {3559, 2979}, - {0, 3872}, - {4635, 580}, - {287, 2}, - {91, 2341}, - {2462, 2}, - {3685, 3225}, - {3351, 2}, - {4375, 2578}, - {4045, 2}, - {3226, 629}, - {4595, 2}, - {4701, 3106}, - {364, 2}, - {203, 890}, - {2379, 2}, - {3750, 1954}, - {3281, 2}, - {4424, 1153}, - {3944, 2}, - {3291, 3032}, - {4505, 2}, - {3097, 2869}, - {1635, 2}, - {1783, 1176}, - {847, 2}, - {2969, 2211}, - {4626, 2}, - {3376, 938}, - {2748, 2}, - {4493, 2828}, - {3316, 2}, - {2548, 1994}, - {2197, 2}, - {2324, 3879}, - {126, 2}, - {3546, 3084}, - {4007, 2}, - {2839, 3692}, - {3337, 2}, - {3985, 1887}, - {2775, 2}, - {2067, 494}, - {2961, 2}, - {2825, 2304}, - {4433, 2}, - {1644, 3171}, - {1231, 2}, - {2371, 2518}, - {1407, 2}, - {1184, 384}, - {2009, 2}, - {3372, 2049}, - {1333, 2}, - {1489, 3532}, - {1120, 2}, - {2687, 2721}, - {4340, 2}, - {3106, 3751}, - {3045, 2}, - {4233, 2076}, - {3607, 2}, - {1656, 2671}, - {3205, 2}, - {3358, 321}, - {3984, 2}, - {2130, 1415}, - {94, 2}, - {1372, 608}, - {2343, 2}, - {124, 2575}, - {1756, 2}, - {592, 3510}, - {4367, 2}, - {4245, 1435}, - {3031, 2}, - {759, 294}, - {1518, 2}, - {283, 1699}, - {1109, 2}, - {1444, 3426}, - {531, 2}, - {4091, 2613}, - {908, 2}, - {771, 219}, - {1877, 2}, - {4258, 1362}, - {2791, 2}, - {3805, 538}, - {4586, 2}, - {2659, 2660}, - {4035, 2}, - {0, 2366}, - {0, 541}, - {0, 1638}, - {894, 2}, - {511, 2}, - {2077, 2}, - {1094, 2}, - {985, 2}, - {4175, 2}, - {4009, 2}, - {3222, 2}, - {516, 3103}, - {2325, 733}, - {1242, 3705}, - {69, 347}, - {2457, 1898}, - {751, 2522}, - {916, 3215}, - {4081, 1926}, - {3931, 2}, - {3297, 2}, - {448, 2}, - {2399, 2}, - {1175, 2}, - {175, 2}, - {2298, 3447}, - {2569, 2137}, - {2736, 1372}, - {4491, 2260}, - {1543, 208}, - {718, 2494}, - {835, 2}, - {2358, 2}, - {1658, 2}, - {3202, 2}, - {3350, 2}, - {3989, 2}, - {2135, 2}, - {90, 2}, - {1375, 2596}, - {2339, 2139}, - {134, 647}, - {1750, 3534}, - {3615, 1776}, - {1540, 3150}, - {1395, 3761}, - {1180, 1103}, - {2573, 2}, - {4395, 2}, - {3282, 2}, - {2808, 2}, - {4431, 2}, - {3369, 2}, - {2014, 2}, - {2880, 2}, - {3027, 2565}, - {4230, 1708}, - {1846, 3406}, - {1016, 1425}, - {2264, 2310}, - {1464, 1847}, - {1116, 74}, - {2059, 3878}, - {1642, 2}, - {3090, 2}, - {3223, 2}, - {4004, 2}, - {2065, 2}, - {122, 2}, - {95, 3199}, - {1838, 1099}, - {645, 2224}, - {4447, 714}, - {4316, 438}, - {2984, 3445}, - {312, 2}, - {999, 2}, - {1517, 2}, - {381, 2}, - {4208, 2}, - {938, 2}, - {790, 2}, - {1729, 2}, - {2660, 2410}, - {4532, 2781}, - {3964, 1160}, - {3902, 2105}, - {3780, 2}, - {3563, 2}, - {152, 2}, - {2079, 2}, - {958, 2}, - {407, 2}, - {2110, 2}, - {1019, 2}, - {862, 989}, - {4136, 2472}, - {3987, 2715}, - {3353, 1931}, - {427, 3541}, - {2455, 2141}, - {1159, 2917}, - {156, 1502}, - {2326, 2}, - {805, 383}, - {933, 2}, - {4216, 1045}, - {4071, 2}, - {3277, 1263}, - {494, 2}, - {2383, 1522}, - {1225, 2}, - {42, 201}, - {2397, 2}, - {737, 1907}, - {2188, 2}, - {2554, 710}, - {1440, 1600}, - {838, 657}, - {1899, 161}, - {1820, 349}, - {717, 2251}, - {2412, 735}, - {1641, 1222}, - {3091, 3090}, - {3225, 1600}, - {4003, 657}, - {2064, 161}, - {138, 349}, - {1300, 2251}, - {2427, 735}, - {87, 1222}, - {1841, 3090}, - {3553, 1107}, - {1441, 2626}, - {1290, 1654}, - {1237, 1854}, - {2551, 3232}, - {4432, 86}, - {3271, 2334}, - {2929, 429}, - {4393, 1107}, - {3507, 2626}, - {1890, 1654}, - {2861, 1854}, - {2999, 3232}, - {4343, 86}, - {1746, 2334}, - {1117, 429}, - {2208, 1951}, - {1525, 1094}, - {1015, 1161}, - {2137, 2725}, - {3715, 3036}, - {998, 613}, - {1140, 888}, - {1345, 1691}, - {4654, 1951}, - {2876, 1094}, - {3958, 1161}, - {4446, 2725}, - {2849, 3036}, - {3884, 613}, - {2746, 888}, - {2435, 1691}, - {2278, 2}, - {258, 2}, - {3452, 909}, - {4117, 1871}, - {3015, 2183}, - {4191, 2}, - {2493, 195}, - {1549, 3040}, - {3579, 552}, - {3441, 819}, - {3793, 383}, - {2267, 1871}, - {546, 3422}, - {1848, 480}, - {1914, 3422}, - {692, 3073}, - {1308, 1250}, - {3298, 2839}, - {1874, 214}, - {1714, 1100}, - {2903, 2}, - {4682, 3566}, - {3597, 817}, - {2508, 1045}, - {4694, 2863}, - {3118, 1263}, - {3516, 214}, - {1473, 3696}, - {1332, 3498}, - {1261, 471}, - {2501, 2}, - {4470, 2}, - {3245, 2}, - {2887, 945}, - {3577, 2}, - {1550, 2}, - {1398, 2143}, - {1198, 2918}, - {2581, 1139}, - {4398, 1522}, - {2815, 2388}, - {4413, 3712}, - {3381, 413}, - {4219, 2}, - {458, 2}, - {607, 2}, - {2001, 2728}, - {4092, 2}, - {3495, 2}, - {4509, 2}, - {3875, 2}, - {3367, 3891}, - {4429, 81}, - {3717, 1113}, - {997, 1907}, - {1137, 2817}, - {1348, 1760}, - {4655, 1577}, - {2874, 1064}, - {2852, 1199}, - {3883, 1316}, - {881, 1215}, - {3938, 2}, - {3308, 546}, - {450, 2502}, - {2402, 201}, - {1202, 3155}, - {192, 710}, - {2350, 1316}, - {833, 176}, - {4480, 754}, - {272, 722}, - {2290, 722}, - {216, 722}, - {3687, 3362}, - {4022, 720}, - {402, 1}, - {1523, 1}, - {3143, 1}, - {1006, 2222}, - {2770, 281}, - {3173, 1680}, - {2986, 3063}, - {1423, 3695}, - {2702, 2703}, - {2028, 1058}, - {4053, 3079}, - {3518, 785}, - {3682, 1581}, - {2611, 50}, - {4353, 482}, - {4478, 30}, - {3416, 800}, - {4503, 167}, - {48, 1077}, - {251, 105}, - {2266, 637}, - {3792, 420}, - {3176, 362}, - {4235, 447}, - {4150, 755}, - {3105, 28}, - {4688, 131}, - {1051, 50}, - {3664, 222}, - {3800, 731}, - {3453, 432}, - {259, 30}, - {1955, 800}, - {740, 167}, - {668, 1077}, - {1936, 105}, - {1254, 637}, - {3925, 420}, - {760, 362}, - {900, 447}, - {1699, 755}, - {4370, 28}, - {3690, 181}, - {4711, 551}, - {2480, 485}, - {4184, 162}, - {3733, 1041}, - {1123, 29}, - {1268, 320}, - {1344, 268}, - {4725, 134}, - {2857, 131}, - {4031, 307}, - {4379, 544}, - {2885, 198}, - {3030, 1275}, - {1511, 1528}, - {374, 2859}, - {111, 7}, - {4386, 1539}, - {3057, 2812}, - {703, 705}, - {1533, 133}, - {1062, 2499}, - {522, 286}, - {71, 29}, - {85, 29}, - {3703, 1693}, - {431, 482}, - {415, 268}, - {632, 268}, - {582, 131}, - {1985, 667}, - {286, 307}, - {598, 191}, - {166, 37}, - {2782, 1651}, - {2393, 3846}, - {2248, 3236}, - {151, 5}, - {3069, 297}, - {1664, 320}, - {3177, 2692}, - {467, 171}, - {46, 551}, - {298, 551}, - {774, 184}, - {0, 1126}, - {426, 134}, - {616, 485}, - {3111, 1547}, - {3234, 1807}, - {4028, 2807}, - {2069, 700}, - {144, 482}, - {2449, 2486}, - {56, 36}, - {1866, 215}, - {635, 215}, - {74, 36}, - {4344, 716}, - {284, 101}, - {271, 101}, - {559, 68}, - {2762, 3779}, - {3970, 317}, - {1226, 3586}, - {3901, 1336}, - {3763, 2108}, - {3554, 3083}, - {115, 1070}, - {2060, 2849}, - {925, 1852}, - {404, 2319}, - {2139, 3556}, - {1017, 612}, - {868, 70}, - {4112, 2713}, - {3952, 2473}, - {3330, 1678}, - {375, 482}, - {2416, 521}, - {1146, 791}, - {112, 1769}, - {2330, 107}, - {786, 3851}, - {946, 1062}, - {4197, 140}, - {4050, 1048}, - {3256, 162}, - {477, 2073}, - {2347, 3394}, - {1218, 268}, - {5, 7}, - {2405, 101}, - {704, 134}, - {2202, 482}, - {2524, 521}, - {2699, 791}, - {4601, 1769}, - {1419, 107}, - {822, 3851}, - {1887, 1062}, - {1798, 140}, - {723, 1048}, - {2391, 162}, - {1604, 2073}, - {3108, 3394}, - {3233, 268}, - {4029, 7}, - {2070, 101}, - {139, 134}, - {0, 2420}, - {4412, 1333}, - {4837, 2}, - {4870, 2}, - {5021, 2}, - {3953, 2}, - {3328, 2}, - {1832, 2}, - {3940, 2}, - {2166, 2}, - {31, 2}, - {5090, 2}, - {5056, 2}, - {4834, 2}, - {4872, 2}, - {2257, 2}, - {5032, 2}, - {4415, 2}, - {4951, 2}, - {2344, 2}, - {5098, 2}, - {1829, 2}, - {4959, 2}, - {3161, 2}, - {339, 680}, - {1634, 3499}, - {3232, 694}, - {3109, 408}, - {4924, 2}, - {275, 2}, - {5063, 2}, - {4196, 2}, - {4985, 2}, - {2215, 2}, - {5108, 2}, - {209, 2}, - {4923, 2}, - {1430, 2}, - {4858, 2}, - {3439, 2}, - {5050, 2}, - {4935, 2}, - {2497, 2}, - {1258, 2}, - {1587, 2}, - {541, 2}, - {907, 2}, - {5061, 2}, - {4853, 2}, - {3732, 2}, - {1124, 2}, - {4931, 2}, - {5009, 2}, - {4723, 2}, - {2856, 2}, - {5121, 2}, - {4894, 2}, - {5111, 2}, - {4893, 2}, - {4159, 2}, - {3077, 2}, - {4904, 2}, - {5019, 2}, - {1096, 2}, - {247, 2}, - {5074, 2}, - {4831, 2}, - {1052, 2}, - {3662, 2}, - {4916, 2}, - {5086, 2}, - {4832, 2}, - {5007, 2}, - {4932, 2}, - {4933, 2}, - {1735, 2}, - {1974, 2}, - {566, 2}, - {1378, 2}, - {4838, 2}, - {5069, 2}, - {4875, 2}, - {5066, 2}, - {1340, 2}, - {678, 2}, - {4489, 2}, - {77, 2}, - {3080, 2}, - {4708, 2}, - {4300, 2}, - {537, 2}, - {267, 1271}, - {82, 1724}, - {3119, 222}, - {4188, 731}, - {1941, 432}, - {332, 30}, - {1475, 800}, - {2293, 167}, - {254, 1077}, - {1705, 105}, - {2939, 637}, - {2071, 1414}, - {1933, 2167}, - {680, 3000}, - {3110, 1162}, - {3916, 2782}, - {2679, 1960}, - {3463, 2409}, - {3787, 3630}, - {2888, 525}, - {2382, 3895}, - {2662, 1714}, - {2483, 1961}, - {4703, 2779}, - {1318, 880}, - {932, 2992}, - {2054, 2165}, - {1686, 2634}, - {912, 3828}, - {2280, 165}, - {2160, 526}, - {3017, 3064}, - {2866, 2390}, - {4352, 1228}, - {1673, 3241}, - {1129, 1497}, - {2434, 2591}, - {1309, 2142}, - {1267, 643}, - {1912, 3529}, - {2080, 3066}, - {2936, 663}, - {2802, 1}, - {4407, 1}, - {1608, 1}, - {1214, 1}, - {2354, 1}, - {1380, 1}, - {1193, 1}, - {1983, 1}, - {1115, 1}, - {3723, 1}, - {3856, 1}, - {3364, 1}, - {345, 1}, - {1886, 1}, - {827, 1}, - {588, 1}, - {1999, 1}, - {1174, 1}, - {469, 1}, - {4337, 1}, - {4464, 2247}, - {2853, 1056}, - {940, 746}, - {1328, 738}, - {162, 1411}, - {1162, 345}, - {1354, 1900}, - {579, 2528}, - {4716, 341}, - {337, 2997}, - {171, 2318}, - {2345, 472}, - {3730, 1138}, - {3260, 1713}, - {4417, 1571}, - {3922, 1747}, - {3305, 443}, - {4481, 2837}, - {834, 402}, - {3991, 3365}, - {4153, 2937}, - {3081, 279}, - {664, 2737}, - {2180, 1092}, - {1100, 3333}, - {242, 431}, - {2287, 181}, - {883, 171}, - {102, 7}, - {1249, 101}, - {1103, 551}, - {1462, 184}, - {4571, 286}, - {2988, 29}, - {4152, 482}, - {4231, 68}, - {3048, 320}, - {3660, 268}, - {2540, 134}, - {2179, 131}, - {2305, 485}, - {113, 307}, - {3541, 191}, - {163, 37}, - {2848, 544}, - {3326, 198}, - {3976, 57}, - {2764, 107}, - {1291, 44}, - {3421, 162}, - {3550, 120}, - {3767, 5}, - {2322, 181}, - {519, 171}, - {1572, 7}, - {2118, 101}, - {424, 551}, - {1506, 184}, - {3133, 286}, - {1585, 29}, - {1741, 482}, - {800, 68}, - {2998, 320}, - {4578, 268}, - {3436, 134}, - {2779, 131}, - {4517, 485}, - {3339, 307}, - {3491, 191}, - {1377, 37}, - {1529, 544}, - {1036, 198}, - {2793, 57}, - {4253, 107}, - {3189, 44}, - {3002, 162}, - {4327, 120}, - {3570, 5}, - {3413, 50}, - {1171, 3561}, - {4302, 999}, - {457, 1878}, - {4494, 354}, - {1274, 2749}, - {4867, 2}, - {0, 642}, - {0, 967}, - {0, 920}, + {0, 2106}, + {0, 451}, + {0, 2916}, + {0, 3032}, + {0, 2779}, + {504, 499}, + {4550, 1}, + {0, 2071}, + {0, 2947}, + {0, 2664}, + {0, 3112}, + {0, 3358}, + {0, 2921}, + {2560, 1453}, + {2273, 1}, + {1970, 1320}, + {3777, 1}, + {0, 740}, + {1049, 1348}, + {4076, 1}, + {5120, 68}, + {5064, 1}, + {4578, 1801}, + {123, 1}, + {503, 1909}, + {3369, 1}, + {3323, 280}, + {3145, 1}, + {0, 1946}, + {292, 1099}, + {3360, 1}, + {2563, 2614}, + {2272, 1}, + {1972, 2545}, + {3776, 1}, + {5070, 3679}, + {4972, 1}, + {1051, 2520}, + {4078, 1}, + {2582, 2452}, + {707, 1}, + {306, 1024}, + {4711, 1}, + {4456, 1195}, + {1461, 1}, + {1752, 1710}, + {1864, 1}, + {3627, 1153}, + {1763, 1}, + {0, 142}, + {4286, 2682}, + {470, 1}, {0, 2827}, - {0, 3001}, - {0, 3678}, - {0, 2371}, - {0, 3548}, - {0, 1277}, - {0, 1456}, - {0, 3904}, - {0, 3344}, - {0, 3290}, - {0, 1401}, - {0, 1608}, - {0, 314}, - {0, 3694}, - {0, 2303}, - {0, 682}, - {0, 832}, - {0, 2590}, - {0, 2970}, - {0, 2813}, - {0, 937}, - {0, 988}, - {0, 1890}, - {0, 381}, - {0, 2160}, + {0, 3253}, + {0, 2811}, + {0, 1955}, + {0, 3406}, + {0, 3528}, + {0, 3090}, {0, 3497}, - {0, 3375}, - {0, 1824}, - {0, 1407}, - {0, 1568}, - {0, 3331}, - {0, 3268}, - {0, 2556}, - {0, 3839}, - {0, 2497}, - {0, 1086}, - {0, 1164}, - {0, 2407}, - {0, 2733}, - {0, 3078}, - {0, 1106}, - {0, 753}, - {0, 2196}, - {0, 1662}, + {0, 3795}, + {0, 1495}, + {0, 1635}, + {0, 1145}, + {0, 1589}, + {0, 3931}, + {0, 1643}, + {0, 1475}, {0, 962}, - {0, 2158}, - {0, 2980}, - {0, 3116}, - {0, 356}, - {0, 3049}, - {0, 3884}, - {0, 3740}, - {0, 1743}, - {0, 3615}, - {0, 2696}, - {0, 2243}, - {0, 1335}, - {0, 2517}, - {3423, 68}, - {1364, 107}, - {0, 40}, - {0, 1911}, - {0, 3306}, - {0, 2078}, - {0, 1303}, - {0, 3482}, - {0, 655}, - {0, 3338}, - {0, 1925}, - {0, 1674}, - {0, 3157}, - {0, 3071}, - {0, 2035}, - {0, 3218}, - {0, 3832}, - {0, 1768}, - {0, 2399}, - {0, 1249}, - {0, 3831}, - {0, 3216}, - {0, 1499}, - {0, 1318}, - {0, 2338}, - {0, 985}, - {0, 67}, - {0, 2592}, - {0, 3274}, - {0, 96}, - {0, 3026}, - {0, 2344}, - {0, 396}, - {0, 1621}, - {0, 2579}, - {0, 729}, - {0, 453}, - {0, 2384}, - {0, 2650}, - {0, 1548}, - {0, 3635}, - {0, 3442}, - {0, 1232}, - {0, 2179}, - {0, 2956}, - {0, 230}, - {0, 1109}, - {0, 2712}, - {0, 555}, - {0, 3412}, - {0, 1963}, - {0, 1722}, - {0, 3185}, - {0, 3614}, - {0, 1765}, - {0, 3321}, - {0, 3915}, - {4544, 2610}, - {2643, 2085}, - {2626, 1718}, - {1384, 1655}, - {2151, 3579}, - {1002, 1569}, - {3454, 2163}, - {1035, 547}, - {4345, 3543}, - {164, 892}, - {4546, 2780}, - {2846, 1128}, - {1893, 3120}, - {4628, 1830}, - {3924, 1986}, - {2758, 3525}, - {257, 3738}, - {2790, 3720}, - {1676, 1905}, - {3571, 2112}, - {1530, 878}, - {4702, 961}, - {358, 1664}, - {2908, 3922}, - {3617, 3799}, - {4218, 1297}, - {1954, 1896}, - {4257, 2075}, - {1139, 3736}, - {4034, 3685}, - {770, 2994}, - {3539, 3871}, - {1443, 2455}, - {3933, 1046}, - {4636, 1189}, - {3184, 2447}, - {739, 2701}, - {3187, 3110}, - {2426, 1122}, - {2854, 798}, - {1963, 825}, - {2612, 596}, - {2258, 2003}, - {4411, 3385}, - {3728, 3517}, - {2981, 1997}, - {670, 1226}, - {3003, 1498}, - {1304, 3450}, - {3359, 3206}, - {1744, 2633}, - {4679, 2199}, - {208, 473}, - {2821, 2931}, - {3532, 3060}, - {4338, 265}, - {1937, 732}, - {4325, 224}, - {1260, 3096}, - {3967, 2741}, - {791, 3830}, - {3182, 2237}, - {1665, 3645}, - {3857, 1470}, - {4293, 1298}, - {3542, 3796}, - {1253, 3456}, - {3572, 3186}, - {1909, 1205}, - {2789, 1717}, - {2333, 164}, - {4301, 1111}, - {521, 1538}, - {2794, 3820}, - {3207, 1307}, - {4647, 1437}, - {2400, 1790}, - {4627, 1659}, - {730, 3829}, - {3858, 3591}, - {1176, 3095}, - {510, 2606}, - {4312, 3741}, - {2394, 1557}, - {1655, 1730}, - {253, 3707}, - {2766, 3145}, - {280, 968}, - {3965, 1156}, - {1259, 1323}, - {3808, 621}, - {660, 2825}, - {4438, 3130}, - {2253, 1819}, - {1805, 1971}, - {67, 3507}, - {2602, 3754}, - {80, 3709}, - {4118, 1928}, - {1112, 2098}, - {3672, 901}, - {1913, 1752}, - {2823, 139}, - {212, 2884}, - {714, 2752}, - {2428, 457}, - {4653, 1129}, - {2446, 734}, - {3183, 2719}, - {1474, 3068}, - {3605, 3616}, - {4149, 3659}, - {991, 2220}, - {3492, 761}, - {3070, 944}, - {3668, 2686}, - {1347, 2908}, - {3671, 2894}, - {563, 840}, - {4581, 1079}, - {79, 1945}, - {3405, 2026}, - {1295, 563}, - {4089, 3109}, - {4497, 2971}, - {3335, 146}, - {886, 829}, - {3342, 1050}, - {2277, 2905}, - {2994, 2874}, - {2121, 3803}, - {4570, 3054}, - {185, 3329}, - {3055, 2090}, - {3482, 2208}, - {4349, 3294}, - {2117, 3528}, - {4380, 3906}, - {1001, 2149}, - {4189, 1860}, - {915, 1143}, - {3794, 1673}, - {1201, 954}, - {3135, 2536}, - {2701, 2694}, - {3999, 936}, - {1573, 14}, - {4030, 656}, - {311, 2603}, - {4238, 2023}, - {533, 3480}, - {3464, 1196}, - {1389, 1565}, - {4209, 3748}, - {4619, 1791}, - {3246, 1403}, - {943, 1823}, - {3215, 2162}, - {2213, 1382}, - {3011, 3576}, - {2051, 3018}, - {4350, 1806}, - {614, 2823}, - {2531, 150}, - {3263, 144}, - {4566, 2973}, - {2181, 2593}, - {4582, 2296}, - {937, 18}, - {3669, 622}, - {1110, 1325}, - {843, 2174}, - {3994, 511}, - {1515, 2934}, - {1968, 3020}, - {1196, 223}, - {3643, 788}, - {1185, 1102}, - {4278, 3075}, - {351, 2704}, - {4634, 3864}, - {4012, 3520}, - {829, 2965}, - {3619, 412}, - {2909, 601}, - {3790, 2830}, - {1505, 2280}, - {3819, 2611}, - {382, 648}, - {4722, 87}, - {289, 1636}, - {4161, 3715}, - {981, 2291}, - {3484, 697}, - {3061, 869}, - {3657, 2612}, - {1360, 2960}, - {3683, 2834}, - {545, 924}, - {4597, 1002}, - {93, 1495}, - {3099, 757}, - {1630, 1458}, - {3824, 3653}, - {4260, 3545}, - {3575, 1517}, - {1150, 2193}, - {3616, 1775}, - {1949, 3581}, - {2678, 3843}, - {2456, 2729}, - {669, 759}, - {4427, 3180}, - {2250, 1757}, - {1800, 1130}, - {57, 2045}, - {2613, 3801}, - {1837, 722}, - {0, 327}, - {4780, 2}, - {2928, 2032}, - {1967, 3580}, - {4224, 3862}, - {4827, 2}, - {5078, 2}, - {3814, 2}, - {4966, 2}, - {3795, 2}, - {5036, 2}, - {4704, 2}, - {4839, 2}, - {4369, 2}, - {4847, 2}, - {2553, 2}, - {4860, 2}, - {4590, 2}, - {5038, 2}, - {4554, 2}, - {4971, 2}, - {3654, 2}, - {5054, 2}, - {2864, 2}, - {5094, 2}, - {4743, 2}, - {5070, 2}, - {2664, 2}, - {4937, 2}, - {2671, 2}, - {4960, 2}, - {1472, 2}, - {4882, 2}, - {1189, 2}, - {5004, 2}, - {2722, 2}, - {5052, 2}, - {3930, 2}, - {753, 2}, - {4829, 2}, - {2834, 2}, - {3853, 2}, - {4878, 2}, - {3877, 2}, - {475, 2}, - {4889, 2}, - {372, 2}, - {768, 2}, - {5017, 2}, - {1436, 2}, - {1896, 2}, - {1461, 2}, - {4770, 2}, - {3269, 2655}, - {4574, 897}, - {5048, 2}, - {4569, 2}, - {944, 2571}, - {4849, 2}, - {4879, 2}, - {3670, 2}, - {4994, 2}, - {3278, 2}, - {5008, 2}, - {4192, 2}, - {4881, 2}, - {4151, 2}, - {5124, 2}, - {4351, 2}, - {4902, 2}, - {4724, 2}, - {4908, 2}, - {2923, 2}, - {4925, 2}, - {4244, 2}, - {5126, 2}, - {4234, 2}, - {4884, 2}, - {4014, 2}, - {4989, 2}, - {2485, 2}, - {4999, 2}, - {4387, 2}, - {4945, 2}, - {564, 2}, - {4964, 2}, - {1346, 2}, - {4897, 2}, - {1878, 2}, - {5127, 2}, - {3661, 2}, - {575, 2}, - {5106, 2}, - {60, 2}, - {4010, 2}, - {5077, 2}, - {3622, 2}, - {2911, 2}, - {4871, 2}, - {1504, 2}, - {3815, 2}, - {5014, 2}, - {4729, 2}, - {282, 2}, - {4848, 2}, - {5071, 2}, - {5025, 2}, - {5010, 2}, - {1156, 2}, - {3851, 2}, - {1546, 2}, - {2925, 2}, - {2356, 2}, - {4907, 2}, - {2624, 2}, - {3345, 1114}, - {2991, 452}, - {3739, 1909}, - {1294, 1771}, - {3736, 2511}, - {648, 503}, - {4492, 269}, - {183, 1503}, - {2656, 1165}, - {2373, 726}, - {4264, 1182}, - {3829, 1579}, - {2877, 1375}, - {392, 1857}, - {2896, 1384}, - {1493, 1837}, - {3126, 2147}, - {1710, 3042}, - {2386, 2329}, - {2642, 3025}, - {406, 1504}, - {1153, 896}, - {1997, 1127}, - {4289, 782}, - {1996, 2213}, - {3639, 1744}, - {1615, 1255}, - {3154, 550}, - {2234, 703}, - {2478, 1195}, - {577, 461}, - {1026, 1762}, - {2163, 1472}, - {4403, 1488}, - {2156, 3399}, - {3497, 1990}, - {1766, 2036}, - {3294, 816}, - {371, 1826}, - {4687, 124}, - {1964, 860}, - {1513, 1032}, - {452, 390}, - {2931, 1200}, - {441, 681}, - {3842, 1220}, - {826, 1383}, - {3934, 3570}, - {3389, 3387}, - {1306, 1526}, - {4133, 241}, - {4540, 850}, - {3312, 13}, - {875, 2963}, - {3293, 2840}, - {2254, 916}, - {2951, 1014}, - {2155, 1868}, - {4212, 2079}, - {930, 640}, - {3465, 3061}, - {3040, 2929}, - {3714, 35}, - {1414, 917}, - {3709, 964}, - {606, 2968}, - {4609, 2801}, - {16, 3766}, - {2959, 3115}, - {2056, 3374}, - {4549, 2019}, - {4142, 2157}, - {2593, 3259}, - {32, 3587}, - {2563, 3874}, - {1824, 2190}, - {3366, 1812}, - {1388, 1098}, - {3171, 1742}, - {1674, 1030}, - {3904, 2470}, - {4333, 2608}, - {3526, 861}, - {1234, 125}, - {3522, 592}, - {1898, 2663}, - {2730, 2272}, - {2360, 3423}, - {4087, 1134}, - {901, 1492}, - {3402, 3800}, - {2974, 3921}, - {3724, 1471}, - {1282, 1759}, - {3748, 2203}, - {2594, 1655}, - {2270, 892}, - {4462, 263}, - {3773, 38}, - {2953, 491}, - {657, 108}, - {2952, 765}, - {1288, 116}, - {3292, 547}, - {1765, 1253}, - {3280, 3917}, - {1720, 391}, - {3674, 963}, - {4364, 1128}, - {1316, 2315}, - {3378, 3688}, - {858, 1351}, - {11, 1258}, - {1835, 3762}, - {4116, 3486}, - {1870, 3151}, - {2601, 1344}, - {2105, 1653}, - {3049, 51}, - {3395, 760}, - {1302, 1455}, - {4125, 3657}, - {4534, 3547}, - {3304, 1513}, - {880, 2191}, - {3301, 1773}, - {2259, 3583}, - {2943, 3844}, - {2159, 2726}, - {3536, 481}, - {1456, 2188}, - {3974, 3465}, - {4674, 3332}, - {3164, 1774}, - {731, 1459}, - {3152, 1516}, - {2401, 3377}, - {2809, 3233}, - {1987, 2485}, - {3751, 3516}, - {3343, 407}, - {2618, 595}, - {4093, 2835}, - {1822, 2282}, - {4085, 2614}, - {33, 645}, - {4416, 82}, - {602, 1639}, - {2377, 1556}, - {2645, 1197}, - {418, 2605}, - {1163, 2461}, - {2008, 666}, - {4283, 353}, - {1988, 372}, - {3634, 2538}, - {1625, 2336}, - {3153, 3367}, - {497, 3292}, - {4323, 2760}, - {2448, 6}, - {1698, 253}, - {233, 3046}, - {2749, 2539}, - {210, 2368}, - {3939, 359}, - {1221, 427}, - {3832, 1365}, - {1632, 123}, - {3088, 1989}, - {1167, 3244}, - {422, 3129}, - {1557, 2005}, - {3843, 1740}, - {1537, 1212}, - {2930, 3188}, - {2346, 3424}, - {2728, 2273}, - {2172, 1717}, - {3012, 2453}, - {443, 2228}, - {4240, 3649}, - {2307, 1451}, - {1564, 1287}, - {338, 3788}, - {2703, 3471}, - {368, 3176}, - {4049, 1239}, - {1200, 1697}, - {3879, 183}, - {1561, 2189}, - {3578, 483}, - {798, 2915}, - {314, 3047}, - {1628, 251}, - {4074, 756}, - {1623, 452}, - {2714, 2511}, - {1990, 1503}, - {2810, 726}, - {2945, 3042}, - {2075, 2329}, - {4524, 896}, - {4115, 782}, - {2566, 2213}, - {18, 1255}, - {2588, 550}, - {1794, 703}, - {3399, 1195}, - {1412, 461}, - {2101, 1201}, - {2937, 867}, - {27, 2430}, - {867, 2288}, - {2286, 1023}, - {4551, 585}, - {2283, 114}, - {3347, 2233}, - {1315, 2632}, - {3461, 3212}, - {1938, 1999}, - {2803, 598}, - {230, 3100}, - {727, 2964}, - {2447, 110}, - {4680, 847}, - {2430, 1022}, - {1467, 1655}, - {3584, 892}, - {697, 263}, - {4406, 38}, - {2255, 2060}, - {1813, 1836}, - {78, 3289}, - {2629, 1986}, - {66, 3903}, - {4130, 1896}, - {1099, 1790}, - {3667, 1156}, - {3116, 968}, - {1606, 1659}, - {3845, 622}, - {4281, 1189}, - {3606, 1307}, - {1165, 1908}, - {3586, 2082}, - {1961, 3726}, - {2669, 3690}, - {2429, 2986}, - {3919, 2832}, - {1211, 3114}, - {3167, 1838}, - {2743, 1993}, - {3975, 3519}, - {1709, 825}, - {3961, 3718}, - {273, 1912}, - {4331, 2103}, - {394, 891}, - {2675, 1778}, - {2352, 248}, - {4287, 2889}, - {3848, 2761}, - {2900, 491}, - {414, 108}, - {2873, 765}, - {1528, 355}, - {3082, 805}, - {1678, 3602}, - {3479, 2238}, - {1381, 3642}, - {4205, 1474}, - {4612, 1301}, - {3230, 3793}, - {963, 3454}, - {3229, 3184}, - {2206, 1208}, - {3022, 1721}, - {2062, 158}, - {3797, 3590}, - {1194, 2424}, - {3130, 858}, - {2692, 698}, - {3992, 2474}, - {1581, 3092}, - {4044, 2717}, - {297, 745}, - {4247, 1110}, - {543, 1801}, - {2905, 600}, - {1984, 2000}, - {4745, 3389}, - {4061, 3521}, - {2670, 1991}, - {333, 1221}, - {2667, 1746}, - {1590, 3452}, - {3587, 3210}, - {1468, 2627}, - {4084, 1582}, - {906, 1178}, - {3407, 2620}, - {2982, 2481}, - {3729, 689}, - {1281, 336}, - {3746, 399}, - {622, 2531}, - {4511, 2346}, - {196, 602}, - {910, 996}, - {4076, 871}, - {1286, 1097}, - {2034, 979}, - {1108, 2255}, - {3438, 2091}, - {1104, 632}, - {4467, 1074}, - {62, 839}, - {4573, 65}, - {766, 898}, - {3928, 983}, - {1437, 204}, - {1897, 61}, - {1266, 2943}, - {3568, 2658}, - {1251, 2254}, - {4334, 180}, - {261, 403}, - {4699, 1233}, - {1883, 290}, - {3284, 1863}, - {1075, 462}, - {640, 244}, - {1324, 1530}, - {3785, 1614}, - {1320, 1349}, - {2997, 849}, - {2276, 692}, - {2490, 2387}, - {4248, 2320}, - {437, 2722}, - {2713, 741}, - {3144, 1116}, - {4712, 1793}, - {2338, 925}, - {4698, 1293}, - {799, 1321}, - {3798, 1672}, - {1250, 21}, - {2788, 631}, - {2392, 1922}, - {4307, 3360}, - {3874, 3435}, - {2855, 1631}, - {540, 1330}, - {2845, 1652}, - {1471, 3475}, - {3185, 3140}, - {1580, 2597}, - {3813, 3413}, - {1181, 3072}, - {3145, 549}, - {2716, 450}, - {4037, 2742}, - {1594, 2396}, - {3995, 2512}, - {335, 501}, - {4223, 264}, - {509, 1505}, - {4591, 1078}, - {167, 1701}, - {3072, 3845}, - {3499, 3776}, - {4368, 1262}, - {2136, 1937}, - {4362, 2042}, - {1027, 3813}, - {4164, 3658}, - {896, 2914}, - {2665, 1549}, - {2372, 1091}, - {4259, 2645}, - {3823, 2557}, - {2862, 799}, - {400, 227}, - {2906, 524}, - {1498, 2489}, - {3114, 2446}, - {1711, 3381}, - {4042, 2866}, - {815, 3197}, - {3635, 1810}, - {2920, 1895}, - {3804, 3434}, - {1527, 3806}, - {3799, 3629}, - {413, 1948}, - {4696, 2016}, - {260, 836}, - {2912, 492}, - {1975, 2184}, - {4693, 3462}, - {3998, 3336}, - {2700, 1779}, - {342, 1461}, - {2715, 1518}, - {1621, 3380}, - {3632, 3229}, - {1434, 2488}, - {1962, 2984}, - {2917, 3494}, - {373, 2125}, - {850, 2039}, - {2342, 3148}, - {4706, 3680}, - {2304, 3758}, - {3117, 2111}, - {1499, 1899}, - {3540, 970}, - {2127, 2306}, - {3064, 3691}, - {200, 1356}, - {989, 1256}, - {2211, 3759}, - {4576, 3484}, - {2177, 3149}, - {3250, 1337}, - {1352, 1658}, - {3409, 45}, - {411, 1431}, - {4269, 775}, - {2385, 2245}, - {1640, 2335}, - {330, 1105}, - {2673, 517}, - {296, 225}, - {4038, 2406}, - {1135, 2462}, - {3881, 3256}, - {3349, 3207}, - {1803, 2854}, - {3745, 234}, - {4430, 80}, - {3433, 2954}, - {1113, 2637}, - {3410, 2269}, - {2102, 156}, - {2599, 597}, - {2176, 1209}, - {3678, 1711}, - {1046, 1067}, - {3273, 2513}, - {2549, 2583}, - {4187, 815}, - {1740, 169}, - {4156, 543}, - {159, 2639}, - {4348, 2229}, - {663, 3457}, - {2628, 2564}, - {2251, 3880}, - {4426, 1642}, - {3743, 1541}, - {2992, 3575}, - {694, 3272}, - {2987, 3371}, - {1327, 1601}, - {3332, 1406}, - {1727, 375}, - {3561, 2113}, - {1427, 606}, - {3949, 3030}, - {4646, 2947}, - {3206, 94}, - {752, 887}, - {3174, 1010}, - {2450, 2985}, - {2843, 2848}, - {1944, 3727}, - {3756, 441}, - {1085, 2124}, - {3299, 3488}, - {2575, 3420}, - {4122, 1859}, - {1830, 1350}, - {4128, 1616}, - {63, 3356}, - {4468, 3295}, - {571, 2529}, - {2990, 333}, - {2026, 2305}, - {4513, 717}, - {4101, 814}, - {2633, 2586}, - {76, 2999}, - {2600, 2811}, - {1871, 883}, - {3408, 972}, - {1351, 1901}, - {1660, 1490}, - {3188, 1136}, - {1239, 2674}, - {504, 2534}, - {1417, 736}, - {3862, 272}, - {1442, 459}, - {2800, 2482}, - {2409, 2393}, - {2723, 3418}, - {3200, 3774}, - {1652, 2570}, - {3870, 1155}, - {4304, 1076}, - {3565, 611}, - {1272, 2796}, - {3549, 3012}, - {1926, 981}, - {2771, 940}, - {2320, 2054}, - {3361, 3164}, - {1797, 2793}, - {3738, 312}, - {4422, 179}, - {3424, 3013}, - {1127, 1859}, - {3419, 2325}, - {2089, 60}, - {2608, 662}, - {2192, 1281}, - {3978, 237}, - {707, 1799}, - {3531, 3208}, - {2820, 3283}, - {3914, 2180}, - {1483, 1527}, - {3893, 1442}, - {529, 3221}, - {4664, 3388}, - {307, 1675}, - {2138, 2244}, - {3053, 1675}, - {188, 1430}, - {980, 1320}, - {2201, 3805}, - {4588, 1265}, - {2191, 3191}, - {3238, 1265}, - {1362, 1729}, - {3420, 148}, - {103, 1}, - {4483, 2044}, - {2029, 3401}, - {1285, 1482}, - {679, 1947}, - {3009, 1}, - {677, 1703}, - {3784, 3438}, - {890, 3174}, - {4170, 2688}, - {1369, 3347}, - {3490, 3034}, - {993, 611}, - {202, 502}, - {1754, 2770}, - {4176, 2349}, - {1717, 2547}, - {2504, 451}, - {2112, 333}, - {2973, 1594}, - {2336, 982}, - {2697, 1650}, - {456, 1}, - {1197, 3811}, - {1969, 1315}, - {4251, 1880}, - {1951, 2092}, - {3601, 3775}, - {1582, 3699}, - {3180, 2978}, - {117, 1609}, - {4613, 1154}, - {2152, 2567}, - {1387, 2490}, - {560, 712}, - {3023, 330}, - {583, 434}, - {3651, 2558}, - {965, 2363}, - {4141, 3335}, - {1748, 2792}, - {3261, 3163}, - {1047, 1855}, - {611, 1946}, - {1374, 3476}, - {3686, 3770}, - {1361, 3668}, - {3038, 1893}, - {2194, 2059}, - {2609, 943}, - {3500, 1241}, - {1367, 826}, - {4190, 2443}, - {4589, 2295}, - {3274, 1049}, - {979, 567}, - {3258, 145}, - {2235, 2216}, - {3056, 2662}, - {2018, 3189}, - {1358, 3559}, - {3504, 2356}, - {0, 2343}, + {0, 1521}, + {0, 1210}, + {0, 2583}, + {0, 2473}, + {0, 3754}, + {0, 2485}, + {0, 3870}, + {0, 1690}, + {0, 1541}, + {0, 1041}, + {0, 2576}, + {0, 3124}, + {0, 2750}, + {0, 1792}, + {0, 2422}, + {0, 1914}, + {0, 3346}, + {0, 343}, + {0, 3154}, + {0, 1896}, + {0, 2718}, + {0, 3641}, + {0, 2414}, + {0, 1430}, + {0, 2769}, {0, 1342}, - {0, 3888}, - {0, 3276}, - {0, 1580}, - {0, 2787}, - {0, 625}, - {0, 903}, - {0, 2972}, - {0, 324}, - {0, 3160}, - {0, 2135}, - {0, 1369}, - {0, 3341}, - {0, 3767}, - {0, 1167}, - {0, 2322}, + {0, 3862}, + {0, 795}, + {0, 3682}, + {0, 1303}, + {0, 2389}, + {0, 419}, + {0, 2077}, {0, 3004}, - {0, 934}, - {0, 545}, - {0, 3414}, - {0, 1959}, - {0, 3898}, - {0, 3285}, - {0, 1599}, - {0, 1216}, - {0, 2290}, - {0, 1033}, - {0, 126}, - {0, 2640}, - {0, 3260}, - {0, 135}, - {0, 3112}, - {0, 2452}, - {0, 515}, - {0, 1508}, - {2919, 2535}, - {3633, 1665}, - {0, 2580}, - {0, 33}, - {0, 728}, - {0, 3675}, - {0, 1623}, - {0, 1864}, - {0, 3918}, - {0, 1943}, - {0, 3404}, - {0, 3598}, - {0, 2187}, - {0, 54}, - {0, 3297}, - {0, 2086}, - {0, 1310}, - {0, 3489}, - {0, 975}, - {0, 3910}, - {0, 1312}, - {0, 2089}, - {0, 3689}, - {0, 3863}, - {0, 1053}, - {0, 2441}, - {0, 3105}, - {0, 780}, - {0, 2006}, - {0, 3097}, - {0, 117}, - {0, 1027}, - {0, 2851}, - {0, 3648}, - {0, 740}, - {0, 2672}, - {0, 2879}, - {0, 1071}, - {0, 669}, - {0, 1554}, - {2143, 1554}, - {0, 129}, - {0, 2615}, - {0, 48}, - {0, 603}, - {0, 2754}, - {0, 1904}, - {0, 3325}, - {0, 3536}, - {0, 977}, - {0, 1796}, - {0, 635}, - {0, 2316}, - {0, 236}, - {0, 2952}, - {0, 2266}, - {0, 599}, - {0, 1820}, - {0, 2816}, - {0, 379}, - {0, 674}, - {0, 3019}, - {0, 1562}, - {0, 2598}, - {0, 1645}, - {0, 673}, - {0, 357}, - {0, 376}, - {0, 2328}, - {0, 3372}, - {0, 2673}, - {0, 3791}, - {0, 1491}, - {0, 3647}, + {0, 1650}, + {0, 3052}, + {0, 92}, + {0, 3507}, + {0, 377}, + {0, 3083}, + {0, 1966}, + {0, 3051}, + {0, 3530}, + {0, 627}, + {0, 3808}, + {0, 460}, + {0, 2813}, + {0, 2017}, + {2202, 2528}, + {4809, 1}, + {4796, 1}, + {4792, 1}, + {4808, 1}, + {4807, 1}, + {4794, 1}, + {4824, 1}, + {4823, 1}, + {4814, 1}, + {4782, 1}, + {4789, 1}, + {4804, 1}, + {4786, 1}, + {4790, 1}, + {4802, 1}, + {4819, 1}, + {4800, 1}, + {4821, 1}, + {5004, 1}, + {4899, 1}, + {4854, 1}, + {4875, 1}, + {5125, 1}, + {5124, 1}, + {5062, 1}, + {4903, 1}, + {5100, 1}, + {5046, 1}, + {4943, 1}, + {5098, 1}, + {4842, 1}, + {4892, 1}, + {4932, 1}, + {4857, 1}, + {4879, 1}, + {5073, 1}, + {5109, 1}, + {4890, 1}, + {4891, 1}, + {4835, 1}, + {4827, 1}, + {4788, 1}, + {4785, 1}, + {4806, 1}, + {1202, 1}, + {2942, 1}, + {3442, 1}, + {1410, 1}, + {1778, 1}, + {4939, 1}, + {4936, 1}, + {5034, 1}, + {4801, 1}, + {4778, 1}, + {4813, 1}, + {4815, 1}, + {4818, 1}, + {4787, 1}, + {4273, 1544}, + {4610, 2953}, + {1651, 275}, + {1615, 3410}, + {1387, 1}, + {5106, 1}, + {895, 1}, + {5105, 1}, + {2505, 1}, + {5111, 1}, + {4803, 1}, + {4960, 1}, + {4981, 1}, + {4872, 1}, + {4923, 1}, + {4908, 1}, + {4959, 1}, + {4853, 1}, + {2284, 1}, + {4885, 1}, + {4980, 1}, + {4925, 1}, + {3386, 1}, + {4831, 1}, + {576, 1}, + {4766, 1}, + {4777, 1}, + {4564, 1522}, + {107, 3023}, + {526, 1608}, + {3396, 3616}, + {3340, 1073}, + {3180, 3794}, + {1443, 1645}, + {3330, 2498}, + {5016, 1}, + {4900, 1}, + {5045, 1}, + {4783, 1}, + {4759, 1}, + {5013, 1}, + {2776, 1}, + {2194, 1}, + {2459, 538}, + {4121, 2768}, + {3908, 2956}, + {5114, 1}, + {5116, 1}, + {5061, 1}, + {5052, 1}, + {4858, 1}, + {4310, 2129}, + {894, 2902}, + {4911, 1}, + {784, 2819}, + {2512, 976}, + {782, 1571}, + {4448, 2618}, + {4913, 1}, + {4965, 1}, + {5024, 1}, + {1586, 1}, + {2867, 1}, + {3502, 1}, + {3682, 1052}, + {971, 3860}, + {5055, 1}, + {266, 1}, + {4868, 1}, + {4910, 1}, + {2620, 1}, + {2221, 1}, + {903, 1}, + {5051, 1}, + {4399, 1}, + {4825, 1}, + {4769, 1}, + {5089, 1}, + {1476, 1}, + {4998, 1}, + {2209, 1}, + {1390, 1}, + {3081, 1}, + {145, 1}, + {5094, 1}, + {4975, 1}, + {1933, 1}, + {3347, 1}, + {3586, 1}, + {4763, 1}, + {4893, 1}, + {1805, 1}, + {3383, 1}, + {1797, 1}, + {4679, 1}, + {4594, 205}, + {4820, 1}, + {4816, 1}, + {2485, 51}, + {4795, 1}, + {4781, 1}, + {1423, 576}, + {4267, 2740}, + {3373, 3895}, + {4793, 1}, + {5041, 1}, + {4876, 1}, + {3024, 1718}, + {4828, 1}, + {1606, 2699}, + {4919, 1}, + {2727, 3141}, + {4889, 1}, + {4145, 1775}, + {4886, 1}, + {4120, 3858}, + {4362, 1772}, + {4822, 1}, + {4784, 1}, + {3067, 2649}, + {4811, 1}, + {2718, 2397}, + {2103, 708}, + {2516, 3688}, + {4127, 777}, + {2379, 1287}, + {353, 1318}, + {5096, 1}, + {4954, 1}, + {2376, 3190}, + {4841, 1}, + {1286, 1239}, + {4861, 1}, + {2094, 1177}, + {4966, 1}, + {1193, 2596}, + {4873, 1}, + {3572, 3893}, + {5044, 1}, + {4940, 1}, + {2192, 2416}, + {4922, 1}, + {413, 1}, + {0, 2793}, + {0, 1773}, + {0, 3271}, + {0, 121}, + {0, 3306}, + {0, 2824}, + {0, 1872}, + {0, 2233}, + {0, 1726}, + {0, 3540}, + {0, 49}, + {0, 3304}, + {0, 1743}, + {0, 2856}, + {0, 1644}, + {0, 1196}, + {0, 3928}, + {0, 459}, + {0, 3807}, + {0, 1398}, + {0, 2507}, + {0, 1591}, + {0, 3836}, + {0, 1082}, + {0, 921}, + {0, 1413}, + {0, 2391}, + {0, 1711}, + {0, 2215}, + {0, 1208}, + {0, 3559}, + {0, 891}, + {0, 2265}, + {0, 1438}, + {0, 2814}, + {0, 3321}, + {0, 344}, + {0, 3596}, + {0, 3050}, + {0, 3192}, + {3482, 551}, + {0, 2748}, + {0, 1457}, + {0, 2874}, + {0, 392}, + {0, 3326}, + {0, 95}, + {4907, 1}, + {3968, 1}, + {5112, 1}, + {2451, 1}, + {5037, 1}, + {4534, 1}, + {4956, 1}, + {406, 1}, + {4896, 1}, + {3235, 1}, + {5060, 1}, + {947, 1}, + {4988, 1}, + {4481, 1}, + {4948, 1}, + {1070, 1}, + {4921, 1}, + {4880, 1}, + {2950, 1}, + {2821, 1}, + {4930, 1}, + {2916, 1}, + {0, 2058}, + {0, 1300}, + {0, 1595}, + {0, 896}, + {0, 3203}, + {0, 772}, + {0, 2568}, + {0, 1346}, + {0, 2383}, + {0, 742}, + {0, 3677}, + {0, 1445}, + {0, 809}, + {0, 3649}, + {0, 90}, + {0, 551}, + {0, 1654}, + {0, 2251}, + {0, 1450}, + {0, 3569}, + {0, 904}, + {0, 2066}, + {0, 408}, + {0, 3354}, + {0, 1109}, {0, 3455}, - {0, 1261}, - {0, 486}, - {0, 3459}, - {0, 1783}, - {0, 1519}, - {0, 3227}, - {0, 1657}, - {0, 2439}, - {0, 3588}, - {0, 1405}, - {0, 3378}, - {0, 3254}, - {0, 1304}, - {0, 47}, - {0, 2585}, - {0, 2767}, - {0, 1919}, - {3270, 7}, - {987, 184}, - {3266, 191}, - {0, 3897}, - {4667, 1693}, - {225, 571}, - {898, 728}, - {4183, 2381}, - {1256, 2980}, - {3866, 2323}, - {3363, 3573}, - {0, 1553}, - {0, 366}, - {0, 2100}, - {0, 619}, - {0, 3021}, - {0, 2938}, - {0, 77}, - {0, 912}, - {0, 991}, - {0, 3010}, - {0, 2820}, - {0, 3744}, - {0, 3652}, - {0, 2221}, + {0, 1798}, + {0, 3012}, + {0, 2021}, + {0, 3484}, + {0, 447}, + {0, 1707}, + {0, 1123}, + {0, 3880}, + {0, 374}, + {0, 3757}, + {0, 1455}, + {0, 2451}, + {0, 1658}, + {0, 3790}, + {0, 1157}, + {0, 2743}, + {0, 3109}, + {0, 8}, + {0, 3684}, + {0, 273}, + {0, 2766}, + {0, 217}, + {0, 3206}, + {962, 196}, + {3695, 1923}, + {4754, 158}, + {2239, 57}, + {2528, 154}, + {2806, 1164}, + {1105, 169}, + {954, 119}, + {706, 167}, + {3688, 4}, + {964, 163}, + {2122, 115}, + {3816, 55}, + {4283, 22}, + {176, 157}, + {3101, 106}, + {3629, 160}, + {3468, 54}, + {1771, 139}, + {3624, 213}, + {980, 150}, + {3117, 2043}, + {1672, 1778}, + {1358, 2177}, + {4331, 158}, + {4642, 57}, + {4542, 154}, + {400, 278}, + {4633, 1651}, + {893, 873}, + {380, 169}, + {3889, 163}, + {4168, 55}, + {2389, 1181}, + {2185, 930}, + {2751, 2220}, + {2076, 1465}, + {1944, 160}, + {3710, 139}, + {4469, 213}, + {674, 2722}, + {322, 1281}, + {3277, 76}, + {3446, 682}, + {3641, 341}, + {1893, 583}, + {3438, 27}, + {4539, 697}, + {1625, 258}, + {2465, 167}, + {2734, 54}, + {3031, 213}, + {1183, 76}, + {855, 341}, + {985, 583}, + {3903, 351}, + {864, 697}, + {3156, 258}, + {3647, 1762}, + {525, 1042}, + {1748, 48}, + {4565, 3692}, + {4069, 888}, + {1225, 187}, + {3014, 2562}, + {2580, 1333}, + {2683, 866}, + {2152, 752}, + {2546, 788}, + {376, 311}, + {3417, 1827}, + {3033, 2790}, + {2203, 1286}, + {2466, 2727}, + {4123, 597}, + {3748, 3149}, + {3912, 329}, + {1003, 2691}, + {3721, 1931}, + {2326, 1249}, + {4027, 743}, + {4678, 3598}, + {261, 340}, + {527, 2639}, + {3616, 1476}, + {3085, 1725}, + {3258, 1258}, + {1468, 3708}, + {3089, 677}, + {3199, 2214}, + {118, 67}, + {887, 744}, + {4061, 3319}, + {3847, 915}, + {2190, 94}, + {4817, 1}, + {4810, 1}, + {2784, 3594}, + {1101, 1}, + {672, 1241}, + {4458, 1}, + {4718, 1404}, + {1852, 1}, + {1416, 864}, + {1617, 1}, + {3299, 1362}, + {1411, 1}, + {4030, 1728}, + {2327, 1}, + {1798, 3193}, + {3224, 1}, + {3574, 3308}, + {651, 1}, + {78, 2880}, + {216, 1}, + {4401, 3291}, + {70, 1}, + {3782, 1902}, + {2026, 1}, + {1478, 3246}, + {3521, 1}, + {3255, 3138}, + {285, 1}, + {425, 2723}, + {529, 1}, + {4668, 3116}, + {434, 1}, + {472, 2849}, + {3493, 1}, + {2958, 197}, + {2120, 1}, + {2396, 97}, + {4180, 1}, + {3675, 1745}, + {3844, 1}, + {914, 31}, + {3652, 1}, + {2646, 1831}, + {814, 1}, + {219, 3298}, + {4655, 1}, + {4391, 3204}, + {1569, 1}, + {1667, 2784}, + {1796, 1}, + {3536, 3168}, + {1687, 1}, + {3944, 1525}, + {2266, 1}, + {1926, 3839}, + {3339, 1}, + {3579, 3894}, + {564, 1}, + {106, 2631}, + {325, 1}, + {4433, 3925}, + {120, 1}, + {3198, 2120}, + {119, 1}, + {885, 3535}, + {4062, 1}, + {3846, 3396}, + {2193, 1}, + {2291, 2969}, + {2394, 1}, + {2973, 3424}, + {2263, 1}, + {3943, 2231}, + {2264, 1}, + {1924, 765}, + {3341, 1}, + {3578, 905}, + {566, 1}, + {110, 1463}, + {328, 1}, + {4432, 882}, + {117, 1}, + {1906, 825}, + {4715, 1}, + {3929, 2405}, + {728, 1}, + {1098, 2327}, + {2878, 1}, + {2702, 3617}, + {2537, 1}, + {2012, 2300}, + {2696, 1}, + {3496, 3054}, + {456, 1}, + {1192, 531}, + {3815, 1}, + {4109, 418}, + {2453, 1}, + {1996, 2007}, + {2091, 1}, + {2699, 359}, + {2005, 1}, + {766, 3240}, + {2540, 1}, + {3291, 1883}, + {1867, 1}, + {1621, 1823}, + {4375, 1}, + {4606, 162}, + {4713, 1}, + {686, 1783}, + {4600, 1}, + {2030, 1444}, + {3784, 1}, + {4393, 3646}, + {573, 1}, + {225, 3581}, + {3355, 1}, + {3381, 2258}, + {3571, 1}, + {1808, 3570}, + {3372, 1}, + {2332, 3384}, + {4017, 1}, + {4637, 2055}, + {198, 1}, + {601, 2171}, + {3611, 1}, + {3127, 579}, + {3252, 1}, + {1536, 2205}, + {3114, 1}, + {3159, 401}, + {143, 1}, + {976, 2988}, + {4126, 1}, + {3804, 3060}, + {2208, 1}, + {2222, 3515}, + {2421, 1}, + {2917, 3081}, + {2248, 1}, + {1153, 3430}, + {2862, 1}, + {3507, 1982}, + {1466, 1}, + {1845, 2115}, + {4710, 1}, + {4262, 515}, + {4373, 1}, + {278, 2139}, + {4219, 1}, + {1942, 1}, + {3707, 1}, + {4465, 1}, + {676, 1}, + {321, 1282}, + {3280, 2007}, + {0, 1253}, + {511, 3188}, + {3440, 1}, + {2951, 1717}, + {2114, 1}, + {2427, 1877}, + {4141, 1}, + {3678, 245}, + {3799, 1}, + {943, 1840}, + {3708, 1}, + {1945, 1215}, + {3709, 1}, + {4468, 2588}, + {675, 1}, + {323, 2466}, + {3278, 1}, + {3445, 3746}, + {3640, 1}, + {1892, 2495}, + {3439, 1}, + {4487, 2538}, + {1565, 1}, + {1962, 997}, + {2788, 1}, + {2548, 1077}, + {804, 1}, + {1215, 1600}, + {1032, 1}, + {3960, 1129}, + {1227, 1}, + {136, 91}, + {3181, 1}, + {2665, 2759}, + {2384, 1}, + {2146, 2852}, + {3882, 1}, + {3981, 3296}, + {4097, 1}, + {1222, 2877}, + {3969, 1}, + {2829, 2050}, + {1034, 1}, + {644, 3376}, + {4446, 1}, + {4732, 3441}, + {1794, 1}, + {1431, 3029}, + {1560, 1}, + {3334, 3459}, + {1439, 1}, + {4016, 3779}, + {2331, 1}, + {1847, 1581}, + {3270, 1}, + {3511, 1652}, + {666, 1}, + {12, 1173}, + {243, 1}, + {4356, 1681}, + {21, 1}, + {609, 141}, + {3633, 1}, + {2815, 2679}, + {2003, 1}, + {2251, 2832}, + {4056, 1}, + {3810, 3262}, + {3716, 1}, + {742, 2800}, + {3797, 1}, + {3905, 3177}, + {2179, 1}, + {1360, 1734}, + {3395, 1}, + {3121, 1854}, + {112, 1}, + {559, 264}, + {384, 1}, + {4525, 1836}, + {593, 1}, + {1876, 58}, + {4738, 1}, + {3951, 2742}, + {768, 1}, + {1054, 2878}, + {2900, 1}, + {2690, 3310}, + {2578, 1}, + {1982, 2853}, + {2652, 1}, + {0, 1135}, + {0, 2646}, + {0, 2529}, + {4170, 1}, + {4021, 1}, + {1167, 1}, + {4167, 1}, + {2460, 1}, + {4164, 1}, + {4543, 1}, + {86, 1}, + {388, 3070}, + {3488, 66}, + {3216, 3492}, + {3120, 353}, + {1324, 3106}, + {3244, 1947}, + {236, 3657}, + {3243, 2393}, + {2602, 1}, + {2308, 1}, + {2081, 1}, + {3676, 1}, + {4174, 1}, + {4022, 1}, + {2616, 1227}, + {840, 745}, + {260, 3604}, + {4681, 325}, + {4336, 3717}, + {1600, 1506}, + {3515, 1}, + {1652, 1}, + {2169, 1}, + {3920, 1}, + {4232, 1}, + {421, 1}, + {30, 1}, + {3211, 1}, + {3524, 549}, + {3426, 3418}, + {1646, 2117}, + {3517, 2978}, + {4652, 2684}, + {1832, 3194}, + {2360, 146}, + {2640, 3715}, + {2847, 1}, + {1073, 1}, + {986, 1}, + {839, 1}, + {3731, 1}, + {996, 1}, + {3637, 1}, + {615, 1}, + {1058, 2238}, + {3667, 1867}, + {3955, 2381}, + {2298, 1038}, + {2129, 3681}, + {1947, 792}, + {2569, 2346}, + {2141, 1354}, + {3720, 1}, + {2075, 1}, + {1519, 1}, + {3560, 1}, + {3248, 1}, + {362, 1}, + {4647, 2434}, + {377, 1242}, + {509, 3585}, + {3437, 2313}, + {2948, 1335}, + {2115, 2850}, + {3679, 1}, + {3800, 1}, + {940, 1}, + {3706, 1}, + {2599, 1}, + {865, 1}, + {244, 1}, + {4662, 1}, + {1613, 1070}, + {1848, 764}, + {1627, 1328}, + {2247, 2111}, + {1884, 1}, + {3292, 1}, + {3646, 1}, + {556, 1}, + {156, 1}, + {318, 1}, + {4480, 1}, + {144, 1}, + {3157, 1007}, + {141, 1501}, + {974, 2461}, + {4129, 2135}, + {3803, 2591}, + {2210, 754}, + {2223, 3889}, + {2423, 1067}, + {2915, 1}, + {2246, 1305}, + {3945, 1}, + {2245, 1569}, + {1883, 1}, + {3293, 2212}, + {3644, 1}, + {558, 137}, + {158, 1}, + {320, 1944}, + {4478, 1}, + {142, 1919}, + {1901, 1}, + {4731, 71}, + {1035, 1572}, + {2882, 2052}, + {2668, 1662}, + {2544, 1767}, + {1949, 1178}, + {2684, 111}, + {3433, 1677}, + {524, 2471}, + {1208, 1572}, + {3834, 2052}, + {4093, 1662}, + {2493, 1767}, + {1969, 1178}, + {2149, 111}, + {2677, 1677}, + {1953, 2471}, + {745, 855}, + {2550, 3572}, + {3350, 96}, + {1930, 1803}, + {1564, 823}, + {4390, 1439}, + {4553, 1374}, + {4727, 398}, + {631, 855}, + {4566, 3572}, + {2077, 96}, + {3722, 1803}, + {4371, 823}, + {548, 1439}, + {245, 1374}, + {3284, 398}, + {3408, 2027}, + {3506, 9}, + {1839, 445}, + {3418, 1715}, + {1541, 2078}, + {4338, 3011}, + {3746, 555}, + {1124, 2196}, + {845, 2027}, + {2508, 9}, + {3034, 445}, + {2843, 1715}, + {2350, 2078}, + {3046, 3011}, + {2930, 555}, + {1219, 2196}, + {499, 1}, + {4316, 1}, + {4571, 2952}, + {1678, 276}, + {1592, 3409}, + {3185, 1}, + {1552, 2113}, + {257, 3536}, + {3226, 3031}, + {2617, 2123}, + {2324, 1305}, + {2066, 276}, + {3661, 3318}, + {4151, 369}, + {4007, 3318}, + {1147, 1998}, + {4188, 3061}, + {1898, 3612}, + {4722, 2227}, + {3978, 1237}, + {1037, 1}, + {2884, 3801}, + {2666, 834}, + {2559, 1569}, + {1957, 1384}, + {2672, 2212}, + {952, 2227}, + {2675, 2789}, + {3142, 1826}, + {1696, 2280}, + {1442, 1}, + {4206, 1}, + {4751, 1}, + {4572, 3315}, + {1900, 1}, + {4724, 1}, + {3979, 2483}, + {793, 2104}, + {1038, 2570}, + {2883, 137}, + {2556, 1010}, + {1958, 2602}, + {2673, 1536}, + {3957, 1}, + {2255, 1}, + {1873, 1}, + {3288, 3331}, + {3636, 1}, + {552, 1}, + {164, 1}, + {314, 1}, + {4476, 982}, + {153, 3911}, + {1234, 257}, + {2920, 1919}, + {3451, 2866}, + {1413, 1327}, + {1741, 2246}, + {4497, 560}, + {138, 2778}, + {4484, 1833}, + {3317, 2180}, + {727, 1}, + {3930, 948}, + {3711, 3340}, + {2049, 1944}, + {2435, 2909}, + {2257, 71}, + {2824, 1833}, + {2415, 608}, + {4335, 3873}, + {2063, 291}, + {2893, 291}, + {396, 291}, + {3755, 1524}, + {215, 3558}, + {2175, 2}, + {2607, 2}, + {166, 2}, + {336, 1844}, + {649, 2364}, + {3170, 3642}, + {3356, 719}, + {2689, 2090}, + {2132, 183}, + {4596, 1124}, + {4292, 3464}, + {1385, 1791}, + {3464, 2260}, + {3165, 360}, + {77, 167}, + {4591, 265}, + {607, 350}, + {592, 1141}, + {3503, 387}, + {2869, 529}, + {2041, 1546}, + {2340, 567}, + {3924, 1248}, + {3896, 454}, + {3724, 109}, + {861, 1821}, + {3910, 22}, + {2653, 360}, + {968, 206}, + {147, 89}, + {4601, 21}, + {4302, 265}, + {1392, 350}, + {1889, 1141}, + {1781, 387}, + {3455, 529}, + {1869, 1546}, + {4161, 567}, + {2463, 1248}, + {1631, 454}, + {3074, 109}, + {3420, 1821}, + {272, 196}, + {25, 154}, + {4264, 157}, + {238, 212}, + {3239, 278}, + {241, 119}, + {870, 163}, + {4047, 115}, + {3727, 55}, + {1992, 22}, + {2454, 160}, + {2333, 80}, + {2858, 139}, + {1648, 1708}, + {749, 564}, + {3791, 3395}, + {427, 48}, + {3792, 806}, + {479, 93}, + {131, 3584}, + {3069, 1651}, + {3431, 1451}, + {89, 169}, + {765, 119}, + {113, 119}, + {2968, 2056}, + {187, 167}, + {751, 115}, + {268, 115}, + {76, 22}, + {313, 1965}, + {379, 160}, + {42, 397}, + {394, 54}, + {2919, 116}, + {1233, 1729}, + {502, 2697}, + {983, 67}, + {1585, 63}, + {4158, 163}, + {2473, 2563}, + {729, 158}, + {486, 154}, + {270, 154}, + {18, 187}, + {0, 884}, + {253, 55}, + {599, 157}, + {4237, 557}, + {3915, 3472}, + {1314, 956}, + {987, 1704}, + {46, 167}, + {3038, 2156}, + {175, 15}, + {1110, 583}, + {1276, 583}, + {1068, 15}, + {628, 571}, + {346, 57}, + {830, 57}, + {258, 4}, + {1252, 3428}, + {4013, 528}, + {1768, 1255}, + {4563, 736}, + {4098, 3601}, + {916, 332}, + {1214, 3730}, + {2997, 1481}, + {2552, 2426}, + {2659, 1261}, + {2121, 3705}, + {2588, 684}, + {710, 1841}, + {2586, 289}, + {3327, 3283}, + {1918, 798}, + {1590, 167}, + {4416, 1701}, + {4570, 2674}, + {4750, 1862}, + {639, 76}, + {4560, 240}, + {1766, 2497}, + {4561, 1102}, + {4096, 1054}, + {919, 212}, + {1212, 1170}, + {3001, 2261}, + {2554, 115}, + {2663, 48}, + {2119, 57}, + {2585, 55}, + {4071, 167}, + {2431, 1701}, + {1745, 2674}, + {3190, 1862}, + {3454, 76}, + {437, 240}, + {312, 2497}, + {163, 1102}, + {4301, 1054}, + {286, 212}, + {1050, 1170}, + {2810, 2261}, + {3643, 115}, + {1624, 48}, + {1878, 57}, + {4675, 55}, + {0, 3292}, + {2212, 3276}, + {4978, 1}, + {5018, 1}, + {4897, 1}, + {210, 1}, + {4648, 1}, + {1494, 1}, + {4477, 1}, + {4700, 1}, + {1834, 1}, + {4839, 1}, + {4989, 1}, + {5011, 1}, + {5097, 1}, + {201, 1}, + {5053, 1}, + {2914, 1}, + {4997, 1}, + {1092, 1}, + {4878, 1}, + {1703, 1}, + {4877, 1}, + {4113, 1}, + {2116, 2296}, + {2504, 1400}, + {2502, 2980}, + {3303, 2041}, + {4928, 1}, + {2393, 1}, + {4867, 1}, + {3842, 1}, + {5115, 1}, + {2746, 1}, + {4914, 1}, + {2956, 1}, + {4971, 1}, + {2595, 1}, + {4898, 1}, + {247, 1}, + {5082, 1}, + {5035, 1}, + {920, 1}, + {1213, 1}, + {3002, 1}, + {2553, 1}, + {2662, 1}, + {5095, 1}, + {4976, 1}, + {3735, 1}, + {2068, 1}, + {5092, 1}, + {5091, 1}, + {3232, 1}, + {341, 1}, + {4938, 1}, + {5113, 1}, + {5074, 1}, + {4905, 1}, + {629, 1}, + {4431, 1}, + {5030, 1}, + {5077, 1}, + {1440, 1}, + {1587, 1}, + {5022, 1}, + {4871, 1}, + {4291, 1}, + {1434, 1}, + {4937, 1}, + {4953, 1}, + {5059, 1}, + {5110, 1}, + {5108, 1}, + {5039, 1}, + {735, 1}, + {975, 1}, + {3814, 1}, + {717, 1}, + {5021, 1}, + {5026, 1}, + {4979, 1}, + {5090, 1}, + {2832, 1}, + {2411, 1}, + {4626, 1}, + {1858, 1}, + {3736, 1}, + {992, 1}, + {2767, 1}, + {994, 1}, + {2204, 952}, + {1384, 641}, + {2996, 206}, + {2181, 89}, + {2492, 21}, + {4094, 265}, + {3774, 350}, + {3885, 1141}, + {1019, 387}, + {3770, 529}, + {2535, 1546}, + {769, 3577}, + {350, 702}, + {4739, 3235}, + {4426, 804}, + {1502, 2548}, + {1709, 1390}, + {1908, 2309}, + {3588, 832}, + {1721, 3613}, + {4048, 3064}, + {2305, 3452}, + {1822, 540}, + {3245, 3769}, + {3547, 406}, + {626, 2848}, + {61, 2002}, + {196, 3093}, + {4385, 362}, + {85, 3538}, + {3077, 2499}, + {87, 3760}, + {1016, 953}, + {4165, 3474}, + {3884, 1126}, + {2144, 2298}, + {2316, 1642}, + {2494, 2546}, + {3011, 1079}, + {2310, 3837}, + {4049, 1937}, + {2307, 269}, + {1824, 2}, + {3242, 2}, + {3548, 2}, + {621, 2}, + {57, 2}, + {193, 2}, + {4387, 2}, + {88, 2}, + {1800, 2}, + {4680, 2}, + {4029, 2}, + {841, 2}, + {1126, 2}, + {2822, 2}, + {2735, 2}, + {2644, 2}, + {2050, 2}, + {2723, 2}, + {3376, 2}, + {420, 2}, + {1318, 3085}, + {3919, 593}, + {4142, 703}, + {2425, 1288}, + {2022, 1415}, + {2207, 1502}, + {2728, 994}, + {2047, 365}, + {815, 781}, + {2641, 1262}, + {3254, 2250}, + {1831, 827}, + {1475, 2369}, + {4473, 29}, + {4520, 3501}, + {4683, 117}, + {554, 2387}, + {4500, 1310}, + {1999, 1702}, + {3669, 536}, + {4422, 159}, + {616, 3062}, + {342, 305}, + {3231, 1945}, + {3499, 1889}, + {3601, 1873}, + {1936, 196}, + {3478, 158}, + {932, 48}, + {4051, 57}, + {4674, 154}, + {255, 187}, + {555, 169}, + {3642, 119}, + {3086, 167}, + {3276, 4}, + {1485, 163}, + {3079, 115}, + {3204, 55}, + {105, 22}, + {930, 157}, + {4102, 160}, + {3838, 397}, + {2187, 54}, + {2258, 80}, + {2387, 139}, + {2961, 213}, + {2287, 76}, + {1114, 150}, + {2896, 212}, + {3541, 19}, + {1510, 67}, + {1816, 196}, + {4746, 158}, + {4214, 48}, + {4412, 57}, + {232, 154}, + {4198, 187}, + {1983, 169}, + {3672, 119}, + {4438, 167}, + {633, 4}, + {364, 163}, + {3253, 115}, + {3491, 55}, + {3612, 22}, + {1931, 157}, + {3483, 160}, + {477, 397}, + {3484, 54}, + {2981, 80}, + {2151, 139}, + {2392, 213}, + {4169, 76}, + {3648, 150}, + {3835, 212}, + {892, 19}, + {3673, 67}, + {1985, 360}, + {3112, 1151}, + {4677, 326}, + {1810, 1292}, + {3531, 1224}, + {1354, 1671}, + {5063, 1}, + {0, 381}, + {0, 1564}, + {0, 3117}, + {0, 2888}, + {0, 1570}, + {0, 575}, + {0, 511}, + {0, 1334}, + {0, 2236}, + {0, 1679}, + {0, 3509}, + {0, 2581}, + {0, 293}, + {0, 1756}, + {0, 2594}, + {0, 3435}, + {0, 2999}, + {0, 3660}, + {0, 916}, + {0, 3764}, + {0, 1992}, + {0, 1035}, + {0, 2721}, + {0, 3284}, + {0, 1019}, + {0, 2093}, + {0, 2092}, + {0, 771}, + {0, 3553}, + {0, 1191}, + {0, 3069}, + {0, 3871}, + {0, 1899}, + {0, 101}, + {0, 3879}, + {0, 3001}, + {0, 667}, + {0, 2198}, + {0, 3008}, + {0, 1810}, + {0, 3593}, + {0, 2720}, + {0, 1037}, + {0, 1634}, + {0, 2732}, + {0, 3722}, + {0, 1297}, + {0, 546}, + {0, 3724}, + {0, 773}, + {0, 2796}, + {0, 862}, + {0, 2523}, + {0, 659}, + {0, 2165}, + {0, 1778}, + {0, 3149}, + {0, 2043}, + {0, 1042}, + {0, 2677}, + {0, 3373}, + {2206, 4}, + {3878, 76}, + {0, 1273}, + {0, 596}, + {0, 3487}, + {0, 2336}, + {0, 1560}, + {0, 3111}, + {0, 220}, + {0, 2460}, + {0, 3289}, + {0, 605}, + {0, 2382}, + {0, 1901}, + {0, 3815}, + {0, 2808}, + {0, 2088}, + {0, 3714}, + {0, 2843}, + {0, 1039}, + {0, 1849}, + {0, 3009}, + {0, 902}, + {0, 1353}, + {0, 3521}, + {0, 2264}, + {0, 1533}, + {0, 3195}, + {0, 2776}, + {0, 1190}, + {0, 1739}, + {0, 2934}, {0, 758}, - {0, 939}, - {0, 2691}, - {0, 2912}, - {0, 2896}, - {0, 837}, - {0, 1075}, - {0, 1949}, - {0, 1354}, - {0, 718}, - {0, 2317}, - {0, 2391}, - {0, 1148}, - {0, 446}, + {0, 507}, + {0, 2242}, + {0, 3503}, {0, 295}, - {0, 2345}, - {0, 2532}, - {0, 3296}, - {0, 2123}, - {0, 440}, - {0, 2990}, - {0, 3067}, - {0, 293}, - {0, 721}, - {0, 1145}, - {0, 3028}, + {0, 2587}, + {0, 3199}, + {0, 1694}, + {0, 84}, + {0, 3365}, + {0, 1309}, + {0, 233}, + {0, 2488}, + {0, 3322}, + {0, 625}, + {0, 2352}, {0, 2756}, - {0, 3907}, - {0, 2935}, - {0, 3443}, - {0, 2173}, - {0, 2099}, - {0, 3196}, + {0, 1163}, + {0, 1727}, + {0, 2905}, + {0, 785}, + {0, 1855}, + {0, 2757}, + {0, 2846}, {0, 3636}, - {0, 3809}, - {0, 2050}, - {0, 1966}, - {0, 1055}, - {0, 1112}, - {0, 1535}, - {0, 3824}, - {0, 3892}, - {0, 1434}, - {0, 1785}, - {0, 2176}, - {0, 3833}, - {0, 3592}, - {0, 3093}, - {0, 2747}, - {0, 3214}, - {0, 1953}, - {0, 1861}, - {0, 3419}, - {0, 3835}, - {0, 3619}, - {0, 1795}, - {0, 2207}, - {0, 737}, - {0, 1884}, - {0, 71}, - {0, 2788}, - {0, 2875}, - {0, 624}, - {0, 984}, - {0, 902}, - {0, 2800}, - {4757, 2}, - {4172, 1542}, - {1716, 2170}, - {4179, 1806}, - {116, 3608}, - {4373, 3860}, - {682, 2708}, - {3322, 3080}, - {1825, 2045}, - {4418, 2129}, - {3417, 622}, - {1088, 3605}, - {3426, 3842}, - {146, 1914}, - {2621, 1780}, - {2198, 1123}, - {4359, 2101}, - {605, 617}, - {2521, 3035}, - {3254, 2948}, - {2693, 89}, - {2190, 875}, - {4594, 1003}, - {923, 2993}, - {3684, 2833}, - {1125, 3737}, - {3996, 2559}, - {841, 3882}, - {3625, 1648}, - {2914, 1552}, - {3796, 3568}, - {1501, 3263}, - {3810, 3361}, - {403, 1610}, - {4709, 1399}, - {279, 388}, - {3240, 3773}, - {1761, 2569}, - {3718, 1157}, - {4404, 1073}, - {3476, 928}, - {1030, 115}, - {3448, 3014}, - {2140, 980}, - {2471, 941}, - {2273, 2061}, - {4564, 310}, - {197, 1856}, - {3065, 3165}, - {3486, 3230}, - {4355, 2128}, - {2113, 1597}, - {4372, 1050}, - {1018, 3267}, - {3644, 2107}, - {904, 2362}, - {383, 2403}, - {4286, 3611}, - {2353, 1247}, - {1614, 1015}, - {301, 3834}, - {2650, 3417}, - {323, 3219}, - {4015, 1443}, - {1152, 1495}, - {3911, 273}, - {4273, 927}, - {397, 1295}, - {2690, 3554}, - {3127, 3662}, - {4756, 1668}, - {2368, 2055}, - {4731, 1921}, - {839, 3701}, - {3830, 3768}, - {1210, 2794}, - {4399, 650}, - {561, 2069}, - {2507, 3342}, - {3248, 3466}, - {4622, 1923}, - {2232, 1282}, - {4605, 1671}, - {992, 3501}, - {3695, 3161}, - {1061, 2573}, - {2921, 3400}, - {1957, 3085}, - {4727, 582}, - {4043, 405}, - {2720, 2723}, - {356, 2428}, - {1637, 436}, - {3621, 242}, - {812, 1180}, - {871, 1731}, - {2958, 1043}, - {1334, 2361}, - {1601, 2588}, - {1079, 834}, - {3383, 147}, - {1060, 570}, - {4437, 2679}, - {4, 2258}, - {4606, 3433}, - {1399, 3167}, - {3455, 2899}, - {956, 256}, - {158, 24}, - {1780, 2909}, - {1610, 2689}, - {1151, 2218}, - {2555, 150}, - {2148, 527}, - {2941, 1274}, - {38, 346}, - {4521, 1833}, - {2076, 3117}, - {1329, 3239}, - {647, 2151}, - {2964, 1592}, - {634, 1394}, - {3740, 3301}, - {859, 3349}, - {4201, 2351}, - {1223, 3704}, - {3897, 2299}, - {1713, 676}, - {2465, 825}, - {738, 2600}, - {3160, 2976}, - {702, 2815}, - {4641, 929}, - {479, 994}, - {4262, 1881}, - {1275, 2360}, - {3440, 3553}, - {895, 961}, - {68, 1463}, - {1806, 3899}, - {4077, 3334}, - {1810, 3286}, - {2572, 1412}, - {2037, 1596}, - {3071, 331}, - {641, 2072}, - {4459, 651}, - {2303, 3039}, - {1884, 2911}, - {45, 23}, - {2580, 942}, - {3, 956}, - {4096, 2974}, - {1063, 2797}, - {3696, 3772}, - {3827, 3631}, - {1166, 2253}, - {3089, 784}, - {2653, 911}, - {4052, 2654}, - {4069, 2867}, - {353, 808}, - {4271, 1038}, - {489, 1980}, - {1155, 1385}, - {3833, 687}, - {1646, 2285}, - {2387, 2415}, - {3101, 409}, - {779, 344}, - {4718, 2376}, - {390, 2554}, - {4320, 3275}, - {1029, 2148}, - {3704, 398}, - {1782, 2962}, - {2238, 3086}, - {961, 343}, - {3242, 693}, - {927, 1179}, - {4593, 3053}, - {552, 2775}, - {4453, 3886}, - {1512, 2906}, - {3629, 3468}, - {848, 2192}, - {367, 2066}, - {1599, 1749}, - {1567, 3784}, - {2682, 2028}, - {1946, 1938}, - {2829, 1088}, - {4537, 1130}, - {20, 1500}, - {2962, 3802}, - {3388, 3920}, - {4471, 1465}, - {2083, 1751}, - {1095, 2197}, - {1126, 3854}, - {4105, 3613}, - {926, 3070}, - {3039, 2724}, - {2153, 3235}, - {4621, 1985}, - {4211, 1836}, - {2506, 3397}, - {148, 3858}, - {2476, 3596}, - {1749, 1761}, - {3446, 2181}, - {1310, 769}, - {4137, 1927}, - {857, 17}, - {3379, 2764}, - {3781, 653}, - {1336, 949}, - {3764, 933}, - {681, 2824}, - {4531, 3007}, - {114, 3672}, - {4336, 2375}, - {483, 3542}, - {2755, 1309}, - {3172, 1475}, - {4684, 3909}, - {2443, 3316}, - {4649, 3298}, - {767, 18}, - {3888, 1613}, - {1133, 299}, - {2977, 3724}, - {2041, 2275}, - {4495, 685}, - {4088, 854}, - {2615, 2622}, - {51, 2967}, - {2616, 2846}, - {1843, 918}, - {3428, 1012}, - {1370, 1874}, - {3774, 400}, - {1068, 1079}, - {3321, 3522}, - {2597, 3398}, - {4147, 1835}, - {1859, 1379}, - {4102, 1584}, - {88, 3328}, - {4454, 3273}, - {553, 2552}, - {720, 3351}, - {3973, 3031}, - {1445, 607}, - {1904, 497}, - {1206, 2772}, - {3524, 2354}, - {1235, 2548}, - {4295, 437}, - {235, 14}, - {4753, 1578}, - {3981, 2023}, - {709, 568}, - {3530, 3111}, - {2819, 2982}, - {2689, 1040}, - {3909, 587}, - {853, 828}, - {2459, 373}, - {1922, 1555}, - {3779, 1042}, - {1339, 564}, - {3769, 138}, - {687, 2225}, - {3290, 2648}, - {130, 3200}, - {3199, 829}, - {3871, 1302}, - {763, 3326}, - {936, 1376}, - {2772, 1622}, - {2227, 3284}, - {1771, 3168}, - {140, 2067}, - {2517, 1686}, - {129, 1291}, - {4186, 3136}, - {1009, 3091}, - {3768, 2324}, - {2300, 2594}, - {656, 1828}, - {646, 1572}, - {155, 957}, - {2073, 58}, - {1289, 1454}, - {2061, 3495}, - {3429, 1683}, - {1842, 1319}, - {3228, 628}, - {1023, 1498}, - {201, 1133}, - {1787, 2668}, - {348, 255}, - {962, 743}, - {2437, 111}, - {922, 468}, - {1764, 2468}, - {506, 2402}, - {3809, 2711}, - {324, 2920}, - {810, 2882}, - {781, 2185}, - {1553, 2062}, - {417, 3178}, - {2897, 3665}, - {393, 3726}, - {3801, 2020}, - {795, 1941}, - {3960, 1083}, - {2187, 2507}, - {2544, 3114}, - {591, 575}, - {1042, 387}, - {573, 1392}, - {4358, 2438}, - {41, 1035}, - {1751, 211}, - {3352, 1545}, - {951, 830}, - {2049, 872}, - {1403, 3585}, - {1032, 1734}, - {3469, 2027}, - {1008, 1973}, - {747, 3539}, - {132, 1360}, - {2804, 53}, - {2147, 2484}, - {733, 2881}, - {121, 1700}, - {2223, 3600}, - {3759, 542}, - {2230, 2743}, - {3265, 1544}, - {1400, 1457}, - {3373, 484}, - {4623, 3911}, - {481, 1641}, - {2510, 1311}, - {149, 1913}, - {2474, 2088}, - {1752, 3730}, - {3447, 84}, - {1311, 2699}, - {1992, 1897}, - {1039, 3044}, - {4075, 3182}, - {315, 1663}, - {2636, 1308}, - {1595, 3123}, - {3583, 3490}, - {1449, 2313}, - {4374, 3250}, - {597, 2706}, - {2545, 151}, - {3272, 361}, - {4583, 3108}, - {2203, 188}, - {4561, 2442}, - {3646, 509}, - {1693, 1214}, - {3157, 859}, - {1229, 2426}, - {499, 2294}, - {1491, 1025}, - {2537, 1995}, - {2420, 2625}, - {2637, 3095}, - {1643, 466}, - {1574, 122}, - {23, 2235}, - {4717, 583}, - {385, 178}, - {4318, 1709}, - {1687, 803}, - {485, 3512}, - {1222, 3382}, - {1924, 1816}, - {4342, 1398}, - {3566, 3337}, - {1118, 3266}, - {3094, 2013}, - {1330, 3729}, - {3032, 2358}, - {878, 1177}, - {1873, 2283}, - {4129, 2836}, - {2630, 974}, - {3020, 2120}, - {1247, 2526}, - {1357, 3560}, - {1657, 1660}, - {2395, 1483}, - {3178, 3307}, - {4668, 1576}, - {1930, 8}, - {239, 2755}, - {1053, 634}, - {4675, 960}, - {2419, 914}, - {3204, 2841}, - {1451, 2989}, - {1864, 3069}, - {2765, 435}, - {1065, 1037}, - {2019, 493}, - {2595, 283}, - {2236, 1485}, - {1881, 558}, - {3283, 660}, - {299, 3045}, - {642, 2923}, - {1325, 10}, - {3786, 932}, - {1321, 950}, - {2996, 2981}, - {4328, 3461}, - {1262, 1733}, - {3962, 1264}, - {788, 536}, - {3604, 1587}, - {1538, 1173}, - {4072, 1173}, - {587, 3710}, - {3028, 3755}, - {1376, 2063}, - {3218, 1889}, - {1847, 986}, - {1953, 2359}, - {4824, 2}, - {1136, 382}, - {4040, 318}, - {778, 1547}, - {3124, 700}, - {1603, 1288}, - {3839, 3549}, - {4274, 3651}, - {3599, 1681}, - {1173, 2065}, - {3592, 1932}, - {1972, 420}, - {2657, 3777}, - {2433, 2791}, - {1552, 3192}, - {3589, 2870}, - {804, 220}, - {326, 75}, - {1636, 2939}, - {4066, 2652}, - {1613, 2248}, - {2724, 193}, - {1980, 561}, - {2801, 1244}, - {3574, 1840}, - {4060, 2838}, - {4744, 2709}, - {3098, 410}, - {782, 1181}, - {3100, 696}, - {2895, 3037}, - {3449, 1589}, - {1406, 1175}, - {4608, 2469}, - {3220, 695}, - {3237, 406}, - {2193, 2519}, - {3037, 2357}, - {2091, 3345}, - {3789, 2684}, - {1204, 3787}, - {3137, 1515}, - {2704, 1684}, - {4011, 3660}, - {1565, 3170}, - {4023, 1736}, - {306, 1736}, - {4241, 458}, - {526, 458}, - {2271, 458}, - {2591, 458}, - {631, 1466}, - {1064, 1466}, - {2057, 1466}, - {4451, 1466}, - {2092, 1479}, - {3418, 1479}, - {1855, 1479}, - {3236, 1479}, - {554, 1210}, - {4401, 1210}, - {2221, 1210}, - {1762, 1210}, - {119, 1473}, - {2475, 1473}, - {150, 1473}, - {4169, 1473}, - {1022, 235}, - {3783, 235}, - {1840, 235}, - {3310, 235}, - {1057, 654}, - {624, 654}, - {1307, 654}, - {3762, 654}, - {1337, 9}, - {2975, 9}, - {2297, 9}, - {2505, 9}, - {1906, 1764}, - {2826, 1764}, - {218, 1764}, - {719, 1764}, - {2436, 1839}, - {4650, 1839}, - {2438, 1839}, - {3181, 1839}, - {1478, 724}, - {3603, 724}, - {684, 724}, - {4419, 724}, - {2261, 121}, - {1823, 121}, - {99, 121}, - {2620, 121}, - {49, 42}, - {4140, 42}, - {1093, 614}, - {3649, 614}, - {1298, 1174}, - {3391, 1174}, - {863, 3733}, - {25, 3733}, - {1852, 1380}, - {4107, 1380}, - {1857, 2144}, - {2607, 2144}, - {2088, 670}, - {3036, 670}, - {1790, 670}, - {3214, 670}, - {1021, 1564}, - {569, 1564}, - {1397, 1564}, - {3721, 1564}, - {1394, 1822}, - {3074, 1822}, - {2220, 1822}, - {2574, 1822}, - {3217, 1332}, - {1775, 1332}, - {3700, 1332}, - {4384, 1332}, - {3450, 659}, - {1004, 659}, - {3473, 112}, - {2106, 112}, - {2512, 112}, - {2295, 112}, - {3095, 2949}, - {1629, 2949}, - {3825, 2102}, - {4261, 2102}, - {3576, 2102}, - {1143, 2102}, - {3614, 1020}, - {1947, 1020}, - {2681, 1020}, - {2463, 1020}, - {4165, 426}, - {982, 426}, - {3483, 3015}, - {3060, 3015}, - {2768, 764}, - {1929, 764}, - {2886, 764}, - {2274, 764}, - {2583, 821}, - {628, 821}, - {1059, 1059}, - {2052, 1059}, - {4456, 157}, - {2096, 157}, - {3400, 2270}, - {1880, 2669}, - {3247, 2669}, - {285, 772}, - {4632, 772}, - {1895, 3557}, - {1435, 3557}, - {534, 1537}, - {2859, 1537}, - {520, 1537}, - {3906, 1537}, - {749, 2121}, - {4000, 2121}, - {1681, 2951}, - {3166, 2951}, - {1212, 500}, - {476, 500}, - {1453, 2264}, - {3891, 2264}, - {1484, 559}, - {2831, 559}, - {2461, 109}, - {2680, 109}, - {1868, 2284}, - {3286, 2284}, - {1077, 1225}, - {649, 1225}, - {1331, 1225}, - {1071, 1313}, - {1317, 1313}, - {2989, 1313}, - {2281, 97}, - {2486, 97}, - {3302, 97}, - {1863, 97}, - {3754, 3318}, - {4442, 1766}, - {3362, 1230}, - {3394, 1811}, - {2023, 3217}, - {2589, 2510}, - {2243, 2697}, - {3151, 136}, - {1702, 2171}, - {3887, 3141}, - {4321, 947}, - {3514, 1809}, - {1219, 1424}, - {3537, 1231}, - {1885, 3403}, - {2751, 2252}, - {2376, 2454}, - {4086, 31}, - {899, 2991}, - {3404, 448}, - {2976, 557}, - {3725, 2458}, - {1283, 2314}, - {3749, 1732}, - {623, 618}, - {4506, 32}, - {204, 1666}, - {1989, 1598}, - {2890, 1168}, - {300, 1521}, - {787, 1252}, - {2351, 520}, - {4741, 137}, - {2375, 421}, - {3128, 2561}, - {1562, 577}, - {3538, 1057}, - {211, 843}, - {4676, 231}, - {1910, 62}, - {1452, 207}, - {474, 3024}, - {2807, 1566}, - {496, 1191}, - {3854, 311}, - {734, 380}, - {4070, 678}, - {1536, 168}, - {3611, 1958}, - {789, 338}, - {305, 385}, - {1617, 2037}, - {4047, 442}, - {1633, 1254}, - {2706, 1290}, - {1998, 2339}, - {2818, 2242}, - {2225, 3599}, - {2496, 930}, - {549, 812}, - {996, 706}, - {2146, 952}, - {4396, 1016}, - {2173, 2263}, - {3485, 789}, - {1779, 39}, - {3319, 19}, - {369, 2256}, - {4685, 848}, - {1966, 1416}, - {1514, 1317}, - {453, 2855}, - {2932, 3446}, - {442, 3202}, - {3841, 243}, - {828, 99}, - {3936, 141}, - {1624, 386}, - {3104, 512}, - {1130, 2298}, - {376, 177}, - {1531, 209}, - {3835, 779}, - {1560, 1096}, - {2913, 323}, - {2378, 1850}, - {2753, 3158}, - {92, 1649}, - {4490, 2198}, - {2036, 1625}, - {1287, 1529}, - {686, 3565}, - {3005, 2595}, - {671, 3358}, - {3778, 1615}, - {893, 1381}, - {4162, 401}, - {4496, 1039}, - {73, 1738}, - {2978, 3875}, - {3406, 3752}, - {4410, 1230}, - {2027, 1965}, - {1058, 1811}, - {4097, 3633}, - {995, 2942}, - {4633, 136}, - {277, 1976}, - {2842, 2171}, - {3544, 3141}, - {4294, 2015}, - {1888, 1726}, - {4308, 1231}, - {1205, 3175}, - {3948, 3403}, - {844, 2252}, - {2578, 3310}, - {2289, 2748}, - {4441, 31}, - {3752, 275}, - {2934, 2991}, - {636, 448}, - {2967, 1958}, - {1278, 338}, - {3314, 442}, - {1784, 1254}, - {1182, 1290}, - {3811, 930}, - {1571, 812}, - {2311, 706}, - {818, 952}, - {3136, 39}, - {845, 19}, - {4734, 2256}, - {464, 2577}, - {4310, 2855}, - {1654, 3500}, - {3193, 2977}, - {1246, 386}, - {512, 579}, - {1420, 512}, - {3859, 2298}, - {1438, 2595}, - {2796, 664}, - {2414, 63}, - {2719, 1649}, - {436, 476}, - {4249, 2198}, - {2319, 1625}, - {1576, 3318}, - {347, 1766}, - {2698, 1477}, - {361, 1230}, - {4057, 1370}, - {1192, 3217}, - {3869, 2510}, - {975, 2697}, - {4177, 136}, - {1350, 1124}, - {2111, 947}, - {1040, 1809}, - {3489, 1424}, - {1050, 1231}, - {4383, 1036}, - {199, 31}, - {4512, 557}, - {1645, 2458}, - {3079, 2314}, - {1154, 1732}, - {410, 618}, - {1548, 1666}, - {3850, 1598}, - {1544, 1168}, - {2927, 1521}, - {2355, 1252}, - {2735, 520}, - {350, 1977}, - {4705, 137}, - {1943, 421}, - {1496, 2561}, - {435, 577}, - {2918, 1057}, - {463, 843}, - {3826, 62}, - {846, 207}, - {3950, 3024}, - {715, 1566}, - {3969, 1191}, - {1446, 311}, - {1907, 380}, - {1209, 678}, - {3520, 168}, - {1230, 385}, - {4292, 2037}, - {237, 2339}, - {4754, 2242}, - {3983, 3599}, - {711, 930}, - {3529, 812}, - {2814, 1016}, - {3912, 2263}, - {1486, 789}, - {3895, 39}, - {532, 1072}, - {4662, 848}, - {302, 1416}, - {4146, 1317}, - {854, 2855}, - {3374, 243}, - {2955, 99}, - {3775, 141}, - {1343, 386}, - {3771, 2118}, - {691, 177}, - {4527, 209}, - {127, 1223}, - {3197, 323}, - {1651, 1850}, - {3872, 3158}, - {4306, 1649}, - {3567, 2134}, - {1270, 1230}, - {3548, 1370}, - {1923, 136}, - {2776, 1124}, - {2323, 1231}, - {585, 1036}, - {4381, 31}, - {2228, 1346}, - {1772, 1252}, - {141, 1468}, - {2511, 1525}, - {128, 1536}, - {4182, 930}, - {1010, 812}, - {3770, 39}, - {2301, 386}, - {2561, 2118}, - {639, 1649}, - {1073, 2134}, - {2068, 1865}, - {4477, 1334}, - {2066, 1626}, - {3431, 228}, - {1836, 495}, - {3221, 2515}, - {1020, 2417}, - {3710, 3076}, - {1788, 534}, - {2245, 422}, - {964, 1794}, - {3231, 1867}, - {918, 2493}, - {4587, 508}, - {558, 261}, - {4445, 1506}, - {328, 1069}, - {4739, 851}, - {2003, 899}, - {1551, 1322}, - {416, 1259}, - {2901, 1964}, - {395, 1647}, - {3807, 1377}, - {793, 1888}, - {3957, 2926}, - {2183, 1525}, - {2541, 1117}, - {593, 2425}, - {1043, 2550}, - {2115, 767}, - {4356, 228}, - {2131, 495}, - {3442, 2515}, - {1755, 2417}, - {3356, 3076}, - {960, 534}, - {4200, 422}, - {1401, 1794}, - {2164, 1867}, - {1028, 2493}, - {3475, 508}, - {1011, 261}, - {4371, 1506}, - {123, 1069}, - {4526, 851}, - {3816, 899}, - {1178, 1322}, - {3142, 1259}, - {2712, 1964}, - {4025, 1647}, - {1596, 1377}, - {4008, 1888}, - {317, 2926}, - {4236, 1525}, - {515, 1117}, - {1188, 2425}, - {3803, 2550}, - {1568, 767}, - {2308, 1377}, - {816, 1888}, - {3138, 2926}, - {849, 1525}, - {4738, 1468}, - {462, 1536}, - {4313, 231}, - {1045, 1598}, - {3675, 1168}, - {1726, 1521}, - {2182, 1377}, - {970, 1888}, - {3264, 2926}, - {984, 231}, - {4602, 62}, - {619, 1108}, - {4436, 1108}, - {4099, 719}, - {983, 1845}, - {3063, 1845}, - {2126, 332}, - {4559, 2829}, - {4157, 2714}, - {2528, 416}, - {176, 1186}, - {2547, 699}, - {1757, 699}, - {3509, 3033}, - {1292, 3558}, - {4079, 2895}, - {909, 3173}, - {3412, 1777}, - {2985, 1934}, - {3731, 1934}, - {1277, 3781}, - {3744, 1978}, - {637, 1978}, - {4500, 811}, - {190, 811}, - {4299, 1467}, - {530, 751}, - {2763, 751}, - {3175, 2385}, - {4629, 456}, - {2398, 456}, - {4644, 266}, - {710, 266}, - {3876, 2509}, - {1203, 866}, - {2970, 866}, - {2048, 1203}, - {4535, 1203}, - {4126, 3714}, - {2579, 1748}, - {44, 2011}, - {2576, 1996}, - {1816, 1996}, - {3368, 3819}, - {1393, 2853}, - {3735, 3391}, - {1106, 3099}, - {3323, 417}, - {2603, 417}, - {4078, 1327}, - {1807, 2419}, - {4100, 620}, - {7, 474}, - {4434, 229}, - {618, 1357}, - {461, 1357}, - {4228, 715}, - {2331, 715}, - {1588, 1152}, - {359, 1152}, - {2717, 449}, - {349, 302}, - {4064, 2352}, - {1187, 2524}, - {3860, 3299}, - {4237, 3650}, - {451, 2227}, - {4689, 2681}, - {2327, 2904}, - {4728, 2892}, - {785, 831}, - {3817, 1080}, - {1273, 1942}, - {4354, 1942}, - {609, 2921}, - {2529, 489}, - {3262, 658}, - {4565, 2214}, - {2184, 2214}, - {4584, 2683}, - {920, 566}, - {3693, 185}, - {1121, 1698}, - {2884, 419}, - {2000, 2138}, - {4730, 3515}, - {4046, 3392}, - {2635, 1843}, - {310, 1390}, - {2688, 1590}, - {1575, 3319}, - {3608, 3280}, - {1488, 2545}, - {891, 2599}, - {4095, 3747}, - {1276, 1563}, - {2022, 1723}, - {1092, 3706}, - {3414, 3142}, - {1122, 3505}, - {4444, 1667}, - {97, 1327}, - {4585, 620}, - {1359, 11}, - {3503, 1933}, - {968, 3146}, - {173, 3177}, - {1723, 1285}, - {4163, 337}, - {1743, 1285}, - {2468, 3146}, - {2142, 3474}, - {3004, 2326}, - {58, 3247}, - {4507, 2710}, - {2024, 103}, - {1279, 337}, - {667, 2011}, - {2983, 1467}, - {690, 2433}, - {3772, 274}, - {1236, 1634}, - {3847, 90}, - {4341, 776}, - {472, 1432}, - {2737, 3638}, - {3159, 3572}, - {4670, 1540}, - {2460, 2168}, - {4665, 1802}, - {764, 3604}, - {3890, 3867}, - {1144, 2702}, - {4474, 507}, - {953, 1607}, - {4199, 1159}, - {1404, 1}, - {2167, 1272}, - {1033, 530}, - {3472, 289}, - {1003, 428}, - {4366, 2555}, - {137, 2372}, - {4529, 1}, - {1626, 1}, - {2366, 701}, - {797, 2496}, - {796, 25}, - {4713, 755}, - {391, 28}, - {4330, 1151}, - {1365, 725}, - {3493, 2768}, - {966, 1421}, - {169, 1328}, - {1719, 3807}, - {4171, 3441}, - {1753, 3193}, - {2473, 1271}, - {2133, 1724}, - {3010, 153}, - {586, 2084}, - {4382, 506}, - {2226, 2933}, - {2513, 793}, - {135, 818}, - {4185, 2703}, - {1005, 2703}, - {3765, 2703}, - {1759, 2703}, - {565, 25}, - {1390, 1607}, - {3698, 1159}, - {1402, 1}, - {2229, 530}, - {2584, 1272}, - {3235, 428}, - {1767, 289}, - {3720, 701}, - {4405, 755}, - {3478, 28}, - {1024, 1151}, - {3444, 725}, - {2134, 2768}, - {2477, 1421}, - {2265, 1269}, - {3112, 1619}, - {1618, 1141}, - {3846, 420}, - {4282, 2505}, - {3610, 723}, - {1164, 296}, - {3582, 447}, - {2638, 1251}, - {2421, 3317}, - {4178, 2651}, - {976, 3810}, - {3648, 3437}, - {584, 1702}, - {4558, 1234}, - {1928, 496}, - {238, 3429}, - {732, 3350}, - {2452, 1792}, - {4673, 1438}, - {2422, 1524}, - {3201, 3416}, - {1448, 3238}, - {3581, 2478}, - {321, 2401}, - {4742, 3612}, - {2010, 1246}, - {1555, 1348}, - {420, 1348}, - {2891, 3220}, - {388, 3220}, - {3821, 1441}, - {780, 1441}, - {3954, 276}, - {1480, 276}, - {3515, 906}, - {728, 906}, - {234, 906}, - {1700, 906}, - {3980, 69}, - {1684, 69}, - {2781, 806}, - {1920, 806}, - {2881, 806}, - {2288, 806}, - {2577, 1877}, - {655, 1877}, - {1083, 1358}, - {2100, 1358}, - {4465, 1358}, - {2046, 1358}, - {3437, 260}, - {1833, 260}, - {3210, 260}, - {245, 260}, - {4645, 166}, - {1892, 166}, - {1431, 166}, - {525, 166}, - {2832, 79}, - {527, 79}, - {3894, 79}, - {765, 79}, - {4024, 1061}, - {1695, 1061}, - {3156, 1061}, - {1232, 1061}, - {500, 1347}, - {1492, 1347}, - {3910, 1520}, - {1447, 1520}, - {2860, 554}, - {2423, 554}, - {2640, 1163}, - {2950, 1163}, - {2072, 306}, - {4516, 306}, - {4106, 306}, - {2558, 306}, - {24, 786}, - {2596, 786}, - {1801, 786}, - {3387, 786}, - {1415, 163}, - {2095, 163}, - {2938, 163}, - {34, 163}, - {872, 371}, - {2292, 371}, - {4545, 371}, - {2275, 371}, - {3340, 199}, - {1322, 199}, - {3458, 199}, - {1939, 199}, - {2795, 1453}, - {229, 1453}, - {726, 1453}, - {2445, 1453}, - {4681, 329}, - {2431, 329}, - {3195, 329}, - {1466, 329}, - {3596, 498}, - {695, 498}, - {4414, 498}, - {2256, 498}, - {1814, 609}, - {81, 609}, - {2627, 609}, - {64, 609}, - {4127, 127}, - {1101, 127}, - {3659, 127}, - {3120, 127}, - {1605, 787}, - {3837, 787}, - {4270, 787}, - {3598, 787}, - {1170, 221}, - {3595, 221}, - {1971, 221}, - {2654, 221}, - {2432, 189}, - {3921, 189}, - {1207, 189}, - {3162, 189}, - {2740, 328}, - {3972, 328}, - {1712, 328}, - {3963, 328}, - {276, 95}, - {4326, 95}, - {401, 95}, - {2672, 95}, - {2363, 352}, - {4288, 352}, - {3849, 2121}, - {2904, 2121}, - {412, 304}, - {2870, 304}, - {1520, 304}, - {3083, 304}, - {1672, 2287}, - {3474, 2287}, - {1382, 904}, - {4207, 904}, - {4614, 778}, - {3244, 778}, - {952, 2785}, - {3216, 2785}, - {1199, 289}, - {3132, 1368}, - {2695, 1269}, - {3993, 3317}, - {1579, 2651}, - {4039, 1619}, - {295, 1326}, - {4255, 755}, - {539, 28}, - {2898, 1141}, - {1986, 420}, - {4748, 1607}, - {4068, 2505}, - {2677, 327}, - {327, 707}, - {2655, 50}, - {1586, 222}, - {3594, 731}, - {1465, 432}, - {2365, 30}, - {2663, 800}, - {428, 167}, - {1169, 1077}, - {2015, 105}, - {4272, 637}, - {1982, 1272}, - {3640, 530}, - {1611, 723}, - {3147, 447}, - {2651, 296}, - {2380, 428}, - {4266, 3810}, - {3831, 181}, - {2879, 171}, - {389, 7}, - {2894, 101}, - {1508, 551}, - {3102, 184}, - {1697, 286}, - {2470, 29}, - {2244, 482}, - {4392, 68}, - {3711, 320}, - {3026, 268}, - {551, 134}, - {3034, 131}, - {1363, 485}, - {3243, 307}, - {1862, 191}, - {4691, 37}, - {363, 544}, - {2916, 198}, - {3626, 57}, - {4232, 107}, - {1945, 44}, - {4242, 162}, - {1145, 120}, - {4019, 5}, - {762, 793}, - {1296, 1251}, - {3393, 818}, - {861, 2398}, - {22, 25}, - {1849, 1064}, - {4104, 181}, - {1860, 171}, - {2605, 7}, - {2082, 101}, - {3033, 551}, - {921, 184}, - {4217, 286}, - {1392, 29}, - {2158, 482}, - {1012, 68}, - {3445, 320}, - {1025, 268}, - {4357, 134}, - {147, 131}, - {4533, 485}, - {2063, 307}, - {2954, 191}, - {6, 37}, - {855, 544}, - {2269, 198}, - {4530, 57}, - {2299, 107}, - {3325, 44}, - {1335, 162}, - {3480, 120}, - {1679, 5}, - {3170, 1151}, - {1216, 1150}, - {480, 725}, - {1460, 2312}, - {3889, 2803}, - {1477, 2988}, - {2847, 327}, - {2442, 153}, - {2676, 2084}, - {905, 1159}, - {4082, 3889}, - {1293, 1631}, - {2040, 1523}, - {1119, 3563}, - {3427, 3281}, - {1091, 3354}, - {4476, 1611}, - {52, 1391}, - {4560, 394}, - {2272, 1870}, - {2590, 98}, - {633, 2776}, - {1066, 2346}, - {2058, 602}, - {4455, 996}, - {2086, 871}, - {3422, 1097}, - {1858, 979}, - {3241, 2255}, - {2170, 2091}, - {3016, 632}, - {153, 1074}, - {948, 839}, - {2233, 65}, - {4617, 898}, - {2219, 983}, - {3268, 204}, - {1396, 61}, - {3370, 2943}, - {3029, 2658}, - {2161, 2254}, - {4600, 180}, - {4194, 403}, - {2467, 1233}, - {131, 290}, - {2519, 1863}, - {1724, 462}, - {3470, 244}, - {1338, 1530}, - {2882, 1614}, - {2006, 1349}, - {4737, 849}, - {4048, 692}, - {2646, 2387}, - {304, 2320}, - {2683, 2722}, - {1566, 741}, - {3613, 1116}, - {1481, 1793}, - {4361, 925}, - {604, 1293}, - {2523, 1321}, - {3259, 1672}, - {4556, 21}, - {2196, 631}, - {4592, 1922}, - {928, 3700}, - {3688, 3771}, - {1128, 2798}, - {1682, 13}, - {3165, 452}, - {1213, 1909}, - {478, 1771}, - {1455, 2511}, - {3892, 503}, - {1482, 269}, - {2833, 1503}, - {2466, 1165}, - {2684, 726}, - {1142, 1182}, - {3844, 1579}, - {1607, 1375}, - {2348, 1857}, - {784, 1384}, - {3093, 1837}, - {806, 2147}, - {4690, 3042}, - {425, 2329}, - {4339, 3025}, - {2424, 1504}, - {2747, 896}, - {482, 1127}, - {1220, 782}, - {1919, 2213}, - {4322, 1744}, - {1927, 1255}, - {3555, 550}, - {1694, 703}, - {3113, 1195}, - {1319, 461}, - {1827, 1762}, - {4124, 1472}, - {1882, 1488}, - {2604, 3399}, - {2094, 1990}, - {3051, 2036}, - {1663, 816}, - {2404, 1826}, - {754, 124}, - {3203, 860}, - {750, 1032}, - {4671, 390}, - {1921, 1200}, - {2813, 681}, - {205, 1220}, - {701, 1383}, - {2415, 3570}, - {4663, 3387}, - {1479, 1526}, - {3612, 241}, - {2103, 850}, - {2284, 2769}, - {4550, 2347}, - {2282, 2544}, - {3348, 444}, - {1312, 339}, - {3459, 1588}, - {2946, 2031}, - {4522, 3107}, - {4114, 2975}, - {2565, 152}, - {14, 838}, - {2586, 1054}, - {1795, 2910}, - {3397, 2871}, - {0, 2858}, - {0, 3204}, - {0, 1786}, - {0, 1873}, - {0, 3431}, - {0, 3823}, - {0, 3626}, - {0, 1955}, - {0, 2008}, - {0, 856}, - {0, 1423}, - {0, 781}, - {0, 2249}, - {0, 2332}, - {0, 1101}, - {0, 513}, - {0, 218}, - {0, 2404}, - {0, 2465}, - {0, 3252}, - {0, 801}, - {0, 1268}, - {0, 3603}, - {0, 3671}, - {0, 1695}, + {4702, 1405}, + {3898, 3775}, + {691, 1697}, + {2885, 688}, + {1307, 3906}, + {3285, 2179}, + {1177, 1095}, + {1334, 1510}, + {4211, 3114}, + {1981, 1104}, + {3683, 2024}, + {1217, 1636}, + {989, 133}, + {2605, 3143}, + {979, 512}, + {3631, 2642}, + {819, 3444}, + {1683, 1473}, + {4532, 657}, + {2275, 1220}, + {3936, 2514}, + {3009, 422}, + {2697, 3033}, + {790, 2169}, + {2693, 2706}, + {549, 666}, + {2572, 1796}, + {4579, 3753}, + {1702, 2673}, + {4009, 1806}, + {2352, 861}, + {2587, 1116}, + {2845, 1770}, + {1275, 2717}, + {2861, 1158}, + {173, 3944}, + {2982, 3010}, + {4411, 911}, + {1507, 1252}, + {3823, 3016}, + {2117, 1344}, + {2679, 3820}, + {3036, 2791}, + {1170, 1939}, + {3030, 2891}, + {308, 992}, + {2888, 2019}, + {4213, 3574}, + {1331, 2421}, + {3659, 2023}, + {2007, 1105}, + {2147, 1610}, + {2449, 179}, + {4023, 3123}, + {2456, 636}, + {4489, 2619}, + {2295, 3488}, + {75, 1437}, + {3107, 679}, + {767, 3480}, + {2533, 2535}, + {2551, 2536}, + {2877, 3232}, + {1239, 335}, + {2866, 3336}, + {130, 1530}, + {3018, 148}, + {4394, 2266}, + {1544, 3709}, + {3856, 453}, + {2089, 1609}, + {2615, 1011}, + {2809, 1860}, + {1230, 2845}, + {2816, 1989}, + {31, 3759}, + {2960, 523}, + {4445, 654}, + {1559, 1468}, + {3863, 2986}, + {2220, 2559}, + {843, 1491}, + {1066, 336}, + {2913, 3229}, + {1055, 494}, + {3106, 2500}, + {1194, 3367}, + {1607, 1326}, + {4491, 842}, + {2218, 3382}, + {3869, 2660}, + {259, 2465}, + {624, 3324}, + {3458, 191}, + {611, 3431}, + {2768, 1539}, + {474, 432}, + {2016, 2301}, + {3691, 3674}, + {1380, 435}, + {4205, 1683}, + {4682, 2130}, + {4435, 732}, + {1417, 3589}, + {4424, 1162}, + {2490, 3104}, + {4285, 3855}, + {2831, 1921}, + {1076, 36}, + {3413, 3846}, + {391, 2963}, + {4334, 2586}, + {4749, 3174}, + {1746, 104}, + {4741, 3495}, + {2168, 1700}, + {4618, 519}, + {2517, 2425}, + {748, 3552}, + {3103, 506}, + {52, 1551}, + {1601, 759}, + {1823, 2146}, + {4501, 3059}, + {1811, 1755}, + {3830, 3550}, + {1655, 2047}, + {852, 728}, + {2650, 1680}, + {182, 2777}, + {3138, 3668}, + {1639, 3892}, + {1445, 2752}, + {4461, 1744}, + {1453, 3074}, + {3996, 1203}, + {1611, 2114}, + {1184, 3729}, + {2938, 2221}, + {543, 2109}, + {3551, 1008}, + {1828, 1071}, + {1594, 1852}, + {4277, 2870}, + {1576, 1973}, + {4156, 3777}, + {1424, 2973}, + {1080, 699}, + {2827, 1423}, + {448, 1672}, + {3363, 3845}, + {3514, 2556}, + {3343, 3198}, + {152, 40}, + {3351, 872}, + {1253, 1664}, + {3208, 548}, + {3921, 2404}, + {2236, 3028}, + {4510, 559}, + {1671, 1584}, + {1650, 1583}, + {1433, 228}, + {4475, 1419}, + {1429, 395}, + {4011, 2484}, + {1604, 3411}, + {1198, 1279}, + {2932, 877}, + {533, 2332}, + {3568, 2557}, + {501, 3763}, + {43, 2879}, + {3218, 1824}, + {29, 2995}, + {2807, 1013}, + {218, 1999}, + {2487, 3610}, + {4194, 2380}, + {1938, 2012}, + {4696, 1198}, + {3467, 2506}, + {3111, 3251}, + {274, 304}, + {3119, 3355}, + {1061, 1493}, + {3257, 469}, + {4144, 2230}, + {2452, 3738}, + {4691, 487}, + {1939, 1647}, + {2923, 1540}, + {2763, 234}, + {859, 3297}, + {2774, 410}, + {635, 2468}, + {2643, 3422}, + {4494, 1232}, + {1643, 933}, + {3938, 3426}, + {2268, 2603}, + {2093, 3098}, + {2488, 665}, + {4039, 780}, + {2495, 3864}, + {4437, 2127}, + {2355, 1183}, + {6, 2825}, + {3088, 3165}, + {741, 1167}, + {2567, 1949}, + {2441, 1112}, + {2162, 44}, + {3753, 3212}, + {2177, 290}, + {4756, 586}, + {2031, 3514}, + {2002, 291}, + {0, 1311}, + {4805, 1}, + {2825, 3899}, + {1084, 3630}, + {1422, 1976}, + {4958, 1}, + {4962, 1}, + {401, 1}, + {5086, 1}, + {4709, 1}, + {4983, 1}, + {4136, 1}, + {5040, 1}, + {3042, 1}, + {5058, 1}, + {738, 1}, + {5050, 1}, + {585, 1}, + {4912, 1}, + {4612, 1}, + {4870, 1}, + {4036, 1}, + {4849, 1}, + {2470, 1}, + {5088, 1}, + {3713, 1}, + {5103, 1}, + {4657, 1}, + {4951, 1}, + {476, 1}, + {4833, 1}, + {2908, 1}, + {4829, 1}, + {2584, 1}, + {5087, 1}, + {2579, 1}, + {5009, 1}, + {1178, 1}, + {713, 1}, + {5083, 1}, + {726, 1}, + {3424, 1}, + {5042, 1}, + {1929, 1}, + {4730, 1}, + {5006, 1}, + {4149, 1}, + {2846, 1}, + {4977, 1}, + {937, 1}, + {2577, 1}, + {746, 1}, + {4764, 1}, + {1577, 270}, + {4159, 2355}, + {4862, 1}, + {1081, 1}, + {2835, 1047}, + {5054, 1}, + {4864, 1}, + {4239, 1}, + {4852, 1}, + {1872, 1}, + {4863, 1}, + {2058, 1}, + {4993, 1}, + {2694, 1}, + {5121, 1}, + {3267, 1}, + {5065, 1}, + {4333, 1}, + {5032, 1}, + {1744, 1}, + {5023, 1}, + {2167, 1}, + {4894, 1}, + {2514, 1}, + {4935, 1}, + {3102, 1}, + {4949, 1}, + {248, 1}, + {4994, 1}, + {3441, 1}, + {5017, 1}, + {483, 1}, + {4950, 1}, + {3699, 1}, + {4967, 1}, + {4203, 1}, + {4986, 1}, + {2719, 1}, + {957, 1}, + {5101, 1}, + {213, 1}, + {1335, 1}, + {4881, 1}, + {4734, 1}, + {1779, 1}, + {4840, 1}, + {1928, 1}, + {890, 1}, + {5071, 1}, + {205, 1}, + {3264, 1}, + {4887, 1}, + {4895, 1}, + {4826, 1}, + {5005, 1}, + {2506, 1}, + {755, 1}, + {1750, 1}, + {4611, 1}, + {2365, 1}, + {5104, 1}, + {2823, 1}, + {1203, 3755}, + {2576, 28}, + {372, 3096}, + {2711, 525}, + {4704, 1363}, + {1905, 56}, + {4147, 1395}, + {2481, 748}, + {3906, 2898}, + {4074, 2462}, + {2242, 820}, + {4059, 3101}, + {1534, 2037}, + {3932, 988}, + {3210, 734}, + {140, 1753}, + {2631, 978}, + {821, 2194}, + {2178, 1749}, + {2430, 908}, + {3972, 1212}, + {2444, 1446}, + {4359, 361}, + {2282, 1577}, + {92, 388}, + {3160, 2862}, + {827, 854}, + {2628, 554}, + {1361, 468}, + {1742, 1417}, + {4752, 572}, + {1757, 1049}, + {3750, 1971}, + {1909, 2550}, + {910, 30}, + {2657, 1917}, + {185, 1156}, + {3279, 3184}, + {3393, 556}, + {3193, 2571}, + {357, 1811}, + {3200, 1369}, + {1132, 796}, + {3316, 2149}, + {4090, 3302}, + {2374, 250}, + {4624, 2159}, + {1855, 969}, + {3122, 391}, + {3452, 373}, + {627, 1657}, + {3469, 241}, + {851, 20}, + {3600, 2611}, + {3828, 242}, + {2143, 1786}, + {4403, 2617}, + {1474, 3347}, + {111, 2695}, + {435, 3948}, + {3550, 1075}, + {452, 3633}, + {2518, 1766}, + {581, 704}, + {2172, 2966}, + {3880, 3469}, + {1579, 715}, + {4466, 1925}, + {561, 2200}, + {315, 664}, + {3143, 3614}, + {300, 1098}, + {3032, 3037}, + {127, 3910}, + {2269, 1879}, + {3983, 128}, + {1688, 3917}, + {4493, 2894}, + {385, 2931}, + {168, 3702}, + {3325, 829}, + {178, 3813}, + {2852, 2051}, + {349, 959}, + {2377, 2780}, + {4087, 3238}, + {1809, 968}, + {4673, 2160}, + {4526, 589}, + {4306, 1267}, + {1549, 2307}, + {4290, 1628}, + {2328, 3453}, + {4452, 2653}, + {2965, 198}, + {594, 688}, + {281, 1104}, + {3182, 1394}, + {294, 2522}, + {3065, 480}, + {96, 1500}, + {2279, 349}, + {3948, 2798}, + {1668, 1510}, + {4515, 587}, + {850, 746}, + {1047, 2138}, + {2931, 3055}, + {1063, 1636}, + {3419, 1477}, + {3154, 318}, + {301, 3242}, + {3144, 474}, + {1162, 2521}, + {3287, 3353}, + {4131, 1312}, + {2419, 860}, + {4666, 3360}, + {1815, 2672}, + {389, 1029}, + {162, 1875}, + {3329, 2837}, + {181, 2003}, + {2854, 3748}, + {345, 2994}, + {2380, 672}, + {4092, 1458}, + {1812, 3003}, + {4676, 3876}, + {1274, 3810}, + {934, 2817}, + {2590, 1890}, + {953, 2927}, + {3530, 935}, + {764, 2067}, + {1718, 3571}, + {4547, 2436}, + {2300, 2076}, + {4052, 1131}, + {3883, 623}, + {2289, 2335}, + {4114, 1598}, + {1493, 3490}, + {3958, 2623}, + {3155, 230}, + {90, 1781}, + {2594, 2615}, + {875, 3342}, + {4166, 3933}, + {3806, 2686}, + {1960, 1817}, + {3818, 3015}, + {1841, 1149}, + {3665, 2163}, + {3475, 3670}, + {513, 2295}, + {2905, 2157}, + {1111, 957}, + {2385, 1247}, + {2211, 634}, + {3772, 3443}, + {2217, 175}, + {4706, 2284}, + {2069, 3159}, + {371, 1552}, + {3378, 1114}, + {1057, 3153}, + {2814, 2431}, + {2055, 2670}, + {2256, 3132}, + {4060, 165}, + {2243, 3450}, + {4218, 1627}, + {2404, 607}, + {339, 2386}, + {3359, 3592}, + {1024, 602}, + {2726, 1478}, + {2174, 453}, + {2433, 313}, + {2747, 3896}, + {2945, 2709}, + {1039, 1780}, + {2934, 3034}, + {242, 1097}, + {2804, 2186}, + {4321, 3648}, + {1446, 2338}, + {3780, 2192}, + {2021, 998}, + {2082, 999}, + {2226, 1912}, + {4099, 2816}, + {2235, 2034}, + {4260, 3824}, + {2369, 2908}, + {355, 28}, + {3322, 1363}, + {1012, 748}, + {2740, 2462}, + {4568, 2194}, + {4241, 1749}, + {1527, 1446}, + {4227, 1577}, + {2237, 388}, + {4392, 854}, + {3021, 554}, + {1254, 468}, + {3589, 1417}, + {690, 572}, + {1759, 2917}, + {1346, 3742}, + {4352, 803}, + {1362, 3838}, + {3963, 2025}, + {1477, 1002}, + {1292, 2746}, + {3052, 3256}, + {688, 995}, + {3597, 2185}, + {2445, 1970}, + {2160, 929}, + {3757, 3650}, + {2182, 1064}, + {4757, 2950}, + {2027, 3788}, + {432, 1784}, + {1074, 688}, + {2800, 1104}, + {2710, 1394}, + {2987, 2522}, + {1137, 86}, + {2994, 3494}, + {361, 1692}, + {2849, 512}, + {4242, 2433}, + {1365, 1796}, + {3685, 523}, + {1974, 842}, + {2929, 1326}, + {2762, 654}, + {863, 2332}, + {2777, 1158}, + {637, 1989}, + {2639, 3850}, + {4499, 1927}, + {1647, 59}, + {3940, 3859}, + {2271, 2970}, + {1298, 3185}, + {905, 2595}, + {2523, 1656}, + {922, 2272}, + {3558, 12}, + {739, 1344}, + {1736, 3351}, + {4605, 3086}, + {2357, 1357}, + {4002, 251}, + {709, 565}, + {1180, 1315}, + {3027, 2262}, + {1166, 1665}, + {3135, 480}, + {1315, 1500}, + {1469, 349}, + {4377, 1142}, + {2111, 1294}, + {3827, 3397}, + {946, 3427}, + {1262, 2360}, + {2857, 1456}, + {1268, 2464}, + {3332, 400}, + {1131, 1548}, + {1363, 3163}, + {4244, 2842}, + {2011, 1554}, + {3654, 522}, + {3786, 2097}, + {4189, 778}, + {2335, 3565}, + {4171, 1200}, + {1558, 3073}, + {4058, 3882}, + {3080, 1886}, + {32, 88}, + {2536, 3869}, + {758, 2992}, + {756, 2991}, + {1148, 3656}, + {3061, 909}, + {1159, 3758}, + {3178, 1981}, + {1281, 1021}, + {1486, 2729}, + {4343, 3290}, + {2088, 1032}, + {3860, 2099}, + {2759, 3526}, + {2925, 2222}, + {1053, 1347}, + {2910, 2561}, + {264, 568}, + {2787, 1659}, + {4330, 3259}, + {1430, 2753}, + {3769, 1661}, + {2040, 386}, + {988, 1101}, + {1218, 2885}, + {2817, 687}, + {1231, 1110}, + {3229, 2022}, + {1090, 1093}, + {1395, 2861}, + {4289, 1845}, + {2044, 1106}, + {3766, 1020}, + {44, 1979}, + {496, 751}, + {3638, 2388}, + {507, 1176}, + {2611, 1221}, + {658, 2525}, + {2107, 1941}, + {3795, 24}, + {1459, 3374}, + {4420, 1480}, + {4518, 496}, + {4319, 2247}, + {1618, 223}, + {4325, 504}, + {2319, 1557}, + {4454, 414}, + {2941, 255}, + {1181, 3286}, + {3501, 403}, + {595, 1696}, + {4240, 1954}, + {4567, 914}, + {1875, 912}, + {4586, 1051}, + {2060, 2593}, + {4707, 3088}, + {2695, 1763}, + {966, 253}, + {3269, 3771}, + {202, 2144}, + {1408, 1166}, + {1680, 2475}, + {4669, 1568}, + {1689, 2370}, + {3655, 244}, + {1843, 1448}, + {984, 3478}, + {2733, 2945}, + {303, 1435}, + {3336, 5}, + {1829, 396}, + {1593, 1467}, + {4275, 2351}, + {1575, 1578}, + {4157, 3399}, + {1425, 2493}, + {1079, 136}, + {2828, 1859}, + {450, 2489}, + {3364, 3524}, + {1640, 3520}, + {1444, 2278}, + {4460, 1306}, + {1451, 2607}, + {3998, 530}, + {1612, 1705}, + {1182, 3241}, + {2940, 2762}, + {544, 1695}, + {3553, 405}, + {3406, 1984}, + {3183, 869}, + {283, 3678}, + {3162, 1006}, + {1142, 2993}, + {3306, 3743}, + {4118, 1805}, + {2447, 221}, + {4687, 3752}, + {1791, 3075}, + {1854, 3076}, + {1551, 3587}, + {4307, 733}, + {1574, 3890}, + {4193, 2102}, + {1400, 1218}, + {1087, 2801}, + {2808, 3202}, + {418, 1211}, + {3390, 1983}, + {1863, 642}, + {1539, 1251}, + {4229, 2322}, + {1529, 1616}, + {4070, 3473}, + {1393, 2638}, + {1113, 259}, + {2874, 1769}, + {492, 2633}, + {3474, 3332}, + {4748, 2131}, + {4337, 731}, + {1357, 3588}, + {4347, 1161}, + {2446, 3102}, + {4202, 3853}, + {2898, 1922}, + {1143, 38}, + {3477, 3849}, + {485, 2964}, + {3966, 3043}, + {3744, 3599}, + {2173, 710}, + {3752, 3903}, + {1749, 2211}, + {3876, 1085}, + {3540, 2863}, + {586, 3130}, + {2969, 1078}, + {1188, 2028}, + {779, 1490}, + {1125, 339}, + {3000, 3230}, + {1141, 495}, + {3197, 2502}, + {1259, 3368}, + {1511, 1325}, + {4409, 840}, + {2140, 3381}, + {3802, 2657}, + {1067, 2906}, + {842, 3728}, + {2772, 800}, + {856, 3831}, + {3462, 2016}, + {1013, 990}, + {1814, 2754}, + {4629, 3260}, + {2370, 1000}, + {4133, 2193}, + {2909, 323}, + {2510, 1479}, + {921, 2540}, + {2521, 1367}, + {439, 3274}, + {2655, 2396}, + {4747, 558}, + {1912, 2039}, + {4152, 2403}, + {2472, 3131}, + {2681, 3333}, + {3035, 2430}, + {1169, 1383}, + {3029, 2537}, + {309, 461}, + {2889, 1517}, + {4212, 3173}, + {1333, 2834}, + {3660, 1523}, + {2008, 635}, + {2589, 581}, + {2844, 1264}, + {1273, 2290}, + {2860, 1623}, + {174, 3448}, + {2984, 2647}, + {4410, 202}, + {1508, 1822}, + {3825, 2658}, + {2118, 3380}, + {1967, 2935}, + {2346, 3707}, + {4175, 849}, + {2337, 3817}, + {4288, 2053}, + {2482, 965}, + {231, 2775}, + {3230, 3225}, + {898, 951}, + {2709, 2153}, + {2660, 2152}, + {3044, 685}, + {1157, 3603}, + {3056, 1118}, + {298, 3021}, + {2906, 3923}, + {4197, 1834}, + {1340, 180}, + {3668, 3929}, + {1994, 2936}, + {3916, 3471}, + {4065, 2286}, + {2253, 1289}, + {4073, 2622}, + {1545, 638}, + {3923, 1599}, + {3205, 3307}, + {129, 2696}, + {2623, 1590}, + {829, 458}, + {2164, 3099}, + {2440, 3564}, + {3956, 779}, + {2434, 3863}, + {4346, 2125}, + {2290, 1182}, + {104, 2826}, + {3177, 3166}, + {832, 1169}, + {2621, 1951}, + {1348, 2206}, + {1755, 675}, + {4745, 3622}, + {1747, 1111}, + {3740, 3041}, + {1915, 2053}, + {931, 1870}, + {2669, 113}, + {194, 3907}, + {3271, 2889}, + {3382, 2504}, + {3201, 3252}, + {343, 306}, + {3189, 3356}, + {1118, 1494}, + {3331, 471}, + {4100, 2229}, + {2390, 3736}, + {4632, 485}, + {1846, 833}, + {3109, 2014}, + {2708, 833}, + {617, 3704}, + {3461, 975}, + {837, 2904}, + {3607, 346}, + {3839, 1724}, + {2153, 346}, + {4415, 3822}, + {1463, 3049}, + {98, 2}, + {445, 2526}, + {3534, 1513}, + {436, 2045}, + {2501, 320}, + {591, 2}, + {2186, 3539}, + {3891, 2896}, + {1591, 1388}, + {4457, 118}, + {574, 464}, + {302, 1409}, + {3149, 2125}, + {310, 1529}, + {3039, 3335}, + {121, 2543}, + {2259, 52}, + {3975, 1935}, + {1679, 2152}, + {4502, 3467}, + {373, 3449}, + {180, 2329}, + {3313, 2}, + {161, 2668}, + {2839, 584}, + {360, 1639}, + {2388, 3301}, + {4103, 2712}, + {1821, 1646}, + {4661, 486}, + {4536, 2059}, + {4294, 805}, + {1573, 3741}, + {4304, 941}, + {2342, 2940}, + {4442, 3802}, + {2962, 1741}, + {1223, 301}, + {3561, 3797}, + {537, 3024}, + {584, 3025}, + {293, 3631}, + {3173, 644}, + {287, 3943}, + {3053, 2155}, + {108, 1139}, + {2288, 2857}, + {3961, 3151}, + {1673, 1150}, + {4509, 2057}, + {2936, 3548}, + {2755, 3080}, + {872, 2105}, + {2748, 2760}, + {645, 749}, + {2630, 1740}, + {4516, 3803}, + {1634, 2610}, + {3931, 1746}, + {2280, 932}, + {1211, 2289}, + {997, 3477}, + {0, 2342}, + {0, 378}, + {0, 1432}, + {0, 2626}, + {0, 239}, + {0, 3505}, + {0, 2240}, + {0, 1487}, + {0, 3207}, + {0, 3685}, + {0, 1990}, + {0, 919}, + {0, 3941}, + {0, 1846}, + {0, 723}, + {0, 3068}, + {0, 3554}, + {0, 950}, + {0, 2767}, + {0, 3719}, + {0, 2083}, + {0, 859}, + {0, 2432}, + {0, 1693}, + {0, 3239}, + {0, 2678}, + {0, 673}, + {0, 1782}, + {0, 2951}, + {0, 695}, + {0, 1225}, + {0, 3446}, + {0, 2292}, + {0, 1542}, + {0, 3147}, + {0, 3938}, + {2836, 1421}, + {1210, 928}, + {0, 3164}, + {0, 1555}, + {0, 527}, + {0, 2244}, + {0, 3519}, + {0, 286}, + {0, 2585}, + {0, 2541}, + {0, 3273}, + {0, 561}, + {0, 2406}, + {0, 1874}, + {0, 3772}, + {0, 2864}, + {0, 2209}, + {0, 3662}, + {0, 2829}, + {0, 972}, + {0, 1920}, + {0, 3103}, + {0, 824}, + {0, 1231}, + {0, 3456}, + {0, 2299}, + {0, 1538}, + {0, 3139}, + {0, 2685}, + {0, 1107}, + {0, 1789}, + {0, 2946}, + {0, 680}, + {0, 643}, + {0, 2320}, + {0, 3475}, + {0, 256}, + {0, 2632}, + {0, 3133}, + {0, 122}, + {3854, 122}, + {0, 1416}, + {0, 2448}, {0, 2046}, - {0, 1940}, - {0, 3640}, - {0, 3780}, - {0, 2901}, - {0, 3409}, - {0, 3074}, - {0, 531}, - {0, 423}, - {0, 2735}, - {0, 2412}, - {0, 2500}, + {0, 2441}, + {0, 2705}, + {0, 1140}, + {0, 1807}, + {0, 2987}, + {0, 1004}, + {0, 866}, + {0, 2107}, + {0, 3733}, + {0, 433}, + {0, 1471}, + {0, 2644}, + {0, 201}, + {0, 3739}, + {0, 2061}, + {0, 845}, + {0, 3886}, + {0, 1906}, + {0, 934}, + {0, 2984}, + {0, 873}, + {0, 1333}, + {0, 1626}, + {0, 311}, + {0, 2847}, + {0, 3546}, + {0, 2790}, + {0, 2579}, + {0, 1668}, + {0, 34}, + {0, 3337}, + {0, 1338}, + {0, 725}, + {0, 3067}, + {0, 3557}, + {0, 947}, + {0, 2765}, + {0, 340}, + {0, 2601}, + {0, 3187}, + {0, 3506}, + {0, 532}, + {0, 2445}, + {0, 543}, + {0, 1316}, + {0, 3493}, + {0, 2219}, + {0, 1503}, + {0, 3222}, + {0, 2362}, + {0, 354}, + {697, 80}, + {2731, 48}, + {517, 187}, + {1943, 397}, + {0, 2481}, + {3194, 2056}, + {3394, 1953}, + {4173, 527}, + {2458, 755}, + {2986, 773}, + {2715, 2091}, + {2100, 3434}, + {0, 260}, + {0, 1336}, + {0, 1337}, {0, 510}, - {0, 259}, - {0, 1511}, - {0, 3567}, - {0, 1851}, - {0, 2156}, - {0, 679}, - {0, 884}, + {0, 3534}, + {0, 13}, + {0, 2274}, + {0, 3169}, + {0, 1520}, + {0, 1187}, + {0, 3179}, + {0, 2368}, + {0, 2694}, + {0, 3949}, + {0, 1074}, + {0, 3634}, + {0, 1765}, + {0, 705}, + {0, 2965}, + {0, 3470}, + {0, 716}, + {0, 1924}, + {0, 3167}, + {0, 2578}, + {0, 1667}, + {0, 2257}, + {0, 33}, + {0, 1330}, + {0, 3339}, + {0, 3100}, {0, 1339}, - {0, 3562}, - {0, 3627}, - {0, 1629}, - {0, 2106}, - {0, 1872}, - {0, 3693}, - {0, 3728}, - {0, 2842}, - {0, 2995}, - {0, 3485}, - {0, 2122}, - {0, 2034}, - {0, 3153}, - {0, 3686}, - {0, 3764}, - {0, 2104}, - {0, 1915}, - {0, 959}, - {0, 2169}, - {0, 519}, - {0, 2945}, - {0, 3023}, - {0, 200}, - {0, 777}, - {0, 1090}, - {0, 3082}, - {0, 2700}, - {0, 3870}, - {0, 2631}, - {0, 3818}, - {0, 2873}, - {0, 3804}, - {0, 3057}, - {0, 3322}, - {0, 2083}, - {0, 2212}, - {0, 3303}, - {0, 3533}, + {0, 271}, + {0, 114}, + {0, 1622}, + {0, 2628}, + {0, 1263}, + {0, 3128}, + {0, 2318}, + {0, 363}, + {0, 2207}, + {0, 2325}, + {0, 3277}, + {0, 3737}, + {0, 2907}, + {0, 2062}, + {0, 2804}, + {0, 846}, + {0, 1911}, + {0, 3885}, + {0, 2505}, + {0, 1905}, + {0, 651}, + {0, 345}, + {0, 1504}, + {0, 2539}, + {0, 1386}, + {0, 3258}, + {0, 2419}, + {0, 570}, + {0, 2013}, + {0, 2408}, + {0, 3110}, + {0, 2899}, + {0, 3726}, + {0, 821}, + {0, 3828}, + {0, 2038}, + {0, 987}, + {0, 2735}, + {0, 3270}, + {0, 977}, + {0, 2195}, + {0, 1934}, + {0, 945}, + {0, 3835}, + {0, 808}, + {0, 2836}, + {0, 3694}, + {0, 2121}, + {0, 463}, + {4758, 1}, + {3907, 1086}, + {1704, 2210}, + {801, 1583}, + {2573, 2315}, + {63, 2199}, + {3092, 973}, + {4449, 1265}, + {1677, 586}, + {4665, 120}, + {2101, 2332}, + {4530, 3118}, + {2619, 1563}, + {816, 1091}, + {3146, 3107}, + {165, 2415}, + {4538, 2621}, + {4272, 3144}, + {1597, 147}, + {4282, 3465}, + {2366, 1615}, + {4429, 621}, + {2970, 2349}, + {1200, 3628}, + {3543, 617}, + {551, 1531}, + {4646, 1482}, + {4467, 324}, + {1438, 3247}, + {4455, 483}, + {2461, 2530}, + {4322, 3359}, + {2803, 1304}, + {1045, 852}, + {3370, 3357}, + {433, 2669}, + {598, 3947}, + {291, 2693}, + {3174, 1794}, + {297, 3022}, + {3057, 1117}, + {95, 1065}, + {2281, 3683}, + {3950, 2287}, + {1663, 2178}, + {4519, 943}, + {4523, 944}, + {4296, 1926}, + {1563, 2809}, + {4287, 2054}, + {2338, 3816}, + {4453, 2925}, + {2964, 728}, + {1232, 1408}, + {1465, 2919}, + {528, 3945}, + {3422, 769}, + {3150, 2087}, + {304, 3094}, + {1697, 1713}, + {1165, 3580}, + {3286, 2734}, + {4134, 986}, + {2426, 1670}, + {4670, 2603}, + {1819, 3664}, + {383, 1284}, + {170, 606}, + {3326, 3460}, + {179, 140}, + {2851, 2319}, + {348, 3129}, + {2378, 1576}, + {4086, 1088}, + {1807, 3134}, + {4672, 2400}, + {1269, 2273}, + {938, 3502}, + {2583, 553}, + {948, 3180}, + {3527, 1329}, + {770, 32}, + {1714, 2553}, + {4545, 3857}, + {2296, 53}, + {4050, 1429}, + {3886, 1838}, + {4107, 1055}, + {2293, 3765}, + {4116, 918}, + {1499, 2858}, + {3949, 3675}, + {93, 426}, + {2596, 3671}, + {876, 77}, + {4163, 2356}, + {1168, 853}, + {1956, 384}, + {1420, 3316}, + {1840, 1449}, + {3670, 243}, + {3472, 2613}, + {510, 3782}, + {2903, 236}, + {1109, 1349}, + {2383, 1066}, + {2213, 1848}, + {3768, 2873}, + {2215, 1969}, + {4703, 3773}, + {2072, 653}, + {369, 706}, + {3374, 1419}, + {1052, 2957}, + {2811, 3852}, + {2057, 188}, + {2250, 3000}, + {4063, 1957}, + {2244, 2884}, + {4223, 885}, + {2403, 1876}, + {340, 3908}, + {3362, 2477}, + {1027, 1871}, + {2729, 770}, + {2180, 753}, + {2429, 2142}, + {3970, 3063}, + {2443, 1344}, + {4360, 3549}, + {2283, 2782}, + {91, 960}, + {3161, 1676}, + {828, 2773}, + {2629, 3672}, + {2749, 2374}, + {2943, 3391}, + {1040, 422}, + {2935, 3287}, + {246, 1461}, + {2802, 200}, + {4323, 2656}, + {1448, 3766}, + {3785, 207}, + {2024, 1321}, + {2079, 1322}, + {2227, 574}, + {4095, 3498}, + {2232, 98}, + {518, 2224}, + {2373, 3220}, + {352, 1497}, + {3320, 1189}, + {1009, 3215}, + {2739, 2373}, + {4575, 2710}, + {4238, 3902}, + {1531, 1147}, + {4231, 3597}, + {2240, 1820}, + {3023, 2982}, + {1257, 3445}, + {3592, 645}, + {694, 1907}, + {1754, 3224}, + {1349, 2574}, + {4349, 1682}, + {1359, 2249}, + {1481, 1324}, + {1288, 3371}, + {3047, 3056}, + {683, 1319}, + {3594, 189}, + {2442, 178}, + {2163, 1611}, + {3754, 2661}, + {2176, 1244}, + {4755, 3146}, + {2032, 2303}, + {426, 431}, + {3400, 2151}, + {1072, 2291}, + {2798, 3231}, + {2712, 3687}, + {2985, 2923}, + {1139, 2029}, + {2998, 2812}, + {363, 815}, + {4249, 3854}, + {1367, 2549}, + {3686, 1930}, + {1975, 711}, + {2924, 290}, + {2765, 1515}, + {860, 2519}, + {2773, 1399}, + {634, 3243}, + {2645, 2427}, + {969, 517}, + {1644, 2084}, + {3939, 2438}, + {2267, 3162}, + {1294, 2928}, + {907, 3696}, + {2520, 836}, + {917, 3494}, + {3552, 2044}, + {743, 954}, + {1731, 2785}, + {4603, 3237}, + {2354, 967}, + {3997, 2166}, + {714, 1904}, + {1176, 991}, + {3028, 3800}, + {3137, 2787}, + {1311, 3731}, + {1472, 2112}, + {4382, 482}, + {2113, 3735}, + {3829, 2711}, + {950, 2690}, + {1260, 3940}, + {2859, 1081}, + {1270, 3629}, + {3337, 1761}, + {1127, 700}, + {1366, 2972}, + {4251, 877}, + {2013, 712}, + {3656, 1929}, + {3789, 327}, + {4187, 1486}, + {2339, 2547}, + {4178, 1377}, + {1566, 3280}, + {4054, 2407}, + {3083, 547}, + {34, 2031}, + {2541, 2398}, + {761, 3126}, + {754, 3125}, + {1149, 506}, + {3058, 1592}, + {1158, 2328}, + {3176, 107}, + {1283, 1280}, + {1483, 3408}, + {4339, 3038}, + {2086, 1285}, + {3859, 328}, + {1010, 1083}, + {4544, 1802}, + {1903, 2702}, + {4555, 2190}, + {2080, 3915}, + {4695, 3039}, + {2703, 875}, + {939, 1277}, + {3261, 2973}, + {224, 3832}, + {1319, 1672}, + {1776, 103}, + {4728, 3175}, + {1761, 578}, + {896, 1380}, + {227, 3412}, + {2424, 3160}, + {3973, 127}, + {2412, 683}, + {4366, 1593}, + {2274, 637}, + {125, 2363}, + {3152, 2871}, + {807, 629}, + {2642, 1516}, + {3012, 2047}, + {786, 3727}, + {546, 1246}, + {873, 316}, + {4001, 3805}, + {1031, 338}, + {2937, 3334}, + {237, 1528}, + {2801, 446}, + {4324, 2267}, + {1452, 3710}, + {711, 457}, + {2029, 1613}, + {891, 812}, + {720, 2068}, + {2881, 1993}, + {1308, 1618}, + {3282, 1653}, + {1175, 2823}, + {1336, 1186}, + {4215, 1519}, + {1973, 2831}, + {3684, 3625}, + {1156, 3574}, + {731, 2435}, + {2670, 1918}, + {438, 1553}, + {3141, 231}, + {909, 2026}, + {1911, 3590}, + {3289, 611}, + {2491, 2033}, + {1048, 1089}, + {1245, 1133}, + {972, 897}, + {2547, 2708}, + {965, 2168}, + {3505, 3920}, + {796, 3018}, + {1712, 59}, + {4587, 1234}, + {2321, 3027}, + {4032, 3806}, + {22, 2513}, + {3812, 2595}, + {1952, 312}, + {3821, 3361}, + {1774, 1508}, + {3663, 490}, + {3479, 2218}, + {2899, 481}, + {1115, 1637}, + {1160, 1638}, + {723, 134}, + {2682, 3140}, + {705, 603}, + {904, 2429}, + {1934, 1472}, + {2687, 656}, + {1394, 3436}, + {4143, 2511}, + {1042, 3861}, + {866, 2774}, + {2757, 1716}, + {329, 1154}, + {646, 2136}, + {869, 3711}, + {4641, 2268}, + {2399, 2141}, + {4115, 1056}, + {999, 132}, + {2592, 2582}, + {516, 1607}, + {2732, 618}, + {4688, 2353}, + {1838, 3638}, + {1201, 626}, + {2397, 1532}, + {3247, 62}, + {5, 2572}, + {3237, 545}, + {3095, 3522}, + {4038, 1379}, + {2368, 794}, + {4616, 3531}, + {1700, 2496}, + {1603, 3002}, + {1827, 3665}, + {4496, 913}, + {1817, 3768}, + {3822, 1994}, + {1654, 1040}, + {862, 2715}, + {171, 1027}, + {1895, 1582}, + {1518, 222}, + {4247, 3313}, + {1506, 393}, + {4083, 2482}, + {316, 878}, + {469, 3403}, + {3494, 2559}, + {1414, 1975}, + {2933, 1160}, + {1870, 1861}, + {1085, 2487}, + {2214, 1856}, + {398, 789}, + {1041, 302}, + {1857, 2887}, + {4531, 1956}, + {1978, 3787}, + {4663, 2948}, + {978, 1431}, + {280, 2384}, + {356, 1505}, + {4482, 3874}, + {3094, 867}, + {1645, 1758}, + {2138, 1213}, + {4504, 2096}, + {857, 2237}, + {116, 1025}, + {319, 1550}, + {568, 263}, + {3423, 3285}, + {579, 428}, + {414, 3433}, + {3725, 917}, + {3281, 2589}, + {1509, 100}, + {1948, 358}, + {4690, 516}, + {2730, 2424}, + {1002, 3551}, + {3310, 505}, + {3436, 1737}, + {2048, 738}, + {692, 2962}, + {2134, 1355}, + {4396, 3084}, + {1480, 3793}, + {13, 1605}, + {514, 171}, + {3123, 2252}, + {520, 632}, + {2600, 2616}, + {693, 3482}, + {2085, 1442}, + {3805, 692}, + {9, 1100}, + {3090, 1559}, + {730, 2875}, + {2571, 3573}, + {2329, 3792}, + {1971, 1864}, + {3793, 1864}, + {2006, 3071}, + {464, 857}, + {3460, 1298}, + {1121, 3066}, + {2892, 3749}, + {2532, 411}, + {4798, 1}, + {1780, 3686}, + {4053, 421}, + {2297, 557}, + {2361, 1704}, + {1946, 45}, + {3819, 3208}, + {1950, 537}, + {4541, 2590}, + {2090, 3512}, + {685, 1410}, + {3615, 567}, + {1287, 3504}, + {3015, 2454}, + {4577, 161}, + {4225, 1594}, + {1546, 2671}, + {4234, 1230}, + {2252, 3161}, + {4389, 2283}, + {3008, 412}, + {1236, 2170}, + {3584, 2282}, + {696, 3244}, + {1740, 1759}, + {4345, 3872}, + {1345, 760}, + {3959, 2770}, + {1492, 3566}, + {1300, 2069}, + {704, 3561}, + {2439, 2726}, + {2184, 3913}, + {2171, 3608}, + {4744, 1800}, + {454, 2997}, + {3414, 3439}, + {1083, 661}, + {2794, 1893}, + {2705, 1366}, + {3003, 479}, + {1117, 3344}, + {2990, 322}, + {344, 2413}, + {2855, 3257}, + {4266, 1003}, + {1379, 1003}, + {3689, 2333}, + {1966, 2333}, + {2922, 2333}, + {2779, 2333}, + {838, 837}, + {2771, 837}, + {613, 837}, + {2648, 837}, + {4506, 850}, + {1657, 850}, + {3942, 850}, + {2261, 850}, + {1290, 493}, + {925, 493}, + {2500, 493}, + {911, 493}, + {3535, 105}, + {747, 105}, + {1756, 105}, + {4623, 105}, + {2363, 2531}, + {3994, 2531}, + {718, 2531}, + {1163, 2531}, + {3040, 281}, + {1171, 281}, + {3148, 281}, + {1310, 281}, + {1457, 164}, + {4367, 164}, + {2104, 164}, + {3833, 164}, + {941, 131}, + {1277, 131}, + {2840, 131}, + {1266, 131}, + {3312, 394}, + {1136, 394}, + {1377, 394}, + {4270, 394}, + {2014, 2334}, + {3651, 2334}, + {3801, 2334}, + {4185, 2334}, + {2343, 811}, + {4191, 811}, + {1571, 811}, + {4041, 811}, + {3075, 3078}, + {23, 3078}, + {2527, 801}, + {775, 801}, + {737, 1134}, + {1152, 1134}, + {3054, 701}, + {1146, 701}, + {3172, 2675}, + {1301, 2675}, + {1490, 620}, + {4350, 620}, + {2098, 906}, + {3845, 906}, + {2561, 906}, + {2865, 906}, + {1255, 1832}, + {2871, 1832}, + {146, 1832}, + {3013, 1832}, + {4383, 1119}, + {1526, 1119}, + {3850, 1119}, + {2092, 1119}, + {734, 303}, + {1150, 303}, + {3050, 303}, + {1144, 303}, + {3171, 1243}, + {1304, 1243}, + {1487, 940}, + {4355, 940}, + {2097, 940}, + {3849, 940}, + {290, 2385}, + {597, 2385}, + {3403, 219}, + {588, 219}, + {2654, 219}, + {440, 219}, + {2037, 226}, + {3756, 226}, + {1421, 226}, + {4317, 226}, + {4694, 1193}, + {4419, 1193}, + {1364, 774}, + {4408, 774}, + {3025, 901}, + {663, 901}, + {3606, 901}, + {1891, 901}, + {1522, 2010}, + {4245, 2010}, + {1505, 1881}, + {4081, 1881}, + {1375, 1094}, + {1138, 1094}, + {2856, 275}, + {467, 2882}, + {3492, 2882}, + {3639, 2256}, + {3222, 2256}, + {33, 569}, + {3228, 569}, + {1229, 7}, + {3071, 7}, + {4046, 7}, + {2334, 7}, + {4592, 23}, + {1728, 23}, + {1735, 434}, + {1352, 434}, + {4344, 272}, + {1344, 272}, + {3952, 2357}, + {1495, 2357}, + {1297, 1046}, + {3059, 1046}, + {700, 2254}, + {3580, 2254}, + {4576, 2377}, + {4224, 2377}, + {1543, 389}, + {4233, 389}, + {2249, 389}, + {1496, 284}, + {3007, 284}, + {1240, 284}, + {3583, 573}, + {698, 573}, + {1738, 573}, + {1350, 573}, + {4342, 802}, + {1341, 2064}, + {3954, 735}, + {1295, 1751}, + {3063, 942}, + {702, 996}, + {3581, 2181}, + {2437, 646}, + {2183, 931}, + {3739, 2655}, + {2170, 1063}, + {4740, 2949}, + {2033, 3789}, + {451, 1785}, + {3415, 232}, + {1082, 497}, + {2795, 3082}, + {2706, 514}, + {3006, 3171}, + {1120, 85}, + {2992, 2914}, + {347, 1691}, + {2853, 513}, + {4269, 1371}, + {1376, 2552}, + {3690, 524}, + {1965, 455}, + {2918, 1076}, + {2778, 727}, + {836, 2692}, + {2770, 16}, + {610, 610}, + {2649, 1223}, + {4505, 1928}, + {1658, 60}, + {3941, 3476}, + {2265, 2612}, + {1293, 247}, + {928, 883}, + {2503, 1290}, + {913, 2271}, + {3538, 10}, + {744, 1345}, + {1758, 2981}, + {4620, 1960}, + {2364, 1358}, + {3992, 249}, + {721, 566}, + {1164, 790}, + {3041, 1375}, + {1174, 1666}, + {3151, 2494}, + {1309, 2569}, + {1458, 348}, + {4365, 1721}, + {2106, 1868}, + {3832, 793}, + {942, 2410}, + {1280, 1171}, + {2842, 441}, + {1267, 2463}, + {3314, 399}, + {1133, 1549}, + {1378, 1365}, + {4265, 333}, + {2015, 1496}, + {3650, 521}, + {3798, 2098}, + {4182, 347}, + {2341, 1276}, + {4190, 1201}, + {1567, 424}, + {4042, 3881}, + {3072, 1885}, + {24, 87}, + {2526, 261}, + {777, 2348}, + {733, 2990}, + {1151, 2802}, + {3051, 907}, + {1145, 1058}, + {3167, 1980}, + {1303, 1022}, + {1489, 2730}, + {4353, 2763}, + {2096, 1033}, + {3848, 1219}, + {2410, 1723}, + {2201, 709}, + {3718, 856}, + {2196, 1144}, + {4721, 3013}, + {2046, 2101}, + {422, 1847}, + {3429, 156}, + {1093, 3942}, + {2783, 2924}, + {4105, 526}, + {3893, 1343}, + {2078, 2245}, + {3901, 1687}, + {1899, 735}, + {3758, 2592}, + {375, 1751}, + {2781, 2584}, + {1102, 3429}, + {4556, 646}, + {4243, 2321}, + {1521, 931}, + {4259, 2655}, + {2233, 609}, + {4407, 1625}, + {2988, 1785}, + {1263, 2716}, + {3604, 232}, + {671, 497}, + {103, 993}, + {430, 1908}, + {3556, 514}, + {441, 2032}, + {2522, 3171}, + {587, 85}, + {2159, 790}, + {3872, 1375}, + {1581, 2569}, + {4459, 348}, + {521, 1721}, + {4, 1171}, + {3251, 441}, + {15, 2463}, + {2837, 399}, + {189, 1496}, + {2489, 521}, + {4154, 2098}, + {1913, 1509}, + {4717, 424}, + {3391, 1888}, + {3186, 974}, + {365, 2990}, + {3196, 831}, + {1140, 2802}, + {3319, 907}, + {4084, 2101}, + {2372, 500}, + {4631, 3720}, + {1853, 1723}, + {3346, 2918}, + {3518, 709}, + {393, 856}, + {3509, 802}, + {959, 2064}, + {3371, 937}, + {3781, 735}, + {2061, 2922}, + {4320, 942}, + {1415, 996}, + {3175, 2181}, + {3405, 646}, + {600, 720}, + {3410, 1063}, + {753, 2949}, + {3544, 3789}, + {3874, 1785}, + {2157, 143}, + {4428, 514}, + {1616, 2914}, + {1437, 1691}, + {1635, 513}, + {4645, 1371}, + {1626, 2552}, + {3701, 455}, + {1804, 1076}, + {1025, 727}, + {2752, 2692}, + {338, 16}, + {3298, 610}, + {3335, 613}, + {3522, 1223}, + {381, 1928}, + {3529, 60}, + {949, 3476}, + {3375, 2612}, + {3764, 247}, + {2071, 1290}, + {4326, 2271}, + {1409, 10}, + {2838, 1345}, + {2593, 2981}, + {1001, 1960}, + {2601, 1358}, + {522, 249}, + {2722, 566}, + {4685, 1666}, + {1835, 2494}, + {4108, 1868}, + {2407, 793}, + {1036, 2410}, + {880, 1171}, + {2745, 441}, + {867, 1549}, + {3430, 1365}, + {1028, 333}, + {1801, 1496}, + {4656, 3825}, + {2401, 347}, + {4111, 1276}, + {640, 1201}, + {252, 424}, + {3128, 87}, + {234, 261}, + {2939, 2348}, + {71, 2990}, + {2318, 1614}, + {3999, 1058}, + {1707, 1980}, + {4604, 2270}, + {4444, 2763}, + {4667, 1033}, + {1682, 1219}, + {4660, 1723}, + {2108, 1752}, + {4533, 735}, + {2614, 2922}, + {809, 646}, + {3153, 720}, + {159, 1785}, + {4723, 143}, + {4376, 514}, + {1323, 3543}, + {4364, 16}, + {2413, 2275}, + {4217, 639}, + {2886, 1518}, + {1173, 1171}, + {3498, 441}, + {458, 1496}, + {1787, 2990}, + {1622, 1614}, + {4314, 1723}, + {1610, 1752}, + {4138, 1165}, + {1454, 2145}, + {1043, 3699}, + {2797, 2263}, + {407, 1483}, + {3399, 1043}, + {1436, 797}, + {1649, 2116}, + {4634, 2390}, + {1659, 1735}, + {3693, 415}, + {1806, 2755}, + {1014, 989}, + {2769, 229}, + {351, 2663}, + {3295, 3640}, + {1556, 214}, + {1851, 1296}, + {4529, 1991}, + {1844, 2859}, + {3794, 108}, + {1685, 1853}, + {811, 1588}, + {2612, 630}, + {128, 1168}, + {3187, 722}, + {3328, 639}, + {3519, 550}, + {387, 3508}, + {3525, 64}, + {956, 1730}, + {3385, 2263}, + {3759, 1483}, + {2067, 1043}, + {4328, 797}, + {1406, 2116}, + {1441, 2390}, + {1641, 1735}, + {4640, 415}, + {1629, 2755}, + {3698, 989}, + {1799, 229}, + {1029, 2663}, + {2758, 3640}, + {333, 214}, + {3302, 1296}, + {132, 1991}, + {403, 2859}, + {3508, 108}, + {392, 1853}, + {2555, 1588}, + {557, 630}, + {2205, 1168}, + {3914, 722}, + {1623, 639}, + {4423, 550}, + {3179, 3508}, + {3401, 64}, + {603, 1730}, + {3411, 630}, + {757, 1168}, + {3539, 722}, + {3877, 639}, + {2161, 2275}, + {4430, 1518}, + {1620, 883}, + {2671, 1076}, + {3049, 727}, + {1154, 2692}, + {3066, 630}, + {296, 1168}, + {2897, 722}, + {4201, 883}, + {1347, 1290}, + {3664, 3040}, + {2001, 3040}, + {762, 2903}, + {2538, 2402}, + {3888, 2402}, + {4110, 3364}, + {2286, 467}, + {4119, 3264}, + {1488, 1387}, + {3947, 331}, + {3169, 2555}, + {99, 2555}, + {2591, 321}, + {881, 1278}, + {3974, 1526}, + {3729, 297}, + {2195, 3275}, + {3717, 456}, + {1767, 456}, + {3871, 3338}, + {3570, 816}, + {577, 816}, + {2966, 2627}, + {1189, 2627}, + {4101, 1537}, + {3894, 177}, + {2074, 177}, + {3899, 3442}, + {1896, 595}, + {3760, 595}, + {3380, 2372}, + {374, 2372}, + {2780, 582}, + {1097, 955}, + {1224, 955}, + {993, 1938}, + {2603, 1938}, + {981, 2065}, + {3628, 3798}, + {810, 429}, + {1686, 766}, + {4535, 766}, + {2270, 2938}, + {3937, 3934}, + {3965, 3936}, + {3738, 2687}, + {2189, 1816}, + {3751, 1816}, + {1760, 1036}, + {3879, 2162}, + {3537, 2100}, + {582, 2293}, + {2972, 2154}, + {1187, 539}, + {1320, 539}, + {1777, 1360}, + {4729, 1360}, + {1762, 1709}, + {3726, 1709}, + {1941, 2609}, + {897, 298}, + {2686, 1738}, + {229, 2597}, + {3256, 3413}, + {4261, 2158}, + {4546, 690}, + {2083, 3026}, + {4693, 3926}, + {2704, 1830}, + {936, 166}, + {3262, 3918}, + {221, 2930}, + {3904, 2930}, + {4089, 3576}, + {2231, 756}, + {4106, 3878}, + {1514, 1202}, + {3934, 1202}, + {3192, 2788}, + {167, 3217}, + {2638, 1192}, + {817, 1996}, + {1302, 1573}, + {912, 209}, + {2513, 3311}, + {926, 371}, + {3546, 2478}, + {736, 3400}, + {1743, 1295}, + {4608, 886}, + {2351, 3407}, + {4005, 2566}, + {1005, 2989}, + {1205, 3655}, + {2834, 910}, + {1216, 3756}, + {3246, 1978}, + {1069, 1023}, + {1418, 2731}, + {4278, 3293}, + {2025, 1036}, + {3783, 2100}, + {2720, 194}, + {2991, 1566}, + {1134, 2011}, + {3005, 1454}, + {359, 585}, + {2841, 2375}, + {4252, 585}, + {1371, 2011}, + {3680, 2379}, + {1980, 3218}, + {2863, 3425}, + {2564, 2347}, + {963, 1459}, + {2542, 2375}, + {395, 429}, + {2700, 1537}, + {4712, 3145}, + {1874, 2860}, + {2890, 1771}, + {1119, 814}, + {2457, 2276}, + {2137, 3513}, + {3697, 563}, + {2150, 3189}, + {4639, 1340}, + {2010, 46}, + {460, 2544}, + {3448, 3847}, + {1129, 37}, + {2887, 1424}, + {1661, 1293}, + {3416, 518}, + {3163, 473}, + {295, 2}, + {3184, 317}, + {1155, 2411}, + {3296, 357}, + {4112, 1259}, + {2438, 1001}, + {4684, 3261}, + {1803, 2}, + {3622, 2}, + {523, 2724}, + {2597, 650}, + {689, 938}, + {3813, 109}, + {1479, 1821}, + {4395, 841}, + {4228, 1403}, + {4590, 450}, + {1860, 3115}, + {4569, 294}, + {2053, 2444}, + {4716, 3234}, + {2698, 1678}, + {970, 952}, + {3273, 641}, + {186, 1617}, + {277, 449}, + {606, 3481}, + {3471, 580}, + {461, 170}, + {2009, 799}, + {3681, 183}, + {1373, 183}, + {4210, 183}, + {288, 183}, + {583, 938}, + {2658, 518}, + {447, 473}, + {2036, 2}, + {1426, 2411}, + {4309, 317}, + {3352, 1259}, + {3504, 357}, + {408, 2724}, + {3516, 109}, + {973, 1821}, + {3368, 841}, + {3773, 1403}, + {2052, 450}, + {4313, 3115}, + {1419, 192}, + {2570, 1630}, + {2868, 2248}, + {1249, 567}, + {2876, 3172}, + {139, 1352}, + {3010, 14}, + {4388, 454}, + {3843, 25}, + {2095, 1443}, + {2276, 1850}, + {2042, 741}, + {569, 2172}, + {3569, 404}, + {1220, 3676}, + {1977, 2366}, + {4186, 368}, + {2349, 3328}, + {4299, 1426}, + {2475, 268}, + {209, 2629}, + {3219, 3770}, + {884, 252}, + {2716, 1332}, + {3778, 1053}, + {3925, 1839}, + {2402, 2883}, + {3928, 1958}, + {1389, 1958}, + {4064, 676}, + {3345, 676}, + {332, 1436}, + {2744, 1436}, + {1004, 3651}, + {4082, 3651}, + {3895, 900}, + {2070, 900}, + {3892, 900}, + {1894, 900}, + {3771, 784}, + {3389, 784}, + {382, 509}, + {2786, 509}, + {1089, 509}, + {3988, 509}, + {3723, 2133}, + {2200, 2133}, + {3734, 936}, + {1775, 936}, + {3864, 936}, + {3567, 936}, + {571, 126}, + {2959, 126}, + {1199, 126}, + {1059, 126}, + {858, 409}, + {2764, 409}, + {844, 409}, + {3450, 409}, + {1015, 210}, + {1826, 210}, + {4638, 210}, + {2386, 210}, + {4122, 375}, + {4072, 375}, + {3909, 375}, + {2065, 375}, + {3917, 74}, + {1880, 74}, + {3775, 1256}, + {3366, 1256}, + {390, 285}, + {2793, 285}, + {1077, 508}, + {3055, 508}, + {2656, 786}, + {752, 786}, + {2661, 786}, + {596, 786}, + {2509, 70}, + {4602, 70}, + {1732, 70}, + {4026, 70}, + {2320, 204}, + {1244, 204}, + {967, 204}, + {2557, 204}, + {960, 135}, + {3512, 135}, + {800, 135}, + {1705, 135}, + {4582, 145}, + {2325, 145}, + {4025, 145}, + {399, 145}, + {151, 39}, + {3342, 39}, + {135, 39}, + {2864, 39}, + {334, 383}, + {2406, 383}, + {4079, 383}, + {1795, 383}, + {4686, 218}, + {4207, 218}, + {4599, 218}, + {1923, 218}, + {4595, 390}, + {2039, 390}, + {4735, 390}, + {2691, 390}, + {900, 11}, + {3225, 11}, + {263, 11}, + {4527, 11}, + {4303, 238}, + {1555, 238}, + {4293, 238}, + {2330, 238}, + {4451, 865}, + {2967, 865}, + {1235, 865}, + {3573, 865}, + {531, 1452}, + {1701, 1452}, + {1391, 1452}, + {4386, 1452}, + {1388, 1057}, + {3922, 1057}, + {1540, 1057}, + {1258, 1057}, + {3022, 898}, + {652, 898}, + {3621, 898}, + {1512, 898}, + {1890, 696}, + {4558, 696}, + {1897, 23}, + {3900, 23}, + {1719, 1090}, + {759, 1090}, + {2574, 1090}, + {79, 1090}, + {3078, 3568}, + {1325, 3568}, + {1784, 2095}, + {4725, 2095}, + {1769, 739}, + {3719, 739}, + {1935, 1757}, + {901, 1757}, + {3459, 357}, + {623, 3432}, + {3465, 192}, + {846, 1443}, + {3603, 1850}, + {3826, 1630}, + {2142, 1034}, + {4400, 109}, + {1470, 1821}, + {1530, 2248}, + {1871, 567}, + {4573, 518}, + {1861, 3172}, + {3913, 1311}, + {1708, 102}, + {797, 360}, + {2565, 206}, + {69, 89}, + {3087, 21}, + {3808, 265}, + {4162, 350}, + {2358, 1141}, + {4153, 387}, + {1582, 529}, + {4037, 1546}, + {3096, 317}, + {16, 2411}, + {2524, 1352}, + {785, 454}, + {2130, 14}, + {2462, 1259}, + {4004, 741}, + {2467, 196}, + {4462, 158}, + {2317, 48}, + {49, 57}, + {3126, 154}, + {789, 187}, + {2515, 169}, + {1449, 119}, + {1632, 167}, + {4650, 4}, + {1638, 163}, + {3704, 115}, + {1789, 55}, + {1021, 22}, + {2750, 157}, + {326, 160}, + {3308, 397}, + {3500, 54}, + {3073, 80}, + {223, 139}, + {3084, 213}, + {1095, 76}, + {3215, 150}, + {4184, 212}, + {2478, 19}, + {4726, 67}, + {1904, 170}, + {3147, 25}, + {3421, 799}, + {575, 3734}, + {3428, 938}, + {719, 560}, + {3563, 196}, + {3867, 158}, + {2197, 48}, + {4439, 57}, + {1605, 154}, + {68, 187}, + {482, 169}, + {3590, 119}, + {489, 167}, + {2627, 4}, + {641, 163}, + {2128, 115}, + {3851, 55}, + {1528, 22}, + {4357, 157}, + {614, 160}, + {273, 397}, + {3110, 54}, + {262, 80}, + {2921, 139}, + {84, 213}, + {2304, 76}, + {4018, 150}, + {1729, 212}, + {4593, 19}, + {508, 67}, + {26, 841}, + {3227, 1257}, + {47, 1403}, + {2813, 619}, + {204, 1603}, + {2480, 3327}, + {4181, 1311}, + {1927, 1617}, + {4705, 449}, + {4552, 473}, + {4268, 844}, + {1501, 244}, + {4253, 983}, + {2224, 2912}, + {4413, 3823}, + {3004, 1719}, + {1279, 334}, + {3610, 3819}, + {665, 3045}, + {647, 3044}, + {239, 3605}, + {3131, 678}, + {249, 1661}, + {2946, 386}, + {60, 1101}, + {2311, 2885}, + {3991, 687}, + {1692, 1110}, + {4614, 2022}, + {3617, 1093}, + {3241, 2861}, + {11, 1845}, + {3234, 1106}, + {1207, 1020}, + {3099, 1979}, + {4033, 751}, + {2362, 2388}, + {4622, 1176}, + {1690, 1221}, + {648, 2525}, + {240, 1941}, + {3132, 24}, + {251, 3374}, + {2947, 1480}, + {58, 496}, + {2312, 2247}, + {3990, 223}, + {1694, 504}, + {4613, 1557}, + {1046, 414}, + {871, 255}, + {2753, 3286}, + {879, 403}, + {3435, 1696}, + {1018, 1954}, + {1792, 914}, + {4644, 912}, + {2395, 1051}, + {4117, 2593}, + {3658, 3088}, + {4045, 1763}, + {2483, 253}, + {4057, 3771}, + {1405, 2144}, + {4172, 1166}, + {3221, 2475}, + {214, 3186}, + {2678, 1155}, + {958, 1959}, + {3986, 20}, + {3728, 28}, + {2199, 3096}, + {3732, 525}, + {1773, 1363}, + {3865, 56}, + {3565, 1395}, + {567, 748}, + {2954, 2898}, + {1197, 2462}, + {2323, 820}, + {1991, 3101}, + {3855, 2037}, + {1997, 988}, + {4513, 734}, + {2123, 1753}, + {643, 978}, + {3585, 2194}, + {1238, 1749}, + {3064, 908}, + {2139, 1212}, + {2455, 1446}, + {4015, 361}, + {2450, 1577}, + {4483, 388}, + {2309, 2862}, + {82, 854}, + {3116, 554}, + {778, 468}, + {2530, 1417}, + {1979, 572}, + {4300, 1049}, + {2474, 1971}, + {211, 2550}, + {3223, 30}, + {886, 1917}, + {2721, 1156}, + {1264, 3184}, + {2848, 556}, + {160, 2571}, + {2995, 1811}, + {4421, 1369}, + {1520, 796}, + {2131, 2149}, + {2464, 3302}, + {4008, 250}, + {2469, 2159}, + {4463, 969}, + {2314, 391}, + {791, 373}, + {2511, 1657}, + {3809, 241}, + {1584, 3329}, + {4034, 2358}, + {3097, 614}, + {14, 1967}, + {2525, 2345}, + {783, 3182}, + {2133, 1942}, + {4006, 3829}, + {2468, 819}, + {4464, 2815}, + {2315, 3706}, + {50, 2140}, + {3125, 438}, + {792, 3697}, + {0, 2797}, + {0, 3826}, + {0, 964}, + {0, 3723}, + {0, 1913}, + {0, 847}, + {0, 3053}, + {0, 3379}, + {0, 839}, + {0, 1809}, + {0, 1777}, + {0, 1128}, {0, 3914}, - {0, 2152}, - {0, 1858}, - {0, 948}, - {0, 1687}, - {0, 3902}, - {0, 3786}, - {0, 1278}, - {0, 1918}, - {0, 2053}, - {0, 3750}, - {0, 3667}, - {0, 3011}, + {0, 694}, + {0, 2704}, + {0, 3624}, + {0, 1948}, + {0, 631}, + {0, 3618}, {0, 2821}, - {0, 3132}, - {0, 1815}, - {0, 1969}, - {0, 3513}, - {0, 3711}, - {0, 1924}, - {0, 2096}, - {0, 905}, - {0, 1758}, - {0, 280}, - {0, 2883}, - {0, 465}, - {0, 1135}, - {1653, 2}, - {5128, 2}, - {4869, 2}, - {1385, 2}, - {2711, 3470}, - {1995, 3190}, - {2806, 487}, - {232, 3327}, - {4658, 3052}, - {1485, 460}, - {495, 2758}, - {2816, 2389}, - {473, 2533}, - {3878, 395}, - {705, 43}, - {4051, 1618}, - {1084, 955}, - {3757, 1676}, - {1856, 3900}, - {2285, 3378}, - {866, 1289}, - {3320, 374}, - {864, 2064}, - {4502, 1693}, - {630, 3673}, - {4389, 3002}, - {1428, 1559}, - {3558, 1194}, - {741, 2601}, - {246, 357}, - {1650, 675}, - {3929, 360}, - {1668, 378}, - {2725, 2540}, - {1901, 2331}, - {2933, 3373}, - {501, 2826}, - {4319, 3131}, - {2439, 1818}, - {1689, 191}, - {220, 3506}, - {2754, 3753}, - {217, 356}, - {3942, 1929}, - {1215, 2097}, - {3834, 900}, - {638, 3815}, - {4466, 2644}, - {2263, 1093}, - {1826, 987}, - {2, 2257}, - {43, 2944}, - {4080, 1081}, - {1078, 833}, - {3719, 2022}, - {4473, 1574}, - {625, 1187}, - {2585, 2621}, - {3311, 2475}, - {4538, 686}, - {0, 245}, - {0, 2394}, - {0, 2476}, - {0, 3242}, - {0, 3198}, - {0, 2865}, - {0, 213}, - {0, 66}, - {0, 2941}, - {0, 2656}, - {0, 2250}, - {0, 182}, - {0, 576}, - {0, 1229}, - {0, 1694}, - {0, 1085}, - {0, 2498}, - {0, 2576}, - {0, 802}, - {0, 186}, - {0, 533}, - {0, 2661}, - {0, 2215}, - {0, 3472}, - {0, 2553}, - {0, 3885}, - {0, 1628}, - {0, 1531}, - {0, 3564}, - {0, 3282}, - {0, 3355}, - {0, 1617}, - {0, 1387}, - {0, 397}, - {0, 2095}, - {0, 627}, - {0, 3022}, + {0, 3269}, + {0, 2518}, + {0, 1514}, + {0, 2409}, + {0, 319}, + {0, 1381}, + {0, 3544}, + {0, 2892}, + {0, 1385}, + {0, 124}, + {0, 125}, + {0, 1632}, + {0, 2635}, + {0, 1271}, + {0, 3135}, + {0, 2326}, + {0, 356}, + {0, 2203}, + {0, 2317}, + {0, 3268}, + {0, 50}, + {0, 1933}, + {0, 2551}, + {0, 3466}, + {0, 3812}, + {0, 2828}, + {0, 1887}, {0, 2932}, - {0, 73}, - {0, 907}, - {0, 990}, - {0, 3003}, - {0, 2822}, - {0, 3743}, - {0, 424}, - {0, 2133}, - {0, 3478}, - {0, 3410}, - {0, 1848}, - {0, 1367}, - {0, 1602}, - {0, 2887}, - {0, 2241}, - {0, 2677}, - {0, 589}, - {0, 174}, - {0, 1712}, - {0, 1202}, - {0, 865}, - {0, 2431}, - {0, 2289}, - {0, 1024}, - {0, 586}, - {0, 113}, + {0, 939}, + {0, 2070}, + {0, 3562}, + {0, 2437}, + {0, 2079}, + {0, 1120}, + {0, 1392}, + {0, 440}, + {0, 3378}, + {0, 287}, + {0, 2439}, + {0, 3227}, + {0, 1686}, + {0, 963}, + {0, 3233}, + {0, 2306}, + {0, 2503}, + {0, 3250}, + {0, 308}, + {0, 3352}, + {0, 1492}, + {0, 472}, {0, 2234}, - {0, 2630}, - {0, 3211}, - {0, 2364}, - {0, 3550}, - {0, 1284}, - {0, 1448}, - {0, 3901}, - {0, 3339}, - {5035, 2}, - {2865, 2}, - {4968, 2}, - {3086, 2}, - {5026, 2}, - {2224, 2}, - {2209, 2}, - {4579, 2}, - {4895, 2}, - {5100, 2}, - {4876, 2}, - {455, 2}, - {2910, 2}, - {5113, 2}, - {4054, 2}, - {4934, 2}, - {2017, 2}, - {4830, 2}, - {4508, 2}, - {5091, 2}, - {83, 2}, - {4769, 2}, - {2098, 2}, - {2174, 2}, - {4740, 2}, - {4915, 2}, - {1556, 2}, - {421, 2}, - {386, 2}, - {4979, 2}, - {5102, 2}, - {2039, 2}, - {3076, 2}, - {0, 523}, - {0, 2166}, - {0, 3432}, - {0, 3364}, + {0, 3740}, + {0, 489}, + {0, 1649}, + {0, 1587}, + {0, 153}, + {0, 2418}, + {0, 3122}, + {0, 3600}, + {0, 3042}, + {0, 2174}, + {0, 2713}, + {0, 674}, + {0, 1804}, + {0, 3745}, + {0, 2665}, + {0, 1795}, + {0, 129}, + {0, 1633}, + {0, 2634}, + {0, 1274}, + {0, 3137}, + {0, 2324}, + {0, 355}, + {0, 2202}, + {0, 2316}, + {0, 3267}, + {0, 3048}, + {0, 3609}, + {0, 693}, + {0, 3916}, + {0, 2189}, + {0, 2881}, + {0, 3108}, + {0, 1092}, + {0, 2018}, + {0, 1787}, + {0, 1146}, + {0, 3905}, + {0, 2681}, + {0, 3635}, + {3677, 1}, + {4999, 1}, + {4927, 1}, + {1370, 1}, + {3796, 3468}, + {1471, 714}, + {4398, 1923}, + {703, 2201}, + {188, 663}, + {200, 1096}, + {2977, 3035}, + {3, 3909}, + {2359, 1880}, + {4031, 130}, + {1739, 2447}, + {4589, 2895}, + {480, 2933}, + {62, 3701}, + {3272, 828}, + {53, 532}, + {2796, 2048}, + {254, 958}, + {2471, 2781}, + {4140, 2056}, + {1886, 970}, + {4742, 2161}, + {4615, 591}, + {4195, 1266}, + {1498, 2305}, + {4204, 1626}, + {2292, 3451}, + {4340, 2651}, + {3043, 199}, + {1284, 1808}, + {3620, 2643}, + {653, 3377}, + {662, 2786}, + {230, 2412}, + {3068, 1391}, + {206, 397}, + {2953, 477}, + {38, 1498}, + {2345, 862}, + {4055, 2799}, + {1772, 1511}, + {4551, 590}, + {3613, 1396}, + {3259, 436}, + {81, 3375}, + {3265, 279}, + {1195, 2440}, + {4014, 1688}, + {2302, 966}, + {4548, 3236}, + {1783, 2311}, + {661, 926}, + {233, 1964}, + {3070, 2976}, + {207, 1843}, + {2952, 3673}, + {0, 2492}, + {0, 3904}, + {0, 149}, + {0, 1373}, {0, 1813}, - {0, 1428}, - {0, 1550}, - {0, 3405}, - {0, 3258}, - {0, 2456}, - {0, 2405}, - {0, 3607}, - {0, 1273}, - {0, 1371}, - {0, 3836}, - {0, 3402}, - {0, 3222}, - {0, 1426}, + {0, 1103}, + {0, 3919}, + {0, 669}, + {0, 2707}, + {0, 3606}, + {0, 2006}, + {0, 594}, + {0, 3611}, + {0, 2792}, + {0, 3437}, + {0, 2314}, + {0, 1240}, + {0, 2645}, + {0, 604}, + {0, 1620}, + {0, 3294}, + {0, 2725}, + {0, 1624}, + {0, 501}, + {0, 155}, + {0, 1586}, + {0, 2666}, + {0, 1222}, + {0, 3152}, + {0, 2281}, + {0, 420}, + {0, 2175}, + {0, 2285}, + {0, 3248}, + {0, 3255}, + {0, 2501}, + {0, 1527}, + {0, 2395}, + {0, 337}, + {0, 1361}, + {0, 3533}, + {0, 2911}, + {0, 1372}, + {0, 151}, + {0, 1793}, + {0, 1148}, + {0, 3901}, + {0, 717}, + {0, 2689}, + {0, 3637}, + {0, 1963}, + {0, 1534}, + {0, 452}, + {0, 2255}, + {0, 3703}, + {0, 444}, + {0, 1601}, + {0, 822}, + {0, 2074}, + {0, 2897}, + {0, 1943}, + {0, 3693}, + {0, 2830}, + {0, 1174}, {0, 1512}, - {0, 257}, - {0, 1341}, - {0, 881}, - {0, 2350}, - {0, 2262}, - {0, 1008}, - {0, 610}, - {0, 91}, - {0, 2309}, - {0, 2623}, - {0, 3118}, - {0, 2789}, - {0, 3261}, - {5047, 2}, - {578, 2}, - {4768, 2}, - {1074, 2}, - {3285, 2}, - {2560, 2}, - {4109, 2}, - {1845, 2}, - {4143, 2}, - {55, 2}, - {4475, 2}, - {4772, 2}, - {5064, 2}, - {4766, 2}, - {265, 2}, - {2792, 2}, - {263, 2}, - {0, 1821}, - {0, 363}, - {0, 2814}, - {0, 2705}, - {0, 377}, - {0, 1190}, - {0, 672}, - {0, 2765}, - {0, 3017}, - {0, 3577}, - {0, 2277}, - {0, 3721}, - {0, 1396}, - {0, 1219}, - {0, 3725}, - {0, 3514}, - {0, 3119}, - {0, 1306}, - {0, 1633}, - {0, 92}, - {0, 3540}, - {0, 2378}, - {0, 913}, - {0, 739}, - {0, 2530}, - {0, 3062}, - {0, 2757}, - {0, 688}, - {0, 1142}, - {0, 1862}, - {0, 638}, - {0, 2081}, - {4816, 2}, - {161, 181}, - {1055, 286}, - {438, 68}, - {548, 320}, - {104, 485}, - {37, 544}, - {145, 198}, - {665, 57}, - {1, 107}, - {240, 44}, - {379, 162}, - {255, 120}, - {470, 50}, - {1134, 222}, - {12, 731}, - {182, 432}, - {21, 30}, - {440, 800}, - {662, 167}, - {313, 1077}, - {228, 105}, - {580, 637}, - {5088, 2}, - {4874, 2}, - {3631, 1408}, - {3377, 2514}, - {3501, 820}, - {3920, 3682}, - {1007, 2367}, - {3923, 1007}, - {3481, 2955}, - {4809, 2}, - {5043, 2}, - {5079, 2}, - {4479, 3411}, - {398, 2924}, - {4484, 232}, - {4285, 998}, - {3855, 3681}, - {1931, 1688}, - {84, 181}, - {186, 171}, - {214, 7}, - {745, 184}, - {1341, 320}, - {9, 134}, - {1044, 131}, - {600, 307}, - {207, 191}, - {262, 37}, - {47, 544}, - {331, 198}, - {288, 57}, - {405, 107}, - {493, 44}, - {28, 162}, - {293, 120}, - {100, 5}, - {769, 886}, - {917, 3785}, - {725, 59}, - {224, 106}, - {517, 173}, - {10, 15}, - {1502, 278}, - {870, 155}, - {154, 72}, - {110, 480}, - {599, 615}, - {227, 1324}, - {825, 291}, - {1034, 205}, - {194, 64}, - {934, 83}, - {650, 240}, - {2078, 72}, - {1828, 130}, - {454, 1260}, - {1422, 1418}, - {213, 78}, - {266, 287}, - {120, 216}, - {54, 297}, - {336, 499}, - {290, 59}, - {589, 106}, - {1195, 173}, - {574, 15}, - {2162, 278}, - {969, 155}, - {423, 72}, - {568, 480}, - {344, 615}, - {343, 1324}, - {40, 291}, - {198, 205}, - {1301, 64}, - {1248, 83}, - {674, 240}, - {409, 130}, - {98, 130}, - {292, 1260}, - {241, 1418}, - {876, 78}, - {988, 287}, - {1692, 216}, - {1148, 297}, - {1424, 192}, - {947, 15}, - {70, 72}, - {3313, 615}, - {775, 78}, - {2314, 240}, - {2296, 36}, - {742, 72}, - {1082, 15}, - {4026, 72}, - {2291, 615}, - {1732, 78}, - {4615, 240}, - {2340, 36}, - {1037, 72}, - {3434, 15}, - {3840, 72}, - {1054, 615}, - {4002, 78}, - {2053, 240}, - {1379, 36}, - {2639, 72}, - {4421, 15}, - {4268, 72}, - {4298, 615}, - {3014, 78}, - {1934, 240}, - {2557, 36}, - {949, 72}, - {366, 15}, - {2515, 72}, - {4111, 615}, - {4036, 78}, - {3982, 240}, - {3267, 36}, - {1649, 1213}, - {3457, 1213}, - {1675, 319}, - {3487, 1364}, - {3163, 1146}, - {2708, 2411}, - {807, 1104}, - {3279, 1084}, - {4488, 584}, - {4749, 1661}, - {4639, 2130}, - {2495, 1462}, - {2417, 2340}, - {3067, 1814}, - {4672, 1115}, - {4013, 170}, - {2381, 2392}, - {4599, 636}, - {3329, 203}, - {3115, 2047}, - {3198, 1696}, - {4206, 316}, - {706, 1906}, - {3663, 142}, - {2451, 1400}, - {1569, 425}, - {4746, 2738}, - {2200, 2665}, - {892, 2290}, - {803, 56}, - {761, 100}, - {1789, 702}, - {3155, 794}, - {1356, 3873}, - {4660, 971}, - {4020, 319}, - {2349, 1364}, - {4552, 1146}, - {3355, 2411}, - {3087, 1104}, - {3179, 1084}, - {4204, 584}, - {735, 1661}, - {3677, 2130}, - {756, 1462}, - {308, 2340}, - {3146, 1115}, - {954, 170}, - {2268, 636}, - {2341, 2047}, - {2464, 1696}, - {191, 316}, - {4631, 1906}, - {567, 142}, - {3896, 1400}, - {4243, 2535}, - {1534, 425}, - {3658, 763}, - {3006, 100}, - {2863, 3473}, - {2830, 1784}, - {4388, 926}, - {498, 903}, - {4575, 2154}, - {0, 285}, - {0, 3370}, + {0, 2820}, + {0, 3619}, + {0, 3834}, + {0, 2805}, + {0, 1936}, + {0, 2910}, + {0, 981}, + {0, 2035}, + {4955, 1}, + {1723, 1}, + {4836, 1}, + {2306, 1}, + {4995, 1}, + {2566, 1}, + {906, 1}, + {3409, 1}, + {4845, 1}, + {4834, 1}, + {4973, 1}, + {4128, 1}, + {3290, 1}, + {4945, 1}, + {122, 1}, + {4982, 1}, + {114, 1}, + {5047, 1}, + {3630, 1}, + {4856, 1}, + {680, 1}, + {4773, 1}, + {2254, 1}, + {1666, 1}, + {4248, 1}, + {4848, 1}, + {4298, 1}, + {2348, 1}, + {2955, 1}, + {5072, 1}, + {5056, 1}, + {2087, 1}, + {3858, 1}, + {0, 2728}, + {0, 3912}, + {0, 1127}, + {0, 3607}, + {0, 1799}, + {0, 671}, + {0, 2998}, + {0, 3440}, + {0, 662}, {0, 1894}, - {0, 2862}, - {0, 3249}, - {0, 2043}, - {0, 537}, - {0, 3201}, - {0, 2116}, - {0, 2175}, - {0, 1480}, - {0, 2330}, - {0, 978}, - {0, 3816}, - {0, 2466}, - {0, 810}, - {0, 2890}, - {0, 2021}, - {0, 3121}, - {0, 3251}, - {0, 3618}, - {0, 1193}, + {0, 598}, + {0, 1272}, {0, 2302}, + {0, 1631}, + {0, 3457}, + {0, 2662}, + {0, 190}, + {0, 1815}, + {0, 2650}, + {0, 3372}, + {0, 3148}, + {0, 2624}, + {0, 1640}, + {0, 2288}, + {0, 181}, {0, 1236}, - {0, 770}, - {0, 2687}, - {0, 3179}, - {0, 569}, - {0, 2847}, - {0, 2707}, - {0, 2395}, - {0, 1560}, - {0, 3697}, - {0, 835}, - {1070, 69}, - {708, 806}, - {1224, 166}, - {596, 1347}, - {143, 352}, - {514, 1163}, - {264, 79}, - {1141, 199}, - {556, 304}, - {1532, 787}, - {1098, 221}, - {29, 189}, - {354, 328}, - {219, 306}, - {13, 329}, - {1429, 609}, - {1661, 163}, - {316, 127}, - {1383, 554}, - {15, 786}, - {360, 1358}, - {231, 260}, - {1072, 1061}, - {2774, 1520}, - {1708, 371}, - {2005, 1453}, - {699, 498}, - {757, 469}, - {3309, 659}, - {3880, 1004}, - {3375, 326}, - {444, 95}, - {1872, 1}, - {3947, 3518}, - {2694, 3778}, - {2587, 864}, - {2546, 2480}, - {4669, 1575}, - {107, 992}, - {4297, 2374}, - {2499, 282}, - {3334, 3393}, - {39, 1827}, - {1758, 2247}, - {3552, 1056}, - {157, 746}, - {885, 738}, - {2582, 1411}, - {268, 345}, - {1578, 1900}, - {1865, 2528}, - {1742, 341}, - {736, 2997}, - {4202, 2318}, - {1243, 472}, - {2489, 1138}, - {3341, 1713}, - {8, 1571}, - {2757, 1747}, - {4041, 443}, - {4113, 2837}, - {4160, 402}, - {3158, 3365}, - {1785, 2937}, - {3564, 279}, - {1736, 2737}, - {2279, 1092}, - {4098, 3333}, - {1707, 431}, - {294, 3814}, - {2408, 1482}, - {2527, 1087}, - {3460, 181}, - {2993, 171}, - {1056, 7}, - {3545, 101}, - {4252, 551}, - {4440, 184}, - {4346, 286}, - {2805, 29}, - {2171, 482}, - {2783, 68}, - {1314, 320}, - {2120, 268}, - {3701, 134}, - {1495, 131}, - {538, 485}, - {555, 307}, - {661, 191}, - {1993, 37}, - {2968, 544}, - {2332, 198}, - {4256, 57}, - {3885, 107}, - {1894, 44}, - {4469, 162}, - {3462, 120}, - {3560, 5}, - {3600, 2693}, - {1183, 1149}, - {4108, 2300}, - {430, 3511}, - {1227, 20}, - {2312, 3825}, - {2948, 1243}, - {4710, 3134}, - {2335, 1727}, - {3315, 1930}, - {1509, 3346}, - {2488, 839}, - {1952, 3456}, - {2087, 1018}, - {2129, 2414}, - {502, 1395}, - {4390, 892}, - {249, 2527}, - {3702, 3300}, - {4439, 391}, - {1313, 2698}, - {3863, 2831}, - {2924, 2327}, - {2947, 1749}, - {3066, 3597}, - {4317, 684}, - {570, 1329}, - {4640, 3908}, - {1774, 1903}, - {2252, 2959}, - {4139, 139}, - {1669, 342}, - {341, 708}, - {36, 3857}, - {195, 1224}, - {2441, 2278}, - {2469, 3574}, - {1889, 1655}, - {2231, 263}, - {1804, 3089}, - {4547, 355}, - {2413, 108}, - {819, 805}, - {874, 3732}, - {986, 1382}, - {1690, 2421}, - {3212, 3637}, - {1425, 1486}, - {945, 3324}, - {65, 348}, - {3317, 2082}, - {776, 1790}, - {2313, 2568}, - {2294, 1211}, - {2210, 3847}, - {222, 1184}, - {869, 2459}, - {3186, 2617}, - {4700, 3005}, - {4539, 1984}, - {4580, 3390}, - {2756, 414}, - {2222, 2093}, - {2836, 3312}, - {935, 3537}, - {4624, 1883}, - {536, 3330}, - {118, 923}, - {902, 3734}, - {2564, 1242}, - {244, 1389}, - {1597, 1849}, - {1722, 119}, - {716, 3126}, - {4214, 2783}, - {1265, 644}, - {4528, 2077}, - {1821, 3169}, - {3979, 3305}, - {2634, 1140}, - {2520, 2240}, - {4637, 1299}, - {170, 711}, - {4329, 2609}, - {1013, 2996}, - {688, 1329}, - {3365, 3444}, - {1245, 3353}, - {1977, 3894}, - {2045, 766}, - {2108, 2624}, - {4402, 1188}, - {270, 2112}, - {3761, 3684}, - {4363, 995}, - {1386, 2246}, - {3788, 2348}, - {2858, 1211}, - {3018, 2182}, - {2979, 3213}, - {2189, 2186}, - {4213, 3304}, - {250, 3625}, - {89, 2369}, - {2367, 1452}, - {2559, 822}, - {1950, 488}, - {929, 2751}, - {3131, 2898}, - {4638, 2259}, - {4604, 1670}, - {4485, 3546}, - {2661, 762}, - {2302, 1248}, - {2926, 3876}, - {1081, 1975}, - {590, 2922}, - {3467, 46}, - {1191, 258}, - {1891, 768}, - {2168, 3893}, - {2038, 1276}, - {429, 2226}, - {4460, 3610}, - {340, 1737}, - {3041, 284}, - {449, 26}, - {1426, 877}, - {1405, 3782}, - {1172, 2365}, - {3766, 3683}, - {817, 1567}, - {2109, 246}, - {3716, 3056}, - {1510, 2907}, - {518, 2643}, - {581, 1292}, - {689, 3905}, - {2016, 1120}, - {2949, 1719}, - {2310, 3582}, - {3782, 3868}, - {4360, 752}, - {1413, 2521}, - {3820, 2527}, - {2837, 2958}, - {3046, 1935}, - {3001, 3343}, - {4276, 478}, - {620, 2041}, - {4697, 3253}, - {1305, 3584}, - {2141, 1119}, - {3708, 2380}, - {1507, 2217}, - {535, 2860}, - {562, 2070}, - {666, 247}, - {2957, 1962}, - {2337, 3376}, - {3007, 1782}, - {608, 351}, - {2893, 154}, - {3898, 813}, - {3673, 3745}, - {3776, 1402}, - {3641, 1997}, - {1280, 3623}, - {3078, 1514}, - {1745, 2732}, - {4610, 439}, - {2318, 528}, - {758, 1031}, - {939, 3669}, - {897, 1606}, - {1612, 2492}, - {3307, 3794}, - {1524, 1419}, - {2479, 795}, - {3360, 3841}, - {19, 1355}, - {2769, 1270}, - {4032, 1988}, - {4119, 3009}, - {4167, 315}, - {3148, 3228}, - {1769, 2877}, - {3569, 514}, - {1940, 1204}, - {1500, 2666}, - {2125, 730}, - {1105, 224}, - {1158, 1910}, - {1409, 415}, - {1718, 2007}, - {2798, 870}, - {3642, 3797}, - {399, 1294}, - {3062, 1478}, - {3742, 1805}, - {3836, 3055}, - {3864, 34}, - {3451, 3187}, - {1476, 2731}, - {3275, 590}, - {221, 2427}, - {824, 1494}, - {2686, 3555}, - {1792, 3195}, - {1638, 639}, - {1667, 2750}, - {942, 1763}, - {722, 2292}, - {3122, 3663}, - {990, 3538}, - {2247, 3262}, - {2384, 455}, - {4657, 309}, - {603, 2969}, - {2440, 1021}, - {1577, 3644}, - {4755, 1669}, - {2212, 1484}, - {882, 2172}, - {809, 2753}, - {773, 641}, - {1773, 3451}, - {3150, 3081}, - {1366, 118}, - {4683, 581}, - {3997, 3181}, - {2364, 2056}, - {4577, 2200}, - {3336, 1546}, - {3103, 2383}, - {3190, 969}, - {4210, 3792}, - {713, 2495}, - {3647, 853}, - {1591, 3453}, - {4733, 1920}, - {2178, 1755}, - {914, 1420}, - {783, 2523}, - {743, 919}, - {3168, 2408}, - {1368, 1026}, - {3196, 2236}, - {2668, 1745}, - {836, 3702}, - {3249, 3595}, - {4520, 3224}, - {4721, 392}, - {2389, 202}, - {3024, 2930}, - {1459, 2628}, - {1960, 1245}, - {3828, 3769}, - {1353, 3827}, - {693, 3383}, - {380, 305}, - {2157, 2033}, - {2828, 490}, - {2207, 2850}, - {3590, 3209}, - {1208, 2795}, - {3411, 2744}, - {4378, 2436}, - {4315, 1612}, - {4221, 3677}, - {2942, 823}, - {2012, 1450}, - {2619, 3822}, - {673, 749}, - {1031, 3853}, - {3054, 1413}, - {387, 1227}, - {1490, 1939}, - {1297, 340}, - {1179, 3246}, - {3747, 2864}, - {801, 470}, - {4423, 1464}, - {3705, 2471}, - {2145, 665}, - {4284, 846}, - {3512, 190}, - {3508, 3524}, - {3392, 1841}, - {4059, 2205}, - {2249, 3641}, - {1781, 1028}, - {4567, 2297}, - {2357, 2416}, - {724, 2734}, - {977, 2146}, - {860, 3124}, - {3344, 1808}, - {1559, 3448}, - {1796, 3535}, - {2237, 1171}, - {4168, 2444}, - {1616, 2286}, - {223, 2799}, - {184, 2012}, - {2315, 335}, - {2623, 1892}, - {2013, 3314}, - {50, 1501}, - {959, 2422}, - {2533, 1198}, - {303, 1034}, - {1691, 535}, - {1730, 3122}, - {1850, 2145}, - {821, 3094}, - {4094, 3439}, - {2614, 2210}, - {3239, 2718}, - {168, 389}, - {2652, 593}, - {3986, 1082}, - {4148, 3716}, - {4103, 1583}, - {3134, 2477}, - {1818, 3808}, - {3602, 1476}, - {101, 1767}, - {2539, 365}, - {322, 128}, - {1734, 3731}, - {1861, 1378}, - {837, 2423}, - {4083, 3634}, - {1132, 1496}, - {4110, 3593}, - {4596, 1131}, - {4016, 2232}, - {2785, 2872}, - {2482, 2087}, - {2606, 3311}, - {4732, 267}, - {30, 1944}, - {4250, 3386}, - {550, 774}, - {3502, 2562}, - {1157, 2636}, - {1918, 2903}, - {2128, 1866}, - {466, 505}, - {3691, 2739}, - {4452, 2177}, - {1284, 3264}, - {3913, 3205}, - {2883, 3666}, - {4311, 1436}, - {595, 841}, - {1342, 3449}, - {2114, 104}, - {1516, 3087}, - {523, 2503}, - {683, 3739}, - {2011, 1019}, - {2944, 1551}, - {2306, 2927}, - {3075, 1998}, - {1014, 3504}, - {3624, 3395}, - {4303, 3837}, - {4394, 683}, - {4420, 2607}, - {2875, 1750}, - {2074, 1089}, - {2721, 2239}, - {865, 467}, - {177, 3248}, - {3251, 2161}, - {842, 2009}, - {2388, 1690}, - {2241, 2279}, - {2260, 1172}, - {320, 3855}, - {4523, 2649}, - {447, 750}, - {26, 646}, - {972, 3125}, - {2514, 2030}, - {365, 2150}, - {1647, 1604}, - {1786, 2418}, - {1819, 1029}, - {802, 3735}, - {1190, 921}, - {1854, 2878}, - {2186, 2002}, - {4215, 3137}, - {1598, 3240}, - {243, 3606}, - {160, 1185}, - {96, 2293}, - {2374, 1206}, - {2567, 796}, - {1956, 2664}, - {4144, 2231}, - {4563, 1739}, - {1768, 3698}, - {4027, 3594}, - {2777, 3231}, - {2617, 2845}, - {4751, 1982}, - {17, 226}, - {4222, 2925}, - {1851, 2670}, - {2205, 1207}, - {4198, 3749}, - {1570, 3850}, - {291, 3408}, - {108, 350}, - {53, 2966}, - {2359, 2001}, - {1959, 2876}, - {2625, 594}, - {3227, 3183}, - {193, 2068}, - {2685, 2209}, - {3955, 1543}, - {4138, 965}, - {3141, 3795}, - {1793, 2491}, - {3588, 862}, - {2055, 159}, - {1371, 3427}, - {4385, 1879}, - {1942, 1789}, - {1269, 1460}, - {1000, 2549}, - {1090, 889}, - {1542, 3622}, - {3398, 2449}, - {1593, 1065}, - {3025, 1720}, - {3430, 2268}, - {621, 993}, - {2841, 1118}, - {3818, 479}, - {3753, 3278}, - {3517, 2953}, - {1411, 3379}, - {3191, 1957}, - {1470, 2311}, - {1973, 1627}, - {3822, 3632}, - {698, 3291}, - {378, 504}, - {505, 2861}, - {2154, 1869}, - {2824, 367}, - {2199, 2987}, - {3527, 3687}, - {2915, 1017}, - {1168, 656}, - {3505, 2355}, - {4408, 2759}, - {4290, 2178}, - {4314, 3203}, - {3043, 102}, - {1911, 1817}, - {2534, 3493}, - {700, 1352}, - {362, 2551}, - {3096, 783}, - {973, 885}, - {2396, 1791}, - {109, 2773}, - {4677, 3133}, - {617, 2126}, - {206, 1257}, - {840, 2635}, - {2666, 910}, - {180, 773}, - {1808, 250}, - {1620, 3348}, - {1659, 1875}, - {924, 2856}, - {3977, 3257}, - {1670, 3763}, - {2334, 873}, - {4058, 2653}, - {1728, 2546}, - {75, 3048}, - {309, 1800}, - {256, 3430}, - {2217, 605}, - {2745, 2164}, - {2144, 3147}, - {3966, 3487}, - {4715, 88}, - {1602, 2940}, - {4155, 3029}, - {2632, 2542}, - {2641, 1444}, - {2760, 3821}, - {4607, 1005}, - {236, 1570}, - {4365, 3674}, - {1715, 3152}, - {2316, 604}, - {4063, 2868}, - {1738, 2771}, - {72, 2370}, - {318, 1534}, - {274, 3624}, - {2239, 876}, - {2731, 1410}, - {2107, 3757}, - {346, 809}, - {2492, 727}, - {4131, 358}, - {4005, 3415}, - {3959, 1956}, - {3255, 2808}, - {1662, 3287}, - {3471, 2115}, - {1935, 1656}, - {1494, 2281}, - {2124, 1169}, - {1097, 430}, - {1160, 3245}, - {1264, 2010}, - {1416, 2961}, - {3525, 3368}, - {1725, 1902}, - {2902, 55}, - {3543, 3523}, - {488, 1981}, - {2995, 1458}, - {3665, 1366}, - {3905, 2193}, - {3802, 852}, - {3386, 3719}, - {1541, 2333}, - {3324, 966}, - {3535, 759}, - {2907, 3877} + {0, 3414}, + {0, 3020}, + {0, 1226}, + {0, 299}, + {0, 330}, + {0, 1484}, + {4931, 1}, + {1242, 1}, + {4768, 1}, + {4621, 1}, + {1907, 1}, + {4609, 1}, + {2023, 1}, + {4753, 1}, + {2667, 1}, + {927, 1}, + {3240, 1}, + {4772, 1}, + {5025, 1}, + {4770, 1}, + {2260, 1}, + {4379, 1}, + {3037, 1}, + {0, 3065}, + {0, 3578}, + {0, 729}, + {0, 3883}, + {0, 2085}, + {0, 1205}, + {0, 2810}, + {0, 3205}, + {0, 1214}, + {0, 1995}, + {0, 1961}, + {0, 923}, + {0, 3645}, + {0, 1059}, + {0, 2943}, + {0, 3780}, + {0, 1790}, + {0, 237}, + {0, 3784}, + {0, 3087}, + {0, 3532}, + {0, 2235}, + {0, 1356}, + {0, 2567}, + {0, 577}, + {0, 1663}, + {0, 3249}, + {0, 2749}, + {0, 1655}, + {0, 372}, + {0, 370}, + {0, 1460}, + {0, 73}, + {0, 1910}, + {0, 2508}, + {0, 3454}, + {0, 3226}, + {0, 2533}, + {0, 1499}, + {0, 2423}, + {0, 300}, + {0, 1393}, + {0, 3500}, + {0, 2939}, + {0, 1406}, + {0, 185}, + {0, 110}, + {0, 1619}, + {0, 2630}, + {0, 1260}, + {0, 3127}, + {0, 2312}, + {0, 367}, + {0, 2204}, + {0, 2323}, + {0, 3281}, + {0, 2835}, + {4812, 1}, + {1596, 196}, + {45, 169}, + {1562, 4}, + {682, 163}, + {27, 157}, + {276, 80}, + {94, 139}, + {2051, 213}, + {35, 76}, + {269, 150}, + {806, 212}, + {1725, 19}, + {923, 360}, + {805, 206}, + {17, 89}, + {715, 21}, + {835, 265}, + {155, 350}, + {212, 1141}, + {1209, 387}, + {708, 529}, + {542, 1546}, + {4924, 1}, + {5126, 1}, + {3481, 874}, + {1642, 352}, + {3158, 3415}, + {3788, 2459}, + {3964, 3626}, + {124, 1026}, + {1317, 3091}, + {4799, 1}, + {4846, 1}, + {4920, 1}, + {1553, 2446}, + {1753, 3865}, + {2534, 835}, + {2539, 3898}, + {831, 1382}, + {4177, 2512}, + {397, 196}, + {41, 158}, + {66, 48}, + {36, 187}, + {157, 163}, + {788, 55}, + {64, 22}, + {184, 160}, + {337, 397}, + {732, 54}, + {199, 80}, + {630, 139}, + {133, 213}, + {51, 76}, + {1086, 150}, + {1, 212}, + {888, 19}, + {250, 67}, + {4183, 3652}, + {1190, 3266}, + {54, 254}, + {812, 341}, + {177, 27}, + {1128, 6}, + {1185, 112}, + {780, 927}, + {2651, 94}, + {1020, 369}, + {48, 533}, + {532, 186}, + {411, 726}, + {944, 1575}, + {39, 484}, + {1094, 2239}, + {632, 351}, + {4035, 94}, + {787, 123}, + {1598, 887}, + {794, 314}, + {673, 697}, + {1241, 258}, + {1713, 807}, + {2019, 63}, + {545, 274}, + {83, 254}, + {299, 341}, + {453, 27}, + {740, 6}, + {1062, 112}, + {955, 927}, + {763, 94}, + {1226, 369}, + {2432, 533}, + {902, 186}, + {455, 726}, + {1299, 1575}, + {1940, 484}, + {1737, 2239}, + {203, 351}, + {2944, 123}, + {1161, 123}, + {547, 887}, + {877, 314}, + {1022, 697}, + {889, 258}, + {1256, 807}, + {1064, 63}, + {1674, 544}, + {3333, 6}, + {256, 94}, + {4495, 533}, + {1342, 697}, + {3444, 351}, + {1670, 15}, + {3311, 94}, + {3623, 6}, + {2109, 94}, + {1108, 533}, + {2782, 697}, + {2135, 351}, + {4124, 15}, + {1007, 94}, + {760, 6}, + {1609, 94}, + {1722, 533}, + {2562, 697}, + {1881, 351}, + {4636, 15}, + {1711, 94}, + {1088, 6}, + {4012, 94}, + {725, 533}, + {1588, 697}, + {1764, 351}, + {2499, 15}, + {1578, 94}, + {3250, 6}, + {539, 94}, + {4440, 533}, + {271, 697}, + {4733, 351}, + {2833, 15}, + {2676, 1350}, + {1910, 1350}, + {3447, 402}, + {1984, 713}, + {1987, 488}, + {3763, 1235}, + {1251, 1229}, + {2737, 1301}, + {2381, 266}, + {3026, 2173}, + {2156, 633}, + {150, 848}, + {619, 925}, + {3853, 2449}, + {4507, 2058}, + {1716, 1143}, + {3361, 612}, + {678, 652}, + {4405, 876}, + {305, 1317}, + {4635, 681}, + {2872, 1774}, + {2761, 417}, + {1788, 2208}, + {2136, 890}, + {3897, 1612}, + {1107, 1602}, + {2606, 476}, + {2229, 673}, + {2891, 68}, + {2004, 660}, + {330, 1674}, + {468, 3679}, + {3705, 1087}, + {654, 2779}, + {3528, 402}, + {1382, 713}, + {4522, 488}, + {183, 1235}, + {4209, 1229}, + {466, 1301}, + {2398, 266}, + {2017, 2173}, + {3443, 633}, + {3596, 848}, + {541, 925}, + {4220, 2058}, + {1675, 1143}, + {3203, 652}, + {1330, 1317}, + {3457, 681}, + {4067, 1774}, + {3694, 417}, + {488, 2208}, + {1246, 890}, + {2927, 1421}, + {1990, 1612}, + {3980, 2232}, + {853, 660}, + {3657, 75}, + {1123, 2598}, + {1785, 2640}, + {1374, 1487}, + {2873, 1080}, + {0, 3323}, + {0, 3691}, + {0, 1030}, + {0, 2009}, + {0, 144}, + {0, 3420}, + {0, 2479}, + {0, 787}, + {0, 3875}, + {0, 718}, + {0, 2253}, + {0, 2700}, + {0, 2089}, + {0, 1199}, + {0, 1376}, + {0, 2600}, + {0, 2636}, + {0, 810}, + {0, 3809}, + {0, 879}, + {0, 2417}, + {0, 2867}, + {0, 2075}, + {0, 961}, + {0, 1351}, + {0, 2515}, + {0, 3155}, + {0, 2060}, + {0, 2822}, + {0, 1988}, + {0, 3383}, + {0, 3747}, + {0, 818}, + {0, 1940}, + {172, 784}, + {2496, 509}, + {570, 409}, + {550, 74}, + {1278, 696}, + {868, 508}, + {669, 210}, + {2549, 145}, + {222, 1090}, + {2428, 238}, + {307, 865}, + {803, 1452}, + {572, 1057}, + {1954, 786}, + {19, 383}, + {924, 390}, + {102, 204}, + {59, 11}, + {656, 285}, + {1100, 70}, + {1726, 936}, + {716, 126}, + {195, 375}, + {773, 1256}, + {154, 135}, + {3407, 39}, + {431, 218}, + {2598, 2554}, + {378, 1243}, + {1820, 1470}, + {74, 262}, + {1637, 898}, + {1730, 2}, + {4327, 1567}, + {423, 3833}, + {4554, 3394}, + {28, 307}, + {2166, 1411}, + {2347, 1184}, + {3098, 3712}, + {2976, 1768}, + {1313, 3343}, + {3742, 296}, + {4295, 3085}, + {1075, 593}, + {7, 703}, + {3136, 1288}, + {1921, 1415}, + {4486, 1502}, + {560, 994}, + {4697, 365}, + {220, 781}, + {2035, 1262}, + {2477, 2250}, + {3233, 827}, + {2356, 2369}, + {3982, 29}, + {915, 3501}, + {2928, 117}, + {2198, 2387}, + {2701, 1310}, + {2486, 1702}, + {449, 536}, + {208, 159}, + {4155, 3062}, + {4028, 305}, + {2262, 1945}, + {2664, 1889}, + {1196, 1873}, + {3868, 3263}, + {3412, 2045}, + {3220, 3}, + {1733, 196}, + {4524, 158}, + {197, 48}, + {3532, 57}, + {1554, 154}, + {3260, 187}, + {1937, 169}, + {1078, 119}, + {882, 167}, + {4737, 4}, + {4583, 163}, + {1656, 115}, + {3266, 55}, + {562, 22}, + {4492, 157}, + {217, 160}, + {4698, 397}, + {2792, 54}, + {2717, 80}, + {1879, 139}, + {4488, 213}, + {1542, 76}, + {3379, 150}, + {2, 212}, + {4585, 19}, + {443, 67}, + {4315, 2683}, + {2805, 2455}, + {1435, 1291}, + {4627, 448}, + {1865, 2703}, + {2634, 3423}, + {1660, 152}, + {2148, 2443}, + {1030, 3479}, + {3840, 3774}, + {605, 668}, + {505, 1106}, + {1338, 148}, + {3195, 768}, + {1681, 3950}, + {1285, 3019}, + {813, 1104}, + {4540, 588}, + {1583, 1414}, + {4368, 2138}, + {444, 707}, + {3113, 3866}, + {1770, 1648}, + {3377, 815}, + {1407, 2701}, + {929, 3627}, + {1091, 2279}, + {4279, 1268}, + {4281, 2399}, + {1332, 1108}, + {3542, 732}, + {267, 1172}, + {4736, 2620}, + {538, 3095}, + {4443, 1797}, + {2498, 649}, + {2963, 1565}, + {1589, 688}, + {1595, 1394}, + {4381, 3621}, + {428, 1142}, + {3105, 1500}, + {1782, 1294}, + {3388, 1714}, + {1401, 3028}, + {908, 3937}, + {1096, 2361}, + {4284, 1629}, + {4160, 3341}, + {2417, 1788}, + {2507, 1927}, + {1056, 523}, + {3730, 3120}, + {776, 1882}, + {4043, 1130}, + {3533, 2150}, + {602, 3946}, + {3263, 767}, + {1922, 2339}, + {3523, 2736}, + {1570, 2176}, + {750, 1132}, + {1221, 1433}, + {4425, 2654}, + {1071, 35}, + {1557, 3491}, + {2971, 195}, + {4135, 2688}, + {2371, 466}, + {2568, 3228}, + {1099, 376}, + {3761, 2900}, + {4019, 1407}, + {3513, 282}, + {3104, 2119}, + {2313, 2807}, + {4085, 2134}, + {798, 2772}, + {2819, 2187}, + {2531, 3897}, + {2303, 757}, + {553, 1750}, + {72, 462}, + {3989, 3213}, + {4708, 1050}, + {1818, 2279}, + {3129, 1675}, + {419, 2331}, + {4329, 775}, + {20, 138}, + {4562, 3496}, + {2575, 3689}, + {1693, 1220}, + {1916, 2147}, + {4671, 3314}, + {10, 425}, + {3387, 3254}, + {1403, 1882}, + {3118, 1364}, + {1765, 2476}, + {331, 3537}, + {4557, 72}, + {3367, 2122}, + {3133, 2213}, + {3902, 3210}, + {3993, 2901}, + {80, 1009}, + {4246, 1660}, + {1664, 2310}, + {3214, 721}, + {1351, 182}, + {3434, 3525}, + {4088, 2564}, + {3714, 3725}, + {473, 1175}, + {459, 3781}, + {3365, 1331}, + {1523, 2604}, + {4689, 1269}, + {327, 3582}, + {4341, 3113}, + {650, 534}, + {2230, 1703}, + {2124, 817}, + {3602, 870}, + {4263, 1307}, + {1669, 2641}, + {3206, 1152}, + {1343, 640}, + {4104, 2228}, + {3703, 3827}, + {465, 750}, + {2692, 552}, + {2234, 3221}, + {3674, 624}, + {1103, 3092}, + {3953, 2625}, + {874, 1314}, + {1513, 99}, + {1628, 2040}, + {2637, 2761}, + {3463, 3643}, + {404, 1669}, + {4406, 2223}, + {1836, 588}, + {3357, 3841}, + {1497, 3489}, + {3577, 65}, + {3935, 1313}, + {3857, 985}, + {622, 3560}, + {3696, 2191}, + {2062, 3278}, + {2989, 478}, + {995, 3320}, + {4077, 1932}, + {1296, 1434}, + {3191, 2509}, + {3599, 2737}, + {2155, 2073}, + {2020, 385}, + {1261, 2108}, + {2724, 2676}, + {2405, 47}, + {3062, 686}, + {2126, 3888}, + {169, 992}, + {655, 3272}, + {3836, 520}, + {1447, 1673}, + {3605, 2216}, + {289, 1604}, + {4653, 3856}, + {701, 3483}, + {4384, 69}, + {2636, 1302}, + {3019, 979}, + {1516, 3567}, + {1327, 2751}, + {4274, 364}, + {668, 3300}, + {3353, 437}, + {1833, 2974}, + {3582, 2534}, + {1491, 1466}, + {820, 211}, + {1289, 2197}, + {4370, 2841}, + {3082, 2758}, + {101, 427}, + {1614, 502}, + {3549, 1437}, + {1882, 1418}, + {1464, 246}, + {226, 2164}, + {3490, 3848}, + {429, 1441}, + {4380, 2456}, + {1802, 1389}, + {3301, 3639}, + {1533, 3279}, + {3626, 407}, + {3984, 1547}, + {3807, 691}, + {657, 3761}, + {677, 1209}, + {3554, 2371}, + {1322, 1579}, + {109, 924}, + {4235, 292}, + {515, 3404}, + {2414, 1044}, + {3495, 3547}, + {4374, 2350}, + {1790, 1507}, + {3304, 3744}, + {1547, 3385}, + {3817, 1125}, + {670, 3658}, + {818, 1748}, + {2519, 3421}, + {2409, 267}, + {3841, 3362}, + {1305, 1997}, + {4075, 1485}, + {998, 2359}, + {1326, 3330}, + {1842, 3030}, + {2743, 1858}, + {3632, 724}, + {589, 2467}, + {4208, 1425}, + {1636, 2532}, + {3168, 1005}, + {1383, 503}, + {3487, 3309}, + {4130, 2354}, + {3666, 3930}, + {497, 893}, + {2158, 174}, + {2894, 3463}, + {878, 82}, + {3946, 2714}, + {1106, 2241}, + {3671, 1597}, + {3476, 1829}, + {1963, 3047}, + {2102, 3511}, + {3873, 1837}, + {1179, 2958}, + {2632, 1892}, + {2278, 3303}, + {2870, 3716}, + {512, 172}, + {3649, 3398}, + {4369, 730}, + {1580, 2474}, + {3497, 1420}, + {137, 2524}, + {4537, 1014}, + {478, 498}, + {2742, 2343}, + {2904, 3924}, + {1328, 899}, + {1517, 1851}, + {463, 43}, + {3164, 3438}, + {1633, 2118}, + {3489, 1621}, + {1381, 2277}, + {1011, 3181}, + {1112, 2929}, + {4258, 1722}, + {1368, 225}, + {4308, 3058}, + {636, 1731}, + {3309, 3005}, + {1786, 541}, + {1538, 3586}, + {854, 2745}, + {1243, 3369}, + {4404, 18}, + {1724, 1585}, + {4514, 3575}, + {265, 1206}, + {3545, 3615}, + {1619, 1359}, + {3249, 1760}, + {1862, 3077}, + {4701, 1685}, + {4699, 2458}, + {1793, 762}, + {3115, 3843}, + {442, 670}, + {4312, 2225}, + {8, 2719}, + {4584, 2132}, + {2558, 1401}, + {1720, 2575}, + {1717, 1474}, + {4508, 3877}, + {279, 783}, + {3555, 3921}, + {1608, 1706}, + {3238, 2148}, + {1065, 3579}, + {961, 2516}, + {4692, 1341}, + {3765, 3295}, + {1989, 2110}, + {2926, 2738}, + {918, 2167}, + {4137, 3499}, + {1204, 3939}, + {3918, 776}, + {3124, 1712}, + {3510, 475}, + {1902, 2392}, + {4658, 1197}, + {73, 3583}, + {3404, 1115}, + {1455, 2606}, + {3093, 3007}, + {1698, 1736}, + {1191, 782}, + {799, 1489}, + {4559, 2269}, + {951, 601}, + {2299, 2036}, + {3743, 2844}, + {4040, 920}, + {781, 3830}, + {1602, 2915}, + {1706, 3223}, + {2581, 442}, + {2713, 1987}, + {1023, 3214}, + {2028, 3158}, + {2799, 1742}, + {2367, 1250}, + {2543, 2560}, + {4474, 3529}, + {4581, 2795}, + {774, 2137}, + {3358, 1188}, + {1715, 3591}, + {4271, 1122}, + {405, 2599}, + {4617, 3014}, + {56, 791}, + {3217, 3196}, + {282, 2000}, + {4598, 2872}, + {1450, 2081}, + {3402, 3419}, + {3870, 1865}, + {4024, 600}, + {3275, 3197}, + {366, 2001}, + {1398, 2080}, + {3398, 3417}, + {3108, 868}, + {3911, 1866}, + {4020, 599}, + {65, 2558}, + {530, 892}, + {4236, 3750}, + {1684, 826}, + {3188, 2341}, + {1321, 2833}, + {3466, 1985}, + {4080, 1016}, + {3687, 1275}, + {481, 2470}, + {484, 1698}, + {3392, 3669}, + {1535, 1069}, + {4664, 3721}, + {358, 1462}, + {4378, 1895}, + {612, 2961}, + {2238, 3791}, + {2145, 2297}, + {3587, 1561}, + {3595, 2217}, + {540, 1028}, + {4221, 3647}, + {1676, 971}, + {3202, 2450}, + {1329, 2941}, + {3456, 1857}, + {4066, 889}, + {487, 2365}, + {1026, 79}, + {2714, 2979}, + {2241, 1878}, + {3653, 2926}, + {1135, 423}, + {3987, 949}, + {834, 3654}, + {1525, 2886}, + {1653, 3458}, + {2625, 235}, + {3432, 1299}, + {368, 3762}, + {4397, 881}, + {1856, 3818}, + {3315, 1535}, + {3609, 2865}, + {3927, 3653}, + {3824, 2659}, + {642, 1440}, + {3702, 3363}, + {2073, 1819}, + {3016, 3036}, + {990, 1747}, + {4091, 3150}, + {1306, 3556}, + {3837, 1084}, + {3213, 2183}, + {2125, 3485}, + {1988, 3072}, + {3762, 208}, + {1250, 3401}, + {2736, 288}, + {2382, 2854}, + {2154, 1574}, + {148, 380}, + {620, 1814}, + {3852, 2954}, + {4222, 1308}, + {1427, 3767}, + {3593, 871}, + {324, 3811}, + {4625, 1545}, + {664, 2072}, + {4414, 2869}, + {2626, 3644}, + {2983, 2648}, + {1524, 1447}, + {1356, 224}, + {4305, 3057}, + {684, 1732}, + {3318, 3006}, + {1859, 542}, + {3608, 1113}, + {824, 2744}, + {1316, 3370}, + {4358, 17}, + {191, 1689}, + {3283, 3667}, + {1751, 1072}, + {416, 1464}, + {4549, 1900}, + {40, 2960}, + {2188, 3786}, + {2336, 2304}, + {3091, 1558}, + {699, 41}, + {3576, 2944}, + {1339, 699}, + {4498, 2893}, + {126, 379}, + {4256, 984}, + {500, 3680}, + {2436, 2855}, + {1976, 3486}, + {3485, 193}, + {3473, 3201}, + {410, 2005}, + {4361, 2868}, + {1825, 2082}, + {3634, 872}, + {3962, 1869}, + {3787, 592}, + {687, 3325}, + {695, 535}, + {3566, 2839}, + {1353, 1974}, + {4503, 2794}, + {115, 215}, + {4250, 843}, + {506, 3783}, + {2448, 2968}, + {1968, 3156}, + {2725, 2580}, + {883, 922}, + {3971, 3778}, + {2018, 858}, + {2880, 2376}, + {2228, 2806}, + {2608, 1950}, + {4354, 1048}, + {4521, 1233}, + {822, 2486}, + {519, 3510}, + {3425, 1828}, + {1482, 2971}, + {4630, 1898}, + {317, 3299}, + {4417, 3718}, + {660, 1062}, + {2277, 1972}, + {2112, 173}, + {3625, 3388}, + {1959, 1412}, + {3733, 3932}, + {1282, 698}, + {2760, 3868}, + {2420, 1641}, + {2999, 2094}, + {2105, 2698}, + {100, 3632}, + {679, 2469}, + {3820, 1270}, + {3045, 1422}, + {1008, 2517}, + {4132, 1017}, + {1271, 492}, + {3790, 3317}, + {3166, 2340}, + {3645, 3922}, + {2099, 894}, + {1355, 3517}, + {4297, 1835}, + {3321, 1884}, + {1850, 3305}, + {3614, 3713}, + {1456, 1068}, + {823, 1962}, + {1312, 168}, + {4351, 3392}, + {4230, 2457}, + {1428, 761}, + {3591, 3844}, + {311, 665}, + {4628, 2226}, + {659, 1183}, + {4418, 2126}, + {2633, 1159}, + {2993, 1402}, + {1537, 2573}, + {3274, 1112}, + {367, 2442} }; static const lxb_codepoint_t lxb_unicode_decomposition_cps[6982] = @@ -191096,7 +195657,7 @@ static const lxb_codepoint_t lxb_unicode_decomposition_cps[6982] = 0x4D56, 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x2A600 }; -static const lxb_codepoint_t lxb_unicode_idna_cps[5400] = +static const lxb_codepoint_t lxb_unicode_idna_cps[5428] = { 0x0073, 0x0073, 0x03C3, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, @@ -191477,9364 +196038,9397 @@ static const lxb_codepoint_t lxb_unicode_idna_cps[5400] = 0xA791, 0xA793, 0xA797, 0xA799, 0xA79B, 0xA79D, 0xA79F, 0xA7A1, 0xA7A3, 0xA7A5, 0xA7A7, 0xA7A9, 0x026C, 0x029E, 0x0287, 0xAB53, 0xA7B5, 0xA7B7, 0xA7B9, 0xA7BB, 0xA7BD, 0xA7BF, 0xA7C1, 0xA7C3, - 0xA794, 0x1D8E, 0xA7C8, 0xA7CA, 0x0264, 0xA7CD, 0xA7D1, 0xA7D7, - 0xA7D9, 0xA7DB, 0x019B, 0xA7F6, 0xAB37, 0xAB52, 0x028D, 0x13A0, - 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, 0x13A6, 0x13A7, 0x13A8, - 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, 0x13AE, 0x13AF, 0x13B0, - 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, 0x13B6, 0x13B7, 0x13B8, - 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, 0x13BE, 0x13BF, 0x13C0, - 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, 0x13C6, 0x13C7, 0x13C8, - 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, 0x13CE, 0x13CF, 0x13D0, - 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, 0x13D6, 0x13D7, 0x13D8, - 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, 0x13DE, 0x13DF, 0x13E0, - 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, 0x13E6, 0x13E7, 0x13E8, - 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, 0x13EE, 0x13EF, 0x8C48, - 0x66F4, 0x8CC8, 0x6ED1, 0x4E32, 0x53E5, 0x5951, 0x5587, 0x5948, - 0x61F6, 0x7669, 0x7F85, 0x863F, 0x87BA, 0x88F8, 0x908F, 0x6A02, - 0x6D1B, 0x70D9, 0x73DE, 0x843D, 0x916A, 0x99F1, 0x4E82, 0x5375, - 0x6B04, 0x721B, 0x862D, 0x9E1E, 0x5D50, 0x6FEB, 0x85CD, 0x8964, - 0x62C9, 0x81D8, 0x881F, 0x5ECA, 0x6717, 0x6D6A, 0x72FC, 0x90CE, - 0x4F86, 0x51B7, 0x52DE, 0x64C4, 0x6AD3, 0x7210, 0x76E7, 0x8606, - 0x865C, 0x8DEF, 0x9732, 0x9B6F, 0x9DFA, 0x788C, 0x797F, 0x7DA0, - 0x83C9, 0x9304, 0x8AD6, 0x58DF, 0x5F04, 0x7C60, 0x807E, 0x7262, - 0x78CA, 0x8CC2, 0x96F7, 0x58D8, 0x5C62, 0x6A13, 0x6DDA, 0x6F0F, - 0x7D2F, 0x7E37, 0x964B, 0x52D2, 0x808B, 0x51DC, 0x51CC, 0x7A1C, - 0x7DBE, 0x83F1, 0x9675, 0x8B80, 0x62CF, 0x8AFE, 0x4E39, 0x5BE7, - 0x6012, 0x7387, 0x7570, 0x5317, 0x78FB, 0x4FBF, 0x5FA9, 0x4E0D, - 0x6CCC, 0x6578, 0x7D22, 0x53C3, 0x585E, 0x7701, 0x8449, 0x8AAA, - 0x6BBA, 0x6C88, 0x62FE, 0x82E5, 0x63A0, 0x7565, 0x4EAE, 0x5169, - 0x51C9, 0x6881, 0x7CE7, 0x826F, 0x8AD2, 0x91CF, 0x52F5, 0x5442, - 0x5EEC, 0x65C5, 0x6FFE, 0x792A, 0x95AD, 0x9A6A, 0x9E97, 0x9ECE, - 0x66C6, 0x6B77, 0x8F62, 0x5E74, 0x6190, 0x6200, 0x649A, 0x6F23, - 0x7149, 0x7489, 0x79CA, 0x7DF4, 0x806F, 0x8F26, 0x84EE, 0x9023, - 0x934A, 0x5217, 0x52A3, 0x54BD, 0x70C8, 0x88C2, 0x5EC9, 0x5FF5, - 0x637B, 0x6BAE, 0x7C3E, 0x7375, 0x56F9, 0x5DBA, 0x601C, 0x73B2, - 0x7469, 0x7F9A, 0x8046, 0x9234, 0x96F6, 0x9748, 0x9818, 0x4F8B, - 0x79AE, 0x91B4, 0x96B8, 0x60E1, 0x4E86, 0x50DA, 0x5BEE, 0x5C3F, - 0x6599, 0x71CE, 0x7642, 0x84FC, 0x907C, 0x6688, 0x962E, 0x5289, - 0x677B, 0x67F3, 0x6D41, 0x6E9C, 0x7409, 0x7559, 0x786B, 0x7D10, - 0x985E, 0x622E, 0x9678, 0x502B, 0x5D19, 0x6DEA, 0x8F2A, 0x5F8B, - 0x6144, 0x6817, 0x9686, 0x5229, 0x540F, 0x5C65, 0x6613, 0x674E, - 0x68A8, 0x6CE5, 0x7406, 0x75E2, 0x7F79, 0x88CF, 0x88E1, 0x96E2, - 0x533F, 0x6EBA, 0x541D, 0x71D0, 0x7498, 0x85FA, 0x96A3, 0x9C57, - 0x9E9F, 0x6797, 0x6DCB, 0x81E8, 0x7B20, 0x7C92, 0x72C0, 0x7099, - 0x8B58, 0x4EC0, 0x8336, 0x523A, 0x5207, 0x5EA6, 0x62D3, 0x7CD6, - 0x5B85, 0x6D1E, 0x66B4, 0x8F3B, 0x964D, 0x5ED3, 0x5140, 0x55C0, - 0x585A, 0x6674, 0x51DE, 0x732A, 0x76CA, 0x793C, 0x795E, 0x7965, - 0x798F, 0x9756, 0x7CBE, 0x8612, 0x8AF8, 0x9038, 0x90FD, 0x98EF, - 0x98FC, 0x9928, 0x9DB4, 0x90DE, 0x96B7, 0x4FAE, 0x50E7, 0x514D, - 0x52C9, 0x52E4, 0x5351, 0x559D, 0x5606, 0x5668, 0x5840, 0x58A8, - 0x5C64, 0x6094, 0x6168, 0x618E, 0x61F2, 0x654F, 0x65E2, 0x6691, - 0x6885, 0x6D77, 0x6E1A, 0x6F22, 0x716E, 0x722B, 0x7422, 0x7891, - 0x7949, 0x7948, 0x7950, 0x7956, 0x798D, 0x798E, 0x7A40, 0x7A81, - 0x7BC0, 0x7E09, 0x7E41, 0x7F72, 0x8005, 0x81ED, 0x8279, 0x8457, - 0x8910, 0x8996, 0x8B01, 0x8B39, 0x8CD3, 0x8D08, 0x8FB6, 0x96E3, - 0x97FF, 0x983B, 0x6075, 0x242EE, 0x8218, 0x4E26, 0x51B5, 0x5168, - 0x4F80, 0x5145, 0x5180, 0x52C7, 0x52FA, 0x5555, 0x5599, 0x55E2, - 0x58B3, 0x5944, 0x5954, 0x5A62, 0x5B28, 0x5ED2, 0x5ED9, 0x5F69, - 0x5FAD, 0x60D8, 0x614E, 0x6108, 0x6160, 0x6234, 0x63C4, 0x641C, - 0x6452, 0x6556, 0x671B, 0x6756, 0x6EDB, 0x6ECB, 0x701E, 0x77A7, - 0x7235, 0x72AF, 0x7471, 0x7506, 0x753B, 0x761D, 0x761F, 0x76DB, - 0x76F4, 0x774A, 0x7740, 0x78CC, 0x7AB1, 0x7C7B, 0x7D5B, 0x7F3E, - 0x8352, 0x83EF, 0x8779, 0x8941, 0x8986, 0x8ABF, 0x8ACB, 0x8AED, - 0x8B8A, 0x8F38, 0x9072, 0x9199, 0x9276, 0x967C, 0x97DB, 0x980B, - 0x9B12, 0x2284A, 0x22844, 0x233D5, 0x3B9D, 0x4018, 0x4039, 0x25249, - 0x25CD0, 0x27ED3, 0x9F43, 0x9F8E, 0x0066, 0x0066, 0x0066, 0x0069, - 0x0066, 0x006C, 0x0066, 0x0066, 0x0069, 0x0066, 0x0066, 0x006C, - 0x0073, 0x0074, 0x0574, 0x0576, 0x0574, 0x0565, 0x0574, 0x056B, - 0x057E, 0x0576, 0x0574, 0x056D, 0x05D9, 0x05B4, 0x05F2, 0x05B7, - 0x05E2, 0x05D4, 0x05DB, 0x05DC, 0x05DD, 0x05E8, 0x05EA, 0x05E9, - 0x05C1, 0x05E9, 0x05C2, 0x05E9, 0x05BC, 0x05C1, 0x05E9, 0x05BC, - 0x05C2, 0x05D0, 0x05B7, 0x05D0, 0x05B8, 0x05D0, 0x05BC, 0x05D1, - 0x05BC, 0x05D2, 0x05BC, 0x05D3, 0x05BC, 0x05D4, 0x05BC, 0x05D5, - 0x05BC, 0x05D6, 0x05BC, 0x05D8, 0x05BC, 0x05D9, 0x05BC, 0x05DA, - 0x05BC, 0x05DB, 0x05BC, 0x05DC, 0x05BC, 0x05DE, 0x05BC, 0x05E0, - 0x05BC, 0x05E1, 0x05BC, 0x05E3, 0x05BC, 0x05E4, 0x05BC, 0x05E6, - 0x05BC, 0x05E7, 0x05BC, 0x05E8, 0x05BC, 0x05EA, 0x05BC, 0x05D5, - 0x05B9, 0x05D1, 0x05BF, 0x05DB, 0x05BF, 0x05E4, 0x05BF, 0x05D0, - 0x05DC, 0x0671, 0x067B, 0x067E, 0x0680, 0x067A, 0x067F, 0x0679, - 0x06A4, 0x06A6, 0x0684, 0x0683, 0x0686, 0x0687, 0x068D, 0x068C, - 0x068E, 0x0688, 0x0698, 0x0691, 0x06A9, 0x06AF, 0x06B3, 0x06B1, - 0x06BA, 0x06BB, 0x06C0, 0x06C1, 0x06BE, 0x06D2, 0x06D3, 0x06AD, - 0x06C6, 0x06C8, 0x06CB, 0x06C5, 0x06C9, 0x06D0, 0x0649, 0x0626, - 0x0627, 0x0626, 0x06D5, 0x0626, 0x0648, 0x0626, 0x06C7, 0x0626, - 0x06C6, 0x0626, 0x06C8, 0x0626, 0x06D0, 0x0626, 0x0649, 0x06CC, - 0x0626, 0x062C, 0x0626, 0x062D, 0x0626, 0x0645, 0x0626, 0x064A, - 0x0628, 0x062C, 0x0628, 0x062D, 0x0628, 0x062E, 0x0628, 0x0645, - 0x0628, 0x0649, 0x0628, 0x064A, 0x062A, 0x062C, 0x062A, 0x062D, - 0x062A, 0x062E, 0x062A, 0x0645, 0x062A, 0x0649, 0x062A, 0x064A, - 0x062B, 0x062C, 0x062B, 0x0645, 0x062B, 0x0649, 0x062B, 0x064A, - 0x062C, 0x062D, 0x062C, 0x0645, 0x062D, 0x062C, 0x062D, 0x0645, - 0x062E, 0x062C, 0x062E, 0x062D, 0x062E, 0x0645, 0x0633, 0x062C, - 0x0633, 0x062D, 0x0633, 0x062E, 0x0633, 0x0645, 0x0635, 0x062D, - 0x0635, 0x0645, 0x0636, 0x062C, 0x0636, 0x062D, 0x0636, 0x062E, - 0x0636, 0x0645, 0x0637, 0x062D, 0x0637, 0x0645, 0x0638, 0x0645, - 0x0639, 0x062C, 0x0639, 0x0645, 0x063A, 0x062C, 0x063A, 0x0645, - 0x0641, 0x062C, 0x0641, 0x062D, 0x0641, 0x062E, 0x0641, 0x0645, - 0x0641, 0x0649, 0x0641, 0x064A, 0x0642, 0x062D, 0x0642, 0x0645, - 0x0642, 0x0649, 0x0642, 0x064A, 0x0643, 0x0627, 0x0643, 0x062C, - 0x0643, 0x062D, 0x0643, 0x062E, 0x0643, 0x0644, 0x0643, 0x0645, - 0x0643, 0x0649, 0x0643, 0x064A, 0x0644, 0x062C, 0x0644, 0x062D, - 0x0644, 0x062E, 0x0644, 0x0645, 0x0644, 0x0649, 0x0644, 0x064A, - 0x0645, 0x062C, 0x0645, 0x062D, 0x0645, 0x062E, 0x0645, 0x0645, - 0x0645, 0x0649, 0x0645, 0x064A, 0x0646, 0x062C, 0x0646, 0x062D, - 0x0646, 0x062E, 0x0646, 0x0645, 0x0646, 0x0649, 0x0646, 0x064A, - 0x0647, 0x062C, 0x0647, 0x0645, 0x0647, 0x0649, 0x0647, 0x064A, - 0x064A, 0x062C, 0x064A, 0x062D, 0x064A, 0x062E, 0x064A, 0x0645, - 0x064A, 0x0649, 0x064A, 0x064A, 0x0630, 0x0670, 0x0631, 0x0670, - 0x0649, 0x0670, 0x0020, 0x064C, 0x0651, 0x0020, 0x064D, 0x0651, - 0x0020, 0x064E, 0x0651, 0x0020, 0x064F, 0x0651, 0x0020, 0x0650, - 0x0651, 0x0020, 0x0651, 0x0670, 0x0626, 0x0631, 0x0626, 0x0632, - 0x0626, 0x0646, 0x0628, 0x0631, 0x0628, 0x0632, 0x0628, 0x0646, - 0x062A, 0x0631, 0x062A, 0x0632, 0x062A, 0x0646, 0x062B, 0x0631, - 0x062B, 0x0632, 0x062B, 0x0646, 0x0645, 0x0627, 0x0646, 0x0631, - 0x0646, 0x0632, 0x0646, 0x0646, 0x064A, 0x0631, 0x064A, 0x0632, - 0x064A, 0x0646, 0x0626, 0x062E, 0x0626, 0x0647, 0x0628, 0x0647, - 0x062A, 0x0647, 0x0635, 0x062E, 0x0644, 0x0647, 0x0646, 0x0647, - 0x0647, 0x0670, 0x064A, 0x0647, 0x062B, 0x0647, 0x0633, 0x0647, - 0x0634, 0x0645, 0x0634, 0x0647, 0x0640, 0x064E, 0x0651, 0x0640, - 0x064F, 0x0651, 0x0640, 0x0650, 0x0651, 0x0637, 0x0649, 0x0637, - 0x064A, 0x0639, 0x0649, 0x0639, 0x064A, 0x063A, 0x0649, 0x063A, - 0x064A, 0x0633, 0x0649, 0x0633, 0x064A, 0x0634, 0x0649, 0x0634, - 0x064A, 0x062D, 0x0649, 0x062D, 0x064A, 0x062C, 0x0649, 0x062C, - 0x064A, 0x062E, 0x0649, 0x062E, 0x064A, 0x0635, 0x0649, 0x0635, - 0x064A, 0x0636, 0x0649, 0x0636, 0x064A, 0x0634, 0x062C, 0x0634, - 0x062D, 0x0634, 0x062E, 0x0634, 0x0631, 0x0633, 0x0631, 0x0635, - 0x0631, 0x0636, 0x0631, 0x0627, 0x064B, 0x062A, 0x062C, 0x0645, - 0x062A, 0x062D, 0x062C, 0x062A, 0x062D, 0x0645, 0x062A, 0x062E, - 0x0645, 0x062A, 0x0645, 0x062C, 0x062A, 0x0645, 0x062D, 0x062A, - 0x0645, 0x062E, 0x062C, 0x0645, 0x062D, 0x062D, 0x0645, 0x064A, - 0x062D, 0x0645, 0x0649, 0x0633, 0x062D, 0x062C, 0x0633, 0x062C, - 0x062D, 0x0633, 0x062C, 0x0649, 0x0633, 0x0645, 0x062D, 0x0633, - 0x0645, 0x062C, 0x0633, 0x0645, 0x0645, 0x0635, 0x062D, 0x062D, - 0x0635, 0x0645, 0x0645, 0x0634, 0x062D, 0x0645, 0x0634, 0x062C, - 0x064A, 0x0634, 0x0645, 0x062E, 0x0634, 0x0645, 0x0645, 0x0636, - 0x062D, 0x0649, 0x0636, 0x062E, 0x0645, 0x0637, 0x0645, 0x062D, - 0x0637, 0x0645, 0x0645, 0x0637, 0x0645, 0x064A, 0x0639, 0x062C, - 0x0645, 0x0639, 0x0645, 0x0645, 0x0639, 0x0645, 0x0649, 0x063A, - 0x0645, 0x0645, 0x063A, 0x0645, 0x064A, 0x063A, 0x0645, 0x0649, - 0x0641, 0x062E, 0x0645, 0x0642, 0x0645, 0x062D, 0x0642, 0x0645, - 0x0645, 0x0644, 0x062D, 0x0645, 0x0644, 0x062D, 0x064A, 0x0644, - 0x062D, 0x0649, 0x0644, 0x062C, 0x062C, 0x0644, 0x062E, 0x0645, - 0x0644, 0x0645, 0x062D, 0x0645, 0x062D, 0x062C, 0x0645, 0x062D, - 0x0645, 0x0645, 0x062D, 0x064A, 0x0645, 0x062C, 0x062D, 0x0645, - 0x062C, 0x0645, 0x0645, 0x062E, 0x062C, 0x0645, 0x062E, 0x0645, - 0x0645, 0x062C, 0x062E, 0x0647, 0x0645, 0x062C, 0x0647, 0x0645, - 0x0645, 0x0646, 0x062D, 0x0645, 0x0646, 0x062D, 0x0649, 0x0646, - 0x062C, 0x0645, 0x0646, 0x062C, 0x0649, 0x0646, 0x0645, 0x064A, - 0x0646, 0x0645, 0x0649, 0x064A, 0x0645, 0x0645, 0x0628, 0x062E, - 0x064A, 0x062A, 0x062C, 0x064A, 0x062A, 0x062C, 0x0649, 0x062A, - 0x062E, 0x064A, 0x062A, 0x062E, 0x0649, 0x062A, 0x0645, 0x064A, - 0x062A, 0x0645, 0x0649, 0x062C, 0x0645, 0x064A, 0x062C, 0x062D, - 0x0649, 0x062C, 0x0645, 0x0649, 0x0633, 0x062E, 0x0649, 0x0635, - 0x062D, 0x064A, 0x0634, 0x062D, 0x064A, 0x0636, 0x062D, 0x064A, - 0x0644, 0x062C, 0x064A, 0x0644, 0x0645, 0x064A, 0x064A, 0x062D, - 0x064A, 0x064A, 0x062C, 0x064A, 0x064A, 0x0645, 0x064A, 0x0645, - 0x0645, 0x064A, 0x0642, 0x0645, 0x064A, 0x0646, 0x062D, 0x064A, - 0x0639, 0x0645, 0x064A, 0x0643, 0x0645, 0x064A, 0x0646, 0x062C, - 0x062D, 0x0645, 0x062E, 0x064A, 0x0644, 0x062C, 0x0645, 0x0643, - 0x0645, 0x0645, 0x062C, 0x062D, 0x064A, 0x062D, 0x062C, 0x064A, - 0x0645, 0x062C, 0x064A, 0x0641, 0x0645, 0x064A, 0x0628, 0x062D, - 0x064A, 0x0633, 0x062E, 0x064A, 0x0646, 0x062C, 0x064A, 0x0635, - 0x0644, 0x06D2, 0x0642, 0x0644, 0x06D2, 0x0627, 0x0644, 0x0644, - 0x0647, 0x0627, 0x0643, 0x0628, 0x0631, 0x0645, 0x062D, 0x0645, - 0x062F, 0x0635, 0x0644, 0x0639, 0x0645, 0x0631, 0x0633, 0x0648, - 0x0644, 0x0639, 0x0644, 0x064A, 0x0647, 0x0648, 0x0633, 0x0644, - 0x0645, 0x0635, 0x0644, 0x0649, 0x0635, 0x0644, 0x0649, 0x0020, - 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, - 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0x062C, 0x0644, - 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0x0631, 0x06CC, - 0x0627, 0x0644, 0x002C, 0x3001, 0x3016, 0x3017, 0x2014, 0x2013, - 0x005F, 0x007B, 0x007D, 0x3014, 0x3015, 0x3010, 0x3011, 0x300A, - 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x005B, 0x005D, 0x0023, - 0x0026, 0x002A, 0x002D, 0x003C, 0x003E, 0x005C, 0x0024, 0x0025, - 0x0040, 0x0020, 0x064B, 0x0640, 0x064B, 0x0640, 0x0651, 0x0020, - 0x0652, 0x0640, 0x0652, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, - 0x0629, 0x062F, 0x0632, 0x0644, 0x0622, 0x0644, 0x0623, 0x0644, - 0x0625, 0x0644, 0x0627, 0x0022, 0x0027, 0x002F, 0x005E, 0x007C, - 0x007E, 0x2985, 0x2986, 0x30FB, 0x30A1, 0x30A3, 0x30A5, 0x30A7, - 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, 0x30FC, 0x30F3, 0x3099, - 0x309A, 0x00A2, 0x00A3, 0x00AC, 0x00A6, 0x00A5, 0x20A9, 0x2502, - 0x2190, 0x2191, 0x2192, 0x2193, 0x25A0, 0x25CB, 0x10428, 0x10429, - 0x1042A, 0x1042B, 0x1042C, 0x1042D, 0x1042E, 0x1042F, 0x10430, 0x10431, - 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, 0x10438, 0x10439, - 0x1043A, 0x1043B, 0x1043C, 0x1043D, 0x1043E, 0x1043F, 0x10440, 0x10441, - 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, 0x10448, 0x10449, - 0x1044A, 0x1044B, 0x1044C, 0x1044D, 0x1044E, 0x1044F, 0x104D8, 0x104D9, - 0x104DA, 0x104DB, 0x104DC, 0x104DD, 0x104DE, 0x104DF, 0x104E0, 0x104E1, - 0x104E2, 0x104E3, 0x104E4, 0x104E5, 0x104E6, 0x104E7, 0x104E8, 0x104E9, - 0x104EA, 0x104EB, 0x104EC, 0x104ED, 0x104EE, 0x104EF, 0x104F0, 0x104F1, - 0x104F2, 0x104F3, 0x104F4, 0x104F5, 0x104F6, 0x104F7, 0x104F8, 0x104F9, - 0x104FA, 0x104FB, 0x10597, 0x10598, 0x10599, 0x1059A, 0x1059B, 0x1059C, - 0x1059D, 0x1059E, 0x1059F, 0x105A0, 0x105A1, 0x105A3, 0x105A4, 0x105A5, - 0x105A6, 0x105A7, 0x105A8, 0x105A9, 0x105AA, 0x105AB, 0x105AC, 0x105AD, - 0x105AE, 0x105AF, 0x105B0, 0x105B1, 0x105B3, 0x105B4, 0x105B5, 0x105B6, - 0x105B7, 0x105B8, 0x105B9, 0x105BB, 0x105BC, 0x02D0, 0x02D1, 0x0299, - 0x02A3, 0xAB66, 0x02A5, 0x02A4, 0x1D91, 0x0258, 0x025E, 0x02A9, - 0x0262, 0x029B, 0x029C, 0x0267, 0x0284, 0x02AA, 0x02AB, 0x1DF04, - 0xA78E, 0x026E, 0x1DF05, 0x028E, 0x1DF06, 0x0276, 0x0277, 0x027A, - 0x1DF08, 0x027E, 0x02A8, 0x02A6, 0xAB67, 0x02A7, 0x2C71, 0x028F, - 0x02A1, 0x02A2, 0x0298, 0x01C0, 0x01C1, 0x01C2, 0x1DF0A, 0x1DF1E, - 0x10CC0, 0x10CC1, 0x10CC2, 0x10CC3, 0x10CC4, 0x10CC5, 0x10CC6, 0x10CC7, - 0x10CC8, 0x10CC9, 0x10CCA, 0x10CCB, 0x10CCC, 0x10CCD, 0x10CCE, 0x10CCF, - 0x10CD0, 0x10CD1, 0x10CD2, 0x10CD3, 0x10CD4, 0x10CD5, 0x10CD6, 0x10CD7, - 0x10CD8, 0x10CD9, 0x10CDA, 0x10CDB, 0x10CDC, 0x10CDD, 0x10CDE, 0x10CDF, - 0x10CE0, 0x10CE1, 0x10CE2, 0x10CE3, 0x10CE4, 0x10CE5, 0x10CE6, 0x10CE7, - 0x10CE8, 0x10CE9, 0x10CEA, 0x10CEB, 0x10CEC, 0x10CED, 0x10CEE, 0x10CEF, - 0x10CF0, 0x10CF1, 0x10CF2, 0x10D70, 0x10D71, 0x10D72, 0x10D73, 0x10D74, - 0x10D75, 0x10D76, 0x10D77, 0x10D78, 0x10D79, 0x10D7A, 0x10D7B, 0x10D7C, - 0x10D7D, 0x10D7E, 0x10D7F, 0x10D80, 0x10D81, 0x10D82, 0x10D83, 0x10D84, - 0x10D85, 0x118C0, 0x118C1, 0x118C2, 0x118C3, 0x118C4, 0x118C5, 0x118C6, - 0x118C7, 0x118C8, 0x118C9, 0x118CA, 0x118CB, 0x118CC, 0x118CD, 0x118CE, - 0x118CF, 0x118D0, 0x118D1, 0x118D2, 0x118D3, 0x118D4, 0x118D5, 0x118D6, - 0x118D7, 0x118D8, 0x118D9, 0x118DA, 0x118DB, 0x118DC, 0x118DD, 0x118DE, - 0x118DF, 0x16E60, 0x16E61, 0x16E62, 0x16E63, 0x16E64, 0x16E65, 0x16E66, - 0x16E67, 0x16E68, 0x16E69, 0x16E6A, 0x16E6B, 0x16E6C, 0x16E6D, 0x16E6E, - 0x16E6F, 0x16E70, 0x16E71, 0x16E72, 0x16E73, 0x16E74, 0x16E75, 0x16E76, - 0x16E77, 0x16E78, 0x16E79, 0x16E7A, 0x16E7B, 0x16E7C, 0x16E7D, 0x16E7E, - 0x16E7F, 0x1D157, 0x1D165, 0x1D158, 0x1D165, 0x1D158, 0x1D165, 0x1D16E, - 0x1D158, 0x1D165, 0x1D16F, 0x1D158, 0x1D165, 0x1D170, 0x1D158, 0x1D165, - 0x1D171, 0x1D158, 0x1D165, 0x1D172, 0x1D1B9, 0x1D165, 0x1D1BA, 0x1D165, - 0x1D1B9, 0x1D165, 0x1D16E, 0x1D1BA, 0x1D165, 0x1D16E, 0x1D1B9, 0x1D165, - 0x1D16F, 0x1D1BA, 0x1D165, 0x1D16F, 0x0131, 0x0237, 0x2207, 0x2202, - 0x1E922, 0x1E923, 0x1E924, 0x1E925, 0x1E926, 0x1E927, 0x1E928, 0x1E929, - 0x1E92A, 0x1E92B, 0x1E92C, 0x1E92D, 0x1E92E, 0x1E92F, 0x1E930, 0x1E931, - 0x1E932, 0x1E933, 0x1E934, 0x1E935, 0x1E936, 0x1E937, 0x1E938, 0x1E939, - 0x1E93A, 0x1E93B, 0x1E93C, 0x1E93D, 0x1E93E, 0x1E93F, 0x1E940, 0x1E941, - 0x1E942, 0x1E943, 0x066E, 0x06A1, 0x066F, 0x0030, 0x002C, 0x0031, - 0x002C, 0x0032, 0x002C, 0x0033, 0x002C, 0x0034, 0x002C, 0x0035, - 0x002C, 0x0036, 0x002C, 0x0037, 0x002C, 0x0038, 0x002C, 0x0039, - 0x002C, 0x3014, 0x0073, 0x3015, 0x0077, 0x007A, 0x0068, 0x0076, - 0x0073, 0x0064, 0x0070, 0x0070, 0x0076, 0x0077, 0x0063, 0x006D, - 0x0063, 0x006D, 0x0064, 0x006D, 0x0072, 0x0064, 0x006A, 0x307B, - 0x304B, 0x30B3, 0x30B3, 0x5B57, 0x53CC, 0x591A, 0x89E3, 0x4EA4, - 0x6620, 0x7121, 0x524D, 0x5F8C, 0x518D, 0x65B0, 0x521D, 0x7D42, - 0x8CA9, 0x58F0, 0x5439, 0x6F14, 0x6295, 0x6355, 0x904A, 0x6307, - 0x6253, 0x7981, 0x7A7A, 0x5408, 0x6E80, 0x7533, 0x5272, 0x55B6, - 0x914D, 0x3014, 0x672C, 0x3015, 0x3014, 0x4E09, 0x3015, 0x3014, - 0x4E8C, 0x3015, 0x3014, 0x5B89, 0x3015, 0x3014, 0x70B9, 0x3015, - 0x3014, 0x6253, 0x3015, 0x3014, 0x76D7, 0x3015, 0x3014, 0x52DD, - 0x3015, 0x3014, 0x6557, 0x3015, 0x5F97, 0x53EF, 0x4E3D, 0x4E38, - 0x4E41, 0x20122, 0x4F60, 0x4FBB, 0x5002, 0x507A, 0x5099, 0x50CF, - 0x349E, 0x2063A, 0x5154, 0x5164, 0x5177, 0x2051C, 0x34B9, 0x5167, - 0x2054B, 0x5197, 0x51A4, 0x4ECC, 0x51AC, 0x291DF, 0x5203, 0x34DF, - 0x523B, 0x5246, 0x5277, 0x3515, 0x5305, 0x5306, 0x5349, 0x535A, - 0x5373, 0x537D, 0x537F, 0x20A2C, 0x7070, 0x53CA, 0x53DF, 0x20B63, - 0x53EB, 0x53F1, 0x5406, 0x549E, 0x5438, 0x5448, 0x5468, 0x54A2, - 0x54F6, 0x5510, 0x5553, 0x5563, 0x5584, 0x55AB, 0x55B3, 0x55C2, - 0x5716, 0x5717, 0x5651, 0x5674, 0x58EE, 0x57CE, 0x57F4, 0x580D, - 0x578B, 0x5832, 0x5831, 0x58AC, 0x214E4, 0x58F2, 0x58F7, 0x5906, - 0x5922, 0x5962, 0x216A8, 0x216EA, 0x59EC, 0x5A1B, 0x5A27, 0x59D8, - 0x5A66, 0x36EE, 0x36FC, 0x5B08, 0x5B3E, 0x219C8, 0x5BC3, 0x5BD8, - 0x5BF3, 0x21B18, 0x5BFF, 0x5C06, 0x5F53, 0x3781, 0x5C60, 0x5CC0, - 0x5C8D, 0x21DE4, 0x5D43, 0x21DE6, 0x5D6E, 0x5D6B, 0x5D7C, 0x5DE1, - 0x5DE2, 0x382F, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x3862, 0x22183, - 0x387C, 0x5EB0, 0x5EB3, 0x5EB6, 0x2A392, 0x22331, 0x8201, 0x5F22, - 0x38C7, 0x232B8, 0x261DA, 0x5F62, 0x5F6B, 0x38E3, 0x5F9A, 0x5FCD, - 0x5FD7, 0x5FF9, 0x6081, 0x393A, 0x391C, 0x226D4, 0x60C7, 0x6148, - 0x614C, 0x617A, 0x61B2, 0x61A4, 0x61AF, 0x61DE, 0x6210, 0x621B, - 0x625D, 0x62B1, 0x62D4, 0x6350, 0x22B0C, 0x633D, 0x62FC, 0x6368, - 0x6383, 0x63E4, 0x22BF1, 0x6422, 0x63C5, 0x63A9, 0x3A2E, 0x6469, - 0x647E, 0x649D, 0x6477, 0x3A6C, 0x656C, 0x2300A, 0x65E3, 0x66F8, - 0x6649, 0x3B19, 0x3B08, 0x3AE4, 0x5192, 0x5195, 0x6700, 0x669C, - 0x80AD, 0x43D9, 0x6721, 0x675E, 0x6753, 0x233C3, 0x3B49, 0x67FA, - 0x6785, 0x6852, 0x2346D, 0x688E, 0x681F, 0x6914, 0x6942, 0x69A3, - 0x69EA, 0x6AA8, 0x236A3, 0x6ADB, 0x3C18, 0x6B21, 0x238A7, 0x6B54, - 0x3C4E, 0x6B72, 0x6B9F, 0x6BBB, 0x23A8D, 0x21D0B, 0x23AFA, 0x6C4E, - 0x23CBC, 0x6CBF, 0x6CCD, 0x6C67, 0x6D16, 0x6D3E, 0x6D69, 0x6D78, - 0x6D85, 0x23D1E, 0x6D34, 0x6E2F, 0x6E6E, 0x3D33, 0x6EC7, 0x23ED1, - 0x6DF9, 0x6F6E, 0x23F5E, 0x23F8E, 0x6FC6, 0x7039, 0x701B, 0x3D96, - 0x704A, 0x707D, 0x7077, 0x70AD, 0x20525, 0x7145, 0x24263, 0x719C, - 0x243AB, 0x7228, 0x7250, 0x24608, 0x7280, 0x7295, 0x24735, 0x24814, - 0x737A, 0x738B, 0x3EAC, 0x73A5, 0x3EB8, 0x7447, 0x745C, 0x7485, - 0x74CA, 0x3F1B, 0x7524, 0x24C36, 0x753E, 0x24C92, 0x2219F, 0x7610, - 0x24FA1, 0x24FB8, 0x25044, 0x3FFC, 0x4008, 0x250F3, 0x250F2, 0x25119, - 0x25133, 0x771E, 0x771F, 0x778B, 0x4046, 0x4096, 0x2541D, 0x784E, - 0x40E3, 0x25626, 0x2569A, 0x256C5, 0x79EB, 0x412F, 0x7A4A, 0x7A4F, - 0x2597C, 0x25AA7, 0x7AEE, 0x4202, 0x25BAB, 0x7BC6, 0x7BC9, 0x4227, - 0x25C80, 0x7CD2, 0x42A0, 0x7CE8, 0x7CE3, 0x7D00, 0x25F86, 0x7D63, - 0x4301, 0x7DC7, 0x7E02, 0x7E45, 0x4334, 0x26228, 0x26247, 0x4359, - 0x262D9, 0x7F7A, 0x2633E, 0x7F95, 0x7FFA, 0x264DA, 0x26523, 0x8060, - 0x265A8, 0x8070, 0x2335F, 0x43D5, 0x80B2, 0x8103, 0x440B, 0x813E, - 0x5AB5, 0x267A7, 0x267B5, 0x23393, 0x2339C, 0x8204, 0x8F9E, 0x446B, - 0x8291, 0x828B, 0x829D, 0x52B3, 0x82B1, 0x82B3, 0x82BD, 0x82E6, - 0x26B3C, 0x831D, 0x8363, 0x83AD, 0x8323, 0x83BD, 0x83E7, 0x8353, - 0x83CA, 0x83CC, 0x83DC, 0x26C36, 0x26D6B, 0x26CD5, 0x452B, 0x84F1, - 0x84F3, 0x8516, 0x273CA, 0x8564, 0x26F2C, 0x455D, 0x4561, 0x26FB1, - 0x270D2, 0x456B, 0x8650, 0x8667, 0x8669, 0x86A9, 0x8688, 0x870E, - 0x86E2, 0x8728, 0x876B, 0x8786, 0x45D7, 0x87E1, 0x8801, 0x45F9, - 0x8860, 0x27667, 0x88D7, 0x88DE, 0x4635, 0x88FA, 0x34BB, 0x278AE, - 0x27966, 0x46BE, 0x46C7, 0x8AA0, 0x27CA8, 0x8CAB, 0x8CC1, 0x8D1B, - 0x8D77, 0x27F2F, 0x20804, 0x8DCB, 0x8DBC, 0x8DF0, 0x208DE, 0x8ED4, - 0x285D2, 0x285ED, 0x9094, 0x90F1, 0x9111, 0x2872E, 0x911B, 0x9238, - 0x92D7, 0x92D8, 0x927C, 0x93F9, 0x9415, 0x28BFA, 0x958B, 0x4995, - 0x95B7, 0x28D77, 0x49E6, 0x96C3, 0x5DB2, 0x9723, 0x29145, 0x2921A, - 0x4A6E, 0x4A76, 0x97E0, 0x2940A, 0x4AB2, 0x29496, 0x9829, 0x295B6, - 0x98E2, 0x4B33, 0x9929, 0x99A7, 0x99C2, 0x99FE, 0x4BCE, 0x29B30, - 0x9C40, 0x9CFD, 0x4CCE, 0x4CED, 0x9D67, 0x2A0CE, 0x4CF8, 0x2A105, - 0x2A20E, 0x2A291, 0x4D56, 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x2A600 + 0xA794, 0x1D8E, 0xA7C8, 0xA7CA, 0x0264, 0xA7CD, 0xA7CF, 0xA7D1, + 0xA7D3, 0xA7D5, 0xA7D7, 0xA7D9, 0xA7DB, 0x019B, 0xA7F6, 0xAB37, + 0xAB52, 0x028D, 0x13A0, 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, + 0x13A6, 0x13A7, 0x13A8, 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, + 0x13AE, 0x13AF, 0x13B0, 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, + 0x13B6, 0x13B7, 0x13B8, 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, + 0x13BE, 0x13BF, 0x13C0, 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, + 0x13C6, 0x13C7, 0x13C8, 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, + 0x13CE, 0x13CF, 0x13D0, 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, + 0x13D6, 0x13D7, 0x13D8, 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, + 0x13DE, 0x13DF, 0x13E0, 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, + 0x13E6, 0x13E7, 0x13E8, 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, + 0x13EE, 0x13EF, 0x8C48, 0x66F4, 0x8CC8, 0x6ED1, 0x4E32, 0x53E5, + 0x5951, 0x5587, 0x5948, 0x61F6, 0x7669, 0x7F85, 0x863F, 0x87BA, + 0x88F8, 0x908F, 0x6A02, 0x6D1B, 0x70D9, 0x73DE, 0x843D, 0x916A, + 0x99F1, 0x4E82, 0x5375, 0x6B04, 0x721B, 0x862D, 0x9E1E, 0x5D50, + 0x6FEB, 0x85CD, 0x8964, 0x62C9, 0x81D8, 0x881F, 0x5ECA, 0x6717, + 0x6D6A, 0x72FC, 0x90CE, 0x4F86, 0x51B7, 0x52DE, 0x64C4, 0x6AD3, + 0x7210, 0x76E7, 0x8606, 0x865C, 0x8DEF, 0x9732, 0x9B6F, 0x9DFA, + 0x788C, 0x797F, 0x7DA0, 0x83C9, 0x9304, 0x8AD6, 0x58DF, 0x5F04, + 0x7C60, 0x807E, 0x7262, 0x78CA, 0x8CC2, 0x96F7, 0x58D8, 0x5C62, + 0x6A13, 0x6DDA, 0x6F0F, 0x7D2F, 0x7E37, 0x964B, 0x52D2, 0x808B, + 0x51DC, 0x51CC, 0x7A1C, 0x7DBE, 0x83F1, 0x9675, 0x8B80, 0x62CF, + 0x8AFE, 0x4E39, 0x5BE7, 0x6012, 0x7387, 0x7570, 0x5317, 0x78FB, + 0x4FBF, 0x5FA9, 0x4E0D, 0x6CCC, 0x6578, 0x7D22, 0x53C3, 0x585E, + 0x7701, 0x8449, 0x8AAA, 0x6BBA, 0x6C88, 0x62FE, 0x82E5, 0x63A0, + 0x7565, 0x4EAE, 0x5169, 0x51C9, 0x6881, 0x7CE7, 0x826F, 0x8AD2, + 0x91CF, 0x52F5, 0x5442, 0x5EEC, 0x65C5, 0x6FFE, 0x792A, 0x95AD, + 0x9A6A, 0x9E97, 0x9ECE, 0x66C6, 0x6B77, 0x8F62, 0x5E74, 0x6190, + 0x6200, 0x649A, 0x6F23, 0x7149, 0x7489, 0x79CA, 0x7DF4, 0x806F, + 0x8F26, 0x84EE, 0x9023, 0x934A, 0x5217, 0x52A3, 0x54BD, 0x70C8, + 0x88C2, 0x5EC9, 0x5FF5, 0x637B, 0x6BAE, 0x7C3E, 0x7375, 0x56F9, + 0x5DBA, 0x601C, 0x73B2, 0x7469, 0x7F9A, 0x8046, 0x9234, 0x96F6, + 0x9748, 0x9818, 0x4F8B, 0x79AE, 0x91B4, 0x96B8, 0x60E1, 0x4E86, + 0x50DA, 0x5BEE, 0x5C3F, 0x6599, 0x71CE, 0x7642, 0x84FC, 0x907C, + 0x6688, 0x962E, 0x5289, 0x677B, 0x67F3, 0x6D41, 0x6E9C, 0x7409, + 0x7559, 0x786B, 0x7D10, 0x985E, 0x622E, 0x9678, 0x502B, 0x5D19, + 0x6DEA, 0x8F2A, 0x5F8B, 0x6144, 0x6817, 0x9686, 0x5229, 0x540F, + 0x5C65, 0x6613, 0x674E, 0x68A8, 0x6CE5, 0x7406, 0x75E2, 0x7F79, + 0x88CF, 0x88E1, 0x96E2, 0x533F, 0x6EBA, 0x541D, 0x71D0, 0x7498, + 0x85FA, 0x96A3, 0x9C57, 0x9E9F, 0x6797, 0x6DCB, 0x81E8, 0x7B20, + 0x7C92, 0x72C0, 0x7099, 0x8B58, 0x4EC0, 0x8336, 0x523A, 0x5207, + 0x5EA6, 0x62D3, 0x7CD6, 0x5B85, 0x6D1E, 0x66B4, 0x8F3B, 0x964D, + 0x5ED3, 0x5140, 0x55C0, 0x585A, 0x6674, 0x51DE, 0x732A, 0x76CA, + 0x793C, 0x795E, 0x7965, 0x798F, 0x9756, 0x7CBE, 0x8612, 0x8AF8, + 0x9038, 0x90FD, 0x98EF, 0x98FC, 0x9928, 0x9DB4, 0x90DE, 0x96B7, + 0x4FAE, 0x50E7, 0x514D, 0x52C9, 0x52E4, 0x5351, 0x559D, 0x5606, + 0x5668, 0x5840, 0x58A8, 0x5C64, 0x6094, 0x6168, 0x618E, 0x61F2, + 0x654F, 0x65E2, 0x6691, 0x6885, 0x6D77, 0x6E1A, 0x6F22, 0x716E, + 0x722B, 0x7422, 0x7891, 0x7949, 0x7948, 0x7950, 0x7956, 0x798D, + 0x798E, 0x7A40, 0x7A81, 0x7BC0, 0x7E09, 0x7E41, 0x7F72, 0x8005, + 0x81ED, 0x8279, 0x8457, 0x8910, 0x8996, 0x8B01, 0x8B39, 0x8CD3, + 0x8D08, 0x8FB6, 0x96E3, 0x97FF, 0x983B, 0x6075, 0x242EE, 0x8218, + 0x4E26, 0x51B5, 0x5168, 0x4F80, 0x5145, 0x5180, 0x52C7, 0x52FA, + 0x5555, 0x5599, 0x55E2, 0x58B3, 0x5944, 0x5954, 0x5A62, 0x5B28, + 0x5ED2, 0x5ED9, 0x5F69, 0x5FAD, 0x60D8, 0x614E, 0x6108, 0x6160, + 0x6234, 0x63C4, 0x641C, 0x6452, 0x6556, 0x671B, 0x6756, 0x6EDB, + 0x6ECB, 0x701E, 0x77A7, 0x7235, 0x72AF, 0x7471, 0x7506, 0x753B, + 0x761D, 0x761F, 0x76DB, 0x76F4, 0x774A, 0x7740, 0x78CC, 0x7AB1, + 0x7C7B, 0x7D5B, 0x7F3E, 0x8352, 0x83EF, 0x8779, 0x8941, 0x8986, + 0x8ABF, 0x8ACB, 0x8AED, 0x8B8A, 0x8F38, 0x9072, 0x9199, 0x9276, + 0x967C, 0x97DB, 0x980B, 0x9B12, 0x2284A, 0x22844, 0x233D5, 0x3B9D, + 0x4018, 0x4039, 0x25249, 0x25CD0, 0x27ED3, 0x9F43, 0x9F8E, 0x0066, + 0x0066, 0x0066, 0x0069, 0x0066, 0x006C, 0x0066, 0x0066, 0x0069, + 0x0066, 0x0066, 0x006C, 0x0073, 0x0074, 0x0574, 0x0576, 0x0574, + 0x0565, 0x0574, 0x056B, 0x057E, 0x0576, 0x0574, 0x056D, 0x05D9, + 0x05B4, 0x05F2, 0x05B7, 0x05E2, 0x05D4, 0x05DB, 0x05DC, 0x05DD, + 0x05E8, 0x05EA, 0x05E9, 0x05C1, 0x05E9, 0x05C2, 0x05E9, 0x05BC, + 0x05C1, 0x05E9, 0x05BC, 0x05C2, 0x05D0, 0x05B7, 0x05D0, 0x05B8, + 0x05D0, 0x05BC, 0x05D1, 0x05BC, 0x05D2, 0x05BC, 0x05D3, 0x05BC, + 0x05D4, 0x05BC, 0x05D5, 0x05BC, 0x05D6, 0x05BC, 0x05D8, 0x05BC, + 0x05D9, 0x05BC, 0x05DA, 0x05BC, 0x05DB, 0x05BC, 0x05DC, 0x05BC, + 0x05DE, 0x05BC, 0x05E0, 0x05BC, 0x05E1, 0x05BC, 0x05E3, 0x05BC, + 0x05E4, 0x05BC, 0x05E6, 0x05BC, 0x05E7, 0x05BC, 0x05E8, 0x05BC, + 0x05EA, 0x05BC, 0x05D5, 0x05B9, 0x05D1, 0x05BF, 0x05DB, 0x05BF, + 0x05E4, 0x05BF, 0x05D0, 0x05DC, 0x0671, 0x067B, 0x067E, 0x0680, + 0x067A, 0x067F, 0x0679, 0x06A4, 0x06A6, 0x0684, 0x0683, 0x0686, + 0x0687, 0x068D, 0x068C, 0x068E, 0x0688, 0x0698, 0x0691, 0x06A9, + 0x06AF, 0x06B3, 0x06B1, 0x06BA, 0x06BB, 0x06C0, 0x06C1, 0x06BE, + 0x06D2, 0x06D3, 0x06AD, 0x06C6, 0x06C8, 0x06CB, 0x06C5, 0x06C9, + 0x06D0, 0x0649, 0x0626, 0x0627, 0x0626, 0x06D5, 0x0626, 0x0648, + 0x0626, 0x06C7, 0x0626, 0x06C6, 0x0626, 0x06C8, 0x0626, 0x06D0, + 0x0626, 0x0649, 0x06CC, 0x0626, 0x062C, 0x0626, 0x062D, 0x0626, + 0x0645, 0x0626, 0x064A, 0x0628, 0x062C, 0x0628, 0x062D, 0x0628, + 0x062E, 0x0628, 0x0645, 0x0628, 0x0649, 0x0628, 0x064A, 0x062A, + 0x062C, 0x062A, 0x062D, 0x062A, 0x062E, 0x062A, 0x0645, 0x062A, + 0x0649, 0x062A, 0x064A, 0x062B, 0x062C, 0x062B, 0x0645, 0x062B, + 0x0649, 0x062B, 0x064A, 0x062C, 0x062D, 0x062C, 0x0645, 0x062D, + 0x062C, 0x062D, 0x0645, 0x062E, 0x062C, 0x062E, 0x062D, 0x062E, + 0x0645, 0x0633, 0x062C, 0x0633, 0x062D, 0x0633, 0x062E, 0x0633, + 0x0645, 0x0635, 0x062D, 0x0635, 0x0645, 0x0636, 0x062C, 0x0636, + 0x062D, 0x0636, 0x062E, 0x0636, 0x0645, 0x0637, 0x062D, 0x0637, + 0x0645, 0x0638, 0x0645, 0x0639, 0x062C, 0x0639, 0x0645, 0x063A, + 0x062C, 0x063A, 0x0645, 0x0641, 0x062C, 0x0641, 0x062D, 0x0641, + 0x062E, 0x0641, 0x0645, 0x0641, 0x0649, 0x0641, 0x064A, 0x0642, + 0x062D, 0x0642, 0x0645, 0x0642, 0x0649, 0x0642, 0x064A, 0x0643, + 0x0627, 0x0643, 0x062C, 0x0643, 0x062D, 0x0643, 0x062E, 0x0643, + 0x0644, 0x0643, 0x0645, 0x0643, 0x0649, 0x0643, 0x064A, 0x0644, + 0x062C, 0x0644, 0x062D, 0x0644, 0x062E, 0x0644, 0x0645, 0x0644, + 0x0649, 0x0644, 0x064A, 0x0645, 0x062C, 0x0645, 0x062D, 0x0645, + 0x062E, 0x0645, 0x0645, 0x0645, 0x0649, 0x0645, 0x064A, 0x0646, + 0x062C, 0x0646, 0x062D, 0x0646, 0x062E, 0x0646, 0x0645, 0x0646, + 0x0649, 0x0646, 0x064A, 0x0647, 0x062C, 0x0647, 0x0645, 0x0647, + 0x0649, 0x0647, 0x064A, 0x064A, 0x062C, 0x064A, 0x062D, 0x064A, + 0x062E, 0x064A, 0x0645, 0x064A, 0x0649, 0x064A, 0x064A, 0x0630, + 0x0670, 0x0631, 0x0670, 0x0649, 0x0670, 0x0020, 0x064C, 0x0651, + 0x0020, 0x064D, 0x0651, 0x0020, 0x064E, 0x0651, 0x0020, 0x064F, + 0x0651, 0x0020, 0x0650, 0x0651, 0x0020, 0x0651, 0x0670, 0x0626, + 0x0631, 0x0626, 0x0632, 0x0626, 0x0646, 0x0628, 0x0631, 0x0628, + 0x0632, 0x0628, 0x0646, 0x062A, 0x0631, 0x062A, 0x0632, 0x062A, + 0x0646, 0x062B, 0x0631, 0x062B, 0x0632, 0x062B, 0x0646, 0x0645, + 0x0627, 0x0646, 0x0631, 0x0646, 0x0632, 0x0646, 0x0646, 0x064A, + 0x0631, 0x064A, 0x0632, 0x064A, 0x0646, 0x0626, 0x062E, 0x0626, + 0x0647, 0x0628, 0x0647, 0x062A, 0x0647, 0x0635, 0x062E, 0x0644, + 0x0647, 0x0646, 0x0647, 0x0647, 0x0670, 0x064A, 0x0647, 0x062B, + 0x0647, 0x0633, 0x0647, 0x0634, 0x0645, 0x0634, 0x0647, 0x0640, + 0x064E, 0x0651, 0x0640, 0x064F, 0x0651, 0x0640, 0x0650, 0x0651, + 0x0637, 0x0649, 0x0637, 0x064A, 0x0639, 0x0649, 0x0639, 0x064A, + 0x063A, 0x0649, 0x063A, 0x064A, 0x0633, 0x0649, 0x0633, 0x064A, + 0x0634, 0x0649, 0x0634, 0x064A, 0x062D, 0x0649, 0x062D, 0x064A, + 0x062C, 0x0649, 0x062C, 0x064A, 0x062E, 0x0649, 0x062E, 0x064A, + 0x0635, 0x0649, 0x0635, 0x064A, 0x0636, 0x0649, 0x0636, 0x064A, + 0x0634, 0x062C, 0x0634, 0x062D, 0x0634, 0x062E, 0x0634, 0x0631, + 0x0633, 0x0631, 0x0635, 0x0631, 0x0636, 0x0631, 0x0627, 0x064B, + 0x062A, 0x062C, 0x0645, 0x062A, 0x062D, 0x062C, 0x062A, 0x062D, + 0x0645, 0x062A, 0x062E, 0x0645, 0x062A, 0x0645, 0x062C, 0x062A, + 0x0645, 0x062D, 0x062A, 0x0645, 0x062E, 0x062C, 0x0645, 0x062D, + 0x062D, 0x0645, 0x064A, 0x062D, 0x0645, 0x0649, 0x0633, 0x062D, + 0x062C, 0x0633, 0x062C, 0x062D, 0x0633, 0x062C, 0x0649, 0x0633, + 0x0645, 0x062D, 0x0633, 0x0645, 0x062C, 0x0633, 0x0645, 0x0645, + 0x0635, 0x062D, 0x062D, 0x0635, 0x0645, 0x0645, 0x0634, 0x062D, + 0x0645, 0x0634, 0x062C, 0x064A, 0x0634, 0x0645, 0x062E, 0x0634, + 0x0645, 0x0645, 0x0636, 0x062D, 0x0649, 0x0636, 0x062E, 0x0645, + 0x0637, 0x0645, 0x062D, 0x0637, 0x0645, 0x0645, 0x0637, 0x0645, + 0x064A, 0x0639, 0x062C, 0x0645, 0x0639, 0x0645, 0x0645, 0x0639, + 0x0645, 0x0649, 0x063A, 0x0645, 0x0645, 0x063A, 0x0645, 0x064A, + 0x063A, 0x0645, 0x0649, 0x0641, 0x062E, 0x0645, 0x0642, 0x0645, + 0x062D, 0x0642, 0x0645, 0x0645, 0x0644, 0x062D, 0x0645, 0x0644, + 0x062D, 0x064A, 0x0644, 0x062D, 0x0649, 0x0644, 0x062C, 0x062C, + 0x0644, 0x062E, 0x0645, 0x0644, 0x0645, 0x062D, 0x0645, 0x062D, + 0x062C, 0x0645, 0x062D, 0x0645, 0x0645, 0x062D, 0x064A, 0x0645, + 0x062C, 0x062D, 0x0645, 0x062C, 0x0645, 0x0645, 0x062E, 0x062C, + 0x0645, 0x062E, 0x0645, 0x0645, 0x062C, 0x062E, 0x0647, 0x0645, + 0x062C, 0x0647, 0x0645, 0x0645, 0x0646, 0x062D, 0x0645, 0x0646, + 0x062D, 0x0649, 0x0646, 0x062C, 0x0645, 0x0646, 0x062C, 0x0649, + 0x0646, 0x0645, 0x064A, 0x0646, 0x0645, 0x0649, 0x064A, 0x0645, + 0x0645, 0x0628, 0x062E, 0x064A, 0x062A, 0x062C, 0x064A, 0x062A, + 0x062C, 0x0649, 0x062A, 0x062E, 0x064A, 0x062A, 0x062E, 0x0649, + 0x062A, 0x0645, 0x064A, 0x062A, 0x0645, 0x0649, 0x062C, 0x0645, + 0x064A, 0x062C, 0x062D, 0x0649, 0x062C, 0x0645, 0x0649, 0x0633, + 0x062E, 0x0649, 0x0635, 0x062D, 0x064A, 0x0634, 0x062D, 0x064A, + 0x0636, 0x062D, 0x064A, 0x0644, 0x062C, 0x064A, 0x0644, 0x0645, + 0x064A, 0x064A, 0x062D, 0x064A, 0x064A, 0x062C, 0x064A, 0x064A, + 0x0645, 0x064A, 0x0645, 0x0645, 0x064A, 0x0642, 0x0645, 0x064A, + 0x0646, 0x062D, 0x064A, 0x0639, 0x0645, 0x064A, 0x0643, 0x0645, + 0x064A, 0x0646, 0x062C, 0x062D, 0x0645, 0x062E, 0x064A, 0x0644, + 0x062C, 0x0645, 0x0643, 0x0645, 0x0645, 0x062C, 0x062D, 0x064A, + 0x062D, 0x062C, 0x064A, 0x0645, 0x062C, 0x064A, 0x0641, 0x0645, + 0x064A, 0x0628, 0x062D, 0x064A, 0x0633, 0x062E, 0x064A, 0x0646, + 0x062C, 0x064A, 0x0635, 0x0644, 0x06D2, 0x0642, 0x0644, 0x06D2, + 0x0627, 0x0644, 0x0644, 0x0647, 0x0627, 0x0643, 0x0628, 0x0631, + 0x0645, 0x062D, 0x0645, 0x062F, 0x0635, 0x0644, 0x0639, 0x0645, + 0x0631, 0x0633, 0x0648, 0x0644, 0x0639, 0x0644, 0x064A, 0x0647, + 0x0648, 0x0633, 0x0644, 0x0645, 0x0635, 0x0644, 0x0649, 0x0635, + 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, + 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, + 0x0645, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, + 0x0647, 0x0631, 0x06CC, 0x0627, 0x0644, 0x002C, 0x3001, 0x3016, + 0x3017, 0x2014, 0x2013, 0x005F, 0x007B, 0x007D, 0x3014, 0x3015, + 0x3010, 0x3011, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, + 0x005B, 0x005D, 0x0023, 0x0026, 0x002A, 0x002D, 0x003C, 0x003E, + 0x005C, 0x0024, 0x0025, 0x0040, 0x0020, 0x064B, 0x0640, 0x064B, + 0x0640, 0x0651, 0x0020, 0x0652, 0x0640, 0x0652, 0x0621, 0x0622, + 0x0623, 0x0624, 0x0625, 0x0629, 0x062F, 0x0632, 0x0644, 0x0622, + 0x0644, 0x0623, 0x0644, 0x0625, 0x0644, 0x0627, 0x0022, 0x0027, + 0x002F, 0x005E, 0x007C, 0x007E, 0x2985, 0x2986, 0x30FB, 0x30A1, + 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, + 0x30FC, 0x30F3, 0x3099, 0x309A, 0x00A2, 0x00A3, 0x00AC, 0x00A6, + 0x00A5, 0x20A9, 0x2502, 0x2190, 0x2191, 0x2192, 0x2193, 0x25A0, + 0x25CB, 0x10428, 0x10429, 0x1042A, 0x1042B, 0x1042C, 0x1042D, 0x1042E, + 0x1042F, 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, + 0x10437, 0x10438, 0x10439, 0x1043A, 0x1043B, 0x1043C, 0x1043D, 0x1043E, + 0x1043F, 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, + 0x10447, 0x10448, 0x10449, 0x1044A, 0x1044B, 0x1044C, 0x1044D, 0x1044E, + 0x1044F, 0x104D8, 0x104D9, 0x104DA, 0x104DB, 0x104DC, 0x104DD, 0x104DE, + 0x104DF, 0x104E0, 0x104E1, 0x104E2, 0x104E3, 0x104E4, 0x104E5, 0x104E6, + 0x104E7, 0x104E8, 0x104E9, 0x104EA, 0x104EB, 0x104EC, 0x104ED, 0x104EE, + 0x104EF, 0x104F0, 0x104F1, 0x104F2, 0x104F3, 0x104F4, 0x104F5, 0x104F6, + 0x104F7, 0x104F8, 0x104F9, 0x104FA, 0x104FB, 0x10597, 0x10598, 0x10599, + 0x1059A, 0x1059B, 0x1059C, 0x1059D, 0x1059E, 0x1059F, 0x105A0, 0x105A1, + 0x105A3, 0x105A4, 0x105A5, 0x105A6, 0x105A7, 0x105A8, 0x105A9, 0x105AA, + 0x105AB, 0x105AC, 0x105AD, 0x105AE, 0x105AF, 0x105B0, 0x105B1, 0x105B3, + 0x105B4, 0x105B5, 0x105B6, 0x105B7, 0x105B8, 0x105B9, 0x105BB, 0x105BC, + 0x02D0, 0x02D1, 0x0299, 0x02A3, 0xAB66, 0x02A5, 0x02A4, 0x1D91, + 0x0258, 0x025E, 0x02A9, 0x0262, 0x029B, 0x029C, 0x0267, 0x0284, + 0x02AA, 0x02AB, 0x1DF04, 0xA78E, 0x026E, 0x1DF05, 0x028E, 0x1DF06, + 0x0276, 0x0277, 0x027A, 0x1DF08, 0x027E, 0x02A8, 0x02A6, 0xAB67, + 0x02A7, 0x2C71, 0x028F, 0x02A1, 0x02A2, 0x0298, 0x01C0, 0x01C1, + 0x01C2, 0x1DF0A, 0x1DF1E, 0x10CC0, 0x10CC1, 0x10CC2, 0x10CC3, 0x10CC4, + 0x10CC5, 0x10CC6, 0x10CC7, 0x10CC8, 0x10CC9, 0x10CCA, 0x10CCB, 0x10CCC, + 0x10CCD, 0x10CCE, 0x10CCF, 0x10CD0, 0x10CD1, 0x10CD2, 0x10CD3, 0x10CD4, + 0x10CD5, 0x10CD6, 0x10CD7, 0x10CD8, 0x10CD9, 0x10CDA, 0x10CDB, 0x10CDC, + 0x10CDD, 0x10CDE, 0x10CDF, 0x10CE0, 0x10CE1, 0x10CE2, 0x10CE3, 0x10CE4, + 0x10CE5, 0x10CE6, 0x10CE7, 0x10CE8, 0x10CE9, 0x10CEA, 0x10CEB, 0x10CEC, + 0x10CED, 0x10CEE, 0x10CEF, 0x10CF0, 0x10CF1, 0x10CF2, 0x10D70, 0x10D71, + 0x10D72, 0x10D73, 0x10D74, 0x10D75, 0x10D76, 0x10D77, 0x10D78, 0x10D79, + 0x10D7A, 0x10D7B, 0x10D7C, 0x10D7D, 0x10D7E, 0x10D7F, 0x10D80, 0x10D81, + 0x10D82, 0x10D83, 0x10D84, 0x10D85, 0x118C0, 0x118C1, 0x118C2, 0x118C3, + 0x118C4, 0x118C5, 0x118C6, 0x118C7, 0x118C8, 0x118C9, 0x118CA, 0x118CB, + 0x118CC, 0x118CD, 0x118CE, 0x118CF, 0x118D0, 0x118D1, 0x118D2, 0x118D3, + 0x118D4, 0x118D5, 0x118D6, 0x118D7, 0x118D8, 0x118D9, 0x118DA, 0x118DB, + 0x118DC, 0x118DD, 0x118DE, 0x118DF, 0x16E60, 0x16E61, 0x16E62, 0x16E63, + 0x16E64, 0x16E65, 0x16E66, 0x16E67, 0x16E68, 0x16E69, 0x16E6A, 0x16E6B, + 0x16E6C, 0x16E6D, 0x16E6E, 0x16E6F, 0x16E70, 0x16E71, 0x16E72, 0x16E73, + 0x16E74, 0x16E75, 0x16E76, 0x16E77, 0x16E78, 0x16E79, 0x16E7A, 0x16E7B, + 0x16E7C, 0x16E7D, 0x16E7E, 0x16E7F, 0x16EBB, 0x16EBC, 0x16EBD, 0x16EBE, + 0x16EBF, 0x16EC0, 0x16EC1, 0x16EC2, 0x16EC3, 0x16EC4, 0x16EC5, 0x16EC6, + 0x16EC7, 0x16EC8, 0x16EC9, 0x16ECA, 0x16ECB, 0x16ECC, 0x16ECD, 0x16ECE, + 0x16ECF, 0x16ED0, 0x16ED1, 0x16ED2, 0x16ED3, 0x1D157, 0x1D165, 0x1D158, + 0x1D165, 0x1D158, 0x1D165, 0x1D16E, 0x1D158, 0x1D165, 0x1D16F, 0x1D158, + 0x1D165, 0x1D170, 0x1D158, 0x1D165, 0x1D171, 0x1D158, 0x1D165, 0x1D172, + 0x1D1B9, 0x1D165, 0x1D1BA, 0x1D165, 0x1D1B9, 0x1D165, 0x1D16E, 0x1D1BA, + 0x1D165, 0x1D16E, 0x1D1B9, 0x1D165, 0x1D16F, 0x1D1BA, 0x1D165, 0x1D16F, + 0x0131, 0x0237, 0x2207, 0x2202, 0x1E922, 0x1E923, 0x1E924, 0x1E925, + 0x1E926, 0x1E927, 0x1E928, 0x1E929, 0x1E92A, 0x1E92B, 0x1E92C, 0x1E92D, + 0x1E92E, 0x1E92F, 0x1E930, 0x1E931, 0x1E932, 0x1E933, 0x1E934, 0x1E935, + 0x1E936, 0x1E937, 0x1E938, 0x1E939, 0x1E93A, 0x1E93B, 0x1E93C, 0x1E93D, + 0x1E93E, 0x1E93F, 0x1E940, 0x1E941, 0x1E942, 0x1E943, 0x066E, 0x06A1, + 0x066F, 0x0030, 0x002C, 0x0031, 0x002C, 0x0032, 0x002C, 0x0033, + 0x002C, 0x0034, 0x002C, 0x0035, 0x002C, 0x0036, 0x002C, 0x0037, + 0x002C, 0x0038, 0x002C, 0x0039, 0x002C, 0x3014, 0x0073, 0x3015, + 0x0077, 0x007A, 0x0068, 0x0076, 0x0073, 0x0064, 0x0070, 0x0070, + 0x0076, 0x0077, 0x0063, 0x006D, 0x0063, 0x006D, 0x0064, 0x006D, + 0x0072, 0x0064, 0x006A, 0x307B, 0x304B, 0x30B3, 0x30B3, 0x5B57, + 0x53CC, 0x591A, 0x89E3, 0x4EA4, 0x6620, 0x7121, 0x524D, 0x5F8C, + 0x518D, 0x65B0, 0x521D, 0x7D42, 0x8CA9, 0x58F0, 0x5439, 0x6F14, + 0x6295, 0x6355, 0x904A, 0x6307, 0x6253, 0x7981, 0x7A7A, 0x5408, + 0x6E80, 0x7533, 0x5272, 0x55B6, 0x914D, 0x3014, 0x672C, 0x3015, + 0x3014, 0x4E09, 0x3015, 0x3014, 0x4E8C, 0x3015, 0x3014, 0x5B89, + 0x3015, 0x3014, 0x70B9, 0x3015, 0x3014, 0x6253, 0x3015, 0x3014, + 0x76D7, 0x3015, 0x3014, 0x52DD, 0x3015, 0x3014, 0x6557, 0x3015, + 0x5F97, 0x53EF, 0x4E3D, 0x4E38, 0x4E41, 0x20122, 0x4F60, 0x4FBB, + 0x5002, 0x507A, 0x5099, 0x50CF, 0x349E, 0x2063A, 0x5154, 0x5164, + 0x5177, 0x2051C, 0x34B9, 0x5167, 0x2054B, 0x5197, 0x51A4, 0x4ECC, + 0x51AC, 0x291DF, 0x5203, 0x34DF, 0x523B, 0x5246, 0x5277, 0x3515, + 0x5305, 0x5306, 0x5349, 0x535A, 0x5373, 0x537D, 0x537F, 0x20A2C, + 0x7070, 0x53CA, 0x53DF, 0x20B63, 0x53EB, 0x53F1, 0x5406, 0x549E, + 0x5438, 0x5448, 0x5468, 0x54A2, 0x54F6, 0x5510, 0x5553, 0x5563, + 0x5584, 0x55AB, 0x55B3, 0x55C2, 0x5716, 0x5717, 0x5651, 0x5674, + 0x58EE, 0x57CE, 0x57F4, 0x580D, 0x578B, 0x5832, 0x5831, 0x58AC, + 0x214E4, 0x58F2, 0x58F7, 0x5906, 0x5922, 0x5962, 0x216A8, 0x216EA, + 0x59EC, 0x5A1B, 0x5A27, 0x59D8, 0x5A66, 0x36EE, 0x36FC, 0x5B08, + 0x5B3E, 0x219C8, 0x5BC3, 0x5BD8, 0x5BF3, 0x21B18, 0x5BFF, 0x5C06, + 0x5F53, 0x3781, 0x5C60, 0x5CC0, 0x5C8D, 0x21DE4, 0x5D43, 0x21DE6, + 0x5D6E, 0x5D6B, 0x5D7C, 0x5DE1, 0x5DE2, 0x382F, 0x5DFD, 0x5E28, + 0x5E3D, 0x5E69, 0x3862, 0x22183, 0x387C, 0x5EB0, 0x5EB3, 0x5EB6, + 0x2A392, 0x22331, 0x8201, 0x5F22, 0x38C7, 0x232B8, 0x261DA, 0x5F62, + 0x5F6B, 0x38E3, 0x5F9A, 0x5FCD, 0x5FD7, 0x5FF9, 0x6081, 0x393A, + 0x391C, 0x226D4, 0x60C7, 0x6148, 0x614C, 0x617A, 0x61B2, 0x61A4, + 0x61AF, 0x61DE, 0x6210, 0x621B, 0x625D, 0x62B1, 0x62D4, 0x6350, + 0x22B0C, 0x633D, 0x62FC, 0x6368, 0x6383, 0x63E4, 0x22BF1, 0x6422, + 0x63C5, 0x63A9, 0x3A2E, 0x6469, 0x647E, 0x649D, 0x6477, 0x3A6C, + 0x656C, 0x2300A, 0x65E3, 0x66F8, 0x6649, 0x3B19, 0x3B08, 0x3AE4, + 0x5192, 0x5195, 0x6700, 0x669C, 0x80AD, 0x43D9, 0x6721, 0x675E, + 0x6753, 0x233C3, 0x3B49, 0x67FA, 0x6785, 0x6852, 0x2346D, 0x688E, + 0x681F, 0x6914, 0x6942, 0x69A3, 0x69EA, 0x6AA8, 0x236A3, 0x6ADB, + 0x3C18, 0x6B21, 0x238A7, 0x6B54, 0x3C4E, 0x6B72, 0x6B9F, 0x6BBB, + 0x23A8D, 0x21D0B, 0x23AFA, 0x6C4E, 0x23CBC, 0x6CBF, 0x6CCD, 0x6C67, + 0x6D16, 0x6D3E, 0x6D69, 0x6D78, 0x6D85, 0x23D1E, 0x6D34, 0x6E2F, + 0x6E6E, 0x3D33, 0x6EC7, 0x23ED1, 0x6DF9, 0x6F6E, 0x23F5E, 0x23F8E, + 0x6FC6, 0x7039, 0x701B, 0x3D96, 0x704A, 0x707D, 0x7077, 0x70AD, + 0x20525, 0x7145, 0x24263, 0x719C, 0x243AB, 0x7228, 0x7250, 0x24608, + 0x7280, 0x7295, 0x24735, 0x24814, 0x737A, 0x738B, 0x3EAC, 0x73A5, + 0x3EB8, 0x7447, 0x745C, 0x7485, 0x74CA, 0x3F1B, 0x7524, 0x24C36, + 0x753E, 0x24C92, 0x2219F, 0x7610, 0x24FA1, 0x24FB8, 0x25044, 0x3FFC, + 0x4008, 0x250F3, 0x250F2, 0x25119, 0x25133, 0x771E, 0x771F, 0x778B, + 0x4046, 0x4096, 0x2541D, 0x784E, 0x40E3, 0x25626, 0x2569A, 0x256C5, + 0x79EB, 0x412F, 0x7A4A, 0x7A4F, 0x2597C, 0x25AA7, 0x7AEE, 0x4202, + 0x25BAB, 0x7BC6, 0x7BC9, 0x4227, 0x25C80, 0x7CD2, 0x42A0, 0x7CE8, + 0x7CE3, 0x7D00, 0x25F86, 0x7D63, 0x4301, 0x7DC7, 0x7E02, 0x7E45, + 0x4334, 0x26228, 0x26247, 0x4359, 0x262D9, 0x7F7A, 0x2633E, 0x7F95, + 0x7FFA, 0x264DA, 0x26523, 0x8060, 0x265A8, 0x8070, 0x2335F, 0x43D5, + 0x80B2, 0x8103, 0x440B, 0x813E, 0x5AB5, 0x267A7, 0x267B5, 0x23393, + 0x2339C, 0x8204, 0x8F9E, 0x446B, 0x8291, 0x828B, 0x829D, 0x52B3, + 0x82B1, 0x82B3, 0x82BD, 0x82E6, 0x26B3C, 0x831D, 0x8363, 0x83AD, + 0x8323, 0x83BD, 0x83E7, 0x8353, 0x83CA, 0x83CC, 0x83DC, 0x26C36, + 0x26D6B, 0x26CD5, 0x452B, 0x84F1, 0x84F3, 0x8516, 0x273CA, 0x8564, + 0x26F2C, 0x455D, 0x4561, 0x26FB1, 0x270D2, 0x456B, 0x8650, 0x8667, + 0x8669, 0x86A9, 0x8688, 0x870E, 0x86E2, 0x8728, 0x876B, 0x8786, + 0x45D7, 0x87E1, 0x8801, 0x45F9, 0x8860, 0x27667, 0x88D7, 0x88DE, + 0x4635, 0x88FA, 0x34BB, 0x278AE, 0x27966, 0x46BE, 0x46C7, 0x8AA0, + 0x27CA8, 0x8CAB, 0x8CC1, 0x8D1B, 0x8D77, 0x27F2F, 0x20804, 0x8DCB, + 0x8DBC, 0x8DF0, 0x208DE, 0x8ED4, 0x285D2, 0x285ED, 0x9094, 0x90F1, + 0x9111, 0x2872E, 0x911B, 0x9238, 0x92D7, 0x92D8, 0x927C, 0x93F9, + 0x9415, 0x28BFA, 0x958B, 0x4995, 0x95B7, 0x28D77, 0x49E6, 0x96C3, + 0x5DB2, 0x9723, 0x29145, 0x2921A, 0x4A6E, 0x4A76, 0x97E0, 0x2940A, + 0x4AB2, 0x29496, 0x9829, 0x295B6, 0x98E2, 0x4B33, 0x9929, 0x99A7, + 0x99C2, 0x99FE, 0x4BCE, 0x29B30, 0x9C40, 0x9CFD, 0x4CCE, 0x4CED, + 0x9D67, 0x2A0CE, 0x4CF8, 0x2A105, 0x2A20E, 0x2A291, 0x4D56, 0x9EFE, + 0x9F05, 0x9F0F, 0x9F16, 0x2A600 }; -static const lxb_unicode_normalization_entry_t lxb_unicode_normalization_entries[5131] = +static const lxb_unicode_normalization_entry_t lxb_unicode_normalization_entries[5132] = { {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5504, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4812, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4874, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1637, 276}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 549, 104}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1703, 292}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1372, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1788, 307}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4380, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4736, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1710, 295}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4806, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1841, 314}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1878, 327}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 413, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5411, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 350, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1243, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1700, 291}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 76, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6050, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4338, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6031, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6807, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 316, 92}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6049, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6019, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1267, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2245, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 286, 85}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1370, 260}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1061, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6057, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5920, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1804, 309}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 117}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 204, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6830, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4653, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3030, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 338, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3124, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6156, 457}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4506, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1850, 317}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1869, 324}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1627, 272}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4563, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 431, 101}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5280, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4416, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6083, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1448, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1861, 321}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1856, 319}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3442, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 416, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3028, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2400, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4804, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 18, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1610, 266}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 419, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1630, 273}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1847, 316}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3249, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2417, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4488, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2257, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1261, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4281, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 354, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6892, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2431, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1057, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4722, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1, 54}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 15, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1646, 279}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4607, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2092, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6601, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3080, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4392, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6470, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 314, 91}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4778, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 393, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6661, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3610, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5838, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4404, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3222, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4338, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1850, 317}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1146, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2260, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3433, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1223, 256}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3116, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 222, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2491, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6716, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 104, 73}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4734, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 58, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6910, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 4258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6680, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6655, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 78, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6039, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 434, 102}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1045, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1643, 278}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3020, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6686, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6724, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 332, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 76, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1273, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 8, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6649, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 441, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1684, 285}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4500, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4728, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 288, 86}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3222, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1859, 320}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6034, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 134, 79}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3164, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 312, 90}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4984, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1263, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 64, 64}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1608, 265}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5426, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 129}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1020, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1646, 279}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4764, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4496, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3046, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2391, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1847, 316}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1271, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4446, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1618, 269}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1806, 310}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2260, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1856, 319}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4368, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4582, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4863, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4354, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6109, 445}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6561, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6028, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1615, 268}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1790, 308}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4537, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4498, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4694, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 8, 5730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2384, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1875, 326}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 82, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1630, 273}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 570, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6722, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1725, 300}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6436, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1494, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 264, 84}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 268, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 549, 104}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1697, 290}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6736, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3172, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2910, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1223, 256}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6561, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 535, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6708, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 116}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6028, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 416, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1368, 259}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6653, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6053, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3409, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4398, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6472, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6283, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4498, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1844, 315}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1141, 254}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 114, 75}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1183, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5797, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 375, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1488, 264}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1634, 275}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 62, 63}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2826, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1275, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4332, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4858, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 104, 73}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5504, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4401, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5435, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 32, 56}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6854, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6317, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3204, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5420, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3114, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 92, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3249, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4676, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3216, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2559, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2884, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4419, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4332, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4413, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1706, 293}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2511, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4386, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 395, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1722, 299}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3174, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3034, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1958, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4716, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1319, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 755, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6647, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 216, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6661, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 238, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6019, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 751, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 399, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2228, 334}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6698, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4886, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1955, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 422, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6892, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3012, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1506, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 124, 78}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4504, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6174, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2886, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3152, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6502, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3572, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6238, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1243, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2791, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1438, 262}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6172, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 162, 81}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6164, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 36, 59}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1670, 284}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6722, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5420, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6927, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1157, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1019, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3092, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 286, 85}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5585, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1105, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 332, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3034, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4721, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 42, 60}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3433, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1719, 298}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2092, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4686, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3080, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1124, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5221, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4655, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1863, 322}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1317, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 50, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 62, 63}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2780, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4374, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6682, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4569, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2423, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 296, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 96, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3379, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 282, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 212, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4563, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1772, 305}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1486, 263}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1688, 287}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6962, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6653, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6043, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6470, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1049, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 94, 72}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 401, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4464, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 541, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4714, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6713, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1442, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2118, 333}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6755, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4827, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1019, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4506, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 348, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2423, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1750, 303}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 2, 599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6748, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1730, 302}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3799, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6259, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 168, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6686, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 751, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6714, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4275, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 18, 5712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6840, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1333, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1612, 267}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 410, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6424, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4496, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3110, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1343, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4401, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4674, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1713, 296}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6349, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1275, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 428, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3212, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1472, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1446, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 208, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5278, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4547, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 128}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2333, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6948, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4636, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4752, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6812, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1640, 277}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6734, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1430, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6706, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1031, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6742, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2417, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4607, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5498, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 11, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6058, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2435, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1790, 308}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 82, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 72, 66}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6030, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 565, 106}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4874, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3036, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6045, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 70, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 332}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6790, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 304, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4189, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 88, 71}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2533, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2766, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 242, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6716, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 513, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4366, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 7, 3318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 218, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 262, 83}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6464, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1040, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 547, 103}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4569, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2930, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4746, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6636, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4682, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 350, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3168, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4710, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5408, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5221, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2435, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6039, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4561, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2806, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1776, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6563, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4625, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 310, 89}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6643, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6721, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 18, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6154, 456}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4384, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3040, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 93}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 404, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4755, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1612, 267}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1844, 315}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 330, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4926, 426}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 685, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3991, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3240, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1853, 318}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2499, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6268, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6746, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 431, 101}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5399, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 86, 69}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1700, 291}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4384, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3168, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1826, 311}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6585, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1893, 330}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4494, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4299, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4488, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6706, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 216, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6933, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4452, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4643, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6710, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4452, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6137, 453}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1710, 295}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1686, 286}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 300, 88}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6658, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3166, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6031, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5282, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2248, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 164, 82}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6572, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1668, 283}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4425, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 503, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 117}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 290, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2547, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4948, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6156, 457}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4632, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 767, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6053, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4780, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3088, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6720, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6559, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6483, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6748, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6734, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1488, 264}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1124, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6641, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2892, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 360, 96}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3243, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1454, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1632, 274}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1881, 328}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6927, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4354, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1708, 294}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4374, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 585, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2402, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6736, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1686, 286}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6674, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 882, 225}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1719, 298}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 348, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6670, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1506, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 64, 64}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1031, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 626, 126}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1885, 329}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1837, 312}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 395, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 316, 92}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1893, 330}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4716, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3116, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6111, 446}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3144, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6299, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 15, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 93}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1353, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 72, 66}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2125, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 413, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 419, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 713, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4658, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4843, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6752, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 242, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1235, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1241, 258}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6780, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4748, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1269, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 266, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4869, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 24, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6430, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 80, 67}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 262, 83}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5296, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4585, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 401, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6597, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2245, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 40, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1774, 306}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5259, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 930, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 218, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1374, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6569, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 88, 71}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4871, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4851, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3166, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6449, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 362, 97}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2330, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6682, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1688, 287}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4643, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 112, 74}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5429, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6397, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1323, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 865, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1872, 325}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1640, 277}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1374, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6829, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 116}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2405, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5408, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1875, 326}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 124, 78}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6568, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5561, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1448, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1670, 284}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3424, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6694, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5402, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4419, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3331, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4175, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4610, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1728, 301}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6061, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1654, 282}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6524, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6899, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 563, 105}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 78, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 404, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1722, 299}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3473, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3266, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4281, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 222, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 358, 95}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4730, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6654, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 675, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4428, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2984, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6749, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 60, 62}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1878, 327}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4728, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4596, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3130, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1826, 311}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1279, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 28, 55}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 266, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 354, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 114, 75}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4561, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 641, 127}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1027, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 399, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 240, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2405, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2820, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1442, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6502, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 30, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2262, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4740, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 40, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2319, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 112, 74}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 358, 95}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6130, 450}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 298, 87}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1143, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1618, 269}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4273, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4658, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4080, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2431, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5980, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6034, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5331, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 260, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 451, 100}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6474, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4317, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 166, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6607, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2118, 333}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3088, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4502, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3436, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3999, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4670, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4003, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 465, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6158, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 150, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6806, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4770, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1436, 261}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5259, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1323, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2267, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6740, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6539, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2927, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 597, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4390, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1750, 303}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2296, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4422, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3243, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 451, 100}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3036, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5417, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1652, 281}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 84, 68}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 21, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1668, 283}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 855, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 152, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4446, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1725, 300}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4736, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3146, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1454, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 587, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5840, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1239, 257}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3114, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5636, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6607, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3442, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 11, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4659, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 264, 84}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4661, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6464, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 26, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1774, 306}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1089, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4958, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 641, 127}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5268, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 356, 94}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 236, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4926, 426}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4649, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6436, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2840, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2460, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2257, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6670, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3298, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2265, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5450, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1691, 288}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 425, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1536, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1627, 272}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4404, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 136, 80}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 30, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 26, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2513, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6647, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1409, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6111, 446}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1654, 282}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4088, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 356, 94}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3266, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4366, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1728, 301}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6067, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3163, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1446, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4706, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 44, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 15, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 238, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6676, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1, 54}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6740, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3110, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3489, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1694, 289}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1866, 323}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6623, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1500, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6137, 453}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4679, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 841, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4661, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 260, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4986, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5429, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3985, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6238, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6299, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6563, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 910, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 168, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4464, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 84, 68}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5417, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 68, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1139, 253}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4724, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4271, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 128}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3282, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1460, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2352, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 152, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6038, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4053, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1839, 313}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4372, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 360, 96}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1716, 297}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1239, 257}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 48, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3136, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6323, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 116, 76}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6930, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4751, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 8, 5730, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4909, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2248, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1598, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3012, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4416, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2251, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 52, 61}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 36, 59}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 338, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 312, 90}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1881, 328}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4431, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 70, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1372, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6049, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 375, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4392, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 626, 126}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 300, 88}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4653, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2402, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4032, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6043, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4413, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4706, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 869, 221}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6735, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1637, 276}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 48, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 44, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4680, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4762, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4734, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1859, 320}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3136, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6676, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4708, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2087, 331}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4273, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2410, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4470, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3152, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 4258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1703, 292}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 565, 106}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1634, 275}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1049, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 130, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6747, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 102, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1649, 280}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1643, 278}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6730, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6030, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3148, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1249, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1839, 313}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 449, 99}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 8, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1037, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 501, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 984, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4682, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4748, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6658, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4867, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6886, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3543, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1494, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 92, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 96, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6625, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1837, 312}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4680, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1279, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2267, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3436, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1281, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 4253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 882, 225}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 801, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 164, 82}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4647, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3092, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6797, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6643, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4917, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3430, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 162, 81}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3216, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4857, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6164, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 691, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1281, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 749, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 18, 5712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4279, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 15, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1708, 294}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5244, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4275, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6042, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1652, 281}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 2, 599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1043, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2228, 334}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 32, 56}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 449, 99}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 4253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6764, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1863, 322}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1697, 290}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1303, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 144, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1624, 271}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1370, 260}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6587, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6813, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1606, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2398, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6027, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1141, 254}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 116, 76}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1885, 329}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5423, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6061, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1649, 280}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4698, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3162, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4572, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1632, 274}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6655, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1221, 255}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1684, 285}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1713, 296}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 129}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6496, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1706, 293}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1127, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4710, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6778, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 174, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6958, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1861, 321}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4398, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1061, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5405, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4330, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1621, 270}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 60, 62}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1269, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2087, 331}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6679, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 547, 103}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1752, 304}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 595, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4368, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 50, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 232, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1241, 258}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 130, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6728, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6341, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6649, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 456, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1283, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4686, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2823, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1139, 253}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4944, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3164, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4297, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 598, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5752, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1841, 314}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4694, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 288, 86}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6680, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1752, 304}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6013, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6710, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6036, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1730, 302}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 314, 91}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3144, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2428, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6813, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6259, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 248, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1221, 255}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4649, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6569, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6154, 456}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2243, 335}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2892, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 21, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 57}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1804, 309}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5654, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2194, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 236, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6694, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6525, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6496, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3162, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 136, 80}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 86, 69}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1772, 305}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5426, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1738, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2037, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2778, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5402, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2933, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 52, 61}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2251, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6751, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3042, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6323, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 431, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1063, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4297, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4647, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 869, 221}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4670, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1438, 262}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1368, 259}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4601, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2045, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6020, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4470, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5697, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3552, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1249, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1806, 310}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1869, 324}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4080, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 362, 97}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4299, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4469, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6105, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4713, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 248, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2858, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5435, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5498, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 298, 87}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5450, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5540, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6595, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1691, 288}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3124, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5411, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4422, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5423, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4676, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3708, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4740, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 332}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 134, 79}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2933, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6060, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1500, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1610, 266}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1043, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5999, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 434, 102}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 7, 3318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4915, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4587, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 94, 72}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2398, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4279, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4372, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5399, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5405, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1003, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 212, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1866, 323}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6516, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 166, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3030, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3042, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1621, 270}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1615, 268}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1608, 265}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4472, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4088, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4698, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4696, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 68, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 144, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6040, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6674, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 563, 105}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1694, 289}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4655, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 28, 55}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5250, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4386, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4504, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 172, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4559, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2243, 335}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6042, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6933, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4598, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6698, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 58, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6130, 450}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2636, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1273, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6724, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3959, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4494, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4390, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1484, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3204, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4502, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1027, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4500, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 422, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2714, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1853, 318}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4848, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1424, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 204, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2965, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2927, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3212, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4380, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1624, 271}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6333, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6547, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2384, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4722, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 42, 60}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 721, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 57}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6027, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1267, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4674, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1261, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 240, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6037, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6109, 445}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4283, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1788, 307}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 80, 67}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1716, 297}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3240, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5746, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2948, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1263, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4724, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3028, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1486, 263}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6036, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4968, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3503, 0}, {0, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 1, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 220, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 240, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 91, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 7, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 230, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 216, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 449}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 202, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 444}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 439}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 8, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 240, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 230, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 9, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 8, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 220, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 7, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 1, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 444}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 91, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 449}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 216, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 447}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 439}, {0, LXB_UNICODE_QUICK__UNDEF, 230, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 220, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 18, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 1, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 216, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 220, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 9, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 28, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 233, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 234, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 224, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 122, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 17, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 7, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 9, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 222, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 232, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 16, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 30, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 25, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 130, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 218, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 228, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 107, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 202, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 13, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 11, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 19, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 27, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 31, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 20, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 35, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 30, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 18, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 21, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 23, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 15, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 32, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 232, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 10, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 216, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 13, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 118, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 34, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 31, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 233, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 84, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 132, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 103, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 228, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 202, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 26, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 226, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 214, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 20, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 24, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 27, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 22, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 10, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 36, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 19, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 224, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 32, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 12, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 33, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 11, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 222, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 218, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 132, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 6, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 14, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 36, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 129, 0, 0, 232}, {0, LXB_UNICODE_QUICK__UNDEF, 29, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 24, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 35, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 17, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 26, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 121}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 136}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 378}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 12}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 395}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 437}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 366}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 369}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 18}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 341}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 143}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 131}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 336}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 373}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 382}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 31}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 219}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 191}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 203}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 170}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 172}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 156}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 383}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 421}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 400}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 120}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 108}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 205}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 356}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 112}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 241}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 174}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 134}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 352}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 25}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 384}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 251}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 186}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 148}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 115}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 58}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 113}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 377}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 211}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 428}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 337}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 419}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 342}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 217}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 452}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 375}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 434}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 22}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 396}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 401}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 6}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 404}, + {0, LXB_UNICODE_QUICK__UNDEF, 16, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 33, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 107, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 214, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 34, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 23, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 103, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 25, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 129, 0, 0, 232}, + {0, LXB_UNICODE_QUICK__UNDEF, 15, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 14, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 84, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 423}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 184}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 228}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 392}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 182}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 410}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 11}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 213}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 157}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 175}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 397}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 215}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 150}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 149}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 201}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 362}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 360}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 8}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 391}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 433}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 183}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 430}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 108}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 144}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 339}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 419}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 235}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 174}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 29}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 18}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 432}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 454}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 138}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 440}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 387}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 28}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 22}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 402}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 197}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 164}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 30}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 438}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 177}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 210}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 415}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 1}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 49}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 133}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 236}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 399}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 403}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 401}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 38}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 53}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 41}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 406}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 137}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 363}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 206}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 196}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 425}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 407}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 179}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 118}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 168}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 220}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 50}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 47}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 440}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 367}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 2}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 46}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 348}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 216}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 27}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 386}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 366}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 193}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 238}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 130}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 222}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 235}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 155}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 351}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 347}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 408}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 243}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 242}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 142}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 153}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 141}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 357}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 371}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 372}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 436}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 354}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 4}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 390}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 145}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 147}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 202}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 192}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 107}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 165}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 227}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 224}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 161}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 413}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 252}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 15}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 166}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 52}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 23}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 344}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 248}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 180}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 77}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 132}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 19}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 32}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 189}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 346}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 391}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 17}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 39}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 133}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 414}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 70}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 380}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 239}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 430}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 199}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 30}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 386}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 247}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 162}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 345}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 178}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 251}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 418}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 152}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 13}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 119}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 198}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 231}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 421}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 114}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 230}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 181}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 182}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 175}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 224}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 409}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 422}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 246}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 338}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 352}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 163}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 203}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 58}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 48}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 233}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 125}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 177}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 169}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 21}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 362}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 42}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 441}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 20}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 8}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 207}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 37}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 65}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 349}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 51}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 46}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 228}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 411}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 242}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 195}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 145}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 217}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 211}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 385}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 212}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 350}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 132}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 44}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 110}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 10}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 229}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 154}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 119}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 237}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 402}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 35}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 214}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 455}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 250}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 241}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 194}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 451}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 200}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 45}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 428}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 347}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 156}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 252}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 443}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 176}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 143}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 2}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 410}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 186}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 367}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 359}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 185}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 240}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 135}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 115}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 172}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 12}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 435}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 146}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 157}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 249}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 411}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 414}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 390}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 142}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 368}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 234}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 429}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 245}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 109}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 378}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 196}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 191}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 118}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 379}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 154}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 43}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 149}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 412}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 139}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 195}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 33}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 197}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 393}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 244}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 13}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 370}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 403}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 358}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 424}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 213}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 237}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 415}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 136}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 65}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 155}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 351}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 161}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 434}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 50}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 223}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 98}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 230}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 420}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 123}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 29}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 356}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 398}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 209}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 364}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 236}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 338}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 212}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 193}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 173}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 423}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 431}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 16}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 240}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 160}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 167}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 163}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 343}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 178}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 218}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 429}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 336}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 375}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 199}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 192}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 436}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 381}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 3}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 385}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 27}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 146}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 34}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 21}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 454}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 151}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 231}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 44}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 443}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 399}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 190}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 353}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 124}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 394}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 41}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 26}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 387}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 159}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 416}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 19}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 248}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 340}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 33}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 15}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 125}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 404}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 412}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 431}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 25}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 344}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 220}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 427}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 5}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 123}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 139}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 1}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 162}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 424}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 397}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 131}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 7}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 394}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 121}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 341}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 9}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 144}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 205}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 17}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 36}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 216}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 355}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 169}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 348}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 202}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 413}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 337}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 16}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 151}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 373}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 365}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 408}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 214}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 448}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 28}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 376}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 188}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 122}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 374}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 389}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 422}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 45}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 10}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 365}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 135}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 138}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 418}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 379}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 455}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 183}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 176}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 110}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 246}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 164}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 114}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 368}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 14}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 451}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 185}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 339}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 438}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 171}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 249}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 388}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 34}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 24}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 198}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 184}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 345}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 245}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 433}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 40}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 442}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 107}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 31}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 363}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 39}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 407}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 6}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 187}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 354}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 150}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 244}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 32}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 372}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 382}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 226}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 49}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 417}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 109}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 350}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 5}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 165}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 361}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 234}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 435}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 396}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 153}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 239}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 204}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 152}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 194}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 7}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 208}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 171}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 437}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 112}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 140}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 181}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 359}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 187}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 158}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 405}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 111}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 409}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 416}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 427}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 200}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 250} -}; - -static const lxb_unicode_idna_entry_t lxb_unicode_idna_entries[3923] = -{ - {0, 0, 0}, - {LXB_UNICODE_IDNA_DISALLOWED, 0, 0}, - {LXB_UNICODE_IDNA_VALID, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 673}, - {LXB_UNICODE_IDNA_MAPPED, 2, 532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 27}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 327}, - {LXB_UNICODE_IDNA_IGNORED, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 301}, - {LXB_UNICODE_IDNA_MAPPED, 1, 66}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3328}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1657}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3820}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4861}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2218}, - {LXB_UNICODE_IDNA_DEVIATION, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4990}, - {LXB_UNICODE_IDNA_MAPPED, 1, 627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1070}, - {LXB_UNICODE_IDNA_MAPPED, 1, 10}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1060}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3722}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3738}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5062}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 310}, - {LXB_UNICODE_IDNA_MAPPED, 1, 20}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1812}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 154}, - {LXB_UNICODE_IDNA_MAPPED, 1, 24}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3001}, - {LXB_UNICODE_IDNA_MAPPED, 2, 560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1059}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3443}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 22}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3403}, - {LXB_UNICODE_IDNA_MAPPED, 1, 297}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2192}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3766}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 308}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 12}, - {LXB_UNICODE_IDNA_MAPPED, 1, 526}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 898}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3579}, - {LXB_UNICODE_IDNA_MAPPED, 1, 706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3732}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1016}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 737}, - {LXB_UNICODE_IDNA_MAPPED, 2, 944}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5355}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3143}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4715}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 621}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4444}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3838}, - {LXB_UNICODE_IDNA_MAPPED, 1, 344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 6}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5325}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 23}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1814}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3679}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3413}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3164}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4939}, - {LXB_UNICODE_IDNA_MAPPED, 1, 26}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3485}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1756}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1799}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2953}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2}, - {LXB_UNICODE_IDNA_MAPPED, 1, 16}, - {LXB_UNICODE_IDNA_MAPPED, 1, 196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 15}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2956}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3702}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1591}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3840}, - {LXB_UNICODE_IDNA_MAPPED, 1, 377}, - {LXB_UNICODE_IDNA_MAPPED, 1, 659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1653}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2907}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1614}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3221}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 741}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 303}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 25}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1559}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1062}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3782}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4}, - {LXB_UNICODE_IDNA_MAPPED, 1, 74}, - {LXB_UNICODE_IDNA_MAPPED, 1, 300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 163}, - {LXB_UNICODE_IDNA_MAPPED, 2, 35}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3488}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4627}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 8}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 19}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4791}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 710}, - {LXB_UNICODE_IDNA_MAPPED, 2, 972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 21}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5114}, - {LXB_UNICODE_IDNA_MAPPED, 1, 372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 307}, - {LXB_UNICODE_IDNA_MAPPED, 1, 638}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3768}, - {LXB_UNICODE_IDNA_MAPPED, 1, 882}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3850}, - {LXB_UNICODE_IDNA_MAPPED, 1, 519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4622}, - {LXB_UNICODE_IDNA_MAPPED, 2, 985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 299}, - {LXB_UNICODE_IDNA_MAPPED, 1, 316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 863}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 40}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1546}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5271}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2334}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3965}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1477}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3764}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 115}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3010}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2739}, - {LXB_UNICODE_IDNA_MAPPED, 1, 756}, - {LXB_UNICODE_IDNA_MAPPED, 2, 534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1767}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3214}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4616}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4996}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5020}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 352}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5339}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 466}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1979}, - {LXB_UNICODE_IDNA_MAPPED, 1, 750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3228}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4982}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3720}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3987}, - {LXB_UNICODE_IDNA_MAPPED, 2, 572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1811}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1544}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 14}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 413}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3186}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4300}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4415}, - {LXB_UNICODE_IDNA_MAPPED, 1, 685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 302}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4569}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1037}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4843}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 9}, - {LXB_UNICODE_IDNA_MAPPED, 1, 315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 37}, - {LXB_UNICODE_IDNA_MAPPED, 1, 478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 859}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 251}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 18}, - {LXB_UNICODE_IDNA_MAPPED, 1, 678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3169}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3776}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 375}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 13}, - {LXB_UNICODE_IDNA_MAPPED, 1, 853}, - {LXB_UNICODE_IDNA_MAPPED, 1, 474}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 62}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3262}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4027}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5166}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2170}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4279}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5139}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4888}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3286}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 873}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4900}, - {LXB_UNICODE_IDNA_MAPPED, 2, 924}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1955}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3020}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5376}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4592}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 661}, - {LXB_UNICODE_IDNA_MAPPED, 1, 174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3754}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 160}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3016}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1403}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3558}, - {LXB_UNICODE_IDNA_MAPPED, 1, 289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 846}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3788}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3842}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1759}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3291}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3355}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3883}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1339}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 79}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3210}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3615}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1916}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1011}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4920}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5054}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4036}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 241}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1066}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3754}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3661}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1049}, - {LXB_UNICODE_IDNA_MAPPED, 2, 948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5385}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 34}, - {LXB_UNICODE_IDNA_MAPPED, 1, 363}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2850}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3080}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2619}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3792}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1333}, - {LXB_UNICODE_IDNA_MAPPED, 2, 31}, - {LXB_UNICODE_IDNA_MAPPED, 2, 29}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1068}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3726}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4147}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2251}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5077}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1594}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3634}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 77}, - {LXB_UNICODE_IDNA_MAPPED, 1, 91}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4571}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5142}, - {LXB_UNICODE_IDNA_MAPPED, 3, 998}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1318}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1541}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 379}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 277}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 11}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2050}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 17}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3028}, - {LXB_UNICODE_IDNA_MAPPED, 1, 56}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4970}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1813}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 842}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3967}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4790}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3673}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2266}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4387}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4366}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1661}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4477}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 367}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4527}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3750}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 239}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4689}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2337}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4494}, - {LXB_UNICODE_IDNA_MAPPED, 2, 542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4636}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5173}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 865}, - {LXB_UNICODE_IDNA_MAPPED, 1, 491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 89}, - {LXB_UNICODE_IDNA_MAPPED, 1, 868}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3448}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2944}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 523}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 7}, - {LXB_UNICODE_IDNA_MAPPED, 1, 975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3870}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 640}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3524}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 76}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 743}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4201}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 415}, - {LXB_UNICODE_IDNA_MAPPED, 1, 509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4628}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 237}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 822}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3209}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3377}, - {LXB_UNICODE_IDNA_MAPPED, 1, 752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4670}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 342}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5181}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5282}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1919}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1530}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3013}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1673}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5351}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 855}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4714}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2696}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1141}, - {LXB_UNICODE_IDNA_MAPPED, 2, 960}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3140}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3050}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1579}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2931}, - {LXB_UNICODE_IDNA_MAPPED, 1, 787}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3408}, - {LXB_UNICODE_IDNA_MAPPED, 1, 826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 771}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3008}, - {LXB_UNICODE_IDNA_MAPPED, 1, 371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5070}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1775}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5086}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1377}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1931}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3640}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1636}, - {LXB_UNICODE_IDNA_MAPPED, 2, 920}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 225}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2733}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1281}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3924}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5145}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1952}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1089}, - {LXB_UNICODE_IDNA_MAPPED, 2, 184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4727}, - {LXB_UNICODE_IDNA_MAPPED, 1, 726}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3247}, - {LXB_UNICODE_IDNA_MAPPED, 2, 550}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4505}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1761}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5230}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3347}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4615}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3283}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4748}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2207}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3295}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3613}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1682}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2123}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1745}, - {LXB_UNICODE_IDNA_MAPPED, 1, 798}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1084}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2846}, - {LXB_UNICODE_IDNA_MAPPED, 1, 486}, - {LXB_UNICODE_IDNA_MAPPED, 1, 903}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4141}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1106}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3070}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4021}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 28}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1726}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2963}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5052}, - {LXB_UNICODE_IDNA_MAPPED, 1, 33}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1545}, - {LXB_UNICODE_IDNA_MAPPED, 1, 871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1596}, - {LXB_UNICODE_IDNA_MAPPED, 2, 928}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3118}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2211}, - {LXB_UNICODE_IDNA_MAPPED, 2, 269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2131}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 794}, - {LXB_UNICODE_IDNA_MAPPED, 2, 106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5244}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5006}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1421}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1069}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1690}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1700}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1851}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 406}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4955}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3326}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 96}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2486}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4531}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4423}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2986}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3275}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 200}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 53}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5040}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5262}, - {LXB_UNICODE_IDNA_MAPPED, 1, 214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4482}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3490}, - {LXB_UNICODE_IDNA_MAPPED, 1, 645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4807}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4069}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5026}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2648}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1754}, - {LXB_UNICODE_IDNA_MAPPED, 1, 991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 966}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4969}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5131}, - {LXB_UNICODE_IDNA_MAPPED, 1, 774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1529}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 139}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1615}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3435}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4177}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4825}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 508}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5146}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2076}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 94}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 505}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4674}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2181}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 280}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1509}, - {LXB_UNICODE_IDNA_MAPPED, 3, 604}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4710}, - {LXB_UNICODE_IDNA_MAPPED, 1, 146}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4788}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2607}, - {LXB_UNICODE_IDNA_MAPPED, 2, 962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 167}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1738}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2189}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3995}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2932}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4421}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4567}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 318}, - {LXB_UNICODE_IDNA_MAPPED, 2, 966}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 384}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 218}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 209}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 343}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 400}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 215}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 442}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 124}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 383}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 369}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 247}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 208}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 168}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 377}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 159}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 406}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 141}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 130}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 137}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 70}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 160}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 420}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 441}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 179}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 361}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 23}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 98}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 364}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 77}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 52}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 47}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 20}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 353}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 395}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 37}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 35}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 380}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 393}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 388}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 219}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 376}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 358}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 357}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 53}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 222}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 355}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 233}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 342}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 173}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 40}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 170}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 417}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 148}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 389}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 425}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 189}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 188}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 51}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 371}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 180}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 370}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 190}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 243}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 360}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 206}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 349}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 207}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 134}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 120}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 4}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 158}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 405}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 111}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 3}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 167}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 166}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 452}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 122}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 14}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 113}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 11}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 147} +}; + +static const lxb_unicode_idna_entry_t lxb_unicode_idna_entries[3951] = +{ + {0, 0, 0}, + {LXB_UNICODE_IDNA_VALID, 0, 0}, + {LXB_UNICODE_IDNA_DISALLOWED, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 12}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 301}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 709}, + {LXB_UNICODE_IDNA_MAPPED, 2, 952}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3773}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3055}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 310}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3751}, {LXB_UNICODE_IDNA_MAPPED, 1, 5337}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3276}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3054}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4743}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1771}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1779}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3352}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3163}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3251}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3529}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2943}, - {LXB_UNICODE_IDNA_MAPPED, 2, 819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1400}, - {LXB_UNICODE_IDNA_MAPPED, 1, 835}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3062}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3167}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3268}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1001}, - {LXB_UNICODE_IDNA_MAPPED, 1, 145}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4549}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 81}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3810}, - {LXB_UNICODE_IDNA_MAPPED, 2, 263}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 26}, + {LXB_UNICODE_IDNA_IGNORED, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 34}, + {LXB_UNICODE_IDNA_MAPPED, 1, 16}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3673}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1718}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3025}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4957}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1597}, + {LXB_UNICODE_IDNA_MAPPED, 18, 4343}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3769}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5347}, + {LXB_UNICODE_IDNA_MAPPED, 2, 184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3564}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4332}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5}, + {LXB_UNICODE_IDNA_MAPPED, 1, 631}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4505}, + {LXB_UNICODE_IDNA_MAPPED, 2, 574}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 20}, + {LXB_UNICODE_IDNA_MAPPED, 1, 15}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1722}, + {LXB_UNICODE_IDNA_MAPPED, 1, 6}, + {LXB_UNICODE_IDNA_MAPPED, 1, 862}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2085}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 391}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 317}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 27}, + {LXB_UNICODE_IDNA_MAPPED, 1, 442}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5064}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 296}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4993}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 23}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 62}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 79}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5130}, + {LXB_UNICODE_IDNA_MAPPED, 1, 258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1472}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2079}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3839}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 33}, + {LXB_UNICODE_IDNA_MAPPED, 1, 681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 837}, + {LXB_UNICODE_IDNA_MAPPED, 1, 512}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 304}, + {LXB_UNICODE_IDNA_MAPPED, 1, 667}, + {LXB_UNICODE_IDNA_MAPPED, 2, 938}, + {LXB_UNICODE_IDNA_MAPPED, 1, 761}, {LXB_UNICODE_IDNA_MAPPED, 1, 3269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 626}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1820}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5287}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5096}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 430}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3007}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3166}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2704}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1457}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3055}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 642}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4779}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3145}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 409}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4713}, - {LXB_UNICODE_IDNA_MAPPED, 1, 319}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 82}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3353}, - {LXB_UNICODE_IDNA_MAPPED, 2, 611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3181}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4875}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5080}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2990}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5251}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3432}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3936}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3280}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4432}, {LXB_UNICODE_IDNA_MAPPED, 1, 3376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 54}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1169}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2901}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1616}, - {LXB_UNICODE_IDNA_MAPPED, 1, 439}, - {LXB_UNICODE_IDNA_MAPPED, 2, 267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3098}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1288}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3760}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3736}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1022}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 128}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 83}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3991}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2996}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3067}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1063}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 233}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3361}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1069}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4770}, + {LXB_UNICODE_IDNA_MAPPED, 2, 928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 302}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3082}, + {LXB_UNICODE_IDNA_MAPPED, 1, 14}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1091}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1330}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 10}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3757}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 21}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 457}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 24}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4662}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4893}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4540}, + {LXB_UNICODE_IDNA_MAPPED, 1, 7}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4643}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 17}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 18}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 13}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3644}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2006}, {LXB_UNICODE_IDNA_MAPPED, 3, 4180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4608}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1415}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3308}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4532}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2317}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4605}, - {LXB_UNICODE_IDNA_MAPPED, 2, 952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 518}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1793}, - {LXB_UNICODE_IDNA_MAPPED, 1, 901}, - {LXB_UNICODE_IDNA_MAPPED, 2, 987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 891}, - {LXB_UNICODE_IDNA_MAPPED, 1, 358}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1420}, - {LXB_UNICODE_IDNA_MAPPED, 2, 934}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1478}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1017}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2212}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 11}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 9}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5142}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5390}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5128}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 77}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1541}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4716}, {LXB_UNICODE_IDNA_MAPPED, 1, 5002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 272}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1527}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3138}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1739}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4572}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 806}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1004}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4749}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3085}, - {LXB_UNICODE_IDNA_MAPPED, 1, 356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3073}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4377}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 830}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2840}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 908}, - {LXB_UNICODE_IDNA_MAPPED, 2, 954}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2940}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5241}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3648}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3500}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3215}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3601}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1727}, - {LXB_UNICODE_IDNA_MAPPED, 1, 816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5259}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4957}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4726}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1640}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1943}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5171}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4673}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5050}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1557}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5274}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2111}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4902}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3477}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1027}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4734}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1762}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2147}, - {LXB_UNICODE_IDNA_MAPPED, 2, 930}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3944}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4891}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1535}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5137}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4629}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3692}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2198}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 325}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 799}, - {LXB_UNICODE_IDNA_MAPPED, 1, 629}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 234}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4936}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4865}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1451}, - {LXB_UNICODE_IDNA_MAPPED, 3, 980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1817}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3794}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1743}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5335}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1830}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3027}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 292}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3536}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4483}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5043}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3234}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4553}, - {LXB_UNICODE_IDNA_MAPPED, 1, 324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 337}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4685}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4276}, - {LXB_UNICODE_IDNA_MAPPED, 1, 159}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3561}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4584}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2215}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1553}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3038}, - {LXB_UNICODE_IDNA_MAPPED, 1, 682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4738}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2979}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2824}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1025}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3407}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2216}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4428}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4884}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3655}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1177}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1432}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1117}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4507}, - {LXB_UNICODE_IDNA_MAPPED, 2, 113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 803}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1842}, - {LXB_UNICODE_IDNA_MAPPED, 2, 538}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2631}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5328}, - {LXB_UNICODE_IDNA_MAPPED, 1, 725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5042}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2454}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 755}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 483}, - {LXB_UNICODE_IDNA_MAPPED, 1, 864}, - {LXB_UNICODE_IDNA_MAPPED, 1, 493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 355}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4665}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2937}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4702}, - {LXB_UNICODE_IDNA_MAPPED, 1, 880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 761}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3389}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3650}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1763}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3282}, - {LXB_UNICODE_IDNA_MAPPED, 1, 414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4648}, - {LXB_UNICODE_IDNA_MAPPED, 1, 652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4937}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4225}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3494}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5028}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 432}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3035}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1408}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4753}, - {LXB_UNICODE_IDNA_MAPPED, 1, 740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5372}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5136}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 854}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4472}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4706}, - {LXB_UNICODE_IDNA_MAPPED, 2, 589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 662}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2768}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2481}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5216}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1564}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4414}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3185}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 765}, - {LXB_UNICODE_IDNA_MAPPED, 1, 772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5132}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3404}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3451}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1691}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5295}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3635}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4072}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1749}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3638}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3339}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5187}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3930}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5059}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3636}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4802}, - {LXB_UNICODE_IDNA_MAPPED, 2, 104}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3508}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4898}, - {LXB_UNICODE_IDNA_MAPPED, 2, 528}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1689}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5195}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5169}, - {LXB_UNICODE_IDNA_MAPPED, 1, 917}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1737}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2273}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2960}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1047}, {LXB_UNICODE_IDNA_MAPPED, 1, 387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4707}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1863}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5030}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3625}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1694}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2400}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3868}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 293}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4436}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3886}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1766}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2756}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1073}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3868}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4643}, - {LXB_UNICODE_IDNA_MAPPED, 1, 256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3100}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3954}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1561}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1079}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4325}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2575}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5286}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1471}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3047}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2998}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3380}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4588}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4823}, - {LXB_UNICODE_IDNA_MAPPED, 1, 692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3019}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1641}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4995}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1494}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5362}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1327}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 78}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4611}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4837}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3510}, - {LXB_UNICODE_IDNA_MAPPED, 3, 286}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2929}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1055}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 339}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3541}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3607}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4228}, - {LXB_UNICODE_IDNA_MAPPED, 1, 217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 347}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4769}, + {LXB_UNICODE_IDNA_MAPPED, 1, 306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 8}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5355}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4961}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3}, + {LXB_UNICODE_IDNA_MAPPED, 1, 760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1810}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4596}, {LXB_UNICODE_IDNA_MAPPED, 1, 3261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3174}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 918}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4666}, - {LXB_UNICODE_IDNA_MAPPED, 2, 609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 247}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5036}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1391}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2838}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3343}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2204}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3877}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2965}, - {LXB_UNICODE_IDNA_MAPPED, 1, 643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3866}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3013}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 271}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3753}, + {LXB_UNICODE_IDNA_MAPPED, 2, 572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 40}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3264}, {LXB_UNICODE_IDNA_MAPPED, 1, 5311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2223}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 25}, + {LXB_UNICODE_IDNA_MAPPED, 1, 22}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 332}, {LXB_UNICODE_IDNA_MAPPED, 1, 713}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4739}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 869}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1937}, - {LXB_UNICODE_IDNA_MAPPED, 1, 219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3454}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 181}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3151}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3862}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2819}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1091}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2226}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1845}, - {LXB_UNICODE_IDNA_MAPPED, 2, 938}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 739}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2475}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1423}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 382}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3740}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1440}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3663}, + {LXB_UNICODE_IDNA_MAPPED, 1, 87}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1651}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3988}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3415}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4741}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2929}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1770}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 825}, {LXB_UNICODE_IDNA_MAPPED, 1, 5082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1443}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2764}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4582}, - {LXB_UNICODE_IDNA_MAPPED, 1, 511}, - {LXB_UNICODE_IDNA_MAPPED, 2, 41}, - {LXB_UNICODE_IDNA_MAPPED, 1, 228}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1040}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3564}, - {LXB_UNICODE_IDNA_MAPPED, 1, 793}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3406}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4550}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5239}, - {LXB_UNICODE_IDNA_MAPPED, 2, 964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 767}, - {LXB_UNICODE_IDNA_MAPPED, 1, 99}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4486}, - {LXB_UNICODE_IDNA_MAPPED, 1, 374}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2044}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 149}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1762}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2096}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1017}, + {LXB_UNICODE_IDNA_MAPPED, 1, 315}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3050}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4856}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3509}, {LXB_UNICODE_IDNA_MAPPED, 1, 860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3446}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2280}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4403}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2792}, - {LXB_UNICODE_IDNA_MAPPED, 2, 585}, - {LXB_UNICODE_IDNA_MAPPED, 1, 116}, - {LXB_UNICODE_IDNA_MAPPED, 1, 666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 789}, - {LXB_UNICODE_IDNA_MAPPED, 1, 893}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 360}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5110}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1281}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3081}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4818}, + {LXB_UNICODE_IDNA_MAPPED, 2, 530}, + {LXB_UNICODE_IDNA_MAPPED, 2, 968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 80}, + {LXB_UNICODE_IDNA_MAPPED, 1, 157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 175}, + {LXB_UNICODE_IDNA_MAPPED, 1, 445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 274}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2966}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5313}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 28}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1468}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4875}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4057}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4764}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3493}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1672}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1351}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2750}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4863}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 88}, + {LXB_UNICODE_IDNA_MAPPED, 1, 54}, + {LXB_UNICODE_IDNA_MAPPED, 1, 728}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2026}, + {LXB_UNICODE_IDNA_MAPPED, 1, 313}, + {LXB_UNICODE_IDNA_MAPPED, 1, 340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1367}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4489}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2788}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4048}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3630}, {LXB_UNICODE_IDNA_MAPPED, 2, 2540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1324}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1212}, - {LXB_UNICODE_IDNA_MAPPED, 2, 562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 881}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4722}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4042}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1123}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1571}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3394}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 298}, + {LXB_UNICODE_IDNA_MAPPED, 1, 246}, + {LXB_UNICODE_IDNA_MAPPED, 1, 493}, + {LXB_UNICODE_IDNA_MAPPED, 1, 657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3102}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2774}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3827}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1061}, + {LXB_UNICODE_IDNA_MAPPED, 1, 311}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4558}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1739}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3088}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5069}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 60}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4776}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3883}, + {LXB_UNICODE_IDNA_MAPPED, 1, 277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4754}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2926}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5350}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 256}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1741}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3483}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1653}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 19}, + {LXB_UNICODE_IDNA_MAPPED, 2, 948}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 809}, + {LXB_UNICODE_IDNA_MAPPED, 1, 354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4406}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2309}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1683}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3559}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2204}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 376}, + {LXB_UNICODE_IDNA_MAPPED, 1, 791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 507}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5286}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3833}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3511}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 96}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3299}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3010}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3674}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5071}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 58}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4520}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3809}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 109}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4674}, + {LXB_UNICODE_IDNA_MAPPED, 2, 954}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 696}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4671}, {LXB_UNICODE_IDNA_MAPPED, 1, 1558}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5301}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1483}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 334}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3906}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4869}, - {LXB_UNICODE_IDNA_MAPPED, 2, 615}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1068}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3743}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3400}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4977}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3129}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2798}, + {LXB_UNICODE_IDNA_MAPPED, 1, 135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4963}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 204}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4374}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5044}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 308}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2762}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 356}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3640}, {LXB_UNICODE_IDNA_MAPPED, 1, 1573}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3216}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3734}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 707}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4988}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5265}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 781}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1794}, - {LXB_UNICODE_IDNA_MAPPED, 1, 716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5109}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2149}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1330}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1702}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1809}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1486}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3690}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1449}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 423}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2199}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5149}, + {LXB_UNICODE_IDNA_MAPPED, 1, 431}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3927}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5080}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1503}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3735}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1605}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5058}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3823}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1565}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3741}, {LXB_UNICODE_IDNA_MAPPED, 1, 1720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 177}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1869}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1893}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 888}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4057}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2963}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1064}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 790}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 305}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5013}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5363}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3566}, + {LXB_UNICODE_IDNA_MAPPED, 2, 550}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4141}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1214}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5166}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 884}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1744}, + {LXB_UNICODE_IDNA_MAPPED, 2, 962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1099}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 425}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4320}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1073}, {LXB_UNICODE_IDNA_MAPPED, 1, 2097}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3030}, - {LXB_UNICODE_IDNA_MAPPED, 1, 353}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3104}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 386}, - {LXB_UNICODE_IDNA_MAPPED, 2, 186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2213}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3979}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3116}, - {LXB_UNICODE_IDNA_MAPPED, 1, 727}, - {LXB_UNICODE_IDNA_MAPPED, 2, 548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 182}, - {LXB_UNICODE_IDNA_MAPPED, 6, 2744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5349}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2135}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 166}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1066}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3671}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1382}, + {LXB_UNICODE_IDNA_MAPPED, 2, 576}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4391}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2596}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 299}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2824}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4605}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4591}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5361}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4630}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4084}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3191}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2015}, + {LXB_UNICODE_IDNA_MAPPED, 2, 35}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3907}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 370}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3941}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4454}, + {LXB_UNICODE_IDNA_MAPPED, 2, 188}, + {LXB_UNICODE_IDNA_MAPPED, 1, 243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 417}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1912}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5026}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1478}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 89}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 362}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1973}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1543}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3385}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2675}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5020}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1191}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2992}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2865}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3283}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 83}, + {LXB_UNICODE_IDNA_MAPPED, 1, 145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4920}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1566}, {LXB_UNICODE_IDNA_MAPPED, 1, 410}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5158}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1507}, + {LXB_UNICODE_IDNA_DEVIATION, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 344}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1413}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4697}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4547}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 178}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1547}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 374}, + {LXB_UNICODE_IDNA_MAPPED, 1, 722}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3383}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1141}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5055}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 326}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4564}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4478}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2954}, + {LXB_UNICODE_IDNA_MAPPED, 1, 528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 314}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3652}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1194}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3067}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3235}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4907}, + {LXB_UNICODE_IDNA_MAPPED, 2, 597}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3867}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3311}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3346}, + {LXB_UNICODE_IDNA_MAPPED, 1, 355}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3070}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4829}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1042}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3937}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5001}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5118}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3028}, + {LXB_UNICODE_IDNA_MAPPED, 1, 37}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4726}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5144}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1591}, {LXB_UNICODE_IDNA_MAPPED, 3, 2359}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4561}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5326}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1582}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4721}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1407}, - {LXB_UNICODE_IDNA_MAPPED, 1, 390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1755}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4847}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 67}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3358}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2080}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 502}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 51}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1731}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3695}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 82}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3522}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4426}, {LXB_UNICODE_IDNA_MAPPED, 1, 440}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 167}, + {LXB_UNICODE_IDNA_MAPPED, 1, 742}, + {LXB_UNICODE_IDNA_MAPPED, 1, 879}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1818}, + {LXB_UNICODE_IDNA_MAPPED, 1, 100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1724}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3248}, + {LXB_UNICODE_IDNA_MAPPED, 1, 915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3047}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1610}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5180}, + {LXB_UNICODE_IDNA_MAPPED, 1, 252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 907}, + {LXB_UNICODE_IDNA_MAPPED, 1, 780}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4108}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4936}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3247}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5203}, + {LXB_UNICODE_IDNA_MAPPED, 2, 602}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2119}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2692}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1692}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3492}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5238}, {LXB_UNICODE_IDNA_MAPPED, 1, 897}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4938}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4503}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 202}, - {LXB_UNICODE_IDNA_MAPPED, 2, 940}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2865}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4548}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1628}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2966}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3956}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5209}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1773}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4443}, - {LXB_UNICODE_IDNA_MAPPED, 2, 968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4416}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5293}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 699}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3119}, - {LXB_UNICODE_IDNA_MAPPED, 1, 668}, - {LXB_UNICODE_IDNA_MAPPED, 1, 467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 841}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4007}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 274}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5167}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4794}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 874}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2443}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1303}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3004}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 295}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1435}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3136}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4524}, - {LXB_UNICODE_IDNA_MAPPED, 1, 137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3327}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4601}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 913}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3566}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4267}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 807}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2292}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3803}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 503}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1759}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3974}, + {LXB_UNICODE_IDNA_MAPPED, 2, 41}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4393}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3650}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2062}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1198}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2840}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3125}, + {LXB_UNICODE_IDNA_MAPPED, 1, 679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4837}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 396}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4309}, {LXB_UNICODE_IDNA_MAPPED, 1, 3307}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3425}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1609}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2868}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2788}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3068}, - {LXB_UNICODE_IDNA_MAPPED, 1, 165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 829}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5309}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3784}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4069}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4676}, + {LXB_UNICODE_IDNA_MAPPED, 2, 942}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2981}, + {LXB_UNICODE_IDNA_MAPPED, 1, 784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5256}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4586}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 61}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3925}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1206}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 991}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4473}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5368}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4438}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 364}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1743}, + {LXB_UNICODE_IDNA_MAPPED, 2, 934}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3869}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3551}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5375}, {LXB_UNICODE_IDNA_MAPPED, 1, 2946}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1202}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5021}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1482}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4001}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3097}, - {LXB_UNICODE_IDNA_MAPPED, 1, 136}, - {LXB_UNICODE_IDNA_MAPPED, 2, 576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4562}, - {LXB_UNICODE_IDNA_MAPPED, 2, 570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4979}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3902}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3938}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 817}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5270}, - {LXB_UNICODE_IDNA_MAPPED, 1, 745}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5044}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1752}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2145}, - {LXB_UNICODE_IDNA_MAPPED, 1, 471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 837}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3482}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2070}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2139}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5250}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 718}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4839}, + {LXB_UNICODE_IDNA_MAPPED, 1, 69}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5294}, + {LXB_UNICODE_IDNA_MAPPED, 1, 783}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3242}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 66}, {LXB_UNICODE_IDNA_MAPPED, 1, 5280}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1531}, - {LXB_UNICODE_IDNA_MAPPED, 2, 265}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2012}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5055}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5387}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5165}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 516}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3904}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 425}, - {LXB_UNICODE_IDNA_MAPPED, 3, 47}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4809}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4610}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1638}, - {LXB_UNICODE_IDNA_MAPPED, 1, 648}, - {LXB_UNICODE_IDNA_MAPPED, 2, 591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1610}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3306}, - {LXB_UNICODE_IDNA_MAPPED, 2, 619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5247}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5254}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5152}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3674}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 118}, + {LXB_UNICODE_IDNA_MAPPED, 1, 686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3655}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1736}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2141}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3474}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1395}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2936}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5097}, + {LXB_UNICODE_IDNA_MAPPED, 1, 365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2071}, + {LXB_UNICODE_IDNA_MAPPED, 1, 151}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3707}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1687}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3019}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1893}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3711}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3660}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2844}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3172}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 325}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3031}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5287}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2942}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1190}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3325}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4093}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1101}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4467}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2631}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3134}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3923}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2770}, + {LXB_UNICODE_IDNA_MAPPED, 2, 562}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 84}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1730}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3986}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3331}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1534}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3913}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2068}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 833}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2046}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2048}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2536}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4375}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3007}, {LXB_UNICODE_IDNA_MAPPED, 1, 5122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1753}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3790}, - {LXB_UNICODE_IDNA_MAPPED, 1, 72}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 408}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5012}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4797}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 847}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4555}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 50}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2079}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3168}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4998}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5260}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5404}, + {LXB_UNICODE_IDNA_MAPPED, 2, 113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2188}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2147}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3855}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3507}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5274}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4822}, + {LXB_UNICODE_IDNA_MAPPED, 1, 67}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2153}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3861}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1398}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1419}, + {LXB_UNICODE_IDNA_MAPPED, 1, 895}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 723}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3972}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 416}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3680}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2212}, + {LXB_UNICODE_IDNA_MAPPED, 2, 568}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4410}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3839}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 350}, + {LXB_UNICODE_IDNA_MAPPED, 2, 207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3167}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 906}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1630}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5340}, + {LXB_UNICODE_IDNA_MAPPED, 2, 542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3064}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1776}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 834}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2475}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5307}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3130}, + {LXB_UNICODE_IDNA_MAPPED, 1, 421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3139}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4569}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2185}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4579}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 447}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3535}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2180}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1539}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2183}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5334}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3166}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5235}, + {LXB_UNICODE_IDNA_MAPPED, 1, 698}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5106}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4476}, + {LXB_UNICODE_IDNA_MAPPED, 1, 836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4931}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1908}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4948}, {LXB_UNICODE_IDNA_MAPPED, 1, 3421}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3550}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4585}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 867}, + {LXB_UNICODE_IDNA_MAPPED, 3, 41}, + {LXB_UNICODE_IDNA_MAPPED, 1, 215}, + {LXB_UNICODE_IDNA_MAPPED, 1, 386}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2874}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 369}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3278}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4664}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1952}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2883}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1363}, {LXB_UNICODE_IDNA_MAPPED, 1, 5019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 706}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3488}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 156}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1698}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4010}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2706}, {LXB_UNICODE_IDNA_MAPPED, 2, 1171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 851}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4943}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1490}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1622}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2828}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4923}, - {LXB_UNICODE_IDNA_MAPPED, 2, 524}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1588}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3139}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 909}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3176}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 449}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2439}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2192}, + {LXB_UNICODE_IDNA_MAPPED, 2, 613}, + {LXB_UNICODE_IDNA_MAPPED, 2, 926}, + {LXB_UNICODE_IDNA_MAPPED, 2, 259}, + {LXB_UNICODE_IDNA_MAPPED, 2, 106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 121}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2698}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1695}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4867}, + {LXB_UNICODE_IDNA_MAPPED, 1, 74}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5233}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1406}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4833}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2123}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3831}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 650}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 477}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 281}, + {LXB_UNICODE_IDNA_MAPPED, 1, 216}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2366}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3863}, {LXB_UNICODE_IDNA_MAPPED, 1, 1508}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2596}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4646}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3755}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 878}, + {LXB_UNICODE_IDNA_MAPPED, 1, 285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 358}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4717}, + {LXB_UNICODE_IDNA_MAPPED, 2, 987}, + {LXB_UNICODE_IDNA_MAPPED, 1, 230}, + {LXB_UNICODE_IDNA_MAPPED, 2, 611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3296}, + {LXB_UNICODE_IDNA_MAPPED, 1, 196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3391}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1067}, + {LXB_UNICODE_IDNA_MAPPED, 1, 737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5228}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 409}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4773}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1135}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3085}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2598}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4592}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5010}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5261}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3829}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3374}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 165}, + {LXB_UNICODE_IDNA_MAPPED, 2, 819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 731}, + {LXB_UNICODE_IDNA_MAPPED, 3, 604}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1294}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2669}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3769}, + {LXB_UNICODE_IDNA_MAPPED, 2, 0}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1370}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4369}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2102}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4231}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3996}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1423}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 289}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2283}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5017}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1474}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1706}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1839}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5039}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3039}, + {LXB_UNICODE_IDNA_MAPPED, 1, 373}, {LXB_UNICODE_IDNA_MAPPED, 2, 607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 322}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3942}, - {LXB_UNICODE_IDNA_MAPPED, 1, 85}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3670}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3079}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2621}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5334}, - {LXB_UNICODE_IDNA_MAPPED, 1, 703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 65}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4661}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2936}, - {LXB_UNICODE_IDNA_MAPPED, 1, 624}, - {LXB_UNICODE_IDNA_MAPPED, 1, 879}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 885}, - {LXB_UNICODE_IDNA_MAPPED, 1, 805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 915}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1265}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3288}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1576}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1019}, + {LXB_UNICODE_IDNA_MAPPED, 1, 908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3077}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5008}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 726}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 904}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3052}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3027}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3080}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 501}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1529}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 674}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4844}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2095}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3781}, {LXB_UNICODE_IDNA_MAPPED, 1, 5175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3239}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4547}, - {LXB_UNICODE_IDNA_MAPPED, 1, 150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1787}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1425}, - {LXB_UNICODE_IDNA_MAPPED, 2, 275}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1404}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5352}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1194}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3128}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4801}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4990}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3817}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3624}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2546}, + {LXB_UNICODE_IDNA_MAPPED, 3, 47}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 108}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4622}, + {LXB_UNICODE_IDNA_MAPPED, 2, 946}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4834}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 75}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3468}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4490}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4810}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4493}, {LXB_UNICODE_IDNA_MAPPED, 1, 3105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1475}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2754}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3325}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4962}, - {LXB_UNICODE_IDNA_MAPPED, 2, 970}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3420}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2971}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1884}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1791}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1866}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3302}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1422}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4039}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5087}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4601}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4606}, + {LXB_UNICODE_IDNA_MAPPED, 1, 408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 640}, {LXB_UNICODE_IDNA_MAPPED, 1, 3314}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3864}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5425}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1489}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3178}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3569}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4865}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4906}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2999}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5146}, + {LXB_UNICODE_IDNA_MAPPED, 1, 380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1637}, + {LXB_UNICODE_IDNA_MAPPED, 8, 4361}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5120}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 50}, + {LXB_UNICODE_IDNA_MAPPED, 1, 90}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2927}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5047}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1546}, + {LXB_UNICODE_IDNA_MAPPED, 1, 654}, + {LXB_UNICODE_IDNA_MAPPED, 2, 944}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5085}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1738}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5328}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 684}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 438}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 663}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1872}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3260}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5074}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 172}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4855}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3011}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1506}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5188}, + {LXB_UNICODE_IDNA_MAPPED, 1, 474}, + {LXB_UNICODE_IDNA_MAPPED, 1, 740}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2025}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2198}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3152}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 64}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5214}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1674}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 468}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4762}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 911}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3042}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 883}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3433}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3919}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4683}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3389}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2581}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3957}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3058}, + {LXB_UNICODE_IDNA_MAPPED, 1, 476}, + {LXB_UNICODE_IDNA_MAPPED, 2, 534}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2590}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1032}, + {LXB_UNICODE_IDNA_MAPPED, 1, 769}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4655}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3396}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1458}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5296}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1011}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 352}, + {LXB_UNICODE_IDNA_MAPPED, 2, 526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2109}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3508}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1609}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3414}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5346}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1438}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4921}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4270}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1381}, + {LXB_UNICODE_IDNA_MAPPED, 2, 564}, + {LXB_UNICODE_IDNA_MAPPED, 2, 918}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5315}, + {LXB_UNICODE_IDNA_MAPPED, 1, 307}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1740}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1650}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4539}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 471}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3384}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 152}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5133}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1919}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5061}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3458}, + {LXB_UNICODE_IDNA_MAPPED, 2, 538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1559}, {LXB_UNICODE_IDNA_MAPPED, 1, 1540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 420}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 75}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 834}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4543}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1741}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3294}, + {LXB_UNICODE_IDNA_MAPPED, 1, 381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3401}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3146}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4771}, {LXB_UNICODE_IDNA_MAPPED, 1, 4638}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 68}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1601}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3060}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1035}, - {LXB_UNICODE_IDNA_MAPPED, 1, 129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 902}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4986}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4165}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2027}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3083}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4641}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3020}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4926}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4395}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3437}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3438}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2826}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5396}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 635}, + {LXB_UNICODE_IDNA_MAPPED, 2, 546}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2832}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3406}, + {LXB_UNICODE_IDNA_MAPPED, 1, 682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 704}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4999}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2178}, + {LXB_UNICODE_IDNA_MAPPED, 2, 922}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2100}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3074}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5034}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3188}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1375}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 346}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3254}, + {LXB_UNICODE_IDNA_MAPPED, 2, 930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1386}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1617}, + {LXB_UNICODE_IDNA_MAPPED, 1, 851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 52}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5178}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4525}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3897}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4610}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5338}, + {LXB_UNICODE_IDNA_MAPPED, 1, 483}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2948}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1471}, + {LXB_UNICODE_IDNA_MAPPED, 6, 2303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1604}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1153}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1102}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 697}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1071}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4923}, + {LXB_UNICODE_IDNA_MAPPED, 2, 956}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3449}, + {LXB_UNICODE_IDNA_MAPPED, 1, 823}, + {LXB_UNICODE_IDNA_MAPPED, 2, 581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4442}, + {LXB_UNICODE_IDNA_MAPPED, 1, 97}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5161}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3865}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2776}, {LXB_UNICODE_IDNA_MAPPED, 1, 248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 749}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1093}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4020}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5331}, + {LXB_UNICODE_IDNA_MAPPED, 1, 85}, + {LXB_UNICODE_IDNA_MAPPED, 1, 858}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1462}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2904}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 762}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5304}, {LXB_UNICODE_IDNA_MAPPED, 1, 5108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1550}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2104}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5234}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4947}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4668}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 723}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2766}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4960}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4976}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3697}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1613}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3503}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3596}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5176}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2215}, + {LXB_UNICODE_IDNA_MAPPED, 1, 250}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1778}, + {LXB_UNICODE_IDNA_MAPPED, 2, 924}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4871}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4306}, + {LXB_UNICODE_IDNA_MAPPED, 2, 591}, + {LXB_UNICODE_IDNA_MAPPED, 1, 622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 375}, + {LXB_UNICODE_IDNA_MAPPED, 2, 587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 98}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 716}, + {LXB_UNICODE_IDNA_MAPPED, 1, 203}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2032}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2952}, + {LXB_UNICODE_IDNA_MAPPED, 1, 798}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2078}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4571}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2989}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4740}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 489}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4663}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4551}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4919}, + {LXB_UNICODE_IDNA_MAPPED, 1, 692}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4696}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 940}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2337}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4597}, {LXB_UNICODE_IDNA_MAPPED, 1, 4474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4626}, - {LXB_UNICODE_IDNA_MAPPED, 2, 926}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3274}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2184}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3822}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4606}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4712}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3814}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3012}, - {LXB_UNICODE_IDNA_MAPPED, 1, 176}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4709}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4123}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1946}, + {LXB_UNICODE_IDNA_MAPPED, 1, 214}, {LXB_UNICODE_IDNA_MAPPED, 1, 5302}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2532}, - {LXB_UNICODE_IDNA_MAPPED, 2, 530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 52}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 169}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1070}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 331}, + {LXB_UNICODE_IDNA_MAPPED, 3, 995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 729}, {LXB_UNICODE_IDNA_MAPPED, 1, 5383}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1925}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3501}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5163}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2063}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2951}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5073}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3480}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2898}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5134}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3656}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1025}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 861}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5137}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3210}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 826}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 57}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4617}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1716}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2938}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4402}, {LXB_UNICODE_IDNA_MAPPED, 1, 5153}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1631}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5117}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3489}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 127}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3547}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5244}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 893}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5360}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2727}, {LXB_UNICODE_IDNA_MAPPED, 1, 3246}, - {LXB_UNICODE_IDNA_MAPPED, 2, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 70}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4814}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 843}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2643}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2448}, - {LXB_UNICODE_IDNA_MAPPED, 2, 261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5310}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4432}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3468}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3732}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 627}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1360}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2972}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1854}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5284}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1790}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5412}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3837}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3921}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1357}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1887}, + {LXB_UNICODE_IDNA_MAPPED, 1, 280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5139}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5268}, + {LXB_UNICODE_IDNA_MAPPED, 1, 495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 338}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3284}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3097}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2050}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1596}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 56}, {LXB_UNICODE_IDNA_MAPPED, 1, 3071}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1315}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2084}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3347}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3310}, + {LXB_UNICODE_IDNA_MAPPED, 1, 736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5046}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4506}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3122}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4688}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1277}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4853}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 294}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 875}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5378}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 423}, + {LXB_UNICODE_IDNA_MAPPED, 1, 125}, {LXB_UNICODE_IDNA_MAPPED, 1, 2209}, - {LXB_UNICODE_IDNA_MAPPED, 1, 623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2941}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3398}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2727}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3021}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4803}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4475}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 946}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2492}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1456}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 823}, - {LXB_UNICODE_IDNA_MAPPED, 1, 507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2925}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1463}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3076}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4961}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4711}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3244}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5321}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2922}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3499}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3177}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 867}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4763}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1988}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 80}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4841}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3336}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3287}, - {LXB_UNICODE_IDNA_MAPPED, 1, 111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 783}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5016}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3044}, - {LXB_UNICODE_IDNA_MAPPED, 1, 646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1469}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4578}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 370}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4822}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 711}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4451}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4615}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 516}, + {LXB_UNICODE_IDNA_MAPPED, 2, 31}, + {LXB_UNICODE_IDNA_MAPPED, 1, 327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2070}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 170}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2189}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3853}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 815}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2376}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2314}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5259}, + {LXB_UNICODE_IDNA_MAPPED, 2, 265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2935}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3476}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4733}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5112}, + {LXB_UNICODE_IDNA_MAPPED, 2, 978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5247}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1226}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1860}, + {LXB_UNICODE_IDNA_MAPPED, 1, 385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 792}, + {LXB_UNICODE_IDNA_MAPPED, 1, 194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4823}, + {LXB_UNICODE_IDNA_MAPPED, 1, 530}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3109}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 224}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1535}, + {LXB_UNICODE_IDNA_MAPPED, 1, 161}, + {LXB_UNICODE_IDNA_MAPPED, 1, 694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2064}, {LXB_UNICODE_IDNA_MAPPED, 1, 3416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4699}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5106}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 906}, - {LXB_UNICODE_IDNA_MAPPED, 1, 357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 779}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4876}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5154}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3971}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5250}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1176}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5193}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2119}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4013}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2062}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 336}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5128}, - {LXB_UNICODE_IDNA_MAPPED, 1, 683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 689}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2984}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3475}, + {LXB_UNICODE_IDNA_MAPPED, 2, 950}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3305}, + {LXB_UNICODE_IDNA_MAPPED, 1, 155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3355}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3419}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3116}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5031}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3324}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1615}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 51}, + {LXB_UNICODE_IDNA_MAPPED, 1, 842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1798}, + {LXB_UNICODE_IDNA_MAPPED, 2, 920}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3175}, + {LXB_UNICODE_IDNA_MAPPED, 1, 805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 99}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2838}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4847}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 402}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3693}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 687}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1896}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3403}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3606}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5050}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4677}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4842}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 508}, + {LXB_UNICODE_IDNA_MAPPED, 2, 958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5248}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5242}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4728}, + {LXB_UNICODE_IDNA_MAPPED, 1, 140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4832}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3048}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5397}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3505}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2117}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3825}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2155}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4132}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3875}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2364}, + {LXB_UNICODE_IDNA_MAPPED, 1, 128}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1003}, {LXB_UNICODE_IDNA_MAPPED, 3, 2895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 791}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1524}, - {LXB_UNICODE_IDNA_MAPPED, 2, 602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5299}, - {LXB_UNICODE_IDNA_MAPPED, 2, 566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2026}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 183}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3730}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4905}, - {LXB_UNICODE_IDNA_MAPPED, 2, 554}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 738}, - {LXB_UNICODE_IDNA_MAPPED, 2, 568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 271}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3415}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 911}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1150}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4614}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5052}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3335}, + {LXB_UNICODE_IDNA_MAPPED, 2, 972}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 816}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4969}, + {LXB_UNICODE_IDNA_MAPPED, 1, 774}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3128}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 966}, + {LXB_UNICODE_IDNA_MAPPED, 2, 186}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2696}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5423}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 278}, + {LXB_UNICODE_IDNA_MAPPED, 2, 556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1590}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2417}, {LXB_UNICODE_IDNA_MAPPED, 1, 5185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4405}, - {LXB_UNICODE_IDNA_MAPPED, 1, 140}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4835}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 443}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3444}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4419}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4971}, + {LXB_UNICODE_IDNA_MAPPED, 1, 913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 818}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2218}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4986}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3300}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2641}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2639}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4138}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2871}, {LXB_UNICODE_IDNA_MAPPED, 3, 1103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 490}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2414}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2340}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5037}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4375}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1964}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1803}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4590}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4129}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5083}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1512}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3590}, + {LXB_UNICODE_IDNA_MAPPED, 1, 806}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 361}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4545}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4650}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1494}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1027}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5308}, + {LXB_UNICODE_IDNA_MAPPED, 1, 290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2069}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4973}, + {LXB_UNICODE_IDNA_MAPPED, 1, 218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5042}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2044}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3121}, + {LXB_UNICODE_IDNA_MAPPED, 2, 964}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5076}, {LXB_UNICODE_IDNA_MAPPED, 1, 1414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4632}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 131}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 801}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4087}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1721}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2263}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2544}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4755}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3969}, - {LXB_UNICODE_IDNA_MAPPED, 2, 574}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 845}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5007}, - {LXB_UNICODE_IDNA_MAPPED, 1, 875}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5104}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 71}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4877}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1306}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4559}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 808}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3131}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3041}, + {LXB_UNICODE_IDNA_MAPPED, 1, 719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1627}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3270}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5422}, + {LXB_UNICODE_IDNA_MAPPED, 2, 985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5021}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 406}, + {LXB_UNICODE_IDNA_MAPPED, 1, 628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4535}, {LXB_UNICODE_IDNA_MAPPED, 1, 4745}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3077}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4579}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2672}, - {LXB_UNICODE_IDNA_MAPPED, 1, 380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1632}, - {LXB_UNICODE_IDNA_MAPPED, 1, 633}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1961}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4594}, - {LXB_UNICODE_IDNA_MAPPED, 1, 179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5358}, - {LXB_UNICODE_IDNA_MAPPED, 1, 396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4451}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5347}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5296}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4640}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1412}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2327}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3756}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 123}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3506}, {LXB_UNICODE_IDNA_MAPPED, 1, 892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 132}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2842}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4901}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3160}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4633}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 825}, + {LXB_UNICODE_IDNA_MAPPED, 1, 309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5132}, {LXB_UNICODE_IDNA_MAPPED, 1, 1466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2961}, - {LXB_UNICODE_IDNA_MAPPED, 1, 749}, - {LXB_UNICODE_IDNA_MAPPED, 2, 558}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3040}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 86}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2964}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3895}, + {LXB_UNICODE_IDNA_MAPPED, 3, 286}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4396}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3287}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1315}, + {LXB_UNICODE_IDNA_MAPPED, 1, 683}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3529}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4830}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 193}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1055}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2099}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5215}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3947}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3056}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3953}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5158}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4912}, + {LXB_UNICODE_IDNA_MAPPED, 3, 998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4648}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3592}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3586}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4651}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4715}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2919}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3301}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2957}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 400}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1961}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1180}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5271}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2984}, {LXB_UNICODE_IDNA_MAPPED, 1, 788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1397}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3399}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3872}, - {LXB_UNICODE_IDNA_MAPPED, 1, 884}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 255}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1797}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 862}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 759}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4908}, - {LXB_UNICODE_IDNA_MAPPED, 1, 517}, - {LXB_UNICODE_IDNA_MAPPED, 2, 597}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1586}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3298}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1806}, + {LXB_UNICODE_IDNA_MAPPED, 1, 202}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5000}, {LXB_UNICODE_IDNA_MAPPED, 1, 4613}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4956}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3483}, - {LXB_UNICODE_IDNA_MAPPED, 2, 936}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3132}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4503}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2993}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3905}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3360}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2819}, {LXB_UNICODE_IDNA_MAPPED, 1, 213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2068}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1539}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5336}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5207}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2530}, - {LXB_UNICODE_IDNA_MAPPED, 2, 546}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2557}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2954}, - {LXB_UNICODE_IDNA_MAPPED, 1, 138}, - {LXB_UNICODE_IDNA_MAPPED, 3, 44}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4604}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2322}, - {LXB_UNICODE_IDNA_MAPPED, 1, 95}, - {LXB_UNICODE_IDNA_MAPPED, 1, 763}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4399}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3277}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1710}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 866}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4637}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2913}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1801}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5263}, - {LXB_UNICODE_IDNA_MAPPED, 1, 384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3410}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 730}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 340}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 463}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4198}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3621}, - {LXB_UNICODE_IDNA_MAPPED, 1, 784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1604}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4817}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 477}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3063}, - {LXB_UNICODE_IDNA_MAPPED, 1, 55}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 753}, - {LXB_UNICODE_IDNA_MAPPED, 1, 715}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4879}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1525}, - {LXB_UNICODE_IDNA_MAPPED, 8, 4358}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1047}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1668}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3131}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3597}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4981}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3647}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1437}, + {LXB_UNICODE_IDNA_MAPPED, 1, 398}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2042}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5150}, + {LXB_UNICODE_IDNA_MAPPED, 2, 38}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 898}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4294}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5102}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2248}, {LXB_UNICODE_IDNA_MAPPED, 1, 1479}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1147}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 912}, - {LXB_UNICODE_IDNA_MAPPED, 1, 405}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5125}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3219}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3044}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3386}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1037}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5281}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 237}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3061}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5095}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3275}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3257}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5376}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 180}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 894}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3661}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2018}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 506}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 647}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4656}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2551}, + {LXB_UNICODE_IDNA_MAPPED, 2, 595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3356}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4914}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3199}, + {LXB_UNICODE_IDNA_MAPPED, 1, 337}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4027}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2971}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3353}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4488}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 284}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4600}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3141}, + {LXB_UNICODE_IDNA_MAPPED, 2, 619}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4840}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4541}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3107}, + {LXB_UNICODE_IDNA_MAPPED, 2, 269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1606}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1132}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3442}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2569}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1997}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2947}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2082}, + {LXB_UNICODE_IDNA_MAPPED, 1, 900}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3412}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1902}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5427}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4895}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3037}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3000}, + {LXB_UNICODE_IDNA_MAPPED, 1, 366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 124}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3572}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4884}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5086}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5419}, {LXB_UNICODE_IDNA_MAPPED, 1, 5179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1597}, - {LXB_UNICODE_IDNA_MAPPED, 1, 393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 849}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3211}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3318}, - {LXB_UNICODE_IDNA_MAPPED, 2, 956}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1699}, - {LXB_UNICODE_IDNA_MAPPED, 1, 216}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 102}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5211}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4788}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 912}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1726}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2107}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1580}, + {LXB_UNICODE_IDNA_MAPPED, 1, 829}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5262}, + {LXB_UNICODE_IDNA_MAPPED, 2, 932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3245}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4826}, + {LXB_UNICODE_IDNA_MAPPED, 1, 379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3046}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1476}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4619}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2260}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3471}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1162}, + {LXB_UNICODE_IDNA_MAPPED, 2, 548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4654}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4529}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5048}, + {LXB_UNICODE_IDNA_MAPPED, 1, 223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3446}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3313}, {LXB_UNICODE_IDNA_MAPPED, 1, 451}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1548}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3449}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3109}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3912}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4971}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5085}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5322}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3041}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4449}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 797}, - {LXB_UNICODE_IDNA_MAPPED, 1, 215}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 907}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1833}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1812}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2194}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5121}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4761}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1550}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2575}, + {LXB_UNICODE_IDNA_MAPPED, 1, 832}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3104}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2806}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 449}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3350}, {LXB_UNICODE_IDNA_MAPPED, 2, 1200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4941}, - {LXB_UNICODE_IDNA_MAPPED, 1, 459}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4425}, - {LXB_UNICODE_IDNA_MAPPED, 1, 206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2930}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 103}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3569}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2859}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2715}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5126}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3271}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5164}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 809}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 494}, - {LXB_UNICODE_IDNA_MAPPED, 2, 282}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 63}, - {LXB_UNICODE_IDNA_MAPPED, 2, 581}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2656}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3250}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1018}, - {LXB_UNICODE_IDNA_MAPPED, 2, 207}, - {LXB_UNICODE_IDNA_MAPPED, 1, 651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3057}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4559}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 73}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 836}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4030}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1674}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1686}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3502}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1336}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3595}, - {LXB_UNICODE_IDNA_MAPPED, 2, 983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 98}, - {LXB_UNICODE_IDNA_MAPPED, 1, 777}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4820}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2615}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 238}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4111}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2518}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3830}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5342}, - {LXB_UNICODE_IDNA_MAPPED, 2, 587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4462}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4507}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4854}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1640}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1569}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5229}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 55}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 139}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3286}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 478}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 828}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 914}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1391}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2089}, + {LXB_UNICODE_IDNA_MAPPED, 2, 615}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 353}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3033}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5210}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 176}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4150}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1769}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 448}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1934}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1772}, + {LXB_UNICODE_IDNA_MAPPED, 2, 566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3142}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2672}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4713}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5028}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2928}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3084}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2996}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4497}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 345}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 419}, {LXB_UNICODE_IDNA_MAPPED, 1, 5018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5141}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4621}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2353}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 832}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3574}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4598}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 868}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5327}, + {LXB_UNICODE_IDNA_MAPPED, 2, 593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1809}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4954}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3262}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2615}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5299}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1579}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4707}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3990}, + {LXB_UNICODE_IDNA_MAPPED, 1, 434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4550}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 235}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3161}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2000}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3580}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1517}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2950}, + {LXB_UNICODE_IDNA_MAPPED, 1, 853}, + {LXB_UNICODE_IDNA_MAPPED, 1, 94}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 458}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4882}, + {LXB_UNICODE_IDNA_MAPPED, 1, 888}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2987}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1943}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 166}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1774}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2682}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5398}, + {LXB_UNICODE_IDNA_MAPPED, 2, 583}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3369}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3003}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4627}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3423}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3338}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4546}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3478}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3911}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4640}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3610}, + {LXB_UNICODE_IDNA_MAPPED, 1, 732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4692}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2149}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3857}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3118}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4942}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5049}, {LXB_UNICODE_IDNA_MAPPED, 1, 5199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1618}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2995}, - {LXB_UNICODE_IDNA_MAPPED, 2, 188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1592}, - {LXB_UNICODE_IDNA_MAPPED, 1, 679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 97}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 434}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1606}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3065}, - {LXB_UNICODE_IDNA_MAPPED, 2, 613}, + {LXB_UNICODE_IDNA_MAPPED, 1, 53}, + {LXB_UNICODE_IDNA_MAPPED, 2, 578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 863}, + {LXB_UNICODE_IDNA_MAPPED, 1, 707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5335}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2066}, + {LXB_UNICODE_IDNA_MAPPED, 2, 275}, + {LXB_UNICODE_IDNA_MAPPED, 1, 662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5068}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1621}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2175}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2532}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3984}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 838}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2898}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5032}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2298}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3032}, + {LXB_UNICODE_IDNA_MAPPED, 1, 712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2943}, + {LXB_UNICODE_IDNA_MAPPED, 2, 552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 500}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 335}, {LXB_UNICODE_IDNA_MAPPED, 1, 4972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3227}, - {LXB_UNICODE_IDNA_MAPPED, 1, 813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 90}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4998}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3448}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1618}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3326}, + {LXB_UNICODE_IDNA_MAPPED, 1, 73}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3333}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4201}, + {LXB_UNICODE_IDNA_MAPPED, 3, 992}, + {LXB_UNICODE_IDNA_MAPPED, 1, 730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1816}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4604}, + {LXB_UNICODE_IDNA_MAPPED, 1, 856}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3847}, + {LXB_UNICODE_IDNA_MAPPED, 2, 29}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3095}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4687}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 655}, {LXB_UNICODE_IDNA_MAPPED, 1, 4460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3266}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 388}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2309}, {LXB_UNICODE_IDNA_MAPPED, 2, 2052}, - {LXB_UNICODE_IDNA_MAPPED, 1, 403}, - {LXB_UNICODE_IDNA_MAPPED, 1, 916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3418}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3527}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5272}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5225}, - {LXB_UNICODE_IDNA_MAPPED, 1, 456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1777}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 702}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3052}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4624}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3900}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4528}, - {LXB_UNICODE_IDNA_MAPPED, 1, 142}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3142}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 427}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5307}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5008}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3292}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2073}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1781}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5079}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1613}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2933}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3270}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3249}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3920}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2835}, - {LXB_UNICODE_IDNA_MAPPED, 1, 792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3531}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 141}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2417}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5318}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3517}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3081}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3724}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3146}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4951}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 326}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2654}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4911}, - {LXB_UNICODE_IDNA_MAPPED, 1, 795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3334}, - {LXB_UNICODE_IDNA_MAPPED, 1, 452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4558}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1884}, + {LXB_UNICODE_IDNA_MAPPED, 1, 334}, + {LXB_UNICODE_IDNA_MAPPED, 2, 560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1696}, {LXB_UNICODE_IDNA_MAPPED, 3, 2701}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3165}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4529}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3086}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5357}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2600}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 831}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4045}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3141}, - {LXB_UNICODE_IDNA_MAPPED, 2, 958}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 775}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3265}, - {LXB_UNICODE_IDNA_MAPPED, 1, 974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1734}, - {LXB_UNICODE_IDNA_MAPPED, 2, 552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3526}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1982}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2054}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 64}, - {LXB_UNICODE_IDNA_MAPPED, 1, 469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1620}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1543}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4746}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1042}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 328}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1445}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2245}, - {LXB_UNICODE_IDNA_MAPPED, 2, 978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1667}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1419}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4533}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2977}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 854}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5258}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3126}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 91}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5364}, + {LXB_UNICODE_IDNA_MAPPED, 2, 282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5077}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1562}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3021}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 395}, {LXB_UNICODE_IDNA_MAPPED, 1, 839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3208}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3293}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 230}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4894}, - {LXB_UNICODE_IDNA_MAPPED, 2, 932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5176}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1569}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1547}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2988}, - {LXB_UNICODE_IDNA_MAPPED, 1, 435}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 335}, - {LXB_UNICODE_IDNA_MAPPED, 1, 499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 870}, - {LXB_UNICODE_IDNA_MAPPED, 1, 688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2957}, - {LXB_UNICODE_IDNA_MAPPED, 1, 59}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4737}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 69}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4597}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5333}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4867}, - {LXB_UNICODE_IDNA_MAPPED, 1, 84}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 127}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2234}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3706}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1575}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4270}, + {LXB_UNICODE_IDNA_MAPPED, 1, 866}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5314}, {LXB_UNICODE_IDNA_MAPPED, 1, 5353}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 634}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3214}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4000}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1742}, {LXB_UNICODE_IDNA_MAPPED, 3, 2467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 889}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2974}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5358}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5325}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 664}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3539}, + {LXB_UNICODE_IDNA_MAPPED, 1, 393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 864}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5289}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1380}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4583}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3112}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4966}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4997}, + {LXB_UNICODE_IDNA_MAPPED, 2, 558}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4024}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1483}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3093}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2058}, {LXB_UNICODE_IDNA_MAPPED, 1, 1023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1444}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2935}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 536}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2862}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4944}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 126}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4054}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2796}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3908}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2040}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4440}, + {LXB_UNICODE_IDNA_MAPPED, 1, 320}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2060}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 93}, + {LXB_UNICODE_IDNA_MAPPED, 1, 437}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3935}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3304}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5285}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5160}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4512}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1463}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2619}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 363}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4767}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5278}, + {LXB_UNICODE_IDNA_MAPPED, 2, 263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4738}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5348}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2990}, + {LXB_UNICODE_IDNA_MAPPED, 1, 433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3497}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3713}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2074}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2953}, + {LXB_UNICODE_IDNA_MAPPED, 2, 966}, + {LXB_UNICODE_IDNA_MAPPED, 2, 528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 132}, + {LXB_UNICODE_IDNA_MAPPED, 2, 554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1599}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3068}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 254}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 347}, + {LXB_UNICODE_IDNA_MAPPED, 1, 887}, {LXB_UNICODE_IDNA_MAPPED, 1, 5283}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5063}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2021}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4574}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2776}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3571}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3093}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4620}, - {LXB_UNICODE_IDNA_MAPPED, 1, 900}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4799}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3834}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4463}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1538}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2514}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5125}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4963}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 876}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1185}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3281}, + {LXB_UNICODE_IDNA_MAPPED, 1, 179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 92}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1568}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 810}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4243}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3845}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2137}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2135}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2331}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1866}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1663}, + {LXB_UNICODE_IDNA_MAPPED, 2, 267}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4698}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3472}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1875}, + {LXB_UNICODE_IDNA_MAPPED, 1, 509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5332}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1415}, {LXB_UNICODE_IDNA_MAPPED, 1, 1453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4413}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 773}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5047}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5268}, - {LXB_UNICODE_IDNA_MAPPED, 2, 942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1905}, - {LXB_UNICODE_IDNA_MAPPED, 1, 628}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3319}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 331}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5257}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 674}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2006}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5140}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5013}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3037}, - {LXB_UNICODE_IDNA_MAPPED, 1, 487}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5343}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2955}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5076}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3154}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 86}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 211}, - {LXB_UNICODE_IDNA_MAPPED, 1, 242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 224}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 495}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4234}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4645}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3259}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 691}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5313}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1970}, - {LXB_UNICODE_IDNA_MAPPED, 1, 790}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1624}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3342}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4965}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4945}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 118}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5201}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4398}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3688}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4541}, - {LXB_UNICODE_IDNA_MAPPED, 1, 654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4575}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1621}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4933}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1410}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1890}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1525}, + {LXB_UNICODE_IDNA_MAPPED, 2, 960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5237}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1528}, + {LXB_UNICODE_IDNA_MAPPED, 2, 261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4719}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3165}, + {LXB_UNICODE_IDNA_MAPPED, 2, 536}, {LXB_UNICODE_IDNA_MAPPED, 3, 2856}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2938}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5010}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1388}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3571}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4873}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5340}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3243}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3956}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2859}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1647}, + {LXB_UNICODE_IDNA_MAPPED, 1, 845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2034}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4580}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1788}, {LXB_UNICODE_IDNA_MAPPED, 1, 3364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4953}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4646}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2635}, - {LXB_UNICODE_IDNA_MAPPED, 2, 540}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4692}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1342}, - {LXB_UNICODE_IDNA_MAPPED, 1, 444}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5389}, - {LXB_UNICODE_IDNA_MAPPED, 2, 119}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4793}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2584}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3022}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4596}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1406}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5022}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1902}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3036}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5308}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3372}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4022}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4544}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4562}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 511}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4471}, + {LXB_UNICODE_IDNA_MAPPED, 1, 789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1820}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 811}, + {LXB_UNICODE_IDNA_MAPPED, 3, 980}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3250}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4724}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2940}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 870}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5310}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2125}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1623}, {LXB_UNICODE_IDNA_MAPPED, 4, 2349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1765}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2762}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2141}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4917}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4114}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4219}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4845}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5228}, - {LXB_UNICODE_IDNA_MAPPED, 2, 593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3207}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4704}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2969}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 894}, - {LXB_UNICODE_IDNA_MAPPED, 1, 134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4663}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1481}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2945}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5377}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3183}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3113}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 209}, - {LXB_UNICODE_IDNA_MAPPED, 2, 976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1803}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 244}, - {LXB_UNICODE_IDNA_MAPPED, 1, 861}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5292}, - {LXB_UNICODE_IDNA_MAPPED, 1, 768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4691}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3225}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 476}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4401}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2794}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2353}, {LXB_UNICODE_IDNA_MAPPED, 1, 5177}, - {LXB_UNICODE_IDNA_MAPPED, 1, 92}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 905}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3832}, - {LXB_UNICODE_IDNA_MAPPED, 1, 878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1537}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5087}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2109}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3026}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1555}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 482}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 754}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3532}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2388}, - {LXB_UNICODE_IDNA_MAPPED, 2, 526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 670}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3301}, - {LXB_UNICODE_IDNA_MAPPED, 1, 279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4573}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2038}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 343}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4282}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2230}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 93}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 195}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 813}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3525}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4743}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2214}, + {LXB_UNICODE_IDNA_MAPPED, 1, 192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 465}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5027}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4918}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1690}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1728}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1594}, + {LXB_UNICODE_IDNA_MAPPED, 3, 44}, + {LXB_UNICODE_IDNA_MAPPED, 1, 874}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4568}, + {LXB_UNICODE_IDNA_MAPPED, 1, 708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3111}, {LXB_UNICODE_IDNA_MAPPED, 1, 1439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 210}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4517}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5354}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 109}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5327}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3405}, - {LXB_UNICODE_IDNA_MAPPED, 1, 764}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1405}, - {LXB_UNICODE_IDNA_MAPPED, 3, 995}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1182}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3918}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5227}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1584}, - {LXB_UNICODE_IDNA_MAPPED, 1, 278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 857}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4736}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4216}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1912}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1533}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4829}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1670}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1625}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4545}, - {LXB_UNICODE_IDNA_MAPPED, 1, 887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5160}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3006}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4929}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4741}, - {LXB_UNICODE_IDNA_MAPPED, 1, 914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3337}, + {LXB_UNICODE_IDNA_MAPPED, 1, 435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5012}, {LXB_UNICODE_IDNA_MAPPED, 1, 1497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 407}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4975}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5068}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3668}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4048}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2919}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3506}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4508}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4644}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3870}, - {LXB_UNICODE_IDNA_MAPPED, 2, 989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1764}, - {LXB_UNICODE_IDNA_MAPPED, 2, 259}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4893}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1648}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 622}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3137}, + {LXB_UNICODE_IDNA_MAPPED, 1, 116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4929}, + {LXB_UNICODE_IDNA_MAPPED, 1, 199}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3358}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4774}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3086}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3195}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2470}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2563}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2003}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2997}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2986}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3440}, + {LXB_UNICODE_IDNA_MAPPED, 2, 585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3143}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5305}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4647}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5226}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3381}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3320}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2961}, {LXB_UNICODE_IDNA_MAPPED, 1, 1697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5004}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1872}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3437}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1789}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3057}, + {LXB_UNICODE_IDNA_MAPPED, 1, 200}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4397}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1601}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 112}, + {LXB_UNICODE_IDNA_MAPPED, 1, 857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 65}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2088}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4449}, {LXB_UNICODE_IDNA_MAPPED, 1, 3034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 696}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4882}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2970}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 721}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4484}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4337}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3179}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 734}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 235}, - {LXB_UNICODE_IDNA_MAPPED, 2, 556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4966}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4509}, - {LXB_UNICODE_IDNA_MAPPED, 2, 583}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2368}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5312}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3898}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4897}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 822}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4324}, + {LXB_UNICODE_IDNA_MAPPED, 2, 609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5246}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 78}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5356}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 671}, + {LXB_UNICODE_IDNA_MAPPED, 1, 766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3565}, + {LXB_UNICODE_IDNA_MAPPED, 1, 329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4996}, + {LXB_UNICODE_IDNA_MAPPED, 1, 210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3274}, + {LXB_UNICODE_IDNA_MAPPED, 1, 222}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4204}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3271}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5025}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3043}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3285}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4964}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1572}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3302}, {LXB_UNICODE_IDNA_MAPPED, 1, 1551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2992}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2030}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3059}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 57}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1857}, - {LXB_UNICODE_IDNA_MAPPED, 6, 2303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1600}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 61}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 87}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3423}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5215}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4557}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5035}, - {LXB_UNICODE_IDNA_MAPPED, 1, 814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4386}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 794}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2296}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3315}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3594}, + {LXB_UNICODE_IDNA_MAPPED, 1, 245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1671}, + {LXB_UNICODE_IDNA_MAPPED, 6, 2744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4989}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2067}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3106}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2173}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4376}, + {LXB_UNICODE_IDNA_MAPPED, 1, 855}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4877}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4504}, {LXB_UNICODE_IDNA_MAPPED, 1, 4485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3335}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4586}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 227}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2433}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4782}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5319}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2086}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5057}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2969}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4060}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5043}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3352}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 130}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3259}, + {LXB_UNICODE_IDNA_MAPPED, 1, 76}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1442}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1176}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4264}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5197}, {LXB_UNICODE_IDNA_MAPPED, 1, 840}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1393}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1045}, - {LXB_UNICODE_IDNA_MAPPED, 3, 992}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5266}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2832}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 88}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 872}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5386}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5070}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2828}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1761}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 625}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5124}, + {LXB_UNICODE_IDNA_MAPPED, 1, 865}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4987}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5406}, + {LXB_UNICODE_IDNA_MAPPED, 2, 976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 743}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5045}, {LXB_UNICODE_IDNA_MAPPED, 1, 656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1586}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4564}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1008}, - {LXB_UNICODE_IDNA_MAPPED, 2, 617}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4820}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4437}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1014}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2414}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3395}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3026}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1031}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4927}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1937}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4873}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1773}, + {LXB_UNICODE_IDNA_MAPPED, 1, 122}, + {LXB_UNICODE_IDNA_MAPPED, 1, 146}, + {LXB_UNICODE_IDNA_MAPPED, 1, 220}, {LXB_UNICODE_IDNA_MAPPED, 1, 2093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2085}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4532}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3157}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5301}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 71}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1575}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3289}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4599}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4521}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4472}, {LXB_UNICODE_IDNA_MAPPED, 2, 2617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4935}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1517}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1571}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5391}, {LXB_UNICODE_IDNA_MAPPED, 1, 404}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5027}, - {LXB_UNICODE_IDNA_MAPPED, 1, 632}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5275}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 850}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3894}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4600}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1585}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5373}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2436}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 890}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 636}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1783}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2939}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5118}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3272}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3159}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2688}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2830}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3567}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 212}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4861}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 776}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5143}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2256}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 59}, + {LXB_UNICODE_IDNA_MAPPED, 1, 463}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4237}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3363}, + {LXB_UNICODE_IDNA_MAPPED, 2, 970}, + {LXB_UNICODE_IDNA_MAPPED, 2, 532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1655}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3380}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4718}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 885}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4825}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5109}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1685}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4891}, + {LXB_UNICODE_IDNA_MAPPED, 1, 778}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2104}, {LXB_UNICODE_IDNA_MAPPED, 3, 1107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4490}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4063}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1583}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3512}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5155}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3620}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 844}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4081}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2956}, + {LXB_UNICODE_IDNA_MAPPED, 1, 137}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2605}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2816}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4594}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4706}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5129}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4508}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4576}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3069}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1100}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2396}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2994}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3761}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2922}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2226}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4897}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1548}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4390}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 695}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1545}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5037}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1922}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 872}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2080}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4984}, + {LXB_UNICODE_IDNA_MAPPED, 1, 466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3268}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4766}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1467}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 513}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3568}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 812}, + {LXB_UNICODE_IDNA_MAPPED, 1, 136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2965}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3467}, + {LXB_UNICODE_IDNA_MAPPED, 1, 273}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5003}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 974}, {LXB_UNICODE_IDNA_MAPPED, 1, 4992}, - {LXB_UNICODE_IDNA_MAPPED, 2, 38}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4789}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4552}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3623}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2036}, - {LXB_UNICODE_IDNA_MAPPED, 2, 578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5097}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5038}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1235}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2792}, + {LXB_UNICODE_IDNA_MAPPED, 1, 630}, + {LXB_UNICODE_IDNA_MAPPED, 2, 119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 242}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5101}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2941}, + {LXB_UNICODE_IDNA_MAPPED, 1, 182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3030}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5041}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 244}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2690}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2121}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3604}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5067}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 685}, + {LXB_UNICODE_IDNA_MAPPED, 1, 803}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1899}, + {LXB_UNICODE_IDNA_MAPPED, 2, 936}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3541}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1536}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5172}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4189}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3185}, + {LXB_UNICODE_IDNA_MAPPED, 1, 801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5011}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5208}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1084}, + {LXB_UNICODE_IDNA_MAPPED, 1, 902}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5167}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2356}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1592}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5234}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2021}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 738}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4543}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 234}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4695}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4631}, + {LXB_UNICODE_IDNA_MAPPED, 2, 983}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5174}, + {LXB_UNICODE_IDNA_MAPPED, 2, 540}, + {LXB_UNICODE_IDNA_MAPPED, 1, 787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4483}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4685}, + {LXB_UNICODE_IDNA_MAPPED, 1, 143}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4922}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3411}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4911}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3149}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1708}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2862}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4575}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5088}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3992}, + {LXB_UNICODE_IDNA_MAPPED, 1, 497}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5326}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5275}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4816}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5298}, {LXB_UNICODE_IDNA_MAPPED, 1, 5288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5057}, - {LXB_UNICODE_IDNA_MAPPED, 1, 426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3310}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4246}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2139}, + {LXB_UNICODE_IDNA_MAPPED, 1, 876}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5107}, + {LXB_UNICODE_IDNA_MAPPED, 1, 349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 70}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3189}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5339}, {LXB_UNICODE_IDNA_MAPPED, 1, 1619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4539}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2772}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 796}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2298}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4849}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4537}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3101}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4863}, - {LXB_UNICODE_IDNA_MAPPED, 2, 544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5119}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1567}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1549}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3114}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1413}, - {LXB_UNICODE_IDNA_MAPPED, 3, 41}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5041}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1698}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1875}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2283}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4903}, - {LXB_UNICODE_IDNA_MAPPED, 1, 60}, - {LXB_UNICODE_IDNA_MAPPED, 1, 748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5276}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1160}, - {LXB_UNICODE_IDNA_MAPPED, 1, 468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5264}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3256}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3215}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 677}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5352}, + {LXB_UNICODE_IDNA_MAPPED, 1, 896}, + {LXB_UNICODE_IDNA_MAPPED, 1, 504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2934}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3303}, + {LXB_UNICODE_IDNA_MAPPED, 3, 599}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 724}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 81}, {LXB_UNICODE_IDNA_MAPPED, 1, 3322}, - {LXB_UNICODE_IDNA_MAPPED, 1, 649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2982}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 250}, - {LXB_UNICODE_IDNA_MAPPED, 1, 164}, - {LXB_UNICODE_IDNA_MAPPED, 18, 4340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 68}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 102}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2768}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4461}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 741}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3452}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1449}, + {LXB_UNICODE_IDNA_MAPPED, 1, 891}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5141}, + {LXB_UNICODE_IDNA_MAPPED, 1, 882}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2944}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3929}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4468}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1425}, {LXB_UNICODE_IDNA_MAPPED, 1, 5005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4535}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 421}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1790}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 838}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2569}, - {LXB_UNICODE_IDNA_MAPPED, 1, 705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3299}, - {LXB_UNICODE_IDNA_MAPPED, 1, 708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2927}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4435}, - {LXB_UNICODE_IDNA_MAPPED, 1, 417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4984}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4954}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1210}, - {LXB_UNICODE_IDNA_MAPPED, 2, 564}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3043}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2947}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2518}, {LXB_UNICODE_IDNA_MAPPED, 1, 1626}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4885}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3334}, + {LXB_UNICODE_IDNA_MAPPED, 1, 407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3337}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1677}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4536}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2061}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2334}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5104}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4851}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1863}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 141}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 480}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1716}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 701}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2143}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1564}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5093}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1396}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5320}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3475}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1217}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2973}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3233}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5374}, + {LXB_UNICODE_IDNA_MAPPED, 1, 847}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5007}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3226}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5369}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4742}, + {LXB_UNICODE_IDNA_MAPPED, 1, 95}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3496}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2076}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5270}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3526}, + {LXB_UNICODE_IDNA_MAPPED, 2, 544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 467}, + {LXB_UNICODE_IDNA_MAPPED, 1, 142}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2854}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4102}, + {LXB_UNICODE_IDNA_MAPPED, 1, 321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3332}, + {LXB_UNICODE_IDNA_MAPPED, 2, 989}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2848}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2907}, + {LXB_UNICODE_IDNA_MAPPED, 1, 389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4838}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1881}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 134}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3176}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 241}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4441}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2056}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3943}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4458}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5220}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2525}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3375}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3124}, + {LXB_UNICODE_IDNA_MAPPED, 1, 643}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 770}, + {LXB_UNICODE_IDNA_MAPPED, 1, 183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 63}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1598}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5084}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2083}, + {LXB_UNICODE_IDNA_MAPPED, 1, 111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3237}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3308}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2086}, + {LXB_UNICODE_IDNA_MAPPED, 2, 570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 502}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5395}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1408}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3598}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4828}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1878}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5189}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 699}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3835}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3017}, + {LXB_UNICODE_IDNA_MAPPED, 2, 104}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5056}, + {LXB_UNICODE_IDNA_MAPPED, 1, 916}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 72}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1620}, + {LXB_UNICODE_IDNA_MAPPED, 2, 617}, + {LXB_UNICODE_IDNA_MAPPED, 1, 771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 580}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2027}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4974}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3277}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4620}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4573}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1493}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3244}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4565}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1792}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3425}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5408}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 773}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 226}, + {LXB_UNICODE_IDNA_MAPPED, 1, 637}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 472}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5393}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1940}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 247}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4924}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5202}, {LXB_UNICODE_IDNA_MAPPED, 1, 3340}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 58}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1807}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1512} + {LXB_UNICODE_IDNA_MAPPED, 1, 2937}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3883}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2868}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3180}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4904} }; static const lxb_unicode_composition_entry_t lxb_unicode_composition_entries[458] = diff --git a/ext/lexbor/lexbor/unicode/unicode.c b/ext/lexbor/lexbor/unicode/unicode.c index 991fc0a38823..ced80b430a7c 100644 --- a/ext/lexbor/lexbor/unicode/unicode.c +++ b/ext/lexbor/lexbor/unicode/unicode.c @@ -451,7 +451,7 @@ lxb_unicode_normalize_body(lxb_unicode_normalizer_t *uc, const void *data, uc->starter = p; uc->ican = p; - if (p - buf >= uc->flush_cp) { + if (lxb_size(p - buf) >= uc->flush_cp) { if (!is_cp) { status = lxb_unicode_flush(uc, cb->cb, ctx); } @@ -887,7 +887,7 @@ lxb_unicode_entry(lxb_codepoint_t cp) return &lxb_unicode_entries[0]; } - if (cp < 205744) { + if (cp < 210042) { if (cp < 83527) { if (cp < 57345) { return &lxb_unicode_entries[lxb_unicode_table_map_0_57345[cp - 0]]; @@ -897,11 +897,11 @@ lxb_unicode_entry(lxb_codepoint_t cp) } } else if (cp >= 90368) { - if (cp < 101641) { - return &lxb_unicode_entries[lxb_unicode_table_map_90368_101641[cp - 90368]]; + if (cp < 101875) { + return &lxb_unicode_entries[lxb_unicode_table_map_90368_101875[cp - 90368]]; } else if (cp >= 110576) { - return &lxb_unicode_entries[lxb_unicode_table_map_110576_205744[cp - 110576]]; + return &lxb_unicode_entries[lxb_unicode_table_map_110576_210042[cp - 110576]]; } } } diff --git a/ext/lexbor/lexbor/url/base.h b/ext/lexbor/lexbor/url/base.h index c95377ab89e1..94d0e2a1901c 100644 --- a/ext/lexbor/lexbor/url/base.h +++ b/ext/lexbor/lexbor/url/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Alexander Borisov + * Copyright (C) 2023-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -17,7 +17,7 @@ extern "C" { #define LXB_URL_VERSION_MAJOR 0 -#define LXB_URL_VERSION_MINOR 3 +#define LXB_URL_VERSION_MINOR 4 #define LXB_URL_VERSION_PATCH 0 #define LXB_URL_VERSION_STRING LEXBOR_STRINGIZE(LXB_URL_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/url/url.c b/ext/lexbor/lexbor/url/url.c index 0eef7a6deba4..8099c12089bb 100644 --- a/ext/lexbor/lexbor/url/url.c +++ b/ext/lexbor/lexbor/url/url.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2025 Alexander Borisov + * Copyright (C) 2023-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,14 +14,14 @@ #include "lexbor/core/swar.h" #include "lexbor/unicode/idna.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const size_t lexbor_str_res_alphanumeric_character[256]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value[257]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #define LXB_URL_BUFFER_SIZE 4096 #define LXB_URL_BUFFER_NUM_SIZE 128 @@ -159,7 +159,7 @@ static const uint8_t lxb_url_map[256] = LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5b ([) */ LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5c (\) */ LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5d (]) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ LXB_URL_MAP_UNDEF, /* 0x5f (_) */ LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x60 (`) */ LXB_URL_MAP_UNDEF, /* 0x61 (a) */ @@ -499,6 +499,7 @@ lxb_url_scheme_length = sizeof(lxb_url_scheme_res) / sizeof(lxb_url_scheme_data_ if (tmp == NULL) { \ return NULL; \ } \ + memcpy(tmp, (sbuf_begin), offset); \ } \ else { \ tmp = lexbor_realloc((sbuf_begin), new_len); \ @@ -509,7 +510,7 @@ lxb_url_scheme_length = sizeof(lxb_url_scheme_res) / sizeof(lxb_url_scheme_data_ } \ \ (sbuf) = tmp + offset; \ - (last) = sbuf + lst; \ + (last) = tmp + lst; \ (sbuf_begin) = tmp; \ (sbuf_end) = tmp + new_len; \ } \ @@ -860,7 +861,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; } -lxb_inline bool +bool lxb_url_is_special(const lxb_url_t *url) { return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; @@ -1115,11 +1116,13 @@ lxb_url_host_copy(const lxb_url_host_t *src, lxb_url_host_t *dst, dst->type = src->type; - if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { - if (src->type == LXB_URL_HOST_TYPE__UNDEF) { - return LXB_STATUS_OK; - } + if (src->type == LXB_URL_HOST_TYPE__UNDEF + || src->type == LXB_URL_HOST_TYPE_EMPTY) + { + return LXB_STATUS_OK; + } + if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { return lxb_url_str_copy(&src->u.domain, &dst->u.domain, dst_mraw); } @@ -1152,6 +1155,24 @@ lxb_url_host_set_empty(lxb_url_host_t *host, lexbor_mraw_t *mraw) host->type = LXB_URL_HOST_TYPE_EMPTY; } +lxb_inline bool +lxb_url_host_is_empty(const lxb_url_host_t *host) +{ + if (host->type == LXB_URL_HOST_TYPE_EMPTY) { + return true; + } + + if (host->type == LXB_URL_HOST_TYPE_DOMAIN) { + return host->u.domain.length == 0; + } + + if (host->type == LXB_URL_HOST_TYPE_OPAQUE) { + return host->u.opaque.length == 0; + } + + return false; +} + static bool lxb_url_host_eq(lxb_url_host_t *host, const lxb_char_t *data, size_t length) { @@ -1251,7 +1272,7 @@ lxb_url_normalized_windows_drive_letter(const lxb_char_t *data, static bool lxb_url_cannot_have_user_pass_port(lxb_url_t *url) { - return url->host.type == LXB_URL_HOST_TYPE_EMPTY + return lxb_url_host_is_empty(&url->host) || url->host.type == LXB_URL_HOST_TYPE__UNDEF || url->scheme.type == LXB_URL_SCHEMEL_TYPE_FILE; } @@ -1793,7 +1814,7 @@ lxb_url_parse_basic_h(lxb_url_parser_t *parser, lxb_url_t *url, if (at_sign) { if (begin == p || begin == p - 1) { status = lxb_url_log_append(parser, p, - LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS); + LXB_URL_ERROR_TYPE_HOST_MISSING); if (status != LXB_STATUS_OK) { lxb_url_parse_return(orig_data, buf, status); } @@ -3978,6 +3999,11 @@ lxb_url_opaque_host_parse(lxb_url_parser_t *parser, const lxb_char_t *data, lxb_status_t status; const lxb_char_t *p; + if (data == end) { + lxb_url_host_set_empty(host, mraw); + return LXB_STATUS_OK; + } + p = data; while (p < end) { diff --git a/ext/lexbor/lexbor/url/url.h b/ext/lexbor/lexbor/url/url.h index 4ed3f32aa646..6cc6f1081c8a 100644 --- a/ext/lexbor/lexbor/url/url.h +++ b/ext/lexbor/lexbor/url/url.h @@ -763,6 +763,15 @@ LXB_API lxb_status_t lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, lexbor_callback_f cb, void *ctx); +/** + * Returns whether the URL is special. + * + * @param[in] lxb_url_t *. Cannot be NULL. + * @return true if URL is special, false otherwise. + */ +LXB_API bool +lxb_url_is_special(const lxb_url_t *url); + /* * Inline functions. */ diff --git a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch index 0da274053ec2..f23ec0f5034d 100644 --- a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch +++ b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch @@ -1,7 +1,7 @@ -From 4c133fe5adfe4b8ccdd8b014d884b685143b9e66 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:08:59 +0200 -Subject: [PATCH 1/6] Expose line and column information for use in PHP +Subject: [PATCH 01/11] Expose line and column information for use in PHP --- source/lexbor/dom/interfaces/node.h | 2 ++ @@ -15,10 +15,10 @@ Subject: [PATCH 1/6] Expose line and column information for use in PHP 8 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source/lexbor/dom/interfaces/node.h b/source/lexbor/dom/interfaces/node.h -index b052cf5..b5d2c50 100644 +index 6c74ac5..b95373c 100644 --- a/source/lexbor/dom/interfaces/node.h +++ b/source/lexbor/dom/interfaces/node.h -@@ -83,6 +83,8 @@ struct lxb_dom_node { +@@ -86,6 +86,8 @@ struct lxb_dom_node { lxb_dom_node_type_t type; @@ -41,10 +41,10 @@ index 79accd0..0b7f4fd 100644 const lxb_char_t *text_start; const lxb_char_t *text_end; diff --git a/source/lexbor/html/tokenizer.c b/source/lexbor/html/tokenizer.c -index 741bced..0bd9aec 100644 +index 22b88ed..1d9f378 100644 --- a/source/lexbor/html/tokenizer.c +++ b/source/lexbor/html/tokenizer.c -@@ -91,6 +91,7 @@ lxb_html_tokenizer_init(lxb_html_tokenizer_t *tkz) +@@ -92,6 +92,7 @@ lxb_html_tokenizer_init(lxb_html_tokenizer_t *tkz) tkz->pos = tkz->start; tkz->end = tkz->start + LXB_HTML_TKZ_TEMP_SIZE; @@ -52,7 +52,7 @@ index 741bced..0bd9aec 100644 tkz->tree = NULL; tkz->tags = NULL; -@@ -152,6 +153,8 @@ lxb_html_tokenizer_inherit(lxb_html_tokenizer_t *tkz_to, +@@ -153,6 +154,8 @@ lxb_html_tokenizer_inherit(lxb_html_tokenizer_t *tkz_to, tkz_to->start = tkz_from->start; tkz_to->end = tkz_from->end; tkz_to->pos = tkz_to->start; @@ -61,7 +61,7 @@ index 741bced..0bd9aec 100644 return LXB_STATUS_OK; } -@@ -312,7 +315,26 @@ lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, +@@ -571,7 +574,26 @@ lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, tkz->last = end; while (data < end) { @@ -90,10 +90,10 @@ index 741bced..0bd9aec 100644 return tkz->status; diff --git a/source/lexbor/html/tokenizer.h b/source/lexbor/html/tokenizer.h -index ba9602f..74bb55e 100644 +index 12b7c81..aa1ac37 100644 --- a/source/lexbor/html/tokenizer.h +++ b/source/lexbor/html/tokenizer.h -@@ -73,6 +73,8 @@ struct lxb_html_tokenizer { +@@ -79,6 +79,8 @@ struct lxb_html_tokenizer { const lxb_char_t *end; const lxb_char_t *begin; const lxb_char_t *last; @@ -103,7 +103,7 @@ index ba9602f..74bb55e 100644 /* Entities */ const lexbor_sbst_entry_static_t *entity; diff --git a/source/lexbor/html/tokenizer/state.h b/source/lexbor/html/tokenizer/state.h -index 17939b9..5b095b4 100644 +index 5e91444..52eaa9a 100644 --- a/source/lexbor/html/tokenizer/state.h +++ b/source/lexbor/html/tokenizer/state.h @@ -90,6 +90,8 @@ extern "C" { @@ -116,10 +116,10 @@ index 17939b9..5b095b4 100644 while (0) diff --git a/source/lexbor/html/tree.c b/source/lexbor/html/tree.c -index ece26e9..91bfd17 100644 +index 062ea56..3f4c18d 100644 --- a/source/lexbor/html/tree.c +++ b/source/lexbor/html/tree.c -@@ -427,6 +427,9 @@ lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, +@@ -431,6 +431,9 @@ lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, return NULL; } @@ -129,7 +129,7 @@ index ece26e9..91bfd17 100644 lxb_status_t status; lxb_dom_element_t *element = lxb_dom_interface_element(node); -@@ -763,6 +766,11 @@ lxb_html_tree_insert_character_for_data(lxb_html_tree_t *tree, +@@ -767,6 +770,11 @@ lxb_html_tree_insert_character_for_data(lxb_html_tree_t *tree, lxb_dom_interface_text(text)->char_data.data = *str; @@ -141,7 +141,7 @@ index ece26e9..91bfd17 100644 if (ret_node != NULL) { *ret_node = text; } -@@ -802,6 +810,9 @@ lxb_html_tree_insert_comment(lxb_html_tree_t *tree, +@@ -806,6 +814,9 @@ lxb_html_tree_insert_comment(lxb_html_tree_t *tree, return NULL; } @@ -152,10 +152,10 @@ index ece26e9..91bfd17 100644 tree->document->dom_document.text); if (tree->status != LXB_STATUS_OK) { diff --git a/source/lexbor/html/tree/error.c b/source/lexbor/html/tree/error.c -index e6e43f4..88ad8c4 100644 +index ffdc55c..ef36eab 100644 --- a/source/lexbor/html/tree/error.c +++ b/source/lexbor/html/tree/error.c -@@ -21,8 +21,9 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, +@@ -22,8 +22,9 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, } entry->id = id; @@ -168,10 +168,10 @@ index e6e43f4..88ad8c4 100644 return entry; } diff --git a/source/lexbor/html/tree/error.h b/source/lexbor/html/tree/error.h -index 2fd06cb..ed1859f 100644 +index 7a212af..b186772 100644 --- a/source/lexbor/html/tree/error.h +++ b/source/lexbor/html/tree/error.h -@@ -97,8 +97,9 @@ lxb_html_tree_error_id_t; +@@ -109,8 +109,9 @@ lxb_html_tree_error_id_t; typedef struct { lxb_html_tree_error_id_t id; @@ -183,6 +183,3 @@ index 2fd06cb..ed1859f 100644 } lxb_html_tree_error_t; --- -2.49.0 - diff --git a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch index a2df20e3bae4..8758c09a2e8f 100644 --- a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch +++ b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch @@ -1,7 +1,7 @@ -From eb5e3769950cd9c0bc59066d94d6da9291f43af8 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:18:51 +0200 -Subject: [PATCH 2/6] Track implied added nodes for options use in PHP +Subject: [PATCH 02/11] Track implied added nodes for options use in PHP --- source/lexbor/html/tree.h | 3 +++ @@ -11,7 +11,7 @@ Subject: [PATCH 2/6] Track implied added nodes for options use in PHP 4 files changed, 8 insertions(+) diff --git a/source/lexbor/html/tree.h b/source/lexbor/html/tree.h -index 9564608..8ad32a4 100644 +index 4912efb..7b2c620 100644 --- a/source/lexbor/html/tree.h +++ b/source/lexbor/html/tree.h @@ -55,6 +55,9 @@ struct lxb_html_tree { @@ -62,6 +62,3 @@ index 05fe738..1e09cda 100644 tree->mode = lxb_html_tree_insertion_mode_before_head; break; --- -2.49.0 - diff --git a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch index 4c3cdc67a65d..56458a49deea 100644 --- a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch +++ b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch @@ -1,17 +1,17 @@ -From de74c24d95342280266ebdac6f8dabc70ccfacab Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:57:48 +0200 -Subject: [PATCH 3/6] Patch utilities and data structure to be able to generate - smaller lookup tables +Subject: [PATCH 03/11] Patch utilities and data structure to be able to + generate smaller lookup tables Changed the generation script to check if everything fits in 32-bits. And change the actual field types to 32-bits. This decreases the hash tables in size. --- - source/lexbor/core/shs.h | 4 +- - utils/lexbor/encoding/single-byte.py | 2 +- - utils/lexbor/lexbor/LXB.py | 12 +- - 3 files changed, 12 insertions(+), 6 deletions(-) + source/lexbor/core/shs.h | 4 ++-- + utils/lexbor/encoding/single-byte.py | 4 ++-- + utils/lexbor/lexbor/LXB.py | 12 +++++++++--- + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/source/lexbor/core/shs.h b/source/lexbor/core/shs.h index 7a63a07..c84dfaa 100644 @@ -30,7 +30,7 @@ index 7a63a07..c84dfaa 100644 lexbor_shs_hash_t; diff --git a/utils/lexbor/encoding/single-byte.py b/utils/lexbor/encoding/single-byte.py -index 9a85d54..ec2023c 100755 +index d7d1bb2..5420c16 100755 --- a/utils/lexbor/encoding/single-byte.py +++ b/utils/lexbor/encoding/single-byte.py @@ -128,7 +128,7 @@ class SingleByte: @@ -42,6 +42,15 @@ index 9a85d54..ec2023c 100755 return hash_key.create(rate = 1) +@@ -161,7 +161,7 @@ def toHex(s): + lst = [] + + for ch in bytes(s, 'utf-8'): +- hv = hex(ch).replace('0x', '\\\\x') ++ hv = hex(ch).replace('0x', '\\x') + lst.append("'{}'".format(hv)) + + return ', '.join(lst) diff --git a/utils/lexbor/lexbor/LXB.py b/utils/lexbor/lexbor/LXB.py index 3e75812..2370c66 100755 --- a/utils/lexbor/lexbor/LXB.py @@ -83,6 +92,3 @@ index 3e75812..2370c66 100755 result.append("};") --- -2.49.0 - diff --git a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch index c678146f2ada..f4fe2050998d 100644 --- a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch +++ b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch @@ -1,7 +1,7 @@ -From 1837e6a296a2bac71e37e566435542f208b4fa23 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:26:47 +0100 -Subject: [PATCH 4/6] Remove unused upper case tag static data +Subject: [PATCH 04/11] Remove unused upper case tag static data --- source/lexbor/tag/res.h | 2 ++ @@ -9,10 +9,10 @@ Subject: [PATCH 4/6] Remove unused upper case tag static data 2 files changed, 4 insertions(+) diff --git a/source/lexbor/tag/res.h b/source/lexbor/tag/res.h -index c7190c5..4ad1f37 100644 +index 604757f..5672d4a 100644 --- a/source/lexbor/tag/res.h +++ b/source/lexbor/tag/res.h -@@ -224,6 +224,7 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = +@@ -226,6 +226,7 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = {{.u.short_str = "xmp", .length = 3, .next = NULL}, LXB_TAG_XMP, 1, true} }; @@ -20,13 +20,13 @@ index c7190c5..4ad1f37 100644 static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] = { {{.u.short_str = "#UNDEF", .length = 6, .next = NULL}, LXB_TAG__UNDEF, 1, true}, -@@ -423,6 +424,7 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] +@@ -427,6 +428,7 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] {{.u.short_str = "WBR", .length = 3, .next = NULL}, LXB_TAG_WBR, 1, true}, {{.u.short_str = "XMP", .length = 3, .next = NULL}, LXB_TAG_XMP, 1, true} }; +#endif - static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = + static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[263] = { diff --git a/source/lexbor/tag/tag.c b/source/lexbor/tag/tag.c index 780bc47..be5bb30 100644 @@ -48,6 +48,3 @@ index 780bc47..be5bb30 100644 /* * No inline functions for ABI. --- -2.49.0 - diff --git a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch index bf2acce1a848..f36a2d758181 100644 --- a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch +++ b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch @@ -1,16 +1,15 @@ -From 065923a993a004b8891ad3992c99e7e63e77bad3 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:29:31 +0100 -Subject: [PATCH 5/6] Shrink size of static binary search tree +Subject: [PATCH 05/11] Shrink size of static binary search tree This also makes it more efficient on the data cache. --- source/lexbor/core/sbst.h | 19 ++++++++++++++----- source/lexbor/html/tokenizer/state.c | 2 +- - utils/lexbor/html/tmp/tokenizer_res.h | 2 +- - utils/lexbor/html/tokenizer_entities_bst.py | 10 +++++----- + utils/lexbor/html/tokenizer_entities_bst.py | 8 ++++---- utils/lexbor/lexbor/LXB.py | 2 +- - 5 files changed, 21 insertions(+), 12 deletions(-) + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/lexbor/core/sbst.h b/source/lexbor/core/sbst.h index b0fbc54..15a1d40 100644 @@ -48,10 +47,10 @@ index b0fbc54..15a1d40 100644 lexbor_sbst_entry_static_t; diff --git a/source/lexbor/html/tokenizer/state.c b/source/lexbor/html/tokenizer/state.c -index 158aade..207b909 100644 +index db362c6..6c3cbeb 100644 --- a/source/lexbor/html/tokenizer/state.c +++ b/source/lexbor/html/tokenizer/state.c -@@ -1820,7 +1820,7 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, +@@ -1825,7 +1825,7 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, goto done; } @@ -60,21 +59,8 @@ index 158aade..207b909 100644 tkz->entity_end = (tkz->pos + (data - begin)) - tkz->start; tkz->entity_match = entry; } -diff --git a/utils/lexbor/html/tmp/tokenizer_res.h b/utils/lexbor/html/tmp/tokenizer_res.h -index b3701d5..73ab66e 100644 ---- a/utils/lexbor/html/tmp/tokenizer_res.h -+++ b/utils/lexbor/html/tmp/tokenizer_res.h -@@ -6,7 +6,7 @@ - - /* - * Caution!!! Important!!! -- * This file generated by the script -+ * This file is generated by the script - * "utils/lexbor/html/tokenizer_entities_bst.py"! - * Do not change this file! - */ diff --git a/utils/lexbor/html/tokenizer_entities_bst.py b/utils/lexbor/html/tokenizer_entities_bst.py -index 4fa0999..8bd83b2 100755 +index b34bca1..2bfea81 100755 --- a/utils/lexbor/html/tokenizer_entities_bst.py +++ b/utils/lexbor/html/tokenizer_entities_bst.py @@ -1,6 +1,6 @@ @@ -112,15 +98,8 @@ index 4fa0999..8bd83b2 100755 lst.append(hv) return ''.join(lst) -@@ -210,5 +210,5 @@ def entities_bst_print(bst): - - if __name__ == "__main__": - entities_bst("tmp/tokenizer_res.h", -- "../../../source/lexbor/html/tokenizer_res.h", -+ "../../../source/lexbor/html/tokenizer/res.h", - "data/entities.json"); diff --git a/utils/lexbor/lexbor/LXB.py b/utils/lexbor/lexbor/LXB.py -index 3e75812..b068ea3 100755 +index 2370c66..c41e645 100755 --- a/utils/lexbor/lexbor/LXB.py +++ b/utils/lexbor/lexbor/LXB.py @@ -27,7 +27,7 @@ class Temp: @@ -132,6 +111,3 @@ index 3e75812..b068ea3 100755 self.buffer.append(line) fh.close() --- -2.49.0 - diff --git a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch index aa64d88ceb18..7c6e1beebf46 100644 --- a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch +++ b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch @@ -1,19 +1,17 @@ -From fbb1e8945c4b12d43e7fddc3c34670b5792e2dca Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:59:28 +0100 -Subject: [PATCH 6/6] Patch out unused CSS style code +Subject: [PATCH 06/11] Patch out unused CSS style code --- - source/lexbor/css/rule.h | 2 ++ - source/lexbor/style/dom/interfaces/document.c | 12 ++++++++---- - source/lexbor/style/html/interfaces/document.h | 2 ++ - 3 files changed, 12 insertions(+), 4 deletions(-) + source/lexbor/css/rule.h | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/source/lexbor/css/rule.h b/source/lexbor/css/rule.h -index 7cc4f0b..bd191f9 100644 +index 308dced..d192a01 100644 --- a/source/lexbor/css/rule.h +++ b/source/lexbor/css/rule.h -@@ -339,6 +339,7 @@ lxb_css_rule_ref_dec(lxb_css_rule_t *rule) +@@ -361,6 +361,7 @@ lxb_css_rule_ref_dec(lxb_css_rule_t *rule) lxb_inline void lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) { @@ -21,7 +19,7 @@ index 7cc4f0b..bd191f9 100644 if (rule->ref_count > 0) { rule->ref_count--; } -@@ -346,6 +347,7 @@ lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) +@@ -368,6 +369,7 @@ lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) if (rule->ref_count == 0) { (void) lxb_css_rule_destroy(rule, true); } @@ -29,96 +27,3 @@ index 7cc4f0b..bd191f9 100644 } lxb_inline void -diff --git a/source/lexbor/style/dom/interfaces/document.c b/source/lexbor/style/dom/interfaces/document.c -index 8a63e8e..f885dc3 100644 ---- a/source/lexbor/style/dom/interfaces/document.c -+++ b/source/lexbor/style/dom/interfaces/document.c -@@ -280,6 +280,7 @@ lxb_status_t - lxb_dom_document_stylesheet_apply(lxb_dom_document_t *document, - lxb_css_stylesheet_t *sst) - { -+#if 0 - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; - lxb_css_rule_list_t *list; -@@ -310,7 +311,7 @@ lxb_dom_document_stylesheet_apply(lxb_dom_document_t *document, - - rule = rule->next; - } -- -+#endif - return LXB_STATUS_OK; - } - -@@ -329,6 +330,7 @@ lxb_status_t - lxb_dom_document_stylesheet_remove(lxb_dom_document_t *document, - lxb_css_stylesheet_t *sst) - { -+#if 0 - size_t i, length; - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; -@@ -372,13 +374,14 @@ lxb_dom_document_stylesheet_remove(lxb_dom_document_t *document, - length = lexbor_array_length(document->css->stylesheets); - } - } -- -+#endif - return LXB_STATUS_OK; - } - - lxb_status_t - lxb_dom_document_element_styles_attach(lxb_dom_element_t *element) - { -+#if 0 - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; - lexbor_array_t *ssts; -@@ -413,7 +416,7 @@ lxb_dom_document_element_styles_attach(lxb_dom_element_t *element) - rule = rule->next; - } - } -- -+#endif - return LXB_STATUS_OK; - } - -@@ -521,6 +524,7 @@ lxb_dom_document_style_attach_cb(lxb_dom_node_t *node, - lxb_status_t - lxb_document_apply_stylesheets(lxb_dom_document_t *document) - { -+#if 0 - size_t i, length; - lxb_status_t status; - lxb_css_stylesheet_t *sst; -@@ -539,6 +543,6 @@ lxb_document_apply_stylesheets(lxb_dom_document_t *document) - return status; - } - } -- -+#endif - return LXB_STATUS_OK; - } -diff --git a/source/lexbor/style/html/interfaces/document.h b/source/lexbor/style/html/interfaces/document.h -index 0307cd9..127c4cd 100644 ---- a/source/lexbor/style/html/interfaces/document.h -+++ b/source/lexbor/style/html/interfaces/document.h -@@ -134,6 +134,7 @@ lxb_html_document_stylesheet_destroy_all(lxb_html_document_t *document, - destroy_memory); - } - -+#if 0 - lxb_inline lxb_status_t - lxb_html_document_style_attach(lxb_html_document_t *document, - lxb_css_rule_style_t *style) -@@ -158,6 +159,7 @@ lxb_html_document_style_attach_by_element(lxb_html_document_t *document, - return lxb_dom_document_style_attach_by_element(lxb_dom_interface_document(document), - element, style); - } -+#endif - - lxb_inline lxb_status_t - lxb_html_document_apply_stylesheets(lxb_html_document_t *document) --- -2.49.0 - diff --git a/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch b/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch new file mode 100644 index 000000000000..50bdc2397ba5 --- /dev/null +++ b/ext/lexbor/patches/0007-Add-lxb_url_is_special-to-the-public-API-362.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= +Date: Sun, 17 May 2026 22:17:14 +0200 +Subject: [PATCH 07/11] Add lxb_url_is_special() to the public API (#362) + +As https://wiki.php.net/rfc/uri_followup#uri_type_detection relies on this information. +--- + source/lexbor/url/url.c | 2 +- + source/lexbor/url/url.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index 5a11434..a5b323f 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -860,7 +860,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) + return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; + } + +-lxb_inline bool ++bool + lxb_url_is_special(const lxb_url_t *url) + { + return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; +diff --git a/source/lexbor/url/url.h b/source/lexbor/url/url.h +index 4ed3f32..6cc6f10 100644 +--- a/source/lexbor/url/url.h ++++ b/source/lexbor/url/url.h +@@ -763,6 +763,15 @@ LXB_API lxb_status_t + lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, + lexbor_callback_f cb, void *ctx); + ++/** ++ * Returns whether the URL is special. ++ * ++ * @param[in] lxb_url_t *. Cannot be NULL. ++ * @return true if URL is special, false otherwise. ++ */ ++LXB_API bool ++lxb_url_is_special(const lxb_url_t *url); ++ + /* + * Inline functions. + */ diff --git a/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch b/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch new file mode 100644 index 000000000000..4218461c3bad --- /dev/null +++ b/ext/lexbor/patches/0008-URL-fixed-setters-for-empty-hosts.patch @@ -0,0 +1,191 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Alexander Borisov +Date: Fri, 26 Jun 2026 18:55:56 +0300 +Subject: [PATCH 08/11] URL: fixed setters for empty hosts. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Empty non-special hosts were represented as empty opaque hosts, so +lxb_url_cannot_have_user_pass_port() allowed username, password, and port +setters to modify scheme://. + +For fixed this store empty opaque-host input as LXB_URL_HOST_TYPE_EMPTY. + +Per report from Máté Kocsis (@kocsismate). + +This relates to #387 issue on GitHub. +--- + source/lexbor/url/url.c | 35 ++++++++++++++++++--- + test/files/lexbor/url/changes.ton | 52 +++++++++++++++++++++++++++++-- + test/files/lexbor/url/url.ton | 8 ++++- + 3 files changed, 86 insertions(+), 9 deletions(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index a5b323f..5c6d5cc 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -1115,11 +1115,13 @@ lxb_url_host_copy(const lxb_url_host_t *src, lxb_url_host_t *dst, + + dst->type = src->type; + +- if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { +- if (src->type == LXB_URL_HOST_TYPE__UNDEF) { +- return LXB_STATUS_OK; +- } ++ if (src->type == LXB_URL_HOST_TYPE__UNDEF ++ || src->type == LXB_URL_HOST_TYPE_EMPTY) ++ { ++ return LXB_STATUS_OK; ++ } + ++ if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { + return lxb_url_str_copy(&src->u.domain, + &dst->u.domain, dst_mraw); + } +@@ -1152,6 +1154,24 @@ lxb_url_host_set_empty(lxb_url_host_t *host, lexbor_mraw_t *mraw) + host->type = LXB_URL_HOST_TYPE_EMPTY; + } + ++lxb_inline bool ++lxb_url_host_is_empty(const lxb_url_host_t *host) ++{ ++ if (host->type == LXB_URL_HOST_TYPE_EMPTY) { ++ return true; ++ } ++ ++ if (host->type == LXB_URL_HOST_TYPE_DOMAIN) { ++ return host->u.domain.length == 0; ++ } ++ ++ if (host->type == LXB_URL_HOST_TYPE_OPAQUE) { ++ return host->u.opaque.length == 0; ++ } ++ ++ return false; ++} ++ + static bool + lxb_url_host_eq(lxb_url_host_t *host, const lxb_char_t *data, size_t length) + { +@@ -1251,7 +1271,7 @@ lxb_url_normalized_windows_drive_letter(const lxb_char_t *data, + static bool + lxb_url_cannot_have_user_pass_port(lxb_url_t *url) + { +- return url->host.type == LXB_URL_HOST_TYPE_EMPTY ++ return lxb_url_host_is_empty(&url->host) + || url->host.type == LXB_URL_HOST_TYPE__UNDEF + || url->scheme.type == LXB_URL_SCHEMEL_TYPE_FILE; + } +@@ -3978,6 +3998,11 @@ lxb_url_opaque_host_parse(lxb_url_parser_t *parser, const lxb_char_t *data, + lxb_status_t status; + const lxb_char_t *p; + ++ if (data == end) { ++ lxb_url_host_set_empty(host, mraw); ++ return LXB_STATUS_OK; ++ } ++ + p = data; + + while (p < end) { +diff --git a/test/files/lexbor/url/changes.ton b/test/files/lexbor/url/changes.ton +index 07bc944..1a0b6e3 100644 +--- a/test/files/lexbor/url/changes.ton ++++ b/test/files/lexbor/url/changes.ton +@@ -1,5 +1,5 @@ + [ +- /* Test count: 1 */ ++ /* Test count: 47 */ + /* 1 */ + { + "url": "https://user:pass@lexbor.com/docs/html/path?x=y&a=b#best-fragment", +@@ -982,9 +982,53 @@ + "failed": false + }, + /* 45 */ ++ { ++ "url": "scheme://", ++ "done": "scheme://", ++ "change": { ++ "href": null, ++ "protocol": null, ++ "username": "user", ++ "password": "pass", ++ "host": null, ++ "hostname": null, ++ "port": "433", ++ "pathname": null, ++ "search": null, ++ "hash": null ++ }, ++ "scheme": "scheme", ++ "host": "", ++ "path": "", ++ "failed": false ++ }, ++ /* 46 */ ++ { ++ "url": "scheme://host", ++ "done": "scheme://host:433", ++ "change": { ++ "href": null, ++ "protocol": null, ++ "username": null, ++ "password": null, ++ "host": null, ++ "hostname": null, ++ "port": "433", ++ "pathname": null, ++ "search": null, ++ "hash": null ++ }, ++ "scheme": "scheme", ++ "host": "host", ++ "port": 433, ++ "has_port": true, ++ "path": "", ++ "failed": false ++ }, ++ /* 47 */ + { + "url": "https://example.com:432", +- "done": "https://example.com:432", ++ "done": "https://example.com:432/", + "change": { + "href": null, + "protocol": null, +@@ -999,7 +1043,9 @@ + }, + "scheme": "https", + "host": "example.com", +- "port": "432", ++ "port": 432, ++ "has_port": true, ++ "path": "/", + "failed": true + } + ] +diff --git a/test/files/lexbor/url/url.ton b/test/files/lexbor/url/url.ton +index 2baa4bc..85794c5 100644 +--- a/test/files/lexbor/url/url.ton ++++ b/test/files/lexbor/url/url.ton +@@ -1,5 +1,5 @@ + [ +- /* Test count: 7 */ ++ /* Test count: 8 */ + /* 1 */ + { + "url": "https://user:pass@lexbor.com:450/docs/lexbor/?search=lxb_status_t#version", +@@ -74,5 +74,11 @@ + "path": "", + "failed": false, + "encoding": "utf-8" ++ }, ++ /* 8 */ ++ { ++ "url": "scheme://:433", ++ "failed": true, ++ "encoding": "utf-8" + } + ] diff --git a/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch b/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch new file mode 100644 index 000000000000..91e78a899f44 --- /dev/null +++ b/ext/lexbor/patches/0009-URL-fixed-uninitialized-memory-in-the-path-buffer-gr.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Alexander Borisov +Date: Fri, 5 Jun 2026 22:13:32 +0300 +Subject: [PATCH 09/11] URL: fixed uninitialized memory in the path buffer + growth. + +When a path was long enough to outgrow the on-stack buffer, the first +move to the heap didn't copy what was already written, so the start of +the path could contain garbage. Also fixed the 'last' pointer after the +move. + +Per report from Recep Asan (recep@asan.me) +--- + source/lexbor/url/url.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index 5c6d5cc..1fd044b 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -499,6 +499,7 @@ lxb_url_scheme_length = sizeof(lxb_url_scheme_res) / sizeof(lxb_url_scheme_data_ + if (tmp == NULL) { \ + return NULL; \ + } \ ++ memcpy(tmp, (sbuf_begin), offset); \ + } \ + else { \ + tmp = lexbor_realloc((sbuf_begin), new_len); \ +@@ -509,7 +510,7 @@ lxb_url_scheme_length = sizeof(lxb_url_scheme_res) / sizeof(lxb_url_scheme_data_ + } \ + \ + (sbuf) = tmp + offset; \ +- (last) = sbuf + lst; \ ++ (last) = tmp + lst; \ + (sbuf_begin) = tmp; \ + (sbuf_end) = tmp + new_len; \ + } \ diff --git a/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch b/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch new file mode 100644 index 000000000000..9cbf3e0094ed --- /dev/null +++ b/ext/lexbor/patches/0010-Fix-parsing-for-URL-containing-empty-host-and-userin.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= +Date: Thu, 9 Jul 2026 21:51:05 +0200 +Subject: [PATCH 10/11] Fix parsing for URL containing empty host and userinfo + +The returned error code (LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS) apparently contradicts the specification: + +"If atSignSeen is true and buffer is the empty string, host-missing validation error, return failure." +--- + source/lexbor/url/url.c | 2 +- + test/files/lexbor/url/username_password.ton | 8 +++++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index 1fd044b..aed468a 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -1814,7 +1814,7 @@ again: + if (at_sign) { + if (begin == p || begin == p - 1) { + status = lxb_url_log_append(parser, p, +- LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS); ++ LXB_URL_ERROR_TYPE_HOST_MISSING); + if (status != LXB_STATUS_OK) { + lxb_url_parse_return(orig_data, buf, status); + } +diff --git a/test/files/lexbor/url/username_password.ton b/test/files/lexbor/url/username_password.ton +index 28a27fd..5a5e63e 100644 +--- a/test/files/lexbor/url/username_password.ton ++++ b/test/files/lexbor/url/username_password.ton +@@ -1,5 +1,5 @@ + [ +- /* Test count: 11 */ ++ /* Test count: 12 */ + /* 1 */ + { + "url": "https://user:password@lexbor.com", +@@ -124,4 +124,10 @@ + "failed": false, + "encoding": "utf-8" + } ++ /* 12 */ ++ { ++ "url": "https://user:pass@", ++ "failed": true, ++ "encoding": "utf-8" ++ } + ] diff --git a/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch b/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch new file mode 100644 index 000000000000..2781fad5bcb9 --- /dev/null +++ b/ext/lexbor/patches/0011-Percent-encode-the-caret-in-the-path.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= +Date: Fri, 10 Jul 2026 22:31:16 +0200 +Subject: [PATCH 11/11] Percent-encode the caret in the path + +The caret (^) is part of the path percent-encode set: + +"The path percent-encode set is a percent-encode set consisting of the query percent-encode set and U+003F (?), U+005E (^), U+0060 (`), U+007B ({), and U+007D (})." + +Until now, this character wasn't percent-encoded in the path likely due to a copy-paste error. This is mistake is fixed by adding LXB_URL_MAP_PATH to the lxb_url_map entry for the caret. + +Originally reported at https://github.com/php/php-src/issues/22628 +--- + source/lexbor/url/url.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index aed468a..8099c12 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -159,7 +159,7 @@ static const uint8_t lxb_url_map[256] = + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5b ([) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5c (\) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5d (]) */ +- LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ ++ LXB_URL_MAP_USERINFO|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ + LXB_URL_MAP_UNDEF, /* 0x5f (_) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x60 (`) */ + LXB_URL_MAP_UNDEF, /* 0x61 (a) */ diff --git a/ext/lexbor/patches/README.md b/ext/lexbor/patches/README.md index 53d58e03da08..6c7b78fd59fa 100644 --- a/ext/lexbor/patches/README.md +++ b/ext/lexbor/patches/README.md @@ -1,7 +1,10 @@ # Lexbor patches +> [!IMPORTANT] +> This process was largely automated in update-lexbor.sh. + Upon syncing the Lexbor sources, the patches in this directory need to be applied. -The current Lexbor version is 2.5.0. +The current Lexbor version is 2.7.0. ## Overview diff --git a/ext/lexbor/patches/update-lexbor.sh b/ext/lexbor/patches/update-lexbor.sh new file mode 100755 index 000000000000..92ef8aa58f66 --- /dev/null +++ b/ext/lexbor/patches/update-lexbor.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -e + +PATCHES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LEXBOR_REPO="https://github.com/lexbor/lexbor" +LEXBOR_REF="v2.7.0" +LEXBOR_BASE="$(cd "$PATCHES_DIR/.." && pwd)" +LEXBOR_DIR="$LEXBOR_BASE/lexbor" +LEXBOR_TMP_DIR="$LEXBOR_BASE/lexbor_tmp" +LEXBOR_COMPONENTS=(core css dom encoding html ns ports punycode selectors tag unicode url) + +# Clone +git clone "$LEXBOR_REPO" "$LEXBOR_TMP_DIR" +(cd "$LEXBOR_TMP_DIR" && git checkout "$LEXBOR_REF") + +# Apply patches +patches=() +for f in "$PATCHES_DIR"/*.patch; do + [ -e "$f" ] && patches+=("$f") +done +cd "$LEXBOR_TMP_DIR" +for patch in "${patches[@]}"; do + if ! git am -3 "$patch"; then + read -p "Patch $(basename "$patch") did not apply cleanly. Resolve, stage and press Enter to continue. " + git am --continue + fi +done + +# Refresh patches +rm "$PATCHES_DIR"/*.patch +NUM_PATCHES=${#patches[@]} +git format-patch --no-signature --zero-commit "HEAD~$NUM_PATCHES" -o "$PATCHES_DIR" + +# Run code-generation tools +(cd "$LEXBOR_TMP_DIR/utils/lexbor/encoding" && python3 single-byte.py) +(cd "$LEXBOR_TMP_DIR/utils/lexbor/html" && python3 tokenizer_entities_bst.py) + +# (Re)move files +mv source/lexbor/encoding/multi_res.c source/lexbor/encoding/multi.c +mv source/lexbor/encoding/range_res.c source/lexbor/encoding/range.c +mv source/lexbor/encoding/single_res.c source/lexbor/encoding/single.c +rm source/lexbor/html/serialize.c +rm source/lexbor/ports/posix/lexbor/core/fs.c +rm source/lexbor/ports/posix/lexbor/core/perf.c +rm source/lexbor/ports/windows_nt/lexbor/core/fs.c +rm source/lexbor/ports/windows_nt/lexbor/core/perf.c +rm source/lexbor/selectors/selectors.c +rm source/lexbor/selectors/selectors.h +find . -name "*.cmake" -delete + +# Replace components +for dir in "${LEXBOR_COMPONENTS[@]}"; do + dst="$LEXBOR_DIR/$dir" + rm -rf "$dst" + cp -r "source/lexbor/$dir" "$dst" +done +rm -rf "$LEXBOR_TMP_DIR" diff --git a/ext/lexbor/php_lexbor.c b/ext/lexbor/php_lexbor.c index 7f847bfb0afe..570190eee238 100644 --- a/ext/lexbor/php_lexbor.c +++ b/ext/lexbor/php_lexbor.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | | Mate Kocsis | +----------------------------------------------------------------------+ */ @@ -22,6 +20,7 @@ #include "php.h" #include "zend_globals.h" #include "ext/standard/info.h" +#include "lexbor/core/base.h" #include "lexbor/core/types.h" #include "lexbor/core/lexbor.h" @@ -53,7 +52,7 @@ static PHP_MINFO_FUNCTION(lexbor) { php_info_print_table_start(); php_info_print_table_row(2, "Lexbor support", "active"); - php_info_print_table_row(2, "Lexbor version", LEXBOR_VERSION); + php_info_print_table_row(2, "Lexbor version", LEXBOR_VERSION_STRING); php_info_print_table_end(); } diff --git a/ext/lexbor/php_lexbor.h b/ext/lexbor/php_lexbor.h index fbdc71746dca..dccedb28b29b 100644 --- a/ext/lexbor/php_lexbor.h +++ b/ext/lexbor/php_lexbor.h @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | | Mate Kocsis | +----------------------------------------------------------------------+ */ diff --git a/ext/libxml/image_svg.c b/ext/libxml/image_svg.c index 091f7e283168..88dfdfd81fd8 100644 --- a/ext/libxml/image_svg.c +++ b/ext/libxml/image_svg.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/libxml/image_svg.h b/ext/libxml/image_svg.h index d023334af36b..9e13ef2a421d 100644 --- a/ext/libxml/image_svg.h +++ b/ext/libxml/image_svg.h @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 5a0e1f3c7a09..1f3d7c4d8789 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Shane Caraveo | | Wez Furlong | diff --git a/ext/libxml/mime_sniff.c b/ext/libxml/mime_sniff.c index 14034f3db267..2e54d579814c 100644 --- a/ext/libxml/mime_sniff.c +++ b/ext/libxml/mime_sniff.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ @@ -273,7 +271,7 @@ PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_string(const char *sta /* 11.9.1. Set parameterValue to the result of collecting a sequence of code points that are not ';' */ size_t parameter_value_length = collect_a_sequence_of_code_points(start, end, is_not_semicolon); parameter_value = zend_string_init(start, parameter_value_length, false); - start += parameter_name_length; + start += parameter_value_length; /* 11.9.2. Remove trailing HTTP whitespace from parameterValue */ while (ZSTR_LEN(parameter_value) > 0 && is_http_whitespace(ZSTR_VAL(parameter_value)[ZSTR_LEN(parameter_value) - 1])) { diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index eb10e7e4cb93..5896f70803f8 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Shane Caraveo | | Wez Furlong | diff --git a/ext/libxml/tests/bug61367-read_2.phpt b/ext/libxml/tests/bug61367-read_2.phpt index f4b0f300293c..ec4ce827336b 100644 --- a/ext/libxml/tests/bug61367-read_2.phpt +++ b/ext/libxml/tests/bug61367-read_2.phpt @@ -5,6 +5,7 @@ dom --SKIPIF-- = 2.9.12 only'); +if (preg_match('/[^\x00-\x7F]/', __DIR__)) die('skip path contains non-ASCII characters that libxml URI parser rejects'); ?> --INI-- open_basedir=. @@ -58,6 +59,6 @@ bool(true) int(4) bool(true) -%s: DOMDocument::loadXML(): %Sfailed to load %s +%s: DOMDocument::loadXML(): %s Warning: Attempt to read property "nodeValue" on null in %s on line %d diff --git a/ext/libxml/tests/bug61367-write.phpt b/ext/libxml/tests/bug61367-write.phpt index f11f10952204..e8f004471645 100644 --- a/ext/libxml/tests/bug61367-write.phpt +++ b/ext/libxml/tests/bug61367-write.phpt @@ -44,5 +44,5 @@ bool(true) Warning: DOMDocument::save(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d -Warning: DOMDocument::save(%s): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d +Warning: DOMDocument::save(): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d bool(false) diff --git a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt index fb71c0c8d756..be386154bb20 100644 --- a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt +++ b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt @@ -6,6 +6,7 @@ dom --SKIPIF-- = 2.9.12 only'); +if (preg_match('/[^\x00-\x7F]/', __DIR__)) die('skip path contains non-ASCII characters that libxml URI parser rejects'); ?> --FILE-- --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h index 5cf331a51c7d..775ababfde08 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c index 87bdc590e6d5..0ee74c032140 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c @@ -260,7 +260,7 @@ int mbfl_filt_conv_utf7_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -368,7 +368,7 @@ int mbfl_filt_conv_wchar_utf7(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c index ac49e6a165b4..ba34255ebc13 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c @@ -282,7 +282,7 @@ int mbfl_filt_conv_utf7imap_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -409,7 +409,7 @@ int mbfl_filt_conv_wchar_utf7imap(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c index 63ca5bc6a2e7..f7c99461719e 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c @@ -342,7 +342,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len) /* search MIME charset name */ for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) { if ((*encoding)->mime_name) { - if (strncasecmp((*encoding)->mime_name, name, name_len) == 0 && (*encoding)->mime_name[name_len] == '\0') { + size_t mime_len = strlen((*encoding)->mime_name); + if (mime_len == name_len && strncasecmp((*encoding)->mime_name, name, name_len) == 0) { return *encoding; } } @@ -352,7 +353,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len) for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) { if ((*encoding)->aliases) { for (const char **alias = (*encoding)->aliases; *alias; alias++) { - if (strncasecmp(name, *alias, name_len) == 0 && (*alias)[name_len] == '\0') { + size_t alias_len = strlen(*alias); + if (alias_len == name_len && strncasecmp(name, *alias, name_len) == 0) { return *encoding; } } diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index 4445a0dc5a1b..d0ee90266b52 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rui Hirokawa | | Moriyoshi Koizumi | diff --git a/ext/mbstring/mb_gpc.h b/ext/mbstring/mb_gpc.h index 63337755cdea..fdbb0c818238 100644 --- a/ext/mbstring/mb_gpc.h +++ b/ext/mbstring/mb_gpc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rui Hirokawa | | Moriyoshi Koizumi | diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 95b624ef1d2d..b475b83e02f3 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | | Rui Hirokawa | @@ -56,6 +54,7 @@ #include "mb_gpc.h" #ifdef HAVE_MBREGEX +# include "zend_attributes.h" # include "php_mbregex.h" #endif @@ -625,7 +624,7 @@ static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line, static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *str) /* {{{ */ { - while (*str && isspace(*(unsigned char *)str)) { + while (*str && isspace((unsigned char)*str)) { ++str; } @@ -641,7 +640,7 @@ static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *st } else { char *strend = str; - while (*strend && !isspace(*(unsigned char *)strend)) { + while (*strend && !isspace((unsigned char)*strend)) { ++strend; } return php_mb_rfc1867_substring_conf(encoding, str, strend - str, 0); @@ -1216,17 +1215,17 @@ PHP_FUNCTION(mb_language) ZEND_PARSE_PARAMETERS_END(); if (name == NULL) { - RETVAL_STRING((char *)mbfl_no_language2name(MBSTRG(language))); + RETVAL_STRING(mbfl_no_language2name(MBSTRG(language))); } else { - zend_string *ini_name = ZSTR_INIT_LITERAL("mbstring.language", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("mbstring.language", false); if (FAILURE == zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME)) { zend_argument_value_error(1, "must be a valid language, \"%s\" given", ZSTR_VAL(name)); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); RETURN_THROWS(); } // TODO Make return void RETVAL_TRUE; - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } /* }}} */ @@ -1509,7 +1508,7 @@ PHP_FUNCTION(mb_preferred_mime_name) php_error_docref(NULL, E_WARNING, "No MIME preferred name corresponding to \"%s\"", name); RETVAL_FALSE; } else { - RETVAL_STRING((char *)preferred_name); + RETVAL_STRING(preferred_name); } } /* }}} */ @@ -1943,7 +1942,7 @@ static size_t mb_find_strpos(zend_string *haystack, zend_string *needle, const m } else if (offset >= 0) { found_pos = zend_memnrstr((const char*)offset_pointer, ZSTR_VAL(needle_u8), ZSTR_LEN(needle_u8), ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8)); } else { - size_t needle_len = pointer_to_offset_utf8((unsigned char*)ZSTR_VAL(needle), (unsigned char*)ZSTR_VAL(needle) + ZSTR_LEN(needle)); + size_t needle_len = pointer_to_offset_utf8((unsigned char*)ZSTR_VAL(needle_u8), (unsigned char*)ZSTR_VAL(needle_u8) + ZSTR_LEN(needle_u8)); offset_pointer = offset_to_pointer_utf8(offset_pointer, (unsigned char*)ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8), needle_len); if (!offset_pointer) { offset_pointer = (unsigned char*)ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8); @@ -3517,7 +3516,7 @@ PHP_FUNCTION(mb_detect_encoding) RETURN_FALSE; } - RETVAL_STRING((char *)ret->name); + RETVAL_STRING(ret->name); } /* }}} */ @@ -3563,7 +3562,7 @@ PHP_FUNCTION(mb_encoding_aliases) array_init(return_value); if (encoding->aliases != NULL) { for (const char **alias = encoding->aliases; *alias; ++alias) { - add_next_index_string(return_value, (char *)*alias); + add_next_index_string(return_value, *alias); } } } @@ -4482,12 +4481,14 @@ static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t fld_val = zend_string_init(token, token_pos, 0); } - if (fld_name != NULL && fld_val != NULL) { - zval val; - zend_str_tolower(ZSTR_VAL(fld_name), ZSTR_LEN(fld_name)); - ZVAL_STR(&val, fld_val); + if (fld_name != NULL) { + if (fld_val != NULL) { + zval val; + zend_str_tolower(ZSTR_VAL(fld_name), ZSTR_LEN(fld_name)); + ZVAL_STR(&val, fld_val); - zend_hash_update(ht, fld_name, &val); + zend_hash_update(ht, fld_name, &val); + } zend_string_release_ex(fld_name, 0); } @@ -4528,11 +4529,13 @@ static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t if(token && token_pos > 0) { fld_val = zend_string_init(token, token_pos, 0); } - if (fld_name != NULL && fld_val != NULL) { - zval val; - zend_str_tolower(ZSTR_VAL(fld_name), ZSTR_LEN(fld_name)); - ZVAL_STR(&val, fld_val); - zend_hash_update(ht, fld_name, &val); + if (fld_name != NULL) { + if (fld_val != NULL) { + zval val; + zend_str_tolower(ZSTR_VAL(fld_name), ZSTR_LEN(fld_name)); + ZVAL_STR(&val, fld_val); + zend_hash_update(ht, fld_name, &val); + } zend_string_release_ex(fld_name, 0); } @@ -4768,7 +4771,7 @@ PHP_FUNCTION(mb_send_mail) str_headers = smart_str_extract(&str); - zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL); + zend_string *force_extra_parameters = zend_ini_str_literal("mail.force_extra_parameters"); if (force_extra_parameters) { extra_cmd = php_escape_shell_cmd(force_extra_parameters); } else if (extra_cmd) { @@ -4804,7 +4807,7 @@ PHP_FUNCTION(mb_get_info) { zend_string *type = NULL; size_t n; - char *name; + const char *name; zval row; const mbfl_encoding **entry; const mbfl_language *lang = mbfl_no2language(MBSTRG(language)); @@ -4819,26 +4822,26 @@ PHP_FUNCTION(mb_get_info) if (!type || zend_string_equals_literal_ci(type, "all")) { array_init(return_value); if (MBSTRG(current_internal_encoding)) { - add_assoc_string(return_value, "internal_encoding", (char *)MBSTRG(current_internal_encoding)->name); + add_assoc_string(return_value, "internal_encoding", MBSTRG(current_internal_encoding)->name); } if (MBSTRG(http_input_identify)) { - add_assoc_string(return_value, "http_input", (char *)MBSTRG(http_input_identify)->name); + add_assoc_string(return_value, "http_input", MBSTRG(http_input_identify)->name); } if (MBSTRG(current_http_output_encoding)) { - add_assoc_string(return_value, "http_output", (char *)MBSTRG(current_http_output_encoding)->name); + add_assoc_string(return_value, "http_output", MBSTRG(current_http_output_encoding)->name); } add_assoc_str(return_value, "http_output_conv_mimetypes", - zend_ini_str("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes") - 1, 0) + zend_string_copy(zend_ini_str_literal("mbstring.http_output_conv_mimetypes")) ); - name = (char *)mbfl_no_encoding2name(lang->mail_charset); + name = mbfl_no_encoding2name(lang->mail_charset); add_assoc_string(return_value, "mail_charset", name); - name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding); + name = mbfl_no_encoding2name(lang->mail_header_encoding); add_assoc_string(return_value, "mail_header_encoding", name); - name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding); + name = mbfl_no_encoding2name(lang->mail_body_encoding); add_assoc_string(return_value, "mail_body_encoding", name); add_assoc_long(return_value, "illegal_chars", MBSTRG(illegalchars)); @@ -4849,7 +4852,7 @@ PHP_FUNCTION(mb_get_info) add_assoc_string(return_value, "encoding_translation", "Off"); } - name = (char *)mbfl_no_language2name(MBSTRG(language)); + name = mbfl_no_language2name(MBSTRG(language)); add_assoc_string(return_value, "language", name); // TODO Seems to always have one entry at least? @@ -4880,31 +4883,25 @@ PHP_FUNCTION(mb_get_info) } } else if (zend_string_equals_literal_ci(type, "internal_encoding")) { ZEND_ASSERT(MBSTRG(current_internal_encoding)); - RETURN_STRING((char *)MBSTRG(current_internal_encoding)->name); + RETURN_STRING(MBSTRG(current_internal_encoding)->name); } else if (zend_string_equals_literal_ci(type, "http_input")) { if (MBSTRG(http_input_identify)) { - RETURN_STRING((char *)MBSTRG(http_input_identify)->name); + RETURN_STRING(MBSTRG(http_input_identify)->name); } RETURN_NULL(); } else if (zend_string_equals_literal_ci(type, "http_output")) { ZEND_ASSERT(MBSTRG(current_http_output_encoding)); - RETURN_STRING((char *)MBSTRG(current_http_output_encoding)->name); + RETURN_STRING(MBSTRG(current_http_output_encoding)->name); } else if (zend_string_equals_literal_ci(type, "http_output_conv_mimetypes")) { - RETURN_STR( - zend_ini_str( - "mbstring.http_output_conv_mimetypes", - sizeof("mbstring.http_output_conv_mimetypes") - 1, - false - ) - ); + RETURN_STR_COPY(zend_ini_str_literal("mbstring.http_output_conv_mimetypes")); } else if (zend_string_equals_literal_ci(type, "mail_charset")) { - name = (char *)mbfl_no_encoding2name(lang->mail_charset); + name = mbfl_no_encoding2name(lang->mail_charset); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "mail_header_encoding")) { - name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding); + name = mbfl_no_encoding2name(lang->mail_header_encoding); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "mail_body_encoding")) { - name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding); + name = mbfl_no_encoding2name(lang->mail_body_encoding); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "illegal_chars")) { RETURN_LONG(MBSTRG(illegalchars)); @@ -4915,7 +4912,7 @@ PHP_FUNCTION(mb_get_info) RETURN_STRING("Off"); } } else if (zend_string_equals_literal_ci(type, "language")) { - name = (char *)mbfl_no_language2name(MBSTRG(language)); + name = mbfl_no_language2name(MBSTRG(language)); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "detect_order")) { // TODO Seems to always have one entry at least? @@ -5266,7 +5263,7 @@ static bool mb_fast_check_utf8_default(zend_string *str) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 7256605bd246..c12c61290a15 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | | Hironori Sato | diff --git a/ext/mbstring/mbstring.stub.php b/ext/mbstring/mbstring.stub.php index af9c5cbb93ea..109a3ad564d8 100644 --- a/ext/mbstring/mbstring.stub.php +++ b/ext/mbstring/mbstring.stub.php @@ -7,6 +7,7 @@ * @var string * @cvalue php_mb_oniguruma_version */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] const MB_ONIGURUMA_VERSION = UNKNOWN; #endif @@ -197,57 +198,73 @@ function mb_str_pad(string $string, int $length, string $pad_string = " ", int $ #ifdef HAVE_MBREGEX /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_regex_encoding(?string $encoding = null): string|bool {} /** @param array $matches */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg(string $pattern, string $string, &$matches = null): bool {} /** @param array $matches */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_eregi(string $pattern, string $string, &$matches = null): bool {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_eregi_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_replace_callback(string $pattern, callable $callback, string $string, ?string $options = null): string|false|null {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_split(string $pattern, string $string, int $limit = -1): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_match(string $pattern, string $string, ?string $options = null): bool {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search(?string $pattern = null, ?string $options = null): bool {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_pos(?string $pattern = null, ?string $options = null): array|false {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_regs(?string $pattern = null, ?string $options = null): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_init(string $string, ?string $pattern = null, ?string $options = null): bool {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_getregs(): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_getpos(): int {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_setpos(int $offset): bool {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_regex_set_options(?string $options = null): string {} #endif diff --git a/ext/mbstring/mbstring_arginfo.h b/ext/mbstring/mbstring_arginfo.h index 8fb83425ee1d..bc9db3d415c1 100644 --- a/ext/mbstring/mbstring_arginfo.h +++ b/ext/mbstring/mbstring_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit mbstring.stub.php instead. - * Stub hash: 03c07f68bea7d7b96e6dc11f180f45663b859ed3 */ + * Stub hash: f02c317efd6814f902ea75c9d222893713546845 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_language, 0, 0, MAY_BE_STRING|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, language, IS_STRING, 1, "null") @@ -413,22 +413,22 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mb_chr, arginfo_mb_chr) ZEND_FE(mb_str_pad, arginfo_mb_str_pad) #if defined(HAVE_MBREGEX) - ZEND_FE(mb_regex_encoding, arginfo_mb_regex_encoding) - ZEND_FE(mb_ereg, arginfo_mb_ereg) - ZEND_FE(mb_eregi, arginfo_mb_eregi) - ZEND_FE(mb_ereg_replace, arginfo_mb_ereg_replace) - ZEND_FE(mb_eregi_replace, arginfo_mb_eregi_replace) - ZEND_FE(mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback) - ZEND_FE(mb_split, arginfo_mb_split) - ZEND_FE(mb_ereg_match, arginfo_mb_ereg_match) - ZEND_FE(mb_ereg_search, arginfo_mb_ereg_search) - ZEND_FE(mb_ereg_search_pos, arginfo_mb_ereg_search_pos) - ZEND_FE(mb_ereg_search_regs, arginfo_mb_ereg_search_regs) - ZEND_FE(mb_ereg_search_init, arginfo_mb_ereg_search_init) - ZEND_FE(mb_ereg_search_getregs, arginfo_mb_ereg_search_getregs) - ZEND_FE(mb_ereg_search_getpos, arginfo_mb_ereg_search_getpos) - ZEND_FE(mb_ereg_search_setpos, arginfo_mb_ereg_search_setpos) - ZEND_FE(mb_regex_set_options, arginfo_mb_regex_set_options) + ZEND_RAW_FENTRY("mb_regex_encoding", zif_mb_regex_encoding, arginfo_mb_regex_encoding, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg", zif_mb_ereg, arginfo_mb_ereg, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_eregi", zif_mb_eregi, arginfo_mb_eregi, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_replace", zif_mb_ereg_replace, arginfo_mb_ereg_replace, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_eregi_replace", zif_mb_eregi_replace, arginfo_mb_eregi_replace, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_replace_callback", zif_mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_split", zif_mb_split, arginfo_mb_split, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_match", zif_mb_ereg_match, arginfo_mb_ereg_match, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search", zif_mb_ereg_search, arginfo_mb_ereg_search, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_pos", zif_mb_ereg_search_pos, arginfo_mb_ereg_search_pos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_regs", zif_mb_ereg_search_regs, arginfo_mb_ereg_search_regs, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_init", zif_mb_ereg_search_init, arginfo_mb_ereg_search_init, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_getregs", zif_mb_ereg_search_getregs, arginfo_mb_ereg_search_getregs, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_getpos", zif_mb_ereg_search_getpos, arginfo_mb_ereg_search_getpos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_setpos", zif_mb_ereg_search_setpos, arginfo_mb_ereg_search_setpos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_regex_set_options", zif_mb_regex_set_options, arginfo_mb_regex_set_options, ZEND_ACC_DEPRECATED, NULL, NULL) #endif ZEND_FE_END }; @@ -436,7 +436,7 @@ static const zend_function_entry ext_functions[] = { static void register_mbstring_symbols(int module_number) { #if defined(HAVE_MBREGEX) - REGISTER_STRING_CONSTANT("MB_ONIGURUMA_VERSION", php_mb_oniguruma_version, CONST_PERSISTENT); + zend_constant *const_MB_ONIGURUMA_VERSION = REGISTER_STRING_CONSTANT("MB_ONIGURUMA_VERSION", php_mb_oniguruma_version, CONST_PERSISTENT | CONST_DEPRECATED); #endif REGISTER_LONG_CONSTANT("MB_CASE_UPPER", PHP_UNICODE_CASE_UPPER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_LOWER", PHP_UNICODE_CASE_LOWER, CONST_PERSISTENT); @@ -446,4 +446,145 @@ static void register_mbstring_symbols(int module_number) REGISTER_LONG_CONSTANT("MB_CASE_LOWER_SIMPLE", PHP_UNICODE_CASE_LOWER_SIMPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_TITLE_SIMPLE", PHP_UNICODE_CASE_TITLE_SIMPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_FOLD_SIMPLE", PHP_UNICODE_CASE_FOLD_SIMPLE, CONST_PERSISTENT); + +#if defined(HAVE_MBREGEX) + + zend_attribute *attribute_Deprecated_func_mb_regex_encoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_regex_encoding", sizeof("mb_regex_encoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_regex_encoding_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_encoding_0->args[0].value, attribute_Deprecated_func_mb_regex_encoding_0_arg0_str); + attribute_Deprecated_func_mb_regex_encoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_regex_encoding_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_encoding_0->args[1].value, attribute_Deprecated_func_mb_regex_encoding_0_arg1_str); + attribute_Deprecated_func_mb_regex_encoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg", sizeof("mb_ereg") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_0->args[0].value, attribute_Deprecated_func_mb_ereg_0_arg0_str); + attribute_Deprecated_func_mb_ereg_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_0->args[1].value, attribute_Deprecated_func_mb_ereg_0_arg1_str); + attribute_Deprecated_func_mb_ereg_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_eregi_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_eregi", sizeof("mb_eregi") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_eregi_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_0->args[0].value, attribute_Deprecated_func_mb_eregi_0_arg0_str); + attribute_Deprecated_func_mb_eregi_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_eregi_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_0->args[1].value, attribute_Deprecated_func_mb_eregi_0_arg1_str); + attribute_Deprecated_func_mb_eregi_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_replace_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_replace", sizeof("mb_ereg_replace") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_replace_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_0->args[0].value, attribute_Deprecated_func_mb_ereg_replace_0_arg0_str); + attribute_Deprecated_func_mb_ereg_replace_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_replace_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_0->args[1].value, attribute_Deprecated_func_mb_ereg_replace_0_arg1_str); + attribute_Deprecated_func_mb_ereg_replace_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_eregi_replace_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_eregi_replace", sizeof("mb_eregi_replace") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_eregi_replace_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_replace_0->args[0].value, attribute_Deprecated_func_mb_eregi_replace_0_arg0_str); + attribute_Deprecated_func_mb_eregi_replace_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_eregi_replace_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_replace_0->args[1].value, attribute_Deprecated_func_mb_eregi_replace_0_arg1_str); + attribute_Deprecated_func_mb_eregi_replace_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_replace_callback_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_replace_callback", sizeof("mb_ereg_replace_callback") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_replace_callback_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_callback_0->args[0].value, attribute_Deprecated_func_mb_ereg_replace_callback_0_arg0_str); + attribute_Deprecated_func_mb_ereg_replace_callback_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_replace_callback_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_callback_0->args[1].value, attribute_Deprecated_func_mb_ereg_replace_callback_0_arg1_str); + attribute_Deprecated_func_mb_ereg_replace_callback_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_split_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_split", sizeof("mb_split") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_split_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_split_0->args[0].value, attribute_Deprecated_func_mb_split_0_arg0_str); + attribute_Deprecated_func_mb_split_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_split_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_split_0->args[1].value, attribute_Deprecated_func_mb_split_0_arg1_str); + attribute_Deprecated_func_mb_split_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_match_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_match", sizeof("mb_ereg_match") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_match_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_match_0->args[0].value, attribute_Deprecated_func_mb_ereg_match_0_arg0_str); + attribute_Deprecated_func_mb_ereg_match_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_match_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_match_0->args[1].value, attribute_Deprecated_func_mb_ereg_match_0_arg1_str); + attribute_Deprecated_func_mb_ereg_match_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search", sizeof("mb_ereg_search") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_pos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_pos", sizeof("mb_ereg_search_pos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_pos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_pos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_pos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_pos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_pos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_pos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_pos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_pos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_regs_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_regs", sizeof("mb_ereg_search_regs") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_regs_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_regs_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_regs_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_regs_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_regs_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_regs_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_regs_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_regs_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_init_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_init", sizeof("mb_ereg_search_init") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_init_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_init_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_init_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_init_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_init_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_init_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_init_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_init_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_getregs_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_getregs", sizeof("mb_ereg_search_getregs") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_getregs_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getregs_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_getregs_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_getregs_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_getregs_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getregs_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_getregs_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_getregs_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_getpos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_getpos", sizeof("mb_ereg_search_getpos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_getpos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getpos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_getpos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_getpos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_getpos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getpos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_getpos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_getpos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_setpos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_setpos", sizeof("mb_ereg_search_setpos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_setpos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_setpos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_setpos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_setpos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_setpos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_setpos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_setpos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_setpos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_regex_set_options_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_regex_set_options", sizeof("mb_regex_set_options") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_regex_set_options_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_set_options_0->args[0].value, attribute_Deprecated_func_mb_regex_set_options_0_arg0_str); + attribute_Deprecated_func_mb_regex_set_options_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_regex_set_options_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_set_options_0->args[1].value, attribute_Deprecated_func_mb_regex_set_options_0_arg1_str); + attribute_Deprecated_func_mb_regex_set_options_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif +#if defined(HAVE_MBREGEX) + + zend_attribute *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0 = zend_add_global_constant_attribute(const_MB_ONIGURUMA_VERSION, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[0].value, attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg0_str); + attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[1].value, attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg1_str); + attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif } diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index a819def4b5bd..1043c4a46eb2 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | +----------------------------------------------------------------------+ @@ -409,8 +407,13 @@ int php_mb_regex_set_mbctype(const char *encname) if (mbctype == ONIG_ENCODING_UNDEF) { return FAILURE; } + const mbfl_encoding *mbfl_enc = mbfl_name2encoding(encname); + if (mbfl_enc == NULL) { + /* Encoding supported by Oniguruma but not by mbfl */ + return FAILURE; + } MBREX(current_mbctype) = mbctype; - MBREX(current_mbctype_mbfl_encoding) = mbfl_name2encoding(encname); + MBREX(current_mbctype_mbfl_encoding) = mbfl_enc; return SUCCESS; } /* }}} */ @@ -779,7 +782,7 @@ static inline void mb_regex_substitute( continue; } if (name_end[0] == delim) break; - if (maybe_num && !isdigit(name_end[0])) maybe_num = 0; + if (maybe_num && !isdigit((unsigned char)name_end[0])) maybe_num = 0; name_end++; } p = name_end + 1; @@ -1103,7 +1106,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache) == SUCCESS && !Z_ISUNDEF(retval)) { convert_to_string(&retval); - smart_str_appendl(&out_buf, Z_STRVAL(retval), Z_STRLEN(retval)); + smart_str_append(&out_buf, Z_STR(retval)); smart_str_free(&eval_buf); zval_ptr_dtor(&retval); } diff --git a/ext/mbstring/php_mbregex.h b/ext/mbstring/php_mbregex.h index 18a762d5a614..41c98b6d7465 100644 --- a/ext/mbstring/php_mbregex.h +++ b/ext/mbstring/php_mbregex.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | +----------------------------------------------------------------------+ diff --git a/ext/mbstring/php_unicode.c b/ext/mbstring/php_unicode.c index f4944312bdf5..ce255e401364 100644 --- a/ext/mbstring/php_unicode.c +++ b/ext/mbstring/php_unicode.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ @@ -463,7 +461,7 @@ MBSTRING_API zend_string *php_unicode_convert_case(php_case_mode case_mode, cons } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } converted_end = p; diff --git a/ext/mbstring/php_unicode.h b/ext/mbstring/php_unicode.h index 1326761943dc..ac96f9daee51 100644 --- a/ext/mbstring/php_unicode.h +++ b/ext/mbstring/php_unicode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ diff --git a/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt new file mode 100644 index 000000000000..e58be7e50d8a --- /dev/null +++ b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt @@ -0,0 +1,50 @@ +--TEST-- +GHSA-74r9-qxhc-fx53: Out-of-bounds access in mbfl_name2encoding_ex() +--CREDITS-- +Akshay Jain (AkshayJainG) +--EXTENSIONS-- +mbstring +--FILE-- +getMessage(), "\n"; + } +} + +ini_set('mbstring.detect_order', $encoding); +ini_set('mbstring.detect_order', $alias); +ini_set('mbstring.http_output', $encoding); +ini_set('mbstring.http_output', $alias); + +test(fn () => mb_convert_encoding('foo', $encoding, $encoding)); +test(fn () => mb_convert_encoding('foo', $alias, $alias)); +test(fn () => mb_detect_encoding('foo', $encoding)); +test(fn () => mb_detect_encoding('foo', $alias)); +test(fn () => mb_convert_variables($encoding, $alias, $var)); +test(fn () => mb_detect_order($encoding)); +test(fn () => mb_detect_order($alias)); + +?> +--EXPECTF-- +Warning: ini_set(): INI setting contains invalid encoding "UTF-8" in %s on line %d + +Warning: ini_set(): INI setting contains invalid encoding "binary" in %s on line %d + +Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d + +Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d +ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "UTF-8" +ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "binary" +ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "UTF-8" +ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "binary" +ValueError: mb_convert_variables(): Argument #2 ($from_encoding) contains invalid encoding "binary" +ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "UTF-8" +ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "binary" diff --git a/ext/mbstring/tests/bug43994.phpt b/ext/mbstring/tests/bug43994.phpt index b4ae29ff40e7..cc6953808cc6 100644 --- a/ext/mbstring/tests/bug43994.phpt +++ b/ext/mbstring/tests/bug43994.phpt @@ -31,9 +31,13 @@ try { var_dump($mb_regs); ?> ---EXPECT-- +--EXPECTF-- Without $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg(): Argument #1 ($pattern) must not be empty NULL diff --git a/ext/mbstring/tests/bug69151.phpt b/ext/mbstring/tests/bug69151.phpt index c95fa05c49f8..9dd546d2eee6 100644 --- a/ext/mbstring/tests/bug69151.phpt +++ b/ext/mbstring/tests/bug69151.phpt @@ -18,9 +18,16 @@ var_dump(NULL === mb_ereg_replace('.', "\\0", $str)); var_dump(false === mb_ereg_search_init("\x80", '.')); var_dump(false === mb_ereg_search()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) bool(true) + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/bug72164.phpt b/ext/mbstring/tests/bug72164.phpt index e4ed04ba5eba..2b8f3950d92c 100644 --- a/ext/mbstring/tests/bug72164.phpt +++ b/ext/mbstring/tests/bug72164.phpt @@ -19,5 +19,6 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Option "e" is not supported diff --git a/ext/mbstring/tests/bug72399.phpt b/ext/mbstring/tests/bug72399.phpt index 4d3ea6d28c0b..bf9880c0ab42 100644 --- a/ext/mbstring/tests/bug72399.phpt +++ b/ext/mbstring/tests/bug72399.phpt @@ -19,7 +19,12 @@ try { echo $e->getMessage() . \PHP_EOL; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(0) "" + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d No pattern was provided diff --git a/ext/mbstring/tests/bug72402.phpt b/ext/mbstring/tests/bug72402.phpt index 0441887e33c7..511c18bfec2c 100644 --- a/ext/mbstring/tests/bug72402.phpt +++ b/ext/mbstring/tests/bug72402.phpt @@ -17,5 +17,6 @@ try { } catch(Exception $e) {} ?> DONE ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d DONE diff --git a/ext/mbstring/tests/bug72691.phpt b/ext/mbstring/tests/bug72691.phpt index db299e9d9dbc..9147d149fcb3 100644 --- a/ext/mbstring/tests/bug72691.phpt +++ b/ext/mbstring/tests/bug72691.phpt @@ -27,23 +27,48 @@ mb_ereg_search('\Z'); var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search_getregs()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "foo" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" diff --git a/ext/mbstring/tests/bug72693.phpt b/ext/mbstring/tests/bug72693.phpt index 6596eadd5fea..7b120164afab 100644 --- a/ext/mbstring/tests/bug72693.phpt +++ b/ext/mbstring/tests/bug72693.phpt @@ -26,18 +26,41 @@ var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search('\Z')); var_dump(mb_ereg_search_getpos()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "foo" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) diff --git a/ext/mbstring/tests/bug72694.phpt b/ext/mbstring/tests/bug72694.phpt index ed7d2e79250e..0789f3620817 100644 --- a/ext/mbstring/tests/bug72694.phpt +++ b/ext/mbstring/tests/bug72694.phpt @@ -16,8 +16,17 @@ var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search('\Z')); var_dump(mb_ereg_search_getpos()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) diff --git a/ext/mbstring/tests/bug72710.phpt b/ext/mbstring/tests/bug72710.phpt index ca1558c2ff1f..614abcf542f8 100644 --- a/ext/mbstring/tests/bug72710.phpt +++ b/ext/mbstring/tests/bug72710.phpt @@ -11,4 +11,6 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); mb_ereg('(?<0>a)', 'a'); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): mbregex compile err: invalid group name <0> in %s on line %d diff --git a/ext/mbstring/tests/bug73532.phpt b/ext/mbstring/tests/bug73532.phpt index 27269296894c..1af3e2422904 100644 --- a/ext/mbstring/tests/bug73532.phpt +++ b/ext/mbstring/tests/bug73532.phpt @@ -10,5 +10,6 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug73646.phpt b/ext/mbstring/tests/bug73646.phpt index 9897b866439e..7b3e98164989 100644 --- a/ext/mbstring/tests/bug73646.phpt +++ b/ext/mbstring/tests/bug73646.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); var_dump(mb_ereg_search_init(NULL)); ?> --EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Deprecated: mb_ereg_search_init(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d bool(true) diff --git a/ext/mbstring/tests/bug76999.phpt b/ext/mbstring/tests/bug76999.phpt index 57e286af3b8a..5c6dc442573f 100644 --- a/ext/mbstring/tests/bug76999.phpt +++ b/ext/mbstring/tests/bug76999.phpt @@ -19,9 +19,20 @@ try { } var_dump(mb_regex_set_options()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "pr" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "mr" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(3) "imd" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Option "a" is not supported + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "mr" diff --git a/ext/mbstring/tests/bug77367.phpt b/ext/mbstring/tests/bug77367.phpt index ad1dac2e07c8..f4a1a373a98f 100644 --- a/ext/mbstring/tests/bug77367.phpt +++ b/ext/mbstring/tests/bug77367.phpt @@ -11,5 +11,8 @@ if (!function_exists('mb_split')) die('skip mb_split() not available'); mb_regex_encoding('UTF-8'); var_dump(mb_split("\\w", "\xfc")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77370.phpt b/ext/mbstring/tests/bug77370.phpt index a2e3759c120a..8ccb169f83e0 100644 --- a/ext/mbstring/tests/bug77370.phpt +++ b/ext/mbstring/tests/bug77370.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_split')) die('skip mb_split() not available'); var_dump(mb_split(" \xfd","")); ?> --EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line 2 + Warning: mb_split(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77371.phpt b/ext/mbstring/tests/bug77371.phpt index 767533c66a4e..b4a88ffc5124 100644 --- a/ext/mbstring/tests/bug77371.phpt +++ b/ext/mbstring/tests/bug77371.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_ereg')) die('skip mb_ereg() not available'); var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc","")); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77381.phpt b/ext/mbstring/tests/bug77381.phpt index 76607bc9ceba..cde197c49a68 100644 --- a/ext/mbstring/tests/bug77381.phpt +++ b/ext/mbstring/tests/bug77381.phpt @@ -14,14 +14,22 @@ var_dump(mb_ereg("0000\\"."\xf5","0")); var_dump(mb_ereg("(?i)FFF00000000000000000\xfd","")); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77418.phpt b/ext/mbstring/tests/bug77418.phpt index 352e125d689e..2227eef44a1b 100644 --- a/ext/mbstring/tests/bug77418.phpt +++ b/ext/mbstring/tests/bug77418.phpt @@ -12,5 +12,8 @@ mb_regex_encoding("UTF-32"); var_dump(mb_split("\x00\x00\x00\x5c\x00\x00\x00B","000000000000000000000000000000")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77428.phpt b/ext/mbstring/tests/bug77428.phpt index c65cd000042f..71f9e09b0b1e 100644 --- a/ext/mbstring/tests/bug77428.phpt +++ b/ext/mbstring/tests/bug77428.phpt @@ -15,6 +15,9 @@ var_dump(mb_ereg_replace('(%)', '\\\1', 'a%c')); var_dump(mb_ereg_replace('(%)', '\\\\1', 'a%c')); ?> ---EXPECT-- -string(4) "a\%c" -string(4) "a\%c" +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +string(4) "a\%%c" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +string(4) "a\%%c" diff --git a/ext/mbstring/tests/bug77514.phpt b/ext/mbstring/tests/bug77514.phpt index 4b33cca8a309..f6b7ca5d1808 100644 --- a/ext/mbstring/tests/bug77514.phpt +++ b/ext/mbstring/tests/bug77514.phpt @@ -13,5 +13,6 @@ $a="abc123"; var_dump(mb_ereg_replace("123","def\\",$a)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "abcdef\" diff --git a/ext/mbstring/tests/bug78559.phpt b/ext/mbstring/tests/bug78559.phpt index e107d1ba864a..18b1fe00f83a 100644 --- a/ext/mbstring/tests/bug78559.phpt +++ b/ext/mbstring/tests/bug78559.phpt @@ -12,5 +12,6 @@ $str = "5b5b5b5b5b5b5b492a5bce946b5c4b5d5c6b5c4b5d5c4b5d1cceb04b5d1cceb07a73717e $str = hex2bin($str); var_dump(mb_eregi($str, $str)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug78633.phpt b/ext/mbstring/tests/bug78633.phpt index a5dcd48b9bf9..42a1ccc4ed2d 100644 --- a/ext/mbstring/tests/bug78633.phpt +++ b/ext/mbstring/tests/bug78633.phpt @@ -15,5 +15,6 @@ if (is_bool($res)) { var_dump($res); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok diff --git a/ext/mbstring/tests/empty_pattern.phpt b/ext/mbstring/tests/empty_pattern.phpt index 64e63147ee78..c7a2ca285c29 100644 --- a/ext/mbstring/tests/empty_pattern.phpt +++ b/ext/mbstring/tests/empty_pattern.phpt @@ -24,6 +24,11 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_init(): Argument #2 ($pattern) must not be empty + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d No pattern was provided diff --git a/ext/mbstring/tests/gh18901.phpt b/ext/mbstring/tests/gh18901.phpt index 8d862a537c3b..55e41d48377d 100644 --- a/ext/mbstring/tests/gh18901.phpt +++ b/ext/mbstring/tests/gh18901.phpt @@ -13,7 +13,8 @@ foreach ($vals as $val) { var_dump(mb_split('\d', '123', $val)); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -24,6 +25,8 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -34,6 +37,8 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -44,10 +49,14 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "123" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "123" diff --git a/ext/mbstring/tests/gh22779.phpt b/ext/mbstring/tests/gh22779.phpt new file mode 100644 index 000000000000..2983f4e1194a --- /dev/null +++ b/ext/mbstring/tests/gh22779.phpt @@ -0,0 +1,34 @@ +--TEST-- +GH-22779: mb_strrpos() wrong result for a negative offset in a non-UTF-8 encoding +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +int(1) +int(1) +int(0) +int(1) +int(2) +int(2) +int(2) +int(1) +int(0) +int(0) diff --git a/ext/mbstring/tests/mb_ereg-compat-01.phpt b/ext/mbstring/tests/mb_ereg-compat-01.phpt index e9d407d1013b..c5752806d5c5 100644 --- a/ext/mbstring/tests/mb_ereg-compat-01.phpt +++ b/ext/mbstring/tests/mb_ereg-compat-01.phpt @@ -17,6 +17,9 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build echo "ok\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok diff --git a/ext/mbstring/tests/mb_ereg-compat-02.phpt b/ext/mbstring/tests/mb_ereg-compat-02.phpt index d30b9927cc53..a47f9c665bc8 100644 --- a/ext/mbstring/tests/mb_ereg-compat-02.phpt +++ b/ext/mbstring/tests/mb_ereg-compat-02.phpt @@ -19,7 +19,8 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build echo $registers[2]; echo "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 1 This is a nice and simple string is diff --git a/ext/mbstring/tests/mb_ereg.phpt b/ext/mbstring/tests/mb_ereg.phpt index 53bb58e15a86..5b3f9c125fcd 100644 --- a/ext/mbstring/tests/mb_ereg.phpt +++ b/ext/mbstring/tests/mb_ereg.phpt @@ -31,16 +31,65 @@ output_handler= do_tests( $enc ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 diff --git a/ext/mbstring/tests/mb_ereg1.phpt b/ext/mbstring/tests/mb_ereg1.phpt index 813fe5e41ef0..a92b796423de 100644 --- a/ext/mbstring/tests/mb_ereg1.phpt +++ b/ext/mbstring/tests/mb_ereg1.phpt @@ -24,7 +24,8 @@ foreach ($a as $args) { var_dump($args); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(3) { [0]=> @@ -35,6 +36,8 @@ array(3) { array(0) { } } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ValueError: mb_ereg(): Argument #1 ($pattern) must not be empty array(3) { [0]=> @@ -44,6 +47,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d TypeError: mb_ereg(): Argument #1 ($pattern) must be of type string, array given array(3) { [0]=> @@ -54,6 +59,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d TypeError: mb_ereg(): Argument #2 ($string) must be of type string, array given array(3) { [0]=> @@ -64,6 +71,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(3) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg2.phpt b/ext/mbstring/tests/mb_ereg2.phpt index f87b5c5410a8..22cd29199dda 100644 --- a/ext/mbstring/tests/mb_ereg2.phpt +++ b/ext/mbstring/tests/mb_ereg2.phpt @@ -18,13 +18,16 @@ var_dump($a, $b, $c); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(-1) int(-1) array(1) { [0]=> string(2) "-1" } + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(-1) int(-1) array(1) { diff --git a/ext/mbstring/tests/mb_ereg_basic.phpt b/ext/mbstring/tests/mb_ereg_basic.phpt index 094f2949ea43..d54f3bb3be80 100644 --- a/ext/mbstring/tests/mb_ereg_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_basic.phpt @@ -71,15 +71,23 @@ function base64_encode_var_dump($regs) { } } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : basic functionality *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 **-- ASCII String --** -- Without $regs argument-- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) --With $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(2) { [0]=> @@ -87,6 +95,8 @@ array(2) { [1]=> string(24) "VGhpcyBpcyBhbiBFbmdsaXM=" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -95,9 +105,15 @@ array(1) { **-- Multibyte String --** -- Without $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) -- With $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(3) { [0]=> @@ -107,6 +123,8 @@ array(3) { [2]=> string(8) "MTIzNA==" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(0) { } diff --git a/ext/mbstring/tests/mb_ereg_dupnames.phpt b/ext/mbstring/tests/mb_ereg_dupnames.phpt index cf4444682f57..104dba927189 100644 --- a/ext/mbstring/tests/mb_ereg_dupnames.phpt +++ b/ext/mbstring/tests/mb_ereg_dupnames.phpt @@ -15,7 +15,10 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build mb_ereg($pattern, '中!', $m); var_dump($m); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(6) "中?" @@ -26,6 +29,8 @@ array(4) { ["punct"]=> string(3) "?" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(6) "中!" diff --git a/ext/mbstring/tests/mb_ereg_match_basic.phpt b/ext/mbstring/tests/mb_ereg_match_basic.phpt index 5b7a8c2a5402..671a72d27272 100644 --- a/ext/mbstring/tests/mb_ereg_match_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_match_basic.phpt @@ -38,18 +38,27 @@ var_dump(mb_ereg_match($regex2, $string_mb)); echo "Done"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d *** Testing mb_ereg_match() : basic functionality *** -- ASCII string 1 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) -- ASCII string 2 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) -- Multibyte string 1 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) -- Multibyte string 2 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) Done diff --git a/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt b/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt index 80c17b729d70..7756b49d2128 100644 --- a/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt +++ b/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt @@ -16,7 +16,10 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build mb_ereg('(\s*)(?\w+)', ' 中国', $m); var_dump($m); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(5) { [0]=> string(8) " 中国" @@ -29,6 +32,8 @@ array(5) { ["word"]=> string(6) "中国" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(5) { [0]=> string(3) "国" @@ -41,6 +46,8 @@ array(5) { ["word"]=> string(3) "国" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(3) { [0]=> string(8) " 中国" diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt index 9ce201725219..057460ff01e4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt index 8fec03b486af..b9bebcf8d71f 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt index 0e589a8665bb..167eb6986c87 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="\\'test"; echo mb_ereg_replace("\\\\'","'",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 'test diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt index a9a4fc953281..70d29c8d1805 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="This is a nice and simple string"; echo mb_ereg_replace("^This","That",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d That is a nice and simple string diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt index 4e15d8bfb8eb..0eaa22615b10 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt @@ -13,5 +13,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $b=mb_ereg_replace("abcd","",$a); echo "strlen(\$b)=".strlen($b); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d strlen($b)=0 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt index 396c8e870a26..6c169388387f 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/008.phpt) */ echo mb_ereg_replace("([a-z]*)([-=+|]*)([0-9]+)","\\3 \\1 \\2\n","abc+-|=123"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123 abc +-|= diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt index f0cd2edfe273..bc5ff9a6ca30 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc122222222223"; echo mb_ereg_replace("1(2*)3","\\1def\\1",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc2222222222def2222222222 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt index 8e23aba9cff9..8368e21a2a88 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def\\0ghi",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef123ghi diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt index cb8fce9135d8..efa1eb0e9dc4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123",'def\1ghi',$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef\1ghi diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt index 96c762bc4d5f..d280e93574cb 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def\\g\\\\hi\\",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef\g\\hi\ diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt index a88f358b4b55..8f4b4fe5b295 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="a\\2bxc"; echo mb_ereg_replace("a(.*)b(.*)c","\\1",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d \2 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt index 0f371053e508..1dbc9a0416de 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/015.phpt) */ echo mb_ereg_replace("^","z","abc123"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d zabc123 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt index a271eeff405c..4e6eaf017bc4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/016.phpt) */ echo mb_ereg_replace('\?',"abc","?123?"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc123abc diff --git a/ext/mbstring/tests/mb_ereg_replace.phpt b/ext/mbstring/tests/mb_ereg_replace.phpt index 455b13e23ce5..1221b6b366b0 100644 --- a/ext/mbstring/tests/mb_ereg_replace.phpt +++ b/ext/mbstring/tests/mb_ereg_replace.phpt @@ -12,6 +12,11 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab print mb_ereg_replace( ' ', '-', 'a b c d e' )."\n"; print mb_ereg_replace( '([a-z]+)','[\\1]', 'abc def ghi' ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d a-b-c-d-e + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d [abc] [def] [ghi] diff --git a/ext/mbstring/tests/mb_ereg_replace_basic.phpt b/ext/mbstring/tests/mb_ereg_replace_basic.phpt index a3f18952d375..7faac7371abd 100644 --- a/ext/mbstring/tests/mb_ereg_replace_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_basic.phpt @@ -41,18 +41,28 @@ var_dump(bin2hex($result_4)); echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg_replace() : basic functionality *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + -- ASCII string 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(16) "6162632020313233" -- ASCII string 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(14) "61626320646566" -- Multibyte string 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(72) "e697a5e69cace8aa9e5f5f5f5f5f31323334efbc95efbc96efbc97efbc98efbc99e38082" -- Multibyte string 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(106) "e697a5e69cace8aa9ee38386e382ade382b9e38388e381a7e38199e380823031323334efbc95efbc96efbc97efbc98efbc99e38082" Done diff --git a/ext/mbstring/tests/mb_ereg_replace_callback.phpt b/ext/mbstring/tests/mb_ereg_replace_callback.phpt index 40120c03eab2..d4541d09cafa 100644 --- a/ext/mbstring/tests/mb_ereg_replace_callback.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_callback.phpt @@ -18,6 +18,9 @@ echo mb_ereg_replace_callback('(?\w+) (?\d+).*', function ($m) { return sprintf("%s-%s", $m['digit'], $m['word']); }, $str), "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc(3) 123(3) #",;(4) $foo(4) + +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123-abc diff --git a/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt b/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt index 7e4d8e2e4940..8a58e95dffdf 100644 --- a/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt @@ -26,12 +26,29 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab // An unclosed backref is ignored echo mb_ereg_replace('(?\w+)', '-\k ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d _a_ _b_ _c_ _d_ _e_ + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123456789aa-a- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123456789aa-a- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d a_\k<01> + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\1- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\k<>- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\k ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg_replace() : usage variations *** -- Iteration 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 3 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 4 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 5 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 6 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 7 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 8 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 9 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 10 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(120) "string_valsstring_valtstring_valrstring_valistring_valnstring_valgstring_val_string_valvstring_valastring_vallstring_val" -- Iteration 11 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" Done diff --git a/ext/mbstring/tests/mb_ereg_search.phpt b/ext/mbstring/tests/mb_ereg_search.phpt index f167b9d7607d..25f581b7dd8d 100644 --- a/ext/mbstring/tests/mb_ereg_search.phpt +++ b/ext/mbstring/tests/mb_ereg_search.phpt @@ -32,9 +32,26 @@ function_exists('mb_ereg_search') or die("skip mb_ereg_search() is not available while($r); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(9) "中国abc" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(3) "abc" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "字符" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "china" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "string" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d diff --git a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt index 6979816fe8e0..33ad520e5fe6 100644 --- a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt +++ b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt @@ -14,8 +14,15 @@ var_dump(mb_ereg_search_getregs()); ?> --EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg_search(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt b/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt index 03161cf27cec..bcf73b6b3f40 100644 --- a/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt +++ b/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- --FILE-- =') or die("skip requires oniguruma >= 6.9.4"); +@version_compare(MB_ONIGURUMA_VERSION, '6.9.4', '>=') or die("skip requires oniguruma >= 6.9.4"); ?> --FILE-- =') or die("skip requires onigu mb_ereg_search('(?\s*)(?\w+)(?[?!])'); var_dump(mb_ereg_search_getregs()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(7) { [0]=> string(11) " 中国?" diff --git a/ext/mbstring/tests/mb_ereg_search_pos.phpt b/ext/mbstring/tests/mb_ereg_search_pos.phpt index 7f8f99f0c5d2..2c88cff01e04 100644 --- a/ext/mbstring/tests/mb_ereg_search_pos.phpt +++ b/ext/mbstring/tests/mb_ereg_search_pos.phpt @@ -22,7 +22,12 @@ else{ var_dump("false"); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(2) { [0]=> int(5) diff --git a/ext/mbstring/tests/mb_ereg_search_regs.phpt b/ext/mbstring/tests/mb_ereg_search_regs.phpt index eb883387e620..dd28df903729 100644 --- a/ext/mbstring/tests/mb_ereg_search_regs.phpt +++ b/ext/mbstring/tests/mb_ereg_search_regs.phpt @@ -22,7 +22,10 @@ function_exists('mb_ereg_search_regs') or die("skip mb_ereg_search_regs() not av ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(4) "ов" diff --git a/ext/mbstring/tests/mb_ereg_search_setpos.phpt b/ext/mbstring/tests/mb_ereg_search_setpos.phpt index 6a953447174d..6153d86282df 100644 --- a/ext/mbstring/tests/mb_ereg_search_setpos.phpt +++ b/ext/mbstring/tests/mb_ereg_search_setpos.phpt @@ -35,38 +35,77 @@ foreach($positions as $pos) { } } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + * Position: 5 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(5) * Position: 20 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 21 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 25 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 0 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) * Position: -5 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(15) * Position: -20 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) * Position: -30 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) diff --git a/ext/mbstring/tests/mb_ereg_search_syntax.phpt b/ext/mbstring/tests/mb_ereg_search_syntax.phpt index 5e16a91c3695..f6b427a3c7e6 100644 --- a/ext/mbstring/tests/mb_ereg_search_syntax.phpt +++ b/ext/mbstring/tests/mb_ereg_search_syntax.phpt @@ -13,5 +13,8 @@ mb_ereg_search_init("a"); var_dump(mb_ereg_search("a\\{1,2\\}", "b")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/mb_ereg_search_xxx.phpt b/ext/mbstring/tests/mb_ereg_search_xxx.phpt index 238dcc0e87a5..33d21052ecd3 100644 --- a/ext/mbstring/tests/mb_ereg_search_xxx.phpt +++ b/ext/mbstring/tests/mb_ereg_search_xxx.phpt @@ -35,48 +35,409 @@ output_handler= do_tests( $enc, 'x' ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (7) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d diff --git a/ext/mbstring/tests/mb_ereg_variation3.phpt b/ext/mbstring/tests/mb_ereg_variation3.phpt index 329c5597d440..5735e8248ef2 100644 --- a/ext/mbstring/tests/mb_ereg_variation3.phpt +++ b/ext/mbstring/tests/mb_ereg_variation3.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- =') or die("skip requires oniguruma >= 6.1.0"); +@version_compare(MB_ONIGURUMA_VERSION, '6.1.0', '>=') or die("skip requires oniguruma >= 6.1.0"); ?> --FILE-- ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : variation *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + -- Iteration 1 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -77,6 +81,8 @@ array(1) { } -- Iteration 2 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -84,6 +90,8 @@ array(1) { } -- Iteration 3 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -91,6 +99,8 @@ array(1) { } -- Iteration 4 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -98,6 +108,8 @@ array(1) { } -- Iteration 5 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -105,6 +117,8 @@ array(1) { } -- Iteration 6 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -112,6 +126,8 @@ array(1) { } -- Iteration 7 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -119,6 +135,8 @@ array(1) { } -- Iteration 8 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -126,6 +144,8 @@ array(1) { } -- Iteration 9 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -133,6 +153,8 @@ array(1) { } -- Iteration 10 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -140,6 +162,8 @@ array(1) { } -- Iteration 11 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -147,6 +171,8 @@ array(1) { } -- Iteration 12 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation4.phpt b/ext/mbstring/tests/mb_ereg_variation4.phpt index 05b96a9bf40f..559c5fd467cd 100644 --- a/ext/mbstring/tests/mb_ereg_variation4.phpt +++ b/ext/mbstring/tests/mb_ereg_variation4.phpt @@ -69,10 +69,14 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + -- Iteration 1 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -80,6 +84,8 @@ array(1) { } -- Iteration 2 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -87,6 +93,8 @@ array(1) { } -- Iteration 3 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -94,12 +102,18 @@ array(1) { } -- Iteration 4 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 5 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 6 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -107,6 +121,8 @@ array(1) { } -- Iteration 7 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -114,9 +130,13 @@ array(1) { } -- Iteration 8 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 9 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -124,6 +144,8 @@ array(1) { } -- Iteration 10 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -131,12 +153,18 @@ array(1) { } -- Iteration 11 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 12 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 13 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation5.phpt b/ext/mbstring/tests/mb_ereg_variation5.phpt index 569162534dcd..37cb325bf84b 100644 --- a/ext/mbstring/tests/mb_ereg_variation5.phpt +++ b/ext/mbstring/tests/mb_ereg_variation5.phpt @@ -57,19 +57,29 @@ function base64_encode_var_dump($regs) { } } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** -ASCII String without $regs arg: bool(true) +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +ASCII String without $regs arg: +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +bool(true) ASCII String with $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(52) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4gMDEyMzQ1Njc4OS4=" } -Multibyte String without $regs arg: bool(true) +Multibyte String without $regs arg: +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +bool(true) Multubyte String with $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation6.phpt b/ext/mbstring/tests/mb_ereg_variation6.phpt index cea3fcf661b2..33df1eaf051a 100644 --- a/ext/mbstring/tests/mb_ereg_variation6.phpt +++ b/ext/mbstring/tests/mb_ereg_variation6.phpt @@ -73,18 +73,24 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 --** Pattern is: \w+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(8) "VGhpcw==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -93,12 +99,16 @@ array(1) { --** Pattern is: \W+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(4) "IA==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -107,23 +117,31 @@ array(1) { --** Pattern is: \s+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(4) "IA==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) NULL --** Pattern is: \S+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(8) "VGhpcw==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -132,12 +150,16 @@ array(1) { --** Pattern is: \d+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(16) "MDEyMzQ1Njc4OQ==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -146,12 +168,16 @@ array(1) { --** Pattern is: \D+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(36) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4g" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -160,12 +186,16 @@ array(1) { --** Pattern is: \b **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> bool(false) } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -174,12 +204,16 @@ array(1) { --** Pattern is: \B **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> bool(false) } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation7.phpt b/ext/mbstring/tests/mb_ereg_variation7.phpt index 832bbbfb6f3b..8e6ad836668a 100644 --- a/ext/mbstring/tests/mb_ereg_variation7.phpt +++ b/ext/mbstring/tests/mb_ereg_variation7.phpt @@ -58,9 +58,13 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(5) { [0]=> @@ -74,6 +78,8 @@ array(5) { [4]=> string(4) "ODk=" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(5) { [0]=> diff --git a/ext/mbstring/tests/mb_eregi.phpt b/ext/mbstring/tests/mb_eregi.phpt index 2cdef03a6cb4..1660f154fbf1 100644 --- a/ext/mbstring/tests/mb_eregi.phpt +++ b/ext/mbstring/tests/mb_eregi.phpt @@ -15,7 +15,14 @@ var_dump(mb_eregi('z', 'XYZ')); var_dump(mb_eregi('xyzp', 'XYZ')); var_dump(mb_eregi('ö', 'Öäü')); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/mb_eregi_replace.phpt b/ext/mbstring/tests/mb_eregi_replace.phpt index b03874701f95..89963c922761 100644 --- a/ext/mbstring/tests/mb_eregi_replace.phpt +++ b/ext/mbstring/tests/mb_eregi_replace.phpt @@ -33,7 +33,140 @@ function do_translit($st) { mb_regex_encoding('ISO-8859-1'); echo do_translit("Пеар"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Pear --CREDITS-- Testfest Wuerzburg 2009-06-20 (modified by rui 2011-10-15) diff --git a/ext/mbstring/tests/mb_regex_encoding_basic.phpt b/ext/mbstring/tests/mb_regex_encoding_basic.phpt index 8492369aceff..745cb0cf021b 100644 --- a/ext/mbstring/tests/mb_regex_encoding_basic.phpt +++ b/ext/mbstring/tests/mb_regex_encoding_basic.phpt @@ -25,7 +25,13 @@ echo "Done"; ?> --EXPECTF-- *** Testing mb_regex_encoding() : basic functionality *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(%d) "%s" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" Done diff --git a/ext/mbstring/tests/mb_regex_encoding_error2.phpt b/ext/mbstring/tests/mb_regex_encoding_error2.phpt index 6874f5379a6a..ee665e5aa8bd 100644 --- a/ext/mbstring/tests/mb_regex_encoding_error2.phpt +++ b/ext/mbstring/tests/mb_regex_encoding_error2.phpt @@ -21,6 +21,8 @@ try { } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_regex_encoding() : error conditions *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line 9 mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "unknown" given diff --git a/ext/mbstring/tests/mb_regex_encoding_variation2.phpt b/ext/mbstring/tests/mb_regex_encoding_variation2.phpt index 5d46b3ad7936..55d139eb3ad7 100644 --- a/ext/mbstring/tests/mb_regex_encoding_variation2.phpt +++ b/ext/mbstring/tests/mb_regex_encoding_variation2.phpt @@ -87,286 +87,622 @@ foreach($encoding as $enc) { } echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_regex_encoding() : usage variations *** -- Iteration 1 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 2 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-4BE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 3 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 4 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 5 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2BE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 6 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2LE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 7 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 8 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 9 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 10 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" -- Iteration 11 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" -- Iteration 12 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 13 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UTF-7" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 14 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UTF7-IMAP" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 15 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" -- Iteration 16 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "ASCII" -- Iteration 17 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "ASCII" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" -- Iteration 18 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 19 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" -- Iteration 20 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 21 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "ISO-2022-JP" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 22 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "JIS" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 23 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-1" -- Iteration 24 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-1" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-2" -- Iteration 25 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-2" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-3" -- Iteration 26 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-3" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-4" -- Iteration 27 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-5" -- Iteration 28 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-5" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-6" -- Iteration 29 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-6" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-7" -- Iteration 30 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-7" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-8" -- Iteration 31 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-9" -- Iteration 32 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-9" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-10" -- Iteration 33 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-10" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-13" -- Iteration 34 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-13" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-14" -- Iteration 35 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-14" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 36 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte2be" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 37 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte2le" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 38 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte4be" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 39 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte4le" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 40 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "BASE64" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 41 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "HTML-ENTITIES" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 42 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "7bit" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 43 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "8bit" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 44 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 45 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP936" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 46 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "HZ" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 47 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" -- Iteration 48 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP950" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" -- Iteration 49 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "BIG5" -- Iteration 50 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "BIG5" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 51 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UHC" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 52 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "ISO-2022-KR" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 53 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "Windows-1251" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 54 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "Windows-1252" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 55 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP866" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 56 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "KOI8R" Done diff --git a/ext/mbstring/tests/mb_regex_set_options.phpt b/ext/mbstring/tests/mb_regex_set_options.phpt index a5fb611cacf3..f6994049f502 100644 --- a/ext/mbstring/tests/mb_regex_set_options.phpt +++ b/ext/mbstring/tests/mb_regex_set_options.phpt @@ -14,5 +14,12 @@ function_exists('mb_regex_set_options') or die("skip\n"); mb_regex_set_options( '' ); print mb_ereg_replace(' -', '+', '- - - - -' ); ?> ---EXPECT-- -+ + + + +-++++ +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ++ + + + + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +-++++ diff --git a/ext/mbstring/tests/mb_split-compat-01.phpt b/ext/mbstring/tests/mb_split-compat-01.phpt index 69d398cb0de3..8c5dcc0b4f10 100644 --- a/ext/mbstring/tests/mb_split-compat-01.phpt +++ b/ext/mbstring/tests/mb_split-compat-01.phpt @@ -16,7 +16,8 @@ test"); echo $a[$i] . "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 4 this is diff --git a/ext/mbstring/tests/mb_split.phpt b/ext/mbstring/tests/mb_split.phpt index 208848ee2bf5..8b8df7411a81 100644 --- a/ext/mbstring/tests/mb_split.phpt +++ b/ext/mbstring/tests/mb_split.phpt @@ -33,13 +33,36 @@ function_exists('mb_split') or die("skip mb_split() is not available in this bui verify_split( "\xa1\xa1+", "\xa1\xa1\xa1\xa2\xa2\xa1\xa1\xa1\xa1\xa1\xa1\xa2\xa2\xa1\xa1\xa1", $i ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 2-2 + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 3-3 + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 4-4 diff --git a/ext/mbstring/tests/mb_split_empty_match.phpt b/ext/mbstring/tests/mb_split_empty_match.phpt index 56ee59c31c6d..14604adfa98b 100644 --- a/ext/mbstring/tests/mb_split_empty_match.phpt +++ b/ext/mbstring/tests/mb_split_empty_match.phpt @@ -11,7 +11,10 @@ function_exists('mb_split') or die("skip mb_split() is not available in this bui mb_regex_set_options('m'); var_dump(mb_split('^', "a\nb\nc")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(3) { [0]=> string(2) "a diff --git a/ext/mbstring/tests/mbregex_stack_limit.phpt b/ext/mbstring/tests/mbregex_stack_limit.phpt index a291c280b18d..5b1ac5b2f080 100644 --- a/ext/mbstring/tests/mbregex_stack_limit.phpt +++ b/ext/mbstring/tests/mbregex_stack_limit.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- @@ -24,8 +24,13 @@ var_dump(mb_ereg('\\s+$', $s)); echo 'OK'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) OK diff --git a/ext/mbstring/tests/mbregex_stack_limit2.phpt b/ext/mbstring/tests/mbregex_stack_limit2.phpt index 9c2efcc39ec2..e7860654f3c0 100644 --- a/ext/mbstring/tests/mbregex_stack_limit2.phpt +++ b/ext/mbstring/tests/mbregex_stack_limit2.phpt @@ -6,7 +6,7 @@ iconv --SKIPIF-- @@ -28,6 +28,10 @@ var_dump(mb_trim_regex(str_repeat(' ', 10000))); echo 'OK'; ?> --EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg_replace(): mbregex search failure in php_mbereg_replace_exec(): match-stack limit over in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(0) "" OK diff --git a/ext/mbstring/tests/php_gr_jp_10830.phpt b/ext/mbstring/tests/php_gr_jp_10830.phpt index 02b46c01d3db..4b7517fd6e0f 100644 --- a/ext/mbstring/tests/php_gr_jp_10830.phpt +++ b/ext/mbstring/tests/php_gr_jp_10830.phpt @@ -13,6 +13,7 @@ $a="aaa\n<>"; var_dump( mb_ereg("^[^><]+$",$a) ); var_dump( !!preg_match("/^[^><]+$/",$a) ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) bool(false) diff --git a/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt b/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt index b9d82bf9af9f..4bf317499527 100644 --- a/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt +++ b/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt @@ -12,6 +12,8 @@ set_time_limit(2); var_dump(preg_replace("/.*/", "b", "a")); var_dump(mb_ereg_replace(".*", "b", "a")); ?> ---EXPECT-- +--EXPECTF-- string(2) "bb" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "bb" diff --git a/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt b/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt index 51086285ed61..405a9f6bf96f 100644 --- a/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt +++ b/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt @@ -13,8 +13,11 @@ var_dump(preg_replace("/C?$/", "Z", "ABC")); var_dump(mb_ereg_replace("C*$", "Z", "ABC")); var_dump(preg_replace("/C*$/", "Z", "ABC")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "ABZZ" string(4) "ABZZ" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "ABZZ" string(4) "ABZZ" diff --git a/ext/mbstring/tests/retry_limit.phpt b/ext/mbstring/tests/retry_limit.phpt index bcb1a1def5c0..1ada020e68c6 100644 --- a/ext/mbstring/tests/retry_limit.phpt +++ b/ext/mbstring/tests/retry_limit.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- = 6.9.3'); } ?> @@ -19,6 +19,9 @@ ini_set('mbstring.regex_retry_limit', '100000'); var_dump(mb_ereg($regex, $str)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index caefd9432d14..b45e7416c773 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -325,7 +323,7 @@ static int mysqli_object_has_property(zend_object *object, zend_string *name, in } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } else { has_property = zend_std_has_property(object, name, has_set_exists, cache_slot); @@ -360,12 +358,11 @@ HashTable *mysqli_object_get_debug_info(zend_object *object, int *is_temp) PHP_MYSQLI_EXPORT(zend_object *) mysqli_objects_new(zend_class_entry *class_type) { mysqli_object *intern; - zend_class_entry *mysqli_base_class; zend_object_handlers *handlers; intern = zend_object_alloc(sizeof(mysqli_object), class_type); - mysqli_base_class = class_type; + const zend_class_entry *mysqli_base_class = class_type; while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && mysqli_base_class->parent != NULL) { mysqli_base_class = mysqli_base_class->parent; @@ -482,7 +479,7 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_INI_ENTRIES(); memcpy(&mysqli_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - mysqli_object_handlers.offset = XtOffsetOf(mysqli_object, zo); + mysqli_object_handlers.offset = offsetof(mysqli_object, zo); mysqli_object_handlers.free_obj = mysqli_objects_free_storage; mysqli_object_handlers.clone_obj = NULL; mysqli_object_handlers.read_property = mysqli_read_property; diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 7ca2a20ca1b7..cc6b8c57404a 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -906,6 +906,11 @@ public function real_connect( */ public function real_escape_string(string $string): string {} + /** + * @alias mysqli_quote_string + */ + public function quote_string(string $string): string {} + /** * @tentative-return-type * @alias mysqli_reap_async_query @@ -1547,6 +1552,8 @@ function mysqli_real_escape_string(mysqli $mysql, string $string): string {} /** @alias mysqli_real_escape_string */ function mysqli_escape_string(mysqli $mysql, string $string): string {} +function mysqli_quote_string(mysqli $mysql, string $string): string {} + function mysqli_real_query(mysqli $mysql, string $query): bool {} /** @refcount 1 */ diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 9473f4a06c13..526fd10b2623 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -532,6 +530,10 @@ PHP_FUNCTION(mysqli_execute_query) MYSQLND_PARAM_BIND *params; if (!zend_array_is_list(input_params)) { + if (stmt->query) { + efree(stmt->query); + stmt->query = NULL; + } mysqli_stmt_close(stmt->stmt, false); stmt->stmt = NULL; efree(stmt); @@ -542,6 +544,10 @@ PHP_FUNCTION(mysqli_execute_query) hash_num_elements = zend_hash_num_elements(input_params); param_count = mysql_stmt_param_count(stmt->stmt); if (hash_num_elements != param_count) { + if (stmt->query) { + efree(stmt->query); + stmt->query = NULL; + } mysqli_stmt_close(stmt->stmt, false); stmt->stmt = NULL; efree(stmt); @@ -1198,7 +1204,7 @@ PHP_FUNCTION(mysqli_options) zend_argument_value_error(ERROR_ARG_POS(2), "must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants"); RETURN_THROWS(); } - + if (expected_type != Z_TYPE_P(mysql_value)) { switch (expected_type) { case IS_STRING: @@ -1363,6 +1369,29 @@ PHP_FUNCTION(mysqli_real_escape_string) { RETURN_NEW_STR(newstr); } +PHP_FUNCTION(mysqli_quote_string) { + MY_MYSQL *mysql; + zval *mysql_link = NULL; + char *escapestr; + size_t escapestr_len; + zend_string *newstr; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) { + RETURN_THROWS(); + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); + + newstr = zend_string_safe_alloc(2, escapestr_len, 2, 0); + char *out = ZSTR_VAL(newstr); + *out++ = '\''; + out += mysql_real_escape_string(mysql->mysql, out, escapestr, escapestr_len); + *out++ = '\''; + *out = '\0'; + newstr = zend_string_truncate(newstr, out - ZSTR_VAL(newstr), 0); + + RETURN_NEW_STR(newstr); +} + /* {{{ Undo actions from current transaction */ PHP_FUNCTION(mysqli_rollback) { @@ -1467,6 +1496,15 @@ PHP_FUNCTION(mysqli_stmt_data_seek) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); + if (!stmt->stmt->data || !stmt->stmt->data->result || !stmt->stmt->data->result->stored_data) { + if (hasThis()) { + zend_throw_error(NULL, "mysqli_stmt::data_seek(): No result set associated with the statement"); + } else { + zend_throw_error(NULL, "mysqli_stmt_data_seek(): No result set associated with the statement"); + } + RETURN_THROWS(); + } + mysql_stmt_data_seek(stmt->stmt, offset); } /* }}} */ diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4439908e55dc..0121f36f3cfd 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit mysqli.stub.php instead. - * Stub hash: c0af8c627a063fbd2c8b76c63b5e70c8ddd1e4f9 */ + * Stub hash: dc804bc50cd0a0e14dafc0e03564d5699d641db0 */ 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) @@ -252,6 +252,8 @@ ZEND_END_ARG_INFO() #define arginfo_mysqli_escape_string arginfo_mysqli_real_escape_string +#define arginfo_mysqli_quote_string arginfo_mysqli_real_escape_string + #define arginfo_mysqli_real_query arginfo_mysqli_multi_query ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_reap_async_query, 0, 1, mysqli_result, MAY_BE_BOOL) @@ -527,6 +529,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_real_esca ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_quote_string, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_mysqli_reap_async_query, 0, 0, mysqli_result, MAY_BE_BOOL) ZEND_END_ARG_INFO() @@ -767,6 +773,7 @@ ZEND_FUNCTION(mysqli_report); ZEND_FUNCTION(mysqli_query); ZEND_FUNCTION(mysqli_real_connect); ZEND_FUNCTION(mysqli_real_escape_string); +ZEND_FUNCTION(mysqli_quote_string); ZEND_FUNCTION(mysqli_real_query); ZEND_FUNCTION(mysqli_reap_async_query); ZEND_FUNCTION(mysqli_release_savepoint); @@ -883,6 +890,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mysqli_real_connect, arginfo_mysqli_real_connect) ZEND_FE(mysqli_real_escape_string, arginfo_mysqli_real_escape_string) ZEND_RAW_FENTRY("mysqli_escape_string", zif_mysqli_real_escape_string, arginfo_mysqli_escape_string, 0, NULL, NULL) + ZEND_FE(mysqli_quote_string, arginfo_mysqli_quote_string) ZEND_FE(mysqli_real_query, arginfo_mysqli_real_query) ZEND_FE(mysqli_reap_async_query, arginfo_mysqli_reap_async_query) ZEND_FE(mysqli_release_savepoint, arginfo_mysqli_release_savepoint) @@ -957,6 +965,7 @@ static const zend_function_entry class_mysqli_methods[] = { ZEND_RAW_FENTRY("query", zif_mysqli_query, arginfo_class_mysqli_query, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_connect", zif_mysqli_real_connect, arginfo_class_mysqli_real_connect, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_escape_string", zif_mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_RAW_FENTRY("quote_string", zif_mysqli_quote_string, arginfo_class_mysqli_quote_string, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("reap_async_query", zif_mysqli_reap_async_query, arginfo_class_mysqli_reap_async_query, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("escape_string", zif_mysqli_real_escape_string, arginfo_class_mysqli_escape_string, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_query", zif_mysqli_real_query, arginfo_class_mysqli_real_query, ZEND_ACC_PUBLIC, NULL, NULL) diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index d2c94d881b44..dadb132efc21 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index 7ebc29b60ba6..3f34b3e00501 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_mysqlnd.h b/ext/mysqli/mysqli_mysqlnd.h index 5fb8f542b8fc..b15644c8e1f6 100644 --- a/ext/mysqli/mysqli_mysqlnd.h +++ b/ext/mysqli/mysqli_mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 2e51dca3100f..1e46aeedd93b 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h index 5f7c49f0b297..97d9300a2b79 100644 --- a/ext/mysqli/mysqli_priv.h +++ b/ext/mysqli/mysqli_priv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 6d86a6ad4ca8..b54f6fd6ae44 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c index 06611310b0b0..28b5f151d729 100644 --- a/ext/mysqli/mysqli_report.c +++ b/ext/mysqli/mysqli_report.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c index 5dbeaf1e3b22..013f41d38d0b 100644 --- a/ext/mysqli/mysqli_result_iterator.c +++ b/ext/mysqli/mysqli_result_iterator.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index 0bb730ef6cf6..a276ccf0b1ff 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 7ee999b41e04..5f995a4bbc53 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index ceab4a44f395..8ccead1a7518 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -63,9 +61,7 @@ typedef struct _mysqli_object { zend_object zo; } mysqli_object; /* extends zend_object */ -static inline mysqli_object *php_mysqli_fetch_object(zend_object *obj) { - return (mysqli_object *)((char*)(obj) - XtOffsetOf(mysqli_object, zo)); -} +#define php_mysqli_fetch_object(obj) ZEND_CONTAINER_OF(obj, mysqli_object, zo) #define Z_MYSQLI_P(zv) php_mysqli_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt index bada1d85a5ce..ccac6710edd1 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt @@ -43,6 +43,7 @@ require_once 'skipifconnectfailure.inc'; 'ping' => true, 'prepare' => true, 'query' => true, + 'quote_string' => true, 'real_connect' => true, 'real_escape_string' => true, 'real_query' => true, diff --git a/ext/mysqli/tests/mysqli_execute_query_leak.phpt b/ext/mysqli/tests/mysqli_execute_query_leak.phpt new file mode 100644 index 000000000000..11f56877aece --- /dev/null +++ b/ext/mysqli/tests/mysqli_execute_query_leak.phpt @@ -0,0 +1,37 @@ +--TEST-- +mysqli_execute_query() does not leak stmt->query on input_params validation errors with MYSQLI_REPORT_INDEX +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +execute_query('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?', ['foo', 42]); +} catch (ValueError $e) { + echo '[001] '.$e->getMessage()."\n"; +} + +try { + $link->execute_query('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?', ['foo' => 42]); +} catch (ValueError $e) { + echo '[002] '.$e->getMessage()."\n"; +} + +print "done!"; +?> +--CLEAN-- + +--EXPECT-- +[001] mysqli::execute_query(): Argument #2 ($params) must consist of exactly 3 elements, 2 present +[002] mysqli::execute_query(): Argument #2 ($params) must be a list array +done! diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt index 70e18584326c..2a1a54d6b65f 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt @@ -179,7 +179,7 @@ Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d [300 + 002] [1045] %s -Warning: mysqli::real_connect(%sest_sha256_wrong_%d): Failed to open stream: No such file or directory in %s on line %d +Warning: mysqli::real_connect(): Failed to open stream: No such file or directory in %s on line %d Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d [400 + 002] [1045] %s diff --git a/ext/mysqli/tests/mysqli_quote_string.phpt b/ext/mysqli/tests/mysqli_quote_string.phpt new file mode 100644 index 000000000000..b4a25aa3996f --- /dev/null +++ b/ext/mysqli/tests/mysqli_quote_string.phpt @@ -0,0 +1,86 @@ +--TEST-- +mysqli_quote_string() +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = mysqli_quote_string($link, '" OR 1=1 -- foo'); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = mysqli_quote_string($link, "\n"); +if ($escaped !== "'\\n'") { + printf("[001] Expected '\\n', got %s\n", $escaped); +} + +$escaped = mysqli_quote_string($link, "\r"); +if ($escaped !== "'\\r'") { + printf("[002] Expected '\\r', got %s\n", $escaped); +} + +$escaped = mysqli_quote_string($link, "foo" . chr(0) . "bar"); +if ($escaped !== "'foo\\0bar'") { + printf("[003] Expected 'foo\\0bar', got %s\n", $escaped); +} + +echo "=====================\n"; + +// Test that the SQL injection is impossible with NO_BACKSLASH_ESCAPES mode +$link->query('SET @@sql_mode="NO_BACKSLASH_ESCAPES"'); + +echo $link->quote_string('\\') . "\n"; +echo $link->quote_string('"') . "\n"; +echo $link->quote_string("'") . "\n"; + +$escaped = $link->quote_string("\' \ \""); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = $link->quote_string('" OR 1=1 -- foo'); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +echo "done!"; +?> +--EXPECT-- +'\\' +'\"' +'\'' +'\\\' \\ \"' +\' \ " +'\" OR 1=1 -- foo' +" OR 1=1 -- foo +===================== +'\' +'"' +'''' +'\'' \ "' +\' \ " +'" OR 1=1 -- foo' +" OR 1=1 -- foo +done! diff --git a/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt b/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt new file mode 100644 index 000000000000..7f7731807428 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt @@ -0,0 +1,26 @@ +--TEST-- +mysqli_real_connect() retry on same handle does not corrupt mysqlnd connect_attr +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- + +--EXPECT-- +done! diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index a36daebc7951..e4b913229cd0 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -25,6 +25,11 @@ require_once 'skipifconnectfailure.inc'; if (true !== ($tmp = mysqli_stmt_execute($stmt))) printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_data_seek($stmt, 1); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $id = null; if (!mysqli_stmt_bind_result($stmt, $id)) @@ -82,6 +87,7 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- mysqli_stmt object is not fully initialized +mysqli_stmt_data_seek(): No result set associated with the statement int(3) int(1) int(1) diff --git a/ext/mysqlnd/mysql_float_to_double.h b/ext/mysqlnd/mysql_float_to_double.h index a15458b52de2..f92196e792c9 100644 --- a/ext/mysqlnd/mysql_float_to_double.h +++ b/ext/mysqlnd/mysql_float_to_double.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Keyur Govande | +----------------------------------------------------------------------+ diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 3336d1752afd..032438063bea 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c index 06971b3487dd..187298ca9969 100644 --- a/ext/mysqlnd/mysqlnd_alloc.c +++ b/ext/mysqlnd/mysqlnd_alloc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -201,7 +199,7 @@ static void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -232,7 +230,7 @@ static void _mysqlnd_pefree(void *ptr, bool persistent MYSQLND_MEM_D) #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -264,7 +262,7 @@ static char * _mysqlnd_pememdup(const char * const ptr, size_t length, bool pers #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -295,7 +293,7 @@ static char * _mysqlnd_pestrndup(const char * const ptr, size_t length, bool per #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -336,7 +334,7 @@ static char * _mysqlnd_pestrdup(const char * const ptr, bool persistent MYSQLND_ TRACE_ALLOC_ENTER(mysqlnd_pestrdup_name); #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif diff --git a/ext/mysqlnd/mysqlnd_alloc.h b/ext/mysqlnd/mysqlnd_alloc.h index deaef3748965..203d7207740a 100644 --- a/ext/mysqlnd/mysqlnd_alloc.h +++ b/ext/mysqlnd/mysqlnd_alloc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index 07c393830905..3504caa2dea1 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -587,7 +585,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin = "auth_plugin_mysql_native_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ @@ -640,7 +638,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin "auth_plugin_mysql_clear_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ @@ -936,7 +934,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plu "auth_plugin_sha256_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel ", { NULL, /* no statistics , will be filled later if there are some */ @@ -1297,7 +1295,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_caching_sha2_auth_plugin "auth_plugin_caching_sha2_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Johannes Schlüter ", { NULL, /* no statistics , will be filled later if there are some */ diff --git a/ext/mysqlnd/mysqlnd_auth.h b/ext/mysqlnd/mysqlnd_auth.h index 9ce14a2fc521..f4a0f3146094 100644 --- a/ext/mysqlnd/mysqlnd_auth.h +++ b/ext/mysqlnd/mysqlnd_auth.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_block_alloc.c b/ext/mysqlnd/mysqlnd_block_alloc.c index dafcbcc8bbb8..db836d3f7b92 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.c +++ b/ext/mysqlnd/mysqlnd_block_alloc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_block_alloc.h b/ext/mysqlnd/mysqlnd_block_alloc.h index 7c9aac3b8e5f..31f315235d72 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.h +++ b/ext/mysqlnd/mysqlnd_block_alloc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index a767bab392e5..eacf74240fd1 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -969,40 +967,6 @@ PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset /* }}} */ -static struct st_mysqlnd_plugin_charsets mysqlnd_plugin_charsets_plugin = -{ - { - MYSQLND_PLUGIN_API_VERSION, - "charsets", - MYSQLND_VERSION_ID, - PHP_MYSQLND_VERSION, - "PHP License 3.01", - "Andrey Hristov , Ulf Wendel , Georg Richter ", - { - NULL, /* no statistics , will be filled later if there are some */ - NULL, /* no statistics */ - }, - { - NULL /* plugin shutdown */ - } - }, - {/* methods */ - mysqlnd_find_charset_nr, - mysqlnd_find_charset_name, - mysqlnd_cset_escape_quotes, - mysqlnd_cset_escape_slashes - } -}; - - -/* {{{ mysqlnd_charsets_plugin_register */ -void -mysqlnd_charsets_plugin_register(void) -{ - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_charsets_plugin); -} -/* }}} */ - #if MYSQLND_CHARSETS_SANITY_CHECK void mysqlnd_charsets_sanity_check(void) { diff --git a/ext/mysqlnd/mysqlnd_charset.h b/ext/mysqlnd/mysqlnd_charset.h index a2b1e2f14831..d5e621e38eb1 100644 --- a/ext/mysqlnd/mysqlnd_charset.h +++ b/ext/mysqlnd/mysqlnd_charset.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -28,18 +26,4 @@ PHPAPI zend_ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const chars PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); -struct st_mysqlnd_plugin_charsets -{ - const struct st_mysqlnd_plugin_header plugin_header; - struct - { - const MYSQLND_CHARSET * (*const find_charset_by_nr)(unsigned int charsetnr); - const MYSQLND_CHARSET * (*const find_charset_by_name)(const char * const name); - zend_ulong (*const escape_quotes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - zend_ulong (*const escape_slashes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - } methods; -}; - -void mysqlnd_charsets_plugin_register(void); - #endif /* MYSQLND_CHARSET_H */ diff --git a/ext/mysqlnd/mysqlnd_commands.c b/ext/mysqlnd/mysqlnd_commands.c index a3aad43bbd4b..1bb38be089e6 100644 --- a/ext/mysqlnd/mysqlnd_commands.c +++ b/ext/mysqlnd/mysqlnd_commands.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_commands.h b/ext/mysqlnd/mysqlnd_commands.h index 4203b56ffc15..610de56325ae 100644 --- a/ext/mysqlnd/mysqlnd_commands.h +++ b/ext/mysqlnd/mysqlnd_commands.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 4a9732a02895..517b149c0b4d 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -552,7 +550,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ /* IPv6 without square brackets so without port */ transport.l = mnd_sprintf(&transport.s, 0, "tcp://[%s]:%u", hostname.s, port); } else { - char *p; + const char *p; /* IPv6 addresses are in the format [address]:port */ if (hostname.s[0] == '[') { /* IPv6 */ @@ -1559,17 +1557,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons zval attrz; zend_string *str; + str = zend_string_init(key, strlen(key), conn->persistent); + ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), conn->persistent)); if (conn->persistent) { - str = zend_string_init(key, strlen(key), 1); GC_MAKE_PERSISTENT_LOCAL(str); - ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 1)); GC_MAKE_PERSISTENT_LOCAL(Z_COUNTED(attrz)); - } else { - str = zend_string_init(key, strlen(key), 0); - ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 0)); } zend_hash_update(conn->options->connect_attr, str, &attrz); - zend_string_release_ex(str, 1); + zend_string_release_ex(str, conn->persistent); } break; default: diff --git a/ext/mysqlnd/mysqlnd_connection.h b/ext/mysqlnd/mysqlnd_connection.h index 39d7712b132c..ef71fbd4250c 100644 --- a/ext/mysqlnd/mysqlnd_connection.h +++ b/ext/mysqlnd/mysqlnd_connection.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index ff80c620bee1..80765f36131c 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -742,7 +740,7 @@ static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = "debug_trace", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h index 24eb67ca1a74..3710551bffd4 100644 --- a/ext/mysqlnd/mysqlnd_debug.h +++ b/ext/mysqlnd/mysqlnd_debug.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index 2c1d997177aa..deef03b9a3c1 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -38,7 +36,7 @@ static struct st_mysqlnd_plugin_core mysqlnd_plugin_core = "mysqlnd", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* will be filled later */ diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 851174032c40..abb5def974c8 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.c b/ext/mysqlnd/mysqlnd_ext_plugin.c index 2ca01d113e3b..5ba377e53433 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.c +++ b/ext/mysqlnd/mysqlnd_ext_plugin.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.h b/ext/mysqlnd/mysqlnd_ext_plugin.h index 8780ff463045..84cf6c004be4 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.h +++ b/ext/mysqlnd/mysqlnd_ext_plugin.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h index 646b09d80f4c..0172b554caa0 100644 --- a/ext/mysqlnd/mysqlnd_libmysql_compat.h +++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c index a1e04de27008..caa5205a08e1 100644 --- a/ext/mysqlnd/mysqlnd_loaddata.c +++ b/ext/mysqlnd/mysqlnd_loaddata.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_plugin.c b/ext/mysqlnd/mysqlnd_plugin.c index 4bd9894b8c4b..4209676daf10 100644 --- a/ext/mysqlnd/mysqlnd_plugin.c +++ b/ext/mysqlnd/mysqlnd_plugin.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -47,7 +45,7 @@ static struct st_mysqlnd_typeii_plugin_example mysqlnd_example_plugin = "example", 10001L, "1.00.01", - "PHP License", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov ", { NULL, /* will be filled later */ diff --git a/ext/mysqlnd/mysqlnd_plugin.h b/ext/mysqlnd/mysqlnd_plugin.h index 82b2142fc9fc..04dfcb79cc40 100644 --- a/ext/mysqlnd/mysqlnd_plugin.h +++ b/ext/mysqlnd/mysqlnd_plugin.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 1dbd1093dcac..daad00f0d3e6 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c index 570fba24d663..70a81befdd71 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.h b/ext/mysqlnd/mysqlnd_protocol_frame_codec.h index 63aedddb12ea..1ed6f233365b 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.h +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 76a2eb640d1d..b9b112161570 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ps.h b/ext/mysqlnd/mysqlnd_ps.h index 107e7b6748b9..32af2d423e52 100644 --- a/ext/mysqlnd/mysqlnd_ps.h +++ b/ext/mysqlnd/mysqlnd_ps.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index c60e3d327a8d..934e3637d6aa 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_read_buffer.c b/ext/mysqlnd/mysqlnd_read_buffer.c index 90963c99fa81..e662733e0a36 100644 --- a/ext/mysqlnd/mysqlnd_read_buffer.c +++ b/ext/mysqlnd/mysqlnd_read_buffer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_read_buffer.h b/ext/mysqlnd/mysqlnd_read_buffer.h index 7014f4369690..b3d4c9638303 100644 --- a/ext/mysqlnd/mysqlnd_read_buffer.h +++ b/ext/mysqlnd/mysqlnd_read_buffer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index ae8dc77b4cd9..b4d0bdbd8d2c 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -722,9 +720,6 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c if (ret == FAIL) { COPY_CLIENT_ERROR(&set->error_info, row_packet.error_info); - } else { - /* libmysql's documentation says it should be so for SELECT statements */ - UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, set->row_count); } DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == PASS? "PASS":"FAIL", @@ -1004,18 +999,11 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int } } if (flags & MYSQLND_FETCH_ASSOC) { - /* zend_hash_quick_update needs length + trailing zero */ - /* QQ: Error handling ? */ - /* - zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether - the index is a numeric and convert it to it. This however means constant - hashing of the column name, which is not needed as it can be precomputed. - */ Z_TRY_ADDREF_P(data); - if (meta->fields[i].is_numeric == FALSE) { - zend_hash_update(row_ht, meta->fields[i].sname, data); + if (field->is_numeric == FALSE) { + zend_hash_update(row_ht, field->sname, data); } else { - zend_hash_index_update(row_ht, meta->fields[i].num_key, data); + zend_hash_index_update(row_ht, field->num_key, data); } } @@ -1038,10 +1026,9 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES * result) mysqlnd_result_free_prev_data(result); if (result->m.fetch_row(result, &row_data, 0, &fetched_anything) == PASS && fetched_anything) { unsigned field_count = result->field_count; - MYSQLND_FIELD *field = result->meta->fields; ret = mnd_emalloc(field_count * sizeof(char *)); - for (unsigned i = 0; i < field_count; i++, field++) { + for (unsigned i = 0; i < field_count; i++) { zval *data = &row_data[i]; if (Z_TYPE_P(data) != IS_NULL) { convert_to_string(data); diff --git a/ext/mysqlnd/mysqlnd_result.h b/ext/mysqlnd/mysqlnd_result.h index fe414f0cd65c..db90b4d963cc 100644 --- a/ext/mysqlnd/mysqlnd_result.h +++ b/ext/mysqlnd/mysqlnd_result.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index 92896ccb408e..6a772973c395 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result_meta.h b/ext/mysqlnd/mysqlnd_result_meta.h index e9726abae02a..d3c84776958a 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.h +++ b/ext/mysqlnd/mysqlnd_result_meta.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_reverse_api.c b/ext/mysqlnd/mysqlnd_reverse_api.c index 982aac065eb0..539c8adaaa60 100644 --- a/ext/mysqlnd/mysqlnd_reverse_api.c +++ b/ext/mysqlnd/mysqlnd_reverse_api.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_reverse_api.h b/ext/mysqlnd/mysqlnd_reverse_api.h index ee56666d5eaf..843fa728aacc 100644 --- a/ext/mysqlnd/mysqlnd_reverse_api.h +++ b/ext/mysqlnd/mysqlnd_reverse_api.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index 0d94303ea366..33a47843c9c8 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_statistics.h b/ext/mysqlnd/mysqlnd_statistics.h index 02cd64450cb6..a576f67ffdb1 100644 --- a/ext/mysqlnd/mysqlnd_statistics.h +++ b/ext/mysqlnd/mysqlnd_statistics.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 02c31358da48..80d0abfcae6f 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_vio.c b/ext/mysqlnd/mysqlnd_vio.c index 3a3f7b207214..b6ea490e67b6 100644 --- a/ext/mysqlnd/mysqlnd_vio.c +++ b/ext/mysqlnd/mysqlnd_vio.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_vio.h b/ext/mysqlnd/mysqlnd_vio.h index a96fdb182b17..28f033bd749d 100644 --- a/ext/mysqlnd/mysqlnd_vio.h +++ b/ext/mysqlnd/mysqlnd_vio.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 36fd53233737..b957240a4088 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -461,7 +459,7 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet) packet->auth_protocol = estrdup(""); } else { /* Check if NUL present */ - char *null_terminator = memchr(p, '\0', remaining_size); + const char *null_terminator = memchr(p, '\0', remaining_size); size_t auth_protocol_len; if (null_terminator) { /* If present, do basically estrdup */ diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index f24eb70f4a79..e5d38bc6737e 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index c21697828a9a..f8b2d72ebab9 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/php_mysqlnd.h b/ext/mysqlnd/php_mysqlnd.h index e7a981a5de3e..4da59ed965e8 100644 --- a/ext/mysqlnd/php_mysqlnd.h +++ b/ext/mysqlnd/php_mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/odbc/odbc_utils.c b/ext/odbc/odbc_utils.c index bc6674b9b5e5..8468fa9a06c1 100644 --- a/ext/odbc/odbc_utils.c +++ b/ext/odbc/odbc_utils.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Calvin Buckley | +----------------------------------------------------------------------+ @@ -59,7 +57,7 @@ PHP_FUNCTION(odbc_connection_string_quote) Z_PARAM_STR(str) ZEND_PARSE_PARAMETERS_END(); - size_t new_size = php_odbc_connstr_estimate_quote_length(ZSTR_VAL(str)); + size_t new_size = php_odbc_connstr_get_quoted_length(ZSTR_VAL(str)); zend_string *new_string = zend_string_alloc(new_size, 0); php_odbc_connstr_quote(ZSTR_VAL(new_string), ZSTR_VAL(str), new_size); /* reset length */ diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 7eec40aa656f..4d3081a3b076 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | @@ -62,7 +60,6 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent); static void safe_odbc_disconnect(void *handle); static void close_results_with_connection(odbc_connection *conn); -static inline odbc_result *odbc_result_from_obj(zend_object *obj); static int le_pconn; @@ -71,6 +68,7 @@ static zend_object_handlers odbc_connection_object_handlers, odbc_result_object_ #define Z_ODBC_LINK_P(zv) odbc_link_from_obj(Z_OBJ_P(zv)) #define Z_ODBC_CONNECTION_P(zv) Z_ODBC_LINK_P(zv)->connection +#define odbc_result_from_obj(obj) ZEND_CONTAINER_OF(obj, odbc_result, std) #define Z_ODBC_RESULT_P(zv) odbc_result_from_obj(Z_OBJ_P(zv)) static void odbc_insert_new_result(odbc_connection *connection, zval *result) @@ -87,10 +85,7 @@ static void odbc_insert_new_result(odbc_connection *connection, zval *result) Z_ADDREF_P(result); } -static inline odbc_link *odbc_link_from_obj(zend_object *obj) -{ - return (odbc_link *)((char *)(obj) - XtOffsetOf(odbc_link, std)); -} +#define odbc_link_from_obj(obj) ZEND_CONTAINER_OF(obj, odbc_link, std) static int _close_pconn_with_res(zval *zv, void *p) { @@ -204,11 +199,6 @@ static void odbc_connection_free_obj(zend_object *obj) zend_object_std_dtor(&link->std); } -static inline odbc_result *odbc_result_from_obj(zend_object *obj) -{ - return (odbc_result *)((char *)(obj) - XtOffsetOf(odbc_result, std)); -} - static zend_object *odbc_result_create_object(zend_class_entry *class_type) { odbc_result *intern = zend_object_alloc(sizeof(odbc_result), class_type); @@ -509,7 +499,7 @@ PHP_MINIT_FUNCTION(odbc) odbc_connection_ce->default_object_handlers = &odbc_connection_object_handlers; memcpy(&odbc_connection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - odbc_connection_object_handlers.offset = XtOffsetOf(odbc_link, std); + odbc_connection_object_handlers.offset = offsetof(odbc_link, std); odbc_connection_object_handlers.free_obj = odbc_connection_free_obj; odbc_connection_object_handlers.get_constructor = odbc_connection_get_constructor; odbc_connection_object_handlers.clone_obj = NULL; @@ -521,7 +511,7 @@ PHP_MINIT_FUNCTION(odbc) odbc_result_ce->default_object_handlers = &odbc_result_object_handlers; memcpy(&odbc_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - odbc_result_object_handlers.offset = XtOffsetOf(odbc_result, std); + odbc_result_object_handlers.offset = offsetof(odbc_result, std); odbc_result_object_handlers.free_obj = odbc_result_free_obj; odbc_result_object_handlers.get_constructor = odbc_result_get_constructor; odbc_result_object_handlers.clone_obj = NULL; @@ -637,9 +627,10 @@ void php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode) zval *pv_res; zend_long flag; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &flag) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_LONG(flag) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -670,6 +661,7 @@ void odbc_bindcols(odbc_result *result) for(i = 0; i < result->numcols; i++) { bool char_extra_alloc = false; + result->values[i].value_max_len = 0; colfieldid = SQL_COLUMN_DISPLAY_SIZE; rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_DESC_NAME, @@ -749,6 +741,7 @@ void odbc_bindcols(odbc_result *result) displaysize *= 4; } result->values[i].value = (char *)emalloc(displaysize + 1); + result->values[i].value_max_len = displaysize; rc = SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value, displaysize + 1, &result->values[i].vallen); break; @@ -763,9 +756,9 @@ void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type) RETCODE rc; zval *pv_conn; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_conn, odbc_connection_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -788,9 +781,10 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_LONG(pv_num) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -864,9 +858,10 @@ PHP_FUNCTION(odbc_prepare) int i; SQLUINTEGER scrollopts; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_STRING(query, query_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -977,9 +972,11 @@ PHP_FUNCTION(odbc_execute) int i; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|h", &pv_res, odbc_result_ce, &pv_param_ht) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT(pv_param_ht) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -1130,9 +1127,9 @@ PHP_FUNCTION(odbc_cursor) odbc_result *result; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -1185,9 +1182,10 @@ PHP_FUNCTION(odbc_data_source) UCHAR server_name[100], desc[200]; SQLSMALLINT len1=0, len2=0, fetch_type; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zv_conn, odbc_connection_ce, &zv_fetch_type) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(zv_conn, odbc_connection_ce) + Z_PARAM_LONG(zv_fetch_type) + ZEND_PARSE_PARAMETERS_END(); fetch_type = (SQLSMALLINT) zv_fetch_type; @@ -1243,9 +1241,10 @@ PHP_FUNCTION(odbc_exec) RETCODE rc; SQLUINTEGER scrollopts; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_STRING(query, query_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -1342,12 +1341,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_ result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); - /* TODO deprecate $row argument values less than 1 after PHP 8.4 - * for functions other than odbc_fetch_row (see GH-13910) - */ - if (!result_type && !pv_row_is_null && pv_row < 1) { - php_error_docref(NULL, E_WARNING, "Argument #3 ($row) must be greater than or equal to 1"); - RETURN_FALSE; + if (!pv_row_is_null && pv_row < 1) { + /* row arg no differs between callers */ + zend_argument_value_error(pv_res_arr == return_value ? 2 : 3, + "must be greater than or equal to 1"); + RETURN_THROWS(); } if (result->numcols == 0) { @@ -1462,7 +1460,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_ ZVAL_FALSE(&tmp); break; } - ZVAL_STRINGL(&tmp, result->values[i].value, result->values[i].vallen); + SQLLEN str_len = result->values[i].vallen; + if (str_len > result->values[i].value_max_len) { + str_len = result->values[i].value_max_len; + } + ZVAL_STRINGL(&tmp, result->values[i].value, str_len); break; } @@ -1667,7 +1669,6 @@ PHP_FUNCTION(odbc_result) } ZSTR_VAL(field_str)[ZSTR_LEN(field_str)] = '\0'; RETURN_NEW_STR(field_str); - break; default: if (result->values[field_ind].vallen == SQL_NULL_DATA) { @@ -1676,7 +1677,11 @@ PHP_FUNCTION(odbc_result) php_error_docref(NULL, E_WARNING, "Cannot get data of column #%d (driver cannot determine length)", field_ind + 1); RETURN_FALSE; } else { - RETURN_STRINGL(result->values[field_ind].value, result->values[field_ind].vallen); + SQLLEN str_len = result->values[field_ind].vallen; + if (str_len > result->values[field_ind].value_max_len) { + str_len = result->values[field_ind].value_max_len; + } + RETURN_STRINGL(result->values[field_ind].value, str_len); } break; } @@ -1734,9 +1739,11 @@ PHP_FUNCTION(odbc_result_all) size_t i, pv_format_len = 0; SQLSMALLINT sql_c_type; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s", &pv_res, odbc_result_ce, &pv_format, &pv_format_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(pv_format, pv_format_len) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -1862,9 +1869,9 @@ PHP_FUNCTION(odbc_free_result) zval *pv_res; odbc_result *result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -1945,9 +1952,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool /* Force UID and PWD to be set in the DSN */ if (use_uid_arg || use_pwd_arg) { - db_end--; - if ((unsigned char)*(db_end) == ';') { - *db_end = '\0'; + size_t base_len = db_len; + if (base_len > 0 && db[base_len - 1] == ';') { + base_len--; } char *uid_quoted = NULL, *pwd_quoted = NULL; @@ -1955,35 +1962,35 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(uid) && php_odbc_connstr_should_quote(uid); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(uid); - uid_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(uid_quoted, uid, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(uid); + uid_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(uid_quoted, uid, quoted_length); } else { uid_quoted = uid; } if (!use_pwd_arg) { - spprintf(&ldb, 0, "%s;UID=%s;", db, uid_quoted); + spprintf(&ldb, 0, "%.*s;UID=%s;", (int) base_len, db, uid_quoted); } } if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(pwd) && php_odbc_connstr_should_quote(pwd); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(pwd); - pwd_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(pwd_quoted, pwd, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(pwd); + pwd_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(pwd_quoted, pwd, quoted_length); } else { pwd_quoted = pwd; } if (!use_uid_arg) { - spprintf(&ldb, 0, "%s;PWD=%s;", db, pwd_quoted); + spprintf(&ldb, 0, "%.*s;PWD=%s;", (int) base_len, db, pwd_quoted); } } if (use_uid_arg && use_pwd_arg) { - spprintf(&ldb, 0, "%s;UID=%s;PWD=%s;", db, uid_quoted, pwd_quoted); + spprintf(&ldb, 0, "%.*s;UID=%s;PWD=%s;", (int) base_len, db, uid_quoted, pwd_quoted); } if (uid_quoted && should_quote_uid) { @@ -2031,8 +2038,8 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_STRING(db, db_len) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(uid, uid_len) - Z_PARAM_STRING_OR_NULL(pwd, pwd_len) + Z_PARAM_PATH_OR_NULL(uid, uid_len) + Z_PARAM_PATH_OR_NULL(pwd, pwd_len) Z_PARAM_LONG(pv_opt) ZEND_PARSE_PARAMETERS_END(); @@ -2181,9 +2188,9 @@ PHP_FUNCTION(odbc_close) zval *pv_conn; odbc_link *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_conn, odbc_connection_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + ZEND_PARSE_PARAMETERS_END(); link = Z_ODBC_LINK_P(pv_conn); odbc_connection *connection = Z_ODBC_CONNECTION_P(pv_conn); @@ -2204,9 +2211,9 @@ PHP_FUNCTION(odbc_num_rows) SQLLEN rows; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2223,9 +2230,9 @@ PHP_FUNCTION(odbc_next_result) zval *pv_res; int rc, i; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2269,9 +2276,9 @@ PHP_FUNCTION(odbc_num_fields) odbc_result *result; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2287,9 +2294,10 @@ PHP_FUNCTION(odbc_field_name) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_LONG(pv_num) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2322,9 +2330,10 @@ PHP_FUNCTION(odbc_field_type) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_LONG(pv_num) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2371,9 +2380,10 @@ PHP_FUNCTION(odbc_field_num) odbc_result *result; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_res, odbc_result_ce, &fname, &fname_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_STRING(fname, fname_len) + ZEND_PARSE_PARAMETERS_END(); result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); @@ -2406,9 +2416,11 @@ PHP_FUNCTION(odbc_autocommit) bool pv_onoff = false; bool pv_onoff_is_null = true; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b!", &pv_conn, odbc_connection_ce, &pv_onoff, &pv_onoff_is_null) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL_OR_NULL(pv_onoff, pv_onoff_is_null) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -2454,9 +2466,10 @@ static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode) zval *pv_handle = NULL; char *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pv_handle, odbc_connection_ce) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_OBJECT_OF_CLASS(pv_handle, odbc_connection_ce) + ZEND_PARSE_PARAMETERS_END(); if (pv_handle) { conn = Z_ODBC_CONNECTION_P(pv_handle); @@ -2508,9 +2521,12 @@ PHP_FUNCTION(odbc_setoption) zval *pv_handle; zend_long pv_which, pv_opt, pv_val; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "olll", &pv_handle, &pv_which, &pv_opt, &pv_val) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_OBJECT(pv_handle) + Z_PARAM_LONG(pv_which) + Z_PARAM_LONG(pv_opt) + Z_PARAM_LONG(pv_val) + ZEND_PARSE_PARAMETERS_END(); switch (pv_which) { case 1: /* SQLSetConnectOption */ @@ -2568,10 +2584,14 @@ PHP_FUNCTION(odbc_tables) size_t cat_len = 0, schema_len = 0, table_len = 0, type_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, - &table, &table_len, &type, &type_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 5) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_OPTIONAL + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_PATH_OR_NULL(schema, schema_len) + Z_PARAM_PATH_OR_NULL(table, table_len) + Z_PARAM_PATH_OR_NULL(type, type_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -2633,10 +2653,14 @@ PHP_FUNCTION(odbc_columns) size_t cat_len = 0, schema_len = 0, table_len = 0, column_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, - &table, &table_len, &column, &column_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 5) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_OPTIONAL + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_PATH_OR_NULL(schema, schema_len) + Z_PARAM_PATH_OR_NULL(table, table_len) + Z_PARAM_PATH_OR_NULL(column, column_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -2700,10 +2724,13 @@ PHP_FUNCTION(odbc_columnprivileges) size_t cat_len = 0, schema_len, table_len, column_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!sss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, - &table, &table_len, &column, &column_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(5, 5) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_STRING(schema, schema_len) + Z_PARAM_STRING(table, table_len) + Z_PARAM_STRING(column, column_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -2760,10 +2787,15 @@ PHP_FUNCTION(odbc_foreignkeys) size_t pcat_len = 0, pschema_len, ptable_len, fcat_len, fschema_len, ftable_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!sssss", &pv_conn, odbc_connection_ce, &pcat, &pcat_len, &pschema, &pschema_len, - &ptable, &ptable_len, &fcat, &fcat_len, &fschema, &fschema_len, &ftable, &ftable_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(7, 7) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(pcat, pcat_len) + Z_PARAM_STRING(pschema, pschema_len) + Z_PARAM_STRING(ptable, ptable_len) + Z_PARAM_STRING(fcat, fcat_len) + Z_PARAM_STRING(fschema, fschema_len) + Z_PARAM_STRING(ftable, ftable_len) + ZEND_PARSE_PARAMETERS_END(); #if defined(HAVE_IBMDB2) #define EMPTY_TO_NULL(xstr) \ @@ -2834,9 +2866,11 @@ PHP_FUNCTION(odbc_gettypeinfo) RETCODE rc; SQLSMALLINT data_type; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pv_conn, odbc_connection_ce, &pv_data_type) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(pv_data_type) + ZEND_PARSE_PARAMETERS_END(); data_type = (SQLSMALLINT) pv_data_type; @@ -2891,9 +2925,12 @@ PHP_FUNCTION(odbc_primarykeys) size_t cat_len = 0, schema_len, table_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_STRING(schema, schema_len) + Z_PARAM_STRING(table, table_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -2949,10 +2986,13 @@ PHP_FUNCTION(odbc_procedurecolumns) size_t cat_len = 0, schema_len = 0, proc_len = 0, col_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, - &proc, &proc_len, &col, &col_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 5) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_PATH_OR_NULL(schema, schema_len) + Z_PARAM_PATH_OR_NULL(proc, proc_len) + Z_PARAM_PATH_OR_NULL(col, col_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -3009,9 +3049,12 @@ PHP_FUNCTION(odbc_procedures) size_t cat_len = 0, schema_len = 0, proc_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &proc, &proc_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_PATH_OR_NULL(schema, schema_len) + Z_PARAM_PATH_OR_NULL(proc, proc_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); @@ -3069,10 +3112,15 @@ PHP_FUNCTION(odbc_specialcolumns) SQLUSMALLINT type, scope, nullable; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ols!ssll", &pv_conn, odbc_connection_ce, &vtype, &cat, &cat_len, &schema, &schema_len, - &name, &name_len, &vscope, &vnullable) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(7, 7) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_LONG(vtype) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_STRING(schema, schema_len) + Z_PARAM_STRING(name, name_len) + Z_PARAM_LONG(vscope) + Z_PARAM_LONG(vnullable) + ZEND_PARSE_PARAMETERS_END(); type = (SQLUSMALLINT) vtype; scope = (SQLUSMALLINT) vscope; @@ -3136,10 +3184,14 @@ PHP_FUNCTION(odbc_statistics) SQLUSMALLINT unique, reserved; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ssll", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, - &name, &name_len, &vunique, &vreserved) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(6, 6) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_STRING(schema, schema_len) + Z_PARAM_STRING(name, name_len) + Z_PARAM_LONG(vunique) + Z_PARAM_LONG(vreserved) /* XXX: Documented as 'accuracy' */ + ZEND_PARSE_PARAMETERS_END(); unique = (SQLUSMALLINT) vunique; reserved = (SQLUSMALLINT) vreserved; @@ -3200,9 +3252,12 @@ PHP_FUNCTION(odbc_tableprivileges) size_t cat_len = 0, schema_len, table_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_PATH_OR_NULL(cat, cat_len) + Z_PARAM_STRING(schema, schema_len) + Z_PARAM_STRING(table, table_len) + ZEND_PARSE_PARAMETERS_END(); odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); diff --git a/ext/odbc/php_odbc.h b/ext/odbc/php_odbc.h index 6f6264a482d7..d2815b90d108 100644 --- a/ext/odbc/php_odbc.h +++ b/ext/odbc/php_odbc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h index 058684c2ed03..090dfc3089a9 100644 --- a/ext/odbc/php_odbc_includes.h +++ b/ext/odbc/php_odbc_includes.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | @@ -92,6 +90,7 @@ typedef struct odbc_result_value { char name[256]; char *value; SQLLEN vallen; + SQLLEN value_max_len; SQLLEN coltype; } odbc_result_value; diff --git a/ext/odbc/tests/config.inc b/ext/odbc/tests/config.inc index 8d74feeb6ffb..a0f24f301558 100644 --- a/ext/odbc/tests/config.inc +++ b/ext/odbc/tests/config.inc @@ -1,5 +1,7 @@ +--FILE-- + +--EXPECT-- +clamped to buffer: bool(true) +only value bytes: bool(true) diff --git a/ext/odbc/tests/gh_odbc_dsn_immutability.phpt b/ext/odbc/tests/gh_odbc_dsn_immutability.phpt new file mode 100644 index 000000000000..e3023b387c70 --- /dev/null +++ b/ext/odbc/tests/gh_odbc_dsn_immutability.phpt @@ -0,0 +1,20 @@ +--TEST-- +odbc_connect() must not mutate the caller's DSN string +--EXTENSIONS-- +odbc +--FILE-- + +--EXPECT-- +string(37) "Driver=DoesNotExist;Database=x;SS001;" +string(43) "Driver=DoesNotExist;Database=x;SS001_CONST;" diff --git a/ext/odbc/tests/odbc_fetch_array_001.phpt b/ext/odbc/tests/odbc_fetch_array_001.phpt index bf13ed25e4d6..e7d4ccf328b6 100644 --- a/ext/odbc/tests/odbc_fetch_array_001.phpt +++ b/ext/odbc/tests/odbc_fetch_array_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_array VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_array'); var_dump(odbc_fetch_array($res)); -var_dump(odbc_fetch_array($res, 0)); +var_dump(odbc_fetch_array($res, null)); var_dump(odbc_fetch_array($res, 2)); var_dump(odbc_fetch_array($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_into_001.phpt b/ext/odbc/tests/odbc_fetch_into_001.phpt index 19f7f79268c5..e420475f02cc 100644 --- a/ext/odbc/tests/odbc_fetch_into_001.phpt +++ b/ext/odbc/tests/odbc_fetch_into_001.phpt @@ -20,7 +20,7 @@ $arr = []; var_dump(odbc_fetch_into($res, $arr)); var_dump($arr); $arr = []; -var_dump(odbc_fetch_into($res, $arr, 0)); +var_dump(odbc_fetch_into($res, $arr, null)); var_dump($arr); $arr = []; var_dump(odbc_fetch_into($res, $arr, 2)); diff --git a/ext/odbc/tests/odbc_fetch_object_001.phpt b/ext/odbc/tests/odbc_fetch_object_001.phpt index 62a8fc3b2c7e..eb553409639f 100644 --- a/ext/odbc/tests/odbc_fetch_object_001.phpt +++ b/ext/odbc/tests/odbc_fetch_object_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_object VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_object'); var_dump(odbc_fetch_object($res)); -var_dump(odbc_fetch_object($res, 0)); +var_dump(odbc_fetch_object($res, null)); var_dump(odbc_fetch_object($res, 2)); var_dump(odbc_fetch_object($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_row_001.phpt b/ext/odbc/tests/odbc_fetch_row_001.phpt index 576bb15414ce..fbadc8272590 100644 --- a/ext/odbc/tests/odbc_fetch_row_001.phpt +++ b/ext/odbc/tests/odbc_fetch_row_001.phpt @@ -17,7 +17,11 @@ odbc_exec($conn, 'INSERT INTO fetch_row VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_row'); -var_dump(odbc_fetch_row($res, 0)); +try { + var_dump(odbc_fetch_row($res, 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(odbc_fetch_row($res, null)); var_dump(odbc_result($res, 'test')); @@ -39,9 +43,8 @@ require 'config.inc'; $conn = odbc_connect($dsn, $user, $pass); odbc_exec($conn, 'DROP TABLE fetch_row'); ?> ---EXPECTF-- -Warning: odbc_fetch_row(): Argument #3 ($row) must be greater than or equal to 1 in %s on line %d -bool(false) +--EXPECT-- +odbc_fetch_row(): Argument #2 ($row) must be greater than or equal to 1 bool(true) string(1) "1" bool(true) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index f4134212bc4e..0a7a62eae9a9 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -26,7 +24,9 @@ #include "zend_compile.h" #include "ZendAccelerator.h" #include "zend_modules.h" +#include "zend_operators.h" #include "zend_persist.h" +#include "zend_portability.h" #include "zend_shared_alloc.h" #include "zend_accelerator_module.h" #include "zend_accelerator_blacklist.h" @@ -50,9 +50,9 @@ #include "zend_system_id.h" #include "ext/pcre/php_pcre.h" #include "ext/standard/basic_functions.h" +#include "zend_vm_opcodes.h" #ifdef ZEND_WIN32 -# include "ext/hash/php_hash.h" # include "ext/standard/md5.h" #endif @@ -312,7 +312,7 @@ static inline void accel_restart_leave(void) #endif } -static inline int accel_restart_is_active(void) +static inline bool accel_restart_is_active(void) { if (ZCSG(restart_in_progress)) { #ifndef ZEND_WIN32 @@ -325,19 +325,19 @@ static inline int accel_restart_is_active(void) if (fcntl(lock_file, F_GETLK, &restart_check) == -1) { zend_accel_error(ACCEL_LOG_DEBUG, "RestartC: %s (%d)", strerror(errno), errno); - return FAILURE; + return true; } if (restart_check.l_type == F_UNLCK) { ZCSG(restart_in_progress) = false; - return 0; + return false; } else { - return 1; + return true; } #else return LOCKVAL(restart_in) != 0; #endif } - return 0; + return false; } /* Creates a read lock for SHM access */ @@ -591,13 +591,12 @@ static zend_string* ZEND_FASTCALL accel_new_interned_string_for_php(zend_string static zend_always_inline zend_string *accel_find_interned_string_ex(zend_ulong h, const char *str, size_t size) { zend_string_table_pos_t pos; - zend_string *s; /* check for existing interned string */ pos = *STRTAB_HASH_TO_SLOT(&ZCSG(interned_strings), h); if (EXPECTED(pos != STRTAB_INVALID_POS)) { do { - s = STRTAB_POS_TO_STR(&ZCSG(interned_strings), pos); + zend_string *s = STRTAB_POS_TO_STR(&ZCSG(interned_strings), pos); if (EXPECTED(ZSTR_H(s) == h) && zend_string_equals_cstr(s, str, size)) { return s; } @@ -720,14 +719,13 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int Z_FUNC(q->val)->common.function_name = new_interned_string(Z_FUNC(q->val)->common.function_name); } if (Z_FUNC(q->val)->common.scope == ce) { - uint32_t i; uint32_t num_args = Z_FUNC(q->val)->common.num_args + 1; zend_arg_info *arg_info = Z_FUNC(q->val)->common.arg_info - 1; if (Z_FUNC(q->val)->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } - for (i = 0 ; i < num_args; i++) { + for (uint32_t i = 0 ; i < num_args; i++) { if (i > 0) { arg_info[i].name = new_interned_string(arg_info[i].name); if (arg_info[i].default_value) { @@ -860,7 +858,6 @@ static void accel_use_shm_interned_strings(void) #ifndef ZEND_WIN32 static inline void kill_all_lockers(struct flock *mem_usage_check) { - int tries; /* so that other process won't try to force while we are busy cleaning up */ ZCSG(force_restart_time) = 0; while (mem_usage_check->l_pid > 0) { @@ -868,7 +865,7 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) int signal = SIGTERM; errno = 0; bool success = false; - tries = 10; + int tries = 10; while (tries--) { zend_accel_error(ACCEL_LOG_WARNING, "Attempting to kill locker %d", mem_usage_check->l_pid); @@ -964,7 +961,7 @@ static inline bool accel_is_inactive(void) return false; } -static int zend_get_stream_timestamp(const char *filename, zend_stat_t *statbuf) +static zend_result zend_get_stream_timestamp(const char *filename, zend_stat_t *statbuf) { php_stream_wrapper *wrapper; php_stream_statbuf stream_statbuf; @@ -1056,7 +1053,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_ !EG(current_execute_data) && file_handle->primary_script) { - zend_stat_t *tmpbuf = sapi_module.get_stat(); + const zend_stat_t *tmpbuf = sapi_module.get_stat(); if (tmpbuf) { if (size) { @@ -1137,11 +1134,11 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_ return statbuf.st_mtime; } -static inline int do_validate_timestamps(zend_persistent_script *persistent_script, zend_file_handle *file_handle) +static inline zend_result do_validate_timestamps(const zend_persistent_script *persistent_script, zend_file_handle *file_handle) { zend_file_handle ps_handle; zend_string *full_path_ptr = NULL; - int ret; + zend_result ret; /** check that the persistent script is indeed the same file we cached * (if part of the path is a symlink than it possible that the user will change it) @@ -1225,8 +1222,6 @@ zend_string *accel_make_persistent_key(zend_string *str) { const char *path = ZSTR_VAL(str); size_t path_length = ZSTR_LEN(str); - char *key; - int key_length; ZEND_ASSERT(GC_REFCOUNT(ZCG(key)) == 1); ZSTR_LEN(ZCG(key)) = 0; @@ -1243,9 +1238,8 @@ zend_string *accel_make_persistent_key(zend_string *str) /* pass */ } else { const char *include_path = NULL, *cwd = NULL; - int include_path_len = 0, cwd_len = 0; - zend_string *parent_script = NULL; - size_t parent_script_len = 0; + size_t include_path_len = 0, cwd_len = 0; + const zend_string *parent_script = NULL; if (EXPECTED(ZCG(cwd_key_len))) { cwd = ZCG(cwd_key); @@ -1280,7 +1274,7 @@ zend_string *accel_make_persistent_key(zend_string *str) } if (str) { char buf[32]; - char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); cwd_len = ZCG(cwd_key_len) = buf + sizeof(buf) - 1 - res; cwd = ZCG(cwd_key); @@ -1324,7 +1318,7 @@ zend_string *accel_make_persistent_key(zend_string *str) } if (str) { char buf[32]; - char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); include_path_len = ZCG(include_path_key_len) = buf + sizeof(buf) - 1 - res; include_path = ZCG(include_path_key); @@ -1348,10 +1342,10 @@ zend_string *accel_make_persistent_key(zend_string *str) * since in itself, it may include colons (which we use to separate * different components of the key) */ - key = ZSTR_VAL(ZCG(key)); + char *key = ZSTR_VAL(ZCG(key)); memcpy(key, path, path_length); key[path_length] = ':'; - key_length = path_length + 1; + size_t key_length = path_length + 1; memcpy(key + key_length, cwd, cwd_len); key_length += cwd_len; @@ -1369,7 +1363,7 @@ zend_string *accel_make_persistent_key(zend_string *str) if (EXPECTED(EG(current_execute_data)) && EXPECTED((parent_script = zend_get_executed_filename_ex()) != NULL)) { - parent_script_len = ZSTR_LEN(parent_script); + size_t parent_script_len = ZSTR_LEN(parent_script); while (parent_script_len > 0) { --parent_script_len; if (IS_SLASH(ZSTR_VAL(parent_script)[parent_script_len])) { @@ -1523,7 +1517,7 @@ static void zend_accel_add_key(zend_string *key, zend_accel_hash_entry *bucket) } } -static zend_always_inline bool is_phar_file(zend_string *filename) +static zend_always_inline bool is_phar_file(const zend_string *filename) { return filename && ZSTR_LEN(filename) >= sizeof(".phar") && !memcmp(ZSTR_VAL(filename) + ZSTR_LEN(filename) - (sizeof(".phar")-1), ".phar", sizeof(".phar")-1) && @@ -1974,8 +1968,8 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int if (persistent_script) { if (ZCG(accel_directives).record_warnings) { - persistent_script->num_warnings = EG(num_errors); - persistent_script->warnings = EG(errors); + persistent_script->num_warnings = EG(errors).size; + persistent_script->warnings = EG(errors).errors; } from_memory = false; @@ -1993,7 +1987,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int return op_array; } -static int check_persistent_script_access(zend_persistent_script *persistent_script) +static bool check_persistent_script_access(const zend_persistent_script *persistent_script) { char *phar_path, *ptr; if ((ZSTR_LEN(persistent_script->script.filename)>= 4; + } while (n); + + return dest; +} + +/* Prevents collisions with real scripts, as we don't cache paths prefixed with + * a scheme, except file:// and phar://. */ +#define PFA_KEY_PREFIX "pfa://" + +static zend_string *zend_accel_pfa_key(const zend_op *declaring_opline, + const zend_function *called_function) +{ + const size_t max_key_len = strlen(PFA_KEY_PREFIX) + (sizeof(uintptr_t)*2) + strlen(":") + (sizeof(uintptr_t)*2); + zend_string *key = zend_string_alloc(max_key_len, 0); + + char *dest = ZSTR_VAL(key); + dest = zend_mempcpy(dest, PFA_KEY_PREFIX, strlen(PFA_KEY_PREFIX)); + dest = zend_accel_uintptr_hex(dest, (uintptr_t)declaring_opline); + *dest++ = ':'; + + const void *ptr; + if ((called_function->common.fn_flags & ZEND_ACC_CLOSURE) + && called_function->type == ZEND_USER_FUNCTION) { + /* Can not use 'called_function' as part of the key, as it's an inner + * pointer to a Closure, which may be freed. Use its opcodes instead. + * zend_accel_compile_pfa() ensures to extend the lifetime of opcodes + * in this case. */ + ptr = called_function->op_array.opcodes; + } else { + ptr = called_function; + } + dest = zend_accel_uintptr_hex(dest, (uintptr_t)ptr); + + *dest = '\0'; + ZSTR_LEN(key) = dest - ZSTR_VAL(key); + + return key; +} + +const zend_op_array *zend_accel_pfa_cache_get(const zend_op_array *declaring_op_array, + const zend_op *declaring_opline, const zend_function *called_function) +{ + zend_string *key = zend_accel_pfa_key(declaring_opline, called_function); + zend_op_array *op_array = NULL; + + /* A PFA is SHM-cacheable if the declaring_op_array and called_function are + * cached. */ + if (ZCG(accelerator_enabled) + && !file_cache_only + && !declaring_op_array->refcount + && (called_function->type != ZEND_USER_FUNCTION || !called_function->op_array.refcount)) { + zend_persistent_script *persistent_script = zend_accel_hash_find(&ZCSG(hash), key); + if (persistent_script) { + op_array = persistent_script->script.main_op_array.dynamic_func_defs[0]; + if (persistent_script->num_warnings) { + zend_emit_recorded_errors_ex(persistent_script->num_warnings, + persistent_script->warnings); + } + } + } else { + op_array = zend_hash_find_ptr(&EG(partial_function_application_cache), key); + } + + zend_string_release(key); + + return op_array; +} + +zend_op_array *zend_accel_compile_pfa(zend_ast *ast, + const zend_op_array *declaring_op_array, + const zend_op *declaring_opline, + const zend_function *called_function, + zend_string *pfa_func_name) +{ + zend_begin_record_errors(); + zend_op_array *op_array; + + uint32_t orig_compiler_options = CG(compiler_options); + + zend_try { + CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY; + CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING; + CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION; + CG(compiler_options) |= ZEND_COMPILE_IGNORE_OTHER_FILES; + CG(compiler_options) |= ZEND_COMPILE_IGNORE_OBSERVER; +#ifdef ZEND_WIN32 + /* On Windows, don't compile with internal classes. Shm may be attached from different + * processes with internal classes living in different addresses. */ + CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES; +#endif + + op_array = zend_compile_ast(ast, ZEND_USER_FUNCTION, declaring_op_array->filename); + + CG(compiler_options) = orig_compiler_options; + } zend_catch { + CG(compiler_options) = orig_compiler_options; + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + zend_bailout(); + } zend_end_try(); + + ZEND_ASSERT(op_array->num_dynamic_func_defs == 1); + + zend_string_release(op_array->dynamic_func_defs[0]->function_name); + op_array->dynamic_func_defs[0]->function_name = pfa_func_name; + + zend_string *key = zend_accel_pfa_key(declaring_opline, called_function); + + /* Cache op_array only if the declaring op_array and the called function + * are cached */ + if (!ZCG(accelerator_enabled) + || file_cache_only + || declaring_op_array->refcount + || (called_function->type == ZEND_USER_FUNCTION && called_function->op_array.refcount) + || (ZCSG(restart_in_progress) && accel_restart_is_active()) + || (!ZCG(counted) && accel_activate_add() == FAILURE)) { + zend_op_array *script_op_array = op_array; + zend_op_array *op_array = script_op_array->dynamic_func_defs[0]; + GC_ADDREF(op_array->function_name); + (*op_array->refcount)++; + destroy_op_array(script_op_array); + efree(script_op_array); + + if ((called_function->common.fn_flags & ZEND_ACC_CLOSURE) + && called_function->type == ZEND_USER_FUNCTION + && called_function->op_array.refcount) { + /* Extend the lifetime of the called opcodes if + * the called function is a closure. + * See comment in zend_accel_pfa_key(). */ + zend_op_array *copy = zend_arena_alloc(&CG(arena), sizeof(*copy)); + memcpy(copy, called_function, sizeof(*copy)); + function_add_ref((zend_function *) copy); + /* Reference the copy in op_array->dynamic_func_defs so that it's + * destroyed when op_array is destroyed. */ + ZEND_ASSERT(!op_array->dynamic_func_defs && !op_array->num_dynamic_func_defs); + op_array->dynamic_func_defs = safe_emalloc(1, sizeof(*op_array->dynamic_func_defs), 0); + op_array->dynamic_func_defs[0] = copy; + op_array->num_dynamic_func_defs = 1; + } + + zend_hash_add_new_ptr(&EG(partial_function_application_cache), key, op_array); + zend_string_release(key); + + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + + return op_array; + } + + zend_persistent_script *new_persistent_script = create_persistent_script(); + new_persistent_script->script.main_op_array = *op_array; + efree_size(op_array, sizeof(*op_array)); + new_persistent_script->script.filename = key; + + if (ZCG(accel_directives).record_warnings) { + new_persistent_script->num_warnings = EG(errors).size; + new_persistent_script->warnings = EG(errors).errors; + } + + HANDLE_BLOCK_INTERRUPTIONS(); + SHM_UNPROTECT(); + + bool from_shared_memory; + /* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */ + bool orig_gc_state = gc_enable(false); + char *orig_file_cache = ZCG(accel_directives).file_cache; + /* Disable file_cache temporarily, as we can't guarantee consistency. */ + ZCG(accel_directives).file_cache = NULL; + new_persistent_script = cache_script_in_shared_memory(new_persistent_script, NULL, &from_shared_memory); + ZCG(accel_directives).file_cache = orig_file_cache; + gc_enable(orig_gc_state); + + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); + + /* We may have switched to an existing persistent script that was persisted in + * the meantime. Make sure to use its warnings if available. */ + if (ZCG(accel_directives).record_warnings) { + EG(record_errors) = false; + zend_emit_recorded_errors_ex(new_persistent_script->num_warnings, new_persistent_script->warnings); + } else { + zend_emit_recorded_errors(); + } + zend_free_recorded_errors(); + + return new_persistent_script->script.main_op_array.dynamic_func_defs[0]; +} + /* zend_compile() replacement */ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) { @@ -2199,8 +2388,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) from_shared_memory = false; if (persistent_script) { if (ZCG(accel_directives).record_warnings) { - persistent_script->num_warnings = EG(num_errors); - persistent_script->warnings = EG(errors); + persistent_script->num_warnings = EG(errors).size; + persistent_script->warnings = EG(errors).errors; } /* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */ @@ -2294,7 +2483,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return zend_accel_load_script(persistent_script, from_shared_memory); } -static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_cache_find(zend_inheritance_cache_entry *entry, zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, bool *needs_autoload_ptr) +static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_cache_find(zend_inheritance_cache_entry *entry, const zend_class_entry *ce, const zend_class_entry *parent, zend_class_entry **traits_and_interfaces, bool *needs_autoload_ptr) { uint32_t i; @@ -2316,10 +2505,10 @@ static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_c } if (found && entry->dependencies) { for (i = 0; i < entry->dependencies_count; i++) { - zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); + const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (ce != entry->dependencies[i].ce) { - if (!ce) { + if (dependency_ce != entry->dependencies[i].ce) { + if (!dependency_ce) { needs_autoload = true; } else { found = false; @@ -2341,7 +2530,6 @@ static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_c static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) { - uint32_t i; bool needs_autoload; zend_inheritance_cache_entry *entry = ce->inheritance_cache; @@ -2360,10 +2548,10 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, return ce; } - for (i = 0; i < entry->dependencies_count; i++) { - zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0); + for (uint32_t i = 0; i < entry->dependencies_count; i++) { + const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0); - if (ce == NULL) { + if (dependency_ce == NULL) { return NULL; } } @@ -2428,7 +2616,7 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, } ZCG(current_persistent_script) = &dummy; zend_persist_class_entry_calc(ce); - zend_persist_warnings_calc(EG(num_errors), EG(errors)); + zend_persist_warnings_calc(EG(errors).size, EG(errors).errors); size = dummy.size; zend_shared_alloc_clear_xlat_table(); @@ -2498,8 +2686,8 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, JIT_G(on) = jit_on_old; #endif - entry->num_warnings = EG(num_errors); - entry->warnings = zend_persist_warnings(EG(num_errors), EG(errors)); + entry->num_warnings = EG(errors).size; + entry->warnings = zend_persist_warnings(EG(errors).size, EG(errors).errors); entry->next = proto->inheritance_cache; proto->inheritance_cache = entry; @@ -2541,7 +2729,7 @@ static zend_result accel_gen_uname_id(void) PHP_MD5Update(&ctx, (void *) uname, (unsize - 1) * sizeof(wchar_t)); PHP_MD5Update(&ctx, ZCG(accel_directives).cache_id, strlen(ZCG(accel_directives).cache_id)); PHP_MD5Final(digest, &ctx); - php_hash_bin2hex(accel_uname_id, digest, sizeof digest); + zend_bin2hex(accel_uname_id, digest, sizeof digest); return SUCCESS; } #endif @@ -2592,7 +2780,7 @@ static zend_string* persistent_zend_resolve_path(zend_string *filename) /* lookup by "not-real" path */ key = accel_make_persistent_key(filename); if (key) { - zend_accel_hash_entry *bucket = zend_accel_hash_find_entry(&ZCSG(hash), key); + const zend_accel_hash_entry *bucket = zend_accel_hash_find_entry(&ZCSG(hash), key); if (bucket != NULL) { zend_persistent_script *persistent_script = (zend_persistent_script *)bucket->data; if (!persistent_script->corrupted) { @@ -3269,8 +3457,9 @@ static zend_result accel_post_startup(void) file_cache_only = ZCG(accel_directives).file_cache_only; if (!file_cache_only) { size_t shm_size = ZCG(accel_directives).memory_consumption; -#ifdef HAVE_JIT size_t jit_size = 0; +#ifdef HAVE_JIT + size_t jit_buffer_size = 0; bool reattached = false; if (JIT_G(enabled) && JIT_G(buffer_size) @@ -3282,15 +3471,16 @@ static zend_result accel_post_startup(void) zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - can't get page size."); abort(); } - jit_size = JIT_G(buffer_size); - jit_size = ZEND_MM_ALIGNED_SIZE_EX(jit_size, page_size); + jit_buffer_size = JIT_G(buffer_size); + jit_buffer_size = ZEND_MM_ALIGNED_SIZE_EX(jit_buffer_size, page_size); +# ifndef ZEND_JIT_USE_APPLE_MAP_JIT + jit_size = jit_buffer_size; shm_size += jit_size; +# endif } +#endif switch (zend_shared_alloc_startup(shm_size, jit_size)) { -#else - switch (zend_shared_alloc_startup(shm_size, 0)) { -#endif case ALLOC_SUCCESS: if (zend_accel_init_shm() == FAILURE) { accel_startup_ok = false; @@ -3323,7 +3513,6 @@ static zend_result accel_post_startup(void) accel_startup_ok = false; zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - cannot reattach to exiting shared memory."); return SUCCESS; - break; #if ENABLE_FILE_CACHE_FALLBACK case ALLOC_FALLBACK: zend_shared_alloc_lock(); @@ -3331,7 +3520,6 @@ static zend_result accel_post_startup(void) fallback_process = true; zend_shared_alloc_unlock(); goto file_cache_fallback; - break; #endif } @@ -3346,10 +3534,15 @@ static zend_result accel_post_startup(void) if (JIT_G(buffer_size) == 0) { JIT_G(enabled) = false; JIT_G(on) = false; - } else if (!ZSMMG(reserved)) { - zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: could not use reserved buffer!"); } else { - zend_jit_startup(ZSMMG(reserved), jit_size, reattached); +# ifdef ZEND_JIT_USE_APPLE_MAP_JIT + zend_jit_startup(NULL, jit_buffer_size, reattached); +# else + if (!ZSMMG(reserved)) { + zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: could not use reserved buffer!"); + } + zend_jit_startup(ZSMMG(reserved), jit_buffer_size, reattached); +# endif zend_jit_startup_ok = true; } } @@ -3649,7 +3842,7 @@ static void preload_shutdown(void) if (EG(function_table)) { ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(function_table), zv) { - zend_function *func = Z_PTR_P(zv); + const zend_function *func = Z_PTR_P(zv); if (func->type == ZEND_INTERNAL_FUNCTION) { break; } @@ -3658,7 +3851,7 @@ static void preload_shutdown(void) if (EG(class_table)) { ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) { - zend_class_entry *ce = Z_PTR_P(zv); + const zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_INTERNAL_CLASS && Z_TYPE_P(zv) != IS_ALIAS_PTR) { break; } @@ -3685,7 +3878,7 @@ static void preload_restart(void) } } -static size_t preload_try_strip_filename(zend_string *filename) { +static size_t preload_try_strip_filename(const zend_string *filename) { /*FIXME: better way to handle eval()'d code? see COMPILED_STRING_DESCRIPTION_FORMAT */ if (ZSTR_LEN(filename) > sizeof(" eval()'d code") && *(ZSTR_VAL(filename) + ZSTR_LEN(filename) - sizeof(" eval()'d code")) == ':') { @@ -3806,17 +3999,17 @@ static void preload_sort_classes(void *base, size_t count, size_t siz, compare_f Bucket *b2; Bucket *end = b1 + count; Bucket tmp; - zend_class_entry *ce, *p; + const zend_class_entry *ce, *p; while (b1 < end) { try_again: - ce = (zend_class_entry*)Z_PTR(b1->val); + ce = Z_PTR(b1->val); if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) { p = ce->parent; if (p->type == ZEND_USER_CLASS) { b2 = b1 + 1; while (b2 < end) { - if (p == Z_PTR(b2->val)) { + if (p == Z_PTR(b2->val)) { tmp = *b1; *b1 = *b2; *b2 = tmp; @@ -3833,7 +4026,7 @@ static void preload_sort_classes(void *base, size_t count, size_t siz, compare_f if (p->type == ZEND_USER_CLASS) { b2 = b1 + 1; while (b2 < end) { - if (p == Z_PTR(b2->val)) { + if (p == Z_PTR(b2->val)) { tmp = *b1; *b1 = *b2; *b2 = tmp; @@ -3858,9 +4051,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e memset(error, 0, sizeof(preload_error)); if (ce->parent_name) { - zend_string *key = zend_string_tolower(ce->parent_name); - zend_class_entry *parent = zend_hash_find_ptr(EG(class_table), key); - zend_string_release(key); + const zend_class_entry *parent = zend_hash_find_ptr_lc(EG(class_table), ce->parent_name); if (!parent) { error->kind = "Unknown parent "; error->name = ZSTR_VAL(ce->parent_name); @@ -3870,7 +4061,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e if (ce->num_interfaces) { for (uint32_t i = 0; i < ce->num_interfaces; i++) { - zend_class_entry *interface = + const zend_class_entry *interface = zend_hash_find_ptr(EG(class_table), ce->interface_names[i].lc_name); if (!interface) { error->kind = "Unknown interface "; @@ -3882,7 +4073,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e if (ce->num_traits) { for (uint32_t i = 0; i < ce->num_traits; i++) { - zend_class_entry *trait = + const zend_class_entry *trait = zend_hash_find_ptr(EG(class_table), ce->trait_names[i].lc_name); if (!trait) { error->kind = "Unknown trait "; @@ -3925,10 +4116,9 @@ static bool preload_try_resolve_constants(zend_class_entry *ce) ce->ce_flags &= ~ZEND_ACC_HAS_AST_CONSTANTS; } if (ce->default_properties_count) { - uint32_t i; bool resolved = true; - for (i = 0; i < ce->default_properties_count; i++) { + for (uint32_t i = 0; i < ce->default_properties_count; i++) { zend_property_info *prop = ce->properties_info_table[i]; if (!prop) { continue; @@ -3988,7 +4178,7 @@ static void preload_error_cb(int type, zend_string *error_filename, const uint32 static void preload_remove_declares(zend_op_array *op_array) { zend_op *opline = op_array->opcodes; - zend_op *end = opline + op_array->last; + const zend_op *end = opline + op_array->last; uint32_t skip_dynamic_func_count = 0; zend_string *key; zend_op_array *func; @@ -4133,9 +4323,9 @@ static void preload_link(void) /* Remember the last error. */ zend_error_cb = orig_error_cb; EG(record_errors) = false; - ZEND_ASSERT(EG(num_errors) > 0); - zend_hash_update_ptr(&errors, key, EG(errors)[EG(num_errors)-1]); - EG(num_errors)--; + ZEND_ASSERT(EG(errors).size > 0); + zend_hash_update_ptr(&errors, key, EG(errors).errors[EG(errors).size-1]); + EG(errors).size--; } zend_end_try(); CG(in_compilation) = false; CG(compiled_filename) = NULL; @@ -4279,7 +4469,7 @@ static void preload_remove_empty_includes(void) if (script->empty) { bool empty = true; zend_op *opline = script->script.main_op_array.opcodes; - zend_op *end = opline + script->script.main_op_array.last; + const zend_op *end = opline + script->script.main_op_array.last; while (opline < end) { if (opline->opcode == ZEND_INCLUDE_OR_EVAL && @@ -4320,7 +4510,7 @@ static void preload_remove_empty_includes(void) /* remove empty includes */ ZEND_HASH_MAP_FOREACH_PTR(preload_scripts, script) { zend_op *opline = script->script.main_op_array.opcodes; - zend_op *end = opline + script->script.main_op_array.last; + const zend_op *end = opline + script->script.main_op_array.last; while (opline < end) { if (opline->opcode == ZEND_INCLUDE_OR_EVAL && @@ -4331,7 +4521,7 @@ static void preload_remove_empty_includes(void) zend_string *resolved_path = preload_resolve_path(Z_STR_P(RT_CONSTANT(opline, opline->op1))); if (resolved_path) { - zend_persistent_script *incl = zend_hash_find_ptr(preload_scripts, resolved_path); + const zend_persistent_script *incl = zend_hash_find_ptr(preload_scripts, resolved_path); if (incl && incl->empty && opline->result_type == IS_UNUSED) { MAKE_NOP(opline); } else { @@ -4349,9 +4539,8 @@ static void preload_remove_empty_includes(void) } ZEND_HASH_FOREACH_END(); } -static void preload_register_trait_methods(zend_class_entry *ce) { +static void preload_register_trait_methods(const zend_class_entry *ce) { zend_op_array *op_array; - zend_property_info *info; ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { @@ -4361,7 +4550,7 @@ static void preload_register_trait_methods(zend_class_entry *ce) { } ZEND_HASH_FOREACH_END(); if (ce->num_hooked_props > 0) { - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *info) { if (info->hooks) { for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { if (info->hooks[i]) { @@ -4383,7 +4572,7 @@ static void preload_fix_trait_op_array(zend_op_array *op_array) return; } - zend_op_array *orig_op_array = zend_shared_alloc_get_xlat_entry(op_array->refcount); + const zend_op_array *orig_op_array = zend_shared_alloc_get_xlat_entry(op_array->refcount); ZEND_ASSERT(orig_op_array && "Must be in xlat table"); zend_string *function_name = op_array->function_name; @@ -4392,6 +4581,7 @@ static void preload_fix_trait_op_array(zend_op_array *op_array) uint32_t fn_flags2 = op_array->fn_flags2; zend_function *prototype = op_array->prototype; HashTable *ht = op_array->static_variables; + const zend_property_info *prop_info = op_array->prop_info; *op_array = *orig_op_array; op_array->function_name = function_name; op_array->scope = scope; @@ -4399,9 +4589,10 @@ static void preload_fix_trait_op_array(zend_op_array *op_array) op_array->fn_flags2 = fn_flags2; op_array->prototype = prototype; op_array->static_variables = ht; + op_array->prop_info = prop_info; } -static void preload_fix_trait_methods(zend_class_entry *ce) +static void preload_fix_trait_methods(const zend_class_entry *ce) { zend_op_array *op_array; @@ -4426,7 +4617,7 @@ static void preload_fix_trait_methods(zend_class_entry *ce) static void preload_optimize(zend_persistent_script *script) { - zend_class_entry *ce; + const zend_class_entry *ce; zend_persistent_script *tmp_script; zend_shared_alloc_init_xlat_table(); @@ -4523,10 +4714,10 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s static void preload_load(size_t orig_map_ptr_static_last) { /* Load into process tables */ - zend_script *script = &ZCSG(preload_script)->script; + const zend_script *script = &ZCSG(preload_script)->script; if (zend_hash_num_elements(&script->function_table)) { Bucket *p = script->function_table.arData; - Bucket *end = p + script->function_table.nNumUsed; + const Bucket *end = p + script->function_table.nNumUsed; zend_hash_extend(CG(function_table), CG(function_table)->nNumUsed + script->function_table.nNumUsed, 0); @@ -4537,7 +4728,7 @@ static void preload_load(size_t orig_map_ptr_static_last) if (zend_hash_num_elements(&script->class_table)) { Bucket *p = script->class_table.arData; - Bucket *end = p + script->class_table.nNumUsed; + const Bucket *end = p + script->class_table.nNumUsed; zend_hash_extend(CG(class_table), CG(class_table)->nNumUsed + script->class_table.nNumUsed, 0); @@ -4585,7 +4776,7 @@ static void preload_load(size_t orig_map_ptr_static_last) } #if HAVE_JIT -static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array) +static void zend_accel_clear_call_graph_ptrs(const zend_op_array *op_array) { ZEND_ASSERT(ZEND_USER_CODE(op_array->type)); zend_func_info *info = ZEND_FUNC_INFO(op_array); @@ -4595,9 +4786,9 @@ static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array) } } -static void accel_reset_arena_info(zend_persistent_script *script) +static void accel_reset_arena_info(const zend_persistent_script *script) { - zend_op_array *op_array; + const zend_op_array *op_array; zend_class_entry *ce; zend_accel_clear_call_graph_ptrs(&script->script.main_op_array); @@ -5174,9 +5365,9 @@ static void accel_activate(void) { static zend_extension opcache_extension_entry = { ACCELERATOR_PRODUCT_NAME, /* name */ PHP_VERSION, /* version */ - "Zend Technologies", /* author */ - "http://www.zend.com/", /* URL */ - "Copyright (c)", /* copyright */ + "Zend by Perforce", /* author */ + "https://www.zend.com/", /* URL */ + "Copyright ©", /* copyright */ accel_startup, /* startup */ NULL, /* shutdown */ accel_activate, /* per-script activation */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 524a6f5e1213..ef7eea433c09 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -336,6 +334,16 @@ zend_string* ZEND_FASTCALL accel_new_interned_string(zend_string *str); uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name); +const zend_op_array *zend_accel_pfa_cache_get(const zend_op_array *declaring_op_array, + const zend_op *declaring_opline, + const zend_function *called_function); + +zend_op_array *zend_accel_compile_pfa(zend_ast *ast, + const zend_op_array *declaring_op_array, + const zend_op *declaring_opline, + const zend_function *called_function, + zend_string *pfa_func_name); + END_EXTERN_C() /* memory write protection */ diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 70138726c56e..2a1ac4e332fc 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -31,10 +31,9 @@ AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ PHP_OPCACHE_JIT=no ]) - if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then - AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS]) - PHP_OPCACHE_JIT=no - fi + AS_IF([test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"], + [AC_CHECK_FUNC([pthread_jit_write_protect_np], [], + [AC_MSG_ERROR([OPcache JIT on Apple Silicon with ZTS requires pthread_jit_write_protect_np()])])]) ]) AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ @@ -339,7 +338,7 @@ PHP_NEW_EXTENSION([opcache], m4_normalize([ $ZEND_JIT_SRC ]), [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, + [$JIT_CFLAGS],, [yes]) PHP_ADD_EXTENSION_DEP(opcache, date) diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index 397fa1bdd87d..1ad346b4da31 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -14,7 +14,7 @@ ZEND_EXTENSION('opcache', "\ zend_persist_calc.c \ zend_file_cache.c \ zend_shared_alloc.c \ - shared_alloc_win32.c", false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + shared_alloc_win32.c", false); ADD_EXTENSION_DEP('opcache', 'date'); ADD_EXTENSION_DEP('opcache', 'hash'); diff --git a/ext/opcache/jit/ir/.gitignore b/ext/opcache/jit/ir/.gitignore index 7a37a4fd0593..367a68671bc0 100644 --- a/ext/opcache/jit/ir/.gitignore +++ b/ext/opcache/jit/ir/.gitignore @@ -20,3 +20,6 @@ tests/**/*.log win32/vcpkg win32/build_* + +fuzz/build/ +fuzz/corpus/ diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index f6058c5abe52..f6a0cb60af98 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -161,6 +161,8 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted case IR_CHAR: if (insn->val.c == '\\') { fprintf(f, "'\\\\'"); + } else if (insn->val.c == '\'') { + fprintf(f, "'\\\''"); } else if (insn->val.c >= ' ') { fprintf(f, "'%c'", insn->val.c); } else if (insn->val.c == '\t') { @@ -283,6 +285,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_kind_src IR_OPND_CONTROL #define ir_op_kind_reg IR_OPND_CONTROL_DEP #define ir_op_kind_ret IR_OPND_CONTROL_REF +#define ir_op_kind_grd IR_OPND_CONTROL_GUARD #define ir_op_kind_str IR_OPND_STR #define ir_op_kind_num IR_OPND_NUM #define ir_op_kind_fld IR_OPND_STR @@ -1443,24 +1446,6 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref) } } -static int ir_ref_cmp(const void *p1, const void *p2) -{ - return *(ir_ref*)p1 - *(ir_ref*)p2; -} - -void ir_use_list_sort(ir_ctx *ctx, ir_ref ref) -{ - ir_use_list *use_list; - uint32_t n; - - IR_ASSERT(ref > 0); - use_list = &ctx->use_lists[ref]; - n = use_list->count; - if (n > 1) { - qsort(ctx->use_edges + use_list->refs, n, sizeof(ir_ref), ir_ref_cmp); - } -} - void ir_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref) { int i, j, n, *p, use; @@ -1861,7 +1846,7 @@ int ir_mem_unprotect(void *ptr, size_t size) int ir_mem_flush(void *ptr, size_t size) { - return 1; + return FlushInstructionCache(GetCurrentProcess(), ptr, size) == TRUE ? 1 : 0; } #else @@ -2186,7 +2171,10 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_load_i(const ir_ctx *ctx, ir_ref ref, i if (!(proto->flags & (IR_CONST_FUNC|IR_PURE_FUNC))) { break; } - } else if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_VSTORE) { + } else if (insn->op == IR_MERGE + || insn->op == IR_LOOP_BEGIN + || insn->op == IR_VSTORE + || (insn->op == IR_BEGIN && insn->op2)) { return IR_UNUSED; } ref = insn->op1; @@ -2251,7 +2239,10 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(const ir_ctx *ctx, ir_ref ref, if (!(proto->flags & (IR_CONST_FUNC|IR_PURE_FUNC))) { break; } - } else if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_STORE) { + } else if (insn->op == IR_MERGE + || insn->op == IR_LOOP_BEGIN + || insn->op == IR_STORE + || (insn->op == IR_BEGIN && insn->op2)) { break; } ref = insn->op1; @@ -2344,7 +2335,15 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_store_i(ir_ctx *ctx, ir_ref ref, ir_ref } } else if (insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { guarded = 1; - } else if (insn->op >= IR_START || insn->op == IR_CALL) { + } else if (insn->op >= IR_START) { + if (insn->op == IR_BEGIN && insn->op1 && !insn->op2) { + /* skip END */ + ref = insn->op1; + insn = &ctx->ir_base[ref]; + } else { + break; + } + } else if (insn->op == IR_CALL) { break; } next = ref; @@ -2425,7 +2424,15 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vstore_i(ir_ctx *ctx, ir_ref ref, ir_re } } else if (insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { guarded = 1; - } else if (insn->op >= IR_START || insn->op == IR_CALL || insn->op == IR_LOAD || insn->op == IR_STORE) { + } else if (insn->op >= IR_START) { + if (insn->op == IR_BEGIN && insn->op1 && !insn->op2) { + /* skip END */ + ref = insn->op1; + insn = &ctx->ir_base[ref]; + } else { + break; + } + } else if (insn->op == IR_CALL || insn->op == IR_LOAD || insn->op == IR_STORE) { break; } next = ref; @@ -2440,6 +2447,37 @@ ir_ref ir_find_aliasing_vstore(ir_ctx *ctx, ir_ref ref, ir_ref var, ir_ref val) } /* IR Construction API */ +static ir_ref ir_last_guard(ir_ctx *ctx) +{ + ir_ref ref; + ir_insn *insn; + + IR_ASSERT(ctx->control); + ref = ctx->control; + while (1) { + insn = &ctx->ir_base[ref]; + if (IR_IS_BB_START(insn->op) || insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { + if (insn->op == IR_START) ref = IR_UNUSED; + break; + } + ref = insn->op1; + } + return ref; +} + +ir_ref _ir_DIV(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2) +{ + ir_ref guard = (IR_IS_TYPE_FP(type) || (IR_IS_CONST_REF(op2) && ctx->ir_base[op2].val.u64 != 0)) ? + IR_UNUSED : ir_last_guard(ctx); + return ir_fold3(ctx, IR_OPT(IR_DIV, type), op1, op2, guard); +} + +ir_ref _ir_MOD(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2) +{ + ir_ref guard = (IR_IS_CONST_REF(op2) && ctx->ir_base[op2].val.u64 != 0) ? + IR_UNUSED : ir_last_guard(ctx); + return ir_fold3(ctx, IR_OPT(IR_MOD, type), op1, op2, guard); +} ir_ref _ir_PARAM(ir_ctx *ctx, ir_type type, const char* name, ir_ref num) { diff --git a/ext/opcache/jit/ir/ir.h b/ext/opcache/jit/ir/ir.h index b0a96b511bd0..01db4ecf6b15 100644 --- a/ext/opcache/jit/ir/ir.h +++ b/ext/opcache/jit/ir/ir.h @@ -210,6 +210,7 @@ typedef enum _ir_type { * arg - argument reference CALL/TAILCALL/CARG->CARG * src - reference to a previous control region (IF, IF_TRUE, IF_FALSE, MERGE, LOOP_BEGIN, LOOP_END, RETURN) * reg - data-control dependency on region (PHI, VAR, PARAM) + * grd - optional data-control dependency guard (DIV, MOD) * ret - reference to a previous RETURN instruction (RETURN) * str - string: variable/argument name (VAR, PARAM, CALL, TAILCALL) * num - number: argument number (PARAM) @@ -265,8 +266,8 @@ typedef enum _ir_type { _(ADD, d2C, def, def, ___) /* addition */ \ _(SUB, d2, def, def, ___) /* subtraction (must be ADD+1) */ \ _(MUL, d2C, def, def, ___) /* multiplication */ \ - _(DIV, d2, def, def, ___) /* division */ \ - _(MOD, d2, def, def, ___) /* modulo */ \ + _(DIV, d3, def, def, grd) /* division */ \ + _(MOD, d3, def, def, grd) /* modulo */ \ _(NEG, d1, def, ___, ___) /* change sign */ \ _(ABS, d1, def, ___, ___) /* absolute value */ \ /* (LDEXP, MIN, MAX, FPMATH) */ \ @@ -383,6 +384,14 @@ typedef enum _ir_type { _(RETURN, T2X1, src, def, ret) /* function return */ \ _(UNREACHABLE, T1X2, src, ___, ret) /* unreachable (tailcall, etc) */ \ \ + /* inline assembler */ \ + _(ASM, xN, src, def, def) /* GCC inline assembler */ \ + /* op2 - asm template string */ \ + /* op3 - asm constraint string */ \ + /* opN - asm input argument */ \ + _(ASM_OUT, x1, src, ___, ___) /* ASM data output projection */ \ + _(ASM_GOTO, E1, src, ___, ___) /* ASM goto (bb end after ASM) */ \ + \ /* deoptimization helper */ \ _(EXITCALL, x2, src, def, ___) /* save CPU regs and call op2 */ \ diff --git a/ext/opcache/jit/ir/ir_aarch64.dasc b/ext/opcache/jit/ir/ir_aarch64.dasc index 5a6718b77c1c..fc4bb84f1e05 100644 --- a/ext/opcache/jit/ir/ir_aarch64.dasc +++ b/ext/opcache/jit/ir/ir_aarch64.dasc @@ -402,6 +402,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co int flags = IR_USE_MUST_BE_IN_REG | IR_OP1_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; const ir_proto_t *proto; const ir_call_conv_dsc *cc; + ir_ref next; constraints->def_reg = IR_REG_NONE; constraints->hints_count = 0; @@ -562,11 +563,13 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; } - if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) { - insn = &ctx->ir_base[insn->op2]; - if (IR_IS_SYM_CONST(insn->op) || !aarch64_may_encode_imm12(insn->val.u64)) { - constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); - n++; + if (IR_IS_CONST_REF(insn->op2)) { + if (insn->op1 != insn->op2) { + insn = &ctx->ir_base[insn->op2]; + if (IR_IS_SYM_CONST(insn->op) || !aarch64_may_encode_imm12(insn->val.u64)) { + constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } } } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); @@ -720,7 +723,7 @@ get_arg_hints: break; case IR_PARAM: constraints->def_reg = ir_get_param_reg(ctx, ref); - flags = 0; + flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0; break; case IR_PI: case IR_PHI: @@ -751,6 +754,10 @@ get_arg_hints: break; case IR_SNAPSHOT: flags = 0; + next = ir_next_control(ctx, ref); + if (ctx->ir_base[next].op == IR_GUARD || ctx->ir_base[next].op == IR_GUARD_NOT) { + flags = IR_EXTEND_INPUTS_TO_NEXT; + } break; case IR_VA_START: flags = IR_OP2_MUST_BE_IN_REG; @@ -1199,10 +1206,6 @@ binop_fp: if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { - // TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP -//??? && (insn->op2 == ref - 1 || -//??? (insn->op2 == ctx->prev_ref[ref] - 1 -//??? && ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; return IR_GUARD_CMP_INT; @@ -1265,6 +1268,12 @@ binop_fp: return IR_FUSED | IR_ARGVAL; case IR_NOP: return IR_SKIPPED | IR_NOP; + case IR_ASM: + case IR_ASM_OUT: + case IR_ASM_GOTO: + fprintf(stderr, "ERROR: IR_ASM is not implemented yet\n"); + exit(1); + return IR_SKIPPED | IR_NOP; default: break; } @@ -4996,7 +5005,8 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); | .addr &addr - if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { + if (ctx->ir_base[bb->start].op1 == def + && ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { bb->flags |= IR_BB_EMPTY; } continue; diff --git a/ext/opcache/jit/ir/ir_builder.h b/ext/opcache/jit/ir/ir_builder.h index 03add7590655..9492945b1362 100644 --- a/ext/opcache/jit/ir/ir_builder.h +++ b/ext/opcache/jit/ir/ir_builder.h @@ -118,31 +118,31 @@ extern "C" { #define ir_MUL_D(_op1, _op2) ir_BINARY_OP_D(IR_MUL, (_op1), (_op2)) #define ir_MUL_F(_op1, _op2) ir_BINARY_OP_F(IR_MUL, (_op1), (_op2)) -#define ir_DIV(_type, _op1, _op2) ir_BINARY_OP(IR_DIV, (_type), (_op1), (_op2)) -#define ir_DIV_U8(_op1, _op2) ir_BINARY_OP_U8(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U16(_op1, _op2) ir_BINARY_OP_U16(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U32(_op1, _op2) ir_BINARY_OP_U32(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U64(_op1, _op2) ir_BINARY_OP_U64(IR_DIV, (_op1), (_op2)) -#define ir_DIV_A(_op1, _op2) ir_BINARY_OP_A(IR_DIV, (_op1), (_op2)) -#define ir_DIV_C(_op1, _op2) ir_BINARY_OP_C(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I8(_op1, _op2) ir_BINARY_OP_I8(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I16(_op1, _op2) ir_BINARY_OP_I16(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I32(_op1, _op2) ir_BINARY_OP_I32(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I64(_op1, _op2) ir_BINARY_OP_I64(IR_DIV, (_op1), (_op2)) +#define ir_DIV(_type, _op1, _op2) _ir_DIV(_ir_CTX, (_type), (_op1), (_op2)) +#define ir_DIV_U8(_op1, _op2) ir_DIV(IR_U8, (_op1), (_op2)) +#define ir_DIV_U16(_op1, _op2) ir_DIV(IR_U16, (_op1), (_op2)) +#define ir_DIV_U32(_op1, _op2) ir_DIV(IR_U32, (_op1), (_op2)) +#define ir_DIV_U64(_op1, _op2) ir_DIV(IR_U64, (_op1), (_op2)) +#define ir_DIV_A(_op1, _op2) ir_DIV(IR_ADDR, (_op1), (_op2)) +#define ir_DIV_C(_op1, _op2) ir_DIV(IR_CHAR, (_op1), (_op2)) +#define ir_DIV_I8(_op1, _op2) ir_DIV(IR_I8, (_op1), (_op2)) +#define ir_DIV_I16(_op1, _op2) ir_DIV(IR_I16, (_op1), (_op2)) +#define ir_DIV_I32(_op1, _op2) ir_DIV(IR_I32, (_op1), (_op2)) +#define ir_DIV_I64(_op1, _op2) ir_DIV(IR_I64, (_op1), (_op2)) #define ir_DIV_D(_op1, _op2) ir_BINARY_OP_D(IR_DIV, (_op1), (_op2)) #define ir_DIV_F(_op1, _op2) ir_BINARY_OP_F(IR_DIV, (_op1), (_op2)) -#define ir_MOD(_type, _op1, _op2) ir_BINARY_OP(IR_MOD, (_type), (_op1), (_op2)) -#define ir_MOD_U8(_op1, _op2) ir_BINARY_OP_U8(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U16(_op1, _op2) ir_BINARY_OP_U16(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U32(_op1, _op2) ir_BINARY_OP_U32(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U64(_op1, _op2) ir_BINARY_OP_U64(IR_MOD, (_op1), (_op2)) -#define ir_MOD_A(_op1, _op2) ir_BINARY_OP_A(IR_MOD, (_op1), (_op2)) -#define ir_MOD_C(_op1, _op2) ir_BINARY_OP_C(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I8(_op1, _op2) ir_BINARY_OP_I8(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I16(_op1, _op2) ir_BINARY_OP_I16(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I32(_op1, _op2) ir_BINARY_OP_I32(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I64(_op1, _op2) ir_BINARY_OP_I64(IR_MOD, (_op1), (_op2)) +#define ir_MOD(_type, _op1, _op2) _ir_MOD(_ir_CTX, (_type), (_op1), (_op2)) +#define ir_MOD_U8(_op1, _op2) ir_MOD(IR_U8, (_op1), (_op2)) +#define ir_MOD_U16(_op1, _op2) ir_MOD(IR_U16, (_op1), (_op2)) +#define ir_MOD_U32(_op1, _op2) ir_MOD(IR_U32, (_op1), (_op2)) +#define ir_MOD_U64(_op1, _op2) ir_MOD(IR_U64, (_op1), (_op2)) +#define ir_MOD_A(_op1, _op2) ir_MOD(IR_ADDR, (_op1), (_op2)) +#define ir_MOD_C(_op1, _op2) ir_MOD(IR_CHAR, (_op1), (_op2)) +#define ir_MOD_I8(_op1, _op2) ir_MOD(IR_I8, (_op1), (_op2)) +#define ir_MOD_I16(_op1, _op2) ir_MOD(IR_I16, (_op1), (_op2)) +#define ir_MOD_I32(_op1, _op2) ir_MOD(IR_I32, (_op1), (_op2)) +#define ir_MOD_I64(_op1, _op2) ir_MOD(IR_I64, (_op1), (_op2)) #define ir_NEG(_type, _op1) ir_UNARY_OP(IR_NEG, (_type), (_op1)) #define ir_NEG_C(_op1) ir_UNARY_OP_C(IR_NEG, (_op1)) @@ -633,6 +633,8 @@ extern "C" { #define ir_MERGE_WITH_EMPTY_TRUE(_if) do {ir_ref end = ir_END(); ir_IF_TRUE(_if); ir_MERGE_2(end, ir_END());} while (0) #define ir_MERGE_WITH_EMPTY_FALSE(_if) do {ir_ref end = ir_END(); ir_IF_FALSE(_if); ir_MERGE_2(end, ir_END());} while (0) +ir_ref _ir_DIV(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2); +ir_ref _ir_MOD(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2); ir_ref _ir_ADD_OFFSET(ir_ctx *ctx, ir_ref addr, uintptr_t offset); ir_ref _ir_PHI_2(ir_ctx *ctx, ir_type type, ir_ref src1, ir_ref src2); ir_ref _ir_PHI_N(ir_ctx *ctx, ir_type type, ir_ref n, ir_ref *inputs); @@ -654,7 +656,7 @@ void _ir_TAILCALL_3(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_re void _ir_TAILCALL_4(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4); void _ir_TAILCALL_5(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5); void _ir_TAILCALL_6(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5, ir_ref arg6); -ir_ref _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args); +void _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args); ir_ref _ir_ALLOCA(ir_ctx *ctx, ir_ref size); void _ir_AFREE(ir_ctx *ctx, ir_ref size); ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var); diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index ca57845a0c7a..80258f7515cc 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -211,6 +211,7 @@ static uint32_t IR_NEVER_INLINE ir_cfg_remove_dead_inputs(ir_ctx *ctx, uint32_t if (life_inputs) { ir_remove_phis_inputs(ctx, &ctx->use_lists[bb->start], insn->inputs_count, life_inputs); ir_mem_free(life_inputs); + life_inputs = NULL; } } } @@ -265,14 +266,14 @@ int ir_build_cfg(ir_ctx *ctx) ir_bitset_incl(bb_leaks, *p); } } - /* Skip control nodes untill BB start */ + /* Skip control nodes until BB start */ ref = insn->op1; while (1) { insn = &ctx->ir_base[ref]; if (IR_IS_BB_START(insn->op)) { break; } - ref = insn->op1; // follow connected control blocks untill BB start + ref = insn->op1; // follow connected control blocks until BB start } /* Mark BB Start */ bb_count++; @@ -305,7 +306,7 @@ int ir_build_cfg(ir_ctx *ctx) IR_ASSERT(IR_IS_BB_START(insn->op)); /* Remember BB start */ start = ref; - /* Skip control nodes untill BB end */ + /* Skip control nodes until BB end */ while (1) { ref = ir_next_control(ctx, ref); insn = &ctx->ir_base[ref]; @@ -613,59 +614,64 @@ static int ir_remove_unreachable_blocks(ir_ctx *ctx) return 1; } -static void compute_postnum(const ir_ctx *ctx, uint32_t *cur, uint32_t b) -{ - uint32_t i, *p; - ir_block *bb = &ctx->cfg_blocks[b]; - - if (bb->postnum != 0) { - return; - } - - if (bb->successors_count) { - bb->postnum = -1; /* Marker for "currently visiting" */ - p = ctx->cfg_edges + bb->successors; - i = bb->successors_count; - do { - compute_postnum(ctx, cur, *p); - p++; - } while (--i); - } - bb->postnum = (*cur)++; -} - /* Computes dominator tree using algorithm from "A Simple, Fast Dominance Algorithm" by * Cooper, Harvey and Kennedy. */ static IR_NEVER_INLINE int ir_build_dominators_tree_slow(ir_ctx *ctx) { - uint32_t blocks_count, b, postnum; + uint32_t blocks_count, b, postnum, i; ir_block *blocks, *bb; uint32_t *edges; + uint32_t *rpo = ir_mem_malloc((ctx->cfg_blocks_count + 1) * sizeof(uint32_t)); bool changed; blocks = ctx->cfg_blocks; edges = ctx->cfg_edges; blocks_count = ctx->cfg_blocks_count; - /* Clear the dominators tree */ - for (b = 0, bb = &blocks[0]; b <= blocks_count; b++, bb++) { - bb->idom = 0; - bb->dom_depth = 0; - bb->dom_child = 0; - bb->dom_next_child = 0; - } - ctx->flags2 &= ~IR_NO_LOOPS; postnum = 1; - compute_postnum(ctx, &postnum, 1); + ir_worklist work; + ir_worklist_init(&work, ctx->cfg_blocks_count + 1); + ir_worklist_push(&work, 1); + IR_ASSERT(blocks[1].next_succ == 0); + while (ir_worklist_len(&work)) { +next: + b = ir_worklist_peek(&work); + bb = &blocks[b]; + uint32_t n = bb->successors_count - bb->next_succ; + if (n) { + uint32_t *p = edges + bb->successors + bb->next_succ; + for (; n > 0; p++, n--) { + uint32_t succ = *p; + if (ir_worklist_push(&work, succ)) { + bb->next_succ = bb->successors_count - n + 1; + IR_ASSERT(blocks[succ].next_succ == 0); + goto next; + } + } + } + + /* Start from bb->idom calculated by the fast dominators algorithm */ + // bb->idom = 0; + bb->next_succ = 0; + rpo[postnum] = b; + bb->postnum = postnum++; + ir_worklist_pop(&work); + } + ir_worklist_free(&work); + + IR_ASSERT(rpo[blocks_count] == 1); /* Find immediate dominators by iterative fixed-point algorithm */ blocks[1].idom = 1; do { changed = 0; + /* Iterating in Reverse Post Order */ - for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { + for (i = blocks_count - 1; i > 0; i--) { + b = rpo[i]; + bb = &blocks[b]; IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); IR_ASSERT(bb->predecessors_count > 0); if (bb->predecessors_count == 1) { @@ -718,6 +724,8 @@ static IR_NEVER_INLINE int ir_build_dominators_tree_slow(ir_ctx *ctx) } } while (changed); + ir_mem_free(rpo); + /* Build dominators tree */ blocks[1].idom = 0; blocks[1].dom_depth = 0; @@ -771,7 +779,7 @@ int ir_build_dominators_tree(ir_ctx *ctx) blocks[1].idom = 1; blocks[1].dom_depth = 0; - /* Iterating in Reverse Post Order */ + /* Iterating in Reverse Post Order (relay on existing BB order and fall-back to slow algorithm) */ for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); IR_ASSERT(bb->predecessors_count > 0); @@ -783,8 +791,8 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (UNEXPECTED(idom >= b)) { /* In rare cases, LOOP_BEGIN.op1 may be a back-edge. Skip back-edges. */ ctx->flags2 &= ~IR_NO_LOOPS; -// IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); if (UNEXPECTED(k <= 1)) { + // IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); slow_case: ir_list_free(&worklist); return ir_build_dominators_tree_slow(ctx); @@ -798,6 +806,7 @@ int ir_build_dominators_tree(ir_ctx *ctx) break; } if (UNEXPECTED(k == 0)) { + // IR_ASSERT(0 && "Wrong blocks order: BB is before all its predecessors"); goto slow_case; } ir_list_push(&worklist, idom); @@ -830,13 +839,6 @@ int ir_build_dominators_tree(ir_ctx *ctx) bb->dom_depth = idom_bb->dom_depth + 1; } - /* Construct children lists sorted by block number */ - for (b = blocks_count, bb = &blocks[b]; b >= 2; b--, bb--) { - ir_block *idom_bb = &blocks[bb->idom]; - bb->dom_next_child = idom_bb->dom_child; - idom_bb->dom_child = b; - } - blocks[1].idom = 0; if (ir_list_len(&worklist) != 0) { @@ -874,10 +876,18 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (UNEXPECTED(!complete)) { ir_list_free(&worklist); + // TODO: this algorithm may be incorrect. Prove and/or switch to ir_build_dominators_tree_slow() ??? return ir_build_dominators_tree_iterative(ctx); } } + /* Construct children lists sorted by block number */ + for (b = blocks_count, bb = &blocks[b]; b >= 2; b--, bb--) { + ir_block *idom_bb = &blocks[bb->idom]; + bb->dom_next_child = idom_bb->dom_child; + idom_bb->dom_child = b; + } + ir_list_free(&worklist); return 1; @@ -898,8 +908,6 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) /* Clear the dominators tree, but keep already found dominators */ for (b = 0, bb = &blocks[0]; b <= blocks_count; b++, bb++) { bb->dom_depth = 0; - bb->dom_child = 0; - bb->dom_next_child = 0; } /* Find immediate dominators by iterative fixed-point algorithm */ @@ -917,20 +925,20 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) if (blocks[idom].idom == 0) { while (1) { k--; + if (UNEXPECTED(k == 0)) break; p++; idom = *p; if (blocks[idom].idom > 0) { break; } - IR_ASSERT(k > 0); } + if (UNEXPECTED(k == 0)) continue; } IR_ASSERT(k != 0); while (--k > 0) { uint32_t pred_b = *(++p); if (blocks[pred_b].idom > 0) { - IR_ASSERT(blocks[pred_b].idom > 0); while (idom != pred_b) { while (pred_b > idom) { pred_b = blocks[pred_b].idom; @@ -1094,35 +1102,36 @@ int ir_find_loops(ir_ctx *ctx) times = ir_mem_malloc((ctx->cfg_blocks_count + 1) * 3 * sizeof(uint32_t)); sorted_blocks = times + (ctx->cfg_blocks_count + 1) * 2; + ir_bitset visited = ir_bitset_malloc(ctx->cfg_blocks_count + 1); ir_worklist_push(&work, 1); - ENTRY_TIME(1) = time++; - while (ir_worklist_len(&work)) { - ir_block *bb; - +next: b = ir_worklist_peek(&work); + ir_block *bb = &blocks[b]; - /* Visit successors of "b". */ -next: - bb = &blocks[b]; - n = bb->successors_count; - if (n) { - uint32_t *p = edges + bb->successors; + if (!ir_bitset_in(visited, b)) { + ir_bitset_incl(visited, b); + ENTRY_TIME(b) = time++; + } + uint32_t n = bb->successors_count - bb->next_succ; + if (n) { + uint32_t *p = edges + bb->successors + bb->next_succ; for (; n > 0; p++, n--) { uint32_t succ = *p; - if (ir_worklist_push(&work, succ)) { - b = succ; - ENTRY_TIME(b) = time++; + bb->next_succ = bb->successors_count - n + 1; + IR_ASSERT(blocks[succ].next_succ == 0); goto next; } } } + bb->next_succ = 0; EXIT_TIME(b) = time++; ir_worklist_pop(&work); } + ir_mem_free(visited); /* Sort blocks by level, which is the opposite order in which we want to process them */ /* (Breadth First Search using "sorted_blocks" as a queue) */ @@ -1493,6 +1502,23 @@ static bool ir_is_merged_loop_back_edge(ir_ctx *ctx, uint32_t hdr, uint32_t b) } #endif +static bool ir_should_align_loop(ir_ctx *ctx, ir_chain *chains, uint32_t b, ir_block *bb) +{ + uint32_t n = bb->predecessors_count; + uint32_t *p = ctx->cfg_edges + bb->predecessors; + + for (; n > 0; p++, n--) { + uint32_t pred = *p; + if (chains[pred].head) { + if (ir_chain_head(chains, pred) == b) return 1; + } else { + if (ir_should_align_loop(ctx, chains, b, &ctx->cfg_blocks[pred])) return 1; + } + } + + return 0; +} + static int ir_schedule_blocks_bottom_up(ir_ctx *ctx) { uint32_t max_edges_count = ctx->cfg_edges_count / 2; @@ -1853,7 +1879,7 @@ static int ir_schedule_blocks_bottom_up(ir_ctx *ctx) if (chains[b].head == b) { bb = &ctx->cfg_blocks[b]; if (bb->loop_depth) { - if ((bb->flags & IR_BB_LOOP_HEADER) || ir_chain_head(chains, bb->loop_header) == b) { + if (ir_should_align_loop(ctx, chains, b, bb)) { bb->flags |= IR_BB_ALIGN_LOOP; } } diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index ee951291b1b0..e1be7f6544df 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -148,6 +148,12 @@ bool ir_check(const ir_ctx *ctx) bool ok = 1; ir_check_ctx check_ctx; + if (ctx->insns_count < 1 || ctx->ir_base[1].op != IR_START) { + fprintf(stderr, "ir_base[1].op invalid opcode (%d)\n", + (ctx->insns_count < 1) ? IR_NOP : ctx->ir_base[0].op); + ok = 0; + } + check_ctx.arena = NULL; check_ctx.use_set = NULL; check_ctx.input_set = NULL; @@ -297,6 +303,14 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } break; + case IR_OPND_CONTROL_GUARD: + if (!(ir_op_flags[use_insn->op] & IR_OP_FLAG_BB_START) + && use_insn->op != IR_GUARD + && use_insn->op != IR_GUARD_NOT) { + fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must be BB_START or GUARD\n", i, j, use); + ok = 0; + } + break; default: fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) of unsupported kind\n", i, j, use); ok = 0; @@ -306,6 +320,8 @@ bool ir_check(const ir_ctx *ctx) /* pass (function returns void) */ } else if (insn->op == IR_BEGIN && j == 1) { /* pass (start of unreachable basic block) */ + } else if (IR_OPND_KIND(flags, j) == IR_OPND_CONTROL_GUARD) { + /* reference to control guard is optional */ } else if (IR_OPND_KIND(flags, j) != IR_OPND_CONTROL_REF && (insn->op != IR_SNAPSHOT || j == 1)) { fprintf(stderr, "ir_base[%d].ops[%d] missing reference (%d)\n", i, j, use); @@ -413,6 +429,7 @@ bool ir_check(const ir_ctx *ctx) } break; case IR_IGOTO: + case IR_ASM_GOTO: break; default: /* skip data references */ @@ -464,6 +481,10 @@ bool ir_check(const ir_ctx *ctx) // if (!ok) { // ir_dump_codegen(ctx, stderr); // } + +#ifndef IR_CHECK_NO_ABORT IR_ASSERT(ok); +#endif + return ok; } diff --git a/ext/opcache/jit/ir/ir_dump.c b/ext/opcache/jit/ir/ir_dump.c index 037003f021a7..3b34294d1c76 100644 --- a/ext/opcache/jit/ir/ir_dump.c +++ b/ext/opcache/jit/ir/ir_dump.c @@ -142,6 +142,7 @@ void ir_dump_dot(const ir_ctx *ctx, const char *name, const char *comments, FILE break; case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "\tn%d -> n%d [style=dashed,dir=back,weight=%d];\n", ref, i, REF_WEIGHT); break; case IR_OPND_LABEL_REF: @@ -650,6 +651,7 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) case IR_OPND_CONTROL: case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "%sl_%d", first ? "(" : ", ", ref); first = 0; break; @@ -680,6 +682,8 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) } else if (opnd_kind == IR_OPND_NUM) { fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; + } else if (opnd_kind == IR_OPND_CONTROL_GUARD) { + /* skip */ } else if (j != n && (IR_IS_REF_OPND_KIND(opnd_kind) || (opnd_kind == IR_OPND_UNUSED && p[n-j]))) { fprintf(f, "%snull", first ? "(" : ", "); diff --git a/ext/opcache/jit/ir/ir_fold.h b/ext/opcache/jit/ir/ir_fold.h index 136bbb0e08e1..cbe049be932c 100644 --- a/ext/opcache/jit/ir/ir_fold.h +++ b/ext/opcache/jit/ir/ir_fold.h @@ -1679,44 +1679,6 @@ IR_FOLD(EQ(SEXT, C_I16)) IR_FOLD(EQ(SEXT, C_I32)) IR_FOLD(EQ(SEXT, C_I64)) IR_FOLD(EQ(SEXT, C_ADDR)) -{ - if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { - /* pass */ - } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { - opt = IR_OPT(IR_NOT, IR_BOOL); - op1 = op1_insn->op1; - op2 = IR_UNUSED; - IR_FOLD_RESTART; - } else { - ir_type type = ctx->ir_base[op1_insn->op1].type; - - if (op1_insn->op == IR_ZEXT - && (op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0) { - IR_FOLD_NEXT; - } - if (IR_IS_TYPE_SIGNED(type)) { - switch (ir_type_size[type]) { - case 1: val.i64 = op2_insn->val.i8; break; - case 2: val.i64 = op2_insn->val.i16; break; - case 4: val.i64 = op2_insn->val.i32; break; - default: val.u64 = op2_insn->val.u64; break; - } - } else { - switch (ir_type_size[type]) { - case 1: val.u64 = op2_insn->val.u8; break; - case 2: val.u64 = op2_insn->val.u16; break; - case 4: val.u64 = op2_insn->val.u32; break; - default: val.u64 = op2_insn->val.u64; break; - } - } - op1 = op1_insn->op1; - op2 = ir_const(ctx, val, type); - IR_FOLD_RESTART; - } - - IR_FOLD_NEXT; -} - IR_FOLD(NE(ZEXT, C_U16)) IR_FOLD(NE(ZEXT, C_U32)) IR_FOLD(NE(ZEXT, C_U64)) @@ -1731,16 +1693,93 @@ IR_FOLD(NE(SEXT, C_I16)) IR_FOLD(NE(SEXT, C_I32)) IR_FOLD(NE(SEXT, C_I64)) IR_FOLD(NE(SEXT, C_ADDR)) -{ - if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { +IR_FOLD(ULT(ZEXT, C_U16)) +IR_FOLD(ULT(ZEXT, C_U32)) +IR_FOLD(ULT(ZEXT, C_U64)) +IR_FOLD(ULT(ZEXT, C_I16)) +IR_FOLD(ULT(ZEXT, C_I32)) +IR_FOLD(ULT(ZEXT, C_I64)) +IR_FOLD(ULT(ZEXT, C_ADDR)) +IR_FOLD(UGE(ZEXT, C_U16)) +IR_FOLD(UGE(ZEXT, C_U32)) +IR_FOLD(UGE(ZEXT, C_U64)) +IR_FOLD(UGE(ZEXT, C_I16)) +IR_FOLD(UGE(ZEXT, C_I32)) +IR_FOLD(UGE(ZEXT, C_I64)) +IR_FOLD(UGE(ZEXT, C_ADDR)) +IR_FOLD(ULE(ZEXT, C_U16)) +IR_FOLD(ULE(ZEXT, C_U32)) +IR_FOLD(ULE(ZEXT, C_U64)) +IR_FOLD(ULE(ZEXT, C_I16)) +IR_FOLD(ULE(ZEXT, C_I32)) +IR_FOLD(ULE(ZEXT, C_I64)) +IR_FOLD(ULE(ZEXT, C_ADDR)) +IR_FOLD(UGT(ZEXT, C_U16)) +IR_FOLD(UGT(ZEXT, C_U32)) +IR_FOLD(UGT(ZEXT, C_U64)) +IR_FOLD(UGT(ZEXT, C_I16)) +IR_FOLD(UGT(ZEXT, C_I32)) +IR_FOLD(UGT(ZEXT, C_I64)) +IR_FOLD(UGT(ZEXT, C_ADDR)) +IR_FOLD(LT(SEXT, C_U16)) +IR_FOLD(LT(SEXT, C_U32)) +IR_FOLD(LT(SEXT, C_U64)) +IR_FOLD(LT(SEXT, C_I16)) +IR_FOLD(LT(SEXT, C_I32)) +IR_FOLD(LT(SEXT, C_I64)) +IR_FOLD(LT(SEXT, C_ADDR)) +IR_FOLD(GE(SEXT, C_U16)) +IR_FOLD(GE(SEXT, C_U32)) +IR_FOLD(GE(SEXT, C_U64)) +IR_FOLD(GE(SEXT, C_I16)) +IR_FOLD(GE(SEXT, C_I32)) +IR_FOLD(GE(SEXT, C_I64)) +IR_FOLD(GE(SEXT, C_ADDR)) +IR_FOLD(LE(SEXT, C_U16)) +IR_FOLD(LE(SEXT, C_U32)) +IR_FOLD(LE(SEXT, C_U64)) +IR_FOLD(LE(SEXT, C_I16)) +IR_FOLD(LE(SEXT, C_I32)) +IR_FOLD(LE(SEXT, C_I64)) +IR_FOLD(LE(SEXT, C_ADDR)) +IR_FOLD(GT(SEXT, C_U16)) +IR_FOLD(GT(SEXT, C_U32)) +IR_FOLD(GT(SEXT, C_U64)) +IR_FOLD(GT(SEXT, C_I16)) +IR_FOLD(GT(SEXT, C_I32)) +IR_FOLD(GT(SEXT, C_I64)) +IR_FOLD(GT(SEXT, C_ADDR)) +{ + if (ctx->use_lists && ctx->use_lists[op1].count != 1) { /* pass */ - } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { - IR_FOLD_COPY(op1_insn->op1); } else { ir_type type = ctx->ir_base[op1_insn->op1].type; - if (op1_insn->op == IR_ZEXT - && (op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0) { + if (type == IR_BOOL && op2_insn->val.u64 == 0) { + if ((opt & IR_OPT_OP_MASK) == IR_EQ) { + opt = IR_OPT(IR_NOT, IR_BOOL); + op1 = op1_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } else if ((opt & IR_OPT_OP_MASK) == IR_NE) { + IR_FOLD_COPY(op1_insn->op1); + } + } + if ((op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0 + && (op1_insn->op != IR_SEXT || (op2_insn->val.i64 >> (ir_type_size[type] * 8)) != -1)) { + if ((opt & IR_OPT_OP_MASK) == IR_EQ + || (opt & IR_OPT_OP_MASK) == IR_UGT + || (opt & IR_OPT_OP_MASK) == IR_UGE) { + IR_FOLD_COPY(IR_FALSE); + } else if ((opt & IR_OPT_OP_MASK) == IR_NE + || (opt & IR_OPT_OP_MASK) == IR_ULT + || (opt & IR_OPT_OP_MASK) == IR_ULE) { + IR_FOLD_COPY(IR_TRUE); + } else if ((opt & IR_OPT_OP_MASK) == IR_GT || (opt & IR_OPT_OP_MASK) == IR_GE) { + IR_FOLD_COPY(op2_insn->val.i64 >= 0 ? IR_FALSE : IR_TRUE); + } else if ((opt & IR_OPT_OP_MASK) == IR_LT || (opt & IR_OPT_OP_MASK) == IR_LE) { + IR_FOLD_COPY(op2_insn->val.i64 >= 0 ? IR_TRUE : IR_FALSE); + } IR_FOLD_NEXT; } if (IR_IS_TYPE_SIGNED(type)) { @@ -1765,6 +1804,43 @@ IR_FOLD(NE(SEXT, C_ADDR)) IR_FOLD_NEXT; } +IR_FOLD(EQ(ZEXT, ZEXT)) +IR_FOLD(NE(ZEXT, ZEXT)) +IR_FOLD(ULT(ZEXT, ZEXT)) +IR_FOLD(UGE(ZEXT, ZEXT)) +IR_FOLD(ULE(ZEXT, ZEXT)) +IR_FOLD(UGT(ZEXT, ZEXT)) +IR_FOLD(EQ(SEXT, SEXT)) +IR_FOLD(NE(SEXT, SEXT)) +IR_FOLD(LT(SEXT, SEXT)) +IR_FOLD(GE(SEXT, SEXT)) +IR_FOLD(LE(SEXT, SEXT)) +IR_FOLD(GT(SEXT, SEXT)) +{ + if (ctx->ir_base[op1_insn->op1].type == ctx->ir_base[op2_insn->op1].type + && (!ctx->use_lists || (ctx->use_lists[op1].count == 1 && ctx->use_lists[op2].count == 1))) { + op1 = op1_insn->op1; + op2 = op2_insn->op1; + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} + +IR_FOLD(LT(ZEXT, ZEXT)) +IR_FOLD(GE(ZEXT, ZEXT)) +IR_FOLD(LE(ZEXT, ZEXT)) +IR_FOLD(GT(ZEXT, ZEXT)) +{ + if (ctx->ir_base[op1_insn->op1].type == ctx->ir_base[op2_insn->op1].type + && (!ctx->use_lists || (ctx->use_lists[op1].count == 1 && ctx->use_lists[op2].count == 1))) { + op1 = op1_insn->op1; + op2 = op2_insn->op1; + opt += 4; /* LT -> ULT, ... */ + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} + IR_FOLD(NOT(EQ)) IR_FOLD(NOT(NE)) IR_FOLD(NOT(LT)) diff --git a/ext/opcache/jit/ir/ir_gcm.c b/ext/opcache/jit/ir/ir_gcm.c index 7edb012f6172..b194eeb81770 100644 --- a/ext/opcache/jit/ir/ir_gcm.c +++ b/ext/opcache/jit/ir/ir_gcm.c @@ -148,7 +148,7 @@ static uint32_t ir_gcm_select_best_block(ir_ctx *ctx, ir_ref ref, uint32_t lca) } #if IR_GCM_SPLIT -/* Partially Dead Code Elimination through splitting the node and sunking the clones +/* Partially Dead Code Elimination through splitting the node and sinking the clones * * This code is based on the Benedikt Meurer's idea first implemented in V8. * See: https://codereview.chromium.org/899433005 @@ -309,6 +309,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) struct { ir_ref ref; uint32_t block; + uint32_t lca; uint32_t use_count; uint32_t use; } *clones = ir_mem_malloc(sizeof(*clones) * use_list->count); @@ -344,8 +345,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) clone = clones_count++; ir_hashtab_add(&hash, j, clone); clones[clone].block = j; + clones[clone].lca = i; clones[clone].use_count = 0; clones[clone].use = (uint32_t)-1; + } else { + clones[clone].lca = ir_gcm_find_lca(ctx, clones[clone].lca, i); } uses[uses_count].ref = use; uses[uses_count].block = i; @@ -367,8 +371,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) clone = clones_count++; ir_hashtab_add(&hash, j, clone); clones[clone].block = j; + clones[clone].lca = i; clones[clone].use_count = 0; clones[clone].use = -1; + } else { + clones[clone].lca = ir_gcm_find_lca(ctx, clones[clone].lca, i); } uses[uses_count].ref = use; uses[uses_count].block = i; @@ -378,6 +385,42 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) } } + /* Select best blocks to insert clones */ + for (i = 0; i < clones_count; i++) { + uint32_t b0 = clones[i].block; + uint32_t lca = clones[i].lca; + + if (b0 != lca) { + ir_block *bb = &ctx->cfg_blocks[lca]; + uint32_t loop_depth = bb->loop_depth; + + if (loop_depth) { + uint32_t b; + uint32_t best; + + best = b = lca; + do { + b = bb->dom_parent; + bb = &ctx->cfg_blocks[b]; + if (bb->loop_depth < loop_depth) { + if (!bb->loop_depth) { + best = b; + break; + } + loop_depth = bb->loop_depth; + best = b; + } + } while (b != b0); + lca = best; + } + clones[i].block = lca; + } + } + + // TODO: instead of inserting clone into the block where the expressin is partially available, + // we should insert PHI and the actual clones into the block sources where it's not available + // (similar to SSAPRE) + #ifdef IR_DEBUG if (ctx->flags & IR_DEBUG_GCM_SPLIT) { for (i = 0; i < clones_count; i++) { @@ -408,8 +451,6 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) } /* Reconstruct IR: Update DEF->USE lists, CFG mapping and etc */ - ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list)); - ctx->cfg_map = ir_mem_realloc(ctx->cfg_map, ctx->insns_count * sizeof(uint32_t)); n = ctx->use_lists[ref].refs; for (i = 0; i < clones_count; i++) { clone = clones[i].ref; @@ -428,6 +469,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) uint32_t u = clones[i].use; while (u != (uint32_t)-1) { + uint32_t src = uses[u].block; use = uses[u].ref; ctx->use_edges[n++] = use; u = uses[u].next; @@ -437,9 +479,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) ir_ref k, l = insn->inputs_count; if (insn->op == IR_PHI) { - for (k = 1; k <= l; k++) { - if (ir_insn_op(insn, k) == ref) { - j = ctx->cfg_map[ir_insn_op(&ctx->ir_base[insn->op1], k - 1)]; + ir_insn *merge = &ctx->ir_base[insn->op1]; + for (k = 2; k <= l; k++) { + j = ctx->cfg_map[ir_insn_op(merge, k - 1)]; + if (j == src) { + IR_ASSERT(ir_insn_op(insn, k) == ref); if (j != clones[i].block) { uint32_t dom_depth = ctx->cfg_blocks[clones[i].block].dom_depth; while (ctx->cfg_blocks[j].dom_depth > dom_depth) { @@ -1169,11 +1213,11 @@ int ir_schedule(ir_ctx *ctx) ir_ref use = *p; ir_insn *use_insn = &ctx->ir_base[use]; if (!_xlat[use] && ctx->cfg_map[use]) { - IR_ASSERT(ctx->cfg_map[use] == b); if (use_insn->op == IR_PARAM || use_insn->op == IR_VAR || use_insn->op == IR_PI || use_insn->op == IR_PHI) { + IR_ASSERT(ctx->cfg_map[use] == b); if (_prev[use] != phis) { /* remove "use" */ _prev[_next[use]] = _prev[use]; diff --git a/ext/opcache/jit/ir/ir_gdb.c b/ext/opcache/jit/ir/ir_gdb.c index 8b5fba6b1533..41141bd28715 100644 --- a/ext/opcache/jit/ir/ir_gdb.c +++ b/ext/opcache/jit/ir/ir_gdb.c @@ -521,6 +521,8 @@ IR_NEVER_INLINE void __jit_debug_register_code(void) static bool ir_gdb_register_code(const void *object, size_t size) { ir_gdbjit_code_entry *entry; + ir_elf_header *elf_header; + ir_elf_sectheader *elf_section, *elf_section_end; entry = malloc(sizeof(ir_gdbjit_code_entry) + size); if (entry == NULL) { @@ -532,6 +534,17 @@ static bool ir_gdb_register_code(const void *object, size_t size) memcpy((char *)entry->symfile_addr, object, size); + elf_header = (ir_elf_header*)entry->symfile_addr; + elf_section = (ir_elf_sectheader*)(entry->symfile_addr + elf_header->shofs); + elf_section_end = (ir_elf_sectheader*)((char*)elf_section + (elf_header->shentsize * elf_header->shnum)); + + while (elf_section < elf_section_end) { + if ((elf_section->flags & ELFSECT_FLAGS_ALLOC) && elf_section->addr == 0) { + elf_section->addr = (uintptr_t)(entry->symfile_addr + elf_section->ofs); + } + elf_section = (ir_elf_sectheader*)((char*)elf_section + elf_header->shentsize); + } + entry->prev_entry = NULL; entry->next_entry = __jit_debug_descriptor.first_entry; diff --git a/ext/opcache/jit/ir/ir_perf.c b/ext/opcache/jit/ir/ir_perf.c index e5a5e5937407..c0561ff86ac1 100644 --- a/ext/opcache/jit/ir/ir_perf.c +++ b/ext/opcache/jit/ir/ir_perf.c @@ -30,7 +30,7 @@ #if defined(__linux__) #include -#elif defined(__darwin__) +#elif defined(__APPLE__) # include #elif defined(__FreeBSD__) # include @@ -215,7 +215,7 @@ int ir_perf_jitdump_register(const char *name, const void *start, size_t size) uint32_t thread_id = 0; #if defined(__linux__) thread_id = syscall(SYS_gettid); -#elif defined(__darwin__) +#elif defined(__APPLE__) uint64_t thread_id_u64; pthread_threadid_np(NULL, &thread_id_u64); thread_id = (uint32_t) thread_id_u64; diff --git a/ext/opcache/jit/ir/ir_private.h b/ext/opcache/jit/ir/ir_private.h index 115c5121d755..3e1051ca3379 100644 --- a/ext/opcache/jit/ir/ir_private.h +++ b/ext/opcache/jit/ir/ir_private.h @@ -949,10 +949,11 @@ IR_ALWAYS_INLINE bool ir_ref_is_true(const ir_ctx *ctx, ir_ref ref) #define IR_OPND_LABEL_REF 0x3 #define IR_OPND_CONTROL_DEP 0x4 #define IR_OPND_CONTROL_REF 0x5 -#define IR_OPND_STR 0x6 -#define IR_OPND_NUM 0x7 -#define IR_OPND_PROB 0x8 -#define IR_OPND_PROTO 0x9 +#define IR_OPND_CONTROL_GUARD 0x6 +#define IR_OPND_STR 0x7 +#define IR_OPND_NUM 0x8 +#define IR_OPND_PROB 0x9 +#define IR_OPND_PROTO 0xa #define IR_OP_FLAGS(op_flags, op1_flags, op2_flags, op3_flags) \ ((op_flags) | ((op1_flags) << 20) | ((op2_flags) << 24) | ((op3_flags) << 28)) @@ -966,7 +967,7 @@ IR_ALWAYS_INLINE bool ir_ref_is_true(const ir_ctx *ctx, ir_ref ref) (((flags) >> (16 + (4 * (((i) > 3) ? 3 : (i))))) & 0xf) #define IR_IS_REF_OPND_KIND(kind) \ - ((kind) >= IR_OPND_DATA && (kind) <= IR_OPND_CONTROL_REF) + ((kind) >= IR_OPND_DATA && (kind) <= IR_OPND_CONTROL_GUARD) IR_ALWAYS_INLINE ir_ref ir_operands_count(const ir_ctx *ctx, const ir_insn *insn) { @@ -1047,7 +1048,6 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref def, ir_ref use); void ir_use_list_replace_all(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use); void ir_use_list_replace_one(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use); bool ir_use_list_add(ir_ctx *ctx, ir_ref def, ir_ref use); -void ir_use_list_sort(ir_ctx *ctx, ir_ref def); IR_ALWAYS_INLINE ir_ref ir_next_control(const ir_ctx *ctx, ir_ref ref) { @@ -1100,6 +1100,7 @@ void ir_iter_add_uses(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist); void ir_iter_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist); void ir_iter_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val, ir_bitqueue *worklist); void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist); +void ir_iter_cleanup(ir_ctx *ctx); /*** IR Basic Blocks info ***/ #define IR_IS_BB_START(op) \ @@ -1145,12 +1146,15 @@ struct _ir_block { }; union { uint32_t dom_depth; /* depth from the root of the dominators tree */ - uint32_t postnum; /* used temporary during tree constructon */ + uint32_t postnum; /* used temporary for iterative Post Ordering */ }; uint32_t dom_child; /* first dominated blocks */ uint32_t dom_next_child; /* next dominated block (linked list) */ uint32_t loop_header; - uint32_t loop_depth; + union { + uint32_t loop_depth; + uint32_t next_succ; /* used temporary for iterative Post Ordering */ + }; }; void ir_build_prev_refs(ir_ctx *ctx); @@ -1220,6 +1224,7 @@ typedef struct _ir_use_pos ir_use_pos; #define IR_USE_SHOULD_BE_IN_REG (1<<1) #define IR_DEF_REUSES_OP1_REG (1<<2) #define IR_DEF_CONFLICTS_WITH_INPUT_REGS (1<<3) +#define IR_EXTEND_INPUTS_TO_NEXT (1<<4) /* used for SNAPSHOT followed by GUARD */ #define IR_FUSED_USE (1<<6) #define IR_PHI_USE (1<<7) diff --git a/ext/opcache/jit/ir/ir_ra.c b/ext/opcache/jit/ir/ir_ra.c index 4a893410d499..f22e06083786 100644 --- a/ext/opcache/jit/ir/ir_ra.c +++ b/ext/opcache/jit/ir/ir_ra.c @@ -799,6 +799,34 @@ int ir_compute_live_ranges(ir_ctx *ctx) ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), IR_REG_NONE, IR_USE_SHOULD_BE_IN_REG, 0); continue; } + } else if (def_flags & IR_EXTEND_INPUTS_TO_NEXT) { + ir_ref next = ir_next_control(ctx, ref); + ir_live_pos use_pos; + + IR_ASSERT(insn->op == IR_SNAPSHOT); + j = 2; + p = insn->ops + 2; + for (; j <= insn->inputs_count; j++, p++) { + ir_ref input = *p; + uint32_t v; + + if (input > 0) { + v = ctx->vregs[input]; + IR_ASSERT(v); + use_pos = IR_USE_LIVE_POS_FROM_REF(next); + if (!ir_bitset_in(live, v)) { + /* live.add(opd) */ + ir_bitset_incl(live, v); + /* intervals[opd].addRange(b.from, op.id) */ + ival = ir_add_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); + } else { + ival = ctx->live_intervals[v]; + } + use_pos = IR_USE_LIVE_POS_FROM_REF(ref); + ir_add_use(ctx, ival, j, use_pos, IR_REG_NONE, 0, IR_UNUSED); + } + } + continue; } IR_ASSERT(insn->op != IR_PHI && (!ctx->rules || !(ctx->rules[ref] & (IR_FUSED|IR_SKIPPED)))); @@ -1418,6 +1446,34 @@ int ir_compute_live_ranges(ir_ctx *ctx) ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), IR_REG_NONE, IR_USE_SHOULD_BE_IN_REG, 0); continue; } + } else if (def_flags & IR_EXTEND_INPUTS_TO_NEXT) { + ir_ref next = ir_next_control(ctx, ref); + ir_live_pos use_pos; + + IR_ASSERT(insn->op == IR_SNAPSHOT); + j = 2; + p = insn->ops + 2; + for (; j <= insn->inputs_count; j++, p++) { + ir_ref input = *p; + uint32_t v; + + if (input > 0) { + v = ctx->vregs[input]; + IR_ASSERT(v); + use_pos = IR_USE_LIVE_POS_FROM_REF(next); + if (!IS_LIVE_IN_BLOCK(v, b)) { + /* live.add(opd) */ + SET_LIVE_IN_BLOCK(v, b); + /* intervals[opd].addRange(b.from, op.id) */ + ival = ir_add_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); + } else { + ival = ctx->live_intervals[v]; + } + use_pos = IR_USE_LIVE_POS_FROM_REF(ref); + ir_add_use(ctx, ival, j, use_pos, IR_REG_NONE, 0, IR_UNUSED); + } + } + continue; } IR_ASSERT(insn->op != IR_PHI && (!ctx->rules || !(ctx->rules[ref] & (IR_FUSED|IR_SKIPPED)))); @@ -3004,6 +3060,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li { ir_live_pos nextUsePos[IR_REG_NUM]; ir_live_pos blockPos[IR_REG_NUM]; + int score, best_score, scores[IR_REG_NUM]; int i, reg; ir_live_pos pos, next_use_pos; ir_live_interval *other, *prev; @@ -3032,6 +3089,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li for (i = IR_REG_FP_FIRST; i <= IR_REG_FP_LAST; i++) { nextUsePos[i] = 0x7fffffff; blockPos[i] = 0x7fffffff; + scores[i] = 0; } } else { available = IR_REGSET_GP; @@ -3050,6 +3108,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li for (i = IR_REG_GP_FIRST; i <= IR_REG_GP_LAST; i++) { nextUsePos[i] = 0x7fffffff; blockPos[i] = 0x7fffffff; + scores[i] = 0; } } @@ -3080,6 +3139,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); if (pos < nextUsePos[reg]) { nextUsePos[reg] = pos; + /* Prefer splitting interval that was already splitted before */ + scores[reg] = (other->flags & IR_LIVE_INTERVAL_SPLIT_CHILD) ? 1 : 0; } } } @@ -3100,6 +3161,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_REGSET_FOREACH(regset, reg) { if (overlap < nextUsePos[reg]) { nextUsePos[reg] = overlap; + scores[reg] = 0; } if (overlap < blockPos[reg]) { blockPos[reg] = overlap; @@ -3113,6 +3175,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li if (other->flags & (IR_LIVE_INTERVAL_FIXED|IR_LIVE_INTERVAL_TEMP)) { if (overlap < nextUsePos[reg]) { nextUsePos[reg] = overlap; + scores[reg] = 0; } if (overlap < blockPos[reg]) { blockPos[reg] = overlap; @@ -3122,6 +3185,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); if (pos < nextUsePos[reg]) { nextUsePos[reg] = pos; + /* Prefer splitting interval that was already splitted before */ + scores[reg] = (other->flags & IR_LIVE_INTERVAL_SPLIT_CHILD) ? 1 : 0; } } } @@ -3141,12 +3206,17 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li /* reg = register with highest nextUsePos */ pos = nextUsePos[reg]; + best_score = (scores[reg] << 28) + nextUsePos[reg]; tmp_regset = available; IR_REGSET_EXCL(tmp_regset, reg); IR_REGSET_FOREACH(tmp_regset, i) { if (nextUsePos[i] > pos) { pos = nextUsePos[i]; + } + score = (scores[i] << 28) + nextUsePos[i]; + if (score > best_score) { reg = i; + best_score = score; } } IR_REGSET_FOREACH_END(); @@ -3190,6 +3260,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li return IR_REG_NONE; } if (split_pos >= blockPos[reg]) { +try_next_available_register: IR_REGSET_EXCL(available, reg); if (IR_REGSET_IS_EMPTY(available)) { fprintf(stderr, "LSRA Internal Error: Unsolvable conflict. Allocation is not possible\n"); @@ -3222,31 +3293,33 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_LOG_LSRA_CONFLICT(" ---- Conflict with active", other, overlap); split_pos = ir_last_use_pos_before(other, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); - if (split_pos == 0) { - split_pos = ival->range.start; - } - split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1); - if (split_pos > other->range.start) { - child = ir_split_interval_at(ctx, other, split_pos); - if (prev) { - prev->list_next = other->list_next; + if (split_pos) { + split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1); + if (split_pos > other->range.start) { + child = ir_split_interval_at(ctx, other, split_pos); + if (prev) { + prev->list_next = other->list_next; + } else { + *active = other->list_next; + } + IR_LOG_LSRA(" ---- Finish", other, ""); } else { - *active = other->list_next; + goto try_next_available_register; } - IR_LOG_LSRA(" ---- Finish", other, ""); } else { child = other; - other->reg = IR_REG_NONE; - if (prev) { - prev->list_next = other->list_next; - } else { - *active = other->list_next; - } - IR_LOG_LSRA(" ---- Spill and Finish", other, " (it must not be in reg)"); } split_pos = ir_first_use_pos_after(child, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG) - 1; // TODO: ??? if (split_pos > child->range.start && split_pos < child->end) { + if (child == other) { + other->reg = IR_REG_NONE; + if (prev) { + prev->list_next = other->list_next; + } else { + *active = other->list_next; + } + } ir_live_pos opt_split_pos = ir_find_optimal_split_position(ctx, child, ival->range.start, split_pos, 1); if (opt_split_pos > child->range.start) { split_pos = opt_split_pos; @@ -3259,6 +3332,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li // TODO: this may cause endless loop ir_add_to_unhandled(unhandled, child); IR_LOG_LSRA(" ---- Queue", child, ""); + } else { + goto try_next_available_register; } } break; diff --git a/ext/opcache/jit/ir/ir_save.c b/ext/opcache/jit/ir/ir_save.c index 3f1d943c6870..8b3f3b5c6b5d 100644 --- a/ext/opcache/jit/ir/ir_save.c +++ b/ext/opcache/jit/ir/ir_save.c @@ -283,7 +283,7 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) n = ir_operands_count(ctx, insn); if ((insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) && n != 2) { fprintf(f, "/%d", n); - } else if ((insn->op == IR_CALL || insn->op == IR_TAILCALL) && n != 2) { + } else if ((insn->op == IR_CALL || insn->op == IR_TAILCALL || insn->op == IR_ASM) && n != 2) { fprintf(f, "/%d", n - 2); } else if (insn->op == IR_PHI && n != 3) { fprintf(f, "/%d", n - 1); @@ -321,6 +321,7 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) case IR_OPND_CONTROL: case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "%sl_%d", first ? "(" : ", ", ref); first = 0; break; @@ -352,6 +353,8 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) } else if (opnd_kind == IR_OPND_NUM) { fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; + } else if (opnd_kind == IR_OPND_CONTROL_GUARD) { + /* skip */ } else if (j != n && (IR_IS_REF_OPND_KIND(opnd_kind) || (opnd_kind == IR_OPND_UNUSED && p[n-j]))) { fprintf(f, "%snull", first ? "(" : ", "); diff --git a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c index 6478ec697562..f2b8616e2afa 100644 --- a/ext/opcache/jit/ir/ir_sccp.c +++ b/ext/opcache/jit/ir/ir_sccp.c @@ -603,12 +603,16 @@ static IR_NEVER_INLINE void ir_sccp_analyze(const ir_ctx *ctx, ir_sccp_val *_val bool may_benefit = 0; bool has_top = 0; - if (_values[i].op != IR_TOP) { + if (_values[i].op != IR_TOP || insn->op == IR_COPY) { may_benefit = 1; } IR_ASSERT(!IR_OP_HAS_VAR_INPUTS(flags)); n = IR_INPUT_EDGES_COUNT(flags); + if (insn->op == IR_DIV || insn->op == IR_MOD) { + /* skip data-control guard edge */ + n--; + } for (p = insn->ops + 1; n > 0; p++, n--) { ir_ref input = *p; if (input > 0) { @@ -987,6 +991,7 @@ static void ir_sccp_remove_if(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref re insn->optx = IR_OPTX(IR_END, IR_VOID, 1); next_insn = &ctx->ir_base[dst]; next_insn->op = IR_BEGIN; + next_insn->op2 = IR_UNUSED; } } @@ -1418,7 +1423,7 @@ static ir_ref ir_iter_find_cse(const ir_ctx *ctx, ir_ref ref, uint32_t opt, ir_r if (!IR_IS_CONST_REF(op2) && (!use_list || use_list->count > ctx->use_lists[op2].count)) { use_list = &ctx->use_lists[op2]; } - if (!IR_IS_CONST_REF(op3) && (!use_list || use_list->count > ctx->use_lists[op3].count)) { + if (op3 > 0 && (!use_list || use_list->count > ctx->use_lists[op3].count)) { use_list = &ctx->use_lists[op3]; } if (use_list) { @@ -1906,6 +1911,46 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, insn->op3 = ir_promote_i2i(ctx, type, insn->op3, ref, worklist); } insn->type = type; + if (IR_IS_TYPE_SIGNED(type)) { + ir_insn *cond = &ctx->ir_base[insn->op1]; + if (cond->op == IR_LT || cond->op == IR_LE || cond->op == IR_GT || cond->op == IR_GE) { + if (cond->op1 == insn->op2 && cond->op2 == insn->op3) { + insn->op = (cond->op == IR_LT || cond->op == IR_LE) ? IR_MIN : IR_MAX; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } else if (cond->op1 == insn->op3 && cond->op2 == insn->op1) { + insn->op = (cond->op == IR_LT || cond->op == IR_LE) ? IR_MAX : IR_MIN; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } + } + } else { + IR_ASSERT(IR_IS_TYPE_UNSIGNED(type)); + ir_insn *cond = &ctx->ir_base[insn->op1]; + if (cond->op == IR_ULT || cond->op == IR_ULE || cond->op == IR_UGT || cond->op == IR_UGE) { + if (cond->op1 == insn->op2 && cond->op2 == insn->op3) { + insn->op = (cond->op == IR_ULT || cond->op == IR_ULE) ? IR_MIN : IR_MAX; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } else if (cond->op1 == insn->op3 && cond->op2 == insn->op1) { + insn->op = (cond->op == IR_ULT || cond->op == IR_ULE) ? IR_MAX : IR_MIN; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } + } + } return ref; case IR_PHI: for (p = insn->ops + 2, n = insn->inputs_count - 1; n > 0; p++, n--) { @@ -1994,7 +2039,7 @@ static uint32_t _ir_estimated_control(const ir_ctx *ctx, ir_ref val, ir_ref loop const ir_ref *p; ir_ref n, input, result, ctrl; - if (IR_IS_CONST_REF(val)) { + if (val <= 0) { /* constant or IR_UNUSED */ return 1; /* IR_START */ } @@ -2128,14 +2173,14 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref const ir_insn *use_insn = &ctx->ir_base[use]; if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) { - if (use_insn->op1 == phi_ref) { + if (use_insn->op1 == op_ref) { if (IR_IS_TYPE_SIGNED(type) != IR_IS_TYPE_SIGNED(ctx->ir_base[use_insn->op2].type)) { return 0; } if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->ir_base[phi_ref].op1, ext_ref, op)) { continue; } - } else if (use_insn->op2 == phi_ref) { + } else if (use_insn->op2 == op_ref) { if (IR_IS_TYPE_SIGNED(type) != IR_IS_TYPE_SIGNED(ctx->ir_base[use_insn->op1].type)) { return 0; } @@ -2520,6 +2565,52 @@ static bool ir_is_zero(const ir_ctx *ctx, ir_ref ref) && ctx->ir_base[ref].val.u32 == 0; } +static bool ir_fix_min_max_const(ir_ctx *ctx, ir_insn *cond, ir_ref ref) +{ + if (cond->op == IR_ULE) { + /* (x <= 3 ? 4 : x) => (x < 4 ? 4 : x) => max(x, 4) */ + /* (x <= 3 ? x : 4) => (x < 4 ? x : 4) => min(x, 4) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 - 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_UGE) { + /* (x >= 3 ? 2 : x) => (x > 2 ? 2 : x) => min(x, 2) */ + /* (x >= 3 ? x : 2) => (x > 2 ? x : 2) => max(x, 2) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 + 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_LE) { + /* (x <= 3 ? 4 : x) => (x < 4 ? 4 : x) => max(x, 4) */ + /* (x <= 3 ? x : 4) => (x < 4 ? x : 4) => min(x, 4) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 - 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_GE) { + /* (x >= 3 ? 2 : x) => (x > 2 ? 2 : x) => min(x, 2) */ + /* (x >= 3 ? x : 2) => (x > 2 ? x : 2) => max(x, 2) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.i64 == ctx->ir_base[ref].val.i64 + 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } + return 0; +} + static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) { IR_ASSERT(insn->inputs_count == 3); @@ -2559,8 +2650,18 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re } if (is_cmp - && ((insn->op2 == cond->op1 && insn->op3 == cond->op2) - || (insn->op2 == cond->op2 && insn->op3 == cond->op1))) { + && ((insn->op2 == cond->op1 + && (insn->op3 == cond->op2 + || (IR_IS_CONST_REF(cond->op2) + && (IR_IS_CONST_REF(insn->op3) + && IR_IS_TYPE_INT(insn->type) + && ir_fix_min_max_const(ctx, cond, insn->op3))))) + || (insn->op3 == cond->op1 + && (insn->op2 == cond->op2 + || (IR_IS_CONST_REF(cond->op2) + && (IR_IS_CONST_REF(insn->op2) + && IR_IS_TYPE_INT(insn->type) + && ir_fix_min_max_const(ctx, cond, insn->op2))))))) { /* MAX/MIN * * prev prev @@ -2611,14 +2712,14 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re next->op1 = root->op1; ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); - if (!IR_IS_CONST_REF(insn->op1)) { - ir_use_list_remove_one(ctx, insn->op1, cond_ref); - } - if (!IR_IS_CONST_REF(insn->op2)) { - ir_use_list_remove_one(ctx, insn->op2, cond_ref); - } if (ctx->use_lists[cond_ref].count == 1) { + if (!IR_IS_CONST_REF(insn->op1)) { + ir_use_list_remove_one(ctx, insn->op1, cond_ref); + } + if (!IR_IS_CONST_REF(insn->op2)) { + ir_use_list_remove_one(ctx, insn->op2, cond_ref); + } MAKE_NOP(cond); CLEAR_USES(cond_ref); } else { ir_use_list_remove_one(ctx, cond_ref, root_ref); @@ -2704,11 +2805,11 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re next->op1 = root->op1; ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); ir_use_list_remove_one(ctx, insn->op1, neg_ref); - if (!IR_IS_CONST_REF(insn->op1)) { - ir_use_list_remove_one(ctx, insn->op1, cond_ref); - } if (ctx->use_lists[cond_ref].count == 1) { + if (!IR_IS_CONST_REF(insn->op1)) { + ir_use_list_remove_one(ctx, insn->op1, cond_ref); + } MAKE_NOP(cond); CLEAR_USES(cond_ref); } else { ir_use_list_remove_one(ctx, cond_ref, root_ref); @@ -2726,7 +2827,16 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re } return 1; - } else if (cond->op != IR_OVERFLOW && insn->op2 <= cond_ref && insn->op3 <= cond_ref) { + } else if (insn->op2 <= root_ref && insn->op3 <= root_ref + && cond->op != IR_OVERFLOW + // TODO: temporary disable IF-conversion for RLOAD. + // We don't track anti-dependencies in GCM and Local Scheduling. + // As result COND may be scheduled below the following RSTORE. + // See: https://github.com/dstogov/ir/issues/132 + && cond->op != IR_RLOAD + && !((cond->op >= IR_EQ && cond->op <= IR_UNORDERED) + && ((!IR_IS_CONST_REF(cond->op1) && ctx->ir_base[cond->op1].op == IR_RLOAD) + || (!IR_IS_CONST_REF(cond->op2) && ctx->ir_base[cond->op2].op == IR_RLOAD)))) { /* COND * * prev prev @@ -2968,9 +3078,11 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_false->op1 = end1_ref; + if_false->op2 = IR_UNUSED; if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_true->op1 = end2_ref; + if_true->op2 = IR_UNUSED; ir_bitqueue_add(worklist, if_false_ref); ir_bitqueue_add(worklist, if_true_ref); @@ -3008,6 +3120,7 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue if_true->optx = IR_BEGIN; if_true->op1 = IR_UNUSED; + if_true->op2 = IR_UNUSED; ctx->flags2 &= ~IR_CFG_REACHABLE; @@ -3157,9 +3270,11 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_false->op1 = end1_ref; + if_false->op2 = IR_UNUSED; if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_true->op1 = end2_ref; + if_true->op2 = IR_UNUSED; ir_bitqueue_add(worklist, if_false_ref); ir_bitqueue_add(worklist, if_true_ref); @@ -3201,6 +3316,7 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_true->optx = IR_BEGIN; if_true->op1 = IR_UNUSED; + if_true->op2 = IR_UNUSED; ctx->flags2 &= ~IR_CFG_REACHABLE; @@ -3421,6 +3537,13 @@ static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref con } } + if (condition_insn->op == IR_SHL && IR_IS_CONST_REF(condition_insn->op1)) { + ir_insn *val_insn = &ctx->ir_base[condition_insn->op1]; + if (!IR_IS_SYM_CONST(val_insn->op) && val_insn->val.u64 == 1) { + return IR_TRUE; + } + } + while ((condition_insn->op == IR_BITCAST || condition_insn->op == IR_ZEXT || condition_insn->op == IR_SEXT) @@ -3487,7 +3610,9 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_true = &ctx->ir_base[if_true_ref]; if_false = &ctx->ir_base[if_false_ref]; if_true->op = IR_BEGIN; + if_true->op2 = IR_UNUSED; if_false->op = IR_BEGIN; + if_false->op2 = IR_UNUSED; if (ir_ref_is_true(ctx, condition)) { if_false->op1 = IR_UNUSED; ir_use_list_remove_one(ctx, ref, if_false_ref); @@ -3750,6 +3875,47 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) } } +void ir_iter_cleanup(ir_ctx *ctx) +{ + ir_bitqueue iter_worklist; + ir_bitqueue cfg_worklist; + ir_ref i, n; + ir_insn *insn; + + ir_bitqueue_init(&cfg_worklist, ctx->insns_count); + ir_bitqueue_init(&iter_worklist, ctx->insns_count); + + /* Remove unused nodes */ + for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) { + if (IR_IS_FOLDABLE_OP(insn->op)) { + if (insn->op != IR_NOP && ctx->use_lists[i].count == 0) { + ir_iter_remove_insn(ctx, i, &iter_worklist); + } + } else if (insn->op == IR_IF || insn->op == IR_MERGE) { + ir_bitqueue_add(&cfg_worklist, i); + } + n = insn->inputs_count; + n = ir_insn_inputs_to_len(n); + i += n; + insn += n; + } + + while ((i = ir_bitqueue_pop(&iter_worklist)) >= 0) { + insn = &ctx->ir_base[i]; + if (IR_IS_FOLDABLE_OP(insn->op)) { + if (ctx->use_lists[i].count == 0) { + ir_iter_remove_insn(ctx, i, &iter_worklist); + } + } + } + + /* Cleanup Control Flow */ + ir_iter_opt(ctx, &cfg_worklist); + + ir_bitqueue_free(&iter_worklist); + ir_bitqueue_free(&cfg_worklist); +} + int ir_sccp(ir_ctx *ctx) { ir_bitqueue sccp_worklist, iter_worklist; diff --git a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc index 049c341cc8fe..ca42001a8816 100644 --- a/ext/opcache/jit/ir/ir_x86.dasc +++ b/ext/opcache/jit/ir/ir_x86.dasc @@ -1273,6 +1273,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co int flags = IR_USE_MUST_BE_IN_REG | IR_OP1_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; const ir_proto_t *proto; const ir_call_conv_dsc *cc; + ir_ref next; constraints->def_reg = IR_REG_NONE; constraints->hints_count = 0; @@ -1345,9 +1346,11 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG | IR_OP2_MUST_BE_IN_REG; op2_const: insn = &ctx->ir_base[ref]; - if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) { - constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); - n++; + if (IR_IS_CONST_REF(insn->op2)) { + if (insn->op1 != insn->op2) { + constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; @@ -1666,7 +1669,7 @@ get_arg_hints: break; case IR_PARAM: constraints->def_reg = ir_get_param_reg(ctx, ref); - flags = 0; + flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0; break; case IR_PI: case IR_PHI: @@ -1712,6 +1715,10 @@ get_arg_hints: break; case IR_SNAPSHOT: flags = 0; + next = ir_next_control(ctx, ref); + if (ctx->ir_base[next].op == IR_GUARD || ctx->ir_base[next].op == IR_GUARD_NOT) { + flags = IR_EXTEND_INPUTS_TO_NEXT; + } break; case IR_VA_START: flags = IR_OP2_MUST_BE_IN_REG; @@ -3078,10 +3085,6 @@ store_int: if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { - // TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP -//??? && (insn->op2 == ref - 1 || -//??? (insn->op2 == ctx->prev_ref[ref] - 1 -//??? && ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op) @@ -3262,6 +3265,12 @@ store_int: return IR_FUSED | IR_ARGVAL; case IR_NOP: return IR_SKIPPED | IR_NOP; + case IR_ASM: + case IR_ASM_OUT: + case IR_ASM_GOTO: + fprintf(stderr, "ERROR: IR_ASM is not implemented yet\n"); + exit(1); + return IR_SKIPPED | IR_NOP; default: break; } @@ -9429,7 +9438,8 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); | .aword &addr - if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { + if (ctx->ir_base[bb->start].op1 == def + && ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { bb->flags |= IR_BB_EMPTY; } continue; diff --git a/ext/opcache/jit/tls/zend_jit_tls.h b/ext/opcache/jit/tls/zend_jit_tls.h index 5f9042926725..7faa76fa6a31 100644 --- a/ext/opcache/jit/tls/zend_jit_tls.h +++ b/ext/opcache/jit/tls/zend_jit_tls.h @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Arnaud Le Blanc | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ */ #ifndef ZEND_JIT_TLS_H diff --git a/ext/opcache/jit/tls/zend_jit_tls_aarch64.c b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c index 24f0f88454b6..80d19090312f 100644 --- a/ext/opcache/jit/tls/zend_jit_tls_aarch64.c +++ b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Arnaud Le Blanc | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ */ #include "Zend/zend_portability.h" @@ -126,7 +124,9 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets( "add %2, x8, x0\n" : "=r" (thread_pointer), "=r" (insn), "=r" (addr) : - : "x0", "x1", "x8"); + /* Resolver call clobbers only a few registers: https://github.com/ARM-software/abi-aa/blob/ee4b3c12d57c8424ff60c2ae56e10690d0604ab6/sysvabi64/sysvabi64.rst#calling-convention. + * We also clobber x8. */ + : "x0", "x1", "x8", "x30", "cc", "memory"); ZEND_ASSERT(addr == &_tsrm_ls_cache); diff --git a/ext/opcache/jit/tls/zend_jit_tls_darwin.c b/ext/opcache/jit/tls/zend_jit_tls_darwin.c index ee8a572e04a0..8857ef5e738c 100644 --- a/ext/opcache/jit/tls/zend_jit_tls_darwin.c +++ b/ext/opcache/jit/tls/zend_jit_tls_darwin.c @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Dmitry Stogov | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ */ #include "Zend/zend_portability.h" diff --git a/ext/opcache/jit/tls/zend_jit_tls_win.c b/ext/opcache/jit/tls/zend_jit_tls_win.c index 23f0c1e79baa..5646f3dcba0b 100644 --- a/ext/opcache/jit/tls/zend_jit_tls_win.c +++ b/ext/opcache/jit/tls/zend_jit_tls_win.c @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Dmitry Stogov | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ */ #include "Zend/zend_portability.h" diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86.c b/ext/opcache/jit/tls/zend_jit_tls_x86.c index 4e06bbd1eacd..dae644ab7b7d 100644 --- a/ext/opcache/jit/tls/zend_jit_tls_x86.c +++ b/ext/opcache/jit/tls/zend_jit_tls_x86.c @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Arnaud Le Blanc | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ */ #include "zend_portability.h" @@ -110,6 +108,12 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets( /* Load thread pointer address */ "movl %%gs:0, %%ebx\n" : "=a" (t_addr), "=S" (code), "=b" (thread_pointer) + : + /* call may clobber volatile registers */ + : "ecx", "edx", + "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "cc", "memory" ); ZEND_ASSERT(t_addr == &_tsrm_ls_cache); diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c index 11ffe495fcbb..f3495505c524 100644 --- a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c +++ b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c @@ -1,19 +1,17 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Arnaud Le Blanc | - * +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ */ #include "zend_portability.h" @@ -102,10 +100,18 @@ zend_result zend_jit_resolve_tsrm_ls_cache_offsets( "leaq _tsrm_ls_cache@tlsgd(%%rip), %%rdi\n" ".word 0x6666\n" "rex64\n" - "call __tls_get_addr\n" + "call __tls_get_addr@PLT\n" /* Load thread pointer address */ "movq %%fs:0, %%rsi\n" : "=a" (addr), "=b" (code), "=S" (thread_pointer) + : + /* call may clobber volatile registers */ + : "rcx", "rdx", "rdi", + "r8", "r9", "r10", "r11", + "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "cc", "memory" ); ZEND_ASSERT(addr == &_tsrm_ls_cache); diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 3ffb669e8474..cb2791fb45ac 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -42,8 +40,10 @@ #include "jit/zend_jit_internal.h" -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT +#include #include +#include #endif #ifdef ZTS @@ -78,9 +78,7 @@ int zend_jit_profile_counter_rid = -1; int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT]; const zend_op *zend_jit_halt_op = NULL; -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP -static int zend_write_protect = 1; -#endif +const zend_op *zend_jit_interrupt_op = NULL; static void *dasm_buf = NULL; static void *dasm_end = NULL; @@ -115,7 +113,7 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array); static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, zend_call_info *call_info); static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t op2_info); -static bool dominates(const zend_basic_block *blocks, int a, int b) { +static bool dominates(const zend_basic_block *blocks, uint32_t a, uint32_t b) { while (blocks[b].level > blocks[a].level) { b = blocks[b].idom; } @@ -138,9 +136,9 @@ static bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ssa * if (ssa->cfg.blocks[ssa->cfg.map[use]].loop_header > 0 || (ssa->cfg.blocks[ssa->cfg.map[use]].flags & ZEND_BB_LOOP_HEADER)) { - int b = ssa->cfg.map[use]; + uint32_t b = ssa->cfg.map[use]; int prev_use = ssa->vars[var].use_chain; - int def_block; + uint32_t def_block; if (ssa->vars[var].definition >= 0) { def_block =ssa->cfg.map[ssa->vars[var].definition]; @@ -303,6 +301,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_DO_FCALL_BY_NAME: case ZEND_DO_FCALL: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: return 0; case ZEND_SEND_VAL: case ZEND_SEND_VAR: @@ -388,6 +387,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_DO_FCALL_BY_NAME: case ZEND_DO_FCALL: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: end = opline; if (end - op_array->opcodes >= ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len) { /* INIT_FCALL and DO_FCALL in different BasicBlocks */ @@ -867,6 +867,7 @@ static bool zend_jit_dec_call_level(uint8_t opcode) case ZEND_DO_UCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: + case ZEND_CALLABLE_CONVERT_PARTIAL: return true; default: return false; @@ -880,13 +881,13 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array) if (op_array->function_name) { smart_str_appends(&buf, JIT_PREFIX); if (op_array->scope) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->scope->name), ZSTR_LEN(op_array->scope->name)); + smart_str_append(&buf, op_array->scope->name); smart_str_appends(&buf, "::"); } - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); if (op_array->fn_flags & ZEND_ACC_CLOSURE) { smart_str_appends(&buf, ":"); - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); smart_str_appends(&buf, ":"); smart_str_append_long(&buf, op_array->line_start); } @@ -894,7 +895,7 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array) return buf.s; } else if (op_array->filename) { smart_str_appends(&buf, JIT_PREFIX); - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); smart_str_0(&buf); return buf.s; } else { @@ -1173,7 +1174,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * for (i = 0; i < ssa->vars_count; i++) { if (ssa->vars[i].definition_phi && !ssa->vars[i].no_val) { zend_ssa_phi *phi = ssa->vars[i].definition_phi; - int k, src; + int src; if (phi->pi >= 0) { src = phi->sources[0]; @@ -1188,6 +1189,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * } } else { int need_move = 0; + uint32_t k; for (k = 0; k < ssa->cfg.blocks[phi->block].predecessors_count; k++) { src = phi->sources[k]; @@ -1342,7 +1344,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * static int zend_jit_compute_post_order(zend_cfg *cfg, int start, int *post_order) { int count = 0; - int b, n, *p; + int b, *p; zend_basic_block *bb; zend_worklist worklist; ALLOCA_FLAG(use_heap) @@ -1354,7 +1356,7 @@ static int zend_jit_compute_post_order(zend_cfg *cfg, int start, int *post_order next: b = zend_worklist_peek(&worklist); bb = &cfg->blocks[b]; - n = bb->successors_count; + uint32_t n = bb->successors_count; if (n > 0) { p = bb->successors; do { @@ -1410,7 +1412,7 @@ static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t return (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG); case ZEND_CONCAT: return (op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -2890,7 +2892,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (i == end && (opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { /* smart branch split across basic blocks */ - if (!zend_jit_set_cond(&ctx, opline + 2, opline->result.var)) { + if (!zend_jit_set_cond(&ctx, opline, opline + 2, opline->result.var)) { goto jit_failure; } } @@ -3517,17 +3519,14 @@ int zend_jit_script(zend_script *script) void zend_jit_unprotect(void) { -#ifdef HAVE_MPROTECT +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT + pthread_jit_write_protect_np(0); +#elif defined(HAVE_MPROTECT) if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { int opts = PROT_READ | PROT_WRITE; -#ifdef ZTS -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - if (zend_write_protect) { - pthread_jit_write_protect_np(0); - } -#endif +# ifdef ZTS opts |= PROT_EXEC; -#endif +# endif if (mprotect(dasm_buf, dasm_size, opts) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); } @@ -3535,11 +3534,11 @@ void zend_jit_unprotect(void) #elif defined(_WIN32) if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { DWORD old, new; -#ifdef ZTS +# ifdef ZTS new = PAGE_EXECUTE_READWRITE; -#else +# else new = PAGE_READWRITE; -#endif +# endif if (!VirtualProtect(dasm_buf, dasm_size, new, &old)) { DWORD err = GetLastError(); char *msg = php_win32_error_to_msg(err); @@ -3552,13 +3551,10 @@ void zend_jit_unprotect(void) void zend_jit_protect(void) { -#ifdef HAVE_MPROTECT +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT + pthread_jit_write_protect_np(1); +#elif defined(HAVE_MPROTECT) if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - if (zend_write_protect) { - pthread_jit_write_protect_np(1); - } -#endif if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_EXEC) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); } @@ -3777,22 +3773,39 @@ int zend_jit_check_support(void) void zend_jit_startup(void *buf, size_t size, bool reattached) { zend_jit_halt_op = zend_get_halt_op(); + zend_jit_interrupt_op = zend_get_interrupt_op(); zend_jit_profile_counter_rid = zend_get_op_array_extension_handle(ACCELERATOR_PRODUCT_NAME); -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - zend_write_protect = pthread_jit_write_protect_supported_np(); +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT + buf = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0); + if (buf == MAP_FAILED) { + int error = errno; + zend_accel_error_noreturn(ACCEL_LOG_FATAL, + "Unable to allocate %zu bytes for JIT buffer using MAP_JIT: %s (%d)", + size, strerror(error), error); + } + if (minherit(buf, size, VM_INHERIT_SHARE) != 0) { + int error = errno; + munmap(buf, size); + zend_accel_error_noreturn(ACCEL_LOG_FATAL, + "Unable to share JIT buffer across fork using minherit(): %s (%d)", + strerror(error), error); + } + if (!pthread_jit_write_protect_supported_np()) { + munmap(buf, size); + zend_accel_error_noreturn(ACCEL_LOG_FATAL, + "Apple Silicon ZTS JIT requires pthread_jit_write_protect_np() support"); + } #endif dasm_buf = buf; dasm_size = size; dasm_ptr = dasm_end = (void*)(((char*)dasm_buf) + size - sizeof(*dasm_ptr) * 2); -#ifdef HAVE_MPROTECT -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - if (zend_write_protect) { - pthread_jit_write_protect_np(1); - } -#endif +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT + pthread_jit_write_protect_np(1); +#elif defined(HAVE_MPROTECT) if (JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP)) { if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); @@ -3873,6 +3886,12 @@ void zend_jit_shutdown(void) zend_jit_trace_free_caches(&jit_globals); #endif +#ifdef ZEND_JIT_USE_APPLE_MAP_JIT + if (dasm_buf != NULL) { + munmap(dasm_buf, dasm_size); + } +#endif + /* Reset global pointers to prevent use-after-free in `zend_jit_status()` * after gracefully restarting Apache with mod_php, see: * https://github.com/php/php-src/pull/19212 */ diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 9b8e054d2292..c4080d86bc6d 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -19,6 +17,13 @@ #ifndef HAVE_JIT_H #define HAVE_JIT_H +#if defined(__APPLE__) && defined(__aarch64__) && defined(ZTS) +# ifndef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP +# error "Apple Silicon ZTS JIT requires pthread_jit_write_protect_np()" +# endif +# define ZEND_JIT_USE_APPLE_MAP_JIT 1 +#endif + #if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32) # define ZEND_JIT_TARGET_X86 1 # define ZEND_JIT_TARGET_ARM64 0 diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 59bb9401d9a9..660a17c05687 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -1976,7 +1974,7 @@ static bool ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, zend_arg_info *arg zend_execute_data *execute_data = EG(current_execute_data); const zend_op *opline = EX(opline); bool ret = zend_check_user_type_slow( - &arg_info->type, arg, /* ref */ NULL, /* is_return_type */ false); + &arg_info->type, arg, /* ref */ NULL, /* current_frame */ false); if (UNEXPECTED(!ret)) { zend_verify_arg_error(EX(func), arg_info, opline->op1.num, arg); return false; @@ -1993,7 +1991,7 @@ static void ZEND_FASTCALL zend_jit_verify_return_slow(zval *arg, const zend_op_a } } if (UNEXPECTED(!zend_check_user_type_slow( - &arg_info->type, arg, /* ref */ NULL, /* is_return_type */ true))) { + &arg_info->type, arg, /* ref */ NULL, /* current_frame */ true))) { zend_verify_return_error((zend_function*)op_array, arg); } } @@ -2285,7 +2283,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( } } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 1; } diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 22bab1ddd7ff..7b5f93f70db7 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -177,6 +175,7 @@ typedef struct _zend_jit_op_array_hot_extension { zend_jit_hash((op_array)->opcodes) extern const zend_op *zend_jit_halt_op; +extern const zend_op *zend_jit_interrupt_op; #ifdef HAVE_GCC_GLOBAL_REGS # define EXECUTE_DATA_D void diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 19b3ce125733..8f6804cb8915 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -1,21 +1,20 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Dmitry Stogov | - * +----------------------------------------------------------------------+ - */ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ +*/ +#include "Zend/zend_cpuinfo.h" #include "Zend/zend_types.h" #include "Zend/zend_type_info.h" #include "jit/ir/ir.h" @@ -859,12 +858,14 @@ void *zend_jit_snapshot_handler(ir_ctx *ctx, ir_ref snapshot_ref, ir_insn *snaps t->stack_map[t->exit_info[exit_point].stack_offset + var].flags = ZREG_TYPE_ONLY; } else { if ((exit_flags & ZEND_JIT_EXIT_FIXED) - && t->stack_map[t->exit_info[exit_point].stack_offset + var].reg != IR_REG_NUM(reg)) { + && (t->stack_map[t->exit_info[exit_point].stack_offset + var].reg != IR_REG_NUM(reg) + || (t->stack_map[t->exit_info[exit_point].stack_offset + var].flags & ~(ZREG_LOAD|ZREG_STORE|ZREG_LAST_USE)))) { exit_point = zend_jit_duplicate_exit_point(ctx, t, exit_point, snapshot_ref); addr = (void*)zend_jit_trace_get_exit_addr(exit_point); exit_flags &= ~ZEND_JIT_EXIT_FIXED; } t->stack_map[t->exit_info[exit_point].stack_offset + var].reg = IR_REG_NUM(reg); + t->stack_map[t->exit_info[exit_point].stack_offset + var].flags &= (ZREG_LOAD|ZREG_STORE|ZREG_LAST_USE); } } else { if ((exit_flags & ZEND_JIT_EXIT_FIXED) @@ -874,6 +875,7 @@ void *zend_jit_snapshot_handler(ir_ctx *ctx, ir_ref snapshot_ref, ir_insn *snaps addr = (void*)zend_jit_trace_get_exit_addr(exit_point); exit_flags &= ~ZEND_JIT_EXIT_FIXED; } + t->stack_map[t->exit_info[exit_point].stack_offset + var].reg = ZREG_NONE; t->stack_map[t->exit_info[exit_point].stack_offset + var].flags = ZREG_TYPE_ONLY; } } else if (!(exit_flags & ZEND_JIT_EXIT_FIXED)) { @@ -1478,8 +1480,7 @@ static void zend_jit_gen_phi(zend_jit_ctx *jit, zend_ssa_phi *phi) { int dst_var = phi->ssa_var; zend_basic_block *bb = &jit->ssa->cfg.blocks[phi->block]; - int n = bb->predecessors_count; - int i; + uint32_t n = bb->predecessors_count; ir_type type = (jit->ssa->var_info[phi->ssa_var].type & MAY_BE_LONG) ? IR_LONG : IR_DOUBLE; ir_ref merge = jit->bb_start_ref[phi->block]; ir_ref ref; @@ -1496,7 +1497,7 @@ static void zend_jit_gen_phi(zend_jit_ctx *jit, zend_ssa_phi *phi) ref = ir_emit_N(&jit->ctx, IR_OPT(IR_PHI, type), n + 1); ir_set_op(&jit->ctx, ref, 1, merge); - for (i = 0; i < n; i++) { + for (uint32_t i = 0; i < n; i++) { int src_var = phi->sources[i]; ZEND_ASSERT(jit->ra[src_var].ref); @@ -3315,6 +3316,27 @@ static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context) static void zend_jit_setup_unwinder(void) { +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + /* TAILCALL VM: fixed_save_regset=0, no registers pushed in prologue. + * fixed_stack_frame_size=40, fixed_call_stack_size=48 (16+IR_SHADOW_ARGS). + * Prologue is: sub rsp, 0x58 (88 bytes = 40+48). */ + static const unsigned char uw_data[] = { + 0x01, // Version=1, Flags=0 + 0x04, // Size of prolog (sub rsp,imm8 = 4 bytes: 48 83 ec 58) + 0x01, // Count of unwind codes + 0x00, // Frame Register=none + 0x04, 0xa2, // offset 4: UWOP_ALLOC_SMALL info=10, alloc=(10+1)*8=88 + 0x00, 0x00, // padding + }; + /* Exit call variant: base 88 + 304 (shadow+GP+FP+padding) = 392 (0x188) */ + static const unsigned char uw_data_exitcall[] = { + 0x01, // Version=1, Flags=0 + 0x07, // Size of prolog (sub rsp,imm32 = 7 bytes: 48 81 ec 88 01 00 00) + 0x02, // Count of unwind codes + 0x00, // Frame Register=none + 0x07, 0x01, 0x31, 0x00, // offset 7: UWOP_ALLOC_LARGE info=0, size/8=49, alloc=392 + }; +#else /* Hardcoded SEH unwind data for JIT-ed PHP functions with "fixed stack frame" */ static const unsigned char uw_data[] = { 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags @@ -3349,6 +3371,7 @@ static void zend_jit_setup_unwinder(void) 0x02, 0x50, // 1: pushq %rbp 0x01, 0x30, // 0: pushq %rbx }; +#endif zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr; *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 + @@ -3396,7 +3419,7 @@ static void zend_jit_setup(bool reattached) if (zend_cpu_supports_avx()) { allowed_opt_flags |= ZEND_JIT_CPU_AVX; } -# if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000) +# ifdef HAVE_ZEND_CPU_SUPPORTS_CLDEMOTE if (zend_cpu_supports_cldemote()) { default_mflags |= IR_X86_CLDEMOTE; } @@ -3497,7 +3520,7 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir_ref ref) { - int i, *p; + int *p; zend_basic_block *bb; ir_ref *r, header; @@ -3505,7 +3528,7 @@ static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir bb = &jit->ssa->cfg.blocks[b]; p = &jit->ssa->cfg.predecessors[bb->predecessor_offset]; r = &jit->bb_edges[jit->bb_predecessors[b]]; - for (i = 0; i < bb->predecessors_count; i++, p++, r++) { + for (uint32_t i = 0; i < bb->predecessors_count; i++, p++, r++) { if (*p == pred) { ZEND_ASSERT(*r == IR_UNUSED || *r == ref); header = jit->bb_start_ref[b]; @@ -3720,14 +3743,14 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ static int zend_jit_bb_start(zend_jit_ctx *jit, int b) { zend_basic_block *bb; - int i, n, *p, pred; + int *p, pred; ir_ref ref, bb_start; ZEND_ASSERT(JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE); ZEND_ASSERT(b < jit->ssa->cfg.blocks_count); bb = &jit->ssa->cfg.blocks[b]; ZEND_ASSERT((bb->flags & ZEND_BB_REACHABLE) != 0); - n = bb->predecessors_count; + uint32_t n = bb->predecessors_count; if (n == 0) { /* pass */ @@ -3797,6 +3820,7 @@ static int zend_jit_bb_start(zend_jit_ctx *jit, int b) entry_path = ir_END(); } pred_refs = (ir_ref *)do_alloca(sizeof(ir_ref) * n, use_heap); + uint32_t i; for (i = 0, p = jit->ssa->cfg.predecessors + bb->predecessor_offset; i < n; p++, i++) { pred = *p; if (jit->bb_start_ref[pred]) { @@ -3966,11 +3990,12 @@ static int zend_jit_cond_jmp(zend_jit_ctx *jit, const zend_op *next_opline, int return 1; } -static int zend_jit_set_cond(zend_jit_ctx *jit, const zend_op *next_opline, uint32_t var) +static int zend_jit_set_cond(zend_jit_ctx *jit, const zend_op *opline, const zend_op *next_opline, uint32_t var) { ir_ref ref; - ref = ir_ADD_U32(ir_ZEXT_U32(jit_CMP_IP(jit, IR_EQ, next_opline)), ir_CONST_U32(IS_FALSE)); + ir_op op = (opline->result_type & IS_SMART_BRANCH_JMPZ) ? IR_EQ : IR_NE; + ref = ir_ADD_U32(ir_ZEXT_U32(jit_CMP_IP(jit, op, next_opline)), ir_CONST_U32(IS_FALSE)); // EX_VAR(var) = ... ir_STORE(ir_ADD_OFFSET(jit_FP(jit), var + offsetof(zval, u1.type_info)), ref); @@ -4685,7 +4710,7 @@ static struct jit_observer_fcall_is_unobserved_data jit_observer_fcall_is_unobse ir_ref observer_handler_user = ir_ADD_OFFSET(run_time_cache, zend_observer_fcall_op_array_extension * sizeof(void *)); ir_MERGE_WITH(if_internal_func_end); - *observer_handler = ir_PHI_2(IR_ADDR, observer_handler_internal, observer_handler_user); + *observer_handler = ir_PHI_2(IR_ADDR, observer_handler_user, observer_handler_internal); } // JIT: if (*observer_handler == ZEND_OBSERVER_NONE_OBSERVED) { @@ -7949,7 +7974,7 @@ static int zend_jit_defined(zend_jit_ctx *jit, const zend_op *opline, uint8_t sm return 1; } -static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, int8_t reg) +static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, const zend_op_array *op_array, int8_t reg) { zend_jit_addr reg_addr = ZEND_ADDR_REF_ZVAL(zend_jit_deopt_rload(jit, IR_ADDR, reg)); ir_ref if_def = ir_IF(jit_Z_TYPE(jit, reg_addr)); @@ -7972,7 +7997,18 @@ static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, } jit_LOAD_IP_ADDR(jit, opline - 1); - ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_escape)); + + /* We can't use trace_escape() because opcode handler may be overridden by JIT */ + zend_jit_op_array_trace_extension *jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); + size_t offset = jit_extension->offset; + ir_ref ref = ir_CONST_FC_FUNC(ZEND_OP_TRACE_INFO((opline - 1), offset)->orig_handler); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + ir_TAILCALL(IR_OPCODE_HANDLER_RET, ref); + } else { + ir_ref opline_ref = ir_CALL_2(IR_OPCODE_HANDLER_RET, ref, jit_FP(jit), jit_IP(jit)); + zend_jit_vm_enter(jit, opline_ref); + } ir_IF_TRUE(if_def); @@ -10078,7 +10114,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } bool may_have_extra_named_params = - opline->extended_value == ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS && + (opline->extended_value & ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS) && (!func || func->common.fn_flags & ZEND_ACC_VARIADIC); if (!jit->reuse_ip) { @@ -10208,10 +10244,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen && ZEND_MAP_PTR_IS_OFFSET(func->op_array.run_time_cache)) { run_time_cache = ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_CG(map_ptr_base)), (uintptr_t)ZEND_MAP_PTR(func->op_array.run_time_cache))); - } else if ((func && (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) || - (JIT_G(current_frame) && - JIT_G(current_frame)->call && - TRACE_FRAME_IS_CLOSURE_CALL(JIT_G(current_frame)->call))) { + } else if (func && (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { /* Closures always use direct pointers */ ir_ref local_func_ref = func_ref ? func_ref : ir_LOAD_A(jit_CALL(rx, func)); @@ -10408,28 +10441,19 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if (ZEND_OBSERVER_ENABLED && (!func || (func->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_GENERATOR)) == 0)) { ir_ref observer_handler; ir_ref rx = jit_FP(jit); + const zend_op *observer_opline = NULL; struct jit_observer_fcall_is_unobserved_data unobserved_data = jit_observer_fcall_is_unobserved_start(jit, func, &observer_handler, rx, func_ref); if (trace && (trace->op != ZEND_JIT_TRACE_END || trace->stop < ZEND_JIT_TRACE_STOP_INTERPRETER)) { ZEND_ASSERT(trace[1].op == ZEND_JIT_TRACE_VM || trace[1].op == ZEND_JIT_TRACE_END); - jit_SET_EX_OPLINE(jit, trace[1].opline); + observer_opline = trace[1].opline; + jit_SET_EX_OPLINE(jit, observer_opline); } else { // EX(opline) = opline ir_STORE(jit_EX(opline), jit_IP(jit)); } jit_observer_fcall_begin(jit, rx, observer_handler); - if (trace) { - int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); - - exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } - } else { - exit_addr = NULL; - } - - zend_jit_check_timeout(jit, NULL /* we're inside the called function */, exit_addr); + zend_jit_check_timeout(jit, observer_opline, NULL); jit_observer_fcall_is_unobserved_end(jit, &unobserved_data); } @@ -10902,7 +10926,7 @@ static int zend_jit_recv_init(zend_jit_ctx *jit, const zend_op *opline, const ze zv, true); } - if (Z_CONSTANT_P(zv)) { + if (Z_TYPE_P(zv) == IS_CONSTANT_AST) { jit_SET_EX_OPLINE(jit, opline); ref = ir_CALL_2(IR_I32, ir_CONST_FC_FUNC(zval_update_constant_ex), jit_ZVAL_ADDR(jit, res_addr), @@ -14212,6 +14236,26 @@ static int zend_jit_class_guard(zend_jit_ctx *jit, const zend_op *opline, ir_ref return 1; } +static int zend_jit_func_arg_by_ref_guard(zend_jit_ctx *jit, const zend_op *opline) +{ + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + ir_ref rx, call_info; + + if (!exit_addr) { + return 0; + } + if (jit->reuse_ip) { + rx = jit_IP(jit); + } else { + rx = ir_LOAD_A(jit_EX(call)); + } + call_info = ir_LOAD_U32(jit_CALL(rx, This.u1.type_info)); + ir_GUARD_NOT(ir_AND_U32(call_info, ir_CONST_U32(ZEND_CALL_SEND_ARG_BY_REF)), + ir_CONST_ADDR(exit_addr)); + return 1; +} + static int zend_jit_fetch_obj(zend_jit_ctx *jit, const zend_op *opline, const zend_op_array *op_array, @@ -16067,7 +16111,7 @@ static int zend_jit_fetch_static_prop(zend_jit_ctx *jit, const zend_op *opline, case ZEND_FETCH_STATIC_PROP_UNSET: fetch_type = BP_VAR_UNSET; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } // JIT: result = CACHED_PTR(cache_slot + sizeof(void *)); @@ -16686,7 +16730,7 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend_ssa *ssa) { - int i, count; + uint32_t i, count; zend_basic_block *bb; zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : (IR_START_BR_TARGET|IR_ENTRY_BR_TARGET)); @@ -17679,7 +17723,9 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa, } if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { - int def_block, use_block, b, use, j; + uint32_t def_block, use_block; + int b, use; + uint32_t j; zend_basic_block *bb; zend_ssa_phi *p; bool ret = true; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 82e173ba4994..505427890129 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -258,14 +256,14 @@ static zend_string *zend_jit_trace_name(const zend_op_array *op_array, uint32_t smart_str_appendc(&buf, '$'); if (op_array->function_name) { if (op_array->scope) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->scope->name), ZSTR_LEN(op_array->scope->name)); + smart_str_append(&buf, op_array->scope->name); smart_str_appends(&buf, "::"); - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); } else { - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); } } else if (op_array->filename) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); } smart_str_appendc(&buf, '$'); smart_str_append_long(&buf, (zend_long)lineno); @@ -2361,6 +2359,9 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin if (ssa_ops[idx].op2_use >= 0 && ssa_ops[idx].op2_def >= 0) { ssa_var_info[ssa_ops[idx].op2_def] = ssa_var_info[ssa_ops[idx].op2_use]; } + if (ssa_ops[idx].result_use >= 0 && ssa_ops[idx].result_def >= 0) { + ssa_var_info[ssa_ops[idx].result_def] = ssa_var_info[ssa_ops[idx].result_use]; + } } else { if (zend_update_type_info(op_array, tssa, script, (zend_op*)opline, ssa_ops + idx, ssa_opcodes, optimization_level) == FAILURE) { // TODO: @@ -3570,6 +3571,8 @@ static int zend_jit_trace_deoptimization( } } } else if (STACK_FLAGS(parent_stack, i) == ZREG_TYPE_ONLY) { + ZEND_ASSERT(reg == ZREG_NONE); + uint8_t type = STACK_TYPE(parent_stack, i); if (!zend_jit_store_type(jit, i, type)) { @@ -3649,7 +3652,7 @@ static int zend_jit_trace_deoptimization( ZEND_ASSERT(STACK_FLAGS(parent_stack, check2) == ZREG_ZVAL_COPY); ZEND_ASSERT(reg != ZREG_NONE); - if (!zend_jit_escape_if_undef(jit, check2, flags, opline, reg)) { + if (!zend_jit_escape_if_undef(jit, check2, flags, opline, exit_info->op_array, reg)) { return 0; } if (!zend_jit_restore_zval(jit, EX_NUM_TO_VAR(check2), reg)) { @@ -3953,7 +3956,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, uint32_t opline_num, uint32_t var_num) { - int ssa_var, j, b = ssa->cfg.map[opline_num]; + int ssa_var, b = ssa->cfg.map[opline_num]; const zend_basic_block *bb = ssa->cfg.blocks + b; const zend_ssa_phi *phi; const zend_ssa_op *ssa_op; @@ -3997,7 +4000,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, ZEND_WORKLIST_ALLOCA(&worklist, ssa->cfg.blocks_count, use_heap); - for (j = 0; j < bb->predecessors_count; j++) { + for (uint32_t j = 0; j < bb->predecessors_count; j++) { b = ssa->cfg.predecessors[bb->predecessor_offset + j]; zend_worklist_push(&worklist, b); } @@ -4038,7 +4041,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, if (ssa_var >= 0) { goto found; } - for (j = 0; j < bb->predecessors_count; j++) { + for (uint32_t j = 0; j < bb->predecessors_count; j++) { b = ssa->cfg.predecessors[bb->predecessor_offset + j]; zend_worklist_push(&worklist, b); } @@ -5218,7 +5221,7 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, && ssa->vars[ssa_op->op2_def].use_chain < 0 && !ssa->vars[ssa_op->op2_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -5271,7 +5274,7 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, && ssa->vars[ssa_op->op1_def].use_chain < 0 && !ssa->vars[ssa_op->op1_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -5368,7 +5371,7 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, && ssa->vars[ssa_op->op1_def].use_chain < 0 && !ssa->vars[ssa_op->op1_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -6036,10 +6039,15 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, case ZEND_FETCH_OBJ_FUNC_ARG: if (!JIT_G(current_frame) || !JIT_G(current_frame)->call - || !JIT_G(current_frame)->call->func - || !TRACE_FRAME_IS_LAST_SEND_BY_VAL(JIT_G(current_frame)->call)) { + || TRACE_FRAME_IS_LAST_SEND_BY_REF(JIT_G(current_frame)->call)) { break; } + if (!JIT_G(current_frame)->call->func + || !TRACE_FRAME_IS_LAST_SEND_BY_VAL(JIT_G(current_frame)->call)) { + if (!zend_jit_func_arg_by_ref_guard(&ctx, opline)) { + goto jit_failure; + } + } ZEND_FALLTHROUGH; case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_IS: @@ -6627,7 +6635,7 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, var_num = EX_VAR_TO_NUM(var_num); if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -7266,7 +7274,7 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, && type != STACK_MEM_TYPE(stack, i) && zend_jit_trace_must_store_type(op_array, op_array_ssa, opline - op_array->opcodes, i, type)) { if (!zend_jit_store_type(jit, i, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, i, type, 1); } @@ -7387,11 +7395,11 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, zend_string_release(name); } +jit_cleanup:; } zend_catch { do_bailout = 1; } zend_end_try(); -jit_cleanup: /* Clean up used op_arrays */ while (num_op_arrays > 0) { op_array = op_arrays[--num_op_arrays]; @@ -8570,7 +8578,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 do { ex = ex->prev_execute_data; n++; - } while (ex && zend_jit_traces[root].op_array != &ex->func->op_array); + } while (ex && (!ex->func || zend_jit_traces[root].op_array != &ex->func->op_array)); if (ex && n <= ZEND_JIT_TRACE_MAX_RET_DEPTH) { ret_depth = n; } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index bed5ab59992e..b01c3aaac62e 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -980,6 +978,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, } } break; + case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_FETCH_OBJ_R: { if (opline->op2_type == IS_CONST) { /* Remove the SIMPLE_GET flag to avoid inlining hooks. */ @@ -994,7 +993,6 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, case ZEND_FETCH_OBJ_W: case ZEND_FETCH_OBJ_RW: case ZEND_FETCH_OBJ_IS: - case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_FETCH_OBJ_UNSET: case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_OBJ_OP: @@ -1059,7 +1057,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, 0, func); } } else if (opline->opcode == ZEND_INCLUDE_OR_EVAL - || opline->opcode == ZEND_CALLABLE_CONVERT) { + || opline->opcode == ZEND_CALLABLE_CONVERT + || opline->opcode == ZEND_CALLABLE_CONVERT_PARTIAL) { /* TODO: Support tracing JIT for ZEND_CALLABLE_CONVERT. */ stop = ZEND_JIT_TRACE_STOP_INTERPRETER; break; @@ -1072,6 +1071,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (UNEXPECTED(opline == zend_jit_halt_op)) { #else opline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + while (UNEXPECTED(opline == zend_jit_interrupt_op)) { + opline = zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } +# endif if (UNEXPECTED(((uintptr_t)opline & ~ZEND_VM_ENTER_BIT) == 0)) { #endif if (prev_opline->opcode == ZEND_YIELD || prev_opline->opcode == ZEND_YIELD_FROM) { @@ -1097,6 +1101,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (UNEXPECTED(!jit_extension) || UNEXPECTED(!(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE))) { if (execute_data->prev_execute_data != prev_execute_data) { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } else { stop = ZEND_JIT_TRACE_STOP_INTERPRETER; } break; diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c index cf5dbb29ebfd..a805912d0d75 100644 --- a/ext/opcache/shared_alloc_mmap.c +++ b/ext/opcache/shared_alloc_mmap.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/shared_alloc_posix.c b/ext/opcache/shared_alloc_posix.c index 3f1e097fe97c..36ed7950044f 100644 --- a/ext/opcache/shared_alloc_posix.c +++ b/ext/opcache/shared_alloc_posix.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/shared_alloc_shm.c b/ext/opcache/shared_alloc_shm.c index b9f8ca4524a0..e98ac615f860 100644 --- a/ext/opcache/shared_alloc_shm.c +++ b/ext/opcache/shared_alloc_shm.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index c51c459ed553..84bd32e9cbad 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/tests/gh20469.phpt b/ext/opcache/tests/gh20469.phpt new file mode 100644 index 000000000000..1cd826c177ef --- /dev/null +++ b/ext/opcache/tests/gh20469.phpt @@ -0,0 +1,134 @@ +--TEST-- +GH-20469: Inheritance cache with reentrant autoloading must not crash +--EXTENSIONS-- +opcache +--CONFLICTS-- +server +--FILE-- + ParentBeingLinked -> CovariantReturnWithTrait + * -> RequiresRootReturnTrait -> ChildOfParentBeingLinked. + */ +file_put_contents($dir . '/test1.php', <<<'PHP' + +--CLEAN-- +isDir()) { + rmdir($file->getPathname()); + } else { + unlink($file->getPathname()); + } + } + rmdir($dir); +} +?> +--EXPECT-- +3 +3 diff --git a/ext/opcache/tests/gh20469_child_variance_resolves_parent.phpt b/ext/opcache/tests/gh20469_child_variance_resolves_parent.phpt new file mode 100644 index 000000000000..4a66c3b0513d --- /dev/null +++ b/ext/opcache/tests/gh20469_child_variance_resolves_parent.phpt @@ -0,0 +1,181 @@ +--TEST-- +GH-20469: Child delayed variance can resolve parent before direct delayed resolution +--DESCRIPTION-- +This variant ensures the cacheability check after load_delayed_classes() is +needed. Loading the delayed child resolves the parent class's variance +obligations reentrantly, so the parent no longer has ZEND_ACC_UNRESOLVED_VARIANCE +when control returns from load_delayed_classes(). The parent was still used while +nearly linked, and must not be inserted into the inheritance cache. +--EXTENSIONS-- +opcache +--CONFLICTS-- +server +--FILE-- + CovariantReturnWithTrait -> RequiresRootReturnTrait + * -> ChildOfParentBeingLinked -> ParentBeingLinked. + * + * ChildOfParentBeingLinked also has delayed variance, so resolving the child's + * dependency on ParentBeingLinked can resolve ParentBeingLinked before it + * reaches its direct resolve_delayed_variance_obligations() call. + */ +file_put_contents($dir . '/test1.php', <<<'PHP' +test()); +PHP); + +file_put_contents($dir . '/test3.php', <<<'PHP' +test()); +PHP); + +file_put_contents($dir . '/classes/RootForTraitReturn.php', <<<'PHP' + +--CLEAN-- +isDir()) { + rmdir($file->getPathname()); + } else { + unlink($file->getPathname()); + } + } + rmdir($dir); +} +?> +--EXPECT-- +3 +3NULL +3NULL diff --git a/ext/opcache/tests/gh20469_inheritance_cache_cleanup.phpt b/ext/opcache/tests/gh20469_inheritance_cache_cleanup.phpt new file mode 100644 index 000000000000..aabbc398cbc3 --- /dev/null +++ b/ext/opcache/tests/gh20469_inheritance_cache_cleanup.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20469: Skipped inheritance cache cleanup must ignore non-cacheable classes +--DESCRIPTION-- +Autoloading the parent makes the child use the runtime class-linking path, but +the child does not enter inheritance-cache construction. Under ASAN, the +uninitialized inheritance_cache field is filled with non-zero bytes. Skipped +cache insertion must not treat that value as a temporary dependency table. +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +ok diff --git a/ext/opcache/tests/gh20469_inherited_method.phpt b/ext/opcache/tests/gh20469_inherited_method.phpt new file mode 100644 index 000000000000..f3c038bdc330 --- /dev/null +++ b/ext/opcache/tests/gh20469_inherited_method.phpt @@ -0,0 +1,138 @@ +--TEST-- +GH-20469: Inheritance cache with reentrant autoloading must preserve inherited methods +--EXTENSIONS-- +opcache +--CONFLICTS-- +server +--FILE-- + ParentBeingLinked -> CovariantReturnWithTrait + * -> RequiresRootReturnTrait -> ChildOfParentBeingLinked. + */ +file_put_contents($dir . '/test1.php', <<<'PHP' +test()); +PHP); + +file_put_contents($dir . '/classes/RootForTraitReturn.php', <<<'PHP' + +--CLEAN-- +isDir()) { + rmdir($file->getPathname()); + } else { + unlink($file->getPathname()); + } + } + rmdir($dir); +} +?> +--EXPECT-- +3 +3NULL diff --git a/ext/opcache/tests/gh21691.phpt b/ext/opcache/tests/gh21691.phpt new file mode 100644 index 000000000000..3926b76c7a12 --- /dev/null +++ b/ext/opcache/tests/gh21691.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-21691 (OPcache CFG optimizer breaks reference returns with JMPZ/JMPZ_EX) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +NULL diff --git a/ext/opcache/tests/gh21770.phpt b/ext/opcache/tests/gh21770.phpt new file mode 100644 index 000000000000..d2fd52a4712b --- /dev/null +++ b/ext/opcache/tests/gh21770.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-21770 (Infinite recursion in property hook getter in opcache preloaded trait) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.preload={PWD}/preload_gh21770.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +a, "\n"; + +$c = new C(); +$c->x = 42; +var_dump($c->x); +?> +--EXPECT-- +a +int(42) diff --git a/ext/opcache/tests/gh22071.phpt b/ext/opcache/tests/gh22071.phpt new file mode 100644 index 000000000000..148ca461be21 --- /dev/null +++ b/ext/opcache/tests/gh22071.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-22071: Assertion failure jit_CONST_FUNC_PROTO on abstract static method call +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1205 +opcache.jit_buffer_size=16M +--FILE-- + +--EXPECT-- +ok diff --git a/ext/opcache/tests/jit/gh13400.phpt b/ext/opcache/tests/jit/gh13400.phpt new file mode 100644 index 000000000000..db3d7b755761 --- /dev/null +++ b/ext/opcache/tests/jit/gh13400.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-13400: JIT code generated after fork is visible to the parent +--DESCRIPTION-- +OPcache metadata and generated JIT code are shared by forked workers, so the +JIT mapping and its allocation pointer must remain shared after fork. This test +records the available JIT space before forking and makes only the child call a +function often enough to generate code. The parent then verifies that it sees +the reduced free space and can execute the generated function. + +Without shared inheritance, a private JIT mapping becomes copy-on-write in the +child. The parent's free-space check would print bool(false), while shared +OPcache metadata could point the parent at code bytes that exist only in the +child and cause a crash instead of printing int(42). A startup-only test would +not detect this failure in fork-based SAPIs such as FPM or Apache. +--EXTENSIONS-- +opcache +pcntl +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit=tracing +opcache.jit_buffer_size=16M +opcache.jit_hot_func=1 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +int(42) diff --git a/ext/opcache/tests/jit/gh21006.phpt b/ext/opcache/tests/jit/gh21006.phpt new file mode 100644 index 000000000000..a201391505ab --- /dev/null +++ b/ext/opcache/tests/jit/gh21006.phpt @@ -0,0 +1,79 @@ +--TEST-- +GH-21006: JIT SEGV with FETCH_OBJ_FUNC_ARG and property hooks +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_hot_loop=1 +opcache.jit_hot_func=1 +opcache.jit_hot_return=1 +opcache.jit_hot_side_exit=1 +--FILE-- + 'sha256'; + } + + public function sign() + { + return hash_hmac( + algo: $this->prop, + data: '', + key: '', + ); + } +} + +$obj = new C(); +for ($i = 0; $i < 100; $i++) { + $obj->sign(); +} + +#[\AllowDynamicProperties] +class D +{ + public function test() + { + return hash_hmac( + algo: $this->algo, + data: '', + key: '', + ); + } +} + +$d = new D(); +$d->algo = 'sha256'; +for ($i = 0; $i < 100; $i++) { + $d->test(); +} + +class E +{ + public $prop { + get => []; + } + + public function sign() + { + (new Trampoline)->f($this->prop); + } +} + +class Trampoline +{ + public function __call($name, $args) {} +} + +$e = new E(); +for ($i = 0; $i < 100; $i++) { + $e->sign(); +} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21158.phpt b/ext/opcache/tests/jit/gh21158.phpt new file mode 100644 index 000000000000..89afd058c665 --- /dev/null +++ b/ext/opcache/tests/jit/gh21158.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-21158: Assertion jit->ra[var].flags & (1<<0) failed in zend_jit_use_reg +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1254 +--FILE-- += 0 && $col - 1 >= 0 && $board[$row - 1][$col - 1] == 1) $live_neighbors++; + if ($row >= 1 && $col + 1 < COL && $board[$row - 1][$col + 1] == 1) $live_neighbors++; + return $live_neighbors; +} +$board = [ + [1,1,0,0,1,1,1,1,1,0], + [0,1,0,1,1,0,0,1,0,0], + [0,1,0,0,1,0,0,0,1,0], + [0,0,1,1,1,1,1,0,0,0], + [1,1,1,1,1,1,0,1,1,0], + [0,1,0,0,1,1,1,0,1,0], + [0,1,1,0,1,1,1,1,0,0], + [1,1,0,0,0,0,1,1,1,0], + [1,0,0,1,1,0,1,1,0,1], + [0,0,1,1,1,0,1,1,0,1], +]; +for ($i = 0; $i < ROW; $i++) { + for ($j = 0; $j < COL; $j++) { + echo count_live_neighbors($board, $i, $j), ","; + } + echo "\n"; +} +?> +--EXPECT-- +1,0,0,1,1,1,1,1,0,0, +2,1,2,2,1,2,3,2,1,1, +2,0,2,2,1,1,1,1,1,0, +1,1,2,2,1,2,0,1,0,1, +1,2,2,3,3,2,2,2,0,0, +2,2,2,3,3,2,2,2,1,1, +2,1,1,2,2,3,2,2,0,1, +2,1,1,2,1,3,3,2,1,0, +1,1,2,1,0,2,2,2,2,1, +0,2,2,2,1,3,2,1,3,0, diff --git a/ext/opcache/tests/jit/gh21267.phpt b/ext/opcache/tests/jit/gh21267.phpt new file mode 100644 index 000000000000..91c8de29c2bf --- /dev/null +++ b/ext/opcache/tests/jit/gh21267.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property in polymorphic context) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_hot_loop=0 +opcache.jit_hot_func=2 +opcache.jit_hot_return=0 +opcache.jit_hot_side_exit=1 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21267_blacklist.phpt b/ext/opcache/tests/jit/gh21267_blacklist.phpt new file mode 100644 index 000000000000..3ec222dc4250 --- /dev/null +++ b/ext/opcache/tests/jit/gh21267_blacklist.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF via blacklisted trace exit) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_hot_loop=0 +opcache.jit_hot_func=2 +opcache.jit_hot_return=0 +opcache.jit_hot_side_exit=1 +opcache.jit_max_side_traces=0 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21368_call_vm.phpt b/ext/opcache/tests/jit/gh21368_call_vm.phpt new file mode 100644 index 000000000000..cc64e62a610e --- /dev/null +++ b/ext/opcache/tests/jit/gh21368_call_vm.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21368 (JIT escape_if_undef SEGV on CALL VM with aggressive trace counters) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=64M +opcache.jit=tracing +opcache.protect_memory=1 +opcache.jit_hot_loop=1 +opcache.jit_hot_func=1 +opcache.jit_hot_return=1 +opcache.jit_hot_side_exit=1 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21593.phpt b/ext/opcache/tests/jit/gh21593.phpt new file mode 100644 index 000000000000..d37500195737 --- /dev/null +++ b/ext/opcache/tests/jit/gh21593.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-21593: Function JIT JMPNZ smart branch +--CREDITS-- +paulmhh +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=function +--FILE-- +a)) { + echo "1\n"; + } +} + +function test2($a) { + if (!isset($a?->a)) { + echo "2\n"; + } +} + +function test3($a) { + if (empty($a?->a)) { + echo "3\n"; + } +} + +function test4($a) { + if (!empty($a?->a)) { + echo "4\n"; + } +} + +$a = new stdClass; +$a->a = 'a'; + +test1($a); +test2($a); +test3($a); +test4($a); + +?> +--EXPECT-- +1 +4 diff --git a/ext/opcache/tests/jit/gh21746.inc b/ext/opcache/tests/jit/gh21746.inc new file mode 100644 index 000000000000..b118625484d0 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.inc @@ -0,0 +1,16 @@ + ''; + $e = fn() => ''; + $f = fn() => ''; + $g = fn() => ''; + return '' + .LR::p(null, '', null, [], '') + .LR::hbbch([null], $d) + .LR::hbbch([null], $e) + .LR::hbbch([null], $f) + .LR::hbbch([null], $g); +}; diff --git a/ext/opcache/tests/jit/gh21746.phpt b/ext/opcache/tests/jit/gh21746.phpt new file mode 100644 index 000000000000..29b3be778be7 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.phpt @@ -0,0 +1,112 @@ +--TEST-- +GH-21746: Segfault with tracing JIT on 2nd call of eval'd closure +--CREDITS-- +theodorejb +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=tracing +--FILE-- + $_) { if ($i === 0) break; } + return $result; + } + public static function hbbch(array $positional, ?\Closure $cb): string { + if ($cb && is_array($positional[0] ?? null)) foreach ($positional[0] as $v) $cb($v); + return ''; + } +} + +$renderFile = __DIR__ . '/gh21746.inc'; + +// prevent JITing $renderFile +ini_set('opcache.file_update_protection', 100); +touch($renderFile); + +$renderer = require $renderFile; + +for ($r = 0; $r < 70; $r++) { + echo "Render $r..."; + $renderer(); + echo "OK\n"; +} + +?> +==DONE== +--EXPECT-- +Render 0...OK +Render 1...OK +Render 2...OK +Render 3...OK +Render 4...OK +Render 5...OK +Render 6...OK +Render 7...OK +Render 8...OK +Render 9...OK +Render 10...OK +Render 11...OK +Render 12...OK +Render 13...OK +Render 14...OK +Render 15...OK +Render 16...OK +Render 17...OK +Render 18...OK +Render 19...OK +Render 20...OK +Render 21...OK +Render 22...OK +Render 23...OK +Render 24...OK +Render 25...OK +Render 26...OK +Render 27...OK +Render 28...OK +Render 29...OK +Render 30...OK +Render 31...OK +Render 32...OK +Render 33...OK +Render 34...OK +Render 35...OK +Render 36...OK +Render 37...OK +Render 38...OK +Render 39...OK +Render 40...OK +Render 41...OK +Render 42...OK +Render 43...OK +Render 44...OK +Render 45...OK +Render 46...OK +Render 47...OK +Render 48...OK +Render 49...OK +Render 50...OK +Render 51...OK +Render 52...OK +Render 53...OK +Render 54...OK +Render 55...OK +Render 56...OK +Render 57...OK +Render 58...OK +Render 59...OK +Render 60...OK +Render 61...OK +Render 62...OK +Render 63...OK +Render 64...OK +Render 65...OK +Render 66...OK +Render 67...OK +Render 68...OK +Render 69...OK +==DONE== diff --git a/ext/opcache/tests/jit/gh22004.phpt b/ext/opcache/tests/jit/gh22004.phpt new file mode 100644 index 000000000000..bb60868a269f --- /dev/null +++ b/ext/opcache/tests/jit/gh22004.phpt @@ -0,0 +1,63 @@ +--TEST-- +GH-22004: ZEND_FE_FETCH_R with key operand +--CREDITS-- +YuanchengJiang +--FILE-- + $line) { + } + } +} +$iter = 20; +doRandom($iter); + +?> +==DONE== +--EXPECTF-- +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d +==DONE== diff --git a/ext/opcache/tests/jit/gh22158.phpt b/ext/opcache/tests/jit/gh22158.phpt new file mode 100644 index 000000000000..ce7f9bc55938 --- /dev/null +++ b/ext/opcache/tests/jit/gh22158.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-22158 (Tracing JIT dispatches observer begin handler through the wrong run_time_cache slot on megamorphic calls) +--EXTENSIONS-- +opcache +zend_test +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=32M +opcache.jit_max_polymorphic_calls=0 +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +zend_test.observer.show_output=0 +zend_test.observer.reserve_op_array_handle=1 +--FILE-- +f(); +} +echo $t, "\n"; +?> +--EXPECT-- +600000 diff --git a/ext/opcache/tests/jit/gh22443.phpt b/ext/opcache/tests/jit/gh22443.phpt new file mode 100644 index 000000000000..4baa3f99fc61 --- /dev/null +++ b/ext/opcache/tests/jit/gh22443.phpt @@ -0,0 +1,57 @@ +--TEST-- +GH-22443 (SIGSEGV in tracing JIT: run_time_cache offset stored without map_ptr dereference) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_max_polymorphic_calls=0 +--FILE-- +helper((int) array_sum($a)); } + private function helper(int $x): int { return $x + 1; } +} + +function makeListener($listener): Closure { + return function ($event, $payload) use ($listener) { + return $listener(...array_values($payload)); + }; +} + +function invokeListeners(array $listeners, string $event, array $payload): int { + $r = 0; + foreach ($listeners as $l) { + $r += $l($event, $payload); + } + return $r; +} + +$svc = new Svc(); +$warm = []; +for ($k = 0; $k < 8; $k++) { + $warm[] = makeListener([$svc, 'm' . $k]); +} +$cold = [makeListener([$svc, 'coldMethod'])]; + +$s = 0; +for ($i = 0; $i < 400; $i++) { + $s += invokeListeners($warm, 'e', [$i & 7, ($i >> 2) & 7]); +} +for ($j = 0; $j < 5; $j++) { + $s += invokeListeners($cold, 'e', [$j, $j + 1]); +} +echo "done\n"; +?> +--EXPECT-- +done diff --git a/ext/opcache/tests/jit/gh22763.phpt b/ext/opcache/tests/jit/gh22763.phpt new file mode 100644 index 000000000000..67d7caa308ed --- /dev/null +++ b/ext/opcache/tests/jit/gh22763.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-22763: JIT fails to clear ZREG_TYPE_ONLY after setting reg +--FILE-- += -$d && $kf <= $d && $vf[$offset + $kf] + $vb[$offset + $k] >= $n) { + return [$n - $x, $m - $y, $n - $xs, $m - $ys]; + } + } + } + + return []; +} + +$from = [3,2,1]; +$to = [1,99,3]; +findMiddleSnake($from, 0, count($from), $to, 0, count($to)); +?> +--EXPECTF-- +int(0) + +Warning: Undefined array key 3 in %s on line %d diff --git a/ext/opcache/tests/opt/gh21972.phpt b/ext/opcache/tests/opt/gh21972.phpt new file mode 100644 index 000000000000..f34f9b45ccf2 --- /dev/null +++ b/ext/opcache/tests/opt/gh21972.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-21972: Typed by-value return must not leak reference wrapper +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +string(6) "string" +string(5) "false" +string(5) "false" diff --git a/ext/opcache/tests/preload_gh21770.inc b/ext/opcache/tests/preload_gh21770.inc new file mode 100644 index 000000000000..7433a15eca92 --- /dev/null +++ b/ext/opcache/tests/preload_gh21770.inc @@ -0,0 +1,20 @@ + $this->a; + } +} + +trait X { + public int $x = 0 { + set(int $value) => $value; + } +} + +class B { + use A; +} + +class C { + use X; +} diff --git a/ext/opcache/zend_accelerator_api.c b/ext/opcache/zend_accelerator_api.c index 27267e8791ab..907b6b96e705 100644 --- a/ext/opcache/zend_accelerator_api.c +++ b/ext/opcache/zend_accelerator_api.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/opcache/zend_accelerator_api.h b/ext/opcache/zend_accelerator_api.h index 4ea42f29d174..002a69eee9f3 100644 --- a/ext/opcache/zend_accelerator_api.h +++ b/ext/opcache/zend_accelerator_api.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index 631f8b34608f..ed03a82e9f3f 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -227,7 +225,7 @@ static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist) { if (blacklist->pos == blacklist->size) { blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE; - blacklist->entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size); + blacklist->entries = (zend_blacklist_entry *) perealloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size, true); } } diff --git a/ext/opcache/zend_accelerator_blacklist.h b/ext/opcache/zend_accelerator_blacklist.h index da6e04e31b7c..4a337dd9814b 100644 --- a/ext/opcache/zend_accelerator_blacklist.h +++ b/ext/opcache/zend_accelerator_blacklist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_debug.c b/ext/opcache/zend_accelerator_debug.c index b2a3105dc627..418ef805d633 100644 --- a/ext/opcache/zend_accelerator_debug.c +++ b/ext/opcache/zend_accelerator_debug.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_debug.h b/ext/opcache/zend_accelerator_debug.h index 4a19da57b5e6..d71a48893871 100644 --- a/ext/opcache/zend_accelerator_debug.h +++ b/ext/opcache/zend_accelerator_debug.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_hash.c b/ext/opcache/zend_accelerator_hash.c index 5198c0b3b78c..e35528f7f414 100644 --- a/ext/opcache/zend_accelerator_hash.c +++ b/ext/opcache/zend_accelerator_hash.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h index 2f9197385386..6091361a68c8 100644 --- a/ext/opcache/zend_accelerator_hash.h +++ b/ext/opcache/zend_accelerator_hash.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 1eaa183f9df5..465b15cd9576 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h index 6eff0624bbbf..cd46e07d1d27 100644 --- a/ext/opcache/zend_accelerator_module.h +++ b/ext/opcache/zend_accelerator_module.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 2de7854fb14c..90496e456593 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -347,6 +345,12 @@ static void zend_accel_do_delayed_early_binding( : NULL; if (parent_ce || (orig_ce->ce_flags & ZEND_ACC_LINKED)) { ce = zend_try_early_bind(orig_ce, parent_ce, early_binding->lcname, zv); + } else if (ZSTR_LEN(early_binding->lc_parent_name) == 0) { + /* Parentless class: use the same binding path as the VM handler */ + zval lcname_zv[2]; + ZVAL_STR(&lcname_zv[0], early_binding->lcname); + ZVAL_STR(&lcname_zv[1], early_binding->rtd_key); + ce = zend_bind_class_in_slot(zv, lcname_zv, early_binding->lc_parent_name); } } if (ce && early_binding->cache_slot != (uint32_t) -1) { diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h index fa248edeef55..a95b2095ebbd 100644 --- a/ext/opcache/zend_accelerator_util_funcs.h +++ b/ext/opcache/zend_accelerator_util_funcs.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index 3114e5b92712..265d5de41476 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -659,6 +657,7 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra SERIALIZE_STR(p->name); } zend_file_cache_serialize_type(&p->type, script, info, buf); + SERIALIZE_STR(p->doc_comment); p++; } } @@ -1309,7 +1308,9 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast, zend_ast_get_op_array(ast)->op_array = Z_PTR(z); } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { zend_ast_fcc *fcc = (zend_ast_fcc*)ast; - ZEND_MAP_PTR_NEW(fcc->fptr); + if (!script->corrupted) { + ZEND_MAP_PTR_NEW(fcc->fptr); + } if (!IS_UNSERIALIZED(fcc->args)) { UNSERIALIZE_PTR(fcc->args); zend_file_cache_unserialize_ast(fcc->args, script, buf); @@ -1562,6 +1563,7 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr UNSERIALIZE_STR(p->name); } zend_file_cache_unserialize_type(&p->type, (op_array->fn_flags & ZEND_ACC_CLOSURE) ? NULL : op_array->scope, script, buf); + UNSERIALIZE_STR(p->doc_comment); p++; } } diff --git a/ext/opcache/zend_file_cache.h b/ext/opcache/zend_file_cache.h index 452f6b2c4c24..37868285b0da 100644 --- a/ext/opcache/zend_file_cache.h +++ b/ext/opcache/zend_file_cache.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 9bc2496837ce..d3e719dbed70 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -197,6 +195,9 @@ static zend_ast *zend_persist_ast(zend_ast *ast) node = (zend_ast *) copy; } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { zend_ast_fcc *copy = zend_shared_memdup(ast, sizeof(zend_ast_fcc)); + if (!ZCG(current_persistent_script)->corrupted) { + ZEND_MAP_PTR_NEW(copy->fptr); + } copy->args = zend_persist_ast(copy->args); node = (zend_ast *) copy; } else if (zend_ast_is_decl(ast)) { @@ -544,9 +545,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_op *new_opcodes = zend_shared_memdup_put(op_array->opcodes, sizeof(zend_op) * op_array->last); zend_op *opline = new_opcodes; zend_op *end = new_opcodes + op_array->last; - int offset = 0; - for (; opline < end ; opline++, offset++) { + for (; opline < end ; opline++) { #if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals)); @@ -652,6 +652,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_accel_store_interned_string(arg_info[i].name); } zend_persist_type(&arg_info[i].type); + if (arg_info[i].doc_comment) { + zend_accel_store_interned_string(arg_info[i].doc_comment); + } } if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { arg_info++; diff --git a/ext/opcache/zend_persist.h b/ext/opcache/zend_persist.h index c8220217630e..453ae0811c17 100644 --- a/ext/opcache/zend_persist.h +++ b/ext/opcache/zend_persist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 0b0ff51d0d4d..9ff37079193b 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -306,6 +304,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) ADD_INTERNED_STRING(arg_info[i].name); } zend_persist_type_calc(&arg_info[i].type); + if (arg_info[i].doc_comment) { + ADD_INTERNED_STRING(arg_info[i].doc_comment); + } } } diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 80ef36b8749d..b264f98a02b7 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 108349b13f81..cf0bb10d8932 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -166,7 +164,11 @@ typedef union _align_test { zend_long lng; } align_test; -#if ZEND_GCC_VERSION >= 2000 +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +# define PLATFORM_ALIGNMENT (alignof(align_test) < 8 ? 8 : alignof(align_test)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define PLATFORM_ALIGNMENT (_Alignof(align_test) < 8 ? 8 : _Alignof(align_test)) +#elif ZEND_GCC_VERSION >= 2000 || defined(__clang__) # define PLATFORM_ALIGNMENT (__alignof__(align_test) < 8 ? 8 : __alignof__(align_test)) #else # define PLATFORM_ALIGNMENT (sizeof(align_test)) diff --git a/ext/openssl/config.w32 b/ext/openssl/config.w32 index 6fd0e928422c..4b7f4b8b8565 100644 --- a/ext/openssl/config.w32 +++ b/ext/openssl/config.w32 @@ -16,9 +16,7 @@ if (PHP_OPENSSL != "no") { AC_DEFINE("LOAD_OPENSSL_LEGACY_PROVIDER", 1, "Define to 1 to load the OpenSSL legacy algorithm provider in addition to the default provider."); } if (PHP_OPENSSL_ARGON2 != "no") { - if (PHP_ZTS != "no") { - WARNING("OpenSSL argon2 hashing not supported in ZTS mode for now"); - } else if (!GREP_HEADER("openssl/thread.h", "OSSL_set_max_threads", PHP_PHP_BUILD + "\\include")) { + if (!GREP_HEADER("openssl/thread.h", "OSSL_set_max_threads", PHP_PHP_BUILD + "\\include")) { WARNING("OpenSSL argon2 hashing requires OpenSSL >= 3.2"); } else { AC_DEFINE("HAVE_OPENSSL_ARGON2", 1, "Define to 1 to enable OpenSSL argon2 password hashing."); diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 1ec9ec85729a..55a437c0865a 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Venaas | | Wez Furlong | @@ -58,6 +56,10 @@ ZEND_DECLARE_MODULE_GLOBALS(openssl) #include "openssl_arginfo.h" +/* OpenSSLException class */ + +zend_class_entry *php_openssl_exception_ce; + /* OpenSSLCertificate class */ zend_class_entry *php_openssl_certificate_ce; @@ -167,6 +169,376 @@ static void php_openssl_pkey_free_obj(zend_object *object) zend_object_std_dtor(&key_object->std); } +/* Openssl\Psk class */ + +zend_class_entry *php_openssl_psk_ce; + +static zend_object_handlers php_openssl_psk_object_handlers; + +bool php_openssl_is_psk_ce(zval *val) +{ + return Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_psk_ce; +} + +zend_string *php_openssl_psk_get_psk(zval *psk_zv) +{ + zval rv; + zval *prop = zend_read_property(php_openssl_psk_ce, Z_OBJ_P(psk_zv), ZEND_STRL("psk"), 0, &rv); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_STRING)) { + return NULL; + } + return Z_STR_P(prop); +} + +zend_string *php_openssl_psk_get_identity(zval *psk_zv) +{ + zval rv; + zval *prop = zend_read_property(php_openssl_psk_ce, Z_OBJ_P(psk_zv), + ZEND_STRL("identity"), 0, &rv); + if (Z_TYPE_P(prop) == IS_NULL) { + return NULL; + } + if (UNEXPECTED(Z_TYPE_P(prop) != IS_STRING)) { + return NULL; + } + return Z_STR_P(prop); +} + +PHP_METHOD(Openssl_Psk, __construct) +{ + zend_string *psk; + zend_string *identity = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(psk) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_NULL(identity) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(psk) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + if (ZSTR_LEN(psk) > PHP_OPENSSL_PSK_MAX_PSK_LEN) { + zend_argument_value_error(1, "must not exceed %d bytes", PHP_OPENSSL_PSK_MAX_PSK_LEN); + RETURN_THROWS(); + } + if (identity != NULL && ZSTR_LEN(identity) > PHP_OPENSSL_PSK_MAX_IDENTITY_LEN) { + zend_argument_value_error(2, "must not exceed %d bytes", PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); + RETURN_THROWS(); + } + + zend_update_property_str(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("psk"), psk); + + if (identity != NULL) { + zend_update_property_str(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), + ZEND_STRL("identity"), identity); + } else { + zend_update_property_null(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("identity")); + } +} + +/* Openssl\Session class */ + +zend_class_entry *php_openssl_session_ce; + +static zend_object_handlers php_openssl_session_object_handlers; + +bool php_openssl_is_session_ce(zval *val) +{ + return Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_session_ce; +} + +SSL_SESSION *php_openssl_session_from_zval(zval *zv) +{ + if (!php_openssl_is_session_ce(zv)) { + return NULL; + } + return Z_OPENSSL_SESSION_P(zv)->session; +} + +void php_openssl_session_object_init(zval *zv, SSL_SESSION *session) +{ + object_init_ex(zv, php_openssl_session_ce); + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(zv); + obj->session = session; + + unsigned int id_len = 0; + const unsigned char *id = SSL_SESSION_get_id(session, &id_len); + zend_update_property_stringl(php_openssl_session_ce, Z_OBJ_P(zv), + ZEND_STRL("id"), (char *)id, id_len); +} + +static zend_object *php_openssl_session_create_object(zend_class_entry *class_type) +{ + php_openssl_session_object *intern = zend_object_alloc(sizeof(php_openssl_session_object), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + + return &intern->std; +} + +static zend_function *php_openssl_session_get_constructor(zend_object *object) +{ + zend_throw_error(NULL, + "Cannot directly construct OpenSSLSession, use OpenSSLSession::import() or TLS session callbacks"); + return NULL; +} + +static void php_openssl_session_free_obj(zend_object *object) +{ + php_openssl_session_object *session_object = php_openssl_session_from_obj(object); + + if (session_object->session) { + SSL_SESSION_free(session_object->session); + session_object->session = NULL; + } + zend_object_std_dtor(&session_object->std); +} + +#define PHP_OPENSSL_SESSION_CHECK() \ + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(ZEND_THIS); \ + if (!obj->session) { \ + zend_throw_exception(php_openssl_exception_ce, "Session is not valid", 0); \ + RETURN_THROWS(); \ + } + +PHP_METHOD(Openssl_Session, export) +{ + zend_long format = ENCODING_PEM; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(format) + ZEND_PARSE_PARAMETERS_END(); + + PHP_OPENSSL_SESSION_CHECK(); + + if (format == ENCODING_DER) { + int len = i2d_SSL_SESSION(obj->session, NULL); + if (len <= 0) { + zend_throw_exception(php_openssl_exception_ce, "Failed to export session", 0); + RETURN_THROWS(); + } + + zend_string *result = zend_string_alloc(len, 0); + unsigned char *p = (unsigned char *)ZSTR_VAL(result); + i2d_SSL_SESSION(obj->session, &p); + ZSTR_VAL(result)[len] = '\0'; + + RETURN_NEW_STR(result); + } + + if (format == ENCODING_PEM) { + BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to create BIO", 0); + RETURN_THROWS(); + } + + if (!PEM_write_bio_SSL_SESSION(bio, obj->session)) { + BIO_free(bio); + zend_throw_exception(php_openssl_exception_ce, "Failed to export session as PEM", 0); + RETURN_THROWS(); + } + + char *data; + long len = BIO_get_mem_data(bio, &data); + zend_string *result = zend_string_init(data, len, 0); + BIO_free(bio); + + RETURN_NEW_STR(result); + } + + zend_argument_value_error(1, "must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM"); + RETURN_THROWS(); +} + +PHP_METHOD(Openssl_Session, import) +{ + zend_string *data; + zend_long format = ENCODING_PEM; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(format) + ZEND_PARSE_PARAMETERS_END(); + + SSL_SESSION *session = NULL; + + if (format == ENCODING_DER) { + const unsigned char *p = (const unsigned char *)ZSTR_VAL(data); + session = d2i_SSL_SESSION(NULL, &p, ZSTR_LEN(data)); + } else if (format == ENCODING_PEM) { + BIO *bio = BIO_new_mem_buf(ZSTR_VAL(data), ZSTR_LEN(data)); + if (bio) { + session = PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } else { + zend_argument_value_error(2, "must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM"); + RETURN_THROWS(); + } + + if (!session) { + zend_throw_exception(php_openssl_exception_ce, "Failed to import session data", 0); + RETURN_THROWS(); + } + + php_openssl_session_object_init(return_value, session); +} + +PHP_METHOD(Openssl_Session, isResumable) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + RETURN_BOOL(SSL_SESSION_is_resumable(obj->session)); +} + +PHP_METHOD(Openssl_Session, getTimeout) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + RETURN_LONG((zend_long)SSL_SESSION_get_timeout(obj->session)); +} + +PHP_METHOD(Openssl_Session, getCreatedAt) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); +#if PHP_OPENSSL_API_VERSION >= 0x30300 + RETURN_LONG((zend_long)SSL_SESSION_get_time_ex(obj->session)); +#else + RETURN_LONG((zend_long)SSL_SESSION_get_time(obj->session)); +#endif +} + +PHP_METHOD(Openssl_Session, getProtocol) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + int version = SSL_SESSION_get_protocol_version(obj->session); + + switch (version) { + case TLS1_3_VERSION: + RETURN_STRING("TLSv1.3"); + case TLS1_2_VERSION: + RETURN_STRING("TLSv1.2"); + case TLS1_1_VERSION: + RETURN_STRING("TLSv1.1"); + case TLS1_VERSION: + RETURN_STRING("TLSv1.0"); + default: + RETURN_NULL(); + } +} + +PHP_METHOD(Openssl_Session, getCipher) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + const SSL_CIPHER *cipher = SSL_SESSION_get0_cipher(obj->session); + if (!cipher) { + RETURN_NULL(); + } + + RETURN_STRING(SSL_CIPHER_get_name(cipher)); +} + +PHP_METHOD(Openssl_Session, hasTicket) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + RETURN_BOOL(SSL_SESSION_has_ticket(obj->session)); +} + +PHP_METHOD(Openssl_Session, getTicketLifetimeHint) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + if (!SSL_SESSION_has_ticket(obj->session)) { + RETURN_NULL(); + } + + RETURN_LONG((zend_long)SSL_SESSION_get_ticket_lifetime_hint(obj->session)); +} +PHP_METHOD(Openssl_Session, __serialize) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + PHP_OPENSSL_SESSION_CHECK(); + + BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to serialize session", 0); + RETURN_THROWS(); + } + + if (!PEM_write_bio_SSL_SESSION(bio, obj->session)) { + BIO_free(bio); + zend_throw_exception(php_openssl_exception_ce, "Failed to serialize session", 0); + RETURN_THROWS(); + } + + char *data; + long len = BIO_get_mem_data(bio, &data); + zend_string *pem = zend_string_init(data, len, 0); + BIO_free(bio); + + array_init(return_value); + add_assoc_str(return_value, "pem", pem); +} + +PHP_METHOD(Openssl_Session, __unserialize) +{ + HashTable *data; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(data) + ZEND_PARSE_PARAMETERS_END(); + + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(ZEND_THIS); + if (obj->session != NULL) { + zend_throw_error(NULL, "Cannot call Openssl\\Session::__unserialize() on an already-initialized session"); + RETURN_THROWS(); + } + + zval *pem_zv = zend_hash_str_find(data, ZEND_STRL("pem")); + if (!pem_zv || Z_TYPE_P(pem_zv) != IS_STRING) { + zend_throw_exception(php_openssl_exception_ce, "Invalid serialization data", 0); + RETURN_THROWS(); + } + + BIO *bio = BIO_new_mem_buf(Z_STRVAL_P(pem_zv), Z_STRLEN_P(pem_zv)); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to unserialize session", 0); + RETURN_THROWS(); + } + + SSL_SESSION *session = PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL); + BIO_free(bio); + + if (!session) { + zend_throw_exception(php_openssl_exception_ce, "Failed to unserialize session", 0); + RETURN_THROWS(); + } + + obj->session = session; + + /* Populate id property */ + unsigned int id_len = 0; + const unsigned char *id = SSL_SESSION_get_id(session, &id_len); + zend_update_property_stringl(php_openssl_session_ce, Z_OBJ_P(ZEND_THIS), + ZEND_STRL("id"), (char *)id, id_len); +} + #if defined(HAVE_OPENSSL_ARGON2) static const zend_module_dep openssl_deps[] = { ZEND_MOD_REQUIRED("standard") @@ -218,9 +590,9 @@ void php_openssl_store_errors(void) errors = OPENSSL_G(errors); do { - errors->top = (errors->top + 1) % ERR_NUM_ERRORS; + errors->top = (errors->top + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; if (errors->top == errors->bottom) { - errors->bottom = (errors->bottom + 1) % ERR_NUM_ERRORS; + errors->bottom = (errors->bottom + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; } errors->buffer[errors->top] = error_code; } while ((error_code = ERR_get_error())); @@ -263,15 +635,13 @@ void php_openssl_errors_restore_mark(void) { static void php_openssl_check_path_error(uint32_t arg_num, int type, const char *format, ...) { va_list va; - const char *arg_name; va_start(va, format); if (type == E_ERROR) { - zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va); + zend_argument_error_variadic(zend_ce_value_error, zend_active_function(), arg_num, format, va); } else { - arg_name = get_active_function_arg_name(arg_num); - php_verror(NULL, arg_name, type, format, va); + php_verror(NULL, type, format, va); } va_end(va); } @@ -279,7 +649,8 @@ static void php_openssl_check_path_error(uint32_t arg_num, int type, const char /* openssl file path check extended */ bool php_openssl_check_path_ex( const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num, - bool contains_file_protocol, bool is_from_array, const char *option_name) + bool contains_file_protocol, bool is_from_array, const char *option_name, + php_stream *stream) { const char *fs_file_path; size_t fs_file_path_len; @@ -314,8 +685,13 @@ bool php_openssl_check_path_ex( if (arg_num == 0) { const char *option_title = option_name ? option_name : "unknown"; const char *option_label = is_from_array ? "array item" : "option"; - php_error_docref(NULL, E_WARNING, "Path for %s %s %s", - option_title, option_label, error_msg); + if (stream != NULL) { + php_stream_warn(stream, InvalidPath, "Path for %s %s %s", + option_title, option_label, error_msg); + } else { + php_error_docref(NULL, E_WARNING, "Path for %s %s %s", + option_title, option_label, error_msg); + } } else if (is_from_array && option_name != NULL) { php_openssl_check_path_error( arg_num, error_type, "option %s array item %s", option_name, error_msg); @@ -383,12 +759,14 @@ PHP_INI_END() /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(openssl) { + php_openssl_exception_ce = register_class_Openssl_OpensslException(zend_ce_exception); + php_openssl_certificate_ce = register_class_OpenSSLCertificate(); php_openssl_certificate_ce->create_object = php_openssl_certificate_create_object; php_openssl_certificate_ce->default_object_handlers = &php_openssl_certificate_object_handlers; memcpy(&php_openssl_certificate_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_certificate_object_handlers.offset = XtOffsetOf(php_openssl_certificate_object, std); + php_openssl_certificate_object_handlers.offset = offsetof(php_openssl_certificate_object, std); php_openssl_certificate_object_handlers.free_obj = php_openssl_certificate_free_obj; php_openssl_certificate_object_handlers.get_constructor = php_openssl_certificate_get_constructor; php_openssl_certificate_object_handlers.clone_obj = NULL; @@ -399,7 +777,7 @@ PHP_MINIT_FUNCTION(openssl) php_openssl_request_ce->default_object_handlers = &php_openssl_request_object_handlers; memcpy(&php_openssl_request_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_request_object_handlers.offset = XtOffsetOf(php_openssl_request_object, std); + php_openssl_request_object_handlers.offset = offsetof(php_openssl_request_object, std); php_openssl_request_object_handlers.free_obj = php_openssl_request_free_obj; php_openssl_request_object_handlers.get_constructor = php_openssl_request_get_constructor; php_openssl_request_object_handlers.clone_obj = NULL; @@ -410,12 +788,28 @@ PHP_MINIT_FUNCTION(openssl) php_openssl_pkey_ce->default_object_handlers = &php_openssl_pkey_object_handlers; memcpy(&php_openssl_pkey_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_pkey_object_handlers.offset = XtOffsetOf(php_openssl_pkey_object, std); + php_openssl_pkey_object_handlers.offset = offsetof(php_openssl_pkey_object, std); php_openssl_pkey_object_handlers.free_obj = php_openssl_pkey_free_obj; php_openssl_pkey_object_handlers.get_constructor = php_openssl_pkey_get_constructor; php_openssl_pkey_object_handlers.clone_obj = NULL; php_openssl_pkey_object_handlers.compare = zend_objects_not_comparable; + php_openssl_psk_ce = register_class_Openssl_Psk(); + php_openssl_psk_ce->default_object_handlers = &php_openssl_psk_object_handlers; + + memcpy(&php_openssl_psk_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + + php_openssl_session_ce = register_class_Openssl_Session(); + php_openssl_session_ce->create_object = php_openssl_session_create_object; + php_openssl_session_ce->default_object_handlers = &php_openssl_session_object_handlers; + + memcpy(&php_openssl_session_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_openssl_session_object_handlers.offset = offsetof(php_openssl_session_object, std); + php_openssl_session_object_handlers.free_obj = php_openssl_session_free_obj; + php_openssl_session_object_handlers.get_constructor = php_openssl_session_get_constructor; + php_openssl_session_object_handlers.clone_obj = NULL; + php_openssl_session_object_handlers.compare = zend_objects_not_comparable; + register_openssl_symbols(module_number); php_openssl_backend_init(); @@ -425,7 +819,7 @@ PHP_MINIT_FUNCTION(openssl) ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL); php_stream_xport_register("ssl", php_openssl_ssl_socket_factory); -#ifndef OPENSSL_NO_SSL3 +#if OPENSSL_VERSION_NUMBER < 0x40000000L && !defined(OPENSSL_NO_SSL3) php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory); #endif php_stream_xport_register("tls", php_openssl_ssl_socket_factory); @@ -499,7 +893,7 @@ PHP_MSHUTDOWN_FUNCTION(openssl) php_unregister_url_stream_wrapper("ftps"); php_stream_xport_unregister("ssl"); -#ifndef OPENSSL_NO_SSL3 +#if OPENSSL_VERSION_NUMBER < 0x40000000L && !defined(OPENSSL_NO_SSL3) php_stream_xport_unregister("sslv3"); #endif php_stream_xport_unregister("tls"); @@ -562,14 +956,11 @@ PHP_FUNCTION(openssl_x509_export_to_file) bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out) { - if (!notext && !X509_print(bio_out, cert)) { - php_openssl_store_errors(); - } - if (!PEM_write_bio_X509(bio_out, cert)) { + if ((notext || X509_print(bio_out, cert)) && PEM_write_bio_X509(bio_out, cert)) { + RETVAL_TRUE; + } else { php_openssl_store_errors(); } - - RETVAL_TRUE; } else { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path); @@ -864,8 +1255,7 @@ PHP_FUNCTION(openssl_x509_export) } if (!notext && !X509_print(bio_out, cert)) { php_openssl_store_errors(); - } - if (PEM_write_bio_X509(bio_out, cert)) { + } else if (PEM_write_bio_X509(bio_out, cert)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -908,7 +1298,7 @@ PHP_FUNCTION(openssl_x509_fingerprint) RETURN_FALSE; } - fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output); + fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output, NULL); if (fingerprint) { RETVAL_STR(fingerprint); } else { @@ -1003,8 +1393,8 @@ PHP_FUNCTION(openssl_x509_parse) zval subitem; zval critext; int critcount = 0; - X509_EXTENSION *extension; - X509_NAME *subject_name; + PHP_OPENSSL_X509_EXTENSION *extension; + const X509_NAME *subject_name; char *cert_name; char *extname; BIO *bio_out; @@ -1069,6 +1459,7 @@ PHP_FUNCTION(openssl_x509_parse) str_serial = i2s_ASN1_INTEGER(NULL, asn1_serial); /* Can return NULL on error or memory allocation failure */ if (!str_serial) { + OPENSSL_free(hex_serial); php_openssl_store_errors(); goto err; } @@ -1102,7 +1493,7 @@ PHP_FUNCTION(openssl_x509_parse) for (i = 0; i < X509_PURPOSE_get_count(); i++) { int id, purpset; char * pname; - X509_PURPOSE * purp; + const X509_PURPOSE * purp; zval subsub; array_init(&subsub); @@ -1156,7 +1547,7 @@ PHP_FUNCTION(openssl_x509_parse) goto err_subitem; } } - else if (X509V3_EXT_print(bio_out, extension, 0, 0)) { + else if (X509V3_EXT_print(bio_out, extension, 0, 0) > 0) { BIO_get_mem_ptr(bio_out, &bio_buf); add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length); } else { @@ -1177,6 +1568,7 @@ PHP_FUNCTION(openssl_x509_parse) err_subitem: zval_ptr_dtor(&subitem); + zval_ptr_dtor(&critext); err: zend_array_destroy(Z_ARR_P(return_value)); if (cert_str) { @@ -1264,9 +1656,20 @@ PHP_FUNCTION(openssl_x509_read) RETURN_FALSE; } + X509 *obj_x509; + if (cert_obj) { + obj_x509 = X509_dup(cert); + if (!obj_x509) { + php_error_docref(NULL, E_WARNING, "X.509 Certificate could not be duplicated"); + RETURN_FALSE; + } + } else { + obj_x509 = cert; + } + object_init_ex(return_value, php_openssl_certificate_ce); x509_cert_obj = Z_OPENSSL_CERTIFICATE_P(return_value); - x509_cert_obj->x509 = cert_obj ? X509_dup(cert) : cert; + x509_cert_obj->x509 = obj_x509; } /* }}} */ @@ -1452,7 +1855,7 @@ PHP_FUNCTION(openssl_pkcs12_export) if (p12 != NULL) { bio_out = BIO_new(BIO_s_mem()); - if (i2d_PKCS12_bio(bio_out, p12)) { + if (bio_out && i2d_PKCS12_bio(bio_out, p12)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1512,12 +1915,13 @@ PHP_FUNCTION(openssl_pkcs12_read) zout = zend_try_array_init(zout); if (!zout) { + sk_X509_pop_free(ca, X509_free); goto cleanup; } if (cert) { bio_out = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(bio_out, cert)) { + if (bio_out && PEM_write_bio_X509(bio_out, cert)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); @@ -1530,6 +1934,10 @@ PHP_FUNCTION(openssl_pkcs12_read) if (pkey) { bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto cleanup; + } + if (PEM_write_bio_PrivateKey(bio_out, pkey, NULL, NULL, 0, 0, NULL)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1544,13 +1952,16 @@ PHP_FUNCTION(openssl_pkcs12_read) cert_num = sk_X509_num(ca); if (ca && cert_num) { array_init(&zextracerts); + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto cleanup; + } for (i = 0; i < cert_num; i++) { zval zextracert; X509* aCA = sk_X509_pop(ca); if (!aCA) break; - bio_out = BIO_new(BIO_s_mem()); if (PEM_write_bio_X509(bio_out, aCA)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1558,9 +1969,10 @@ PHP_FUNCTION(openssl_pkcs12_read) add_index_zval(&zextracerts, i, &zextracert); } + (void)BIO_reset(bio_out); X509_free(aCA); - BIO_free(bio_out); } + BIO_free(bio_out); sk_X509_free(ca); add_assoc_zval(zout, "extracerts", &zextracerts); @@ -1619,9 +2031,9 @@ PHP_FUNCTION(openssl_csr_export_to_file) bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out != NULL) { if (!notext && !X509_REQ_print(bio_out, csr)) { + /* TODO: warn? */ php_openssl_store_errors(); - } - if (!PEM_write_bio_X509_REQ(bio_out, csr)) { + } else if (!PEM_write_bio_X509_REQ(bio_out, csr)) { php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", file_path); php_openssl_store_errors(); } else { @@ -1670,9 +2082,7 @@ PHP_FUNCTION(openssl_csr_export) bio_out = BIO_new(BIO_s_mem()); if (!notext && !X509_REQ_print(bio_out, csr)) { php_openssl_store_errors(); - } - - if (PEM_write_bio_X509_REQ(bio_out, csr)) { + } else if (PEM_write_bio_X509_REQ(bio_out, csr)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1812,10 +2222,17 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } } else { - PHP_OPENSSL_ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial); + if (!PHP_OPENSSL_ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial)) { + php_openssl_store_errors(); + php_error_docref(NULL, E_WARNING, "Error setting serial number"); + goto cleanup; + } } - X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr)); + if (!X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr))) { + php_openssl_store_errors(); + goto cleanup; + } if (cert == NULL) { cert = new_cert; @@ -1824,8 +2241,11 @@ PHP_FUNCTION(openssl_csr_sign) php_openssl_store_errors(); goto cleanup; } - X509_gmtime_adj(X509_getm_notBefore(new_cert), 0); - X509_gmtime_adj(X509_getm_notAfter(new_cert), 60*60*24*num_days); + if (!X509_gmtime_adj(X509_getm_notBefore(new_cert), 0) + || !X509_gmtime_adj(X509_getm_notAfter(new_cert), 60*60*24*num_days)) { + php_openssl_store_errors(); + goto cleanup; + } i = X509_set_pubkey(new_cert, key); if (!i) { php_openssl_store_errors(); @@ -1961,7 +2381,7 @@ PHP_FUNCTION(openssl_csr_get_subject) zend_object *csr_obj; zend_string *csr_str; bool use_shortnames = 1; - X509_NAME *subject; + const X509_NAME *subject; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_OBJ_OF_CLASS_OR_STR(csr_obj, php_openssl_request_ce, csr_str) @@ -2215,6 +2635,10 @@ PHP_FUNCTION(openssl_pkey_export) if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + php_openssl_store_errors(); + goto cleanup; + } if (passphrase && req.priv_key_encrypt) { if (req.priv_key_encrypt_cipher) { @@ -2243,6 +2667,7 @@ PHP_FUNCTION(openssl_pkey_export) php_openssl_store_errors(); } } +cleanup: EVP_PKEY_free(key); BIO_free(bio_out); PHP_SSL_REQ_DISPOSE(&req); @@ -2318,7 +2743,7 @@ PHP_FUNCTION(openssl_pkey_get_details) EVP_PKEY *pkey = Z_OPENSSL_PKEY_P(key)->pkey; BIO *out = BIO_new(BIO_s_mem()); - if (!PEM_write_bio_PUBKEY(out, pkey)) { + if (!out || !PEM_write_bio_PUBKEY(out, pkey)) { BIO_free(out); php_openssl_store_errors(); RETURN_FALSE; @@ -2459,12 +2884,14 @@ PHP_FUNCTION(openssl_pbkdf2) if (PKCS5_PBKDF2_HMAC(password, (int)password_len, (unsigned char *)salt, (int)salt_len, (int)iterations, digest, (int)key_length, (unsigned char*)ZSTR_VAL(out_buffer)) == 1) { ZSTR_VAL(out_buffer)[key_length] = 0; - RETURN_NEW_STR(out_buffer); + RETVAL_NEW_STR(out_buffer); } else { php_openssl_store_errors(); zend_string_release_ex(out_buffer, 0); - RETURN_FALSE; + RETVAL_FALSE; } + + php_openssl_release_evp_md(digest); } /* }}} */ @@ -2712,16 +3139,21 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) /* tack on extra headers */ if (zheaders) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) { + int ret; zend_string *str = zval_try_get_string(zcertval); if (UNEXPECTED(!str)) { goto clean_exit; } if (strindex) { - BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); } else { - BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); } zend_string_release(str); + if (ret < 0) { + php_openssl_store_errors(); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } @@ -2806,33 +3238,41 @@ PHP_FUNCTION(openssl_pkcs7_read) } if (certs != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } for (i = 0; i < sk_X509_num(certs); i++) { X509* ca = sk_X509_value(certs, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509(bio_out, ca)) { + if (PEM_write_bio_X509(bio_out, ca)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } if (crls != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } for (i = 0; i < sk_X509_CRL_num(crls); i++) { X509_CRL* crl = sk_X509_CRL_value(crls, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) { + if (PEM_write_bio_X509_CRL(bio_out, crl)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } RETVAL_TRUE; @@ -2941,6 +3381,7 @@ PHP_FUNCTION(openssl_pkcs7_sign) zend_string_release(str); if (ret < 0) { php_openssl_store_errors(); + goto clean_exit; } } ZEND_HASH_FOREACH_END(); } @@ -3341,16 +3782,21 @@ PHP_FUNCTION(openssl_cms_encrypt) /* tack on extra headers */ if (zheaders && encoding == ENCODING_SMIME) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) { + int ret; zend_string *str = zval_try_get_string(zcertval); if (UNEXPECTED(!str)) { goto clean_exit; } if (strindex) { - BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); } else { - BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); } zend_string_release(str); + if (ret < 0) { + php_openssl_store_errors(); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } @@ -3467,33 +3913,43 @@ PHP_FUNCTION(openssl_cms_read) } if (certs != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } + for (i = 0; i < sk_X509_num(certs); i++) { X509* ca = sk_X509_value(certs, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509(bio_out, ca)) { + if (PEM_write_bio_X509(bio_out, ca)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } if (crls != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } + for (i = 0; i < sk_X509_CRL_num(crls); i++) { X509_CRL* crl = sk_X509_CRL_value(crls, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) { + if (PEM_write_bio_X509_CRL(bio_out, crl)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } RETVAL_TRUE; @@ -3631,6 +4087,7 @@ PHP_FUNCTION(openssl_cms_sign) zend_string_release(str); if (ret < 0) { php_openssl_store_errors(); + goto clean_exit; } } ZEND_HASH_FOREACH_END(); } @@ -4030,7 +4487,7 @@ PHP_FUNCTION(openssl_error_string) RETURN_FALSE; } - OPENSSL_G(errors)->bottom = (OPENSSL_G(errors)->bottom + 1) % ERR_NUM_ERRORS; + OPENSSL_G(errors)->bottom = (OPENSSL_G(errors)->bottom + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; val = OPENSSL_G(errors)->buffer[OPENSSL_G(errors)->bottom]; if (val) { @@ -4066,6 +4523,27 @@ static zend_result php_openssl_setup_rsa_padding(EVP_PKEY_CTX *pctx, EVP_PKEY *p return SUCCESS; } +static zend_result php_openssl_setup_rsa_pss_salt_length(EVP_PKEY_CTX *pctx, EVP_PKEY *pkey, zend_long padding, zend_long salt_length) +{ + /* Only apply if using PSS padding */ + if (padding != RSA_PKCS1_PSS_PADDING) { + return SUCCESS; + } + + /* Only apply to RSA keys */ + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA && EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA_PSS) { + return SUCCESS; + } + + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, (int)salt_length) <= 0) { + php_openssl_store_errors(); + php_error_docref(NULL, E_WARNING, "Could not set RSA-PSS salt length"); + return FAILURE; + } + + return SUCCESS; +} + /* {{{ Signs data */ PHP_FUNCTION(openssl_sign) { @@ -4079,16 +4557,18 @@ PHP_FUNCTION(openssl_sign) zend_long method_long = OPENSSL_ALGO_SHA1; const EVP_MD *mdtype; zend_long padding = 0; + zend_long salt_length = RSA_PSS_SALTLEN_AUTO; EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 5) + ZEND_PARSE_PARAMETERS_START(3, 6) Z_PARAM_STRING(data, data_len) Z_PARAM_ZVAL(signature) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) Z_PARAM_LONG(padding) + Z_PARAM_LONG(salt_length) ZEND_PARSE_PARAMETERS_END(); pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); @@ -4109,12 +4589,14 @@ PHP_FUNCTION(openssl_sign) php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; } + PHP_OPENSSL_CHECK_LONG_TO_INT(salt_length, salt_length, 6); md_ctx = EVP_MD_CTX_create(); size_t siglen; if (md_ctx != NULL && EVP_DigestSignInit(md_ctx, &pctx, mdtype, NULL, pkey) && php_openssl_setup_rsa_padding(pctx, pkey, padding) == SUCCESS && + php_openssl_setup_rsa_pss_salt_length(pctx, pkey, padding, salt_length) == SUCCESS && EVP_DigestSign(md_ctx, NULL, &siglen, (unsigned char*)data, data_len) && (sigbuf = zend_string_alloc(siglen, 0)) != NULL && EVP_DigestSign(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, (unsigned char*)data, data_len)) { @@ -4148,19 +4630,22 @@ PHP_FUNCTION(openssl_verify) zend_string *method_str = NULL; zend_long method_long = OPENSSL_ALGO_SHA1; zend_long padding = 0; + zend_long salt_length = RSA_PSS_SALTLEN_AUTO; EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 5) + ZEND_PARSE_PARAMETERS_START(3, 6) Z_PARAM_STRING(data, data_len) Z_PARAM_STRING(signature, signature_len) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) Z_PARAM_LONG(padding) + Z_PARAM_LONG(salt_length) ZEND_PARSE_PARAMETERS_END(); PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2); + PHP_OPENSSL_CHECK_LONG_TO_INT(salt_length, salt_length, 6); if (method_str) { mdtype = php_openssl_get_evp_md_by_name(ZSTR_VAL(method_str)); @@ -4189,7 +4674,8 @@ PHP_FUNCTION(openssl_verify) } if (!EVP_DigestVerifyInit(md_ctx, &pctx, mdtype, NULL, pkey) || - php_openssl_setup_rsa_padding(pctx, pkey, padding) == FAILURE) { + php_openssl_setup_rsa_padding(pctx, pkey, padding) == FAILURE || + php_openssl_setup_rsa_pss_salt_length(pctx, pkey, padding, salt_length) == FAILURE) { php_openssl_store_errors(); err = -1; goto cleanup; @@ -4245,6 +4731,7 @@ PHP_FUNCTION(openssl_seal) iv_len = EVP_CIPHER_iv_length(cipher); if (!iv && iv_len > 0) { + php_openssl_release_evp_cipher(cipher); zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); RETURN_THROWS(); } @@ -4331,6 +4818,7 @@ PHP_FUNCTION(openssl_seal) efree(eks); efree(eksl); efree(pkeys); + php_openssl_release_evp_cipher(cipher); } /* }}} */ @@ -4369,18 +4857,20 @@ PHP_FUNCTION(openssl_open) cipher = php_openssl_get_evp_cipher_by_name(method); if (!cipher) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); - RETURN_FALSE; + RETVAL_FALSE; + goto out_pkey; } cipher_iv_len = EVP_CIPHER_iv_length(cipher); if (cipher_iv_len > 0) { if (!iv) { zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); - RETURN_THROWS(); + goto out_pkey; } if ((size_t)cipher_iv_len != iv_len) { php_error_docref(NULL, E_WARNING, "IV length is invalid"); - RETURN_FALSE; + RETVAL_FALSE; + goto out_pkey; } iv_buf = (unsigned char *)iv; } else { @@ -4402,8 +4892,10 @@ PHP_FUNCTION(openssl_open) } efree(buf); - EVP_PKEY_free(pkey); EVP_CIPHER_CTX_free(ctx); +out_pkey: + EVP_PKEY_free(pkey); + php_openssl_release_evp_cipher(cipher); } /* }}} */ @@ -4483,7 +4975,8 @@ PHP_FUNCTION(openssl_digest) sigbuf = zend_string_alloc(siglen, 0); md_ctx = EVP_MD_CTX_create(); - if (EVP_DigestInit(md_ctx, mdtype) && + if (md_ctx && + EVP_DigestInit(md_ctx, mdtype) && EVP_DigestUpdate(md_ctx, (unsigned char *)data, data_len) && EVP_DigestFinal (md_ctx, (unsigned char *)ZSTR_VAL(sigbuf), &siglen)) { if (raw_output) { @@ -4519,7 +5012,7 @@ PHP_FUNCTION(openssl_encrypt) zend_string *ret; zval *tag = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszsl", &data, &data_len, &method, &method_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszs!l", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len, &tag, &aad, &aad_len, &tag_len) == FAILURE) { RETURN_THROWS(); } @@ -4541,7 +5034,7 @@ PHP_FUNCTION(openssl_decrypt) size_t data_len, method_len, password_len, iv_len = 0, tag_len = 0, aad_len = 0; zend_string *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s", &data, &data_len, &method, &method_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s!", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len, &tag, &tag_len, &aad, &aad_len) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/openssl/openssl.stub.php b/ext/openssl/openssl.stub.php index 94902a4acf0d..3d3fa3ea634f 100644 --- a/ext/openssl/openssl.stub.php +++ b/ext/openssl/openssl.stub.php @@ -2,6 +2,67 @@ /** @generate-class-entries */ +namespace Openssl { + + class OpensslException extends Exception + { + } + + /** + * @strict-properties + */ + final class Psk + { + /** + * @cvalue PHP_OPENSSL_PSK_MAX_PSK_LEN + */ + public const int MAX_PSK_LEN = UNKNOWN; + + /** + * @cvalue PHP_OPENSSL_PSK_MAX_IDENTITY_LEN + */ + public const int MAX_IDENTITY_LEN = UNKNOWN; + + public readonly string $psk; + public readonly ?string $identity; + + public function __construct(string $psk, ?string $identity = null) {} + } + + /** + * @strict-properties + */ + final class Session + { + public readonly string $id; + + public function export(int $format = OPENSSL_ENCODING_PEM): string {} + + public static function import(string $data, int $format = OPENSSL_ENCODING_PEM): Session {} + + public function isResumable(): bool {} + + public function getTimeout(): int {} + + public function getCreatedAt(): int {} + + public function getProtocol(): ?string {} + + public function getCipher(): ?string {} + + public function hasTicket(): bool {} + + public function getTicketLifetimeHint(): ?int {} + + public function __serialize(): array {} + + public function __unserialize(array $data): void {} + } + +} + +namespace { + /** * @var string * @cvalue OPENSSL_VERSION_TEXT @@ -262,6 +323,22 @@ */ const OPENSSL_PKCS1_PSS_PADDING = UNKNOWN; +/** + * @var int + * @cvalue RSA_PSS_SALTLEN_DIGEST + */ +const OPENSSL_RSA_PSS_SALTLEN_DIGEST = UNKNOWN; +/** + * @var int + * @cvalue RSA_PSS_SALTLEN_AUTO + */ +const OPENSSL_RSA_PSS_SALTLEN_AUTO = UNKNOWN; +/** + * @var int + * @cvalue RSA_PSS_SALTLEN_MAX + */ +const OPENSSL_RSA_PSS_SALTLEN_MAX = UNKNOWN; + /* Informational stream wrapper constants */ /** @@ -409,7 +486,6 @@ */ const OPENSSL_ENCODING_PEM = UNKNOWN; - /** * @strict-properties * @not-serializable @@ -619,10 +695,10 @@ function openssl_error_string(): string|false {} * @param string $signature * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): bool {} +function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0, int $salt_length = OPENSSL_RSA_PSS_SALTLEN_AUTO): bool {} /** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): int|false {} +function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0, int $salt_length = OPENSSL_RSA_PSS_SALTLEN_AUTO): int|false {} /** * @param string $sealed_data @@ -662,9 +738,9 @@ function openssl_digest(string $data, string $digest_algo, bool $binary = false) /** * @param string $tag */ -function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, string $aad = "", int $tag_length = 16): string|false {} +function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, ?string $aad = "", int $tag_length = 16): string|false {} -function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, string $aad = ""): string|false {} +function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, ?string $aad = ""): string|false {} function openssl_cipher_iv_length(string $cipher_algo): int|false {} @@ -699,3 +775,5 @@ function openssl_get_cert_locations(): array {} function openssl_password_hash(string $algo, #[\SensitiveParameter] string $password, array $options = []): string {} function openssl_password_verify(string $algo, #[\SensitiveParameter] string $password, string $hash): bool {} #endif + +} diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index bae435e90241..b1742dcb05f8 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit openssl.stub.php instead. - * Stub hash: 8233a8abc8ab7145d905d0fa51478edfe1e55a06 */ + * Stub hash: 7cad995b734d69f98d489edb97a7878a4ea8f47e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) @@ -285,6 +285,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_sign, 0, 3, _IS_BOOL, 0) ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, salt_length, IS_LONG, 0, "OPENSSL_RSA_PSS_SALTLEN_AUTO") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LONG|MAY_BE_FALSE) @@ -293,6 +294,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LON ZEND_ARG_INFO(0, public_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, salt_length, IS_LONG, 0, "OPENSSL_RSA_PSS_SALTLEN_AUTO") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_seal, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) @@ -337,7 +339,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_encrypt, 0, 3, MAY_BE_ST ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, tag, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 1, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag_length, IS_LONG, 0, "16") ZEND_END_ARG_INFO() @@ -348,7 +350,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_decrypt, 0, 3, MAY_BE_ST ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 1, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_cipher_iv_length, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) @@ -406,6 +408,44 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_password_verify, 0, 3, _ ZEND_END_ARG_INFO() #endif +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Openssl_Psk___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, psk, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, identity, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_export, 0, 0, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "OPENSSL_ENCODING_PEM") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Openssl_Session_import, 0, 1, Openssl\\Session, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "OPENSSL_ENCODING_PEM") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_isResumable, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getTimeout, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session_getCreatedAt arginfo_class_Openssl_Session_getTimeout + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getProtocol, 0, 0, IS_STRING, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session_getCipher arginfo_class_Openssl_Session_getProtocol + +#define arginfo_class_Openssl_Session_hasTicket arginfo_class_Openssl_Session_isResumable + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getTicketLifetimeHint, 0, 0, IS_LONG, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session___serialize arginfo_openssl_get_cert_locations + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_FUNCTION(openssl_x509_export_to_file); ZEND_FUNCTION(openssl_x509_export); ZEND_FUNCTION(openssl_x509_fingerprint); @@ -473,6 +513,18 @@ ZEND_FUNCTION(openssl_get_cert_locations); ZEND_FUNCTION(openssl_password_hash); ZEND_FUNCTION(openssl_password_verify); #endif +ZEND_METHOD(Openssl_Psk, __construct); +ZEND_METHOD(Openssl_Session, export); +ZEND_METHOD(Openssl_Session, import); +ZEND_METHOD(Openssl_Session, isResumable); +ZEND_METHOD(Openssl_Session, getTimeout); +ZEND_METHOD(Openssl_Session, getCreatedAt); +ZEND_METHOD(Openssl_Session, getProtocol); +ZEND_METHOD(Openssl_Session, getCipher); +ZEND_METHOD(Openssl_Session, hasTicket); +ZEND_METHOD(Openssl_Session, getTicketLifetimeHint); +ZEND_METHOD(Openssl_Session, __serialize); +ZEND_METHOD(Openssl_Session, __unserialize); static const zend_function_entry ext_functions[] = { ZEND_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file) @@ -548,6 +600,26 @@ static const zend_function_entry ext_functions[] = { ZEND_FE_END }; +static const zend_function_entry class_Openssl_Psk_methods[] = { + ZEND_ME(Openssl_Psk, __construct, arginfo_class_Openssl_Psk___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_Openssl_Session_methods[] = { + ZEND_ME(Openssl_Session, export, arginfo_class_Openssl_Session_export, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, import, arginfo_class_Openssl_Session_import, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Openssl_Session, isResumable, arginfo_class_Openssl_Session_isResumable, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getTimeout, arginfo_class_Openssl_Session_getTimeout, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getCreatedAt, arginfo_class_Openssl_Session_getCreatedAt, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getProtocol, arginfo_class_Openssl_Session_getProtocol, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getCipher, arginfo_class_Openssl_Session_getCipher, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, hasTicket, arginfo_class_Openssl_Session_hasTicket, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getTicketLifetimeHint, arginfo_class_Openssl_Session_getTicketLifetimeHint, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, __serialize, arginfo_class_Openssl_Session___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, __unserialize, arginfo_class_Openssl_Session___unserialize, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static void register_openssl_symbols(int module_number) { REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_PERSISTENT); @@ -606,6 +678,9 @@ static void register_openssl_symbols(int module_number) REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_RSA_PSS_SALTLEN_DIGEST", RSA_PSS_SALTLEN_DIGEST, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_RSA_PSS_SALTLEN_AUTO", RSA_PSS_SALTLEN_AUTO, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_RSA_PSS_SALTLEN_MAX", RSA_PSS_SALTLEN_MAX, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("OPENSSL_DEFAULT_STREAM_CIPHERS", OPENSSL_DEFAULT_STREAM_CIPHERS, CONST_PERSISTENT); #if !defined(OPENSSL_NO_RC2) REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_RC2_40", PHP_OPENSSL_CIPHER_RC2_40, CONST_PERSISTENT); @@ -751,6 +826,66 @@ static void register_openssl_symbols(int module_number) #endif } +static zend_class_entry *register_class_Openssl_OpensslException(zend_class_entry *class_entry_Openssl_Exception) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "OpensslException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Openssl_Exception, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Openssl_Psk(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "Psk", class_Openssl_Psk_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zval const_MAX_PSK_LEN_value; + ZVAL_LONG(&const_MAX_PSK_LEN_value, PHP_OPENSSL_PSK_MAX_PSK_LEN); + zend_string *const_MAX_PSK_LEN_name = zend_string_init_interned("MAX_PSK_LEN", sizeof("MAX_PSK_LEN") - 1, true); + zend_declare_typed_class_constant(class_entry, const_MAX_PSK_LEN_name, &const_MAX_PSK_LEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_MAX_PSK_LEN_name, true); + + zval const_MAX_IDENTITY_LEN_value; + ZVAL_LONG(&const_MAX_IDENTITY_LEN_value, PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); + zend_string *const_MAX_IDENTITY_LEN_name = zend_string_init_interned("MAX_IDENTITY_LEN", sizeof("MAX_IDENTITY_LEN") - 1, true); + zend_declare_typed_class_constant(class_entry, const_MAX_IDENTITY_LEN_name, &const_MAX_IDENTITY_LEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_MAX_IDENTITY_LEN_name, true); + + zval property_psk_default_value; + ZVAL_UNDEF(&property_psk_default_value); + zend_string *property_psk_name = zend_string_init("psk", sizeof("psk") - 1, true); + zend_declare_typed_property(class_entry, property_psk_name, &property_psk_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_psk_name, true); + + zval property_identity_default_value; + ZVAL_UNDEF(&property_identity_default_value); + zend_string *property_identity_name = zend_string_init("identity", sizeof("identity") - 1, true); + zend_declare_typed_property(class_entry, property_identity_name, &property_identity_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release_ex(property_identity_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_Openssl_Session(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "Session", class_Openssl_Session_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zval property_id_default_value; + ZVAL_UNDEF(&property_id_default_value); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_id_name, true); + + return class_entry; +} + static zend_class_entry *register_class_OpenSSLCertificate(void) { zend_class_entry ce, *class_entry; diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 6f257af49819..7261a617af32 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -35,16 +33,16 @@ /* true global; readonly after module startup */ static char default_ssl_conf_filename[MAXPATHLEN]; -void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname) +void php_openssl_add_assoc_name_entry(zval * val, char * key, const X509_NAME * name, int shortname) { zval *data; zval subitem, tmp; int i; char *sname; int nid; - X509_NAME_ENTRY * ne; - ASN1_STRING * str = NULL; - ASN1_OBJECT * obj; + const X509_NAME_ENTRY * ne; + const ASN1_STRING * str = NULL; + const ASN1_OBJECT * obj; if (key != NULL) { array_init(&subitem); @@ -108,9 +106,9 @@ void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, } } -void php_openssl_add_assoc_asn1_string(zval * val, char * key, ASN1_STRING * str) +void php_openssl_add_assoc_asn1_string(zval * val, char * key, const ASN1_STRING * str) { - add_assoc_stringl(val, key, (char *)str->data, str->length); + add_assoc_stringl(val, key, (const char *)ASN1_STRING_get0_data(str), ASN1_STRING_length(str)); } time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) @@ -142,12 +140,12 @@ time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) } if (timestr_len < 13) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && timestr_len < 15) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } @@ -309,7 +307,7 @@ int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args /* read in the oids */ str = php_openssl_conf_get_string(req->req_config, NULL, "oid_file"); - if (str != NULL && php_openssl_check_path_ex(str, strlen(str), path, 0, false, false, "oid_file")) { + if (str != NULL && php_openssl_check_path_ex(str, strlen(str), path, 0, false, false, "oid_file", NULL)) { BIO *oid_bio = BIO_new_file(path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (oid_bio) { OBJ_create_objects(oid_bio); @@ -504,10 +502,8 @@ void php_openssl_set_cert_locations(zval *return_value) add_assoc_string(return_value, "default_cert_dir_env", (char *) X509_get_default_cert_dir_env()); add_assoc_string(return_value, "default_private_dir", (char *) X509_get_default_private_dir()); add_assoc_string(return_value, "default_default_cert_area", (char *) X509_get_default_cert_area()); - add_assoc_string(return_value, "ini_cafile", - zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0)); - add_assoc_string(return_value, "ini_capath", - zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0)); + add_assoc_str(return_value, "ini_cafile", zend_string_copy(zend_ini_str_literal("openssl.cafile"))); + add_assoc_str(return_value, "ini_capath", zend_string_copy(zend_ini_str_literal("openssl.capath"))); } X509 *php_openssl_x509_from_str( @@ -517,7 +513,7 @@ X509 *php_openssl_x509_from_str( BIO *in; if (ZSTR_LEN(cert_str) > 7 && memcmp(ZSTR_VAL(cert_str), "file://", sizeof("file://") - 1) == 0) { - if (!php_openssl_check_path_str_ex(cert_str, cert_path, arg_num, true, is_from_array, option_name)) { + if (!php_openssl_check_path_str_ex(cert_str, cert_path, arg_num, true, is_from_array, option_name, NULL)) { return NULL; } @@ -586,7 +582,7 @@ X509 *php_openssl_x509_from_zval( return cert; } -zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw) +zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw, php_stream *stream) { unsigned char md[EVP_MAX_MD_SIZE]; const EVP_MD *mdtype; @@ -594,11 +590,20 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r zend_string *ret; if (!(mdtype = php_openssl_get_evp_md_by_name(method))) { - php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); + if (stream != NULL) { + php_stream_warn(stream, Generic, "Unknown digest algorithm"); + } else { + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); + } return NULL; } else if (!X509_digest(peer, mdtype, md, &n)) { + php_openssl_release_evp_md(mdtype); php_openssl_store_errors(); - php_error_docref(NULL, E_ERROR, "Could not generate signature"); + if (stream != NULL) { + php_stream_warn(stream, EncodingFailed, "Could not generate signature"); + } else { + php_error_docref(NULL, E_WARNING, "Could not generate signature"); + } return NULL; } @@ -610,17 +615,18 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r ZSTR_VAL(ret)[n * 2] = '\0'; } + php_openssl_release_evp_md(mdtype); return ret; } /* Special handling of subjectAltName, see CVE-2013-4073 * Christian Heimes */ -int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) +int openssl_x509v3_subjectAltName(BIO *bio, PHP_OPENSSL_X509_EXTENSION *extension) { GENERAL_NAMES *names; const X509V3_EXT_METHOD *method = NULL; - ASN1_OCTET_STRING *extension_data; + const ASN1_OCTET_STRING *extension_data; long i, length, num; const unsigned char *p; @@ -630,8 +636,8 @@ int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) } extension_data = X509_EXTENSION_get_data(extension); - p = extension_data->data; - length = extension_data->length; + p = ASN1_STRING_get0_data(extension_data); + length = ASN1_STRING_length(extension_data); if (method->it) { names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, length, ASN1_ITEM_ptr(method->it))); @@ -748,6 +754,7 @@ int php_openssl_check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedch return 0; } if (!X509_STORE_CTX_init(csc, ctx, x, untrustedchain)) { + X509_STORE_CTX_free(csc); php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Certificate store initialization failed"); return 0; @@ -793,7 +800,7 @@ X509_STORE *php_openssl_setup_verify(zval *calist, uint32_t arg_num) return NULL; } - if (!php_openssl_check_path_str_ex(str, file_path, arg_num, false, true, NULL)) { + if (!php_openssl_check_path_str_ex(str, file_path, arg_num, false, true, NULL, NULL)) { zend_string_release(str); continue; } @@ -975,7 +982,12 @@ zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, zval *item, *subitem; zend_string *strindex = NULL; - subj = X509_REQ_get_subject_name(csr); + subj = X509_NAME_new(); + if (subj == NULL) { + php_openssl_store_errors(); + return FAILURE; + } + /* apply values from the dn hash */ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(dn), strindex, item) { if (strindex) { @@ -984,10 +996,12 @@ zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, if (Z_TYPE_P(item) == IS_ARRAY) { ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(item), i, subitem) { if (php_openssl_csr_add_subj_entry(subitem, subj, nid) == FAILURE) { + X509_NAME_free(subj); return FAILURE; } } ZEND_HASH_FOREACH_END(); } else if (php_openssl_csr_add_subj_entry(item, subj, nid) == FAILURE) { + X509_NAME_free(subj); return FAILURE; } } else { @@ -1038,13 +1052,23 @@ zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_UTF8, (unsigned char*)v->value, -1, -1, 0)) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value); + X509_NAME_free(subj); return FAILURE; } if (!X509_NAME_entry_count(subj)) { php_error_docref(NULL, E_WARNING, "No objects specified in config file"); + X509_NAME_free(subj); return FAILURE; } } + + if (!X509_REQ_set_subject_name(csr, subj)) { + php_openssl_store_errors(); + X509_NAME_free(subj); + return FAILURE; + } + X509_NAME_free(subj); + if (attribs) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(attribs), strindex, item) { int nid; @@ -1089,13 +1113,15 @@ zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, } } } + + if (!X509_REQ_set_pubkey(csr, req->priv_key)) { + php_openssl_store_errors(); + } } else { php_openssl_store_errors(); + return FAILURE; } - if (!X509_REQ_set_pubkey(csr, req->priv_key)) { - php_openssl_store_errors(); - } return SUCCESS; } @@ -1519,7 +1545,7 @@ EVP_PKEY *php_openssl_generate_private_key(struct php_x509_request * req) case EVP_PKEY_ED448: break; #endif - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) { @@ -1651,10 +1677,14 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV { int cipher_mode = EVP_CIPHER_mode(cipher_type); memset(mode, 0, sizeof(struct php_openssl_cipher_mode)); + switch (cipher_mode) { case EVP_CIPH_GCM_MODE: case EVP_CIPH_CCM_MODE: - /* We check for EVP_CIPH_OCB_MODE, because LibreSSL does not support it. */ + /* We check for EVP_CIPH_SIV_MODE and EVP_CIPH_SIV_MODE, because older OpenSSL and LibreSSL do not support them. */ +#ifdef EVP_CIPH_SIV_MODE + case EVP_CIPH_SIV_MODE: +#endif #ifdef EVP_CIPH_OCB_MODE case EVP_CIPH_OCB_MODE: /* For OCB mode, explicitly set the tag length even when decrypting, @@ -1664,6 +1694,9 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV php_openssl_set_aead_flags(mode); mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE; mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE; +#ifdef EVP_CIPH_SIV_MODE + mode->aad_supports_vector = cipher_mode == EVP_CIPH_SIV_MODE; +#endif break; #ifdef NID_chacha20_poly1305 default: @@ -1804,6 +1837,13 @@ zend_result php_openssl_cipher_update(const EVP_CIPHER *cipher_type, const char *aad, size_t aad_len, int enc) { int i = 0; + size_t outlen = data_len + EVP_CIPHER_block_size(cipher_type); + + /* For AEAD modes that do not support vector AAD, treat NULL AAD as zero-length AAD */ + if (!mode->aad_supports_vector && aad == NULL) { + aad_len = 0; + aad = ""; + } if (mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, NULL, (int)data_len)) { php_openssl_store_errors(); @@ -1811,13 +1851,27 @@ zend_result php_openssl_cipher_update(const EVP_CIPHER *cipher_type, return FAILURE; } - if (mode->is_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *) aad, (int) aad_len)) { + /* Only pass AAD to OpenSSL if caller provided it. + This makes NULL mean zero AAD items, while "" with len 0 means one empty AAD item. */ + if (mode->is_aead && aad != NULL && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *)aad, (int)aad_len)) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Setting of additional application data failed"); return FAILURE; } - *poutbuf = zend_string_alloc((int)data_len + EVP_CIPHER_block_size(cipher_type), 0); +#ifdef EVP_CIPH_WRAP_MODE + if ((EVP_CIPHER_mode(cipher_type)) == EVP_CIPH_WRAP_MODE) { + /* + * RFC 5649 wrap-with-padding rounds the input up to the block size + * and prepends an integrity block, we reserve one extra block. + * See EVP_EncryptUpdate(3): wrap mode may write up to + * inl + cipher_block_size bytes. + */ + outlen += EVP_CIPHER_block_size(cipher_type); + } +#endif + + *poutbuf = zend_string_alloc(outlen, false); if (!EVP_CipherUpdate(cipher_ctx, (unsigned char*)ZSTR_VAL(*poutbuf), &i, (const unsigned char *)data, (int)data_len)) { diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index 81c327dbfe34..0c1ac6b955f6 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -140,7 +138,14 @@ static bool php_openssl_pkey_init_dsa_data(DSA *dsa, zval *data, bool *is_privat OPENSSL_PKEY_SET_BN(data, p); OPENSSL_PKEY_SET_BN(data, q); OPENSSL_PKEY_SET_BN(data, g); - if (!p || !q || !g || !DSA_set0_pqg(dsa, p, q, g)) { + if (!p || !q || !g) { + BN_free(p); + BN_free(q); + BN_free(g); + return false; + } + + if (!DSA_set0_pqg(dsa, p, q, g)) { return false; } @@ -201,7 +206,12 @@ static bool php_openssl_pkey_init_dh_data(DH *dh, zval *data, bool *is_private) OPENSSL_PKEY_SET_BN(data, p); OPENSSL_PKEY_SET_BN(data, q); OPENSSL_PKEY_SET_BN(data, g); - if (!p || !g || !DH_set0_pqg(dh, p, q, g)) { + if (!p || !q) { + BN_free(p); + return false; + } + + if (!DH_set0_pqg(dh, p, q, g)) { return false; } @@ -214,6 +224,10 @@ static bool php_openssl_pkey_init_dh_data(DH *dh, zval *data, bool *is_private) if (priv_key) { pub_key = php_openssl_dh_pub_from_priv(priv_key, g, p); if (pub_key == NULL) { + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(priv_key); return false; } return DH_set0_key(dh, pub_key, priv_key); @@ -261,6 +275,9 @@ static bool php_openssl_pkey_init_ec_data(EC_KEY *eckey, zval *data, bool *is_pr EC_POINT *point_q = NULL; EC_GROUP *group = NULL; BN_CTX *bctx = BN_CTX_new(); + if (!bctx) { + goto clean_exit; + } *is_private = false; @@ -632,7 +649,6 @@ const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo) #endif default: return NULL; - break; } return mdtype; } @@ -653,40 +669,31 @@ const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo) #ifndef OPENSSL_NO_RC2 case PHP_OPENSSL_CIPHER_RC2_40: return EVP_rc2_40_cbc(); - break; case PHP_OPENSSL_CIPHER_RC2_64: return EVP_rc2_64_cbc(); - break; case PHP_OPENSSL_CIPHER_RC2_128: return EVP_rc2_cbc(); - break; #endif #ifndef OPENSSL_NO_DES case PHP_OPENSSL_CIPHER_DES: return EVP_des_cbc(); - break; case PHP_OPENSSL_CIPHER_3DES: return EVP_des_ede3_cbc(); - break; #endif #ifndef OPENSSL_NO_AES case PHP_OPENSSL_CIPHER_AES_128_CBC: return EVP_aes_128_cbc(); - break; case PHP_OPENSSL_CIPHER_AES_192_CBC: return EVP_aes_192_cbc(); - break; case PHP_OPENSSL_CIPHER_AES_256_CBC: return EVP_aes_256_cbc(); - break; #endif default: return NULL; - break; } } diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index 6e3e883080f3..375c0104fac5 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -404,7 +402,7 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) { } OPENSSL_PKEY_SET_BN(data, cofactor); - if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor) || + if ((cofactor && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) || !EC_GROUP_set_generator(group, point_g, order, cofactor)) { goto cleanup; } @@ -454,6 +452,9 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) { } EVP_PKEY_CTX_free(ctx); ctx = EVP_PKEY_CTX_new(param_key, NULL); + if (!ctx) { + goto cleanup; + } } if (EVP_PKEY_check(ctx) || EVP_PKEY_public_check_quick(ctx)) { diff --git a/ext/openssl/openssl_pwhash.c b/ext/openssl/openssl_pwhash.c index dc125e3b516d..01f7f0124135 100644 --- a/ext/openssl/openssl_pwhash.c +++ b/ext/openssl/openssl_pwhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Remi Collet | +----------------------------------------------------------------------+ @@ -51,6 +49,7 @@ ZEND_EXTERN_MODULE_GLOBALS(openssl) static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads) { zval *opt; + zend_long sthreads; *iterlimit = PHP_OPENSSL_PWHASH_ITERLIMIT; *memlimit = PHP_OPENSSL_PWHASH_MEMLIMIT; @@ -76,8 +75,7 @@ static inline zend_result get_options(zend_array *options, uint32_t *memlimit, u } *iterlimit = siterlimit; } - if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && (zval_get_long(opt) != 1)) { - zend_long sthreads = zval_get_long(opt); + if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && ((sthreads = zval_get_long(opt)) != 1)) { if ((sthreads < PHP_OPENSSL_THREADS_MIN) || (sthreads > PHP_OPENSSL_THREADS_MAX)) { zend_value_error("Invalid number of threads"); return FAILURE; @@ -331,7 +329,7 @@ PHP_FUNCTION(openssl_password_hash) Z_PARAM_ARRAY_HT(options) ZEND_PARSE_PARAMETERS_END(); - if (strcmp(ZSTR_VAL(algo), "argon2i") && strcmp(ZSTR_VAL(algo), "argon2id")) { + if (!zend_string_equals_literal(algo, "argon2i") && !zend_string_equals_literal(algo, "argon2id")) { zend_argument_value_error(1, "must be a valid password openssl hashing algorithm"); RETURN_THROWS(); } @@ -357,7 +355,7 @@ PHP_FUNCTION(openssl_password_verify) Z_PARAM_STR(digest) ZEND_PARSE_PARAMETERS_END(); - if (strcmp(ZSTR_VAL(algo), "argon2i") && strcmp(ZSTR_VAL(algo), "argon2id")) { + if (!zend_string_equals_literal(algo, "argon2i") && !zend_string_equals_literal(algo, "argon2id")) { zend_argument_value_error(1, "must be a valid password openssl hashing algorithm"); RETURN_THROWS(); } diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index 92ccd9a546f9..588cca0e93d8 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Venaas | | Wez Furlong #include /* OpenSSL version check */ #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -32,10 +31,14 @@ extern zend_module_entry openssl_module_entry; #define PHP_OPENSSL_API_VERSION 0x10100 #elif OPENSSL_VERSION_NUMBER < 0x30200000L #define PHP_OPENSSL_API_VERSION 0x30000 -#else +#elif OPENSSL_VERSION_NUMBER < 0x30300000L #define PHP_OPENSSL_API_VERSION 0x30200 +#else +#define PHP_OPENSSL_API_VERSION 0x30300 #endif +#define PHP_OPENSSL_ERR_BUFFER_SIZE 16 + #define OPENSSL_RAW_DATA 1 #define OPENSSL_ZERO_PADDING 2 #define OPENSSL_DONT_ZERO_PAD_KEY 4 @@ -65,7 +68,7 @@ extern zend_module_entry openssl_module_entry; #endif struct php_openssl_errors { - int buffer[ERR_NUM_ERRORS]; + int buffer[PHP_OPENSSL_ERR_BUFFER_SIZE]; int top; int bottom; }; @@ -100,34 +103,39 @@ void php_openssl_store_errors(void); void php_openssl_errors_set_mark(void); void php_openssl_errors_restore_mark(void); -/* openssl file path extra */ +/* openssl file path extra + * When a non-NULL stream is passed and the path check fails for a stream context option + * (arg_num == 0), the warning is reported via the stream error API so it participates in + * any active stream error operation; otherwise it is emitted immediately. */ bool php_openssl_check_path_ex( const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num, - bool contains_file_protocol, bool is_from_array, const char *option_name); + bool contains_file_protocol, bool is_from_array, const char *option_name, + struct _php_stream *stream); /* openssl file path check */ static inline bool php_openssl_check_path( const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num) { return php_openssl_check_path_ex( - file_path, file_path_len, real_path, arg_num, false, false, NULL); + file_path, file_path_len, real_path, arg_num, false, false, NULL, NULL); } /* openssl file path extra check with zend string */ static inline bool php_openssl_check_path_str_ex( zend_string *file_path, char *real_path, uint32_t arg_num, - bool contains_file_protocol, bool is_from_array, const char *option_name) + bool contains_file_protocol, bool is_from_array, const char *option_name, + struct _php_stream *stream) { return php_openssl_check_path_ex( ZSTR_VAL(file_path), ZSTR_LEN(file_path), real_path, arg_num, contains_file_protocol, - is_from_array, option_name); + is_from_array, option_name, stream); } /* openssl file path check with zend string */ static inline bool php_openssl_check_path_str( zend_string *file_path, char *real_path, uint32_t arg_num) { - return php_openssl_check_path_str_ex(file_path, real_path, arg_num, true, false, NULL); + return php_openssl_check_path_str_ex(file_path, real_path, arg_num, true, false, NULL, NULL); } PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method); @@ -161,9 +169,7 @@ typedef struct _php_openssl_certificate_object { extern zend_class_entry *php_openssl_certificate_ce; -static inline php_openssl_certificate_object *php_openssl_certificate_from_obj(zend_object *obj) { - return (php_openssl_certificate_object *)((char *)(obj) - XtOffsetOf(php_openssl_certificate_object, std)); -} +#define php_openssl_certificate_from_obj(obj) ZEND_CONTAINER_OF(obj, php_openssl_certificate_object, std) #define Z_OPENSSL_CERTIFICATE_P(zv) php_openssl_certificate_from_obj(Z_OBJ_P(zv)) @@ -176,9 +182,7 @@ typedef struct _php_openssl_x509_request_object { zend_object std; } php_openssl_request_object; -static inline php_openssl_request_object *php_openssl_request_from_obj(zend_object *obj) { - return (php_openssl_request_object *)((char *)(obj) - XtOffsetOf(php_openssl_request_object, std)); -} +#define php_openssl_request_from_obj(obj) ZEND_CONTAINER_OF(obj, php_openssl_request_object, std) #define Z_OPENSSL_REQUEST_P(zv) php_openssl_request_from_obj(Z_OBJ_P(zv)) @@ -192,15 +196,47 @@ typedef struct _php_openssl_pkey_object { zend_object std; } php_openssl_pkey_object; -static inline php_openssl_pkey_object *php_openssl_pkey_from_obj(zend_object *obj) { - return (php_openssl_pkey_object *)((char *)(obj) - XtOffsetOf(php_openssl_pkey_object, std)); -} +#define php_openssl_pkey_from_obj(obj) ZEND_CONTAINER_OF(obj, php_openssl_pkey_object, std) #define Z_OPENSSL_PKEY_P(zv) php_openssl_pkey_from_obj(Z_OBJ_P(zv)) bool php_openssl_is_pkey_ce(zval *val); void php_openssl_pkey_object_init(zval *zv, EVP_PKEY *pkey, bool is_private); +/* Openssl\Psk class */ + +/* Matches OpenSSL's PSK_MAX_PSK_LEN and PSK_MAX_IDENTITY_LEN */ +#define PHP_OPENSSL_PSK_MAX_PSK_LEN 256 +#define PHP_OPENSSL_PSK_MAX_IDENTITY_LEN 128 + +extern zend_class_entry *php_openssl_psk_ce; + +bool php_openssl_is_psk_ce(zval *val); +zend_string *php_openssl_psk_get_psk(zval *psk_zv); +zend_string *php_openssl_psk_get_identity(zval *psk_zv); + +/* Openssl\Session class */ + +#include + +typedef struct _php_openssl_session_object { + SSL_SESSION *session; + zend_object std; +} php_openssl_session_object; + +static inline php_openssl_session_object *php_openssl_session_from_obj(zend_object *obj) { + return (php_openssl_session_object *)((char *)(obj) - offsetof(php_openssl_session_object, std)); +} + +#define Z_OPENSSL_SESSION_P(zv) php_openssl_session_from_obj(Z_OBJ_P(zv)) + +/* Extern declarations for xp_ssl.c */ +extern zend_class_entry *php_openssl_session_ce; + +void php_openssl_session_object_init(zval *zv, SSL_SESSION *session); +bool php_openssl_is_session_ce(zval *val); +SSL_SESSION *php_openssl_session_from_zval(zval *zv); + #if defined(HAVE_OPENSSL_ARGON2) /** diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h index 00da5e74fc1b..fcbb8d42542f 100644 --- a/ext/openssl/php_openssl_backend.h +++ b/ext/openssl/php_openssl_backend.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -37,6 +35,12 @@ #include #include +#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 4 +typedef const X509_EXTENSION PHP_OPENSSL_X509_EXTENSION; +#else +typedef X509_EXTENSION PHP_OPENSSL_X509_EXTENSION; +#endif + /* number conversion flags checks */ #define PHP_OPENSSL_CHECK_NUMBER_CONVERSION(_cond, _name, _arg_num) \ do { \ @@ -168,8 +172,8 @@ struct php_x509_request { const EVP_CIPHER * priv_key_encrypt_cipher; }; -void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname); -void php_openssl_add_assoc_asn1_string(zval * val, char * key, ASN1_STRING * str); +void php_openssl_add_assoc_name_entry(zval * val, char * key, const X509_NAME * name, int shortname); +void php_openssl_add_assoc_asn1_string(zval * val, char * key, const ASN1_STRING * str); time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr); int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, CONF *config); char *php_openssl_conf_get_string(CONF *conf, const char *group, const char *name); @@ -264,9 +268,10 @@ X509 *php_openssl_x509_from_param( X509 *php_openssl_x509_from_zval( zval *val, bool *free_cert, uint32_t arg_num, bool is_from_array, const char *option_name); -zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw); +zend_string* php_openssl_x509_fingerprint( + X509 *peer, const char *method, bool raw, struct _php_stream *stream); -int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension); +int openssl_x509v3_subjectAltName(BIO *bio, PHP_OPENSSL_X509_EXTENSION *extension); STACK_OF(X509) *php_openssl_load_all_certs_from_file( char *cert_file, size_t cert_file_len, uint32_t arg_num); @@ -348,6 +353,7 @@ struct php_openssl_cipher_mode { bool is_single_run_aead; bool set_tag_length_always; bool set_tag_length_when_encrypting; + bool aad_supports_vector; int aead_get_tag_flag; int aead_set_tag_flag; int aead_ivlen_flag; diff --git a/ext/openssl/tests/ServerClientTestCase.inc b/ext/openssl/tests/ServerClientTestCase.inc index 8eedbfdebee8..b7e866954fcf 100644 --- a/ext/openssl/tests/ServerClientTestCase.inc +++ b/ext/openssl/tests/ServerClientTestCase.inc @@ -100,7 +100,8 @@ class ServerClientTestCase $ini = php_ini_loaded_file(); $cmd = sprintf( '%s %s "%s" %s', - PHP_BINARY, $ini ? "-n -c $ini" : "", + // XXX: TEST_PHP_EXTRA_ARGS for run-test values won't work here? + PHP_BINARY, $ini ? "-n -c $ini -d error_include_args=0" : "", __FILE__, WORKER_ARGV_VALUE ); @@ -128,6 +129,10 @@ class ServerClientTestCase private function cleanupWorkerProcess($worker) { fclose($this->workerStdIn[$worker]); + /* Drain stdout to EOF before closing it, so late worker writes (e.g. + * buffered error output) don't fail and abort the worker mid-output. */ + stream_set_blocking($this->workerStdOut[$worker], true); + stream_get_contents($this->workerStdOut[$worker]); fclose($this->workerStdOut[$worker]); proc_close($this->workerHandle[$worker]); } @@ -179,6 +184,9 @@ class ServerClientTestCase if (empty($addr)) { throw new \Exception("Failed server start"); } + if (strpos($addr, 'SERVER_EXCEPTION') !== false) { + echo $addr; + } if ($code === false) { $clientCode = preg_replace('/{{\s*ADDR\s*}}/', $addr, $clientCode); } else { diff --git a/ext/openssl/tests/bug28382.phpt b/ext/openssl/tests/bug28382.phpt index e2842023135c..7627da2931b5 100644 --- a/ext/openssl/tests/bug28382.phpt +++ b/ext/openssl/tests/bug28382.phpt @@ -6,6 +6,12 @@ openssl = 0x40000000) { + $extensions = &$ext['extensions']; + $extensions['crlDistributionPoints'] = preg_replace('/^Full Name:\R\s*/', '', trim($extensions['crlDistributionPoints'])); +} + var_dump($ext['extensions']); /* * The reason for %A at the end of crlDistributionPoints and authorityKeyIdentifier is that @@ -30,7 +36,7 @@ array(11) { string(59) "B0:A7:FF:F9:41:15:DE:23:39:BD:DD:31:0F:97:A0:B2:A2:74:E0:FC" ["authorityKeyIdentifier"]=> string(%d) "DirName:/C=RO/ST=Romania/L=Craiova/O=Sergiu/OU=Sergiu SRL/CN=Sergiu CA/emailAddress=n_sergiu@hotmail.com -serial:00%A" +serial:%A" ["keyUsage"]=> string(71) "Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment" ["nsBaseUrl"]=> diff --git a/ext/openssl/tests/bug65538_002.phpt b/ext/openssl/tests/bug65538_002.phpt index 44a322c6828f..853695723379 100644 --- a/ext/openssl/tests/bug65538_002.phpt +++ b/ext/openssl/tests/bug65538_002.phpt @@ -23,4 +23,4 @@ Warning: remote cafile streams are disabled for security purposes in %s on line Warning: file_get_contents(): Failed to enable crypto in %s on line %d -Warning: file_get_contents(%s): Failed to open stream: operation failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: operation failed in %s on line %d diff --git a/ext/openssl/tests/bug68920.phpt b/ext/openssl/tests/bug68920.phpt index 4abe12586b0b..a2d669e5b7d7 100644 --- a/ext/openssl/tests/bug68920.phpt +++ b/ext/openssl/tests/bug68920.phpt @@ -76,8 +76,6 @@ bool(false) Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d -Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d - Warning: stream_socket_client(): Failed to enable crypto in %s on line %d Warning: stream_socket_client(): Unable to connect to %s (Unknown error) in %s on line %d @@ -85,8 +83,6 @@ bool(false) Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d -Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d - Warning: stream_socket_client(): Failed to enable crypto in %s on line %d Warning: stream_socket_client(): Unable to connect to %s (Unknown error) in %s on line %d diff --git a/ext/openssl/tests/bug74796.phpt b/ext/openssl/tests/bug74796.phpt index b3f594d5e60f..8ec5590c064f 100644 --- a/ext/openssl/tests/bug74796.phpt +++ b/ext/openssl/tests/bug74796.phpt @@ -12,13 +12,24 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); + $serverCode = <<<'CODE' $serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", - "uk.php.net" => __DIR__ . "/sni_server_uk.pem", - "us.php.net" => __DIR__ . "/sni_server_us.pem" + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', ] ]]); @@ -33,6 +44,7 @@ $serverCode = <<<'CODE' phpt_wait(); CODE; +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile); $proxyCode = <<<'CODE' function parse_sni_from_client_hello($data) { @@ -134,7 +146,7 @@ CODE; $clientCode = <<<'CODE' $clientCtx = stream_context_create([ 'ssl' => [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'verify_peer' => true, 'verify_peer_name' => true, ], @@ -155,16 +167,21 @@ $clientCode = <<<'CODE' phpt_notify('server'); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, [ - 'server' => $serverCode, - 'proxy' => $proxyCode, + 'server' => $serverCode, + 'proxy' => $proxyCode, ]); ?> --CLEAN-- --EXPECT-- string(19) "Hello from server 0" diff --git a/ext/openssl/tests/bug80770.phpt b/ext/openssl/tests/bug80770.phpt index 9100aaa5aa18..21860dc78eb7 100644 --- a/ext/openssl/tests/bug80770.phpt +++ b/ext/openssl/tests/bug80770.phpt @@ -11,14 +11,25 @@ if (OPENSSL_VERSION_NUMBER < 0x10101000) die("skip OpenSSL v1.1.1 required"); saveCaCert($caCertFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); +$certificateGenerator->saveNewCertAsFileWithKey('Bug80770 Test Client', $clientCertFile); $serverCode = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", - "uk.php.net" => __DIR__ . "/sni_server_uk.pem", - "us.php.net" => __DIR__ . "/sni_server_us.pem" + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', ], 'verify_peer' => true, 'cafile' => '%s', @@ -28,7 +39,6 @@ $serverCode = <<<'CODE' ]]); $server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr, $flags, $ctx); phpt_notify_server_start($server); - $client = stream_socket_accept($server, 30); if ($client) { $success = stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_SERVER); @@ -43,7 +53,7 @@ $serverCode = <<<'CODE' phpt_notify(message: "ACCEPT_FAILED"); } CODE; -$serverCode = sprintf($serverCode, $caCertFile); +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile, $caCertFile); $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; @@ -58,19 +68,11 @@ $clientCode = <<<'CODE' if ($client) { stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); } - $result = phpt_wait(); echo trim($result); CODE; $clientCode = sprintf($clientCode, $clientCertFile); -include 'CertificateGenerator.inc'; - -// Generate CA and client certificate signed by that CA -$certificateGenerator = new CertificateGenerator(); -$certificateGenerator->saveCaCert($caCertFile); -$certificateGenerator->saveNewCertAsFileWithKey('Bug80770 Test Client', $clientCertFile); - include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> @@ -78,6 +80,9 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); --EXPECTF-- CLIENT_CERT_CAPTURED diff --git a/ext/openssl/tests/cipher_tests.inc b/ext/openssl/tests/cipher_tests.inc index f543a42c9f45..9d17e847bfa2 100644 --- a/ext/openssl/tests/cipher_tests.inc +++ b/ext/openssl/tests/cipher_tests.inc @@ -160,6 +160,59 @@ $php_openssl_cipher_tests = array( 'ct' => '1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6A', ), ), + 'aes-128-siv' => array( + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => '', + 'tag' => 'baba5b99dfc42fa9810fb2eb71ac2e9c', + 'pt' => 'b1677d933fa706f7ef349f9dd569c028' . + '279a5e2219728e77cfe916d5db979942' . + '5d8fb93b0e26dbc85ed14c050dc9f054' . + 'd9153c2be1e9b99ae7a109aba1e5a7f1' . + 'f2131786da90fe998d3571c144d066c3', + 'ct' => '91416054151e844965ad20a2057e2baa' . + '0e785269b152ba9d4dc834777e0d5376' . + 'db611856ae0d5d826f446c8eef47acb4' . + '83dccb37da9481648a4907fd3d65335b' . + 'd9585361c0c1834ac2b975f3238ea7c6', + ), + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => null, + 'tag' => '606ac96568128a278b02e3e04de97b7e', + 'pt' => 'ea597a2f9fb0b5c4d5a6f215047b58a3' . + '3d2c885bf67cbb09239239f5aecafd6f' . + 'd2401391154b024b05cd938b40fdc749' . + 'ebccb3f48a3156c0bad69cfc5035360d' . + '21ad626dc866cc539f2d0e34b6824fc3', + 'ct' => '9c75fa0345b35e2d6cbcc91ed3fc7feb' . + '84fea50c35766db0c847fb627385107b' . + '4f257548d8b80ccd04261fa651fb89cc' . + 'e6815ecf0c8c4586ce68544ddce4c3af' . + '01e9587282256569194b1dca788fd987', + ), + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => 'c0ef488e684e6fc95e0bd1da59861259', + 'tag' => 'a24cd6dcc0791bd7719a7f4fcb16de81', + 'pt' => 'b1677d933fa706f7ef349f9dd569c028' . + '279a5e2219728e77cfe916d5db979942' . + '5d8fb93b0e26dbc85ed14c050dc9f054' . + 'd9153c2be1e9b99ae7a109aba1e5a7f1' . + 'f2131786da90fe998d3571c144d066c3', + 'ct' => 'ea597a2f9fb0b5c4d5a6f215047b58a3' . + '3d2c885bf67cbb09239239f5aecafd6f' . + 'd2401391154b024b05cd938b40fdc749' . + 'ebccb3f48a3156c0bad69cfc5035360d' . + '21ad626dc866cc539f2d0e34b6824fc3', + ), + ), 'chacha20-poly1305' => array( array( 'key' => '808182838485868788898a8b8c8d8e8f' . diff --git a/ext/openssl/tests/ecc_custom_params.phpt b/ext/openssl/tests/ecc_custom_params.phpt index 0c63af1450ba..e3854eefa4d8 100644 --- a/ext/openssl/tests/ecc_custom_params.phpt +++ b/ext/openssl/tests/ecc_custom_params.phpt @@ -5,6 +5,30 @@ openssl --SKIPIF-- = 0x40000000) { + $d = hex2bin('8D0AC65AAEA0D6B96254C65817D4A143A9E7A03876F1A37D'); + $p = hex2bin('BDB6F4FE3E8B1D9E0DA8C0D46F4C318CEFE4AFE3B6B8551F'); + $a = hex2bin('BB8E5E8FBC115E139FE6A814FE48AAA6F0ADA1AA5DF91985'); + $b = hex2bin('1854BEBDC31B21B7AEFC80AB0ECD10D5B1B3308E6DBF11C1'); + $g_x = hex2bin('4AD5F7048DE709AD51236DE65E4D4B482C836DC6E4106640'); + $g_y = hex2bin('02BB3A02D4AAADACAE24817A4CA3A1B014B5270432DB27D2'); + $order = hex2bin('BDB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F56564677'); + + if (@openssl_pkey_new(array( + 'ec' => array( + 'p' => $p, + 'a' => $a, + 'b' => $b, + 'order' => $order, + 'g_x' => $g_x, + 'g_y' => $g_y, + 'd' => $d, + ), + )) === false) { + die("skip EC custom params unsupported with OpenSSL 4"); + } +} ?> --FILE-- +--FILE-- + [ + 'SNI_server_certs' => [ + "cs.php.net" => __DIR__ . "/sni_server_cs_expired.pem", + ] + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $serverFlags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 10); + if ($conn) { + fclose($conn); + } + + phpt_wait(); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create([ + 'ssl' => [ + 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'verify_peer' => true, + 'verify_peer_name' => true, + ], + "http" => [ + "proxy" => "tcp://{{ ADDR }}" + ], + ]); + + var_dump(@file_get_contents("https://cs.php.net/", false, $clientCtx)); + + phpt_notify(); +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) diff --git a/ext/openssl/tests/gh22081.phpt b/ext/openssl/tests/gh22081.phpt new file mode 100644 index 000000000000..17f74be7584c --- /dev/null +++ b/ext/openssl/tests/gh22081.phpt @@ -0,0 +1,76 @@ +--TEST-- +GH-22081: server reneg limit not reallocated across non-blocking retries +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + /* Plain TCP listener so the TLS handshake is driven manually below. */ + $server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Complete each handshake in non-blocking mode so that php_openssl_enable_crypto() is + * re-entered across multiple WANT_READ/WANT_WRITE rounds per connection. */ + for ($i = 0; $i < 5; $i++) { + $conn = @stream_socket_accept($server, 30); + if (!$conn) { + continue; + } + stream_set_blocking($conn, false); + do { + $r = stream_socket_enable_crypto($conn, true, STREAM_CRYPTO_METHOD_TLS_SERVER); + } while ($r === 0); + + if ($r === true) { + fwrite($conn, "ok $i\n"); + } + fclose($conn); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ]]); + + for ($i = 0; $i < 5; $i++) { + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client) { + echo trim(fgets($client)) . "\n"; + fclose($client); + } + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('gh22081-server-reneg-nonblocking', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +ok 0 +ok 1 +ok 2 +ok 3 +ok 4 + diff --git a/ext/openssl/tests/gh22186.phpt b/ext/openssl/tests/gh22186.phpt new file mode 100644 index 000000000000..8f28e6c45b58 --- /dev/null +++ b/ext/openssl/tests/gh22186.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-22186 (Heap buffer overflow in openssl_encrypt with AES-WRAP-PAD) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +done diff --git a/ext/openssl/tests/gh9310.phpt b/ext/openssl/tests/gh9310.phpt index 07a7d442cec8..874ed4c781d3 100644 --- a/ext/openssl/tests/gh9310.phpt +++ b/ext/openssl/tests/gh9310.phpt @@ -23,7 +23,21 @@ $certificateGenerator->saveNewCertAndKey('gh9310', $certFile, $pkFile); copy($certFile, $baseDirCertFile); copy($pkFile, $baseDirPkFile); -copy(__DIR__ . '/sni_server_uk_cert.pem', $baseDir . '/sni_server_uk_cert.pem'); + +$sniCaFile = __DIR__ . '/gh9310_sni_ca.pem.tmp'; +$sniCsFile = __DIR__ . '/gh9310_sni_cs.pem.tmp'; +$sniUkCertFile = __DIR__ . '/gh9310_sni_uk_cert.pem.tmp'; +$sniUkKeyFile = __DIR__ . '/gh9310_sni_uk_key.pem.tmp'; +$sniUsCertFile = __DIR__ . '/gh9310_sni_us_cert.pem.tmp'; +$sniUsKeyFile = __DIR__ . '/gh9310_sni_us_key.pem.tmp'; +$baseDirSniUkCertFile = $baseDir . '/sni_uk_cert.pem'; + +$certificateGenerator->saveCaCert($sniCaFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $sniCsFile); +$certificateGenerator->saveNewCertAndKey('uk.php.net', $sniUkCertFile, $sniUkKeyFile); +$certificateGenerator->saveNewCertAndKey('us.php.net', $sniUsCertFile, $sniUsKeyFile); + +copy($sniUkCertFile, $baseDirSniUkCertFile); $serverCodeTemplate = <<<'CODE' @@ -60,7 +74,7 @@ $sniServerCodeV1 = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", + "cs.php.net" => '%s', ] ]]); @@ -69,6 +83,7 @@ $sniServerCodeV1 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV1 = sprintf($sniServerCodeV1, $sniCsFile); $sniServerCodeV2 = <<<'CODE' ini_set('log_errors', 'On'); @@ -77,8 +92,8 @@ $sniServerCodeV2 = <<<'CODE' $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "uk.php.net" => [ - 'local_cert' => __DIR__ . '/gh9310/sni_server_uk_cert.pem', - 'local_pk' => __DIR__ . '/sni_server_uk_key.pem', + 'local_cert' => '%s', + 'local_pk' => '%s', ] ] ]]); @@ -88,6 +103,7 @@ $sniServerCodeV2 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV2 = sprintf($sniServerCodeV2, $baseDirSniUkCertFile, $sniUkKeyFile); $sniServerCodeV3 = <<<'CODE' ini_set('log_errors', 'On'); @@ -96,8 +112,8 @@ $sniServerCodeV3 = <<<'CODE' $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "us.php.net" => [ - 'local_cert' => __DIR__ . '/sni_server_us_cert.pem', - 'local_pk' => __DIR__ . '/sni_server_us_key.pem', + 'local_cert' => '%s', + 'local_pk' => '%s', ] ] ]]); @@ -107,14 +123,15 @@ $sniServerCodeV3 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV3 = sprintf($sniServerCodeV3, $sniUsCertFile, $sniUsKeyFile); $sniClientCodeTemplate = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', + 'peer_name' => '%s', ]; - $ctxArr['peer_name'] = '%s'; $ctx = stream_context_create(['ssl' => $ctxArr]); @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 1, $flags, $ctx); CODE; @@ -131,13 +148,13 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); $serverCode = sprintf($serverCodeTemplate, $baseDirCertFile, $pkFile); ServerClientTestCase::getInstance()->run($clientCode, $serverCode); -$sniClientCode = sprintf($sniClientCodeTemplate, 'cs.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'cs.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV1); -$sniClientCode = sprintf($sniClientCodeTemplate, 'uk.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'uk.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV2); -$sniClientCode = sprintf($sniClientCodeTemplate, 'us.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'us.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV3); ?> @@ -149,7 +166,13 @@ $baseDir = __DIR__ . '/gh9310'; @unlink(__DIR__ . '/gh9310.key'); @unlink($baseDir . '/cert.crt'); @unlink($baseDir . '/private.key'); -@unlink($baseDir . '/sni_server_uk_cert.pem'); +@unlink($baseDir . '/sni_uk_cert.pem'); +@unlink(__DIR__ . '/gh9310_sni_ca.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_cs.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_uk_cert.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_uk_key.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_us_cert.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_us_key.pem.tmp'); @rmdir($baseDir); ?> --EXPECTF-- @@ -169,15 +192,15 @@ PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(% PHP Warning: stream_socket_accept(): Unable to get real path of private key file `%sgh9310.key' in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_cs.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%ssni_server_cs.pem'; file not found in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_cs.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%sgh9310_sni_cs.pem.tmp'; file not found in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_uk_key.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local private key file `%ssni_server_uk_key.pem'; could not open file in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_uk_key.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local private key file `%sgh9310_sni_uk_key.pem.tmp'; could not open file in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_us_cert.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%ssni_server_us_cert.pem'; could not open file in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_us_cert.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%sgh9310_sni_us_cert.pem.tmp'; could not open file in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s diff --git a/ext/openssl/tests/openssl_csr_export_to_file_leak.phpt b/ext/openssl/tests/openssl_csr_export_to_file_leak.phpt index e6ce373d355b..3aea942267f4 100644 --- a/ext/openssl/tests/openssl_csr_export_to_file_leak.phpt +++ b/ext/openssl/tests/openssl_csr_export_to_file_leak.phpt @@ -10,5 +10,5 @@ var_dump(openssl_csr_export_to_file($path, str_repeat("a", 10000))); ?> --EXPECTF-- -Warning: openssl_csr_export_to_file(output_filename): must be a valid file path %s +Warning: openssl_csr_export_to_file(): must be a valid file path %s bool(false) diff --git a/ext/openssl/tests/openssl_decrypt_siv.phpt b/ext/openssl/tests/openssl_decrypt_siv.phpt new file mode 100644 index 000000000000..6fc299546e20 --- /dev/null +++ b/ext/openssl/tests/openssl_decrypt_siv.phpt @@ -0,0 +1,43 @@ +--TEST-- +openssl_decrypt() with SIV cipher algorithm tests +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + $test) { + echo "TEST $idx\n"; + $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $test['tag'], $test['aad']); + var_dump($test['pt'] === $pt); +} + +// failed because no AAD +echo "TEST AAD\n"; +var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $test['tag'])); +// failed because wrong tag +echo "TEST WRONGTAG\n"; +var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], str_repeat('x', 16), $test['aad'])); + +?> +--EXPECTF-- +TEST 0 +bool(true) +TEST 1 +bool(true) +TEST 2 +bool(true) +TEST AAD +bool(false) +TEST WRONGTAG +bool(false) diff --git a/ext/openssl/tests/openssl_encrypt_siv.phpt b/ext/openssl/tests/openssl_encrypt_siv.phpt new file mode 100644 index 000000000000..43a5c5b34b5a --- /dev/null +++ b/ext/openssl/tests/openssl_encrypt_siv.phpt @@ -0,0 +1,51 @@ +--TEST-- +openssl_encrypt() with SIV cipher algorithm tests +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + $test) { + echo "TEST $idx\n"; + $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $tag, $test['aad'], strlen($test['tag'])); + var_dump($test['ct'] === $ct); + var_dump($test['tag'] === $tag); +} + +// Empty tag should not be equivalent to null tag +echo "TEST AAD\n"; +var_dump(openssl_encrypt('data', $method, 'password', 0, '', $tag, '') !== openssl_encrypt('data', $method, 'password', 0, '', $tag, null)); + +// Failing to retrieve tag (max is 16 bytes) +var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 32), $tag, '', 20)); + +// Failing when no tag supplied +var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 32))); +?> +--EXPECTF-- +TEST 0 +bool(true) +bool(true) +TEST 1 +bool(true) +bool(true) +TEST 2 +bool(true) +bool(true) +TEST AAD +bool(true) + +Warning: openssl_encrypt(): Retrieving verification tag failed in %s on line %d +bool(false) + +Warning: openssl_encrypt(): A tag should be provided when using AEAD mode in %s on line %d +bool(false) diff --git a/ext/openssl/tests/openssl_password.phpt b/ext/openssl/tests/openssl_password.phpt index 0dbc1ae42a3f..ca0d20f9bcc3 100644 --- a/ext/openssl/tests/openssl_password.phpt +++ b/ext/openssl/tests/openssl_password.phpt @@ -5,7 +5,10 @@ openssl --SKIPIF-- --FILE-- diff --git a/ext/openssl/tests/openssl_pbkdf2_basic.phpt b/ext/openssl/tests/openssl_pbkdf2_basic.phpt index fd253ac78bb2..ba79f9415ba8 100644 --- a/ext/openssl/tests/openssl_pbkdf2_basic.phpt +++ b/ext/openssl/tests/openssl_pbkdf2_basic.phpt @@ -19,6 +19,8 @@ var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 16777216))); var_dump(bin2hex(openssl_pbkdf2('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 25, 4096))); var_dump(bin2hex(openssl_pbkdf2("pass\0word", "sa\0lt", 16, 4096))); +var_dump(bin2hex(openssl_pbkdf2("password", "salt", 16, 4096, "sha-256"))); + ?> --EXPECT-- string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6" @@ -26,3 +28,4 @@ string(40) "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957" string(40) "4b007901b765489abead49d926f721d065a429c1" string(50) "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038" string(32) "56fa6aa75548099dcc37d7f03425e0c3" +string(32) "c5e478d59288c841aa530db6845c4c8d" diff --git a/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt b/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt new file mode 100644 index 000000000000..b57cd32b686a --- /dev/null +++ b/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt @@ -0,0 +1,23 @@ +--TEST-- +Memory leak when array initialization in openssl_pkcs12_read() fails +--EXTENSIONS-- +openssl +--FILE-- +foo, "csos"); +} catch (TypeError $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +TypeError: Cannot assign array to reference held by property Typed::$foo of type string diff --git a/ext/openssl/tests/openssl_pkey_export_to_file_leak.phpt b/ext/openssl/tests/openssl_pkey_export_to_file_leak.phpt index 5e2bdff6b48f..24bc737d009c 100644 --- a/ext/openssl/tests/openssl_pkey_export_to_file_leak.phpt +++ b/ext/openssl/tests/openssl_pkey_export_to_file_leak.phpt @@ -11,5 +11,5 @@ var_dump(openssl_pkey_export_to_file($key, str_repeat("a", 10000), passphrase: " ?> --EXPECTF-- -Warning: openssl_pkey_export_to_file(output_filename): must be a valid file path %s +Warning: openssl_pkey_export_to_file(): must be a valid file path %s bool(false) diff --git a/ext/openssl/tests/openssl_sign_basic.phpt b/ext/openssl/tests/openssl_sign_basic.phpt index 9d2edbec59f7..d8880a6a1899 100644 --- a/ext/openssl/tests/openssl_sign_basic.phpt +++ b/ext/openssl/tests/openssl_sign_basic.phpt @@ -7,7 +7,6 @@ openssl $data = "Testing openssl_sign()"; $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $wrong = "wrong"; - var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256)); var_dump(bin2hex($sign1)); var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256)); @@ -17,6 +16,10 @@ var_dump(strlen($sign1)); var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); var_dump(strlen($sign2)); var_dump($sign1 === $sign2); +var_dump(openssl_sign($data, $sign3, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_DIGEST)); +var_dump(strlen($sign3)); +var_dump(openssl_sign($data, $sign4, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, 32)); +var_dump(strlen($sign4)); var_dump(openssl_sign($data, $sign, $wrong)); ?> --EXPECTF-- @@ -29,6 +32,10 @@ int(128) bool(true) int(128) bool(false) +bool(true) +int(128) +bool(true) +int(128) Warning: openssl_sign(): Supplied key param cannot be coerced into a private key in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_verify_basic.phpt b/ext/openssl/tests/openssl_verify_basic.phpt index 1b28c1371083..3bcf3ba0e66f 100644 --- a/ext/openssl/tests/openssl_verify_basic.phpt +++ b/ext/openssl/tests/openssl_verify_basic.phpt @@ -13,6 +13,14 @@ $wrong = "wrong"; openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING); var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); +openssl_sign($data, $sign_pss, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_DIGEST); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_DIGEST)); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, 32)); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_AUTO)); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, 20)); +openssl_sign($data, $sign_pss, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_MAX); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_MAX)); +var_dump(openssl_verify($data, $sign_pss, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_DIGEST)); openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256); var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); var_dump(openssl_verify($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); @@ -24,6 +32,12 @@ var_dump(openssl_verify($wrong, $sign, $pubkey, OPENSSL_ALGO_SHA256)); int(1) int(0) int(1) +int(1) +int(1) +int(0) +int(1) +int(0) +int(1) Warning: openssl_verify(): Supplied key param cannot be coerced into a public key in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt index 7c06881c9be7..99c1150b0e85 100644 --- a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt +++ b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt @@ -14,7 +14,7 @@ $cert = "file://" . __DIR__ . "/cert.crt"; $bert = "file://" . __DIR__ . "/bug41033.pem"; $sert = "file://" . __DIR__ . "/san-cert.pem"; $cpca = __DIR__ . "/san-cert.pem"; -$utfl = __DIR__ . "/sni_server_uk.pem"; +$utfl = __DIR__ . "/sni_server.pem"; $rcrt = openssl_x509_read($cert); /* int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose); */ diff --git a/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt b/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt index 5775c2597c3e..4e0570241d80 100644 --- a/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt +++ b/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt @@ -5,10 +5,10 @@ openssl --FILE-- --EXPECTF-- -Warning: openssl_x509_export_to_file(output_filename): must be a valid file path %s +Warning: openssl_x509_export_to_file(): must be a valid file path %s bool(false) diff --git a/ext/openssl/tests/openssl_x509_parse_basic_openssl32.phpt b/ext/openssl/tests/openssl_x509_parse_basic_openssl32.phpt index a0b125fb4ea0..84415d133f55 100644 --- a/ext/openssl/tests/openssl_x509_parse_basic_openssl32.phpt +++ b/ext/openssl/tests/openssl_x509_parse_basic_openssl32.phpt @@ -8,12 +8,28 @@ if (OPENSSL_VERSION_NUMBER < 0x30200000) die('skip For OpenSSL >= 3.2'); ?> --FILE-- --EXPECTF-- bool(true) diff --git a/ext/openssl/tests/session_resumption_cache_disabled.phpt b/ext/openssl/tests/session_resumption_cache_disabled.phpt new file mode 100644 index 000000000000..9e0e8a82f399 --- /dev/null +++ b/ext/openssl/tests/session_resumption_cache_disabled.phpt @@ -0,0 +1,86 @@ +--TEST-- +TLS session resumption - server with cache disabled +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => false, /* Disable session caching */ + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "No cache connection " . ($i + 1) . "\n"); + fclose($client); + } + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $globalSession = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$globalSession) { + $globalSession = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client1); + } + + /* Second connection - server won't use cached session */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $globalSession, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + echo trim(fgets($client2)) . "\n"; + $meta2 = stream_get_meta_data($client2); + echo "Second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client2); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_disabled_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +No cache connection 1 +First connection resumed: no +No cache connection 2 +Second connection resumed: no diff --git a/ext/openssl/tests/session_resumption_client_basic.phpt b/ext/openssl/tests/session_resumption_client_basic.phpt new file mode 100644 index 000000000000..ee1d126a6d9f --- /dev/null +++ b/ext/openssl/tests/session_resumption_client_basic.phpt @@ -0,0 +1,89 @@ +--TEST-- +TLS session resumption - client basic resumption +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } + + /* Second connection - resumed session */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + echo trim(fgets($client2)) . "\n"; + $meta2 = stream_get_meta_data($client2); + echo "Second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client2); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +Hello from server +First connection resumed: no +Session data received: yes +Hello from server +Second connection resumed: yes diff --git a/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt new file mode 100644 index 000000000000..f87f831a7859 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt @@ -0,0 +1,79 @@ +--TEST-- +TLS session resumption - warning when trying to enable tickets with session_get_cb +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-app', + 'no_ticket' => false, // Explicitly trying to enable tickets + 'session_new_cb' => function($stream, $sessionData) { + // Store session + }, + 'session_get_cb' => function($stream, $sessionId) { + return null; + } + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected\n"; + } + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_no_ticket_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: Session tickets cannot be enabled when session_get_cb is setConnection failed as expected + diff --git a/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt b/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt new file mode 100644 index 000000000000..5563b0c22cf8 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt @@ -0,0 +1,82 @@ +--TEST-- +TLS session resumption - num_tickets controls ticket generation (TLS 1.3) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'num_tickets' => 3, // Issue 3 tickets per connection + ]]); + + $server = stream_socket_server('tlsv1.3://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + // Accept one connection + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Ticket test\n"); + // Keep connection open briefly to allow tickets to be sent + usleep(100000); // 100ms + fclose($client); + } + + phpt_notify(message: "SERVER_DONE"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $ticketCount = 0; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'session_new_cb' => function($stream, $session) use (&$ticketCount) { + $ticketCount++; + } + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client) { + $response = fgets($client); + echo trim($response) . "\n"; + + // Keep connection open briefly to receive all tickets + usleep(150000); // 150ms + fclose($client); + } + + echo "Tickets received: $ticketCount\n"; + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_num_tickets_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Ticket test +Tickets received: 3 +SERVER_DONE diff --git a/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt b/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt new file mode 100644 index 000000000000..13654cd451e9 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt @@ -0,0 +1,112 @@ +--TEST-- +TLS session resumption - num_tickets = 0 disables tickets, forces session IDs +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-no-tickets', + 'num_tickets' => 0, // Disable ticket issuance + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled++; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore) { + $key = bin2hex($sessionId); + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + // Accept two connections + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + usleep(50000); // Allow session storage + fclose($client); + } + } + + phpt_notify(message: "NEW_CB_CALLS:$newCbCalled"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + $clientTickets = 0; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData, &$clientTickets) { + $sessionData = $session; + $clientTickets++; + } + ]]); + + // First connection + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + usleep(100000); // Wait for session storage + fclose($client1); + } + + echo "Client received tickets on first connection: $clientTickets\n"; + + // Second connection with resumption + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_no_tickets_zero_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +Client first connection resumed: no +Response 1 +Client received tickets on first connection: 0 +Client second connection resumed: no +Response 2 +Server: NEW_CB_CALLS:0 diff --git a/ext/openssl/tests/session_resumption_import_export_session.phpt b/ext/openssl/tests/session_resumption_import_export_session.phpt new file mode 100644 index 000000000000..0d9a3274b113 --- /dev/null +++ b/ext/openssl/tests/session_resumption_import_export_session.phpt @@ -0,0 +1,98 @@ +--TEST-- +TLS session resumption - import and export session +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept single connections */ + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + if (empty($sessionData)) { + // default should be pem + $pemSessionData = $session->export(); + var_dump($pemSessionData); + $session = Openssl\Session::import($pemSessionData); + $pemSessionData = $session->export(OPENSSL_ENCODING_PEM); + var_dump($pemSessionData); + $session = Openssl\Session::import($pemSessionData, OPENSSL_ENCODING_PEM); + $derSessionData = $session->export(OPENSSL_ENCODING_DER); + var_dump(strlen($derSessionData) > 0); + var_dump(strpos($derSessionData, 'BEGIN SSL SESSION PARAMETERS') === false); + $session = Openssl\Session::import($derSessionData, OPENSSL_ENCODING_DER); + var_dump($session); + } + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +" +string(%d) "-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +" +bool(true) +bool(true) +object(Openssl\Session)#%d (1) { + ["id"]=> + string(32) "%a" +} +Hello from server +First connection resumed: no +Session data received: yes diff --git a/ext/openssl/tests/session_resumption_invalid_callback.phpt b/ext/openssl/tests/session_resumption_invalid_callback.phpt new file mode 100644 index 000000000000..b6cfc90a0554 --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_callback.phpt @@ -0,0 +1,60 @@ +--TEST-- +TLS session resumption - invalid callback throws TypeError +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use invalid callback */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => 'not_a_valid_function', + ]]); + + try { + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + echo "Should not reach here\n"; + } catch (TypeError $e) { + echo "TypeError caught: " . (strpos($e->getMessage(), 'session_new_cb must be a valid callback') !== false ? "YES" : "NO"); + echo "\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_cb_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +TypeError caught: YES diff --git a/ext/openssl/tests/session_resumption_invalid_data.phpt b/ext/openssl/tests/session_resumption_invalid_data.phpt new file mode 100644 index 000000000000..7e50b9235a2b --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_data.phpt @@ -0,0 +1,66 @@ +--TEST-- +TLS session resumption - invalid session data is fatal +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + try { + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed unexpectedlyd\n"; + } + } catch (\Throwable $e) { + echo "Type error thrown: " . $e->getMessage() . "\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): Unable to connect to %s in %s on line %d +Type error thrown: session_data must be an OpenSSLSession instance diff --git a/ext/openssl/tests/session_resumption_invalid_session_import.phpt b/ext/openssl/tests/session_resumption_invalid_session_import.phpt new file mode 100644 index 000000000000..a9c5b65f2051 --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_session_import.phpt @@ -0,0 +1,23 @@ +--TEST-- +TLS session resumption - invalid session import +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +Failed to import session data diff --git a/ext/openssl/tests/session_resumption_new_cb_no_context.phpt b/ext/openssl/tests/session_resumption_new_cb_no_context.phpt new file mode 100644 index 000000000000..ee2852c54ad7 --- /dev/null +++ b/ext/openssl/tests/session_resumption_new_cb_no_context.phpt @@ -0,0 +1,78 @@ +--TEST-- +TLS session resumption - warning when session_new_cb without session_id_context and verify_peer enabled +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'verify_peer' => true, + 'cafile' => '%s', + 'session_new_cb' => function($stream, $session) { + echo "not called new_cb\n"; + }, + 'session_get_cb' => function($stream, $sessionId) { + echo "not called new_cb\n"; + return null; + } + /* Missing: 'session_id_context' => 'myapp' */ + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile, $caCertFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveCaCert($caCertFile); +$certificateGenerator->saveNewCertAsFileWithKey('session_verify_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: session_id_context must be set if session_new_cb is set diff --git a/ext/openssl/tests/session_resumption_persistent_reject.phpt b/ext/openssl/tests/session_resumption_persistent_reject.phpt new file mode 100644 index 000000000000..835e9bb51648 --- /dev/null +++ b/ext/openssl/tests/session_resumption_persistent_reject.phpt @@ -0,0 +1,66 @@ +--TEST-- +TLS session resumption - callbacks rejected on persistent streams +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT; + + /* Try to use callback with persistent stream */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) { + echo "This should never be called\n"; + } + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected with persistent stream\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_persistent_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- + +Warning: stream_socket_client(): session_new_cb is not supported for persistent streams in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): Unable to connect to %s in %s on line %d +Connection failed as expected with persistent stream diff --git a/ext/openssl/tests/session_resumption_require_new_cb.phpt b/ext/openssl/tests/session_resumption_require_new_cb.phpt new file mode 100644 index 000000000000..a08408e2d90b --- /dev/null +++ b/ext/openssl/tests/session_resumption_require_new_cb.phpt @@ -0,0 +1,73 @@ +--TEST-- +TLS session resumption - server requires session_new_cb with session_get_cb +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_get_cb' => function($stream, $sessionId) { + return null; + } + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected\n"; + } + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_require_cb_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: session_new_cb is required when session_get_cb is providedConnection failed as expected diff --git a/ext/openssl/tests/session_resumption_serialize_session.phpt b/ext/openssl/tests/session_resumption_serialize_session.phpt new file mode 100644 index 000000000000..f2f3c98e5e5b --- /dev/null +++ b/ext/openssl/tests/session_resumption_serialize_session.phpt @@ -0,0 +1,84 @@ +--TEST-- +TLS session resumption - serialize session +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept single connections */ + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + if (empty($sessionData)) { + $serializedSessionData = serialize($session); + var_dump($serializedSessionData); + $session = unserialize($serializedSessionData); + var_dump($session); + } + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "O:15:"Openssl\Session":1:{s:3:"pem";s:%d:"-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +";}" +object(Openssl\Session)#9 (1) { + ["id"]=> +%a +} +Hello from server +First connection resumed: no +Session data received: yes diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt new file mode 100644 index 000000000000..02c6a7dcfdc7 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt @@ -0,0 +1,116 @@ +--TEST-- +TLS session resumption - server external cache callbacks with context id +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Report results */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + $result[] = "SESSIONS:" . count($sessionStore); + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session captured: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_external_proper_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Session captured: YES +Client second connection resumed: yes +Response 2 +Server: NEW_CB_CALLED,GET_CB_CALLED,SESSIONS:3 diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt new file mode 100644 index 000000000000..bdc3d2ce1bf6 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt @@ -0,0 +1,116 @@ +--TEST-- +TLS session resumption - server external cache callbacks with context id for TLS 1.2 +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', // Proper configuration + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tlsv1.2://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Report results */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + $result[] = "SESSIONS:" . count($sessionStore); + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session captured: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_external_proper_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Session captured: YES +Client second connection resumed: yes +Response 2 +Server: NEW_CB_CALLED,GET_CB_CALLED,SESSIONS:1 diff --git a/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt b/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt new file mode 100644 index 000000000000..28bb97faff28 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt @@ -0,0 +1,121 @@ +--TEST-- +TLS session resumption - server external cache callbacks with no verify +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'verify_peer' => false, + 'no_ticket' => true, + 'session_cache' => true, + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + 'session_remove_cb' => function($stream, $sessionId) use (&$sessionStore, &$removeCbCalled) { + $key = bin2hex($sessionId); + unset($sessionStore[$key]); + $removeCbCalled = true; + } + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Notify client about callback invocations */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + if ($removeCbCalled) $result[] = "REMOVE_CB_CALLED"; + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server callbacks: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_server_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Client second connection resumed: yes +Response 2 +Server callbacks: NEW_CB_CALLED,GET_CB_CALLED diff --git a/ext/openssl/tests/session_resumption_server_internal.phpt b/ext/openssl/tests/session_resumption_server_internal.phpt new file mode 100644 index 000000000000..d7c2633601e8 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_internal.phpt @@ -0,0 +1,99 @@ +--TEST-- +TLS session resumption - server internal cache +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', + 'session_cache' => true, + 'session_cache_size' => 1024, + 'session_timeout' => 300, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Connection " . ($i + 1) . "\n"); + fclose($client); + } + } + + phpt_notify(message: "SERVER_DONE"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session data received: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Wait for server */ + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_internal_cache_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Connection 1 +Session data received: YES +Client second connection resumed: yes +Connection 2 +SERVER_DONE diff --git a/ext/openssl/tests/session_unserialize_repeat.phpt b/ext/openssl/tests/session_unserialize_repeat.phpt new file mode 100644 index 000000000000..b1e33c2d03bd --- /dev/null +++ b/ext/openssl/tests/session_unserialize_repeat.phpt @@ -0,0 +1,84 @@ +--TEST-- +Openssl\Session::__unserialize throws on a repeat call +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 10); + if ($client) { + fwrite($client, "ok\n"); + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $captured = null; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function ($s, $session) use (&$captured) { + $captured = $session; + return true; + }, + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + ]]); + + $c = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 10, + STREAM_CLIENT_CONNECT, $ctx); + if (!$c) { + echo "connect failed: $errstr\n"; + return; + } + fread($c, 8); + fclose($c); + + if (!$captured instanceof Openssl\Session) { + echo "no session captured\n"; + return; + } + + $payload = $captured->__serialize(); + $sess = unserialize(serialize($captured)); + echo "first: " . (is_object($sess) ? get_class($sess) : "fail") . "\n"; + + try { + $sess->__unserialize($payload); + echo "second: no throw\n"; + } catch (Error $e) { + echo "second: " . $e->getMessage() . "\n"; + } + + echo "alive\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session-unserialize-repeat', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +first: Openssl\Session +second: Cannot call Openssl\Session::__unserialize() on an already-initialized session +alive diff --git a/ext/openssl/tests/sni_server_uk.pem b/ext/openssl/tests/sni_server.pem similarity index 100% rename from ext/openssl/tests/sni_server_uk.pem rename to ext/openssl/tests/sni_server.pem diff --git a/ext/openssl/tests/sni_server.phpt b/ext/openssl/tests/sni_server.phpt index 7f9a4e82872b..db0b0190dab3 100644 --- a/ext/openssl/tests/sni_server.phpt +++ b/ext/openssl/tests/sni_server.phpt @@ -8,13 +8,25 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); + $serverCode = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", - "uk.php.net" => __DIR__ . "/sni_server_uk.pem", - "us.php.net" => __DIR__ . "/sni_server_us.pem" + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', ] ]]); @@ -25,11 +37,12 @@ $serverCode = <<<'CODE' @stream_socket_accept($server, 3); } CODE; +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile); $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'capture_peer_cert' => true ]; @@ -51,10 +64,18 @@ $clientCode = <<<'CODE' $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; var_dump(openssl_x509_parse($cert)['subject']['CN']); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> +--CLEAN-- + --EXPECTF-- string(%d) "cs.php.net" string(%d) "uk.php.net" diff --git a/ext/openssl/tests/sni_server_cs_cert.pem b/ext/openssl/tests/sni_server_cs_cert.pem deleted file mode 100644 index b77c7b83e2ad..000000000000 --- a/ext/openssl/tests/sni_server_cs_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjEyWhcNMjYwNDAy -MTgzNjEyWjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKY3MucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAL8uTYc5LcxHbB02xger6mADZrOa59c1xZkyaxpVgsKC -LDZk32ob2ZKwtXAl02e32zwfF0G6QLc9mUlOznMAVvQfKJGFD6Pc4v6bcHK4LELD -dIa3A/DAUVHHHr8IpnuXy74PBPUSf+vMvctwZ0XFVmDtrACvY7k34nTYxE1NwW9O -aF7/A0g/+qJ10LuLlw4LEN3EV3pXfVAdMWs5kF8soiKl3P3KUwJ2hFWM59vGo+zZ -VG8zauddVFzF2OOMfRHF1qT1We4XjXCTc2OQwjc5rVyq7fcojKVkHD1xM7BElcQD -Kom/bkxTpb1V9eyyD8QRuuej40w/SdYepAWzAlMc7O8CAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFHPfd8dK -Lz1R0Ck4WV1B9AWXd5DSMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQB6WSIHEyDXLZxH -hZjqSNQOA7Wc9Z2FCAiD29xYkGTL8WuPVGGP1mu4B92ytj+PMWwqSReDa7eTGLE7 -O7ozw9l+c+gNmHFNikSsGjlV2E8CToQOFMny+jAQYMSXf8UbTp9xDfgG02t/71hv -SLWqdeHMLcR0xi0nBQH0vDOkwUbuWYqFa3jejHieGhykHM6CkIk6lqnyOEO+ooIF -ZsLprrg1ss/mXCPI6niP0hze55ERKdxI7Rk8sZ4pVkf2SUWqZrUS0aJ+Ymmwi6Xd -2V7izq5N30PkJS8MtqII4FAjRBIkwPh0sy8PmW/DzkYU+lYQnDfYLKDFKcj8xJK/ -o8oZUBsQltrSj0KlM9QuqxCTCBCy1nXZ9WHOhq+jdLiTc1Oi60uEHcUMrLK8aYc4 -HqIvZS6C2iwMI0d1OP3VxmAbMQ9yqRi+FbLYavJ3H40jrU9SYqdxa0BrTaz8MJNE -6AEwgQDPChczSghvHME+Fs4mtGCY3TesbNZKVahQRjaFIhMZIZ4RP4CRc0bJOBG+ -8Me4+KHNsD2ki5b03wAN6C1P2QrMzI+gH9fXLZYp761ciDAsX6YIzrhHHYLxYpJH -BkQKKs8dCQWE5IzgVrdlvC3Z1/l9om66wHqqx7nKnPfYs/Sfnwe9MpCD6xJrXiTm -WS7NM6fbQpO9APNr7o0ZOjbbWFzlNw== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_cs.pem b/ext/openssl/tests/sni_server_cs_expired.pem similarity index 100% rename from ext/openssl/tests/sni_server_cs.pem rename to ext/openssl/tests/sni_server_cs_expired.pem diff --git a/ext/openssl/tests/sni_server_cs_key.pem b/ext/openssl/tests/sni_server_cs_key.pem deleted file mode 100644 index bf1e9f25193b..000000000000 --- a/ext/openssl/tests/sni_server_cs_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEAvy5NhzktzEdsHTbGB6vqYANms5rn1zXFmTJrGlWCwoIsNmTf -ahvZkrC1cCXTZ7fbPB8XQbpAtz2ZSU7OcwBW9B8okYUPo9zi/ptwcrgsQsN0hrcD -8MBRUccevwime5fLvg8E9RJ/68y9y3BnRcVWYO2sAK9juTfidNjETU3Bb05oXv8D -SD/6onXQu4uXDgsQ3cRXeld9UB0xazmQXyyiIqXc/cpTAnaEVYzn28aj7NlUbzNq -511UXMXY44x9EcXWpPVZ7heNcJNzY5DCNzmtXKrt9yiMpWQcPXEzsESVxAMqib9u -TFOlvVX17LIPxBG656PjTD9J1h6kBbMCUxzs7wIDAQABAoIBAQC85lBeY0X4ST3v -I7bJz7kWQ2YP4uhfAdeLhoDDFWjNLffniwYhfwEc6xNri0R2f/jUT9gX7qORKwEx -qPdeNCC2t67LElGg1FlJv2Z9Q7MgCKYzkdQH5s6y4e9kTHTLO/JpiceZKz1QTQ3f -XOH9032E6nIAf0wmr6xHTgOwajrN8VI5BuPEMVmEwIw3AtYeqVuPCNKyGR4HUVkC -2bAydnGngbRJRnNzmKcWJancxpHDGBSFqPyuXMFC7Jgo3ZmyCbGp99vuXVk/sW9x -5aj94M9nRE0guk05ivH2/JZao2uLYkIgjFWlhNxKdWgWRk8DEuN4djC8mKS9YH1q -crYRToMhAoGBAOspUTtKP54mpZmyhxuDqj02JaJRzNTskPHsiF1UhtXuw7uT+ryV -ekUFLNXoFmn9mbx1WVaUvGH4qjilvQOxz7u++lz0ApqJEfyM3jc/cC40Y5zcuGSu -Etbg+SyDoytlgMCIydJyrS7NNALSo5p5oG6XY2f8yd/DCAmo8LzypaHRAoGBANAf -R1SlBMc/bOsi6GrJxcBVSCFMiKYiO5woL5aUKa9yM+UQuQ/6xbQ7Q+sOlt0FH3xo -AJ2L60qTdjyXVtjOdtXs5ZC4l+C6AfnCx6yLr+fNc4SOYXEfqS4LZylgwKd9KyVB -asspIW9Idbgebmi6vPyt9LDkIp0h1VuFGjkvQJK/AoGBAI4pbS0dprXyARyYW6sb -fpgAmuG099IkrT9DUfCx/81myTclr2fAKal+BmvOIXaz0/OlMXvw8K19iVIzh7+r -B70lJ+93p/dKM/BsLI5TsHqOO0YB/QsIXOVAHgJ2FfdPJnW+e9vYba+kZ/Po6PSi -4ITaykJ8BIJcQgis89QWEGFxAoGBAJhQO+jzuDKF9ZWEf6ofrw0anOZZ16wWY5/e -PS2rk3JmVxpuibHrKqPDt+ogTELHDAsFJmYmz3VNxHuFmrajK49Wh4/JuMVr/CQo -6+8YcA1qa/94IFIlBLDBAafjujsZvOjQHnM+z8xcsGKmStF00Pjv6qNG4xoyd646 -FD4DmfOLAoGAWXehpopZKXE9gRAni881ucK6WqxPPBoofbozi09D0MmfarIVaSkv -jNVVHBfLWd7IEXTjiipPBeUqq6Jc3pscN1Vp4rrl8jTmVTdazEv0LuzpdUFqmNo2 -M+xw17uz9D9Q32/aW1Lar0PdIaL/wGEDEyzEBFwrGppcENLilPz8gzU= ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/sni_server_key_cert.phpt b/ext/openssl/tests/sni_server_key_cert.phpt index 49ed6aa5328c..878f97c1e359 100644 --- a/ext/openssl/tests/sni_server_key_cert.phpt +++ b/ext/openssl/tests/sni_server_key_cert.phpt @@ -8,21 +8,36 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAndKey('cs.php.net', $csCertFile, $csKeyFile); +$certificateGenerator->saveNewCertAndKey('uk.php.net', $ukCertFile, $ukKeyFile); +$certificateGenerator->saveNewCertAndKey('us.php.net', $usCertFile, $usKeyFile); + $serverCode = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "cs.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_cs_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_cs_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], "uk.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_uk_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_uk_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], "us.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_us_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_us_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], ] ]]); @@ -34,11 +49,16 @@ $serverCode = <<<'CODE' @stream_socket_accept($server, 3); } CODE; +$serverCode = sprintf($serverCode, + $csCertFile, $csKeyFile, + $ukCertFile, $ukKeyFile, + $usCertFile, $usKeyFile +); $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'capture_peer_cert' => true ]; @@ -60,10 +80,21 @@ $clientCode = <<<'CODE' $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; var_dump(openssl_x509_parse($cert)['subject']['CN']); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> +--CLEAN-- + --EXPECTF-- string(%d) "cs.php.net" string(%d) "uk.php.net" diff --git a/ext/openssl/tests/sni_server_uk_cert.pem b/ext/openssl/tests/sni_server_uk_cert.pem deleted file mode 100644 index 57663855e590..000000000000 --- a/ext/openssl/tests/sni_server_uk_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjMyWhcNMjYwNDAy -MTgzNjMyWjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdWsucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKzKRXj0jVBzRwolFn7Ej0MR2kE6Q36IBCEiDLhquSYR -Lh1spR0XudSVmRot/Wvz2PawApX4P6qj57scBQ6KL4ULKvSndCZ7F1tdQjEqogYp -n/L8oBhP1dgyDonsewG/PucxC+3Aqzcl3w5Pg7qE+zad42khP7t9TjFAMxc+PxC+ -2as5ZCDJBwfxksCyCQfFWx7eB7p39vGy63k3Izv+UKTZEhbSdT721kb91oXkecpE -EFhihfVYMGMEtC7u2JLSxdkRhWYSMqVCvI2syYsLAUUNH2kgqQF00j2Iddhg3oMA -IiqhpC/n2slHVhp56WE1TsrGC/JgqIvQK9AT4LRxFb8CAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJK58uJe -Lv8WDOR8TTLUcSxO1zCyMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQDHayU795hFnQNj -fuYV21sEmkSjgtp6X4rV9JfoCp8U2gieL4mizoCPx9Q8HYaAf98hPYTofGUaCSd+ -Xlzd8lhLt9GCU+BsCxGtJocrjOQDhyhkioN8iirQRTtJpRVC6a4RCBGpenOD7Z7C -Z32uGXohzFuigP/J8/SXBdHrlpNSa03iEkkisPR46mbGj06lFVOFHJDNKA3CnQwM -3VfqvZt0ksZi/gAOol8dtrAd3k5JBfJ2BtqsPbycEGAhsGrTK/MeqiFcO8QZiXpN -qf0wZzOMFZJ4HqTiHs4TMMQaDK8c4qfR0l1OE224ijcB5NlqMjGAZabMfHgNZcl7 -fYPX+POsOMaqubv98uoC0PCK8NCTyfB4V/el72EEoVfwKYOxm3eYXBEE2ZNyIci6 -YKYhNa9e2k+cFueYMztV06HTGgkcHcSJATP+3ISTRx3tj1BPmc4O4WAMEMx1E0gg -PaVrBVAylGzt8kaMaOQMBImpsALSfutq6+KtQiu0OTGS3yVUGamV4AyRjuwF1/ZA -kZbjmNEGsf9d2rzS89ckds24QUx0zrfJ56p7lRvyVK/pML7iadv8dUH3fKDDDerD -oocLjOjNxFGN9Woz+kfidA8Siu0zsfQ6CLPlaQrVAVQH4iMuCZraqMc3TqAiUKRj -iHKp6FFrRZmY8W8HEKHv98uGofn+3g== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_uk_key.pem b/ext/openssl/tests/sni_server_uk_key.pem deleted file mode 100644 index 3baa6efd776e..000000000000 --- a/ext/openssl/tests/sni_server_uk_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEArMpFePSNUHNHCiUWfsSPQxHaQTpDfogEISIMuGq5JhEuHWyl -HRe51JWZGi39a/PY9rAClfg/qqPnuxwFDoovhQsq9Kd0JnsXW11CMSqiBimf8vyg -GE/V2DIOiex7Ab8+5zEL7cCrNyXfDk+DuoT7Np3jaSE/u31OMUAzFz4/EL7Zqzlk -IMkHB/GSwLIJB8VbHt4Hunf28bLreTcjO/5QpNkSFtJ1PvbWRv3WheR5ykQQWGKF -9VgwYwS0Lu7YktLF2RGFZhIypUK8jazJiwsBRQ0faSCpAXTSPYh12GDegwAiKqGk -L+fayUdWGnnpYTVOysYL8mCoi9Ar0BPgtHEVvwIDAQABAoIBAGpg7XyWMxpAno/k -XYEWSo0kRJa75CnWW5R6fhJbwjlpglajONQ8czAqGeRARDFeI0lc+3qRJ8FKv7Q2 -f/Z/pNnoEj4liiDWz350X/gdIztgDRVv6rCNFj7QMps/eEuPDo8PZySs5bxCGJ2a -3qLKlE7/za4/xhkMAEPaHppEvFb15dpomqP2Fjqei9afp8tD+xJv9BGtkFIy9acw -94AWQi974kgW7ZzfEf8RqHM0ExKiESCc26knbcBu0tQ892YHggMccUMk/UrVgR5d -vuGOBurlYGLBstSDSKCCe6la4N/FX3FiC3WhVNescnuTZPXcX3zebh7roGjgrTdd -6UJYBIECgYEA09XYihdwW66G9Y09OatzlzBh1Rvzjv2Vl5NmWHHb6vh38H4PcOof -S1pT0JvRzpt8uEs4i+Eda5PyQyp4iGtD+DQ07Dxh2jiixsE3PRFRG2wg2QCgDHnS -6vgV1VOqA/A4on4nhxLZXxhX4YvHaJYlm1bZ+amG+j5XiI/NtHJm9k8CgYEA0NB9 -bAoaZnc06+T8rMaO45boX5SvYsCZbtY3VRl75SrbMal0IKfnXHELVHuei12LmlMs -LuFgG8jGO3+ncxUqMytoGvrmk/cM9tCNbDKVHtFbqz0qt9lkDAwLsBougKnVsNDW -Aae/tz/wYXJct86unfLh0xtvkx5Iz1we4cS1fZECgYA8YR+vfK7R8xUUuIVTAsOX -vHqmO6lYgH87DRCG9S0x9FB7g/LyxEjXOY/aTg+nTDpobUhY1nmESE8tRdXFTI27 -GWZcT3m0sZ/z9u6/wUfVAST7tWnpJHAx+TR/8bDsHnSGHF836O98Y3vpFeZosSNW -+5J1zxRiD5LzocmIPXOLkQKBgEgHApxXx898YwbTj8zRGMysay89DFpV8RboUWHL -To83/y/cMbBp+kZKwAu+MGwGMndjJSRunUY4NRik6c+qh0nrORfFX+++Efy4529g -60scEDC7Apc0J2x4Yze1cED1VD6PaqJbiKffKD2UwyKr6lOVSgwVtKDcm2Tbc9OQ -lMHhAoGBAIPwYVxzWM6I6pr8x2TucpBZZReLytz7uzybMNvbKCrwlETbNNXubnfp -nPuPKzpeRI0y26pIIAbijzFW0MXq+kIu3H7we8TaImsJ1AaQCTYeoLWBVcr6RISk -3d4i7iT35aWCuhPVve0FNIv/u3jrqX2H2C2MXMiLOsw1GFxPvpi4 ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/sni_server_us.pem b/ext/openssl/tests/sni_server_us.pem deleted file mode 100644 index 170a8a96e75d..000000000000 --- a/ext/openssl/tests/sni_server_us.pem +++ /dev/null @@ -1,57 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA1QkC3tiNYDY+ZxMmPbagYUbMpzuXo9mVBvYh86bYZaeB7bts -QCBK+6VD4D2LjR3RszpzmOzhJXjm8j0t+GeRS3OMIM75/BKAnixXicRSIb8zdIPz -JP992vvMq8p46/XftAfBhAMOaCqcD85zpyX4PhfC9733nOyN4yqx58O4UhVTKih6 -W9/ldp3uwSYAW+HyoINnHls/bFO8vv60K5VIhkxK30LHnC5PvByGfuHOgrscEThs -jW0ESqO0+9l88KhGdmLgzvbBlGxNziCMfn0LcFH6p2ITc3foD4LSzGEFtJ92OZi3 -buCOfbFsN7vWHTsEi89fRcCnWGtMwLUx0TCluQIDAQABAoIBAQCnsUQ1Lrl6trhA -Yu6DPbLZX+XQ7jPbonaQ2Ea5iOhmfIjmHdaEU+cyV1EqvseO+Z4MO0KraiuAV79T -h50cIEpa3kW7vbFCHz5nQ/hUVdlg/yT93rASu5rSOctOnz64Xv8Ms948kDtS+9eF -Cbo4JMdX+VRbt4mmWP8HhqAsFACPexEoWxJcIxwFcI24GTGzySjemNjQzbmcVhzM -a4k6n8DolCL1cRS54C5Aaf5g4+IFDgyydcgZXp1lnX3MnqivSNkejnPnY55NcmrH -X3ZWPlAi9GHOJE33uy8bGWnip7Tn4iTt6tJvjz/yP82TGACDg1B8XsKrqsuQLsoU -cNBVGcQBAoGBAPteCgNmuNOpo4SRA1UVRw1WgnE8YtnNA6vYyVcTLSpqabq33UaD -03L9CQsbHtj88U+E8OH24Iqj3U9x7QJfH8DVmWuBrlwez80JsKGnLdViHydjKcAz -H2Cbv+SiWeaWXkFCkN4Jf7k3q0Ew4SG2LOq5PVUy/NB4bilbJD2ExKpZAoGBANj2 -Hpwo35IQ4XfSSsGaCdn+8ajMcNUMMGZ6YkZqmVO4kogqobyrPL/2KE9ol/hlacw6 -U/6Digox5/wqruYfqyM8lqGOq2/0Xf7c4XfiOTS9Na4JN3OGzlyqPvcn2zdqhYFY -iHPu2RqpA+LhCHW9Zs8C1Bp/KAEPdRP6OabqVaphAoGACLrHVj7nBFLL3vq6RuYq -RYhPl2cld7LrAbjRpTiBRQvVCCsCgERrv36SJdSXSanfJ4fSZcaRHb97HBs0w/RR -wfypC1bBm2lmhhRkEfkgWlzCADgtZwNff5dpHqOUw7FNLK8HIO7rhJ8uT2FHMEiH -Xs94FdFjfknwaXdE1u4ZdmECgYEAgxfbkQHFbO2UPqErGGXp0/WOsS6ucpyF1jXW -kbOxZ3vb1jjkNyrEbzzeSHTrdmRYk9UekWeLjfNvt9dWjKfP8V+XqJCbF+9wqCFw -fs6LQEmfWMQq5DwtDqKznwVPGOHdPzVuZZaJSemb9oeAZBwINccAv+3bDyD23hZQ -pYFsN6ECgYEA33QYDNG/spki4D8rlxyxZ+1MdB/efnrGBhO8FsJpG5+AtmYhWgD9 -sl29+3aiRkmDznoy36z+hoeZePILEAKMcbHyXOymixOHPuaZJ95hbvq6sqd6WMAe -w5tHnxlfEuu11zatolk6WiAmTmG3sZpN5Tqloq0Ye4dvlhVKNV3Bn3E= ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjQ0WhcNMjYwNDAy -MTgzNjQ0WjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdXMucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANUJAt7YjWA2PmcTJj22oGFGzKc7l6PZlQb2IfOm2GWn -ge27bEAgSvulQ+A9i40d0bM6c5js4SV45vI9LfhnkUtzjCDO+fwSgJ4sV4nEUiG/ -M3SD8yT/fdr7zKvKeOv137QHwYQDDmgqnA/Oc6cl+D4Xwve995zsjeMqsefDuFIV -Uyooelvf5Xad7sEmAFvh8qCDZx5bP2xTvL7+tCuVSIZMSt9Cx5wuT7wchn7hzoK7 -HBE4bI1tBEqjtPvZfPCoRnZi4M72wZRsTc4gjH59C3BR+qdiE3N36A+C0sxhBbSf -djmYt27gjn2xbDe71h07BIvPX0XAp1hrTMC1MdEwpbkCAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOXnUeNs -grKQb+EvG36DXjjDDmsFMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQBDLwuLbx75ACSU -5cF2L/D17JEnhlna62MgKNdpNLJSpaofK2Lk2BqsmnQf5JdkrXWMUN/DsmXZc9pq -25XmprfABUP9Cx18KPVqLQ43Z9o+R9xI1Ospt5mrpxGp6l2BHSs/4G69nuPFpcIJ -iabnLYdUk2Z+64lPe4EMBrZH+pj4xn3JA59BACJYNYn0nLaw45DIAyzyLJ0vVSwc -0JtjsztXQov4UqdWXxLRFfe2nEGoK8ZkTJ8ELcCYu6sNSBjw9Ech78uXN1BQOBTK -lhAgN3FKqOp3hqf0umqf35gDvmWwLB/eptUYZ96gBYT0tbPA0P+YsW+iZmamxXma -Odgg8iRcPxKl9bVPt57NLaDy/RQhOxTGXQs1Q2jp7UhzqoZDClwVSDxd6DEppAFA -OZAY+Rsrm7VoCwVQ/1KbcJHmJ/79tArvaWJk3KHLGMpdZq4KwrC3hM8/QxYtyX/6 -cfnXvShBYCdfTGgNlj3t/mNAgp1ZB3s9ClGqRBR/P0Db+ryv5DuxYM6nzEB3Od0y -kT5tHbXDQY+1HCExjOMi7Al0cmC2r3+oxDA4UjGv+npgcfeoxQhXmm/SQRiPdKlb -vT0D594sLoB23jqA9bMehpxEyI7eGjfFUmXwMeu0tJhipvpJI3ogJoM+SCFTyLkc -12cPiz/sR/ALhvhUJXTeUH8wxPjzbA== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_us_cert.pem b/ext/openssl/tests/sni_server_us_cert.pem deleted file mode 100644 index 4452e3c6cfbf..000000000000 --- a/ext/openssl/tests/sni_server_us_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjQ0WhcNMjYwNDAy -MTgzNjQ0WjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdXMucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANUJAt7YjWA2PmcTJj22oGFGzKc7l6PZlQb2IfOm2GWn -ge27bEAgSvulQ+A9i40d0bM6c5js4SV45vI9LfhnkUtzjCDO+fwSgJ4sV4nEUiG/ -M3SD8yT/fdr7zKvKeOv137QHwYQDDmgqnA/Oc6cl+D4Xwve995zsjeMqsefDuFIV -Uyooelvf5Xad7sEmAFvh8qCDZx5bP2xTvL7+tCuVSIZMSt9Cx5wuT7wchn7hzoK7 -HBE4bI1tBEqjtPvZfPCoRnZi4M72wZRsTc4gjH59C3BR+qdiE3N36A+C0sxhBbSf -djmYt27gjn2xbDe71h07BIvPX0XAp1hrTMC1MdEwpbkCAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOXnUeNs -grKQb+EvG36DXjjDDmsFMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQBDLwuLbx75ACSU -5cF2L/D17JEnhlna62MgKNdpNLJSpaofK2Lk2BqsmnQf5JdkrXWMUN/DsmXZc9pq -25XmprfABUP9Cx18KPVqLQ43Z9o+R9xI1Ospt5mrpxGp6l2BHSs/4G69nuPFpcIJ -iabnLYdUk2Z+64lPe4EMBrZH+pj4xn3JA59BACJYNYn0nLaw45DIAyzyLJ0vVSwc -0JtjsztXQov4UqdWXxLRFfe2nEGoK8ZkTJ8ELcCYu6sNSBjw9Ech78uXN1BQOBTK -lhAgN3FKqOp3hqf0umqf35gDvmWwLB/eptUYZ96gBYT0tbPA0P+YsW+iZmamxXma -Odgg8iRcPxKl9bVPt57NLaDy/RQhOxTGXQs1Q2jp7UhzqoZDClwVSDxd6DEppAFA -OZAY+Rsrm7VoCwVQ/1KbcJHmJ/79tArvaWJk3KHLGMpdZq4KwrC3hM8/QxYtyX/6 -cfnXvShBYCdfTGgNlj3t/mNAgp1ZB3s9ClGqRBR/P0Db+ryv5DuxYM6nzEB3Od0y -kT5tHbXDQY+1HCExjOMi7Al0cmC2r3+oxDA4UjGv+npgcfeoxQhXmm/SQRiPdKlb -vT0D594sLoB23jqA9bMehpxEyI7eGjfFUmXwMeu0tJhipvpJI3ogJoM+SCFTyLkc -12cPiz/sR/ALhvhUJXTeUH8wxPjzbA== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_us_key.pem b/ext/openssl/tests/sni_server_us_key.pem deleted file mode 100644 index 8b0d73d7d63e..000000000000 --- a/ext/openssl/tests/sni_server_us_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA1QkC3tiNYDY+ZxMmPbagYUbMpzuXo9mVBvYh86bYZaeB7bts -QCBK+6VD4D2LjR3RszpzmOzhJXjm8j0t+GeRS3OMIM75/BKAnixXicRSIb8zdIPz -JP992vvMq8p46/XftAfBhAMOaCqcD85zpyX4PhfC9733nOyN4yqx58O4UhVTKih6 -W9/ldp3uwSYAW+HyoINnHls/bFO8vv60K5VIhkxK30LHnC5PvByGfuHOgrscEThs -jW0ESqO0+9l88KhGdmLgzvbBlGxNziCMfn0LcFH6p2ITc3foD4LSzGEFtJ92OZi3 -buCOfbFsN7vWHTsEi89fRcCnWGtMwLUx0TCluQIDAQABAoIBAQCnsUQ1Lrl6trhA -Yu6DPbLZX+XQ7jPbonaQ2Ea5iOhmfIjmHdaEU+cyV1EqvseO+Z4MO0KraiuAV79T -h50cIEpa3kW7vbFCHz5nQ/hUVdlg/yT93rASu5rSOctOnz64Xv8Ms948kDtS+9eF -Cbo4JMdX+VRbt4mmWP8HhqAsFACPexEoWxJcIxwFcI24GTGzySjemNjQzbmcVhzM -a4k6n8DolCL1cRS54C5Aaf5g4+IFDgyydcgZXp1lnX3MnqivSNkejnPnY55NcmrH -X3ZWPlAi9GHOJE33uy8bGWnip7Tn4iTt6tJvjz/yP82TGACDg1B8XsKrqsuQLsoU -cNBVGcQBAoGBAPteCgNmuNOpo4SRA1UVRw1WgnE8YtnNA6vYyVcTLSpqabq33UaD -03L9CQsbHtj88U+E8OH24Iqj3U9x7QJfH8DVmWuBrlwez80JsKGnLdViHydjKcAz -H2Cbv+SiWeaWXkFCkN4Jf7k3q0Ew4SG2LOq5PVUy/NB4bilbJD2ExKpZAoGBANj2 -Hpwo35IQ4XfSSsGaCdn+8ajMcNUMMGZ6YkZqmVO4kogqobyrPL/2KE9ol/hlacw6 -U/6Digox5/wqruYfqyM8lqGOq2/0Xf7c4XfiOTS9Na4JN3OGzlyqPvcn2zdqhYFY -iHPu2RqpA+LhCHW9Zs8C1Bp/KAEPdRP6OabqVaphAoGACLrHVj7nBFLL3vq6RuYq -RYhPl2cld7LrAbjRpTiBRQvVCCsCgERrv36SJdSXSanfJ4fSZcaRHb97HBs0w/RR -wfypC1bBm2lmhhRkEfkgWlzCADgtZwNff5dpHqOUw7FNLK8HIO7rhJ8uT2FHMEiH -Xs94FdFjfknwaXdE1u4ZdmECgYEAgxfbkQHFbO2UPqErGGXp0/WOsS6ucpyF1jXW -kbOxZ3vb1jjkNyrEbzzeSHTrdmRYk9UekWeLjfNvt9dWjKfP8V+XqJCbF+9wqCFw -fs6LQEmfWMQq5DwtDqKznwVPGOHdPzVuZZaJSemb9oeAZBwINccAv+3bDyD23hZQ -pYFsN6ECgYEA33QYDNG/spki4D8rlxyxZ+1MdB/efnrGBhO8FsJpG5+AtmYhWgD9 -sl29+3aiRkmDznoy36z+hoeZePILEAKMcbHyXOymixOHPuaZJ95hbvq6sqd6WMAe -w5tHnxlfEuu11zatolk6WiAmTmG3sZpN5Tqloq0Ye4dvlhVKNV3Bn3E= ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/stream_copy_to_stream_ssl_to_file.phpt b/ext/openssl/tests/stream_copy_to_stream_ssl_to_file.phpt new file mode 100644 index 000000000000..76684d2917be --- /dev/null +++ b/ext/openssl/tests/stream_copy_to_stream_ssl_to_file.phpt @@ -0,0 +1,71 @@ +--TEST-- +stream_copy_to_stream() from a TLS stream copies decrypted data (no fd fast-path) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; + $server = stream_socket_server("ssl://127.0.0.1:0", $errno, $errstr, $flags, $serverCtx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 5); + fwrite($conn, str_repeat("secret-", 1000)); + fclose($conn); + fclose($server); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$peerName = 'stream_copy_ssl_peer'; +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'verify_peer' => true, + 'cafile' => '%s', + 'peer_name' => '%s', + ]]); + $client = stream_socket_client("ssl://{{ ADDR }}", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $clientCtx); + + $tmp = tmpfile(); + /* If the copy offloaded the raw socket fd it would write ciphertext; the + * decrypted plaintext proves it correctly fell back to the userspace loop. */ + $copied = stream_copy_to_stream($client, $tmp); + var_dump($copied); + + fseek($tmp, 0, SEEK_SET); + $content = stream_get_contents($tmp); + var_dump(strlen($content)); + var_dump($content === str_repeat("secret-", 1000)); + + fclose($tmp); + fclose($client); +CODE; +$clientCode = sprintf($clientCode, $cacertFile, $peerName); + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveCaCert($cacertFile); +$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +int(7000) +int(7000) +bool(true) diff --git a/ext/openssl/tests/stream_socket_get_crypto_status_basic.phpt b/ext/openssl/tests/stream_socket_get_crypto_status_basic.phpt new file mode 100644 index 000000000000..b659eee79e78 --- /dev/null +++ b/ext/openssl/tests/stream_socket_get_crypto_status_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +stream_socket_get_crypto_status(): constants and behavior on a non-crypto stream +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECT-- +int(0) +int(1) +int(2) +bool(true) diff --git a/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt b/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt new file mode 100644 index 000000000000..7e0f660c980d --- /dev/null +++ b/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt @@ -0,0 +1,141 @@ +--TEST-- +stream_socket_get_crypto_status(): reports WANT_READ/WANT_WRITE during a non-blocking handshake +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + ['local_cert' => '%s']]); + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $server = stream_socket_server("tls://127.0.0.1:0", $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 30); + if ($conn) { + fwrite($conn, "ok\n"); + phpt_wait(); + fclose($conn); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +/* Plain TCP proxy that forwards the server handshake flight in fragments, so the client's + * non-blocking handshake sees a partial TLS record and reports WANT_READ instead of completing + * in a single call (which can otherwise happen depending on timing). */ +$proxyCode = <<<'CODE' + $upstream = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT); + stream_set_blocking($upstream, false); + + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, $flags); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server); + stream_set_blocking($conn, false); + + $read = [$upstream, $conn]; + while (stream_select($read, $write, $except, 1)) { + foreach ($read as $fp) { + $data = stream_get_contents($fp); + if ($data === '') { + continue; + } + if ($fp === $conn) { + fwrite($upstream, $data); + } else { + /* Fragment server -> client to force a partial TLS record. */ + foreach (str_split($data, (int) ceil(strlen($data) / 3)) as $part) { + fwrite($conn, $part); + usleep(50000); + } + } + } + if (feof($upstream) || feof($conn)) { + break; + } + $read = [$upstream, $conn]; + } + + phpt_wait(); +CODE; + +/* Client connects over plain TCP, then completes the TLS handshake in non-blocking mode, using + * the reported crypto status to select the right direction to wait on. */ +$clientCode = <<<'CODE' + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'peer_name' => '%s', + ]]); + + $client = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx); + stream_set_blocking($client, false); + + $sawWant = false; + $pendingAlwaysWant = true; + + do { + $r = stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if ($r === 0) { + $status = stream_socket_get_crypto_status($client); + if ($status === STREAM_CRYPTO_STATUS_WANT_READ + || $status === STREAM_CRYPTO_STATUS_WANT_WRITE) { + $sawWant = true; + } else { + /* must never be NONE while the handshake is still pending */ + $pendingAlwaysWant = false; + } + + /* Wait on the direction the engine actually asked for. */ + $read = $write = $except = null; + if ($status === STREAM_CRYPTO_STATUS_WANT_WRITE) { + $write = [$client]; + } else { + $read = [$client]; + } + stream_select($read, $write, $except, 1); + } + } while ($r === 0); + + var_dump($r); + var_dump($sawWant); + var_dump($pendingAlwaysWant); + /* After a completed handshake the status is reset to NONE. */ + var_dump(stream_socket_get_crypto_status($client) === STREAM_CRYPTO_STATUS_NONE); + + stream_set_blocking($client, true); + echo trim(fgets($client)), "\n"; + phpt_notify('server'); + phpt_notify('proxy'); + fclose($client); +CODE; +$clientCode = sprintf($clientCode, $peerName); + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, [ + 'server' => $serverCode, + 'proxy' => $proxyCode, +]); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +ok diff --git a/ext/openssl/tests/stream_socket_get_crypto_status_read.phpt b/ext/openssl/tests/stream_socket_get_crypto_status_read.phpt new file mode 100644 index 000000000000..308950a8ef03 --- /dev/null +++ b/ext/openssl/tests/stream_socket_get_crypto_status_read.phpt @@ -0,0 +1,95 @@ +--TEST-- +stream_socket_get_crypto_status(): reports WANT_READ on a non-blocking read with no application data +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + ['local_cert' => '%s']]); + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $server = stream_socket_server("tls://127.0.0.1:0", $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 30); + + /* Do not send anything until the client has performed its first read, so that the read is + * guaranteed to find no application data. */ + phpt_wait(); + fwrite($conn, "hello\n"); + + phpt_wait(); + fclose($conn); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'peer_name' => '%s', + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx); + stream_set_blocking($client, false); + + /* No application data has been sent yet - a non-blocking read returns nothing and the crypto + * status reflects that the OpenSSL wants to read. */ + $data = fread($client, 100); + var_dump($data === '' || $data === false); + var_dump(stream_socket_get_crypto_status($client) === STREAM_CRYPTO_STATUS_WANT_READ); + + /* Now let the server send. */ + phpt_notify(); + + $buf = ''; + $read = [$client]; + $write = $except = null; + while (stream_select($read, $write, $except, 5)) { + $chunk = fread($client, 100); + if ($chunk === '' || $chunk === false) { + /* A non-application record (e.g. a TLS 1.3 session ticket) may arrive first. */ + if (feof($client)) { + break; + } + } else { + $buf .= $chunk; + if (strlen($buf) >= 6) { + break; + } + } + $read = [$client]; + $write = $except = null; + } + + echo trim($buf), "\n"; + /* A successful read clears the pending status back to NONE. */ + var_dump(stream_socket_get_crypto_status($client) === STREAM_CRYPTO_STATUS_NONE); + + phpt_notify(); + fclose($client); +CODE; +$clientCode = sprintf($clientCode, $peerName); + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +hello +bool(true) diff --git a/ext/openssl/tests/stream_socket_get_crypto_status_supplemental_read.phpt b/ext/openssl/tests/stream_socket_get_crypto_status_supplemental_read.phpt new file mode 100644 index 000000000000..9044b1bbdbe4 --- /dev/null +++ b/ext/openssl/tests/stream_socket_get_crypto_status_supplemental_read.phpt @@ -0,0 +1,83 @@ +--TEST-- +stream_socket_get_crypto_status(): reports status NONE after supplemental read +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + ['local_cert' => '%s']]); + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $server = stream_socket_server("tls://127.0.0.1:0", $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 30); + + fwrite($conn, "hello\n"); + + phpt_wait(); + fclose($conn); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'peer_name' => '%s', + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx); + stream_set_blocking($client, false); + + $buf = ''; + $read = [$client]; + $write = $except = null; + while (stream_select($read, $write, $except, 5)) { + // Initially, read only the first char, then request more than is stored + // in the buffer, triggering a supplemental read. + $chunk = fread($client, strlen($buf) === 0 ? 1 : 10); + if ($chunk === '' || $chunk === false) { + /* A non-application record (e.g. a TLS 1.3 session ticket) may arrive first. */ + if (feof($client)) { + break; + } + } else { + $buf .= $chunk; + if (strlen($buf) >= 6) { + break; + } + } + $read = [$client]; + $write = $except = null; + } + + echo trim($buf), "\n"; + /* A successful read clears the pending status back to NONE. */ + var_dump(stream_socket_get_crypto_status($client) === STREAM_CRYPTO_STATUS_NONE); + + phpt_notify(); + fclose($client); +CODE; +$clientCode = sprintf($clientCode, $peerName); + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +hello +bool(true) diff --git a/ext/openssl/tests/stream_supplemental_read_timeout.phpt b/ext/openssl/tests/stream_supplemental_read_timeout.phpt new file mode 100644 index 000000000000..0e36f146bf9e --- /dev/null +++ b/ext/openssl/tests/stream_supplemental_read_timeout.phpt @@ -0,0 +1,90 @@ +--TEST-- +Timeout for supplemental read at end of a blocking stream in SSL stream wrapper +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + ['local_cert' => '%s']]); + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $server = stream_socket_server("tls://127.0.0.1:0", $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 30); + + fwrite($conn, "hello\n"); + + phpt_wait(); + fclose($conn); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'peer_name' => '%s', + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx); + stream_set_blocking($client, true); + stream_set_timeout($client, 5); + $start = hrtime(true); + + $buf = ''; + $read = [$client]; + $write = $except = null; + while (true) { + if (!stream_select($read, $write, $except, 5)) { + break; + } + + // Initially, read only the first char, then request more than is stored + // in the buffer, triggering a supplemental read. + $chunk = fread($client, strlen($buf) === 0 ? 1 : 10); + if ($chunk === '' || $chunk === false) { + /* A non-application record (e.g. a TLS 1.3 session ticket) may arrive first. */ + if (feof($client)) { + break; + } + } else { + $buf .= $chunk; + if (strlen($buf) >= 6) { + break; + } + } + $read = [$client]; + $write = $except = null; + } + + echo trim($buf), "\n"; + + $diff = (hrtime(true) - $start) / 1e9; + var_dump($diff < 4.0); + + phpt_notify(); + fclose($client); +CODE; +$clientCode = sprintf($clientCode, $peerName); + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +hello +bool(true) diff --git a/ext/openssl/tests/tls_psk_callback_not_callable.phpt b/ext/openssl/tests/tls_psk_callback_not_callable.phpt new file mode 100644 index 000000000000..29382e2a13ab --- /dev/null +++ b/ext/openssl/tests/tls_psk_callback_not_callable.phpt @@ -0,0 +1,46 @@ +--TEST-- +TLS PSK callback option must be a valid callable +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => 'php_openssl_no_such_function', + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +caught: psk_client_cb must be a valid callback, %s + diff --git a/ext/openssl/tests/tls_psk_callback_wrong_type.phpt b/ext/openssl/tests/tls_psk_callback_wrong_type.phpt new file mode 100644 index 000000000000..78d950f19974 --- /dev/null +++ b/ext/openssl/tests/tls_psk_callback_wrong_type.phpt @@ -0,0 +1,48 @@ +--TEST-- +TLS PSK client callback returning wrong type raises TypeError +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream) { + /* Returning a string instead of Openssl\Psk|null. */ + return "not a Psk object"; + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: PSK callback must return Openssl\Psk or null diff --git a/ext/openssl/tests/tls_psk_client_callback_null.phpt b/ext/openssl/tests/tls_psk_client_callback_null.phpt new file mode 100644 index 000000000000..92d970908c8e --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_callback_null.phpt @@ -0,0 +1,45 @@ +--TEST-- +TLS 1.2 PSK: client callback returning null aborts handshake (no shared cipher) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("doesnotmatter", null); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + /* Reject: no PSK to use, no other ciphers offered. */ + return null; + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/tests/tls_psk_client_callback_throws.phpt b/ext/openssl/tests/tls_psk_client_callback_throws.phpt new file mode 100644 index 000000000000..13b2d71476c2 --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_callback_throws.phpt @@ -0,0 +1,48 @@ +--TEST-- +TLS PSK client callback throwing exception propagates to stream_socket_client caller +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + throw new RuntimeException('callback boom'); + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (RuntimeException $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: callback boom + diff --git a/ext/openssl/tests/tls_psk_client_no_identity.phpt b/ext/openssl/tests/tls_psk_client_no_identity.phpt new file mode 100644 index 000000000000..bfc8d078ceff --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_no_identity.phpt @@ -0,0 +1,49 @@ +--TEST-- +TLS PSK client callback must return Openssl\Psk with a non-null identity +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + /* No identity supplied. */ + return new Openssl\Psk(str_repeat("\x42", 16)); + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (ValueError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: Client PSK callback must return Openssl\Psk with a non-null identity + diff --git a/ext/openssl/tests/tls_psk_mismatch.phpt b/ext/openssl/tests/tls_psk_mismatch.phpt new file mode 100644 index 000000000000..8fa90d115c5a --- /dev/null +++ b/ext/openssl/tests/tls_psk_mismatch.phpt @@ -0,0 +1,44 @@ +--TEST-- +TLS 1.2 PSK: mismatching key material aborts handshake +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x11", 16), $identity); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x22", 16), 'id'); + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/tests/tls_psk_tls12_basic.phpt b/ext/openssl/tests/tls_psk_tls12_basic.phpt new file mode 100644 index 000000000000..2f2a558c4b40 --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls12_basic.phpt @@ -0,0 +1,62 @@ +--TEST-- +TLS 1.2 PSK basic client/server round-trip +--EXTENSIONS-- +openssl +--SKIPIF-- += 1.1.1 required"); +?> +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + if ($identity === 'client_id') { + return new Openssl\Psk("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"); + } + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + $client = stream_socket_accept($server, 30); + fwrite($client, "hello-from-server"); + fread($client, 1024); + fclose($client); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk( + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", + 'client_id' + ); + }, + ]]); + $client = stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 30, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client !== false); + var_dump(fread($client, 1024)); + fwrite($client, "hello-from-client"); + /* Verify PSK was used (no peer cert) */ + $params = stream_context_get_params($client); + var_dump(isset($params['options']['ssl']['peer_certificate'])); + fclose($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(true) +string(17) "hello-from-server" +bool(false) diff --git a/ext/openssl/tests/tls_psk_tls13_basic.phpt b/ext/openssl/tests/tls_psk_tls13_basic.phpt new file mode 100644 index 000000000000..a7642624252a --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls13_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +TLS 1.3 PSK basic client/server round-trip +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + if ($identity === 'tls13-client') { + return new Openssl\Psk(str_repeat("\x42", 32)); + } + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + $client = stream_socket_accept($server, 30); + fwrite($client, "tls13-psk-ok"); + fclose($client); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x42", 32), 'tls13-client'); + }, + ]]); + $client = stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 30, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client !== false); + var_dump(fread($client, 1024)); + /* TLS 1.3 PSK: no peer cert */ + $params = stream_context_get_params($client); + var_dump(isset($params['options']['ssl']['peer_certificate'])); + fclose($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(true) +string(12) "tls13-psk-ok" +bool(false) diff --git a/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt new file mode 100644 index 000000000000..830c02449dc9 --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt @@ -0,0 +1,44 @@ +--TEST-- +TLS 1.3 PSK: server rejects unknown identity (no cert fallback) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x42", 32), 'unknown-id'); + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index bd174f30095c..f2adfc49075f 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Daniel Lowrey | @@ -29,7 +27,7 @@ #include "zend_exceptions.h" #include "php_openssl.h" #include "php_openssl_backend.h" -#include "php_network.h" +#include "php_io.h" #include #include #include @@ -95,7 +93,7 @@ #define HAVE_SEC_LEVEL 1 #endif -#ifndef OPENSSL_NO_SSL3 +#if OPENSSL_VERSION_NUMBER < 0x40000000L && !defined(OPENSSL_NO_SSL3) #define HAVE_SSL3 1 #define PHP_OPENSSL_MIN_PROTO_VERSION STREAM_CRYPTO_METHOD_SSLv3 #else @@ -128,10 +126,6 @@ #define GET_VER_OPT_LONG(_name, _num) \ if (GET_VER_OPT(_name)) _num = zval_get_long(val) -/* Used for peer verification in windows */ -#define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) \ - ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i))) - #ifdef HAVE_IPV6 /* Used for IPv6 Address peer verification */ #define EXPAND_IPV6_ADDRESS(_str, _bytes) \ @@ -151,7 +145,8 @@ #endif extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl); -extern zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw); +extern zend_string* php_openssl_x509_fingerprint( + X509 *peer, const char *method, bool raw, php_stream *stream); extern int php_openssl_get_ssl_stream_data_index(void); static struct timeval php_openssl_subtract_timeval(struct timeval a, struct timeval b); static int php_openssl_compare_timeval(struct timeval a, struct timeval b); @@ -182,6 +177,25 @@ typedef struct _php_openssl_alpn_ctx_t { } php_openssl_alpn_ctx; #endif +/* TLS 1.3 PSK ciphersuite IDs */ +static const unsigned char php_openssl_tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; +static const unsigned char php_openssl_tls13_aes256gcmsha384_id[] = { 0x13, 0x02 }; + +/* Holds PSK callbacks */ +typedef struct _php_openssl_psk_callbacks_t { + int refcount; + zend_fcall_info_cache client_cb; + zend_fcall_info_cache server_cb; +} php_openssl_psk_callbacks_t; + +/* Holds session callback */ +typedef struct _php_openssl_session_callbacks_t { + int refcount; + zend_fcall_info_cache new_cb; + zend_fcall_info_cache get_cb; + zend_fcall_info_cache remove_cb; +} php_openssl_session_callbacks_t; + /* This implementation is very closely tied to the that of the native * sockets implemented in the core. * Don't try this technique in other extensions! @@ -194,6 +208,7 @@ typedef struct _php_openssl_netstream_data_t { int enable_on_connect; int is_client; int ssl_active; + int last_status; php_stream_xport_crypt_method_t method; php_openssl_handshake_bucket_t *reneg; php_openssl_sni_cert_t *sni_certs; @@ -201,6 +216,12 @@ typedef struct _php_openssl_netstream_data_t { #ifdef HAVE_TLS_ALPN php_openssl_alpn_ctx alpn_ctx; #endif + php_openssl_session_callbacks_t *session_callbacks; + php_openssl_psk_callbacks_t *psk_callbacks; + /* Identity buffer for TLS 1.3 client PSK whose lifetime outlives the + * psk_use_session_cb call but OpenSSL doesn't free it, so we own it. */ + unsigned char *psk_identity_buf; + size_t psk_identity_len; char *url_name; unsigned state_set:1; unsigned _spare:31; @@ -252,21 +273,23 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i * packets: retry in next iteration */ errno = EAGAIN; retry = is_init ? true : sslsock->s.is_blocked; + if (!retry) { + sslsock->last_status = err == SSL_ERROR_WANT_READ ? + STREAM_CRYPTO_STATUS_WANT_READ : STREAM_CRYPTO_STATUS_WANT_WRITE; + } break; case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { if (nr_bytes == 0) { if (!php_openssl_is_http_stream_talking_to_iis(stream) && ERR_get_error() != 0) { - php_error_docref(NULL, E_WARNING, "SSL: fatal protocol error"); + php_stream_warn(stream, ProtocolError, "SSL: fatal protocol error"); } SSL_set_shutdown(sslsock->ssl_handle, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); stream->eof = 1; retry = false; } else { char *estr = php_socket_strerror(php_socket_errno(), NULL, 0); - - php_error_docref(NULL, E_WARNING, - "SSL: %s", estr); + php_stream_warn(stream, ProtocolError, "SSL: %s", estr); efree(estr); retry = false; @@ -281,7 +304,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i switch (ERR_GET_REASON(ecode)) { case SSL_R_NO_SHARED_CIPHER: - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolError, "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. " "This could be because the server is missing an SSL certificate " "(local_cert context option)"); @@ -300,7 +323,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i smart_str_0(&ebuf); - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolError, "SSL operation failed with code %d. %s%s", err, ebuf.s ? "OpenSSL Error messages:\n" : "", @@ -355,21 +378,19 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */ } /* }}} */ -static int php_openssl_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected) +static bool php_openssl_x509_fingerprint_is_equal(php_stream *stream, X509 *peer, const char *method, const zend_string *expected) { - zend_string *fingerprint; - int result = -1; - - fingerprint = php_openssl_x509_fingerprint(peer, method, false); + bool is_equal = false; + zend_string *fingerprint = php_openssl_x509_fingerprint(peer, method, false, stream); if (fingerprint) { - result = strcasecmp(expected, ZSTR_VAL(fingerprint)); - zend_string_release_ex(fingerprint, 0); + is_equal = zend_string_equals_ci(fingerprint, expected); + zend_string_release_ex(fingerprint, false); } - return result; + return is_equal; } -static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val) +static bool php_openssl_x509_fingerprint_match(php_stream *stream, X509 *peer, const zval *val) { if (Z_TYPE_P(val) == IS_STRING) { const char *method = NULL; @@ -384,29 +405,41 @@ static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val) break; } - return method && php_openssl_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val)) == 0; + if (UNEXPECTED(method == NULL)) { + php_stream_warn(stream, AuthFailed, "peer_fingerprint length doesn't match a md5 or sha1 hash"); + return false; + } + if (!php_openssl_x509_fingerprint_is_equal(stream, peer, method, Z_STR_P(val))) { + php_stream_warn(stream, AuthFailed, "peer_fingerprint match failure"); + return false; + } + return true; } else if (Z_TYPE_P(val) == IS_ARRAY) { zval *current; zend_string *key; if (!zend_hash_num_elements(Z_ARRVAL_P(val))) { - php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); + // TODO: Should this be a ValueError (also must not be empty error)? + php_stream_warn(stream, Generic, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); return false; } ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) { if (key == NULL || Z_TYPE_P(current) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); + // TODO: Should this be a ValueError? + php_stream_warn(stream, Generic, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); return false; } - if (php_openssl_x509_fingerprint_cmp(peer, ZSTR_VAL(key), Z_STRVAL_P(current)) != 0) { + if (!php_openssl_x509_fingerprint_is_equal(stream, peer, ZSTR_VAL(key), Z_STR_P(current))) { + php_stream_warn(stream, AuthFailed, "peer_fingerprint match failure"); return false; } } ZEND_HASH_FOREACH_END(); return true; } else { - php_error_docref(NULL, E_WARNING, + // TODO: Should this be a TypeError? + php_stream_warn(stream, Generic, "Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required"); } @@ -415,7 +448,7 @@ static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val) static bool php_openssl_matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */ { - char *wildcard = NULL; + const char *wildcard = NULL; ptrdiff_t prefix_len; size_t suffix_len, subject_len; @@ -474,7 +507,10 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); if (san->type == GEN_DNS) { - ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); + if (ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName) < 0) { + /* TODO: warn ? */ + continue; + } if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) { OPENSSL_free(cert_name); /* prevent null-byte poisoning*/ @@ -495,12 +531,12 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / } OPENSSL_free(cert_name); } else if (san->type == GEN_IPADD) { - if (san->d.iPAddress->length == 4) { + if (ASN1_STRING_length(san->d.iPAddress) == 4) { snprintf(ipbuffer, sizeof(ipbuffer), "%d.%d.%d.%d", - san->d.iPAddress->data[0], - san->d.iPAddress->data[1], - san->d.iPAddress->data[2], - san->d.iPAddress->data[3] + ASN1_STRING_get0_data(san->d.iPAddress)[0], + ASN1_STRING_get0_data(san->d.iPAddress)[1], + ASN1_STRING_get0_data(san->d.iPAddress)[2], + ASN1_STRING_get0_data(san->d.iPAddress)[3] ); if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); @@ -509,9 +545,9 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / } } #ifdef HAVE_IPV6_SAN - else if (san->d.ip->length == 16 && subject_name_is_ipv6) { + else if (ASN1_STRING_length(san->d.ip) == 16 && subject_name_is_ipv6) { ipbuffer[0] = 0; - EXPAND_IPV6_ADDRESS(ipbuffer, san->d.iPAddress->data); + EXPAND_IPV6_ADDRESS(ipbuffer, ASN1_STRING_get0_data(san->d.iPAddress)); if (strcasecmp((const char*)subject_name_ipv6_expanded, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); @@ -528,28 +564,52 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / } /* }}} */ -static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name) /* {{{ */ +static bool php_openssl_matches_common_name(php_stream *stream, const X509 *peer, const char *subject_name) /* {{{ */ { - char buf[1024]; - X509_NAME *cert_name; + unsigned char *cert_name = NULL; +#if PHP_OPENSSL_API_VERSION < 0x30000 + X509_NAME *name; +#else + const X509_NAME *name; +#endif + const X509_NAME_ENTRY *name_entry; + const ASN1_STRING *name_asn1; bool is_match = false; + int name_index; int cert_name_len; - cert_name = X509_get_subject_name(peer); - cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf)); + name = X509_get_subject_name(peer); + name_index = X509_NAME_get_index_by_NID(name, NID_commonName, -1); + if (name_index == -1) { + php_stream_warn(stream, NetworkRecvFailed, "Unable to locate peer certificate CN"); + return false; + } + + name_entry = X509_NAME_get_entry(name, name_index); + if (name_entry == NULL) { + php_stream_warn(stream, NetworkRecvFailed, "Unable to locate peer certificate CN"); + return false; + } + name_asn1 = X509_NAME_ENTRY_get_data(name_entry); + cert_name_len = ASN1_STRING_length(name_asn1); + cert_name = (unsigned char *) OPENSSL_strndup((const char *) ASN1_STRING_get0_data(name_asn1), cert_name_len); + if (cert_name == NULL) { + php_stream_warn(stream, NetworkRecvFailed, "Unable to locate peer certificate CN"); + return false; + } - if (cert_name_len == -1) { - php_error_docref(NULL, E_WARNING, "Unable to locate peer certificate CN"); - } else if ((size_t)cert_name_len != strlen(buf)) { - php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf); - } else if (php_openssl_matches_wildcard_name(subject_name, buf)) { + if ((size_t)cert_name_len != strlen((const char *)cert_name)) { + php_stream_warn(stream, AuthFailed, "Peer certificate CN=`%.*s' is malformed", cert_name_len, (const char *)cert_name); + } else if (php_openssl_matches_wildcard_name(subject_name, (const char *)cert_name)) { is_match = true; } else { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, AuthFailed, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", - cert_name_len, buf, subject_name); + cert_name_len, (const char *)cert_name, subject_name); } + OPENSSL_free(cert_name); + return is_match; } /* }}} */ @@ -578,7 +638,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe peer_fingerprint = val; if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) { - php_error_docref(NULL, E_WARNING, "Could not get peer certificate"); + php_stream_warn(stream, NetworkRecvFailed, "Could not get peer certificate"); return FAILURE; } @@ -597,8 +657,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe /* not allowed, so fall through */ ZEND_FALLTHROUGH; default: - php_error_docref(NULL, E_WARNING, - "Could not verify peer: code:%d %s", + php_stream_warn(stream, AuthFailed, "Could not verify peer: code:%d %s", err, X509_verify_cert_error_string(err) ); @@ -609,14 +668,11 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe /* If a peer_fingerprint match is required this trumps peer and peer_name verification */ if (must_verify_fingerprint) { if (Z_TYPE_P(peer_fingerprint) == IS_STRING || Z_TYPE_P(peer_fingerprint) == IS_ARRAY) { - if (!php_openssl_x509_fingerprint_match(peer, peer_fingerprint)) { - php_error_docref(NULL, E_WARNING, - "peer_fingerprint match failure" - ); + if (!php_openssl_x509_fingerprint_match(stream, peer, peer_fingerprint)) { return FAILURE; } } else { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, AuthFailed, "Expected peer fingerprint must be a string or an array" ); return FAILURE; @@ -635,7 +691,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe if (peer_name) { if (php_openssl_matches_san_list(peer, peer_name)) { return SUCCESS; - } else if (php_openssl_matches_common_name(peer, peer_name)) { + } else if (php_openssl_matches_common_name(stream, peer, peer_name)) { return SUCCESS; } else { return FAILURE; @@ -698,7 +754,8 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, err_code = e; } - php_error_docref(NULL, E_WARNING, "Error encoding X509 certificate: %lu: %s", err_code, ERR_error_string(err_code, err_buf)); + php_stream_warn(stream, EncodingFailed, + "Error encoding X509 certificate: %lu: %s", err_code, ERR_error_string(err_code, err_buf)); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } @@ -707,7 +764,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, if (cert_ctx == NULL) { char *err = php_win_err(); - php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", err); + php_stream_warn(stream, CreateFailed, "Error creating certificate context: %s", err); php_win_err_free(err); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } @@ -731,7 +788,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, if (!CertGetCertificateChain(NULL, cert_ctx, NULL, NULL, &chain_params, chain_flags, NULL, &cert_chain_ctx)) { char *err = php_win_err(); - php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", err); + php_stream_warn(stream, NetworkRecvFailed, "Error getting certificate chain: %s", err); php_win_err_free(err); CertFreeCertificateContext(cert_ctx); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); @@ -774,7 +831,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, if (!verify_result) { char *err = php_win_err(); - php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", err); + php_stream_warn(stream, AuthFailed, "Error verifying certificate chain policy: %s", err); php_win_err_free(err); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } @@ -809,11 +866,12 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c stream = php_stream_open_wrapper(cafile, "rb", 0, NULL); if (stream == NULL) { + // TODO: no stream and no wrapper, cannot use php_stream_warn(stream, ReadFailed, ...) nor php_stream_wrapper_log_error() php_error(E_WARNING, "failed loading cafile stream: `%s'", cafile); return 0; } else if (stream->wrapper->is_url) { + php_stream_warn(stream, PermissionDenied, "remote cafile streams are disabled for security purposes"); php_stream_close(stream); - php_error(E_WARNING, "remote cafile streams are disabled for security purposes"); return 0; } @@ -857,8 +915,9 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c buffer_active = 0; if (cert && X509_STORE_add_cert(cert_store, cert)) { ++certs_added; - X509_free(cert); } + /* TODO: notify user when adding certificate failed? */ + X509_free(cert); goto cert_start; } @@ -870,7 +929,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c } if (certs_added == 0) { - php_error(E_WARNING, "no valid certs found cafile stream: `%s'", cafile); + php_stream_warn(stream, DecodingFailed, "no valid certs found cafile stream: `%s'", cafile); } return certs_added; @@ -880,30 +939,30 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */ { zval *val = NULL; - char *cafile = NULL; - char *capath = NULL; + const char *cafile = NULL; + const char *capath = NULL; php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract; GET_VER_OPT_STRING("cafile", cafile); GET_VER_OPT_STRING("capath", capath); if (cafile == NULL) { - cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0); - cafile = strlen(cafile) ? cafile : NULL; + const zend_string *cafile_str = zend_ini_str_literal("openssl.cafile"); + cafile = ZSTR_LEN(cafile_str) ? ZSTR_VAL(cafile_str) : NULL; } else if (!sslsock->is_client) { /* Servers need to load and assign CA names from the cafile */ STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(cafile); if (cert_names != NULL) { SSL_CTX_set_client_CA_list(ctx, cert_names); } else { - php_error(E_WARNING, "SSL: failed loading CA names from cafile"); + php_stream_warn(stream, InvalidFormat, "SSL: failed loading CA names from cafile"); return FAILURE; } } if (capath == NULL) { - capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0); - capath = strlen(capath) ? capath : NULL; + const zend_string *capath_str = zend_ini_str_literal("openssl.capath"); + capath = ZSTR_LEN(capath_str) ? ZSTR_VAL(capath_str) : NULL; } if (cafile || capath) { @@ -918,7 +977,7 @@ static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream SSL_CTX_set_cert_verify_callback(ctx, php_openssl_win_cert_verify_callback, (void *)stream); #else if (sslsock->is_client && !SSL_CTX_set_default_verify_paths(ctx)) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolError, "Unable to set default verify locations and no CA settings specified"); return FAILURE; } @@ -952,13 +1011,13 @@ static zend_result php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream) if (!php_openssl_check_path_ex( certfile, certfile_len, resolved_path_buff, 0, false, false, - "local_cert in ssl stream context")) { - php_error_docref(NULL, E_WARNING, "Unable to get real path of certificate file `%s'", certfile); + "local_cert in ssl stream context", stream)) { + php_stream_warn(stream, NotFound, "Unable to get real path of certificate file `%s'", certfile); return FAILURE; } /* a certificate to use for authentication */ if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, WriteFailed, "Unable to set local cert chain file `%s'; Check that your cafile/capath " "settings include details of your certificate and its issuer", certfile); @@ -968,16 +1027,16 @@ static zend_result php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream) GET_VER_OPT_STRINGL("local_pk", private_key, private_key_len); if (private_key && !php_openssl_check_path_ex( private_key, private_key_len, resolved_path_buff, 0, false, false, - "local_pk in ssl stream context")) { - php_error_docref(NULL, E_WARNING, "Unable to get real path of private key file `%s'", private_key); + "local_pk in ssl stream context", stream)) { + php_stream_warn(stream, NotFound, "Unable to get real path of private key file `%s'", private_key); return FAILURE; } if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) { - php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff); + php_stream_warn(stream, WriteFailed, "Unable to set private key file `%s'", resolved_path_buff); return FAILURE; } if (!SSL_CTX_check_private_key(ctx)) { - php_error_docref(NULL, E_WARNING, "Private key does not match certificate!"); + php_stream_warn(stream, PermissionDenied, "Private key does not match certificate!"); } } @@ -1112,7 +1171,7 @@ static void php_openssl_limit_handshake_reneg(const SSL *ssl) /* {{{ */ /* Closing the stream inside this callback would segfault! */ stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; if (FAILURE == call_user_function(NULL, NULL, val, &retval, 1, ¶m)) { - php_error(E_WARNING, "SSL: failed invoking reneg limit notification callback"); + php_stream_warn(stream, UserspaceCallFailed, "SSL: failed invoking reneg limit notification callback"); } stream->flags ^= PHP_STREAM_FLAG_NO_FCLOSE; @@ -1123,7 +1182,7 @@ static void php_openssl_limit_handshake_reneg(const SSL *ssl) /* {{{ */ zval_ptr_dtor(&retval); } else { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolError, "SSL: client-initiated handshake rate limit exceeded by peer"); } } @@ -1196,7 +1255,7 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX BIO *bio = BIO_new_file(Z_STRVAL_P(zdhpath), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (bio == NULL) { - php_error_docref(NULL, E_WARNING, "Invalid dh_param"); + php_stream_warn(stream, NotFound, "Invalid dh_param"); return FAILURE; } @@ -1205,12 +1264,12 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX BIO_free(bio); if (pkey == NULL) { - php_error_docref(NULL, E_WARNING, "Failed reading DH params"); + php_stream_warn(stream, ReadFailed, "Failed reading DH params"); return FAILURE; } if (SSL_CTX_set0_tmp_dh_pkey(ctx, pkey) == 0) { - php_error_docref(NULL, E_WARNING, "Failed assigning DH params"); + php_stream_warn(stream, WriteFailed, "Failed assigning DH params"); EVP_PKEY_free(pkey); return FAILURE; } @@ -1219,12 +1278,12 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX BIO_free(bio); if (dh == NULL) { - php_error_docref(NULL, E_WARNING, "Failed reading DH params"); + php_stream_warn(stream, ReadFailed, "Failed reading DH params"); return FAILURE; } if (SSL_CTX_set_tmp_dh(ctx, dh) == 0) { - php_error_docref(NULL, E_WARNING, "Failed assigning DH params"); + php_stream_warn(stream, WriteFailed, "Failed assigning DH params"); DH_free(dh); return FAILURE; } @@ -1243,7 +1302,8 @@ static zend_result php_openssl_set_server_specific_opts(php_stream *stream, SSL_ /* We now use php_openssl_tmp_rsa_cb to generate a key of appropriate size whenever necessary */ if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "rsa_key_size") != NULL) { - php_error_docref(NULL, E_WARNING, "rsa_key_size context option has been removed"); + // TODO: Should this be E_DEPRECATED instead? + php_stream_warn(stream, Generic, "rsa_key_size context option has been removed"); } if (php_openssl_set_server_dh_param(stream, ctx) == FAILURE) { @@ -1298,14 +1358,18 @@ static int php_openssl_server_sni_callback(SSL *ssl_handle, int *al, void *arg) } /* }}} */ -static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_path) /* {{{ */ +static SSL_CTX *php_openssl_create_sni_server_ctx(php_stream *stream, char *cert_path, char *key_path) /* {{{ */ { /* The hello method is not inherited by SSL structs when assigning a new context * inside the SNI callback, so the just use SSLv23 */ SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); + if (!ctx) { + php_stream_warn(stream, CreateFailed, "Failed to create the SSL context"); + return NULL; + } if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) != 1) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ReadFailed, "Failed setting local cert chain file `%s'; " \ "check that your cafile/capath settings include " \ "details of your certificate and its issuer", @@ -1314,7 +1378,7 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat SSL_CTX_free(ctx); return NULL; } else if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) != 1) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ReadFailed, "Failed setting private key from file `%s'", key_path ); @@ -1348,7 +1412,8 @@ static zend_result php_openssl_enable_server_sni( } if (Z_TYPE_P(val) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, + // TODO: should this be a TypeError? + php_stream_warn(stream, Generic, "SNI_server_certs requires an array mapping host names to cert paths" ); return FAILURE; @@ -1356,7 +1421,8 @@ static zend_result php_openssl_enable_server_sni( sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_P(val)); if (sslsock->sni_cert_count == 0) { - php_error_docref(NULL, E_WARNING, + // TODO: should this be a ValueError? + php_stream_warn(stream, Generic, "SNI_server_certs host cert array must not be empty" ); return FAILURE; @@ -1371,7 +1437,8 @@ static zend_result php_openssl_enable_server_sni( (void) key_index; if (!key) { - php_error_docref(NULL, E_WARNING, + // TODO: should this be a ValueError? + php_stream_warn(stream, Generic, "SNI_server_certs array requires string host name keys" ); return FAILURE; @@ -1386,7 +1453,8 @@ static zend_result php_openssl_enable_server_sni( local_cert = zend_hash_str_find(Z_ARRVAL_P(current), "local_cert", sizeof("local_cert")-1); if (local_cert == NULL) { - php_error_docref(NULL, E_WARNING, + // TODO: should this be a ValueError? + php_stream_warn(stream, Generic, "local_cert not present in the array" ); return FAILURE; @@ -1398,8 +1466,8 @@ static zend_result php_openssl_enable_server_sni( } if (!php_openssl_check_path_str_ex( local_cert_str, resolved_cert_path_buff, 0, false, false, - "SNI_server_certs local_cert in ssl stream context")) { - php_error_docref(NULL, E_WARNING, + "SNI_server_certs local_cert in ssl stream context", stream)) { + php_stream_warn(stream, OpenFailed, "Failed setting local cert chain file `%s'; could not open file", ZSTR_VAL(local_cert_str) ); @@ -1410,7 +1478,8 @@ static zend_result php_openssl_enable_server_sni( local_pk = zend_hash_str_find(Z_ARRVAL_P(current), "local_pk", sizeof("local_pk")-1); if (local_pk == NULL) { - php_error_docref(NULL, E_WARNING, + // TODO: should this be a ValueError? + php_stream_warn(stream, Generic, "local_pk not present in the array" ); return FAILURE; @@ -1422,8 +1491,8 @@ static zend_result php_openssl_enable_server_sni( } if (!php_openssl_check_path_str_ex( local_pk_str, resolved_pk_path_buff, 0, false, false, - "SNI_server_certs local_pk in ssl stream context")) { - php_error_docref(NULL, E_WARNING, + "SNI_server_certs local_pk in ssl stream context", stream)) { + php_stream_warn(stream, OpenFailed, "Failed setting local private key file `%s'; could not open file", ZSTR_VAL(local_pk_str) ); @@ -1432,18 +1501,19 @@ static zend_result php_openssl_enable_server_sni( } zend_string_release(local_pk_str); - ctx = php_openssl_create_sni_server_ctx(resolved_cert_path_buff, resolved_pk_path_buff); + ctx = php_openssl_create_sni_server_ctx(stream, resolved_cert_path_buff, resolved_pk_path_buff); } else if (Z_TYPE_P(current) == IS_STRING) { - if (php_openssl_check_path_str_ex(Z_STR_P(current), resolved_path_buff, 0, false, false, "SNI_server_certs in ssl stream context")) { - ctx = php_openssl_create_sni_server_ctx(resolved_path_buff, resolved_path_buff); + if (php_openssl_check_path_str_ex(Z_STR_P(current), resolved_path_buff, 0, false, false, "SNI_server_certs in ssl stream context", stream)) { + ctx = php_openssl_create_sni_server_ctx(stream, resolved_path_buff, resolved_path_buff); } else { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, NotFound, "Failed setting local cert chain file `%s'; file not found", Z_STRVAL_P(current) ); } } else { - php_error_docref(NULL, E_WARNING, "SNI_server_certs options values must be of type array|string"); + // TODO: should this be a TypeError? + php_stream_warn(stream, Generic, "SNI_server_certs options values must be of type array|string"); } if (ctx == NULL) { @@ -1508,7 +1578,7 @@ static unsigned char *php_openssl_alpn_protos_parse(unsigned short *outlen, cons return NULL; } - out = emalloc(strlen(in) + 1); + out = emalloc(len + 1); for (i = 0; i <= len; ++i) { if (i == len || in[i] == ',') { @@ -1545,257 +1615,1127 @@ static int php_openssl_server_alpn_callback(SSL *ssl_handle, #endif -static zend_result php_openssl_setup_crypto(php_stream *stream, - php_openssl_netstream_data_t *sslsock, - php_stream_xport_crypto_param *cparam) /* {{{ */ +static int php_openssl_get_ctx_stream_data_index(void) { - const SSL_METHOD *method; - int ssl_ctx_options; - int method_flags; - zend_long min_version = 0; - zend_long max_version = 0; - char *cipherlist = NULL; - char *alpn_protocols = NULL; - zval *val; - bool verify_peer = false; + static int ctx_data_index = -1; + if (ctx_data_index < 0) { + ctx_data_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); + } + return ctx_data_index; +} - if (sslsock->ssl_handle) { - if (sslsock->s.is_blocked) { - php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream"); - return FAILURE; - } else { - return SUCCESS; +/** + * Build a SSL_SESSION suitable for use as an external PSK in TLS 1.3. + */ +static SSL_SESSION *php_openssl_psk_build_session(SSL *ssl, + const unsigned char *psk, size_t psk_len, const EVP_MD *md) +{ + const SSL_CIPHER *cipher; + + cipher = SSL_CIPHER_find(ssl, php_openssl_tls13_aes128gcmsha256_id); + if (cipher == NULL) { + return NULL; + } + + if (md != NULL && SSL_CIPHER_get_handshake_digest(cipher) != md) { + /* Fallback to SHA384 if SHA256 doesn't match */ + cipher = SSL_CIPHER_find(ssl, php_openssl_tls13_aes256gcmsha384_id); + if (cipher == NULL || SSL_CIPHER_get_handshake_digest(cipher) != md) { + return NULL; } } - ERR_clear_error(); + SSL_SESSION *sess = SSL_SESSION_new(); + if (sess == NULL) { + return NULL; + } - /* We need to do slightly different things based on client/server method - * so let's remember which method was selected */ - sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT; - method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT; + if (!SSL_SESSION_set1_master_key(sess, psk, psk_len) + || !SSL_SESSION_set_cipher(sess, cipher) + || !SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { + SSL_SESSION_free(sess); + return NULL; + } - method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method(); - sslsock->ctx = SSL_CTX_new(method); + return sess; +} - if (sslsock->ctx == NULL) { - php_error_docref(NULL, E_WARNING, "SSL context creation failure"); - return FAILURE; - } - GET_VER_OPT_LONG("min_proto_version", min_version); - GET_VER_OPT_LONG("max_proto_version", max_version); - method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version); - ssl_ctx_options = SSL_OP_ALL; +/** + * Invoke a user PHP callback (psk_client_cb or psk_server_cb). + */ +static zend_result php_openssl_call_psk_cb(php_stream *stream, zend_fcall_info_cache *fcc, + const unsigned char *identity, size_t identity_len, + zval *result) +{ + zval args[2]; + zval retval; + int argc; - if (GET_VER_OPT("no_ticket") && zend_is_true(val)) { - ssl_ctx_options |= SSL_OP_NO_TICKET; + ZVAL_RES(&args[0], stream->res); + + if (identity != NULL) { + ZVAL_STRINGL(&args[1], (const char *)identity, identity_len); + argc = 2; + } else { + argc = 1; } - ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + ZVAL_UNDEF(&retval); -#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */ - ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF; -#endif + zend_call_known_fcc(fcc, &retval, argc, args, NULL); - if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) { - ssl_ctx_options |= SSL_OP_NO_COMPRESSION; + if (identity != NULL) { + zval_ptr_dtor(&args[1]); } - if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) { - php_openssl_disable_peer_verification(sslsock->ctx, stream); - } else { - verify_peer = true; - if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) { - return FAILURE; - } + if (Z_ISUNDEF(retval)) { + ZVAL_UNDEF(result); + return FAILURE; } - /* callback for the passphrase (for localcert) */ - if (GET_VER_OPT("passphrase")) { - SSL_CTX_set_default_passwd_cb_userdata(sslsock->ctx, stream); - SSL_CTX_set_default_passwd_cb(sslsock->ctx, php_openssl_passwd_callback); + if (Z_TYPE(retval) == IS_NULL) { + ZVAL_NULL(result); + return SUCCESS; } - GET_VER_OPT_STRING("ciphers", cipherlist); -#ifndef USE_OPENSSL_SYSTEM_CIPHERS - if (!cipherlist) { - cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS; + if (!php_openssl_is_psk_ce(&retval)) { + zval_ptr_dtor(&retval); + zend_type_error("PSK callback must return Openssl\\Psk or null"); + ZVAL_UNDEF(result); + return FAILURE; } -#endif - if (cipherlist) { - if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) { - return FAILURE; - } + + ZVAL_COPY_VALUE(result, &retval); + return SUCCESS; +} + +#ifndef OPENSSL_NO_PSK +/* TLS 1.2 (and below) PSK callbacks. */ + +static unsigned int php_openssl_psk_client_cb(SSL *ssl, const char *hint, + char *identity_out, unsigned int max_identity_len, + unsigned char *psk_out, unsigned int max_psk_len) +{ + (void)hint; /* identity hint deliberately not exposed as it is useless */ + (void)max_identity_len; + (void)max_psk_len; + + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 0; } - if (GET_VER_OPT("security_level")) { - zend_long lval = zval_get_long(val); - if (lval < 0 || lval > 5) { - php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5"); - } -#ifdef HAVE_SEC_LEVEL - SSL_CTX_set_security_level(sslsock->ctx, lval); -#endif + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) { + return 0; } - GET_VER_OPT_STRING("alpn_protocols", alpn_protocols); - if (alpn_protocols) { -#ifdef HAVE_TLS_ALPN - { - unsigned short alpn_len; - unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols); + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->client_cb, + NULL, 0, &result) != SUCCESS) { + return 0; + } - if (alpn == NULL) { - php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string"); - SSL_CTX_free(sslsock->ctx); - sslsock->ctx = NULL; - return FAILURE; - } - if (sslsock->is_client) { - SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len); - } else { - sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream)); - sslsock->alpn_ctx.len = alpn_len; - SSL_CTX_set_alpn_select_cb(sslsock->ctx, php_openssl_server_alpn_callback, sslsock); - } + if (Z_TYPE(result) == IS_NULL) { + return 0; + } - efree(alpn); - } -#else - php_error_docref(NULL, E_WARNING, - "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked"); -#endif + zend_string *psk_str = php_openssl_psk_get_psk(&result); + zend_string *identity_str = php_openssl_psk_get_identity(&result); + + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; } - if (FAILURE == php_openssl_set_local_cert(sslsock->ctx, stream)) { - return FAILURE; + if (identity_str == NULL) { + zval_ptr_dtor(&result); + zend_value_error("Client PSK callback must return Openssl\\Psk with a non-null identity"); + return 0; } - SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options); + memcpy(identity_out, ZSTR_VAL(identity_str), ZSTR_LEN(identity_str)); + identity_out[ZSTR_LEN(identity_str)] = '\0'; + memcpy(psk_out, ZSTR_VAL(psk_str), ZSTR_LEN(psk_str)); - SSL_CTX_set_min_proto_version(sslsock->ctx, php_openssl_get_min_proto_version(method_flags)); - SSL_CTX_set_max_proto_version(sslsock->ctx, php_openssl_get_max_proto_version(method_flags)); + unsigned int psk_len = (unsigned int)ZSTR_LEN(psk_str); + zval_ptr_dtor(&result); + return psk_len; +} - if (sslsock->is_client == 0 && - PHP_STREAM_CONTEXT(stream) && - FAILURE == php_openssl_set_server_specific_opts(stream, sslsock->ctx) - ) { - return FAILURE; - } +static unsigned int php_openssl_psk_server_cb(SSL *ssl, const char *identity, + unsigned char *psk_out, unsigned int max_psk_len) +{ + (void)max_psk_len; - sslsock->ssl_handle = SSL_new(sslsock->ctx); + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 0; + } - if (sslsock->ssl_handle == NULL) { - php_error_docref(NULL, E_WARNING, "SSL handle creation failure"); - SSL_CTX_free(sslsock->ctx); - sslsock->ctx = NULL; -#ifdef HAVE_TLS_ALPN - if (sslsock->alpn_ctx.data) { - pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream)); - sslsock->alpn_ctx.data = NULL; - } -#endif - return FAILURE; - } else { - SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream); + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) { + return 0; } - if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { - php_openssl_handle_ssl_error(stream, 0, true); + if (SSL_version(ssl) >= TLS1_3_VERSION) { + return 0; } -#ifdef HAVE_TLS_SNI - /* Enable server-side SNI */ - if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock, verify_peer) == FAILURE) { - return FAILURE; + if (identity == NULL) { + return 0; } -#endif - /* Enable server-side handshake renegotiation rate-limiting */ - if (!sslsock->is_client) { - php_openssl_init_server_reneg_limit(stream, sslsock); + size_t identity_len = strlen(identity); + + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->server_cb, + (const unsigned char *)identity, identity_len, &result) != SUCCESS) { + return 0; } -#ifdef SSL_MODE_RELEASE_BUFFERS - SSL_set_mode(sslsock->ssl_handle, SSL_MODE_RELEASE_BUFFERS); -#endif + if (Z_TYPE(result) == IS_NULL) { + return 0; + } - if (cparam->inputs.session) { - if (cparam->inputs.session->ops != &php_openssl_socket_ops) { - php_error_docref(NULL, E_WARNING, "Supplied session stream must be an SSL enabled stream"); - } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) { - php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not initialized"); - } else { - SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle); - } + zend_string *psk_str = php_openssl_psk_get_psk(&result); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; } - return SUCCESS; + memcpy(psk_out, ZSTR_VAL(psk_str), ZSTR_LEN(psk_str)); + unsigned int psk_len = (unsigned int)ZSTR_LEN(psk_str); + + zval_ptr_dtor(&result); + return psk_len; } -/* }}} */ +#endif /* OPENSSL_NO_PSK */ -static int php_openssl_capture_peer_certs(php_stream *stream, - php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */ +/* TLS 1.3 PSK callbacks */ + +static int php_openssl_psk_use_session_cb(SSL *ssl, const EVP_MD *md, + const unsigned char **id, size_t *idlen, SSL_SESSION **sess) { - zval *val, zcert; - php_openssl_certificate_object *cert_object; - int cert_captured = 0; + *id = NULL; + *idlen = 0; + *sess = NULL; - if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), - "ssl", "capture_peer_cert")) && - zend_is_true(val) - ) { - object_init_ex(&zcert, php_openssl_certificate_ce); - cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); - cert_object->x509 = peer_cert; + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 1; + } - php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert); - zval_ptr_dtor(&zcert); - cert_captured = 1; + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) { + return 1; } - if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), - "ssl", "capture_peer_cert_chain")) && - zend_is_true(val) - ) { - zval arr; - STACK_OF(X509) *chain; + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->client_cb, + NULL, 0, &result) != SUCCESS) { + return 0; + } - chain = SSL_get_peer_cert_chain(sslsock->ssl_handle); + if (Z_TYPE(result) == IS_NULL) { + return 1; /* user rejected, continue without PSK */ + } - if (chain && sk_X509_num(chain) > 0) { - int i; - array_init(&arr); + zend_string *psk_str = php_openssl_psk_get_psk(&result); + zend_string *identity_str = php_openssl_psk_get_identity(&result); - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *mycert = X509_dup(sk_X509_value(chain, i)); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; + } - object_init_ex(&zcert, php_openssl_certificate_ce); - cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); - cert_object->x509 = mycert; - add_next_index_zval(&arr, &zcert); - } + if (identity_str == NULL) { + zval_ptr_dtor(&result); + zend_value_error("Client PSK callback must return Openssl\\Psk with a non-null identity"); + return 0; + } - } else { - ZVAL_NULL(&arr); + SSL_SESSION *session = php_openssl_psk_build_session(ssl, + (const unsigned char *)ZSTR_VAL(psk_str), ZSTR_LEN(psk_str), md); + if (session == NULL) { + zval_ptr_dtor(&result); + if (md != NULL) { + /* Could not satisfy the server's chosen digest */ + return 1; } + return 0; + } - php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr); - zval_ptr_dtor(&arr); + /* Identity buffer must outlive this callback. */ + if (sslsock->psk_identity_buf == NULL) { + sslsock->psk_identity_buf = emalloc(PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); } + memcpy(sslsock->psk_identity_buf, ZSTR_VAL(identity_str), ZSTR_LEN(identity_str)); + sslsock->psk_identity_len = ZSTR_LEN(identity_str); - return cert_captured; + *id = sslsock->psk_identity_buf; + *idlen = sslsock->psk_identity_len; + *sess = session; + + zval_ptr_dtor(&result); + return 1; } -/* }}} */ -static zend_result php_openssl_set_blocking(php_openssl_netstream_data_t *sslsock, int block) +static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identity, + size_t identity_len, SSL_SESSION **sess) { - zend_result result = php_set_sock_blocking(sslsock->s.socket, block); - if (EXPECTED(SUCCESS == result)) { - sslsock->s.is_blocked = block; - } + *sess = NULL; + + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 1; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) { + return 1; + } + + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->server_cb, + identity, identity_len, &result) != SUCCESS) { + return 0; + } + + if (Z_TYPE(result) == IS_NULL) { + return 1; /* identity unknown - let handshake fall through */ + } + + zend_string *psk_str = php_openssl_psk_get_psk(&result); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; + } + + SSL_SESSION *session = php_openssl_psk_build_session(ssl, + (const unsigned char *)ZSTR_VAL(psk_str), ZSTR_LEN(psk_str), NULL); + + zval_ptr_dtor(&result); + + if (session == NULL) { + return 0; + } + + *sess = session; + return 1; +} + +/* PSK setup */ + +static zend_result php_openssl_validate_and_allocate_psk_callback( + php_stream *stream, + php_openssl_netstream_data_t *sslsock, const zval *callable, + bool is_client, bool is_persistent) +{ + const char *callback_name = is_client ? "psk_client_cb" : "psk_server_cb"; + if (is_persistent) { + php_stream_warn(stream, PersistentNotSupported, + "%s is not supported for persistent streams", callback_name); + return FAILURE; + } + + char *is_callable_error = NULL; + zend_fcall_info_cache fcc = {0}; + if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (is_callable_error) { + zend_type_error("%s must be a valid callback, %s", + callback_name, is_callable_error); + efree(is_callable_error); + } else { + zend_type_error("%s must be a valid callback", callback_name); + } + return FAILURE; + } + + if (!sslsock->psk_callbacks) { + sslsock->psk_callbacks = (php_openssl_psk_callbacks_t *)pecalloc( + 1, sizeof(php_openssl_psk_callbacks_t), is_persistent); + sslsock->psk_callbacks->refcount = 1; + } + zend_fcc_addref(&fcc); + if (is_client) { + sslsock->psk_callbacks->client_cb = fcc; + } else { + sslsock->psk_callbacks->server_cb = fcc; + } + + return SUCCESS; +} + +static zend_result php_openssl_setup_client_psk(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (!GET_VER_OPT("psk_client_cb")) { + return SUCCESS; + } + + if (FAILURE == php_openssl_validate_and_allocate_psk_callback( + stream, sslsock, val, true, php_stream_is_persistent(stream))) { + return FAILURE; + } + +#ifndef OPENSSL_NO_PSK + SSL_CTX_set_psk_client_callback(sslsock->ctx, php_openssl_psk_client_cb); +#endif + SSL_CTX_set_psk_use_session_callback(sslsock->ctx, php_openssl_psk_use_session_cb); + + return SUCCESS; +} + +static zend_result php_openssl_setup_server_psk(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (!GET_VER_OPT("psk_server_cb")) { + return SUCCESS; + } + + if (FAILURE == php_openssl_validate_and_allocate_psk_callback( + stream, sslsock, val, false, php_stream_is_persistent(stream))) { + return FAILURE; + } + +#ifndef OPENSSL_NO_PSK + SSL_CTX_set_psk_server_callback(sslsock->ctx, php_openssl_psk_server_cb); +#endif + SSL_CTX_set_psk_find_session_callback(sslsock->ctx, php_openssl_psk_find_session_cb); + + if (!GET_VER_OPT("session_id_context")) { + static const unsigned char default_psk_sid_ctx[] = "PHP_PSK"; + SSL_CTX_set_session_id_context(sslsock->ctx, default_psk_sid_ctx, + sizeof(default_psk_sid_ctx) - 1); + } + + return SUCCESS; +} + +/** + * OpenSSL new session callback - called when a new session is established + */ +static int php_openssl_session_new_cb(SSL *ssl, SSL_SESSION *session) +{ + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, php_openssl_get_ssl_stream_data_index()); + if (!stream) { + return 0; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + return 0; + } + + /* Increment reference - we're giving ownership to the PHP object */ + SSL_SESSION_up_ref(session); + + zval args[2]; + + ZVAL_RES(&args[0], stream->res); + php_openssl_session_object_init(&args[1], session); + + zend_call_known_fcc(&sslsock->session_callbacks->new_cb, NULL, 2, args, NULL); + + zval_ptr_dtor(&args[1]); + + return 0; +} + +/** + * OpenSSL get session callback - called when server needs to retrieve a session + */ +static SSL_SESSION *php_openssl_session_get_cb(SSL *ssl, const unsigned char *session_id, + int session_id_len, int *copy) +{ + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, php_openssl_get_ssl_stream_data_index()); + if (!stream) { + *copy = 0; + return NULL; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + *copy = 0; + return NULL; + } + + zval args[2]; + zval retval; + + ZVAL_RES(&args[0], stream->res); + ZVAL_STRINGL(&args[1], (char *)session_id, session_id_len); + + SSL_SESSION *session = NULL; + + zend_call_known_fcc(&sslsock->session_callbacks->get_cb, &retval, 2, args, NULL); + zval_ptr_dtor(&args[1]); + + if (php_openssl_is_session_ce(&retval)) { + /* Get session from object and increment ref since OpenSSL will own it */ + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(&retval); + if (obj->session) { + SSL_SESSION_up_ref(obj->session); + session = obj->session; + } + } else if (Z_TYPE(retval) != IS_NULL) { + zend_type_error("session_get_cb return type must be null or OpenSSLSession"); + } + + zval_ptr_dtor(&retval); + + *copy = 0; + return session; +} + +/** + * OpenSSL remove session callback - called when a session is evicted from cache + */ +static void php_openssl_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *session) +{ + php_stream *stream = (php_stream *)SSL_CTX_get_ex_data(ctx, php_openssl_get_ctx_stream_data_index()); + if (!stream) { + return; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + return; + } + + unsigned int session_id_len = 0; + const unsigned char *session_id = SSL_SESSION_get_id(session, &session_id_len); + + zval args[2]; + + ZVAL_RES(&args[0], stream->res); + ZVAL_STRINGL(&args[1], (char *)session_id, session_id_len); + + zend_call_known_fcc(&sslsock->session_callbacks->remove_cb, NULL, 2, args, NULL); + zval_ptr_dtor(&args[1]); +} + + +enum php_openssl_session_callback_type { + PHP_OPENSSL_NEW_CB, + PHP_OPENSSL_GET_CB, + PHP_OPENSSL_REMOVE_CB, +}; +/** + * Validate callable and allocate callback structure if needed. + */ +static zend_result php_openssl_validate_and_allocate_session_callback( + php_stream *stream, + php_openssl_netstream_data_t *sslsock, const zval *callable, + enum php_openssl_session_callback_type cb_type, bool is_persistent) +{ + char *is_callable_error = NULL; + const char *callback_name; + + switch (cb_type) { + case PHP_OPENSSL_NEW_CB: + callback_name = "session_new_cb"; + break; + case PHP_OPENSSL_GET_CB: + callback_name = "session_get_cb"; + break; + case PHP_OPENSSL_REMOVE_CB: + callback_name = "session_remove_cb"; + break; + } + + /* Callbacks not supported for persistent streams */ + if (is_persistent) { + php_stream_warn(stream, PersistentNotSupported, + "%s is not supported for persistent streams", callback_name); + return FAILURE; + } + + /* Validate callable */ + zend_fcall_info_cache fcc; + if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (is_callable_error) { + zend_type_error("%s must be a valid callback, %s", callback_name, is_callable_error); + efree(is_callable_error); + } else { + zend_type_error("%s must be a valid callback", callback_name); + } + return FAILURE; + } + + /* Allocate callback structure if not already allocated */ + if (!sslsock->session_callbacks) { + sslsock->session_callbacks = (php_openssl_session_callbacks_t *)pecalloc( + 1, sizeof(php_openssl_session_callbacks_t), is_persistent); + sslsock->session_callbacks->refcount = 1; + } + + zend_fcc_addref(&fcc); + switch (cb_type) { + case PHP_OPENSSL_NEW_CB: + sslsock->session_callbacks->new_cb = fcc; + break; + case PHP_OPENSSL_GET_CB: + sslsock->session_callbacks->get_cb = fcc; + break; + case PHP_OPENSSL_REMOVE_CB: + sslsock->session_callbacks->remove_cb = fcc; + break; + } + + return SUCCESS; +} + +/** + * Configure session resumption options for client connections + */ +static zend_result php_openssl_setup_client_session(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + bool enable_client_cache = false; + bool is_persistent = php_stream_is_persistent(stream); + + if (GET_VER_OPT("session_data")) { + if (php_openssl_is_session_ce(val)) { + enable_client_cache = true; + } else if (Z_TYPE_P(val) != IS_NULL) { + zend_type_error("session_data must be an OpenSSLSession instance"); + return FAILURE; + } + } + + if (GET_VER_OPT("session_new_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_session_callback( + stream, sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) { + return FAILURE; + } + + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + enable_client_cache = true; + } + + if (enable_client_cache) { + SSL_CTX_set_session_cache_mode(sslsock->ctx, + SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); + } + + return SUCCESS; +} + +static bool php_openssl_is_session_cache_enabled(php_stream *stream, bool internal_only) +{ + zval *val; + + if (GET_VER_OPT("session_cache")) { + return zend_is_true(val); + } + + if (internal_only) { + return false; + } + + return GET_VER_OPT("session_get_cb"); +} + +/** + * Configure session resumption options for server connections + */ +static zend_result php_openssl_setup_server_session(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + bool has_get_cb = false; + bool has_new_cb = false; + bool has_remove_cb = false; + bool has_session_id_context = false; + bool is_persistent = php_stream_is_persistent(stream); + + /* Check for session_get_cb first (determines cache mode) */ + if (GET_VER_OPT("session_get_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_session_callback( + stream, sslsock, val, PHP_OPENSSL_GET_CB, is_persistent)) { + return FAILURE; + } + has_get_cb = true; + } + + if (GET_VER_OPT("session_id_context")) { + if (Z_TYPE_P(val) != IS_STRING || Z_STRLEN_P(val) == 0) { + zend_type_error("session_id_context must be a non empty string"); + return FAILURE; + } + SSL_CTX_set_session_id_context(sslsock->ctx, (const unsigned char *) Z_STRVAL_P(val), + Z_STRLEN_P(val)); + has_session_id_context = true; + } + + /* Check for session_new_cb */ + if (GET_VER_OPT("session_new_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_session_callback( + stream, sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) { + return FAILURE; + } + has_new_cb = true; + + if (!has_session_id_context && + (SSL_CTX_get_verify_mode(sslsock->ctx) & SSL_VERIFY_PEER) != 0) { + zend_value_error("session_id_context must be set if session_new_cb is set"); + return FAILURE; + } + } + + /* Validate: if session_get_cb is provided, session_new_cb is required */ + if (has_get_cb && !has_new_cb) { + zend_value_error("session_new_cb is required when session_get_cb is provided"); + return FAILURE; + } + + /* Check for session_remove_cb (optional) */ + if (GET_VER_OPT("session_remove_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_session_callback( + stream, sslsock, val, PHP_OPENSSL_REMOVE_CB, is_persistent)) { + return FAILURE; + } + + has_remove_cb = true; + } + + /* Configure cache mode based on whether external callbacks are provided */ + if (has_get_cb) { + /* External cache mode - disable internal cache */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, + SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL); + + /* Set callbacks */ + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + SSL_CTX_sess_set_get_cb(sslsock->ctx, php_openssl_session_get_cb); + + if (has_remove_cb) { + SSL_CTX_sess_set_remove_cb(sslsock->ctx, php_openssl_session_remove_cb); + } + + // Disable tickets (they won't work anyway) and warn if explicity enabled + SSL_CTX_set_options(sslsock->ctx, SSL_OP_NO_TICKET); + if (GET_VER_OPT("no_ticket") && !zend_is_true(val)) { + zend_value_error("Session tickets cannot be enabled when session_get_cb is set"); + } + } else if (php_openssl_is_session_cache_enabled(stream, true)) { + if (!has_session_id_context && + (SSL_CTX_get_verify_mode(sslsock->ctx) & SSL_VERIFY_PEER) != 0) { + zend_value_error("session_id_context must be set for internal session cache"); + } + + /* Internal cache mode */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_SERVER); + + /* Handle session_cache_size */ + if (GET_VER_OPT("session_cache_size")) { + zend_long cache_size = zval_get_long(val); + if (cache_size > 0) { + SSL_CTX_sess_set_cache_size(sslsock->ctx, cache_size); + } else { + zend_value_error("session_cache_size must be positive"); + } + } else { + /* Default cache size from RFC */ + SSL_CTX_sess_set_cache_size(sslsock->ctx, 20480); + } + + /* Handle session_timeout */ + if (GET_VER_OPT("session_timeout")) { + zend_long timeout = zval_get_long(val); + if (timeout > 0) { + SSL_CTX_set_timeout(sslsock->ctx, timeout); + } else { + zend_value_error("session_timeout must be positive"); + } + } else { + /* Default timeout from RFC */ + SSL_CTX_set_timeout(sslsock->ctx, 300); + } + + /* Optional notification callback for internal cache */ + if (has_new_cb) { + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + } + } else { + /* Session caching disabled */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_OFF); + } + + return SUCCESS; +} + +static zend_result php_openssl_apply_client_session_data(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (GET_VER_OPT("session_data")) { + SSL_SESSION *session = NULL; + bool needs_free = false; + + if (php_openssl_is_session_ce(val)) { + session = php_openssl_session_from_zval(val); + if (!session) { + // TODO: Should this be a TypeError? + php_stream_warn(stream, Generic, + "Invalid OpenSSLSession object, falling back to full handshake"); + return FAILURE; + } + /* Object owns the session, we just borrow it */ + needs_free = false; + } else if (Z_TYPE_P(val) != IS_NULL) { + zend_type_error("session_data must be an OpenSSLSession instance"); + return FAILURE; + } + + if (session) { + if (SSL_set_session(sslsock->ssl_handle, session) != 1) { + php_stream_warn(stream, ResumptionFailed, + "Failed to set session for resumption, falling back to full handshake"); + if (needs_free) { + SSL_SESSION_free(session); + } + ERR_clear_error(); + return FAILURE; + } + + if (needs_free) { + SSL_SESSION_free(session); + } + } + } + + return SUCCESS; +} + +static zend_result php_openssl_create_server_ctx(php_stream *stream, + php_openssl_netstream_data_t *sslsock, int method_flags) +{ + zval *val; + + const SSL_METHOD *method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method(); + sslsock->ctx = SSL_CTX_new(method); + + if (sslsock->ctx == NULL) { + php_stream_warn(stream, CreateFailed, "SSL context creation failure"); + return FAILURE; + } + + SSL_CTX_set_ex_data(sslsock->ctx, php_openssl_get_ctx_stream_data_index(), stream); + + zend_long min_version = 0; + zend_long max_version = 0; + GET_VER_OPT_LONG("min_proto_version", min_version); + GET_VER_OPT_LONG("max_proto_version", max_version); + method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version); + int ssl_ctx_options = SSL_OP_ALL; + + if (GET_VER_OPT("no_ticket") && zend_is_true(val)) { + ssl_ctx_options |= SSL_OP_NO_TICKET; + } + if (GET_VER_OPT("num_tickets")) { + zend_long num_tickets = zval_get_long(val); + if (num_tickets >= 0) { + SSL_CTX_set_num_tickets(sslsock->ctx, num_tickets); + } + } + + ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF + /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */ + ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF; +#endif + + if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) { + ssl_ctx_options |= SSL_OP_NO_COMPRESSION; + } + + bool verify_peer = false; + if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) { + php_openssl_disable_peer_verification(sslsock->ctx, stream); + } else { + verify_peer = true; + if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) { + return FAILURE; + } + } + + /* callback for the passphrase (for localcert) */ + if (GET_VER_OPT("passphrase")) { + SSL_CTX_set_default_passwd_cb_userdata(sslsock->ctx, stream); + SSL_CTX_set_default_passwd_cb(sslsock->ctx, php_openssl_passwd_callback); + } + + char *cipherlist = NULL; + GET_VER_OPT_STRING("ciphers", cipherlist); +#ifndef USE_OPENSSL_SYSTEM_CIPHERS + if (!cipherlist) { + cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS; + } +#endif + if (cipherlist) { + if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) { + return FAILURE; + } + } + + if (GET_VER_OPT("security_level")) { + zend_long lval = zval_get_long(val); + if (lval < 0 || lval > 5) { + // TODO: Should this be a ValueError? + php_stream_warn(stream, Generic, "Security level must be between 0 and 5"); + } +#ifdef HAVE_SEC_LEVEL + SSL_CTX_set_security_level(sslsock->ctx, lval); +#endif + } + + char *alpn_protocols = NULL; + GET_VER_OPT_STRING("alpn_protocols", alpn_protocols); + if (alpn_protocols) { +#ifdef HAVE_TLS_ALPN + { + unsigned short alpn_len; + unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols); + + if (alpn == NULL) { + php_stream_warn(stream, DecodingFailed, "Failed parsing comma-separated TLS ALPN protocol string"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + return FAILURE; + } + if (sslsock->is_client) { + SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len); + } else { + sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream)); + sslsock->alpn_ctx.len = alpn_len; + SSL_CTX_set_alpn_select_cb(sslsock->ctx, php_openssl_server_alpn_callback, sslsock); + } + + efree(alpn); + } +#else + php_stream_warn(stream, ProtocolUnsupported, + "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked"); +#endif + } + + if (FAILURE == php_openssl_set_local_cert(sslsock->ctx, stream)) { + return FAILURE; + } + + SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options); + + SSL_CTX_set_min_proto_version(sslsock->ctx, php_openssl_get_min_proto_version(method_flags)); + SSL_CTX_set_max_proto_version(sslsock->ctx, php_openssl_get_max_proto_version(method_flags)); + + + if (sslsock->is_client) { + if (FAILURE == php_openssl_setup_client_session(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_setup_client_psk(stream, sslsock)) { + return FAILURE; + } + } else if (PHP_STREAM_CONTEXT(stream)) { + if (FAILURE == php_openssl_setup_server_session(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_setup_server_psk(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_set_server_specific_opts(stream, sslsock->ctx)) { + return FAILURE; + } + } + +#ifdef HAVE_TLS_SNI + /* Enable server-side SNI */ + if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock, verify_peer) == FAILURE) { + return FAILURE; + } +#endif + + return SUCCESS; +} + +static zend_result php_openssl_setup_crypto(php_stream *stream, + php_openssl_netstream_data_t *sslsock, + php_stream_xport_crypto_param *cparam) /* {{{ */ +{ + if (sslsock->ssl_handle) { + if (sslsock->s.is_blocked) { + php_stream_warn(stream, Generic, "SSL/TLS already set-up for this stream"); + return FAILURE; + } else { + return SUCCESS; + } + } + + ERR_clear_error(); + + /* We need to do slightly different things based on client/server method + * so let's remember which method was selected */ + sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT; + int method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT; + + /* Re-use SSL_CTX if session is set */ + if (cparam->inputs.session) { + php_openssl_netstream_data_t *parent_sslsock; + + if (cparam->inputs.session->ops != &php_openssl_socket_ops) { + php_stream_warn(stream, SslNotSupported, "Supplied session stream must be an SSL enabled stream"); + } else if ((parent_sslsock = cparam->inputs.session->abstract)->ctx == NULL) { + php_stream_warn(stream, SslNotSupported, "Supplied SSL session stream is not set up"); + } else if (sslsock->is_client && parent_sslsock->ssl_handle == NULL) { + php_stream_warn(stream, SslNotSupported, "Supplied SSL session stream is not initialized"); + } else { + SSL_CTX_up_ref(parent_sslsock->ctx); + sslsock->ctx = parent_sslsock->ctx; + if (parent_sslsock->session_callbacks) { + parent_sslsock->session_callbacks->refcount++; + sslsock->session_callbacks = parent_sslsock->session_callbacks; + } + if (parent_sslsock->psk_callbacks) { + parent_sslsock->psk_callbacks->refcount++; + sslsock->psk_callbacks = parent_sslsock->psk_callbacks; + } + + sslsock->ssl_handle = SSL_new(sslsock->ctx); + if (!sslsock->ssl_handle) { + php_stream_warn(stream, CreateFailed, "SSL handle creation failure"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + return FAILURE; + } + + SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream); + + if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { + php_openssl_handle_ssl_error(stream, 0, true); + } + + if (sslsock->is_client) { + if (SSL_copy_session_id(sslsock->ssl_handle, parent_sslsock->ssl_handle)) { + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_CLIENT); + } else { + php_stream_warn(stream, CreateFailed, "SSL session copying failed creation failure"); + } + } + + return SUCCESS; + } + } + + if (php_openssl_create_server_ctx(stream, sslsock, method_flags) == FAILURE) { + return FAILURE; + } + + sslsock->ssl_handle = SSL_new(sslsock->ctx); + + if (sslsock->ssl_handle == NULL + || !SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream)) { + php_stream_warn(stream, CreateFailed, "SSL handle creation failure"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; +#ifdef HAVE_TLS_ALPN + if (sslsock->alpn_ctx.data) { + pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream)); + sslsock->alpn_ctx.data = NULL; + } +#endif + return FAILURE; + } + + if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { + php_openssl_handle_ssl_error(stream, 0, true); + } + + return SUCCESS; +} +/* }}} */ + +static int php_openssl_capture_peer_certs(php_stream *stream, + php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */ +{ + zval *val, zcert; + php_openssl_certificate_object *cert_object; + int cert_captured = 0; + + if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), + "ssl", "capture_peer_cert")) && + zend_is_true(val) + ) { + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = peer_cert; + + php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert); + zval_ptr_dtor(&zcert); + cert_captured = 1; + } + + if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), + "ssl", "capture_peer_cert_chain")) && + zend_is_true(val) + ) { + zval arr; + STACK_OF(X509) *chain; + + chain = SSL_get_peer_cert_chain(sslsock->ssl_handle); + + if (chain && sk_X509_num(chain) > 0) { + int i; + array_init(&arr); + + for (i = 0; i < sk_X509_num(chain); i++) { + X509 *mycert = X509_dup(sk_X509_value(chain, i)); + + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = mycert; + add_next_index_zval(&arr, &zcert); + } + + } else { + ZVAL_NULL(&arr); + } + + php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr); + zval_ptr_dtor(&arr); + } + + return cert_captured; +} +/* }}} */ + +static zend_result php_openssl_set_blocking(php_openssl_netstream_data_t *sslsock, int block) +{ + zend_result result = php_set_sock_blocking(sslsock->s.socket, block); + if (EXPECTED(SUCCESS == result)) { + sslsock->s.is_blocked = block; + } return result; } @@ -1808,25 +2748,36 @@ static int php_openssl_enable_crypto(php_stream *stream, int cert_captured = 0; X509 *peer_cert; + sslsock->last_status = STREAM_CRYPTO_STATUS_NONE; + if (cparam->inputs.activate && !sslsock->ssl_active) { struct timeval start_time, *timeout; bool blocked = sslsock->s.is_blocked, has_timeout = false; -#ifdef HAVE_TLS_SNI - if (sslsock->is_client) { - php_openssl_enable_client_sni(stream, sslsock); - } -#endif - if (!sslsock->state_set) { +#ifdef PHP_OPENSSL_TLS_DEBUG + BIO *b_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); + SSL_set_msg_callback(sslsock->ssl_handle, SSL_trace); + SSL_set_msg_callback_arg(sslsock->ssl_handle, b_out); +#endif if (sslsock->is_client) { + /* Set session data for client */ + if (php_openssl_apply_client_session_data(stream, sslsock) == FAILURE) { + return -1; + } +#ifdef HAVE_TLS_SNI + php_openssl_enable_client_sni(stream, sslsock); +#endif SSL_set_connect_state(sslsock->ssl_handle); } else { + php_openssl_init_server_reneg_limit(stream, sslsock); SSL_set_accept_state(sslsock->ssl_handle); } sslsock->state_set = 1; } + SSL_set_mode(sslsock->ssl_handle, SSL_MODE_RELEASE_BUFFERS); + if (SUCCESS == php_openssl_set_blocking(sslsock, 0)) { /* The following mode are added only if we are able to change socket * to non blocking mode which is also used for read and write */ @@ -1855,7 +2806,7 @@ static int php_openssl_enable_crypto(php_stream *stream, elapsed_time = php_openssl_subtract_timeval(cur_time, start_time); if (php_openssl_compare_timeval( elapsed_time, *timeout) > 0) { - php_error_docref(NULL, E_WARNING, "SSL: Handshake timed out"); + php_stream_warn(stream, TimeOut, "SSL: Handshake timed out"); return -1; } } @@ -1947,7 +2898,11 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si /* Only do this if SSL is active. */ if (sslsock->ssl_active) { - int retry = 1; + /* We have already returned some buffered data. Don't retry and don't + * block. We're just trying to fill the buffer more, but the stream might + * be empty, so we don't want to wait in vain. */ + bool supplemental = stream->has_buffered_data; + int retry = !supplemental; struct timeval start_time; struct timeval *timeout = NULL; bool began_blocked = sslsock->s.is_blocked; @@ -1960,11 +2915,11 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si } /* never use a timeout with non-blocking sockets */ - if (began_blocked) { + if (began_blocked && !supplemental) { timeout = &sslsock->s.timeout; } - if (timeout) { + if (timeout || supplemental) { php_openssl_set_blocking(sslsock, 0); } @@ -1998,6 +2953,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si /* Now, do the IO operation. Don't block if we can't complete... */ ERR_clear_error(); + sslsock->last_status = STREAM_CRYPTO_STATUS_NONE; if (read) { nr_bytes = SSL_read(sslsock->ssl_handle, buf, (int)count); @@ -2038,7 +2994,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si } /* Don't loop indefinitely in non-blocking mode if no data is available */ - if (began_blocked == 0) { + if (began_blocked == 0 || supplemental) { break; } @@ -2072,6 +3028,10 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : (POLLOUT|POLLPRI), has_timeout ? &left_time : NULL); } + } else if (err == SSL_ERROR_WANT_READ) { + sslsock->last_status = STREAM_CRYPTO_STATUS_WANT_READ; + } else if (err == SSL_ERROR_WANT_WRITE) { + sslsock->last_status = STREAM_CRYPTO_STATUS_WANT_WRITE; } } @@ -2083,6 +3043,16 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0); } + /* This might be a supplemental read after consuming buffered data. If + * the read returned nothing, ignore status WANT_READ. */ + if (read && + supplemental && + nr_bytes <= 0 && + sslsock->last_status == STREAM_CRYPTO_STATUS_WANT_READ + ) { + sslsock->last_status = STREAM_CRYPTO_STATUS_NONE; + } + /* And if we were originally supposed to be blocking, let's reset the socket to that. */ if (began_blocked) { php_openssl_set_blocking(sslsock, 1); @@ -2200,6 +3170,34 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{ pefree(sslsock->reneg, php_stream_is_persistent(stream)); } + if (sslsock->session_callbacks && --sslsock->session_callbacks->refcount == 0) { + if (ZEND_FCC_INITIALIZED(sslsock->session_callbacks->new_cb)) { + zend_fcc_dtor(&sslsock->session_callbacks->new_cb); + } + if (ZEND_FCC_INITIALIZED(sslsock->session_callbacks->get_cb)) { + zend_fcc_dtor(&sslsock->session_callbacks->get_cb); + } + if (ZEND_FCC_INITIALIZED(sslsock->session_callbacks->remove_cb)) { + zend_fcc_dtor(&sslsock->session_callbacks->remove_cb); + } + pefree(sslsock->session_callbacks, php_stream_is_persistent(stream)); + } + + if (sslsock->psk_callbacks && --sslsock->psk_callbacks->refcount == 0) { + if (ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) { + zend_fcc_dtor(&sslsock->psk_callbacks->client_cb); + } + + if (ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) { + zend_fcc_dtor(&sslsock->psk_callbacks->server_cb); + } + pefree(sslsock->psk_callbacks, php_stream_is_persistent(stream)); + } + + if (sslsock->psk_identity_buf) { + efree(sslsock->psk_identity_buf); + } + pefree(sslsock, php_stream_is_persistent(stream)); return 0; @@ -2276,9 +3274,9 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ clisockdata->method = sock->method; if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method, - NULL) < 0 || php_stream_xport_crypto_enable( + sock->ctx ? stream : NULL) < 0 || php_stream_xport_crypto_enable( xparam->outputs.client, 1) < 0) { - php_error_docref(NULL, E_WARNING, "Failed to enable crypto"); + php_stream_warn(stream, ProtocolError, "Failed to enable crypto"); php_stream_close(xparam->outputs.client); xparam->outputs.client = NULL; @@ -2335,6 +3333,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val add_assoc_string(&tmp, "cipher_name", (char *) SSL_CIPHER_get_name(cipher)); add_assoc_long(&tmp, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL)); add_assoc_string(&tmp, "cipher_version", SSL_CIPHER_get_version(cipher)); + add_assoc_bool(&tmp, "session_reused", SSL_session_reused(sslsock->ssl_handle)); #ifdef HAVE_TLS_ALPN { @@ -2511,11 +3510,12 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val case STREAM_XPORT_CRYPTO_OP_SETUP: cparam->outputs.returncode = php_openssl_setup_crypto(stream, sslsock, cparam); return PHP_STREAM_OPTION_RETURN_OK; - break; case STREAM_XPORT_CRYPTO_OP_ENABLE: cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam); return PHP_STREAM_OPTION_RETURN_OK; - break; + case STREAM_XPORT_CRYPTO_OP_GET_STATUS: + cparam->outputs.returncode = sslsock->last_status; + return PHP_STREAM_OPTION_RETURN_OK; default: /* fall through */ break; @@ -2537,14 +3537,36 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC && xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS))) { - if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL) < 0 || + zval *val; + php_stream *session_stream = NULL; + + if (GET_VER_OPT("session_stream")) { + php_stream_from_zval_no_verify(session_stream, val); + } + + if (php_stream_xport_crypto_setup(stream, sslsock->method, session_stream) < 0 || php_stream_xport_crypto_enable(stream, 1) < 0) { - php_error_docref(NULL, E_WARNING, "Failed to enable crypto"); + php_stream_warn(stream, ProtocolError, "Failed to enable crypto"); xparam->outputs.returncode = -1; } } return PHP_STREAM_OPTION_RETURN_OK; + case STREAM_XPORT_OP_LISTEN: + /* Do normal listen first */ + xparam->outputs.returncode = php_stream_socket_ops.set_option( + stream, option, value, ptrparam); + + if (xparam->outputs.returncode == 0 && sslsock->enable_on_connect) { + /* Check if we should create SSL_CTX early for session resumption */ + if (php_openssl_is_session_cache_enabled(stream, false)) { + if (FAILURE == php_openssl_create_server_ctx(stream, sslsock, sslsock->method)) { + xparam->outputs.returncode = -1; + } + } + } + return PHP_STREAM_OPTION_RETURN_OK; + case STREAM_XPORT_OP_ACCEPT: /* we need to copy the additional fields that the underlying tcp transport * doesn't know about */ @@ -2605,6 +3627,18 @@ static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret) *(php_socket_t *)ret = sslsock->s.socket; } return SUCCESS; + case PHP_STREAM_AS_FD_FOR_COPY: + if (sslsock->ssl_active) { + return FAILURE; + } + if (ret) { + php_io_fd *copy_fd = (php_io_fd *) ret; + copy_fd->socket = sslsock->s.socket; + copy_fd->fd_type = PHP_IO_FD_SOCKET; + copy_fd->timeout = sslsock->s.timeout; + copy_fd->is_blocked = sslsock->s.is_blocked; + } + return SUCCESS; default: return FAILURE; } @@ -2720,7 +3754,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock->enable_on_connect = 1; sslsock->method = php_openssl_get_crypto_method(context, STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT); } else if (strncmp(proto, "sslv2", protolen) == 0) { - php_error_docref(NULL, E_WARNING, "SSLv2 unavailable in this PHP version"); + php_stream_warn(stream, ProtocolUnsupported, "SSLv2 unavailable in this PHP version"); php_stream_close(stream); return NULL; } else if (strncmp(proto, "sslv3", protolen) == 0) { @@ -2728,7 +3762,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT; #else - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolUnsupported, "SSLv3 support is not compiled into the OpenSSL library against which PHP is linked"); php_stream_close(stream); return NULL; @@ -2744,7 +3778,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; #else - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolUnsupported, "TLSv1.1 support is not compiled into the OpenSSL library against which PHP is linked"); php_stream_close(stream); return NULL; @@ -2754,7 +3788,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; #else - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolUnsupported, "TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked"); php_stream_close(stream); return NULL; @@ -2764,7 +3798,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT; #else - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, ProtocolUnsupported, "TLSv1.3 support is not compiled into the OpenSSL library against which PHP is linked"); php_stream_close(stream); return NULL; diff --git a/ext/pcntl/config.m4 b/ext/pcntl/config.m4 index cfe6e80ca110..553419114fd2 100644 --- a/ext/pcntl/config.m4 +++ b/ext/pcntl/config.m4 @@ -68,9 +68,6 @@ int main(void) { [AC_DEFINE([HAVE_SCHED_GETCPU], [1], [Define to 1 if the 'sched_getcpu' function is properly supported.])]) - AC_CHECK_TYPE([siginfo_t], [PCNTL_CFLAGS="-DHAVE_STRUCT_SIGINFO_T"],, - [#include ]) - PHP_NEW_EXTENSION([pcntl], [pcntl.c php_signal.c], [$ext_shared], diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 0ef87fffa287..794e75a1716e 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -154,6 +152,7 @@ typedef psetid_t cpu_set_t; #include "Zend/zend_max_execution_timer.h" #include "pcntl_arginfo.h" +#include "pcntl_decl.h" static zend_class_entry *QosClass_ce; ZEND_DECLARE_MODULE_GLOBALS(pcntl) @@ -185,12 +184,8 @@ ZEND_GET_MODULE(pcntl) static void (*orig_interrupt_function)(zend_execute_data *execute_data); -#ifdef HAVE_STRUCT_SIGINFO_T static void pcntl_signal_handler(int, siginfo_t*, void*); static void pcntl_siginfo_to_zval(int, siginfo_t*, zval*); -#else -static void pcntl_signal_handler(int); -#endif static void pcntl_signal_dispatch(void); static void pcntl_signal_dispatch_tick_function(int dummy_int, void *dummy_pointer); static void pcntl_interrupt_function(zend_execute_data *execute_data); @@ -240,7 +235,7 @@ PHP_RSHUTDOWN_FUNCTION(pcntl) /* Reset all signals to their default disposition */ ZEND_HASH_FOREACH_NUM_KEY_VAL(&PCNTL_G(php_signal_table), signo, handle) { if (Z_TYPE_P(handle) != IS_LONG || Z_LVAL_P(handle) != (zend_long)SIG_DFL) { - php_signal(signo, (Sigfunc *)(zend_long)SIG_DFL, 0); + php_signal(signo, (Sigfunc *)(zend_long)SIG_DFL, false); } } ZEND_HASH_FOREACH_END(); @@ -681,7 +676,11 @@ PHP_FUNCTION(pcntl_exec) ZEND_PARSE_PARAMETERS_END(); if (args != NULL) { - // TODO Check array is a list? + if (!zend_array_is_list(Z_ARRVAL_P(args))) { + zend_argument_value_error(2, "must be a list array"); + RETURN_THROWS(); + } + /* Build argument list */ SEPARATE_ARRAY(args); const HashTable *args_ht = Z_ARRVAL_P(args); @@ -835,7 +834,7 @@ PHP_FUNCTION(pcntl_signal) zend_argument_value_error(2, "must be either SIG_DFL or SIG_IGN when an integer value is given"); RETURN_THROWS(); } - if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == (void *)SIG_ERR) { + if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), restart_syscalls) == (void *)SIG_ERR) { PCNTL_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Error assigning signal"); RETURN_FALSE; @@ -1007,8 +1006,7 @@ PHP_FUNCTION(pcntl_sigprocmask) /* }}} */ #endif -#ifdef HAVE_STRUCT_SIGINFO_T -# ifdef HAVE_SIGWAITINFO +#ifdef HAVE_SIGWAITINFO /* {{{ Synchronously wait for queued signals */ PHP_FUNCTION(pcntl_sigwaitinfo) @@ -1050,8 +1048,9 @@ PHP_FUNCTION(pcntl_sigwaitinfo) RETURN_LONG(signal_no); } /* }}} */ -# endif -# ifdef HAVE_SIGTIMEDWAIT +#endif + +#ifdef HAVE_SIGTIMEDWAIT /* {{{ Wait for queued signals */ PHP_FUNCTION(pcntl_sigtimedwait) { @@ -1113,7 +1112,7 @@ PHP_FUNCTION(pcntl_sigtimedwait) RETURN_LONG(signal_no); } /* }}} */ -# endif +#endif static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_siginfo) /* {{{ */ { @@ -1183,7 +1182,6 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi } } /* }}} */ -#endif #ifdef HAVE_GETPRIORITY /* {{{ Get the priority of any process */ @@ -1325,11 +1323,7 @@ PHP_FUNCTION(pcntl_strerror) /* }}} */ /* Our custom signal handler that calls the appropriate php_function */ -#ifdef HAVE_STRUCT_SIGINFO_T static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context) -#else -static void pcntl_signal_handler(int signo) -#endif { struct php_pcntl_pending_signal *psig = PCNTL_G(spares); if (!psig) { @@ -1341,9 +1335,7 @@ static void pcntl_signal_handler(int signo) psig->signo = signo; psig->next = NULL; -#ifdef HAVE_STRUCT_SIGINFO_T psig->siginfo = *siginfo; -#endif /* the head check is important, as the tick handler cannot atomically clear both * the head and tail */ @@ -1395,19 +1387,14 @@ void pcntl_signal_dispatch(void) if ((handle = zend_hash_index_find(&PCNTL_G(php_signal_table), queue->signo)) != NULL) { if (Z_TYPE_P(handle) != IS_LONG) { ZVAL_LONG(¶ms[0], queue->signo); -#ifdef HAVE_STRUCT_SIGINFO_T array_init(¶ms[1]); pcntl_siginfo_to_zval(queue->signo, &queue->siginfo, ¶ms[1]); -#else - ZVAL_NULL(¶ms[1]); -#endif /* Call php signal handler - Note that we do not report errors, and we ignore the return value */ call_user_function(NULL, NULL, handle, &retval, 2, params); zval_ptr_dtor(&retval); -#ifdef HAVE_STRUCT_SIGINFO_T zval_ptr_dtor(¶ms[1]); -#endif + if (EG(exception)) { break; } @@ -1481,7 +1468,6 @@ PHP_FUNCTION(pcntl_unshare) case EINVAL: zend_argument_value_error(1, "must be a combination of CLONE_* flags, or at least one flag is unsupported by the kernel"); RETURN_THROWS(); - break; #endif #ifdef ENOMEM case ENOMEM: @@ -1854,28 +1840,28 @@ static qos_class_t qos_enum_to_pthread(zend_enum_Pcntl_QosClass entry) static zend_object *qos_lval_to_zval(qos_class_t qos_class) { - const char *entryname; + int entry_id; switch (qos_class) { case QOS_CLASS_USER_INTERACTIVE: - entryname = "UserInteractive"; + entry_id = ZEND_ENUM_Pcntl_QosClass_UserInteractive; break; case QOS_CLASS_USER_INITIATED: - entryname = "UserInitiated"; + entry_id = ZEND_ENUM_Pcntl_QosClass_UserInitiated; break; case QOS_CLASS_UTILITY: - entryname = "Utility"; + entry_id = ZEND_ENUM_Pcntl_QosClass_Utility; break; case QOS_CLASS_BACKGROUND: - entryname = "Background"; + entry_id = ZEND_ENUM_Pcntl_QosClass_Background; break; case QOS_CLASS_DEFAULT: default: - entryname = "Default"; + entry_id = ZEND_ENUM_Pcntl_QosClass_Default; break; } - return zend_enum_get_case_cstr(QosClass_ce, entryname); + return zend_enum_get_case_by_id(QosClass_ce, entry_id); } PHP_FUNCTION(pcntl_getqos_class) diff --git a/ext/pcntl/pcntl.stub.php b/ext/pcntl/pcntl.stub.php index 2da540fa71ec..4a4b8fe86931 100644 --- a/ext/pcntl/pcntl.stub.php +++ b/ext/pcntl/pcntl.stub.php @@ -1035,14 +1035,12 @@ function pcntl_signal_dispatch(): bool {} function pcntl_sigprocmask(int $mode, array $signals, &$old_signals = null): bool {} #endif -#ifdef HAVE_STRUCT_SIGINFO_T #if (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) /** @param array $info */ function pcntl_sigwaitinfo(array $signals, &$info = []): int|false {} /** @param array $info */ function pcntl_sigtimedwait(array $signals, &$info = [], int $seconds = 0, int $nanoseconds = 0): int|false {} -#endif #endif function pcntl_wifexited(int $status): bool {} diff --git a/ext/pcntl/pcntl_arginfo.h b/ext/pcntl/pcntl_arginfo.h index d9624a226057..2da7c8ad5db8 100644 --- a/ext/pcntl/pcntl_arginfo.h +++ b/ext/pcntl/pcntl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit pcntl.stub.php instead. - * Stub hash: dfa1e84a14e1926a50a42919e24ada58348fe4d9 + * Stub hash: 04e7b30c6fb23cf6ce6bc26fe094fd5b4dbfe826 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_fork, 0, 0, IS_LONG, 0) @@ -49,7 +49,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pcntl_sigprocmask, 0, 2, _IS_BOO ZEND_END_ARG_INFO() #endif -#if defined(HAVE_STRUCT_SIGINFO_T) && (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) +#if (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pcntl_sigwaitinfo, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, signals, IS_ARRAY, 0) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, info, "[]") @@ -185,7 +185,7 @@ ZEND_FUNCTION(pcntl_signal_dispatch); #if defined(HAVE_SIGPROCMASK) ZEND_FUNCTION(pcntl_sigprocmask); #endif -#if defined(HAVE_STRUCT_SIGINFO_T) && (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) +#if (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) ZEND_FUNCTION(pcntl_sigwaitinfo); ZEND_FUNCTION(pcntl_sigtimedwait); #endif @@ -246,7 +246,7 @@ static const zend_function_entry ext_functions[] = { #if defined(HAVE_SIGPROCMASK) ZEND_FE(pcntl_sigprocmask, arginfo_pcntl_sigprocmask) #endif -#if defined(HAVE_STRUCT_SIGINFO_T) && (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) +#if (defined(HAVE_SIGWAITINFO) && defined(HAVE_SIGTIMEDWAIT)) ZEND_FE(pcntl_sigwaitinfo, arginfo_pcntl_sigwaitinfo) ZEND_FE(pcntl_sigtimedwait, arginfo_pcntl_sigtimedwait) #endif diff --git a/ext/pcntl/pcntl_decl.h b/ext/pcntl/pcntl_decl.h index 1059485bc934..7f8e5172cedb 100644 --- a/ext/pcntl/pcntl_decl.h +++ b/ext/pcntl/pcntl_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit pcntl.stub.php instead. - * Stub hash: dfa1e84a14e1926a50a42919e24ada58348fe4d9 */ + * Stub hash: 04e7b30c6fb23cf6ce6bc26fe094fd5b4dbfe826 */ -#ifndef ZEND_PCNTL_DECL_dfa1e84a14e1926a50a42919e24ada58348fe4d9_H -#define ZEND_PCNTL_DECL_dfa1e84a14e1926a50a42919e24ada58348fe4d9_H +#ifndef ZEND_PCNTL_DECL_04e7b30c6fb23cf6ce6bc26fe094fd5b4dbfe826_H +#define ZEND_PCNTL_DECL_04e7b30c6fb23cf6ce6bc26fe094fd5b4dbfe826_H typedef enum zend_enum_Pcntl_QosClass { ZEND_ENUM_Pcntl_QosClass_UserInteractive = 1, @@ -12,4 +12,4 @@ typedef enum zend_enum_Pcntl_QosClass { ZEND_ENUM_Pcntl_QosClass_Background = 5, } zend_enum_Pcntl_QosClass; -#endif /* ZEND_PCNTL_DECL_dfa1e84a14e1926a50a42919e24ada58348fe4d9_H */ +#endif /* ZEND_PCNTL_DECL_04e7b30c6fb23cf6ce6bc26fe094fd5b4dbfe826_H */ diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h index e02f93246e88..aaf1ea0ad473 100644 --- a/ext/pcntl/php_pcntl.h +++ b/ext/pcntl/php_pcntl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -19,7 +17,7 @@ #include "pcntl_decl.h" -#if defined(HAVE_DECL_WCONTINUED) && HAVE_DECL_WCONTINUED == 1 && defined(HAVE_WIFCONTINUED) && HAVE_WIFCONTINUED == 1 +#if defined(HAVE_DECL_WCONTINUED) && HAVE_DECL_WCONTINUED == 1 && defined(HAVE_WIFCONTINUED) #define HAVE_WCONTINUED 1 #endif @@ -38,9 +36,7 @@ PHP_MINFO_FUNCTION(pcntl); struct php_pcntl_pending_signal { struct php_pcntl_pending_signal *next; zend_long signo; -#ifdef HAVE_STRUCT_SIGINFO_T siginfo_t siginfo; -#endif }; ZEND_BEGIN_MODULE_GLOBALS(pcntl) diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c index 14c169310e60..b0357d86f02b 100644 --- a/ext/pcntl/php_signal.c +++ b/ext/pcntl/php_signal.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -21,24 +19,18 @@ /* php_signal using sigaction is derived from Advanced Programming * in the Unix Environment by W. Richard Stevens p 298. */ -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) +Sigfunc *php_signal4(int signo, Sigfunc *func, bool restart, bool mask_all) { struct sigaction act,oact; -#ifdef HAVE_STRUCT_SIGINFO_T act.sa_sigaction = func; -#else - act.sa_handler = func; -#endif if (mask_all) { sigfillset(&act.sa_mask); } else { sigemptyset(&act.sa_mask); } act.sa_flags = SA_ONSTACK; -#ifdef HAVE_STRUCT_SIGINFO_T act.sa_flags |= SA_SIGINFO; -#endif if (!restart) { #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; /* SunOS */ @@ -50,14 +42,10 @@ Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) } zend_sigaction(signo, &act, &oact); -#ifdef HAVE_STRUCT_SIGINFO_T return oact.sa_sigaction; -#else - return oact.sa_handler; -#endif } -Sigfunc *php_signal(int signo, Sigfunc *func, int restart) +Sigfunc *php_signal(int signo, Sigfunc *func, bool restart) { - return php_signal4(signo, func, restart, 0); + return php_signal4(signo, func, restart, false); } diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index 256898e70acb..7b103793e544 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -18,12 +16,9 @@ #ifndef PHP_SIGNAL_H #define PHP_SIGNAL_H -#ifdef HAVE_STRUCT_SIGINFO_T typedef void Sigfunc(int, siginfo_t*, void*); -#else -typedef void Sigfunc(int); -#endif -Sigfunc *php_signal(int signo, Sigfunc *func, int restart); -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all); + +Sigfunc *php_signal(int signo, Sigfunc *func, bool restart); +Sigfunc *php_signal4(int signo, Sigfunc *func, bool restart, bool mask_all); #endif diff --git a/ext/pcntl/tests/pcntl_exec_list_args.phpt b/ext/pcntl/tests/pcntl_exec_list_args.phpt new file mode 100644 index 000000000000..5cd8c0fbe228 --- /dev/null +++ b/ext/pcntl/tests/pcntl_exec_list_args.phpt @@ -0,0 +1,14 @@ +--TEST-- +pcntl_exec(): Argument array must be a list +--EXTENSIONS-- +pcntl +--FILE-- + '-n']); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECT-- +ValueError: pcntl_exec(): Argument #2 ($args) must be a list array diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index 7c09456b8961..93d9df201d51 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -1,7 +1,7 @@ // vim:ft=javascript EXTENSION("pcre", "php_pcre.c", false /* never shared */, - "-Iext/pcre/pcre2lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + "-Iext/pcre/pcre2lib"); ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre"); ADD_DEF_FILE("ext\\pcre\\php_pcre.def"); diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index e71d9a795574..025b54eb7805 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -57,8 +57,7 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then PHP_NEW_EXTENSION([pcre], [php_pcre.c], - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) PHP_INSTALL_HEADERS([ext/pcre], [php_pcre.h]) else AC_MSG_CHECKING([for PCRE library to use]) @@ -101,7 +100,6 @@ else $PHP_PCRE_CFLAGS -DHAVE_CONFIG_H -DHAVE_MEMMOVE - -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -I@ext_srcdir@/pcre2lib "]) diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 32ab6b0e5090..6a62d9717e7b 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ @@ -622,7 +620,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* Parse through the leading whitespace, and display a warning if we get to the end without encountering a delimiter. */ - while (isspace((int)*(unsigned char *)p)) p++; + while (isspace((unsigned char)*p)) p++; if (p >= end_p) { if (key != regex) { zend_string_release_ex(key, 0); @@ -635,7 +633,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* Get the delimiter and display a warning if it is alphanumeric or a backslash. */ delimiter = *p++; - if (isalnum((int)*(unsigned char *)&delimiter) || delimiter == '\\' || delimiter == '\0') { + if (isalnum((unsigned char)delimiter) || delimiter == '\\' || delimiter == '\0') { if (key != regex) { zend_string_release_ex(key, 0); } @@ -750,21 +748,23 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo } if (key != regex) { - tables = (uint8_t *)zend_hash_find_ptr(&char_tables, BG(ctype_string)); - if (!tables) { - zend_string *_k; + zv = zend_hash_str_lookup(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string))); + if (Z_ISNULL_P(zv)) { tables = pcre2_maketables(gctx); if (UNEXPECTED(!tables)) { + /* Remove the placeholder entry created by zend_hash_str_lookup(), + * set ptr to NULL first so the destructor (pefree) is safe. */ + ZVAL_PTR(zv, NULL); + zend_hash_str_del(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string))); php_error_docref(NULL,E_WARNING, "Failed to generate locale character tables"); pcre_handle_exec_error(PCRE2_ERROR_NOMEMORY); zend_string_release_ex(key, 0); efree(pattern); return NULL; } - _k = zend_string_init(ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)), 1); - GC_MAKE_PERSISTENT_LOCAL(_k); - zend_hash_add_ptr(&char_tables, _k, (void *)tables); - zend_string_release(_k); + ZVAL_PTR(zv, (void *)tables); + } else { + tables = Z_PTR_P(zv); } } pcre2_set_character_tables(cctx, tables); @@ -826,19 +826,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo new_entry.refcount = 0; new_entry.subpats_table = NULL; - rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count); - if (rc < 0) { - if (key != regex) { - zend_string_release_ex(key, 0); - } - pcre2_code_free(new_entry.re); - php_error_docref(NULL, E_WARNING, "Internal pcre2_pattern_info() error %d", rc); - pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); - return NULL; - } - - rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count); - if (rc < 0) { + if ((rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count)) < 0 || + (rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count)) < 0) { if (key != regex) { zend_string_release_ex(key, 0); } @@ -1090,7 +1079,7 @@ static void populate_subpat_array( /* Add MARK, if available */ if (mark) { ZVAL_STRING(&val, (char *)mark); - zend_hash_str_add_new(subpats_ht, ZEND_STRL("MARK"), &val); + zend_hash_str_update(subpats_ht, ZEND_STRL("MARK"), &val); } } @@ -1570,6 +1559,7 @@ static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cach fci->retval = &retval; fci->param_count = 1; fci->params = &arg; + fci->consumed_args = zend_fci_consumed_arg(0); zend_call_function(fci, fcc); zval_ptr_dtor(&arg); if (EXPECTED(Z_TYPE(retval) == IS_STRING)) { @@ -2495,7 +2485,7 @@ PHP_FUNCTION(preg_replace_callback_array) case IS_NULL: RETVAL_NULL(); goto error; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (EG(exception)) { diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index e180d68a3d48..ebaa686a31c3 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ diff --git a/ext/pcre/tests/mark_named_collision.phpt b/ext/pcre/tests/mark_named_collision.phpt new file mode 100644 index 000000000000..b644c4d44023 --- /dev/null +++ b/ext/pcre/tests/mark_named_collision.phpt @@ -0,0 +1,15 @@ +--TEST-- +preg_match: (*MARK:name) directive does not collide with named group called MARK +--FILE-- +[abc])(*MARK:value)/', "abc", $m); +echo "count: ", count($m), "\n"; +echo "MARK: ", $m['MARK'], "\n"; +echo "json: ", json_encode($m), "\n"; +echo "keys: ", implode(',', array_keys($m)), "\n"; +?> +--EXPECT-- +count: 3 +MARK: value +json: {"0":"a","MARK":"value","1":"a"} +keys: 0,MARK,1 diff --git a/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt b/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt new file mode 100644 index 000000000000..0ae802654c9a --- /dev/null +++ b/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt @@ -0,0 +1,37 @@ +--TEST-- +preg_replace_callback(): capture match array refcount stays low during callback +--FILE-- + static function ($matches) { + debug_zval_dump($matches); + return ''; +}], 'abc')); +?> +--EXPECTF-- +array(4) packed refcount(2){ + [0]=> + string(3) "abc"%s + [1]=> + string(1) "a" interned + [2]=> + string(1) "b" interned + [3]=> + string(1) "c" interned +} +string(0) "" +array(4) packed refcount(2){ + [0]=> + string(3) "abc"%s + [1]=> + string(1) "a" interned + [2]=> + string(1) "b" interned + [3]=> + string(1) "c" interned +} +string(0) "" diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index 2966cd0be569..5b881b0f56da 100644 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -241,7 +239,7 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s } } - while (i < data_source_len && isspace(data_source[i])) { + while (i < data_source_len && isspace((unsigned char)data_source[i])) { i++; } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 34f19e364faa..dcd9f7b126df 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -1486,7 +1484,6 @@ static zend_function *dbh_method_get(zend_object **object, zend_string *method_n { zend_function *fbc = NULL; pdo_dbh_object_t *dbh_obj = php_pdo_dbh_fetch_object(*object); - zend_string *lc_method_name; if ((fbc = zend_std_get_method(object, method_name, key)) == NULL) { /* not a pre-defined method, nor a user-defined method; check @@ -1499,9 +1496,7 @@ static zend_function *dbh_method_get(zend_object **object, zend_string *method_n } } - lc_method_name = zend_string_tolower(method_name); - fbc = zend_hash_find_ptr(dbh_obj->inner->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH], lc_method_name); - zend_string_release_ex(lc_method_name, 0); + fbc = zend_hash_find_ptr_lc(dbh_obj->inner->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH], method_name); } out: @@ -1531,7 +1526,7 @@ void pdo_dbh_init(int module_number) pdo_dbh_ce->default_object_handlers = &pdo_dbh_object_handlers; memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_dbh_object_handlers.offset = XtOffsetOf(pdo_dbh_object_t, std); + pdo_dbh_object_handlers.offset = offsetof(pdo_dbh_object_t, std); pdo_dbh_object_handlers.free_obj = pdo_dbh_free_storage; pdo_dbh_object_handlers.clone_obj = NULL; pdo_dbh_object_handlers.get_method = dbh_method_get; diff --git a/ext/pdo/pdo_sql_parser.h b/ext/pdo/pdo_sql_parser.h index 0701d984ae64..9baca65e5f90 100644 --- a/ext/pdo/pdo_sql_parser.h +++ b/ext/pdo/pdo_sql_parser.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 1897f9f238bf..d77425531cc4 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ @@ -117,7 +115,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string if (t == PDO_PARSER_BIND) { ptrdiff_t len = s.cur - s.tok; - if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { + if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum((unsigned char)s.cur[-len - 1])) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; diff --git a/ext/pdo/pdo_sqlstate.c b/ext/pdo/pdo_sqlstate.c index a44b95a9181d..089c1bdd027f 100644 --- a/ext/pdo/pdo_sqlstate.c +++ b/ext/pdo/pdo_sqlstate.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 73d4530e8f65..09b9fd3550e6 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -148,7 +146,7 @@ bool pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */ stmt->columns[col].name = zend_string_toupper(orig_name); zend_string_release(orig_name); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -823,7 +821,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h * However, if we fetch a group key we will have over allocated. */ fetch_function_params = safe_emalloc(sizeof(zval), stmt->column_count, 0); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if (group_key) { @@ -918,7 +916,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h case PDO_FETCH_FUNC: ZVAL_COPY_VALUE(&fetch_function_params[fetch_function_param_num++], &val); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -1181,7 +1179,7 @@ PHP_METHOD(PDOStatement, fetchAll) zend_class_entry *fetch_class = NULL; if (arg2) { if (Z_TYPE_P(arg2) != IS_STRING) { - zend_argument_type_error(2, "must be of type string, %s given", zend_zval_value_name(arg2)); + zend_wrong_parameter_type_error(2, Z_EXPECTED_STRING, arg2); RETURN_THROWS(); } fetch_class = zend_lookup_class(Z_STR_P(arg2)); @@ -1230,7 +1228,7 @@ PHP_METHOD(PDOStatement, fetchAll) if (arg2) { // Reuse convert_to_long(arg2); ? if (Z_TYPE_P(arg2) != IS_LONG) { - zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(arg2)); + zend_wrong_parameter_type_error(2, Z_EXPECTED_LONG, arg2); RETURN_THROWS(); } if (Z_LVAL_P(arg2) < 0) { @@ -1700,7 +1698,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a return false; } if (Z_TYPE(args[0]) != IS_STRING) { - zend_argument_type_error(arg1_arg_num, "must be of type string, %s given", zend_zval_value_name(&args[0])); + zend_wrong_parameter_type_error(arg1_arg_num, Z_EXPECTED_STRING, &args[0]); return false; } cep = zend_lookup_class(Z_STR(args[0])); @@ -1712,8 +1710,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a /* TODO: Improve logic? */ if (variadic_num_args == 2) { if (Z_TYPE(args[1]) != IS_NULL && Z_TYPE(args[1]) != IS_ARRAY) { - zend_argument_type_error(constructor_arg_num, "must be of type ?array, %s given", - zend_zval_value_name(&args[1])); + zend_wrong_parameter_type_error(constructor_arg_num, Z_EXPECTED_ARRAY_OR_NULL, &args[1]); return false; } if (Z_TYPE(args[1]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL(args[1]))) { @@ -1738,7 +1735,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a return false; } if (Z_TYPE(args[0]) != IS_OBJECT) { - zend_argument_type_error(arg1_arg_num, "must be of type object, %s given", zend_zval_value_name(&args[0])); + zend_wrong_parameter_type_error(arg1_arg_num, Z_EXPECTED_OBJECT, &args[0]); return false; } @@ -1916,9 +1913,7 @@ PHP_METHOD(PDOStatement, debugDumpParams) PHP_METHOD(PDOStatement, getIterator) { - if (zend_parse_parameters_none() == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_NONE(); zend_create_internal_iterator_zval(return_value, ZEND_THIS); } @@ -2424,7 +2419,7 @@ void pdo_stmt_init(void) pdo_dbstmt_ce->default_object_handlers = &pdo_dbstmt_object_handlers; memcpy(&pdo_dbstmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_dbstmt_object_handlers.offset = XtOffsetOf(pdo_stmt_t, std); + pdo_dbstmt_object_handlers.offset = offsetof(pdo_stmt_t, std); pdo_dbstmt_object_handlers.free_obj = pdo_dbstmt_free_storage; pdo_dbstmt_object_handlers.write_property = dbstmt_prop_write; pdo_dbstmt_object_handlers.unset_property = dbstmt_prop_delete; @@ -2438,7 +2433,7 @@ void pdo_stmt_init(void) pdo_row_ce->default_object_handlers = &pdo_row_object_handlers; memcpy(&pdo_row_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_row_object_handlers.offset = XtOffsetOf(pdo_row_t, std); + pdo_row_object_handlers.offset = offsetof(pdo_row_t, std); pdo_row_object_handlers.free_obj = pdo_row_free_storage; pdo_row_object_handlers.clone_obj = NULL; pdo_row_object_handlers.get_property_ptr_ptr = pdo_row_get_property_ptr_ptr; diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h index 59789a04c73f..39443bb35c89 100644 --- a/ext/pdo/php_pdo.h +++ b/ext/pdo/php_pdo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 9c5986ff8bce..479a1b5436c9 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -520,12 +518,10 @@ struct _pdo_dbh_object_t { }; static inline pdo_dbh_t *php_pdo_dbh_fetch_inner(zend_object *obj) { - return (pdo_dbh_t *)(((pdo_dbh_object_t *)((char*)(obj) - XtOffsetOf(pdo_dbh_object_t, std)))->inner); + return (pdo_dbh_t *)((ZEND_CONTAINER_OF(obj, pdo_dbh_object_t, std))->inner); } -static inline pdo_dbh_object_t *php_pdo_dbh_fetch_object(zend_object *obj) { - return (pdo_dbh_object_t *)((char*)(obj) - XtOffsetOf(pdo_dbh_object_t, std)); -} +#define php_pdo_dbh_fetch_object(obj) ZEND_CONTAINER_OF(obj, pdo_dbh_object_t, std) #define Z_PDO_DBH_P(zv) php_pdo_dbh_fetch_inner(Z_OBJ_P((zv))) #define Z_PDO_OBJECT_P(zv) php_pdo_dbh_fetch_object(Z_OBJ_P((zv))) @@ -639,11 +635,7 @@ struct _pdo_stmt_t { zend_object std; }; - - -static inline pdo_stmt_t *php_pdo_stmt_fetch_object(zend_object *obj) { - return (pdo_stmt_t *)((char*)(obj) - XtOffsetOf(pdo_stmt_t, std)); -} +#define php_pdo_stmt_fetch_object(obj) ZEND_CONTAINER_OF(obj, pdo_stmt_t, std) #define Z_PDO_STMT_P(zv) php_pdo_stmt_fetch_object(Z_OBJ_P((zv))) @@ -652,9 +644,7 @@ struct _pdo_row_t { zend_object std; }; -static inline pdo_row_t *php_pdo_row_fetch_object(zend_object *obj) { - return (pdo_row_t *)((char*)(obj) - XtOffsetOf(pdo_row_t, std)); -} +#define php_pdo_row_fetch_object(obj) ZEND_CONTAINER_OF(obj, pdo_row_t, std) struct _pdo_scanner_t { const char *ptr, *cur, *tok, *end; diff --git a/ext/pdo/php_pdo_error.h b/ext/pdo/php_pdo_error.h index 50c751a0f490..79d1c482d609 100644 --- a/ext/pdo/php_pdo_error.h +++ b/ext/pdo/php_pdo_error.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index e8befe9f819a..dde79af73aa0 100644 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 68e251c2b6a9..7189954ec412 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | @@ -233,8 +231,8 @@ zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name) pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; RETCODE ret; - BYTE id[32]; - size_t len; + BYTE id[40]; + DBINT len; /* * Would use scope_identity() but it's not implemented on Sybase @@ -266,9 +264,13 @@ zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name) return NULL; } - len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1); + len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)sizeof(id)); dbcancel(H->link); + if (len < 0) { + return NULL; + } + return zend_string_init((const char *) id, len, 0); } @@ -422,6 +424,17 @@ static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_valu return 1; } +static zend_result dblib_handle_check_liveness(pdo_dbh_t *dbh) +{ + pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; + + if (dbdead(H->link)) { + return FAILURE; + } + + return SUCCESS; +} + static const struct pdo_dbh_methods dblib_methods = { dblib_handle_closer, dblib_handle_preparer, @@ -434,7 +447,7 @@ static const struct pdo_dbh_methods dblib_methods = { dblib_handle_last_id, /* last insert id */ dblib_fetch_error, /* fetch error */ dblib_get_attribute, /* get attr */ - NULL, /* check liveness */ + dblib_handle_check_liveness, /* check_liveness */ NULL, /* get driver methods */ NULL, /* request shutdown */ NULL, /* in transaction, use PDO's internal tracking mechanism */ @@ -535,7 +548,6 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) } if (i==nvers) { - printf("Invalid version '%s'\n", vars[5].optval); pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Invalid version specified in connection string."); goto cleanup; /* unknown version specified */ } diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index e6e91b60fa27..0b97b1dfb076 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index 9c59ddbc6184..47cf1497ef7d 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/php_pdo_dblib.h b/ext/pdo_dblib/php_pdo_dblib.h index 7cd13d6eb4bb..60e3d8c082a6 100644 --- a/ext/pdo_dblib/php_pdo_dblib.h +++ b/ext/pdo_dblib/php_pdo_dblib.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index 2067d944c718..21ffa9c86243 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 76384a187477..36f380b2122b 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ @@ -295,7 +293,7 @@ static FbTokenType php_firebird_get_token(const char** begin, const char* end) return ret; } -static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTable* named_params) +static int php_firebird_preprocess(const zend_string* sql, char* sql_out, size_t* sql_out_len, HashTable* named_params) { bool passAsIs = true, execBlock = false; zend_long pindex = -1; @@ -326,7 +324,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident, i, l); + memcpy(ident, i, l); ident[l] = '\0'; if (!strcasecmp(ident, "EXECUTE")) { @@ -351,7 +349,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident2, i2, l); + memcpy(ident2, i2, l); ident2[l] = '\0'; execBlock = !strcasecmp(ident2, "BLOCK"); passAsIs = false; @@ -367,11 +365,15 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (passAsIs) { - strcpy(sql_out, ZSTR_VAL(sql)); + memcpy(sql_out, ZSTR_VAL(sql), ZSTR_LEN(sql)); + sql_out[ZSTR_LEN(sql)] = '\0'; + *sql_out_len = ZSTR_LEN(sql); return 1; } - strncat(sql_out, start, p - start); + char *sql_out_p = sql_out; + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; while (p < end) { @@ -379,10 +381,12 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa tok = php_firebird_get_token(&p, end); switch (tok) { - case ttParamMark: - tok = php_firebird_get_token(&p, end); + case ttParamMark: { + const char* p_peek = p; + tok = php_firebird_get_token(&p_peek, end); if (tok == ttIdent /*|| tok == ttString*/) { + p = p_peek; ++pindex; l = p - start; /* check the length of the identifier */ @@ -391,7 +395,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 253) { return 0; } - strncpy(pname, start, l); + memcpy(pname, start, l); pname[l] = '\0'; if (named_params) { @@ -400,7 +404,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa zend_hash_str_update(named_params, pname, l, &tmp); } - strcat(sql_out, "?"); + *sql_out_p++ = '?'; } else { @@ -410,10 +414,11 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa return 0; } ++pindex; - strncat(sql_out, start, p - start); + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; } break; - + } case ttIdent: if (execBlock) { @@ -425,11 +430,14 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident, start, l); + memcpy(ident, start, l); ident[l] = '\0'; if (!strcasecmp(ident, "AS")) { - strncat(sql_out, start, end - start); + memcpy(sql_out_p, start, end - start); + sql_out_p += end - start; + *sql_out_p = '\0'; + *sql_out_len = sql_out_p - sql_out; return 1; } } @@ -440,7 +448,8 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa case ttComment: case ttString: case ttOther: - strncat(sql_out, start, p - start); + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; break; case ttBrokenComment: @@ -455,9 +464,10 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa case ttNone: /* Execute statement preprocess SQL error */ return 0; - break; } } + *sql_out_p = '\0'; + *sql_out_len = sql_out_p - sql_out; return 1; } @@ -792,7 +802,7 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { size_t qcount = 0; - char const *co, *l, *r; + char const *co, *l; char *c; size_t quotedlen; zend_string *quoted_str; @@ -801,9 +811,15 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un return ZSTR_INIT_LITERAL("''", 0); } + const char * const end = ZSTR_VAL(unquoted) + ZSTR_LEN(unquoted); + /* Firebird only requires single quotes to be doubled if string lengths are used */ /* count the number of ' characters */ - for (co = ZSTR_VAL(unquoted); (co = strchr(co,'\'')); qcount++, co++); + for (co = ZSTR_VAL(unquoted); co < end; co++) { + if (*co == '\'') { + qcount++; + } + } if (UNEXPECTED(ZSTR_LEN(unquoted) + 2 > ZSTR_MAX_LEN - qcount)) { return NULL; @@ -815,15 +831,14 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un *c++ = '\''; /* foreach (chunk that ends in a quote) */ - for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) { - strncpy(c, l, r-l+1); - c += (r-l+1); - /* add the second quote */ - *c++ = '\''; + for (l = ZSTR_VAL(unquoted); l < end; l++) { + *c++ = *l; + if (*l == '\'') { + /* add the second quote */ + *c++ = '\''; + } } - /* copy the remainder */ - strncpy(c, l, quotedlen-(c-ZSTR_VAL(quoted_str))-1); ZSTR_VAL(quoted_str)[quotedlen-1] = '\''; ZSTR_VAL(quoted_str)[quotedlen] = '\0'; @@ -1001,6 +1016,7 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; char *new_sql; + size_t new_sql_len; /* allocate the statement */ if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) { @@ -1012,14 +1028,14 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq we need to replace :foo by ?, and store the name we just replaced */ new_sql = emalloc(ZSTR_LEN(sql)+1); new_sql[0] = '\0'; - if (!php_firebird_preprocess(sql, new_sql, named_params)) { + if (!php_firebird_preprocess(sql, new_sql, &new_sql_len, named_params)) { php_firebird_error_with_info(dbh, "07000", strlen("07000"), NULL, 0); efree(new_sql); return 0; } /* prepare the statement */ - if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) { + if (isc_dsql_prepare(H->isc_status, &H->tr, s, new_sql_len, new_sql, H->sql_dialect, out_sqlda)) { php_firebird_error(dbh); efree(new_sql); return 0; @@ -1373,6 +1389,10 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* char const *dpb_values[] = { dbh->username, dbh->password, vars[1].optval, vars[2].optval }; char dpb_buffer[256] = { isc_dpb_version1 }, *dpb; + if (EG(exception)) { + break; + } + dpb = dpb_buffer + 1; /* loop through all the provided arguments and set dpb fields accordingly */ @@ -1409,7 +1429,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* } } - if (!dbh->methods) { + if (!dbh->methods && !EG(exception)) { char errmsg[512]; const ISC_STATUS *s = H->isc_status; fb_interpret(errmsg, sizeof(errmsg),&s); diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index d506aa69eed3..bdca5af974cf 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ @@ -492,7 +490,7 @@ static int pdo_firebird_stmt_get_col( break; case SQL_DOUBLE: break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if ((var->sqltype & ~1) == SQL_DOUBLE) { diff --git a/ext/pdo_firebird/pdo_firebird.c b/ext/pdo_firebird/pdo_firebird.c index ece55926b0f4..74ba7f8994ca 100644 --- a/ext/pdo_firebird/pdo_firebird.c +++ b/ext/pdo_firebird/pdo_firebird.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/pdo_firebird_utils.cpp b/ext/pdo_firebird/pdo_firebird_utils.cpp index 715963eec17c..cd54da8cd9c6 100644 --- a/ext/pdo_firebird/pdo_firebird_utils.cpp +++ b/ext/pdo_firebird/pdo_firebird_utils.cpp @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Simonov Denis | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/pdo_firebird_utils.h b/ext/pdo_firebird/pdo_firebird_utils.h index 19b0d0ab4ba4..3a3ee4ab7c41 100644 --- a/ext/pdo_firebird/pdo_firebird_utils.h +++ b/ext/pdo_firebird/pdo_firebird_utils.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Simonov Denis | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/php_pdo_firebird.h b/ext/pdo_firebird/php_pdo_firebird.h index 19ce061c959f..6d897dfd2933 100644 --- a/ext/pdo_firebird/php_pdo_firebird.h +++ b/ext/pdo_firebird/php_pdo_firebird.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index a62c152ffab3..7e83b2687a72 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/tests/autocommit.phpt b/ext/pdo_firebird/tests/autocommit.phpt index 3f4f7e8f370f..daa91898a8e9 100644 --- a/ext/pdo_firebird/tests/autocommit.phpt +++ b/ext/pdo_firebird/tests/autocommit.phpt @@ -71,9 +71,9 @@ array(1) { ========== not in auto commit mode ========== auto commit mode OFF insert, expect error -SQLSTATE[08003]: Connection does not exist: %s +%r(SQLSTATE\[08003\]: Connection does not exist|SQLSTATE\[HY000\]: General error)%r: %s select, expect error -SQLSTATE[08003]: Connection does not exist: %s +%r(SQLSTATE\[08003\]: Connection does not exist|SQLSTATE\[HY000\]: General error)%r: %s done! diff --git a/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt new file mode 100644 index 000000000000..3046fbc011b7 --- /dev/null +++ b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt @@ -0,0 +1,46 @@ +--TEST-- +GHSA-w476-322c-wpvm: SQL injection in pdo_firebird via NUL bytes in quoted strings +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +exec('CREATE TABLE ghsa_w476_322c_wpvm (name VARCHAR(255))'); + +$param = $dbh->quote("\0"); +$param2 = $dbh->quote('or 1=1--'); +var_export($param); +echo("\n"); + +echo "prepare: "; +$stmt = $dbh->prepare("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}"); +$stmt->execute(); +echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n"; + +echo "query: "; +$stmt = $dbh->query("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}"); +echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n"; + +echo "exec: "; +$affectedRows = $dbh->exec("UPDATE ghsa_w476_322c_wpvm SET name = 'updated' WHERE name = {$param} AND name = {$param2}"); +echo $affectedRows . "\n"; +?> +--CLEAN-- +exec("DROP TABLE ghsa_w476_322c_wpvm"); +?> +--EXPECT-- +'\'' . "\0" . '\'' +prepare: [] +query: [] +exec: 0 diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 808f4acbfa37..54a8803971ca 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | diff --git a/ext/pdo_mysql/mysql_sql_parser.re b/ext/pdo_mysql/mysql_sql_parser.re index 01afbefaaa8d..9db54063889d 100644 --- a/ext/pdo_mysql/mysql_sql_parser.re +++ b/ext/pdo_mysql/mysql_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 8b2519ce90aa..f6b182fcb9ad 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c index b45dafbf5d98..fe5ebc7e6ed8 100644 --- a/ext/pdo_mysql/pdo_mysql.c +++ b/ext/pdo_mysql/pdo_mysql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Johannes Schlueter | diff --git a/ext/pdo_mysql/php_pdo_mysql.h b/ext/pdo_mysql/php_pdo_mysql.h index 650c51b497a2..55b2cded0f28 100644 --- a/ext/pdo_mysql/php_pdo_mysql.h +++ b/ext/pdo_mysql/php_pdo_mysql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index ec49d6c311c3..baba729aa53d 100644 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | diff --git a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt index d74e348fb99a..be7eb74b5b35 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt @@ -76,6 +76,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_subclass'); ?> --EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d __construct('%S', '%S', %s) Deprecated: Callables of the form ["MyPDO", "parent::__construct"] are deprecated in %s on line %d diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 7401023c573c..dbdb0066578b 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -95,6 +93,8 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { errmsgsize = 0; + } else if ((size_t) errmsgsize >= sizeof(einfo->last_err_msg)) { + errmsgsize = sizeof(einfo->last_err_msg) - 1; } einfo->last_err_msg[errmsgsize] = '\0'; @@ -550,9 +550,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(dbh->username) && php_odbc_connstr_should_quote(dbh->username); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->username); - uid = emalloc(estimated_length); - php_odbc_connstr_quote(uid, dbh->username, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->username); + uid = emalloc(quoted_length); + php_odbc_connstr_quote(uid, dbh->username, quoted_length); } else { uid = dbh->username; } @@ -567,9 +567,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(dbh->password) && php_odbc_connstr_should_quote(dbh->password); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->password); - pwd = emalloc(estimated_length); - php_odbc_connstr_quote(pwd, dbh->password, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->password); + pwd = emalloc(quoted_length); + php_odbc_connstr_quote(pwd, dbh->password, quoted_length); } else { pwd = dbh->password; } @@ -605,7 +605,11 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen, SQL_DRIVER_NOPROMPT); } if (!use_direct) { - rc = SQLConnect(H->dbc, (SQLCHAR *) dbh->data_source, SQL_NTS, (SQLCHAR *) dbh->username, SQL_NTS, (SQLCHAR *) dbh->password, SQL_NTS); + /* unixODBC pooling strcmp()s the credentials when matching a cached + * connection and crashes on a NULL username/password, so pass "". */ + rc = SQLConnect(H->dbc, (SQLCHAR *) dbh->data_source, SQL_NTS, + (SQLCHAR *) (dbh->username ? dbh->username : ""), SQL_NTS, + (SQLCHAR *) (dbh->password ? dbh->password : ""), SQL_NTS); } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 171fb7b7b1e9..b7772ec3ac34 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -135,6 +133,11 @@ static void free_cols(pdo_stmt_t *stmt, pdo_odbc_stmt *S) } } +static void odbc_free_out_buffer(zval *el) +{ + efree(Z_PTR_P(el)); +} + static int odbc_stmt_dtor(pdo_stmt_t *stmt) { pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; @@ -151,11 +154,41 @@ static int odbc_stmt_dtor(pdo_stmt_t *stmt) if (S->convbuf) { efree(S->convbuf); } + if (S->out_buffers) { + zend_hash_destroy(S->out_buffers); + FREE_HASHTABLE(S->out_buffers); + } efree(S); return 1; } +static bool odbc_bind_param(pdo_stmt_t *stmt, struct pdo_bound_param_data *param) +{ + pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; + pdo_odbc_param *P = (pdo_odbc_param*)param->driver_data; + RETCODE rc; + + if (!P) { + return true; + } + + rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1, + P->paramtype, P->ctype, P->sqltype, P->precision, P->scale, + P->paramtype == SQL_PARAM_INPUT ? + (SQLPOINTER)param : + P->outbuf, + P->outbuf ? P->outbuflen : 0, + &P->len + ); + + if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { + return true; + } + pdo_odbc_stmt_error("SQLBindParameter"); + return false; +} + static int odbc_stmt_execute(pdo_stmt_t *stmt) { RETCODE rc, rc1; @@ -167,6 +200,24 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt) SQLCloseCursor(S->stmt); } + if (S->params_dirty) { + rc = SQLFreeStmt(S->stmt, SQL_RESET_PARAMS); + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + pdo_odbc_stmt_error("SQLFreeStmt: SQL_RESET_PARAMS"); + return 0; + } + if (stmt->bound_params) { + struct pdo_bound_param_data *param; + + ZEND_HASH_FOREACH_PTR(stmt->bound_params, param) { + if (!odbc_bind_param(stmt, param)) { + return 0; + } + } ZEND_HASH_FOREACH_END(); + } + S->params_dirty = false; + } + rc = SQLExecute(S->stmt); while (rc == SQL_NEED_DATA) { @@ -310,6 +361,7 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p if (P) { efree(P); } + S->params_dirty = true; break; case PDO_PARAM_EVT_ALLOC: @@ -358,6 +410,7 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p param->driver_data = P; P->len = 0; /* is re-populated each EXEC_PRE */ + P->outbuflen = 0; P->outbuf = NULL; P->is_unicode = pdo_odbc_sqltype_is_unicode(S, sqltype); @@ -382,6 +435,12 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p P->len *= 2; } P->outbuf = emalloc(P->len + (P->is_unicode ? 2:1)); + P->outbuflen = P->len; + if (!S->out_buffers) { + ALLOC_HASHTABLE(S->out_buffers); + zend_hash_init(S->out_buffers, HT_MIN_SIZE, NULL, odbc_free_out_buffer, false); + } + zend_hash_next_index_insert_ptr(S->out_buffers, P->outbuf); } } @@ -390,20 +449,12 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p return 0; } - rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1, - P->paramtype, ctype, sqltype, precision, scale, - P->paramtype == SQL_PARAM_INPUT ? - (SQLPOINTER)param : - P->outbuf, - P->len, - &P->len - ); - - if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { - return 1; - } - pdo_odbc_stmt_error("SQLBindParameter"); - return 0; + P->sqltype = sqltype; + P->ctype = ctype; + P->precision = precision; + P->scale = scale; + S->params_dirty = true; + return 1; } case PDO_PARAM_EVT_EXEC_PRE: @@ -479,10 +530,16 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p case PDO_ODBC_CONV_FAIL: case PDO_ODBC_CONV_NOT_REQUIRED: P->len = Z_STRLEN_P(parameter); + if (P->len > P->outbuflen) { + P->len = P->outbuflen; + } memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len); break; case PDO_ODBC_CONV_OK: P->len = ulen; + if (P->len > P->outbuflen) { + P->len = P->outbuflen; + } memcpy(P->outbuf, S->convbuf, P->len); break; } @@ -504,6 +561,9 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p zval_ptr_dtor(parameter); if (P->len >= 0) { + if (P->len > P->outbuflen) { + P->len = P->outbuflen; + } ZVAL_STRINGL(parameter, P->outbuf, P->len); switch (pdo_odbc_ucs22utf8(P->is_unicode, parameter)) { case PDO_ODBC_CONV_FAIL: @@ -704,8 +764,9 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo } ssize_t to_fetch_byte = to_fetch_len + 1; char *buf2 = emalloc(to_fetch_byte); - zend_string *str = zend_string_init(C->data, to_fetch_byte, 0); - size_t used = to_fetch_len; + ssize_t seed_len = to_fetch_len > (LONG_COLUMN_BUFFER_SIZE - 1) ? (LONG_COLUMN_BUFFER_SIZE - 1) : to_fetch_len; + zend_string *str = zend_string_init(C->data, seed_len + 1, 0); + size_t used = seed_len; do { C->fetched_len = 0; @@ -728,7 +789,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo str = zend_string_realloc(str, used + to_fetch_byte, 0); memcpy(ZSTR_VAL(str) + used, buf2, to_fetch_byte); used = used + to_fetch_len; - } else if (rc==SQL_SUCCESS) { + } else if (rc == SQL_SUCCESS && C->fetched_len != 0) { str = zend_string_realloc(str, used + C->fetched_len, 0); memcpy(ZSTR_VAL(str) + used, buf2, C->fetched_len); used = used + C->fetched_len; @@ -762,7 +823,14 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo return 1; } else if (C->fetched_len >= 0) { /* it was stored perfectly */ - ZVAL_STRINGL_FAST(result, C->data, C->fetched_len); + SQLLEN data_len = C->fetched_len; + if (!C->is_long) { + SQLLEN max_len = C->is_unicode ? (SQLLEN)C->datalen + 1 : (SQLLEN)C->datalen; + if (data_len > max_len) { + data_len = max_len; + } + } + ZVAL_STRINGL_FAST(result, C->data, data_len); if (C->is_unicode) { goto unicode_conv; } diff --git a/ext/pdo_odbc/pdo_odbc.c b/ext/pdo_odbc/pdo_odbc.c index 1181e314c4d0..47a19062947c 100644 --- a/ext/pdo_odbc/pdo_odbc.c +++ b/ext/pdo_odbc/pdo_odbc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_odbc/php_pdo_odbc.h b/ext/pdo_odbc/php_pdo_odbc.h index 3f0417029784..6c72b6f2ebe9 100644 --- a/ext/pdo_odbc/php_pdo_odbc.h +++ b/ext/pdo_odbc/php_pdo_odbc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index 473d70ff7076..52d66abfba01 100644 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -145,15 +143,22 @@ typedef struct { pdo_odbc_errinfo einfo; char *convbuf; zend_ulong convbufsize; + HashTable *out_buffers; unsigned going_long:1; unsigned assume_utf8:1; + unsigned params_dirty:1; signed col_count:16; - unsigned _spare:14; + unsigned _spare:13; } pdo_odbc_stmt; typedef struct { SQLLEN len; + SQLLEN outbuflen; SQLSMALLINT paramtype; + SQLSMALLINT sqltype; + SQLSMALLINT ctype; + SQLSMALLINT scale; + SQLULEN precision; char *outbuf; unsigned is_unicode:1; unsigned _spare:31; diff --git a/ext/pdo_odbc/tests/bound_param_rebind.phpt b/ext/pdo_odbc/tests/bound_param_rebind.phpt new file mode 100644 index 000000000000..1ae9651f3a7d --- /dev/null +++ b/ext/pdo_odbc/tests/bound_param_rebind.phpt @@ -0,0 +1,28 @@ +--TEST-- +pdo_odbc: a bound parameter does not leave a stale ODBC binding on re-execute +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$stmt = $pdo->prepare('SELECT ? AS v'); +$v = 'bound'; +$stmt->bindParam(1, $v, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 256); +$stmt->execute(['from_array']); + +var_dump($stmt->fetch(PDO::FETCH_ASSOC)['v']); +?> +--EXPECT-- +string(10) "from_array" diff --git a/ext/pdo_odbc/tests/config.inc b/ext/pdo_odbc/tests/config.inc new file mode 100644 index 000000000000..185602bb7ed6 --- /dev/null +++ b/ext/pdo_odbc/tests/config.inc @@ -0,0 +1,3 @@ + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$db->exec('DROP TABLE test_gh22349'); +if (false === $db->exec('CREATE TABLE test_gh22349 (data text)') + && false === $db->exec('CREATE TABLE test_gh22349 (data CLOB)') + && false === $db->exec('CREATE TABLE test_gh22349 (data longtext)')) { + die("BORK: no large text column type available here: " . implode(", ", $db->errorInfo()) . "\n"); +} + +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +// The driver fetches a long column into an internal buffer of roughly one +// memory page and reassembles the remainder. Exercise values that span and +// exceed that buffer so the seeded length must match the bytes present. +foreach ([4096, 8192, 65536] as $len) { + $db->exec('DELETE FROM test_gh22349'); + $text = str_repeat('A', $len); + $db->exec("INSERT INTO test_gh22349 VALUES ('$text')"); + $got = $db->query('SELECT data FROM test_gh22349')->fetchColumn(); + printf("%d: %s\n", $len, ($got === $text) ? 'ok' : ('MISMATCH len=' . strlen($got))); +} +?> +--CLEAN-- +exec('DROP TABLE test_gh22349'); +?> +--EXPECT-- +4096: ok +8192: ok +65536: ok diff --git a/ext/pdo_odbc/tests/gh22665.phpt b/ext/pdo_odbc/tests/gh22665.phpt new file mode 100644 index 000000000000..d6edc62288e8 --- /dev/null +++ b/ext/pdo_odbc/tests/gh22665.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-22665 (OOB write in pdo_odbc_error when the driver reports a long message) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_SILENT, +]); + +// A failing query with a long identifier makes the driver report a diagnostic +// message length >= the fixed last_err_msg buffer. The terminator write must +// stay inside the buffer. +$pdo->query('SELECT * FROM "' . str_repeat('A', 4096) . '"'); +$info = $pdo->errorInfo(); + +echo "sqlstate: ", $info[0], "\n"; +echo "done\n"; +?> +--EXPECT-- +sqlstate: HY000 +done diff --git a/ext/pdo_odbc/tests/gh22666.phpt b/ext/pdo_odbc/tests/gh22666.phpt new file mode 100644 index 000000000000..b6ba2265b9be --- /dev/null +++ b/ext/pdo_odbc/tests/gh22666.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-22666 (Heap buffer overflow when an output param value exceeds its maxlen) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +prepare('SELECT ?'); +$stmt->bindParam(1, $value, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 4); +$stmt->execute(); + +echo "bounded to maxlen: "; var_dump($value); +?> +--EXPECT-- +bounded to maxlen: string(4) "AAAA" diff --git a/ext/pdo_odbc/tests/gh22667.phpt b/ext/pdo_odbc/tests/gh22667.phpt new file mode 100644 index 000000000000..bcbd715da20c --- /dev/null +++ b/ext/pdo_odbc/tests/gh22667.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-22667 (Heap buffer over-read when a column value exceeds the bound buffer) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +query("SELECT printf('%.*c', 4096, 'A') AS data"); +$row = $stmt->fetch(PDO::FETCH_ASSOC); +$s = $row['data']; + +echo "clamped to buffer: "; var_dump(strlen($s) < 4096); +echo "only value bytes: "; var_dump(strlen($s) === substr_count($s, 'A')); +?> +--EXPECT-- +clamped to buffer: bool(true) +only value bytes: bool(true) diff --git a/ext/pdo_odbc/tests/output_param_leak.phpt b/ext/pdo_odbc/tests/output_param_leak.phpt new file mode 100644 index 000000000000..f6d4aad5a8c6 --- /dev/null +++ b/ext/pdo_odbc/tests/output_param_leak.phpt @@ -0,0 +1,29 @@ +--TEST-- +pdo_odbc: bound output parameter buffer is released (no leak) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$stmt = $pdo->prepare('SELECT ? AS v'); +$var = 'seed'; +$stmt->bindParam(1, $var, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 256); +$stmt->execute(); +$row = $stmt->fetch(PDO::FETCH_ASSOC); + +var_dump($row['v']); +?> +--EXPECT-- +string(4) "seed" diff --git a/ext/pdo_pgsql/config.w32 b/ext/pdo_pgsql/config.w32 index 5fc25f215900..87ad0a661b53 100644 --- a/ext/pdo_pgsql/config.w32 +++ b/ext/pdo_pgsql/config.w32 @@ -7,6 +7,7 @@ if (PHP_PDO_PGSQL != "no") { CHECK_HEADER("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c pgsql_sql_parser.c"); + AC_DEFINE('HAVE_PG_RESULT_MEMORY_SIZE', 1, "Define to 1 if libpq has the 'PQresultMemorySize' function (PostgreSQL 12 or later)."); AC_DEFINE('HAVE_PDO_PGSQL', 1, "Define to 1 if the PHP extension 'pdo_pgsql' is available."); ADD_EXTENSION_DEP('pdo_pgsql', 'pdo'); diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index e6849aed1195..d552aa5e61dd 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index be429075c51a..8f5e22640ccc 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | @@ -716,6 +714,9 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS) if (Z_TYPE_P(pg_rows) == IS_ARRAY) { ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), tmp) { if (!_pdo_pgsql_send_copy_data(H, tmp)) { + if (EG(exception)) { + RETURN_THROWS(); + } pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; @@ -738,6 +739,9 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS) tmp = iter->funcs->get_current_data(iter); if (!_pdo_pgsql_send_copy_data(H, tmp)) { zend_iterator_dtor(iter); + if (EG(exception)) { + RETURN_THROWS(); + } pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; diff --git a/ext/pdo_pgsql/pgsql_sql_parser.re b/ext/pdo_pgsql/pgsql_sql_parser.re index caea615c4073..011fce56a1a0 100644 --- a/ext/pdo_pgsql/pgsql_sql_parser.re +++ b/ext/pdo_pgsql/pgsql_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 426a878d8eff..1620544556b6 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | @@ -573,6 +571,12 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, } S->result = PQgetResult(S->H->server); + if (!S->result) { + S->is_running_unbuffered = false; + stmt->row_count = 0; + S->current_row = 0; + return 0; + } status = PQresultStatus(S->result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && status != PGRES_SINGLE_TUPLE) { diff --git a/ext/pdo_pgsql/php_pdo_pgsql.h b/ext/pdo_pgsql/php_pdo_pgsql.h index fa28214f71a7..345535108cb1 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql.h +++ b/ext/pdo_pgsql/php_pdo_pgsql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 881b4e704650..47c9223540ad 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | diff --git a/ext/pdo_pgsql/tests/copy_from_array_non_stringable.phpt b/ext/pdo_pgsql/tests/copy_from_array_non_stringable.phpt new file mode 100644 index 000000000000..65edb30d6671 --- /dev/null +++ b/ext/pdo_pgsql/tests/copy_from_array_non_stringable.phpt @@ -0,0 +1,49 @@ +--TEST-- +PDO PgSQL pgsqlCopyFromArray()/copyFromArray() with a non-stringable row throws without polluting errorInfo +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$db->exec('CREATE TABLE test_copy_non_stringable (v text)'); + +try { + $db->pgsqlCopyFromArray('test_copy_non_stringable', [new stdClass()]); +} catch (\Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +var_dump($db->errorInfo()[0]); + +$pgsql = PDOTest::test_factory(__DIR__ . '/common.phpt', Pdo\Pgsql::class, true); +$pgsql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +try { + $pgsql->copyFromArray('test_copy_non_stringable', [new stdClass()]); +} catch (\Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +var_dump($pgsql->errorInfo()[0]); +?> +--CLEAN-- +query('DROP TABLE IF EXISTS test_copy_non_stringable CASCADE'); +?> +--EXPECTF-- +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d +Object of class stdClass could not be converted to string +string(5) "00000" +Object of class stdClass could not be converted to string +string(5) "00000" diff --git a/ext/pdo_pgsql/tests/gh21683.phpt b/ext/pdo_pgsql/tests/gh21683.phpt new file mode 100644 index 000000000000..bd941511767a --- /dev/null +++ b/ext/pdo_pgsql/tests/gh21683.phpt @@ -0,0 +1,48 @@ +--TEST-- +PDO PgSQL single-row mode (ATTR_PREFETCH=0) on empty result set +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$pdo->setAttribute(PDO::ATTR_PREFETCH, 0); + +$pdo->exec("CREATE TEMP TABLE empty_t (id int, val text)"); + +echo "=== query / fetch ===\n"; +$stmt = $pdo->query("SELECT * FROM empty_t"); +var_dump($stmt->fetch()); + +echo "=== prepare / fetchAll ===\n"; +$stmt = $pdo->prepare("SELECT * FROM empty_t"); +$stmt->execute(); +var_dump($stmt->fetchAll()); + +echo "=== connection still works ===\n"; +$stmt = $pdo->query("SELECT 1 AS alive"); +var_dump($stmt->fetch(PDO::FETCH_ASSOC)); + +echo "Done\n"; +?> +--EXPECT-- +=== query / fetch === +bool(false) +=== prepare / fetchAll === +array(0) { +} +=== connection still works === +array(1) { + ["alive"]=> + string(1) "1" +} +Done diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index 667948fea9f1..2da9329e2a04 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -205,7 +203,7 @@ static int php_pdosqlite3_stream_seek(php_stream *stream, zend_off_t offset, int switch(whence) { case SEEK_CUR: if (offset < 0) { - if (sqlite3_stream->position < (size_t)(-offset)) { + if (sqlite3_stream->position < -(size_t)offset) { sqlite3_stream->position = 0; *newoffs = -1; return -1; @@ -243,7 +241,7 @@ static int php_pdosqlite3_stream_seek(php_stream *stream, zend_off_t offset, int sqlite3_stream->position = sqlite3_stream->size; *newoffs = -1; return -1; - } else if (sqlite3_stream->size < (size_t)(-offset)) { + } else if (sqlite3_stream->size < -(size_t)offset) { sqlite3_stream->position = 0; *newoffs = -1; return -1; diff --git a/ext/pdo_sqlite/php_pdo_sqlite.h b/ext/pdo_sqlite/php_pdo_sqlite.h index c29a81ebb240..a567e8c87ee6 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite.h +++ b/ext/pdo_sqlite/php_pdo_sqlite.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_sqlite/php_pdo_sqlite_int.h b/ext/pdo_sqlite/php_pdo_sqlite_int.h index 0cb09cfaa4fb..122f714040de 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite_int.h +++ b/ext/pdo_sqlite/php_pdo_sqlite_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 5a30d27193ec..39efa02dd583 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_sqlite/sqlite_sql_parser.re b/ext/pdo_sqlite/sqlite_sql_parser.re index 5678e6025577..c836f6b2b499 100644 --- a/ext/pdo_sqlite/sqlite_sql_parser.re +++ b/ext/pdo_sqlite/sqlite_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c index ffb8c1ad4b3c..25c9e6917e43 100644 --- a/ext/pdo_sqlite/sqlite_statement.c +++ b/ext/pdo_sqlite/sqlite_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -278,8 +276,13 @@ static int pdo_sqlite_stmt_get_col( int64_t i = sqlite3_column_int64(S->stmt, colno); #if SIZEOF_ZEND_LONG < 8 if (i > ZEND_LONG_MAX || i < ZEND_LONG_MIN) { + const char *text = (const char *) sqlite3_column_text(S->stmt, colno); + if (UNEXPECTED(!text)) { + pdo_sqlite_error_stmt(stmt); + return 0; + } ZVAL_STRINGL(result, - (char *) sqlite3_column_text(S->stmt, colno), + text, sqlite3_column_bytes(S->stmt, colno)); return 1; } @@ -297,10 +300,15 @@ static int pdo_sqlite_stmt_get_col( sqlite3_column_blob(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno)); return 1; - default: - ZVAL_STRINGL_FAST(result, - (char *) sqlite3_column_text(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno)); + default: { + const char *text = (const char *) sqlite3_column_text(S->stmt, colno); + if (UNEXPECTED(!text)) { + pdo_sqlite_error_stmt(stmt); + return 0; + } + ZVAL_STRINGL_FAST(result, text, sqlite3_column_bytes(S->stmt, colno)); return 1; + } } } diff --git a/ext/pdo_sqlite/tests/bug38334.phpt b/ext/pdo_sqlite/tests/bug38334.phpt index b4e9a378d717..eefd997cc71a 100644 --- a/ext/pdo_sqlite/tests/bug38334.phpt +++ b/ext/pdo_sqlite/tests/bug38334.phpt @@ -7,11 +7,11 @@ pdo_sqlite $db = new PDO('sqlite::memory:'); $db->exec('CREATE TABLE test_38334 (i INTEGER , f DOUBLE, s VARCHAR(255))'); -$db->exec('INSERT INTO test_38334 VALUES (42, 46.7, "test")'); +$db->exec("INSERT INTO test_38334 VALUES (42, 46.7, 'test')"); var_dump($db->query('SELECT * FROM test_38334')->fetch(PDO::FETCH_ASSOC)); // Check handling of integers larger than 32-bit. -$db->exec('INSERT INTO test_38334 VALUES (10000000000, 0.0, "")'); +$db->exec("INSERT INTO test_38334 VALUES (10000000000, 0.0, '')"); $i = $db->query('SELECT i FROM test_38334 WHERE f = 0.0')->fetchColumn(0); if (PHP_INT_SIZE >= 8) { var_dump($i === 10000000000); @@ -20,8 +20,8 @@ if (PHP_INT_SIZE >= 8) { } // Check storing of strings into integer/float columns. -$db->exec('INSERT INTO test_38334 VALUES ("test", "test", "x")'); -var_dump($db->query('SELECT * FROM test_38334 WHERE s = "x"')->fetch(PDO::FETCH_ASSOC)); +$db->exec("INSERT INTO test_38334 VALUES ('test', 'test', 'x')"); +var_dump($db->query("SELECT * FROM test_38334 WHERE s = 'x'")->fetch(PDO::FETCH_ASSOC)); ?> --EXPECT-- diff --git a/ext/pdo_sqlite/tests/bug_42589.phpt b/ext/pdo_sqlite/tests/bug_42589.phpt index 46ded8d027a6..39b87b106521 100644 --- a/ext/pdo_sqlite/tests/bug_42589.phpt +++ b/ext/pdo_sqlite/tests/bug_42589.phpt @@ -15,7 +15,7 @@ if(!in_array('ENABLE_COLUMN_METADATA', $options, true)) $db = new PDO("sqlite::memory:"); $db->exec('CREATE TABLE test_42589 (field1 VARCHAR(10))'); -$db->exec('INSERT INTO test_42589 VALUES("test")'); +$db->exec("INSERT INTO test_42589 VALUES('test')"); $result = $db->query('SELECT * FROM test_42589 t1 LEFT JOIN test_42589 t2 ON t1.field1 = t2.field1'); $meta1 = $result->getColumnMeta(0); diff --git a/ext/pdo_sqlite/tests/gh20964.phpt b/ext/pdo_sqlite/tests/gh20964.phpt new file mode 100644 index 000000000000..65070cb1838a --- /dev/null +++ b/ext/pdo_sqlite/tests/gh20964.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20964 (fseek() on PDO SQLite blob stream with PHP_INT_MIN causes undefined behavior) +--EXTENSIONS-- +pdo_sqlite +--FILE-- +exec('CREATE TABLE test (id INTEGER PRIMARY KEY, data BLOB)'); +$db->exec("INSERT INTO test (id, data) VALUES (1, 'hello')"); + +$stream = $db->openBlob('test', 'data', 1); + +var_dump(fseek($stream, PHP_INT_MIN, SEEK_END)); + +rewind($stream); +var_dump(fseek($stream, PHP_INT_MIN, SEEK_CUR)); + +fclose($stream); +?> +--EXPECT-- +int(-1) +int(-1) diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt index 1a620d6b9d5f..cba2c49556f7 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt @@ -9,7 +9,7 @@ $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createaggregate (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->sqliteCreateAggregate('testing', function(&$a, $b) { $a .= $b; return $a; }, function(&$v) { return $v; }); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt index 14a2c2e0d023..eb5ea6c97b7d 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt @@ -10,7 +10,7 @@ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->query('CREATE TABLE test_pdo_sqlite_createcollation (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, "1"), (NULL, "2"), (NULL, "10")'); +$db->query("INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, '1'), (NULL, '2'), (NULL, '10')"); $db->sqliteCreateCollation('MYCOLLATE', function($a, $b) { return strnatcmp($a, $b); }); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt index b2cb073cb58f..49daabf5a7a9 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt @@ -9,7 +9,7 @@ $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createfunction (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt index 6f507789dbf2..fafa4f6bfa21 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt @@ -4,7 +4,7 @@ PDO_sqlite: Testing sqliteCreateFunction() with flags pdo_sqlite --SKIPIF-- = 3.8.3'); ?> --FILE-- query('CREATE TABLE test_pdo_sqlite_createfunction_with_flags (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt new file mode 100644 index 000000000000..8ae668428484 --- /dev/null +++ b/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt @@ -0,0 +1,27 @@ +--TEST-- +PDO_sqlite: Testing DQS support +--EXTENSIONS-- +pdo_sqlite +--SKIPIF-- +exec('SELECT "test"'); +} catch (\PDOException) { + die('skip SQLite is lacking DQS'); +} +?> +--FILE-- +exec('CREATE TABLE test (s1 VARCHAR(255), s2 VARCHAR(255))'); +$db->exec('INSERT INTO test VALUES (\'test\', "test")'); +var_dump($db->query('SELECT * FROM test')->fetch(PDO::FETCH_ASSOC)); +?> +--EXPECT-- +array(2) { + ["s1"]=> + string(4) "test" + ["s2"]=> + string(4) "test" +} diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt index 7e55ed60d5f1..0f1cba84dcce 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt @@ -7,7 +7,7 @@ pdo_sqlite $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_lastinsertid (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_lastinsertid VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_lastinsertid VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); var_dump($db->query('SELECT * FROM test_pdo_sqlite_lastinsertid')); var_dump($db->errorInfo()); var_dump($db->lastInsertId()); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt index d5eda8d9b827..c1eed6f3adc8 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt @@ -31,9 +31,8 @@ foreach ($queries as $k => $query) { // One parameter $queries = [ "SELECT * FROM {$table} WHERE '1' = ?", - "SELECT * FROM {$table} WHERE \"?\" IN (?, \"?\")", + "SELECT * FROM {$table} WHERE '?' IN (?, '?')", "SELECT * FROM {$table} WHERE `a``?` = ?", - "SELECT * FROM {$table} WHERE \"a`?\" = ?", "SELECT * FROM {$table} WHERE [a`?] = ?", ]; @@ -43,6 +42,22 @@ foreach ($queries as $k => $query) { var_dump($stmt->fetch(PDO::FETCH_NUM) === [0 => 1]); } +// Check if DQS are enabled. +$dqs = true; +try { + $db->exec('SELECT "test"'); +} catch (\PDOException) { + $dqs = false; +} + +if ($dqs) { + $stmt = $db->prepare("SELECT * FROM {$table} WHERE \"a`?\" = ?"); + $stmt->execute([1]); + var_dump($stmt->fetch(PDO::FETCH_NUM) === [0 => 1]); +} else { + var_dump(true); +} + ?> --CLEAN-- query('CREATE TABLE test_pdo_sqlite_transaction (id INT AUTO INCREMENT, nam $db->commit(); $db->beginTransaction(); -$db->query('INSERT INTO test_pdo_sqlite_transaction VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_transaction VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->rollback(); $r = $db->query('SELECT COUNT(*) FROM test_pdo_sqlite_transaction'); diff --git a/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt b/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt index e8e0b34141c7..f7aa61206f6f 100644 --- a/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt +++ b/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt @@ -2,6 +2,10 @@ PDO_sqlite: PHP 8.5 deprecations --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- = 3.8.3'); +?> --FILE-- createFunction('strtoupper', [new TrampolineTest(), 'strtoupper'])); -foreach ($db->query('SELECT strtoupper("test")') as $row) { +foreach ($db->query("SELECT strtoupper('test')") as $row) { var_dump($row); } -foreach ($db->query('SELECT strtoupper("test")') as $row) { +foreach ($db->query("SELECT strtoupper('test')") as $row) { var_dump($row); } @@ -33,14 +33,14 @@ foreach ($db->query('SELECT strtoupper("test")') as $row) { bool(true) Trampoline for strtoupper array(2) { - ["strtoupper("test")"]=> + ["strtoupper('test')"]=> string(4) "TEST" [0]=> string(4) "TEST" } Trampoline for strtoupper array(2) { - ["strtoupper("test")"]=> + ["strtoupper('test')"]=> string(4) "TEST" [0]=> string(4) "TEST" diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt index 1f96da8e1fa3..af04daaec7fa 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt @@ -10,7 +10,7 @@ $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createaggregate (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->createAggregate('testing', function(&$a, $b) { $a .= $b; return $a; }, function(&$v) { return $v; }); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt index d043dda7a526..4ba37ec6aa6e 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt @@ -11,7 +11,7 @@ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->query('CREATE TABLE test_pdo_sqlite_createcollation (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, "1"), (NULL, "2"), (NULL, "10")'); +$db->query("INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, '1'), (NULL, '2'), (NULL, '10')"); $db->createCollation('MYCOLLATE', function($a, $b) { return strnatcmp($a, $b); }); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt index 1635fd700771..7f2b309ebf4c 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt @@ -9,7 +9,7 @@ $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createcollation_trampoline (s VARCHAR(4))'); -$stmt = $db->query('INSERT INTO test_pdo_sqlite_createcollation_trampoline VALUES ("a1"), ("a10"), ("a2")'); +$stmt = $db->query("INSERT INTO test_pdo_sqlite_createcollation_trampoline VALUES ('a1'), ('a10'), ('a2')"); class TrampolineTest { public function __call(string $name, array $arguments) { diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt index c828817d2c3a..07359a69bc4c 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt @@ -4,14 +4,14 @@ PDO_sqlite: Testing createFunction() with flags pdo_sqlite --SKIPIF-- = 3.8.3'); ?> --FILE-- query('CREATE TABLE test_pdo_sqlite_createfunction_with_flags (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt index 230fb7390ae5..c1f82e96c07b 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt @@ -8,7 +8,7 @@ pdo_sqlite $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_busy (a string);'); -$db->query('INSERT INTO test_busy VALUES ("interleaved"), ("statements")'); +$db->query("INSERT INTO test_busy VALUES ('interleaved'), ('statements')"); $st = $db->prepare('SELECT a FROM test_busy'); var_dump($st->getAttribute(Pdo\Sqlite::ATTR_BUSY_STATEMENT)); $st->execute(); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt index 383457f3a79e..d2a6c2a5f52b 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt @@ -13,7 +13,7 @@ if (!defined('Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN')) die('skip system sqlite does n $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_explain (a string);'); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN); var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT) == Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN); $r = $stmt->execute(); @@ -24,7 +24,7 @@ var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT) == Pdo\Sqlite:: $r = $stmts->execute(); var_dump($stmts->fetchAll(PDO::FETCH_ASSOC)); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_PREPARED); $stmt->execute(); $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_PREPARED); @@ -88,7 +88,7 @@ array(%d) { ["opcode"]=> string(13) "InitCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -109,7 +109,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -126,7 +126,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -147,7 +147,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -164,7 +164,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -183,7 +183,7 @@ array(%d) { ["opcode"]=> string(12) "EndCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -221,7 +221,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -242,7 +242,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(1) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -259,11 +259,11 @@ array(%d) { ["opcode"]=> string(10) "MakeRecord" ["p1"]=> - int(2) + int(%d) ["p2"]=> int(1) ["p3"]=> - int(4) + int(%d) ["p4"]=> string(1) "C" ["p5"]=> @@ -280,9 +280,9 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(4) + int(%d) ["p3"]=> - int(1) + int(%d) ["p4"]=> string(12) "test_explain" ["p5"]=> diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt index ea88a6316b64..40ec0a7799f0 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt @@ -2,6 +2,10 @@ Pdo\Sqlite basic --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- query('CREATE TABLE pdosqlite_001 (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO pdosqlite_001 VALUES (NULL, "PHP")'); -$db->query('INSERT INTO pdosqlite_001 VALUES (NULL, "PHP6")'); +$db->query("INSERT INTO pdosqlite_001 VALUES (NULL, 'PHP')"); +$db->query("INSERT INTO pdosqlite_001 VALUES (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt index 28534f4a2365..fddf2138f84e 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt @@ -2,6 +2,10 @@ Pdo\Sqlite create through PDO::connect and function define. --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- query('CREATE TABLE pdosqlite_002 (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO pdosqlite_002 VALUES (NULL, "PHP")'); -$db->query('INSERT INTO pdosqlite_002 VALUES (NULL, "PHP6")'); +$db->query("INSERT INTO pdosqlite_002 VALUES (NULL, 'PHP')"); +$db->query("INSERT INTO pdosqlite_002 VALUES (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index 1409f879b52c..63e996fe06da 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -38,7 +38,7 @@ if test "$PHP_PGSQL" != "no"; then old_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $PGSQL_CFLAGS" - AC_CHECK_DECLS([PGRES_TUPLES_CHUNK], + AC_CHECK_DECL([PGRES_TUPLES_CHUNK], PHP_CHECK_LIBRARY([pq], [PQsetChunkedRowsMode], [AC_DEFINE([HAVE_PG_SET_CHUNKED_ROWS_SIZE], [1], [Define to 1 if libpq has the 'PQsetChunkedRowsMode' function (PostgreSQL diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index 14eb5a07a0e9..4c8d6f3bd715 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -6,6 +6,7 @@ if (PHP_PGSQL != "no") { if (CHECK_LIB("libpq.lib", "pgsql", PHP_PGSQL) && CHECK_HEADER("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { EXTENSION("pgsql", "pgsql.c", PHP_PGSQL_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + AC_DEFINE('HAVE_PG_RESULT_MEMORY_SIZE', 1, "Define to 1 if libpq has the 'PQresultMemorySize' function (PostgreSQL 12 or later)."); AC_DEFINE('HAVE_PGSQL', 1, "Define to 1 if the PHP extension 'pgsql' is available."); ADD_FLAG("CFLAGS_PGSQL", "/D PGSQL_EXPORTS"); ADD_EXTENSION_DEP('pgsql', 'pcre'); diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index f50bc680c4b9..0ea766c12b42 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Zeev Suraski | | Jouni Ahto | @@ -153,9 +151,7 @@ static int le_plink; static zend_class_entry *pgsql_link_ce, *pgsql_result_ce, *pgsql_lob_ce; static zend_object_handlers pgsql_link_object_handlers, pgsql_result_object_handlers, pgsql_lob_object_handlers; -static inline pgsql_link_handle *pgsql_link_from_obj(zend_object *obj) { - return (pgsql_link_handle *)((char *)(obj) - XtOffsetOf(pgsql_link_handle, std)); -} +#define pgsql_link_from_obj(obj) ZEND_CONTAINER_OF(obj, pgsql_link_handle, std) #define Z_PGSQL_LINK_P(zv) pgsql_link_from_obj(Z_OBJ_P(zv)) @@ -209,9 +205,7 @@ static void pgsql_link_free_obj(zend_object *obj) zend_object_std_dtor(&link->std); } -static inline pgsql_result_handle *pgsql_result_from_obj(zend_object *obj) { - return (pgsql_result_handle *)((char *)(obj) - XtOffsetOf(pgsql_result_handle, std)); -} +#define pgsql_result_from_obj(obj) ZEND_CONTAINER_OF(obj, pgsql_result_handle, std) #define Z_PGSQL_RESULT_P(zv) pgsql_result_from_obj(Z_OBJ_P(zv)) @@ -246,9 +240,7 @@ static void pgsql_result_free_obj(zend_object *obj) zend_object_std_dtor(&pg_result->std); } -static inline pgLofp *pgsql_lob_from_obj(zend_object *obj) { - return (pgLofp *)((char *)(obj) - XtOffsetOf(pgLofp, std)); -} +#define pgsql_lob_from_obj(obj) ZEND_CONTAINER_OF(obj, pgLofp, std) #define Z_PGSQL_LOB_P(zv) pgsql_lob_from_obj(Z_OBJ_P(zv)) @@ -576,7 +568,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_link_ce->default_object_handlers = &pgsql_link_object_handlers; memcpy(&pgsql_link_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_link_object_handlers.offset = XtOffsetOf(pgsql_link_handle, std); + pgsql_link_object_handlers.offset = offsetof(pgsql_link_handle, std); pgsql_link_object_handlers.free_obj = pgsql_link_free_obj; pgsql_link_object_handlers.get_constructor = pgsql_link_get_constructor; pgsql_link_object_handlers.clone_obj = NULL; @@ -587,7 +579,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_result_ce->default_object_handlers = &pgsql_result_object_handlers; memcpy(&pgsql_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_result_object_handlers.offset = XtOffsetOf(pgsql_result_handle, std); + pgsql_result_object_handlers.offset = offsetof(pgsql_result_handle, std); pgsql_result_object_handlers.free_obj = pgsql_result_free_obj; pgsql_result_object_handlers.get_constructor = pgsql_result_get_constructor; pgsql_result_object_handlers.clone_obj = NULL; @@ -598,7 +590,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_lob_ce->default_object_handlers = &pgsql_lob_object_handlers; memcpy(&pgsql_lob_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_lob_object_handlers.offset = XtOffsetOf(pgLofp, std); + pgsql_lob_object_handlers.offset = offsetof(pgLofp, std); pgsql_lob_object_handlers.free_obj = pgsql_lob_free_obj; pgsql_lob_object_handlers.get_constructor = pgsql_lob_get_constructor; pgsql_lob_object_handlers.clone_obj = NULL; @@ -1013,7 +1005,7 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type break; } #endif - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (result) { RETURN_STRING(result); @@ -1212,7 +1204,6 @@ PHP_FUNCTION(pg_query) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1231,7 +1222,7 @@ PHP_FUNCTION(pg_query) /* The char pointer MUST refer to the char* of a zend_string struct */ static void php_pgsql_zend_string_release_from_char_pointer(char *ptr) { - zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val))); + zend_string_release((zend_string*) (ptr - offsetof(zend_string, val))); } static void _php_pgsql_free_params(char **params, uint32_t num_params) @@ -1351,7 +1342,6 @@ PHP_FUNCTION(pg_query_params) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1437,7 +1427,6 @@ PHP_FUNCTION(pg_prepare) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1536,7 +1525,6 @@ PHP_FUNCTION(pg_execute) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1582,7 +1570,7 @@ static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_ty case PHP_PG_CMD_TUPLES: RETVAL_LONG(atoi(PQcmdTuples(pgsql_result))); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1648,7 +1636,6 @@ PHP_FUNCTION(pg_last_notice) zend_hash_clean(notices); } RETURN_TRUE; - break; default: zend_argument_value_error(2, "must be one of PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR"); RETURN_THROWS(); @@ -1814,19 +1801,15 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ switch (entry_type) { case PHP_PG_FIELD_NAME: RETURN_STRING(PQfname(pgsql_result, (int)field)); - break; case PHP_PG_FIELD_SIZE: RETURN_LONG(PQfsize(pgsql_result, (int)field)); - break; case PHP_PG_FIELD_TYPE: RETURN_STR(get_field_name(pg_result->conn, PQftype(pgsql_result, (int)field))); - break; case PHP_PG_FIELD_TYPE_OID: oid = PQftype(pgsql_result, (int)field); PGSQL_RETURN_OID(oid); - break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2140,26 +2123,17 @@ PHP_FUNCTION(pg_fetch_object) ce = zend_standard_class_def; } - if (!ce->constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0) { - zend_argument_value_error(3, - "must be empty when the specified class (%s) does not have a constructor", - ZSTR_VAL(ce->name) - ); + if (UNEXPECTED(object_init_ex(return_value, ce) == FAILURE)) { RETURN_THROWS(); } zval dataset; if (UNEXPECTED(!php_pgsql_fetch_hash(&dataset, result, row, row_is_null, PGSQL_ASSOC))) { /* Either an exception is thrown, or we return false */ + zval_ptr_dtor(return_value); RETURN_FALSE; } - // TODO: Check CE is an instantiable class earlier? - zend_result obj_initialized = object_init_ex(return_value, ce); - if (UNEXPECTED(obj_initialized == FAILURE)) { - zval_ptr_dtor(&dataset); - RETURN_THROWS(); - } if (!ce->default_properties_count && !ce->__set) { Z_OBJ_P(return_value)->properties = Z_ARR(dataset); } else { @@ -2167,10 +2141,32 @@ PHP_FUNCTION(pg_fetch_object) zval_ptr_dtor(&dataset); } - // TODO: Need to grab constructor via object handler as this allows instantiating internal objects with overridden get_constructor - if (ce->constructor) { - zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value), + zend_object *obj = Z_OBJ_P(return_value); + const zend_class_entry *old = EG(fake_scope); + EG(fake_scope) = ce; + zend_function *constructor = obj->handlers->get_constructor(obj); + EG(fake_scope) = old; + + if (UNEXPECTED(EG(exception))) { + /* visibility error or override refused - VM dtors return_value */ + return; + } + + if (UNEXPECTED(!constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0)) { + zend_argument_value_error(4, + "must be empty when the specified class (%s) does not have a constructor", + ZSTR_VAL(ce->name) + ); + RETURN_THROWS(); + } + + if (constructor) { + zend_call_known_function(constructor, obj, ce, /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params); + if (EG(exception)) { + zend_object_store_ctor_failed(obj); + RETURN_THROWS(); + } } } /* }}} */ @@ -2357,7 +2353,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type, bo case PHP_PG_DATA_ISNULL: RETVAL_LONG(PQgetisnull(pgsql_result, pgsql_row, field_offset)); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -3405,7 +3401,6 @@ PHP_FUNCTION(pg_copy_to) case -2: PHP_PQ_ERROR("getline failed: %s", pgsql); RETURN_FALSE; - break; default: add_next_index_string(return_value, csv); PQfreemem(csv); @@ -3424,7 +3419,6 @@ PHP_FUNCTION(pg_copy_to) PQclear(pgsql_result); PHP_PQ_ERROR("Copy command failed: %s", pgsql); RETURN_FALSE; - break; } } /* }}} */ @@ -3440,7 +3434,7 @@ static zend_result pgsql_copy_from_query(PGconn *pgsql, PGresult *pgsql_result, int result; if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(tmp)[ZSTR_LEN(tmp) - 1] != '\n') { char *zquery = emalloc(ZSTR_LEN(tmp) + 2); - memcpy(zquery, ZSTR_VAL(tmp), ZSTR_LEN(tmp) + 1); + memcpy(zquery, ZSTR_VAL(tmp), ZSTR_LEN(tmp)); zquery[ZSTR_LEN(tmp)] = '\n'; zquery[ZSTR_LEN(tmp) + 1] = '\0'; result = PQputCopyData(pgsql, zquery, ZSTR_LEN(tmp) + 1); @@ -3555,12 +3549,10 @@ PHP_FUNCTION(pg_copy_from) RETURN_FALSE; } RETURN_TRUE; - break; default: PQclear(pgsql_result); PHP_PQ_ERROR("Copy command failed: %s", pgsql); RETURN_FALSE; - break; } } /* }}} */ @@ -3934,7 +3926,7 @@ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) PQfreeCancel(c); break; } - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); @@ -4545,8 +4537,8 @@ PHP_FUNCTION(pg_flush) } switch (ret) { - case 0: RETURN_TRUE; break; - case 1: RETURN_LONG(0); break; + case 0: RETURN_TRUE; + case 1: RETURN_LONG(0); default: RETURN_FALSE; } } @@ -5797,7 +5789,6 @@ PHP_FUNCTION(pg_insert) PHP_PQ_ERROR("Query failed: %s", pg_link); PQclear(pg_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pg_result) { diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 7a5770cb5936..a865a7ce73a4 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Zeev Suraski | | Jouni Ahto | diff --git a/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt new file mode 100644 index 000000000000..bd3df73acba4 --- /dev/null +++ b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt @@ -0,0 +1,69 @@ +--TEST-- +pg_fetch_object() constructor handling: ctor_params validation, throwing constructor, property visibility +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- +num}, str={$this->str}\n"; + } + public function __destruct() { + echo "SeesProps::__destruct called\n"; + } +} + +$table_name = "pg_fetch_object_ctor_paths"; +$db = pg_connect($conn_str); +pg_query($db, "CREATE TABLE {$table_name} (num int, str text)"); +pg_query($db, "INSERT INTO {$table_name} VALUES(1, 'hello')"); + +$sql = "SELECT * FROM {$table_name} WHERE num = 1"; + +// 1) ctor_params on a class with no constructor must throw ValueError +try { + pg_fetch_object(pg_query($db, $sql), null, 'NoCtor', [1, 2]); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +// 2) Constructor that throws: __destruct must NOT run on the partially constructed object +try { + pg_fetch_object(pg_query($db, $sql), null, 'ThrowingCtor'); +} catch (RuntimeException $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// 3) Constructor sees row properties already merged onto $this +$obj = pg_fetch_object(pg_query($db, $sql), null, 'SeesProps'); +unset($obj); + +echo "Ok\n"; +?> +--CLEAN-- + +--EXPECT-- +pg_fetch_object(): Argument #4 ($constructor_args) must be empty when the specified class (NoCtor) does not have a constructor +caught: boom +ctor sees: num=1, str=hello +SeesProps::__destruct called +Ok diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index f37599e7db11..1e41b2d0801d 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar:// stream wrapper support | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -21,8 +19,6 @@ #include "phar_internal.h" #include "dirstream.h" -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_dir); - static const php_stream_ops phar_dir_ops = { phar_dir_write, /* write */ phar_dir_read, /* read */ @@ -153,12 +149,12 @@ static int phar_compare_dir_name(Bucket *f, Bucket *s) /* {{{ */ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const HashTable *manifest) /* {{{ */ { HashTable *data; - char *entry; + const char *entry; ALLOC_HASHTABLE(data); zend_hash_init(data, 64, NULL, NULL, 0); - if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || (dirlen >= sizeof(".phar")-1 && !memcmp(dir, ".phar", sizeof(".phar")-1))) { + if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || phar_path_is_magic_phar_ex(dir, dirlen)) { /* make empty root directory for empty phar */ /* make empty directory for .phar magic directory */ return php_stream_alloc(&phar_dir_ops, data, NULL, "r"); @@ -175,7 +171,7 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has if (*dir == '/') { /* root directory */ - if (zend_string_starts_with_literal(str_key, ".phar")) { + if (phar_is_magic_phar(str_key)) { /* do not add any magic entries to this directory */ continue; } @@ -185,9 +181,7 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has /* the entry has a path separator and is a subdirectory */ keylen = has_slash - ZSTR_VAL(str_key); } - entry = safe_emalloc(keylen, 1, 1); - memcpy(entry, ZSTR_VAL(str_key), keylen); - entry[keylen] = '\0'; + entry = ZSTR_VAL(str_key); } else { if (0 != memcmp(ZSTR_VAL(str_key), dir, dirlen)) { /* entry in directory not found */ @@ -205,16 +199,12 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has if (has_slash) { /* is subdirectory */ save -= dirlen + 1; - entry = safe_emalloc(has_slash - save + dirlen, 1, 1); - memcpy(entry, save + dirlen + 1, has_slash - save - dirlen - 1); keylen = has_slash - save - dirlen - 1; - entry[keylen] = '\0'; + entry = save + dirlen + 1; } else { /* is file */ save -= dirlen + 1; - entry = safe_emalloc(keylen - dirlen, 1, 1); - memcpy(entry, save + dirlen + 1, keylen - dirlen - 1); - entry[keylen - dirlen - 1] = '\0'; + entry = save + dirlen + 1; keylen = keylen - dirlen - 1; } } @@ -231,8 +221,6 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has ZVAL_NULL(&dummy); zend_hash_str_update(data, entry, keylen, &dummy); } - - efree(entry); } ZEND_HASH_FOREACH_END(); if (FAILURE != zend_hash_has_more_elements(data)) { @@ -249,50 +237,52 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has */ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */ { - php_url *resource = NULL; char *error; - phar_archive_data *phar; - if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { - php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path); + php_url *resource = phar_parse_url(wrapper, context, path, mode, options); + if (resource == NULL) { + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar url \"%s\" is unknown", path); return NULL; } /* we must have at the very least phar://alias.phar/ */ if (!resource->scheme || !resource->host || !resource->path) { if (resource->host && !resource->path) { - php_stream_wrapper_log_error(wrapper, options, "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", path, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidPath, + "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", + path, ZSTR_VAL(resource->host)); php_url_free(resource); return NULL; } php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\", must have at least phar://%s/", path, path); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url \"%s\", must have at least phar://%s/", path, path); return NULL; } if (!zend_string_equals_literal_ci(resource->scheme, "phar")) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar url \"%s\"", path); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: not a phar url \"%s\"", path); return NULL; } phar_request_initialize(); - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + const phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { if (error) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, "%s", error); efree(error); } else { - php_stream_wrapper_log_error(wrapper, options, "phar file \"%s\" is unknown", ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "phar file \"%s\" is unknown", ZSTR_VAL(resource->host)); } php_url_free(resource); return NULL; } - if (error) { - efree(error); - } - if (zend_string_equals(resource->path, ZSTR_CHAR('/'))) { /* root directory requested */ php_url_free(resource); @@ -306,7 +296,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ size_t internal_file_len = ZSTR_LEN(resource->path) - 1; - phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + const phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); php_stream *ret; if (NULL != entry && !entry->is_dir) { @@ -345,66 +335,75 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, */ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mode, int options, php_stream_context *context) /* {{{ */ { - phar_entry_info entry, *e; - phar_archive_data *phar = NULL; - char *error, *arch; - size_t arch_len; + phar_entry_info entry; + char *error; php_url *resource = NULL; /* pre-readonly check, we need to know if this is a data phar */ - if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, NULL, NULL, 2, 2)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", no phar archive specified", url_from); + zend_string *arch = phar_split_fname(url_from, strlen(url_from), NULL, 2, 2); + if (!arch) { + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "phar error: cannot create directory \"%s\", no phar archive specified", url_from); return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - phar = NULL; - } + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); - efree(arch); + zend_string_release_ex(arch, false); if (PHAR_G(readonly) && (!phar || !phar->is_data)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", write operations disabled", url_from); + php_stream_wrapper_log_warn(wrapper, context, options, Readonly, + "phar error: cannot create directory \"%s\", write operations disabled", url_from); return 0; } - if ((resource = phar_parse_url(wrapper, url_from, "w", options)) == NULL) { + if ((resource = phar_parse_url(wrapper, context, url_from, "w", options)) == NULL) { return 0; } /* we must have at the very least phar://alias.phar/internalfile.php */ if (!resource->scheme || !resource->host || !resource->path) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", url_from); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url \"%s\"", url_from); return 0; } if (!zend_string_equals_literal_ci(resource->scheme, "phar")) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", url_from); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: not a phar stream url \"%s\"", url_from); return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { + php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed, + "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", + ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); return 0; } - if ((e = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 2, &error, true))) { + phar_entry_info *e = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 2, &error, true); + if (e) { /* directory exists, or is a subdirectory of an existing file */ if (e->is_temp_dir) { zend_string_efree(e->filename); efree(e); } - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", directory already exists", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, AlreadyExists, + "phar error: cannot create directory \"%s\" in phar \"%s\", directory already exists", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); php_url_free(resource); return 0; } if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); + php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed, + "phar error: cannot create directory \"%s\" in phar \"%s\", %s", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); return 0; @@ -412,13 +411,17 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo if (phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 0, &error, true)) { /* entry exists as a file */ - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", file already exists", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, AlreadyExists, + "phar error: cannot create directory \"%s\" in phar \"%s\", file already exists", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); php_url_free(resource); return 0; } if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); + php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed, + "phar error: cannot create directory \"%s\" in phar \"%s\", %s", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); return 0; @@ -447,7 +450,9 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo entry.old_flags = PHAR_ENT_PERM_DEF_DIR; if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", ZSTR_VAL(entry.filename), phar->fname); + php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed, + "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", + ZSTR_VAL(entry.filename), ZSTR_VAL(phar->fname)); zend_string_efree(entry.filename); return 0; } @@ -455,7 +460,9 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo phar_flush(phar, &error); if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry.filename), phar->fname, error); + php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed, + "phar error: cannot create directory \"%s\" in phar \"%s\", %s", + ZSTR_VAL(entry.filename), ZSTR_VAL(phar->fname), error); zend_hash_del(&phar->manifest, entry.filename); efree(error); return 0; @@ -471,48 +478,51 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo */ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) /* {{{ */ { - phar_entry_info *entry; - phar_archive_data *phar = NULL; - char *error, *arch; - size_t arch_len; - php_url *resource = NULL; + char *error; /* pre-readonly check, we need to know if this is a data phar */ - if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, NULL, NULL, 2, 2)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url); + zend_string *arch = phar_split_fname(url, strlen(url), NULL, 2, 2); + if (!arch) { + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url); return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - phar = NULL; - } + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); - efree(arch); + zend_string_release_ex(arch, false); if (PHAR_G(readonly) && (!phar || !phar->is_data)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot rmdir directory \"%s\", write operations disabled", url); + php_stream_wrapper_log_warn(wrapper, context, options, Readonly, + "phar error: cannot rmdir directory \"%s\", write operations disabled", url); return 0; } - if ((resource = phar_parse_url(wrapper, url, "w", options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, context, url, "w", options); + if (!resource) { return 0; } /* we must have at the very least phar://alias.phar/internalfile.php */ if (!resource->scheme || !resource->host || !resource->path) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", url); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url \"%s\"", url); return 0; } if (!zend_string_equals_literal_ci(resource->scheme, "phar")) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", url); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: not a phar stream url \"%s\"", url); return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { + php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed, + "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); return 0; @@ -520,12 +530,17 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options size_t path_len = ZSTR_LEN(resource->path) - 1; - if (!(entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, true))) { + phar_entry_info *entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, true); + if (!entry) { if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); + php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed, + "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); } else { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", directory does not exist", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "phar error: cannot remove directory \"%s\" in phar \"%s\", directory does not exist", + ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); } php_url_free(resource); return 0; @@ -539,7 +554,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource->path)+1, path_len) && IS_SLASH(ZSTR_VAL(str_key)[path_len]) ) { - php_stream_wrapper_log_error(wrapper, options, "phar error: Directory not empty"); + php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed, + "phar error: Directory not empty"); if (entry->is_temp_dir) { zend_string_efree(entry->filename); efree(entry); @@ -555,7 +571,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource->path)+1, path_len) && IS_SLASH(ZSTR_VAL(str_key)[path_len]) ) { - php_stream_wrapper_log_error(wrapper, options, "phar error: Directory not empty"); + php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed, + "phar error: Directory not empty"); if (entry->is_temp_dir) { zend_string_efree(entry->filename); efree(entry); @@ -576,7 +593,9 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options phar_flush(phar, &error); if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry->filename), phar->fname, error); + php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed, + "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", + ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname), error); php_url_free(resource); efree(error); return 0; diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index 4debfecde41a..179150229e3e 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -24,7 +22,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options #ifdef PHAR_DIRSTREAM #include "ext/standard/url.h" -php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); +php_url* phar_parse_url(php_stream_wrapper *wrapper, php_stream_context *context, const char *filename, const char *mode, int options); /* directory handlers */ static ssize_t phar_dir_write(php_stream *stream, const char *buf, size_t count); diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 5d5242e59009..f6e69f20035c 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ @@ -40,8 +38,6 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -50,24 +46,23 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { php_stream_context *context = NULL; php_stream *stream; char *name; - entry = estrndup(filename, filename_len); /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - entry = phar_fix_filepath(entry, &entry_len, 1); + zend_string *entry = phar_fix_filepath(filename, filename_len, true); - if (entry[0] == '/') { - spprintf(&name, 4096, "phar://%s%s", arch, entry); + if (ZSTR_VAL(entry)[0] == '/') { + spprintf(&name, 4096, "phar://%s%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } else { - spprintf(&name, 4096, "phar://%s/%s", arch, entry); + spprintf(&name, 4096, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); if (zcontext) { context = php_stream_context_from_zval(zcontext, 0); } @@ -88,8 +83,6 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool using_include_path) { - char *arch; - size_t arch_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -98,56 +91,56 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool return NULL; } - if (FAILURE == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (!arch) { return NULL; } /* fopen within phar, if :// is not in the url, then prepend phar:/// */ /* retrieving a file defaults to within the current directory, so use this if possible */ - phar_archive_data *phar; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + if (!phar) { + zend_string_release_ex(arch, false); return NULL; } zend_string *name = NULL; if (using_include_path) { - if (!(name = phar_find_in_include_path(filename, NULL))) { + name = phar_find_in_include_path(filename); + if (!name) { /* this file is not in the phar, use the original path */ - efree(arch); + zend_string_release_ex(arch, false); return NULL; } } else { - size_t entry_len = ZSTR_LEN(filename); - char *entry = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &entry_len, 1); - if (entry[0] == '/') { - if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) { - /* this file is not in the phar, use the original path */ -notfound: - efree(entry); - efree(arch); - return NULL; - } + zend_string *entry = phar_fix_filepath(ZSTR_VAL(filename), ZSTR_LEN(filename), true); + bool is_in_phar; + if (ZSTR_VAL(entry)[0] == '/') { + is_in_phar = zend_hash_str_exists(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) { - goto notfound; - } + is_in_phar = zend_hash_exists(&(phar->manifest), entry); + } + /* this file is not in the phar, use the original path */ + if (!is_in_phar) { + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); + return NULL; } /* auto-convert to phar:// */ - if (entry[0] == '/') { - ZEND_ASSERT(strlen("phar://") + arch_len + entry_len < 4096); + if (ZSTR_VAL(entry)[0] == '/') { + ZEND_ASSERT(strlen("phar://") + ZSTR_LEN(arch) + ZSTR_LEN(entry) < 4096); name = zend_string_concat3( "phar://", strlen("phar://"), - arch, arch_len, - entry, entry_len + ZSTR_VAL(arch), ZSTR_LEN(arch), + ZSTR_VAL(entry), ZSTR_LEN(entry) ); } else { - name = strpprintf(4096, "phar://%s/%s", arch, entry); + name = strpprintf(4096, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } - efree(entry); + zend_string_release_ex(entry, false); } - efree(arch); + zend_string_release_ex(arch, false); return name; } @@ -330,10 +323,6 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev, stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks; int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ - char *stat_sb_names[13] = { - "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", - "size", "atime", "mtime", "ctime", "blksize", "blocks" - }; if (type >= FS_IS_W && type <= FS_IS_X) { if(stat_sb->st_uid==getuid()) { @@ -345,15 +334,12 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) wmask=S_IWGRP; xmask=S_IXGRP; } else { - int groups, n, i; - gid_t *gids; - - groups = getgroups(0, NULL); - if(groups > 0) { - gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0); - n=getgroups(groups, gids); - for(i=0;ist_gid==gids[i]) { + int groups = getgroups(0, NULL); + if (groups > 0) { + gid_t *gids = safe_emalloc(groups, sizeof(gid_t), 0); + int n = getgroups(groups, gids); + for(int i = 0; i < n; ++i){ + if (stat_sb->st_gid==gids[i]) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; @@ -453,19 +439,19 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &stat_blocks); /* Store string indexes referencing the same zval*/ - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("dev"), &stat_dev); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("ino"), &stat_ino); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("mode"), &stat_mode); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("nlink"), &stat_nlink); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("uid"), &stat_uid); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("gid"), &stat_gid); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("rdev"), &stat_rdev); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("size"), &stat_size); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("atime"), &stat_atime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("mtime"), &stat_mtime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("ctime"), &stat_ctime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("blksize"), &stat_blksize); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("blocks"), &stat_blocks); return; } @@ -481,11 +467,8 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ } if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname; zend_stat_t sb = {0}; - phar_entry_info *data = NULL; phar_archive_data *phar; fname = zend_get_executed_filename_ex(); @@ -496,40 +479,38 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ goto skip_phar; } - if (PHAR_G(last_phar) && ZSTR_LEN(fname) - 7 >= PHAR_G(last_phar_name_len) && !memcmp(ZSTR_VAL(fname) + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) { - arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)); - arch_len = PHAR_G(last_phar_name_len); - entry = estrndup(filename, filename_length); + if (PHAR_G(last_phar) && ZSTR_LEN(fname) - 7 >= ZSTR_LEN(PHAR_G(last_phar_name)) && !memcmp(ZSTR_VAL(fname) + 7, ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name)))) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_length; phar = PHAR_G(last_phar); goto splitted; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) { - entry = estrndup(filename, filename_length); + + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_length; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); - efree(entry); + phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (!phar) { goto skip_phar; } -splitted: - entry = phar_fix_filepath(entry, &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - efree(entry); +splitted:; + zend_string *entry = phar_fix_filepath(filename, filename_length, true); + const phar_entry_info *data = NULL; + if (ZSTR_VAL(entry)[0] == '/') { + data = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); + if (data) { + zend_string_release_ex(entry, false); goto stat_entry; } goto notfound; } - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - efree(entry); + data = zend_hash_find_ptr(&(phar->manifest), entry); + if (data) { + zend_string_release_ex(entry, false); goto stat_entry; } - if (zend_hash_str_exists(&(phar->virtual_dirs), entry, entry_len)) { - efree(entry); - efree(arch); + if (zend_hash_exists(&(phar->virtual_dirs), entry)) { + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { RETURN_TRUE; } @@ -545,31 +526,28 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ size_t save_len; notfound: - efree(entry); + zend_string_release_ex(entry, false); save = PHAR_G(cwd); save_len = PHAR_G(cwd_len); /* this file is not in the current directory, use the original path */ - entry = estrndup(filename, filename_length); - entry_len = filename_length; PHAR_G(cwd) = "/"; PHAR_G(cwd_len) = 0; /* clean path without cwd */ - entry = phar_fix_filepath(entry, &entry_len, 1); - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { + entry = phar_fix_filepath(filename, filename_length, true); + data = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); + if (data) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { - efree(arch); RETURN_TRUE; } goto stat_entry; } - if (zend_hash_str_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) { + if (zend_hash_str_exists(&(phar->virtual_dirs), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1)) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { RETURN_TRUE; } @@ -583,8 +561,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ } PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); /* Error Occurred */ if (!IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename); @@ -592,11 +569,10 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ RETURN_FALSE; } stat_entry: - efree(arch); if (!data->is_dir) { sb.st_size = data->uncompressed_filesize; sb.st_mode = data->flags & PHAR_ENT_PERM_MASK; - if (data->link) { + if (data->symlink) { sb.st_mode |= S_IFREG|S_IFLNK; /* regular file */ } else { sb.st_mode |= S_IFREG; /* regular file */ @@ -609,7 +585,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ sb.st_size = 0; sb.st_mode = data->flags & PHAR_ENT_PERM_MASK; sb.st_mode |= S_IFDIR; /* regular directory */ - if (data->link) { + if (data->symlink) { sb.st_mode |= S_IFLNK; } /* timestamp is just the timestamp when this was added to the phar */ @@ -737,8 +713,6 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ goto skip_phar; } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -747,35 +721,29 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) { - phar_archive_data *phar; + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { + ; - entry = filename; /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (phar) { phar_entry_info *etemp; - entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - /* this file is not in the current directory, use the original path */ -found_it: - efree(entry); - efree(arch); - RETURN_BOOL(!etemp->is_dir); - } + zend_string *entry = phar_fix_filepath(filename, filename_len, true); + if (ZSTR_VAL(entry)[0] == '/') { + etemp = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - goto found_it; - } + etemp = zend_hash_find_ptr(&(phar->manifest), entry); } + zend_string_release_ex(entry, false); + if (etemp) { + RETURN_BOOL(!etemp->is_dir); + } + /* this file is not in the current directory, use the original path */ } - if (entry != filename) { - efree(entry); - } - efree(arch); RETURN_FALSE; } } @@ -802,8 +770,6 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ goto skip_phar; } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -812,33 +778,26 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0)) { - phar_archive_data *phar; - - entry = filename; + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (phar) { phar_entry_info *etemp; - entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - /* this file is not in the current directory, use the original path */ -found_it: - efree(entry); - efree(arch); - RETURN_BOOL(etemp->link); - } + zend_string *entry = phar_fix_filepath(filename, filename_len, true); + if (ZSTR_VAL(entry)[0] == '/') { + etemp = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - goto found_it; - } + etemp = zend_hash_find_ptr(&(phar->manifest), entry); + } + zend_string_release_ex(entry, false); + if (etemp) { + RETURN_BOOL(etemp->symlink); } } - efree(entry); - efree(arch); RETURN_FALSE; } } @@ -877,7 +836,8 @@ void phar_release_functions(void) /* {{{ void phar_intercept_functions_init(void) */ #define PHAR_INTERCEPT(func) \ PHAR_G(orig_##func) = NULL; \ - if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \ + orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1); \ + if (orig) { \ PHAR_G(orig_##func) = orig->internal_function.handler; \ orig->internal_function.handler = PHP_FN(phar_##func); \ } @@ -926,6 +886,7 @@ void phar_intercept_functions_shutdown(void) PHAR_RELEASE(fopen); PHAR_RELEASE(file_get_contents); PHAR_RELEASE(is_file); + PHAR_RELEASE(is_link); PHAR_RELEASE(is_dir); PHAR_RELEASE(opendir); PHAR_RELEASE(file_exists); diff --git a/ext/phar/func_interceptors.h b/ext/phar/func_interceptors.h index 06906ee79e80..af68b0410d4c 100644 --- a/ext/phar/func_interceptors.h +++ b/ext/phar/func_interceptors.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/makestub.php b/ext/phar/makestub.php index 34d270751bfb..e5cbe89ff4bd 100755 --- a/ext/phar/makestub.php +++ b/ext/phar/makestub.php @@ -35,15 +35,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension generated stub | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ diff --git a/ext/phar/phar.1.in b/ext/phar/phar.1.in index db22d40abc3f..8dffd2cf2dd0 100644 --- a/ext/phar/phar.1.in +++ b/ext/phar/phar.1.in @@ -511,17 +511,9 @@ contributors all around the world. .SH VERSION INFORMATION This manpage describes \fBphar\fP, version @PHP_VERSION@. .SH COPYRIGHT -Copyright \(co The PHP Group +Copyright \(co The PHP Group and Contributors .LP -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: -.PD 0 -.P -.B https://www.php.net/license/3_01.txt -.PD 1 -.P -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 -.B license@php.net -so we can mail you a copy immediately. +This source file is subject to the Modified BSD License that is +bundled with this package in the file LICENSE, and is available +through the World Wide Web at +.B https://www.php.net/license/ diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 619017038637..9f0ccc627279 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -93,7 +91,7 @@ HashTable cached_alias; static void phar_split_cache_list(void) /* {{{ */ { char *tmp; - char *key, *lasts, *end; + char *key, *lasts; char ds[2]; phar_archive_data *phar; uint32_t i = 0; @@ -126,14 +124,14 @@ static void phar_split_cache_list(void) /* {{{ */ key; key = php_strtok_r(NULL, ds, &lasts)) { size_t len; - end = strchr(key, DEFAULT_DIR_SEPARATOR); + const char *end = strchr(key, DEFAULT_DIR_SEPARATOR); if (end) { len = end - key; } else { len = strlen(key); } - if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, &phar, NULL)) { phar->phar_pos = i++; php_stream_close(phar->fp); phar->fp = NULL; @@ -194,13 +192,13 @@ PHP_INI_END() */ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ { - if (phar->alias && phar->alias != phar->fname) { + if (phar->alias) { pefree(phar->alias, phar->is_persistent); phar->alias = NULL; } if (phar->fname) { - pefree(phar->fname, phar->is_persistent); + zend_string_release_ex(phar->fname, phar->is_persistent); phar->fname = NULL; } @@ -251,14 +249,15 @@ bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ if (--phar->refcount < 0) { if (PHAR_G(request_done) - || zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + || zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { phar_destroy_phar_data(phar); } return true; } else if (!phar->refcount) { /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; /* This is a new phar that has perhaps had an alias/metadata set, but has never been flushed. */ bool remove_fname_cache = !zend_hash_num_elements(&phar->manifest); @@ -280,7 +279,7 @@ bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ } if (remove_fname_cache) { - if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + if (zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { phar_destroy_phar_data(phar); } return true; @@ -375,9 +374,9 @@ void destroy_phar_manifest_entry_int(phar_entry_info *entry) /* {{{ */ zend_string_release_ex(entry->filename, entry->is_persistent); - if (entry->link) { - pefree(entry->link, entry->is_persistent); - entry->link = 0; + if (entry->symlink) { + zend_string_release_ex(entry->symlink, entry->is_persistent); + entry->symlink = NULL; } if (entry->tmp) { @@ -485,9 +484,15 @@ ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **err /** * Open an already loaded phar */ -static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ - phar_archive_data *phar; +static zend_result phar_open_parsed_phar( + char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { #ifdef PHP_WIN32 char *save_fname; ALLOCA_FLAG(fname_use_heap) @@ -505,16 +510,22 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al phar_unixify_path_separators(fname, fname_len); } #endif - if (SUCCESS == phar_get_archive(&phar, fname, fname_len, alias, alias_len, error) - && ((alias && fname_len == phar->fname_len - && !strncmp(fname, phar->fname, fname_len)) || !alias) - ) { + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + phar_archive_data *phar = phar_get_archive(fname, fname_len, alias_cstr, alias_len, error); + /* logic is as follows: + - If no alias was passed in, then it can match either and be valid + - If an explicit alias was requested, ensure the filename passed in matches the phar's filename. + */ + bool process_phar = phar && (!alias || zend_string_equals_cstr(phar->fname, fname, fname_len)); #ifdef PHP_WIN32 - if (fname != save_fname) { - free_alloca(fname, fname_use_heap); - fname = save_fname; - } + if (fname != save_fname) { + free_alloca(fname, fname_use_heap); + fname = save_fname; + } #endif + + if (process_phar) { /* logic above is as follows: If an explicit alias was requested, ensure the filename passed in matches the phar's filename. @@ -539,12 +550,6 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al return SUCCESS; } else { -#ifdef PHP_WIN32 - if (fname != save_fname) { - free_alloca(fname, fname_use_heap); - fname = save_fname; - } -#endif if (pphar) { *pphar = NULL; } @@ -556,7 +561,6 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al return FAILURE; } } -/* }}}*/ /** * Attempt to serialize the data. @@ -724,7 +728,7 @@ void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker * This is used by phar_open_from_filename to process the manifest, but can be called * directly. */ -static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ +static zend_result phar_parse_pharfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char b32[4], *buffer, *endbuffer, *savebuf; phar_archive_data *mydata = NULL; @@ -827,7 +831,6 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname SAFE_PHAR_GET_32(buffer, endbuffer, manifest_flags); - manifest_flags &= ~PHAR_HDR_COMPRESSION_MASK; manifest_flags &= ~PHAR_FILE_COMPRESSION_MASK; /* remember whether this entire phar was compressed with gz/bzip2 */ manifest_flags |= compression; @@ -1112,11 +1115,13 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname zend_get_hash_value, NULL, mydata->is_persistent); zend_hash_init(&mydata->virtual_dirs, manifest_count * 2, zend_get_hash_value, NULL, mydata->is_persistent); - mydata->fname = pestrndup(fname, fname_len, mydata->is_persistent); + mydata->fname = zend_string_init(fname, fname_len, mydata->is_persistent); + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(mydata->fname); + } #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); #endif - mydata->fname_len = fname_len; offset = halt_offset + manifest_len + 4; memset(&entry, 0, sizeof(phar_entry_info)); entry.phar = mydata; @@ -1231,22 +1236,22 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname snprintf(mydata->version, sizeof(mydata->version), "%u.%u.%u", manifest_ver >> 12, (manifest_ver >> 8) & 0xF, (manifest_ver >> 4) & 0xF); mydata->halt_offset = halt_offset; mydata->flags = manifest_flags; - endbuffer = strrchr(mydata->fname, '/'); + endbuffer = strrchr(ZSTR_VAL(mydata->fname), '/'); if (endbuffer) { - mydata->ext = memchr(endbuffer, '.', (mydata->fname + fname_len) - endbuffer); + mydata->ext = memchr(endbuffer, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - endbuffer); if (mydata->ext == endbuffer) { - mydata->ext = memchr(endbuffer + 1, '.', (mydata->fname + fname_len) - endbuffer - 1); + mydata->ext = memchr(endbuffer + 1, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - endbuffer - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + mydata->fname_len) - mydata->ext; + mydata->ext_len = (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - mydata->ext; } } mydata->alias = alias ? pestrndup(alias, alias_len, mydata->is_persistent) : - pestrndup(mydata->fname, fname_len, mydata->is_persistent); - mydata->alias_len = alias ? alias_len : fname_len; + pestrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), mydata->is_persistent); + mydata->alias_len = alias ? alias_len : ZSTR_LEN(mydata->fname); mydata->sig_flags = sig_flags; mydata->fp = fp; mydata->sig_len = sig_len; @@ -1264,8 +1269,9 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname MAPPHAR_FAIL("Cannot open archive \"%s\", invalid alias"); } - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { signature = NULL; fp = NULL; MAPPHAR_FAIL("Cannot open archive \"%s\", alias is already in use by existing archive"); @@ -1284,12 +1290,12 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname } if (mydata->is_persistent) { - str = zend_string_init_interned(mydata->fname, fname_len, 1); + str = zend_string_init_interned(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), true); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), str, mydata); + zend_string_release(str); } else { - str = zend_string_init(mydata->fname, fname_len, 0); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); } - zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), str, mydata); - zend_string_release(str); efree(savebuf); if (pphar) { @@ -1303,8 +1309,14 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /** * Create or open a phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_filename( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { const char *ext_str, *z; char *my_error; size_t ext_len; @@ -1315,31 +1327,31 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(ch *error = NULL; /* first try to open an existing file */ - if (phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, !is_data, 0, true) == SUCCESS) { + if (phar_detect_phar_fname_ext(ZSTR_VAL(fname), ZSTR_LEN(fname), &ext_str, &ext_len, !is_data, 0, true) == SUCCESS) { goto check_file; } /* next try to create a new file */ - if (FAILURE == phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, !is_data, 1, true)) { + if (FAILURE == phar_detect_phar_fname_ext(ZSTR_VAL(fname), ZSTR_LEN(fname), &ext_str, &ext_len, !is_data, 1, true)) { if (ext_len == -2) { - spprintf(error, 0, "Cannot create a phar archive from a URL like \"%s\". Phar objects can only be created from local files", fname); + spprintf(error, 0, "Cannot create a phar archive from a URL like \"%s\". Phar objects can only be created from local files", ZSTR_VAL(fname)); } else { - spprintf(error, 0, "Cannot create phar '%s', file extension (or combination) not recognised or the directory does not exist", fname); + spprintf(error, 0, "Cannot create phar '%s', file extension (or combination) not recognised or the directory does not exist", ZSTR_VAL(fname)); } return FAILURE; } check_file: - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, test, &my_error) == SUCCESS) { + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, is_data, options, test, &my_error) == SUCCESS) { *pphar = *test; if ((*test)->is_data && !(*test)->is_tar && !(*test)->is_zip) { - spprintf(error, 0, "Cannot open '%s' as a PharData object. Use Phar::__construct() for executable archives", fname); + spprintf(error, 0, "Cannot open '%s' as a PharData object. Use Phar::__construct() for executable archives", ZSTR_VAL(fname)); return FAILURE; } if (PHAR_G(readonly) && !(*test)->is_data && ((*test)->is_tar || (*test)->is_zip)) { if (!zend_hash_str_exists(&((*test)->manifest), ZEND_STRL(".phar/stub.php"))) { - spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname); + spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", ZSTR_VAL(fname)); return FAILURE; } } @@ -1355,40 +1367,45 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(ch if (ext_len > 3 && (z = memchr(ext_str, 'z', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ip", 2)) { /* assume zip-based phar */ - return phar_open_or_create_zip(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_zip(fname, alias, is_data, options, pphar, error); } if (ext_len > 3 && (z = memchr(ext_str, 't', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ar", 2)) { /* assume tar-based phar */ - return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_tar(fname, alias, is_data, options, pphar, error); } - return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_create_or_parse_filename(fname, alias, is_data, options, pphar, error); } -/* }}} */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +static zend_result phar_open_from_fp(php_stream* fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_create_or_parse_filename( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { php_stream *fp; zend_string *actual = NULL; + zend_string *save_fname = fname; char *p; - if (php_check_open_basedir(fname)) { + if (php_check_open_basedir(ZSTR_VAL(fname))) { return FAILURE; } /* first open readonly so it won't be created if not present */ - fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, &actual); + fp = php_stream_open_wrapper(ZSTR_VAL(fname), "rb", IGNORE_URL|STREAM_MUST_SEEK|0, &actual); if (actual) { - fname = ZSTR_VAL(actual); - fname_len = ZSTR_LEN(actual); + fname = actual; } if (fp) { - if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error) == SUCCESS) { + if (phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, options, pphar, error) == SUCCESS) { if ((*pphar)->is_data || !PHAR_G(readonly)) { (*pphar)->is_writeable = 1; } @@ -1407,35 +1424,37 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c if (actual) { zend_string_release_ex(actual, 0); + fname = save_fname; } if (PHAR_G(readonly) && !is_data) { if (options & REPORT_ERRORS) { - spprintf(error, 0, "creating archive \"%s\" disabled by the php.ini setting phar.readonly", fname); + spprintf(error, 0, "creating archive \"%s\" disabled by the php.ini setting phar.readonly", ZSTR_VAL(fname)); } return FAILURE; } /* set up our manifest */ phar_archive_data *mydata = ecalloc(1, sizeof(phar_archive_data)); - mydata->fname = expand_filepath(fname, NULL); - if (mydata->fname == NULL) { + /* TODO: prevent reallocation via a new expand_filepath() API? */ + char *new_fname = expand_filepath(ZSTR_VAL(fname), NULL); + if (new_fname == NULL) { efree(mydata); return FAILURE; } - fname_len = strlen(mydata->fname); + size_t new_fname_len = strlen(new_fname); #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(new_fname, new_fname_len); #endif - p = strrchr(mydata->fname, '/'); + p = strrchr(new_fname, '/'); if (p) { - mydata->ext = memchr(p, '.', (mydata->fname + fname_len) - p); + mydata->ext = memchr(p, '.', (new_fname + new_fname_len) - p); if (mydata->ext == p) { - mydata->ext = memchr(p + 1, '.', (mydata->fname + fname_len) - p - 1); + mydata->ext = memchr(p + 1, '.', (new_fname + new_fname_len) - p - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + fname_len) - mydata->ext; + mydata->ext_len = (new_fname + new_fname_len) - mydata->ext; } } @@ -1445,29 +1464,28 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c zend_get_hash_value, NULL, 0); zend_hash_init(&mydata->virtual_dirs, sizeof(char *), zend_get_hash_value, NULL, mydata->is_persistent); - mydata->fname_len = fname_len; + mydata->fname = zend_string_init(new_fname, new_fname_len, false); + efree(new_fname); snprintf(mydata->version, sizeof(mydata->version), "%s", PHP_PHAR_API_VERSION); mydata->is_temporary_alias = alias ? 0 : 1; mydata->fp = NULL; mydata->is_writeable = 1; mydata->is_brandnew = 1; phar_request_initialize(); - zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); if (is_data) { alias = NULL; - alias_len = 0; mydata->is_data = 1; /* assume tar format, PharData can specify other */ mydata->is_tar = 1; } else { - phar_archive_data *fd_ptr; - - if (alias && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { - spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, alias); + if (alias) { + const phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr && SUCCESS != phar_free_alias(fd_ptr)) { + spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", ZSTR_VAL(mydata->fname), ZSTR_VAL(alias)); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); *pphar = NULL; @@ -1476,17 +1494,17 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c } ZEND_ASSERT(!mydata->is_persistent); - mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len); - mydata->alias_len = alias ? alias_len : fname_len; + mydata->alias = alias ? estrndup(ZSTR_VAL(alias), ZSTR_LEN(alias)) : estrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); + mydata->alias_len = alias ? ZSTR_LEN(alias) : ZSTR_LEN(mydata->fname); } - if (alias_len && alias) { - if (NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata)) { + if (alias) { + if (NULL == zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, mydata)) { if (options & REPORT_ERRORS) { - spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, alias); + spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", ZSTR_VAL(fname), ZSTR_VAL(alias)); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); *pphar = NULL; @@ -1497,7 +1515,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c *pphar = mydata; return SUCCESS; } -/* }}}*/ /** * Return an already opened filename. @@ -1506,8 +1523,14 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +zend_result phar_open_from_filename( + char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + uint32_t options, + phar_archive_data** pphar, + char **error +) { php_stream *fp; zend_string *actual; bool is_data = false; @@ -1520,7 +1543,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, is_data = true; } - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { + if (phar_open_parsed_phar(fname, fname_len, alias, is_data, options, pphar, error) == SUCCESS) { return SUCCESS; } else if (error && *error) { return FAILURE; @@ -1548,7 +1571,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, fname_len = ZSTR_LEN(actual); } - zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -1556,15 +1579,21 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, return ret; } -/* }}}*/ /** * Scan an open fp for the required __HALT_COMPILER(); ?> token and verify * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +static zend_result phar_open_from_fp( + php_stream* fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + uint32_t options, + phar_archive_data** pphar, + char **error +) { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; static const char gz_magic[] = "\x1f\x8b\x08"; @@ -1670,14 +1699,14 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l continue; } else if (!memcmp(pos, bz_magic, 3)) { php_stream_filter *filter; - php_stream *temp; if (!PHAR_G(has_bz2)) { MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\" to temporary file, enable bz2 extension in php.ini") } /* entire file is bzip-compressed, uncompress to temporary file */ - if (!(temp = php_stream_fopen_tmpfile())) { + php_stream *temp = php_stream_fopen_tmpfile(); + if (!temp) { MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of bzipped phar archive \"%s\"") } @@ -1715,20 +1744,22 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l if (!memcmp(pos, zip_magic, 4)) { php_stream_seek(fp, 0, SEEK_END); - return phar_parse_zipfile(fp, fname, fname_len, alias, alias_len, pphar, error); + return phar_parse_zipfile(fp, fname, fname_len, alias, pphar, error); } if (got >= 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); + return phar_parse_tarfile(fp, fname, fname_len, alias, pphar, compression, error); } } } if (got > 0 && (pos = php_memnistr(buffer, token, tokenlen, buffer + got + sizeof(token))) != NULL) { halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */ - return phar_parse_pharfile(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, compression, error); + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + return phar_parse_pharfile(fp, fname, fname_len, alias_cstr, alias_len, halt_offset, pphar, compression, error); } halt_offset += got; @@ -1737,7 +1768,6 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (__HALT_COMPILER(); not found)") } -/* }}} */ /* * given the location of the file extension and the start of the file path, @@ -1751,10 +1781,10 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l static zend_result phar_analyze_path(const char *fname, const char *ext, size_t ext_len, int for_create) /* {{{ */ { php_stream_statbuf ssb; - char *realpath; char *filename = estrndup(fname, (ext - fname) + ext_len); - if ((realpath = expand_filepath(filename, NULL))) { + char *realpath = expand_filepath(filename, NULL); + if (realpath) { #ifdef PHP_WIN32 phar_unixify_path_separators(realpath, strlen(realpath)); #endif @@ -1801,7 +1831,8 @@ static zend_result phar_analyze_path(const char *fname, const char *ext, size_t if (SUCCESS != php_stream_stat_path((char *) filename, &ssb)) { if (!slash) { - if (!(realpath = expand_filepath(filename, NULL))) { + realpath = expand_filepath(filename, NULL); + if (!realpath) { efree(filename); return FAILURE; } @@ -1944,7 +1975,8 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len phar_archive_data *pphar; if (is_complete) { - if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), (char *) filename, filename_len))) { + pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), filename, filename_len); + if (pphar) { *ext_str = filename + (filename_len - pphar->ext_len); woohoo: *ext_len = pphar->ext_len; @@ -1964,7 +1996,8 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len return FAILURE; } - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, (char *) filename, filename_len))) { + pphar = PHAR_G(manifest_cached) ? zend_hash_str_find_ptr(&cached_phars, filename, filename_len) : NULL; + if (pphar) { *ext_str = filename + (filename_len - pphar->ext_len); goto woohoo; } @@ -2061,31 +2094,29 @@ static bool php_check_dots(const char *element, size_t n) /* {{{ */ /** * Remove .. and . references within a phar filename */ -char *phar_fix_filepath(char *path, size_t *new_len, bool use_cwd) /* {{{ */ +zend_string* phar_fix_filepath(const char *path, size_t path_length, bool use_cwd) /* {{{ */ { - char *newpath; - size_t newpath_len; - char *ptr; - char *tok; - size_t ptr_length, path_length = *new_len; - - if (PHAR_G(cwd_len) && use_cwd && path_length > 2 && path[0] == '.' && path[1] == '/') { - newpath_len = PHAR_G(cwd_len); - newpath = emalloc(strlen(path) + newpath_len + 1); - memcpy(newpath, PHAR_G(cwd), newpath_len); + zend_string *new_path; + size_t new_path_len; + size_t ptr_length; + + if (use_cwd && PHAR_G(cwd_len) && path_length > 2 && path[0] == '.' && path[1] == '/') { + new_path = zend_string_alloc(path_length + PHAR_G(cwd_len) + 1, false); + new_path_len = PHAR_G(cwd_len); + memcpy(ZSTR_VAL(new_path), PHAR_G(cwd), PHAR_G(cwd_len)); } else { - newpath = emalloc(strlen(path) + 2); - newpath[0] = '/'; - newpath_len = 1; + new_path = zend_string_alloc(path_length + 2, false); + ZSTR_VAL(new_path)[0] = '/'; + new_path_len = 1; } - ptr = path; + const char *ptr = path; if (*ptr == '/') { ++ptr; } - tok = ptr; + const char *tok = ptr; do { ptr = memchr(ptr, '/', path_length - (ptr - path)); @@ -2095,46 +2126,42 @@ char *phar_fix_filepath(char *path, size_t *new_len, bool use_cwd) /* {{{ */ switch (path_length - (tok - path)) { case 1: if (*tok == '.') { - efree(path); - *new_len = 1; - efree(newpath); - return estrndup("/", 1); + zend_string_release_ex(new_path, false); + return ZSTR_CHAR('/'); } break; case 2: if (tok[0] == '.' && tok[1] == '.') { - efree(path); - *new_len = 1; - efree(newpath); - return estrndup("/", 1); + zend_string_release_ex(new_path, false); + return ZSTR_CHAR('/'); } } - efree(newpath); - return path; + zend_string_release_ex(new_path, false); + return zend_string_init(path, path_length, false); } while (ptr) { ptr_length = ptr - tok; last_time: if (IS_DIRECTORY_UP(tok, ptr_length)) { - while (newpath_len > 1 && !IS_BACKSLASH(newpath[newpath_len - 1])) { - newpath_len--; + while (new_path_len > 1 && !IS_BACKSLASH(ZSTR_VAL(new_path)[new_path_len - 1])) { + new_path_len--; } - if (newpath[0] != '/') { - newpath[newpath_len] = '\0'; - } else if (newpath_len > 1) { - --newpath_len; + if (ZSTR_VAL(new_path)[0] != '/') { + ZSTR_VAL(new_path)[new_path_len] = '\0'; + } else if (new_path_len > 1) { + --new_path_len; } } else if (!IS_DIRECTORY_CURRENT(tok, ptr_length)) { - if (newpath_len > 1) { - newpath[newpath_len++] = '/'; - memcpy(newpath + newpath_len, tok, ptr_length+1); + if (new_path_len > 1) { + ZSTR_VAL(new_path)[new_path_len++] = '/'; + memcpy(ZSTR_VAL(new_path) + new_path_len, tok, ptr_length+1); } else { - memcpy(newpath + newpath_len, tok, ptr_length+1); + memcpy(ZSTR_VAL(new_path) + new_path_len, tok, ptr_length+1); } - newpath_len += ptr_length; + new_path_len += ptr_length; } if (ptr == path + path_length) { @@ -2154,10 +2181,8 @@ char *phar_fix_filepath(char *path, size_t *new_len, bool use_cwd) /* {{{ */ } } - efree(path); - *new_len = newpath_len; - newpath[newpath_len] = '\0'; - return erealloc(newpath, newpath_len + 1); + ZSTR_VAL(new_path)[new_path_len] = '\0'; + return zend_string_realloc(new_path, new_path_len, false); } /* }}} */ @@ -2173,7 +2198,7 @@ char *phar_fix_filepath(char *path, size_t *new_len, bool use_cwd) /* {{{ */ * * This is used by phar_parse_url() */ -zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ +zend_string* phar_split_fname_ex(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create, const char **error) /* {{{ */ { const char *ext_str; #ifdef PHP_WIN32 @@ -2181,8 +2206,11 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a #endif size_t ext_len; + if (error) { + *error = NULL; + } if (zend_char_has_nul_byte(filename, filename_len)) { - return FAILURE; + return NULL; } if (!strncasecmp(filename, "phar://", 7)) { @@ -2200,12 +2228,12 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a #endif if (phar_detect_phar_fname_ext(filename, filename_len, &ext_str, &ext_len, executable, for_create, false) == FAILURE) { if (ext_len != -1) { - if (!ext_str) { + if (!ext_str && error) { /* no / detected, restore arch for error message */ #ifdef PHP_WIN32 - *arch = save; + *error = save; #else - *arch = (char*)filename; + *error = filename; #endif } @@ -2214,27 +2242,24 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a efree((char *)filename); } #endif - return FAILURE; + return NULL; } ext_len = 0; /* no extension detected - instead we are dealing with an alias */ } - *arch_len = ext_str - filename + ext_len; - *arch = estrndup(filename, *arch_len); + size_t arch_len = ext_str - filename + ext_len; + zend_string *arch = zend_string_init(filename, arch_len, false); if (entry) { if (ext_str[ext_len]) { - *entry_len = filename_len - *arch_len; - *entry = estrndup(ext_str+ext_len, *entry_len); - #ifdef PHP_WIN32 - phar_unixify_path_separators(*entry, *entry_len); - #endif - *entry = phar_fix_filepath(*entry, entry_len, 0); + size_t computed_entry_len = filename_len - arch_len; + /* We don't need to unixify the path on Windows, + * as ext_str is derived from filename that was already unixify */ + *entry = phar_fix_filepath(ext_str+ext_len, computed_entry_len, false); } else { - *entry_len = 1; - *entry = estrndup("/", 1); + *entry = ZSTR_CHAR('/'); } } @@ -2244,15 +2269,19 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a } #endif - return SUCCESS; + return arch; } /* }}} */ +zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create) { + return phar_split_fname_ex(filename, filename_len, entry, executable, for_create, NULL); +} + /** * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error) /* {{{ */ { *error = NULL; @@ -2263,7 +2292,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *ali return FAILURE; } - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { return SUCCESS; } @@ -2292,7 +2321,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *ali fname = actual; } - zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2320,14 +2349,14 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, if (!stream) { spprintf(error, 0, "phar error: unable to open zip-based phar archive \"%s\" to verify local file header for file \"%s\"", - idata->phar->fname, ZSTR_VAL(entry->filename)); + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } php_stream_seek(stream, entry->header_offset, SEEK_SET); if (sizeof(local) != php_stream_read(stream, (char *) &local, sizeof(local))) { spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local file header for file \"%s\")", - idata->phar->fname, ZSTR_VAL(entry->filename)); + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -2341,7 +2370,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, if (sizeof(desc) != php_stream_read(stream, (char *) &desc, sizeof(desc))) { spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local data descriptor for file \"%s\")", - idata->phar->fname, ZSTR_VAL(entry->filename)); + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } if (desc.signature[0] == 'P' && desc.signature[1] == 'K') { @@ -2354,7 +2383,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, /* verify local header */ if (ZSTR_LEN(entry->filename) != PHAR_ZIP_16(local.filename_len) || entry->crc32 != PHAR_ZIP_32(local.crc32) || entry->uncompressed_filesize != PHAR_ZIP_32(local.uncompsize) || entry->compressed_filesize != PHAR_ZIP_32(local.compsize)) { spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (local header of file \"%s\" does not match central directory)", - idata->phar->fname, ZSTR_VAL(entry->filename)); + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -2383,7 +2412,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, return SUCCESS; } else { spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (crc32 mismatch on file \"%s\")", - idata->phar->fname, ZSTR_VAL(entry->filename)); + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } } @@ -2495,7 +2524,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream *shared_cfp = NULL; if (phar->is_persistent) { - spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -2524,7 +2553,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } newfile = php_stream_fopen_tmpfile(); @@ -2544,7 +2573,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(oldfile); } php_stream_close(newfile); - spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", phar->fname); + spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", ZSTR_VAL(phar->fname)); return EOF; } @@ -2560,7 +2589,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(oldfile); } php_stream_close(newfile); - spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } phar->halt_offset = len + end_sequence_len; @@ -2582,9 +2611,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } php_stream_close(newfile); if (new_stub) { - spprintf(error, 0, "unable to create stub in new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub in new phar \"%s\"", ZSTR_VAL(phar->fname)); } else { - spprintf(error, 0, "unable to copy stub of old phar to new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to copy stub of old phar to new phar \"%s\"", ZSTR_VAL(phar->fname)); } if (new_stub) { zend_string_free(new_stub); @@ -2606,7 +2635,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen /* compress as necessary, calculate crcs, serialize meta-data, manifest size, and file sizes */ main_metadata_str.s = NULL; if (phar->metadata_tracker.str) { - smart_str_appendl(&main_metadata_str, ZSTR_VAL(phar->metadata_tracker.str), ZSTR_LEN(phar->metadata_tracker.str)); + smart_str_append(&main_metadata_str, phar->metadata_tracker.str); } else if (!Z_ISUNDEF(phar->metadata_tracker.val)) { PHP_VAR_SERIALIZE_INIT(metadata_hash); php_var_serialize(&main_metadata_str, &phar->metadata_tracker.val, &metadata_hash); @@ -2682,7 +2711,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(oldfile); } php_stream_close(newfile); - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); return EOF; } newcrc32 = php_crc32_bulk_init(); @@ -2694,7 +2723,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen entry->compressed_filesize = entry->uncompressed_filesize; continue; } - filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0); + const char *compression_filter_name = phar_get_compress_filter_name(entry); + ZEND_ASSERT(compression_filter_name && "Must have as this has a compression flag set"); + filter = php_stream_filter_create(compression_filter_name, NULL, false); if (!filter) { if (must_close_old_file) { php_stream_close(oldfile); @@ -2703,7 +2734,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen spprintf(error, 0, "unable to %s compress file \"%s\" to new phar \"%s\"", entry->flags & PHAR_ENT_COMPRESSED_GZ ? "gzip" : "bzip2", ZSTR_VAL(entry->filename), - phar->fname); + ZSTR_VAL(phar->fname)); return EOF; } @@ -2734,7 +2765,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } php_stream_close(newfile); spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", - ZSTR_VAL(entry->filename), phar->fname); + ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } php_stream_filter_append((&entry->cfp->writefilters), filter); @@ -2745,7 +2776,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } php_stream_close(newfile); spprintf(error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", - ZSTR_VAL(entry->filename), phar->fname); + ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } php_stream_filter_flush(filter, 1); @@ -2805,7 +2836,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(newfile); phar->alias_len = restore_alias_len; - spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2824,7 +2855,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(newfile); phar->alias_len = restore_alias_len; - spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2856,9 +2887,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } php_stream_close(newfile); if (entry->is_dir) { - spprintf(error, 0, "unable to write filename of directory \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to write filename of directory \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); } else { - spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); } goto cleanup; } @@ -2890,7 +2921,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(newfile); - spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2927,7 +2958,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(oldfile); } php_stream_close(newfile); - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } } @@ -2937,7 +2968,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(oldfile); } php_stream_close(newfile); - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2951,7 +2982,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen php_stream_close(newfile); - spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2994,17 +3025,12 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen switch(phar->sig_flags) { default: { - char *digest = NULL; - size_t digest_len; - char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &digest, &digest_len, &signature_error)) { + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { spprintf(error, 0, "phar error: unable to write signature: %s", signature_error); efree(signature_error); - if (digest) { - efree(digest); - } if (must_close_old_file) { php_stream_close(oldfile); } @@ -3012,14 +3038,14 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen return EOF; } - php_stream_write(newfile, digest, digest_len); - efree(digest); + php_stream_write(newfile, ZSTR_VAL(signature), ZSTR_LEN(signature)); if (phar->sig_flags == PHAR_SIG_OPENSSL || phar->sig_flags == PHAR_SIG_OPENSSL_SHA256 || phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) { - phar_set_32(sig_buf, digest_len); + phar_set_32(sig_buf, ZSTR_LEN(signature)); php_stream_write(newfile, sig_buf, 4); } + zend_string_release_ex(signature, false); break; } } @@ -3055,10 +3081,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen /* deferred flush */ phar->fp = newfile; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { phar->fp = newfile; - spprintf(error, 4096, "unable to open new phar \"%s\" for writing", phar->fname); + spprintf(error, 4096, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); return EOF; } @@ -3072,7 +3098,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen zend_array_destroy(Z_ARR(filterparams)); if (!filter) { - spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname); + spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", ZSTR_VAL(phar->fname)); return EOF; } @@ -3100,7 +3126,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } if (-1 == php_stream_seek(phar->fp, phar->halt_offset, SEEK_SET)) { - spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -3143,7 +3169,7 @@ zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type static zend_string *phar_resolve_path(zend_string *filename) { - zend_string *ret = phar_find_in_include_path(filename, NULL); + zend_string *ret = phar_find_in_include_path(filename); if (!ret) { ret = phar_save_resolve_path(filename); } @@ -3161,7 +3187,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) return phar_orig_compile_file(file_handle, type); } if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) { - if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, &phar, NULL)) { if (phar->is_zip || phar->is_tar) { zend_file_handle f; @@ -3346,7 +3372,8 @@ void phar_request_initialize(void) /* {{{ */ if (!PHAR_G(request_init)) { PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; PHAR_G(has_bz2) = zend_hash_str_exists(&module_registry, "bz2", sizeof("bz2")-1); PHAR_G(has_zlib) = zend_hash_str_exists(&module_registry, "zlib", sizeof("zlib")-1); PHAR_G(request_init) = 1; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 62b5520ba50f..30d863b02f09 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -40,10 +38,6 @@ #define PHAR_API_MAJORVER_MASK 0xF000 #define PHAR_API_VER_MASK 0xFFF0 -#define PHAR_HDR_COMPRESSION_MASK 0x0000F000 -#define PHAR_HDR_COMPRESSED_NONE 0x00000000 -#define PHAR_HDR_COMPRESSED_GZ 0x00001000 -#define PHAR_HDR_COMPRESSED_BZ2 0x00002000 #define PHAR_HDR_SIGNATURE 0x00010000 /* flags for defining that the entire file should be compressed */ @@ -148,10 +142,9 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) char *openssl_privatekey; uint32_t openssl_privatekey_len; /* phar_get_archive cache */ - char* last_phar_name; - uint32_t last_phar_name_len; + const zend_string *last_phar_name; uint32_t last_alias_len; - char* last_alias; + const char* last_alias; phar_archive_data* last_phar; HashTable mime_types; ZEND_END_MODULE_GLOBALS(phar) @@ -219,7 +212,7 @@ typedef struct _phar_entry_info { unsigned int fileinfo_lock_count; char *tmp; phar_archive_data *phar; - char *link; /* symbolic link to another file */ + zend_string *symlink; char tar_type; /* position in the manifest */ uint32_t manifest_pos; @@ -245,11 +238,10 @@ typedef struct _phar_entry_info { /* information about a phar file (the archive itself) */ struct _phar_archive_data { - char *fname; - uint32_t fname_len; - /* for phar_detect_fname_ext, this stores the location of the file extension within fname */ + zend_string *fname; + /* The ext field stores the location of the file extension from the fname field, and thus should never be freed. */ uint32_t ext_len; - char *ext; + const char *ext; char *alias; uint32_t alias_len; char version[12]; @@ -380,27 +372,51 @@ static inline bool phar_validate_alias(const char *alias, size_t alias_len) /* { } /* }}} */ -static inline void phar_set_inode(phar_entry_info *entry) /* {{{ */ +static inline bool phar_path_is_magic_phar_ex(const char *path, size_t path_len) /* {{{ */ { - char tmp[MAXPATHLEN]; - size_t tmp_len; - size_t len1, len2; + if (path_len > 0 && path[0] == '/') { + path++; + path_len--; + } - tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + entry->phar->fname_len); + if (path_len < sizeof(".phar") - 1 || memcmp(path, ".phar", sizeof(".phar") - 1) != 0) { + return false; + } - len1 = MIN(entry->phar->fname_len, tmp_len); - if (entry->phar->fname) { - memcpy(tmp, entry->phar->fname, len1); + if (path_len == sizeof(".phar") - 1) { + return true; } - len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename)); - memcpy(tmp + len1, entry->filename, len2); + return path[sizeof(".phar") - 1] == '/' || path[sizeof(".phar") - 1] == '\\'; +} +/* }}} */ - entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len); +static inline bool phar_is_magic_phar(const zend_string *path) /* {{{ */ +{ + return phar_path_is_magic_phar_ex(ZSTR_VAL(path), ZSTR_LEN(path)); +} +/* }}} */ + +static inline void phar_set_inode(phar_entry_info *entry) /* {{{ */ +{ + if (entry->phar->fname) { + char tmp[MAXPATHLEN]; + size_t tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + ZSTR_LEN(entry->phar->fname)); + + size_t len1 = MIN(ZSTR_LEN(entry->phar->fname), tmp_len); + memcpy(tmp, ZSTR_VAL(entry->phar->fname), len1); + + size_t len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename)); + memcpy(tmp + len1, entry->filename, len2); + + entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len); + } else { + entry->inode = (unsigned short) zend_string_hash_val(entry->filename); + } } /* }}} */ -static inline bool phar_entry_can_remove(phar_entry_info *entry) +static inline bool phar_entry_can_remove(const phar_entry_info *entry) { return entry->fp_refcount == 0 && entry->fileinfo_lock_count == 0; } @@ -411,25 +427,25 @@ void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); -zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); -zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); -zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); -ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); +zend_result phar_open_from_filename(char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_filename(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_create_or_parse_filename(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error); +zend_result phar_free_alias(const phar_archive_data *phar); +phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error); /* utility functions */ zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error); -const char *phar_decompress_filter(const phar_entry_info *entry, bool return_unknown); -const char *phar_compress_filter(const phar_entry_info *entry, bool return_unknown); +const char *phar_get_decompress_filter_name(const phar_entry_info *entry); +const char *phar_get_compress_filter_name(const phar_entry_info *entry); /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */ -void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); -zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); -zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar); -char *phar_fix_filepath(char *path, size_t *new_len, bool use_cwd); +void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len); +zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size_t filename_len, char *path, size_t path_len); + zend_string *phar_find_in_include_path(const zend_string *file); +zend_string* phar_fix_filepath(const char *path, size_t path_length, bool use_cwd); ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data *phar, phar_entry_info *entry, char **error); void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent); bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, bool persistent); @@ -450,13 +466,13 @@ zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ bool phar_is_tar(const char *buf, const char *fname); -zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, phar_archive_data** pphar, uint32_t compression, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_tar(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); /* zip functions in zip.c */ -zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_zip(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); #ifdef PHAR_MAIN @@ -471,12 +487,13 @@ void phar_entry_delref(phar_entry_data *idata); phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, bool security); phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, bool security); -ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp); -ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security); +ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp); +ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, const zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); ZEND_ATTRIBUTE_NONNULL int phar_flush(phar_archive_data *archive, char **error); zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, bool is_complete); -zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); +zend_string* phar_split_fname_ex(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create, const char **error); +zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create); typedef enum { pcr_use_query, diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index d4b084217b5b..0139f0889a81 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -46,7 +44,6 @@ static zend_class_entry *phar_ce_entry; static int phar_file_type(const HashTable *mimes, const char *file, char **mime_type) /* {{{ */ { - phar_mime_type *mime; const char *ext = strrchr(file, '.'); if (!ext) { *mime_type = "text/plain"; @@ -54,7 +51,9 @@ static int phar_file_type(const HashTable *mimes, const char *file, char **mime_ return PHAR_MIME_OTHER; } ++ext; - if (NULL == (mime = zend_hash_str_find_ptr(mimes, ext, strlen(ext)))) { + + phar_mime_type *mime = zend_hash_str_find_ptr(mimes, ext, strlen(ext)); + if (!mime) { *mime_type = "application/octet-stream"; return PHAR_MIME_OTHER; } @@ -66,7 +65,6 @@ static int phar_file_type(const HashTable *mimes, const char *file, char **mime_ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, const char *basename, size_t request_uri_len) /* {{{ */ { HashTable *_SERVER; - zval *stuff; char *path_info; size_t basename_len = strlen(basename); size_t code; @@ -80,23 +78,25 @@ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, co _SERVER = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); /* PATH_INFO and PATH_TRANSLATED should always be munged */ - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO")-1))) { + zval *stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PATH_INFO")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > (size_t)entry_len && !memcmp(path_info, entry, entry_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + entry_len, request_uri_len); - zend_hash_str_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PATH_INFO"), &temp); } } - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PATH_TRANSLATED")); + if (stuff) { zend_string *str = strpprintf(4096, "phar://%s%s", fname, entry); ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_NEW_STR(stuff, str); - zend_hash_str_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PATH_TRANSLATED"), &temp); } if (!PHAR_G(phar_SERVER_mung_list)) { @@ -104,46 +104,50 @@ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, co } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_REQUEST_URI) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("REQUEST_URI")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > basename_len && !memcmp(path_info, basename, basename_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len); - zend_hash_str_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_REQUEST_URI"), &temp); } } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_PHP_SELF) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PHP_SELF")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > basename_len && !memcmp(path_info, basename, basename_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len); - zend_hash_str_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PHP_SELF"), &temp); } } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_SCRIPT_NAME) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("SCRIPT_NAME")); + if (stuff) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, entry, entry_len); - zend_hash_str_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_SCRIPT_NAME"), &temp); } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_SCRIPT_FILENAME) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("SCRIPT_FILENAME")); + if (stuff) { zend_string *str = strpprintf(4096, "phar://%s%s", fname, entry); ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_NEW_STR(stuff, str); - zend_hash_str_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_SCRIPT_FILENAME"), &temp); } } } @@ -321,10 +325,9 @@ static void phar_do_403(void) /* {{{ */ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, zend_string *f404) /* {{{ */ { sapi_header_line ctr = {0}; - phar_entry_info *info; if (phar && f404 && ZSTR_LEN(f404)) { - info = phar_get_entry_info(phar, ZSTR_VAL(f404), ZSTR_LEN(f404), NULL, true); + phar_entry_info *info = phar_get_entry_info(phar, ZSTR_VAL(f404), ZSTR_LEN(f404), NULL, true); if (info) { /* Status doesn't matter, we're exiting anyway. */ @@ -346,9 +349,10 @@ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, /* post-process REQUEST_URI and retrieve the actual request URI. This is for cases like http://localhost/blah.phar/path/to/file.php/extra/stuff which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */ -static void phar_postprocess_ru_web(char *fname, size_t fname_len, char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ +static void phar_postprocess_ru_web(const char *fname, size_t fname_len, char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ { - char *e = entry + 1, *u1 = NULL, *u = NULL, *saveu = NULL; + char *e = entry + 1; + char *u1 = NULL, *u = NULL, *saveu = NULL; size_t e_len = *entry_len - 1, u_len = 0; phar_archive_data *pphar; @@ -405,33 +409,27 @@ static void phar_postprocess_ru_web(char *fname, size_t fname_len, char *entry, */ PHP_METHOD(Phar, running) { - zend_string *fname; - char *arch; - size_t arch_len; bool retphar = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &retphar) == FAILURE) { RETURN_THROWS(); } - fname = zend_get_executed_filename_ex(); + const zend_string *fname = zend_get_executed_filename_ex(); if (!fname) { RETURN_EMPTY_STRING(); } - if ( - zend_string_starts_with_literal_ci(fname, "phar://") - && SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 2, 0) - ) { - if (retphar) { - RETVAL_STRINGL(ZSTR_VAL(fname), arch_len + 7); - efree(arch); - return; - } else { - // TODO: avoid reallocation ??? - RETVAL_STRINGL(arch, arch_len); - efree(arch); - return; + if (zend_string_starts_with_literal_ci(fname, "phar://")) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { + if (retphar) { + RETVAL_STRINGL(ZSTR_VAL(fname), ZSTR_LEN(arch) + 7); + zend_string_release_ex(arch, false); + return; + } else { + RETURN_STR(arch); + } } } @@ -446,8 +444,8 @@ PHP_METHOD(Phar, running) */ PHP_METHOD(Phar, mount) { - char *fname, *arch = NULL, *entry = NULL, *path, *actual; - size_t fname_len, arch_len, entry_len; + char *fname, *path, *actual; + size_t fname_len; size_t path_len, actual_len; phar_archive_data *pphar; #ifdef PHP_WIN32 @@ -478,41 +476,39 @@ PHP_METHOD(Phar, mount) } #endif - if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, NULL, NULL, 2, 0)) { - entry = NULL; - + zend_string *entry = NULL; + zend_string *arch = NULL; + if (fname_len > 7 && !memcmp(fname, "phar://", 7) && (arch = phar_split_fname(fname, fname_len, NULL, 2, 0))) { if (path_len > 7 && !memcmp(path, "phar://", 7)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Can only mount internal paths within a phar archive, use a relative path instead of \"%s\"", path); - efree(arch); + zend_string_release_ex(arch, false); goto finish; } carry_on2: - if (NULL == (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len))) { - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len))) { + pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), arch); + if (!pphar) { + if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_find_ptr(&cached_phars, arch))) { if (SUCCESS == phar_copy_on_write(&pphar)) { goto carry_on; } } - zend_throw_exception_ex(phar_ce_PharException, 0, "%s is not a phar archive, cannot mount", arch); - - if (arch) { - efree(arch); - } + zend_throw_exception_ex(phar_ce_PharException, 0, "%s is not a phar archive, cannot mount", ZSTR_VAL(arch)); + zend_string_release_ex(arch, false); goto finish; } carry_on: if (SUCCESS != phar_mount_entry(pphar, actual, actual_len, path, path_len)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, arch); + zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, ZSTR_VAL(arch)); } - if (entry && path == entry) { - efree(entry); + if (entry && path == ZSTR_VAL(entry)) { + zend_string_release_ex(entry, false); } if (arch) { - efree(arch); + zend_string_release_ex(arch, false); } goto finish; @@ -524,9 +520,9 @@ PHP_METHOD(Phar, mount) } goto carry_on; - } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { - path = entry; - path_len = entry_len; + } else if ((arch = phar_split_fname(path, path_len, &entry, 2, 0))) { + path = ZSTR_VAL(entry); + path_len = ZSTR_LEN(entry); goto carry_on2; } @@ -553,8 +549,8 @@ PHP_METHOD(Phar, webPhar) zval *mimeoverride = NULL; zend_fcall_info rewrite_fci = {0}; zend_fcall_info_cache rewrite_fcc; - char *alias = NULL, *error, *index_php = NULL, *ru = NULL; - size_t alias_len = 0, free_pathinfo = 0; + char *error, *index_php = NULL, *ru = NULL; + size_t free_pathinfo = 0; zend_string *f404 = NULL; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; @@ -566,14 +562,15 @@ PHP_METHOD(Phar, webPhar) phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); phar_action_status status = PHAR_ACT_DO_EXIT; + zend_string *alias = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!S!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!s!S!af!", &alias, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { + if (phar_open_executed_filename(alias, &error) != SUCCESS) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); @@ -650,7 +647,12 @@ PHP_METHOD(Phar, webPhar) } else { char *testit = sapi_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1); - if (!(pt = strstr(testit, basename))) { + if (!testit) { + goto finish; + } + + pt = strstr(testit, basename); + if (!pt) { efree(testit); goto finish; } @@ -676,7 +678,8 @@ PHP_METHOD(Phar, webPhar) } else { path_info = SG(request_info).request_uri; - if (!(pt = strstr(path_info, basename))) { + pt = strstr(path_info, basename); + if (!pt) { /* this can happen with rewrite rules - and we have no idea what to do then, so return */ goto finish; } @@ -751,8 +754,8 @@ PHP_METHOD(Phar, webPhar) entry_len = sizeof("/index.php")-1; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || - (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { + phar = phar_get_archive(fname, fname_len, NULL, 0, NULL); + if (!phar || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { phar_do_404(phar, fname, fname_len, f404); } else { char *tmp = NULL, sa = '\0'; @@ -792,8 +795,8 @@ PHP_METHOD(Phar, webPhar) goto cleanup_skip_entry; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || - (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { + phar = phar_get_archive(fname, fname_len, NULL, 0, NULL); + if (!phar || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { phar_do_404(phar, fname, fname_len, f404); goto cleanup; } @@ -945,17 +948,17 @@ PHP_METHOD(Phar, createDefaultStub) /* {{{ Reads the currently executed file (a phar) and registers its manifest */ PHP_METHOD(Phar, mapPhar) { - char *alias = NULL, *error; - size_t alias_len = 0; + zend_string *alias = NULL; + char *error; zend_long dataoffset = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!l", &alias, &alias_len, &dataoffset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!l", &alias, &dataoffset) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error) == SUCCESS); + RETVAL_BOOL(phar_open_executed_filename(alias, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -966,16 +969,17 @@ PHP_METHOD(Phar, mapPhar) /* {{{ Loads any phar archive with an alias */ PHP_METHOD(Phar, loadPhar) { - char *fname, *alias = NULL, *error; - size_t fname_len, alias_len = 0; + zend_string *fname; + zend_string *alias = NULL; + char *error; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &fname, &alias) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); + RETVAL_BOOL(phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -1080,9 +1084,9 @@ static const spl_other_handler phar_spl_foreign_handler = { */ PHP_METHOD(Phar, __construct) { - char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname; - size_t fname_len, alias_len = 0; - size_t arch_len, entry_len; + zend_string *fname; + zend_string *alias = NULL; + char *error; bool is_data; zend_long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS; zend_long format = 0; @@ -1095,11 +1099,11 @@ PHP_METHOD(Phar, __construct) is_data = instanceof_function(Z_OBJCE_P(ZEND_THIS), phar_ce_data); if (is_data) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|lS!l", &fname, &flags, &alias, &format) == FAILURE) { RETURN_THROWS(); } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|lS!", &fname, &flags, &alias) == FAILURE) { RETURN_THROWS(); } } @@ -1109,33 +1113,25 @@ PHP_METHOD(Phar, __construct) RETURN_THROWS(); } - save_fname = fname; - if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2)) { + zend_string *entry = NULL; + /* phar_split_fname() will unixify the path */ + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &entry, !is_data, 2); + if (arch) { /* use arch (the basename for the archive) for fname instead of fname */ /* this allows support for RecursiveDirectoryIterator of subdirectories */ -#ifdef PHP_WIN32 - phar_unixify_path_separators(arch, arch_len); -#endif fname = arch; - fname_len = arch_len; -#ifdef PHP_WIN32 - } else { - arch = estrndup(fname, fname_len); - arch_len = fname_len; - fname = arch; - phar_unixify_path_separators(arch, arch_len); -#endif } - if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + zend_result phar_status = phar_open_or_create_filename(fname, alias, is_data, REPORT_ERRORS, &phar_data, &error); - if (fname == arch && fname != save_fname) { - efree(arch); - fname = save_fname; - } + if (arch) { + zend_string_release_ex(arch, false); + } + + if (phar_status == FAILURE) { if (entry) { - efree(entry); + zend_string_release_ex(entry, false); } if (error) { @@ -1155,11 +1151,6 @@ PHP_METHOD(Phar, __construct) phar_data->is_tar = false; } - if (fname == arch) { - efree(arch); - fname = save_fname; - } - if ((is_data && !phar_data->is_data) || (!is_data && phar_data->is_data)) { if (is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, @@ -1168,7 +1159,7 @@ PHP_METHOD(Phar, __construct) zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Phar class can only be used for executable tar and zip archives"); } - efree(entry); + zend_string_release_ex(entry, false); RETURN_THROWS(); } @@ -1181,20 +1172,29 @@ PHP_METHOD(Phar, __construct) phar_obj->archive = phar_data; phar_obj->spl.oth_handler = &phar_spl_foreign_handler; + zend_string *file_name_for_recursive_director_iterator_constructor; if (entry) { - fname_len = spprintf(&fname, 0, "phar://%s%s", phar_data->fname, entry); - efree(entry); + file_name_for_recursive_director_iterator_constructor = zend_string_concat3( + ZEND_STRL("phar://"), + ZSTR_VAL(phar_data->fname), ZSTR_LEN(phar_data->fname), + ZSTR_VAL(entry), ZSTR_LEN(entry) + ); + zend_string_release_ex(entry, false); } else { - fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname); + file_name_for_recursive_director_iterator_constructor = zend_string_concat2( + ZEND_STRL("phar://"), + ZSTR_VAL(phar_data->fname), ZSTR_LEN(phar_data->fname) + ); } - ZVAL_STRINGL(&arg1, fname, fname_len); + ZVAL_STR(&arg1, file_name_for_recursive_director_iterator_constructor); ZVAL_LONG(&arg2, flags); zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor, Z_OBJ_P(ZEND_THIS), NULL, &arg1, &arg2); - zval_ptr_dtor(&arg1); + /* Freeing arg1 */ + zend_string_release_ex(file_name_for_recursive_director_iterator_constructor, false); if (!phar_data->is_persistent) { phar_obj->archive->is_data = is_data; @@ -1204,7 +1204,6 @@ PHP_METHOD(Phar, __construct) } phar_obj->spl.info_class = phar_ce_entry; - efree(fname); } /* }}} */ @@ -1254,64 +1253,62 @@ PHP_METHOD(Phar, getSupportedCompression) /* {{{ Completely remove a phar archive from memory and disk */ PHP_METHOD(Phar, unlinkArchive) { - char *fname, *error, *arch; - size_t fname_len; - size_t arch_len; + char *error; + zend_string *fname; phar_archive_data *phar; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &fname) == FAILURE) { RETURN_THROWS(); } - if (!fname_len) { + if (ZSTR_LEN(fname) == 0) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"\""); RETURN_THROWS(); } - if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, 0, REPORT_ERRORS, &phar, &error)) { + if (FAILURE == phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, REPORT_ERRORS, &phar, &error)) { if (error) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", fname, error); + zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", ZSTR_VAL(fname), error); efree(error); } else { - zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\"", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\"", ZSTR_VAL(fname)); } RETURN_THROWS(); } - zend_string *zend_file_name = zend_get_executed_filename_ex(); - - if ( - zend_file_name - && zend_string_starts_with_literal_ci(zend_file_name, "phar://") - && SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, NULL, NULL, 2, 0) - ) { - if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", fname); - efree(arch); - RETURN_THROWS(); + const zend_string *zend_file_name = zend_get_executed_filename_ex(); + if (zend_file_name && zend_string_starts_with_literal_ci(zend_file_name, "phar://")) { + zend_string *arch = phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), NULL, 2, 0); + if (arch) { + if (zend_string_equals(arch, fname)) { + zend_string_release_ex(arch, false); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", ZSTR_VAL(fname)); + RETURN_THROWS(); + } + zend_string_release_ex(arch, false); } - efree(arch); } if (phar->is_persistent) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" is in phar.cache_list, cannot unlinkArchive()", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" is in phar.cache_list, cannot unlinkArchive()", ZSTR_VAL(fname)); RETURN_THROWS(); } if (phar->refcount) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", ZSTR_VAL(fname)); RETURN_THROWS(); } - fname = estrndup(phar->fname, phar->fname_len); + fname = zend_string_copy(phar->fname); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; phar_archive_delref(phar); - unlink(fname); - efree(fname); + unlink(ZSTR_VAL(fname)); + zend_string_release(fname); RETURN_TRUE; } /* }}} */ @@ -1347,7 +1344,7 @@ static zend_always_inline void phar_call_method_with_unwrap(zend_object *obj, co } /* This is the same as phar_get_or_create_entry_data(), but allows overriding metadata via SplFileInfo. */ -static phar_entry_data *phar_build_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, char **error, zval *file_info) +static phar_entry_data *phar_build_entry_data(zend_string *fname, char *path, size_t path_len, char **error, zval *file_info) { uint32_t timestamp; @@ -1373,7 +1370,7 @@ static phar_entry_data *phar_build_entry_data(char *fname, size_t fname_len, cha timestamp = time(NULL); } - return phar_get_or_create_entry_data(fname, fname_len, path, path_len, "w+b", 0, error, true, timestamp); + return phar_get_or_create_entry_data(fname, path, path_len, "w+b", 0, error, true, timestamp); } static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ @@ -1615,7 +1612,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } after_open_fp: - if (str_key_len >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) { + if (phar_path_is_magic_phar_ex(str_key, str_key_len)) { /* silently skip any files that would be added to the magic .phar directory */ if (save) { efree(save); @@ -1636,7 +1633,8 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_KEEP; } - if (!(data = phar_build_entry_data(phar_obj->archive->fname, phar_obj->archive->fname_len, str_key, str_key_len, &error, value))) { + data = phar_build_entry_data(phar_obj->archive->fname, str_key, str_key_len, &error, value); + if (!data) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s cannot be created: %s", str_key, error); efree(error); @@ -1659,9 +1657,6 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } else { - if (error) { - efree(error); - } /* convert to PHAR_UFP */ if (data->internal_file->fp_type == PHAR_MOD) { php_stream_close(data->internal_file->fp); @@ -1770,7 +1765,7 @@ PHP_METHOD(Phar, buildFromDirectory) if (apply_reg) { zval_ptr_dtor(®exiter); } - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" unable to create temporary file", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" unable to create temporary file", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1780,7 +1775,7 @@ PHP_METHOD(Phar, buildFromDirectory) zval_ptr_dtor(®exiter); } php_stream_close(pass.fp); - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1838,7 +1833,7 @@ PHP_METHOD(Phar, buildFromIterator) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1851,7 +1846,7 @@ PHP_METHOD(Phar, buildFromIterator) pass.count = 0; pass.fp = php_stream_fopen_tmpfile(); if (pass.fp == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\": unable to create temporary file", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\": unable to create temporary file", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1915,16 +1910,16 @@ static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *f char *error; zend_off_t offset; - ZEND_ASSERT(!entry->link); + ZEND_ASSERT(!entry->symlink); if (FAILURE == phar_open_entry_fp(entry, &error, true)) { if (error) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", entry->phar->fname, ZSTR_VAL(entry->filename), error); + "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename), error); efree(error); } else { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents", entry->phar->fname, ZSTR_VAL(entry->filename)); + "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return FAILURE; } @@ -1934,7 +1929,7 @@ static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *f offset = php_stream_tell(fp); if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), fp, entry->uncompressed_filesize, NULL)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", entry->phar->fname, ZSTR_VAL(entry->filename)); + "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -1947,17 +1942,15 @@ static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *f static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* {{{ */ { - const char *oldname = NULL; phar_archive_data *phar = *sphar; - char *oldpath = NULL; char *basename = NULL, *basepath = NULL; - char *newname = NULL, *newpath = NULL; + char *newname = NULL; zval ret, arg1; zend_class_entry *ce; char *error = NULL; const char *pcr_error; size_t ext_len = ext ? strlen(ext) : 0; - size_t new_len, oldname_len, phar_ext_len; + size_t phar_ext_len; phar_archive_data *pphar = NULL; php_stream_statbuf ssb; @@ -2029,34 +2022,38 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } else if (phar_path_check(&ext, &ext_len, &pcr_error) > pcr_is_ok) { if (phar->is_data) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar converted from \"%s\" has invalid extension %s", phar->fname, ext); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar converted from \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar converted from \"%s\" has invalid extension %s", phar->fname, ext); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar converted from \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); } return NULL; } - oldpath = estrndup(phar->fname, phar->fname_len); - if ((oldname = zend_memrchr(phar->fname, '/', phar->fname_len))) { - ++oldname; + zend_string *old_path = zend_string_copy(phar->fname); + + const char *old_name = zend_memrchr(ZSTR_VAL(phar->fname), '/', ZSTR_LEN(phar->fname)); + size_t old_name_len; + if (old_name) { + ++old_name; + old_name_len = strlen(old_name); } else { - oldname = phar->fname; + old_name = ZSTR_VAL(phar->fname); + old_name_len = ZSTR_LEN(phar->fname); } - oldname_len = strlen(oldname); /* Copy the old name to create base for the new name */ - basename = estrndup(oldname, oldname_len); + basename = estrndup(old_name, old_name_len); phar_ext_list_len = sizeof(phar_ext_list)/sizeof(phar_ext_list[0]); /* Remove possible PHAR extensions */ /* phar_ext_list must be in order of longest extension to shortest */ for (i=0; i < phar_ext_list_len; i++) { phar_ext_len = strlen(phar_ext_list[i]); - if (phar_ext_len && oldname_len > phar_ext_len) { + if (phar_ext_len && old_name_len > phar_ext_len) { /* Check if the basename strings ends with the extension */ - if (memcmp(phar_ext_list[i], basename + (oldname_len - phar_ext_len), phar_ext_len) == 0) { - ext_pos = basename + (oldname_len - phar_ext_len); + if (memcmp(phar_ext_list[i], basename + (old_name_len - phar_ext_len), phar_ext_len) == 0) { + ext_pos = basename + (old_name_len - phar_ext_len); ext_pos[0] = '\0'; break; } @@ -2080,21 +2077,21 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* spprintf(&newname, 0, "%s.%s", basename, ext); efree(basename); - basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); - new_len = spprintf(&newpath, 0, "%s%s", basepath, newname); - phar->fname_len = new_len; + basepath = estrndup(ZSTR_VAL(old_path), (ZSTR_LEN(old_path) - old_name_len)); + + zend_string *newpath = strpprintf(0, "%s%s", basepath, newname); + phar->ext = ZSTR_VAL(newpath) + ZSTR_LEN(newpath) - strlen(ext) - 1; phar->fname = newpath; - phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); efree(newname); - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", phar->fname); + if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_find_ptr(&cached_phars, newpath))) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", ZSTR_VAL(phar->fname)); goto err_oldpath; } - if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len))) { - if (pphar->fname_len == phar->fname_len && !memcmp(pphar->fname, phar->fname, phar->fname_len)) { + if (NULL != (pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), newpath))) { + if (zend_string_equals(pphar->fname, phar->fname)) { if (!zend_hash_num_elements(&phar->manifest)) { pphar->is_tar = phar->is_tar; pphar->is_zip = phar->is_zip; @@ -2109,22 +2106,22 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* phar = pphar; /* NOTE: this phar is now reused, so the refcount must be increased. */ phar->refcount++; - newpath = oldpath; + newpath = old_path; goto its_ok; } } - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", phar->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", ZSTR_VAL(phar->fname)); goto err_oldpath; } its_ok: - if (SUCCESS == php_stream_stat_path(newpath, &ssb)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" exists and must be unlinked prior to conversion", newpath); + if (SUCCESS == php_stream_stat_path(ZSTR_VAL(newpath), &ssb)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" exists and must be unlinked prior to conversion", ZSTR_VAL(newpath)); goto err_reused_oldpath; } if (!phar->is_data) { - if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &ext_len, 1, 1, true)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" has invalid extension %s", phar->fname, ext); + if (SUCCESS != phar_detect_phar_fname_ext(ZSTR_VAL(newpath), ZSTR_LEN(newpath), &(phar->ext), &ext_len, 1, 1, true)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); goto err_reused_oldpath; } phar->ext_len = ext_len; @@ -2137,17 +2134,17 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* phar->alias = NULL; phar->alias_len = 0; } else { - phar->alias = pestrndup(newpath, strlen(newpath), phar->is_persistent); - phar->alias_len = strlen(newpath); + phar->alias = pestrndup(ZSTR_VAL(newpath), ZSTR_LEN(newpath), phar->is_persistent); + phar->alias_len = ZSTR_LEN(newpath); phar->is_temporary_alias = 1; - zend_hash_str_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar->fname_len, phar); + zend_hash_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar); } } } else { - if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &ext_len, 0, 1, true)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar \"%s\" has invalid extension %s", phar->fname, ext); + if (SUCCESS != phar_detect_phar_fname_ext(ZSTR_VAL(newpath), ZSTR_LEN(newpath), &(phar->ext), &ext_len, 0, 1, true)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); goto err_reused_oldpath; } phar->ext_len = ext_len; @@ -2159,22 +2156,22 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } } - if ((!pphar || phar == pphar) && NULL == zend_hash_str_update_ptr(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len, phar)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname); + if ((!pphar || phar == pphar) && NULL == zend_hash_update_ptr(&(PHAR_G(phar_fname_map)), newpath, phar)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars", ZSTR_VAL(phar->fname)); goto err_oldpath; } phar_flush_ex(phar, NULL, true, &error); if (error) { - zend_hash_str_del(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), newpath); *sphar = NULL; zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s", error); efree(error); goto err_oldpath; } - efree(oldpath); + zend_string_release(old_path); if (phar->is_data) { ce = phar_ce_data; @@ -2182,9 +2179,8 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* ce = phar_ce_archive; } - ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len); + ZVAL_STR(&arg1, phar->fname); zend_result result = object_init_with_constructor(&ret, ce, 1, &arg1, NULL); - zval_ptr_dtor_str(&arg1); if (SUCCESS != result) { return NULL; } @@ -2197,7 +2193,7 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } /* fallthrough */ err_oldpath: - efree(oldpath); + zend_string_release(old_path); return NULL; } /* }}} */ @@ -2210,7 +2206,8 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; php_stream *tmp_fp = php_stream_fopen_tmpfile(); if (tmp_fp == NULL) { @@ -2244,7 +2241,6 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert phar->fp = tmp_fp; phar->fname = source->fname; - phar->fname_len = source->fname_len; phar->is_temporary_alias = source->is_temporary_alias; phar->alias = source->alias; @@ -2255,8 +2251,8 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert newentry = *entry; - if (newentry.link) { - newentry.link = estrdup(newentry.link); + if (newentry.symlink) { + zend_string_addref(newentry.symlink); goto no_copy; } @@ -2314,7 +2310,7 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert if (phar->fname != source->fname) { /* Depending on when phar_rename_archive() errors, the new filename * may have already been assigned or it may still be the old one. */ - efree(phar->fname); + zend_string_release(phar->fname); } efree(phar); } @@ -2576,7 +2572,7 @@ PHP_METHOD(Phar, isWritable) RETURN_FALSE; } - if (SUCCESS != php_stream_stat_path(phar_obj->archive->fname, &ssb)) { + if (SUCCESS != php_stream_stat_path(ZSTR_VAL(phar_obj->archive->fname), &ssb)) { /* assume it works if the file doesn't exist yet */ RETURN_BOOL(phar_obj->archive->is_brandnew); } @@ -2605,7 +2601,7 @@ PHP_METHOD(Phar, delete) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { @@ -2640,7 +2636,7 @@ PHP_METHOD(Phar, getAlias) PHAR_ARCHIVE_OBJECT(); - if (phar_obj->archive->alias && phar_obj->archive->alias != phar_obj->archive->fname) { + if (phar_obj->archive->alias) { RETURN_STRINGL(phar_obj->archive->alias, phar_obj->archive->alias_len); } } @@ -2653,7 +2649,7 @@ PHP_METHOD(Phar, getPath) PHAR_ARCHIVE_OBJECT(); - RETURN_STRINGL(phar_obj->archive->fname, phar_obj->archive->fname_len); + RETURN_STR_COPY(phar_obj->archive->fname); } /* }}} */ @@ -2682,7 +2678,8 @@ PHP_METHOD(Phar, setAlias) /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; if (phar_obj->archive->is_data) { if (phar_obj->archive->is_tar) { @@ -2699,17 +2696,17 @@ PHP_METHOD(Phar, setAlias) RETURN_TRUE; } if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), new_alias))) { - if (SUCCESS != phar_free_alias(fd_ptr, ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), fd_ptr->fname); + if (SUCCESS != phar_free_alias(fd_ptr)) { + zend_throw_exception_ex(phar_ce_PharException, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), ZSTR_VAL(fd_ptr->fname)); RETURN_THROWS(); } } else if (!phar_validate_alias(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), phar_obj->archive->fname); + "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (phar_obj->archive->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias, phar_obj->archive->alias_len))) { @@ -2854,7 +2851,7 @@ PHP_METHOD(Phar, setStub) if ((php_stream_from_zval_no_verify(stream, zstub)) != NULL) { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -2866,7 +2863,7 @@ PHP_METHOD(Phar, setStub) } if (stub_file_content == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "unable to read resource to copy stub to new phar \"%s\"", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "unable to read resource to copy stub to new phar \"%s\"", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -2884,7 +2881,7 @@ PHP_METHOD(Phar, setStub) } } else if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &stub) == SUCCESS) { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ false, &error); @@ -2965,7 +2962,7 @@ PHP_METHOD(Phar, setDefaultStub) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ true, &error); @@ -3016,7 +3013,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) case PHAR_SIG_OPENSSL_SHA256: case PHAR_SIG_OPENSSL_SHA512: if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_obj->archive->sig_flags = (uint32_t)algo; @@ -3326,7 +3323,7 @@ PHP_METHOD(Phar, compressFiles) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } pharobj_set_compression(&phar_obj->archive->manifest, flags); @@ -3365,7 +3362,7 @@ PHP_METHOD(Phar, decompressFiles) RETURN_TRUE; } else { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } pharobj_set_compression(&phar_obj->archive->manifest, PHAR_ENT_COMPRESSED_NONE); @@ -3388,7 +3385,7 @@ PHP_METHOD(Phar, copy) { char *error; const char *pcr_error; - phar_entry_info *oldentry, newentry = {0}, *temp; + phar_entry_info newentry = {0}; zend_string *new_file = NULL; zend_string *old_file = NULL; @@ -3404,29 +3401,31 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } - if (zend_string_starts_with_literal(old_file, ".phar")) { + if (phar_is_magic_phar(old_file)) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (zend_string_starts_with_literal(new_file, ".phar")) { + if (phar_is_magic_phar(new_file)) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (NULL == (oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file)) || oldentry->is_deleted) { + phar_entry_info *oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file); + if (!oldentry || oldentry->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (NULL != (temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file)) && !temp->is_deleted) { + const phar_entry_info *temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file); + if (temp && !temp->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -3434,13 +3433,13 @@ PHP_METHOD(Phar, copy) char *tmp_new_file = ZSTR_VAL(new_file); if (phar_path_check(&tmp_new_file, &tmp_len, &pcr_error) > pcr_is_ok) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), phar_obj->archive->fname); + "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (phar_obj->archive->is_persistent) { if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } /* re-populate with copied-on-write entry */ @@ -3496,7 +3495,7 @@ PHP_METHOD(Phar, offsetExists) } /* none of these are real files, so they don't exist */ - RETURN_BOOL(!zend_string_starts_with_literal(file_name, ".phar")); + RETURN_BOOL(!phar_is_magic_phar(file_name)); } else { /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { @@ -3511,7 +3510,6 @@ PHP_METHOD(Phar, offsetExists) PHP_METHOD(Phar, offsetGet) { char *error; - phar_entry_info *entry; zend_string *file_name = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { @@ -3521,30 +3519,31 @@ PHP_METHOD(Phar, offsetGet) PHAR_ARCHIVE_OBJECT(); /* security is 0 here so that we can get a better error message than "entry doesn't exist" */ - if (!(entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, false))) { + phar_entry_info *entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, false); + if (!entry) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", ZSTR_VAL(file_name), error?", ":"", error?error:""); } else { + if (entry->is_temp_dir) { + zend_string_efree(entry->filename); + efree(entry); + } + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (zend_string_starts_with_literal(file_name, ".phar")) { + if (phar_is_magic_phar(file_name)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot directly get any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } - if (entry->is_temp_dir) { - zend_string_efree(entry->filename); - efree(entry); - } - - zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, ZSTR_VAL(file_name)); + zend_string *sfname = strpprintf(0, "phar://%s/%s", ZSTR_VAL(phar_obj->archive->fname), ZSTR_VAL(file_name)); zval zfname; ZVAL_NEW_STR(&zfname, sfname); @@ -3562,7 +3561,6 @@ PHP_METHOD(Phar, offsetGet) static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, const zend_string *content, zval *zresource) { char *error; - phar_entry_data *data; php_stream *contents_file = NULL; php_stream_statbuf ssb; #ifdef PHP_WIN32 @@ -3570,16 +3568,9 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con ALLOCA_FLAG(filename_use_heap) #endif - if ( - zend_string_starts_with_literal(file_name, ".phar") - || zend_string_starts_with_literal(file_name, "/.phar") - ) { - size_t prefix_len = (ZSTR_VAL(file_name)[0] == '/') + sizeof(".phar")-1; - char next_char = ZSTR_VAL(file_name)[prefix_len]; - if (next_char == '/' || next_char == '\\' || next_char == '\0') { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); - return; - } + if (phar_is_magic_phar(file_name)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); + return; } /* TODO How to handle Windows path normalisation with zend_string ? */ @@ -3594,7 +3585,8 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con } #endif - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, filename, filename_len, "w+b", 0, &error, true, time(NULL)))) { + phar_entry_data *data = phar_get_or_create_entry_data((*pphar)->fname, filename, filename_len, "w+b", 0, &error, true, time(NULL)); + if (!data) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be created: %s", filename, error); efree(error); @@ -3603,10 +3595,6 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con } goto finish; } else { - if (error) { - efree(error); - } - if (!data->internal_file->is_dir) { size_t contents_len = 0; if (content) { @@ -3614,11 +3602,13 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con size_t written_len = php_stream_write(data->fp, ZSTR_VAL(content), ZSTR_LEN(content)); if (written_len != contents_len) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); + phar_entry_delref(data); goto finish; } } else { if (!(php_stream_from_zval_no_verify(contents_file, zresource))) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); + phar_entry_delref(data); goto finish; } php_stream_copy_to_stream_ex(contents_file, data->fp, PHP_STREAM_COPY_ALL, &contents_len); @@ -3664,9 +3654,14 @@ finish: ; static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) { char *error; - phar_entry_data *data; - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), "w+b", 2, &error, true, time(NULL)))) { + phar_entry_data *data = phar_get_or_create_entry_data( + (*pphar)->fname, + ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), + "w+b", 2, &error, true, + time(NULL) + ); + if (!data) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", ZSTR_VAL(dir_name), error); efree(error); @@ -3676,10 +3671,6 @@ static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) return; } else { - if (error) { - efree(error); - } - /* check for copy on write */ if (data->phar != *pphar) { *pphar = data->phar; @@ -3715,16 +3706,16 @@ PHP_METHOD(Phar, offsetSet) } if (zend_string_equals_literal(file_name, ".phar/stub.php")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (zend_string_starts_with_literal(file_name, ".phar")) { + if (phar_is_magic_phar(file_name)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3738,7 +3729,6 @@ PHP_METHOD(Phar, offsetUnset) { char *error; zend_string *file_name; - phar_entry_info *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); @@ -3751,32 +3741,32 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } - if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { - if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { - if (entry->is_deleted) { - /* entry is deleted, but has not been flushed to disk yet */ - return; - } + phar_entry_info *entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + if (entry) { + if (entry->is_deleted) { + /* entry is deleted, but has not been flushed to disk yet */ + return; + } - if (phar_obj->archive->is_persistent) { - if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); - RETURN_THROWS(); - } - /* re-populate entry after copy on write */ - entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + if (phar_obj->archive->is_persistent) { + if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); + RETURN_THROWS(); } - entry->is_modified = 0; - entry->is_deleted = 1; - /* we need to "flush" the stream to save the newly deleted file on disk */ - phar_flush(phar_obj->archive, &error); + /* re-populate entry after copy on write */ + entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + } + entry->is_modified = 0; + entry->is_deleted = 1; + /* we need to "flush" the stream to save the newly deleted file on disk */ + phar_flush(phar_obj->archive, &error); - if (error) { - zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); - efree(error); - } + if (error) { + zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); + efree(error); } } + } /* }}} */ @@ -3791,7 +3781,7 @@ PHP_METHOD(Phar, addEmptyDir) PHAR_ARCHIVE_OBJECT(); - if (zend_string_starts_with_literal(dir_name, ".phar")) { + if (phar_is_magic_phar(dir_name)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3805,7 +3795,6 @@ PHP_METHOD(Phar, addFile) { zend_string *file_name; zend_string *local_name = NULL; - php_stream *resource; zval zresource; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &file_name, &local_name) == FAILURE) { @@ -3819,7 +3808,8 @@ PHP_METHOD(Phar, addFile) RETURN_THROWS(); } - if (!(resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL))) { + php_stream *resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL); + if (!resource) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", ZSTR_VAL(file_name)); RETURN_THROWS(); } @@ -3857,32 +3847,29 @@ PHP_METHOD(Phar, getStub) zend_string *buf; php_stream *fp; php_stream_filter *filter = NULL; - phar_entry_info *stub; ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); if (phar_obj->archive->is_tar || phar_obj->archive->is_zip) { + const phar_entry_info *stub = zend_hash_str_find_ptr(&(phar_obj->archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1); - if (NULL != (stub = zend_hash_str_find_ptr(&(phar_obj->archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) { + if (stub) { if (phar_obj->archive->fp && !phar_obj->archive->is_brandnew && !(stub->flags & PHAR_ENT_COMPRESSION_MASK)) { fp = phar_obj->archive->fp; } else { - if (!(fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", 0, NULL))) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to open phar \"%s\"", phar_obj->archive->fname); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", 0, NULL); + if (!fp) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to open phar \"%s\"", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (stub->flags & PHAR_ENT_COMPRESSION_MASK) { - const char *filter_name = phar_decompress_filter(stub, false); - - if (filter_name != NULL) { - filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp)); - } else { - filter = NULL; - } - if (!filter) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", phar_obj->archive->fname, phar_decompress_filter(stub, true)); + const char *decompression_filter_name = phar_get_decompress_filter_name(stub); + ZEND_ASSERT(decompression_filter_name && "Must have as this has a decompression flag set"); + filter = php_stream_filter_create(decompression_filter_name, NULL, php_stream_is_persistent(fp)); + if (UNEXPECTED(filter == NULL)) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", ZSTR_VAL(phar_obj->archive->fname), decompression_filter_name); RETURN_THROWS(); } php_stream_filter_append(&fp->readfilters, filter); @@ -3907,7 +3894,7 @@ PHP_METHOD(Phar, getStub) if (phar_obj->archive->fp && !phar_obj->archive->is_brandnew) { fp = phar_obj->archive->fp; } else { - fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", 0, NULL); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", 0, NULL); } if (!fp) { @@ -4025,7 +4012,7 @@ PHP_METHOD(Phar, setMetadata) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -4093,7 +4080,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result phar_extract_file(bool overwrite, phar return SUCCESS; } - if (zend_string_starts_with_literal(entry->filename, ".phar")) { + if (phar_is_magic_phar(entry->filename)) { return SUCCESS; } /* strip .. from path and restrict it to be under dest directory */ @@ -4149,7 +4136,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result phar_extract_file(bool overwrite, phar } if (php_check_open_basedir(fullpath)) { - spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", openbasedir/safe mode restrictions in effect", ZSTR_VAL(entry->filename), fullpath); + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", open_basedir restrictions in effect", ZSTR_VAL(entry->filename), fullpath); efree(fullpath); efree(new_state.cwd); return FAILURE; @@ -4305,11 +4292,11 @@ PHP_METHOD(Phar, extractTo) PHAR_ARCHIVE_OBJECT(); - fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); if (!fp) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, - "Invalid argument, %s cannot be found", phar_obj->archive->fname); + "Invalid argument, %s cannot be found", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -4354,13 +4341,13 @@ PHP_METHOD(Phar, extractTo) switch (extract_helper(phar_obj->archive, Z_STR_P(zval_file), path_to, overwrite, &error)) { case -1: zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", - phar_obj->archive->fname, error); + ZSTR_VAL(phar_obj->archive->fname), error); efree(error); RETURN_THROWS(); case 0: zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: attempted to extract non-existent file or directory \"%s\" from phar \"%s\"", - ZSTR_VAL(Z_STR_P(zval_file)), phar_obj->archive->fname); + ZSTR_VAL(Z_STR_P(zval_file)), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } } ZEND_HASH_FOREACH_END(); @@ -4370,12 +4357,12 @@ PHP_METHOD(Phar, extractTo) ret = extract_helper(phar_obj->archive, filename, path_to, overwrite, &error); if (-1 == ret) { zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", - phar_obj->archive->fname, error); + ZSTR_VAL(phar_obj->archive->fname), error); efree(error); } else if (0 == ret && NULL != filename) { zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: attempted to extract non-existent file or directory \"%s\" from phar \"%s\"", - ZSTR_VAL(filename), phar_obj->archive->fname); + ZSTR_VAL(filename), ZSTR_VAL(phar_obj->archive->fname)); } else { RETURN_TRUE; } @@ -4386,11 +4373,9 @@ PHP_METHOD(Phar, extractTo) /* {{{ Construct a Phar entry object */ PHP_METHOD(PharFileInfo, __construct) { - char *fname, *arch, *entry, *error; + char *fname, *error; size_t fname_len; - size_t arch_len, entry_len; phar_entry_object *entry_obj; - phar_entry_info *entry_info; phar_archive_data *phar_data; zval arg1; @@ -4405,14 +4390,22 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if (fname_len < 7 || memcmp(fname, "phar://", 7) || phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0) == FAILURE) { + if (fname_len < 7 || memcmp(fname, "phar://", 7)) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, + "'%s' is not a valid phar archive URL (must have at least phar://filename.phar)", fname); + RETURN_THROWS(); + } + + zend_string *entry = NULL; + zend_string *arch = phar_split_fname(fname, fname_len, &entry, 2, 0); + if (!arch) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "'%s' is not a valid phar archive URL (must have at least phar://filename.phar)", fname); RETURN_THROWS(); } - if (phar_open_from_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data, &error) == FAILURE) { - efree(arch); + if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + zend_string_release_ex(arch, false); efree(entry); if (error) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, @@ -4425,16 +4418,18 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if ((entry_info = phar_get_entry_info_dir(phar_data, entry, entry_len, 1, &error, true)) == NULL) { + phar_entry_info *entry_info = phar_get_entry_info_dir(phar_data, ZSTR_VAL(entry), ZSTR_LEN(entry), 1, &error, true); + if (UNEXPECTED(!entry_info)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, - "Cannot access phar file entry '%s' in archive '%s'%s%s", entry, arch, error ? ", " : "", error ? error : ""); - efree(arch); - efree(entry); + "Cannot access phar file entry '%s' in archive '%s'%s%s", + ZSTR_VAL(entry), ZSTR_VAL(arch), error ? ", " : "", error ? error : ""); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); RETURN_THROWS(); } - efree(arch); - efree(entry); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); entry_obj->entry = entry_info; if (!entry_info->is_persistent && !entry_info->is_temp_dir) { @@ -4596,7 +4591,7 @@ PHP_METHOD(PharFileInfo, chmod) } if (PHAR_G(readonly) && !entry_obj->entry->phar->is_data) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Cannot modify permissions for file \"%s\" in phar \"%s\", write operations are prohibited", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "Cannot modify permissions for file \"%s\" in phar \"%s\", write operations are prohibited", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } @@ -4604,7 +4599,7 @@ PHP_METHOD(PharFileInfo, chmod) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4697,7 +4692,7 @@ PHP_METHOD(PharFileInfo, setMetadata) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4745,7 +4740,7 @@ PHP_METHOD(PharFileInfo, delMetadata) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4776,7 +4771,6 @@ PHP_METHOD(PharFileInfo, delMetadata) PHP_METHOD(PharFileInfo, getContent) { char *error; - php_stream *fp; phar_entry_info *link; zend_string *str; @@ -4786,7 +4780,7 @@ PHP_METHOD(PharFileInfo, getContent) if (entry_obj->entry->is_dir) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } @@ -4798,14 +4792,15 @@ PHP_METHOD(PharFileInfo, getContent) if (SUCCESS != phar_open_entry_fp(link, &error, false)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } - if (!(fp = phar_get_efp(link, false))) { + php_stream *fp = phar_get_efp(link, false); + if (!fp) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + "phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } @@ -4859,7 +4854,7 @@ PHP_METHOD(PharFileInfo, compress) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4881,7 +4876,7 @@ PHP_METHOD(PharFileInfo, compress) /* decompress this file indirectly */ if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } @@ -4912,7 +4907,7 @@ PHP_METHOD(PharFileInfo, compress) /* decompress this file indirectly */ if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } @@ -4994,7 +4989,7 @@ PHP_METHOD(PharFileInfo, decompress) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -5015,7 +5010,7 @@ PHP_METHOD(PharFileInfo, decompress) /* decompress this file indirectly */ if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } diff --git a/ext/phar/phar_path_check.re b/ext/phar/phar_path_check.re index 689ffaa51244..39b18bfc0b44 100644 --- a/ext/phar/phar_path_check.re +++ b/ext/phar/phar_path_check.re @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/phar/pharzip.h b/ext/phar/pharzip.h index 5c814747b692..5a827f7a7294 100644 --- a/ext/phar/pharzip.h +++ b/ext/phar/pharzip.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index 18e3485fc3a9..f086f9cfff2d 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 786b19551786..9474498e3892 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar:// stream wrapper support | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -57,38 +55,44 @@ const php_stream_wrapper php_stream_phar_wrapper = { /** * Open a phar file for streams API */ -php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options) /* {{{ */ +php_url* phar_parse_url(php_stream_wrapper *wrapper, php_stream_context *context, + const char *filename, const char *mode, int options) { php_url *resource; - char *arch = NULL, *entry = NULL, *error; - size_t arch_len, entry_len; + char *error; if (strncasecmp(filename, "phar://", 7)) { return NULL; } if (mode[0] == 'a') { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: open mode append not supported"); + php_stream_wrapper_log_warn(wrapper, context, options, ModeNotSupported, + "phar error: open mode append not supported"); } return NULL; } - if (phar_split_fname(filename, strlen(filename), &arch, &arch_len, &entry, &entry_len, 2, (mode[0] == 'w' ? 2 : 0)) == FAILURE) { + + zend_string *entry = NULL; + const char *arch_error = NULL; + zend_string *arch = phar_split_fname_ex(filename, strlen(filename), &entry, 2, (mode[0] == 'w' ? 2 : 0), &arch_error); + if (!arch) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - if (arch && !entry) { - php_stream_wrapper_log_error(wrapper, options, "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", filename, arch); + if (arch_error && !entry) { + php_stream_wrapper_log_warn(wrapper, context, options, InvalidPath, + "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", + filename, arch_error); arch = NULL; } else { - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url or non-existent phar \"%s\"", filename); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url or non-existent phar \"%s\"", filename); } } return NULL; } resource = ecalloc(1, sizeof(php_url)); resource->scheme = ZSTR_INIT_LITERAL("phar", 0); - resource->host = zend_string_init(arch, arch_len, 0); - efree(arch); - resource->path = zend_string_init(entry, entry_len, 0); - efree(entry); + resource->host = arch; + resource->path = entry; #ifdef MBO_0 if (resource) { @@ -111,16 +115,17 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const } if (PHAR_G(readonly) && (!pphar || !pphar->is_data)) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: write operations disabled by the php.ini setting phar.readonly"); + php_stream_wrapper_log_warn(wrapper, context, options, Readonly, + "phar error: write operations disabled by the php.ini setting phar.readonly"); } php_url_free(resource); return NULL; } - if (phar_open_or_create_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, 0, options, &phar, &error) == FAILURE) + if (phar_open_or_create_filename(resource->host, NULL, 0, options, &phar, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, NULL, options, OpenFailed, "%s", error); } efree(error); } @@ -131,7 +136,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const if (error) { spprintf(&error, 0, "Cannot open cached phar '%s' as writeable, copy on write failed", ZSTR_VAL(resource->host)); if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, OpenFailed, "%s", error); } efree(error); } @@ -139,11 +144,11 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const return NULL; } } else { - if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, options, NULL, &error) == FAILURE) + if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, options, NULL, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, "%s", error); } efree(error); } @@ -153,7 +158,6 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const } return resource; } -/* }}} */ /** * used for fopen('phar://...') and company @@ -165,24 +169,26 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha char *internal_file; char *error; HashTable *pharcontext; - php_url *resource = NULL; php_stream *fpf; zval *pzoption, *metadata; - if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, context, path, mode, options); + if (!resource) { return NULL; } /* we must have at the very least phar://alias.phar/internalfile.php */ if (!resource->scheme || !resource->host || !resource->path) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", path); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url \"%s\"", path); return NULL; } if (!zend_string_equals_literal_ci(resource->scheme, "phar")) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", path); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: not a phar stream url \"%s\"", path); return NULL; } @@ -191,26 +197,25 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha /* strip leading "/" */ internal_file = estrndup(ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1); if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) { - if (NULL == (idata = phar_get_or_create_entry_data(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, strlen(internal_file), mode, 0, &error, true, time(NULL)))) { + if (NULL == (idata = phar_get_or_create_entry_data(resource->host, internal_file, strlen(internal_file), mode, 0, &error, true, time(NULL)))) { if (error) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, CreateFailed, "%s", error); efree(error); } else { - php_stream_wrapper_log_error(wrapper, options, "phar error: file \"%s\" could not be created in phar \"%s\"", internal_file, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, CreateFailed, + "phar error: file \"%s\" could not be created in phar \"%s\"", internal_file, ZSTR_VAL(resource->host)); } efree(internal_file); php_url_free(resource); return NULL; } - if (error) { - efree(error); - } fpf = php_stream_alloc(&phar_ops, idata, NULL, mode); php_url_free(resource); efree(internal_file); - if (context && Z_TYPE(context->options) != IS_UNDEF && (pzoption = zend_hash_str_find_ind(HASH_OF(&context->options), "phar", sizeof("phar")-1)) != NULL) { - pharcontext = HASH_OF(pzoption); + if (context && Z_TYPE(context->options) != IS_UNDEF && (pzoption = zend_hash_str_find(Z_ARR(context->options), "phar", sizeof("phar")-1)) != NULL) { + ZEND_ASSERT(Z_TYPE_P(pzoption) == IS_ARRAY); + pharcontext = Z_ARR_P(pzoption); if (idata->internal_file->uncompressed_filesize == 0 && idata->internal_file->compressed_filesize == 0 && (pzoption = zend_hash_str_find_ind(pharcontext, "compress", sizeof("compress")-1)) != NULL @@ -229,25 +234,27 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } } if (opened_path) { - *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%s/%S", idata->phar->fname, idata->internal_file->filename); + *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%S/%S", idata->phar->fname, idata->internal_file->filename); } return fpf; } else { if (!*internal_file && (options & STREAM_OPEN_FOR_INCLUDE)) { /* retrieve the stub */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL)) { - php_stream_wrapper_log_error(wrapper, options, "file %s is not a valid phar archive", ZSTR_VAL(resource->host)); + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL); + if (!phar) { + php_stream_wrapper_log_warn(wrapper, context, options, InvalidFormat, + "file %s is not a valid phar archive", ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); return NULL; } if (phar->is_tar || phar->is_zip) { - if ((FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), ".phar/stub.php", sizeof(".phar/stub.php")-1, "r", 0, &error, false)) || !idata) { + if ((FAILURE == phar_get_entry_data(&idata, resource->host, ".phar/stub.php", sizeof(".phar/stub.php")-1, "r", 0, &error, false)) || !idata) { goto idata_error; } efree(internal_file); if (opened_path) { - *opened_path = strpprintf(MAXPATHLEN, "%s", phar->fname); + *opened_path = zend_string_copy(phar->fname); } php_url_free(resource); goto phar_stub; @@ -256,7 +263,8 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha if (stream == NULL) { stream = phar_open_archive_fp(phar); if (UNEXPECTED(!stream)) { - php_stream_wrapper_log_error(wrapper, options, "phar error: could not reopen phar \"%s\"", ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, OpenFailed, + "phar error: could not reopen phar \"%s\"", ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); return NULL; @@ -283,20 +291,21 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha ++(entry->fp_refcount); php_url_free(resource); if (opened_path) { - *opened_path = strpprintf(MAXPATHLEN, "%s", phar->fname); + *opened_path = zend_string_copy(phar->fname); } efree(internal_file); goto phar_stub; } } /* read-only access is allowed to magic files in .phar directory */ - if ((FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, strlen(internal_file), "r", 0, &error, false)) || !idata) { + if ((FAILURE == phar_get_entry_data(&idata, resource->host, internal_file, strlen(internal_file), "r", 0, &error, false)) || !idata) { idata_error: if (error) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, "%s", error); efree(error); } else { - php_stream_wrapper_log_error(wrapper, options, "phar error: \"%s\" is not a file in phar \"%s\"", internal_file, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "phar error: \"%s\" is not a file in phar \"%s\"", internal_file, ZSTR_VAL(resource->host)); } efree(internal_file); php_url_free(resource); @@ -305,7 +314,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } php_url_free(resource); #ifdef MBO_0 - fprintf(stderr, "Pharname: %s\n", idata->phar->fname); + fprintf(stderr, "Pharname: %s\n", ZSTR_VAL(idata->phar->fname)); fprintf(stderr, "Filename: %s\n", internal_file); fprintf(stderr, "Entry: %s\n", ZSTR_VAL(idata->internal_file->filename)); fprintf(stderr, "Size: %u\n", idata->internal_file->uncompressed_filesize); @@ -314,7 +323,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha /* check length, crc32 */ if (!idata->internal_file->is_crc_checked && phar_postprocess_file(idata, idata->internal_file->crc32, &error, 2) != SUCCESS) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, ArchivingFailed, "%s", error); efree(error); phar_entry_delref(idata); efree(internal_file); @@ -322,7 +331,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } if (!PHAR_G(cwd_init) && (options & STREAM_OPEN_FOR_INCLUDE)) { - char *entry = ZSTR_VAL(idata->internal_file->filename), *cwd; + const char *entry = ZSTR_VAL(idata->internal_file->filename), *cwd; PHAR_G(cwd_init) = 1; if ((idata->phar->is_tar || idata->phar->is_zip) && zend_string_equals_literal(idata->internal_file->filename, ".phar/stub.php")) { @@ -338,7 +347,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } } if (opened_path) { - *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%s/%S", idata->phar->fname, idata->internal_file->filename); + *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%S/%S", idata->phar->fname, idata->internal_file->filename); } efree(internal_file); phar_stub: @@ -353,11 +362,11 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha static int phar_stream_close(php_stream *stream, int close_handle) /* {{{ */ { /* for some reasons phar needs to be flushed even if there is no write going on */ - phar_stream_flush(stream); + int ret = phar_stream_flush(stream); phar_entry_delref((phar_entry_data *)stream->abstract); - return 0; + return ret; } /* }}} */ @@ -368,9 +377,9 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* { phar_entry_data *data = (phar_entry_data *)stream->abstract; ssize_t got; - phar_entry_info *entry; + const phar_entry_info *entry; - if (data->internal_file->link) { + if (data->internal_file->symlink) { entry = phar_get_link_source(data->internal_file); } else { entry = data->internal_file; @@ -398,11 +407,11 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* static int phar_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */ { phar_entry_data *data = (phar_entry_data *)stream->abstract; - phar_entry_info *entry; + const phar_entry_info *entry; int res; zend_ulong temp; - if (data->internal_file->link) { + if (data->internal_file->symlink) { entry = phar_get_link_source(data->internal_file); } else { entry = data->internal_file; @@ -445,7 +454,9 @@ static ssize_t phar_stream_write(php_stream *stream, const char *buf, size_t cou php_stream_seek(data->fp, data->position + data->zero, SEEK_SET); if (count != php_stream_write(data->fp, buf, count)) { - php_stream_wrapper_log_error(stream->wrapper, stream->flags, "phar error: Could not write %zu characters to \"%s\" in phar \"%s\"", count, ZSTR_VAL(data->internal_file->filename), data->phar->fname); + php_stream_warn(stream, WriteFailed, + "phar error: Could not write %zu characters to \"%s\" in phar \"%s\"", + count, ZSTR_VAL(data->internal_file->filename), ZSTR_VAL(data->phar->fname)); return -1; } data->position = php_stream_tell(data->fp) - data->zero; @@ -466,13 +477,13 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ { char *error; int ret; - phar_entry_data *data = (phar_entry_data *) stream->abstract; + const phar_entry_data *data = stream->abstract; if (data->internal_file->is_modified) { data->internal_file->timestamp = time(0); ret = phar_flush(data->phar, &error); if (error) { - php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS, "%s", error); + php_stream_warn(stream, FlushFailed, "%s", error); efree(error); } return ret; @@ -486,7 +497,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ /** * stat an opened phar file handle stream, used by phar_stat() */ -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) +static void phar_dostat(const phar_archive_data *phar, const phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) { memset(ssb, 0, sizeof(php_stream_statbuf)); @@ -540,7 +551,7 @@ void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_stat */ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { - phar_entry_data *data = (phar_entry_data *)stream->abstract; + const phar_entry_data *data = stream->abstract; /* If ssb is NULL then someone is misbehaving */ if (!ssb) { @@ -558,13 +569,11 @@ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context) /* {{{ */ { - php_url *resource = NULL; char *internal_file; - phar_archive_data *phar; - phar_entry_info *entry; size_t internal_file_len; - if ((resource = phar_parse_url(wrapper, url, "r", flags|PHP_STREAM_URL_STAT_QUIET)) == NULL) { + php_url *resource = phar_parse_url(wrapper, context, url, "r", flags|PHP_STREAM_URL_STAT_QUIET); + if (!resource) { return FAILURE; } @@ -583,7 +592,8 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ /* find the phar in our trusty global hash indexed by alias (host of phar://blah.phar/file.whatever) */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL); + if (!phar) { php_url_free(resource); return FAILURE; } @@ -599,7 +609,8 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f } internal_file_len = strlen(internal_file); /* search through the manifest of files, and if we have an exact match, it's a file */ - if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) { + phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + if (entry) { phar_dostat(phar, entry, ssb, false); php_url_free(resource); return SUCCESS; @@ -638,7 +649,9 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f goto free_resource; } efree(test); - if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) { + + entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + if (!entry) { goto free_resource; } phar_dostat(phar, entry, ssb, false); @@ -658,60 +671,64 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f */ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) /* {{{ */ { - php_url *resource; char *internal_file, *error; size_t internal_file_len; phar_entry_data *idata; - phar_archive_data *pphar; - if ((resource = phar_parse_url(wrapper, url, "rb", options)) == NULL) { - php_stream_wrapper_log_error(wrapper, options, "phar error: unlink failed"); + php_url *resource = phar_parse_url(wrapper, context, url, "rb", options); + if (!resource) { + php_stream_wrapper_log_warn(wrapper, context, options, UnlinkFailed, + "phar error: unlink failed"); return 0; } /* we must have at the very least phar://alias.phar/internalfile.php */ if (!resource->scheme || !resource->host || !resource->path) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", url); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "phar error: invalid url \"%s\"", url); return 0; } if (!zend_string_equals_literal_ci(resource->scheme, "phar")) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", url); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: not a phar stream url \"%s\"", url); return 0; } phar_request_initialize(); - pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); + const phar_archive_data *pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); if (PHAR_G(readonly) && (!pphar || !pphar->is_data)) { php_url_free(resource); - php_stream_wrapper_log_error(wrapper, options, "phar error: write operations disabled by the php.ini setting phar.readonly"); + php_stream_wrapper_log_warn(wrapper, context, options, Readonly, + "phar error: write operations disabled by the php.ini setting phar.readonly"); return 0; } /* need to copy to strip leading "/", will get touched again */ internal_file = estrndup(ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1); internal_file_len = ZSTR_LEN(resource->path) - 1; - if (FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, internal_file_len, "r", 0, &error, true)) { + if (FAILURE == phar_get_entry_data(&idata, resource->host, internal_file, internal_file_len, "r", 0, &error, true)) { /* constraints of fp refcount were not met */ if (error) { - php_stream_wrapper_log_error(wrapper, options, "unlink of \"%s\" failed: %s", url, error); + php_stream_wrapper_log_warn(wrapper, context, options, UnlinkFailed, + "unlink of \"%s\" failed: %s", url, error); efree(error); } else { - php_stream_wrapper_log_error(wrapper, options, "unlink of \"%s\" failed, file does not exist", url); + php_stream_wrapper_log_warn(wrapper, context, options, NotFound, + "unlink of \"%s\" failed, file does not exist", url); } efree(internal_file); php_url_free(resource); return 0; } - if (error) { - efree(error); - } if (idata->internal_file->fp_refcount > 1) { /* more than just our fp resource is open for this file */ - php_stream_wrapper_log_error(wrapper, options, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot unlink", internal_file, ZSTR_VAL(resource->host)); + php_stream_wrapper_log_warn(wrapper, context, options, UnlinkFailed, + "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot unlink", + internal_file, ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); phar_entry_delref(idata); @@ -721,7 +738,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int efree(internal_file); phar_entry_remove(idata, &error); if (error) { - php_stream_wrapper_log_error(wrapper, options, "%s", error); + php_stream_wrapper_log_warn(wrapper, context, options, UnlinkFailed, "%s", error); efree(error); } return 1; @@ -730,53 +747,52 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context) /* {{{ */ { - php_url *resource_from, *resource_to; char *error; - phar_archive_data *phar, *pfrom, *pto; - phar_entry_info *entry; bool is_dir = false; bool is_modified = false; error = NULL; - if ((resource_from = phar_parse_url(wrapper, url_from, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) { - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_from); + php_url *resource_from = phar_parse_url(wrapper, context, url_from, "wb", options|PHP_STREAM_URL_STAT_QUIET); + if (!resource_from) { + php_stream_wrapper_warn(wrapper, context, options, InvalidUrl, + "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", + url_from, url_to, url_from); return 0; } - if (SUCCESS != phar_get_archive(&pfrom, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { - pfrom = NULL; - if (error) { - efree(error); - } - } + + phar_archive_data *pfrom = phar_get_archive(ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, NULL); if (PHAR_G(readonly) && (!pfrom || !pfrom->is_data)) { php_url_free(resource_from); - php_error_docref(NULL, E_WARNING, "phar error: Write operations disabled by the php.ini setting phar.readonly"); + php_stream_wrapper_warn(wrapper, context, options, Readonly, + "phar error: Write operations disabled by the php.ini setting phar.readonly"); return 0; } - if ((resource_to = phar_parse_url(wrapper, url_to, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) { + php_url *resource_to = phar_parse_url(wrapper, context, url_to, "wb", options|PHP_STREAM_URL_STAT_QUIET); + if (!resource_to) { php_url_free(resource_from); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_to); + php_stream_wrapper_warn(wrapper, context, options, InvalidUrl, + "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", + url_from, url_to, url_to); return 0; } - if (SUCCESS != phar_get_archive(&pto, ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, &error)) { - if (error) { - efree(error); - } - pto = NULL; - } + + phar_archive_data *pto = phar_get_archive(ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, NULL); if (PHAR_G(readonly) && (!pto || !pto->is_data)) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: Write operations disabled by the php.ini setting phar.readonly"); + php_stream_wrapper_warn(wrapper, context, options, Readonly, + "phar error: Write operations disabled by the php.ini setting phar.readonly"); return 0; } if (!zend_string_equals(resource_from->host, resource_to->host)) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\", not within the same phar archive", url_from, url_to); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "phar error: cannot rename \"%s\" to \"%s\", not within the same phar archive", + url_from, url_to); return 0; } @@ -784,35 +800,45 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (!resource_from->scheme || !resource_from->host || !resource_from->path) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", url_from, url_to, url_from); + php_stream_wrapper_warn(wrapper, context, options, InvalidUrl, + "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", + url_from, url_to, url_from); return 0; } if (!resource_to->scheme || !resource_to->host || !resource_to->path) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", url_from, url_to, url_to); + php_stream_wrapper_warn(wrapper, context, options, InvalidUrl, + "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", + url_from, url_to, url_to); return 0; } if (!zend_string_equals_literal_ci(resource_from->scheme, "phar")) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", url_from, url_to, url_from); + php_stream_wrapper_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", + url_from, url_to, url_from); return 0; } if (!zend_string_equals_literal_ci(resource_to->scheme, "phar")) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", url_from, url_to, url_to); + php_stream_wrapper_warn(wrapper, context, options, ProtocolUnsupported, + "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", + url_from, url_to, url_to); return 0; } - if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error); + if (!phar) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); efree(error); return 0; } @@ -820,18 +846,23 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": could not make cached phar writeable", url_from, url_to); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "phar error: cannot rename \"%s\" to \"%s\": could not make cached phar writeable", + url_from, url_to); return 0; } - if (NULL != (entry = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(resource_from->path)+1, ZSTR_LEN(resource_from->path)-1))) { + phar_entry_info *entry = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(resource_from->path)+1, ZSTR_LEN(resource_from->path)-1); + if (entry) { phar_entry_info new, *source; /* perform rename magic */ if (entry->is_deleted) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", url_from, url_to); + php_stream_wrapper_warn(wrapper, context, options, NotFound, + "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", + url_from, url_to); return 0; } /* transfer all data over to the new entry */ @@ -840,7 +871,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from entry->is_deleted = 1; entry->fp = NULL; ZVAL_UNDEF(&entry->metadata_tracker.val); - entry->link = entry->tmp = NULL; + entry->symlink = NULL; + entry->tmp = NULL; source = entry; /* add to the manifest, and then store the pointer to the new guy in entry @@ -851,7 +883,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (FAILURE == phar_copy_entry_fp(source, entry, &error)) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); efree(error); zend_hash_del(&phar->manifest, entry->filename); return 0; @@ -865,7 +898,9 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from /* file does not exist */ php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source does not exist", url_from, url_to); + php_stream_wrapper_warn(wrapper, context, options, NotFound, + "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source does not exist", + url_from, url_to); return 0; } @@ -944,7 +979,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (error) { php_url_free(resource_from); php_url_free(resource_to); - php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); efree(error); return 0; } diff --git a/ext/phar/stream.h b/ext/phar/stream.h index 83b395b4cfca..ebac093402b1 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -20,7 +18,7 @@ BEGIN_EXTERN_C() #include "ext/standard/url.h" -php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); +php_url* phar_parse_url(php_stream_wrapper *wrapper, php_stream_context *context, const char *filename, const char *mode, int options); ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **error); static php_stream* phar_wrapper_open_url(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); diff --git a/ext/phar/stub.h b/ext/phar/stub.h index 2c62e05900ac..79887a62d7b8 100644 --- a/ext/phar/stub.h +++ b/ext/phar/stub.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension generated stub | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 0c93de243adc..bc78472afce3 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | TAR archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Gregory Beaver | @@ -128,10 +126,16 @@ bool phar_is_tar(const char *buf, const char *fname) /* {{{ */ } /* }}} */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_tar( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { phar_archive_data *phar; - zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, alias, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -152,10 +156,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *f } /* we've reached here - the phar exists and is a regular phar */ - spprintf(error, 4096, "phar tar error: \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a tar-based phar", fname); + spprintf(error, 4096, "phar tar error: \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a tar-based phar", ZSTR_VAL(fname)); return FAILURE; } -/* }}} */ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ { @@ -199,8 +202,15 @@ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream } /* }}} */ -zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ -{ +zend_result phar_parse_tarfile( + php_stream* fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + phar_archive_data** pphar, + uint32_t compression, + char **error +) { char buf[512], *actual_alias = NULL, *p; phar_entry_info entry = {0}; size_t pos = 0, read, totalsize; @@ -494,8 +504,8 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch entry.is_dir = 0; } - entry.link = NULL; - /* link field is null-terminated unless it has 100 non-null chars. + entry.symlink = NULL; + /* linkname field is null-terminated unless it has 100 non-null chars. * Thus we cannot use strlen. */ linkname_len = zend_strnlen(hdr->linkname, 100); if (entry.tar_type == TAR_LINK) { @@ -508,9 +518,9 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch phar_destroy_phar_data(myphar); return FAILURE; } - entry.link = estrndup(hdr->linkname, linkname_len); + entry.symlink = zend_string_init(hdr->linkname, linkname_len, false); } else if (entry.tar_type == TAR_SYMLINK) { - entry.link = estrndup(hdr->linkname, linkname_len); + entry.symlink = zend_string_init(hdr->linkname, linkname_len, false); } phar_set_inode(&entry); @@ -628,27 +638,29 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch return FAILURE; } - myphar->fname = pestrndup(fname, fname_len, myphar->is_persistent); + myphar->fname = zend_string_init(fname, fname_len, myphar->is_persistent); + if (myphar->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(myphar->fname); + } #ifdef PHP_WIN32 - phar_unixify_path_separators(myphar->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(myphar->fname), ZSTR_LEN(myphar->fname)); #endif - myphar->fname_len = fname_len; myphar->fp = fp; - p = strrchr(myphar->fname, '/'); + p = strrchr(ZSTR_VAL(myphar->fname), '/'); if (p) { - myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p); + myphar->ext = memchr(p, '.', (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - p); if (myphar->ext == p) { - myphar->ext = memchr(p + 1, '.', (myphar->fname + fname_len) - p - 1); + myphar->ext = memchr(p + 1, '.', (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - p - 1); } if (myphar->ext) { - myphar->ext_len = (myphar->fname + fname_len) - myphar->ext; + myphar->ext_len = (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - myphar->ext; } } phar_request_initialize(); - if (NULL == (actual = zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len, myphar))) { + if (NULL == (actual = zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), myphar->fname, myphar))) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\" to phar registry", fname); } @@ -660,40 +672,37 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch myphar = actual; if (actual_alias) { - phar_archive_data *fd_ptr; - myphar->is_temporary_alias = 0; - - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, myphar->alias_len)) { + phar_archive_data *fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), myphar->fname); return FAILURE; } } zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len, myphar); } else { - phar_archive_data *fd_ptr; - - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + if (alias) { + phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), myphar->fname); return FAILURE; } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, myphar); - myphar->alias = pestrndup(alias, alias_len, myphar->is_persistent); - myphar->alias_len = alias_len; + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, myphar); + myphar->alias = pestrndup(ZSTR_VAL(alias), ZSTR_LEN(alias), myphar->is_persistent); + myphar->alias_len = ZSTR_LEN(alias); } else { - myphar->alias = pestrndup(myphar->fname, fname_len, myphar->is_persistent); - myphar->alias_len = fname_len; + myphar->alias = pestrndup(ZSTR_VAL(myphar->fname), ZSTR_LEN(myphar->fname), myphar->is_persistent); + myphar->alias_len = ZSTR_LEN(myphar->fname); } myphar->is_temporary_alias = 1; @@ -705,7 +714,6 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch return SUCCESS; } -/* }}} */ struct _phar_pass_tar_info { php_stream *old; @@ -742,7 +750,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* char *boundary; if (ZSTR_LEN(entry->filename) > 256) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -752,7 +760,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* } if (!*boundary || ((boundary - ZSTR_VAL(entry->filename)) > 155)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -766,14 +774,14 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* if (FAILURE == phar_tar_octal(header.size, entry->uncompressed_filesize, sizeof(header.size)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } if (FAILURE == phar_tar_octal(header.mtime, entry->timestamp, sizeof(header.mtime)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, file modification time of file \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, file modification time of file \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -781,10 +789,10 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* calc checksum */ header.typeflag = entry->tar_type; - if (entry->link) { - if (strlcpy(header.linkname, entry->link, sizeof(header.linkname)) >= sizeof(header.linkname)) { + if (entry->symlink) { + if (strlcpy(header.linkname, ZSTR_VAL(entry->symlink), sizeof(header.linkname)) >= sizeof(header.linkname)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", entry->phar->fname, entry->link); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->symlink)); } return ZEND_HASH_APPLY_STOP; } @@ -797,7 +805,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* if (FAILURE == phar_tar_octal(header.checksum, entry->crc32, sizeof(header.checksum)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, checksum of file \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, checksum of file \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -805,9 +813,9 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* write header */ entry->header_offset = php_stream_tell(fp->new); - if (sizeof(header) != php_stream_write(fp->new, (char *) &header, sizeof(header))) { + if (sizeof(header) != php_stream_write(fp->new, (const char *) &header, sizeof(header))) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -822,14 +830,14 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), fp->new, entry->uncompressed_filesize, NULL)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -909,9 +917,9 @@ ZEND_ATTRIBUTE_NONNULL static int phar_tar_setmetadata(const phar_metadata_track ZEND_ATTRIBUTE_NONNULL static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ { - struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; + const struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; char **error = i->error; - phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv), *metadata, newentry = {0}; + phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv), newentry = {0}; if (zend_string_starts_with_literal(entry->filename, ".phar/.metadata")) { if (zend_string_equals_literal(entry->filename, ".phar/.metadata.bin")) { @@ -939,7 +947,8 @@ ZEND_ATTRIBUTE_NONNULL static int phar_tar_setupmetadata(zval *zv, void *argumen return ZEND_HASH_APPLY_KEEP; } - if (NULL != (metadata = zend_hash_find_ptr(&entry->phar->manifest, lookfor))) { + phar_entry_info *metadata = zend_hash_find_ptr(&entry->phar->manifest, lookfor); + if (metadata) { int ret; ret = phar_tar_setmetadata(&entry->metadata_tracker, metadata, error); zend_string_efree(lookfor); @@ -951,7 +960,8 @@ ZEND_ATTRIBUTE_NONNULL static int phar_tar_setupmetadata(zval *zv, void *argumen newentry.tar_type = TAR_FILE; newentry.is_tar = 1; - if (NULL == (metadata = zend_hash_add_mem(&entry->phar->manifest, lookfor, &newentry, sizeof(phar_entry_info)))) { + metadata = zend_hash_add_mem(&entry->phar->manifest, lookfor, &newentry, sizeof(phar_entry_info)); + if (!metadata) { zend_string_efree(lookfor); spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for file \"%s\"", ZSTR_VAL(entry->filename)); return ZEND_HASH_APPLY_STOP; @@ -969,9 +979,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze phar_entry_info entry = {0}; php_stream *oldfile, *newfile; bool must_close_old_file = false; - size_t signature_length; struct _phar_pass_tar_info pass; - char *buf, *signature, sigbuf[8]; + char *buf, sigbuf[8]; entry.flags = PHAR_ENT_PERM_DEF_FILE; entry.timestamp = time(NULL); @@ -985,7 +994,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze entry.filename = NULL; if (phar->is_persistent) { - spprintf(error, 0, "internal error: attempt to flush cached tar-based phar \"%s\"", phar->fname); + spprintf(error, 0, "internal error: attempt to flush cached tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -1001,7 +1010,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze return EOF; } if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { - spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); return EOF; } @@ -1021,7 +1030,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), sizeof(halt_stub) - 1); if (pos == NULL) { - spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname); + spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -1040,7 +1049,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len) || end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len) ) { - spprintf(error, 0, "unable to create stub from string in new tar-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub from string in new tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); return EOF; } @@ -1057,7 +1066,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) { php_stream_close(entry.fp); spprintf(error, 0, "unable to %s stub in%star-based phar \"%s\", failed", - user_stub ? "overwrite" : "create", user_stub ? " " : " new ", phar->fname); + user_stub ? "overwrite" : "create", user_stub ? " " : " new ", ZSTR_VAL(phar->fname)); return EOF; } @@ -1069,7 +1078,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { php_stream_close(entry.fp); zend_string_efree(entry.filename); - spprintf(error, 0, "unable to create stub in tar-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub in tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } } else { @@ -1086,7 +1095,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } @@ -1106,8 +1115,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze pass.free_ufp = true; if (phar_metadata_tracker_has_data(&phar->metadata_tracker, phar->is_persistent)) { - phar_entry_info *mentry; - if (NULL != (mentry = zend_hash_str_find_ptr(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1))) { + phar_entry_info *mentry = zend_hash_str_find_ptr(&(phar->manifest), ZEND_STRL(".phar/.metadata.bin")); + if (mentry) { if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(&phar->metadata_tracker, mentry, error)) { if (must_close_old_file) { php_stream_close(oldfile); @@ -1122,9 +1131,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze newentry.tar_type = TAR_FILE; newentry.is_tar = 1; - if (NULL == (mentry = zend_hash_add_mem(&phar->manifest, newentry.filename, &newentry, sizeof(phar_entry_info)))) { + mentry = zend_hash_add_mem(&phar->manifest, newentry.filename, &newentry, sizeof(phar_entry_info)); + if (!mentry) { zend_string_efree(newentry.filename); - spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for phar archive \"%s\"", phar->fname); + spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for phar archive \"%s\"", ZSTR_VAL(phar->fname)); if (must_close_old_file) { php_stream_close(oldfile); } @@ -1168,7 +1178,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, &signature_error)) { + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", signature_error); efree(signature_error); @@ -1184,7 +1195,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze if (entry.fp == NULL) { *error = estrdup("phar error: unable to create temporary file"); - efree(signature); + zend_string_release_ex(signature, false); if (must_close_old_file) { php_stream_close(oldfile); } @@ -1203,11 +1214,11 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze # define PHAR_SET_32(destination, source) memcpy(destination, &source, 4) #endif PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (8 != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); - spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", phar->fname); + if (8 != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); + spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", ZSTR_VAL(phar->fname)); if (must_close_old_file) { php_stream_close(oldfile); @@ -1218,11 +1229,11 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; /* throw out return value and write the signature */ phar_tar_writeheaders_int(&entry, &pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); + zend_string_release_ex(signature, false); if (*error) { if (must_close_old_file) { @@ -1261,10 +1272,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze /* deferred flush */ phar->fp = newfile; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { phar->fp = newfile; - spprintf(error, 0, "unable to open new phar \"%s\" for writing", phar->fname); + spprintf(error, 0, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); return EOF; } @@ -1286,7 +1297,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze /* copy contents uncompressed rather than lose them */ php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_close(newfile); - spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname); + spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", ZSTR_VAL(phar->fname)); return EOF; } diff --git a/ext/phar/tar.h b/ext/phar/tar.h index 55ce5501eeb1..80e4586e8db9 100644 --- a/ext/phar/tar.h +++ b/ext/phar/tar.h @@ -4,15 +4,13 @@ +----------------------------------------------------------------------+ | TAR archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Gregory Beaver | diff --git a/ext/phar/tests/013.phpt b/ext/phar/tests/013.phpt index f0315b151bef..63bdabb31833 100644 --- a/ext/phar/tests/013.phpt +++ b/ext/phar/tests/013.phpt @@ -20,4 +20,4 @@ echo file_get_contents($pname.'/a'); --CLEAN-- --EXPECTF-- -Warning: file_get_contents(phar://%s/a): Failed to open stream: phar error: internal corruption of phar "%s" (%s file "a") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (%s file "a") in %s on line %d diff --git a/ext/phar/tests/014.phpt b/ext/phar/tests/014.phpt index 7b2a6d0166e8..7ce06ce5d912 100644 --- a/ext/phar/tests/014.phpt +++ b/ext/phar/tests/014.phpt @@ -20,4 +20,4 @@ echo file_get_contents($pname.'/a'); --CLEAN-- --EXPECTF-- -Warning: file_get_contents(phar://%s/a): Failed to open stream: phar error: internal corruption of phar "%s" (crc32 mismatch on file "a") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (crc32 mismatch on file "a") in %s on line %d diff --git a/ext/phar/tests/016.phpt b/ext/phar/tests/016.phpt index d14c1292a6e2..17052735b044 100644 --- a/ext/phar/tests/016.phpt +++ b/ext/phar/tests/016.phpt @@ -28,12 +28,12 @@ var_dump(file_get_contents($pname . '/d')); --CLEAN-- --EXPECTF-- -Warning: file_get_contents(phar://%s/a): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "a") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "a") in %s on line %d bool(false) -Warning: file_get_contents(phar://%s/b): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "b") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "b") in %s on line %d bool(false) string(1) "*" -Warning: file_get_contents(phar://%s/d): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "d") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "d") in %s on line %d bool(false) diff --git a/ext/phar/tests/016b.phpt b/ext/phar/tests/016b.phpt index 72b7019def54..ba07a10bb752 100644 --- a/ext/phar/tests/016b.phpt +++ b/ext/phar/tests/016b.phpt @@ -21,4 +21,4 @@ echo file_get_contents($pname . '/a'); --CLEAN-- --EXPECTF-- -Warning: file_get_contents(phar://%s/a): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "a") in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "a") in %s on line %d diff --git a/ext/phar/tests/017.phpt b/ext/phar/tests/017.phpt index 74ffddad40b5..14ebddc787e7 100644 --- a/ext/phar/tests/017.phpt +++ b/ext/phar/tests/017.phpt @@ -27,5 +27,5 @@ $dir = opendir('phar://hio'); string(%d) "%s017.phar.php" bool(true) -Warning: opendir(phar://hio): Failed to open directory: phar error: no directory in "phar://hio", must have at least phar://hio/ for root directory (always use full path to a new phar) +Warning: opendir(): Failed to open directory: phar error: no directory in "phar://hio", must have at least phar://hio/ for root directory (always use full path to a new phar) phar url "phar://hio" is unknown in %s017.php on line %d diff --git a/ext/phar/tests/027.phpt b/ext/phar/tests/027.phpt index e5c2add435e6..b285f16f8088 100644 --- a/ext/phar/tests/027.phpt +++ b/ext/phar/tests/027.phpt @@ -83,10 +83,10 @@ bool(false) bool(false) opendir edge cases -Warning: opendir(phar://): Failed to open directory: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) +Warning: opendir(): Failed to open directory: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) phar url "phar://" is unknown in %s027.php on line %d bool(false) -Warning: opendir(phar://foo.phar/hi): Failed to open directory: phar error: invalid url or non-existent phar "phar://foo.phar/hi" +Warning: opendir(): Failed to open directory: phar error: invalid url or non-existent phar "phar://foo.phar/hi" phar url "phar://foo.phar/hi" is unknown in %s027.php on line %d bool(false) diff --git a/ext/phar/tests/bug69720.phpt b/ext/phar/tests/bug69720.phpt index a6afe0f15e7f..dbcae78db733 100644 --- a/ext/phar/tests/bug69720.phpt +++ b/ext/phar/tests/bug69720.phpt @@ -24,7 +24,7 @@ try { --EXPECTF-- MY_METADATA_NULL -Warning: file_get_contents(phar://%s): Failed to open stream: phar error: "test.php" is not a file in phar "%s.phar" in %s.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "test.php" is not a file in phar "%s.phar" in %s.php on line %d array(1) { ["whatever"]=> int(123) diff --git a/ext/phar/tests/bug77432.phpt b/ext/phar/tests/bug77432.phpt index 86a07fe99a4e..1223575badf6 100644 --- a/ext/phar/tests/bug77432.phpt +++ b/ext/phar/tests/bug77432.phpt @@ -39,6 +39,6 @@ hello world hello world --- After unlink --- -Warning: include(%sbug77432.phar): Failed to open stream: phar error: could not reopen phar "%sbug77432.phar" in %s on line %d +Warning: include(): Failed to open stream: phar error: could not reopen phar "%sbug77432.phar" in %s on line %d Warning: include(): Failed opening '%sbug77432.phar' for inclusion (include_path=%s) in %s on line %d diff --git a/ext/phar/tests/bug81726.phpt b/ext/phar/tests/bug81726.phpt index a86c52a64980..e27f9d7e2f3f 100644 --- a/ext/phar/tests/bug81726.phpt +++ b/ext/phar/tests/bug81726.phpt @@ -8,5 +8,5 @@ zlib var_dump(fopen("phar://" . __DIR__ . "/bug81726.gz", "r")); ?> --EXPECTF-- -Warning: fopen(phar://%s): Failed to open stream: unable to decompress gzipped phar archive "%s" in %s on line %d +Warning: fopen(): Failed to open stream: unable to decompress gzipped phar archive "%s" in %s on line %d bool(false) diff --git a/ext/phar/tests/cache_list/frontcontroller22.phpt b/ext/phar/tests/cache_list/frontcontroller22.phpt index 6747da6dc795..ac12e7ef01c6 100644 --- a/ext/phar/tests/cache_list/frontcontroller22.phpt +++ b/ext/phar/tests/cache_list/frontcontroller22.phpt @@ -21,6 +21,6 @@ Content-type: text/html; charset=UTF-8 string(4) "test" string(12) "oof/test.php" -Warning: include(./hi.php): Failed to open stream: No such file or directory in phar://%s/oof/test.php on line %d +Warning: include(): Failed to open stream: No such file or directory in phar://%s/oof/test.php on line %d Warning: include(): Failed opening './hi.php' for inclusion (include_path='%s') in phar://%soof/test.php on line %d diff --git a/ext/phar/tests/create_new_phar_b.phpt b/ext/phar/tests/create_new_phar_b.phpt index fb106153ca87..9d9c8640dd5f 100644 --- a/ext/phar/tests/create_new_phar_b.phpt +++ b/ext/phar/tests/create_new_phar_b.phpt @@ -13,9 +13,9 @@ file_put_contents('phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.pha include 'phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.phar.php/a.php'; ?> --EXPECTF-- -Warning: file_put_contents(phar://%screate_new_phar_b.phar.php/a.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d +Warning: file_put_contents(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d -Warning: include(phar://%screate_new_phar_b.phar.php/a.php): Failed to open stream: %s in %screate_new_phar_b.php on line %d +Warning: include(): Failed to open stream: %s in %screate_new_phar_b.php on line %d Warning: include(): Failed opening 'phar://%screate_new_phar_b.phar.php/a.php' for inclusion (include_path='%s') in %screate_new_phar_b.php on line %d diff --git a/ext/phar/tests/create_path_error.phpt b/ext/phar/tests/create_path_error.phpt index fea390e477cb..13a0fea2bb7f 100644 --- a/ext/phar/tests/create_path_error.phpt +++ b/ext/phar/tests/create_path_error.phpt @@ -65,17 +65,17 @@ foreach($checks as $check) --EXPECTF-- string(5) "query" string(5) "query" -1:Error: file_put_contents(phar://%s//): Failed to open stream: phar error: file "" in phar "%s" must not be empty -2:Error: file_put_contents(phar://%s/.): Failed to open stream: phar error: file "" in phar "%s" must not be empty -3:Error: file_put_contents(phar://%s/../): Failed to open stream: phar error: file "" in phar "%s" must not be empty -4:Error: file_put_contents(phar://%s/a/..): Failed to open stream: phar error: file "" in phar "%s" must not be empty +1:Error: file_put_contents(): Failed to open stream: phar error: file "" in phar "%s" must not be empty +2:Error: file_put_contents(): Failed to open stream: phar error: file "" in phar "%s" must not be empty +3:Error: file_put_contents(): Failed to open stream: phar error: file "" in phar "%s" must not be empty +4:Error: file_put_contents(): Failed to open stream: phar error: file "" in phar "%s" must not be empty 5: 6: 7: 8: -9:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character -10:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character -11:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character -12:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character -13:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character +9:Error: file_put_contents(): Failed to open stream: phar error: invalid path "%s" contains illegal character +10:Error: file_put_contents(): Failed to open stream: phar error: invalid path "%s" contains illegal character +11:Error: file_put_contents(): Failed to open stream: phar error: invalid path "%s" contains illegal character +12:Error: file_put_contents(): Failed to open stream: phar error: invalid path "%s" contains illegal character +13:Error: file_put_contents(): Failed to open stream: phar error: invalid path "%s" contains illegal character Exception: Phar::offsetSet(): Argument #1 ($localName) must not contain any null bytes diff --git a/ext/phar/tests/delete.phpt b/ext/phar/tests/delete.phpt index 1cf95cb82d5b..3264e7312638 100644 --- a/ext/phar/tests/delete.phpt +++ b/ext/phar/tests/delete.phpt @@ -28,4 +28,4 @@ echo file_get_contents($pname . '/a') . "\n"; --EXPECTF-- a -Warning: file_get_contents(phar://%sdelete.phar.php/a): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.php" in %sdelete.php on line 16 +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.php" in %sdelete.php on line 16 diff --git a/ext/phar/tests/delete_in_phar.phpt b/ext/phar/tests/delete_in_phar.phpt index 11978fdce7bc..78149bf87619 100644 --- a/ext/phar/tests/delete_in_phar.phpt +++ b/ext/phar/tests/delete_in_phar.phpt @@ -41,7 +41,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar.phar.php/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.php" in %sdelete_in_phar.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.php" in %sdelete_in_phar.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar.phar.php/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar.php on line %d diff --git a/ext/phar/tests/delete_in_phar_confirm.phpt b/ext/phar/tests/delete_in_phar_confirm.phpt index 12d1099bf635..215f20ddf9cf 100644 --- a/ext/phar/tests/delete_in_phar_confirm.phpt +++ b/ext/phar/tests/delete_in_phar_confirm.phpt @@ -45,7 +45,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar_confirm.phar.php/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.php" in %sdelete_in_phar_confirm.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.php" in %sdelete_in_phar_confirm.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar_confirm.phar.php/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar_confirm.php on line %d diff --git a/ext/phar/tests/dir.phpt b/ext/phar/tests/dir.phpt index db5d0262add5..84645e41d9d3 100644 --- a/ext/phar/tests/dir.phpt +++ b/ext/phar/tests/dir.phpt @@ -71,7 +71,7 @@ Warning: mkdir(): phar error: cannot create directory "fails" in phar "%sok.phar Warning: mkdir(): phar error: cannot create directory "sub" in phar "%sok.phar", directory already exists in %sdir.php on line %d -Warning: mkdir(): phar error: cannot create directory "sub/directory.txt" in phar "%sok.phar", phar error: path "sub/directory.txt" exists and is a not a directory in %sdir.php on line %d +Warning: mkdir(): phar error: cannot create directory "sub/directory.txt" in phar "%sok.phar", phar error: path "sub/directory.txt" exists and is not a directory in %sdir.php on line %d Warning: mkdir(): internal corruption of phar "%soops.phar" (truncated manifest at stub end) in %sdir.php on line %d diff --git a/ext/phar/tests/fgc_edgecases.phpt b/ext/phar/tests/fgc_edgecases.phpt index 81a2f43e80a1..1daa3a13e59b 100644 --- a/ext/phar/tests/fgc_edgecases.phpt +++ b/ext/phar/tests/fgc_edgecases.phpt @@ -90,7 +90,7 @@ echo file_get_contents("./hi"); echo file_get_contents("./hi", 0, $context, 0, 0); ?> -Warning: file_get_contents(phar://%sfgc_edgecases.phar.php/oops): Failed to open stream: phar error: path "oops" is a directory in phar://%sfgc_edgecases.phar.php/foo/hi on line %d +Warning: file_get_contents(): Failed to open stream: phar error: path "oops" is a directory in phar://%sfgc_edgecases.phar.php/foo/hi on line %d Warning: file_get_contents(): Failed to seek to position 50000 in the stream in phar://%sfgc_edgecases.phar.php/foo/hi on line %d --EXPECTF-- hihi -Warning: fopen(notfound.txt): Failed to open stream: No such file or directory in phar://%sfopen.phar.php/index.php on line %d +Warning: fopen(): Failed to open stream: No such file or directory in phar://%sfopen.phar.php/index.php on line %d diff --git a/ext/phar/tests/fopen_edgecases.phpt b/ext/phar/tests/fopen_edgecases.phpt index 12b4ecde7589..5c8e6c87dfb2 100644 --- a/ext/phar/tests/fopen_edgecases.phpt +++ b/ext/phar/tests/fopen_edgecases.phpt @@ -71,16 +71,16 @@ include $pname . '/test.php'; --EXPECTF-- -Warning: fopen(phar://%sfopen_edgecases.phar.php/b/c.php): Failed to open stream: phar error: open mode append not supported in %sfopen_edgecases.php on line %d +Warning: fopen(): Failed to open stream: phar error: open mode append not supported in %sfopen_edgecases.php on line %d -Warning: fopen(phar://%sfopen_edgecases.phar.php.phar.gz): Failed to open stream: phar error: invalid url or non-existent phar "phar://%sfopen_edgecases.phar.php.phar.gz" in %sfopen_edgecases.php on line %d +Warning: fopen(): Failed to open stream: phar error: invalid url or non-existent phar "phar://%sfopen_edgecases.phar.php.phar.gz" in %sfopen_edgecases.php on line %d bool(false) -Warning: fopen(phar://%sfopen_edgecases.2.phar.php/hi): Failed to open stream: internal corruption of phar "%sfopen_edgecases.2.phar.php" (truncated manifest at stub end) in %sfopen_edgecases.php on line %d +Warning: fopen(): Failed to open stream: internal corruption of phar "%sfopen_edgecases.2.phar.php" (truncated manifest at stub end) in %sfopen_edgecases.php on line %d -Warning: fopen(phar://): Failed to open stream: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) in %sfopen_edgecases.php on line %d +Warning: fopen(): Failed to open stream: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) in %sfopen_edgecases.php on line %d -Warning: fopen(phar://foo.phar): Failed to open stream: %s in %sfopen_edgecases.php on line %d +Warning: fopen(): Failed to open stream: %s in %sfopen_edgecases.php on line %d int(0) int(1) int(0) @@ -118,5 +118,5 @@ Warning: rename(): phar error: cannot rename "phar://%sfopen_edgecases.phar.php/ Warning: rename(): phar error: cannot rename "phar://%sfopen_edgecases.phar.php/hi" to "phar://%sfopen_edgecases.phar.php/there": invalid or non-writable url "phar://%sfopen_edgecases.phar.php/hi" in %sfopen_edgecases.php on line %d -Warning: fopen(./notfound.php): Failed to open stream: No such file or directory in phar://%sfopen_edgecases.phar.php/test.php on line %d +Warning: fopen(): Failed to open stream: No such file or directory in phar://%sfopen_edgecases.phar.php/test.php on line %d diff --git a/ext/phar/tests/fopen_edgecases2.phpt b/ext/phar/tests/fopen_edgecases2.phpt index 6fae07c0fda4..697ce81cf339 100644 --- a/ext/phar/tests/fopen_edgecases2.phpt +++ b/ext/phar/tests/fopen_edgecases2.phpt @@ -41,4 +41,4 @@ fopen(): Argument #1 ($filename) must be of type string, array given blah test -Warning: fopen(phar://%sfopen_edgecases2.phar.php/oops): Failed to open stream: phar error: path "oops" is a directory in phar://%sfopen_edgecases2.phar.php/foo/hi on line %d +Warning: fopen(): Failed to open stream: phar error: path "oops" is a directory in phar://%sfopen_edgecases2.phar.php/foo/hi on line %d diff --git a/ext/phar/tests/frontcontroller22.phpt b/ext/phar/tests/frontcontroller22.phpt index 5fb9490e2dca..431e8991ce64 100644 --- a/ext/phar/tests/frontcontroller22.phpt +++ b/ext/phar/tests/frontcontroller22.phpt @@ -16,6 +16,6 @@ Content-type: text/html; charset=UTF-8 string(4) "test" string(12) "oof/test.php" -Warning: include(./hi.php): Failed to open stream: No such file or directory in phar://%s/oof/test.php on line %d +Warning: include(): Failed to open stream: No such file or directory in phar://%s/oof/test.php on line %d Warning: include(): Failed opening './hi.php' for inclusion (include_path='%s') in phar://%soof/test.php on line %d diff --git a/ext/phar/tests/gh21797.phpt b/ext/phar/tests/gh21797.phpt new file mode 100644 index 000000000000..b24e30b7829a --- /dev/null +++ b/ext/phar/tests/gh21797.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21797: Phar::webPhar() NULL dereference when SCRIPT_NAME absent from SAPI environment +--CGI-- +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +variables_order=EGPC +register_argc_argv=0 +cgi.fix_pathinfo=0 +--ENV-- +REQUEST_METHOD=GET +PATH_INFO=/gh21797.phar +--FILE-- +addFromString('index.php', ''); +$phar->setStub(''); +unset($phar); +include $fname; +?> +--CLEAN-- + +--EXPECT-- +no crash diff --git a/ext/phar/tests/gh21798-add-file-delref.phpt b/ext/phar/tests/gh21798-add-file-delref.phpt new file mode 100644 index 000000000000..fa893a1975e3 --- /dev/null +++ b/ext/phar/tests/gh21798-add-file-delref.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-21798: phar_add_file must call phar_entry_delref on write error paths +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('hello.txt', 'hello world'); +$phar->addFromString('empty.txt', ''); +unset($phar); + +$phar = new Phar($fname); +echo $phar['hello.txt']->getContent() . "\n"; +echo ($phar->offsetExists('empty.txt') ? 'empty exists' : 'missing') . "\n"; +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +hello world +empty exists +no crash diff --git a/ext/phar/tests/gh21798-offsetget-temp-entry.phpt b/ext/phar/tests/gh21798-offsetget-temp-entry.phpt new file mode 100644 index 000000000000..b5b11ad43634 --- /dev/null +++ b/ext/phar/tests/gh21798-offsetget-temp-entry.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-21798: Phar::offsetGet() must free is_temp_dir entry before rejecting .phar/* paths +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('index.php', ''); +unset($phar); + +$phar = new Phar($fname); +try { + $phar->offsetGet('.phar/stub.php'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +try { + $phar->offsetGet('.phar/alias.txt'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +try { + $phar->offsetGet('.phar/internal'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +Entry .phar/stub.php does not exist +Entry .phar/alias.txt does not exist +Entry .phar/internal does not exist +no crash diff --git a/ext/phar/tests/gh21799-stream-close-flush.phpt b/ext/phar/tests/gh21799-stream-close-flush.phpt new file mode 100644 index 000000000000..aaa6c17fac38 --- /dev/null +++ b/ext/phar/tests/gh21799-stream-close-flush.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21799: phar_stream_close propagates phar_stream_flush return value +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('hello.txt', 'hello'); +unset($phar); + +$fp = fopen('phar://' . $fname . '/hello.txt', 'rb'); +$content = fread($fp, 1024); +$result = fclose($fp); + +echo $content . "\n"; +var_dump($result); +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +hello +bool(true) +no crash diff --git a/ext/phar/tests/include_path.phpt b/ext/phar/tests/include_path.phpt index 0f2dd585904e..a7fe9a468877 100644 --- a/ext/phar/tests/include_path.phpt +++ b/ext/phar/tests/include_path.phpt @@ -29,6 +29,6 @@ include 'file2.php'; file1.php test/file1.php -Warning: include(file2.php): Failed to open stream: No such file or directory in %sinclude_path.php on line %d +Warning: include(): Failed to open stream: No such file or directory in %sinclude_path.php on line %d Warning: include(): Failed opening 'file2.php' for inclusion (include_path='%sphar://%stempmanifest1.phar.php/test') in %sinclude_path.php on line %d diff --git a/ext/phar/tests/invalid_string_phar_mungserver.phpt b/ext/phar/tests/invalid_string_phar_mungserver.phpt index 46de113f6c08..8128987dacbc 100644 --- a/ext/phar/tests/invalid_string_phar_mungserver.phpt +++ b/ext/phar/tests/invalid_string_phar_mungserver.phpt @@ -1,5 +1,7 @@ --TEST-- Passing invalid string to Phar::mungServer() +--EXTENSIONS-- +phar --FILE-- addEmptyDir('.phar'); } catch (Exception $e) { echo $e->getMessage(),"\n"; } +try { +$a->addEmptyDir('/.phar'); +} catch (Exception $e) { +echo $e->getMessage(),"\n"; +} +$a->addEmptyDir('/.pharx'); +var_dump(is_dir($pname . '/.pharx')); ?> --CLEAN-- -Warning: file_get_contents(phar://%stempmanifest1.phar.php/testit/directory): Failed to open stream: phar error: path "testit/directory" is a directory in phar://%stempmanifest1.phar.php/index.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: path "testit/directory" is a directory in phar://%stempmanifest1.phar.php/index.php on line %d oops string(%d) "phar://%sextfile.php" diff --git a/ext/phar/tests/open_for_write_existing_b.phpt b/ext/phar/tests/open_for_write_existing_b.phpt index c11fb9a67f12..e590e68919cc 100644 --- a/ext/phar/tests/open_for_write_existing_b.phpt +++ b/ext/phar/tests/open_for_write_existing_b.phpt @@ -23,6 +23,6 @@ include $pname . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_b.phar.php/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/open_for_write_existing_c.phpt b/ext/phar/tests/open_for_write_existing_c.phpt index e8867d83b461..56fdccee0679 100644 --- a/ext/phar/tests/open_for_write_existing_c.phpt +++ b/ext/phar/tests/open_for_write_existing_c.phpt @@ -23,6 +23,6 @@ include $pname . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_c.phar.php/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/open_for_write_newfile_b.phpt b/ext/phar/tests/open_for_write_newfile_b.phpt index 498e3dd4be3e..76248ceeb6f4 100644 --- a/ext/phar/tests/open_for_write_newfile_b.phpt +++ b/ext/phar/tests/open_for_write_newfile_b.phpt @@ -25,11 +25,11 @@ include $pname . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_b.phar.php/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_b.phar.php/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.php" in %sopen_for_write_newfile_b.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.php" in %sopen_for_write_newfile_b.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_b.phar.php/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_b.php on line %d diff --git a/ext/phar/tests/open_for_write_newfile_c.phpt b/ext/phar/tests/open_for_write_newfile_c.phpt index 8bb0e2ba6803..9a940823dd36 100644 --- a/ext/phar/tests/open_for_write_newfile_c.phpt +++ b/ext/phar/tests/open_for_write_newfile_c.phpt @@ -25,11 +25,11 @@ include $pname . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_c.phar.php/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_c.phar.php/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.php" in %sopen_for_write_newfile_c.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.php" in %sopen_for_write_newfile_c.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_c.phar.php/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_c.php on line %d diff --git a/ext/phar/tests/opendir.phpt b/ext/phar/tests/opendir.phpt index 77a17c80f221..a11c50e00015 100644 --- a/ext/phar/tests/opendir.phpt +++ b/ext/phar/tests/opendir.phpt @@ -35,8 +35,8 @@ opendir('phar://hi.phar'); --EXPECTF-- file1.txtfile2.txtfile3.txt -Warning: opendir(phar://): Failed to open directory: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) +Warning: opendir(): Failed to open directory: phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) phar url "phar://" is unknown in %sopendir.php on line %d -Warning: opendir(phar://hi.phar): Failed to open directory: phar error: invalid url or non-existent phar "phar://hi.phar" +Warning: opendir(): Failed to open directory: phar error: invalid url or non-existent phar "phar://hi.phar" phar url "phar://hi.phar" is unknown in %sopendir.php on line %d diff --git a/ext/phar/tests/opendir_edgecases.phpt b/ext/phar/tests/opendir_edgecases.phpt index fbca644d18db..4d35f0655c92 100644 --- a/ext/phar/tests/opendir_edgecases.phpt +++ b/ext/phar/tests/opendir_edgecases.phpt @@ -60,4 +60,4 @@ opendir(): Argument #1 ($directory) must be of type string, array given .. foo -Warning: opendir(phar://%sopendir_edgecases.phar.php/oops): Failed to open directory: %s in phar://%sopendir_edgecases.phar.php/foo on line %d +Warning: opendir(): Failed to open directory: %s in phar://%sopendir_edgecases.phar.php/foo on line %d diff --git a/ext/phar/tests/phar-is-link-intercept.phpt b/ext/phar/tests/phar-is-link-intercept.phpt new file mode 100644 index 000000000000..f81f1ae425d7 --- /dev/null +++ b/ext/phar/tests/phar-is-link-intercept.phpt @@ -0,0 +1,29 @@ +--TEST-- +phar: is_link() intercept correctly delegates for non-symlink phar entries +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('file.txt', 'hello'); +$phar->setStub(''); +include $fname; +?> +--CLEAN-- + +--EXPECT-- +regular entry (not a symlink): bool(false) +missing entry: bool(false) +absolute phar:// path (bypasses intercept): bool(false) diff --git a/ext/phar/tests/phar_buildfromdirectory2-win.phpt b/ext/phar/tests/phar_buildfromdirectory2-win.phpt index 19a5ae8bfa2e..6a41caf03883 100644 --- a/ext/phar/tests/phar_buildfromdirectory2-win.phpt +++ b/ext/phar/tests/phar_buildfromdirectory2-win.phpt @@ -19,6 +19,6 @@ try { echo $e->getMessage() . "\n"; } ?> ---EXPECTF-- -%s(24) "UnexpectedValueException" -RecursiveDirectoryIterator::__construct(1): %s (code: 2) +--EXPECT-- +string(24) "UnexpectedValueException" +RecursiveDirectoryIterator::__construct(): Failed to open directory: No such file or directory diff --git a/ext/phar/tests/phar_buildfromdirectory2.phpt b/ext/phar/tests/phar_buildfromdirectory2.phpt index c828587548a9..b5f14671dbfc 100644 --- a/ext/phar/tests/phar_buildfromdirectory2.phpt +++ b/ext/phar/tests/phar_buildfromdirectory2.phpt @@ -21,4 +21,4 @@ try { ?> --EXPECTF-- %s(24) "UnexpectedValueException" -RecursiveDirectoryIterator::__construct(1): Failed to open directory: No such file or directory +RecursiveDirectoryIterator::__construct(): Failed to open directory: No such file or directory diff --git a/ext/phar/tests/phar_extract2.phpt b/ext/phar/tests/phar_extract2.phpt index f57d96ad5e92..b22c00977665 100644 --- a/ext/phar/tests/phar_extract2.phpt +++ b/ext/phar/tests/phar_extract2.phpt @@ -46,8 +46,6 @@ $dir = __DIR__ . '/extract2/'; @rmdir($dir . 'one/level'); @rmdir($dir . 'one'); @rmdir($dir); -$dir = __DIR__ . '/extract1/'; -@rmdir($dir); ?> --EXPECTF-- %sextract2%cfile1.txt diff --git a/ext/phar/tests/phar_gobyebye-win32.phpt b/ext/phar/tests/phar_gobyebye-win32.phpt index 7baa0c618fe6..552fab406e78 100644 --- a/ext/phar/tests/phar_gobyebye-win32.phpt +++ b/ext/phar/tests/phar_gobyebye-win32.phpt @@ -31,11 +31,11 @@ include $pname . '/foo/hi'; unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.2.php'); ?> --EXPECTF-- -Warning: readfile(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d +Warning: readfile(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d -Warning: fopen(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d +Warning: fopen(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d -Warning: file_get_contents(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d Warning: stat(): stat failed for foo/hi in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d bool(false) @@ -44,6 +44,4 @@ bool(false) bool(false) bool(false) -Warning: opendir(foo/hi): %s (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d - -Warning: opendir(foo/hi): Failed to open directory: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d +Warning: opendir(): Failed to open directory: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d diff --git a/ext/phar/tests/phar_gobyebye.phpt b/ext/phar/tests/phar_gobyebye.phpt index 4db6e0d91cdc..a42757936d7a 100644 --- a/ext/phar/tests/phar_gobyebye.phpt +++ b/ext/phar/tests/phar_gobyebye.phpt @@ -32,11 +32,11 @@ include $pname . '/foo/hi'; unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.2.php'); ?> --EXPECTF-- -Warning: readfile(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d +Warning: readfile(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d -Warning: fopen(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d +Warning: fopen(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d -Warning: file_get_contents(foo/hi): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d Warning: stat(): stat failed for foo/hi in phar://%sphar_gobyebye.phar.php/foo/hi on line %d bool(false) @@ -45,4 +45,4 @@ bool(false) bool(false) bool(false) -Warning: opendir(foo/hi): Failed to open directory: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d +Warning: opendir(): Failed to open directory: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d diff --git a/ext/phar/tests/phar_magic_dir_prefix.phpt b/ext/phar/tests/phar_magic_dir_prefix.phpt new file mode 100644 index 000000000000..e1f1c517632e --- /dev/null +++ b/ext/phar/tests/phar_magic_dir_prefix.phpt @@ -0,0 +1,80 @@ +--TEST-- +Phar: .phar-prefixed non-magic directories are accessible +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('.pharx/from-string.txt', 'from-string'); +$phar->addFromString('/.phary/leading.txt', 'leading'); +$phar->copy('.pharx/array.txt', '.pharx/copy.txt'); + +var_dump(isset($phar['.pharx/array.txt'])); +echo $phar['.pharx/array.txt']->getContent(), "\n"; +echo file_get_contents($pname . '/.pharx/from-string.txt'), "\n"; +echo file_get_contents($pname . '/.phary/leading.txt'), "\n"; +echo file_get_contents($pname . '/.pharx/copy.txt'), "\n"; + +$root = []; +$dh = opendir($pname . '/'); +while (false !== ($entry = readdir($dh))) { + $root[] = $entry; +} +closedir($dh); +sort($root); +var_dump($root); + +$subdir = []; +$dh = opendir($pname . '/.pharx'); +while (false !== ($entry = readdir($dh))) { + $subdir[] = $entry; +} +closedir($dh); +sort($subdir); +var_dump($subdir); + +try { + $phar->addFromString('.phar/still-magic.txt', 'no'); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $phar->addEmptyDir('/.phar'); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +bool(true) +array +from-string +leading +array +array(2) { + [0]=> + string(6) ".pharx" + [1]=> + string(6) ".phary" +} +array(3) { + [0]=> + string(9) "array.txt" + [1]=> + string(8) "copy.txt" + [2]=> + string(15) "from-string.txt" +} +Cannot create any files in magic ".phar" directory +Cannot create a directory in magic ".phar" directory diff --git a/ext/phar/tests/readfile_edgecases.phpt b/ext/phar/tests/readfile_edgecases.phpt index c4de84eefe3c..781016051302 100644 --- a/ext/phar/tests/readfile_edgecases.phpt +++ b/ext/phar/tests/readfile_edgecases.phpt @@ -54,4 +54,4 @@ readfile("./hi", 0, $context); readfile("../oops"); ?> -Warning: readfile(phar://%sreadfile_edgecases.phar.php/oops): Failed to open stream: phar error: path "oops" is a directory in phar://%sreadfile_edgecases.phar.php/foo/hi on line %d +Warning: readfile(): Failed to open stream: phar error: path "oops" is a directory in phar://%sreadfile_edgecases.phar.php/foo/hi on line %d diff --git a/ext/phar/tests/rename.phpt b/ext/phar/tests/rename.phpt index 1793d34834d2..ea0d28446c02 100644 --- a/ext/phar/tests/rename.phpt +++ b/ext/phar/tests/rename.phpt @@ -29,4 +29,4 @@ echo file_get_contents($pname . '/a') . "\n"; a a -Warning: file_get_contents(phar://%srename.phar.php/a): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.php" in %srename.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.php" in %srename.php on line %d diff --git a/ext/phar/tests/rename_dir.phpt b/ext/phar/tests/rename_dir.phpt index bbba70137fb3..7bf59e1f1d9c 100644 --- a/ext/phar/tests/rename_dir.phpt +++ b/ext/phar/tests/rename_dir.phpt @@ -30,4 +30,4 @@ echo file_get_contents($pname . '/a/x') . "\n"; a a -Warning: file_get_contents(phar://%srename_dir.phar.php/a/x): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.php" in %srename_dir.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.php" in %srename_dir.php on line %d diff --git a/ext/phar/tests/tar/create_new_phar_b.phpt b/ext/phar/tests/tar/create_new_phar_b.phpt index 7ec06f42931c..2c09c0470cd6 100644 --- a/ext/phar/tests/tar/create_new_phar_b.phpt +++ b/ext/phar/tests/tar/create_new_phar_b.phpt @@ -13,9 +13,9 @@ file_put_contents('phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.pha include 'phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.phar.tar/a.php'; ?> --EXPECTF-- -Warning: file_put_contents(phar://%screate_new_phar_b.phar.tar/a.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d +Warning: file_put_contents(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d -Warning: include(phar://%screate_new_phar_b.phar.tar/a.php): Failed to open stream: %s in %screate_new_phar_b.php on line %d +Warning: include(): Failed to open stream: %s in %screate_new_phar_b.php on line %d Warning: include(): Failed opening 'phar://%screate_new_phar_b.phar.tar/a.php' for inclusion (include_path='%s') in %screate_new_phar_b.php on line %d diff --git a/ext/phar/tests/tar/delete.phpt b/ext/phar/tests/tar/delete.phpt index eab91d5a0e13..2a6a8f57667f 100644 --- a/ext/phar/tests/tar/delete.phpt +++ b/ext/phar/tests/tar/delete.phpt @@ -29,4 +29,4 @@ echo file_get_contents($alias . '/a') . "\n"; --EXPECTF-- a -Warning: file_get_contents(phar://%sdelete.phar.tar/a): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.tar" in %sdelete.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.tar" in %sdelete.php on line %d diff --git a/ext/phar/tests/tar/delete_in_phar.phpt b/ext/phar/tests/tar/delete_in_phar.phpt index b9f624c728da..79aeeba0d0f3 100644 --- a/ext/phar/tests/tar/delete_in_phar.phpt +++ b/ext/phar/tests/tar/delete_in_phar.phpt @@ -42,7 +42,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar.phar.tar/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.tar" in %sdelete_in_phar.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.tar" in %sdelete_in_phar.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar.phar.tar/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar.php on line %d diff --git a/ext/phar/tests/tar/delete_in_phar_confirm.phpt b/ext/phar/tests/tar/delete_in_phar_confirm.phpt index 4a952a4b9f1b..cdd08441e86c 100644 --- a/ext/phar/tests/tar/delete_in_phar_confirm.phpt +++ b/ext/phar/tests/tar/delete_in_phar_confirm.phpt @@ -45,7 +45,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar_confirm.phar.tar/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.tar" in %sdelete_in_phar_confirm.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.tar" in %sdelete_in_phar_confirm.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar_confirm.phar.tar/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar_confirm.php on line %d diff --git a/ext/phar/tests/tar/gh16695_1.phpt b/ext/phar/tests/tar/gh16695_1.phpt index 8ce82bcf28dd..8613c77658d6 100644 --- a/ext/phar/tests/tar/gh16695_1.phpt +++ b/ext/phar/tests/tar/gh16695_1.phpt @@ -24,5 +24,5 @@ var_dump($buffer); --EXPECTF-- int(512) -Warning: file_get_contents(%stls): Failed to open stream: phar error: path "tls" is a directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: phar error: path "tls" is a directory in %s on line %d bool(false) diff --git a/ext/phar/tests/tar/gh21986.phpt b/ext/phar/tests/tar/gh21986.phpt new file mode 100644 index 000000000000..13205d40a65d --- /dev/null +++ b/ext/phar/tests/tar/gh21986.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-21986 (PharData::getContent() crash on circular symlink chain in tar) +--EXTENSIONS-- +phar +--FILE-- +getContent()); +?> +--CLEAN-- + +--EXPECT-- +string(0) "" diff --git a/ext/phar/tests/tar/open_for_write_existing_b.phpt b/ext/phar/tests/tar/open_for_write_existing_b.phpt index ce400ab687ff..b8afb8b21c02 100644 --- a/ext/phar/tests/tar/open_for_write_existing_b.phpt +++ b/ext/phar/tests/tar/open_for_write_existing_b.phpt @@ -36,7 +36,7 @@ include $alias . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_b.phar.tar/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/tar/open_for_write_existing_c.phpt b/ext/phar/tests/tar/open_for_write_existing_c.phpt index 0d251944b9f4..0cba841f2d86 100644 --- a/ext/phar/tests/tar/open_for_write_existing_c.phpt +++ b/ext/phar/tests/tar/open_for_write_existing_c.phpt @@ -36,7 +36,7 @@ include $alias . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_c.phar.tar/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/tar/open_for_write_newfile_b.phpt b/ext/phar/tests/tar/open_for_write_newfile_b.phpt index c4192f2a8623..794d02d8acf4 100644 --- a/ext/phar/tests/tar/open_for_write_newfile_b.phpt +++ b/ext/phar/tests/tar/open_for_write_newfile_b.phpt @@ -37,11 +37,11 @@ include $alias . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_b.phar.tar/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_b.phar.tar/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.tar" in %sopen_for_write_newfile_b.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.tar" in %sopen_for_write_newfile_b.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_b.phar.tar/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_b.php on line %d diff --git a/ext/phar/tests/tar/open_for_write_newfile_c.phpt b/ext/phar/tests/tar/open_for_write_newfile_c.phpt index 89887823cc26..13c80ec857ae 100644 --- a/ext/phar/tests/tar/open_for_write_newfile_c.phpt +++ b/ext/phar/tests/tar/open_for_write_newfile_c.phpt @@ -36,11 +36,11 @@ include $alias . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_c.phar.tar/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_c.phar.tar/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.tar" in %sopen_for_write_newfile_c.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.tar" in %sopen_for_write_newfile_c.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_c.phar.tar/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_c.php on line %d diff --git a/ext/phar/tests/tar/rename.phpt b/ext/phar/tests/tar/rename.phpt index b80362bd33fb..7173697c46d3 100644 --- a/ext/phar/tests/tar/rename.phpt +++ b/ext/phar/tests/tar/rename.phpt @@ -39,4 +39,4 @@ echo file_get_contents($alias . '/a') . "\n"; a a -Warning: file_get_contents(phar://%srename.phar.tar/a): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.tar" in %srename.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.tar" in %srename.php on line %d diff --git a/ext/phar/tests/tar/rename_dir.phpt b/ext/phar/tests/tar/rename_dir.phpt index e043cf236a84..205f7d0bd82e 100644 --- a/ext/phar/tests/tar/rename_dir.phpt +++ b/ext/phar/tests/tar/rename_dir.phpt @@ -39,4 +39,4 @@ echo file_get_contents($alias . '/a/x') . "\n"; a a -Warning: file_get_contents(phar://%srename_dir.phar.tar/a/x): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.tar" in %srename_dir.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.tar" in %srename_dir.php on line %d diff --git a/ext/phar/tests/tar/tar_001.phpt b/ext/phar/tests/tar/tar_001.phpt index 55b56c0469ae..2ddeae188e41 100644 --- a/ext/phar/tests/tar/tar_001.phpt +++ b/ext/phar/tests/tar/tar_001.phpt @@ -24,5 +24,5 @@ try { @unlink(__DIR__ . '/tar_001.phar.tar'); ?> --EXPECTF-- -Warning: fopen(phar://%star_001.phar.tar/tar_001.phpt): Failed to open stream: phar error: "%star_001.phar.tar" is a corrupted tar file (truncated) in %star_001.php on line 9 +Warning: fopen(): Failed to open stream: phar error: "%star_001.phar.tar" is a corrupted tar file (truncated) in %star_001.php on line 9 phar error: "%star_001.phar.tar" is a corrupted tar file (truncated) diff --git a/ext/phar/tests/tar/tar_002.phpt b/ext/phar/tests/tar/tar_002.phpt index 75bbe91d8c37..12c7ec3bbccc 100644 --- a/ext/phar/tests/tar/tar_002.phpt +++ b/ext/phar/tests/tar/tar_002.phpt @@ -27,5 +27,5 @@ try { @unlink(__DIR__ . '/tar_002.phar.tar'); ?> --EXPECTF-- -Warning: fopen(phar://%star_002.phar.tar/tar_002.phpt): Failed to open stream: phar error: "%star_002.phar.tar" is a corrupted tar file (truncated) in %star_002.php on line 9 +Warning: fopen(): Failed to open stream: phar error: "%star_002.phar.tar" is a corrupted tar file (truncated) in %star_002.php on line 9 phar error: "%star_002.phar.tar" is a corrupted tar file (truncated) diff --git a/ext/phar/tests/tar/tar_nostub.phpt b/ext/phar/tests/tar/tar_nostub.phpt index 061fa6c8f5ef..708354f82dca 100644 --- a/ext/phar/tests/tar/tar_nostub.phpt +++ b/ext/phar/tests/tar/tar_nostub.phpt @@ -41,6 +41,6 @@ try { @unlink(__DIR__ . '/tar_nostub.tar'); ?> --EXPECTF-- -RecursiveDirectoryIterator::__construct(phar://%star_nostub.phar.tar/): Failed to open directory: '%star_nostub.phar.tar' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive +RecursiveDirectoryIterator::__construct(): Failed to open directory: '%star_nostub.phar.tar' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive phar url "phar://%star_nostub.phar.tar/" is unknown string(0) "" diff --git a/ext/phar/tests/test77022na49ia3c4t8cefa4Wbt b/ext/phar/tests/test77022na49ia3c4t8cefa4Wbt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ext/phar/tests/test_alias_unset.phpt b/ext/phar/tests/test_alias_unset.phpt index 3a11fbac6d5a..0b332514a34b 100644 --- a/ext/phar/tests/test_alias_unset.phpt +++ b/ext/phar/tests/test_alias_unset.phpt @@ -40,4 +40,4 @@ $a = file_get_contents($pname . '/file1.txt'); // this fails because $fname2 ref Cannot open archive "%stest_alias_unset.2.phar.php", alias is already in use by existing archive string(5) "first" -Warning: file_get_contents(phar://%sfile1.txt): Failed to open stream: Cannot open archive "%stest_alias_unset.phar.php", alias is already in use by existing archive in %stest_alias_unset.php on line %d +Warning: file_get_contents(): Failed to open stream: Cannot open archive "%stest_alias_unset.phar.php", alias is already in use by existing archive in %stest_alias_unset.php on line %d diff --git a/ext/phar/tests/zip/create_new_phar_b.phpt b/ext/phar/tests/zip/create_new_phar_b.phpt index 0f4e239f91de..c976a3a2dde0 100644 --- a/ext/phar/tests/zip/create_new_phar_b.phpt +++ b/ext/phar/tests/zip/create_new_phar_b.phpt @@ -13,9 +13,9 @@ file_put_contents('phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.pha include 'phar://' . __DIR__ . '/' . basename(__FILE__, '.php') . '.phar.zip/a.php'; ?> --EXPECTF-- -Warning: file_put_contents(phar://%screate_new_phar_b.phar.zip/a.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d +Warning: file_put_contents(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %screate_new_phar_b.php on line %d -Warning: include(phar://%screate_new_phar_b.phar.zip/a.php): Failed to open stream: %s in %screate_new_phar_b.php on line %d +Warning: include(): Failed to open stream: %s in %screate_new_phar_b.php on line %d Warning: include(): Failed opening 'phar://%screate_new_phar_b.phar.zip/a.php' for inclusion (include_path='%s') in %screate_new_phar_b.php on line %d diff --git a/ext/phar/tests/zip/delete.phpt b/ext/phar/tests/zip/delete.phpt index 7453445f2249..9247a70ea067 100644 --- a/ext/phar/tests/zip/delete.phpt +++ b/ext/phar/tests/zip/delete.phpt @@ -28,4 +28,4 @@ echo file_get_contents($alias . '/a') . "\n"; --EXPECTF-- a -Warning: file_get_contents(phar://%sdelete.phar.zip/a): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.zip" in %sdelete.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%sdelete.phar.zip" in %sdelete.php on line %d diff --git a/ext/phar/tests/zip/delete_in_phar.phpt b/ext/phar/tests/zip/delete_in_phar.phpt index b07f0bdbd8bd..8ebdd95cd2de 100644 --- a/ext/phar/tests/zip/delete_in_phar.phpt +++ b/ext/phar/tests/zip/delete_in_phar.phpt @@ -41,7 +41,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar.phar.zip/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.zip" in %sdelete_in_phar.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.zip" in %sdelete_in_phar.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar.phar.zip/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar.php on line %d diff --git a/ext/phar/tests/zip/delete_in_phar_confirm.phpt b/ext/phar/tests/zip/delete_in_phar_confirm.phpt index f5f65c8ede87..14a2a78b62e0 100644 --- a/ext/phar/tests/zip/delete_in_phar_confirm.phpt +++ b/ext/phar/tests/zip/delete_in_phar_confirm.phpt @@ -46,7 +46,7 @@ This is b/c This is a This is b -Warning: include(%sdelete_in_phar_confirm.phar.zip/b/c.php): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.zip" in %sdelete_in_phar_confirm.php on line %d +Warning: include(): Failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar_confirm.phar.zip" in %sdelete_in_phar_confirm.php on line %d Warning: include(): Failed opening 'phar://%sdelete_in_phar_confirm.phar.zip/b/c.php' for inclusion (include_path='%s') in %sdelete_in_phar_confirm.php on line %d diff --git a/ext/phar/tests/zip/notphar.phpt b/ext/phar/tests/zip/notphar.phpt index ab4f80e430bb..31e8b3f7bb5d 100644 --- a/ext/phar/tests/zip/notphar.phpt +++ b/ext/phar/tests/zip/notphar.phpt @@ -20,5 +20,5 @@ unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.zip'); __HALT_COMPILER(); ?> --EXPECTF-- -Warning: include(phar://%snotphar.phar.zip/.phar/stub.php): Failed to open stream: '%snotphar.phar.zip' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive in %snotphar.php on line %d +Warning: include(): Failed to open stream: '%snotphar.phar.zip' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive in %snotphar.php on line %d PK%a diff --git a/ext/phar/tests/zip/open_for_write_existing_b.phpt b/ext/phar/tests/zip/open_for_write_existing_b.phpt index 9383f3bfe5e5..cc8d07e549b6 100644 --- a/ext/phar/tests/zip/open_for_write_existing_b.phpt +++ b/ext/phar/tests/zip/open_for_write_existing_b.phpt @@ -33,6 +33,6 @@ include $alias . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_b.phar.zip/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_b.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/zip/open_for_write_existing_c.phpt b/ext/phar/tests/zip/open_for_write_existing_c.phpt index 2e972c112f31..b99f76523457 100644 --- a/ext/phar/tests/zip/open_for_write_existing_c.phpt +++ b/ext/phar/tests/zip/open_for_write_existing_c.phpt @@ -33,6 +33,6 @@ include $alias . '/b/c.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_existing_c.phar.zip/b/c.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_existing_c.php on line %d bool(false) This is b/c diff --git a/ext/phar/tests/zip/open_for_write_newfile_b.phpt b/ext/phar/tests/zip/open_for_write_newfile_b.phpt index c70968809b56..4ca15e58c29d 100644 --- a/ext/phar/tests/zip/open_for_write_newfile_b.phpt +++ b/ext/phar/tests/zip/open_for_write_newfile_b.phpt @@ -36,11 +36,11 @@ include $alias . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_b.phar.zip/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_b.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_b.phar.zip/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.zip" in %sopen_for_write_newfile_b.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.zip" in %sopen_for_write_newfile_b.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_b.phar.zip/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_b.php on line %d diff --git a/ext/phar/tests/zip/open_for_write_newfile_c.phpt b/ext/phar/tests/zip/open_for_write_newfile_c.phpt index fbfe2104c84e..89a380d345a9 100644 --- a/ext/phar/tests/zip/open_for_write_newfile_c.phpt +++ b/ext/phar/tests/zip/open_for_write_newfile_c.phpt @@ -36,11 +36,11 @@ include $alias . '/b/new.php'; --CLEAN-- --EXPECTF-- -Warning: fopen(phar://%sopen_for_write_newfile_c.phar.zip/b/new.php): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d +Warning: fopen(): Failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly in %sopen_for_write_newfile_c.php on line %d bool(false) This is b/c -Warning: include(phar://%sopen_for_write_newfile_c.phar.zip/b/new.php): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.zip" in %sopen_for_write_newfile_c.php on line %d +Warning: include(): Failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_c.phar.zip" in %sopen_for_write_newfile_c.php on line %d Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_c.phar.zip/b/new.php' for inclusion (include_path='%s') in %sopen_for_write_newfile_c.php on line %d diff --git a/ext/phar/tests/zip/rename.phpt b/ext/phar/tests/zip/rename.phpt index 209a6b4ac475..362f0c04d00e 100644 --- a/ext/phar/tests/zip/rename.phpt +++ b/ext/phar/tests/zip/rename.phpt @@ -31,4 +31,4 @@ echo file_get_contents($alias . '/a') . "\n"; a a -Warning: file_get_contents(phar://%srename.phar.zip/a): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.zip" in %srename.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a" is not a file in phar "%srename.phar.zip" in %srename.php on line %d diff --git a/ext/phar/tests/zip/rename_dir.phpt b/ext/phar/tests/zip/rename_dir.phpt index 76d07734e5b9..e8a26f153841 100644 --- a/ext/phar/tests/zip/rename_dir.phpt +++ b/ext/phar/tests/zip/rename_dir.phpt @@ -31,4 +31,4 @@ echo file_get_contents($alias . '/a/x') . "\n"; a a -Warning: file_get_contents(phar://%srename_dir.phar.zip/a/x): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.zip" in %srename_dir.php on line %d +Warning: file_get_contents(): Failed to open stream: phar error: "a/x" is not a file in phar "%srename_dir.phar.zip" in %srename_dir.php on line %d diff --git a/ext/phar/tests/zip/zip_extra_underflow.phpt b/ext/phar/tests/zip/zip_extra_underflow.phpt new file mode 100644 index 000000000000..e37a3493b663 --- /dev/null +++ b/ext/phar/tests/zip/zip_extra_underflow.phpt @@ -0,0 +1,91 @@ +--TEST-- +Phar: ZIP extra field length must not underflow +--EXTENSIONS-- +phar +--FILE-- +getMTime(), "\n"; +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +?> +--CLEAN-- + +--EXPECTF-- +phar error: Unable to process extra field header for file in central directory in zip-based phar "%szip_extra_underflow.zip" diff --git a/ext/phar/util.c b/ext/phar/util.c index fdadc4d9b6bf..c78ee50ece15 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -3,15 +3,13 @@ | phar php single-file executable PHP extension | | utility functions | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -36,54 +34,62 @@ #include #include #else -static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); +ZEND_ATTRIBUTE_NONNULL static bool phar_call_openssl_verify(php_stream *fp, zend_off_t end, zend_string *public_key, const char *signature, size_t signature_len, uint32_t sig_type); +static zend_result phar_call_openssl_sign(php_stream *fp, zend_off_t end, const char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); #endif /* for links to relative location, prepend cwd of the entry */ -static char *phar_get_link_location(phar_entry_info *entry) /* {{{ */ +static zend_string *phar_get_link_location(phar_entry_info *entry) /* {{{ */ { - char *p, *ret = NULL; - if (!entry->link) { - return NULL; - } - if (entry->link[0] == '/') { - return estrdup(entry->link + 1); + ZEND_ASSERT(entry->symlink); + + if (ZSTR_VAL(entry->symlink)[0] == '/') { + return zend_string_init(ZSTR_VAL(entry->symlink) + 1, ZSTR_LEN(entry->symlink) - 1, false); } - p = strrchr(ZSTR_VAL(entry->filename), '/'); + const char *p = strrchr(ZSTR_VAL(entry->filename), '/'); if (p) { /* Important: don't modify the original `p` data because it is a shared string. */ zend_string *new_name = zend_string_init(ZSTR_VAL(entry->filename), p - ZSTR_VAL(entry->filename), false); - spprintf(&ret, 0, "%s/%s", ZSTR_VAL(new_name), entry->link); + zend_string *location = zend_string_concat3( + ZSTR_VAL(new_name), ZSTR_LEN(new_name), + ZEND_STRL("/"), + ZSTR_VAL(entry->symlink), ZSTR_LEN(entry->symlink) + ); zend_string_release(entry->filename); entry->filename = new_name; - return ret; + return location; } - return entry->link; + return zend_string_copy(entry->symlink); } /* }}} */ phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */ { phar_entry_info *link_entry; - char *link; + uint32_t depth = 0, max_depth; - if (!entry->link) { + if (!entry->symlink) { return entry; } - link = phar_get_link_location(entry); - if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) || - NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) { - if (link != entry->link) { - efree(link); + max_depth = zend_hash_num_elements(&(entry->phar->manifest)); + + while (entry->symlink) { + if (UNEXPECTED(++depth > max_depth)) { + return NULL; } - return phar_get_link_source(link_entry); - } else { - if (link != entry->link) { - efree(link); + zend_string *link = phar_get_link_location(entry); + + if (NULL != (link_entry = zend_hash_find_ptr(&(entry->phar->manifest), entry->symlink)) || + NULL != (link_entry = zend_hash_find_ptr(&(entry->phar->manifest), link))) { + zend_string_release(link); + entry = link_entry; + } else { + zend_string_release(link); + return NULL; } - return NULL; } + return entry; } /* }}} */ @@ -98,7 +104,7 @@ static php_stream *phar_get_entrypufp(const phar_entry_info *entry) /* retrieve a phar_entry_info's current file pointer for reading contents */ php_stream *phar_get_efp(phar_entry_info *entry, bool follow_links) /* {{{ */ { - if (follow_links && entry->link) { + if (follow_links && entry->symlink) { phar_entry_info *link_entry = phar_get_link_source(entry); if (link_entry && link_entry != entry) { @@ -190,7 +196,7 @@ int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_of /* }}} */ /* mount an absolute path or uri to a path internal to the phar archive */ -zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ +zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ { phar_entry_info entry = {0}; php_stream_statbuf ssb; @@ -201,7 +207,7 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil return FAILURE; } - if (path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) { + if (phar_path_is_magic_phar_ex(path, path_len)) { /* no creating magic phar files by mounting them */ return FAILURE; } @@ -265,19 +271,13 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil } /* }}} */ -zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */ +zend_string *phar_find_in_include_path(const zend_string *filename) /* {{{ */ { zend_string *ret; - char *path, *arch, *test; - size_t arch_len; + char *path; + zend_string *arch; phar_archive_data *phar; - if (pphar) { - *pphar = NULL; - } else { - pphar = &phar; - } - if (!zend_is_executing() || !PHAR_G(cwd)) { return NULL; } @@ -293,72 +293,57 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data if ( PHAR_G(last_phar) && is_file_a_phar_wrapper - && ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len) - && !memcmp(ZSTR_VAL(fname) + length_phar_protocol, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)) + && ZSTR_LEN(fname) - length_phar_protocol >= ZSTR_LEN(PHAR_G(last_phar_name)) + && !memcmp(ZSTR_VAL(fname) + length_phar_protocol, ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name))) ) { - arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)); - arch_len = PHAR_G(last_phar_name_len); + arch = zend_string_init(ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name)), false); phar = PHAR_G(last_phar); goto splitted; } - if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, NULL, NULL, 1, 0)) { + if (!is_file_a_phar_wrapper) { + return NULL; + } + arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 1, 0); + if (!arch) { return NULL; } if (*ZSTR_VAL(filename) == '.') { - size_t try_len; - - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); + phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + if (!phar) { + zend_string_release_ex(arch, false); return NULL; } -splitted: - if (pphar) { - *pphar = phar; - } - - try_len = ZSTR_LEN(filename); - test = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &try_len, 1); - - if (*test == '/') { - if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) { - ret = strpprintf(0, "phar://%s%s", arch, test); - efree(arch); - efree(test); +splitted:; + zend_string *test = phar_fix_filepath(ZSTR_VAL(filename), ZSTR_LEN(filename), true); + if (ZSTR_VAL(test)[0] == '/') { + if (zend_hash_str_exists(&(phar->manifest), ZSTR_VAL(test) + 1, ZSTR_LEN(test) - 1)) { + ret = zend_string_concat3( + "phar://", strlen("phar://"), + ZSTR_VAL(arch), ZSTR_LEN(arch), + ZSTR_VAL(test), ZSTR_LEN(test) + ); + zend_string_release_ex(test, false); + zend_string_release_ex(arch, false); return ret; } } else { - if (zend_hash_str_exists(&(phar->manifest), test, try_len)) { - ret = strpprintf(0, "phar://%s/%s", arch, test); - efree(arch); - efree(test); + if (zend_hash_exists(&(phar->manifest), test)) { + ret = strpprintf(0, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(test)); + zend_string_release_ex(test, false); + zend_string_release_ex(arch, false); return ret; } } - efree(test); + zend_string_release_ex(test, false); } - spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); - efree(arch); + spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", ZSTR_VAL(arch), PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); + zend_string_release_ex(arch, false); ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path); efree(path); - if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) { - /* found phar:// */ - if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, NULL, NULL, 1, 0)) { - return ret; - } - - *pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len); - - if (!*pphar && PHAR_G(manifest_cached)) { - *pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len); - } - - efree(arch); - } - return ret; } /* }}} */ @@ -385,9 +370,9 @@ static ZEND_ATTRIBUTE_NONNULL zend_result phar_create_writeable_entry(phar_archi } /* open a new temp file for writing */ - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } @@ -438,13 +423,13 @@ ZEND_ATTRIBUTE_NONNULL static zend_result phar_separate_entry_fp(phar_entry_info } if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, false), fp, link->uncompressed_filesize, NULL)) { - spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return FAILURE; } - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } @@ -464,9 +449,8 @@ ZEND_ATTRIBUTE_NONNULL static zend_result phar_separate_entry_fp(phar_entry_info * appended, truncated, or read. For read, if the entry is marked unmodified, it is * assumed that the file pointer, if present, is opened for reading */ -ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, const zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security) /* {{{ */ { - phar_archive_data *phar; phar_entry_info *entry; bool for_write = mode[0] != 'r' || mode[1] == '+'; bool for_append = mode[0] == 'a'; @@ -476,29 +460,32 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch *ret = NULL; *error = NULL; - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 0, error); + if (!phar) { return FAILURE; } if (for_write && PHAR_G(readonly) && !phar->is_data) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, fname); + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, ZSTR_VAL(fname)); return FAILURE; } if (!path_len) { - spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", fname); + spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", ZSTR_VAL(fname)); return FAILURE; } really_get_entry: if (allow_dir) { - if ((entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) { + entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security); + if (!entry) { if (for_create && (!PHAR_G(readonly) || phar->is_data)) { return SUCCESS; } return FAILURE; } } else { - if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) { + entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security); + if (!entry) { if (for_create && (!PHAR_G(readonly) || phar->is_data)) { return SUCCESS; } @@ -508,7 +495,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch if (for_write && phar->is_persistent) { if (FAILURE == phar_copy_on_write(&phar)) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, fname); + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, ZSTR_VAL(fname)); return FAILURE; } else { goto really_get_entry; @@ -516,12 +503,12 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch } if (entry->is_modified && !for_write) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, fname); + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, ZSTR_VAL(fname)); return FAILURE; } if (entry->fp_refcount && for_write) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, fname); + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, ZSTR_VAL(fname)); return FAILURE; } @@ -557,9 +544,9 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch } } else { if (for_write) { - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } @@ -584,7 +571,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch (*ret)->phar = phar; (*ret)->internal_file = entry; (*ret)->fp = phar_get_efp(entry, true); - if (entry->link) { + if (entry->symlink) { phar_entry_info *link = phar_get_link_source(entry); if(!link) { efree(*ret); @@ -607,10 +594,9 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, ch /** * Create a new dummy file slot within a writeable phar for a newly created file */ -ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp) /* {{{ */ { - phar_archive_data *phar; - phar_entry_info *entry, etemp; + phar_entry_info etemp; phar_entry_data *ret; const char *pcr_error; char is_dir; @@ -621,11 +607,12 @@ ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fnam is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0; - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 0, error); + if (!phar) { return NULL; } - if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error, security)) { + if (FAILURE == phar_get_entry_data(&ret, fname, path, path_len, mode, allow_dir, error, security)) { return NULL; } else if (ret) { return ret; @@ -637,7 +624,7 @@ ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fnam } if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, fname); + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, ZSTR_VAL(fname)); return NULL; } @@ -680,10 +667,11 @@ ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fnam etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE; } - if (NULL == (entry = zend_hash_add_mem(&phar->manifest, etemp.filename, &etemp, sizeof(phar_entry_info)))) { + phar_entry_info *entry = zend_hash_add_mem(&phar->manifest, etemp.filename, &etemp, sizeof(phar_entry_info)); + if (!entry) { php_stream_close(etemp.fp); spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", - ZSTR_VAL(etemp.filename), phar->fname); + ZSTR_VAL(etemp.filename), ZSTR_VAL(phar->fname)); efree(ret); zend_string_efree(etemp.filename); return NULL; @@ -718,11 +706,11 @@ php_stream *phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ return stream; } - if (php_check_open_basedir(phar->fname)) { + if (php_check_open_basedir(ZSTR_VAL(phar->fname))) { return NULL; } - stream = php_stream_open_wrapper(phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); + stream = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); phar_set_pharfp(phar, stream); return stream; @@ -738,9 +726,9 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_copy_entry_fp(phar_entry_info *source, p return FAILURE; } - if (dest->link) { - efree(dest->link); - dest->link = NULL; + if (dest->symlink) { + zend_string_release(dest->symlink); + dest->symlink = NULL; dest->tar_type = (dest->is_tar ? TAR_FILE : '\0'); } @@ -763,7 +751,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_copy_entry_fp(phar_entry_info *source, p php_stream_close(dest->fp); dest->fp_type = PHAR_FP; spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", - ZSTR_VAL(source->filename), ZSTR_VAL(dest->filename), source->phar->fname); + ZSTR_VAL(source->filename), ZSTR_VAL(dest->filename), ZSTR_VAL(source->phar->fname)); return FAILURE; } @@ -799,13 +787,12 @@ static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zen */ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, bool follow_links) /* {{{ */ { - php_stream_filter *filter; phar_archive_data *phar = entry->phar; zend_off_t loc; php_stream *ufp; phar_entry_data dummy; - if (follow_links && entry->link) { + if (follow_links && entry->symlink) { phar_entry_info *link_entry = phar_get_link_source(entry); if (link_entry && link_entry != entry) { return phar_open_entry_fp(link_entry, error, true); @@ -830,7 +817,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch if (!phar_get_pharfp(phar)) { if (!phar_open_archive_fp(phar)) { - spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", phar->fname); + spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", ZSTR_VAL(phar->fname)); return FAILURE; } } @@ -849,7 +836,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch if (!phar_get_entrypufp(entry)) { phar_set_entrypufp(entry, php_stream_fopen_tmpfile()); if (!phar_get_entrypufp(entry)) { - spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } } @@ -864,15 +851,16 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch ufp = phar_get_entrypufp(entry); - const char *filter_name = phar_decompress_filter(entry, false); - if (filter_name != NULL) { - filter = php_stream_filter_create(filter_name, NULL, 0); - } else { - filter = NULL; + const char *decompression_filter_name = phar_get_decompress_filter_name(entry); + if (UNEXPECTED(!decompression_filter_name)) { + spprintf(error, 4096, "phar error: unable to read phar \"%s\" (file \"%s\" is compressed with an unknown compression algorithm)", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); + return FAILURE; } + php_stream_filter *filter = php_stream_filter_create(decompression_filter_name, NULL, 0); + if (!filter) { - spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, true), ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", ZSTR_VAL(phar->fname), decompression_filter_name, ZSTR_VAL(entry->filename)); return FAILURE; } @@ -885,7 +873,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch if (entry->uncompressed_filesize) { if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry), ufp, entry->compressed_filesize, NULL)) { - spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); php_stream_filter_remove(filter, 1); return FAILURE; } @@ -896,7 +884,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, ch php_stream_filter_remove(filter, 1); if (php_stream_tell(ufp) - loc != (zend_off_t) entry->uncompressed_filesize) { - spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -924,27 +912,28 @@ ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data * return NULL; } if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, true)) { - spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); return NULL; } return entry; } /* }}} */ -zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ +zend_result phar_free_alias(const phar_archive_data *phar) /* {{{ */ { if (phar->refcount || phar->is_persistent) { return FAILURE; } /* this archive has no open references, so emit a notice and remove it */ - if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + if (zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { return FAILURE; } /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; return SUCCESS; } @@ -954,11 +943,9 @@ zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_l * Looks up a phar archive in the filename map, connecting it to the alias * (if any) or returns null */ -zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ +phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error) /* {{{ */ { - phar_archive_data *fd, *fd_ptr; - char *my_realpath, *save; - size_t save_len; + phar_archive_data *archive; phar_request_initialize(); @@ -966,199 +953,169 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn *error = NULL; } - *archive = NULL; - - if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) { - *archive = PHAR_G(last_phar); + if (PHAR_G(last_phar) && zend_string_equals_cstr(PHAR_G(last_phar_name), fname, fname_len)) { + archive = PHAR_G(last_phar); if (alias && alias_len) { if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(PHAR_G(last_phar)->fname), fname); } - *archive = NULL; - return FAILURE; + return NULL; } - if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) { + if (PHAR_G(last_phar)->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len)) { zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); PHAR_G(last_alias) = alias; PHAR_G(last_alias_len) = alias_len; } - return SUCCESS; - } - - if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { - fd = PHAR_G(last_phar); - fd_ptr = fd; - goto alias_success; + return archive; } if (alias && alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { -alias_success: - if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) { + /* If the alias stored in the last_phar cache matches, just use it directly */ + if (PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { + archive = PHAR_G(last_phar); + } else { + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + } + + /* If we didn't find the alias, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_alias, alias, alias_len); + } + + if (archive) { + if (!zend_string_equals_cstr(archive->fname, fname, fname_len)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) { + if (SUCCESS == phar_free_alias(archive)) { if (error) { efree(*error); *error = NULL; } } - return FAILURE; + return NULL; } - *archive = fd_ptr; - fd = fd_ptr; - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; PHAR_G(last_alias) = alias; PHAR_G(last_alias_len) = alias_len; - return SUCCESS; - } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) { - goto alias_success; + return archive; } } - my_realpath = NULL; - save = fname; - save_len = fname_len; - if (fname && fname_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) { - *archive = fd_ptr; - fd = fd_ptr; - + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len); + if (archive) { if (alias && alias_len) { - if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) { + if (!archive->is_temporary_alias && (alias_len != archive->alias_len || memcmp(archive->alias, alias, alias_len))) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - return FAILURE; + return NULL; } - if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len); + if (archive->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), archive->alias, archive->alias_len)) { + zend_hash_str_del(&(PHAR_G(phar_alias_map)), archive->alias, archive->alias_len); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { - *archive = fd_ptr; - fd = fd_ptr; - + if (PHAR_G(manifest_cached) && NULL != (archive = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { /* this could be problematic - alias should never be different from manifest alias for cached phars */ - if (!fd->is_temporary_alias && alias && alias_len) { - if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) { + if (!archive->is_temporary_alias && alias && alias_len) { + if (alias_len != archive->alias_len || memcmp(archive->alias, alias, alias_len)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - return FAILURE; + return NULL; } } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len))) { - fd = *archive = fd_ptr; + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fname, fname_len); - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; - - return SUCCESS; + /* If we didn't find the fname in the alias map, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_alias, fname, fname_len); } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) { - fd = *archive = fd_ptr; + if (archive) { + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; - - return SUCCESS; + return archive; } /* not found, try converting \ to / */ - my_realpath = expand_filepath(fname, my_realpath); + char *my_realpath = expand_filepath(fname, NULL); - if (my_realpath) { - fname_len = strlen(my_realpath); - fname = my_realpath; - } else { - return FAILURE; + if (UNEXPECTED(!my_realpath)) { + return NULL; } + + size_t my_realpath_len = strlen(my_realpath); #ifdef PHP_WIN32 - phar_unixify_path_separators(fname, fname_len); + phar_unixify_path_separators(my_realpath, my_realpath_len); #endif - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) { -realpath_success: - *archive = fd_ptr; - fd = fd_ptr; + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), my_realpath, my_realpath_len); + /* If we didn't find the path in the fname map, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_phars, my_realpath, my_realpath_len); + } + efree(my_realpath); + + if (archive) { if (alias && alias_len) { - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); } - efree(my_realpath); - - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; - } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { - goto realpath_success; + return archive; } - - efree(my_realpath); } - return FAILURE; + return NULL; } /* }}} */ /** * Determine which stream compression filter (if any) we need to read this file */ -const char * phar_compress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */ +const char * phar_get_compress_filter_name(const phar_entry_info *entry) { switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) { case PHAR_ENT_COMPRESSED_GZ: @@ -1166,15 +1123,14 @@ const char * phar_compress_filter(const phar_entry_info *entry, bool return_unkn case PHAR_ENT_COMPRESSED_BZ2: return "bzip2.compress"; default: - return return_unknown ? "unknown" : NULL; + return NULL; } } -/* }}} */ /** * Determine which stream decompression filter (if any) we need to read this file */ -const char * phar_decompress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */ +const char * phar_get_decompress_filter_name(const phar_entry_info *entry) { uint32_t flags; @@ -1190,10 +1146,9 @@ const char * phar_decompress_filter(const phar_entry_info *entry, bool return_un case PHAR_ENT_COMPRESSED_BZ2: return "bzip2.decompress"; default: - return return_unknown ? "unknown" : NULL; + return NULL; } } -/* }}} */ /** * retrieve information on a file contained within a phar, or null if it ain't there @@ -1212,7 +1167,6 @@ phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, bool security) /* {{{ */ { const char *pcr_error; - phar_entry_info *entry; bool is_dir; #ifdef PHP_WIN32 @@ -1225,7 +1179,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si *error = NULL; } - if (security && path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) { + if (security && phar_path_is_magic_phar_ex(path, path_len)) { if (error) { spprintf(error, 4096, "phar error: cannot directly access magic \".phar\" directory or files within it"); } @@ -1257,7 +1211,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si path_len--; } - if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) { + phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len); + if (entry) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return NULL; @@ -1271,7 +1226,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si if (!entry->is_dir && dir == 2) { /* user requested a directory, we must return one */ if (error) { - spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path); + spprintf(error, 4096, "phar error: path \"%s\" exists and is not a directory", path); } return NULL; } @@ -1301,7 +1256,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si size_t test_len; php_stream_statbuf ssb; - if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) { + entry = zend_hash_find_ptr(&phar->manifest, str_key); + if (!entry) { if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", ZSTR_VAL(str_key)); } @@ -1334,7 +1290,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si efree(test); /* user requested a directory, we must return one */ if (error) { - spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path); + spprintf(error, 4096, "phar error: path \"%s\" exists and is not a directory", path); } return NULL; } @@ -1350,7 +1306,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si efree(test); - if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) { + entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len); + if (!entry) { if (error) { spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test); } @@ -1367,53 +1324,61 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si static const char hexChars[] = "0123456789ABCDEF"; -static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* {{{ */ +static size_t phar_hex_str(const char *digest, size_t digest_len, char **signature) /* {{{ */ { - int pos = -1; + size_t pos = 0; size_t len = 0; *signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist)); for (; len < digest_len; ++len) { - (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] >> 4]; - (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] & 0x0F]; + (*signature)[pos++] = hexChars[((const unsigned char *)digest)[len] >> 4]; + (*signature)[pos++] = hexChars[((const unsigned char *)digest)[len] & 0x0F]; } - (*signature)[++pos] = '\0'; + (*signature)[pos] = '\0'; return pos; } /* }}} */ #ifndef PHAR_HAVE_OPENSSL -static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ -{ - zval retval, zp[4]; - zend_string *str; - - zend_function *fn = NULL; - if (is_sign) { - fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_sign")); - } else { - fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_verify")); - } +ZEND_ATTRIBUTE_NONNULL static bool phar_call_openssl_verify( + php_stream *fp, + zend_off_t end, + zend_string *public_key, + const char *signature, + size_t signature_len, + uint32_t sig_type +) { + ZEND_ASSERT(signature_len != 0); + zend_function *fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_verify")); /* OpenSSL is not available, even as a shared module */ - if (fn == NULL) { - return FAILURE; + if (UNEXPECTED(fn == NULL)) { + return false; } - if (*signature_len) { - ZVAL_STRINGL(&zp[1], *signature, *signature_len); - } else { - ZVAL_EMPTY_STRING(&zp[1]); - } - ZVAL_STRINGL(&zp[2], key, key_len); + /* Read and copy stream content */ php_stream_rewind(fp); - str = php_stream_copy_to_mem(fp, (size_t) end, 0); - if (str) { - ZVAL_STR(&zp[0], str); - } else { - ZVAL_EMPTY_STRING(&zp[0]); - } + zend_string *str = php_stream_copy_to_mem(fp, (size_t) end, false); + /* No content thus signing must fail */ + if (UNEXPECTED(str == NULL || (size_t)end != ZSTR_LEN(str))) { + return false; + } + + /* Set up parameters for call to openssl_verify() + * openssl_verify( + * string $data, + * string $signature, + * OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key, + * string|int $algorithm = OPENSSL_ALGO_SHA1, + * int $padding = 0 + * ): int|false + */ + zval retval, zp[4]; + ZVAL_STR(&zp[0], str); + ZVAL_STRINGL(&zp[1], signature, signature_len); + /* Note we do not own the lifetime of the public key, but it is fine as calling the function will increase the refcount) */ + ZVAL_STR(&zp[2], public_key); if (sig_type == PHAR_SIG_OPENSSL_SHA512) { ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */ } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) { @@ -1422,52 +1387,84 @@ static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, ze /* don't rely on default value which may change in the future */ ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */ } + zend_call_known_function(fn, NULL, NULL, &retval, /* param_count */ 4, zp, NULL); + /* Free string arguments that we own */ + zval_ptr_dtor_str(&zp[0]); + zval_ptr_dtor_str(&zp[1]); - if ((size_t)end != Z_STRLEN(zp[0])) { - zval_ptr_dtor_str(&zp[0]); - zval_ptr_dtor_str(&zp[1]); - zval_ptr_dtor_str(&zp[2]); + /* Returns 1 if the signature is correct, 0 if it is incorrect, and -1 or false on error. */ + switch (Z_TYPE(retval)) { + case IS_LONG: + if (1 == Z_LVAL(retval)) { + return true; + } + ZEND_FALLTHROUGH; + default: + /* Unlikely, but the openssl_verify() function may be disabled and redefined in userland and return bollocks */ + zval_ptr_dtor(&retval); + return false; + } +} + +static zend_result phar_call_openssl_sign(php_stream *fp, zend_off_t end, const char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ +{ + ZEND_ASSERT(end != 0); + ZEND_ASSERT(*signature_len == 0); + zval retval, zp[4]; + + zend_function *fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_sign")); + + /* OpenSSL is not available, even as a shared module */ + if (fn == NULL) { + return FAILURE; + } + + /* Read and copy stream content */ + php_stream_rewind(fp); + zend_string *str = php_stream_copy_to_mem(fp, (size_t) end, false); + /* No content thus signing must fail */ + if (!str || (size_t)end != ZSTR_LEN(str)) { return FAILURE; } - Z_ADDREF(zp[0]); - if (is_sign) { - ZVAL_NEW_REF(&zp[1], &zp[1]); + /* Set up parameters for call to openssl_sign() + * openssl_sign( + * string $data, + * string &$signature, + * #[\SensitiveParameter] OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, + * string|int $algorithm = OPENSSL_ALGO_SHA1, + * int $padding = 0 + * ): bool + */ + ZVAL_STR(&zp[0], str); + ZVAL_EMPTY_STRING(&zp[1]); + ZVAL_NEW_REF(&zp[1], &zp[1]); + ZVAL_STRINGL(&zp[2], key, key_len); + if (sig_type == PHAR_SIG_OPENSSL_SHA512) { + ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */ + } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) { + ZVAL_LONG(&zp[3], 7); /* value from openssl.c #define OPENSSL_ALGO_SHA256 7 */ } else { - Z_ADDREF(zp[1]); + /* don't rely on default value which may change in the future */ + ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */ } - Z_ADDREF(zp[2]); zend_call_known_function(fn, NULL, NULL, &retval, /* param_count */ 4, zp, NULL); - Z_DELREF(zp[0]); - - if (is_sign) { - ZVAL_UNREF(&zp[1]); - } else { - Z_DELREF(zp[1]); - } - Z_DELREF(zp[2]); + ZVAL_UNREF(&zp[1]); zval_ptr_dtor_str(&zp[0]); zval_ptr_dtor_str(&zp[2]); switch (Z_TYPE(retval)) { - case IS_LONG: - zval_ptr_dtor(&zp[1]); - if (1 == Z_LVAL(retval)) { - return SUCCESS; - } - return FAILURE; case IS_TRUE: *signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1])); *signature_len = Z_STRLEN(zp[1]); zval_ptr_dtor(&zp[1]); return SUCCESS; default: + /* Unlikely, but the openssl_sign() function may be disabled and redefined in userland and return bollocks */ zval_ptr_dtor(&retval); - ZEND_FALLTHROUGH; - case IS_FALSE: zval_ptr_dtor(&zp[1]); return FAILURE; } @@ -1475,7 +1472,7 @@ static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, ze /* }}} */ #endif /* #ifndef PHAR_HAVE_OPENSSL */ -zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ { size_t read_size, len; zend_off_t read_len; @@ -1500,8 +1497,6 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } else { mdtype = EVP_sha1(); } -#else - size_t tempsig; #endif zend_string *pubkey = NULL; char *pfile; @@ -1519,21 +1514,24 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL); efree(pfile); - if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !ZSTR_LEN(pubkey)) { - if (pfp) { - php_stream_close(pfp); - } + if (!pfp) { if (error) { *error = estrdup("openssl public key could not be read"); } return FAILURE; } + pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0); php_stream_close(pfp); -#ifndef PHAR_HAVE_OPENSSL - tempsig = sig_len; + if (!pubkey || !ZSTR_LEN(pubkey)) { + if (error) { + *error = estrdup("openssl public key could not be read"); + } + return FAILURE; + } - if (FAILURE == phar_call_openssl_signverify(false, fp, end_of_phar, ZSTR_VAL(pubkey), ZSTR_LEN(pubkey), &sig, &tempsig, sig_type)) { +#ifndef PHAR_HAVE_OPENSSL + if (!phar_call_openssl_verify(fp, end_of_phar, pubkey, sig, sig_len, sig_type)) { zend_string_release_ex(pubkey, 0); if (error) { @@ -1543,9 +1541,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s return FAILURE; } - zend_string_release_ex(pubkey, 0); - - sig_len = tempsig; + zend_string_release_ex(pubkey, false); #else in = BIO_new_mem_buf(ZSTR_VAL(pubkey), ZSTR_LEN(pubkey)); @@ -1573,6 +1569,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (md_ctx) { EVP_MD_CTX_destroy(md_ctx); } + EVP_PKEY_free(key); if (error) { *error = estrdup("openssl signature could not be verified"); } @@ -1616,7 +1613,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s EVP_MD_CTX_destroy(md_ctx); #endif - *signature_len = phar_hex_str((const char*)sig, sig_len, signature); + *signature_len = phar_hex_str(sig, sig_len, signature); } break; case PHAR_SIG_SHA512: { @@ -1789,8 +1786,9 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } /* }}} */ -ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error) /* {{{ */ { + zend_string *signature = NULL; unsigned char buf[1024]; size_t sig_len; @@ -1813,8 +1811,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA512Final(digest, &context); - *signature = estrndup((char *) digest, 64); - *signature_length = 64; + signature = zend_string_init((const char*)digest, 64, false); break; } default: @@ -1831,8 +1828,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA256Final(digest, &context); - *signature = estrndup((char *) digest, 32); - *signature_length = 32; + signature = zend_string_init((const char*)digest, 32, false); break; } case PHAR_SIG_OPENSSL_SHA512: @@ -1857,8 +1853,8 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len)); if (in == NULL) { - spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname); - return FAILURE; + spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } key = PEM_read_bio_PrivateKey(in, NULL,NULL, ""); @@ -1866,14 +1862,14 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar if (!key) { *error = estrdup("unable to process private key"); - return FAILURE; + return NULL; } md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { EVP_PKEY_free(key); - spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname); - return FAILURE; + spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } siglen = EVP_PKEY_size(key); @@ -1883,8 +1879,8 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname); - return FAILURE; + spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { @@ -1892,8 +1888,8 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", phar->fname); - return FAILURE; + spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } } @@ -1901,26 +1897,28 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); - return FAILURE; + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } sigbuf[siglen] = '\0'; EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #else size_t siglen; sigbuf = NULL; siglen = 0; php_stream_seek(fp, 0, SEEK_END); - if (FAILURE == phar_call_openssl_signverify(true, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) { - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); - return FAILURE; + if (FAILURE == phar_call_openssl_sign(fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) { + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #endif - *signature = (char *) sigbuf; - *signature_length = siglen; } break; case PHAR_SIG_SHA1: { @@ -1934,8 +1932,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA1Final(digest, &context); - *signature = estrndup((char *) digest, 20); - *signature_length = 20; + signature = zend_string_init((const char*)digest, 20, false); break; } case PHAR_SIG_MD5: { @@ -1949,19 +1946,18 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_MD5Final(digest, &context); - *signature = estrndup((char *) digest, 16); - *signature_length = 16; + signature = zend_string_init((const char*)digest, 16, false); break; } } - phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature); - return SUCCESS; + phar->sig_len = phar_hex_str(ZSTR_VAL(signature), ZSTR_LEN(signature), &phar->signature); + return signature; } /* }}} */ // TODO: convert this to zend_string too -void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len) /* {{{ */ +void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len) /* {{{ */ { const char *s; zend_string *str; @@ -1992,8 +1988,8 @@ static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */ entry->phar = (phar_archive_data *)argument; - if (entry->link) { - entry->link = estrdup(entry->link); + if (entry->symlink) { + zend_string_addref(entry->symlink); } if (entry->tmp) { @@ -2017,19 +2013,15 @@ static void phar_manifest_copy_ctor(zval *zv) /* {{{ */ } /* }}} */ -static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ +static phar_archive_data* phar_copy_cached_phar(const phar_archive_data *persistent_phar) /* {{{ */ { - phar_archive_data *phar; HashTable newmanifest; - char *fname; phar_archive_object *objphar; - phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data)); - *phar = **pphar; + phar_archive_data *phar = emalloc(sizeof(phar_archive_data)); + *phar = *persistent_phar; phar->is_persistent = 0; - fname = phar->fname; - phar->fname = estrndup(phar->fname, phar->fname_len); - phar->ext = phar->fname + (phar->ext - fname); + zend_string_addref(phar->fname); if (phar->alias) { phar->alias = estrndup(phar->alias, phar->alias_len); @@ -2041,45 +2033,40 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ phar_metadata_tracker_clone(&phar->metadata_tracker); - zend_hash_init(&newmanifest, sizeof(phar_entry_info), - zend_get_hash_value, destroy_phar_manifest_entry, 0); - zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor); + zend_hash_init(&newmanifest, sizeof(phar_entry_info), NULL, destroy_phar_manifest_entry, 0); + zend_hash_copy(&newmanifest, &persistent_phar->manifest, phar_manifest_copy_ctor); zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar); phar->manifest = newmanifest; - zend_hash_init(&phar->mounted_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_init(&phar->virtual_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL); - *pphar = phar; + zend_hash_init(&phar->mounted_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_init(&phar->virtual_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_copy(&phar->virtual_dirs, &persistent_phar->virtual_dirs, NULL); /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */ ZEND_HASH_MAP_FOREACH_PTR(&PHAR_G(phar_persist_map), objphar) { - if (objphar->archive->fname_len == phar->fname_len && !memcmp(objphar->archive->fname, phar->fname, phar->fname_len)) { + if (zend_string_equals(objphar->archive->fname, phar->fname)) { objphar->archive = phar; } } ZEND_HASH_FOREACH_END(); + return phar; } /* }}} */ zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ { - zval zv, *pzv; - phar_archive_data *newpphar; + phar_archive_data *newpphar = phar_copy_cached_phar(*pphar); - ZVAL_PTR(&zv, *pphar); - if (NULL == (pzv = zend_hash_str_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len, &zv))) { + zval *pzv = zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), newpphar->fname, newpphar); + if (!pzv) { return FAILURE; } - phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv)); - newpphar = Z_PTR_P(pzv); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) { - zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), newpphar->fname); return FAILURE; } diff --git a/ext/phar/zip.c b/ext/phar/zip.c index c342c8868d3e..8703979f234b 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | ZIP archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ @@ -41,19 +39,30 @@ static inline void phar_write_16(char buffer[2], uint32_t value) # define PHAR_SET_32(var, value) phar_write_32(var, (uint32_t) (value)); # define PHAR_SET_16(var, value) phar_write_16(var, (uint16_t) (value)); -static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, uint16_t len) /* {{{ */ +static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, uint16_t extra_len) /* {{{ */ { union { phar_zip_extra_field_header header; phar_zip_unix3 unix3; phar_zip_unix_time time; } h; + size_t len = extra_len; size_t read; - do { + while (len) { + size_t header_size; + + if (len < sizeof(h.header)) { + return FAILURE; + } if (sizeof(h.header) != php_stream_read(fp, (char *) &h.header, sizeof(h.header))) { return FAILURE; } + len -= sizeof(h.header); + header_size = PHAR_GET_16(h.header.size); + if (header_size > len) { + return FAILURE; + } if (h.header.tag[0] == 'U' && h.header.tag[1] == 'T') { /* Unix timestamp header found. @@ -62,7 +71,6 @@ static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry * We only store the modification time in the entry, so only read that. */ const size_t min_size = 5; - uint16_t header_size = PHAR_GET_16(h.header.size); if (header_size >= min_size) { read = php_stream_read(fp, &h.time.flags, min_size); if (read != min_size) { @@ -73,12 +81,11 @@ static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry entry->timestamp = PHAR_GET_32(h.time.time); } - len -= header_size + 4; - /* Consume remaining bytes */ - if (header_size != read) { - php_stream_seek(fp, header_size - read, SEEK_CUR); + if (header_size != read && -1 == php_stream_seek(fp, header_size - read, SEEK_CUR)) { + return FAILURE; } + len -= header_size; continue; } /* Fallthrough to next if to skip header */ @@ -86,23 +93,36 @@ static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry if (h.header.tag[0] != 'n' || h.header.tag[1] != 'u') { /* skip to next header */ - php_stream_seek(fp, PHAR_GET_16(h.header.size), SEEK_CUR); - len -= PHAR_GET_16(h.header.size) + 4; + if (header_size && -1 == php_stream_seek(fp, header_size, SEEK_CUR)) { + return FAILURE; + } + len -= header_size; continue; } /* unix3 header found */ - read = php_stream_read(fp, (char *) &(h.unix3.crc32), sizeof(h.unix3) - sizeof(h.header)); - len -= read + 4; + size_t unix3_size = sizeof(h.unix3) - sizeof(h.header); + size_t field_size = header_size; + if (field_size == unix3_size - sizeof(h.unix3.crc32)) { + /* Some archives omit the CRC32 from the unix3 size field. */ + field_size = unix3_size; + } + if (field_size < unix3_size || field_size > len) { + return FAILURE; + } - if (sizeof(h.unix3) - sizeof(h.header) != read) { + read = php_stream_read(fp, (char *) &(h.unix3.crc32), unix3_size); + if (unix3_size != read) { return FAILURE; } - if (PHAR_GET_16(h.unix3.size) > sizeof(h.unix3) - 4) { + if (field_size > unix3_size) { /* skip symlink filename - we may add this support in later */ - php_stream_seek(fp, PHAR_GET_16(h.unix3.size) - sizeof(h.unix3.size), SEEK_CUR); + if (-1 == php_stream_seek(fp, field_size - unix3_size, SEEK_CUR)) { + return FAILURE; + } } + len -= field_size; /* set permissions */ entry->flags &= PHAR_ENT_COMPRESSION_MASK; @@ -113,7 +133,7 @@ static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry entry->flags |= PHAR_GET_16(h.unix3.perms) & PHAR_ENT_PERM_MASK; } - } while (len); + } return SUCCESS; } @@ -226,8 +246,14 @@ static char *phar_find_eocd(const char *s, size_t n) * This is used by phar_open_from_fp to process a zip-based phar, but can be called * directly. */ -zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error) /* {{{ */ -{ +zend_result phar_parse_zipfile( + php_stream *fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + phar_archive_data** pphar, + char **error +) { phar_zip_dir_end locator; char buf[sizeof(locator) + 65536]; zend_off_t size; @@ -310,21 +336,23 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch ZVAL_UNDEF(&mydata->metadata_tracker.val); } - mydata->fname = pestrndup(fname, fname_len, mydata->is_persistent); + mydata->fname = zend_string_init(fname, fname_len, mydata->is_persistent); + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(mydata->fname); + } #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); #endif mydata->is_zip = 1; - mydata->fname_len = fname_len; - ext = strrchr(mydata->fname, '/'); + ext = strrchr(ZSTR_VAL(mydata->fname), '/'); if (ext) { - mydata->ext = memchr(ext, '.', (mydata->fname + fname_len) - ext); + mydata->ext = memchr(ext, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - ext); if (mydata->ext == ext) { - mydata->ext = memchr(ext + 1, '.', (mydata->fname + fname_len) - ext - 1); + mydata->ext = memchr(ext + 1, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - ext - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + fname_len) - mydata->ext; + mydata->ext_len = (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - mydata->ext; } } @@ -356,9 +384,9 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch efree(mydata->signature); \ } \ if (error) { \ - spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \ + spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, ZSTR_VAL(mydata->fname)); \ } \ - pefree(mydata->fname, mydata->is_persistent); \ + zend_string_release_ex(mydata->fname, mydata->is_persistent); \ if (mydata->alias) { \ pefree(mydata->alias, mydata->is_persistent); \ } \ @@ -725,29 +753,29 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch mydata->fp = fp; - zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); if (actual_alias) { - phar_archive_data *fd_ptr; if (!phar_validate_alias(actual_alias, mydata->alias_len)) { if (error) { spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname); } efree(actual_alias); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } mydata->is_temporary_alias = 0; - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, mydata->alias_len)) { + phar_archive_data *fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname); } efree(actual_alias); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } } @@ -760,24 +788,23 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata); } else { - phar_archive_data *fd_ptr; - - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + if (alias) { + phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata); - mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent); - mydata->alias_len = alias_len; + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, mydata); + mydata->alias = pestrndup(ZSTR_VAL(alias), ZSTR_LEN(alias), mydata->is_persistent); + mydata->alias_len = ZSTR_LEN(alias); } else { - mydata->alias = pestrndup(mydata->fname, fname_len, mydata->is_persistent); + mydata->alias = pestrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), mydata->is_persistent); mydata->alias_len = fname_len; } @@ -795,10 +822,16 @@ zend_result phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, ch /** * Create or open a zip-based phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_zip( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { phar_archive_data *phar; - zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, alias, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -819,11 +852,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *f } /* we've reached here - the phar exists and is a regular phar */ - spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", fname); + spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", ZSTR_VAL(fname)); return FAILURE; } -/* }}} */ struct _phar_zip_pass { php_stream *filefp; @@ -903,7 +935,6 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ /* do extra field for perms later */ if (entry->is_modified) { - php_stream_filter *filter; php_stream *efp; if (entry->is_dir) { @@ -917,7 +948,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ } if (FAILURE == phar_open_entry_fp(entry, p->error, false)) { - spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -928,7 +959,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ } if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { - spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -949,13 +980,15 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ goto not_compressed; } - filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0); + const char *compression_filter_name = phar_get_compress_filter_name(entry); + ZEND_ASSERT(compression_filter_name && "Must have as this has a compression flag set"); + php_stream_filter *filter = php_stream_filter_create(compression_filter_name, NULL, false); if (!filter) { if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { - spprintf(p->error, 0, "unable to gzip compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to gzip compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); } else { - spprintf(p->error, 0, "unable to bzip2 compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to bzip2 compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); } return ZEND_HASH_APPLY_STOP; } @@ -967,7 +1000,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (!entry->cfp) { php_stream_filter_free(filter); - spprintf(p->error, 0, "unable to create temporary file for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to create temporary file for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -975,7 +1008,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { php_stream_filter_free(filter); - spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -983,7 +1016,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (SUCCESS != php_stream_copy_to_stream_ex(efp, entry->cfp, entry->uncompressed_filesize, NULL)) { php_stream_filter_remove(filter, 1); - spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -1006,7 +1039,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ PHAR_SET_32(local.compsize, entry->compressed_filesize); if (p->old) { if (-1 == php_stream_seek(p->old, entry->offset_abs, SEEK_SET)) { - spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1025,61 +1058,61 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ offset = entry->header_offset + sizeof(local) + ZSTR_LEN(entry->filename) + (entry->is_dir ? 1 : 0) + sizeof(perms); if (sizeof(local) != php_stream_write(p->filefp, (char *)&local, sizeof(local))) { - spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (sizeof(central) != php_stream_write(p->centralfp, (char *)¢ral, sizeof(central))) { - spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (entry->is_dir) { if (ZSTR_LEN(entry->filename) != php_stream_write(p->filefp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (1 != php_stream_write(p->filefp, "/", 1)) { - spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (ZSTR_LEN(entry->filename) != php_stream_write(p->centralfp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (1 != php_stream_write(p->centralfp, "/", 1)) { - spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } else { if (ZSTR_LEN(entry->filename) != php_stream_write(p->filefp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (ZSTR_LEN(entry->filename) != php_stream_write(p->centralfp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } if (sizeof(perms) != php_stream_write(p->filefp, (char *)&perms, sizeof(perms))) { - spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (sizeof(perms) != php_stream_write(p->centralfp, (char *)&perms, sizeof(perms))) { - spprintf(p->error, 0, "unable to write central extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write central extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (!not_really_modified && entry->is_modified) { if (entry->cfp) { if (SUCCESS != php_stream_copy_to_stream_ex(entry->cfp, p->filefp, entry->compressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -1093,7 +1126,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ phar_seek_efp(entry, 0, SEEK_SET, 0, false); if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), p->filefp, entry->uncompressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1119,7 +1152,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ } if (!entry->is_dir && entry->compressed_filesize && SUCCESS != php_stream_copy_to_stream_ex(p->old, p->filefp, entry->compressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1130,7 +1163,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (entry->metadata_tracker.str) { if (ZSTR_LEN(entry->metadata_tracker.str) != php_stream_write(p->centralfp, ZSTR_VAL(entry->metadata_tracker.str), ZSTR_LEN(entry->metadata_tracker.str))) { - spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1149,8 +1182,7 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar { /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { - size_t signature_length; - char *signature, sigbuf[8]; + char sigbuf[8]; phar_entry_info entry = {0}; php_stream *newfile; zend_off_t tell; @@ -1172,11 +1204,10 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar } char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, &signature_error)) { - if (signature_error) { - spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", signature_error); - efree(signature_error); - } + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", signature_error); + efree(signature_error); php_stream_close(newfile); return FAILURE; @@ -1186,19 +1217,19 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar entry.fp_type = PHAR_MOD; entry.is_modified = 1; if (entry.fp == NULL) { - efree(signature); + zend_string_release_ex(signature, false); spprintf(pass->error, 0, "phar error: unable to create temporary file for signature"); php_stream_close(newfile); return FAILURE; } PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); + if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); if (pass->error) { - spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", phar->fname); + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", ZSTR_VAL(phar->fname)); } php_stream_close(newfile); @@ -1207,13 +1238,13 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; entry.phar = phar; /* throw out return value and write the signature */ phar_zip_changed_apply_int(&entry, (void *)pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); php_stream_close(newfile); + zend_string_release_ex(signature, false); if (pass->error && *(pass->error)) { /* error is set by writeheaders */ @@ -1243,7 +1274,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze entry.fp_type = PHAR_MOD; if (phar->is_persistent) { - spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -1260,7 +1291,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze } if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { php_stream_close(entry.fp); - spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -1274,17 +1305,18 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze /* register alias */ if (phar->alias_len) { - if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, error)) { + phar = phar_get_archive(ZSTR_VAL(phar->fname), ZSTR_LEN(phar->fname), phar->alias, phar->alias_len, error); + if (!phar) { return EOF; } } /* set stub */ if (user_stub && !is_default_stub) { - char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub)); + const char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub)); if (pos == NULL) { - spprintf(error, 0, "illegal stub for zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "illegal stub for zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } @@ -1303,7 +1335,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len) || end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len) ) { - spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); return EOF; } @@ -1320,7 +1352,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze } if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) { php_stream_close(entry.fp); - spprintf(error, 0, "unable to %s stub in%szip-based phar \"%s\", failed", user_stub ? "overwrite" : "create", user_stub ? " " : " new ", phar->fname); + spprintf(error, 0, "unable to %s stub in%szip-based phar \"%s\", failed", user_stub ? "overwrite" : "create", user_stub ? " " : " new ", ZSTR_VAL(phar->fname)); return EOF; } @@ -1332,7 +1364,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { php_stream_close(entry.fp); zend_string_efree(entry.filename); - spprintf(error, 0, "unable to create stub in zip-based phar \"%s\"", phar->fname); + spprintf(error, 0, "unable to create stub in zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); return EOF; } } else { @@ -1349,7 +1381,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } @@ -1365,7 +1397,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze if (must_close_old_file) { php_stream_close(oldfile); } - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to open temporary file", phar->fname); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to open temporary file", ZSTR_VAL(phar->fname)); return EOF; } @@ -1395,7 +1427,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze phar_metadata_tracker_try_ensure_has_serialized_data(&phar->metadata_tracker, phar->is_persistent); if (pass_error || FAILURE == phar_zip_applysignature(phar, &pass)) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", phar->fname, pass_error); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", ZSTR_VAL(phar->fname), pass_error); efree(pass_error); nopasserror: php_stream_close(pass.centralfp); @@ -1418,7 +1450,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze size_t clen; zend_result ret = php_stream_copy_to_stream_ex(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL, &clen); if (SUCCESS != ret || clen != cdir_size) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", phar->fname); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", ZSTR_VAL(phar->fname)); goto nopasserror; } } @@ -1431,17 +1463,17 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze PHAR_SET_16(eocd.comment_len, ZSTR_LEN(phar->metadata_tracker.str)); if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", ZSTR_VAL(phar->fname)); goto nocentralerror; } if (ZSTR_LEN(phar->metadata_tracker.str) != php_stream_write(pass.filefp, ZSTR_VAL(phar->metadata_tracker.str), ZSTR_LEN(phar->metadata_tracker.str))) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", phar->fname); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", ZSTR_VAL(phar->fname)); goto nocentralerror; } } else { if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", ZSTR_VAL(phar->fname)); goto nocentralerror; } } @@ -1464,13 +1496,13 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze /* deferred flush */ phar->fp = pass.filefp; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { if (must_close_old_file) { php_stream_close(oldfile); } phar->fp = pass.filefp; - spprintf(error, 4096, "unable to open new phar \"%s\" for writing", phar->fname); + spprintf(error, 4096, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); return EOF; } php_stream_rewind(pass.filefp); diff --git a/ext/posix/php_posix.h b/ext/posix/php_posix.h index 79e6fe83ef9e..82208bb63088 100644 --- a/ext/posix/php_posix.h +++ b/ext/posix/php_posix.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kristian Koehntopp | +----------------------------------------------------------------------+ diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 76e14f6ecb0c..a9fe723f454b 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kristian Koehntopp | +----------------------------------------------------------------------+ @@ -690,7 +688,11 @@ static void php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ array_init(&array_members); zend_hash_real_init_packed(Z_ARRVAL(array_members)); - add_assoc_string(array_group, "name", g->gr_name); + if (g->gr_name) { + add_assoc_string(array_group, "name", g->gr_name); + } else { + add_assoc_null(array_group, "name"); + } if (g->gr_passwd) { add_assoc_string(array_group, "passwd", g->gr_passwd); } else { @@ -928,13 +930,33 @@ static void php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* { ZEND_ASSERT(Z_TYPE_P(return_value) == IS_ARRAY); - add_assoc_string(return_value, "name", pw->pw_name); - add_assoc_string(return_value, "passwd", pw->pw_passwd); - add_assoc_long (return_value, "uid", pw->pw_uid); - add_assoc_long (return_value, "gid", pw->pw_gid); - add_assoc_string(return_value, "gecos", pw->pw_gecos); - add_assoc_string(return_value, "dir", pw->pw_dir); - add_assoc_string(return_value, "shell", pw->pw_shell); + if (pw->pw_name) { + add_assoc_string(return_value, "name", pw->pw_name); + } else { + add_assoc_null(return_value, "name"); + } + if (pw->pw_passwd) { + add_assoc_string(return_value, "passwd", pw->pw_passwd); + } else { + add_assoc_null(return_value, "passwd"); + } + add_assoc_long(return_value, "uid", pw->pw_uid); + add_assoc_long(return_value, "gid", pw->pw_gid); + if (pw->pw_gecos) { + add_assoc_string(return_value, "gecos", pw->pw_gecos); + } else { + add_assoc_null(return_value, "gecos"); + } + if (pw->pw_dir) { + add_assoc_string(return_value, "dir", pw->pw_dir); + } else { + add_assoc_null(return_value, "dir"); + } + if (pw->pw_shell) { + add_assoc_string(return_value, "shell", pw->pw_shell); + } else { + add_assoc_null(return_value, "shell"); + } } /* }}} */ diff --git a/ext/random/config.m4 b/ext/random/config.m4 index 484f0549e019..3561d502e708 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -32,8 +32,7 @@ PHP_NEW_EXTENSION([random], m4_normalize([ randomizer.c zend_utils.c ]), - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) PHP_INSTALL_HEADERS([ext/random], m4_normalize([ php_random_csprng.h php_random_uint128.h diff --git a/ext/random/config.w32 b/ext/random/config.w32 index bb0badbd183d..fa6788803f0b 100644 --- a/ext/random/config.w32 +++ b/ext/random/config.w32 @@ -1,4 +1,4 @@ -EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("random", "random.c", false /* never shared */); PHP_RANDOM="yes"; ADD_SOURCES(configure_module_dirname, "csprng.c engine_mt19937.c engine_pcgoneseq128xslrr64.c engine_xoshiro256starstar.c engine_secure.c engine_user.c gammasection.c randomizer.c zend_utils.c", "random"); PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_csprng.h php_random_uint128.h random_decl.h"); diff --git a/ext/random/csprng.c b/ext/random/csprng.c index 73832d7d0685..4c474fb86796 100644 --- a/ext/random/csprng.c +++ b/ext/random/csprng.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | diff --git a/ext/random/engine_mt19937.c b/ext/random/engine_mt19937.c index f2cb2fd7e9bc..a84fb9585c80 100644 --- a/ext/random/engine_mt19937.c +++ b/ext/random/engine_mt19937.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -391,11 +389,11 @@ PHP_METHOD(Random_Engine_Mt19937, __debugInfo) if (engine->engine.algo->serialize) { array_init(&t); + zend_hash_str_add(Z_ARR_P(return_value), "__states", strlen("__states"), &t); if (!engine->engine.algo->serialize(engine->engine.state, Z_ARRVAL(t))) { zend_throw_exception(NULL, "Engine serialize failed", 0); RETURN_THROWS(); } - zend_hash_str_add(Z_ARR_P(return_value), "__states", strlen("__states"), &t); } } /* }}} */ diff --git a/ext/random/engine_pcgoneseq128xslrr64.c b/ext/random/engine_pcgoneseq128xslrr64.c index 9ff4f911920b..9472ce918fef 100644 --- a/ext/random/engine_pcgoneseq128xslrr64.c +++ b/ext/random/engine_pcgoneseq128xslrr64.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | | | diff --git a/ext/random/engine_secure.c b/ext/random/engine_secure.c index 0a03a03bdf13..1fd0748e2b81 100644 --- a/ext/random/engine_secure.c +++ b/ext/random/engine_secure.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sammy Kaye Powers | | Go Kudo | diff --git a/ext/random/engine_user.c b/ext/random/engine_user.c index 955ddebdb99a..f759613ea8cf 100644 --- a/ext/random/engine_user.c +++ b/ext/random/engine_user.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ diff --git a/ext/random/engine_xoshiro256starstar.c b/ext/random/engine_xoshiro256starstar.c index 1a054362f065..8dd0156dcb2d 100644 --- a/ext/random/engine_xoshiro256starstar.c +++ b/ext/random/engine_xoshiro256starstar.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | | | @@ -151,6 +149,10 @@ static bool unserialize(void *state, HashTable *data) } } + if (UNEXPECTED(s->state[0] == 0 && s->state[1] == 0 && s->state[2] == 0 && s->state[3] == 0)) { + return false; + } + return true; } diff --git a/ext/random/gammasection.c b/ext/random/gammasection.c index 732f8a2b0d9b..ef0352773a77 100644 --- a/ext/random/gammasection.c +++ b/ext/random/gammasection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | | diff --git a/ext/random/php_random.h b/ext/random/php_random.h index e4d6b4bdf3d9..f5db3403ec18 100644 --- a/ext/random/php_random.h +++ b/ext/random/php_random.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -38,16 +36,6 @@ PHPAPI double php_combined_lcg(void); -typedef struct _php_random_fallback_seed_state php_random_fallback_seed_state; - -PHPAPI uint64_t php_random_generate_fallback_seed(void); -PHPAPI uint64_t php_random_generate_fallback_seed_ex(php_random_fallback_seed_state *state); - -static inline zend_long GENERATE_SEED(void) -{ - return (zend_long)php_random_generate_fallback_seed(); -} - # define PHP_MT_RAND_MAX ((zend_long) (0x7FFFFFFF)) /* (1<<31) - 1 */ enum php_random_mt19937_mode { @@ -62,31 +50,31 @@ PHPAPI uint32_t php_mt_rand(void); PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max); PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max); -typedef struct _php_random_status_state_mt19937 { +typedef struct php_random_status_state_mt19937 { uint32_t count; enum php_random_mt19937_mode mode; uint32_t state[624]; } php_random_status_state_mt19937; -typedef struct _php_random_status_state_pcgoneseq128xslrr64 { +typedef struct php_random_status_state_pcgoneseq128xslrr64 { php_random_uint128_t state; } php_random_status_state_pcgoneseq128xslrr64; -typedef struct _php_random_status_state_xoshiro256starstar { +typedef struct php_random_status_state_xoshiro256starstar { uint64_t state[4]; } php_random_status_state_xoshiro256starstar; -typedef struct _php_random_status_state_user { +typedef struct php_random_status_state_user { zend_object *object; zend_function *generate_method; } php_random_status_state_user; -typedef struct _php_random_result { +typedef struct php_random_result { uint64_t result; size_t size; } php_random_result; -typedef struct _php_random_algo { +typedef struct php_random_algo { const size_t state_size; php_random_result (*generate)(void *state); zend_long (*range)(void *state, zend_long min, zend_long max); @@ -94,12 +82,12 @@ typedef struct _php_random_algo { bool (*unserialize)(void *state, HashTable *data); } php_random_algo; -typedef struct _php_random_algo_with_state { +typedef struct php_random_algo_with_state { const php_random_algo *algo; void *state; } php_random_algo_with_state; -typedef struct _php_random_fallback_seed_state { +typedef struct php_random_fallback_seed_state { bool initialized; unsigned char seed[20]; } php_random_fallback_seed_state; @@ -110,12 +98,12 @@ extern PHPAPI const php_random_algo php_random_algo_xoshiro256starstar; extern PHPAPI const php_random_algo php_random_algo_secure; extern PHPAPI const php_random_algo php_random_algo_user; -typedef struct _php_random_engine { +typedef struct php_random_engine { php_random_algo_with_state engine; zend_object std; } php_random_engine; -typedef struct _php_random_randomizer { +typedef struct php_random_randomizer { php_random_algo_with_state engine; bool is_userland_algo; zend_object std; @@ -137,18 +125,21 @@ extern PHPAPI zend_class_entry *random_ce_Random_Randomizer; extern PHPAPI zend_class_entry *random_ce_Random_IntervalBoundary; -static inline php_random_engine *php_random_engine_from_obj(zend_object *object) { - return (php_random_engine *)((char *)(object) - XtOffsetOf(php_random_engine, std)); -} - -static inline php_random_randomizer *php_random_randomizer_from_obj(zend_object *object) { - return (php_random_randomizer *)((char *)(object) - XtOffsetOf(php_random_randomizer, std)); -} +#define php_random_engine_from_obj(object) ZEND_CONTAINER_OF(object, php_random_engine, std) +#define php_random_randomizer_from_obj(object) ZEND_CONTAINER_OF(object, php_random_randomizer, std) # define Z_RANDOM_ENGINE_P(zval) php_random_engine_from_obj(Z_OBJ_P(zval)) # define Z_RANDOM_RANDOMIZER_P(zval) php_random_randomizer_from_obj(Z_OBJ_P(zval)); +PHPAPI uint64_t php_random_generate_fallback_seed(void); +PHPAPI uint64_t php_random_generate_fallback_seed_ex(php_random_fallback_seed_state *state); + +static inline zend_long GENERATE_SEED(void) +{ + return (zend_long)php_random_generate_fallback_seed(); +} + PHPAPI void *php_random_status_alloc(const php_random_algo *algo, const bool persistent); PHPAPI void *php_random_status_copy(const php_random_algo *algo, void *old_status, void *new_status); PHPAPI void php_random_status_free(void *status, const bool persistent); diff --git a/ext/random/php_random_csprng.h b/ext/random/php_random_csprng.h index 7fb0d7357f61..6028bbf62522 100644 --- a/ext/random/php_random_csprng.h +++ b/ext/random/php_random_csprng.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | diff --git a/ext/random/php_random_uint128.h b/ext/random/php_random_uint128.h index 8c484ce5ba9f..25d2677da436 100644 --- a/ext/random/php_random_uint128.h +++ b/ext/random/php_random_uint128.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | @@ -23,7 +21,7 @@ # include # if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128) -typedef struct _php_random_uint128_t { +typedef struct php_random_uint128_t { uint64_t hi; uint64_t lo; } php_random_uint128_t; diff --git a/ext/random/php_random_zend_utils.h b/ext/random/php_random_zend_utils.h index db37805904cb..56718e5c214b 100644 --- a/ext/random/php_random_zend_utils.h +++ b/ext/random/php_random_zend_utils.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | | Tim Düsterhus | @@ -22,7 +20,7 @@ # include "php_random.h" # include "zend.h" -typedef struct _php_random_bytes_insecure_state_for_zend { +typedef struct php_random_bytes_insecure_state_for_zend { bool initialized; php_random_status_state_xoshiro256starstar xoshiro256starstar_state; } php_random_bytes_insecure_state_for_zend; diff --git a/ext/random/random.c b/ext/random/random.c index f9feaadcbb15..e7fe2c21801e 100644 --- a/ext/random/random.c +++ b/ext/random/random.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sammy Kaye Powers | | Go Kudo | @@ -47,10 +45,6 @@ # include #endif -#ifdef HAVE_SYS_PARAM_H -# include -#endif - #include "random_arginfo.h" PHPAPI ZEND_DECLARE_MODULE_GLOBALS(random) @@ -275,7 +269,7 @@ PHPAPI void php_random_engine_common_free_object(zend_object *object) PHPAPI zend_object *php_random_engine_common_clone_object(zend_object *object) { - php_random_engine *old_engine = php_random_engine_from_obj(object); + const php_random_engine *old_engine = php_random_engine_from_obj(object); php_random_engine *new_engine = php_random_engine_from_obj(old_engine->std.ce->create_object(old_engine->std.ce)); new_engine->engine.algo = old_engine->engine.algo; @@ -747,7 +741,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Engine_Mt19937->create_object = php_random_engine_mt19937_new; random_ce_Random_Engine_Mt19937->default_object_handlers = &random_engine_mt19937_object_handlers; memcpy(&random_engine_mt19937_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_mt19937_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_mt19937_object_handlers.offset = offsetof(php_random_engine, std); random_engine_mt19937_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_mt19937_object_handlers.clone_obj = php_random_engine_common_clone_object; @@ -756,7 +750,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Engine_PcgOneseq128XslRr64->create_object = php_random_engine_pcgoneseq128xslrr64_new; random_ce_Random_Engine_PcgOneseq128XslRr64->default_object_handlers = &random_engine_pcgoneseq128xslrr64_object_handlers; memcpy(&random_engine_pcgoneseq128xslrr64_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_pcgoneseq128xslrr64_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_pcgoneseq128xslrr64_object_handlers.offset = offsetof(php_random_engine, std); random_engine_pcgoneseq128xslrr64_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_pcgoneseq128xslrr64_object_handlers.clone_obj = php_random_engine_common_clone_object; @@ -765,7 +759,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Engine_Xoshiro256StarStar->create_object = php_random_engine_xoshiro256starstar_new; random_ce_Random_Engine_Xoshiro256StarStar->default_object_handlers = &random_engine_xoshiro256starstar_object_handlers; memcpy(&random_engine_xoshiro256starstar_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_xoshiro256starstar_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_xoshiro256starstar_object_handlers.offset = offsetof(php_random_engine, std); random_engine_xoshiro256starstar_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_xoshiro256starstar_object_handlers.clone_obj = php_random_engine_common_clone_object; @@ -774,7 +768,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Engine_Secure->create_object = php_random_engine_secure_new; random_ce_Random_Engine_Secure->default_object_handlers = &random_engine_secure_object_handlers; memcpy(&random_engine_secure_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_secure_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_secure_object_handlers.offset = offsetof(php_random_engine, std); random_engine_secure_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_secure_object_handlers.clone_obj = NULL; @@ -783,7 +777,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Randomizer->create_object = php_random_randomizer_new; random_ce_Random_Randomizer->default_object_handlers = &random_randomizer_object_handlers; memcpy(&random_randomizer_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_randomizer_object_handlers.offset = XtOffsetOf(php_random_randomizer, std); + random_randomizer_object_handlers.offset = offsetof(php_random_randomizer, std); random_randomizer_object_handlers.free_obj = randomizer_free_obj; random_randomizer_object_handlers.clone_obj = NULL; diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index a576cd12955a..0738380ca253 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ diff --git a/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt new file mode 100644 index 000000000000..6ebcd03e8570 --- /dev/null +++ b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-21731: Xoshiro256StarStar::__unserialize() must reject the all-zero state +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Invalid serialization data for Random\Engine\Xoshiro256StarStar object diff --git a/ext/random/zend_utils.c b/ext/random/zend_utils.c index 64ba2c87ef70..19067f343afb 100644 --- a/ext/random/zend_utils.c +++ b/ext/random/zend_utils.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | | Tim Düsterhus | diff --git a/ext/readline/php_readline.h b/ext/readline/php_readline.h index f67238db663a..c1a337713069 100644 --- a/ext/readline/php_readline.h +++ b/ext/readline/php_readline.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/readline/readline.c b/ext/readline/readline.c index b9671ac1caa0..cbc0ebdd8713 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index 312129991c70..3b2a08a15843 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | | Johannes Schlueter | @@ -529,7 +527,8 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ } else if (text[0] == '#' && text[1] != '[') { retval = cli_completion_generator_ini(text, textlen, &cli_completion_state); } else { - char *lc_text, *class_name_end; + char *lc_text; + const char *class_name_end; zend_string *class_name = NULL; zend_class_entry *ce = NULL; @@ -661,6 +660,7 @@ static int readline_shell_run(void) /* {{{ */ zend_string_release_ex(prompt, 0); /* TODO: This might be wrong! */ prompt = cli_get_prompt("php", '>'); + free(line); continue; } } diff --git a/ext/readline/readline_cli.h b/ext/readline/readline_cli.h index 6db09ce991ce..31c21d8eedc1 100644 --- a/ext/readline/readline_cli.h +++ b/ext/readline/readline_cli.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | | Johannes Schlueter | diff --git a/ext/readline/tests/readline_cli_ini_directive.phpt b/ext/readline/tests/readline_cli_ini_directive.phpt new file mode 100644 index 000000000000..ebf4ac10a281 --- /dev/null +++ b/ext/readline/tests/readline_cli_ini_directive.phpt @@ -0,0 +1,21 @@ +--TEST-- +Interactive shell: setting an INI directive via #name=value +--EXTENSIONS-- +readline +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +%AINI[5]%A diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4 index 10ce256f01a8..cd287c140642 100644 --- a/ext/reflection/config.m4 +++ b/ext/reflection/config.m4 @@ -1,4 +1,3 @@ PHP_NEW_EXTENSION([reflection], [php_reflection.c], - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32 index 7f000b02ab63..f305095405d7 100644 --- a/ext/reflection/config.w32 +++ b/ext/reflection/config.w32 @@ -1,4 +1,4 @@ // vim:ft=javascript -EXTENSION("reflection", "php_reflection.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("reflection", "php_reflection.c", false /* never shared */); PHP_REFLECTION="yes"; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 40a759043f0a..a068f9f48ac6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Timm Friebe | | George Schlossnagle | @@ -135,7 +133,7 @@ typedef struct _property_reference { typedef struct _parameter_reference { uint32_t offset; bool required; - struct _zend_arg_info *arg_info; + const struct _zend_arg_info *arg_info; zend_function *fptr; } parameter_reference; @@ -176,11 +174,9 @@ typedef struct { zend_object zo; } reflection_object; -static inline reflection_object *reflection_object_from_obj(zend_object *obj) { - return (reflection_object*)((char*)(obj) - XtOffsetOf(reflection_object, zo)); -} +#define reflection_object_from_obj(obj) ZEND_CONTAINER_OF(obj, reflection_object, zo) -#define Z_REFLECTION_P(zv) reflection_object_from_obj(Z_OBJ_P((zv))) +#define Z_REFLECTION_P(zv) reflection_object_from_obj(Z_OBJ_P((zv))) /* }}} */ static zend_object_handlers reflection_object_handlers; @@ -197,26 +193,24 @@ static inline bool is_closure_invoke(const zend_class_entry *ce, const zend_stri static zend_function *_copy_function(zend_function *fptr) /* {{{ */ { if (fptr - && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) + && (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - zend_function *copy_fptr; - copy_fptr = emalloc(sizeof(zend_function)); + zend_function *copy_fptr = emalloc(sizeof(zend_function)); memcpy(copy_fptr, fptr, sizeof(zend_function)); - copy_fptr->internal_function.function_name = zend_string_copy(fptr->internal_function.function_name); + copy_fptr->common.function_name = zend_string_copy(fptr->common.function_name); return copy_fptr; - } else { - /* no copy needed */ - return fptr; } + /* no copy needed */ + return fptr; } /* }}} */ static void _free_function(zend_function *fptr) /* {{{ */ { if (fptr - && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) + && (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - zend_string_release_ex(fptr->internal_function.function_name, 0); + zend_string_release_ex(fptr->common.function_name, false); zend_free_trampoline(fptr); } } @@ -224,7 +218,7 @@ static void _free_function(zend_function *fptr) /* {{{ */ static void reflection_free_property_reference(property_reference *reference) { - zend_string_release_ex(reference->unmangled_name, 0); + zend_string_release_ex(reference->unmangled_name, false); efree(reference); } @@ -240,37 +234,36 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ if (intern->ptr) { switch (intern->ref_type) { - case REF_TYPE_PARAMETER: - reflection_free_parameter_reference(intern->ptr); - break; - case REF_TYPE_TYPE: - { - type_reference *type_ref = intern->ptr; - if (ZEND_TYPE_HAS_NAME(type_ref->type)) { - zend_string_release(ZEND_TYPE_NAME(type_ref->type)); + case REF_TYPE_PARAMETER: + reflection_free_parameter_reference(intern->ptr); + break; + case REF_TYPE_TYPE: { + type_reference *type_ref = intern->ptr; + if (ZEND_TYPE_HAS_NAME(type_ref->type)) { + zend_string_release(ZEND_TYPE_NAME(type_ref->type)); + } + efree(type_ref); + break; } - efree(type_ref); - break; - } - case REF_TYPE_FUNCTION: - _free_function(intern->ptr); - break; - case REF_TYPE_PROPERTY: - reflection_free_property_reference(intern->ptr); - break; - case REF_TYPE_ATTRIBUTE: { - attribute_reference *attr_ref = intern->ptr; - if (attr_ref->filename) { - zend_string_release(attr_ref->filename); + case REF_TYPE_FUNCTION: + _free_function(intern->ptr); + break; + case REF_TYPE_PROPERTY: + reflection_free_property_reference(intern->ptr); + break; + case REF_TYPE_ATTRIBUTE: { + attribute_reference *attr_ref = intern->ptr; + if (attr_ref->filename) { + zend_string_release(attr_ref->filename); + } + efree(intern->ptr); + break; } - efree(intern->ptr); - break; - } - case REF_TYPE_GENERATOR: - case REF_TYPE_FIBER: - case REF_TYPE_CLASS_CONSTANT: - case REF_TYPE_OTHER: - break; + case REF_TYPE_GENERATOR: + case REF_TYPE_FIBER: + case REF_TYPE_CLASS_CONSTANT: + case REF_TYPE_OTHER: + break; } } intern->ptr = NULL; @@ -298,31 +291,29 @@ static zend_object *reflection_objects_new(zend_class_entry *class_type) /* {{{ } /* }}} */ -static void _const_string(smart_str *str, const char *name, zval *value, const char *indent); -static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, const char* indent); -static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, const char* indent); -static void _class_const_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char* indent); -static void _enum_case_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char* indent); +static void _const_string(smart_str *str, const zend_string *name, const zval *value, const char *indent); +static void _function_string(smart_str *str, const zend_function *fptr, const zend_class_entry *scope, const char *indent); +static void _property_string(smart_str *str, const zend_property_info *prop, const zend_string *prop_name, const char *indent); +static void _class_const_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char *indent); +static void _enum_case_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char *indent); static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const char *indent); -static void _extension_string(smart_str *str, const zend_module_entry *module, const char *indent); -static void _zend_extension_string(smart_str *str, const zend_extension *extension, const char *indent); +static void _extension_string(smart_str *str, const zend_module_entry *module); +static void _zend_extension_string(smart_str *str, const zend_extension *extension); /* {{{ _class_string */ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const char *indent) { - int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0; - zend_string *sub_indent = strpprintf(0, "%s ", indent); - /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ if (ce->doc_comment) { - smart_str_append_printf(str, "%s%s", indent, ZSTR_VAL(ce->doc_comment)); + smart_str_appends(str, indent); + smart_str_append(str, ce->doc_comment); smart_str_appendc(str, '\n'); } if (obj && Z_TYPE_P(obj) == IS_OBJECT) { smart_str_append_printf(str, "%sObject of class [ ", indent); } else { - char *kind = "Class"; + const char *kind = "Class"; if (ce->ce_flags & ZEND_ACC_INTERFACE) { kind = "Interface"; } else if (ce->ce_flags & ZEND_ACC_TRAIT) { @@ -370,15 +361,13 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const ); } if (ce->num_interfaces) { - uint32_t i; - ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); if (ce->ce_flags & ZEND_ACC_INTERFACE) { smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name)); } else { smart_str_append_printf(str, " implements %s", ZSTR_VAL(ce->interfaces[0]->name)); } - for (i = 1; i < ce->num_interfaces; ++i) { + for (uint32_t i = 1; i < ce->num_interfaces; ++i) { smart_str_append_printf(str, ", %s", ZSTR_VAL(ce->interfaces[i]->name)); } } @@ -386,10 +375,12 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const /* The information where a class is declared is only available for user classes */ if (ce->type == ZEND_USER_CLASS) { - smart_str_append_printf(str, "%s @@ %s %d-%d\n", indent, ZSTR_VAL(ce->info.user.filename), + smart_str_append_printf(str, "%s @@ %s %" PRIu32 "-%" PRIu32 "\n", indent, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, ce->info.user.line_end); } + zend_string *sub_indent = strpprintf(0, "%s ", indent); + /* Constants */ uint32_t total_count = zend_hash_num_elements(&ce->constants_table); uint32_t constant_count = 0; @@ -400,10 +391,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const * times (count the constants vs. enum cases, print the constants, print * the enum cases) use some temporary helper smart strings. */ if (total_count > 0) { - zend_string *key; - zend_class_constant *c; - - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), key, c) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), zend_string *key, zend_class_constant *c) { if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_CLASS_CONST_IS_CASE) { _enum_case_string(&enum_case_str, key, c, ZSTR_VAL(sub_indent)); enum_case_count++; @@ -422,12 +410,12 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const // Enum cases go first, but the heading is only shown if there are any if (enum_case_count) { smart_str_appendc(str, '\n'); - smart_str_append_printf(str, "%s - Enum cases [%d] {\n", indent, enum_case_count); + smart_str_append_printf(str, "%s - Enum cases [%" PRIu32 "] {\n", indent, enum_case_count); smart_str_append_smart_str(str, &enum_case_str); smart_str_append_printf(str, "%s }\n", indent); } smart_str_appendc(str, '\n'); - smart_str_append_printf(str, "%s - Constants [%d] {\n", indent, constant_count); + smart_str_append_printf(str, "%s - Constants [%" PRIu32 "] {\n", indent, constant_count); smart_str_append_smart_str(str, &constant_str); smart_str_append_printf(str, "%s }\n", indent); @@ -436,11 +424,11 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const /* Static properties */ /* counting static properties */ - count = zend_hash_num_elements(&ce->properties_info); + uint32_t count = zend_hash_num_elements(&ce->properties_info); + uint32_t count_static_props = 0; + uint32_t count_shadow_props = 0; if (count > 0) { - zend_property_info *prop; - - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) { if ((prop->flags & ZEND_ACC_PRIVATE) && prop->ce != ce) { count_shadow_props++; } else if (prop->flags & ZEND_ACC_STATIC) { @@ -450,11 +438,9 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const } /* static properties */ - smart_str_append_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); + smart_str_append_printf(str, "\n%s - Static properties [%" PRIu32 "] {\n", indent, count_static_props); if (count_static_props > 0) { - zend_property_info *prop; - - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) { if ((prop->flags & ZEND_ACC_STATIC) && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) { _property_string(str, prop, NULL, ZSTR_VAL(sub_indent)); } @@ -465,10 +451,9 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const /* Static methods */ /* counting static methods */ count = zend_hash_num_elements(&ce->function_table); + uint32_t count_static_funcs = 0; if (count > 0) { - zend_function *mptr; - - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *mptr) { if ((mptr->common.fn_flags & ZEND_ACC_STATIC) && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) { @@ -478,11 +463,9 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const } /* static methods */ - smart_str_append_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); + smart_str_append_printf(str, "\n%s - Static methods [%" PRIu32 "] {", indent, count_static_funcs); if (count_static_funcs > 0) { - zend_function *mptr; - - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *mptr) { if ((mptr->common.fn_flags & ZEND_ACC_STATIC) && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) { @@ -497,13 +480,12 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const /* Default/Implicit properties */ count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; - smart_str_append_printf(str, "\n%s - Properties [%d] {\n", indent, count); + smart_str_append_printf(str, "\n%s - Properties [%" PRIu32 "] {\n", indent, count); if (count > 0) { - zend_property_info *prop; - - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) { if (!(prop->flags & ZEND_ACC_STATIC) - && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) { + && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce) + ) { _property_string(str, prop, NULL, ZSTR_VAL(sub_indent)); } } ZEND_HASH_FOREACH_END(); @@ -511,17 +493,16 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const smart_str_append_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - HashTable *properties = zend_get_properties_no_lazy_init(Z_OBJ_P(obj)); - zend_string *prop_name; + HashTable *properties = zend_get_properties_no_lazy_init(Z_OBJ_P(obj)); smart_str prop_str = {0}; count = 0; if (properties && zend_hash_num_elements(properties)) { - ZEND_HASH_FOREACH_STR_KEY(properties, prop_name) { + ZEND_HASH_FOREACH_STR_KEY(properties, zend_string *prop_name) { if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) { /* skip all private and protected properties */ if (!zend_hash_exists(&ce->properties_info, prop_name)) { count++; - _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent)); + _property_string(&prop_str, NULL, prop_name, ZSTR_VAL(sub_indent)); } } } ZEND_HASH_FOREACH_END(); @@ -536,11 +517,10 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const /* Non static methods */ count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; if (count > 0) { - zend_function *mptr; smart_str method_str = {0}; count = 0; - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *mptr) { if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) { @@ -559,7 +539,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const _free_function(closure); } } ZEND_HASH_FOREACH_END(); - smart_str_append_printf(str, "\n%s - Methods [%d] {", indent, count); + smart_str_append_printf(str, "\n%s - Methods [%" PRIu32 "] {", indent, count); smart_str_append_smart_str(str, &method_str); if (!count) { smart_str_appendc(str, '\n'); @@ -571,14 +551,13 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const smart_str_append_printf(str, "%s }\n", indent); smart_str_append_printf(str, "%s}\n", indent); - zend_string_release_ex(sub_indent, 0); + zend_string_release_ex(sub_indent, false); } /* }}} */ /* {{{ _const_string */ -static void _const_string(smart_str *str, const char *name, zval *value, const char *indent) +static void _const_string(smart_str *str, const zend_string *name, const zval *value, const char *indent) { - const char *type = zend_zval_type_name(value); uint32_t flags = Z_CONSTANT_FLAGS_P(value); smart_str_appends(str, indent); @@ -604,15 +583,18 @@ static void _const_string(smart_str *str, const char *name, zval *value, const c smart_str_appends(str, "> "); } + const char *type = zend_zval_type_name(value); smart_str_appends(str, type); smart_str_appendc(str, ' '); - smart_str_appends(str, name); + smart_str_append(str, name); smart_str_appends(str, " ] { "); if (Z_TYPE_P(value) == IS_ARRAY) { smart_str_append(str, ZSTR_KNOWN(ZEND_STR_ARRAY_CAPITALIZED)); } else if (Z_TYPE_P(value) == IS_STRING) { - smart_str_appends(str, Z_STRVAL_P(value)); + smart_str_append(str, Z_STR_P(value)); + } else if (Z_TYPE_P(value) == IS_DOUBLE) { + smart_str_append_double(str, Z_DVAL_P(value), (int) EG(precision), false); } else { zend_string *tmp_value_str; zend_string *value_str = zval_get_tmp_string(value, &tmp_value_str); @@ -631,20 +613,24 @@ static void _class_const_string(smart_str *str, const zend_string *name, zend_cl return; } + if (c->doc_comment) { + smart_str_appends(str, indent); + smart_str_append(str, c->doc_comment); + smart_str_appendc(str, '\n'); + } const char *visibility = zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)); const char *final = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_FINAL ? "final " : ""; zend_string *type_str = ZEND_TYPE_IS_SET(c->type) ? zend_type_to_string(c->type) : NULL; const char *type = type_str ? ZSTR_VAL(type_str) : zend_zval_type_name(&c->value); - if (c->doc_comment) { - smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(c->doc_comment)); - } smart_str_append_printf(str, "%sConstant [ %s%s %s %s ] { ", indent, final, visibility, type, ZSTR_VAL(name)); if (Z_TYPE(c->value) == IS_ARRAY) { smart_str_appends(str, "Array"); } else if (Z_TYPE(c->value) == IS_OBJECT) { smart_str_appends(str, "Object"); + } else if (Z_TYPE(c->value) == IS_DOUBLE) { + smart_str_append_double(str, Z_DVAL(c->value), (int) EG(precision), false); } else { zend_string *tmp_value_str; zend_string *value_str = zval_get_tmp_string(&c->value, &tmp_value_str); @@ -666,7 +652,9 @@ static void _enum_case_string(smart_str *str, const zend_string *name, zend_clas } if (c->doc_comment) { - smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(c->doc_comment)); + smart_str_appends(str, indent); + smart_str_append(str, c->doc_comment); + smart_str_appendc(str, '\n'); } smart_str_append_printf(str, "%sCase %s", indent, ZSTR_VAL(name)); if (c->ce->enum_backing_type == IS_UNDEF) { @@ -680,7 +668,9 @@ static void _enum_case_string(smart_str *str, const zend_string *name, zend_clas zval *enum_val = zend_enum_fetch_case_value(Z_OBJ(c->value)); zend_string *tmp_value_str; zend_string *value_str = zval_get_tmp_string(enum_val, &tmp_value_str); - smart_str_append_printf(str, " = %s\n", ZSTR_VAL(value_str)); + smart_str_appends(str, " = "); + smart_str_append(str, value_str); + smart_str_appendc(str, '\n'); zend_tmp_string_release(tmp_value_str); } } @@ -693,7 +683,7 @@ static zend_op *get_recv_op(const zend_op_array *op_array, uint32_t offset) ++offset; while (op < end) { if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT - || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == offset) + || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == offset) { return op; } @@ -703,7 +693,7 @@ static zend_op *get_recv_op(const zend_op_array *op_array, uint32_t offset) return NULL; } -static zval *get_default_from_recv(zend_op_array *op_array, uint32_t offset) { +static zval *get_default_from_recv(const zend_op_array *op_array, uint32_t offset) { zend_op *recv = get_recv_op(op_array, offset); if (!recv || recv->opcode != ZEND_RECV_INIT) { return NULL; @@ -712,17 +702,14 @@ static zval *get_default_from_recv(zend_op_array *op_array, uint32_t offset) { return RT_CONSTANT(recv, recv->op2); } -static void format_default_value(smart_str *str, zval *value) { +static void format_default_value(smart_str *str, const zval *value) { if (smart_str_append_zval(str, value, SIZE_MAX) == SUCCESS) { /* Nothing to do. */ } else if (Z_TYPE_P(value) == IS_ARRAY) { - zend_string *str_key; - zend_long num_key; - zval *zv; bool is_list = zend_array_is_list(Z_ARRVAL_P(value)); bool first = true; smart_str_appendc(str, '['); - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(value), num_key, str_key, zv) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(value), zend_long num_key, zend_string *str_key, zval *zv) { if (!first) { smart_str_appends(str, ", "); } @@ -745,8 +732,8 @@ static void format_default_value(smart_str *str, zval *value) { /* This branch is reached if the constant AST was already evaluated and * resulted in an object; enums are already handled in smart_str_append_zval() * (GH-15902) */ - zend_object *obj = Z_OBJ_P(value); - zend_class_entry *class = obj->ce; + const zend_object *obj = Z_OBJ_P(value); + const zend_class_entry *class = obj->ce; ZEND_ASSERT(!(class->ce_flags & ZEND_ACC_ENUM)); smart_str_appends(str, "object("); smart_str_append(str, class->name); @@ -760,9 +747,9 @@ static void format_default_value(smart_str *str, zval *value) { } /* {{{ _parameter_string */ -static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_arg_info *arg_info, uint32_t offset, bool required, char* indent) +static void _parameter_string(smart_str *str, const zend_function *fptr, const zend_arg_info *arg_info, uint32_t offset, bool required) { - smart_str_append_printf(str, "Parameter #%d [ ", offset); + smart_str_append_printf(str, "Parameter #%" PRIu32 " [ ", offset); if (!required) { smart_str_appends(str, " "); } else { @@ -793,7 +780,7 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_ smart_str_appends(str, ""); } } else { - zval *default_value = get_default_from_recv((zend_op_array*)fptr, offset); + const zval *default_value = get_default_from_recv((const zend_op_array*)fptr, offset); if (default_value) { smart_str_appends(str, " = "); format_default_value(str, default_value); @@ -805,24 +792,24 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_ /* }}} */ /* {{{ _function_parameter_string */ -static void _function_parameter_string(smart_str *str, zend_function *fptr, char* indent) +static void _function_parameter_string(smart_str *str, const zend_function *fptr, const char *indent) { - struct _zend_arg_info *arg_info = fptr->common.arg_info; - uint32_t i, num_args, num_required = fptr->common.required_num_args; - + const zend_arg_info *arg_info = fptr->common.arg_info; if (!arg_info) { return; } - num_args = fptr->common.num_args; + uint32_t num_args = fptr->common.num_args; if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } + uint32_t num_required = fptr->common.required_num_args; + smart_str_appendc(str, '\n'); - smart_str_append_printf(str, "%s- Parameters [%d] {\n", indent, num_args); - for (i = 0; i < num_args; i++) { + smart_str_append_printf(str, "%s- Parameters [%" PRIu32 "] {\n", indent, num_args); + for (uint32_t i = 0; i < num_args; i++) { smart_str_append_printf(str, "%s ", indent); - _parameter_string(str, fptr, arg_info, i, i < num_required, indent); + _parameter_string(str, fptr, arg_info, i, i < num_required); smart_str_appendc(str, '\n'); arg_info++; } @@ -831,48 +818,44 @@ static void _function_parameter_string(smart_str *str, zend_function *fptr, char /* }}} */ /* {{{ _function_closure_string */ -static void _function_closure_string(smart_str *str, const zend_function *fptr, const char* indent) +static void _function_closure_string(smart_str *str, const zend_function *fptr, const char *indent) { - uint32_t i, count; - const zend_string *key; - const HashTable *static_variables; - if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) { return; } - static_variables = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); - count = zend_hash_num_elements(static_variables); + const HashTable *static_variables = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); + uint32_t count = zend_hash_num_elements(static_variables); if (!count) { return; } smart_str_appendc(str, '\n'); - smart_str_append_printf(str, "%s- Bound Variables [%u] {\n", indent, count); - i = 0; - ZEND_HASH_MAP_FOREACH_STR_KEY(static_variables, key) { - smart_str_append_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, ZSTR_VAL(key)); + smart_str_append_printf(str, "%s- Bound Variables [%" PRIu32 "] {\n", indent, count); + uint32_t i = 0; + ZEND_HASH_MAP_FOREACH_STR_KEY(static_variables, const zend_string *key) { + smart_str_append_printf(str, "%s Variable #%" PRIu32 " [ $%s ]\n", indent, i++, ZSTR_VAL(key)); } ZEND_HASH_FOREACH_END(); smart_str_append_printf(str, "%s}\n", indent); } /* }}} */ /* {{{ _function_string */ -static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, const char* indent) +static void _function_string(smart_str *str, const zend_function *fptr, const zend_class_entry *scope, const char *indent) { - smart_str param_indent = {0}; - zend_function *overwrites; - zend_string *lc_name; - /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) * What's "wrong" is that any whitespace before the doc comment start is * swallowed, leading to an unaligned comment. */ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { - smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment)); + smart_str_appends(str, indent); + smart_str_append(str, fptr->op_array.doc_comment); + smart_str_appendc(str, '\n'); } else if (fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.doc_comment) { - smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->internal_function.doc_comment)); + smart_str_appends(str, indent); + smart_str_append(str, fptr->internal_function.doc_comment); + smart_str_appendc(str, '\n'); } smart_str_appends(str, indent); @@ -881,21 +864,24 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) { smart_str_appends(str, ", deprecated"); } - if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) { - smart_str_append_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name); + if (fptr->type == ZEND_INTERNAL_FUNCTION && ((const zend_internal_function*)fptr)->module) { + smart_str_append_printf(str, ":%s", ((const zend_internal_function*)fptr)->module->name); } if (scope && fptr->common.scope) { if (fptr->common.scope != scope) { smart_str_append_printf(str, ", inherits %s", ZSTR_VAL(fptr->common.scope->name)); } else if (fptr->common.scope->parent) { - lc_name = zend_string_tolower(fptr->common.function_name); - if ((overwrites = zend_hash_find_ptr(&fptr->common.scope->parent->function_table, lc_name)) != NULL) { - if (fptr->common.scope != overwrites->common.scope && !(overwrites->common.fn_flags & ZEND_ACC_PRIVATE)) { - smart_str_append_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name)); - } + zend_function *overwrites = zend_hash_find_ptr_lc( + &fptr->common.scope->parent->function_table, + fptr->common.function_name + ); + if (overwrites != NULL + && fptr->common.scope != overwrites->common.scope + && !(overwrites->common.fn_flags & ZEND_ACC_PRIVATE) + ) { + smart_str_append_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name)); } - zend_string_release_ex(lc_name, 0); } } if (fptr->common.prototype && fptr->common.prototype->common.scope) { @@ -937,17 +923,18 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent smart_str_appends(str, "function "); } - if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) { + if (fptr->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) { smart_str_appendc(str, '&'); } smart_str_append_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name)); /* The information where a function is declared is only available for user classes */ if (fptr->type == ZEND_USER_FUNCTION) { - smart_str_append_printf(str, "%s @@ %s %d - %d\n", indent, + smart_str_append_printf(str, "%s @@ %s %" PRIu32 " - %" PRIu32 "\n", indent, ZSTR_VAL(fptr->op_array.filename), fptr->op_array.line_start, fptr->op_array.line_end); } + smart_str param_indent = {0}; smart_str_append_printf(¶m_indent, "%s ", indent); smart_str_0(¶m_indent); if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) { @@ -955,7 +942,7 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent } _function_parameter_string(str, fptr, ZSTR_VAL(param_indent.s)); smart_str_free(¶m_indent); - if ((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { + if ((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { smart_str_append_printf(str, " %s- %s [ ", indent, ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]) ? "Tentative return" : "Return"); if (ZEND_TYPE_IS_SET(fptr->common.arg_info[-1].type)) { zend_string *type_str = zend_type_to_string(fptr->common.arg_info[-1].type); @@ -968,158 +955,182 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent } /* }}} */ -static zval *property_get_default(zend_property_info *prop_info) { - zend_class_entry *ce = prop_info->ce; +static zval *property_get_default(const zend_property_info *prop_info) { + const zend_class_entry *ce = prop_info->ce; if (prop_info->flags & ZEND_ACC_STATIC) { zval *prop = &ce->default_static_members_table[prop_info->offset]; ZVAL_DEINDIRECT(prop); return prop; - } else if (prop_info->flags & ZEND_ACC_VIRTUAL) { + } + if (prop_info->flags & ZEND_ACC_VIRTUAL) { return NULL; - } else { - return &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; } + return &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; } /* {{{ _property_string */ -static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, const char* indent) +static void _property_string(smart_str *str, const zend_property_info *prop, const zend_string *prop_name, const char *indent) { - if (prop && prop->doc_comment) { - smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(prop->doc_comment)); + if (!prop) { + // Dynamic property, known to have no doc comment, flags, etc. + ZEND_ASSERT(prop_name && "Properties without info must have a name provided"); + smart_str_append_printf(str, "%sProperty [ public $", indent); + smart_str_append(str, prop_name); + smart_str_appends(str, " ]\n"); + return; + } + if (prop->doc_comment) { + smart_str_appends(str, indent); + smart_str_append(str, prop->doc_comment); + smart_str_appendc(str, '\n'); } smart_str_append_printf(str, "%sProperty [ ", indent); - if (!prop) { - smart_str_append_printf(str, " public $%s", prop_name); + if (prop->flags & ZEND_ACC_ABSTRACT) { + smart_str_appends(str, "abstract "); + } + if (prop->flags & ZEND_ACC_FINAL) { + smart_str_appends(str, "final "); + } + /* These are mutually exclusive */ + switch (prop->flags & ZEND_ACC_PPP_MASK) { + case ZEND_ACC_PUBLIC: + smart_str_appends(str, "public "); + break; + case ZEND_ACC_PRIVATE: + smart_str_appends(str, "private "); + break; + case ZEND_ACC_PROTECTED: + smart_str_appends(str, "protected "); + break; + } + switch (prop->flags & ZEND_ACC_PPP_SET_MASK) { + case ZEND_ACC_PRIVATE_SET: + smart_str_appends(str, "private(set) "); + break; + case ZEND_ACC_PROTECTED_SET: + smart_str_appends(str, "protected(set) "); + break; + case ZEND_ACC_PUBLIC_SET: + ZEND_UNREACHABLE(); + break; + } + if (prop->flags & ZEND_ACC_STATIC) { + smart_str_appends(str, "static "); + } + if (prop->flags & ZEND_ACC_READONLY) { + smart_str_appends(str, "readonly "); + } + if (prop->flags & ZEND_ACC_VIRTUAL) { + smart_str_appends(str, "virtual "); + } + if (ZEND_TYPE_IS_SET(prop->type)) { + zend_string *type_str = zend_type_to_string(prop->type); + smart_str_append(str, type_str); + smart_str_appendc(str, ' '); + zend_string_release(type_str); + } + smart_str_appendc(str, '$'); + if (!prop_name) { + const char *class_name; + const char *prop_name_cstr; + zend_unmangle_property_name(prop->name, &class_name, &prop_name_cstr); + smart_str_appends(str, prop_name_cstr); } else { - if (prop->flags & ZEND_ACC_ABSTRACT) { - smart_str_appends(str, "abstract "); - } - if (prop->flags & ZEND_ACC_FINAL) { - smart_str_appends(str, "final "); - } - /* These are mutually exclusive */ - switch (prop->flags & ZEND_ACC_PPP_MASK) { - case ZEND_ACC_PUBLIC: - smart_str_appends(str, "public "); - break; - case ZEND_ACC_PRIVATE: - smart_str_appends(str, "private "); - break; - case ZEND_ACC_PROTECTED: - smart_str_appends(str, "protected "); - break; - } - switch (prop->flags & ZEND_ACC_PPP_SET_MASK) { - case ZEND_ACC_PRIVATE_SET: - smart_str_appends(str, "private(set) "); - break; - case ZEND_ACC_PROTECTED_SET: - smart_str_appends(str, "protected(set) "); - break; - case ZEND_ACC_PUBLIC_SET: - ZEND_UNREACHABLE(); - break; - } - if (prop->flags & ZEND_ACC_STATIC) { - smart_str_appends(str, "static "); - } - if (prop->flags & ZEND_ACC_READONLY) { - smart_str_appends(str, "readonly "); - } - if (prop->flags & ZEND_ACC_VIRTUAL) { - smart_str_appends(str, "virtual "); - } - if (ZEND_TYPE_IS_SET(prop->type)) { - zend_string *type_str = zend_type_to_string(prop->type); - smart_str_append(str, type_str); - smart_str_appendc(str, ' '); - zend_string_release(type_str); - } - if (!prop_name) { - const char *class_name; - zend_unmangle_property_name(prop->name, &class_name, &prop_name); - } - smart_str_append_printf(str, "$%s", prop_name); + smart_str_append(str, prop_name); + } - zval *default_value = property_get_default(prop); - if (default_value && !Z_ISUNDEF_P(default_value)) { - smart_str_appends(str, " = "); - format_default_value(str, default_value); - } - if (prop->hooks != NULL) { - smart_str_appends(str, " {"); - const zend_function *get_hooked = prop->hooks[ZEND_PROPERTY_HOOK_GET]; - if (get_hooked != NULL) { - if (get_hooked->common.fn_flags & ZEND_ACC_FINAL) { - smart_str_appends(str, " final get;"); - } else { - smart_str_appends(str, " get;"); - } + const zval *default_value = property_get_default(prop); + if (default_value && !Z_ISUNDEF_P(default_value)) { + smart_str_appends(str, " = "); + format_default_value(str, default_value); + } + if (prop->hooks != NULL) { + smart_str_appends(str, " {"); + const zend_function *get_hooked = prop->hooks[ZEND_PROPERTY_HOOK_GET]; + if (get_hooked != NULL) { + if (get_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final get;"); + } else { + smart_str_appends(str, " get;"); } - const zend_function *set_hooked = prop->hooks[ZEND_PROPERTY_HOOK_SET]; - if (set_hooked != NULL) { - if (set_hooked->common.fn_flags & ZEND_ACC_FINAL) { - smart_str_appends(str, " final set;"); - } else { - smart_str_appends(str, " set;"); - } + } + const zend_function *set_hooked = prop->hooks[ZEND_PROPERTY_HOOK_SET]; + if (set_hooked != NULL) { + if (set_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final set;"); + } else { + smart_str_appends(str, " set;"); } - smart_str_appends(str, " }"); } + smart_str_appends(str, " }"); } smart_str_appends(str, " ]\n"); } /* }}} */ -static void _extension_ini_string(const zend_ini_entry *ini_entry, smart_str *str, const char *indent, int number) /* {{{ */ +static void _extension_ini_string(const zend_ini_entry *ini_entry, smart_str *str, int number) /* {{{ */ { - char *comma = ""; - - if (number == ini_entry->module_number) { - smart_str_append_printf(str, " %sEntry [ %s <", indent, ZSTR_VAL(ini_entry->name)); - if (ini_entry->modifiable == ZEND_INI_ALL) { - smart_str_appends(str, "ALL"); - } else { - if (ini_entry->modifiable & ZEND_INI_USER) { - smart_str_appends(str, "USER"); - comma = ","; - } - if (ini_entry->modifiable & ZEND_INI_PERDIR) { - smart_str_append_printf(str, "%sPERDIR", comma); - comma = ","; - } - if (ini_entry->modifiable & ZEND_INI_SYSTEM) { - smart_str_append_printf(str, "%sSYSTEM", comma); - } + if (number != ini_entry->module_number) { + return; + } + smart_str_append_printf(str, " Entry [ %s <", ZSTR_VAL(ini_entry->name)); + if (ini_entry->modifiable == ZEND_INI_ALL) { + smart_str_appends(str, "ALL"); + } else { + const char *comma = ""; + if (ini_entry->modifiable & ZEND_INI_USER) { + smart_str_appends(str, "USER"); + comma = ","; } + if (ini_entry->modifiable & ZEND_INI_PERDIR) { + smart_str_append_printf(str, "%sPERDIR", comma); + comma = ","; + } + if (ini_entry->modifiable & ZEND_INI_SYSTEM) { + smart_str_append_printf(str, "%sSYSTEM", comma); + } + } - smart_str_appends(str, "> ]\n"); - smart_str_append_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ZSTR_VAL(ini_entry->value) : ""); - if (ini_entry->modified) { - smart_str_append_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : ""); + smart_str_appends(str, "> ]\n"); + if (ini_entry->value) { + smart_str_appends(str, " Current = '"); + smart_str_append(str, ini_entry->value); + smart_str_appends(str, "'\n"); + } else { + smart_str_appends(str, " Current = ''\n"); + } + if (ini_entry->modified) { + if (ini_entry->orig_value) { + smart_str_appends(str, " Default = '"); + smart_str_append(str, ini_entry->orig_value); + smart_str_appends(str, "'\n"); + } else { + smart_str_appends(str, " Default = ''\n"); } - smart_str_append_printf(str, " %s}\n", indent); } + smart_str_appends(str, " }\n"); } /* }}} */ -static void _extension_class_string(zend_class_entry *ce, zend_string *key, smart_str *str, const char *indent, const zend_module_entry *module, int *num_classes) /* {{{ */ +static void _extension_class_string(zend_class_entry *ce, zend_string *key, smart_str *str, const char *indent, const zend_module_entry *module, uint32_t *num_classes) /* {{{ */ { - if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { + if (ce->type == ZEND_INTERNAL_CLASS + && ce->info.internal.module + && !strcasecmp(ce->info.internal.module->name, module->name) /* dump class if it is not an alias */ - if (zend_string_equals_ci(ce->name, key)) { - smart_str_appendc(str, '\n'); - _class_string(str, ce, NULL, indent); - (*num_classes)++; - } + && zend_string_equals_ci(ce->name, key) + ) { + smart_str_appendc(str, '\n'); + _class_string(str, ce, NULL, indent); + (*num_classes)++; } } /* }}} */ -static void _extension_string(smart_str *str, const zend_module_entry *module, const char *indent) /* {{{ */ +static void _extension_string(smart_str *str, const zend_module_entry *module) /* {{{ */ { - smart_str_append_printf(str, "%sExtension [ ", indent); + smart_str_appends(str, "Extension [ "); if (module->type == MODULE_PERSISTENT) { smart_str_appends(str, ""); } @@ -1131,26 +1142,26 @@ static void _extension_string(smart_str *str, const zend_module_entry *module, c (module->version == NO_VERSION_YET) ? "" : module->version); if (module->deps) { - const zend_module_dep* dep = module->deps; + const zend_module_dep *dep = module->deps; smart_str_appends(str, "\n - Dependencies {\n"); - while(dep->name) { - smart_str_append_printf(str, "%s Dependency [ %s (", indent, dep->name); + while (dep->name) { + smart_str_append_printf(str, " Dependency [ %s (", dep->name); switch(dep->type) { - case MODULE_DEP_REQUIRED: - smart_str_appends(str, "Required"); - break; - case MODULE_DEP_CONFLICTS: - smart_str_appends(str, "Conflicts"); - break; - case MODULE_DEP_OPTIONAL: - smart_str_appends(str, "Optional"); - break; - default: - smart_str_appends(str, "Error"); /* shouldn't happen */ - break; + case MODULE_DEP_REQUIRED: + smart_str_appends(str, "Required"); + break; + case MODULE_DEP_CONFLICTS: + smart_str_appends(str, "Conflicts"); + break; + case MODULE_DEP_OPTIONAL: + smart_str_appends(str, "Optional"); + break; + default: + smart_str_appends(str, "Error"); /* shouldn't happen */ + break; } if (dep->rel) { @@ -1162,82 +1173,76 @@ static void _extension_string(smart_str *str, const zend_module_entry *module, c smart_str_appends(str, ") ]\n"); dep++; } - smart_str_append_printf(str, "%s }\n", indent); + smart_str_appends(str, " }\n"); } { smart_str str_ini = {0}; - zend_ini_entry *ini_entry; - ZEND_HASH_MAP_FOREACH_PTR(EG(ini_directives), ini_entry) { - _extension_ini_string(ini_entry, &str_ini, indent, module->module_number); + ZEND_HASH_MAP_FOREACH_PTR(EG(ini_directives), zend_ini_entry *ini_entry) { + _extension_ini_string(ini_entry, &str_ini, module->module_number); } ZEND_HASH_FOREACH_END(); if (smart_str_get_len(&str_ini) > 0) { smart_str_appends(str, "\n - INI {\n"); smart_str_append_smart_str(str, &str_ini); - smart_str_append_printf(str, "%s }\n", indent); + smart_str_appends(str, " }\n"); } smart_str_free(&str_ini); } { smart_str str_constants = {0}; - zend_constant *constant; - int num_constants = 0; + uint32_t num_constants = 0; - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), const zend_constant *constant) { if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) { - _const_string(&str_constants, ZSTR_VAL(constant->name), &constant->value, " "); + _const_string(&str_constants, constant->name, &constant->value, " "); num_constants++; } } ZEND_HASH_FOREACH_END(); if (num_constants) { - smart_str_append_printf(str, "\n - Constants [%d] {\n", num_constants); + smart_str_append_printf(str, "\n - Constants [%" PRIu32 "] {\n", num_constants); smart_str_append_smart_str(str, &str_constants); - smart_str_append_printf(str, "%s }\n", indent); + smart_str_appends(str, " }\n"); } smart_str_free(&str_constants); } { - zend_function *fptr; - int first = 1; + bool first = true; - ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), fptr) { + ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zend_function *fptr) { if (fptr->common.type==ZEND_INTERNAL_FUNCTION - && fptr->internal_function.module == module) { + && fptr->internal_function.module == module + ) { if (first) { smart_str_appends(str, "\n - Functions {\n"); - first = 0; + first = false; } _function_string(str, fptr, NULL, " "); } } ZEND_HASH_FOREACH_END(); if (!first) { - smart_str_append_printf(str, "%s }\n", indent); + smart_str_appends(str, " }\n"); } } { - zend_string *sub_indent = strpprintf(0, "%s ", indent); smart_str str_classes = {0}; - zend_string *key; - zend_class_entry *ce; - int num_classes = 0; + uint32_t num_classes = 0; - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { - _extension_class_string(ce, key, &str_classes, ZSTR_VAL(sub_indent), module, &num_classes); + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), zend_string *key, zend_class_entry *ce) { + _extension_class_string(ce, key, &str_classes, " ", module, &num_classes); } ZEND_HASH_FOREACH_END(); if (num_classes) { - smart_str_append_printf(str, "\n - Classes [%d] {", num_classes); + smart_str_append_printf(str, "\n - Classes [%" PRIu32 "] {", num_classes); smart_str_append_smart_str(str, &str_classes); - smart_str_append_printf(str, "%s }\n", indent); + smart_str_appends(str, " }\n"); } smart_str_free(&str_classes); - zend_string_release_ex(sub_indent, 0); } - smart_str_append_printf(str, "%s}\n", indent); + smart_str_appends(str, "}\n"); } /* }}} */ @@ -1245,12 +1250,9 @@ static void _extension_string(smart_str *str, const zend_module_entry *module, c static void reflection_attribute_factory(zval *object, HashTable *attributes, zend_attribute *data, zend_class_entry *scope, uint32_t target, zend_string *filename) { - reflection_object *intern; - attribute_reference *reference; - object_init_ex(object, reflection_attribute_ptr); - intern = Z_REFLECTION_P(object); - reference = (attribute_reference*) emalloc(sizeof(attribute_reference)); + reflection_object *intern = Z_REFLECTION_P(object); + attribute_reference *reference = (attribute_reference*) emalloc(sizeof(attribute_reference)); reference->attributes = attributes; reference->data = data; reference->scope = scope; @@ -1263,18 +1265,16 @@ static void reflection_attribute_factory(zval *object, HashTable *attributes, ze /* }}} */ static zend_result read_attributes(zval *ret, HashTable *attributes, zend_class_entry *scope, - uint32_t offset, uint32_t target, zend_string *name, zend_class_entry *base, zend_string *filename) /* {{{ */ + uint32_t offset, uint32_t target, zend_string *name, const zend_class_entry *base, zend_string *filename) /* {{{ */ { ZEND_ASSERT(attributes != NULL); - - zend_attribute *attr; zval tmp; if (name) { // Name based filtering using lowercased key. zend_string *filter = zend_string_tolower(name); - ZEND_HASH_PACKED_FOREACH_PTR(attributes, attr) { + ZEND_HASH_PACKED_FOREACH_PTR(attributes, zend_attribute *attr) { if (attr->offset == offset && zend_string_equals(attr->lcname, filter)) { reflection_attribute_factory(&tmp, attributes, attr, scope, target, filename); add_next_index_zval(ret, &tmp); @@ -1285,14 +1285,14 @@ static zend_result read_attributes(zval *ret, HashTable *attributes, zend_class_ return SUCCESS; } - ZEND_HASH_PACKED_FOREACH_PTR(attributes, attr) { + ZEND_HASH_PACKED_FOREACH_PTR(attributes, zend_attribute *attr) { if (attr->offset != offset) { continue; } if (base) { // Base type filtering. - zend_class_entry *ce = zend_lookup_class_ex(attr->name, attr->lcname, 0); + const zend_class_entry *ce = zend_lookup_class_ex(attr->name, attr->lcname, 0); if (ce == NULL) { // Bailout on error, otherwise ignore unavailable class. @@ -1321,7 +1321,7 @@ static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attribut { zend_string *name = NULL; zend_long flags = 0; - zend_class_entry *base = NULL; + const zend_class_entry *base = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!l", &name, &flags) == FAILURE) { RETURN_THROWS(); @@ -1356,9 +1356,9 @@ static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attribut } /* }}} */ -static void _zend_extension_string(smart_str *str, const zend_extension *extension, const char *indent) /* {{{ */ +static void _zend_extension_string(smart_str *str, const zend_extension *extension) /* {{{ */ { - smart_str_append_printf(str, "%sZend Extension [ %s ", indent, extension->name); + smart_str_append_printf(str, "Zend Extension [ %s ", extension->name); if (extension->version) { smart_str_append_printf(str, "%s ", extension->version); @@ -1380,8 +1380,8 @@ static void _zend_extension_string(smart_str *str, const zend_extension *extensi /* {{{ _function_check_flag */ static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(mptr); @@ -1392,12 +1392,10 @@ static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ zend_reflection_class_factory */ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object) { - reflection_object *intern; - zend_class_entry *reflection_ce = ce->ce_flags & ZEND_ACC_ENUM ? reflection_enum_ptr : reflection_class_ptr; object_init_ex(object, reflection_ce); - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); intern->ptr = ce; intern->ref_type = REF_TYPE_OTHER; intern->ce = ce; @@ -1405,8 +1403,8 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object) } /* }}} */ -/* {{{ reflection_extension_factory_ex */ -static void reflection_extension_factory_ex(zval *object, zend_module_entry *module) +/* {{{ reflection_extension_factory */ +static void reflection_extension_factory(zval *object, zend_module_entry *module) { object_init_ex(object, reflection_extension_ptr); reflection_object *intern = Z_REFLECTION_P(object); @@ -1417,29 +1415,12 @@ static void reflection_extension_factory_ex(zval *object, zend_module_entry *mod } /* }}} */ -/* {{{ reflection_extension_factory */ -static void reflection_extension_factory(zval *object, const char *name_str) -{ - size_t name_len = strlen(name_str); - struct _zend_module_entry *module = zend_hash_str_find_ptr_lc(&module_registry, name_str, name_len); - if (!module) { - return; - } - - reflection_extension_factory_ex(object, module); -} -/* }}} */ - /* {{{ reflection_parameter_factory */ -static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, uint32_t offset, bool required, zval *object) +static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, const zend_arg_info *arg_info, uint32_t offset, bool required, zval *object) { - reflection_object *intern; - parameter_reference *reference; - zval *prop_name; - object_init_ex(object, reflection_parameter_ptr); - intern = Z_REFLECTION_P(object); - reference = (parameter_reference*) emalloc(sizeof(parameter_reference)); + reflection_object *intern = Z_REFLECTION_P(object); + parameter_reference *reference = (parameter_reference*) emalloc(sizeof(parameter_reference)); reference->arg_info = arg_info; reference->offset = offset; reference->required = required; @@ -1451,7 +1432,7 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(closure_object)); } - prop_name = reflection_prop_name(object); + zval *prop_name = reflection_prop_name(object); ZVAL_STR_COPY(prop_name, arg_info->name); } /* }}} */ @@ -1500,8 +1481,6 @@ static reflection_type_kind get_type_kind(zend_type type) { /* {{{ reflection_type_factory */ static void reflection_type_factory(zend_type type, zval *object, bool legacy_behavior) { - reflection_object *intern; - type_reference *reference; reflection_type_kind type_kind = get_type_kind(type); bool is_mixed = ZEND_TYPE_PURE_MASK(type) == MAY_BE_ANY; bool is_only_null = (ZEND_TYPE_PURE_MASK(type) == MAY_BE_NULL && !ZEND_TYPE_IS_COMPLEX(type)); @@ -1516,11 +1495,11 @@ static void reflection_type_factory(zend_type type, zval *object, bool legacy_be case NAMED_TYPE: object_init_ex(object, reflection_named_type_ptr); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } - intern = Z_REFLECTION_P(object); - reference = (type_reference*) emalloc(sizeof(type_reference)); + reflection_object *intern = Z_REFLECTION_P(object); + type_reference *reference = (type_reference*) emalloc(sizeof(type_reference)); reference->type = type; reference->legacy_behavior = legacy_behavior && type_kind == NAMED_TYPE && !is_mixed && !is_only_null; intern->ptr = reference; @@ -1540,9 +1519,8 @@ static void reflection_type_factory(zend_type type, zval *object, bool legacy_be /* {{{ reflection_function_factory */ static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object) { - reflection_object *intern; object_init_ex(object, reflection_function_ptr); - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); intern->ptr = function; intern->ref_type = REF_TYPE_FUNCTION; intern->ce = NULL; @@ -1556,10 +1534,8 @@ static void reflection_function_factory(zend_function *function, zval *closure_o /* {{{ reflection_method_factory */ static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object) { - reflection_object *intern; - object_init_ex(object, reflection_method_ptr); - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); intern->ptr = method; intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; @@ -1575,12 +1551,9 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho /* {{{ reflection_property_factory */ static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object) { - reflection_object *intern; - property_reference *reference; - object_init_ex(object, reflection_property_ptr); - intern = Z_REFLECTION_P(object); - reference = (property_reference*) emalloc(sizeof(property_reference)); + reflection_object *intern = Z_REFLECTION_P(object); + property_reference *reference = (property_reference*) emalloc(sizeof(property_reference)); reference->prop = prop; reference->unmangled_name = zend_string_copy(name); memset(reference->cache_slot, 0, sizeof(reference->cache_slot)); @@ -1594,18 +1567,16 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name, static void reflection_property_factory_str(zend_class_entry *ce, const char *name_str, size_t name_len, zend_property_info *prop, zval *object) { - zend_string *name = zend_string_init(name_str, name_len, 0); + zend_string *name = zend_string_init(name_str, name_len, false); reflection_property_factory(ce, name, prop, object); - zend_string_release(name); + zend_string_release_ex(name, false); } /* {{{ reflection_class_constant_factory */ static void reflection_class_constant_factory(zend_string *name_str, zend_class_constant *constant, zval *object) { - reflection_object *intern; - object_init_ex(object, reflection_class_constant_ptr); - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; @@ -1615,15 +1586,13 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_ } /* }}} */ -static void reflection_enum_case_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object) +static void reflection_enum_case_factory(const zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object) { - reflection_object *intern; - zend_class_entry *case_reflection_class = ce->enum_backing_type == IS_UNDEF ? reflection_enum_unit_case_ptr : reflection_enum_backed_case_ptr; object_init_ex(object, case_reflection_class); - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; @@ -1632,22 +1601,21 @@ static void reflection_enum_case_factory(zend_class_entry *ce, zend_string *name ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name); } -static zend_result get_parameter_default(zval *result, parameter_reference *param) { +static zend_result get_parameter_default(zval *result, const parameter_reference *param) { if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { if (param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) { /* We don't have a way to determine the default value for this case right now. */ return FAILURE; } return zend_get_default_from_internal_arg_info(result, param->arg_info); - } else { - zval *default_value = get_default_from_recv((zend_op_array *) param->fptr, param->offset); - if (!default_value) { - return FAILURE; - } - - ZVAL_COPY(result, default_value); - return SUCCESS; } + zval *default_value = get_default_from_recv((const zend_op_array *) param->fptr, param->offset); + if (!default_value) { + return FAILURE; + } + + ZVAL_COPY(result, default_value); + return SUCCESS; } /* {{{ Preventing __clone from being called */ @@ -1714,14 +1682,12 @@ ZEND_METHOD(Reflection, getModifierNames) /* {{{ Constructor. Throws an Exception in case the given function does not exist */ ZEND_METHOD(ReflectionFunction, __construct) { - zval *object; zend_object *closure_obj = NULL; - reflection_object *intern; zend_function *fptr; zend_string *fname, *lcname; - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJ_OF_CLASS_OR_STR(closure_obj, zend_ce_closure, fname) @@ -1770,13 +1736,13 @@ ZEND_METHOD(ReflectionFunction, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionFunction, __toString) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - _function_string(&str, fptr, intern->ce, ""); + _function_string(&str, fptr, NULL, ""); RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -1784,8 +1750,8 @@ ZEND_METHOD(ReflectionFunction, __toString) /* {{{ Returns this function's name */ ZEND_METHOD(ReflectionFunctionAbstract, getName) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -1797,8 +1763,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getName) /* {{{ Returns whether this is a closure */ ZEND_METHOD(ReflectionFunctionAbstract, isClosure) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -1811,13 +1777,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, isClosure) ZEND_METHOD(ReflectionFunctionAbstract, getClosureThis) { reflection_object *intern; - zval* closure_this; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT(); if (!Z_ISUNDEF(intern->obj)) { - closure_this = zend_get_closure_this_ptr(&intern->obj); + zval *closure_this = zend_get_closure_this_ptr(&intern->obj); if (!Z_ISUNDEF_P(closure_this)) { RETURN_OBJ_COPY(Z_OBJ_P(closure_this)); } @@ -1828,13 +1793,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureThis) /* {{{ Returns the scope associated to the closure */ ZEND_METHOD(ReflectionFunctionAbstract, getClosureScopeClass) { - reflection_object *intern; - const zend_function *closure_func; + const reflection_object *intern; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT(); if (!Z_ISUNDEF(intern->obj)) { - closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); + const zend_function *closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); if (closure_func && closure_func->common.scope) { zend_reflection_class_factory(closure_func->common.scope, return_value); } @@ -1845,7 +1809,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureScopeClass) /* {{{ Returns the called scope associated to the closure */ ZEND_METHOD(ReflectionFunctionAbstract, getClosureCalledClass) { - reflection_object *intern; + const reflection_object *intern; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT(); @@ -1854,9 +1818,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureCalledClass) zend_function *closure_func; zend_object *object; if (Z_OBJ_HANDLER(intern->obj, get_closure) - && Z_OBJ_HANDLER(intern->obj, get_closure)(Z_OBJ(intern->obj), &called_scope, &closure_func, &object, 1) == SUCCESS - && closure_func && (called_scope || closure_func->common.scope)) { - zend_reflection_class_factory(called_scope ? (zend_class_entry *) called_scope : closure_func->common.scope, return_value); + && Z_OBJ_HANDLER(intern->obj, get_closure)(Z_OBJ(intern->obj), &called_scope, &closure_func, &object, true) == SUCCESS + && closure_func && (called_scope || closure_func->common.scope) + ) { + zend_reflection_class_factory(called_scope ? called_scope : closure_func->common.scope, return_value); } } } @@ -1865,57 +1830,59 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureCalledClass) /* {{{ Returns an associative array containing the closures lexical scope variables */ ZEND_METHOD(ReflectionFunctionAbstract, getClosureUsedVariables) { - reflection_object *intern; - const zend_function *closure_func; + const reflection_object *intern; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT(); - array_init(return_value); - if (!Z_ISUNDEF(intern->obj)) { - closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); - if (closure_func == NULL || - closure_func->type != ZEND_USER_FUNCTION || - closure_func->op_array.static_variables == NULL) { - return; - } + if (Z_ISUNDEF(intern->obj)) { + RETURN_EMPTY_ARRAY(); + } - const zend_op_array *ops = &closure_func->op_array; + const zend_function *closure_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); + if (closure_func == NULL || + closure_func->type != ZEND_USER_FUNCTION || + closure_func->op_array.static_variables == NULL + ) { + RETURN_EMPTY_ARRAY(); + } - HashTable *static_variables = ZEND_MAP_PTR_GET(ops->static_variables_ptr); + const zend_op_array *ops = &closure_func->op_array; - if (!static_variables) { - return; - } + const HashTable *static_variables = ZEND_MAP_PTR_GET(ops->static_variables_ptr); - zend_op *opline = ops->opcodes + ops->num_args; - if (ops->fn_flags & ZEND_ACC_VARIADIC) { - opline++; - } + if (!static_variables) { + RETURN_EMPTY_ARRAY(); + } - for (; opline->opcode == ZEND_BIND_STATIC; opline++) { - if (!(opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) { - continue; - } + array_init(return_value); + const zend_op *opline = ops->opcodes + ops->num_args; + if (ops->fn_flags & ZEND_ACC_VARIADIC) { + opline++; + } - Bucket *bucket = (Bucket*) - (((char*)static_variables->arData) + - (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); + for (; opline->opcode == ZEND_BIND_STATIC; opline++) { + if (!(opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) { + continue; + } - if (Z_ISUNDEF(bucket->val)) { - continue; - } + Bucket *bucket = (Bucket*) + (((char*)static_variables->arData) + + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); - zend_hash_add_new(Z_ARRVAL_P(return_value), bucket->key, &bucket->val); - Z_TRY_ADDREF(bucket->val); + if (Z_ISUNDEF(bucket->val)) { + continue; } + + zend_hash_add_new(Z_ARRVAL_P(return_value), bucket->key, &bucket->val); + Z_TRY_ADDREF(bucket->val); } } /* }}} */ /* {{{ Returns a dynamically created closure for the function */ ZEND_METHOD(ReflectionFunction, getClosure) { - reflection_object *intern; + const reflection_object *intern; zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -1933,8 +1900,8 @@ ZEND_METHOD(ReflectionFunction, getClosure) /* {{{ Returns whether this is an internal function */ ZEND_METHOD(ReflectionFunctionAbstract, isInternal) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); @@ -1945,8 +1912,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, isInternal) /* {{{ Returns whether this is a user-defined function */ ZEND_METHOD(ReflectionFunctionAbstract, isUserDefined) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); @@ -1957,8 +1924,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, isUserDefined) /* {{{ Returns whether this function is an anonymous closure or not */ ZEND_METHOD(ReflectionFunction, isAnonymous) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -1980,8 +1947,8 @@ ZEND_METHOD(ReflectionFunction, isDisabled) /* {{{ Returns the filename of the file this function was declared in */ ZEND_METHOD(ReflectionFunctionAbstract, getFileName) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); @@ -1995,8 +1962,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getFileName) /* {{{ Returns the line this function's declaration starts at */ ZEND_METHOD(ReflectionFunctionAbstract, getStartLine) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); @@ -2010,8 +1977,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getStartLine) /* {{{ Returns the line this function's declaration ends at */ ZEND_METHOD(ReflectionFunctionAbstract, getEndLine) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); @@ -2025,19 +1992,15 @@ ZEND_METHOD(ReflectionFunctionAbstract, getEndLine) /* {{{ Returns the doc comment for this function */ ZEND_METHOD(ReflectionFunctionAbstract, getDocComment) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { - RETURN_STR_COPY(fptr->op_array.doc_comment); - } - - if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function *) fptr)->doc_comment) { - RETURN_STR_COPY(((zend_internal_function *) fptr)->doc_comment); + if (fptr->common.doc_comment) { + RETURN_STR_COPY(fptr->common.doc_comment); } RETURN_FALSE; @@ -2047,12 +2010,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, getDocComment) /* {{{ Returns the attributes of this function */ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes) { - reflection_object *intern; - zend_function *fptr; - uint32_t target; + const reflection_object *intern; + const zend_function *fptr; GET_REFLECTION_OBJECT_PTR(fptr); - + + uint32_t target; if (fptr->common.scope && (fptr->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) { target = ZEND_ATTRIBUTE_TARGET_METHOD; } else { @@ -2068,7 +2031,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes) /* {{{ Returns an associative array containing this function's static variables and their values */ ZEND_METHOD(ReflectionFunctionAbstract, getStaticVariables) { - reflection_object *intern; + const reflection_object *intern; zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -2076,10 +2039,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getStaticVariables) /* Return an empty array in case no static variables exist */ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) { - HashTable *ht; - array_init(return_value); - ht = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); + HashTable *ht = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); if (!ht) { ht = zend_array_dup(fptr->op_array.static_variables); ZEND_MAP_PTR_SET(fptr->op_array.static_variables_ptr, ht); @@ -2094,12 +2055,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, getStaticVariables) /* {{{ Invokes the function */ ZEND_METHOD(ReflectionFunction, invoke) { - zval retval; zval *params; uint32_t num_args; HashTable *named_params; - zend_fcall_info_cache fcc; - reflection_object *intern; + const reflection_object *intern; zend_function *fptr; ZEND_PARSE_PARAMETERS_START(0, -1) @@ -2108,15 +2067,17 @@ ZEND_METHOD(ReflectionFunction, invoke) GET_REFLECTION_OBJECT_PTR(fptr); + zend_fcall_info_cache fcc; fcc.function_handler = fptr; fcc.called_scope = NULL; fcc.object = NULL; if (!Z_ISUNDEF(intern->obj)) { Z_OBJ_HT(intern->obj)->get_closure( - Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0); + Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, false); } + zval retval; zend_call_known_fcc(&fcc, &retval, num_args, params, named_params); if (Z_ISREF(retval)) { @@ -2129,9 +2090,7 @@ ZEND_METHOD(ReflectionFunction, invoke) /* {{{ Invokes the function and pass its arguments as array. */ ZEND_METHOD(ReflectionFunction, invokeArgs) { - zval retval; - zend_fcall_info_cache fcc; - reflection_object *intern; + const reflection_object *intern; zend_function *fptr; HashTable *params; @@ -2141,15 +2100,17 @@ ZEND_METHOD(ReflectionFunction, invokeArgs) GET_REFLECTION_OBJECT_PTR(fptr); + zend_fcall_info_cache fcc; fcc.function_handler = fptr; fcc.called_scope = NULL; fcc.object = NULL; if (!Z_ISUNDEF(intern->obj)) { Z_OBJ_HT(intern->obj)->get_closure( - Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, 0); + Z_OBJ(intern->obj), &fcc.called_scope, &fcc.function_handler, &fcc.object, false); } + zval retval; zend_call_known_fcc(&fcc, &retval, /* num_params */ 0, /* params */ NULL, params); if (Z_ISREF(retval)) { @@ -2162,29 +2123,28 @@ ZEND_METHOD(ReflectionFunction, invokeArgs) /* {{{ Gets whether this function returns a reference */ ZEND_METHOD(ReflectionFunctionAbstract, returnsReference) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0); + RETURN_BOOL((fptr->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0); } /* }}} */ /* {{{ Gets the number of parameters */ ZEND_METHOD(ReflectionFunctionAbstract, getNumberOfParameters) { - reflection_object *intern; - zend_function *fptr; - uint32_t num_args; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - num_args = fptr->common.num_args; + uint32_t num_args = fptr->common.num_args; if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } @@ -2196,8 +2156,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getNumberOfParameters) /* {{{ Gets the number of required parameters */ ZEND_METHOD(ReflectionFunctionAbstract, getNumberOfRequiredParameters) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -2212,15 +2172,13 @@ ZEND_METHOD(ReflectionFunctionAbstract, getParameters) { reflection_object *intern; zend_function *fptr; - uint32_t i, num_args; - struct _zend_arg_info *arg_info; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - arg_info= fptr->common.arg_info; - num_args = fptr->common.num_args; + const zend_arg_info *arg_info = fptr->common.arg_info; + uint32_t num_args = fptr->common.num_args; if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } @@ -2230,7 +2188,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getParameters) } array_init(return_value); - for (i = 0; i < num_args; i++) { + for (uint32_t i = 0; i < num_args; i++) { zval parameter; reflection_parameter_factory( @@ -2251,9 +2209,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getParameters) /* {{{ Returns NULL or the extension the function belongs to */ ZEND_METHOD(ReflectionFunctionAbstract, getExtension) { - reflection_object *intern; - zend_function *fptr; - zend_internal_function *internal; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -2263,9 +2220,9 @@ ZEND_METHOD(ReflectionFunctionAbstract, getExtension) RETURN_NULL(); } - internal = (zend_internal_function *)fptr; + const zend_internal_function *internal = (zend_internal_function *)fptr; if (internal->module) { - reflection_extension_factory(return_value, internal->module->name); + reflection_extension_factory(return_value, internal->module); } else { RETURN_NULL(); } @@ -2275,9 +2232,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getExtension) /* {{{ Returns false or the name of the extension the function belongs to */ ZEND_METHOD(ReflectionFunctionAbstract, getExtensionName) { - reflection_object *intern; - zend_function *fptr; - zend_internal_function *internal; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -2287,7 +2243,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getExtensionName) RETURN_FALSE; } - internal = (zend_internal_function *)fptr; + const zend_internal_function *internal = (zend_internal_function *)fptr; if (internal->module) { RETURN_STRING(internal->module->name); } else { @@ -2299,11 +2255,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, getExtensionName) /* {{{ */ ZEND_METHOD(ReflectionGenerator, __construct) { - zval *generator, *object; - reflection_object *intern; + zval *generator; - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) { RETURN_THROWS(); @@ -2330,10 +2285,9 @@ ZEND_METHOD(ReflectionGenerator, getTrace) { zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); - zend_generator *root_generator; zend_execute_data *ex_backup = EG(current_execute_data); zend_execute_data *ex = generator->execute_data; - zend_execute_data *root_prev = NULL, *cur_prev; + zend_execute_data *root_prev = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &options) == FAILURE) { RETURN_THROWS(); @@ -2341,9 +2295,9 @@ ZEND_METHOD(ReflectionGenerator, getTrace) REFLECTION_CHECK_VALID_GENERATOR(ex) - root_generator = zend_generator_get_current(generator); + zend_generator *root_generator = zend_generator_get_current(generator); - cur_prev = generator->execute_data->prev_execute_data; + zend_execute_data *cur_prev = generator->execute_data->prev_execute_data; if (generator == root_generator) { generator->execute_data->prev_execute_data = NULL; } else { @@ -2364,8 +2318,8 @@ ZEND_METHOD(ReflectionGenerator, getTrace) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getExecutingLine) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); - zend_execute_data *ex = generator->execute_data; + const zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2378,8 +2332,8 @@ ZEND_METHOD(ReflectionGenerator, getExecutingLine) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getExecutingFile) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); - zend_execute_data *ex = generator->execute_data; + const zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2392,7 +2346,7 @@ ZEND_METHOD(ReflectionGenerator, getExecutingFile) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getFunction) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_function *func = generator->func; ZEND_PARSE_PARAMETERS_NONE(); @@ -2401,8 +2355,8 @@ ZEND_METHOD(ReflectionGenerator, getFunction) zval closure; ZVAL_OBJ(&closure, ZEND_CLOSURE_OBJECT(func)); reflection_function_factory(func, &closure, return_value); - } else if (func->op_array.scope) { - reflection_method_factory(func->op_array.scope, func, NULL, return_value); + } else if (func->common.scope) { + reflection_method_factory(func->common.scope, func, NULL, return_value); } else { reflection_function_factory(func, NULL, return_value); } @@ -2412,7 +2366,7 @@ ZEND_METHOD(ReflectionGenerator, getFunction) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getThis) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2432,20 +2386,19 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator) { zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; - zend_generator *current; ZEND_PARSE_PARAMETERS_NONE(); REFLECTION_CHECK_VALID_GENERATOR(ex) - current = zend_generator_get_current(generator); + zend_generator *current = zend_generator_get_current(generator); RETURN_OBJ_COPY(¤t->std); } /* }}} */ ZEND_METHOD(ReflectionGenerator, isClosed) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2460,104 +2413,110 @@ ZEND_METHOD(ReflectionParameter, __construct) zval *reference; zend_string *arg_name = NULL; zend_long position; - zval *object; - zval *prop_name; - reflection_object *intern; zend_function *fptr; - struct _zend_arg_info *arg_info; - uint32_t num_args; zend_class_entry *ce = NULL; - bool is_closure = 0; + bool is_closure = false; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_ZVAL(reference) Z_PARAM_STR_OR_LONG(arg_name, position) ZEND_PARSE_PARAMETERS_END(); - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); /* First, find the function */ switch (Z_TYPE_P(reference)) { - case IS_STRING: - { - zend_string *lcname = zend_string_tolower(Z_STR_P(reference)); - fptr = zend_hash_find_ptr(EG(function_table), lcname); + case IS_STRING: { + zend_string *fname = Z_STR_P(reference); + zend_string *lcname; + if (UNEXPECTED(ZSTR_VAL(fname)[0] == '\\')) { + /* Ignore leading "\" */ + ALLOCA_FLAG(use_heap) + ZSTR_ALLOCA_ALLOC(lcname, ZSTR_LEN(fname) - 1, use_heap); + zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(fname) + 1, ZSTR_LEN(fname) - 1); + fptr = zend_fetch_function(lcname); + ZSTR_ALLOCA_FREE(lcname, use_heap); + } else { + lcname = zend_string_tolower(fname); + fptr = zend_fetch_function(lcname); zend_string_release(lcname); - if (!fptr) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Function %s() does not exist", Z_STRVAL_P(reference)); - RETURN_THROWS(); - } - ce = fptr->common.scope; } + if (!fptr) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Function %s() does not exist", Z_STRVAL_P(reference)); + RETURN_THROWS(); + } + ce = fptr->common.scope; break; + } case IS_ARRAY: { - zval *classref; - zval *method; - zend_string *name, *lcname; - - if (((classref = zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL) - || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL)) - { - zend_throw_exception(reflection_exception_ptr, "Expected array($object, $method) or array($classname, $method)", 0); - RETURN_THROWS(); - } - - if (Z_TYPE_P(classref) == IS_OBJECT) { - ce = Z_OBJCE_P(classref); - } else { - name = zval_try_get_string(classref); - if (UNEXPECTED(!name)) { - return; - } - if ((ce = zend_lookup_class(name)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Class \"%s\" does not exist", ZSTR_VAL(name)); - zend_string_release(name); - RETURN_THROWS(); - } - zend_string_release(name); - } + zval *classref; + zval *method; + zend_string *name; + + if (((classref = zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL) + || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL) + ) { + zend_throw_exception(reflection_exception_ptr, "Expected array($object, $method) or array($classname, $method)", 0); + RETURN_THROWS(); + } - name = zval_try_get_string(method); + if (Z_TYPE_P(classref) == IS_OBJECT) { + ce = Z_OBJCE_P(classref); + } else { + name = zval_try_get_string(classref); if (UNEXPECTED(!name)) { return; } - - lcname = zend_string_tolower(name); - if (Z_TYPE_P(classref) == IS_OBJECT && is_closure_invoke(ce, lcname) - && (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL) - { - /* nothing to do. don't set is_closure since is the invoke handler, - not the closure itself */ - } else if ((fptr = zend_hash_find_ptr(&ce->function_table, lcname)) == NULL) { + if ((ce = zend_lookup_class(name)) == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + "Class \"%s\" does not exist", ZSTR_VAL(name)); zend_string_release(name); - zend_string_release(lcname); RETURN_THROWS(); } zend_string_release(name); + } + + name = zval_try_get_string(method); + if (UNEXPECTED(!name)) { + return; + } + + zend_string *lcname = zend_string_tolower(name); + if (Z_TYPE_P(classref) == IS_OBJECT && is_closure_invoke(ce, lcname) + && (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL) + { + /* nothing to do. don't set is_closure since is the invoke handler, + not the closure itself */ + } else if ((fptr = zend_hash_find_ptr(&ce->function_table, lcname)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zend_string_release(name); zend_string_release(lcname); + RETURN_THROWS(); } + zend_string_release(name); + zend_string_release(lcname); break; + } case IS_OBJECT: { - ce = Z_OBJCE_P(reference); - - if (instanceof_function(ce, zend_ce_closure)) { - fptr = (zend_function *)zend_get_closure_method_def(Z_OBJ_P(reference)); - Z_ADDREF_P(reference); - is_closure = 1; - } else if ((fptr = zend_hash_find_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME); - RETURN_THROWS(); - } + ce = Z_OBJCE_P(reference); + + // No need for instanceof_function, the Closure class is final + if (ce == zend_ce_closure) { + fptr = (zend_function *)zend_get_closure_method_def(Z_OBJ_P(reference)); + Z_ADDREF_P(reference); + is_closure = true; + } else if ((fptr = zend_hash_find_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME); + RETURN_THROWS(); } break; + } default: zend_argument_error(reflection_exception_ptr, 1, "must be a string, an array(class, method), or a callable object, %s given", zend_zval_value_name(reference)); @@ -2565,21 +2524,20 @@ ZEND_METHOD(ReflectionParameter, __construct) } /* Now, search for the parameter */ - arg_info = fptr->common.arg_info; - num_args = fptr->common.num_args; + const zend_arg_info *arg_info = fptr->common.arg_info; + uint32_t num_args = fptr->common.num_args; if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } if (arg_name != NULL) { - uint32_t i; position = -1; - for (i = 0; i < num_args; i++) { - if (arg_info[i].name) { - if (zend_string_equals(arg_name, arg_info[i].name)) { - position = i; - break; - } + for (uint32_t i = 0; i < num_args; i++) { + if (arg_info[i].name + && zend_string_equals(arg_name, arg_info[i].name) + ) { + position = i; + break; } } if (position == -1) { @@ -2617,14 +2575,14 @@ ZEND_METHOD(ReflectionParameter, __construct) ZVAL_UNDEF(&intern->obj); } - prop_name = reflection_prop_name(object); + zval *prop_name = reflection_prop_name(object); zval_ptr_dtor(prop_name); ZVAL_STR_COPY(prop_name, arg_info[position].name); return; failure: if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - zend_string_release_ex(fptr->common.function_name, 0); + zend_string_release_ex(fptr->common.function_name, false); zend_free_trampoline(fptr); } if (is_closure) { @@ -2637,23 +2595,39 @@ ZEND_METHOD(ReflectionParameter, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionParameter, __toString) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); - _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, ""); + _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required); RETURN_STR(smart_str_extract(&str)); } /* }}} */ +/* {{{ Returns the doc comment for this parameter */ +ZEND_METHOD(ReflectionParameter, getDocComment) +{ + const reflection_object *intern; + const parameter_reference *param; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(param); + if (param->arg_info->doc_comment) { + RETURN_STR_COPY(param->arg_info->doc_comment); + } + RETURN_FALSE; +} +/* }}} */ + /* {{{ Returns this parameter's name */ ZEND_METHOD(ReflectionParameter, getName) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); @@ -2666,7 +2640,7 @@ ZEND_METHOD(ReflectionParameter, getName) ZEND_METHOD(ReflectionParameter, getDeclaringFunction) { reflection_object *intern; - parameter_reference *param; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2682,8 +2656,8 @@ ZEND_METHOD(ReflectionParameter, getDeclaringFunction) /* {{{ Returns in which class this parameter is defined (not the type of the parameter) */ ZEND_METHOD(ReflectionParameter, getDeclaringClass) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2697,9 +2671,8 @@ ZEND_METHOD(ReflectionParameter, getDeclaringClass) /* {{{ Returns this parameters's class hint or NULL if there is none */ ZEND_METHOD(ReflectionParameter, getClass) { - reflection_object *intern; - parameter_reference *param; - zend_class_entry *ce; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2718,9 +2691,8 @@ ZEND_METHOD(ReflectionParameter, getClass) * TODO: Think about moving these checks to the compiler or some sort of * lint-mode. */ - zend_string *class_name; - - class_name = ZEND_TYPE_NAME(param->arg_info->type); + zend_class_entry *ce; + zend_string *class_name = ZEND_TYPE_NAME(param->arg_info->type); if (zend_string_equals_ci(class_name, ZSTR_KNOWN(ZEND_STR_SELF))) { ce = param->fptr->common.scope; if (!ce) { @@ -2757,8 +2729,8 @@ ZEND_METHOD(ReflectionParameter, getClass) /* {{{ Returns whether parameter has a type */ ZEND_METHOD(ReflectionParameter, hasType) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2770,8 +2742,8 @@ ZEND_METHOD(ReflectionParameter, hasType) /* {{{ Returns the type associated with the parameter */ ZEND_METHOD(ReflectionParameter, getType) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2786,9 +2758,8 @@ ZEND_METHOD(ReflectionParameter, getType) /* {{{ Returns whether parameter MUST be an array */ ZEND_METHOD(ReflectionParameter, isArray) { - reflection_object *intern; - parameter_reference *param; - uint32_t type_mask; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2798,7 +2769,7 @@ ZEND_METHOD(ReflectionParameter, isArray) RETURN_FALSE; } - type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type); + uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type); RETVAL_BOOL(type_mask == MAY_BE_ARRAY); } /* }}} */ @@ -2806,14 +2777,13 @@ ZEND_METHOD(ReflectionParameter, isArray) /* {{{ Returns whether parameter MUST be callable */ ZEND_METHOD(ReflectionParameter, isCallable) { - reflection_object *intern; - parameter_reference *param; - uint32_t type_mask; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); - type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type); + uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type); RETVAL_BOOL(type_mask == MAY_BE_CALLABLE); } /* }}} */ @@ -2821,8 +2791,8 @@ ZEND_METHOD(ReflectionParameter, isCallable) /* {{{ Returns whether NULL is allowed as this parameter's value */ ZEND_METHOD(ReflectionParameter, allowsNull) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2832,11 +2802,11 @@ ZEND_METHOD(ReflectionParameter, allowsNull) } /* }}} */ -/* {{{ Returns whether this parameters is passed to by reference */ +/* {{{ Returns whether this parameter is passed to by reference */ ZEND_METHOD(ReflectionParameter, isPassedByReference) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2848,8 +2818,8 @@ ZEND_METHOD(ReflectionParameter, isPassedByReference) /* {{{ Returns whether this parameter can be passed by value */ ZEND_METHOD(ReflectionParameter, canBePassedByValue) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2862,8 +2832,8 @@ ZEND_METHOD(ReflectionParameter, canBePassedByValue) /* {{{ Get parameter attributes. */ ZEND_METHOD(ReflectionParameter, getAttributes) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; GET_REFLECTION_OBJECT_PTR(param); @@ -2878,8 +2848,8 @@ ZEND_METHOD(ReflectionParameter, getAttributes) /* {{{ Returns the index of the parameter, starting from 0 */ ZEND_METHOD(ReflectionParameter, getPosition) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2891,8 +2861,8 @@ ZEND_METHOD(ReflectionParameter, getPosition) /* {{{ Returns whether this parameter is an optional parameter */ ZEND_METHOD(ReflectionParameter, isOptional) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -2904,8 +2874,8 @@ ZEND_METHOD(ReflectionParameter, isOptional) /* {{{ Returns whether the default value of this parameter is available */ ZEND_METHOD(ReflectionParameter, isDefaultValueAvailable) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); @@ -2914,7 +2884,7 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueAvailable) if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { RETURN_BOOL(param->arg_info->default_value); } else { - zval *default_value = get_default_from_recv((zend_op_array *)param->fptr, param->offset); + const zval *default_value = get_default_from_recv((const zend_op_array *)param->fptr, param->offset); RETURN_BOOL(default_value != NULL); } } @@ -2923,8 +2893,8 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueAvailable) /* {{{ Returns the default value of this parameter or throws an exception */ ZEND_METHOD(ReflectionParameter, getDefaultValue) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); @@ -2945,8 +2915,8 @@ ZEND_METHOD(ReflectionParameter, getDefaultValue) /* {{{ Returns whether the default value of this parameter is constant */ ZEND_METHOD(ReflectionParameter, isDefaultValueConstant) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); @@ -2960,7 +2930,7 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueConstant) } if (Z_TYPE(default_value) == IS_CONSTANT_AST) { - zend_ast *ast = Z_ASTVAL(default_value); + const zend_ast *ast = Z_ASTVAL(default_value); RETVAL_BOOL(ast->kind == ZEND_AST_CONSTANT || ast->kind == ZEND_AST_CONSTANT_CLASS || ast->kind == ZEND_AST_CLASS_CONST); @@ -2975,8 +2945,8 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueConstant) /* {{{ Returns the default value's constant name if default value is constant or null */ ZEND_METHOD(ReflectionParameter, getDefaultValueConstantName) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); @@ -3000,8 +2970,8 @@ ZEND_METHOD(ReflectionParameter, getDefaultValueConstantName) } else if (ast->kind == ZEND_AST_CONSTANT_CLASS) { RETVAL_STRINGL("__CLASS__", sizeof("__CLASS__")-1); } else if (ast->kind == ZEND_AST_CLASS_CONST) { - zend_string *class_name = zend_ast_get_str(ast->child[0]); - zend_string *const_name = zend_ast_get_str(ast->child[1]); + const zend_string *class_name = zend_ast_get_str(ast->child[0]); + const zend_string *const_name = zend_ast_get_str(ast->child[1]); RETVAL_NEW_STR(zend_string_concat3( ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", sizeof("::")-1, @@ -3015,8 +2985,8 @@ ZEND_METHOD(ReflectionParameter, getDefaultValueConstantName) /* {{{ Returns whether this parameter is a variadic parameter */ ZEND_METHOD(ReflectionParameter, isVariadic) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3028,8 +2998,8 @@ ZEND_METHOD(ReflectionParameter, isVariadic) /* {{{ Returns this constructor parameter has been promoted to a property */ ZEND_METHOD(ReflectionParameter, isPromoted) { - reflection_object *intern; - parameter_reference *param; + const reflection_object *intern; + const parameter_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3038,11 +3008,11 @@ ZEND_METHOD(ReflectionParameter, isPromoted) } /* }}} */ -/* {{{ Returns whether parameter MAY be null */ +/* {{{ Returns whether the type MAY be null */ ZEND_METHOD(ReflectionType, allowsNull) { - reflection_object *intern; - type_reference *param; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3054,25 +3024,19 @@ ZEND_METHOD(ReflectionType, allowsNull) /* For BC with iterable for named types */ static zend_string *zend_named_reflection_type_to_string(zend_type type) { if (ZEND_TYPE_IS_ITERABLE_FALLBACK(type)) { - zend_string *iterable = ZSTR_KNOWN(ZEND_STR_ITERABLE); if (ZEND_TYPE_FULL_MASK(type) & MAY_BE_NULL) { - return zend_string_concat2("?", strlen("?"), ZSTR_VAL(iterable), ZSTR_LEN(iterable)); + return ZSTR_INIT_LITERAL("?iterable", false); } - return iterable; + return ZSTR_KNOWN(ZEND_STR_ITERABLE); } return zend_type_to_string(type); } -static zend_string *zend_type_to_string_without_null(zend_type type) { - ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL; - return zend_named_reflection_type_to_string(type); -} - /* {{{ Return the text of the type hint */ ZEND_METHOD(ReflectionType, __toString) { - reflection_object *intern; - type_reference *param; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3084,24 +3048,26 @@ ZEND_METHOD(ReflectionType, __toString) /* {{{ Return the name of the type */ ZEND_METHOD(ReflectionNamedType, getName) { - reflection_object *intern; - type_reference *param; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); + // Make a copy so that we don't modify the stored type information + zend_type type = param->type; if (param->legacy_behavior) { - RETURN_STR(zend_type_to_string_without_null(param->type)); + ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL; } - RETURN_STR(zend_named_reflection_type_to_string(param->type)); + RETURN_STR(zend_named_reflection_type_to_string(type)); } /* }}} */ /* {{{ Returns whether type is a builtin type */ ZEND_METHOD(ReflectionNamedType, isBuiltin) { - reflection_object *intern; - type_reference *param; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3117,12 +3083,12 @@ ZEND_METHOD(ReflectionNamedType, isBuiltin) /* }}} */ static void append_type(zval *return_value, zend_type type) { - zval reflection_type; /* Drop iterable BC bit for type list */ if (ZEND_TYPE_IS_ITERABLE_FALLBACK(type)) { ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_ITERABLE_BIT; } + zval reflection_type; reflection_type_factory(type, &reflection_type, false); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &reflection_type); } @@ -3134,9 +3100,8 @@ static void append_type_mask(zval *return_value, uint32_t type_mask) { /* {{{ Returns the types that are part of this union type */ ZEND_METHOD(ReflectionUnionType, getTypes) { - reflection_object *intern; - type_reference *param; - uint32_t type_mask; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3149,10 +3114,10 @@ ZEND_METHOD(ReflectionUnionType, getTypes) } ZEND_TYPE_LIST_FOREACH_END(); } else if (ZEND_TYPE_HAS_NAME(param->type)) { zend_string *name = ZEND_TYPE_NAME(param->type); - append_type(return_value, (zend_type) ZEND_TYPE_INIT_CLASS(name, 0, 0)); + append_type(return_value, (zend_type) ZEND_TYPE_INIT_CLASS(name, false, 0)); } - type_mask = ZEND_TYPE_PURE_MASK(param->type); + uint32_t type_mask = ZEND_TYPE_PURE_MASK(param->type); ZEND_ASSERT(!(type_mask & MAY_BE_VOID)); ZEND_ASSERT(!(type_mask & MAY_BE_NEVER)); if (type_mask & MAY_BE_STATIC) { @@ -3192,9 +3157,8 @@ ZEND_METHOD(ReflectionUnionType, getTypes) /* {{{ Returns the types that are part of this intersection type */ ZEND_METHOD(ReflectionIntersectionType, getTypes) { - reflection_object *intern; - type_reference *param; - const zend_type *list_type; + const reflection_object *intern; + const type_reference *param; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); @@ -3202,7 +3166,7 @@ ZEND_METHOD(ReflectionIntersectionType, getTypes) ZEND_ASSERT(ZEND_TYPE_HAS_LIST(param->type)); array_init(return_value); - ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(param->type), list_type) { + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(param->type), const zend_type *list_type) { append_type(return_value, *list_type); } ZEND_TYPE_LIST_FOREACH_END(); } @@ -3218,13 +3182,8 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ zend_object *orig_obj = NULL; zend_class_entry *ce = NULL; zend_string *class_name = NULL; - char *method_name; + const char *method_name; size_t method_name_len; - char *lcname; - - zval *object; - reflection_object *intern; - zend_function *mptr; if (is_constructor) { if (ZEND_NUM_ARGS() == 1) { @@ -3261,17 +3220,16 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ method_name = ZSTR_VAL(arg2_str); method_name_len = ZSTR_LEN(arg2_str); } else { - char *tmp; - size_t tmp_len; - char *name = ZSTR_VAL(arg1_str); + const char *tmp; + const char *name = ZSTR_VAL(arg1_str); if ((tmp = strstr(name, "::")) == NULL) { zend_argument_error(reflection_exception_ptr, 1, "must be a valid method name"); RETURN_THROWS(); } - tmp_len = tmp - name; + size_t tmp_len = tmp - name; - class_name = zend_string_init(name, tmp_len, 0); + class_name = zend_string_init(name, tmp_len, false); method_name = tmp + 2; method_name_len = ZSTR_LEN(arg1_str) - tmp_len - 2; } @@ -3288,16 +3246,18 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ zend_string_release(class_name); } + zval *object; if (is_constructor) { object = ZEND_THIS; } else { object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : reflection_method_ptr); object = return_value; } - intern = Z_REFLECTION_P(object); + reflection_object *intern = Z_REFLECTION_P(object); - lcname = zend_str_tolower_dup(method_name, method_name_len); + char *lcname = zend_str_tolower_dup(method_name, method_name_len); + zend_function *mptr; if (ce == zend_ce_closure && orig_obj && (method_name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 && (mptr = zend_get_closure_invoke_method(orig_obj)) != NULL) @@ -3333,8 +3293,8 @@ ZEND_METHOD(ReflectionMethod, createFromMethodName) { /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionMethod, __toString) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); @@ -3344,7 +3304,7 @@ ZEND_METHOD(ReflectionMethod, __toString) } /* }}} */ -/* {{{ Invokes the function */ +/* {{{ Returns a dynamically created closure for the function */ ZEND_METHOD(ReflectionMethod, getClosure) { reflection_object *intern; @@ -3357,41 +3317,39 @@ ZEND_METHOD(ReflectionMethod, getClosure) GET_REFLECTION_OBJECT_PTR(mptr); - if (mptr->common.fn_flags & ZEND_ACC_STATIC) { + if (mptr->common.fn_flags & ZEND_ACC_STATIC) { zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL); - } else { - if (!obj) { - zend_argument_value_error(1, "cannot be null for non-static methods"); - RETURN_THROWS(); - } + return; + } + if (!obj) { + zend_argument_value_error(1, "cannot be null for non-static methods"); + RETURN_THROWS(); + } - if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) { - zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this method was declared in", 0); - RETURN_THROWS(); - } + if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) { + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this method was declared in", 0); + RETURN_THROWS(); + } - /* This is an original closure object and __invoke is to be called. */ - if (Z_OBJCE_P(obj) == zend_ce_closure && - (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) - { - RETURN_OBJ_COPY(Z_OBJ_P(obj)); - } else { - zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); - } + /* This is an original closure object and __invoke is to be called. */ + if (Z_OBJCE_P(obj) == zend_ce_closure && + (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) + { + RETURN_OBJ_COPY(Z_OBJ_P(obj)); } + zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); } /* }}} */ /* {{{ reflection_method_invoke */ -static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) +static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, bool variadic) { - zval retval; zval *params = NULL, *object; HashTable *named_params = NULL; reflection_object *intern; - zend_function *mptr, *callback; + zend_function *mptr; uint32_t argc = 0; - zend_class_entry *obj_ce; + const zend_class_entry *obj_ce; GET_REFLECTION_OBJECT_PTR(mptr); @@ -3441,14 +3399,27 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) } /* For Closure::__invoke(), closures from different source locations have - * different signatures, so we must reject those. However, closures created - * from the same source (e.g. in a loop) share the same op_array and should - * be allowed. Compare the underlying function pointer via op_array. */ + * different signatures, so we must reject those. */ if (obj_ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) && Z_OBJ_P(object) != Z_OBJ(intern->obj)) { const zend_function *orig_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); const zend_function *given_func = zend_get_closure_method_def(Z_OBJ_P(object)); - if (orig_func->op_array.opcodes != given_func->op_array.opcodes) { + + bool same_closure = false; + /* Check if they are either both fake closures or they both are not. */ + if ((orig_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) == (given_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { + if (orig_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + /* For fake closures, scope and name must match. */ + same_closure = orig_func->common.scope == given_func->common.scope + && orig_func->common.function_name == given_func->common.function_name; + } else { + /* Otherwise the opcode structure must be identical. */ + ZEND_ASSERT(orig_func->type == ZEND_USER_FUNCTION); + same_closure = orig_func->op_array.opcodes == given_func->op_array.opcodes; + } + } + + if (!same_closure) { if (!variadic) { efree(params); } @@ -3458,7 +3429,8 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) } } /* Copy the zend_function when calling via handler (e.g. Closure::__invoke()) */ - callback = _copy_function(mptr); + zend_function *callback = _copy_function(mptr); + zval retval; zend_call_known_function(callback, (object ? Z_OBJ_P(object) : NULL), intern->ce, &retval, argc, params, named_params); if (Z_ISREF(retval)) { @@ -3471,14 +3443,14 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) /* {{{ Invokes the method. */ ZEND_METHOD(ReflectionMethod, invoke) { - reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ /* {{{ Invokes the function and pass its arguments as array. */ ZEND_METHOD(ReflectionMethod, invokeArgs) { - reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ @@ -3548,8 +3520,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, isStatic) /* {{{ Returns whether this function is defined in namespace */ ZEND_METHOD(ReflectionFunctionAbstract, inNamespace) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -3559,7 +3531,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, inNamespace) RETURN_FALSE; } - zend_string *name = fptr->common.function_name; + const zend_string *name = fptr->common.function_name; const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); RETURN_BOOL(backslash); } @@ -3568,8 +3540,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, inNamespace) /* {{{ Returns the name of namespace where this function is defined */ ZEND_METHOD(ReflectionFunctionAbstract, getNamespaceName) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -3579,7 +3551,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getNamespaceName) RETURN_EMPTY_STRING(); } - zend_string *name = fptr->common.function_name; + const zend_string *name = fptr->common.function_name; const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); if (backslash) { RETURN_STRINGL(ZSTR_VAL(name), backslash - ZSTR_VAL(name)); @@ -3591,8 +3563,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getNamespaceName) /* {{{ Returns the short name of the function (without namespace part) */ ZEND_METHOD(ReflectionFunctionAbstract, getShortName) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -3613,28 +3585,28 @@ ZEND_METHOD(ReflectionFunctionAbstract, getShortName) /* {{{ Return whether the function has a return type */ ZEND_METHOD(ReflectionFunctionAbstract, hasReturnType) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - RETVAL_BOOL((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])); + RETVAL_BOOL((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])); } /* }}} */ /* {{{ Returns the return type associated with the function */ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) { + if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) { RETURN_NULL(); } @@ -3642,31 +3614,31 @@ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType) } /* }}} */ -/* {{{ Return whether the function has a return type */ +/* {{{ Return whether the function has a tentative return type */ ZEND_METHOD(ReflectionFunctionAbstract, hasTentativeReturnType) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])); + RETVAL_BOOL(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])); } /* }}} */ -/* {{{ Returns the return type associated with the function */ +/* {{{ Returns the tentative return type associated with the function */ ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType) { - reflection_object *intern; - zend_function *fptr; + const reflection_object *intern; + const zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(fptr); - if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) { + if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) { RETURN_NULL(); } @@ -3677,12 +3649,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType) /* {{{ Returns whether this method is the constructor */ ZEND_METHOD(ReflectionMethod, isConstructor) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(mptr); - /* we need to check if the ctor is the ctor of the class level we we + /* we need to check if the ctor is the ctor of the class level we are * looking at since we might be looking at an inherited old style ctor * defined in base class. */ RETURN_BOOL((mptr->common.fn_flags & ZEND_ACC_CTOR) && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope); @@ -3692,8 +3664,8 @@ ZEND_METHOD(ReflectionMethod, isConstructor) /* {{{ Returns whether this method is a destructor */ ZEND_METHOD(ReflectionMethod, isDestructor) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(mptr); @@ -3702,11 +3674,11 @@ ZEND_METHOD(ReflectionMethod, isDestructor) } /* }}} */ -/* {{{ Returns a bitfield of the access modifiers for this method */ +/* {{{ Returns a bitfield of the modifiers for this method */ ZEND_METHOD(ReflectionMethod, getModifiers) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL; @@ -3720,8 +3692,8 @@ ZEND_METHOD(ReflectionMethod, getModifiers) /* {{{ Get the declaring class */ ZEND_METHOD(ReflectionMethod, getDeclaringClass) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -3734,21 +3706,21 @@ ZEND_METHOD(ReflectionMethod, getDeclaringClass) /* {{{ Returns whether a method has a prototype or not */ ZEND_METHOD(ReflectionMethod, hasPrototype) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; - ZEND_PARSE_PARAMETERS_NONE(); + ZEND_PARSE_PARAMETERS_NONE(); - GET_REFLECTION_OBJECT_PTR(mptr); - RETURN_BOOL(mptr->common.prototype != NULL); + GET_REFLECTION_OBJECT_PTR(mptr); + RETURN_BOOL(mptr->common.prototype != NULL); } /* }}} */ /* {{{ Get the prototype */ ZEND_METHOD(ReflectionMethod, getPrototype) { - reflection_object *intern; - zend_function *mptr; + const reflection_object *intern; + const zend_function *mptr; ZEND_PARSE_PARAMETERS_NONE(); @@ -3778,12 +3750,9 @@ ZEND_METHOD(ReflectionMethod, setAccessible) /* {{{ Constructor. Throws an Exception in case the given class constant does not exist */ ZEND_METHOD(ReflectionClassConstant, __construct) { - zval *object; zend_string *classname_str; zend_object *classname_obj; zend_string *constname; - reflection_object *intern; - zend_class_entry *ce; zend_class_constant *constant = NULL; ZEND_PARSE_PARAMETERS_START(2, 2) @@ -3791,17 +3760,16 @@ ZEND_METHOD(ReflectionClassConstant, __construct) Z_PARAM_STR(constname) ZEND_PARSE_PARAMETERS_END(); + zend_class_entry *ce; if (classname_obj) { ce = classname_obj->ce; - } else { - if ((ce = zend_lookup_class(classname_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); - RETURN_THROWS(); - } + } else if ((ce = zend_lookup_class(classname_str)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); + RETURN_THROWS(); } - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); if ((constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), constname)) == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(constname)); @@ -3819,7 +3787,7 @@ ZEND_METHOD(ReflectionClassConstant, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionClassConstant, __toString) { - reflection_object *intern; + const reflection_object *intern; zend_class_constant *ref; smart_str str = {0}; @@ -3862,8 +3830,8 @@ ZEND_METHOD(ReflectionClassConstant, getName) /* Returns the type associated with the class constant */ ZEND_METHOD(ReflectionClassConstant, getType) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -3879,8 +3847,8 @@ ZEND_METHOD(ReflectionClassConstant, getType) /* Returns whether class constant has a type */ ZEND_METHOD(ReflectionClassConstant, hasType) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -3890,8 +3858,8 @@ ZEND_METHOD(ReflectionClassConstant, hasType) static void _class_constant_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -3926,11 +3894,11 @@ ZEND_METHOD(ReflectionClassConstant, isFinal) _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL); } -/* {{{ Returns a bitfield of the access modifiers for this constant */ +/* {{{ Returns a bitfield of the modifiers for this constant */ ZEND_METHOD(ReflectionClassConstant, getModifiers) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; uint32_t keep_flags = ZEND_ACC_FINAL | ZEND_ACC_PPP_MASK; ZEND_PARSE_PARAMETERS_NONE(); @@ -3943,14 +3911,14 @@ ZEND_METHOD(ReflectionClassConstant, getModifiers) /* {{{ Returns this constant's value */ ZEND_METHOD(ReflectionClassConstant, getValue) { - reflection_object *intern; + const reflection_object *intern; zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - zval *name = reflection_prop_name(ZEND_THIS); + const zval *name = reflection_prop_name(ZEND_THIS); if (Z_ISUNDEF_P(name)) { zend_throw_error(NULL, "Typed property ReflectionClassConstant::$name " @@ -3971,8 +3939,8 @@ ZEND_METHOD(ReflectionClassConstant, getValue) /* {{{ Get the declaring class */ ZEND_METHOD(ReflectionClassConstant, getDeclaringClass) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -3984,8 +3952,8 @@ ZEND_METHOD(ReflectionClassConstant, getDeclaringClass) /* {{{ Returns the doc comment for this constant */ ZEND_METHOD(ReflectionClassConstant, getDocComment) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -3999,7 +3967,7 @@ ZEND_METHOD(ReflectionClassConstant, getDocComment) /* {{{ Returns the attributes of this constant */ ZEND_METHOD(ReflectionClassConstant, getAttributes) { - reflection_object *intern; + const reflection_object *intern; zend_class_constant *ref; GET_REFLECTION_OBJECT_PTR(ref); @@ -4012,34 +3980,19 @@ ZEND_METHOD(ReflectionClassConstant, getAttributes) ZEND_METHOD(ReflectionClassConstant, isEnumCase) { - reflection_object *intern; - zend_class_constant *ref; - - GET_REFLECTION_OBJECT_PTR(ref); - - RETURN_BOOL(ZEND_CLASS_CONST_FLAGS(ref) & ZEND_CLASS_CONST_IS_CASE); + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_CLASS_CONST_IS_CASE); } ZEND_METHOD(ReflectionClassConstant, isDeprecated) { - reflection_object *intern; - zend_constant *ref; - - ZEND_PARSE_PARAMETERS_NONE(); - - GET_REFLECTION_OBJECT_PTR(ref); - - RETURN_BOOL(ZEND_CLASS_CONST_FLAGS(ref) & ZEND_ACC_DEPRECATED); + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED); } /* {{{ reflection_class_object_ctor */ -static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object) +static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, bool is_object) { - zval *object; zend_string *arg_class = NULL; zend_object *arg_obj; - reflection_object *intern; - zend_class_entry *ce; if (is_object) { ZEND_PARSE_PARAMETERS_START(1, 1) @@ -4051,8 +4004,8 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob ZEND_PARSE_PARAMETERS_END(); } - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); /* Note: class entry name is interned, no need to destroy them */ if (arg_obj) { @@ -4063,6 +4016,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob ZVAL_OBJ_COPY(&intern->obj, arg_obj); } } else { + zend_class_entry *ce; if ((ce = zend_lookup_class(arg_class)) == NULL) { if (!EG(exception)) { zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" does not exist", ZSTR_VAL(arg_class)); @@ -4080,20 +4034,17 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob /* {{{ Constructor. Takes a string or an instance as an argument */ ZEND_METHOD(ReflectionClass, __construct) { - reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ /* {{{ add_class_vars */ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_value) { - zend_property_info *prop_info; - zval *prop, prop_copy; - zend_string *key; + zval prop_copy; - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { - if (((prop_info->flags & ZEND_ACC_PRIVATE) && - prop_info->ce != ce)) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, zend_property_info *prop_info) { + if ((prop_info->flags & ZEND_ACC_PRIVATE) && prop_info->ce != ce) { continue; } @@ -4102,7 +4053,7 @@ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_valu continue; } - prop = property_get_default(prop_info); + zval *prop = property_get_default(prop_info); if (!prop || Z_ISUNDEF_P(prop)) { continue; } @@ -4113,10 +4064,10 @@ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_valu /* this is necessary to make it able to work with default array * properties, returned to user */ - if (Z_TYPE(prop_copy) == IS_CONSTANT_AST) { - if (UNEXPECTED(zval_update_constant_ex(&prop_copy, ce) != SUCCESS)) { - return; - } + if (Z_TYPE(prop_copy) == IS_CONSTANT_AST + && UNEXPECTED(zval_update_constant_ex(&prop_copy, ce) != SUCCESS) + ) { + return; } zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy); @@ -4127,11 +4078,8 @@ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_valu /* {{{ Returns an associative array containing all static property values of the class */ ZEND_METHOD(ReflectionClass, getStaticProperties) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_property_info *prop_info; - zval *prop; - zend_string *key; ZEND_PARSE_PARAMETERS_NONE(); @@ -4141,22 +4089,31 @@ ZEND_METHOD(ReflectionClass, getStaticProperties) RETURN_THROWS(); } - if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) { + // default_static_members_count includes inherited static members, see + // zend_do_inheritance_ex(). + // PHP does not support *dynamic* static properties the same way non-static + // properties can be dynamic (i.e. present on an object without having been + // declared on the class). Thus, default_static_members_count will always + // reflect the count of all static members that a class might have. + if (ce->default_static_members_count == 0) { + RETURN_EMPTY_ARRAY(); + } + + if (!CE_STATIC_MEMBERS(ce)) { zend_class_init_statics(ce); } array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { - if (((prop_info->flags & ZEND_ACC_PRIVATE) && - prop_info->ce != ce)) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, zend_property_info *prop_info) { + if ((prop_info->flags & ZEND_ACC_PRIVATE) && prop_info->ce != ce) { continue; } if ((prop_info->flags & ZEND_ACC_STATIC) == 0) { continue; } - prop = &CE_STATIC_MEMBERS(ce)[prop_info->offset]; + zval *prop = &CE_STATIC_MEMBERS(ce)[prop_info->offset]; ZVAL_DEINDIRECT(prop); if (ZEND_TYPE_IS_SET(prop_info->type) && Z_ISUNDEF_P(prop)) { @@ -4175,10 +4132,10 @@ ZEND_METHOD(ReflectionClass, getStaticProperties) /* {{{ Returns the value of a static property */ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; zend_string *name; - zval *prop, *def_value = NULL; + zval *def_value = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &name, &def_value) == FAILURE) { RETURN_THROWS(); @@ -4192,7 +4149,7 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; - prop = zend_std_get_static_property(ce, name, BP_VAR_IS); + zval *prop = zend_std_get_static_property(ce, name, BP_VAR_IS); EG(fake_scope) = old_scope; if (prop && !Z_ISUNDEF_P(prop)) { @@ -4216,11 +4173,10 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) /* {{{ Sets the value of a static property */ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_property_info *prop_info; zend_string *name; - zval *variable_ptr, *value; + zval *value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) { RETURN_THROWS(); @@ -4233,7 +4189,8 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) } const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; - variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info); + zend_property_info *prop_info; + zval *variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info); EG(fake_scope) = old_scope; if (!variable_ptr) { zend_clear_exception(); @@ -4246,12 +4203,12 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) zend_reference *ref = Z_REF_P(variable_ptr); variable_ptr = Z_REFVAL_P(variable_ptr); - if (!zend_verify_ref_assignable_zval(ref, value, 0)) { + if (!zend_verify_ref_assignable_zval(ref, value, false)) { return; } } - if (ZEND_TYPE_IS_SET(prop_info->type) && !zend_verify_property_type(prop_info, value, 0)) { + if (ZEND_TYPE_IS_SET(prop_info->type) && !zend_verify_property_type(prop_info, value, false)) { return; } @@ -4264,7 +4221,7 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) /* {{{ Returns an associative array containing copies of all default property values of the class */ ZEND_METHOD(ReflectionClass, getDefaultProperties) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -4295,8 +4252,8 @@ ZEND_METHOD(ReflectionClass, __toString) /* {{{ Returns the class' name */ ZEND_METHOD(ReflectionClass, getName) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -4308,8 +4265,8 @@ ZEND_METHOD(ReflectionClass, getName) /* {{{ Returns whether this class is an internal class */ ZEND_METHOD(ReflectionClass, isInternal) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4320,8 +4277,8 @@ ZEND_METHOD(ReflectionClass, isInternal) /* {{{ Returns whether this class is user-defined */ ZEND_METHOD(ReflectionClass, isUserDefined) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4329,23 +4286,30 @@ ZEND_METHOD(ReflectionClass, isUserDefined) } /* }}} */ -/* {{{ Returns whether this class is anonymous */ -ZEND_METHOD(ReflectionClass, isAnonymous) +/* {{{ _class_check_flag */ +static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); - RETURN_BOOL(ce->ce_flags & ZEND_ACC_ANON_CLASS); + RETURN_BOOL(ce->ce_flags & mask); +} +/* }}} */ + +/* {{{ Returns whether this class is anonymous */ +ZEND_METHOD(ReflectionClass, isAnonymous) +{ + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ANON_CLASS); } /* }}} */ /* {{{ Returns the filename of the file this class was declared in */ ZEND_METHOD(ReflectionClass, getFileName) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4359,8 +4323,8 @@ ZEND_METHOD(ReflectionClass, getFileName) /* {{{ Returns the line this class' declaration starts at */ ZEND_METHOD(ReflectionClass, getStartLine) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4374,8 +4338,8 @@ ZEND_METHOD(ReflectionClass, getStartLine) /* {{{ Returns the line this class' declaration ends at */ ZEND_METHOD(ReflectionClass, getEndLine) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4389,8 +4353,8 @@ ZEND_METHOD(ReflectionClass, getEndLine) /* {{{ Returns the doc comment for this class */ ZEND_METHOD(ReflectionClass, getDocComment) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4404,7 +4368,7 @@ ZEND_METHOD(ReflectionClass, getDocComment) /* {{{ Returns the attributes for this class */ ZEND_METHOD(ReflectionClass, getAttributes) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; GET_REFLECTION_OBJECT_PTR(ce); @@ -4418,7 +4382,7 @@ ZEND_METHOD(ReflectionClass, getAttributes) /* {{{ Returns the class' constructor if there is one, NULL otherwise */ ZEND_METHOD(ReflectionClass, getConstructor) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -4435,16 +4399,16 @@ ZEND_METHOD(ReflectionClass, getConstructor) /* {{{ Returns whether a method exists or not */ ZEND_METHOD(ReflectionClass, hasMethod) { - reflection_object *intern; - zend_class_entry *ce; - zend_string *name, *lc_name; + const reflection_object *intern; + const zend_class_entry *ce; + zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - lc_name = zend_string_tolower(name); + zend_string *lc_name = zend_string_tolower(name); RETVAL_BOOL(zend_hash_exists(&ce->function_table, lc_name) || is_closure_invoke(ce, lc_name)); zend_string_release(lc_name); } @@ -4453,18 +4417,18 @@ ZEND_METHOD(ReflectionClass, hasMethod) /* {{{ Returns the class' method specified by its name */ ZEND_METHOD(ReflectionClass, getMethod) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_function *mptr; - zval obj_tmp; - zend_string *name, *lc_name; + zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - lc_name = zend_string_tolower(name); + zend_string *lc_name = zend_string_tolower(name); + zend_function *mptr; + zval obj_tmp; if (!Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name) && (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL) { @@ -4507,9 +4471,8 @@ static bool _addmethod(zend_function *mptr, zend_class_entry *ce, HashTable *ht, /* {{{ Returns an array of this class' methods */ ZEND_METHOD(ReflectionClass, getMethods) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_function *mptr; zend_long filter; bool filter_is_null = true; @@ -4524,29 +4487,31 @@ ZEND_METHOD(ReflectionClass, getMethods) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *mptr) { _addmethod(mptr, ce, Z_ARRVAL_P(return_value), filter); } ZEND_HASH_FOREACH_END(); - if (instanceof_function(ce, zend_ce_closure)) { - bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF; - zval obj_tmp; - zend_object *obj; - if (!has_obj) { - object_init_ex(&obj_tmp, ce); - obj = Z_OBJ(obj_tmp); - } else { - obj = Z_OBJ(intern->obj); - } - zend_function *closure = zend_get_closure_invoke_method(obj); - if (closure) { - if (!_addmethod(closure, ce, Z_ARRVAL_P(return_value), filter)) { - _free_function(closure); - } - } - if (!has_obj) { - zval_ptr_dtor(&obj_tmp); - } + // No need for instanceof_function, the Closure class is final + if (ce != zend_ce_closure) { + return; + } + bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF; + zval obj_tmp; + zend_object *obj; + if (!has_obj) { + object_init_ex(&obj_tmp, ce); + obj = Z_OBJ(obj_tmp); + } else { + obj = Z_OBJ(intern->obj); + } + zend_function *closure = zend_get_closure_invoke_method(obj); + if (closure + && !_addmethod(closure, ce, Z_ARRVAL_P(return_value), filter) + ) { + _free_function(closure); + } + if (!has_obj) { + zval_ptr_dtor(&obj_tmp); } } /* }}} */ @@ -4554,9 +4519,8 @@ ZEND_METHOD(ReflectionClass, getMethods) /* {{{ Returns whether a property exists or not */ ZEND_METHOD(ReflectionClass, hasProperty) { - reflection_object *intern; - zend_property_info *property_info; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { @@ -4564,67 +4528,66 @@ ZEND_METHOD(ReflectionClass, hasProperty) } GET_REFLECTION_OBJECT_PTR(ce); - if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) { - if ((property_info->flags & ZEND_ACC_PRIVATE) && property_info->ce != ce) { - RETURN_FALSE; - } + zend_property_info *property_info; + if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL + && (!(property_info->flags & ZEND_ACC_PRIVATE) + || property_info->ce == ce) + ) { RETURN_TRUE; - } else { - if (Z_TYPE(intern->obj) != IS_UNDEF) { - if (Z_OBJ_HANDLER(intern->obj, has_property)(Z_OBJ(intern->obj), name, ZEND_PROPERTY_EXISTS, NULL)) { - RETURN_TRUE; - } + } + if (Z_TYPE(intern->obj) != IS_UNDEF) { + if (Z_OBJ_HANDLER(intern->obj, has_property)(Z_OBJ(intern->obj), name, ZEND_PROPERTY_EXISTS, NULL)) { + RETURN_TRUE; } - RETURN_FALSE; } + RETURN_FALSE; } /* }}} */ /* {{{ Returns the class' property specified by its name */ ZEND_METHOD(ReflectionClass, getProperty) { - reflection_object *intern; - zend_class_entry *ce, *ce2; - zend_property_info *property_info; - zend_string *name, *classname; - char *tmp, *str_name; - size_t classname_len, str_name_len; + const reflection_object *intern; + zend_class_entry *ce; + zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) { - if (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce) { - reflection_property_factory(ce, name, property_info, return_value); - return; - } - } else if (Z_TYPE(intern->obj) != IS_UNDEF) { + zend_property_info *property_info; + if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL + && (!(property_info->flags & ZEND_ACC_PRIVATE) + || property_info->ce == ce) + ) { + reflection_property_factory(ce, name, property_info, return_value); + return; + } + if (Z_TYPE(intern->obj) != IS_UNDEF) { /* Check for dynamic properties */ if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(Z_OBJ(intern->obj)), name)) { reflection_property_factory(ce, name, NULL, return_value); return; } } - str_name = ZSTR_VAL(name); + const char *str_name = ZSTR_VAL(name); + const char *tmp; if ((tmp = strstr(ZSTR_VAL(name), "::")) != NULL) { - classname_len = tmp - ZSTR_VAL(name); - classname = zend_string_alloc(classname_len, 0); - zend_str_tolower_copy(ZSTR_VAL(classname), ZSTR_VAL(name), classname_len); - ZSTR_VAL(classname)[classname_len] = '\0'; - str_name_len = ZSTR_LEN(name) - (classname_len + 2); + size_t classname_len = tmp - ZSTR_VAL(name); + zend_string *classname = zend_string_init(ZSTR_VAL(name), classname_len, false); + size_t str_name_len = ZSTR_LEN(name) - (classname_len + 2); str_name = tmp + 2; - ce2 = zend_lookup_class(classname); + zend_class_entry *ce2 = zend_lookup_class(classname); if (!ce2) { if (!EG(exception)) { zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" does not exist", ZSTR_VAL(classname)); } - zend_string_release_ex(classname, 0); + zend_string_release_ex(classname, false); RETURN_THROWS(); } - zend_string_release_ex(classname, 0); + zend_string_release_ex(classname, false); if (!instanceof_function(ce, ce2)) { zend_throw_exception_ex(reflection_exception_ptr, -1, "Fully qualified property name %s::$%s does not specify a base class of %s", ZSTR_VAL(ce2->name), str_name, ZSTR_VAL(ce->name)); @@ -4634,8 +4597,9 @@ ZEND_METHOD(ReflectionClass, getProperty) property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len); if (property_info != NULL - && (!(property_info->flags & ZEND_ACC_PRIVATE) - || property_info->ce == ce)) { + && (!(property_info->flags & ZEND_ACC_PRIVATE) + || property_info->ce == ce) + ) { reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value); return; } @@ -4651,7 +4615,7 @@ static void _addproperty(zend_property_info *pptr, zend_string *key, zend_class_ return; } - if (pptr->flags & filter) { + if (pptr->flags & filter) { zval property; reflection_property_factory(ce, key, pptr, &property); zend_hash_next_index_insert_new(ht, &property); @@ -4662,8 +4626,6 @@ static void _addproperty(zend_property_info *pptr, zend_string *key, zend_class_ /* {{{ _adddynproperty */ static void _adddynproperty(zval *ptr, zend_string *key, zend_class_entry *ce, zval *retval) { - zval property; - /* under some circumstances, the properties hash table may contain numeric * properties (e.g. when casting from array). This is a WON'T FIX bug, at * least for the moment. Ignore these */ @@ -4676,6 +4638,7 @@ static void _adddynproperty(zval *ptr, zend_string *key, zend_class_entry *ce, z return; } + zval property; reflection_property_factory(ce, key, NULL, &property); add_next_index_zval(retval, &property); } @@ -4684,10 +4647,8 @@ static void _adddynproperty(zval *ptr, zend_string *key, zend_class_entry *ce, z /* {{{ Returns an array of this class' properties */ ZEND_METHOD(ReflectionClass, getProperties) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_string *key; - zend_property_info *prop_info; zend_long filter; bool filter_is_null = true; @@ -4702,14 +4663,14 @@ ZEND_METHOD(ReflectionClass, getProperties) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { + zend_string *key; + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, key, zend_property_info *prop_info) { _addproperty(prop_info, key, ce, Z_ARRVAL_P(return_value), filter); } ZEND_HASH_FOREACH_END(); if (Z_TYPE(intern->obj) != IS_UNDEF && (filter & ZEND_ACC_PUBLIC) != 0) { HashTable *properties = Z_OBJ_HT(intern->obj)->get_properties(Z_OBJ(intern->obj)); - zval *prop; - ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) { + ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, zval *prop) { _adddynproperty(prop, key, ce, return_value); } ZEND_HASH_FOREACH_END(); } @@ -4719,8 +4680,8 @@ ZEND_METHOD(ReflectionClass, getProperties) /* {{{ Returns whether a constant exists or not */ ZEND_METHOD(ReflectionClass, hasConstant) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { @@ -4728,22 +4689,15 @@ ZEND_METHOD(ReflectionClass, hasConstant) } GET_REFLECTION_OBJECT_PTR(ce); - if (zend_hash_exists(&ce->constants_table, name)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_hash_exists(&ce->constants_table, name)); } /* }}} */ /* {{{ Returns an associative array containing this class' constants and their values */ ZEND_METHOD(ReflectionClass, getConstants) { - reflection_object *intern; - zend_class_entry *ce; - zend_string *key; - zend_class_constant *constant; - zval val; + const reflection_object *intern; + const zend_class_entry *ce; zend_long filter; bool filter_is_null = true; @@ -4757,8 +4711,14 @@ ZEND_METHOD(ReflectionClass, getConstants) GET_REFLECTION_OBJECT_PTR(ce); + const HashTable *constants_table = CE_CONSTANTS_TABLE(ce); + if (zend_hash_num_elements(constants_table) == 0) { + RETURN_EMPTY_ARRAY(); + } + array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), key, constant) { + zval val; + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(constants_table, zend_string *key, zend_class_constant *constant) { if (UNEXPECTED(Z_TYPE(constant->value) == IS_CONSTANT_AST && zend_update_class_constant(constant, key, constant->ce) != SUCCESS)) { RETURN_THROWS(); } @@ -4774,10 +4734,8 @@ ZEND_METHOD(ReflectionClass, getConstants) /* {{{ Returns an associative array containing this class' constants as ReflectionClassConstant objects */ ZEND_METHOD(ReflectionClass, getReflectionConstants) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_string *name; - zend_class_constant *constant; zend_long filter; bool filter_is_null = true; @@ -4791,8 +4749,13 @@ ZEND_METHOD(ReflectionClass, getReflectionConstants) GET_REFLECTION_OBJECT_PTR(ce); + const HashTable *constants_table = CE_CONSTANTS_TABLE(ce); + if (zend_hash_num_elements(constants_table) == 0) { + RETURN_EMPTY_ARRAY(); + } + array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), name, constant) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(constants_table, zend_string *name, zend_class_constant *constant) { if (ZEND_CLASS_CONST_FLAGS(constant) & filter) { zval class_const; reflection_class_constant_factory(name, constant, &class_const); @@ -4805,19 +4768,18 @@ ZEND_METHOD(ReflectionClass, getReflectionConstants) /* {{{ Returns the class' constant specified by its name */ ZEND_METHOD(ReflectionClass, getConstant) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - HashTable *constants_table; - zend_class_constant *c; - zend_string *name, *key; + zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - constants_table = CE_CONSTANTS_TABLE(ce); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(constants_table, key, c) { + const HashTable *constants_table = CE_CONSTANTS_TABLE(ce); + zend_class_constant *c; + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(constants_table, zend_string *key, c) { if (UNEXPECTED(Z_TYPE(c->value) == IS_CONSTANT_AST && zend_update_class_constant(c, key, c->ce) != SUCCESS)) { RETURN_THROWS(); } @@ -4837,9 +4799,8 @@ ZEND_METHOD(ReflectionClass, getConstant) /* {{{ Returns the class' constant as ReflectionClassConstant objects */ ZEND_METHOD(ReflectionClass, getReflectionConstant) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_class_constant *constant; zend_string *name; GET_REFLECTION_OBJECT_PTR(ce); @@ -4847,6 +4808,7 @@ ZEND_METHOD(ReflectionClass, getReflectionConstant) RETURN_THROWS(); } + zend_class_constant *constant; if ((constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), name)) == NULL) { RETURN_FALSE; } @@ -4854,23 +4816,11 @@ ZEND_METHOD(ReflectionClass, getReflectionConstant) } /* }}} */ -/* {{{ _class_check_flag */ -static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) -{ - reflection_object *intern; - zend_class_entry *ce; - - ZEND_PARSE_PARAMETERS_NONE(); - GET_REFLECTION_OBJECT_PTR(ce); - RETVAL_BOOL(ce->ce_flags & mask); -} -/* }}} */ - /* {{{ Returns whether this class is instantiable */ ZEND_METHOD(ReflectionClass, isInstantiable) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4891,9 +4841,8 @@ ZEND_METHOD(ReflectionClass, isInstantiable) /* {{{ Returns whether this class is cloneable */ ZEND_METHOD(ReflectionClass, isCloneable) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zval obj; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -4906,6 +4855,7 @@ ZEND_METHOD(ReflectionClass, isCloneable) if (!Z_ISUNDEF(intern->obj)) { RETURN_BOOL(Z_OBJ_HANDLER(intern->obj, clone_obj) != NULL); } else { + zval obj; if (UNEXPECTED(object_init_ex(&obj, ce) != SUCCESS)) { return; } @@ -4956,11 +4906,11 @@ ZEND_METHOD(ReflectionClass, isAbstract) } /* }}} */ -/* {{{ Returns a bitfield of the access modifiers for this class */ +/* {{{ Returns a bitfield of the modifiers for this class */ ZEND_METHOD(ReflectionClass, getModifiers) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; uint32_t keep_flags = ZEND_ACC_FINAL | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_READONLY_CLASS; ZEND_PARSE_PARAMETERS_NONE(); @@ -4973,9 +4923,9 @@ ZEND_METHOD(ReflectionClass, getModifiers) /* {{{ Returns whether the given object is an instance of this class */ ZEND_METHOD(ReflectionClass, isInstance) { - reflection_object *intern; - zend_class_entry *ce; - zval *object; + const reflection_object *intern; + const zend_class_entry *ce; + const zval *object; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) { RETURN_THROWS(); @@ -4988,9 +4938,8 @@ ZEND_METHOD(ReflectionClass, isInstance) /* {{{ Returns an instance of this class */ ZEND_METHOD(ReflectionClass, newInstance) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - zend_function *constructor; GET_REFLECTION_OBJECT_PTR(ce); @@ -5000,21 +4949,20 @@ ZEND_METHOD(ReflectionClass, newInstance) const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; - constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); + zend_function *constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); EG(fake_scope) = old_scope; /* Run the constructor if there is one */ if (constructor) { - zval *params; - int num_args; - HashTable *named_params; - if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name)); zval_ptr_dtor(return_value); RETURN_NULL(); } + zval *params; + uint32_t num_args; + HashTable *named_params; ZEND_PARSE_PARAMETERS_START(0, -1) Z_PARAM_VARIADIC_WITH_NAMED(params, num_args, named_params) ZEND_PARSE_PARAMETERS_END(); @@ -5035,7 +4983,7 @@ ZEND_METHOD(ReflectionClass, newInstance) /* {{{ Returns an instance of this class without invoking its constructor */ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; GET_REFLECTION_OBJECT_PTR(ce); @@ -5055,11 +5003,9 @@ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor) /* {{{ Returns an instance of this class */ ZEND_METHOD(ReflectionClass, newInstanceArgs) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; - int argc = 0; HashTable *args = NULL; - zend_function *constructor; GET_REFLECTION_OBJECT_PTR(ce); @@ -5067,6 +5013,7 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) RETURN_THROWS(); } + uint32_t argc = 0; if (args) { argc = zend_hash_num_elements(args); } @@ -5077,7 +5024,7 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; - constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); + zend_function *constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); EG(fake_scope) = old_scope; /* Run the constructor if there is one */ @@ -5103,7 +5050,7 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, int strategy, bool is_reset) { - reflection_object *intern; + const reflection_object *intern; zend_object *obj; zend_class_entry *ce; zend_fcall_info fci; @@ -5207,7 +5154,7 @@ PHP_METHOD(ReflectionClass, resetAsLazyProxy) /* {{{ Returns whether object lazy and uninitialized */ ZEND_METHOD(ReflectionClass, isUninitializedLazyObject) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; zend_object *object; @@ -5224,7 +5171,7 @@ ZEND_METHOD(ReflectionClass, isUninitializedLazyObject) /* {{{ Trigger object initialization */ ZEND_METHOD(ReflectionClass, initializeLazyObject) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; zend_object *object; @@ -5250,7 +5197,7 @@ ZEND_METHOD(ReflectionClass, initializeLazyObject) /* {{{ Mark object as initialized without calling the initializer */ ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; zend_object *object; @@ -5276,7 +5223,7 @@ ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized) /* {{{ Get lazy object initializer */ ZEND_METHOD(ReflectionClass, getLazyInitializer) { - reflection_object *intern; + const reflection_object *intern; zend_class_entry *ce; zend_object *object; @@ -5287,29 +5234,28 @@ ZEND_METHOD(ReflectionClass, getLazyInitializer) ZEND_PARSE_PARAMETERS_END(); if (!zend_object_is_lazy(object) - || zend_lazy_object_initialized(object)) { + || zend_lazy_object_initialized(object) + ) { RETURN_NULL(); } - RETURN_ZVAL(zend_lazy_object_get_initializer_zv(object), 1, 0); + RETURN_ZVAL(zend_lazy_object_get_initializer_zv(object), true, false); } /* }}} */ /* {{{ Returns an array of interfaces this class implements */ ZEND_METHOD(ReflectionClass, getInterfaces) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); if (ce->num_interfaces) { - uint32_t i; - ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); array_init(return_value); - for (i=0; i < ce->num_interfaces; i++) { + for (uint32_t i=0; i < ce->num_interfaces; i++) { zval interface; zend_reflection_class_factory(ce->interfaces[i], &interface); zend_hash_update(Z_ARRVAL_P(return_value), ce->interfaces[i]->name, &interface); @@ -5323,9 +5269,8 @@ ZEND_METHOD(ReflectionClass, getInterfaces) /* {{{ Returns an array of names of interfaces this class implements */ ZEND_METHOD(ReflectionClass, getInterfaceNames) { - reflection_object *intern; - zend_class_entry *ce; - uint32_t i; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -5338,7 +5283,7 @@ ZEND_METHOD(ReflectionClass, getInterfaceNames) ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); array_init(return_value); - for (i=0; i < ce->num_interfaces; i++) { + for (uint32_t i=0; i < ce->num_interfaces; i++) { add_next_index_str(return_value, zend_string_copy(ce->interfaces[i]->name)); } } @@ -5347,9 +5292,8 @@ ZEND_METHOD(ReflectionClass, getInterfaceNames) /* {{{ Returns an array of traits used by this class */ ZEND_METHOD(ReflectionClass, getTraits) { - reflection_object *intern; - zend_class_entry *ce; - uint32_t i; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -5360,11 +5304,10 @@ ZEND_METHOD(ReflectionClass, getTraits) array_init(return_value); - for (i=0; i < ce->num_traits; i++) { + for (uint32_t i=0; i < ce->num_traits; i++) { zval trait; - zend_class_entry *trait_ce; - trait_ce = zend_fetch_class_by_name(ce->trait_names[i].name, + zend_class_entry *trait_ce = zend_fetch_class_by_name(ce->trait_names[i].name, ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT); ZEND_ASSERT(trait_ce); zend_reflection_class_factory(trait_ce, &trait); @@ -5376,9 +5319,8 @@ ZEND_METHOD(ReflectionClass, getTraits) /* {{{ Returns an array of names of traits used by this class */ ZEND_METHOD(ReflectionClass, getTraitNames) { - reflection_object *intern; - zend_class_entry *ce; - uint32_t i; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -5389,7 +5331,7 @@ ZEND_METHOD(ReflectionClass, getTraitNames) array_init(return_value); - for (i=0; i < ce->num_traits; i++) { + for (uint32_t i=0; i < ce->num_traits; i++) { add_next_index_str(return_value, zend_string_copy(ce->trait_names[i].name)); } } @@ -5398,49 +5340,44 @@ ZEND_METHOD(ReflectionClass, getTraitNames) /* {{{ Returns an array of trait aliases */ ZEND_METHOD(ReflectionClass, getTraitAliases) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); + if (!ce->trait_aliases) { + RETURN_EMPTY_ARRAY(); + } - if (ce->trait_aliases) { - uint32_t i = 0; + array_init(return_value); + for (uint32_t i = 0; ce->trait_aliases[i]; i++) { + const zend_trait_method_reference *cur_ref = &ce->trait_aliases[i]->trait_method; - array_init(return_value); - while (ce->trait_aliases[i]) { - zend_string *mname; - zend_trait_method_reference *cur_ref = &ce->trait_aliases[i]->trait_method; - - if (ce->trait_aliases[i]->alias) { - zend_string *class_name = cur_ref->class_name; - - if (!class_name) { - uint32_t j = 0; - zend_string *lcname = zend_string_tolower(cur_ref->method_name); - - for (j = 0; j < ce->num_traits; j++) { - zend_class_entry *trait = - zend_hash_find_ptr(CG(class_table), ce->trait_names[j].lc_name); - ZEND_ASSERT(trait && "Trait must exist"); - if (zend_hash_exists(&trait->function_table, lcname)) { - class_name = trait->name; - break; - } - } - zend_string_release_ex(lcname, 0); - ZEND_ASSERT(class_name != NULL); - } + if (!ce->trait_aliases[i]->alias) { + continue; + } + zend_string *class_name = cur_ref->class_name; - mname = zend_string_alloc(ZSTR_LEN(class_name) + ZSTR_LEN(cur_ref->method_name) + 2, 0); - snprintf(ZSTR_VAL(mname), ZSTR_LEN(mname) + 1, "%s::%s", ZSTR_VAL(class_name), ZSTR_VAL(cur_ref->method_name)); - add_assoc_str_ex(return_value, ZSTR_VAL(ce->trait_aliases[i]->alias), ZSTR_LEN(ce->trait_aliases[i]->alias), mname); + if (!class_name) { + zend_string *lcname = zend_string_tolower(cur_ref->method_name); + + for (uint32_t j = 0; j < ce->num_traits; j++) { + const zend_class_entry *trait = + zend_hash_find_ptr(CG(class_table), ce->trait_names[j].lc_name); + ZEND_ASSERT(trait && "Trait must exist"); + if (zend_hash_exists(&trait->function_table, lcname)) { + class_name = trait->name; + break; + } } - i++; + zend_string_release_ex(lcname, false); + ZEND_ASSERT(class_name != NULL); } - } else { - RETURN_EMPTY_ARRAY(); + + zend_string *mname = zend_string_alloc(ZSTR_LEN(class_name) + ZSTR_LEN(cur_ref->method_name) + 2, false); + snprintf(ZSTR_VAL(mname), ZSTR_LEN(mname) + 1, "%s::%s", ZSTR_VAL(class_name), ZSTR_VAL(cur_ref->method_name)); + add_assoc_str_ex(return_value, ZSTR_VAL(ce->trait_aliases[i]->alias), ZSTR_LEN(ce->trait_aliases[i]->alias), mname); } } /* }}} */ @@ -5448,8 +5385,8 @@ ZEND_METHOD(ReflectionClass, getTraitAliases) /* {{{ Returns the class' parent class, or, if none exists, FALSE */ ZEND_METHOD(ReflectionClass, getParentClass) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); @@ -5465,7 +5402,7 @@ ZEND_METHOD(ReflectionClass, getParentClass) /* {{{ Returns whether this class is a subclass of another class */ ZEND_METHOD(ReflectionClass, isSubclassOf) { - reflection_object *intern, *argument; + const reflection_object *intern; zend_class_entry *ce, *class_ce; zend_string *class_str; zend_object *class_obj; @@ -5475,7 +5412,7 @@ ZEND_METHOD(ReflectionClass, isSubclassOf) ZEND_PARSE_PARAMETERS_END(); if (class_obj) { - argument = reflection_object_from_obj(class_obj); + const reflection_object *argument = reflection_object_from_obj(class_obj); if (argument->ptr == NULL) { zend_throw_error(NULL, "Internal error: Failed to retrieve the argument's reflection object"); RETURN_THROWS(); @@ -5491,14 +5428,14 @@ ZEND_METHOD(ReflectionClass, isSubclassOf) GET_REFLECTION_OBJECT_PTR(ce); - RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce))); + RETURN_BOOL(ce != class_ce && instanceof_function(ce, class_ce)); } /* }}} */ /* {{{ Returns whether this class is a subclass of another class */ ZEND_METHOD(ReflectionClass, implementsInterface) { - reflection_object *intern, *argument; + const reflection_object *intern; zend_string *interface_str; zend_class_entry *ce, *interface_ce; zend_object *interface_obj; @@ -5508,18 +5445,16 @@ ZEND_METHOD(ReflectionClass, implementsInterface) ZEND_PARSE_PARAMETERS_END(); if (interface_obj) { - argument = reflection_object_from_obj(interface_obj); + const reflection_object *argument = reflection_object_from_obj(interface_obj); if (argument->ptr == NULL) { zend_throw_error(NULL, "Internal error: Failed to retrieve the argument's reflection object"); RETURN_THROWS(); } interface_ce = argument->ptr; - } else { - if ((interface_ce = zend_lookup_class(interface_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Interface \"%s\" does not exist", ZSTR_VAL(interface_str)); - RETURN_THROWS(); - } + } else if ((interface_ce = zend_lookup_class(interface_str)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Interface \"%s\" does not exist", ZSTR_VAL(interface_str)); + RETURN_THROWS(); } if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) { @@ -5536,8 +5471,8 @@ ZEND_METHOD(ReflectionClass, implementsInterface) /* {{{ Returns whether this class is iterable (can be used inside foreach) */ ZEND_METHOD(ReflectionClass, isIterable) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -5556,15 +5491,15 @@ ZEND_METHOD(ReflectionClass, isIterable) /* {{{ Returns NULL or the extension the class belongs to */ ZEND_METHOD(ReflectionClass, getExtension) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) { - reflection_extension_factory(return_value, ce->info.internal.module->name); + reflection_extension_factory(return_value, ce->info.internal.module); } } /* }}} */ @@ -5572,8 +5507,8 @@ ZEND_METHOD(ReflectionClass, getExtension) /* {{{ Returns false or the name of the extension the class belongs to */ ZEND_METHOD(ReflectionClass, getExtensionName) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -5590,14 +5525,14 @@ ZEND_METHOD(ReflectionClass, getExtensionName) /* {{{ Returns whether this class is defined in namespace */ ZEND_METHOD(ReflectionClass, inNamespace) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); - zend_string *name = ce->name; + const zend_string *name = ce->name; const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); RETURN_BOOL(backslash); } @@ -5606,14 +5541,14 @@ ZEND_METHOD(ReflectionClass, inNamespace) /* {{{ Returns the name of namespace where this class is defined */ ZEND_METHOD(ReflectionClass, getNamespaceName) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); - zend_string *name = ce->name; + const zend_string *name = ce->name; const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); if (backslash) { RETURN_STRINGL(ZSTR_VAL(name), backslash - ZSTR_VAL(name)); @@ -5625,8 +5560,8 @@ ZEND_METHOD(ReflectionClass, getNamespaceName) /* {{{ Returns the short name of the class (without namespace part) */ ZEND_METHOD(ReflectionClass, getShortName) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -5644,7 +5579,7 @@ ZEND_METHOD(ReflectionClass, getShortName) /* {{{ Constructor. Takes an instance as an argument */ ZEND_METHOD(ReflectionObject, __construct) { - reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ @@ -5654,41 +5589,36 @@ ZEND_METHOD(ReflectionProperty, __construct) zend_string *classname_str; zend_object *classname_obj; zend_string *name; - int dynam_prop = 0; - zval *object; - reflection_object *intern; zend_class_entry *ce; - zend_property_info *property_info = NULL; - property_reference *reference; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_OBJ_OR_STR(classname_obj, classname_str) Z_PARAM_STR(name) ZEND_PARSE_PARAMETERS_END(); - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); if (classname_obj) { ce = classname_obj->ce; - } else { - if ((ce = zend_lookup_class(classname_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); - RETURN_THROWS(); - } + } else if ((ce = zend_lookup_class(classname_str)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); + RETURN_THROWS(); } - property_info = zend_hash_find_ptr(&ce->properties_info, name); + zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, name); + bool dynam_prop = false; if (property_info == NULL - || ((property_info->flags & ZEND_ACC_PRIVATE) - && property_info->ce != ce)) { + || ((property_info->flags & ZEND_ACC_PRIVATE) + && property_info->ce != ce) + ) { /* Check for dynamic properties */ - if (property_info == NULL && classname_obj) { - if (zend_hash_exists(classname_obj->handlers->get_properties(classname_obj), name)) { - dynam_prop = 1; - } + if (property_info == NULL && classname_obj + && zend_hash_exists(classname_obj->handlers->get_properties(classname_obj), name) + ) { + dynam_prop = true; } - if (dynam_prop == 0) { + if (!dynam_prop) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Property %s::$%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); RETURN_THROWS(); } @@ -5698,7 +5628,7 @@ ZEND_METHOD(ReflectionProperty, __construct) zval_ptr_dtor(prop_name); ZVAL_STR_COPY(prop_name, name); /* Note: class name are always interned, no need to destroy them */ - if (dynam_prop == 0) { + if (!dynam_prop) { ZVAL_STR_COPY(reflection_prop_class(object), property_info->ce->name); } else { ZVAL_STR_COPY(reflection_prop_class(object), ce->name); @@ -5708,7 +5638,7 @@ ZEND_METHOD(ReflectionProperty, __construct) reflection_free_property_reference(intern->ptr); } - reference = (property_reference*) emalloc(sizeof(property_reference)); + property_reference *reference = (property_reference*) emalloc(sizeof(property_reference)); reference->prop = dynam_prop ? NULL : property_info; reference->unmangled_name = zend_string_copy(name); memset(reference->cache_slot, 0, sizeof(reference->cache_slot)); @@ -5721,22 +5651,22 @@ ZEND_METHOD(ReflectionProperty, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionProperty, __toString) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - _property_string(&str, ref->prop, ZSTR_VAL(ref->unmangled_name), ""); + _property_string(&str, ref->prop, ref->unmangled_name, ""); RETURN_STR(smart_str_extract(&str)); } /* }}} */ -/* {{{ Returns the class' name */ +/* {{{ Returns the property's name */ ZEND_METHOD(ReflectionProperty, getName) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -5747,14 +5677,14 @@ ZEND_METHOD(ReflectionProperty, getName) ZEND_METHOD(ReflectionProperty, getMangledName) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); if (ref->prop == NULL) { - RETURN_STR_COPY(ref->unmangled_name); + RETURN_STR_COPY(ref->unmangled_name); } RETURN_STR_COPY(ref->prop->name); @@ -5762,8 +5692,8 @@ ZEND_METHOD(ReflectionProperty, getMangledName) static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -5826,8 +5756,8 @@ ZEND_METHOD(ReflectionProperty, isVirtual) static void _property_check_dynamic(INTERNAL_FUNCTION_PARAMETERS, bool dynamic_true) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -5856,11 +5786,11 @@ ZEND_METHOD(ReflectionProperty, isPromoted) } /* }}} */ -/* {{{ Returns a bitfield of the access modifiers for this property */ +/* {{{ Returns a bitfield of the modifiers for this property */ ZEND_METHOD(ReflectionProperty, getModifiers) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL | ZEND_ACC_FINAL; ZEND_PARSE_PARAMETERS_NONE(); @@ -5873,10 +5803,9 @@ ZEND_METHOD(ReflectionProperty, getModifiers) /* {{{ Returns this property's value */ ZEND_METHOD(ReflectionProperty, getValue) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zval *object = NULL; - zval *member_p = NULL; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL @@ -5886,49 +5815,48 @@ ZEND_METHOD(ReflectionProperty, getValue) GET_REFLECTION_OBJECT_PTR(ref); if (prop_get_flags(ref) & ZEND_ACC_STATIC) { - member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0); + zval *member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, false); if (member_p) { RETURN_COPY_DEREF(member_p); } - } else { - zval rv; - - if (!object) { - zend_argument_type_error(1, "must be provided for instance properties"); - RETURN_THROWS(); - } + return; + } + if (!object) { + zend_argument_type_error(1, "must be provided for instance properties"); + RETURN_THROWS(); + } - /* TODO: Should this always use intern->ce? */ - if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { - zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); - RETURN_THROWS(); - } + /* TODO: Should this always use intern->ce? */ + if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); + RETURN_THROWS(); + } - if (ref->cache_slot[0] == Z_OBJCE_P(object)) { - uintptr_t prop_offset = (uintptr_t) ref->cache_slot[1]; + if (ref->cache_slot[0] == Z_OBJCE_P(object)) { + uintptr_t prop_offset = (uintptr_t) ref->cache_slot[1]; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - zval *retval = OBJ_PROP(Z_OBJ_P(object), prop_offset); - if (EXPECTED(!Z_ISUNDEF_P(retval))) { - RETURN_COPY_DEREF(retval); - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + zval *retval = OBJ_PROP(Z_OBJ_P(object), prop_offset); + if (EXPECTED(!Z_ISUNDEF_P(retval))) { + RETURN_COPY_DEREF(retval); } } + } - const zend_class_entry *old_scope = EG(fake_scope); - EG(fake_scope) = intern->ce; - member_p = Z_OBJ_P(object)->handlers->read_property(Z_OBJ_P(object), - ref->unmangled_name, BP_VAR_R, ref->cache_slot, &rv); - EG(fake_scope) = old_scope; + zval rv; + const zend_class_entry *old_scope = EG(fake_scope); + EG(fake_scope) = intern->ce; + zval *member_p = Z_OBJ_P(object)->handlers->read_property(Z_OBJ_P(object), + ref->unmangled_name, BP_VAR_R, ref->cache_slot, &rv); + EG(fake_scope) = old_scope; - if (member_p != &rv) { - RETURN_COPY_DEREF(member_p); - } else { - if (Z_ISREF_P(member_p)) { - zend_unwrap_reference(member_p); - } - RETURN_COPY_VALUE(member_p); + if (member_p != &rv) { + RETURN_COPY_DEREF(member_p); + } else { + if (Z_ISREF_P(member_p)) { + zend_unwrap_reference(member_p); } + RETURN_COPY_VALUE(member_p); } } /* }}} */ @@ -5936,15 +5864,15 @@ ZEND_METHOD(ReflectionProperty, getValue) /* {{{ Sets this property's value */ ZEND_METHOD(ReflectionProperty, setValue) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zval *value; - zval *tmp; GET_REFLECTION_OBJECT_PTR(ref); if (prop_get_flags(ref) & ZEND_ACC_STATIC) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) { + zval *tmp; if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) { RETURN_THROWS(); } @@ -5987,17 +5915,17 @@ ZEND_METHOD(ReflectionProperty, setValue) * property is overridden on 'object' and was not private in 'scope'. * The effective prop may add hooks or change flags. */ static zend_property_info *reflection_property_get_effective_prop( - property_reference *ref, zend_class_entry *scope, zend_object *object) { - zend_property_info *prop = ref->prop; + zend_property_info *prop, zend_string *unmangled_name, + const zend_class_entry *scope, const zend_object *object) { if (scope != object->ce && !(prop && (prop->flags & ZEND_ACC_PRIVATE))) { - prop = zend_hash_find_ptr(&object->ce->properties_info, ref->unmangled_name); + prop = zend_hash_find_ptr(&object->ce->properties_info, unmangled_name); } return prop; } ZEND_METHOD(ReflectionProperty, getRawValue) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zval *object; @@ -6023,8 +5951,8 @@ ZEND_METHOD(ReflectionProperty, getRawValue) } } - zend_property_info *prop = reflection_property_get_effective_prop(ref, - intern->ce, Z_OBJ_P(object)); + const zend_property_info *prop = reflection_property_get_effective_prop(ref->prop, + ref->unmangled_name, intern->ce, Z_OBJ_P(object)); if (UNEXPECTED(prop && (prop->flags & ZEND_ACC_STATIC))) { zend_throw_exception(reflection_exception_ptr, "May not use getRawValue on static properties", 0); @@ -6054,13 +5982,15 @@ ZEND_METHOD(ReflectionProperty, getRawValue) } } -static void reflection_property_set_raw_value(zend_property_info *prop, - zend_string *unmangled_name, void *cache_slot[3], reflection_object *intern, - zend_object *object, zval *value) +static void zend_reflection_property_set_raw_value_ex(zend_property_info *prop, + zend_string *unmangled_name, void *cache_slot[3], + const zend_class_entry *scope, zend_object *object, zval *value) { + ZEND_ASSERT(!prop || !(prop->flags & ZEND_ACC_STATIC)); + if (!prop || !prop->hooks || !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { const zend_class_entry *old_scope = EG(fake_scope); - EG(fake_scope) = intern->ce; + EG(fake_scope) = scope; object->handlers->write_property(object, unmangled_name, value, cache_slot); EG(fake_scope) = old_scope; } else { @@ -6069,9 +5999,25 @@ static void reflection_property_set_raw_value(zend_property_info *prop, } } +PHPAPI void zend_reflection_property_set_raw_value(zend_property_info *prop, + zend_string *unmangled_name, void *cache_slot[3], + const zend_class_entry *scope, zend_object *object, zval *value) +{ + prop = reflection_property_get_effective_prop(prop, + unmangled_name, scope, object); + + if (UNEXPECTED(prop && (prop->flags & ZEND_ACC_STATIC))) { + zend_throw_exception(reflection_exception_ptr, "May not use setRawValue on static properties", 0); + return; + } + + zend_reflection_property_set_raw_value_ex(prop, unmangled_name, cache_slot, + scope, object, value); +} + ZEND_METHOD(ReflectionProperty, setRawValue) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zval *object; zval *value; @@ -6083,26 +6029,18 @@ ZEND_METHOD(ReflectionProperty, setRawValue) Z_PARAM_ZVAL(value) } ZEND_PARSE_PARAMETERS_END(); - zend_property_info *prop = reflection_property_get_effective_prop(ref, - intern->ce, Z_OBJ_P(object)); - - if (UNEXPECTED(prop && (prop->flags & ZEND_ACC_STATIC))) { - zend_throw_exception(reflection_exception_ptr, "May not use setRawValue on static properties", 0); - RETURN_THROWS(); - } - - reflection_property_set_raw_value(prop, ref->unmangled_name, - ref->cache_slot, intern, Z_OBJ_P(object), value); + zend_reflection_property_set_raw_value(ref->prop, ref->unmangled_name, + ref->cache_slot, intern->ce, Z_OBJ_P(object), value); } static zend_result reflection_property_check_lazy_compatible( - zend_property_info *prop, zend_string *unmangled_name, - reflection_object *intern, zend_object *object, const char *method) + const zend_property_info *prop, zend_string *unmangled_name, + const zend_class_entry *scope, const zend_object *object, const char *method) { if (!prop) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Can not use %s on dynamic property %s::$%s", - method, ZSTR_VAL(intern->ce->name), + method, ZSTR_VAL(scope->name), ZSTR_VAL(unmangled_name)); return FAILURE; } @@ -6123,13 +6061,13 @@ static zend_result reflection_property_check_lazy_compatible( return FAILURE; } - if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { - if (!zend_class_can_be_lazy(object->ce)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use %s on internal class %s", - method, ZSTR_VAL(object->ce->name)); - return FAILURE; - } + if (UNEXPECTED(object->handlers->write_property != zend_std_write_property) + && !zend_class_can_be_lazy(object->ce) + ) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use %s on internal class %s", + method, ZSTR_VAL(object->ce->name)); + return FAILURE; } ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(prop->offset)); @@ -6137,32 +6075,23 @@ static zend_result reflection_property_check_lazy_compatible( return SUCCESS; } -/* {{{ Set property value without triggering initializer while skipping hooks if any */ -ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +PHPAPI void zend_reflection_property_set_raw_value_without_lazy_initialization( + zend_property_info *prop, zend_string *unmangled_name, + void *cache_slot[3], const zend_class_entry *scope, + zend_object *object, zval *value) { - reflection_object *intern; - property_reference *ref; - zend_object *object; - zval *value; - - GET_REFLECTION_OBJECT_PTR(ref); - - ZEND_PARSE_PARAMETERS_START(2, 2) { - Z_PARAM_OBJ_OF_CLASS(object, intern->ce) - Z_PARAM_ZVAL(value) - } ZEND_PARSE_PARAMETERS_END(); - while (zend_object_is_lazy_proxy(object) && zend_lazy_object_initialized(object)) { object = zend_lazy_object_get_instance(object); } - zend_property_info *prop = reflection_property_get_effective_prop(ref, - intern->ce, object); + prop = reflection_property_get_effective_prop(prop, + unmangled_name, scope, object); - if (reflection_property_check_lazy_compatible(prop, ref->unmangled_name, - intern, object, "setRawValueWithoutLazyInitialization") == FAILURE) { - RETURN_THROWS(); + if (reflection_property_check_lazy_compatible(prop, unmangled_name, + scope, object, "setRawValueWithoutLazyInitialization") == FAILURE) { + ZEND_ASSERT(EG(exception)); + return; } zval *var_ptr = OBJ_PROP(object, prop->offset); @@ -6171,8 +6100,8 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) /* Do not trigger initialization */ Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_LAZY; - reflection_property_set_raw_value(prop, ref->unmangled_name, - ref->cache_slot, intern, object, value); + zend_reflection_property_set_raw_value_ex(prop, unmangled_name, + cache_slot, scope, object, value); /* Mark property as lazy again if an exception prevented update */ if (EG(exception) && prop_was_lazy && Z_TYPE_P(var_ptr) == IS_UNDEF @@ -6183,18 +6112,38 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) /* Object becomes non-lazy if this was the last lazy prop */ if (prop_was_lazy && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY) - && zend_object_is_lazy(object) - && !zend_lazy_object_initialized(object)) { - if (zend_lazy_object_decr_lazy_props(object)) { - zend_lazy_object_realize(object); - } + && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object) + && zend_lazy_object_decr_lazy_props(object) + ) { + zend_lazy_object_realize(object); } } +/* {{{ Set property value without triggering initializer while skipping hooks if any */ +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +{ + const reflection_object *intern; + property_reference *ref; + zend_object *object; + zval *value; + + GET_REFLECTION_OBJECT_PTR(ref); + + ZEND_PARSE_PARAMETERS_START(2, 2) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + Z_PARAM_ZVAL(value) + } ZEND_PARSE_PARAMETERS_END(); + + zend_reflection_property_set_raw_value_without_lazy_initialization( + ref->prop, ref->unmangled_name, ref->cache_slot, intern->ce, + object, value); +} + /* {{{ Mark property as non-lazy, and initialize to default value */ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zend_object *object; @@ -6205,7 +6154,7 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) } ZEND_PARSE_PARAMETERS_END(); if (reflection_property_check_lazy_compatible(ref->prop, - ref->unmangled_name, intern, object, + ref->unmangled_name, intern->ce, object, "skipLazyInitialization") == FAILURE) { RETURN_THROWS(); } @@ -6215,7 +6164,7 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) object = zend_lazy_object_get_instance(object); } - zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; + const zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; zval *dst = OBJ_PROP(object, ref->prop->offset); if (!(Z_PROP_FLAG_P(dst) & IS_PROP_LAZY)) { @@ -6229,17 +6178,17 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) /* Object becomes non-lazy if this was the last lazy prop */ if (zend_object_is_lazy(object) - && !zend_lazy_object_initialized(object)) { - if (zend_lazy_object_decr_lazy_props(object)) { - zend_lazy_object_realize(object); - } + && !zend_lazy_object_initialized(object) + && zend_lazy_object_decr_lazy_props(object) + ) { + zend_lazy_object_realize(object); } } ZEND_METHOD(ReflectionProperty, isLazy) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; zend_object *object; GET_REFLECTION_OBJECT_PTR(ref); @@ -6263,10 +6212,9 @@ ZEND_METHOD(ReflectionProperty, isLazy) /* {{{ Returns true if property was initialized */ ZEND_METHOD(ReflectionProperty, isInitialized) { - reflection_object *intern; + const reflection_object *intern; property_reference *ref; zval *object = NULL; - zval *member_p = NULL; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL @@ -6276,56 +6224,52 @@ ZEND_METHOD(ReflectionProperty, isInitialized) GET_REFLECTION_OBJECT_PTR(ref); if (prop_get_flags(ref) & ZEND_ACC_STATIC) { - member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 1); + const zval *member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, true); if (member_p) { RETURN_BOOL(!Z_ISUNDEF_P(member_p)); } RETURN_FALSE; - } else { - int retval; - - if (!object) { - zend_argument_type_error(1, "must be provided for instance properties"); - RETURN_THROWS(); - } + } + if (!object) { + zend_argument_type_error(1, "must be provided for instance properties"); + RETURN_THROWS(); + } - /* TODO: Should this always use intern->ce? */ - if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { - zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); - RETURN_THROWS(); - } + /* TODO: Should this always use intern->ce? */ + if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); + RETURN_THROWS(); + } - if (ref->cache_slot[0] == Z_OBJCE_P(object)) { - uintptr_t prop_offset = (uintptr_t) ref->cache_slot[1]; + if (ref->cache_slot[0] == Z_OBJCE_P(object)) { + uintptr_t prop_offset = (uintptr_t) ref->cache_slot[1]; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - zval *value = OBJ_PROP(Z_OBJ_P(object), prop_offset); - RETURN_BOOL(!Z_ISUNDEF_P(value)); - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + zval *value = OBJ_PROP(Z_OBJ_P(object), prop_offset); + RETURN_BOOL(!Z_ISUNDEF_P(value)); } + } - const zend_class_entry *old_scope = EG(fake_scope); - EG(fake_scope) = intern->ce; - retval = Z_OBJ_HT_P(object)->has_property(Z_OBJ_P(object), - ref->unmangled_name, ZEND_PROPERTY_EXISTS, ref->cache_slot); - EG(fake_scope) = old_scope; + const zend_class_entry *old_scope = EG(fake_scope); + EG(fake_scope) = intern->ce; + int retval = Z_OBJ_HT_P(object)->has_property(Z_OBJ_P(object), + ref->unmangled_name, ZEND_PROPERTY_EXISTS, ref->cache_slot); + EG(fake_scope) = old_scope; - RETVAL_BOOL(retval); - } + RETVAL_BOOL(retval); } /* }}} */ /* {{{ Get the declaring class */ ZEND_METHOD(ReflectionProperty, getDeclaringClass) { - reflection_object *intern; - property_reference *ref; - zend_class_entry *ce; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - ce = ref->prop ? ref->prop->ce : intern->ce; + zend_class_entry *ce = ref->prop ? ref->prop->ce : intern->ce; zend_reflection_class_factory(ce, return_value); } /* }}} */ @@ -6333,8 +6277,8 @@ ZEND_METHOD(ReflectionProperty, getDeclaringClass) /* {{{ Returns the doc comment for this property */ ZEND_METHOD(ReflectionProperty, getDocComment) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -6348,8 +6292,8 @@ ZEND_METHOD(ReflectionProperty, getDocComment) /* {{{ Returns the attributes of this property */ ZEND_METHOD(ReflectionProperty, getAttributes) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; GET_REFLECTION_OBJECT_PTR(ref); @@ -6363,7 +6307,7 @@ ZEND_METHOD(ReflectionProperty, getAttributes) } /* }}} */ -/* {{{ Sets whether non-public properties can be requested */ +/* {{{ No-op; previously controlled whether non-public properties can be requested */ ZEND_METHOD(ReflectionProperty, setAccessible) { bool visible; @@ -6377,8 +6321,8 @@ ZEND_METHOD(ReflectionProperty, setAccessible) /* {{{ Returns the type associated with the property */ ZEND_METHOD(ReflectionProperty, getType) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -6394,29 +6338,29 @@ ZEND_METHOD(ReflectionProperty, getType) ZEND_METHOD(ReflectionProperty, getSettableType) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - zend_property_info *prop = ref->prop; + const zend_property_info *prop = ref->prop; /* Dynamic property is untyped. */ - if (!ref->prop) { + if (!prop) { RETURN_NULL(); } /* Get-only virtual property can never be written to. */ if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); + zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, false, 0); reflection_type_factory(never_type, return_value, true); return; } /* Extract set $value parameter type. */ if (prop->hooks && prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_arg_info *arg_info = &prop->hooks[ZEND_PROPERTY_HOOK_SET]->common.arg_info[0]; + const zend_arg_info *arg_info = &prop->hooks[ZEND_PROPERTY_HOOK_SET]->common.arg_info[0]; if (!ZEND_TYPE_IS_SET(arg_info->type)) { RETURN_NULL(); } @@ -6425,17 +6369,17 @@ ZEND_METHOD(ReflectionProperty, getSettableType) } /* Fall back to property type */ - if (!ZEND_TYPE_IS_SET(ref->prop->type)) { + if (!ZEND_TYPE_IS_SET(prop->type)) { RETURN_NULL(); } - reflection_type_factory(ref->prop->type, return_value, true); + reflection_type_factory(prop->type, return_value, true); } /* {{{ Returns whether property has a type */ ZEND_METHOD(ReflectionProperty, hasType) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -6448,22 +6392,20 @@ ZEND_METHOD(ReflectionProperty, hasType) /* {{{ Returns whether property has a default value */ ZEND_METHOD(ReflectionProperty, hasDefaultValue) { - reflection_object *intern; - property_reference *ref; - zend_property_info *prop_info; - zval *prop; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - prop_info = ref->prop; + const zend_property_info *prop_info = ref->prop; if (prop_info == NULL) { RETURN_FALSE; } - prop = property_get_default(prop_info); + const zval *prop = property_get_default(prop_info); RETURN_BOOL(prop && !Z_ISUNDEF_P(prop)); } /* }}} */ @@ -6471,16 +6413,14 @@ ZEND_METHOD(ReflectionProperty, hasDefaultValue) /* {{{ Returns the default value of a property */ ZEND_METHOD(ReflectionProperty, getDefaultValue) { - reflection_object *intern; - property_reference *ref; - zend_property_info *prop_info; - zval *prop; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); - prop_info = ref->prop; + const zend_property_info *prop_info = ref->prop; if (prop_info == NULL) { // Dynamic property @@ -6492,7 +6432,7 @@ ZEND_METHOD(ReflectionProperty, getDefaultValue) return; } - prop = property_get_default(prop_info); + zval *prop = property_get_default(prop_info); if (!prop || Z_ISUNDEF_P(prop)) { zend_error( E_DEPRECATED, @@ -6508,18 +6448,18 @@ ZEND_METHOD(ReflectionProperty, getDefaultValue) /* this is necessary to make it able to work with default array * properties, returned to user */ - if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zval_update_constant_ex(return_value, prop_info->ce) != SUCCESS)) { - RETURN_THROWS(); - } + if (Z_TYPE_P(return_value) == IS_CONSTANT_AST + && UNEXPECTED(zval_update_constant_ex(return_value, prop_info->ce) != SUCCESS) + ) { + RETURN_THROWS(); } } /* }}} */ ZEND_METHOD(ReflectionProperty, hasHooks) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -6530,8 +6470,8 @@ ZEND_METHOD(ReflectionProperty, hasHooks) ZEND_METHOD(ReflectionProperty, getHooks) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -6559,9 +6499,8 @@ ZEND_METHOD(ReflectionProperty, getHooks) ZEND_METHOD(ReflectionProperty, hasHook) { - - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; zend_enum_PropertyHookType type; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -6582,8 +6521,8 @@ ZEND_METHOD(ReflectionProperty, hasHook) ZEND_METHOD(ReflectionProperty, getHook) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; zend_enum_PropertyHookType type; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -6616,7 +6555,7 @@ ZEND_METHOD(ReflectionProperty, isFinal) _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL); } -static zend_result get_ce_from_scope_name(zend_class_entry **scope, zend_string *scope_name, zend_execute_data *execute_data) +static zend_result get_ce_from_scope_name(zend_class_entry **scope, zend_string *scope_name) { if (!scope_name) { *scope = NULL; @@ -6640,11 +6579,11 @@ static zend_always_inline uint32_t set_visibility_to_visibility(uint32_t set_vis return ZEND_ACC_PROTECTED; case ZEND_ACC_PRIVATE_SET: return ZEND_ACC_PRIVATE; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } -static bool check_visibility(uint32_t visibility, zend_class_entry *ce, zend_class_entry *scope) +static bool check_visibility(uint32_t visibility, const zend_class_entry *ce, const zend_class_entry *scope) { if (!(visibility & ZEND_ACC_PUBLIC) && (scope != ce)) { if (!scope) { @@ -6663,8 +6602,8 @@ static bool check_visibility(uint32_t visibility, zend_class_entry *ce, zend_cla ZEND_METHOD(ReflectionProperty, isReadable) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; zend_string *scope_name; zend_object *obj = NULL; @@ -6686,7 +6625,8 @@ ZEND_METHOD(ReflectionProperty, isReadable) zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); RETURN_THROWS(); } - prop = reflection_property_get_effective_prop(ref, intern->ce, obj); + prop = reflection_property_get_effective_prop(ref->prop, + ref->unmangled_name, intern->ce, obj); } zend_class_entry *ce = obj ? obj->ce : intern->ce; @@ -6704,6 +6644,11 @@ ZEND_METHOD(ReflectionProperty, isReadable) zval member; ZVAL_STR(&member, ref->unmangled_name); zend_call_known_instance_method_with_1_params(ce->__isset, obj, return_value, &member); + + if (Z_TYPE_P(return_value) == IS_REFERENCE) { + zend_unwrap_reference(return_value); + } + *guard &= ~ZEND_GUARD_PROPERTY_ISSET; OBJ_RELEASE(obj); return; @@ -6724,7 +6669,7 @@ ZEND_METHOD(ReflectionProperty, isReadable) } zend_class_entry *scope; - if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) { + if (get_ce_from_scope_name(&scope, scope_name) == FAILURE) { RETURN_THROWS(); } @@ -6769,8 +6714,8 @@ retry_declared:; ZEND_METHOD(ReflectionProperty, isWritable) { - reflection_object *intern; - property_reference *ref; + const reflection_object *intern; + const property_reference *ref; zend_string *scope_name; zend_object *obj = NULL; @@ -6792,10 +6737,11 @@ ZEND_METHOD(ReflectionProperty, isWritable) zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); RETURN_THROWS(); } - prop = reflection_property_get_effective_prop(ref, intern->ce, obj); + prop = reflection_property_get_effective_prop(ref->prop, + ref->unmangled_name, intern->ce, obj); } - zend_class_entry *ce = obj ? obj->ce : intern->ce; + const zend_class_entry *ce = obj ? obj->ce : intern->ce; if (!prop) { if (!(ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) { RETURN_TRUE; @@ -6809,7 +6755,7 @@ ZEND_METHOD(ReflectionProperty, isWritable) } zend_class_entry *scope; - if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) { + if (get_ce_from_scope_name(&scope, scope_name) == FAILURE) { RETURN_THROWS(); } @@ -6836,8 +6782,9 @@ ZEND_METHOD(ReflectionProperty, isWritable) retry:; zval *prop_val = OBJ_PROP(obj, prop->offset); if (Z_TYPE_P(prop_val) == IS_UNDEF - && zend_lazy_object_must_init(obj) - && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY)) { + && zend_lazy_object_must_init(obj) + && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY) + ) { obj = zend_lazy_object_init(obj); if (!obj) { RETURN_THROWS(); @@ -6855,17 +6802,15 @@ retry:; /* {{{ Constructor. Throws an Exception in case the given extension does not exist */ ZEND_METHOD(ReflectionExtension, __construct) { - zval *object; - reflection_object *intern; - zend_module_entry *module; zend_string *name_str; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name_str) == FAILURE) { RETURN_THROWS(); } - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); + zend_module_entry *module; if ((module = zend_hash_find_ptr_lc(&module_registry, name_str)) == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Extension \"%s\" does not exist", ZSTR_VAL(name_str)); @@ -6883,13 +6828,13 @@ ZEND_METHOD(ReflectionExtension, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionExtension, __toString) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); - _extension_string(&str, module, ""); + _extension_string(&str, module); RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -6897,8 +6842,8 @@ ZEND_METHOD(ReflectionExtension, __toString) /* {{{ Returns this extension's name */ ZEND_METHOD(ReflectionExtension, getName) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); @@ -6910,8 +6855,8 @@ ZEND_METHOD(ReflectionExtension, getName) /* {{{ Returns this extension's version */ ZEND_METHOD(ReflectionExtension, getVersion) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); @@ -6928,18 +6873,18 @@ ZEND_METHOD(ReflectionExtension, getVersion) /* {{{ Returns an array of this extension's functions */ ZEND_METHOD(ReflectionExtension, getFunctions) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; zval function; - zend_function *fptr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), fptr) { + ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zend_function *fptr) { if (fptr->common.type==ZEND_INTERNAL_FUNCTION - && fptr->internal_function.module == module) { + && fptr->internal_function.module == module + ) { reflection_function_factory(fptr, NULL, &function); zend_hash_update(Z_ARRVAL_P(return_value), fptr->common.function_name, &function); } @@ -6950,15 +6895,14 @@ ZEND_METHOD(ReflectionExtension, getFunctions) /* {{{ Returns an associative array containing this extension's constants and their values */ ZEND_METHOD(ReflectionExtension, getConstants) { - reflection_object *intern; - zend_module_entry *module; - zend_constant *constant; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), zend_constant *constant) { if (module->module_number == ZEND_CONSTANT_MODULE_NUMBER(constant)) { zval const_val; ZVAL_COPY_OR_DUP(&const_val, &constant->value); @@ -6969,7 +6913,7 @@ ZEND_METHOD(ReflectionExtension, getConstants) /* }}} */ /* {{{ _addinientry */ -static void _addinientry(zend_ini_entry *ini_entry, zval *retval, int number) +static void _addinientry(const zend_ini_entry *ini_entry, const zval *retval, int number) { if (number == ini_entry->module_number) { zval zv; @@ -6986,22 +6930,21 @@ static void _addinientry(zend_ini_entry *ini_entry, zval *retval, int number) /* {{{ Returns an associative array containing this extension's INI entries and their values */ ZEND_METHOD(ReflectionExtension, getINIEntries) { - reflection_object *intern; - zend_module_entry *module; - zend_ini_entry *ini_entry; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(EG(ini_directives), ini_entry) { + ZEND_HASH_MAP_FOREACH_PTR(EG(ini_directives), zend_ini_entry *ini_entry) { _addinientry(ini_entry, return_value, module->module_number); } ZEND_HASH_FOREACH_END(); } /* }}} */ /* {{{ add_extension_class */ -static void add_extension_class(zend_class_entry *ce, zend_string *key, zval *class_array, zend_module_entry *module, bool add_reflection_class) +static void add_extension_class(zend_class_entry *ce, zend_string *key, zval *class_array, const zend_module_entry *module, bool add_reflection_class) { if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { zend_string *name; @@ -7027,16 +6970,14 @@ static void add_extension_class(zend_class_entry *ce, zend_string *key, zval *cl /* {{{ Returns an array containing ReflectionClass objects for all classes of this extension */ ZEND_METHOD(ReflectionExtension, getClasses) { - reflection_object *intern; - zend_module_entry *module; - zend_string *key; - zend_class_entry *ce; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), zend_string *key, zend_class_entry *ce) { add_extension_class(ce, key, return_value, module, true); } ZEND_HASH_FOREACH_END(); } @@ -7045,16 +6986,14 @@ ZEND_METHOD(ReflectionExtension, getClasses) /* {{{ Returns an array containing all names of all classes of this extension */ ZEND_METHOD(ReflectionExtension, getClassNames) { - reflection_object *intern; - zend_module_entry *module; - zend_string *key; - zend_class_entry *ce; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), zend_string *key, zend_class_entry *ce) { add_extension_class(ce, key, return_value, module, false); } ZEND_HASH_FOREACH_END(); } @@ -7063,24 +7002,21 @@ ZEND_METHOD(ReflectionExtension, getClassNames) /* {{{ Returns an array containing all names of all extensions this extension depends on */ ZEND_METHOD(ReflectionExtension, getDependencies) { - reflection_object *intern; - zend_module_entry *module; - const zend_module_dep *dep; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); - dep = module->deps; + const zend_module_dep *dep = module->deps; - if (!dep) - { + if (!dep) { RETURN_EMPTY_ARRAY(); } array_init(return_value); - while(dep->name) { - zend_string *relation; - char *rel_type; + while (dep->name) { + const char *rel_type; size_t len = 0; switch(dep->type) { @@ -7110,7 +7046,7 @@ ZEND_METHOD(ReflectionExtension, getDependencies) len += strlen(dep->version) + 1; } - relation = zend_string_alloc(len, 0); + zend_string *relation = zend_string_alloc(len, false); snprintf(ZSTR_VAL(relation), ZSTR_LEN(relation) + 1, "%s%s%s%s%s", rel_type, dep->rel ? " " : "", @@ -7126,7 +7062,7 @@ ZEND_METHOD(ReflectionExtension, getDependencies) /* {{{ Prints phpinfo block for the extension */ ZEND_METHOD(ReflectionExtension, info) { - reflection_object *intern; + const reflection_object *intern; zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); @@ -7139,8 +7075,8 @@ ZEND_METHOD(ReflectionExtension, info) /* {{{ Returns whether this extension is persistent */ ZEND_METHOD(ReflectionExtension, isPersistent) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); @@ -7152,8 +7088,8 @@ ZEND_METHOD(ReflectionExtension, isPersistent) /* {{{ Returns whether this extension is temporary */ ZEND_METHOD(ReflectionExtension, isTemporary) { - reflection_object *intern; - zend_module_entry *module; + const reflection_object *intern; + const zend_module_entry *module; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(module); @@ -7165,20 +7101,17 @@ ZEND_METHOD(ReflectionExtension, isTemporary) /* {{{ Constructor. Throws an Exception in case the given Zend extension does not exist */ ZEND_METHOD(ReflectionZendExtension, __construct) { - zval *object; - reflection_object *intern; - zend_extension *extension; - char *name_str; + const char *name_str; size_t name_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) { RETURN_THROWS(); } - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); - extension = zend_get_extension(name_str); + zend_extension *extension = zend_get_extension(name_str); if (!extension) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Zend Extension \"%s\" does not exist", name_str); @@ -7194,13 +7127,13 @@ ZEND_METHOD(ReflectionZendExtension, __construct) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionZendExtension, __toString) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); - _zend_extension_string(&str, extension, ""); + _zend_extension_string(&str, extension); RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -7208,8 +7141,8 @@ ZEND_METHOD(ReflectionZendExtension, __toString) /* {{{ Returns the name of this Zend extension */ ZEND_METHOD(ReflectionZendExtension, getName) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); @@ -7221,8 +7154,8 @@ ZEND_METHOD(ReflectionZendExtension, getName) /* {{{ Returns the version information of this Zend extension */ ZEND_METHOD(ReflectionZendExtension, getVersion) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); @@ -7238,8 +7171,8 @@ ZEND_METHOD(ReflectionZendExtension, getVersion) /* {{{ Returns the name of this Zend extension's author */ ZEND_METHOD(ReflectionZendExtension, getAuthor) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); @@ -7255,8 +7188,8 @@ ZEND_METHOD(ReflectionZendExtension, getAuthor) /* {{{ Returns this Zend extension's URL*/ ZEND_METHOD(ReflectionZendExtension, getURL) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); @@ -7272,8 +7205,8 @@ ZEND_METHOD(ReflectionZendExtension, getURL) /* {{{ Returns this Zend extension's copyright information */ ZEND_METHOD(ReflectionZendExtension, getCopyright) { - reflection_object *intern; - zend_extension *extension; + const reflection_object *intern; + const zend_extension *extension; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(extension); @@ -7295,7 +7228,7 @@ ZEND_METHOD(ReflectionReference, __construct) } /* }}} */ -static bool is_ignorable_reference(HashTable *ht, zval *ref) { +static bool is_ignorable_reference(const HashTable *ht, const zval *ref) { if (Z_REFCOUNT_P(ref) != 1) { return false; } @@ -7309,16 +7242,15 @@ static bool is_ignorable_reference(HashTable *ht, zval *ref) { ZEND_METHOD(ReflectionReference, fromArrayElement) { HashTable *ht; - zval *item; zend_string *string_key = NULL; zend_long int_key = 0; - reflection_object *intern; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_ARRAY_HT(ht) Z_PARAM_STR_OR_LONG(string_key, int_key) ZEND_PARSE_PARAMETERS_END(); + zval *item; if (string_key) { item = zend_hash_find(ht, string_key); } else { @@ -7335,7 +7267,7 @@ ZEND_METHOD(ReflectionReference, fromArrayElement) } object_init_ex(return_value, reflection_reference_ptr); - intern = Z_REFLECTION_P(return_value); + reflection_object *intern = Z_REFLECTION_P(return_value); ZVAL_COPY(&intern->obj, item); intern->ref_type = REF_TYPE_OTHER; } @@ -7345,13 +7277,9 @@ ZEND_METHOD(ReflectionReference, fromArrayElement) * The format of the return value is unspecified and may change. */ ZEND_METHOD(ReflectionReference, getId) { - reflection_object *intern; - unsigned char digest[20]; - PHP_SHA1_CTX context; - ZEND_PARSE_PARAMETERS_NONE(); - intern = Z_REFLECTION_P(ZEND_THIS); + reflection_object *intern = Z_REFLECTION_P(ZEND_THIS); if (Z_TYPE(intern->obj) != IS_REFERENCE) { zend_throw_exception(reflection_exception_ptr, "Corrupted ReflectionReference object", 0); RETURN_THROWS(); @@ -7366,9 +7294,11 @@ ZEND_METHOD(ReflectionReference, getId) } /* SHA1(ref || key) to avoid directly exposing memory addresses. */ + PHP_SHA1_CTX context; PHP_SHA1Init(&context); PHP_SHA1Update(&context, (unsigned char *) &Z_REF(intern->obj), sizeof(zend_reference *)); PHP_SHA1Update(&context, REFLECTION_G(key), REFLECTION_KEY_LEN); + unsigned char digest[20]; PHP_SHA1Final(digest, &context); RETURN_STRINGL((char *) digest, sizeof(digest)); @@ -7389,8 +7319,8 @@ ZEND_METHOD(ReflectionAttribute, __clone) /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionAttribute, __toString) { - reflection_object *intern; - attribute_reference *attr; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); @@ -7403,10 +7333,10 @@ ZEND_METHOD(ReflectionAttribute, __toString) if (attr->data->argc > 0) { smart_str_appends(&str, " {\n"); - smart_str_append_printf(&str, " - Arguments [%d] {\n", attr->data->argc); + smart_str_append_printf(&str, " - Arguments [%" PRIu32 "] {\n", attr->data->argc); for (uint32_t i = 0; i < attr->data->argc; i++) { - smart_str_append_printf(&str, " Argument #%d [ ", i); + smart_str_append_printf(&str, " Argument #%" PRIu32 " [ ", i); if (attr->data->args[i].name != NULL) { smart_str_append(&str, attr->data->args[i].name); smart_str_appends(&str, " = "); @@ -7430,8 +7360,8 @@ ZEND_METHOD(ReflectionAttribute, __toString) /* {{{ Returns the name of the attribute */ ZEND_METHOD(ReflectionAttribute, getName) { - reflection_object *intern; - attribute_reference *attr; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(attr); @@ -7443,8 +7373,8 @@ ZEND_METHOD(ReflectionAttribute, getName) /* {{{ Returns the target of the attribute */ ZEND_METHOD(ReflectionAttribute, getTarget) { - reflection_object *intern; - attribute_reference *attr; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(attr); @@ -7456,8 +7386,8 @@ ZEND_METHOD(ReflectionAttribute, getTarget) /* {{{ Returns true if the attribute is repeated */ ZEND_METHOD(ReflectionAttribute, isRepeated) { - reflection_object *intern; - attribute_reference *attr; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(attr); @@ -7469,18 +7399,20 @@ ZEND_METHOD(ReflectionAttribute, isRepeated) /* {{{ Returns the arguments passed to the attribute */ ZEND_METHOD(ReflectionAttribute, getArguments) { - reflection_object *intern; - attribute_reference *attr; - - zval tmp; - uint32_t i; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(attr); + if (attr->data->argc == 0) { + RETURN_EMPTY_ARRAY(); + } + array_init(return_value); - for (i = 0; i < attr->data->argc; i++) { + zval tmp; + for (uint32_t i = 0; i < attr->data->argc; i++) { if (FAILURE == zend_get_attribute_value(&tmp, attr->data, i, attr->scope)) { RETURN_THROWS(); } @@ -7498,21 +7430,20 @@ ZEND_METHOD(ReflectionAttribute, getArguments) /* {{{ Returns the attribute as an object */ ZEND_METHOD(ReflectionAttribute, newInstance) { - reflection_object *intern; - attribute_reference *attr; - zend_attribute *marker; - - zend_class_entry *ce; + const reflection_object *intern; + const attribute_reference *attr; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(attr); + zend_class_entry *ce; if (NULL == (ce = zend_lookup_class(attr->data->name))) { zend_throw_error(NULL, "Attribute class \"%s\" not found", ZSTR_VAL(attr->data->name)); RETURN_THROWS(); } + zend_attribute *marker; if (NULL == (marker = zend_get_attribute_str(ce->attributes, ZEND_STRL("attribute")))) { zend_throw_error(NULL, "Attempting to use non-attribute class \"%s\" as attribute", ZSTR_VAL(attr->data->name)); RETURN_THROWS(); @@ -7559,7 +7490,7 @@ ZEND_METHOD(ReflectionAttribute, newInstance) * more expensive than just an assertion and so we don't worry about it * for non-debug builds. See discussion on GH-18817. */ #if ZEND_DEBUG - zend_attribute *delayed_target_validation = zend_get_attribute_str( + const zend_attribute *delayed_target_validation = zend_get_attribute_str( attr->attributes, "delayedtargetvalidation", strlen("delayedtargetvalidation") @@ -7572,13 +7503,12 @@ ZEND_METHOD(ReflectionAttribute, newInstance) /* Repetition validation is done even if #[DelayedTargetValidation] is used * and so can be skipped for internal attributes. */ - if (ce->type == ZEND_USER_CLASS) { - if (!(flags & ZEND_ATTRIBUTE_IS_REPEATABLE)) { - if (zend_is_attribute_repeated(attr->attributes, attr->data)) { - zend_throw_error(NULL, "Attribute \"%s\" must not be repeated", ZSTR_VAL(attr->data->name)); - RETURN_THROWS(); - } - } + if (ce->type == ZEND_USER_CLASS + && !(flags & ZEND_ATTRIBUTE_IS_REPEATABLE) + && zend_is_attribute_repeated(attr->attributes, attr->data) + ) { + zend_throw_error(NULL, "Attribute \"%s\" must not be repeated", ZSTR_VAL(attr->data->name)); + RETURN_THROWS(); } zval obj; @@ -7592,13 +7522,13 @@ ZEND_METHOD(ReflectionAttribute, newInstance) ZEND_METHOD(ReflectionEnum, __construct) { - reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); if (EG(exception)) { RETURN_THROWS(); } - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; GET_REFLECTION_OBJECT_PTR(ce); if (!(ce->ce_flags & ZEND_ACC_ENUM)) { @@ -7609,8 +7539,8 @@ ZEND_METHOD(ReflectionEnum, __construct) ZEND_METHOD(ReflectionEnum, hasCase) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { @@ -7619,7 +7549,7 @@ ZEND_METHOD(ReflectionEnum, hasCase) GET_REFLECTION_OBJECT_PTR(ce); - zend_class_constant *class_const = zend_hash_find_ptr(&ce->constants_table, name); + const zend_class_constant *class_const = zend_hash_find_ptr(&ce->constants_table, name); if (class_const == NULL) { RETURN_FALSE; } @@ -7629,8 +7559,8 @@ ZEND_METHOD(ReflectionEnum, hasCase) ZEND_METHOD(ReflectionEnum, getCase) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; zend_string *name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { @@ -7654,17 +7584,15 @@ ZEND_METHOD(ReflectionEnum, getCase) ZEND_METHOD(ReflectionEnum, getCases) { - reflection_object *intern; - zend_class_entry *ce; - zend_string *name; - zend_class_constant *constant; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), name, constant) { + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), zend_string *name, zend_class_constant *constant) { if (ZEND_CLASS_CONST_FLAGS(constant) & ZEND_CLASS_CONST_IS_CASE) { zval class_const; reflection_enum_case_factory(ce, name, constant, &class_const); @@ -7675,8 +7603,8 @@ ZEND_METHOD(ReflectionEnum, getCases) ZEND_METHOD(ReflectionEnum, isBacked) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -7686,8 +7614,8 @@ ZEND_METHOD(ReflectionEnum, isBacked) ZEND_METHOD(ReflectionEnum, getBackingType) { - reflection_object *intern; - zend_class_entry *ce; + const reflection_object *intern; + const zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -7696,7 +7624,7 @@ ZEND_METHOD(ReflectionEnum, getBackingType) if (ce->enum_backing_type == IS_UNDEF) { RETURN_NULL(); } else { - zend_type type = ZEND_TYPE_INIT_CODE(ce->enum_backing_type, 0, 0); + zend_type type = ZEND_TYPE_INIT_CODE(ce->enum_backing_type, false, 0); reflection_type_factory(type, return_value, false); } } @@ -7708,13 +7636,13 @@ ZEND_METHOD(ReflectionEnumUnitCase, __construct) RETURN_THROWS(); } - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; GET_REFLECTION_OBJECT_PTR(ref); if (!(ZEND_CLASS_CONST_FLAGS(ref) & ZEND_CLASS_CONST_IS_CASE)) { - zval *case_name = reflection_prop_name(ZEND_THIS); + const zval *case_name = reflection_prop_name(ZEND_THIS); zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant %s::%s is not a case", ZSTR_VAL(ref->ce->name), Z_STRVAL_P(case_name)); RETURN_THROWS(); } @@ -7722,8 +7650,8 @@ ZEND_METHOD(ReflectionEnumUnitCase, __construct) ZEND_METHOD(ReflectionEnumUnitCase, getEnum) { - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ref); @@ -7738,13 +7666,13 @@ ZEND_METHOD(ReflectionEnumBackedCase, __construct) RETURN_THROWS(); } - reflection_object *intern; - zend_class_constant *ref; + const reflection_object *intern; + const zend_class_constant *ref; GET_REFLECTION_OBJECT_PTR(ref); if (ref->ce->enum_backing_type == IS_UNDEF) { - zval *case_name = reflection_prop_name(ZEND_THIS); + const zval *case_name = reflection_prop_name(ZEND_THIS); zend_throw_exception_ex(reflection_exception_ptr, 0, "Enum case %s::%s is not a backed case", ZSTR_VAL(ref->ce->name), Z_STRVAL_P(case_name)); RETURN_THROWS(); } @@ -7752,7 +7680,7 @@ ZEND_METHOD(ReflectionEnumBackedCase, __construct) ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue) { - reflection_object *intern; + const reflection_object *intern; zend_class_constant *ref; ZEND_PARSE_PARAMETERS_NONE(); @@ -7766,7 +7694,7 @@ ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue) } ZEND_ASSERT(intern->ce->enum_backing_type != IS_UNDEF); - zval *member_p = zend_enum_fetch_case_value(Z_OBJ(ref->value)); + const zval *member_p = zend_enum_fetch_case_value(Z_OBJ(ref->value)); ZVAL_COPY_OR_DUP(return_value, member_p); } @@ -7774,11 +7702,10 @@ ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue) /* {{{ proto ReflectionFiber::__construct(Fiber $fiber) */ ZEND_METHOD(ReflectionFiber, __construct) { - zval *fiber, *object; - reflection_object *intern; + zval *fiber; - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); + zval *object = ZEND_THIS; + reflection_object *intern = Z_REFLECTION_P(object); ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJECT_OF_CLASS(fiber, zend_ce_fiber) @@ -7812,7 +7739,6 @@ ZEND_METHOD(ReflectionFiber, getTrace) { zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; - zend_execute_data *prev_execute_data; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL @@ -7821,7 +7747,7 @@ ZEND_METHOD(ReflectionFiber, getTrace) REFLECTION_CHECK_VALID_FIBER(fiber); - prev_execute_data = fiber->stack_bottom->prev_execute_data; + zend_execute_data *prev_execute_data = fiber->stack_bottom->prev_execute_data; fiber->stack_bottom->prev_execute_data = NULL; if (EG(active_fiber) != fiber) { @@ -7837,13 +7763,13 @@ ZEND_METHOD(ReflectionFiber, getTrace) ZEND_METHOD(ReflectionFiber, getExecutingLine) { - zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); - zend_execute_data *prev_execute_data; + const zend_fiber *fiber = (const zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); ZEND_PARSE_PARAMETERS_NONE(); REFLECTION_CHECK_VALID_FIBER(fiber); + zend_execute_data *prev_execute_data; if (EG(active_fiber) == fiber) { prev_execute_data = execute_data->prev_execute_data; } else { @@ -7861,13 +7787,13 @@ ZEND_METHOD(ReflectionFiber, getExecutingLine) ZEND_METHOD(ReflectionFiber, getExecutingFile) { - zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); - zend_execute_data *prev_execute_data; + const zend_fiber *fiber = (const zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); ZEND_PARSE_PARAMETERS_NONE(); REFLECTION_CHECK_VALID_FIBER(fiber); + zend_execute_data *prev_execute_data; if (EG(active_fiber) == fiber) { prev_execute_data = execute_data->prev_execute_data; } else { @@ -7885,7 +7811,7 @@ ZEND_METHOD(ReflectionFiber, getExecutingFile) ZEND_METHOD(ReflectionFiber, getCallable) { - zend_fiber *fiber = (zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + const zend_fiber *fiber = (const zend_fiber *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); ZEND_PARSE_PARAMETERS_NONE(); @@ -7906,9 +7832,7 @@ static zval *_reflection_write_property(zend_object *object, zend_string *name, zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot set read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name)); return &EG(uninitialized_zval); - } - else - { + } else { return zend_std_write_property(object, name, value, cache_slot); } } @@ -7927,7 +7851,7 @@ ZEND_METHOD(ReflectionConstant, __construct) /* Build name with lowercased ns. */ bool backslash_prefixed = ZSTR_VAL(name)[0] == '\\'; - char *source = ZSTR_VAL(name) + backslash_prefixed; + const char *source = ZSTR_VAL(name) + backslash_prefixed; size_t source_len = ZSTR_LEN(name) - backslash_prefixed; zend_string *lc_name = zend_string_alloc(source_len, /* persistent */ false); const char *ns_end = zend_memrchr(source, '\\', source_len); @@ -7955,8 +7879,8 @@ ZEND_METHOD(ReflectionConstant, __construct) ZEND_METHOD(ReflectionConstant, getName) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -7966,8 +7890,8 @@ ZEND_METHOD(ReflectionConstant, getName) ZEND_METHOD(ReflectionConstant, inNamespace) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -7980,8 +7904,8 @@ ZEND_METHOD(ReflectionConstant, inNamespace) ZEND_METHOD(ReflectionConstant, getNamespaceName) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -7998,8 +7922,8 @@ ZEND_METHOD(ReflectionConstant, getNamespaceName) ZEND_METHOD(ReflectionConstant, getShortName) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -8017,8 +7941,8 @@ ZEND_METHOD(ReflectionConstant, getShortName) ZEND_METHOD(ReflectionConstant, getValue) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -8028,8 +7952,8 @@ ZEND_METHOD(ReflectionConstant, getValue) ZEND_METHOD(ReflectionConstant, isDeprecated) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -8039,8 +7963,8 @@ ZEND_METHOD(ReflectionConstant, isDeprecated) ZEND_METHOD(ReflectionConstant, getFileName) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); @@ -8053,13 +7977,13 @@ ZEND_METHOD(ReflectionConstant, getFileName) static void reflection_constant_find_ext(INTERNAL_FUNCTION_PARAMETERS, bool only_name) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(const_); - int module_number = ZEND_CONSTANT_MODULE_NUMBER(const_); + uint32_t module_number = ZEND_CONSTANT_MODULE_NUMBER(const_); if (module_number == PHP_USER_CONSTANT) { // For user constants, ReflectionConstant::getExtension() returns null, // ReflectionConstant::getExtensionName() returns false @@ -8068,22 +7992,21 @@ static void reflection_constant_find_ext(INTERNAL_FUNCTION_PARAMETERS, bool only } RETURN_NULL(); } - zend_module_entry *module; - ZEND_HASH_MAP_FOREACH_PTR(&module_registry, module) { + ZEND_HASH_MAP_FOREACH_PTR(&module_registry, zend_module_entry *module) { if (module->module_number != module_number) { continue; } if (only_name) { RETURN_STRING(module->name); } - reflection_extension_factory_ex(return_value, module); + reflection_extension_factory(return_value, module); return; } ZEND_HASH_FOREACH_END(); zend_throw_exception_ex( reflection_exception_ptr, 0, - "Unable to locate extension with module_number %d that provides constant %s", + "Unable to locate extension with module_number %" PRIu32 " that provides constant %s", module_number, ZSTR_VAL(const_->name) ); @@ -8106,8 +8029,8 @@ ZEND_METHOD(ReflectionConstant, getExtensionName) ZEND_METHOD(ReflectionConstant, getAttributes) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; GET_REFLECTION_OBJECT_PTR(const_); @@ -8118,21 +8041,21 @@ ZEND_METHOD(ReflectionConstant, getAttributes) ZEND_METHOD(ReflectionConstant, __toString) { - reflection_object *intern; - zend_constant *const_; + const reflection_object *intern; + const zend_constant *const_; smart_str str = {0}; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(const_); - _const_string(&str, ZSTR_VAL(const_->name), &const_->value, ""); + _const_string(&str, const_->name, &const_->value, ""); RETURN_STR(smart_str_extract(&str)); } PHP_MINIT_FUNCTION(reflection) /* {{{ */ { memcpy(&reflection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - reflection_object_handlers.offset = XtOffsetOf(reflection_object, zo); + reflection_object_handlers.offset = offsetof(reflection_object, zo); reflection_object_handlers.free_obj = reflection_free_objects_storage; reflection_object_handlers.clone_obj = NULL; reflection_object_handlers.write_property = _reflection_write_property; diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index dc2240734298..93b53de74133 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: George Schlossnagle | +----------------------------------------------------------------------+ @@ -52,6 +50,27 @@ extern PHPAPI zend_class_entry *reflection_lazy_object_ptr; PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object); +/* Sets the value of a property, bypassing a set hook if defined. + * 'prop': The property to set + * 'unmangled_name': The name of the property + * 'cache_slot': An opaque pointer used as an internal cache. The same + * cache_slot can be used again with the same 'unmangled_name' and 'scope'. + * Must be zeroed on first use. May be NULL. + * 'scope': The scope from which to set the property + * 'object': The object to set the value on + * 'value': The value to set + */ +PHPAPI void zend_reflection_property_set_raw_value( + zend_property_info *prop, zend_string *unmangled_name, + void *cache_slot[3], const zend_class_entry *scope, + zend_object *object, zval *value); + +/* Same as zend_reflection_property_set_raw_value(), but skips lazy object initialization. */ +PHPAPI void zend_reflection_property_set_raw_value_without_lazy_initialization( + zend_property_info *prop, zend_string *unmangled_name, + void *cache_slot[3], const zend_class_entry *scope, + zend_object *object, zval *value); + END_EXTERN_C() #endif /* PHP_REFLECTION_H */ diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index b0273a3174f8..dd605100f8ba 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -652,6 +652,8 @@ public function __construct($function, int|string $param) {} public function __toString(): string {} + public function getDocComment(): string|false {} + /** @tentative-return-type */ public function getName(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 66605a22bbd6..65571f38d43c 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_reflection.stub.php instead. - * Stub hash: 267472e2b726ca5e788eb5cc3e946bc9aa7c9c41 + * Stub hash: c80946cc8c8215bb6527e09bb71b3a97a76a6a98 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) @@ -526,6 +526,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionParameter___toString arginfo_class_ReflectionFunction___toString +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionParameter_getDocComment, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_END_ARG_INFO() + #define arginfo_class_ReflectionParameter_getName arginfo_class_ReflectionFunctionAbstract_getName #define arginfo_class_ReflectionParameter_isPassedByReference arginfo_class_ReflectionFunctionAbstract_inNamespace @@ -721,13 +724,12 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionConstant_isDeprecated arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionConstant_getFileName, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) -ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionConstant_getFileName arginfo_class_ReflectionParameter_getDocComment ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionConstant_getExtension, 0, 0, ReflectionExtension, 1) ZEND_END_ARG_INFO() -#define arginfo_class_ReflectionConstant_getExtensionName arginfo_class_ReflectionConstant_getFileName +#define arginfo_class_ReflectionConstant_getExtensionName arginfo_class_ReflectionParameter_getDocComment #define arginfo_class_ReflectionConstant___toString arginfo_class_ReflectionFunction___toString @@ -921,6 +923,7 @@ ZEND_METHOD(ReflectionClassConstant, hasType); ZEND_METHOD(ReflectionClassConstant, getType); ZEND_METHOD(ReflectionParameter, __construct); ZEND_METHOD(ReflectionParameter, __toString); +ZEND_METHOD(ReflectionParameter, getDocComment); ZEND_METHOD(ReflectionParameter, getName); ZEND_METHOD(ReflectionParameter, isPassedByReference); ZEND_METHOD(ReflectionParameter, canBePassedByValue); @@ -1237,6 +1240,7 @@ static const zend_function_entry class_ReflectionParameter_methods[] = { ZEND_RAW_FENTRY("__clone", zim_ReflectionClass___clone, arginfo_class_ReflectionParameter___clone, ZEND_ACC_PRIVATE, NULL, NULL) ZEND_ME(ReflectionParameter, __construct, arginfo_class_ReflectionParameter___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, __toString, arginfo_class_ReflectionParameter___toString, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionParameter, getDocComment, arginfo_class_ReflectionParameter_getDocComment, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, getName, arginfo_class_ReflectionParameter_getName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, isPassedByReference, arginfo_class_ReflectionParameter_isPassedByReference, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, canBePassedByValue, arginfo_class_ReflectionParameter_canBePassedByValue, ZEND_ACC_PUBLIC) diff --git a/ext/reflection/php_reflection_decl.h b/ext/reflection/php_reflection_decl.h index a5e8affd0beb..a87e1635419b 100644 --- a/ext/reflection/php_reflection_decl.h +++ b/ext/reflection/php_reflection_decl.h @@ -1,12 +1,12 @@ /* This is a generated file, edit php_reflection.stub.php instead. - * Stub hash: 267472e2b726ca5e788eb5cc3e946bc9aa7c9c41 */ + * Stub hash: c80946cc8c8215bb6527e09bb71b3a97a76a6a98 */ -#ifndef ZEND_PHP_REFLECTION_DECL_267472e2b726ca5e788eb5cc3e946bc9aa7c9c41_H -#define ZEND_PHP_REFLECTION_DECL_267472e2b726ca5e788eb5cc3e946bc9aa7c9c41_H +#ifndef ZEND_PHP_REFLECTION_DECL_c80946cc8c8215bb6527e09bb71b3a97a76a6a98_H +#define ZEND_PHP_REFLECTION_DECL_c80946cc8c8215bb6527e09bb71b3a97a76a6a98_H typedef enum zend_enum_PropertyHookType { ZEND_ENUM_PropertyHookType_Get = 1, ZEND_ENUM_PropertyHookType_Set = 2, } zend_enum_PropertyHookType; -#endif /* ZEND_PHP_REFLECTION_DECL_267472e2b726ca5e788eb5cc3e946bc9aa7c9c41_H */ +#endif /* ZEND_PHP_REFLECTION_DECL_c80946cc8c8215bb6527e09bb71b3a97a76a6a98_H */ diff --git a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt index c47f9e4fffd7..8be2f4bf85b6 100644 --- a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt +++ b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt @@ -244,4 +244,4 @@ Fully qualified property name X::$privC does not specify a base class of C --- (Reflecting on X::doesNotExist) --- Fully qualified property name X::$doesNotExist does not specify a base class of C --- (Reflecting on doesNotexist::doesNotExist) --- -Class "doesnotexist" does not exist +Class "doesNotexist" does not exist diff --git a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt index 32e2d7876f6d..6a4f44ee5977 100644 --- a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt +++ b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt @@ -248,4 +248,4 @@ Fully qualified property name X::$privC does not specify a base class of C --- (Reflecting on X::doesNotExist) --- Fully qualified property name X::$doesNotExist does not specify a base class of C --- (Reflecting on doesNotexist::doesNotExist) --- -Class "doesnotexist" does not exist +Class "doesNotexist" does not exist diff --git a/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt b/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt new file mode 100644 index 000000000000..89d894f83989 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt @@ -0,0 +1,57 @@ +--TEST-- +ReflectionClass::getStaticProperties() +--FILE-- +getStaticProperties()); +var_dump($child->getStaticProperties()); + +echo "\nTyped properties initialized\n:"; +Base::$pubTyped = true; +$base->setStaticPropertyValue('privTyped', true); + +var_dump($base->getStaticProperties()); +var_dump($child->getStaticProperties()); +?> +--EXPECT-- +Start: +array(2) { + ["pub"]=> + NULL + ["priv"]=> + NULL +} +array(1) { + ["pub"]=> + NULL +} + +Typed properties initialized +:array(4) { + ["pub"]=> + NULL + ["priv"]=> + NULL + ["pubTyped"]=> + bool(true) + ["privTyped"]=> + bool(true) +} +array(2) { + ["pub"]=> + NULL + ["pubTyped"]=> + bool(true) +} diff --git a/ext/reflection/tests/ReflectionConstant_null_byte_value.phpt b/ext/reflection/tests/ReflectionConstant_null_byte_value.phpt new file mode 100644 index 000000000000..8b6a8e85c2fc --- /dev/null +++ b/ext/reflection/tests/ReflectionConstant_null_byte_value.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22658: ReflectionConstant with a string value with a null byte +--FILE-- +getValue() ); + +?> +--EXPECTF-- +Constant [ string DEMO ] { f%0oo } +string(4) "f%0oo" diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt index 47813255381e..c497855f7347 100644 --- a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt +++ b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt @@ -14,7 +14,30 @@ foreach ($classNames as $className) { --EXPECT-- AssertionError Directory +Io\IoException +Io\Poll\Backend +Io\Poll\BackendUnavailableException +Io\Poll\Context +Io\Poll\Event +Io\Poll\FailedContextInitializationException +Io\Poll\FailedHandleAddException +Io\Poll\FailedPollOperationException +Io\Poll\FailedPollWaitException +Io\Poll\FailedWatcherModificationException +Io\Poll\Handle +Io\Poll\HandleAlreadyWatchedException +Io\Poll\InactiveWatcherException +Io\Poll\InvalidHandleException +Io\Poll\PollException +Io\Poll\Watcher RoundingMode +SortDirection StreamBucket +StreamError +StreamErrorCode +StreamErrorMode +StreamErrorStore +StreamException +StreamPollHandle __PHP_Incomplete_Class php_user_filter diff --git a/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt index 656fde814d93..c9237e296427 100644 --- a/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt +++ b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt @@ -1,5 +1,5 @@ --TEST-- -Reflection::getClosureThis() +ReflectionMethod::getClosureThis() --FILE-- property = $value; } +} +} + +function global_function( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) {} + +$closure = function( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) {}; + +$arrow_function = fn( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) => true; + +foreach([ + 'A::method' => (new ReflectionClass('A'))->getMethod('method'), + 'global_function' => new ReflectionFunction('global_function'), + 'closure' => new ReflectionFunction($closure), + 'arrow_function' => new ReflectionFunction($arrow_function), + 'property hook' => (new ReflectionClass('A'))->getProperty('property')->getHook(PropertyHookType::Set), + ] as $function => $rc) { + $rps = $rc->getParameters(); + foreach($rps as $rp) { + echo "\n---> Doc comment for $function parameter $" . $rp->getName() . ":\n"; + var_dump($rp->getDocComment()); + } +} + +?> +--EXPECTF-- +---> Doc comment for A::method parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for A::method parameter $b: +bool(false) + +---> Doc comment for A::method parameter $c: +bool(false) + +---> Doc comment for A::method parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for A::method parameter $e: +bool(false) + +---> Doc comment for A::method parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for A::method parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for A::method parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for global_function parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for global_function parameter $b: +bool(false) + +---> Doc comment for global_function parameter $c: +bool(false) + +---> Doc comment for global_function parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for global_function parameter $e: +bool(false) + +---> Doc comment for global_function parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for global_function parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for global_function parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for closure parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for closure parameter $b: +bool(false) + +---> Doc comment for closure parameter $c: +bool(false) + +---> Doc comment for closure parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for closure parameter $e: +bool(false) + +---> Doc comment for closure parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for closure parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for closure parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for arrow_function parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for arrow_function parameter $b: +bool(false) + +---> Doc comment for arrow_function parameter $c: +bool(false) + +---> Doc comment for arrow_function parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for arrow_function parameter $e: +bool(false) + +---> Doc comment for arrow_function parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for arrow_function parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for arrow_function parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for property hook parameter $value: +string(%d) "/** Doc Comment for property hook parameter $value */" + diff --git a/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt b/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt new file mode 100644 index 000000000000..ede7a00e0edd --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt @@ -0,0 +1,84 @@ +--TEST-- +Test ReflectionParameter::getDocComment() usage when methods are indented. +--INI-- +opcache.save_comments=1 +--FILE-- +property = $value; } + } +} + +foreach([ + 'A::method' => (new ReflectionClass('A'))->getMethod('method'), + 'property hook' => (new ReflectionClass('A'))->getProperty('property')->getHook(PropertyHookType::Set), + ] as $function => $rc) { + $rps = $rc->getParameters(); + foreach($rps as $rp) { + echo "\n---> Doc comment for $function parameter $" . $rp->getName() . ":\n"; + var_dump($rp->getDocComment()); + } +} + +?> +--EXPECTF-- +---> Doc comment for A::method parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for A::method parameter $b: +bool(false) + +---> Doc comment for A::method parameter $c: +bool(false) + +---> Doc comment for A::method parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for A::method parameter $e: +bool(false) + +---> Doc comment for A::method parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for A::method parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for A::method parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for property hook parameter $value: +string(%d) "/** Doc Comment for property hook parameter $value */" diff --git a/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt b/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt new file mode 100644 index 000000000000..5689a2c46aca --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt @@ -0,0 +1,143 @@ +--TEST-- +Test ReflectionParameter::getDocComment() usage for property with hook. +--INI-- +opcache.save_comments=1 +--FILE-- +getProperty('foo'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$foo::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +// --------- + +$rp = $rc->getConstructor()->getParameters()[1]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getProperty('bar'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$bar::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +// --------- + +$rp = $rc->getConstructor()->getParameters()[2]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getProperty('baz'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$baz::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getConstructor()->getParameters()[0]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +?> +--EXPECTF-- +---> Doc comment for A::property $foo: +string(11) "/** $foo */" + +---> Doc comment for A::property $foo::get: +string(13) "/** getter */" + +---> Doc comment for A::property $foo::set: +string(13) "/** setter */" + +---> Doc comment for A::property $foo::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $bar: +string(11) "/** $bar */" + +---> Doc comment for A::property $bar: +string(11) "/** $bar */" + +---> Doc comment for A::property $bar::get: +string(13) "/** getter */" + +---> Doc comment for A::property $bar::set: +string(13) "/** setter */" + +---> Doc comment for A::property $bar::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $baz: +bool(false) + +---> Doc comment for A::property $baz: +bool(false) + +---> Doc comment for A::property $baz::get: +string(13) "/** getter */" + +---> Doc comment for A::property $baz::set: +string(13) "/** setter */" + +---> Doc comment for A::property $baz::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $foo: +string(11) "/** $foo */" diff --git a/ext/reflection/tests/ReflectionParameter_leading_backslash.phpt b/ext/reflection/tests/ReflectionParameter_leading_backslash.phpt new file mode 100644 index 000000000000..b0a7827c2764 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_leading_backslash.phpt @@ -0,0 +1,17 @@ +--TEST-- +ReflectionParameter::__construct(): a leading "\" in the function name is ignored +--FILE-- +getName()); + +$p = new ReflectionParameter("demo", 0); +var_dump($p->getName()); + +?> +--EXPECT-- +string(3) "arg" +string(3) "arg" diff --git a/ext/reflection/tests/ReflectionParameter_isDefault.phpt b/ext/reflection/tests/ReflectionProperty_isDefault.phpt similarity index 94% rename from ext/reflection/tests/ReflectionParameter_isDefault.phpt rename to ext/reflection/tests/ReflectionProperty_isDefault.phpt index 3ab0d980fd04..ebb55a6a0d94 100644 --- a/ext/reflection/tests/ReflectionParameter_isDefault.phpt +++ b/ext/reflection/tests/ReflectionProperty_isDefault.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionParameter::isDefault() +ReflectionProperty::isDefault() --FILE-- getURL()); var_dump($reflection->getVersion() === PHP_VERSION); ?> --EXPECT-- -string(17) "Zend Technologies" -string(13) "Copyright (c)" +string(16) "Zend by Perforce" +string(12) "Copyright ©" string(12) "Zend OPcache" -string(20) "http://www.zend.com/" +string(21) "https://www.zend.com/" bool(true) diff --git a/ext/reflection/tests/bug36434.phpt b/ext/reflection/tests/bug36434.phpt index 3f4cc70c7554..0dfa5d117b2c 100644 --- a/ext/reflection/tests/bug36434.phpt +++ b/ext/reflection/tests/bug36434.phpt @@ -26,6 +26,9 @@ foreach ($r->GetProperties() as $p) } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d bar foo ancestor ancestor diff --git a/ext/reflection/tests/gh21362.phpt b/ext/reflection/tests/gh21362.phpt index ce7840b494ed..1f5619ce779d 100644 --- a/ext/reflection/tests/gh21362.phpt +++ b/ext/reflection/tests/gh21362.phpt @@ -43,6 +43,60 @@ $m2 = new ReflectionMethod($closures[0], '__invoke'); foreach ($closures as $closure) { var_dump($m2->invoke($closure)); } + +// First-class callable of a userland function +function my_func($x) { return "my_func: $x"; } +function other_func($x) { return "other_func: $x"; } + +$mf = my_func(...); +$mf2 = my_func(...); +$of = other_func(...); + +$m3 = new ReflectionMethod($mf, '__invoke'); +var_dump($m3->invoke($mf, 'test')); +var_dump($m3->invoke($mf2, 'test')); + +try { + $m3->invoke($of, 'test'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Internal closures (first-class callable syntax) should also be validated +$vd = var_dump(...); +$pr = print_r(...); + +$m4 = new ReflectionMethod($vd, '__invoke'); +$m4->invoke($vd, 'internal closure OK'); + +// Cloned internal closure is a different object but same function - should work +$vd2 = clone $vd; +$m4->invoke($vd2, 'cloned internal closure OK'); + +// Different internal closure should throw +try { + $m4->invoke($pr, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Cross-type: userland Closure to internal Closure's invoke should throw +try { + $m4->invoke($c1, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Cross-type: internal Closure to userland Closure's invoke should throw +try { + $m->invoke($vd, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} ?> --EXPECT-- c1: foo=FOO, bar=BAR @@ -51,3 +105,11 @@ Given Closure is not the same as the reflected Closure int(0) int(1) int(2) +string(13) "my_func: test" +string(13) "my_func: test" +Given Closure is not the same as the reflected Closure +string(19) "internal closure OK" +string(26) "cloned internal closure OK" +Given Closure is not the same as the reflected Closure +Given Closure is not the same as the reflected Closure +Given Closure is not the same as the reflected Closure diff --git a/ext/reflection/tests/gh22000.phpt b/ext/reflection/tests/gh22000.phpt new file mode 100644 index 000000000000..aee4863e9b7d --- /dev/null +++ b/ext/reflection/tests/gh22000.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-22000 - Ensure __isset returning a reference is supported by ReflectionProperty::isReadable() +--FILE-- +b); + unset($this->c); + } + + public function __isset($name) { + return $name === 'b'; + } + + public function __get($name) {} +} + +class TestClass2 { + public int $d; + public int $e; + public int $f; + + public function __construct() { + unset($this->e); + unset($this->f); + } + + public function &__isset($name) { + return $name === 'f'; + } + + public function __get($name) {} +} + + +function test($class) { + $rc = new ReflectionClass($class); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from global:'; + var_dump($rp->isReadable(null, new $class)); + } +} + +test('TestClass1'); +test('TestClass2'); +?> +--EXPECTF-- +a from global:bool(true) +b from global:bool(true) +c from global:bool(false) +d from global:bool(false) +e from global: +Notice: Only variable references should be returned by reference in %s on line %d +bool(false) +f from global: +Notice: Only variable references should be returned by reference in %s on line %d +bool(true) diff --git a/ext/reflection/tests/gh22441.phpt b/ext/reflection/tests/gh22441.phpt new file mode 100644 index 000000000000..9ca3cb0eee74 --- /dev/null +++ b/ext/reflection/tests/gh22441.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-22441 (ReflectionClass::hasProperty()/getProperty() ignore dynamic properties shadowing a private parent property) +--FILE-- +shadow = true; +$o->noShadow = true; + +$r = new ReflectionObject($o); + +echo "hasProperty:\n"; +echo "shadow (dynamic over private parent): "; var_dump($r->hasProperty('shadow')); +echo "noShadow (plain dynamic): "; var_dump($r->hasProperty('noShadow')); +echo "onlyBase (private parent, no dynamic): "; var_dump($r->hasProperty('onlyBase')); + +echo "\ngetProperty:\n"; +foreach (['shadow', 'noShadow', 'onlyBase'] as $name) { + try { + $p = $r->getProperty($name); + printf("%s: %s::\$%s\n", $name, $p->getDeclaringClass()->getName(), $p->getName()); + } catch (ReflectionException $e) { + printf("%s: %s\n", $name, $e->getMessage()); + } +} +?> +--EXPECT-- +hasProperty: +shadow (dynamic over private parent): bool(true) +noShadow (plain dynamic): bool(true) +onlyBase (private parent, no dynamic): bool(false) + +getProperty: +shadow: Child::$shadow +noShadow: Child::$noShadow +onlyBase: Property Child::$onlyBase does not exist diff --git a/ext/reflection/tests/gh22681/ReflectionClassConstant_doc_comment.phpt b/ext/reflection/tests/gh22681/ReflectionClassConstant_doc_comment.phpt new file mode 100644 index 000000000000..5002f066ff69 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionClassConstant_doc_comment.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-22681: null bytes in doc comment truncate ReflectionClassConstant::__toString() +--FILE-- +getDocComment() ); + +echo new ReflectionClass(Demo::class); + +?> +--EXPECTF-- +/** F%0oo */ +Constant [ public bool DEMO ] { 1 } +string(11) "/** F%0oo */" +Class [ class Demo ] { + @@ %s(%d) : eval()'d code %d-%d + + - Constants [1] { + /** F%0oo */ + Constant [ public bool DEMO ] { 1 } + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/gh22681/ReflectionClass_doc_comment.phpt b/ext/reflection/tests/gh22681/ReflectionClass_doc_comment.phpt new file mode 100644 index 000000000000..fc34cd95b1e3 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionClass_doc_comment.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-22681: null bytes in doc comment truncate ReflectionClass::__toString() +--FILE-- +getDocComment() ); + +?> +--EXPECTF-- +/** F%0oo */ +Class [ class Demo ] { + @@ %s(%d) : eval()'d code %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} +string(11) "/** F%0oo */" diff --git a/ext/reflection/tests/gh22681/ReflectionConstant_name.phpt b/ext/reflection/tests/gh22681/ReflectionConstant_name.phpt new file mode 100644 index 000000000000..c43397200c82 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionConstant_name.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22681: null bytes in name truncate ReflectionConstant::__toString() +--FILE-- +getName() ); + +?> +--EXPECTF-- +Constant [ bool F%0oo ] { 1 } +string(4) "F%0oo" diff --git a/ext/reflection/tests/gh22681/ReflectionEnum_backed_value.phpt b/ext/reflection/tests/gh22681/ReflectionEnum_backed_value.phpt new file mode 100644 index 000000000000..f28c39daa100 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionEnum_backed_value.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-22681: null bytes in backed value truncate ReflectionEnum::__toString() +--FILE-- +getBackingValue() ); +?> +--EXPECTF-- +Enum [ enum Demo: string implements UnitEnum, BackedEnum ] { + @@ %s %d-%d + + - Enum cases [1] { + Case DEMO = F%0oo + } + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [3] { + Method [ static public method cases ] { + + - Parameters [0] { + } + - Return [ array ] + } + + Method [ static public method from ] { + + - Parameters [1] { + Parameter #0 [ string|int $value ] + } + - Return [ static ] + } + + Method [ static public method tryFrom ] { + + - Parameters [1] { + Parameter #0 [ string|int $value ] + } + - Return [ ?static ] + } + } + + - Properties [2] { + Property [ public protected(set) readonly string $name ] + Property [ public protected(set) readonly string $value ] + } + + - Methods [0] { + } +} +string(4) "F%0oo" diff --git a/ext/reflection/tests/gh22681/ReflectionEnum_case_doc_comment.phpt b/ext/reflection/tests/gh22681/ReflectionEnum_case_doc_comment.phpt new file mode 100644 index 000000000000..3945ad8639e7 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionEnum_case_doc_comment.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-22681: null bytes in doc comment truncate ReflectionEnum::__toString() +--FILE-- +getDocComment() ); +?> +--EXPECTF-- +Enum [ enum Demo implements UnitEnum ] { + @@ %s(%d) : eval()'d code %d-%d + + - Enum cases [1] { + /** F%0oo */ + Case C + } + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [1] { + Method [ static public method cases ] { + + - Parameters [0] { + } + - Return [ array ] + } + } + + - Properties [1] { + Property [ public protected(set) readonly string $name ] + } + + - Methods [0] { + } +} +string(11) "/** F%0oo */" diff --git a/ext/reflection/tests/gh22681/ReflectionExtension_ini_value.phpt b/ext/reflection/tests/gh22681/ReflectionExtension_ini_value.phpt new file mode 100644 index 000000000000..f12088b3a9e0 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionExtension_ini_value.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-22681: null bytes in INI values truncate ReflectionExtension::__toString() +--FILE-- +getINIEntries()['arg_separator.output'] ); + +?> +--EXPECTF-- +Entry [ arg_separator.output ] + Current = 'f%0oo' + Default = '&' + } + +string(4) "f%0oo" diff --git a/ext/reflection/tests/gh22681/ReflectionFunctionAbstract_doc_comment.phpt b/ext/reflection/tests/gh22681/ReflectionFunctionAbstract_doc_comment.phpt new file mode 100644 index 000000000000..fdd42903c3be --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionFunctionAbstract_doc_comment.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-22681: null bytes in doc comment truncate ReflectionFunctionAbstract::__toString() +--FILE-- +getDocComment() ); + +$r = new ReflectionMethod(Demo::class, 'demo'); +echo $r; +var_dump( $r->getDocComment() ); + +?> +--EXPECTF-- +/** F%0oo */ +Function [ function demo ] { + @@ %s(%d) : eval()'d code %d - %d +} +string(11) "/** F%0oo */" +/** B%0ar */ +Method [ public method demo ] { + @@ %s(%d) : eval()'d code %d - %d +} +string(11) "/** B%0ar */" diff --git a/ext/reflection/tests/gh22681/ReflectionProperty_doc_comment.phpt b/ext/reflection/tests/gh22681/ReflectionProperty_doc_comment.phpt new file mode 100644 index 000000000000..ca218216b2c3 --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionProperty_doc_comment.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-22681: null bytes in doc comment truncate ReflectionProperty::__toString() +--FILE-- +getDocComment() ); + +echo new ReflectionClass(Demo::class); + +?> +--EXPECTF-- +/** F%0oo */ +Property [ public $prop = NULL ] +string(11) "/** F%0oo */" +Class [ class Demo ] { + @@ %s(%d) : eval()'d code %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [1] { + /** F%0oo */ + Property [ public $prop = NULL ] + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/gh22681/ReflectionProperty_dynamic_name.phpt b/ext/reflection/tests/gh22681/ReflectionProperty_dynamic_name.phpt new file mode 100644 index 000000000000..d8cecb0002aa --- /dev/null +++ b/ext/reflection/tests/gh22681/ReflectionProperty_dynamic_name.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-22681: null bytes in name truncate ReflectionProperty::__toString() +--FILE-- + true]; +$r = new ReflectionProperty($obj, "F\0oo"); +echo $r; +var_dump( $r->getDocComment() ); + +echo new ReflectionObject($obj); + +?> +--EXPECTF-- +Property [ public $F%0oo ] +bool(false) +Object of class [ class stdClass ] { + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Dynamic properties [1] { + Property [ public $F%0oo ] + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/gh22683.phpt b/ext/reflection/tests/gh22683.phpt new file mode 100644 index 000000000000..9dfe8eba25c2 --- /dev/null +++ b/ext/reflection/tests/gh22683.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-22683 (Reflection(Class)Constant::__toString() should not warn on NAN conversions) +--FILE-- + +--EXPECT-- +Constant [ float NAN ] { NAN } +Constant [ float INF ] { INF } +Constant [ public float MY_NAN ] { NAN } +Constant [ public float MY_INF ] { INF } +Constant [ public float MY_FLOAT ] { 1.5 } +Constant [ public float MY_WHOLE ] { 2 } diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 87bcb7e3690f..3a7f8aec4522 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -103,7 +101,6 @@ const ps_module ps_mod_files = { PS_MOD_UPDATE_TIMESTAMP(files) }; - static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const zend_string *key) { const char *p; @@ -153,7 +150,7 @@ static void ps_files_open(ps_files *data, /* const */ zend_string *key) { char buf[MAXPATHLEN]; #if !defined(O_NOFOLLOW) || !defined(PHP_WIN32) - struct stat sbuf = {0}; + struct stat sbuf = {0}; #endif int ret; @@ -183,7 +180,7 @@ static void ps_files_open(ps_files *data, /* const */ zend_string *key) #else /* Check to make sure that the opened file is not outside of allowable dirs. This is not 100% safe but it's hard to do something better without O_NOFOLLOW */ - if(PG(open_basedir) && lstat(buf, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && php_check_open_basedir(buf)) { + if (PG(open_basedir) && lstat(buf, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && php_check_open_basedir(buf)) { return; } data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY, data->filemode); @@ -230,7 +227,7 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string /* PS(id) may be changed by calling session_regenerate_id(). Re-initialization should be tried here. ps_files_open() checks - data->last_key and reopen when it is needed. */ + data->last_key and reopen when it is needed. */ ps_files_open(data, key); if (data->fd < 0) { return FAILURE; @@ -258,7 +255,7 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string buf = wrote > -1 ? buf + wrote : 0; to_write = wrote > -1 ? SESS_FILE_BUF_SIZE(ZSTR_LEN(val) - n) : 0; - } while(wrote > 0); + } while (wrote > 0); } #else n = write(data->fd, ZSTR_VAL(val), ZSTR_LEN(val)); @@ -277,7 +274,10 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string return SUCCESS; } -static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetime) +/* Recursively remove expired session files. When dirdepth > 0 the + * cleanup descends into subdirectories up to that many levels before + * inspecting individual session files. */ +static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetime, size_t remaining_depth) { DIR *dir; struct dirent *entry; @@ -292,8 +292,6 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim return -1; } - time(&now); - if (ZSTR_LEN(dirname) >= MAXPATHLEN) { php_error_docref(NULL, E_NOTICE, "ps_files_cleanup_dir: dirname(%s) is too long", ZSTR_VAL(dirname)); closedir(dir); @@ -305,31 +303,52 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim buf[ZSTR_LEN(dirname)] = PHP_DIR_SEPARATOR; while ((entry = readdir(dir))) { - /* does the file start with our prefix? */ - if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) { - size_t entry_len = strlen(entry->d_name); - - /* does it fit into our buffer? */ - if (entry_len + ZSTR_LEN(dirname) + 2 < MAXPATHLEN) { - /* create the full path.. */ - memcpy(buf + ZSTR_LEN(dirname) + 1, entry->d_name, entry_len); - - /* NUL terminate it and */ - buf[ZSTR_LEN(dirname) + entry_len + 1] = '\0'; - - /* check whether its last access was more than maxlifetime ago */ - if (VCWD_STAT(buf, &sbuf) == 0 && - (now - sbuf.st_mtime) > maxlifetime) { - VCWD_UNLINK(buf); - nrdels++; + /* skip . and .. */ + if (entry->d_name[0] == '.' && + (entry->d_name[1] == '\0' || + (entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) { + continue; + } + size_t entry_len = strlen(entry->d_name); + /* does it fit into our buffer? */ + if (ZSTR_LEN(dirname) + 1 + entry_len >= MAXPATHLEN) { + continue; + } + /* create the full path and NUL-terminate it */ + memcpy(buf + ZSTR_LEN(dirname) + 1, entry->d_name, entry_len); + buf[ZSTR_LEN(dirname) + 1 + entry_len] = '\0'; + + if (remaining_depth == 0) { + /* target depth: delete expired session files */ + if (strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1) != 0) { + continue; + } + if (VCWD_STAT(buf, &sbuf) != 0) { + continue; + } + time(&now); + if ((now - sbuf.st_mtime) > maxlifetime) { + VCWD_UNLINK(buf); + nrdels++; + } + } else { + /* intermediate depth: recurse into subdirectories */ + if (VCWD_STAT(buf, &sbuf) != 0) { + continue; + } + if (S_ISDIR(sbuf.st_mode)) { + zend_string *subdir = zend_string_init(buf, ZSTR_LEN(dirname) + 1 + entry_len, 0); + int n = ps_files_cleanup_dir(subdir, maxlifetime, remaining_depth - 1); + zend_string_release(subdir); + if (n >= 0) { + nrdels += n; } } } } closedir(dir); - - return (nrdels); + return nrdels; } static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) @@ -346,10 +365,8 @@ static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) return SUCCESS; } - #define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA() - /* * Open save handler. Setup resources that are needed by the handler. * PARAMETERS: PS_OPEN_ARGS in php_session.h @@ -427,7 +444,6 @@ PS_OPEN_FUNC(files) return SUCCESS; } - /* * Clean up opened resources. * PARAMETERS: PS_CLOSE_ARGS in php_session.h @@ -456,7 +472,6 @@ PS_CLOSE_FUNC(files) return SUCCESS; } - /* * Read session data from opened resource. * PARAMETERS: PS_READ_ARGS in php_session.h @@ -508,7 +523,7 @@ PS_READ_FUNC(files) buf = read_in > -1 ? buf + read_in : 0; to_read = read_in > -1 ? SESS_FILE_BUF_SIZE(ZSTR_LEN(*val) - n) : 0; - } while(read_in > 0); + } while (read_in > 0); } #else @@ -531,7 +546,6 @@ PS_READ_FUNC(files) return SUCCESS; } - /* * Write session data. * PARAMETERS: PS_WRITE_ARGS in php_session.h @@ -547,7 +561,6 @@ PS_WRITE_FUNC(files) return ps_files_write(data, key, val); } - /* * Update session data modification/access time stamp. * PARAMETERS: PS_UPDATE_TIMESTAMP_ARGS in php_session.h @@ -582,7 +595,6 @@ PS_UPDATE_TIMESTAMP_FUNC(files) return SUCCESS; } - /* * Delete session data. * PARAMETERS: PS_DESTROY_ARGS in php_session.h @@ -617,7 +629,6 @@ PS_DESTROY_FUNC(files) return SUCCESS; } - /* * Cleanup expired session data. * PARAMETERS: PS_GC_ARGS in php_session.h @@ -633,20 +644,11 @@ PS_GC_FUNC(files) { PS_FILES_DATA; - /* We don't perform any cleanup, if dirdepth is larger than 0. - we return SUCCESS, since all cleanup should be handled by - an external entity (i.e. find -ctime x | xargs rm) */ - - if (data->dirdepth == 0) { - *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime); - } else { - *nrdels = -1; // Cannot process multiple depth save dir - } + *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime, data->dirdepth); return *nrdels; } - /* * Create session ID. * PARAMETERS: PS_CREATE_SID_ARGS in php_session.h @@ -684,12 +686,11 @@ PS_CREATE_SID_FUNC(files) return NULL; } } - } while(!sid); + } while (!sid); return sid; } - /* * Check session ID existence for use_strict_mode support. * PARAMETERS: PS_VALIDATE_SID_ARGS in php_session.h diff --git a/ext/session/mod_files.h b/ext/session/mod_files.h index 31ed4afbffcc..9eae00fb9c7a 100644 --- a/ext/session/mod_files.h +++ b/ext/session/mod_files.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index d6312c5fa1f3..70000f5ca848 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -40,11 +38,11 @@ typedef struct ps_sd { struct ps_sd *next; - uint32_t hv; /* hash value of key */ - time_t ctime; /* time of last change */ + uint32_t hv; /* hash value of key */ + time_t ctime; /* time of last change */ void *data; - size_t datalen; /* amount of valid data */ - size_t alloclen; /* amount of allocated memory for data */ + size_t datalen; /* amount of valid data */ + size_t alloclen; /* amount of allocated memory for data */ zend_string *key; } ps_sd; @@ -464,7 +462,7 @@ PS_CREATE_SID_FUNC(mm) return NULL; } } - } while(!sid); + } while (!sid); return sid; } @@ -483,7 +481,7 @@ PS_VALIDATE_SID_FUNC(mm) PS_MM_DATA; mm_lock(data->mm, MM_LOCK_RD); - zend_result ret = ps_mm_key_exists(data, key) + zend_result ret = ps_mm_key_exists(data, key); mm_unlock(data->mm); return ret; } diff --git a/ext/session/mod_mm.h b/ext/session/mod_mm.h index b35e0b632ee9..990eab09147c 100644 --- a/ext/session/mod_mm.h +++ b/ext/session/mod_mm.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 90b91926a62c..71b8abdea8b0 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -22,7 +20,6 @@ const ps_module ps_mod_user = { PS_MOD_UPDATE_TIMESTAMP(user) }; - static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) { int i; @@ -30,16 +27,16 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) PS(in_save_handler) = false; ZVAL_UNDEF(retval); php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner"); - return; - } - PS(in_save_handler) = true; - if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) { - zval_ptr_dtor(retval); - ZVAL_UNDEF(retval); - } else if (Z_ISUNDEF_P(retval)) { - ZVAL_NULL(retval); + } else { + PS(in_save_handler) = true; + if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) { + zval_ptr_dtor(retval); + ZVAL_UNDEF(retval); + } else if (Z_ISUNDEF_P(retval)) { + ZVAL_NULL(retval); + } + PS(in_save_handler) = false; } - PS(in_save_handler) = false; for (i = 0; i < argc; i++) { zval_ptr_dtor(&argv[i]); } @@ -47,7 +44,7 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) #define PSF(a) PS(mod_user_names).ps_##a -static zend_result verify_bool_return_type_userland_calls(const zval* value) +static zend_result verify_bool_return_type_userland_calls(const zval *value) { /* Exit or exception in userland call */ if (Z_TYPE_P(value) == IS_UNDEF) { @@ -75,8 +72,8 @@ static zend_result verify_bool_return_type_userland_calls(const zval* value) } if (!EG(exception)) { zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value)); \ - } - return FAILURE; + } + return FAILURE; } PS_OPEN_FUNC(user) @@ -217,6 +214,7 @@ PS_GC_FUNC(user) /* Anything else is some kind of error */ *nrdels = -1; // Error } + zval_ptr_dtor(&retval); return *nrdels; } diff --git a/ext/session/mod_user.h b/ext/session/mod_user.h index 58772b48ec82..9c36c315819a 100644 --- a/ext/session/mod_user.h +++ b/ext/session/mod_user.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index eb5a47b19cee..a6bd69c91a07 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Arpad Ray | +----------------------------------------------------------------------+ @@ -17,7 +15,7 @@ #include "php.h" #include "php_session.h" -#define PS_SANITY_CHECK \ +#define PS_SANITY_CHECK \ if (PS(session_status) != php_session_active) { \ zend_throw_error(NULL, "Session is not active"); \ RETURN_THROWS(); \ @@ -27,11 +25,11 @@ RETURN_THROWS(); \ } -#define PS_SANITY_CHECK_IS_OPEN \ +#define PS_SANITY_CHECK_IS_OPEN \ PS_SANITY_CHECK; \ - if (!PS(mod_user_is_open)) { \ - php_error_docref(NULL, E_WARNING, "Parent session handler is not open"); \ - RETURN_FALSE; \ + if (!PS(mod_user_is_open)) { \ + php_error_docref(NULL, E_WARNING, "Parent session handler is not open"); \ + RETURN_FALSE; \ } PHP_METHOD(SessionHandler, open) diff --git a/ext/session/php_session.h b/ext/session/php_session.h index b7ed88a8f6c7..2a1d782fd727 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -52,15 +50,15 @@ typedef struct ps_module_struct { #define PS_GET_MOD_DATA() *mod_data #define PS_SET_MOD_DATA(a) *mod_data = (a) -#define PS_OPEN_FUNC(x) zend_result ps_open_##x(PS_OPEN_ARGS) -#define PS_CLOSE_FUNC(x) zend_result ps_close_##x(PS_CLOSE_ARGS) -#define PS_READ_FUNC(x) zend_result ps_read_##x(PS_READ_ARGS) -#define PS_WRITE_FUNC(x) zend_result ps_write_##x(PS_WRITE_ARGS) -#define PS_DESTROY_FUNC(x) zend_result ps_delete_##x(PS_DESTROY_ARGS) -#define PS_GC_FUNC(x) zend_long ps_gc_##x(PS_GC_ARGS) -#define PS_CREATE_SID_FUNC(x) zend_string *ps_create_sid_##x(PS_CREATE_SID_ARGS) -#define PS_VALIDATE_SID_FUNC(x) zend_result ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) -#define PS_UPDATE_TIMESTAMP_FUNC(x) zend_result ps_update_timestamp_##x(PS_UPDATE_TIMESTAMP_ARGS) +#define PS_OPEN_FUNC(x) zend_result ps_open_##x(PS_OPEN_ARGS) +#define PS_CLOSE_FUNC(x) zend_result ps_close_##x(PS_CLOSE_ARGS) +#define PS_READ_FUNC(x) zend_result ps_read_##x(PS_READ_ARGS) +#define PS_WRITE_FUNC(x) zend_result ps_write_##x(PS_WRITE_ARGS) +#define PS_DESTROY_FUNC(x) zend_result ps_delete_##x(PS_DESTROY_ARGS) +#define PS_GC_FUNC(x) zend_long ps_gc_##x(PS_GC_ARGS) +#define PS_CREATE_SID_FUNC(x) zend_string *ps_create_sid_##x(PS_CREATE_SID_ARGS) +#define PS_VALIDATE_SID_FUNC(x) zend_result ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) +#define PS_UPDATE_TIMESTAMP_FUNC(x) zend_result ps_update_timestamp_##x(PS_UPDATE_TIMESTAMP_ARGS) /* Save handler module definitions without timestamp enabled */ #define PS_FUNCS(x) \ @@ -69,7 +67,7 @@ typedef struct ps_module_struct { PS_READ_FUNC(x); \ PS_WRITE_FUNC(x); \ PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ + PS_GC_FUNC(x); \ PS_CREATE_SID_FUNC(x); \ PS_VALIDATE_SID_FUNC(x); @@ -95,7 +93,6 @@ typedef struct ps_module_struct { ps_delete_##x, ps_gc_##x, ps_create_sid_##x, \ ps_validate_sid_##x, ps_update_timestamp_##x - typedef enum { php_session_disabled, php_session_none, @@ -115,8 +112,8 @@ typedef struct _php_session_rfc1867_progress { zval data; /* the array exported to session data */ zval files; /* data["files"] array */ - zval *post_bytes_processed; /* data["bytes_processed"] */ - zval *current_file_bytes_processed; + zval *post_bytes_processed; /* data["bytes_processed"] */ + zval *current_file_bytes_processed; zval current_file; /* array of currently uploading file */ } php_session_rfc1867_progress; @@ -186,6 +183,7 @@ typedef struct _php_ps_globals { bool mod_user_is_open; bool mod_user_uses_object_methods_as_handlers; bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + bool random_seeded; } php_ps_globals; typedef php_ps_globals zend_ps_globals; @@ -256,23 +254,23 @@ PHPAPI zend_result php_session_reset_id(void); /* Do not use a return statement in `code` because that may leak memory. * Break out of the loop instead. */ -#define PS_ENCODE_LOOP(code) do { \ - zval _zv; \ - /* protect against user interference */ \ - ZVAL_COPY(&_zv, Z_REFVAL(PS(http_session_vars))); \ +#define PS_ENCODE_LOOP(code) do { \ + zval _zv; \ + /* protect against user interference */ \ + ZVAL_COPY(&_zv, Z_REFVAL(PS(http_session_vars))); \ ZEND_HASH_FOREACH_KEY(Z_ARRVAL(_zv), zend_ulong num_key, zend_string * key) { \ - if (key == NULL) { \ - php_error_docref(NULL, E_WARNING, \ - "Skipping numeric key " ZEND_LONG_FMT, num_key);\ - continue; \ - } \ - zval *struc = php_get_session_var(key); \ - if (struc) { \ - code; \ - } \ - } ZEND_HASH_FOREACH_END(); \ - zval_ptr_dtor(&_zv); \ -} while(0) + if (key == NULL) { \ + php_error_docref(NULL, E_WARNING, \ + "Skipping numeric key " ZEND_LONG_FMT, num_key); \ + continue; \ + } \ + zval *struc = php_get_session_var(key); \ + if (struc) { \ + code; \ + } \ + } ZEND_HASH_FOREACH_END(); \ + zval_ptr_dtor(&_zv); \ +} while (0) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(ps) diff --git a/ext/session/session.c b/ext/session/session.c index e790fa074d60..dd968d453bda 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sascha Schumann | | Andrei Zmievski | @@ -76,6 +74,7 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define PS_MAX_SID_LENGTH 256 + /* *********** * Helpers * *********** */ @@ -83,16 +82,16 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define IF_SESSION_VARS() \ if (Z_ISREF_P(&PS(http_session_vars)) && Z_TYPE_P(Z_REFVAL(PS(http_session_vars))) == IS_ARRAY) -#define SESSION_CHECK_ACTIVE_STATE \ - if (PS(session_status) == php_session_active) { \ - php_session_session_already_started_error(E_WARNING, "Session ini settings cannot be changed when a session is active"); \ - return FAILURE; \ +#define SESSION_CHECK_ACTIVE_STATE \ + if (PS(session_status) == php_session_active) { \ + php_session_session_already_started_error(E_WARNING, "Session ini settings cannot be changed when a session is active"); \ + return FAILURE; \ } -#define SESSION_CHECK_OUTPUT_STATE \ - if (SG(headers_sent) && stage != ZEND_INI_STAGE_DEACTIVATE) { \ - php_session_headers_already_sent_error(E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \ - return FAILURE; \ +#define SESSION_CHECK_OUTPUT_STATE \ + if (SG(headers_sent) && stage != ZEND_INI_STAGE_DEACTIVATE) { \ + php_session_headers_already_sent_error(E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \ + return FAILURE; \ } #define SESSION_FORBIDDEN_CHARS "=,;.[ \t\r\n\013\014" @@ -220,7 +219,7 @@ PHPAPI void php_add_session_var(zend_string *name) } } -PHPAPI zval* php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash) +PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash) { IF_SESSION_VARS() { zval *sess_var = Z_REFVAL(PS(http_session_vars)); @@ -230,7 +229,7 @@ PHPAPI zval* php_set_session_var(zend_string *name, zval *state_val, php_unseria return NULL; } -PHPAPI zval* php_get_session_var(zend_string *name) +PHPAPI zval *php_get_session_var(zend_string *name) { IF_SESSION_VARS() { return zend_hash_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name); @@ -238,7 +237,7 @@ PHPAPI zval* php_get_session_var(zend_string *name) return NULL; } -PHPAPI zval* php_get_session_var_str(const char *name, size_t name_len) +PHPAPI zval *php_get_session_var_str(const char *name, size_t name_len) { IF_SESSION_VARS() { return zend_hash_str_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name, name_len); @@ -267,7 +266,7 @@ static void php_session_track_init(void) static zend_string *php_session_encode(void) { IF_SESSION_VARS() { - ZEND_ASSERT(PS(serializer)); + ZEND_ASSERT(PS(serializer)); return PS(serializer)->encode(); } else { php_error_docref(NULL, E_WARNING, "Cannot encode non-existent session"); @@ -284,7 +283,7 @@ static ZEND_COLD void php_session_cancel_decode(void) static zend_result php_session_decode(const zend_string *data) { - ZEND_ASSERT(PS(serializer)); + ZEND_ASSERT(PS(serializer)); zend_result result = SUCCESS; zend_try { if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) { @@ -386,7 +385,6 @@ PHPAPI zend_result php_session_valid_key(const char *key) return SUCCESS; } - static zend_long php_session_gc(bool immediate) { zend_long sessions_deleted = -1; @@ -396,6 +394,18 @@ static zend_long php_session_gc(bool immediate) if ((PS(mod_data) || PS(mod_user_implemented))) { /* Use probability-based GC if not forced and probability is configured */ if (!collect && PS(gc_probability) > 0) { + /* Seed lazily on first GC draw per process. */ + if (UNEXPECTED(!PS(random_seeded))) { + php_random_uint128_t seed; + if (php_random_bytes_silent(&seed, sizeof(seed)) == FAILURE) { + seed = php_random_uint128_constant( + php_random_generate_fallback_seed(), + php_random_generate_fallback_seed() + ); + } + php_random_pcgoneseq128xslrr64_seed128(PS(random).state, seed); + PS(random_seeded) = true; + } collect = php_random_range(PS(random), 0, PS(gc_divisor) - 1) < PS(gc_probability); } @@ -448,9 +458,7 @@ static zend_result php_session_initialize(void) } else if (PS(use_strict_mode) && PS(mod)->s_validate_sid && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == FAILURE ) { - if (PS(id)) { - zend_string_release_ex(PS(id), false); - } + zend_string_release_ex(PS(id), false); PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { PS(id) = php_session_create_id(NULL); @@ -564,25 +572,26 @@ static void php_session_normalize_vars(void) } } + /* ************************* * INI Settings/Handlers * ************************* */ static PHP_INI_MH(OnUpdateSaveHandler) { - const ps_module *tmp; + const ps_module *new_module; int err_type = E_ERROR; SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - tmp = _php_find_ps_module(ZSTR_VAL(new_value)); + new_module = _php_find_ps_module(ZSTR_VAL(new_value)); if (stage == ZEND_INI_STAGE_RUNTIME) { err_type = E_WARNING; } - if (PG(modules_activated) && !tmp) { + if (PG(modules_activated) && !new_module) { /* Do not output error when restoring ini options. */ if (stage != ZEND_INI_STAGE_DEACTIVATE) { php_error_docref(NULL, err_type, "Session save handler \"%s\" cannot be found", ZSTR_VAL(new_value)); @@ -592,27 +601,27 @@ static PHP_INI_MH(OnUpdateSaveHandler) } /* "user" save handler should not be set by user */ - if (!PS(set_handler) && tmp == ps_user_ptr) { + if (!PS(set_handler) && new_module == ps_user_ptr) { php_error_docref(NULL, err_type, "Session save handler \"user\" cannot be set by ini_set()"); return FAILURE; } PS(default_mod) = PS(mod); - PS(mod) = tmp; + PS(mod) = new_module; return SUCCESS; } static PHP_INI_MH(OnUpdateSerializer) { - const ps_serializer *tmp; + const ps_serializer *new_serializer; SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - tmp = _php_find_ps_serializer(ZSTR_VAL(new_value)); + new_serializer = _php_find_ps_serializer(ZSTR_VAL(new_value)); - if (PG(modules_activated) && !tmp) { + if (PG(modules_activated) && !new_serializer) { int err_type; if (stage == ZEND_INI_STAGE_RUNTIME) { @@ -627,7 +636,8 @@ static PHP_INI_MH(OnUpdateSerializer) } return FAILURE; } - PS(serializer) = tmp; + + PS(serializer) = new_serializer; return SUCCESS; } @@ -637,12 +647,15 @@ static PHP_INI_MH(OnUpdateSaveDir) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - /* Only do the open_basedir check at runtime */ - if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { - if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) != NULL) { - return FAILURE; + if (zend_str_has_nul_byte(new_value)) { + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + php_error_docref(NULL, E_WARNING, "\"%s\" must not contain null bytes", ZSTR_VAL(entry->name)); } + return FAILURE; + } + /* Only do the open_basedir check at runtime */ + if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { /* we do not use zend_memrchr() since path can contain ; itself */ const char *p = strchr(ZSTR_VAL(new_value), ';'); if (p) { @@ -664,7 +677,6 @@ static PHP_INI_MH(OnUpdateSaveDir) return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateName) { SESSION_CHECK_ACTIVE_STATE; @@ -695,7 +707,6 @@ static PHP_INI_MH(OnUpdateName) return OnUpdateStrNotEmpty(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateCookieLifetime) { SESSION_CHECK_ACTIVE_STATE; @@ -706,21 +717,30 @@ static PHP_INI_MH(OnUpdateCookieLifetime) #else const zend_long maxcookie = ZEND_LONG_MAX / 2 - 1; #endif - zend_long v = (zend_long)atol(ZSTR_VAL(new_value)); - if (v < 0) { - php_error_docref(NULL, E_WARNING, "CookieLifetime cannot be negative"); + zend_long lval = 0; + int oflow = 0; + uint8_t type = is_numeric_string_ex(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &lval, NULL, false, &oflow, NULL); + if (UNEXPECTED(type != IS_LONG)) { + if (oflow != 0) { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be between 0 and " ZEND_LONG_FMT, maxcookie); + } else { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be of type int"); + } return FAILURE; - } else if (v > maxcookie) { - return SUCCESS; } + if (lval < 0 || lval > maxcookie) { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be between 0 and " ZEND_LONG_FMT, maxcookie); + return FAILURE; + } + return OnUpdateLongGEZero(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateSessionLong) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + return OnUpdateLong(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } @@ -728,18 +748,39 @@ static PHP_INI_MH(OnUpdateSessionStr) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + + if (new_value && zend_str_has_nul_byte(new_value)) { + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + php_error_docref(NULL, E_WARNING, "\"%s\" must not contain null bytes", ZSTR_VAL(entry->name)); + } + return FAILURE; + } + return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +static PHP_INI_MH(OnUpdateSessionSameSite) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + if (new_value && ZSTR_LEN(new_value) > 0 && !php_is_valid_samesite_value(new_value)) { + php_error_docref(NULL, E_WARNING, + "session.cookie_samesite must be \"Strict\", \"Lax\", \"None\", or \"\""); + return FAILURE; + } + + return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} static PHP_INI_MH(OnUpdateSessionBool) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateSidLength) { zend_long val; @@ -747,19 +788,21 @@ static PHP_INI_MH(OnUpdateSidLength) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + val = ZEND_STRTOL(ZSTR_VAL(new_value), &endptr, 10); + if (val != 32) { php_error_docref("session.configuration", E_DEPRECATED, "session.sid_length INI setting is deprecated"); } - if (endptr && (*endptr == '\0') - && val >= 22 && val <= PS_MAX_SID_LENGTH) { - /* Numeric value */ - PS(sid_length) = val; - return SUCCESS; + + if (!endptr || (*endptr != '\0') || (val < 22) || (val > PS_MAX_SID_LENGTH)) { + php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_length\" must be between 22 and 256"); + return FAILURE; } - php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_length\" must be between 22 and 256"); - return FAILURE; + PS(sid_length) = val; + + return SUCCESS; } static PHP_INI_MH(OnUpdateSidBits) @@ -769,73 +812,78 @@ static PHP_INI_MH(OnUpdateSidBits) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + val = ZEND_STRTOL(ZSTR_VAL(new_value), &endptr, 10); + if (val != 4) { php_error_docref("session.configuration", E_DEPRECATED, "session.sid_bits_per_character INI setting is deprecated"); } - if (endptr && (*endptr == '\0') - && val >= 4 && val <=6) { - /* Numeric value */ - PS(sid_bits_per_character) = val; - return SUCCESS; + + if (!endptr || (*endptr != '\0') || (val < 4) || (val > 6)) { + php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_bits_per_character\" must be between 4 and 6"); + return FAILURE; } - php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_bits_per_character\" must be between 4 and 6"); - return FAILURE; + PS(sid_bits_per_character) = val; + + return SUCCESS; } static PHP_INI_MH(OnUpdateSessionGcProbability) { - SESSION_CHECK_ACTIVE_STATE; - SESSION_CHECK_OUTPUT_STATE; + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; - zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + zend_long new_probability = zend_ini_parse_quantity_warn(new_value, entry->name); - if (tmp < 0) { - php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); - return FAILURE; - } + if (new_probability < 0) { + php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); + return FAILURE; + } - zend_long *p = ZEND_INI_GET_ADDR(); - *p = tmp; + zend_long *p = ZEND_INI_GET_ADDR(); + *p = new_probability; - return SUCCESS; + return SUCCESS; } static PHP_INI_MH(OnUpdateSessionDivisor) { - SESSION_CHECK_ACTIVE_STATE; - SESSION_CHECK_OUTPUT_STATE; + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; - zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + zend_long new_divisor = zend_ini_parse_quantity_warn(new_value, entry->name); - if (tmp <= 0) { - php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); - return FAILURE; - } + if (new_divisor <= 0) { + php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); + return FAILURE; + } - zend_long *p = ZEND_INI_GET_ADDR(); - *p = tmp; + zend_long *p = ZEND_INI_GET_ADDR(); + *p = new_divisor; - return SUCCESS; + return SUCCESS; } static PHP_INI_MH(OnUpdateRfc1867Freq) { - int tmp = ZEND_ATOL(ZSTR_VAL(new_value)); - if(tmp < 0) { + int new_freq = ZEND_ATOL(ZSTR_VAL(new_value)); + + if (new_freq < 0) { php_error_docref(NULL, E_WARNING, "session.upload_progress.freq must be greater than or equal to 0"); return FAILURE; } - if(ZSTR_LEN(new_value) > 0 && ZSTR_VAL(new_value)[ZSTR_LEN(new_value)-1] == '%') { - if(tmp > 100) { + + if (ZSTR_LEN(new_value) > 0 && ZSTR_VAL(new_value)[ZSTR_LEN(new_value) - 1] == '%') { + if (new_freq > 100) { php_error_docref(NULL, E_WARNING, "session.upload_progress.freq must be less than or equal to 100%%"); return FAILURE; } - PS(rfc1867_freq) = -tmp; + PS(rfc1867_freq) = -new_freq; } else { - PS(rfc1867_freq) = tmp; + PS(rfc1867_freq) = new_freq; } + return SUCCESS; } @@ -843,11 +891,14 @@ static PHP_INI_MH(OnUpdateUseOnlyCookies) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); + if (!*p) { php_error_docref("session.configuration", E_DEPRECATED, "Disabling session.use_only_cookies INI setting is deprecated"); } + return SUCCESS; } @@ -855,11 +906,14 @@ static PHP_INI_MH(OnUpdateUseTransSid) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); + if (*p) { php_error_docref("session.configuration", E_DEPRECATED, "Enabling session.use_trans_sid INI setting is deprecated"); } + return SUCCESS; } @@ -867,9 +921,18 @@ static PHP_INI_MH(OnUpdateRefererCheck) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + + if (zend_str_has_nul_byte(new_value)) { + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + php_error_docref(NULL, E_WARNING, "\"%s\" must not contain null bytes", ZSTR_VAL(entry->name)); + } + return FAILURE; + } + if (ZSTR_LEN(new_value) != 0) { php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.referer_check INI setting is deprecated"); } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } @@ -887,11 +950,11 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("session.cookie_domain", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_domain, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.cookie_secure", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_secure, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.cookie_partitioned", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_partitioned, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_samesite, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_httponly", "1", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_samesite", "Lax", PHP_INI_ALL, OnUpdateSessionSameSite, cookie_samesite, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionStr, cache_limiter, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) @@ -917,9 +980,11 @@ PHP_INI_BEGIN() /* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */ PHP_INI_END() + /* *************** * Serializers * *************** */ + PS_SERIALIZER_ENCODE_FUNC(php_serialize) { smart_str buf = {0}; @@ -1130,6 +1195,7 @@ PHPAPI zend_result php_session_register_serializer(const char *name, zend_string return ret; } + /* ******************* * Storage Modules * ******************* */ @@ -1311,6 +1377,7 @@ static int php_session_cache_limiter(void) return -1; } + /* ********************* * Cookie Management * ********************* */ @@ -1408,8 +1475,8 @@ static zend_result php_session_send_cookie(void) smart_str_0(&ncookie); php_session_remove_cookie(); /* remove already sent session ID cookie */ - /* 'replace' must be 0 here, else a previous Set-Cookie - header, probably sent with setcookie() will be replaced! */ + /* 'replace' must be 0 here, else a previous Set-Cookie + header, probably sent with setcookie() will be replaced! */ sapi_add_header_ex(estrndup(ZSTR_VAL(ncookie.s), ZSTR_LEN(ncookie.s)), ZSTR_LEN(ncookie.s), false, false); smart_str_free(&ncookie); @@ -1548,7 +1615,6 @@ static void proposed_session_id_to_session_id(const zval *proposed_session_id) { } } - PHPAPI zend_result php_session_reset_id(void) { int module_number = PS(module_number); @@ -1627,17 +1693,15 @@ PHPAPI zend_result php_session_reset_id(void) return SUCCESS; } - PHPAPI zend_result php_session_start(void) { switch (PS(session_status)) { case php_session_active: php_session_session_already_started_error(E_NOTICE, "Ignoring session_start() because a session has already been started"); return FAILURE; - break; case php_session_disabled: { - const char *value = zend_ini_string(ZEND_STRL("session.save_handler"), false); + const char *value = zend_ini_string_literal("session.save_handler"); if (!PS(mod) && value) { PS(mod) = _php_find_ps_module(value); if (!PS(mod)) { @@ -1645,7 +1709,7 @@ PHPAPI zend_result php_session_start(void) return FAILURE; } } - value = zend_ini_string(ZEND_STRL("session.serialize_handler"), false); + value = zend_ini_string_literal("session.serialize_handler"); if (!PS(serializer) && value) { PS(serializer) = _php_find_ps_serializer(value); if (!PS(serializer)) { @@ -1738,6 +1802,7 @@ static bool php_session_reset(void) return PS(session_status) == php_session_active && php_session_initialize() == SUCCESS; } + /* ******************************** * Userspace exported functions * ******************************** */ @@ -2399,10 +2464,10 @@ PHP_FUNCTION(session_create_id) } if (prefix && ZSTR_LEN(prefix)) { - if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { - zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); - RETURN_THROWS(); - } + if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { + zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); + RETURN_THROWS(); + } if (php_session_valid_key(ZSTR_VAL(prefix)) == FAILURE) { /* E_ERROR raised for security reason. */ php_error_docref(NULL, E_WARNING, "Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, \"-\", and \",\" characters are allowed"); @@ -2577,7 +2642,7 @@ PHP_FUNCTION(session_start) zend_argument_value_error(1, "must be of type array with keys as string"); RETURN_THROWS(); } - switch(Z_TYPE_P(value)) { + switch (Z_TYPE_P(value)) { case IS_STRING: case IS_TRUE: case IS_FALSE: @@ -2676,7 +2741,6 @@ PHP_FUNCTION(session_gc) RETURN_LONG(num); } - PHP_FUNCTION(session_write_close) { ZEND_PARSE_PARAMETERS_NONE(); @@ -2740,6 +2804,7 @@ PHP_FUNCTION(session_register_shutdown) } } + /* ******************************** * Module Setup and Destruction * ******************************** */ @@ -2750,14 +2815,14 @@ static zend_result php_rinit_session(bool auto_start) PS(mod) = NULL; { - const char *value = zend_ini_string(ZEND_STRL("session.save_handler"), false); + const char *value = zend_ini_string_literal("session.save_handler"); if (value) { PS(mod) = _php_find_ps_module(value); } } if (PS(serializer) == NULL) { - const char *value = zend_ini_string(ZEND_STRL("session.serialize_handler"), false); + const char *value = zend_ini_string_literal("session.serialize_handler"); if (value) { PS(serializer) = _php_find_ps_serializer(value); } @@ -2787,7 +2852,6 @@ static PHP_RINIT_FUNCTION(session) ZVAL_UNDEF(&PS(mod_user_names).struct_name); \ } - static PHP_RSHUTDOWN_FUNCTION(session) { if (PS(session_status) == php_session_active) { @@ -2849,14 +2913,7 @@ static PHP_GINIT_FUNCTION(ps) .algo = &php_random_algo_pcgoneseq128xslrr64, .state = &ps_globals->random_state, }; - php_random_uint128_t seed; - if (php_random_bytes_silent(&seed, sizeof(seed)) == FAILURE) { - seed = php_random_uint128_constant( - php_random_generate_fallback_seed(), - php_random_generate_fallback_seed() - ); - } - php_random_pcgoneseq128xslrr64_seed128(ps_globals->random.state, seed); + ps_globals->random_seeded = false; } static PHP_MINIT_FUNCTION(session) @@ -2958,6 +3015,7 @@ static PHP_MINFO_FUNCTION(session) DISPLAY_INI_ENTRIES(); } + /* ************************ * Upload hook handling * ************************ */ @@ -3071,7 +3129,7 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ progress = PS(rfc1867_progress); - switch(event) { + switch (event) { case MULTIPART_EVENT_START: { const multipart_event_start *data = event_data; progress = ecalloc(1, sizeof(php_session_rfc1867_progress)); diff --git a/ext/session/tests/bug74892.phpt b/ext/session/tests/bug74892.phpt index 916120cb4d44..7a2211210b45 100644 --- a/ext/session/tests/bug74892.phpt +++ b/ext/session/tests/bug74892.phpt @@ -4,6 +4,7 @@ Bug #74892 Url Rewriting (trans_sid) not working on urls that start with # session.use_cookies=0 session.use_only_cookies=0 session.use_trans_sid=1 +session.use_strict_mode=0 --EXTENSIONS-- session --SKIPIF-- diff --git a/ext/session/tests/bug80774.phpt b/ext/session/tests/bug80774.phpt index 7dd86add02b0..1e98da74e9d6 100644 --- a/ext/session/tests/bug80774.phpt +++ b/ext/session/tests/bug80774.phpt @@ -2,6 +2,10 @@ Bug #80774 (session_name() problem with backslash) --EXTENSIONS-- session +--INI-- +session.use_strict_mode=0 +session.cookie_samesite=Lax +session.cookie_httponly=1 --FILE-- --EXPECTHEADERS-- -Set-Cookie: foo\bar=12345; path=/ +Set-Cookie: foo\bar=12345; path=/; HttpOnly; SameSite=Lax --EXPECT-- diff --git a/ext/session/tests/gh16290.phpt b/ext/session/tests/gh16290.phpt index d341eb47471b..df57b129649d 100644 --- a/ext/session/tests/gh16290.phpt +++ b/ext/session/tests/gh16290.phpt @@ -6,8 +6,11 @@ session --FILE-- ---EXPECT-- +--EXPECTF-- +Warning: session_set_cookie_params(): session.cookie_lifetime must be between 0 and %d in %s on line %d DONE diff --git a/ext/session/tests/gh9200.phpt b/ext/session/tests/gh9200.phpt index fd6e28ab8b90..cb97f2707a19 100644 --- a/ext/session/tests/gh9200.phpt +++ b/ext/session/tests/gh9200.phpt @@ -2,6 +2,9 @@ GH-9200: setcookie has an obsolete expires date format --INI-- session.cookie_lifetime=3600 +session.use_strict_mode=0 +session.cookie_samesite=Lax +session.cookie_httponly=1 --EXTENSIONS-- session --CGI-- @@ -12,7 +15,7 @@ session_id('bar'); session_start(); foreach (headers_list() as $header) { - if (preg_match('/^Set-Cookie: foo=bar; expires=(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2[0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT; Max-Age=3600; path=\\/$/', $header)) { + if (preg_match('/^Set-Cookie: foo=bar; expires=(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2[0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT; Max-Age=3600; path=\/; HttpOnly; SameSite=Lax$/', $header)) { echo "Success", PHP_EOL; exit; } diff --git a/ext/session/tests/mod_files/gc_dirdepth2.phpt b/ext/session/tests/mod_files/gc_dirdepth2.phpt new file mode 100644 index 000000000000..d858c1f95db8 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth2.phpt @@ -0,0 +1,46 @@ +--TEST-- +session GC cleans expired sessions with save_path dirdepth=2 (two subdir levels) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(1) +expired file removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt b/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt new file mode 100644 index 000000000000..dc3d4720dd23 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt @@ -0,0 +1,69 @@ +--TEST-- +session GC correctly cleans expired sessions when save_path dirdepth > 0 +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=1 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +dirdepth=1 — session_gc() return value: int(1) +dirdepth=1 — expired session file removed: bool(true) +dirdepth=0 — session_gc() return value: int(1) +dirdepth=0 — expired session file removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt b/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt new file mode 100644 index 000000000000..c5e916c86fd2 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt @@ -0,0 +1,55 @@ +--TEST-- +session GC accumulates correct total count across multiple subdirs, including empty ones (dirdepth=1) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(3) +all expired files removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_selective.phpt b/ext/session/tests/mod_files/gc_dirdepth_selective.phpt new file mode 100644 index 000000000000..1f0785d66fed --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_selective.phpt @@ -0,0 +1,58 @@ +--TEST-- +session GC deletes only expired sess_* files and leaves all other files untouched (dirdepth=1) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + gc_maxlifetime=10 → deleted + +file_put_contents($fresh, 'user|s:5:"alice";'); +touch($fresh, time() - 1); // 1 s old < gc_maxlifetime=10 → kept + +file_put_contents($other, 'untouched'); +touch($other, time() - 100); // old but no sess_ prefix → kept + +session_id('a0000000000000000000000000'); // first char 'a' → $base/a/ +session_start(); +$result = session_gc(); // int(1): exactly one deletion proves selectivity +session_destroy(); + +echo "session_gc() return value: "; +var_dump($result); + +echo "expired sess_ file removed: "; +var_dump(!file_exists($expired)); + +echo "other file kept: "; +var_dump(file_exists($other)); +?> +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(1) +expired sess_ file removed: bool(true) +other file kept: bool(true) diff --git a/ext/session/tests/session_cookie_lifetime_invalid.phpt b/ext/session/tests/session_cookie_lifetime_invalid.phpt new file mode 100644 index 000000000000..8665a53447b9 --- /dev/null +++ b/ext/session/tests/session_cookie_lifetime_invalid.phpt @@ -0,0 +1,55 @@ +--TEST-- +session.cookie_lifetime rejects invalid values +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: ini_set(): session.cookie_lifetime must be of type int in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be of type int in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" +string(3) "200" diff --git a/ext/session/tests/session_get_cookie_params_basic.phpt b/ext/session/tests/session_get_cookie_params_basic.phpt index 1c7cdf189fc9..8e7f8da4e3fb 100644 --- a/ext/session/tests/session_get_cookie_params_basic.phpt +++ b/ext/session/tests/session_get_cookie_params_basic.phpt @@ -22,7 +22,7 @@ echo "*** Testing session_get_cookie_params() : basic functionality ***\n"; var_dump(session_get_cookie_params()); var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE)); var_dump(session_get_cookie_params()); -var_dump(session_set_cookie_params(1234567890, "/guff", "foo", TRUE, TRUE)); +var_dump(session_set_cookie_params(1000000000, "/guff", "foo", TRUE, TRUE)); var_dump(session_get_cookie_params()); var_dump(session_set_cookie_params([ "lifetime" => 123, @@ -30,7 +30,7 @@ var_dump(session_set_cookie_params([ "domain" => "baz", "secure" => FALSE, "httponly" => FALSE, - "samesite" => "please"])); + "samesite" => "Strict"])); var_dump(session_get_cookie_params()); var_dump(session_set_cookie_params([ "secure" => TRUE, @@ -40,7 +40,7 @@ var_dump(session_get_cookie_params()); echo "Done"; ob_end_flush(); ?> ---EXPECTF-- +--EXPECT-- *** Testing session_get_cookie_params() : basic functionality *** array(7) { ["lifetime"]=> @@ -78,7 +78,7 @@ array(7) { bool(true) array(7) { ["lifetime"]=> - int(%d) + int(1000000000) ["path"]=> string(5) "/guff" ["domain"]=> @@ -107,7 +107,7 @@ array(7) { ["httponly"]=> bool(false) ["samesite"]=> - string(6) "please" + string(6) "Strict" } bool(true) array(7) { @@ -124,6 +124,6 @@ array(7) { ["httponly"]=> bool(false) ["samesite"]=> - string(6) "please" + string(6) "Strict" } Done diff --git a/ext/session/tests/session_get_cookie_params_variation1.phpt b/ext/session/tests/session_get_cookie_params_variation1.phpt index 7ce112c9b94d..0ab0f233530b 100644 --- a/ext/session/tests/session_get_cookie_params_variation1.phpt +++ b/ext/session/tests/session_get_cookie_params_variation1.phpt @@ -30,7 +30,7 @@ ini_set("session.cookie_secure", TRUE); var_dump(session_get_cookie_params()); ini_set("session.cookie_httponly", TRUE); var_dump(session_get_cookie_params()); -ini_set("session.cookie_samesite", "foo"); +ini_set("session.cookie_samesite", "Lax"); var_dump(session_get_cookie_params()); ini_set("session.cookie_partitioned", TRUE); var_dump(session_get_cookie_params()); @@ -150,7 +150,7 @@ array(7) { ["httponly"]=> bool(true) ["samesite"]=> - string(3) "foo" + string(3) "Lax" } array(7) { ["lifetime"]=> @@ -166,6 +166,6 @@ array(7) { ["httponly"]=> bool(true) ["samesite"]=> - string(3) "foo" + string(3) "Lax" } Done diff --git a/ext/session/tests/session_regenerate_id_cookie.phpt b/ext/session/tests/session_regenerate_id_cookie.phpt index 6516ad7061d1..7147e36a774c 100644 --- a/ext/session/tests/session_regenerate_id_cookie.phpt +++ b/ext/session/tests/session_regenerate_id_cookie.phpt @@ -4,6 +4,8 @@ Test session_regenerate_id() function : basic functionality session --INI-- session.sid_length = 32 +session.cookie_samesite=Lax +session.cookie_httponly=1 --SKIPIF-- +--FILE-- + +--EXPECTF-- +Warning: ini_set(): "session.save_path" must not contain null bytes in %s on line %d +bool(false) + +Warning: ini_set(): "session.referer_check" must not contain null bytes in %s on line %d +bool(false) +Done diff --git a/ext/session/tests/session_set_cookie_params_basic.phpt b/ext/session/tests/session_set_cookie_params_basic.phpt index 386280d17861..27cfd59b183e 100644 --- a/ext/session/tests/session_set_cookie_params_basic.phpt +++ b/ext/session/tests/session_set_cookie_params_basic.phpt @@ -15,7 +15,7 @@ var_dump(session_set_cookie_params(3600)); var_dump(session_start()); var_dump(session_set_cookie_params(1800)); var_dump(session_destroy()); -var_dump(session_set_cookie_params(1234567890)); +var_dump(session_set_cookie_params(1000000000)); echo "Done"; ob_end_flush(); diff --git a/ext/session/tests/session_set_cookie_params_invalid_ini.phpt b/ext/session/tests/session_set_cookie_params_invalid_ini.phpt new file mode 100644 index 000000000000..8ebef4a5209d --- /dev/null +++ b/ext/session/tests/session_set_cookie_params_invalid_ini.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test session.cookie_samesite with invalid INI value +--INI-- +session.cookie_samesite=Invalid +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: PHP Startup: session.cookie_samesite must be "Strict", "Lax", "None", or "" in Unknown on line 0 +string(3) "Lax" +Done diff --git a/ext/session/tests/session_set_cookie_params_variation1.phpt b/ext/session/tests/session_set_cookie_params_variation1.phpt index ed0b8dc9755d..ce4b98457bea 100644 --- a/ext/session/tests/session_set_cookie_params_variation1.phpt +++ b/ext/session/tests/session_set_cookie_params_variation1.phpt @@ -24,7 +24,7 @@ var_dump(ini_get("session.cookie_lifetime")); var_dump(session_destroy()); var_dump(ini_get("session.cookie_lifetime")); -var_dump(session_set_cookie_params(1234567890)); +var_dump(session_set_cookie_params(1000000000)); var_dump(ini_get("session.cookie_lifetime")); echo "Done"; @@ -44,5 +44,5 @@ string(4) "3600" bool(true) string(4) "3600" bool(true) -string(10) "1234567890" +string(10) "1000000000" Done diff --git a/ext/session/tests/session_set_cookie_params_variation6.phpt b/ext/session/tests/session_set_cookie_params_variation6.phpt index 61243f82751e..fbf958a0be07 100644 --- a/ext/session/tests/session_set_cookie_params_variation6.phpt +++ b/ext/session/tests/session_set_cookie_params_variation6.phpt @@ -1,7 +1,7 @@ --TEST-- -Test session_set_cookie_params() function : variation +Test session_set_cookie_params() samesite validation --INI-- -session.cookie_samesite=test +session.cookie_samesite=Lax --EXTENSIONS-- session --SKIPIF-- @@ -11,36 +11,56 @@ session ob_start(); -echo "*** Testing session_set_cookie_params() : variation ***\n"; - +echo "-- Valid values --\n"; var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "nothing"])); +var_dump(session_set_cookie_params(["samesite" => "Strict"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_start()); +var_dump(session_set_cookie_params(["samesite" => "None"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "test"])); +var_dump(session_set_cookie_params(["samesite" => ""])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_destroy()); + +echo "-- Invalid value via session_set_cookie_params --\n"; +var_dump(session_set_cookie_params(["samesite" => "Invalid"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "other"])); + +echo "-- Invalid value via ini_set --\n"; +var_dump(ini_set("session.cookie_samesite", "Invalid")); var_dump(ini_get("session.cookie_samesite")); +echo "-- Cannot change while session is active --\n"; +var_dump(session_set_cookie_params(["samesite" => "Lax"])); +var_dump(session_start()); +var_dump(session_set_cookie_params(["samesite" => "Strict"])); +var_dump(session_destroy()); + echo "Done"; ob_end_flush(); ?> --EXPECTF-- -*** Testing session_set_cookie_params() : variation *** -string(4) "test" +-- Valid values -- +string(3) "Lax" bool(true) -string(7) "nothing" +string(6) "Strict" bool(true) -string(7) "nothing" +string(4) "None" +bool(true) +string(0) "" +-- Invalid value via session_set_cookie_params -- -Warning: session_set_cookie_params(): Session cookie parameters cannot be changed when a session is active (started from %s on line %d) in %s on line %d +Warning: session_set_cookie_params(): session.cookie_samesite must be "Strict", "Lax", "None", or "" in %s on line %d +bool(false) +string(0) "" +-- Invalid value via ini_set -- + +Warning: ini_set(): session.cookie_samesite must be "Strict", "Lax", "None", or "" in %s on line %d bool(false) -string(7) "nothing" +string(0) "" +-- Cannot change while session is active -- bool(true) -string(7) "nothing" bool(true) -string(5) "other" + +Warning: session_set_cookie_params(): Session cookie parameters cannot be changed when a session is active (started from %s on line %d) in %s on line %d +bool(false) +bool(true) Done diff --git a/ext/session/tests/session_set_cookie_params_variation7.phpt b/ext/session/tests/session_set_cookie_params_variation7.phpt index 430c6efc36e9..3780fc0222f1 100644 --- a/ext/session/tests/session_set_cookie_params_variation7.phpt +++ b/ext/session/tests/session_set_cookie_params_variation7.phpt @@ -33,7 +33,7 @@ try { var_dump(ini_get("session.cookie_secure")); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["secure" => true, "samesite" => "please"])); +var_dump(session_set_cookie_params(["secure" => true, "samesite" => "Strict"])); var_dump(ini_get("session.cookie_secure")); var_dump(ini_get("session.cookie_samesite")); @@ -66,7 +66,7 @@ string(1) "0" string(0) "" bool(true) string(1) "1" -string(6) "please" +string(6) "Strict" string(1) "0" bool(true) string(2) "42" diff --git a/ext/session/tests/session_set_cookie_params_variation8.phpt b/ext/session/tests/session_set_cookie_params_variation8.phpt index 891133b5b01e..1497ded69d5f 100644 --- a/ext/session/tests/session_set_cookie_params_variation8.phpt +++ b/ext/session/tests/session_set_cookie_params_variation8.phpt @@ -25,7 +25,7 @@ bool(true) string(1) "0" string(1) "0" -Warning: session_set_cookie_params(): CookieLifetime cannot be negative in %s on line %d +Warning: session_set_cookie_params(): session.cookie_lifetime must be between 0 and %d in %s on line %d bool(false) string(1) "0" Done diff --git a/ext/session/tests/session_start_partitioned_headers.phpt b/ext/session/tests/session_start_partitioned_headers.phpt index 6fa3815aa85d..8afae811152e 100644 --- a/ext/session/tests/session_start_partitioned_headers.phpt +++ b/ext/session/tests/session_start_partitioned_headers.phpt @@ -2,6 +2,10 @@ session_start() with partitioned cookies - header test --EXTENSIONS-- session +--INI-- +session.use_strict_mode=0 +session.cookie_samesite=Lax +session.cookie_httponly=1 --FILE-- true, "partitioned" => true]); session_start(); ?> --EXPECTHEADERS-- -Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned +Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned; HttpOnly; SameSite=Lax --EXPECT-- diff --git a/ext/session/tests/session_str_settings_null_byte.phpt b/ext/session/tests/session_str_settings_null_byte.phpt new file mode 100644 index 000000000000..693ec6971601 --- /dev/null +++ b/ext/session/tests/session_str_settings_null_byte.phpt @@ -0,0 +1,37 @@ +--TEST-- +session.cookie_path, session.cookie_domain, and session.cache_limiter must not contain null bytes +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: ini_set(): "session.cookie_path" must not contain null bytes in %s on line %d +bool(false) + +Warning: ini_set(): "session.cookie_domain" must not contain null bytes in %s on line %d +bool(false) + +Warning: ini_set(): "session.cache_limiter" must not contain null bytes in %s on line %d +bool(false) + +Warning: session_set_cookie_params(): "session.cookie_path" must not contain null bytes in %s on line %d +bool(false) + +Warning: session_set_cookie_params(): "session.cookie_domain" must not contain null bytes in %s on line %d +bool(false) +Done diff --git a/ext/session/tests/user_session_module/gh_gc_retval_leak.phpt b/ext/session/tests/user_session_module/gh_gc_retval_leak.phpt new file mode 100644 index 000000000000..f04f36c2276b --- /dev/null +++ b/ext/session/tests/user_session_module/gh_gc_retval_leak.phpt @@ -0,0 +1,33 @@ +--TEST-- +session_gc(): user handler returning non-bool/non-int does not leak memory +--INI-- +session.gc_probability=0 +session.save_handler=files +--EXTENSIONS-- +session +--FILE-- + +--EXPECTF-- + +Deprecated: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in %s on line %d +bool(false) diff --git a/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt b/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt new file mode 100644 index 000000000000..2b954494e87c --- /dev/null +++ b/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt @@ -0,0 +1,31 @@ +--TEST-- +ps_call_handler() releases argv when a recursive save-handler call is rejected +--INI-- +session.save_path= +session.name=PHPSESSID +--EXTENSIONS-- +session +--FILE-- +tripped) { + $this->tripped = true; + session_destroy(); + } + return true; + } +} + +session_set_save_handler(new H, true); +session_start(); +$_SESSION['x'] = 1; +session_write_close(); +echo "done\n"; +?> +--EXPECTF-- +Warning: session_destroy(): Cannot call session save handler in a recursive manner in %s on line %d + +Warning: session_destroy(): Session object destruction failed in %s on line %d +done diff --git a/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt b/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt index cb708e33f52b..84e49f26d122 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt @@ -83,6 +83,6 @@ array(3) { } Destroy [%s,%s] -Warning: unlink(%s): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt index a3e21c35e49d..7354f90f28ca 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt @@ -97,6 +97,6 @@ GC [0] bool(true) Destroy [%s,PHPT-%d] -Warning: unlink(%s): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/shmop/php_shmop.h b/ext/shmop/php_shmop.h index 8d1d3cd8fd44..265753ea454a 100644 --- a/ext/shmop/php_shmop.h +++ b/ext/shmop/php_shmop.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Slava Poliakov | | Ilia Alshanetsky | diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index 67f060f3c82c..7903a294a037 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | PHP version 7 | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Slava Poliakov | | Ilia Alshanetsky | @@ -72,10 +68,7 @@ typedef struct php_shmop zend_class_entry *shmop_ce; static zend_object_handlers shmop_object_handlers; -static inline php_shmop *shmop_from_obj(zend_object *obj) -{ - return (php_shmop *)((char *)(obj) - XtOffsetOf(php_shmop, std)); -} +#define shmop_from_obj(obj) ZEND_CONTAINER_OF(obj, php_shmop, std) #define Z_SHMOP_P(zv) shmop_from_obj(Z_OBJ_P(zv)) @@ -112,7 +105,7 @@ PHP_MINIT_FUNCTION(shmop) shmop_ce->default_object_handlers = &shmop_object_handlers; memcpy(&shmop_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - shmop_object_handlers.offset = XtOffsetOf(php_shmop, std); + shmop_object_handlers.offset = offsetof(php_shmop, std); shmop_object_handlers.free_obj = shmop_free_obj; shmop_object_handlers.get_constructor = shmop_get_constructor; shmop_object_handlers.clone_obj = NULL; @@ -136,13 +129,20 @@ PHP_MINFO_FUNCTION(shmop) /* {{{ gets and attaches a shared memory segment */ PHP_FUNCTION(shmop_open) { - zend_long key, mode, size; + zend_long key_arg, mode, size; + key_t key; php_shmop *shmop; struct shmid_ds shm; char *flags; size_t flags_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsll", &key, &flags, &flags_len, &mode, &size) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsll", &key_arg, &flags, &flags_len, &mode, &size) == FAILURE) { + RETURN_THROWS(); + } + + key = (key_t) key_arg; + if ((zend_long) key != key_arg) { + zend_argument_value_error(1, "is out of range"); RETURN_THROWS(); } @@ -224,7 +224,6 @@ PHP_FUNCTION(shmop_read) zend_long start, count; php_shmop *shmop; char *startaddr; - int bytes; zend_string *return_string; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oll", &shmid, shmop_ce, &start, &count) == FAILURE) { @@ -244,7 +243,7 @@ PHP_FUNCTION(shmop_read) } startaddr = shmop->addr + start; - bytes = count ? count : shmop->size - start; + zend_long bytes = count ? count : shmop->size - start; return_string = zend_string_init(startaddr, bytes, 0); diff --git a/ext/shmop/tests/gh9945.phpt b/ext/shmop/tests/gh9945.phpt new file mode 100644 index 000000000000..f22f79149bfb --- /dev/null +++ b/ext/shmop/tests/gh9945.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-9945: shmop_open() must reject keys outside the key_t range +--EXTENSIONS-- +shmop +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +shmop_open(): Argument #1 ($key) is out of range diff --git a/ext/simplexml/php_simplexml.h b/ext/simplexml/php_simplexml.h index 5d16794fa644..f8d78937b9d9 100644 --- a/ext/simplexml/php_simplexml.h +++ b/ext/simplexml/php_simplexml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sterling Hughes | +----------------------------------------------------------------------+ diff --git a/ext/simplexml/php_simplexml_exports.h b/ext/simplexml/php_simplexml_exports.h index 4ae02674d6da..fb940f2fbc77 100644 --- a/ext/simplexml/php_simplexml_exports.h +++ b/ext/simplexml/php_simplexml_exports.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sterling Hughes | | Marcus Boerger | @@ -37,10 +35,7 @@ PHP_SXE_API zend_object *sxe_object_new(zend_class_entry *ce); -static inline php_sxe_object *php_sxe_fetch_object(zend_object *obj) /* {{{ */ { - return (php_sxe_object *)((char*)(obj) - XtOffsetOf(php_sxe_object, zo)); -} -/* }}} */ +#define php_sxe_fetch_object(obj) ZEND_CONTAINER_OF(obj, php_sxe_object, zo) #define Z_SXEOBJ_P(zv) php_sxe_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 16a8aaa22fc3..d86198c7639e 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | | Marcus Boerger | @@ -1614,9 +1612,7 @@ PHP_METHOD(SimpleXMLElement, getName) xmlNodePtr node; int namelen; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sxe = Z_SXEOBJ_P(ZEND_THIS); @@ -1900,9 +1896,7 @@ static zend_result sxe_object_cast(zend_object *readobj, zval *writeobj, int typ /* {{{ Returns the string content */ PHP_METHOD(SimpleXMLElement, __toString) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_result rv = sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING); ZEND_IGNORE_VALUE(rv); @@ -1950,9 +1944,7 @@ PHP_METHOD(SimpleXMLElement, count) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(php_sxe_count_elements_helper(sxe)); } @@ -1962,9 +1954,7 @@ PHP_METHOD(SimpleXMLElement, count) /* {{{ Rewind to first element */ PHP_METHOD(SimpleXMLElement, rewind) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); php_sxe_rewind_iterator(Z_SXEOBJ_P(ZEND_THIS)); } @@ -1975,9 +1965,7 @@ PHP_METHOD(SimpleXMLElement, valid) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(!Z_ISUNDEF(sxe->iter.data)); } @@ -1988,9 +1976,7 @@ PHP_METHOD(SimpleXMLElement, current) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data)) { zend_throw_error(NULL, "Iterator not initialized or already consumed"); @@ -2008,9 +1994,7 @@ PHP_METHOD(SimpleXMLElement, key) php_sxe_object *intern; php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data)) { zend_throw_error(NULL, "Iterator not initialized or already consumed"); @@ -2031,9 +2015,7 @@ PHP_METHOD(SimpleXMLElement, key) /* {{{ Move to next element */ PHP_METHOD(SimpleXMLElement, next) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); php_sxe_move_forward_iterator(Z_SXEOBJ_P(ZEND_THIS)); } @@ -2046,9 +2028,7 @@ PHP_METHOD(SimpleXMLElement, hasChildren) php_sxe_object *child; xmlNodePtr node; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) { RETURN_FALSE; @@ -2071,9 +2051,7 @@ PHP_METHOD(SimpleXMLElement, getChildren) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) { return; /* return NULL */ @@ -2653,7 +2631,7 @@ PHP_MINIT_FUNCTION(simplexml) ce_SimpleXMLElement->get_iterator = php_sxe_get_iterator; memcpy(&sxe_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sxe_object_handlers.offset = XtOffsetOf(php_sxe_object, zo); + sxe_object_handlers.offset = offsetof(php_sxe_object, zo); sxe_object_handlers.free_obj = sxe_object_free_storage; sxe_object_handlers.clone_obj = sxe_object_clone; sxe_object_handlers.read_property = sxe_property_read; diff --git a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index 935af16621e9..6faf873c885f 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -51,7 +51,7 @@ public function getName(): string {} public function __toString(): string {} - public function __debugInfo(): ?array {} + public function __debugInfo(): array {} /** @tentative-return-type */ public function count(): int {} diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 419c7874fbc5..5a62efbc7be5 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit simplexml.stub.php instead. - * Stub hash: cee51320f0f09f14962fb72125ef8ff6073a642a */ + * Stub hash: 83f1bd204b309a4558c1b09128fe29f972f54252 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_simplexml_load_file, 0, 1, SimpleXMLElement, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -79,7 +79,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___toString, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___debugInfo, 0, 0, IS_ARRAY, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___debugInfo, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_count, 0, 0, IS_LONG, 0) diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index 0e3887c0de68..bf63e89a9607 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -9,6 +9,7 @@ if (PHP_SNMP != "no") { EXTENSION('snmp', 'snmp.c'); ADD_EXTENSION_DEP('snmp', 'spl'); AC_DEFINE('HAVE_SNMP', 1, "Define to 1 if the PHP extension 'snmp' is available."); + AC_DEFINE('HAVE_SHUTDOWN_SNMP_LOGGING', 1, "Define to 1 if SNMP library has the 'shutdown_snmp_logging' function."); } else { WARNING("snmp not enabled; libraries and headers not found"); } diff --git a/ext/snmp/php_snmp.h b/ext/snmp/php_snmp.h index ce9849588b19..d889eb37ab95 100644 --- a/ext/snmp/php_snmp.h +++ b/ext/snmp/php_snmp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Mike Jackson | @@ -58,9 +56,7 @@ typedef struct _php_snmp_object { zend_object zo; } php_snmp_object; -static inline php_snmp_object *php_snmp_fetch_object(zend_object *obj) { - return (php_snmp_object *)((char*)(obj) - XtOffsetOf(php_snmp_object, zo)); -} +#define php_snmp_fetch_object(obj) ZEND_CONTAINER_OF(obj, php_snmp_object, zo) #define Z_SNMP_P(zv) php_snmp_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index d116339dd1f4..c45e3a6522b8 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Mike Jackson | @@ -220,7 +218,7 @@ static void php_snmp_error(zval *object, int type, const char *format, ...) zend_throw_exception_ex(php_snmp_exception_ce, type, "%s", snmp_object->snmp_errstr); } else { va_start(args, format); - php_verror(NULL, "", E_WARNING, format, args); + php_verror(NULL, E_WARNING, format, args); va_end(args); } } @@ -626,7 +624,7 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st, static void php_snmp_zend_string_release_from_char_pointer(char *ptr) { if (ptr) { - zend_string *pptr = (zend_string *)(ptr - XtOffsetOf(zend_string, val)); + zend_string *pptr = (zend_string *)(ptr - offsetof(zend_string, val)); zend_string_release(pptr); } } @@ -655,7 +653,8 @@ static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid */ static bool php_snmp_parse_oid( zval *object, int st, struct objid_query *objid_query, zend_string *oid_str, HashTable *oid_ht, - zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht + zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht, + uint32_t oid_arg_num, uint32_t type_arg_num, uint32_t value_arg_num ) { char *pptr; uint32_t idx_type = 0, idx_value = 0; @@ -682,7 +681,7 @@ static bool php_snmp_parse_oid( ZEND_ASSERT(type_str && value_str); if (ZSTR_LEN(type_str) != 1) { - zend_value_error("Type must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); efree(objid_query->vars); return false; } @@ -693,7 +692,7 @@ static bool php_snmp_parse_oid( objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - zend_value_error("Array of object IDs must not be empty"); + zend_argument_value_error(oid_arg_num, "must not be empty when passed as an array"); return false; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); @@ -738,14 +737,14 @@ static bool php_snmp_parse_oid( char ptype = *ZSTR_VAL(type); zend_string_release(type); if (len != 1) { - zend_value_error("Type must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } objid_query->vars[objid_query->count].type = ptype; idx_type++; } else { - php_error_docref(NULL, E_WARNING, "'%s': no type set", ZSTR_VAL(tmp)); + zend_argument_value_error(type_arg_num, "must contain a type for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -780,7 +779,7 @@ static bool php_snmp_parse_oid( objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp); idx_value++; } else { - php_error_docref(NULL, E_WARNING, "'%s': no value set", ZSTR_VAL(tmp)); + zend_argument_value_error(value_arg_num, "must contain a value for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -827,7 +826,7 @@ static bool php_snmp_parse_oid( /* {{{ snmp_session_init allocates memory for session and session->peername, caller should free it manually using snmp_session_free() and efree() */ -static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, int timeout_argument_offset) +static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, uint32_t hostname_arg_num, uint32_t timeout_arg_num) { php_snmp_session *session; char *pptr, *host_ptr; @@ -841,34 +840,24 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st ZEND_ASSERT(hostname != NULL); ZEND_ASSERT(community != NULL); - if (zend_str_has_nul_byte(hostname)) { - zend_argument_value_error(2, "must not contain any null bytes"); - return false; - } - if (ZSTR_LEN(hostname) >= MAX_NAME_LEN) { - zend_argument_value_error(2, "length must be lower than %d", MAX_NAME_LEN); - return false; - } - - if (zend_str_has_nul_byte(community)) { - zend_argument_value_error(3, "must not contain any null bytes"); + zend_argument_value_error(hostname_arg_num, "length must be lower than %d", MAX_NAME_LEN); return false; } if (ZSTR_LEN(community) == 0) { - zend_argument_must_not_be_empty_error(3); + zend_argument_must_not_be_empty_error(hostname_arg_num + 1); return false; } - if (timeout_argument_offset != -1) { + if (timeout_arg_num != 0) { if (timeout < -1 || timeout > LONG_MAX) { - zend_argument_value_error(timeout_argument_offset, "must be between -1 and %ld", LONG_MAX); + zend_argument_value_error(timeout_arg_num, "must be between -1 and %ld", LONG_MAX); return false; } if (retries < -1 || retries > INT_MAX) { - zend_argument_value_error(timeout_argument_offset + 1, "must be between -1 and %d", INT_MAX); + zend_argument_value_error(timeout_arg_num + 1, "must be between -1 and %d", INT_MAX); return false; } } @@ -899,14 +888,14 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 2; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(2, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; } *pptr = '\0'; } else { - php_error_docref(NULL, E_WARNING, "Malformed IPv6 address, closing square bracket missing"); + zend_argument_value_error(hostname_arg_num, "has a malformed IPv6 address, closing square bracket missing"); return false; } } else { /* IPv4 address */ @@ -914,7 +903,7 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 1; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(2, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; @@ -956,6 +945,7 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st if (strlen(session->peername) == 0) { php_error_docref(NULL, E_WARNING, "Unknown failure while resolving '%s'", ZSTR_VAL(hostname)); + php_network_freeaddresses(psal); return false; } /* XXX FIXME @@ -1123,14 +1113,13 @@ static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_sec_key(struct snmp_session /* }}} */ /* {{{ Set context Engine Id in the snmpv3 session */ -static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string * contextEngineID) +static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string *contextEngineID, uint32_t context_engine_id_arg_num) { size_t ebuf_len = 32, eout_len = 0; uint8_t *ebuf = (uint8_t *) emalloc(ebuf_len); if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, ZSTR_VAL(contextEngineID))) { - // TODO Promote to Error? - php_error_docref(NULL, E_WARNING, "Bad engine ID value '%s'", ZSTR_VAL(contextEngineID)); + zend_argument_value_error(context_engine_id_arg_num, "must be a valid context engine ID"); efree(ebuf); return false; } @@ -1145,11 +1134,14 @@ static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string } /* }}} */ -/* {{{ Set all snmpv3-related security options */ +/* {{{ Set all snmpv3-related security options + * auth_protocol_arg_num and context_engine_id_arg_num are the userland + * argument numbers used for error reporting. + */ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level, zend_string *auth_protocol, zend_string *auth_passphrase, zend_string *priv_protocol, zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID, - uint32_t auth_protocol_argnum) + uint32_t auth_protocol_arg_num, uint32_t context_engine_id_arg_num) { /* Setting the security level. */ @@ -1161,7 +1153,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { if (!auth_protocol) { - zend_argument_value_error(auth_protocol_argnum, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); return false; } @@ -1172,7 +1164,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } if (!auth_passphrase) { - zend_argument_value_error(auth_protocol_argnum + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); return false; } @@ -1185,7 +1177,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { if (!priv_protocol) { - zend_argument_value_error(auth_protocol_argnum + 2, "cannot be null when security level is \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 2, "cannot be null when security level is \"authPriv\""); return false; } @@ -1196,7 +1188,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } if (!priv_passphrase) { - zend_argument_value_error(auth_protocol_argnum + 3, "cannot be null when security level is \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 3, "cannot be null when security level is \"authPriv\""); return false; } @@ -1215,7 +1207,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } /* Setting contextEngineIS if specified */ - if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID)) { + if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID, context_engine_id_arg_num)) { /* Warning message sent already, just bail out */ return false; } @@ -1235,14 +1227,17 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) { zend_string *oid_str, *type_str = NULL, *value_str = NULL; HashTable *oid_ht, *type_ht = NULL, *value_ht = NULL; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *hostname = NULL, *community_or_security_name = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; bool use_orignames = 0, suffix_keys = 0; zend_long timeout = SNMP_DEFAULT_TIMEOUT; zend_long retries = SNMP_DEFAULT_RETRIES; struct objid_query objid_query; php_snmp_session *session; int session_less_mode = (getThis() == NULL); - int timeout_argument_offset = -1; + uint32_t timeout_arg_num = 0; + uint32_t oid_arg_num = 1, type_arg_num = 0, value_arg_num = 0; php_snmp_object *snmp_object; php_snmp_object glob_snmp_object; @@ -1255,13 +1250,13 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) if (version == SNMP_VERSION_3) { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(10, 12) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1270,33 +1265,37 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 10; + timeout_arg_num = 10; + oid_arg_num = 8; + type_arg_num = 9; + value_arg_num = 10; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(8, 10) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 9; + timeout_arg_num = 9; + oid_arg_num = 8; } } else { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(5, 7) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1305,22 +1304,26 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 6; + timeout_arg_num = 6; + oid_arg_num = 3; + type_arg_num = 4; + value_arg_num = 5; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(3, 5) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 4; + timeout_arg_num = 4; + oid_arg_num = 3; } } } else { @@ -1330,6 +1333,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) ZEND_PARSE_PARAMETERS_END(); + type_arg_num = 2; + value_arg_num = 3; } else if (st & SNMP_CMD_WALK) { ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) @@ -1359,20 +1364,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) } } - if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type_str, type_ht, value_str, value_ht)) { + if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type_str, type_ht, value_str, value_ht, + oid_arg_num, type_arg_num, value_arg_num)) { RETURN_FALSE; } if (session_less_mode) { - if (!snmp_session_init(&session, version, a1, a2, timeout, retries, timeout_argument_offset)) { + if (!snmp_session_init(&session, version, hostname, community_or_security_name, timeout, retries, 1, timeout_arg_num)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); RETURN_FALSE; } - if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL, 4)) { + if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, NULL, NULL, 4, 0)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); - /* Warning message sent already, just bail out */ + /* An error has already been emitted, just bail out. */ RETURN_FALSE; } } else { @@ -1457,9 +1463,7 @@ PHP_FUNCTION(snmpset) /* {{{ Return the current status of quick_print */ PHP_FUNCTION(snmp_get_quick_print) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)); } @@ -1610,9 +1614,7 @@ PHP_FUNCTION(snmp_set_valueretrieval) /* {{{ Return the method how the SNMP values will be returned */ PHP_FUNCTION(snmp_get_valueretrieval) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(SNMP_G(valueretrieval)); } @@ -1649,7 +1651,7 @@ PHP_METHOD(SNMP, __construct) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lSS|ll", &version, &a1, &a2, &timeout, &retries) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lPP|ll", &version, &a1, &a2, &timeout, &retries) == FAILURE) { RETURN_THROWS(); } @@ -1668,7 +1670,7 @@ PHP_METHOD(SNMP, __construct) snmp_session_free(&(snmp_object->session)); } - if (!snmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries, 4)) { + if (!snmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries, 2, 4)) { return; } snmp_object->max_oids = 0; @@ -1689,9 +1691,7 @@ PHP_METHOD(SNMP, close) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); snmp_session_free(&(snmp_object->session)); @@ -1732,7 +1732,11 @@ PHP_METHOD(SNMP, setSecurity) { php_snmp_object *snmp_object; zval *object = ZEND_THIS; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; + zend_string *context_name = NULL, *context_engine_id = NULL; + uint32_t auth_protocol_arg_num = 2; + uint32_t context_engine_id_arg_num = 7; snmp_object = Z_SNMP_P(object); if (!snmp_object->session) { @@ -1740,12 +1744,12 @@ PHP_METHOD(SNMP, setSecurity) RETURN_THROWS(); } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &a1, &a2, &a3, &a4,&a5, &a6, &a7) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &security_level, &auth_protocol, &auth_passphrase, &privacy_protocol, &privacy_passphrase, &context_name, &context_engine_id) == FAILURE) { RETURN_THROWS(); } - if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7, 2)) { - /* Warning message sent already, just bail out */ + if (!snmp_session_set_security(snmp_object->session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, context_name, context_engine_id, auth_protocol_arg_num, context_engine_id_arg_num)) { + /* An error has already been emitted, just bail out. */ RETURN_FALSE; } RETURN_TRUE; @@ -1760,9 +1764,7 @@ PHP_METHOD(SNMP, getErrno) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(snmp_object->snmp_errno); } @@ -1776,9 +1778,7 @@ PHP_METHOD(SNMP, getError) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_STRING(snmp_object->snmp_errstr); } @@ -2145,7 +2145,7 @@ PHP_MINIT_FUNCTION(snmp) php_snmp_ce = register_class_SNMP(); php_snmp_ce->create_object = php_snmp_object_new; php_snmp_ce->default_object_handlers = &php_snmp_object_handlers; - php_snmp_object_handlers.offset = XtOffsetOf(php_snmp_object, zo); + php_snmp_object_handlers.offset = offsetof(php_snmp_object, zo); php_snmp_object_handlers.clone_obj = NULL; php_snmp_object_handlers.free_obj = php_snmp_object_free_storage; diff --git a/ext/snmp/tests/bug64124.phpt b/ext/snmp/tests/bug64124.phpt index 4fbf80f0400a..5e2c43dc6ada 100644 --- a/ext/snmp/tests/bug64124.phpt +++ b/ext/snmp/tests/bug64124.phpt @@ -13,6 +13,8 @@ if (@inet_ntop($packed) === false) { die("skip no IPv6 support"); } ?> +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- --ENV-- MIBS=noneXistent +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- getMessage() . \PHP_EOL; +} ?> --EXPECTF-- string(%d) "%s" - -Warning: snmpget(): Malformed IPv6 address, closing square bracket missing in %s on line %d -bool(false) +snmpget(): Argument #1 ($hostname) has a malformed IPv6 address, closing square bracket missing diff --git a/ext/snmp/tests/snmp-object-errno-errstr.phpt b/ext/snmp/tests/snmp-object-errno-errstr.phpt index d6757111b020..ae279cd4e652 100644 --- a/ext/snmp/tests/snmp-object-errno-errstr.phpt +++ b/ext/snmp/tests/snmp-object-errno-errstr.phpt @@ -9,6 +9,8 @@ snmp require_once(__DIR__.'/skipif.inc'); if (getenv('SKIP_ASAN')) die('skip Timeouts under ASAN'); ?> +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- setSecurity('authPriv', 'MD5', $auth_pass, 'AES', '')); var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'ty')); -var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'test12345', 'context', 'dsa')); +try { + var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'test12345', 'context', 'dsa')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump($session->close()); @@ -76,7 +80,5 @@ bool(false) Warning: SNMP::setSecurity(): Error generating a key for privacy pass phrase 'ty': Generic error (The supplied password length is too short.) in %s on line %d bool(false) - -Warning: SNMP::setSecurity(): Bad engine ID value 'dsa' in %s on line %d -bool(false) +SNMP::setSecurity(): Argument #7 ($contextEngineId) must be a valid context engine ID bool(true) diff --git a/ext/snmp/tests/snmp-object.phpt b/ext/snmp/tests/snmp-object.phpt index 13461675cc80..1a9ce63fc6c2 100644 --- a/ext/snmp/tests/snmp-object.phpt +++ b/ext/snmp/tests/snmp-object.phpt @@ -8,6 +8,8 @@ snmp +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- --ENV-- MIBS= +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID & type, single value in array\n"; -$z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -167,7 +177,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character No value (timeout instead), retries instead of timeout Warning: snmp2_set(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -216,23 +226,19 @@ Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value - -Warning: snmp2_set(): '%s': no type set in %s on line %d -bool(false) +snmp2_set(): Argument #4 ($type) must contain a type for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID & type, single value in array - -Warning: snmp2_set(): '%s': no value set in %s on line %d -bool(false) +snmp2_set(): Argument #5 ($value) must contain a value for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID, 1st bogus, single type, multiple value diff --git a/ext/snmp/tests/snmp2_walk.phpt b/ext/snmp/tests/snmp2_walk.phpt index fcf14424ca05..362db1fa3cbd 100644 --- a/ext/snmp/tests/snmp2_walk.phpt +++ b/ext/snmp/tests/snmp2_walk.phpt @@ -9,6 +9,8 @@ snmp require_once(__DIR__.'/skipif.inc'); if (getenv('SKIP_ASAN')) die('skip Timeouts under ASAN'); ?> +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--EXPECTF-- +Warning: snmpget(): Unknown failure while resolving '[127.0.0.1]' in %s on line %d +bool(false) diff --git a/ext/snmp/tests/snmpget.phpt b/ext/snmp/tests/snmpget.phpt index ea7924ed8e57..9e0d38541597 100644 --- a/ext/snmp/tests/snmpget.phpt +++ b/ext/snmp/tests/snmpget.phpt @@ -9,6 +9,8 @@ snmp require_once(__DIR__.'/skipif.inc'); if (getenv('SKIP_ASAN')) die('skip Timeouts under ASAN'); ?> +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- --ENV-- MIBS= +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID & type, single value in array\n"; -$z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -161,7 +171,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character No value (timeout instead), retries instead of timeout Warning: snmpset(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -207,23 +217,19 @@ Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value - -Warning: snmpset(): '%s': no type set in %s on line %d -bool(false) +snmpset(): Argument #4 ($type) must contain a type for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID & type, single value in array - -Warning: snmpset(): '%s': no value set in %s on line %d -bool(false) +snmpset(): Argument #5 ($value) must contain a value for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID, 1st bogus, single type, multiple value diff --git a/ext/snmp/tests/snmpwalk.phpt b/ext/snmp/tests/snmpwalk.phpt index 61ef33a70a29..bc1e4c37385d 100644 --- a/ext/snmp/tests/snmpwalk.phpt +++ b/ext/snmp/tests/snmpwalk.phpt @@ -9,6 +9,8 @@ snmp require_once(__DIR__.'/skipif.inc'); if (getenv('SKIP_ASAN')) die('skip Timeouts under ASAN'); ?> +--XFAIL-- +SNMP tests might possibly fail on Windows --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -16,6 +14,7 @@ +----------------------------------------------------------------------+ */ +#include #include #include "php_soap.h" @@ -83,6 +82,11 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data); static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); +static zend_always_inline const char *soap_type_name(encodeTypePtr type) +{ + return (type && type->type_str) ? type->type_str : "unknown"; +} + static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *out_type); static xmlNodePtr check_and_resolve_href(xmlNodePtr data); @@ -254,11 +258,12 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type) { if (sdl && sdl->encoders) { encodePtr enc; + size_t type_len = strlen(type); ZEND_HASH_FOREACH_PTR(sdl->encoders, enc) { if (type[0] == '{') { if (enc->details.clark_notation - && strcmp(ZSTR_VAL(enc->details.clark_notation), type) == 0) { + && zend_string_equals_cstr(enc->details.clark_notation, type, type_len)) { return enc; } } else { @@ -278,7 +283,7 @@ static bool soap_check_zval_ref(zval *data, xmlNodePtr node) { if (Z_TYPE_P(data) == IS_OBJECT) { data = (zval*)Z_OBJ_P(data); } - if ((node_ptr = zend_hash_index_find_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)data)) != NULL) { + if ((node_ptr = zend_hash_index_find_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)data)) != NULL) { xmlAttrPtr attr = node_ptr->properties; char *id; smart_str prefix = {0}; @@ -324,7 +329,7 @@ static bool soap_check_zval_ref(zval *data, xmlNodePtr node) { smart_str_free(&prefix); return true; } else { - zend_hash_index_update_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)data, node); + zend_hash_index_update_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)data, node); } } return false; @@ -335,7 +340,7 @@ static bool soap_check_xml_ref(zval *data, xmlNodePtr node) zval *data_ptr; if (SOAP_GLOBAL(ref_map)) { - if ((data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (zend_ulong)node)) != NULL) { + if ((data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)node)) != NULL) { if (!Z_REFCOUNTED_P(data) || !Z_REFCOUNTED_P(data_ptr) || Z_COUNTED_P(data) != Z_COUNTED_P(data_ptr)) { @@ -351,7 +356,8 @@ static bool soap_check_xml_ref(zval *data, xmlNodePtr node) static void soap_add_xml_ref(zval *data, xmlNodePtr node) { if (SOAP_GLOBAL(ref_map)) { - zend_hash_index_update(SOAP_GLOBAL(ref_map), (zend_ulong)node, data); + Z_TRY_ADDREF_P(data); + zend_hash_index_update(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)node, data); } } @@ -659,7 +665,7 @@ static zval *to_zval_string(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_EMPTY_STRING(ret); @@ -692,7 +698,7 @@ static zval *to_zval_stringr(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_EMPTY_STRING(ret); @@ -725,7 +731,7 @@ static zval *to_zval_stringc(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_EMPTY_STRING(ret); @@ -744,17 +750,17 @@ static zval *to_zval_base64(zval *ret, encodeTypePtr type, xmlNodePtr data) whiteSpace_collapse(data->children->content); str = php_base64_decode(data->children->content, strlen((char*)data->children->content)); if (!str) { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } ZVAL_STR(ret, str); } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { str = php_base64_decode(data->children->content, strlen((char*)data->children->content)); if (!str) { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } ZVAL_STR(ret, str); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_EMPTY_STRING(ret); @@ -765,6 +771,7 @@ static zval *to_zval_base64(zval *ret, encodeTypePtr type, xmlNodePtr data) static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) { zend_string *str; + size_t content_len; size_t i, j; unsigned char c; @@ -774,10 +781,15 @@ static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { whiteSpace_collapse(data->children->content); } else if (data->children->type != XML_CDATA_SECTION_NODE || data->children->next != NULL) { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); + return ret; + } + content_len = strlen((char*) data->children->content); + if (content_len % 2 != 0) { + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain an even number of hexadecimal digits", soap_type_name(type)); return ret; } - str = zend_string_alloc(strlen((char*)data->children->content) / 2, 0); + str = zend_string_alloc(content_len / 2, 0); for (i = j = 0; i < ZSTR_LEN(str); i++) { c = data->children->content[j++]; if (c >= '0' && c <= '9') { @@ -787,7 +799,7 @@ static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (c >= 'A' && c <= 'F') { ZSTR_VAL(str)[i] = (c - 'A' + 10) << 4; } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } c = data->children->content[j++]; if (c >= '0' && c <= '9') { @@ -797,7 +809,7 @@ static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (c >= 'A' && c <= 'F') { ZSTR_VAL(str)[i] |= c - 'A' + 10; } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } } ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0'; @@ -1018,11 +1030,11 @@ static zval *to_zval_double(zval *ret, encodeTypePtr type, xmlNodePtr data) } else if (strncasecmp((char*)data->children->content, "-INF", sizeof("-INF")-1) == 0) { ZVAL_DOUBLE(ret, -php_get_inf()); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } } } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_NULL(ret); @@ -1051,10 +1063,10 @@ static zval *to_zval_long(zval *ret, encodeTypePtr type, xmlNodePtr data) ZVAL_DOUBLE(ret, dval); break; default: - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Invalid value for type '%s'", soap_type_name(type)); } } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } } else { ZVAL_NULL(ret); @@ -1120,7 +1132,7 @@ static zval *to_zval_bool(zval *ret, encodeTypePtr type, xmlNodePtr data) } if (data->children->type != XML_TEXT_NODE || data->children->next != NULL) { // TODO Convert to exception? - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error1(E_ERROR, "Encoding: Type '%s' value must contain a single text or CDATA node", soap_type_name(type)); } whiteSpace_collapse(data->children->content); @@ -2049,6 +2061,15 @@ static int calc_dimension_12(const char* str) return i; } +static void soap_array_position_add_digit(int *position, int digit) +{ + if (UNEXPECTED(*position > (INT_MAX - digit) / 10)) { + soap_error0(E_ERROR, "Encoding: array index out of range"); + } + + *position = (*position * 10) + digit; +} + static int* get_position_12(int dimension, const char* str) { int *pos; @@ -2069,7 +2090,7 @@ static int* get_position_12(int dimension, const char* str) i++; flag = 1; } - pos[i] = (pos[i]*10)+(*str-'0'); + soap_array_position_add_digit(&pos[i], *str - '0'); } else if (*str == '*') { soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list"); } else { @@ -2099,7 +2120,7 @@ static void get_position_ex(int dimension, const char* str, int** pos) memset(*pos,0,sizeof(int)*dimension); while (*str != ']' && *str != '\0' && i < dimension) { if (*str >= '0' && *str <= '9') { - (*pos)[i] = ((*pos)[i]*10)+(*str-'0'); + soap_array_position_add_digit(&(*pos)[i], *str - '0'); } else if (*str == ',') { i++; } @@ -2686,16 +2707,20 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) /* Increment position */ i = dimension; while (i > 0) { - i--; - pos[i]++; - if (pos[i] >= dims[i]) { - if (i > 0) { - pos[i] = 0; - } else { - /* TODO: Array index overflow */ - } - } else { - break; + i--; + if (UNEXPECTED(pos[i] == INT_MAX)) { + efree(dims); + efree(pos); + zval_ptr_dtor(ret); + ZVAL_UNDEF(ret); + soap_error0(E_ERROR, "Encoding: array index out of range"); + } + pos[i]++; + if (pos[i] < dims[i]) { + break; + } + if (i > 0) { + pos[i] = 0; } } } @@ -2785,7 +2810,7 @@ static zval *to_zval_map(zval *ret, encodeTypePtr type, xmlNodePtr data) } xmlValue = get_node(item->children, "value"); - if (!xmlKey) { + if (!xmlValue) { soap_error0(E_ERROR, "Encoding: Can't decode apache map, missing value"); } @@ -3076,7 +3101,9 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP } smart_str_appends(&list, (char*)dummy->children->content); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error2(E_ERROR, + "Encoding: Failed to encode list item of type '%s' for list type '%s'", + soap_type_name(&list_enc->details), soap_type_name(enc)); } xmlUnlinkNode(dummy); xmlFreeNode(dummy); @@ -3118,7 +3145,9 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP } smart_str_appends(&list, (char*)dummy->children->content); } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + soap_error2(E_ERROR, + "Encoding: Failed to encode list item of type '%s' for list type '%s'", + soap_type_name(&list_enc->details), soap_type_name(enc)); } xmlUnlinkNode(dummy); xmlFreeNode(dummy); @@ -3522,7 +3551,7 @@ void encode_reset_ns(void) } else { SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable)); } - zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0); + zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, ZVAL_PTR_DTOR, 0); } void encode_finish(void) diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index ef05c9ebe787..e01154e17456 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index bac21d26b358..b49acd947b39 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -17,19 +15,36 @@ */ #include "php_soap.h" -#include "ext/hash/php_hash.h" /* For php_hash_bin2hex() */ #include "ext/uri/php_uri.h" static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); -static char *get_http_header_value(char *headers, char *type); -static zend_string *get_http_body(php_stream *socketd, int close, char *headers); +static char *get_http_header_value(zend_string *headers, char *type); +static zend_string *get_http_body(php_stream *socketd, bool close, zend_string *headers); static zend_string *get_http_headers(php_stream *socketd); #define smart_str_append_const(str, const) \ smart_str_appendl(str,const,sizeof(const)-1) +static void soap_smart_str_append_header_value_ex(smart_str *dest, const char *src, size_t len, const char *header_name) +{ + size_t i = 0; + while (i < len && src[i] != '\r' && src[i] != '\n') { + i++; + } + smart_str_appendl(dest, src, i); + if (i < len) { + php_error_docref(NULL, E_WARNING, + "Header %s value contains newline characters and has been truncated", header_name); + } +} + +static void soap_smart_str_append_header_value(smart_str *dest, const zend_string *value, const char *header_name) +{ + soap_smart_str_append_header_value_ex(dest, ZSTR_VAL(value), ZSTR_LEN(value), header_name); +} + /* Proxy HTTP Authentication */ -int proxy_authentication(zval* this_ptr, smart_str* soap_headers) +bool proxy_authentication(zval* this_ptr, smart_str* soap_headers) { zval *login = Z_CLIENT_PROXY_LOGIN_P(this_ptr); if (Z_TYPE_P(login) == IS_STRING) { @@ -46,15 +61,15 @@ int proxy_authentication(zval* this_ptr, smart_str* soap_headers) smart_str_append_const(soap_headers, "Proxy-Authorization: Basic "); smart_str_append(soap_headers, buf); smart_str_append_const(soap_headers, "\r\n"); - zend_string_release_ex(buf, 0); + zend_string_release_ex(buf, false); smart_str_free(&auth); - return 1; + return true; } - return 0; + return false; } /* HTTP Authentication */ -int basic_authentication(zval* this_ptr, smart_str* soap_headers) +bool basic_authentication(zval* this_ptr, smart_str* soap_headers) { zval *login = Z_CLIENT_LOGIN_P(this_ptr); zval *use_digest = Z_CLIENT_USE_DIGEST_P(this_ptr); @@ -72,11 +87,11 @@ int basic_authentication(zval* this_ptr, smart_str* soap_headers) smart_str_append_const(soap_headers, "Authorization: Basic "); smart_str_append(soap_headers, buf); smart_str_append_const(soap_headers, "\r\n"); - zend_string_release_ex(buf, 0); + zend_string_release_ex(buf, false); smart_str_free(&auth); - return 1; + return true; } - return 0; + return false; } static void http_context_add_header(const char *s, @@ -163,7 +178,7 @@ void http_context_headers(php_stream_context* context, } } -static php_stream* http_connect(zval* this_ptr, php_uri *uri, int use_ssl, php_stream_context *context, int *use_proxy) +static php_stream* http_connect(zval* this_ptr, php_uri *uri, bool use_ssl, php_stream_context *context, int *use_proxy) { php_stream *stream; zval *tmp, ssl_proxy_peer_name; @@ -254,12 +269,12 @@ static php_stream* http_connect(zval* this_ptr, php_uri *uri, int use_ssl, php_s } smart_str_append_const(&soap_headers, "CONNECT "); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->host)); + smart_str_append(&soap_headers, uri->host); smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, uri->port); smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->host)); + smart_str_append(&soap_headers, uri->host); if (uri->port != 80) { smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, uri->port); @@ -327,7 +342,7 @@ static bool in_domain(const zend_string *host, const zend_string *domain) { if (ZSTR_VAL(domain)[0] == '.') { if (ZSTR_LEN(host) > ZSTR_LEN(domain)) { - return strcmp(ZSTR_VAL(host)+ZSTR_LEN(host)-ZSTR_LEN(domain), ZSTR_VAL(domain)) == 0; + return zend_string_equals_cstr(domain, ZSTR_VAL(host) + ZSTR_LEN(host) - ZSTR_LEN(domain), ZSTR_LEN(domain)); } else { return false; } @@ -336,7 +351,7 @@ static bool in_domain(const zend_string *host, const zend_string *domain) } } -int make_http_soap_request( +bool make_http_soap_request( zval *this_ptr, zend_string *buf, zend_string *location, char *soapaction, int soap_version, zend_string *uri_parser_class, zval *return_value ) { @@ -348,14 +363,13 @@ int make_http_soap_request( php_stream *stream; zval *tmp; int use_proxy = 0; - int use_ssl; zend_string *http_body; char *content_type, *http_version, *cookie_itt; size_t cookie_len; - int http_close; + bool http_close; zend_string *http_headers; char *connection; - int http_1_1; + bool http_1_1; int http_status; int content_type_xml = 0; zend_long redirect_max = 20; @@ -368,7 +382,7 @@ int make_http_soap_request( bool has_cookies = false; if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) { - return FALSE; + return false; } request = buf; @@ -414,7 +428,7 @@ int make_http_soap_request( zend_string_release_ex(request, 0); } smart_str_free(&soap_headers_z); - return FALSE; + return false; } } } @@ -434,7 +448,7 @@ int make_http_soap_request( const php_uri_parser *uri_parser = php_uri_get_parser(uri_parser_class); if (uri_parser == NULL) { zend_argument_value_error(6, "must be a valid URI parser name"); - return FALSE; + return false; } uri = php_uri_parse_to_struct(uri_parser, ZSTR_VAL(location), ZSTR_LEN(location), PHP_URI_COMPONENT_READ_MODE_RAW, true); } @@ -463,12 +477,12 @@ int make_http_soap_request( add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } - use_ssl = 0; + bool use_ssl = false; if (uri->scheme != NULL && zend_string_equals_literal(uri->scheme, "https")) { - use_ssl = 1; + use_ssl = true; } else if (uri->scheme == NULL || !zend_string_equals_literal(uri->scheme, "http")) { php_uri_struct_free(uri); if (request != buf) { @@ -477,7 +491,7 @@ int make_http_soap_request( add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } old_allow_url_fopen = PG(allow_url_fopen); @@ -491,7 +505,7 @@ int make_http_soap_request( PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } if (uri->port == 0) { @@ -544,7 +558,7 @@ int make_http_soap_request( PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } } PG(allow_url_fopen) = old_allow_url_fopen; @@ -567,31 +581,31 @@ int make_http_soap_request( (tmp = php_stream_context_get_option(context, "http", "protocol_version")) != NULL && Z_TYPE_P(tmp) == IS_DOUBLE && Z_DVAL_P(tmp) == 1.0) { - http_1_1 = 0; + http_1_1 = false; } else { - http_1_1 = 1; + http_1_1 = true; } smart_str_append_const(&soap_headers, "POST "); if (use_proxy && !use_ssl) { - smart_str_appends(&soap_headers, ZSTR_VAL(uri->scheme)); + smart_str_append(&soap_headers, uri->scheme); smart_str_append_const(&soap_headers, "://"); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->host)); + smart_str_append(&soap_headers, uri->host); smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, uri->port); } if (uri->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(uri->path)); + smart_str_append(&soap_headers, uri->path); } else { smart_str_appendc(&soap_headers, '/'); } if (uri->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->query)); + smart_str_append(&soap_headers, uri->query); } if (uri->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->fragment)); + smart_str_append(&soap_headers, uri->fragment); } if (http_1_1) { smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); @@ -599,7 +613,7 @@ int make_http_soap_request( smart_str_append_const(&soap_headers, " HTTP/1.0\r\n"); } smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->host)); + smart_str_append(&soap_headers, uri->host); if (uri->port != (use_ssl?443:80)) { smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, uri->port); @@ -611,25 +625,25 @@ int make_http_soap_request( smart_str_append_const(&soap_headers, "\r\n" "Connection: Keep-Alive\r\n"); } + zend_string *ua_str = NULL; + tmp = Z_CLIENT_USER_AGENT_P(this_ptr); if (Z_TYPE_P(tmp) == IS_STRING) { - if (Z_STRLEN_P(tmp) > 0) { - smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); - smart_str_append_const(&soap_headers, "\r\n"); - } + ua_str = Z_STR_P(tmp); } else if (context && (tmp = php_stream_context_get_option(context, "http", "user_agent")) != NULL && Z_TYPE_P(tmp) == IS_STRING) { - if (Z_STRLEN_P(tmp) > 0) { + ua_str = Z_STR_P(tmp); + } else if (FG(user_agent)) { + ua_str = FG(user_agent); + } + + if (ua_str) { + if (ZSTR_LEN(ua_str) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + soap_smart_str_append_header_value(&soap_headers, ua_str, "User-Agent"); smart_str_append_const(&soap_headers, "\r\n"); } - } else if (FG(user_agent)) { - smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appends(&soap_headers, FG(user_agent)); - smart_str_append_const(&soap_headers, "\r\n"); } else { smart_str_append_const(&soap_headers, "User-Agent: PHP-SOAP/"PHP_VERSION"\r\n"); } @@ -643,13 +657,13 @@ int make_http_soap_request( Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + soap_smart_str_append_header_value(&soap_headers, Z_STR_P(tmp), "Content-Type"); } else { smart_str_append_const(&soap_headers, "Content-Type: application/soap+xml; charset=utf-8"); } if (soapaction) { smart_str_append_const(&soap_headers,"; action=\""); - smart_str_appends(&soap_headers, soapaction); + soap_smart_str_append_header_value_ex(&soap_headers, soapaction, strlen(soapaction), "SOAPAction"); smart_str_append_const(&soap_headers,"\""); } smart_str_append_const(&soap_headers,"\r\n"); @@ -660,14 +674,14 @@ int make_http_soap_request( Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + soap_smart_str_append_header_value(&soap_headers, Z_STR_P(tmp), "Content-Type"); smart_str_append_const(&soap_headers, "\r\n"); } else { smart_str_append_const(&soap_headers, "Content-Type: text/xml; charset=utf-8\r\n"); } if (soapaction) { smart_str_append_const(&soap_headers, "SOAPAction: \""); - smart_str_appends(&soap_headers, soapaction); + soap_smart_str_append_header_value_ex(&soap_headers, soapaction, strlen(soapaction), "SOAPAction"); smart_str_append_const(&soap_headers, "\"\r\n"); } } @@ -696,10 +710,10 @@ int make_http_soap_request( smart_str_free(&soap_headers_z); smart_str_free(&soap_headers); efree(http_msg); - return FALSE; + return false; } - php_hash_bin2hex(cnonce, nonce, sizeof(nonce)); + zend_bin2hex(cnonce, nonce, sizeof(nonce)); cnonce[32] = 0; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL && @@ -780,30 +794,30 @@ int make_http_soap_request( make_digest(response, hash); smart_str_append_const(&soap_headers, "Authorization: Digest username=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(login), Z_STRLEN_P(login)); + smart_str_append(&soap_headers, Z_STR_P(login)); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", realm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", nonce=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\", uri=\""); if (uri->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(uri->path)); + smart_str_append(&soap_headers, uri->path); } else { smart_str_appendc(&soap_headers, '/'); } if (uri->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->query)); + smart_str_append(&soap_headers, uri->query); } if (uri->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(uri->fragment)); + smart_str_append(&soap_headers, uri->fragment); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { @@ -819,12 +833,12 @@ int make_http_soap_request( if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "opaque", sizeof("opaque")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", opaque=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", algorithm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\"\r\n"); } else { @@ -879,9 +893,9 @@ int make_http_soap_request( smart_str_appends(&soap_headers, "; "); } first_cookie = false; - smart_str_append(&soap_headers, key); + soap_smart_str_append_header_value(&soap_headers, key, "Cookie"); smart_str_appendc(&soap_headers, '='); - smart_str_append(&soap_headers, Z_STR_P(value)); + soap_smart_str_append_header_value(&soap_headers, Z_STR_P(value), "Cookie"); } } } @@ -899,7 +913,7 @@ int make_http_soap_request( ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr), ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); } - smart_str_appendl(&soap_headers, request->val, request->len); + smart_str_append(&soap_headers, request); smart_str_0(&soap_headers); err = php_stream_write(stream, ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); @@ -914,14 +928,14 @@ int make_http_soap_request( add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } smart_str_free(&soap_headers); } else { add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } http_headers = NULL; @@ -938,7 +952,7 @@ int make_http_soap_request( add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } if (client_trace) { @@ -947,28 +961,28 @@ int make_http_soap_request( } /* Check to see what HTTP status was sent */ - http_1_1 = 0; + http_1_1 = false; http_status = 0; - http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/"); + http_version = get_http_header_value(http_headers, "HTTP/"); if (http_version) { char *tmp; if (!strncmp(http_version,"1.1", 3)) { - http_1_1 = 1; + http_1_1 = true; } tmp = strstr(http_version," "); if (tmp != NULL) { tmp++; http_status = atoi(tmp); - } - tmp = strstr(tmp," "); - if (tmp != NULL) { - tmp++; - if (http_msg) { - efree(http_msg); + tmp = strstr(tmp," "); + if (tmp != NULL) { + tmp++; + if (http_msg) { + efree(http_msg); + } + http_msg = estrdup(tmp); } - http_msg = estrdup(tmp); } efree(http_version); @@ -1071,41 +1085,41 @@ int make_http_soap_request( /* See if the server requested a close */ if (http_1_1) { - http_close = FALSE; + http_close = false; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); + connection = get_http_header_value(http_headers, "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { - http_close = TRUE; + http_close = true; } efree(connection); } } - if (http_close == FALSE) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); + if (http_close == false) { + connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { - http_close = TRUE; + http_close = true; } efree(connection); } } } else { - http_close = TRUE; + http_close = true; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); + connection = get_http_header_value(http_headers, "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { - http_close = FALSE; + http_close = false; } efree(connection); } } - if (http_close == TRUE) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); + if (http_close == true) { + connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { - http_close = FALSE; + http_close = false; } efree(connection); } @@ -1113,7 +1127,7 @@ int make_http_soap_request( } - http_body = get_http_body(stream, http_close, ZSTR_VAL(http_headers)); + http_body = get_http_body(stream, http_close, http_headers); if (!http_body) { if (request != buf) { zend_string_release_ex(request, 0); @@ -1127,7 +1141,7 @@ int make_http_soap_request( efree(http_msg); } smart_str_free(&soap_headers_z); - return FALSE; + return false; } if (request != buf) { @@ -1145,12 +1159,12 @@ int make_http_soap_request( if (http_status >= 300 && http_status < 400) { char *loc; - if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location:")) != NULL) { + if ((loc = get_http_header_value(http_headers, "Location:")) != NULL) { const php_uri_parser *uri_parser = php_uri_get_parser(uri_parser_class); if (uri_parser == NULL) { efree(loc); zend_argument_value_error(6, "must be a valid URI parser name"); - return FALSE; + return false; } php_uri *new_uri = php_uri_parse_to_struct(uri_parser, loc, strlen(loc), PHP_URI_COMPONENT_READ_MODE_RAW, true); @@ -1160,12 +1174,14 @@ int make_http_soap_request( zend_string_release_ex(http_headers, 0); zend_string_release_ex(http_body, 0); if (new_uri->scheme == NULL && new_uri->path != NULL) { - new_uri->scheme = new_uri->scheme ? zend_string_copy(new_uri->scheme) : NULL; - new_uri->host = new_uri->host ? zend_string_copy(new_uri->host) : NULL; - new_uri->port = new_uri->port; + new_uri->scheme = uri->scheme ? zend_string_copy(uri->scheme) : NULL; + if (new_uri->host == NULL) { + new_uri->host = uri->host ? zend_string_copy(uri->host) : NULL; + new_uri->port = uri->port; + } if (new_uri->path && ZSTR_VAL(new_uri->path)[0] != '/') { - if (new_uri->path) { - char *t = ZSTR_VAL(new_uri->path); + if (uri->path) { + char *t = ZSTR_VAL(uri->path); char *p = strrchr(t, '/'); if (p) { zend_string *s = zend_string_concat2(t, (p - t) + 1, ZSTR_VAL(new_uri->path), ZSTR_LEN(new_uri->path)); @@ -1185,7 +1201,7 @@ int make_http_soap_request( add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } goto try_again; @@ -1196,7 +1212,7 @@ int make_http_soap_request( zval *digest = Z_CLIENT_DIGEST_P(this_ptr); zval *login = Z_CLIENT_LOGIN_P(this_ptr); zval *password = Z_CLIENT_PASSWORD_P(this_ptr); - char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate:"); + char *auth = get_http_header_value(http_headers, "WWW-Authenticate:"); if (auth && strstr(auth, "Digest") == auth && Z_TYPE_P(digest) != IS_ARRAY && Z_TYPE_P(login) == IS_STRING && Z_TYPE_P(password) == IS_STRING) { char *s; @@ -1266,7 +1282,7 @@ int make_http_soap_request( smart_str_free(&soap_headers_z); /* Check and see if the server even sent a xml document */ - content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type:"); + content_type = get_http_header_value(http_headers, "Content-Type:"); if (content_type) { char *pos = NULL; int cmplen; @@ -1288,7 +1304,7 @@ int make_http_soap_request( efree(content_type); zend_string_release_ex(http_headers, 0); efree(http_body); - return FALSE; + return false; } */ } @@ -1296,7 +1312,7 @@ int make_http_soap_request( } /* Decompress response */ - content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:"); + content_encoding = get_http_header_value(http_headers, "Content-Encoding:"); if (content_encoding) { zval retval; zval params[1]; @@ -1319,7 +1335,7 @@ int make_http_soap_request( efree(http_msg); } add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL, soap_lang_en); - return FALSE; + return false; } zend_call_known_function(decompression_fn, NULL, NULL, &retval, 1, params, NULL); if (Z_TYPE(retval) == IS_STRING) { @@ -1334,7 +1350,7 @@ int make_http_soap_request( if (http_msg) { efree(http_msg); } - return FALSE; + return false; } efree(content_encoding); } else { @@ -1366,7 +1382,7 @@ int make_http_soap_request( ZVAL_UNDEF(return_value); add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL, soap_lang_en); efree(http_msg); - return FALSE; + return false; } } @@ -1374,7 +1390,7 @@ int make_http_soap_request( efree(http_msg); } - return TRUE; + return true; } static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) @@ -1430,12 +1446,12 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) return NULL; } -static char *get_http_header_value(char *headers, char *type) +static char *get_http_header_value(zend_string *headers, char *type) { size_t len; char *value; - value = get_http_header_value_nodup(headers, type, &len); + value = get_http_header_value_nodup(ZSTR_VAL(headers), type, &len); if (value) { return estrndup(value, len); @@ -1444,22 +1460,27 @@ static char *get_http_header_value(char *headers, char *type) return NULL; } -static zend_string* get_http_body(php_stream *stream, int close, char *headers) +static zend_string* get_http_body(php_stream *stream, bool close, zend_string *headers) { zend_string *http_buf = NULL; char *header; - int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0; + bool header_close = close, header_chunked = false; + int header_length = 0, http_buf_size = 0; if (!close) { header = get_http_header_value(headers, "Connection:"); if (header) { - if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1; + if (!strncasecmp(header, "close", sizeof("close")-1)) { + header_close = true; + } efree(header); } } header = get_http_header_value(headers, "Transfer-Encoding:"); if (header) { - if(!strncasecmp(header, "chunked", sizeof("chunked")-1)) header_chunked = 1; + if (!strncasecmp(header, "chunked", sizeof("chunked")-1)) { + header_chunked = true; + } efree(header); } header = get_http_header_value(headers, "Content-Length:"); @@ -1473,9 +1494,8 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) } if (header_chunked) { - char ch, done, headerbuf[8192]; - - done = FALSE; + char ch, headerbuf[8192]; + bool done = false; while (!done) { int buf_size = 0; @@ -1485,7 +1505,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) if (buf_size > 0) { size_t len_size = 0; - if (http_buf_size + buf_size + 1 < 0) { + if (UNEXPECTED(http_buf_size + buf_size + 1 < 0)) { if (http_buf) { zend_string_release_ex(http_buf, 0); } @@ -1500,9 +1520,9 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) while (len_size < buf_size) { ssize_t len_read = php_stream_read(stream, http_buf->val + http_buf_size, buf_size - len_size); - if (len_read <= 0) { + if (UNEXPECTED(len_read <= 0)) { /* Error or EOF */ - done = TRUE; + done = true; break; } len_size += len_read; @@ -1514,7 +1534,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) if (ch == '\r') { ch = php_stream_getc(stream); } - if (ch != '\n') { + if (UNEXPECTED(ch != '\n')) { /* Something wrong in chunked encoding */ if (http_buf) { zend_string_release_ex(http_buf, 0); @@ -1530,7 +1550,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) return NULL; } if (buf_size == 0) { - done = TRUE; + done = true; } } @@ -1552,13 +1572,13 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) } } else if (header_length) { - if (header_length < 0 || header_length >= INT_MAX) { + if (UNEXPECTED(header_length < 0 || header_length >= INT_MAX)) { return NULL; } http_buf = zend_string_alloc(header_length, 0); while (http_buf_size < header_length) { ssize_t len_read = php_stream_read(stream, http_buf->val + http_buf_size, header_length - http_buf_size); - if (len_read <= 0) { + if (UNEXPECTED(len_read <= 0)) { break; } http_buf_size += len_read; diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index 7716e86720bd..4f13b79f1164 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -19,13 +17,13 @@ #ifndef PHP_HTTP_H #define PHP_HTTP_H -int make_http_soap_request( +bool make_http_soap_request( zval *this_ptr, zend_string *buf, zend_string *location, char *soapaction, int soap_version, zend_string *uri_parser_class, zval *return_value ); -int proxy_authentication(zval* this_ptr, smart_str* soap_headers); -int basic_authentication(zval* this_ptr, smart_str* soap_headers); +bool proxy_authentication(zval* this_ptr, smart_str* soap_headers); +bool basic_authentication(zval* this_ptr, smart_str* soap_headers); void http_context_headers(php_stream_context* context, bool has_authorization, bool has_proxy_authorization, diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 1019949093f0..29ed1294f364 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -18,32 +16,54 @@ #include "php_soap.h" +static void master_to_zval_with_doc_cleanup(zval *ret, encodePtr encode, xmlNodePtr data, xmlDocPtr doc) +{ + bool bailout = false; + + ZVAL_UNDEF(ret); + + /* SoapClient can turn decode errors into a bailout before parse_packet_soap() frees the response doc. */ + zend_try { + master_to_zval(ret, encode, data); + } zend_catch { + bailout = true; + } zend_end_try(); + + if (bailout) { + if (!Z_ISUNDEF_P(ret)) { + zval_ptr_dtor(ret); + } + xmlFreeDoc(doc); + zend_bailout(); + } +} + /* SOAP client calls this function to parse response from SOAP server */ -bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value, zval *soap_headers) +bool parse_packet_soap(zval *this_ptr, zend_string *buffer, sdlFunctionPtr fn, zval *return_value, zval *soap_headers) { - char* envelope_ns = NULL; + const char *envelope_ns = NULL; xmlDocPtr response; - xmlNodePtr trav, env, head, body, resp, cur, fault; + xmlNodePtr trav, env, head, body, resp, fault; xmlAttrPtr attr; - int param_count = 0; + uint32_t param_count = 0; int soap_version = SOAP_1_1; HashTable *hdrs = NULL; ZVAL_NULL(return_value); - /* Response for one-way opearation */ - if (buffer_size == 0) { + /* Response for one-way operation */ + if (ZSTR_LEN(buffer) == 0) { return true; } /* Parse XML packet */ - response = soap_xmlParseMemory(buffer, buffer_size); + response = soap_xmlParseMemory(ZSTR_VAL(buffer), ZSTR_LEN(buffer)); - if (!response) { + if (UNEXPECTED(!response)) { add_soap_fault(this_ptr, "Client", "looks like we got no XML document", NULL, NULL, soap_lang_en); return false; } - if (xmlGetIntSubset(response) != NULL) { + if (UNEXPECTED(xmlGetIntSubset(response) != NULL)) { add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; @@ -70,7 +90,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } trav = trav->next; } - if (env == NULL) { + if (UNEXPECTED(env == NULL)) { add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; @@ -87,7 +107,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; - } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) { + } else if (strcmp((const char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) { add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; @@ -119,7 +139,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio while (trav != NULL && trav->type != XML_ELEMENT_NODE) { trav = trav->next; } - if (body == NULL) { + if (UNEXPECTED(body == NULL)) { add_soap_fault(this_ptr, "Client", "Body must be present in a SOAP envelope", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; @@ -145,7 +165,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } attr = attr->next; } - if (trav != NULL && soap_version == SOAP_1_2) { + if (UNEXPECTED(trav != NULL && soap_version == SOAP_1_2)) { add_soap_fault(this_ptr, "Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; @@ -176,7 +196,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio /* Check if contains element */ fault = get_node_ex(body->children,"Fault",envelope_ns); if (fault != NULL) { - char *faultcode = NULL; + const char *faultcode = NULL; zend_string *lang = ZSTR_EMPTY_ALLOC(); zend_string *faultstring = NULL, *faultactor = NULL; zval details; @@ -186,13 +206,13 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio if (soap_version == SOAP_1_1) { tmp = get_node(fault->children, "faultcode"); if (tmp != NULL && tmp->children != NULL) { - faultcode = (char*)tmp->children->content; + faultcode = (const char*)tmp->children->content; } tmp = get_node(fault->children, "faultstring"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultstring = Z_STR(zv); } @@ -200,21 +220,21 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(fault->children, "faultactor"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultactor = Z_STR(zv); } tmp = get_node(fault->children, "detail"); if (tmp != NULL) { - master_to_zval(&details, NULL, tmp); + master_to_zval_with_doc_cleanup(&details, NULL, tmp, response); } } else { tmp = get_node(fault->children, "Code"); if (tmp != NULL && tmp->children != NULL) { tmp = get_node(tmp->children, "Value"); if (tmp != NULL && tmp->children != NULL) { - faultcode = (char*)tmp->children->content; + faultcode = (const char*)tmp->children->content; } } @@ -223,7 +243,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(tmp->children,"Text"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultstring = Z_STR(zv); @@ -238,10 +258,10 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(fault->children,"Detail"); if (tmp != NULL) { - master_to_zval(&details, NULL, tmp); + master_to_zval_with_doc_cleanup(&details, NULL, tmp, response); } } - add_soap_fault(this_ptr, faultcode, faultstring ? ZSTR_VAL(faultstring) : NULL, faultactor ? ZSTR_VAL(faultactor) : NULL, &details, lang); + add_soap_fault(this_ptr, faultcode, faultstring ? ZSTR_VAL(faultstring) : NULL, faultactor, &details, lang); if (faultstring) { zend_string_release_ex(faultstring, 0); } @@ -267,16 +287,15 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio /* Function has WSDL description */ sdlParamPtr param = NULL; xmlNodePtr val = NULL; - char *name, *ns = NULL; zval tmp; sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; - int res_count; hdrs = fnb->output.headers; if (fn->responseParameters) { - res_count = zend_hash_num_elements(fn->responseParameters); + uint32_t res_count = zend_hash_num_elements(fn->responseParameters); ZEND_HASH_FOREACH_PTR(fn->responseParameters, param) { + const char *name, *ns = NULL; if (fnb->style == SOAP_DOCUMENT) { if (param->element) { name = param->element->name; @@ -294,7 +313,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } /* Get value of parameter */ - cur = get_node_ex(resp, name, ns); + xmlNodePtr cur = get_node_ex(resp, name, ns); if (!cur) { cur = get_node(resp, name); /* TODO: produce warning invalid ns */ @@ -332,9 +351,9 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } else { /* Decoding value of parameter */ if (param != NULL) { - master_to_zval(&tmp, param->encode, val); + master_to_zval_with_doc_cleanup(&tmp, param->encode, val, response); } else { - master_to_zval(&tmp, NULL, val); + master_to_zval_with_doc_cleanup(&tmp, NULL, val, response); } } add_assoc_zval(return_value, param->paramName, &tmp); @@ -353,20 +372,22 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio if (val != NULL) { if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) { zval tmp; - zval *arr; - master_to_zval(&tmp, NULL, val); + master_to_zval_with_doc_cleanup(&tmp, NULL, val, response); if (val->name) { - if ((arr = zend_hash_str_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name))) != NULL) { + const char *val_name = (const char*) val->name; + size_t val_name_len = strlen(val_name); + zval *arr = zend_hash_str_find(Z_ARRVAL_P(return_value), val_name, val_name_len); + if (arr != NULL) { add_next_index_zval(arr, &tmp); - } else if (val->next && get_node(val->next, (char*)val->name)) { - zval arr; + } else if (val->next && get_node(val->next, val_name)) { + zval new_arr; - array_init(&arr); - add_next_index_zval(&arr, &tmp); - add_assoc_zval(return_value, (char*)val->name, &arr); + array_init(&new_arr); + add_next_index_zval(&new_arr, &tmp); + add_assoc_zval_ex(return_value, val_name, val_name_len, &new_arr); } else { - add_assoc_zval(return_value, (char*)val->name, &tmp); + add_assoc_zval_ex(return_value, val_name, val_name_len, &tmp); } } else { add_next_index_zval(return_value, &tmp); @@ -410,18 +431,18 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio sdlSoapBindingFunctionHeaderPtr hdr; if (trav->ns) { - smart_str_appends(&key, (char*)trav->ns->href); + smart_str_appends(&key, (const char*)trav->ns->href); smart_str_appendc(&key,':'); } - smart_str_appends(&key, (char*)trav->name); + smart_str_appends(&key, (const char*)trav->name); smart_str_0(&key); if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) { enc = hdr->encode; } smart_str_free(&key); } - master_to_zval(&val, enc, trav); - add_assoc_zval(soap_headers, (char*)trav->name, &val); + master_to_zval_with_doc_cleanup(&val, enc, trav, response); + add_assoc_zval(soap_headers, (const char*)trav->name, &val); } trav = trav->next; } diff --git a/ext/soap/php_packet_soap.h b/ext/soap/php_packet_soap.h index 5a9fc62418a6..dc4b44176867 100644 --- a/ext/soap/php_packet_soap.h +++ b/ext/soap/php_packet_soap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -19,6 +17,6 @@ #ifndef PHP_PACKET_SOAP_H #define PHP_PACKET_SOAP_H -bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value, zval *soap_headers); +bool parse_packet_soap(zval *this_ptr, zend_string *buffer, sdlFunctionPtr fn, zval *return_value, zval *soap_headers); #endif diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index dc6816034dea..b675b97b469f 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -55,6 +53,28 @@ static bool node_is_equal_xsd(xmlNodePtr node, const char *name) return node_is_equal_ex_one_of(node, name, ns); } +static int schema_parse_int(const xmlChar *value, const char *name, bool allow_negative) +{ + const char *str = (const char *) value; + zend_long lval = 0; + int oflow_info = 0; + uint8_t type = is_numeric_string_ex(str, strlen(str), &lval, NULL, true, &oflow_info, NULL); + + if (type != IS_LONG) { + errno = 0; + lval = ZEND_STRTOL(str, NULL, 10); + if (UNEXPECTED(oflow_info || (errno == ERANGE && lval != 0))) { + soap_error1(E_ERROR, "Parsing Schema: %s value is out of range", name); + } + } + + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(lval) || (!allow_negative && lval < 0))) { + soap_error1(E_ERROR, "Parsing Schema: %s value is out of range", name); + } + + return (int) lval; +} + static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type) { smart_str nscat = {0}; @@ -856,7 +876,7 @@ static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valp soap_error0(E_ERROR, "Parsing Schema: missing restriction value"); } - (*valptr)->value = atoi((char*)value->children->content); + (*valptr)->value = schema_parse_int(value->children->content, (const char *) val->name, true); return TRUE; } @@ -1018,7 +1038,7 @@ void schema_min_max(xmlNodePtr node, sdlContentModelPtr model) xmlAttrPtr attr = get_attribute(node->properties, "minOccurs"); if (attr) { - model->min_occurs = atoi((char*)attr->children->content); + model->min_occurs = schema_parse_int(attr->children->content, "minOccurs", false); } else { model->min_occurs = 1; } @@ -1028,7 +1048,7 @@ void schema_min_max(xmlNodePtr node, sdlContentModelPtr model) if (!strncmp((char*)attr->children->content, "unbounded", sizeof("unbounded"))) { model->max_occurs = -1; } else { - model->max_occurs = atoi((char*)attr->children->content); + model->max_occurs = schema_parse_int(attr->children->content, "maxOccurs", false); } } else { model->max_occurs = 1; diff --git a/ext/soap/php_schema.h b/ext/soap/php_schema.h index 68035000e1e5..b92c8a8fb4c4 100644 --- a/ext/soap/php_schema.h +++ b/ext/soap/php_schema.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index ad37867dd460..73886af5a567 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -1526,22 +1524,22 @@ static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, size_t uri_len char *in, *buf; f = open(fn, O_RDONLY|O_BINARY); - if (f < 0) { + if (UNEXPECTED(f < 0)) { return NULL; } - if (fstat(f, &st) != 0) { + if (UNEXPECTED(fstat(f, &st) != 0)) { close(f); return NULL; } buf = in = emalloc(st.st_size); - if (read(f, in, st.st_size) != st.st_size) { + if (UNEXPECTED(read(f, in, st.st_size) != st.st_size)) { close(f); efree(in); return NULL; } close(f); - if (strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0') { + if (UNEXPECTED(strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0')) { unlink(fn); efree(buf); return NULL; @@ -2098,7 +2096,7 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s zend_string *temp_file_path; f = php_open_temporary_fd_ex(SOAP_GLOBAL(cache_dir), "tmp.wsdl.", &temp_file_path, PHP_TMP_FILE_SILENT); - if (f < 0) {return;} + if (UNEXPECTED(f < 0)) {return;} zend_hash_init(&tmp_types, 0, NULL, NULL, 0); zend_hash_init(&tmp_encoders, 0, NULL, NULL, 0); @@ -3240,7 +3238,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) tmp = Z_CLIENT_USER_AGENT_P(this_ptr); if (Z_TYPE_P(tmp) == IS_STRING && Z_STRLEN_P(tmp) > 0) { smart_str_appends(&headers, "User-Agent: "); - smart_str_appends(&headers, Z_STRVAL_P(tmp)); + smart_str_append(&headers, Z_STR_P(tmp)); smart_str_appends(&headers, "\r\n"); } @@ -3250,7 +3248,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) zval str_proxy; smart_str proxy = {0}; smart_str_appends(&proxy,"tcp://"); - smart_str_appends(&proxy,Z_STRVAL_P(proxy_host)); + smart_str_append(&proxy, Z_STR_P(proxy_host)); smart_str_appends(&proxy,":"); smart_str_append_long(&proxy,Z_LVAL_P(proxy_port)); ZVAL_STR(&str_proxy, smart_str_extract(&proxy)); @@ -3362,7 +3360,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) zend_hash_str_update_mem(SOAP_GLOBAL(mem_cache), uri, uri_len, &p, sizeof(sdl_cache_bucket)); - /* remove non-persitent sdl structure */ + /* remove non-persistent sdl structure */ delete_sdl_impl(sdl); /* and replace it with persistent one */ sdl = psdl; diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 3df4fbdca015..7c9d8ce7382b 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -166,7 +164,7 @@ struct _sdlContentModel { union { sdlTypePtr element; /* pointer to element */ sdlTypePtr group; /* pointer to group */ - HashTable *content; /* array of sdlContentModel for sequnce,all,choice*/ + HashTable *content; /* array of sdlContentModel for sequence,all,choice*/ char *group_ref; /* reference to group */ } u; }; diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index aa3fb79e5709..f35f357ae394 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -197,7 +195,7 @@ extern zend_class_entry* soap_sdl_class_entry; extern HashTable php_soap_defEncNs, php_soap_defEnc, php_soap_defEncIndex; -void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, zend_string *lang); +void add_soap_fault(zval *obj, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *lang); #define soap_error0(severity, format) \ php_error(severity, "SOAP-ERROR: " format) @@ -226,45 +224,41 @@ static zend_always_inline zval *php_soap_deref(zval *zv) { #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) +#define Z_CLIENT_HTTPSOCKET_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 7) +#define Z_CLIENT_HTTPURL_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 8) +#define Z_CLIENT_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 9) +#define Z_CLIENT_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 10) +#define Z_CLIENT_USE_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 11) +#define Z_CLIENT_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 12) +#define Z_CLIENT_PROXY_HOST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 13) +#define Z_CLIENT_PROXY_PORT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 14) +#define Z_CLIENT_PROXY_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 15) +#define Z_CLIENT_PROXY_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 16) +#define Z_CLIENT_EXCEPTIONS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 17) +#define Z_CLIENT_ENCODING_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 18) +#define Z_CLIENT_CLASSMAP_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 19) +#define Z_CLIENT_FEATURES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 20) +#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 21) +#define Z_CLIENT_STREAM_CONTEXT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 22) +#define Z_CLIENT_USER_AGENT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 23) +#define Z_CLIENT_KEEP_ALIVE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 24) +#define Z_CLIENT_SSL_METHOD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 25) +#define Z_CLIENT_SOAP_VERSION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 26) +#define Z_CLIENT_USE_PROXY_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 27) +#define Z_CLIENT_COOKIES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 28) +#define Z_CLIENT_DEFAULT_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 29) +#define Z_CLIENT_SOAP_FAULT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 30) +#define Z_CLIENT_LAST_REQUEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 31) +#define Z_CLIENT_LAST_RESPONSE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 32) +#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 33) +#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 34) typedef struct soap_url_object { php_uri *uri; zend_object std; } soap_url_object; -static inline soap_url_object *soap_url_object_fetch(zend_object *obj) -{ - return (soap_url_object *) ((char *) obj - XtOffsetOf(soap_url_object, std)); -} +#define soap_url_object_fetch(obj) ZEND_CONTAINER_OF(obj, soap_url_object, std) #define Z_SOAP_URL_P(zv) soap_url_object_fetch(Z_OBJ_P(zv)) diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index a2536b98f39b..a4c638410a73 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -150,7 +148,7 @@ xmlNsPtr node_find_ns(xmlNodePtr node) } } -int attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns) +bool attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns) { if (node->name && strcmp((const char *) node->name, name) == 0) { xmlNsPtr nsPtr = node->ns; @@ -158,17 +156,17 @@ int attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns) if (nsPtr) { return (strcmp((const char *) nsPtr->href, ns) == 0); } else { - return FALSE; + return false; } } else if (nsPtr) { - return FALSE; + return false; } - return TRUE; + return true; } - return FALSE; + return false; } -int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns) +bool node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns) { if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) { if (ns) { @@ -176,29 +174,29 @@ int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns) if (nsPtr) { return strcmp((const char *) nsPtr->href, ns) == 0; } else { - return FALSE; + return false; } } - return TRUE; + return true; } - return FALSE; + return false; } -int node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces) +bool node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces) { if ((node->name) && strcmp((char*)node->name, name) == 0) { xmlNsPtr nsPtr = node_find_ns(node); if (nsPtr) { do { if (strcmp((const char *) nsPtr->href, *namespaces) == 0) { - return TRUE; + return true; } namespaces++; } while (*namespaces != NULL); } - return FALSE; + return false; } - return FALSE; + return false; } xmlAttrPtr get_attribute_any_ns(xmlAttrPtr node, const char *name) diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index c967ac09d738..d87f4a758748 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -31,9 +29,9 @@ xmlDocPtr soap_xmlParseFile(const char *filename); xmlDocPtr soap_xmlParseMemory(const void *buf, size_t size); xmlNsPtr node_find_ns(xmlNodePtr node); -int attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns); -int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns); -int node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces); +bool attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns); +bool node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns); +bool node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces); xmlAttrPtr get_attribute_any_ns(xmlAttrPtr node, const char *name); xmlAttrPtr get_attribute_ex(xmlAttrPtr node, const char *name, const char *ns); xmlNodePtr get_node_ex(xmlNodePtr node, const char *name, const char *ns); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 7d4f3d20cff1..171b529b3355 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -50,13 +48,13 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf); static void type_to_string(sdlTypePtr type, smart_str *buf, int level); static void clear_soap_fault(zval *obj); -static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fault_code, const char *fault_string, const char *fault_actor, zval *fault_detail, zend_string *name, zend_string *lang); -static void add_soap_fault_en(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail); -static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, zend_string *lang); -static void add_soap_fault_ex_en(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail); -static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *actor, zval* details, zend_string *name, zend_string *lang); +static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *name, zend_string *lang); +static void add_soap_fault_en(zval *obj, const char *fault_code, const char *fault_string); +static void add_soap_fault_ex(zval *fault, zval *obj, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *lang); +static void add_soap_fault_ex_en(zval *fault, zval *obj, const char *fault_code, const char *fault_string); +static ZEND_NORETURN void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string *name, zend_string *lang); static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr); -static ZEND_NORETURN void soap_server_fault_en(char* code, char* string, char *actor, zval* details, zend_string *name); +static ZEND_NORETURN void soap_server_fault_en(const char *code, const char *string); static sdlParamPtr get_param(sdlFunctionPtr function, const char *param_name, zend_ulong index, int); static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name, size_t function_name_length); @@ -190,6 +188,7 @@ zend_class_entry* soap_var_class_entry; zend_class_entry *soap_url_class_entry; zend_class_entry *soap_sdl_class_entry; +static zend_object_handlers soap_client_object_handlers; static zend_object_handlers soap_server_object_handlers; static zend_object_handlers soap_url_object_handlers; static zend_object_handlers soap_sdl_object_handlers; @@ -201,8 +200,29 @@ typedef struct { zend_object std; } soap_server_object; -static inline soap_server_object *soap_server_object_fetch(zend_object *obj) { - return (soap_server_object *) ((char *) obj - XtOffsetOf(soap_server_object, std)); +typedef struct { + HashTable *typemap; + zend_object std; +} soap_client_object; + +#define soap_client_object_fetch(obj) ZEND_CONTAINER_OF(obj, soap_client_object, std) +#define soap_server_object_fetch(obj) ZEND_CONTAINER_OF(obj, soap_server_object, std) + +static zend_object *soap_client_object_create(zend_class_entry *ce) +{ + soap_client_object *obj = zend_object_alloc(sizeof(soap_client_object), ce); + zend_object_std_init(&obj->std, ce); + object_properties_init(&obj->std, ce); + return &obj->std; +} + +static void soap_client_object_free(zend_object *obj) { + soap_client_object *client_obj = soap_client_object_fetch(obj); + if (client_obj->typemap) { + zend_hash_destroy(client_obj->typemap); + FREE_HASHTABLE(client_obj->typemap); + } + zend_object_std_dtor(obj); } static zend_object *soap_server_object_create(zend_class_entry *ce) @@ -261,10 +281,7 @@ static zend_result soap_url_cast_object(zend_object *obj, zval *result, int type return zend_std_cast_object_tostring(obj, result, type); } -static inline soap_sdl_object *soap_sdl_object_fetch(zend_object *obj) -{ - return (soap_sdl_object *) ((char *) obj - XtOffsetOf(soap_sdl_object, std)); -} +#define soap_sdl_object_fetch(obj) ZEND_CONTAINER_OF(obj, soap_sdl_object, std) #define Z_SOAP_SDL_P(zv) soap_sdl_object_fetch(Z_OBJ_P(zv)) @@ -360,7 +377,7 @@ static PHP_INI_MH(OnUpdateCacheDir) if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { char *p; - if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) != NULL) { + if (zend_str_has_nul_byte(new_value)) { return FAILURE; } @@ -503,6 +520,13 @@ PHP_MINIT_FUNCTION(soap) /* Register SoapClient class */ soap_class_entry = register_class_SoapClient(); + soap_class_entry->create_object = soap_client_object_create; + soap_class_entry->default_object_handlers = &soap_client_object_handlers; + + memcpy(&soap_client_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + soap_client_object_handlers.offset = offsetof(soap_client_object, std); + soap_client_object_handlers.free_obj = soap_client_object_free; + soap_client_object_handlers.clone_obj = NULL; /* Register SoapVar class */ soap_var_class_entry = register_class_SoapVar(); @@ -513,7 +537,7 @@ PHP_MINIT_FUNCTION(soap) soap_server_class_entry->default_object_handlers = &soap_server_object_handlers; memcpy(&soap_server_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_server_object_handlers.offset = XtOffsetOf(soap_server_object, std); + soap_server_object_handlers.offset = offsetof(soap_server_object, std); soap_server_object_handlers.free_obj = soap_server_object_free; soap_server_object_handlers.clone_obj = NULL; @@ -530,7 +554,7 @@ PHP_MINIT_FUNCTION(soap) soap_url_class_entry->default_object_handlers = &soap_url_object_handlers; memcpy(&soap_url_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_url_object_handlers.offset = XtOffsetOf(soap_url_object, std); + soap_url_object_handlers.offset = offsetof(soap_url_object, std); soap_url_object_handlers.free_obj = soap_url_object_free; soap_url_object_handlers.get_constructor = soap_url_object_get_constructor; soap_url_object_handlers.clone_obj = NULL; @@ -542,7 +566,7 @@ PHP_MINIT_FUNCTION(soap) soap_sdl_class_entry->default_object_handlers = &soap_sdl_object_handlers; memcpy(&soap_sdl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_sdl_object_handlers.offset = XtOffsetOf(soap_sdl_object, std); + soap_sdl_object_handlers.offset = offsetof(soap_sdl_object, std); soap_sdl_object_handlers.free_obj = soap_sdl_object_free; soap_sdl_object_handlers.get_constructor = soap_sdl_object_get_constructor; soap_sdl_object_handlers.clone_obj = NULL; @@ -669,8 +693,9 @@ static void soap_fault_dtor_properties(zval *obj) /* {{{ SoapFault constructor */ PHP_METHOD(SoapFault, __construct) { - char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL, *fault_code_ns = NULL; - size_t fault_string_len, fault_actor_len = 0, fault_code_len = 0; + char *fault_string = NULL, *fault_code = NULL, *fault_code_ns = NULL; + size_t fault_string_len, fault_code_len = 0; + zend_string *fault_actor = NULL; zend_string *name = NULL; zend_string *lang = ZSTR_EMPTY_ALLOC(); zval *details = NULL, *headerfault = NULL, *this_ptr; @@ -681,7 +706,7 @@ PHP_METHOD(SoapFault, __construct) Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(code_ht, code_str) Z_PARAM_STRING(fault_string, fault_string_len) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(fault_actor, fault_actor_len) + Z_PARAM_STR_OR_NULL(fault_actor) Z_PARAM_ZVAL_OR_NULL(details) Z_PARAM_STR_OR_NULL(name) Z_PARAM_ZVAL_OR_NULL(headerfault) @@ -730,9 +755,7 @@ PHP_METHOD(SoapFault, __toString) zend_string *faultcode_val, *faultstring_val, *file_val; zend_long line_val; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); this_ptr = ZEND_THIS; faultcode = zend_read_property(soap_fault_class_entry, Z_OBJ_P(this_ptr), "faultcode", sizeof("faultcode")-1, 1, &rv1); @@ -910,103 +933,157 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht) /* {{{ */ /* {{{ SoapServer constructor */ PHP_METHOD(SoapServer, __construct) { - soapServicePtr service; - zval *options = NULL; + HashTable *options = NULL; zend_string *wsdl; int version = SOAP_1_1; zend_long cache_wsdl; HashTable *typemap_ht = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!|a", &wsdl, &options) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!|h", &wsdl, &options) == FAILURE) { RETURN_THROWS(); } - SOAP_SERVER_BEGIN_CODE(); - - service = emalloc(sizeof(soapService)); + soapServicePtr service = emalloc(sizeof(soapService)); memset(service, 0, sizeof(soapService)); - service->send_errors = 1; + service->send_errors = true; cache_wsdl = SOAP_GLOBAL(cache_enabled) ? SOAP_GLOBAL(cache_mode) : 0; if (options != NULL) { - HashTable *ht = Z_ARRVAL_P(options); - zval *tmp; - - if ((tmp = zend_hash_str_find(ht, "soap_version", sizeof("soap_version")-1)) != NULL) { - if (Z_TYPE_P(tmp) == IS_LONG && - (Z_LVAL_P(tmp) == SOAP_1_1 || Z_LVAL_P(tmp) == SOAP_1_2)) { - version = Z_LVAL_P(tmp); - } else { - php_error_docref(NULL, E_ERROR, "'soap_version' option must be SOAP_1_1 or SOAP_1_2"); + const zval *soap_version_zv = zend_hash_str_find(options, ZEND_STRL("soap_version")); + if (soap_version_zv) { + if (UNEXPECTED(Z_TYPE_P(soap_version_zv) != IS_LONG)) { + zend_argument_type_error(2, "\"soap_version\" option must be of type int, %s given", zend_zval_type_name(soap_version_zv)); + goto cleanup; } + zend_long soap_version = Z_LVAL_P(soap_version_zv); + if (UNEXPECTED(soap_version != SOAP_1_1 && soap_version != SOAP_1_2)) { + zend_argument_value_error(2, "\"soap_version\" option must be SOAP_1_1 or SOAP_1_2"); + goto cleanup; + } + version = soap_version; } - if ((tmp = zend_hash_str_find(ht, "uri", sizeof("uri")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - service->uri = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + const zval *uri_zv = zend_hash_str_find(options, ZEND_STRL("uri")); + if (uri_zv) { + if (UNEXPECTED(Z_TYPE_P(uri_zv) != IS_STRING)) { + zend_argument_type_error(2, "\"uri\" option must be of type string, %s given", zend_zval_type_name(uri_zv)); + goto cleanup; + } + service->uri = estrndup(Z_STRVAL_P(uri_zv), Z_STRLEN_P(uri_zv)); } else if (!wsdl) { - php_error_docref(NULL, E_ERROR, "'uri' option is required in nonWSDL mode"); + zend_argument_value_error(2, "\"uri\" option is required when argument #1 ($wsdl) is null"); + goto cleanup; } - if ((tmp = zend_hash_str_find(ht, "actor", sizeof("actor")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - service->actor = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + const zval *actor_zv = zend_hash_str_find(options, ZEND_STRL("actor")); + if (actor_zv) { + if (UNEXPECTED(Z_TYPE_P(actor_zv) != IS_STRING)) { + zend_argument_type_error(2, "\"actor\" option must be of type string, %s given", zend_zval_type_name(actor_zv)); + goto cleanup; + } + service->actor = estrndup(Z_STRVAL_P(actor_zv), Z_STRLEN_P(actor_zv)); } - if ((tmp = zend_hash_str_find(ht, "encoding", sizeof("encoding")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - xmlCharEncodingHandlerPtr encoding; + const zval *encoding_zv = zend_hash_str_find(options, ZEND_STRL("encoding")); + if (encoding_zv) { + if (UNEXPECTED(Z_TYPE_P(encoding_zv) != IS_STRING)) { + zend_argument_type_error(2, "\"encoding\" option must be of type string, %s given", zend_zval_type_name(encoding_zv)); + goto cleanup; + } - encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp)); - if (encoding == NULL) { - php_error_docref(NULL, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp)); - } else { - service->encoding = encoding; + // TODO Check for null bytes? + xmlCharEncodingHandlerPtr encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(encoding_zv)); + if (UNEXPECTED(encoding == NULL)) { + zend_argument_value_error(2, "\"encoding\" option must be a valid encoding, \"%s\" given", Z_STRVAL_P(encoding_zv)); + goto cleanup; } + service->encoding = encoding; } - if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL && - Z_TYPE_P(tmp) == IS_ARRAY) { - if (HT_IS_PACKED(Z_ARRVAL_P(tmp))) { - php_error_docref(NULL, E_ERROR, "'classmap' option must be an associative array"); + const zval *class_map_zv = zend_hash_str_find(options, ZEND_STRL("classmap")); + if (class_map_zv) { + if (UNEXPECTED(Z_TYPE_P(class_map_zv) != IS_ARRAY)) { + zend_argument_type_error(2, "\"classmap\" option must be of type array, %s given", zend_zval_type_name(class_map_zv)); + goto cleanup; + } + // TODO: this still accepts mixed keys arrays and not all numerically indexed arrays are packed + if (UNEXPECTED(HT_IS_PACKED(Z_ARRVAL_P(class_map_zv)))) { + zend_argument_value_error(2, "\"classmap\" option must be an associative array"); + goto cleanup; } - service->class_map = zend_array_dup(Z_ARRVAL_P(tmp)); + service->class_map = zend_array_dup(Z_ARR_P(class_map_zv)); } - if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL && - Z_TYPE_P(tmp) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_P(tmp)) > 0) { - typemap_ht = Z_ARRVAL_P(tmp); + const zval *type_map_zv = zend_hash_str_find(options, ZEND_STRL("typemap")); + if (type_map_zv) { + if (UNEXPECTED(Z_TYPE_P(type_map_zv) != IS_ARRAY)) { + zend_argument_type_error(2, "\"typemap\" option must be of type array, %s given", zend_zval_type_name(type_map_zv)); + goto cleanup; + } + if (zend_hash_num_elements(Z_ARR_P(type_map_zv)) > 0) { + typemap_ht = Z_ARRVAL_P(type_map_zv); + } } - if ((tmp = zend_hash_str_find(ht, "features", sizeof("features")-1)) != NULL && - Z_TYPE_P(tmp) == IS_LONG) { - service->features = Z_LVAL_P(tmp); + const zval *features_zv = zend_hash_str_find(options, ZEND_STRL("features")); + if (features_zv) { + if (UNEXPECTED(Z_TYPE_P(features_zv) != IS_LONG)) { + zend_argument_type_error(2, "\"features\" option must be of type int, %s given", zend_zval_type_name(features_zv)); + goto cleanup; + } + service->features = Z_LVAL_P(features_zv); } - if ((tmp = zend_hash_str_find(ht, "cache_wsdl", sizeof("cache_wsdl")-1)) != NULL && - Z_TYPE_P(tmp) == IS_LONG) { - cache_wsdl = Z_LVAL_P(tmp); + const zval *cache_wsdl_zv = zend_hash_str_find(options, ZEND_STRL("cache_wsdl")); + if (cache_wsdl_zv) { + if (UNEXPECTED(Z_TYPE_P(cache_wsdl_zv) != IS_LONG)) { + zend_argument_type_error(2, "\"cache_wsdl\" option must be of type int, %s given", zend_zval_type_name(cache_wsdl_zv)); + goto cleanup; + } + cache_wsdl = Z_LVAL_P(cache_wsdl_zv); } - if ((tmp = zend_hash_str_find(ht, "send_errors", sizeof("send_errors")-1)) != NULL) { - if (Z_TYPE_P(tmp) == IS_FALSE) { - service->send_errors = 0; - } else if (Z_TYPE_P(tmp) == IS_TRUE) { - service->send_errors = 1; - } else if (Z_TYPE_P(tmp) == IS_LONG) { - service->send_errors = Z_LVAL_P(tmp); + const zval *send_errors_zv = zend_hash_str_find(options, ZEND_STRL("send_errors")); + if (send_errors_zv) { + if (UNEXPECTED(Z_TYPE_P(send_errors_zv) != IS_FALSE && Z_TYPE_P(send_errors_zv) != IS_TRUE && Z_TYPE_P(send_errors_zv) != IS_LONG)) { + zend_argument_type_error(2, "\"send_errors\" option must be of type bool, %s given", zend_zval_type_name(send_errors_zv)); + goto cleanup; + } + switch (Z_TYPE_P(send_errors_zv)) { + case IS_FALSE: + service->send_errors = false; + break; + case IS_TRUE: + service->send_errors = true; + break; + case IS_LONG: + service->send_errors = Z_LVAL_P(send_errors_zv); + break; } } - if ((tmp = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_TRACE))) != NULL && - (Z_TYPE_P(tmp) == IS_TRUE || - (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 1))) { - service->trace = true; + const zval *trace_zv = zend_hash_find(options, ZSTR_KNOWN(ZEND_STR_TRACE)); + if (trace_zv) { + if (UNEXPECTED(Z_TYPE_P(trace_zv) != IS_FALSE && Z_TYPE_P(trace_zv) != IS_TRUE && Z_TYPE_P(trace_zv) != IS_LONG)) { + zend_argument_type_error(2, "\"trace\" option must be of type bool, %s given", zend_zval_type_name(trace_zv)); + goto cleanup; + } + switch (Z_TYPE_P(trace_zv)) { + case IS_FALSE: + service->trace = false; + break; + case IS_TRUE: + service->trace = true; + break; + case IS_LONG: + service->trace = Z_LVAL_P(trace_zv); + break; + } } } else if (!wsdl) { - php_error_docref(NULL, E_ERROR, "'uri' option is required in nonWSDL mode"); + zend_argument_value_error(2, "\"uri\" option is required when argument #1 ($wsdl) is null"); + goto cleanup; } service->version = version; @@ -1014,6 +1091,7 @@ PHP_METHOD(SoapServer, __construct) service->soap_functions.functions_all = FALSE; service->soap_functions.ft = zend_new_array(0); + SOAP_SERVER_BEGIN_CODE(); if (wsdl) { zend_try { service->sdl = get_sdl(ZEND_THIS, ZSTR_VAL(wsdl), cache_wsdl); @@ -1040,6 +1118,11 @@ PHP_METHOD(SoapServer, __construct) server_obj->service = service; SOAP_SERVER_END_CODE(); + return; + +cleanup: + delete_service(service); + RETURN_THROWS(); } /* }}} */ @@ -1134,9 +1217,7 @@ PHP_METHOD(SoapServer, getFunctions) soapServicePtr service; HashTable *ft = NULL; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); FETCH_THIS_SERVICE_NO_BAILOUT(service); @@ -1265,10 +1346,10 @@ static void _soap_server_exception(soapServicePtr service, sdlFunctionPtr functi if (service->send_errors) { zval rv; zend_string *msg = zval_get_string(zend_read_property_ex(zend_ce_error, Z_OBJ(exception_object), ZSTR_KNOWN(ZEND_STR_MESSAGE), /* silent */ false, &rv)); - add_soap_fault_ex_en(&exception_object, this_ptr, "Server", ZSTR_VAL(msg), NULL, NULL); + add_soap_fault_ex_en(&exception_object, this_ptr, "Server", ZSTR_VAL(msg)); zend_string_release_ex(msg, 0); } else { - add_soap_fault_ex_en(&exception_object, this_ptr, "Server", "Internal Error", NULL, NULL); + add_soap_fault_ex_en(&exception_object, this_ptr, "Server", "Internal Error"); } soap_server_fault_ex(function, &exception_object, NULL); } @@ -1308,7 +1389,7 @@ PHP_METHOD(SoapServer, handle) SOAP_GLOBAL(soap_version) = service->version; if (arg && ZEND_SIZE_T_INT_OVFL(arg_len)) { - soap_server_fault_en("Server", "Input string is too long", NULL, NULL, NULL); + soap_server_fault_en("Server", "Input string is too long"); SOAP_SERVER_END_CODE(); return; } @@ -1334,13 +1415,13 @@ PHP_METHOD(SoapServer, handle) php_stream_passthru(stream); php_stream_close(stream); } else { - soap_server_fault_en("Server", "Couldn't find WSDL", NULL, NULL, NULL); + soap_server_fault_en("Server", "Couldn't find WSDL"); } SOAP_SERVER_END_CODE(); return; } else { - soap_server_fault_en("Server", "WSDL generation is not supported yet", NULL, NULL, NULL); + soap_server_fault_en("Server", "WSDL generation is not supported yet"); /* sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8"), 1); PUTS("\n 0) { + soap_action = Z_STRVAL_P(soap_action_z); + } } doc_request = soap_xmlParseFile("php://input"); @@ -1413,7 +1494,7 @@ PHP_METHOD(SoapServer, handle) } if (doc_request == NULL) { - soap_server_fault_en("Client", "Bad Request", NULL, NULL, NULL); + soap_server_fault_en("Client", "Bad Request"); } if (xmlGetIntSubset(doc_request) != NULL) { xmlNodePtr env = get_node(doc_request->children,"Envelope"); @@ -1425,7 +1506,7 @@ PHP_METHOD(SoapServer, handle) } } xmlFreeDoc(doc_request); - soap_server_fault_en("Server", "DTD are not supported by SOAP", NULL, NULL, NULL); + soap_server_fault_en("Server", "DTD are not supported by SOAP"); } old_sdl = SOAP_GLOBAL(sdl); @@ -1483,7 +1564,7 @@ PHP_METHOD(SoapServer, handle) soap_obj = tmp_soap_p; } else if (Z_OBJCE_P(tmp_soap_p) == php_ce_incomplete_class) { /* See #51561, communicate limitation to user */ - soap_server_fault_en("Server", "SoapServer class was deserialized from the session prior to loading the class passed to SoapServer::setClass(). Start the session after loading all classes to resolve this issue.", NULL, NULL, NULL); + soap_server_fault_en("Server", "SoapServer class was deserialized from the session prior to loading the class passed to SoapServer::setClass(). Start the session after loading all classes to resolve this issue."); } } } @@ -1542,7 +1623,7 @@ PHP_METHOD(SoapServer, handle) #if 0 if (service->sdl && !h->function && !h->hdr) { if (h->mustUnderstand) { - soap_server_fault_en("MustUnderstand","Header not understood", NULL, NULL, NULL); + soap_server_fault_en("MustUnderstand","Header not understood"); } else { continue; } @@ -1564,16 +1645,24 @@ PHP_METHOD(SoapServer, handle) instanceof_function(Z_OBJCE(h->retval), soap_fault_class_entry)) { php_output_discard(); soap_server_fault_ex(function, &h->retval, h); - if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);} + if (service->type == SOAP_CLASS && soap_obj) { + if (service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) { + zval_ptr_dtor(soap_obj); + } + } goto fail; } else if (EG(exception)) { php_output_discard(); _soap_server_exception(service, function, ZEND_THIS); - if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);} + if (service->type == SOAP_CLASS && soap_obj) { + if (service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) { + zval_ptr_dtor(soap_obj); + } + } goto fail; } } else if (h->mustUnderstand) { - soap_server_fault_en("MustUnderstand","Header not understood", NULL, NULL, NULL); + soap_server_fault_en("MustUnderstand","Header not understood"); } } } @@ -1665,7 +1754,7 @@ PHP_METHOD(SoapServer, handle) sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1); } - if (INI_INT("zlib.output_compression")) { + if (zend_ini_long_literal("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); @@ -1732,16 +1821,17 @@ PHP_METHOD(SoapServer, handle) /* {{{ Issue SoapFault indicating an error */ PHP_METHOD(SoapServer, fault) { - char *code, *string, *actor=NULL; - size_t code_len, string_len, actor_len = 0; + char *code, *string; + size_t code_len, string_len; + zend_string *actor = NULL; zval* details = NULL; zend_string *name = NULL; zend_string *lang = ZSTR_EMPTY_ALLOC(); soapServicePtr service; xmlCharEncodingHandlerPtr old_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|szSP", - &code, &code_len, &string, &string_len, &actor, &actor_len, &details, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|SzSP", + &code, &code_len, &string, &string_len, &actor, &details, &name, &lang) == FAILURE) { RETURN_THROWS(); } @@ -1827,7 +1917,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade if (use_http_error_status) { sapi_add_header("HTTP/1.1 500 Internal Server Error", sizeof("HTTP/1.1 500 Internal Server Error")-1, 1); } - if (INI_INT("zlib.output_compression")) { + if (zend_ini_long_literal("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); @@ -1847,7 +1937,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade } /* }}} */ -static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *actor, zval* details, zend_string* name, zend_string *lang) /* {{{ */ +static ZEND_NORETURN void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string* name, zend_string *lang) /* {{{ */ { zval ret; @@ -1859,9 +1949,9 @@ static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *acto } /* }}} */ -static ZEND_NORETURN void soap_server_fault_en(char* code, char* string, char *actor, zval* details, zend_string* name) +static ZEND_NORETURN void soap_server_fault_en(const char *code, const char *string) { - soap_server_fault(code, string, actor, details, name, soap_lang_en); + soap_server_fault(code, string, NULL, NULL, NULL, soap_lang_en); } static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message) /* {{{ */ @@ -1887,7 +1977,7 @@ static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, z code = "Client"; } - add_soap_fault_ex_en(&fault, &SOAP_GLOBAL(error_object), code, ZSTR_VAL(message), NULL, NULL); + add_soap_fault_ex_en(&fault, &SOAP_GLOBAL(error_object), code, ZSTR_VAL(message)); Z_ADDREF(fault); zend_throw_exception_object(&fault); zend_bailout(); @@ -1921,7 +2011,7 @@ static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, z } else { buffer = zend_string_copy(message); - /* Get output buffer and send as fault detials */ + /* Get output buffer and send as fault details */ zval outbuflen; if (php_output_get_length(&outbuflen) != FAILURE && Z_LVAL(outbuflen) != 0) { php_output_get_contents(&outbuf); @@ -1997,6 +2087,7 @@ PHP_FUNCTION(is_soap_fault) /* SoapClient functions */ /* {{{ SoapClient constructor */ +/* FIXME: double construct call will break this class */ PHP_METHOD(SoapClient, __construct) { @@ -2133,7 +2224,7 @@ PHP_METHOD(SoapClient, __construct) xmlCharEncodingHandlerPtr encoding; encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp)); - if (encoding == NULL) { + if (UNEXPECTED(encoding == NULL)) { php_error_docref(NULL, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp)); } else { xmlCharEncCloseFunc(encoding); @@ -2142,7 +2233,7 @@ PHP_METHOD(SoapClient, __construct) } if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL && Z_TYPE_P(tmp) == IS_ARRAY) { - if (HT_IS_PACKED(Z_ARRVAL_P(tmp))) { + if (UNEXPECTED(HT_IS_PACKED(Z_ARRVAL_P(tmp)))) { php_error_docref(NULL, E_ERROR, "'classmap' option must be an associative array"); } ZVAL_COPY(Z_CLIENT_CLASSMAP_P(this_ptr), tmp); @@ -2220,10 +2311,7 @@ PHP_METHOD(SoapClient, __construct) } if (typemap_ht) { - HashTable *typemap = soap_create_typemap(sdl, typemap_ht); - if (typemap) { - ZVAL_ARR(Z_CLIENT_TYPEMAP_P(this_ptr), typemap); - } + soap_client_object_fetch(Z_OBJ_P(this_ptr))->typemap = soap_create_typemap(sdl, typemap_ht); } SOAP_CLIENT_END_CODE(); } @@ -2241,10 +2329,14 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size); if (!buf) { - add_soap_fault_en(this_ptr, "HTTP", "Error build soap request", NULL, NULL); + add_soap_fault_en(this_ptr, "HTTP", "Error build soap request"); return false; } + ZVAL_UNDEF(¶ms[0]); + ZVAL_UNDEF(¶ms[1]); + ZVAL_UNDEF(¶ms[2]); + zend_try { ZVAL_STRINGL(¶ms[0], buf, buf_size); ZVAL_STRING(¶ms[1], location); @@ -2271,7 +2363,7 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co if (EG(exception) && instanceof_function(EG(exception)->ce, zend_ce_error)) { /* Programmer error in __doRequest() implementation, let it bubble up. */ } else if (Z_TYPE_P(Z_CLIENT_SOAP_FAULT_P(this_ptr)) != IS_OBJECT) { - add_soap_fault_en(this_ptr, "Client", "SoapClient::__doRequest() returned non string value", NULL, NULL); + add_soap_fault_en(this_ptr, "Client", "SoapClient::__doRequest() returned non string value"); } ret = false; } else if (Z_TYPE_P(trace) == IS_TRUE) { @@ -2351,10 +2443,7 @@ static void do_soap_call(zend_execute_data *execute_data, sdl = Z_SOAP_SDL_P(tmp)->sdl; } - tmp = Z_CLIENT_TYPEMAP_P(this_ptr); - if (Z_TYPE_P(tmp) == IS_ARRAY) { - typemap = Z_ARR_P(tmp); - } + typemap = soap_client_object_fetch(Z_OBJ_P(this_ptr))->typemap; clear_soap_fault(this_ptr); @@ -2418,9 +2507,19 @@ static void do_soap_call(zend_execute_data *execute_data, request = NULL; if (ret && Z_TYPE(response) == IS_STRING) { + bool parse_bailout = false; + encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers); + zend_try { + ret = parse_packet_soap(this_ptr, Z_STR(response), fn, return_value, output_headers); + } zend_catch { + parse_bailout = true; + } zend_end_try(); encode_finish(); + if (parse_bailout) { + zval_ptr_dtor(&response); + zend_bailout(); + } } zval_ptr_dtor(&response); @@ -2431,15 +2530,15 @@ static void do_soap_call(zend_execute_data *execute_data, smart_str_append(&error,function); smart_str_appends(&error,"\") is not a valid method for this service"); smart_str_0(&error); - add_soap_fault_en(this_ptr, "Client", ZSTR_VAL(error.s), NULL, NULL); + add_soap_fault_en(this_ptr, "Client", ZSTR_VAL(error.s)); smart_str_free(&error); } } else { zval *uri = Z_CLIENT_URI_P(this_ptr); if (Z_TYPE_P(uri) != IS_STRING) { - add_soap_fault_en(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL); + add_soap_fault_en(this_ptr, "Client", "Error finding \"uri\" property"); } else if (location == NULL) { - add_soap_fault_en(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL); + add_soap_fault_en(this_ptr, "Client", "Error could not find \"location\" property"); } else { if (call_uri == NULL) { call_uri = Z_STR_P(uri); @@ -2462,9 +2561,19 @@ static void do_soap_call(zend_execute_data *execute_data, request = NULL; if (ret && Z_TYPE(response) == IS_STRING) { + bool parse_bailout = false; + encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers); + zend_try { + ret = parse_packet_soap(this_ptr, Z_STR(response), NULL, return_value, output_headers); + } zend_catch { + parse_bailout = true; + } zend_end_try(); encode_finish(); + if (parse_bailout) { + zval_ptr_dtor(&response); + zend_bailout(); + } } zval_ptr_dtor(&response); @@ -2476,7 +2585,7 @@ static void do_soap_call(zend_execute_data *execute_data, if (Z_TYPE_P(fault) == IS_OBJECT) { ZVAL_COPY(return_value, fault); } else { - add_soap_fault_ex_en(return_value, this_ptr, "Client", "Unknown Error", NULL, NULL); + add_soap_fault_ex_en(return_value, this_ptr, "Client", "Unknown Error"); Z_ADDREF_P(return_value); } } else { @@ -2692,9 +2801,7 @@ PHP_METHOD(SoapClient, __soapCall) /* {{{ Returns list of SOAP functions */ PHP_METHOD(SoapClient, __getFunctions) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sdl *sdl; FETCH_THIS_SDL(sdl); @@ -2717,9 +2824,7 @@ PHP_METHOD(SoapClient, __getFunctions) /* {{{ Returns list of SOAP types */ PHP_METHOD(SoapClient, __getTypes) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sdl *sdl; FETCH_THIS_SDL(sdl); @@ -2744,9 +2849,7 @@ PHP_METHOD(SoapClient, __getTypes) /* {{{ Returns last SOAP request */ PHP_METHOD(SoapClient, __getLastRequest) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_REQUEST_P(ZEND_THIS)); } @@ -2756,9 +2859,7 @@ PHP_METHOD(SoapClient, __getLastRequest) /* {{{ Returns last SOAP response */ PHP_METHOD(SoapClient, __getLastResponse) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_RESPONSE_P(ZEND_THIS)); } @@ -2768,9 +2869,7 @@ PHP_METHOD(SoapClient, __getLastResponse) /* {{{ Returns last SOAP request headers */ PHP_METHOD(SoapClient, __getLastRequestHeaders) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_REQUEST_HEADERS_P(ZEND_THIS)); } @@ -2780,9 +2879,7 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders) /* {{{ Returns last SOAP response headers */ PHP_METHOD(SoapClient, __getLastResponseHeaders) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(ZEND_THIS)); } @@ -2821,7 +2918,7 @@ PHP_METHOD(SoapClient, __doRequest) } /* }}} */ -/* {{{ Sets cookie thet will sent with SOAP request. +/* {{{ Sets cookie that will sent with SOAP request. The call to this function will effect all following calls of SOAP methods. If value is not specified cookie is removed. */ PHP_METHOD(SoapClient, __setCookie) @@ -2848,9 +2945,7 @@ PHP_METHOD(SoapClient, __setCookie) /* {{{ Returns list of cookies */ PHP_METHOD(SoapClient, __getCookies) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_COOKIES_P(ZEND_THIS)); } @@ -2924,7 +3019,7 @@ static void clear_soap_fault(zval *obj) /* {{{ */ } /* }}} */ -static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, zend_string *lang) /* {{{ */ +static void add_soap_fault_ex(zval *fault, zval *obj, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *lang) /* {{{ */ { ZVAL_NULL(fault); set_soap_fault(fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL, lang); @@ -2941,24 +3036,24 @@ static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fa } /* }}} */ -static void add_soap_fault_ex_en(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail) +static void add_soap_fault_ex_en(zval *fault, zval *obj, const char *fault_code, const char *fault_string) { - add_soap_fault_ex(fault, obj, fault_code, fault_string, fault_actor, fault_detail, soap_lang_en); + add_soap_fault_ex(fault, obj, fault_code, fault_string, NULL, NULL, soap_lang_en); } -void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, zend_string *lang) /* {{{ */ +void add_soap_fault(zval *obj, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *lang) /* {{{ */ { zval fault; add_soap_fault_ex(&fault, obj, fault_code, fault_string, fault_actor, fault_detail, lang); } /* }}} */ -static void add_soap_fault_en(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail) +static void add_soap_fault_en(zval *obj, const char *fault_code, const char *fault_string) { - add_soap_fault(obj, fault_code, fault_string, fault_actor, fault_detail, soap_lang_en); + add_soap_fault(obj, fault_code, fault_string, NULL, NULL, soap_lang_en); } -static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fault_code, const char *fault_string, const char *fault_actor, zval *fault_detail, zend_string *name, zend_string *lang) /* {{{ */ +static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *name, zend_string *lang) /* {{{ */ { if (Z_TYPE_P(obj) != IS_OBJECT) { object_init_ex(obj, soap_fault_class_entry); @@ -3001,7 +3096,7 @@ static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fau } } if (fault_actor != NULL) { - ZVAL_STRING(Z_FAULT_ACTOR_P(obj), fault_actor); + ZVAL_STR_COPY(Z_FAULT_ACTOR_P(obj), fault_actor); } if (fault_detail != NULL && Z_TYPE_P(fault_detail) != IS_UNDEF) { ZVAL_COPY(Z_FAULT_DETAIL_P(obj), fault_detail); @@ -3080,7 +3175,7 @@ static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, u sdlParamPtr param = NULL; if (function != NULL && (param = zend_hash_index_find_ptr(function->requestParameters, cur_param)) == NULL) { - soap_server_fault_en("Client", "Error cannot find parameter", NULL, NULL, NULL); + soap_server_fault_en("Client", "Error cannot find parameter"); } if (param == NULL) { enc = NULL; @@ -3095,7 +3190,7 @@ static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, u } } if (num_of_params > cur_param) { - soap_server_fault_en("Client","Missing parameter", NULL, NULL, NULL); + soap_server_fault_en("Client","Missing parameter"); } (*parameters) = tmp_parameters; (*num_params) = num_of_params; @@ -3150,6 +3245,10 @@ static sdlFunctionPtr find_function_using_soap_action(const sdl *sdl, const char soap_action_length -= 2; } + if (UNEXPECTED(soap_action_length == 0)) { + return NULL; + } + /* TODO: This may depend on a particular target namespace, in which case this won't find a match when multiple different * target namespaces are used until #45282 is resolved. */ sdlFunctionPtr function; @@ -3182,7 +3281,7 @@ static xmlNodePtr get_envelope(xmlNodePtr trav, int *version, char **envelope_ns return trav; } - soap_server_fault_en("VersionMismatch", "Wrong Version", NULL, NULL, NULL); + soap_server_fault_en("VersionMismatch", "Wrong Version"); } trav = trav->next; } @@ -3202,18 +3301,18 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c /* Get element */ env = get_envelope(request->children, version, &envelope_ns); if (!env) { - soap_server_fault_en("Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, NULL); + soap_server_fault_en("Client", "looks like we got XML without \"Envelope\" element"); } attr = env->properties; while (attr != NULL) { if (attr->ns == NULL) { - soap_server_fault_en("Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL, NULL); + soap_server_fault_en("Client", "A SOAP Envelope element cannot have non Namespace qualified attributes"); } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (*version == SOAP_1_2) { - soap_server_fault_en("Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, NULL); + soap_server_fault_en("Client", "encodingStyle cannot be specified on the Envelope"); } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) { - soap_server_fault_en("Client", "Unknown data encoding style", NULL, NULL, NULL); + soap_server_fault_en("Client", "Unknown data encoding style"); } } attr = attr->next; @@ -3243,26 +3342,26 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c trav = trav->next; } if (body == NULL) { - soap_server_fault_en("Client", "Body must be present in a SOAP envelope", NULL, NULL, NULL); + soap_server_fault_en("Client", "Body must be present in a SOAP envelope"); } attr = body->properties; while (attr != NULL) { if (attr->ns == NULL) { if (*version == SOAP_1_2) { - soap_server_fault_en("Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL, NULL); + soap_server_fault_en("Client", "A SOAP Body element cannot have non Namespace qualified attributes"); } } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (*version == SOAP_1_2) { - soap_server_fault_en("Client", "encodingStyle cannot be specified on the Body", NULL, NULL, NULL); + soap_server_fault_en("Client", "encodingStyle cannot be specified on the Body"); } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) { - soap_server_fault_en("Client", "Unknown data encoding style", NULL, NULL, NULL); + soap_server_fault_en("Client", "Unknown data encoding style"); } } attr = attr->next; } if (trav != NULL && *version == SOAP_1_2) { - soap_server_fault_en("Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, NULL); + soap_server_fault_en("Client", "A SOAP 1.2 envelope can contain only Header and Body"); } func = NULL; @@ -3271,7 +3370,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c if (trav->type == XML_ELEMENT_NODE) { /* if (func != NULL) { - soap_server_fault_en("Client", "looks like we got \"Body\" with several functions call", NULL, NULL, NULL); + soap_server_fault_en("Client", "looks like we got \"Body\" with several functions call"); } */ func = trav; @@ -3288,19 +3387,19 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c if (function) { ZVAL_STRING(function_name, (char *)function->functionName); } else { - soap_server_fault_en("Client", "looks like we got \"Body\" without function call", NULL, NULL, NULL); + soap_server_fault_en("Client", "looks like we got \"Body\" without function call"); } } } else { if (*version == SOAP_1_1) { attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE); if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) { - soap_server_fault_en("Client","Unknown Data Encoding Style", NULL, NULL, NULL); + soap_server_fault_en("Client","Unknown Data Encoding Style"); } } else { attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE); if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) { - soap_server_fault_en("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL); + soap_server_fault_en("DataEncodingUnknown","Unknown Data Encoding Style"); } } if (!function) { @@ -3308,7 +3407,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c } if (sdl != NULL && function == NULL) { if (*version == SOAP_1_2) { - soap_server_fault_en("rpc:ProcedureNotPresent","Procedure not present", NULL, NULL, NULL); + soap_server_fault_en("rpc:ProcedureNotPresent","Procedure not present"); } else { php_error(E_ERROR, "Procedure '%s' not present", func->name); } @@ -3322,12 +3421,12 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c attr = head->properties; while (attr != NULL) { if (attr->ns == NULL) { - soap_server_fault_en("Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL, NULL); + soap_server_fault_en("Client", "A SOAP Header element cannot have non Namespace qualified attributes"); } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (*version == SOAP_1_2) { - soap_server_fault_en("Client", "encodingStyle cannot be specified on the Header", NULL, NULL, NULL); + soap_server_fault_en("Client", "encodingStyle cannot be specified on the Header"); } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) { - soap_server_fault_en("Client", "Unknown data encoding style", NULL, NULL, NULL); + soap_server_fault_en("Client", "Unknown data encoding style"); } } attr = attr->next; @@ -3341,7 +3440,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c if (*version == SOAP_1_1) { attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE); if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) { - soap_server_fault_en("Client","Unknown Data Encoding Style", NULL, NULL, NULL); + soap_server_fault_en("Client","Unknown Data Encoding Style"); } attr = get_attribute_ex(hdr_func->properties,"actor",envelope_ns); if (attr != NULL) { @@ -3353,7 +3452,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c } else if (*version == SOAP_1_2) { attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE); if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) { - soap_server_fault_en("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL); + soap_server_fault_en("DataEncodingUnknown","Unknown Data Encoding Style"); } attr = get_attribute_ex(hdr_func->properties,"role",envelope_ns); if (attr != NULL) { @@ -3373,7 +3472,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c strcmp((char*)attr->children->content,"false") == 0) { mustUnderstand = 0; } else { - soap_server_fault_en("Client","mustUnderstand value is not boolean", NULL, NULL, NULL); + soap_server_fault_en("Client","mustUnderstand value is not boolean"); } } h = emalloc(sizeof(soapHeader)); @@ -3390,7 +3489,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c smart_str_appends(&key, (char*)hdr_func->ns->href); smart_str_appendc(&key, ':'); } - smart_str_appendl(&key, Z_STRVAL(h->function_name), Z_STRLEN(h->function_name)); + smart_str_append(&key, Z_STR(h->function_name)); smart_str_0(&key); if ((hdr = zend_hash_find_ptr(fnb->input.headers, key.s)) != NULL) { h->hdr = hdr; @@ -3602,7 +3701,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENV_NAMESPACE), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX)); xmlSetNs(envelope,ns); } else { - soap_server_fault_en("Server", "Unknown SOAP version", NULL, NULL, NULL); + soap_server_fault_en("Server", "Unknown SOAP version"); } xmlDocSetRootElement(doc, envelope); @@ -3627,14 +3726,14 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu tmp = Z_HEADER_NAMESPACE_P(hdr_ret); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); smart_str_appendc(&key, ':'); hdr_ns = Z_STRVAL_P(tmp); } tmp = Z_HEADER_NAME_P(hdr_ret); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); hdr_name = Z_STRVAL_P(tmp); } smart_str_0(&key); @@ -3860,13 +3959,13 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu tmp = Z_HEADER_NAMESPACE_P(&h->retval); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); smart_str_appendc(&key, ':'); hdr_ns = Z_STRVAL_P(tmp); } tmp = Z_HEADER_NAME_P(&h->retval); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); hdr_name = Z_STRVAL_P(tmp); } smart_str_0(&key); @@ -4102,9 +4201,9 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function smart_str key = {0}; sdlSoapBindingFunctionHeaderPtr hdr; - smart_str_appendl(&key, Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + smart_str_append(&key, Z_STR_P(ns)); smart_str_appendc(&key, ':'); - smart_str_appendl(&key, Z_STRVAL_P(name), Z_STRLEN_P(name)); + smart_str_append(&key, Z_STR_P(name)); smart_str_0(&key); if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) { hdr_use = hdr->use; @@ -4437,7 +4536,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ smart_str_appendc(&spaces, ' '); } if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } switch (type->kind) { case XSD_TYPEKIND_SIMPLE: @@ -4576,7 +4675,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } if (enc) { if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, ' '); smart_str_appends(buf, type->encode->details.type_str); @@ -4591,7 +4690,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ ZEND_HASH_FOREACH_PTR(type->attributes, attr) { if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, ' '); if (attr->encode && attr->encode->details.type_str) { @@ -4605,7 +4704,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } ZEND_HASH_FOREACH_END(); } if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, '}'); } diff --git a/ext/soap/soap.stub.php b/ext/soap/soap.stub.php index 851b32042bd1..fdd4a46e109f 100644 --- a/ext/soap/soap.stub.php +++ b/ext/soap/soap.stub.php @@ -541,7 +541,6 @@ class SoapClient private bool $trace = false; private ?int $compression = null; private ?Soap\Sdl $sdl = null; - private ?array $typemap = null; /** @var resource|null */ private $httpsocket = null; private ?Soap\Url $httpurl = null; diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index e3fdd48e58ff..2f7d56ca4221 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit soap.stub.php instead. - * Stub hash: 24e266bf0933d5622f2a341db5b694ecb1740f13 */ + * Stub hash: 14c74a5d6f547837f536920d5abb741e2b6e4373 */ 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") @@ -575,12 +575,6 @@ static zend_class_entry *register_class_SoapClient(void) zend_declare_typed_property(class_entry, property_sdl_name, &property_sdl_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_sdl_class_Soap_Sdl, 0, MAY_BE_NULL)); zend_string_release_ex(property_sdl_name, true); - zval property_typemap_default_value; - ZVAL_NULL(&property_typemap_default_value); - zend_string *property_typemap_name = zend_string_init("typemap", sizeof("typemap") - 1, true); - zend_declare_typed_property(class_entry, property_typemap_name, &property_typemap_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release_ex(property_typemap_name, true); - zval property_httpsocket_default_value; ZVAL_NULL(&property_httpsocket_default_value); zend_string *property_httpsocket_name = zend_string_init("httpsocket", sizeof("httpsocket") - 1, true); diff --git a/ext/soap/tests/GHSA-85c2-q967-79q5.phpt b/ext/soap/tests/GHSA-85c2-q967-79q5.phpt new file mode 100644 index 000000000000..8bcac26ad187 --- /dev/null +++ b/ext/soap/tests/GHSA-85c2-q967-79q5.phpt @@ -0,0 +1,61 @@ +--TEST-- +GHSA-85c2-q967-79q5: Stale SOAP_GLOBAL(ref_map) pointer with Apache Map +--CREDITS-- +brettgervasoni +--EXTENSIONS-- +soap +--FILE-- + + + + + + + + foo + bar + + + foo + baz + + + + + + +XML; + +$s = new SoapServer(null, ['uri' => 'urn:a']); +$s->setClass(Handler::class); +$s->handle($envelope); +var_dump($result); + +?> +--EXPECTF-- + + +array(2) { + [0]=> + array(1) { + ["foo"]=> + string(3) "baz" + } + [1]=> + object(stdClass)#%d (1) { + ["object"]=> + string(3) "bar" + } +} diff --git a/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt b/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt new file mode 100644 index 000000000000..e46ab2e4607d --- /dev/null +++ b/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt @@ -0,0 +1,39 @@ +--TEST-- +GHSA-hmxp-6pc4-f3vv: Null pointer dereference on missing Apache map value +--CREDITS-- +Ilia Alshanetsky (iliaal) +--EXTENSIONS-- +soap +--FILE-- + + + + + + + hello + + + + +XML; + +$server = new SoapServer(null, [ + 'uri' => 'urn:test', + 'typemap' => [['type_name' => 'anything']], +]); +$server->addFunction('test'); +function test($m) { return null; } +$server->handle($request); + +?> +--EXPECT-- + +SOAP-ENV:ServerSOAP-ERROR: Encoding: Can't decode apache map, missing value diff --git a/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt b/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt new file mode 100644 index 000000000000..bcf441ccd18a --- /dev/null +++ b/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt @@ -0,0 +1,58 @@ +--TEST-- +GHSA-m33r-qmcv-p97q: Use-after-free after header parsing failure with SOAP_PERSISTENCE_SESSION +--CREDITS-- +Ilia Alshanetsky (iliaal) +--EXTENSIONS-- +soap +session +--FILE-- + 'urn:a']); +$srv->setClass(Handler::class); +$srv->setPersistence(SOAP_PERSISTENCE_SESSION); + +$srv->handle(<< + + + + + + + + +XML); + +$srv->handle(<< + + + + + + + + +XML); + +?> +--EXPECT-- + +SOAP-ENV:Serverdenied + +SOAP-ENV:Serverdenied diff --git a/ext/soap/tests/SoapServer/SoapServer_constructor_errors.phpt b/ext/soap/tests/SoapServer/SoapServer_constructor_errors.phpt new file mode 100644 index 000000000000..61b0a352b339 --- /dev/null +++ b/ext/soap/tests/SoapServer/SoapServer_constructor_errors.phpt @@ -0,0 +1,91 @@ +--TEST-- +SoapServer constructor invalid type errors +--EXTENSIONS-- +soap +--FILE-- + 25, +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'actor' => 25, +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'classmap' => 25, +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'typemap' => 25, +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'features' => 'not an int', +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'cache_wsdl' => 'not an int', +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'send_errors' => 'not an int or bool', +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$options = [ + 'trace' => 'not an int or bool', +]; +try { + $server = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +TypeError: SoapServer::__construct(): Argument #2 ($options) "uri" option must be of type string, int given +TypeError: SoapServer::__construct(): Argument #2 ($options) "actor" option must be of type string, int given +TypeError: SoapServer::__construct(): Argument #2 ($options) "classmap" option must be of type array, int given +TypeError: SoapServer::__construct(): Argument #2 ($options) "typemap" option must be of type array, int given +TypeError: SoapServer::__construct(): Argument #2 ($options) "features" option must be of type int, string given +TypeError: SoapServer::__construct(): Argument #2 ($options) "cache_wsdl" option must be of type int, string given +TypeError: SoapServer::__construct(): Argument #2 ($options) "send_errors" option must be of type bool, string given +TypeError: SoapServer::__construct(): Argument #2 ($options) "trace" option must be of type bool, string given diff --git a/ext/soap/tests/bugs/gh19784.phpt b/ext/soap/tests/SoapServer/gh19784.phpt similarity index 59% rename from ext/soap/tests/bugs/gh19784.phpt rename to ext/soap/tests/SoapServer/gh19784.phpt index 1f718e74c459..d855bc47909a 100644 --- a/ext/soap/tests/bugs/gh19784.phpt +++ b/ext/soap/tests/SoapServer/gh19784.phpt @@ -4,10 +4,10 @@ GH-19784 (SoapServer memory leak) soap --FILE-- $v_5257); -new SoapServer('foobarbaz',$v_5238,); + +$options = ['encoding' => 'UTF-8']; +$server = new SoapServer('foobarbaz', $options); + ?> --EXPECTF-- diff --git a/ext/soap/tests/SoapServer/invalid-encoding-option-type.phpt b/ext/soap/tests/SoapServer/invalid-encoding-option-type.phpt new file mode 100644 index 000000000000..c67e86c322c0 --- /dev/null +++ b/ext/soap/tests/SoapServer/invalid-encoding-option-type.phpt @@ -0,0 +1,29 @@ +--TEST-- +SoapServer constructor with an invalid encoding option +--EXTENSIONS-- +soap +--FILE-- + 25, +]; +try { + $client = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + $client = new ExtendedSoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + + +?> +--EXPECT-- +TypeError: SoapServer::__construct(): Argument #2 ($options) "encoding" option must be of type string, int given +TypeError: SoapServer::__construct(): Argument #2 ($options) "encoding" option must be of type string, int given diff --git a/ext/soap/tests/SoapServer/invalid-encoding-option.phpt b/ext/soap/tests/SoapServer/invalid-encoding-option.phpt index f594d57dd8a4..08b27c43a673 100644 --- a/ext/soap/tests/SoapServer/invalid-encoding-option.phpt +++ b/ext/soap/tests/SoapServer/invalid-encoding-option.phpt @@ -25,5 +25,5 @@ try { ?> --EXPECT-- - -SOAP-ENV:ServerSoapServer::__construct(): Invalid 'encoding' option - 'non-sense' +ValueError: SoapServer::__construct(): Argument #2 ($options) "encoding" option must be a valid encoding, "non-sense" given +ValueError: SoapServer::__construct(): Argument #2 ($options) "encoding" option must be a valid encoding, "non-sense" given diff --git a/ext/soap/tests/SoapServer/invalid-soap_version-option-type.phpt b/ext/soap/tests/SoapServer/invalid-soap_version-option-type.phpt new file mode 100644 index 000000000000..690a35159a7c --- /dev/null +++ b/ext/soap/tests/SoapServer/invalid-soap_version-option-type.phpt @@ -0,0 +1,29 @@ +--TEST-- +SoapServer constructor with an invalid soap_version option +--EXTENSIONS-- +soap +--FILE-- + "I am not an integer", +]; +try { + $client = new SoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + $client = new ExtendedSoapServer($wsdl, $options); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + + +?> +--EXPECT-- +TypeError: SoapServer::__construct(): Argument #2 ($options) "soap_version" option must be of type int, string given +TypeError: SoapServer::__construct(): Argument #2 ($options) "soap_version" option must be of type int, string given diff --git a/ext/soap/tests/SoapServer/invalid-soap_version-option.phpt b/ext/soap/tests/SoapServer/invalid-soap_version-option.phpt index 17e45f2dac1b..6b8b25e44e12 100644 --- a/ext/soap/tests/SoapServer/invalid-soap_version-option.phpt +++ b/ext/soap/tests/SoapServer/invalid-soap_version-option.phpt @@ -1,5 +1,5 @@ --TEST-- -SoapServer constructor with an invalid encoding option +SoapServer constructor with an invalid soap_version option --EXTENSIONS-- soap --FILE-- @@ -25,5 +25,5 @@ try { ?> --EXPECT-- - -SOAP-ENV:ServerSoapServer::__construct(): 'soap_version' option must be SOAP_1_1 or SOAP_1_2 +ValueError: SoapServer::__construct(): Argument #2 ($options) "soap_version" option must be SOAP_1_1 or SOAP_1_2 +ValueError: SoapServer::__construct(): Argument #2 ($options) "soap_version" option must be SOAP_1_1 or SOAP_1_2 diff --git a/ext/soap/tests/SoapServer/missing-options-non-wsdl-mode.phpt b/ext/soap/tests/SoapServer/missing-options-non-wsdl-mode.phpt index 54e6493879e1..4f1fc89195ed 100644 --- a/ext/soap/tests/SoapServer/missing-options-non-wsdl-mode.phpt +++ b/ext/soap/tests/SoapServer/missing-options-non-wsdl-mode.phpt @@ -48,5 +48,9 @@ try { ?> --EXPECT-- $options not provided - -SOAP-ENV:ServerSoapServer::__construct(): 'uri' option is required in nonWSDL mode +ValueError: SoapServer::__construct(): Argument #2 ($options) "uri" option is required when argument #1 ($wsdl) is null +ValueError: SoapServer::__construct(): Argument #2 ($options) "uri" option is required when argument #1 ($wsdl) is null +Empty $options array +ValueError: SoapServer::__construct(): Argument #2 ($options) "uri" option is required when argument #1 ($wsdl) is null +ValueError: SoapServer::__construct(): Argument #2 ($options) "uri" option is required when argument #1 ($wsdl) is null +$options array only sets "uri" option diff --git a/ext/soap/tests/bugs/bug39832.phpt b/ext/soap/tests/bugs/bug39832.phpt index f5742c709840..bc8e8e861ab3 100644 --- a/ext/soap/tests/bugs/bug39832.phpt +++ b/ext/soap/tests/bugs/bug39832.phpt @@ -26,4 +26,4 @@ $x->handle($HTTP_RAW_POST_DATA); ?> --EXPECT-- -SOAP-ENV:ServerSOAP-ERROR: Encoding: Violation of encoding rules +SOAP-ENV:ServerSOAP-ERROR: Encoding: Invalid value for type 'integer' diff --git a/ext/soap/tests/bugs/gh16256.phpt b/ext/soap/tests/bugs/gh16256.phpt index ca8c00af5bbf..ce2ba1314069 100644 --- a/ext/soap/tests/bugs/gh16256.phpt +++ b/ext/soap/tests/bugs/gh16256.phpt @@ -21,5 +21,4 @@ try { ?> --EXPECT-- SoapClient::__construct(): 'classmap' option must be an associative array - -SOAP-ENV:ServerSoapServer::__construct(): 'classmap' option must be an associative array +SoapServer::__construct(): Argument #2 ($options) "classmap" option must be an associative array diff --git a/ext/soap/tests/bugs/gh21421.phpt b/ext/soap/tests/bugs/gh21421.phpt new file mode 100644 index 000000000000..1b8bb3be716f --- /dev/null +++ b/ext/soap/tests/bugs/gh21421.phpt @@ -0,0 +1,90 @@ +--TEST-- +GH-21421 (SoapClient typemap property breaks engine assumptions) +--EXTENSIONS-- +soap +--FILE-- + 'http://schemas.nothing.com', +'location' => 'test://', +'typemap' => array(array("type_ns" => "http://schemas.nothing.com", +"type_name" => "book", +"from_xml" => "book_from_xml")) +); +$client = new SoapClient(NULL, $options); +var_dump($client); +?> +--EXPECTF-- +object(SoapClient)#%d (35) { + ["uri":"SoapClient":private]=> + string(26) "http://schemas.nothing.com" + ["style":"SoapClient":private]=> + NULL + ["use":"SoapClient":private]=> + NULL + ["location":"SoapClient":private]=> + string(7) "test://" + ["trace":"SoapClient":private]=> + bool(false) + ["compression":"SoapClient":private]=> + NULL + ["sdl":"SoapClient":private]=> + NULL + ["httpsocket":"SoapClient":private]=> + NULL + ["httpurl":"SoapClient":private]=> + NULL + ["_login":"SoapClient":private]=> + NULL + ["_password":"SoapClient":private]=> + NULL + ["_use_digest":"SoapClient":private]=> + bool(false) + ["_digest":"SoapClient":private]=> + NULL + ["_proxy_host":"SoapClient":private]=> + NULL + ["_proxy_port":"SoapClient":private]=> + NULL + ["_proxy_login":"SoapClient":private]=> + NULL + ["_proxy_password":"SoapClient":private]=> + NULL + ["_exceptions":"SoapClient":private]=> + bool(true) + ["_encoding":"SoapClient":private]=> + NULL + ["_classmap":"SoapClient":private]=> + NULL + ["_features":"SoapClient":private]=> + NULL + ["_connection_timeout":"SoapClient":private]=> + int(0) + ["_stream_context":"SoapClient":private]=> + resource(%d) of type (stream-context) + ["_user_agent":"SoapClient":private]=> + NULL + ["_keep_alive":"SoapClient":private]=> + bool(true) + ["_ssl_method":"SoapClient":private]=> + NULL + ["_soap_version":"SoapClient":private]=> + int(1) + ["_use_proxy":"SoapClient":private]=> + NULL + ["_cookies":"SoapClient":private]=> + array(0) { + } + ["__default_headers":"SoapClient":private]=> + NULL + ["__soap_fault":"SoapClient":private]=> + NULL + ["__last_request":"SoapClient":private]=> + NULL + ["__last_response":"SoapClient":private]=> + NULL + ["__last_request_headers":"SoapClient":private]=> + NULL + ["__last_response_headers":"SoapClient":private]=> + NULL +} diff --git a/ext/soap/tests/bugs/gh22167.phpt b/ext/soap/tests/bugs/gh22167.phpt new file mode 100644 index 000000000000..f24bfb0eac32 --- /dev/null +++ b/ext/soap/tests/bugs/gh22167.phpt @@ -0,0 +1,128 @@ +--TEST-- +GH-22167 (Out-of-range XML Schema integer values in SOAP WSDL) +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +--FILE-- + + + + + $schema + + + + + + + + + + + + + + + +XML; +} + +function occurrence_schema(string $attribute, string $value = "2147483648"): string { + return << + + + + +XML; +} + +function restriction_schema(string $facet, string $value = "2147483648"): string { + return << + + + + +XML; +} + +$cases = [ + "minOccurs" => occurrence_schema("minOccurs"), + "maxOccurs" => occurrence_schema("maxOccurs"), + "negative minOccurs" => occurrence_schema("minOccurs", "-1"), + "negative maxOccurs" => occurrence_schema("maxOccurs", "-1"), + "minExclusive" => restriction_schema("minExclusive"), + "minInclusive" => restriction_schema("minInclusive"), + "maxExclusive" => restriction_schema("maxExclusive"), + "maxInclusive" => restriction_schema("maxInclusive"), + "totalDigits" => restriction_schema("totalDigits"), + "fractionDigits" => restriction_schema("fractionDigits"), + "length" => restriction_schema("length"), + "minLength" => restriction_schema("minLength"), + "maxLength" => restriction_schema("maxLength"), +]; + +$numeric_string_cases = [ + "leading whitespace numeric-string" => " 2147483648", + "leading plus numeric-string" => "+2147483648", + "leading zero numeric-string" => "00000000002147483648", + "leading numeric-string with trailing data" => "2147483648abc", + "negative out-of-range numeric-string" => "-2147483649", + "decimal numeric-string" => "2147483648.0", + "exponent numeric-string" => "2147483648e0", +]; + +foreach ($numeric_string_cases as $name => $value) { + $cases[$name] = occurrence_schema("maxOccurs", $value); +} + +$cases["fractional numeric-string within int range"] = occurrence_schema("maxOccurs", "3.141"); + +foreach ($cases as $name => $schema) { + $file = tempnam(sys_get_temp_dir(), "wsdl"); + file_put_contents($file, wsdl_with_schema($schema)); + + try { + new SoapClient($file, ["cache_wsdl" => WSDL_CACHE_NONE]); + echo "$name: parsed\n"; + } catch (SoapFault $e) { + echo "$name: {$e->getMessage()}\n"; + } finally { + unlink($file); + } +} +?> +--EXPECT-- +minOccurs: SOAP-ERROR: Parsing Schema: minOccurs value is out of range +maxOccurs: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +negative minOccurs: SOAP-ERROR: Parsing Schema: minOccurs value is out of range +negative maxOccurs: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +minExclusive: SOAP-ERROR: Parsing Schema: minExclusive value is out of range +minInclusive: SOAP-ERROR: Parsing Schema: minInclusive value is out of range +maxExclusive: SOAP-ERROR: Parsing Schema: maxExclusive value is out of range +maxInclusive: SOAP-ERROR: Parsing Schema: maxInclusive value is out of range +totalDigits: SOAP-ERROR: Parsing Schema: totalDigits value is out of range +fractionDigits: SOAP-ERROR: Parsing Schema: fractionDigits value is out of range +length: SOAP-ERROR: Parsing Schema: length value is out of range +minLength: SOAP-ERROR: Parsing Schema: minLength value is out of range +maxLength: SOAP-ERROR: Parsing Schema: maxLength value is out of range +leading whitespace numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +leading plus numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +leading zero numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +leading numeric-string with trailing data: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +negative out-of-range numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +decimal numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +exponent numeric-string: SOAP-ERROR: Parsing Schema: maxOccurs value is out of range +fractional numeric-string within int range: parsed diff --git a/ext/soap/tests/bugs/gh22285.phpt b/ext/soap/tests/bugs/gh22285.phpt new file mode 100644 index 000000000000..8c7e0933588e --- /dev/null +++ b/ext/soap/tests/bugs/gh22285.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-22285 (SoapServer dispatches to the first function when the SOAPAction header is empty) +--CREDITS-- +Jarkko Hyvärinen +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +--SKIPIF-- + +--POST-- + + + + World + + + +--FILE-- + 'Hello ' . $params->name]; + } + public function goodbye($params) { + return ['message' => 'Goodbye ' . $params->name]; + } +} + +$server = new SoapServer(__DIR__ . '/gh22285.wsdl', [ + 'cache_wsdl' => WSDL_CACHE_NONE, + 'encoding' => 'UTF-8', + 'soap_version' => SOAP_1_1, +]); +$server->setClass('TestWS'); +$_SERVER['HTTP_SOAPACTION'] = '""'; +$server->handle(); +?> +--EXPECTF-- + +Goodbye World diff --git a/ext/soap/tests/bugs/gh22285.wsdl b/ext/soap/tests/bugs/gh22285.wsdl new file mode 100644 index 000000000000..66b9e6749071 --- /dev/null +++ b/ext/soap/tests/bugs/gh22285.wsdl @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/soap/tests/bugs/protocol_relative_redirect.phpt b/ext/soap/tests/bugs/protocol_relative_redirect.phpt new file mode 100644 index 000000000000..e8f30ca66872 --- /dev/null +++ b/ext/soap/tests/bugs/protocol_relative_redirect.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP client follows a protocol-relative (//host/path) redirect Location without leaking the host +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- +', + '', + 'ok', + ''; +} else { + http_response_code(302); + header("Location: //" . $_SERVER["HTTP_HOST"] . "/redirected"); +} +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start', + 'uri' => 'test-uri', +]); + +try { + $client->__soapCall("foo", []); + echo "redirect followed\n"; +} catch (SoapFault $e) { + echo "SoapFault: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +redirect followed diff --git a/ext/soap/tests/bugs/relative_redirect.phpt b/ext/soap/tests/bugs/relative_redirect.phpt new file mode 100644 index 000000000000..774e7cbd98d7 --- /dev/null +++ b/ext/soap/tests/bugs/relative_redirect.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP client follows a redirect with a scheme-less (relative) Location +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- +', + '', + 'ok', + ''; +} else { + http_response_code(302); + header("Location: /redirected"); +} +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start', + 'uri' => 'test-uri', +]); + +try { + $client->__soapCall("foo", []); + echo "redirect followed\n"; +} catch (SoapFault $e) { + echo "SoapFault: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +redirect followed diff --git a/ext/soap/tests/bugs/relative_redirect_path.phpt b/ext/soap/tests/bugs/relative_redirect_path.phpt new file mode 100644 index 000000000000..09d4c857cc92 --- /dev/null +++ b/ext/soap/tests/bugs/relative_redirect_path.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP client follows a redirect with a relative Location resolved against the request path +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- +', + '', + 'ok', + ''; +} else { + http_response_code(302); + header("Location: redirected"); +} +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/svc/start', + 'uri' => 'test-uri', +]); + +try { + $client->__soapCall("foo", []); + echo "redirect followed\n"; +} catch (SoapFault $e) { + echo "SoapFault: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +redirect followed diff --git a/ext/soap/tests/content_type_header_injection.phpt b/ext/soap/tests/content_type_header_injection.phpt new file mode 100644 index 000000000000..d04cf337164e --- /dev/null +++ b/ext/soap/tests/content_type_header_injection.phpt @@ -0,0 +1,62 @@ +--TEST-- +SoapClient must truncate a content_type context option that contains newline characters +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + ['content_type' => "text/xml\r\nX-Injected: yes"], +]); + +foreach ([SOAP_1_1, SOAP_1_2] as $version) { + $client = new SoapClient(NULL, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS, + 'uri' => 'misc-uri', + 'trace' => true, + 'soap_version' => $version, + 'stream_context' => $context, + ]); + + $client->__soapCall("foo", []); + echo $client->__getLastRequestHeaders(); +} + +?> +--EXPECTF-- +Warning: SoapClient::__doRequest(): Header Content-Type value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: PHP-SOAP/%s +Content-Type: text/xml +SOAPAction: "misc-uri#foo" +Content-Length: %d + + +Warning: SoapClient::__doRequest(): Header Content-Type value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: PHP-SOAP/%s +Content-Type: text/xml; action="misc-uri#foo" +Content-Length: %d diff --git a/ext/soap/tests/cookie_header_injection.phpt b/ext/soap/tests/cookie_header_injection.phpt new file mode 100644 index 000000000000..880050e84d03 --- /dev/null +++ b/ext/soap/tests/cookie_header_injection.phpt @@ -0,0 +1,52 @@ +--TEST-- +SoapClient must truncate a cookie name or value that contains newline characters +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + 'http://' . PHP_CLI_SERVER_ADDRESS, + 'uri' => 'misc-uri', + 'trace' => true, +]); + +$client->__setCookie("evil-value", "a\r\nX-Injected: yes"); +$client->__setCookie("evil-name\r\nX-Injected: yes", "b"); +$client->__setCookie("harmless", "c"); + +$client->__soapCall("foo", []); +echo $client->__getLastRequestHeaders(); + +?> +--EXPECTF-- +Warning: SoapClient::__doRequest(): Header Cookie value contains newline characters and has been truncated in %s on line %d + +Warning: SoapClient::__doRequest(): Header Cookie value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: PHP-SOAP/%s +Content-Type: text/xml; charset=utf-8 +SOAPAction: "misc-uri#foo" +Content-Length: %d +Cookie: evil-value=a; evil-name=b; harmless=c diff --git a/ext/soap/tests/gh22218.phpt b/ext/soap/tests/gh22218.phpt new file mode 100644 index 000000000000..5b0714037a0a --- /dev/null +++ b/ext/soap/tests/gh22218.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-22218 (SoapServer::handle() segfault on non-array/unset $_SERVER) +--EXTENSIONS-- +soap +--CREDITS-- +Rex-Reynolds +--SKIPIF-- + +--POST-- + + + + + +--FILE-- + 'http://test-uri']); +$server->handle(); +?> +--EXPECTF-- +%AFunction 'test' doesn't exist%A diff --git a/ext/soap/tests/gh22585.phpt b/ext/soap/tests/gh22585.phpt new file mode 100644 index 000000000000..9d007d012b44 --- /dev/null +++ b/ext/soap/tests/gh22585.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-22585 (Use of uninitialized params in do_request() on out-of-memory bailout) +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +memory_limit=64M +--FILE-- + "http://localhost/soap.php", 'uri' => "http://localhost/"] + ); + $soap->call(1.1); + main(); + } + } + + main(); +} catch (\Throwable $e) { +} +echo "Done" . PHP_EOL; +?> +--EXPECTREGEX-- +(?s)(Done|.*Allowed memory size of \d+ bytes exhausted.*) diff --git a/ext/soap/tests/hexbin_odd_length.phpt b/ext/soap/tests/hexbin_odd_length.phpt new file mode 100644 index 000000000000..cc1cdcbab1fd --- /dev/null +++ b/ext/soap/tests/hexbin_odd_length.phpt @@ -0,0 +1,37 @@ +--TEST-- +SOAP rejects odd-length xsd:hexBinary values +--EXTENSIONS-- +soap +--FILE-- + + + + + ABC + + + +XML; + } +} + +$client = new TestSoapClient(null, [ + 'location' => 'test://', + 'uri' => 'urn:test', + 'exceptions' => true, +]); + +try { + var_dump(bin2hex($client->test())); +} catch (SoapFault $e) { + echo $e->faultstring, "\n"; +} +?> +--EXPECT-- +SOAP-ERROR: Encoding: Type 'hexBinary' value must contain an even number of hexadecimal digits diff --git a/ext/soap/tests/http_status_line_no_code.phpt b/ext/soap/tests/http_status_line_no_code.phpt new file mode 100644 index 000000000000..de943571a492 --- /dev/null +++ b/ext/soap/tests/http_status_line_no_code.phpt @@ -0,0 +1,33 @@ +--TEST-- +SoapClient: malformed HTTP status line without status code must not crash +--EXTENSIONS-- +soap +--FILE-- + 'http://{{ ADDR }}', + 'uri' => 'http://testuri.org', + 'connection_timeout' => 3, +]); +var_dump($client->__doRequest('', 'http://{{ ADDR }}', 'T', 1)); +CODE; + +include sprintf('%s/../../openssl/tests/ServerClientTestCase.inc', __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +string(0) "" diff --git a/ext/soap/tests/scalar_error_messages.phpt b/ext/soap/tests/scalar_error_messages.phpt new file mode 100644 index 000000000000..fde4449d6d84 --- /dev/null +++ b/ext/soap/tests/scalar_error_messages.phpt @@ -0,0 +1,52 @@ +--TEST-- +SOAP reports specific scalar encoding errors +--EXTENSIONS-- +soap +--FILE-- +response; + } +} + +function soap_response(string $type, string $value): string { + return << + + + + $value + + + +XML; +} + +function run_case(string $label, string $type, string $value): void { + $client = new ScalarErrorClient(null, [ + 'location' => 'test://', + 'uri' => 'urn:test', + 'exceptions' => true, + ]); + $client->response = soap_response($type, $value); + + try { + $client->__soapCall('test', []); + } catch (SoapFault $e) { + echo $label, ': ', $e->faultstring, "\n"; + } +} + +run_case('double', 'xsd:double', 'abc'); +run_case('long', 'xsd:long', 'abc'); +run_case('base64Binary node', 'xsd:base64Binary', 'abc'); +?> +--EXPECT-- +double: SOAP-ERROR: Encoding: Invalid value for type 'double' +long: SOAP-ERROR: Encoding: Invalid value for type 'long' +base64Binary node: SOAP-ERROR: Encoding: Type 'base64Binary' value must contain a single text or CDATA node diff --git a/ext/soap/tests/soap12/T27.phpt b/ext/soap/tests/soap12/T27.phpt index 09591b7faebd..5bb6572e3df2 100644 --- a/ext/soap/tests/soap12/T27.phpt +++ b/ext/soap/tests/soap12/T27.phpt @@ -25,4 +25,4 @@ include "soap12-test.inc"; ?> --EXPECT-- -env:ReceiverSOAP-ERROR: Encoding: Violation of encoding rules +env:ReceiverSOAP-ERROR: Encoding: Type 'string' value must contain a single text or CDATA node diff --git a/ext/soap/tests/soap12/T58.phpt b/ext/soap/tests/soap12/T58.phpt index 69c20a4f8670..a8619d20b298 100644 --- a/ext/soap/tests/soap12/T58.phpt +++ b/ext/soap/tests/soap12/T58.phpt @@ -24,4 +24,4 @@ include "soap12-test.inc"; ?> --EXPECT-- -env:ReceiverSOAP-ERROR: Encoding: Violation of encoding rules +env:ReceiverSOAP-ERROR: Encoding: Type 'int' value must contain a single text or CDATA node diff --git a/ext/soap/tests/soap_array_index_overflow.phpt b/ext/soap/tests/soap_array_index_overflow.phpt new file mode 100644 index 000000000000..ae481ee317ff --- /dev/null +++ b/ext/soap/tests/soap_array_index_overflow.phpt @@ -0,0 +1,89 @@ +--TEST-- +SOAP array index overflow is rejected +--EXTENSIONS-- +soap +--FILE-- +response; + } +} + +function soap_response(string $attributes, string $itemAttributes = ''): string { + return << + + + + + value + + + + +XML; +} + +function test_overflow(string $name, string $response): void { + $client = new TestSoapClient(NULL, [ + 'location' => 'test://', + 'uri' => 'http://example.org/', + 'exceptions' => true, + ]); + $client->response = $response; + + try { + $client->test(); + echo "$name: no fault\n"; + } catch (SoapFault $e) { + echo "$name: $e->faultstring\n"; + } +} + +function test_boundary_position(): void { + $client = new TestSoapClient(NULL, [ + 'location' => 'test://', + 'uri' => 'http://example.org/', + 'exceptions' => true, + ]); + $client->response = soap_response( + 'SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array"', + 'SOAP-ENC:position="[2147483646]"' + ); + + var_dump($client->test()); +} + +test_overflow( + 'arrayType', + soap_response('SOAP-ENC:arrayType="xsd:string[2147483648]" xsi:type="SOAP-ENC:Array"') +); + +test_overflow( + 'offset', + soap_response('SOAP-ENC:arrayType="xsd:string[1]" SOAP-ENC:offset="[2147483648]" xsi:type="SOAP-ENC:Array"') +); + +test_overflow( + 'position', + soap_response('SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array"', 'SOAP-ENC:position="[2147483647]"') +); + +test_boundary_position(); +?> +--EXPECT-- +arrayType: SOAP-ERROR: Encoding: array index out of range +offset: SOAP-ERROR: Encoding: array index out of range +position: SOAP-ERROR: Encoding: array index out of range +array(1) { + [2147483646]=> + string(5) "value" +} diff --git a/ext/soap/tests/soapaction_header_injection.phpt b/ext/soap/tests/soapaction_header_injection.phpt new file mode 100644 index 000000000000..996c193624f1 --- /dev/null +++ b/ext/soap/tests/soapaction_header_injection.phpt @@ -0,0 +1,57 @@ +--TEST-- +SoapClient must truncate a soapaction that contains newline characters +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + 'http://' . PHP_CLI_SERVER_ADDRESS, + 'uri' => 'misc-uri', + 'trace' => true, + 'soap_version' => $version, + ]); + + $client->__soapCall("foo", [], ['soapaction' => "an-action\r\nX-Injected: yes"]); + echo $client->__getLastRequestHeaders(); +} + +?> +--EXPECTF-- +Warning: SoapClient::__doRequest(): Header SOAPAction value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: PHP-SOAP/%s +Content-Type: text/xml; charset=utf-8 +SOAPAction: "an-action" +Content-Length: %d + + +Warning: SoapClient::__doRequest(): Header SOAPAction value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: PHP-SOAP/%s +Content-Type: application/soap+xml; charset=utf-8; action="an-action" +Content-Length: %d diff --git a/ext/soap/tests/user_agent_header_injection.phpt b/ext/soap/tests/user_agent_header_injection.phpt new file mode 100644 index 000000000000..979e1e579280 --- /dev/null +++ b/ext/soap/tests/user_agent_header_injection.phpt @@ -0,0 +1,47 @@ +--TEST-- +SoapClient must truncate a user_agent that contains newline characters +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + 'http://' . PHP_CLI_SERVER_ADDRESS, + 'uri' => 'misc-uri', + 'trace' => true, +]); + +$client->__soapCall("foo", []); +echo $client->__getLastRequestHeaders(); + +?> +--EXPECTF-- +Warning: SoapClient::__doRequest(): Header User-Agent value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: evil +Content-Type: text/xml; charset=utf-8 +SOAPAction: "misc-uri#foo" +Content-Length: %d diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 1c735ef5e6d8..9b36e087e071 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifdef __sun /* to enable 'new' ancillary data layout instead */ # define _XPG4_2 @@ -1204,6 +1218,7 @@ static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx) if (iovlen > UINT_MAX) { do_to_zval_err(ctx, "unexpectedly large value for iov_len: %lu", (unsigned long)iovlen); + return; } array_init_size(zv, (uint32_t)iovlen); @@ -1267,11 +1282,10 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context #elif defined(SIOCGIFINDEX) { struct ifreq ifr; - if (ZSTR_LEN(str) >= sizeof(ifr.ifr_name)) { + if (strlcpy(ifr.ifr_name, ZSTR_VAL(str), sizeof(ifr.ifr_name)) + >= sizeof(ifr.ifr_name)) { do_from_zval_err(ctx, "the interface name \"%s\" is too large ", ZSTR_VAL(str)); - } - memcpy(ifr.ifr_name, ZSTR_VAL(str), ZSTR_LEN(str) + 1); - if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) { + } else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) { if (errno == ENODEV) { do_from_zval_err(ctx, "no interface with name \"%s\" could be " "found", ZSTR_VAL(str)); @@ -1384,7 +1398,7 @@ static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, se return; } - iarr[i] = sock->bsd_socket; + iarr[i - 1] = sock->bsd_socket; return; } diff --git a/ext/sockets/conversions.h b/ext/sockets/conversions.h index 1f1fd29c5c05..1d3ce11463d8 100644 --- a/ext/sockets/conversions.h +++ b/ext/sockets/conversions.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SOCK_CONVERSIONS_H #define PHP_SOCK_CONVERSIONS_H 1 diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index 522e6b346f66..9ff7eb0b136a 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -654,7 +652,7 @@ zend_result php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struc retry: retval = GetIpAddrTable(addr_table, &size, 0); if (retval == ERROR_INSUFFICIENT_BUFFER) { - erealloc(addr_table, size); + addr_table = erealloc(addr_table, size); goto retry; } if (retval != NO_ERROR) { @@ -696,7 +694,7 @@ zend_result php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, uns retry: retval = GetIpAddrTable(addr_table, &size, 0); if (retval == ERROR_INSUFFICIENT_BUFFER) { - erealloc(addr_table, size); + addr_table = erealloc(addr_table, size); goto retry; } if (retval != NO_ERROR) { diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index f2232921c6b9..5a40147cdd6f 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index 89c613ba4307..4d047885dbaa 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Chris Vandomelen | | Sterling Hughes | @@ -77,9 +75,7 @@ typedef struct { extern PHP_SOCKETS_API zend_class_entry *socket_ce; -static inline php_socket *socket_from_obj(zend_object *obj) { - return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std)); -} +#define socket_from_obj(obj) ZEND_CONTAINER_OF(obj, php_socket, std) #define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv)) diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index cd7fd4839fb0..cc268bd68b0a 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/sockets/sendrecvmsg.h b/ext/sockets/sendrecvmsg.h index fd68b178ce5c..f430affe6779 100644 --- a/ext/sockets/sendrecvmsg.h +++ b/ext/sockets/sendrecvmsg.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SENDRECVMSG_H #define PHP_SENDRECVMSG_H 1 diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c index 333ef2533a11..949639d475f2 100644 --- a/ext/sockets/sockaddr_conv.c +++ b/ext/sockets/sockaddr_conv.c @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #include #include #include "php_sockets.h" diff --git a/ext/sockets/sockaddr_conv.h b/ext/sockets/sockaddr_conv.h index 93104e6470fb..ebca73862ef8 100644 --- a/ext/sockets/sockaddr_conv.h +++ b/ext/sockets/sockaddr_conv.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SOCKADR_CONV_H #define PHP_SOCKADR_CONV_H diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 464bd87d5d30..c4c6f224dcfa 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Chris Vandomelen | | Sterling Hughes | @@ -182,9 +180,7 @@ typedef struct { zend_class_entry *address_info_ce; static zend_object_handlers address_info_object_handlers; -static inline php_addrinfo *address_info_from_obj(zend_object *obj) { - return (php_addrinfo *)((char *)(obj) - XtOffsetOf(php_addrinfo, std)); -} +#define address_info_from_obj(obj) ZEND_CONTAINER_OF(obj, php_addrinfo, std) #define Z_ADDRESS_INFO_P(zv) address_info_from_obj(Z_OBJ_P(zv)) @@ -486,7 +482,7 @@ static PHP_MINIT_FUNCTION(sockets) socket_ce->default_object_handlers = &socket_object_handlers; memcpy(&socket_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - socket_object_handlers.offset = XtOffsetOf(php_socket, std); + socket_object_handlers.offset = offsetof(php_socket, std); socket_object_handlers.free_obj = socket_free_obj; socket_object_handlers.get_constructor = socket_get_constructor; socket_object_handlers.clone_obj = NULL; @@ -498,7 +494,7 @@ static PHP_MINIT_FUNCTION(sockets) address_info_ce->default_object_handlers = &address_info_object_handlers; memcpy(&address_info_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - address_info_object_handlers.offset = XtOffsetOf(php_addrinfo, std); + address_info_object_handlers.offset = offsetof(php_addrinfo, std); address_info_object_handlers.free_obj = address_info_free_obj; address_info_object_handlers.get_constructor = address_info_get_constructor; address_info_object_handlers.clone_obj = NULL; @@ -854,18 +850,17 @@ PHP_FUNCTION(socket_listen) PHP_FUNCTION(socket_close) { zval *arg1; - php_socket *php_socket; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJECT_OF_CLASS(arg1, socket_ce) ZEND_PARSE_PARAMETERS_END(); - php_socket = Z_SOCKET_P(arg1); - ENSURE_SOCKET_VALID(php_socket); + php_socket *socket = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(socket); - if (!Z_ISUNDEF(php_socket->zstream)) { + if (!Z_ISUNDEF(socket->zstream)) { php_stream *stream = NULL; - php_stream_from_zval_no_verify(stream, &php_socket->zstream); + php_stream_from_zval_no_verify(stream, &socket->zstream); if (stream != NULL) { /* close & destroy stream, incl. removing it from the rsrc list; * resource stored in php_sock->zstream will become invalid */ @@ -874,13 +869,13 @@ PHP_FUNCTION(socket_close) (stream->is_persistent?PHP_STREAM_FREE_CLOSE_PERSISTENT:0)); } } else { - if (!IS_INVALID_SOCKET(php_socket)) { - close(php_socket->bsd_socket); + if (!IS_INVALID_SOCKET(socket)) { + close(socket->bsd_socket); } } - ZVAL_UNDEF(&php_socket->zstream); - php_socket->bsd_socket = -1; + ZVAL_UNDEF(&socket->zstream); + socket->bsd_socket = -1; } /* }}} */ @@ -1033,7 +1028,6 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, htons(sin6->sin6_port)); } RETURN_TRUE; - break; #endif case AF_INET: sin = (struct sockaddr_in *) sa; @@ -1044,14 +1038,12 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, htons(sin->sin_port)); } RETURN_TRUE; - break; case AF_UNIX: s_un = (struct sockaddr_un *) sa; ZEND_TRY_ASSIGN_REF_STRING(addr, s_un->sun_path); RETURN_TRUE; - break; #ifdef AF_PACKET case AF_PACKET: sll = (struct sockaddr_ll *) sa; @@ -1067,7 +1059,6 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, sll->sll_ifindex); } RETURN_TRUE; - break; #endif default: @@ -1123,7 +1114,6 @@ PHP_FUNCTION(socket_getpeername) } RETURN_TRUE; - break; #endif case AF_INET: sin = (struct sockaddr_in *) sa; @@ -1135,14 +1125,12 @@ PHP_FUNCTION(socket_getpeername) } RETURN_TRUE; - break; case AF_UNIX: s_un = (struct sockaddr_un *) sa; ZEND_TRY_ASSIGN_REF_STRING(arg2, s_un->sun_path); RETURN_TRUE; - break; default: zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6"); @@ -1281,7 +1269,7 @@ PHP_FUNCTION(socket_connect) s_un.sun_family = AF_UNIX; memcpy(&s_un.sun_path, ZSTR_VAL(addr), ZSTR_LEN(addr)); retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un, - (socklen_t)(XtOffsetOf(struct sockaddr_un, sun_path) + ZSTR_LEN(addr))); + (socklen_t)(offsetof(struct sockaddr_un, sun_path) + ZSTR_LEN(addr))); break; } @@ -1504,7 +1492,7 @@ PHP_FUNCTION(socket_send) /* {{{ Receives data from a socket, connected or not */ PHP_FUNCTION(socket_recvfrom) { - zval *arg1, *arg2, *arg5, *arg6 = NULL; + zval *zsocket, *zdata, *zaddr, *zport = NULL; php_socket *php_sock; struct sockaddr_un s_un; struct sockaddr_in sin; @@ -1512,36 +1500,69 @@ PHP_FUNCTION(socket_recvfrom) struct sockaddr_in6 sin6; #endif #ifdef AF_PACKET - //struct sockaddr_ll sll; + struct sockaddr_ll sll; #endif char addrbuf[INET6_ADDRSTRLEN]; socklen_t slen; int retval; - zend_long arg3, arg4; + zend_long length, flags; const char *address; zend_string *recv_buf; ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_OBJECT_OF_CLASS(arg1, socket_ce) - Z_PARAM_ZVAL(arg2) - Z_PARAM_LONG(arg3) - Z_PARAM_LONG(arg4) - Z_PARAM_ZVAL(arg5) + Z_PARAM_OBJECT_OF_CLASS(zsocket, socket_ce) + Z_PARAM_ZVAL(zdata) + Z_PARAM_LONG(length) + Z_PARAM_LONG(flags) + Z_PARAM_ZVAL(zaddr) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(arg6) + Z_PARAM_ZVAL(zport) ZEND_PARSE_PARAMETERS_END(); - php_sock = Z_SOCKET_P(arg1); + php_sock = Z_SOCKET_P(zsocket); ENSURE_SOCKET_VALID(php_sock); +#ifdef AF_PACKET + /* On packet sockets, restrict flags to a finite safe subset. In + * particular MSG_TRUNC must be excluded: it makes recvfrom() report the + * untruncated frame length, which can exceed the buffer. */ + if (php_sock->type == AF_PACKET) { + const zend_long allowed_flags = 0 +#ifdef MSG_OOB + | MSG_OOB +#endif +#ifdef MSG_PEEK + | MSG_PEEK +#endif +#ifdef MSG_WAITALL + | MSG_WAITALL +#endif +#ifdef MSG_DONTWAIT + | MSG_DONTWAIT +#endif +#ifdef MSG_ERRQUEUE + | MSG_ERRQUEUE +#endif +#ifdef MSG_CMSG_CLOEXEC + | MSG_CMSG_CLOEXEC +#endif + ; + + if (flags & ~allowed_flags) { + zend_argument_value_error(4, "must be a combination of MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC for AF_PACKET sockets"); + RETURN_THROWS(); + } + } +#endif + /* overflow check */ /* Shouldthrow ? */ - if (arg3 <= 0 || arg3 > ZEND_LONG_MAX - 1) { + if (length <= 0 || length > ZEND_LONG_MAX - 1) { RETURN_FALSE; } - recv_buf = zend_string_alloc(arg3 + 1, 0); + recv_buf = zend_string_alloc(length + 1, 0); switch (php_sock->type) { case AF_UNIX: @@ -1549,18 +1570,18 @@ PHP_FUNCTION(socket_recvfrom) memset(&s_un, 0, slen); s_un.sun_family = AF_UNIX; - retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&s_un, (socklen_t *)&slen); + retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), length, flags, (struct sockaddr *)&s_un, (socklen_t *)&slen); if (retval < 0) { PHP_SOCKET_ERROR(php_sock, "Unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } - ZSTR_LEN(recv_buf) = retval; + ZSTR_LEN(recv_buf) = MIN((size_t)retval, (size_t)length); ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0'; - ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf); - ZEND_TRY_ASSIGN_REF_STRING(arg5, s_un.sun_path); + ZEND_TRY_ASSIGN_REF_NEW_STR(zdata, recv_buf); + ZEND_TRY_ASSIGN_REF_STRING(zaddr, s_un.sun_path); break; case AF_INET: @@ -1568,7 +1589,7 @@ PHP_FUNCTION(socket_recvfrom) memset(&sin, 0, slen); sin.sin_family = AF_INET; - if (arg6 == NULL) { + if (zport == NULL) { zend_string_efree(recv_buf); zend_throw_exception( zend_ce_argument_count_error, @@ -1577,21 +1598,21 @@ PHP_FUNCTION(socket_recvfrom) RETURN_THROWS(); } - retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sin, (socklen_t *)&slen); + retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), length, flags, (struct sockaddr *)&sin, (socklen_t *)&slen); if (retval < 0) { PHP_SOCKET_ERROR(php_sock, "Unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } - ZSTR_LEN(recv_buf) = retval; + ZSTR_LEN(recv_buf) = MIN((size_t)retval, (size_t)length); ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0'; address = inet_ntop(AF_INET, &sin.sin_addr, addrbuf, sizeof(addrbuf)); - ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf); - ZEND_TRY_ASSIGN_REF_STRING(arg5, address ? address : "0.0.0.0"); - ZEND_TRY_ASSIGN_REF_LONG(arg6, ntohs(sin.sin_port)); + ZEND_TRY_ASSIGN_REF_NEW_STR(zdata, recv_buf); + ZEND_TRY_ASSIGN_REF_STRING(zaddr, address ? address : "0.0.0.0"); + ZEND_TRY_ASSIGN_REF_LONG(zport, ntohs(sin.sin_port)); break; #ifdef HAVE_IPV6 case AF_INET6: @@ -1599,7 +1620,7 @@ PHP_FUNCTION(socket_recvfrom) memset(&sin6, 0, slen); sin6.sin6_family = AF_INET6; - if (arg6 == NULL) { + if (zport == NULL) { zend_string_efree(recv_buf); zend_throw_exception( zend_ce_argument_count_error, @@ -1608,41 +1629,38 @@ PHP_FUNCTION(socket_recvfrom) RETURN_THROWS(); } - retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sin6, (socklen_t *)&slen); + retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), length, flags, (struct sockaddr *)&sin6, (socklen_t *)&slen); if (retval < 0) { PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } - ZSTR_LEN(recv_buf) = retval; + ZSTR_LEN(recv_buf) = MIN((size_t)retval, (size_t)length); ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0'; inet_ntop(AF_INET6, &sin6.sin6_addr, addrbuf, sizeof(addrbuf)); - ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf); - ZEND_TRY_ASSIGN_REF_STRING(arg5, addrbuf[0] ? addrbuf : "::"); - ZEND_TRY_ASSIGN_REF_LONG(arg6, ntohs(sin6.sin6_port)); + ZEND_TRY_ASSIGN_REF_NEW_STR(zdata, recv_buf); + ZEND_TRY_ASSIGN_REF_STRING(zaddr, addrbuf[0] ? addrbuf : "::"); + ZEND_TRY_ASSIGN_REF_LONG(zport, ntohs(sin6.sin6_port)); break; #endif #ifdef AF_PACKET - /* - case AF_PACKET: - // TODO expose and use proper ethernet frame type instead i.e. src mac, dst mac and payload to userland - // ditto for socket_sendto - slen = sizeof(sll); - memset(&sll, 0, sizeof(sll)); - sll.sll_family = AF_PACKET; + case AF_PACKET: { char ifrname[IFNAMSIZ]; - retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sll, (socklen_t *)&slen); + slen = sizeof(sll); + memset(&sll, 0, slen); + + retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), length, flags, (struct sockaddr *)&sll, (socklen_t *)&slen); if (retval < 0) { PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } - ZSTR_LEN(recv_buf) = retval; + ZSTR_LEN(recv_buf) = MIN((size_t)retval, (size_t)length); ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0'; if (UNEXPECTED(!if_indextoname(sll.sll_ifindex, ifrname))) { @@ -1651,14 +1669,17 @@ PHP_FUNCTION(socket_recvfrom) RETURN_FALSE; } - ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf); - ZEND_TRY_ASSIGN_REF_STRING(arg5, ifrname); - ZEND_TRY_ASSIGN_REF_LONG(arg6, sll.sll_ifindex); + ZEND_TRY_ASSIGN_REF_NEW_STR(zdata, recv_buf); + ZEND_TRY_ASSIGN_REF_STRING(zaddr, ifrname); + + if (zport) { + ZEND_TRY_ASSIGN_REF_LONG(zport, sll.sll_ifindex); + } break; - */ + } #endif default: - zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6"); + zend_argument_value_error(1, "must be one of AF_UNIX, AF_PACKET, AF_INET, or AF_INET6"); RETURN_THROWS(); } @@ -1669,7 +1690,7 @@ PHP_FUNCTION(socket_recvfrom) /* {{{ Sends a message to a socket, whether it is connected or not */ PHP_FUNCTION(socket_sendto) { - zval *arg1; + zval *zsocket; php_socket *php_sock; struct sockaddr_un s_un; struct sockaddr_in sin; @@ -1677,7 +1698,7 @@ PHP_FUNCTION(socket_sendto) struct sockaddr_in6 sin6; #endif #ifdef AF_PACKET - //struct sockaddr_ll sll; + struct sockaddr_ll sll; #endif int retval; size_t buf_len; @@ -1687,7 +1708,7 @@ PHP_FUNCTION(socket_sendto) zend_string *addr; ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_OBJECT_OF_CLASS(arg1, socket_ce) + Z_PARAM_OBJECT_OF_CLASS(zsocket, socket_ce) Z_PARAM_STRING(buf, buf_len) Z_PARAM_LONG(len) Z_PARAM_LONG(flags) @@ -1696,14 +1717,19 @@ PHP_FUNCTION(socket_sendto) Z_PARAM_LONG_OR_NULL(port, port_is_null) ZEND_PARSE_PARAMETERS_END(); - php_sock = Z_SOCKET_P(arg1); + php_sock = Z_SOCKET_P(zsocket); ENSURE_SOCKET_VALID(php_sock); - if (port < 0 || port > USHRT_MAX) { - zend_argument_value_error(6, "must be between 0 and %u", USHRT_MAX); - RETURN_THROWS(); +#ifdef AF_PACKET + if (php_sock->type != AF_PACKET) { +#endif + if (port < 0 || port > USHRT_MAX) { + zend_argument_value_error(6, "must be between 0 and %u", USHRT_MAX); + RETURN_THROWS(); + } +#ifdef AF_PACKET } - +#endif if (len < 0) { zend_argument_value_error(3, "must be greater than or equal to 0"); @@ -1760,7 +1786,6 @@ PHP_FUNCTION(socket_sendto) break; #endif #ifdef AF_PACKET - /* case AF_PACKET: if (port_is_null) { zend_argument_value_error(6, "cannot be null when the socket type is AF_PACKET"); @@ -1769,14 +1794,13 @@ PHP_FUNCTION(socket_sendto) memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; - sll.sll_ifindex = port; + sll.sll_ifindex = (int)port; - retval = sendto(php_sock->bsd_socket, buf, ((size_t)len > buf_len) ? buf_len : (size_t)len, flags, (struct sockaddr *) &sin, sizeof(sin)); + retval = sendto(php_sock->bsd_socket, buf, ((size_t)len > buf_len) ? buf_len : (size_t)len, flags, (struct sockaddr *)&sll, sizeof(sll)); break; - */ #endif default: - zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6"); + zend_argument_value_error(1, "must be one of AF_UNIX, AF_PACKET, AF_INET, or AF_INET6"); RETURN_THROWS(); } @@ -2008,6 +2032,7 @@ PHP_FUNCTION(socket_get_option) #endif optlen = sizeof(other_val); + other_val = 0; if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) { PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); @@ -2033,6 +2058,10 @@ PHP_FUNCTION(socket_set_option) DWORD timeout; #else struct timeval tv; +#endif +#ifdef SO_ATTACH_REUSEPORT_CBPF + struct sock_filter cbpf[8] = {0}; + struct sock_fprog bpfprog; #endif zend_long level, optname; void *opt_ptr; @@ -2130,7 +2159,7 @@ PHP_FUNCTION(socket_set_option) // TCP_USER_TIMEOUT unsigned int if (timeout < 0 || timeout > UINT_MAX) { - zend_argument_value_error(4, "must be of between 0 and %u", UINT_MAX); + zend_argument_value_error(4, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } @@ -2187,7 +2216,7 @@ PHP_FUNCTION(socket_set_option) } if (val_linger < 0 || val_linger > USHRT_MAX) { - zend_argument_value_error(4, "\"%s\" must be between 0 and %d", l_linger, USHRT_MAX); + zend_argument_value_error(4, "\"%s\" must be between 0 and %u", l_linger_key, USHRT_MAX); RETURN_THROWS(); } @@ -2321,8 +2350,6 @@ PHP_FUNCTION(socket_set_option) optname = SO_DETACH_BPF; } else { uint32_t k = (uint32_t)cbpf_val; - static struct sock_filter cbpf[8] = {0}; - static struct sock_fprog bpfprog; switch (k) { case SKF_AD_CPU: @@ -2351,8 +2378,8 @@ PHP_FUNCTION(socket_set_option) // UDP segmentation offload maximum size or 0 to disable it if (ov < 0 || ov > USHRT_MAX) { - zend_argument_value_error(4, "must be of between 0 and %u", USHRT_MAX); - RETURN_FALSE; + zend_argument_value_error(4, "must be between 0 and %u", USHRT_MAX); + RETURN_THROWS(); } optlen = sizeof(ov); @@ -2621,6 +2648,7 @@ PHP_FUNCTION(socket_import_stream) retsock = Z_SOCKET_P(return_value); if (!socket_import_file_descriptor(socket, retsock)) { + retsock->bsd_socket = -1; zval_ptr_dtor(return_value); RETURN_FALSE; } diff --git a/ext/sockets/tests/gh21161.phpt b/ext/sockets/tests/gh21161.phpt index 8a3958a583d9..f8dbe909c8d6 100644 --- a/ext/sockets/tests/gh21161.phpt +++ b/ext/sockets/tests/gh21161.phpt @@ -7,6 +7,7 @@ sockets if (substr(PHP_OS, 0, 3) == 'WIN') { die('skip.. Not valid for Windows'); } +require 'ipv6_skipif.inc'; ?> --FILE-- --EXPECT-- -socket_setopt(): Argument #4 ($value) must be of between 0 and 65535 -socket_setopt(): Argument #4 ($value) must be of between 0 and 65535 +socket_setopt(): Argument #4 ($value) must be between 0 and 65535 +socket_setopt(): Argument #4 ($value) must be between 0 and 65535 diff --git a/ext/sockets/tests/socket_recvfrom_afpacket_no_port.phpt b/ext/sockets/tests/socket_recvfrom_afpacket_no_port.phpt new file mode 100644 index 000000000000..fd6c4c3a4daf --- /dev/null +++ b/ext/sockets/tests/socket_recvfrom_afpacket_no_port.phpt @@ -0,0 +1,64 @@ +--TEST-- +AF_PACKET socket_recvfrom() without optional port argument +--EXTENSIONS-- +sockets +posix +--SKIPIF-- + +--FILE-- += 60); +var_dump($addr === 'lo'); + +socket_close($s_send); +socket_close($s_recv); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt b/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt new file mode 100644 index 000000000000..907ea70ac169 --- /dev/null +++ b/ext/sockets/tests/socket_sendmsg_scm_rights_object.phpt @@ -0,0 +1,77 @@ +--TEST-- +socket_sendmsg(): SCM_RIGHTS transfers Socket objects with the correct fds +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + ['x'], + 'control' => [[ + 'level' => SOL_SOCKET, + 'type' => SCM_RIGHTS, + 'data' => [$payload1, $payload2], + ]], +], 0); + +$data = [ + 'name' => [], + 'buffer_size' => 64, + 'controllen' => socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, 2), +]; +socket_recvmsg($recv, $data, 0); + +$got = $data['control'][0]['data']; +var_dump(count($got)); +var_dump($got[0] instanceof Socket); +var_dump($got[1] instanceof Socket); +socket_getsockname($got[0], $addr0); +socket_getsockname($got[1], $addr1); +var_dump($addr0 === $ppath1); +var_dump($addr1 === $ppath2); +?> +--CLEAN-- + +--EXPECT-- +int(2) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_sendto_recvfrom_afpacket.phpt b/ext/sockets/tests/socket_sendto_recvfrom_afpacket.phpt new file mode 100644 index 000000000000..f2857671b94d --- /dev/null +++ b/ext/sockets/tests/socket_sendto_recvfrom_afpacket.phpt @@ -0,0 +1,126 @@ +--TEST-- +Test if socket_recvfrom() receives raw data sent by socket_sendto() via AF_PACKET +--EXTENSIONS-- +sockets +posix +--SKIPIF-- + +--FILE-- += 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +var_dump(is_string($buf)); +var_dump($addr === 'lo'); +var_dump(is_string($buf) && str_contains($buf, "ETH_P_ALL test")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- ETH_P_LOOP send and receive ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +$header = $dst_mac . $src_mac . pack("n", ETH_P_LOOP); +$frame = build_frame($dst_mac, $src_mac, ETH_P_LOOP, "loopback payload"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent >= 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +// Verify ETH_P_LOOP ethertype at offset 12-13. +var_dump(is_string($buf) && unpack("n", $buf, 12)[1] === ETH_P_LOOP); +var_dump(is_string($buf) && str_contains($buf, "loopback payload")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Large payload ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +$header = $dst_mac . $src_mac . pack("n", 0x9000); +$payload = random_bytes(1024); +$frame = build_frame($dst_mac, $src_mac, 0x9000, $payload); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent >= strlen($frame)); + +$buf = recv_matching($s_recv, $header, 65536, $addr, $port); +var_dump($buf !== false && strlen($buf) >= strlen($frame)); +var_dump(is_int($port)); +// Verify the payload is intact in the raw buffer. +var_dump(is_string($buf) && str_contains($buf, $payload)); + +socket_close($s_send); +socket_close($s_recv); +?> +--EXPECT-- +--- ETH_P_ALL send and receive --- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +--- ETH_P_LOOP send and receive --- +bool(true) +bool(true) +bool(true) +bool(true) +--- Large payload --- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_sendto_recvfrom_afpacket_errors.phpt b/ext/sockets/tests/socket_sendto_recvfrom_afpacket_errors.phpt new file mode 100644 index 000000000000..a63c36c4f6b0 --- /dev/null +++ b/ext/sockets/tests/socket_sendto_recvfrom_afpacket_errors.phpt @@ -0,0 +1,71 @@ +--TEST-- +AF_PACKET socket_sendto() and socket_recvfrom() error cases +--EXTENSIONS-- +sockets +posix +--SKIPIF-- + +--CONFLICTS-- +all +--FILE-- +getMessage(), PHP_EOL; +} +socket_close($s); + +echo "--- sendto with invalid interface name ---\n"; +$s = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s, 'lo'); + +$ret = @socket_sendto($s, str_repeat("\x00", 60), 60, 0, "lo", 999999); +var_dump($ret === false); +socket_close($s); + +echo "--- recvfrom on non-blocking socket with no data ---\n"; +$s = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s, 'lo'); +socket_set_nonblock($s); + +$ret = @socket_recvfrom($s, $buf, 65536, 0, $addr); +var_dump($ret === false); +socket_close($s); + +echo "--- recvfrom with MSG_TRUNC is rejected ---\n"; +$s = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s, 'lo'); + +try { + socket_recvfrom($s, $buf, 65536, MSG_TRUNC, $addr); +} catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +socket_close($s); + +?> +--EXPECT-- +--- sendto without port (ifindex) --- +socket_sendto(): Argument #6 ($port) cannot be null when the socket type is AF_PACKET +--- sendto with invalid interface name --- +bool(true) +--- recvfrom on non-blocking socket with no data --- +bool(true) +--- recvfrom with MSG_TRUNC is rejected --- +socket_recvfrom(): Argument #4 ($flags) must be a combination of MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC for AF_PACKET sockets diff --git a/ext/sockets/tests/socket_sendto_recvfrom_afpacket_malformed.phpt b/ext/sockets/tests/socket_sendto_recvfrom_afpacket_malformed.phpt new file mode 100644 index 000000000000..68af685cf0bf --- /dev/null +++ b/ext/sockets/tests/socket_sendto_recvfrom_afpacket_malformed.phpt @@ -0,0 +1,225 @@ +--TEST-- +AF_PACKET socket_sendto/socket_recvfrom with malformed and edge-case frames +--EXTENSIONS-- +sockets +posix +--SKIPIF-- + +--FILE-- += 60); +// The raw buffer is just padding after the header. +var_dump(is_string($buf) && strlen($buf) >= 60); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Bogus ethertype ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +// Use a made-up ethertype (0xBEEF). Kernel delivers it fine on loopback. +$header = $dst_mac . $src_mac . pack("n", 0xBEEF); +$frame = str_pad($header . "bogus", 60, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +// Ethertype bytes should be in the raw buffer at offset 12-13. +var_dump(is_string($buf) && unpack("n", $buf, 12)[1] === 0xBEEF); +var_dump(is_string($buf) && str_contains($buf, "bogus")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Garbage payload with custom ethertype ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +// Use a non-standard ethertype (0x88B5, reserved for local experimental use) +// with garbage payload. Avoids kernel IP/IPv6 stack interception. +$header = $dst_mac . $src_mac . pack("n", 0x88B5); +$frame = str_pad($header . "\xDE\xAD\xBE\xEF", 60, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +// Raw buffer is delivered as-is — PHP doesn't parse, so no crash. +var_dump(is_string($buf) && str_contains($buf, "\xDE\xAD\xBE\xEF")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Another garbage payload with experimental ethertype ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +// Use 0x88B6, another local experimental ethertype. +$header = $dst_mac . $src_mac . pack("n", 0x88B6); +$frame = str_pad($header . "\xCA\xFE", 60, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +// Delivered raw — no parsing, no crash. +var_dump(is_string($buf) && str_contains($buf, "\xCA\xFE")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Invalid ethertype 0x0000 ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +$header = $dst_mac . $src_mac . pack("n", 0x0000); +$frame = str_pad($header . "zerotype", 60, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +var_dump(is_string($buf) && unpack("n", $buf, 12)[1] === 0x0000); +var_dump(is_string($buf) && str_contains($buf, "zerotype")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Invalid ethertype 0xFFFF ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +$header = $dst_mac . $src_mac . pack("n", 0xFFFF); +$frame = str_pad($header . "maxtype", 60, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 60); + +$buf = recv_matching($s_recv, $header, 65536, $addr); +var_dump($buf !== false && strlen($buf) >= 60); +var_dump(is_string($buf) && unpack("n", $buf, 12)[1] === 0xFFFF); +var_dump(is_string($buf) && str_contains($buf, "maxtype")); + +socket_close($s_send); +socket_close($s_recv); + +echo "--- Small receive buffer (truncation) ---\n"; +$s_send = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +$s_recv = socket_create(AF_PACKET, SOCK_RAW, ETH_P_ALL); +socket_bind($s_send, 'lo'); +socket_bind($s_recv, 'lo'); + +$header = $dst_mac . $src_mac . pack("n", 0x9000); +$payload = str_repeat("X", 200); +$frame = str_pad($header . $payload, 214, "\x00"); +$sent = socket_sendto($s_send, $frame, strlen($frame), 0, "lo", 1); +var_dump($sent === 214); + +// Request only 30 bytes — less than the frame. Kernel truncates. +$buf = recv_matching($s_recv, $header, 30, $addr); +var_dump($buf !== false && strlen($buf) === 30); +var_dump(is_string($buf) && strlen($buf) === 30); + +socket_close($s_send); +socket_close($s_recv); +?> +--EXPECT-- +--- Undersized frame (below 14-byte ethernet header) --- +bool(true) +--- Zero-length payload (header only, padded to 60) --- +bool(true) +bool(true) +bool(true) +--- Bogus ethertype --- +bool(true) +bool(true) +bool(true) +bool(true) +--- Garbage payload with custom ethertype --- +bool(true) +bool(true) +bool(true) +--- Another garbage payload with experimental ethertype --- +bool(true) +bool(true) +bool(true) +--- Invalid ethertype 0x0000 --- +bool(true) +bool(true) +bool(true) +bool(true) +--- Invalid ethertype 0xFFFF --- +bool(true) +bool(true) +bool(true) +bool(true) +--- Small receive buffer (truncation) --- +bool(true) +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_set_option_timeo_error.phpt b/ext/sockets/tests/socket_set_option_timeo_error.phpt index 1db5e01c3622..befdfb095855 100644 --- a/ext/sockets/tests/socket_set_option_timeo_error.phpt +++ b/ext/sockets/tests/socket_set_option_timeo_error.phpt @@ -13,6 +13,7 @@ $options_2 = array("sec" => new stdClass(), "usec" => "1"); $options_3 = array("l_onoff" => "aaaa", "l_linger" => "1"); $options_4 = array("l_onoff" => "1", "l_linger" => []); $options_5 = array("l_onoff" => PHP_INT_MAX, "l_linger" => "1"); +$options_6 = array("l_onoff" => "1", "l_linger" => PHP_INT_MAX); try { socket_set_option( $socket, SOL_SOCKET, SO_RCVTIMEO, new stdClass); @@ -56,6 +57,11 @@ try { } catch (\ValueError $e) { echo $e->getMessage() . PHP_EOL; } +try { + socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_6); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} ?> --EXPECTF-- socket_set_option(): Argument #4 ($value) must have key "sec" @@ -64,3 +70,4 @@ Warning: Object of class stdClass could not be converted to int in %s on line %d socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_RCVTIMEO, string given socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_LINGER, string given socket_set_option(): Argument #4 ($value) "l_onoff" must be between 0 and %d +socket_set_option(): Argument #4 ($value) "l_linger" must be between 0 and %d diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt index 3f12120e54d8..05970b719874 100644 --- a/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt @@ -29,6 +29,6 @@ var_dump($retval_3 === $timeout); socket_close($socket); ?> --EXPECTF-- -socket_setopt(): Argument #4 ($value) must be of between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d bool(true) bool(true) diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt index 8dbb7f80e48b..894a24d2a49b 100644 --- a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt @@ -35,7 +35,7 @@ var_dump($retval_3 === $timeout); socket_close($socket); ?> --EXPECTF-- -socket_setopt(): Argument #4 ($value) must be of between 0 and %d -socket_setopt(): Argument #4 ($value) must be of between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d bool(true) bool(true) diff --git a/ext/sockets/windows_common.h b/ext/sockets/windows_common.h index 0b8cdfe2e5d9..9c7e711ffe5b 100644 --- a/ext/sockets/windows_common.h +++ b/ext/sockets/windows_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ #ifndef WINDOWS_COMMON_H diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index bb11a6ef9116..8c85991150b5 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Frank Denis | +----------------------------------------------------------------------+ @@ -571,9 +569,8 @@ PHP_FUNCTION(sodium_crypto_box_keypair) zend_string *keypair; size_t keypair_len; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair_len = crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES; keypair = zend_string_alloc(keypair_len, 0); if (crypto_box_keypair((unsigned char *) ZSTR_VAL(keypair) + @@ -891,9 +888,8 @@ PHP_FUNCTION(sodium_crypto_sign_keypair) zend_string *keypair; size_t keypair_len; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair_len = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES; keypair = zend_string_alloc(keypair_len, 0); if (crypto_sign_keypair((unsigned char *) ZSTR_VAL(keypair) + @@ -1433,23 +1429,28 @@ PHP_FUNCTION(sodium_crypto_pwhash) RETURN_THROWS(); } if (hash_len <= 0) { - zend_argument_error(sodium_exception_ce, 1, "must be greater than 0"); + zend_argument_value_error(1, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (hash_len >= 0xffffffff) { - zend_argument_error(sodium_exception_ce, 1, "is too large"); + zend_argument_value_error(1, "must be less than 4294967295 bytes"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (passwd_len >= 0xffffffff) { - zend_argument_error(sodium_exception_ce, 2, "is too long"); + zend_argument_value_error(2, "must be less than 4294967295 bytes"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (opslimit <= 0) { - zend_argument_error(sodium_exception_ce, 4, "must be greater than 0"); + zend_argument_value_error(4, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (memlimit <= 0 || memlimit > SIZE_MAX) { - zend_argument_error(sodium_exception_ce, 5, "must be greater than 0"); + zend_argument_value_error(5, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (alg != crypto_pwhash_ALG_ARGON2I13 @@ -1464,15 +1465,19 @@ PHP_FUNCTION(sodium_crypto_pwhash) zend_error(E_WARNING, "empty password"); } if (salt_len != crypto_pwhash_SALTBYTES) { - zend_argument_error(sodium_exception_ce, 3, "must be SODIUM_CRYPTO_PWHASH_SALTBYTES bytes long"); + zend_argument_value_error(3, "must be SODIUM_CRYPTO_PWHASH_SALTBYTES bytes long"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (opslimit < crypto_pwhash_OPSLIMIT_MIN) { - zend_argument_error(sodium_exception_ce, 4, "must be greater than or equal to %d", crypto_pwhash_OPSLIMIT_MIN); + zend_argument_value_error(4, "must be greater than or equal to %d", crypto_pwhash_OPSLIMIT_MIN); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (memlimit < crypto_pwhash_MEMLIMIT_MIN) { - zend_argument_error(sodium_exception_ce, 5, "must be greater than or equal to %d", crypto_pwhash_MEMLIMIT_MIN); + zend_argument_value_error(5, "must be greater than or equal to %d", crypto_pwhash_MEMLIMIT_MIN); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } hash = zend_string_alloc((size_t) hash_len, 0); ret = -1; @@ -1516,25 +1521,32 @@ PHP_FUNCTION(sodium_crypto_pwhash_str) RETURN_THROWS(); } if (opslimit <= 0) { - zend_argument_error(sodium_exception_ce, 2, "must be greater than 0"); + zend_argument_value_error(2, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (memlimit <= 0 || memlimit > SIZE_MAX) { - zend_argument_error(sodium_exception_ce, 3, "must be greater than 0"); + zend_argument_value_error(3, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (passwd_len >= 0xffffffff) { - zend_argument_error(sodium_exception_ce, 1, "is too long"); + zend_argument_value_error(1, "must be less than 4294967295 bytes"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (passwd_len <= 0) { zend_error(E_WARNING, "empty password"); } if (opslimit < crypto_pwhash_OPSLIMIT_MIN) { - zend_argument_error(sodium_exception_ce, 2, "must be greater than or equal to %d", crypto_pwhash_OPSLIMIT_MIN); + zend_argument_value_error(2, "must be greater than or equal to %d", crypto_pwhash_OPSLIMIT_MIN); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } if (memlimit < crypto_pwhash_MEMLIMIT_MIN) { - zend_argument_error(sodium_exception_ce, 3, "must be greater than or equal to %d", crypto_pwhash_MEMLIMIT_MIN); + zend_argument_value_error(3, "must be greater than or equal to %d", crypto_pwhash_MEMLIMIT_MIN); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } hash_str = zend_string_alloc(crypto_pwhash_STRBYTES - 1, 0); if (crypto_pwhash_str @@ -1620,29 +1632,37 @@ PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256) RETURN_THROWS(); } if (hash_len <= 0 || hash_len >= ZSTR_MAX_LEN || hash_len > 0x1fffffffe0ULL) { - zend_argument_error(sodium_exception_ce, 1, "must be greater than 0"); + zend_argument_value_error(1, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (opslimit <= 0) { - zend_argument_error(sodium_exception_ce, 4, "must be greater than 0"); + zend_argument_value_error(4, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (memlimit <= 0 || memlimit > SIZE_MAX) { - zend_argument_error(sodium_exception_ce, 5, "must be greater than 0"); + zend_argument_value_error(5, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (passwd_len <= 0) { zend_error(E_WARNING, "empty password"); } if (salt_len != crypto_pwhash_scryptsalsa208sha256_SALTBYTES) { - zend_argument_error(sodium_exception_ce, 3, "must be SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes long"); + zend_argument_value_error(3, "must be SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes long"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (opslimit < crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE) { - zend_argument_error(sodium_exception_ce, 4, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE); + zend_argument_value_error(4, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } if (memlimit < crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) { - zend_argument_error(sodium_exception_ce, 5, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); + zend_argument_value_error(5, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } hash = zend_string_alloc((size_t) hash_len, 0); if (crypto_pwhash_scryptsalsa208sha256 @@ -1673,21 +1693,27 @@ PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str) RETURN_THROWS(); } if (opslimit <= 0) { - zend_argument_error(sodium_exception_ce, 2, "must be greater than 0"); + zend_argument_value_error(2, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (memlimit <= 0 || memlimit > SIZE_MAX) { - zend_argument_error(sodium_exception_ce, 3, "must be greater than 0"); + zend_argument_value_error(3, "must be greater than 0"); + sodium_remove_param_values_from_backtrace(EG(exception)); RETURN_THROWS(); } if (passwd_len <= 0) { zend_error(E_WARNING, "empty password"); } if (opslimit < crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE) { - zend_argument_error(sodium_exception_ce, 2, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE); + zend_argument_value_error(2, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } if (memlimit < crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) { - zend_argument_error(sodium_exception_ce, 3, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); + zend_argument_value_error(3, "must be greater than or equal to %d", crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); } hash_str = zend_string_alloc (crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1, 0); @@ -1733,9 +1759,7 @@ PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify) PHP_FUNCTION(sodium_crypto_aead_aes256gcm_is_available) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); #ifdef HAVE_AESGCM RETURN_BOOL(crypto_aead_aes256gcm_is_available()); #else @@ -2719,9 +2743,8 @@ PHP_FUNCTION(sodium_crypto_kx_keypair) unsigned char *pk; zend_string *keypair; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair = zend_string_alloc(crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES, 0); sk = (unsigned char *) ZSTR_VAL(keypair); pk = sk + crypto_kx_SECRETKEYBYTES; @@ -3028,9 +3051,8 @@ PHP_FUNCTION(sodium_crypto_aead_aes256gcm_keygen) { unsigned char key[crypto_aead_aes256gcm_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3041,9 +3063,8 @@ PHP_FUNCTION(sodium_crypto_aead_aegis128l_keygen) { unsigned char key[crypto_aead_aegis128l_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_aead_aegis128l_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3054,9 +3075,8 @@ PHP_FUNCTION(sodium_crypto_aead_aegis256_keygen) { unsigned char key[crypto_aead_aegis256_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_aead_aegis256_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3066,9 +3086,8 @@ PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_keygen) { unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3077,9 +3096,8 @@ PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_ietf_keygen) { unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3089,9 +3107,8 @@ PHP_FUNCTION(sodium_crypto_aead_xchacha20poly1305_ietf_keygen) { unsigned char key[crypto_aead_xchacha20poly1305_IETF_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3101,9 +3118,8 @@ PHP_FUNCTION(sodium_crypto_auth_keygen) { unsigned char key[crypto_auth_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3112,9 +3128,8 @@ PHP_FUNCTION(sodium_crypto_generichash_keygen) { unsigned char key[crypto_generichash_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3123,9 +3138,8 @@ PHP_FUNCTION(sodium_crypto_kdf_keygen) { unsigned char key[crypto_kdf_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3134,9 +3148,8 @@ PHP_FUNCTION(sodium_crypto_secretbox_keygen) { unsigned char key[crypto_secretbox_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3145,9 +3158,8 @@ PHP_FUNCTION(sodium_crypto_shorthash_keygen) { unsigned char key[crypto_shorthash_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3156,9 +3168,8 @@ PHP_FUNCTION(sodium_crypto_stream_keygen) { unsigned char key[crypto_stream_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3167,9 +3178,8 @@ PHP_FUNCTION(sodium_crypto_stream_xchacha20_keygen) { unsigned char key[crypto_stream_xchacha20_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3391,9 +3401,8 @@ PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_keygen) { unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3679,9 +3688,8 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_random) { zend_string *r; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); crypto_core_ristretto255_random((unsigned char *) ZSTR_VAL(r)); ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; @@ -3820,9 +3828,8 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_random) { zend_string *r; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - }; + ZEND_PARSE_PARAMETERS_NONE(); + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); crypto_core_ristretto255_scalar_random((unsigned char *) ZSTR_VAL(r)); ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; @@ -3919,9 +3926,8 @@ PHP_FUNCTION(sodium_crypto_ipcrypt_keygen) { unsigned char key[crypto_ipcrypt_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_ipcrypt_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3992,9 +3998,8 @@ PHP_FUNCTION(sodium_crypto_ipcrypt_nd_keygen) { unsigned char key[crypto_ipcrypt_ND_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -4069,9 +4074,8 @@ PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_keygen) { unsigned char key[crypto_ipcrypt_NDX_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_ipcrypt_ndx_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -4146,9 +4150,8 @@ PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_keygen) { unsigned char key[crypto_ipcrypt_PFX_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_ipcrypt_pfx_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } diff --git a/ext/sodium/php_libsodium.h b/ext/sodium/php_libsodium.h index 673541fe784c..8132472d684f 100644 --- a/ext/sodium/php_libsodium.h +++ b/ext/sodium/php_libsodium.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Frank Denis | +----------------------------------------------------------------------+ diff --git a/ext/sodium/sodium_pwhash.c b/ext/sodium/sodium_pwhash.c index 32e4f72634c3..ba48b0158cac 100644 --- a/ext/sodium/sodium_pwhash.c +++ b/ext/sodium/sodium_pwhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/sodium/tests/pwhash_memlimit_below_min.phpt b/ext/sodium/tests/pwhash_memlimit_below_min.phpt new file mode 100644 index 000000000000..8913afb382f0 --- /dev/null +++ b/ext/sodium/tests/pwhash_memlimit_below_min.phpt @@ -0,0 +1,27 @@ +--TEST-- +sodium_crypto_pwhash(): a below-minimum memlimit reports a precise argument error +--EXTENSIONS-- +sodium +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +try { + sodium_crypto_pwhash_str("password", SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, 1); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +sodium_crypto_pwhash(): Argument #5 ($memlimit) must be greater than or equal to %d +sodium_crypto_pwhash_str(): Argument #3 ($memlimit) must be greater than or equal to %d diff --git a/ext/sodium/tests/pwhash_valueerror_scrub.phpt b/ext/sodium/tests/pwhash_valueerror_scrub.phpt new file mode 100644 index 000000000000..1cbd776e1839 --- /dev/null +++ b/ext/sodium/tests/pwhash_valueerror_scrub.phpt @@ -0,0 +1,25 @@ +--TEST-- +sodium pwhash argument errors throw ValueError and keep the whole backtrace scrubbed +--EXTENSIONS-- +sodium +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ValueError: sodium_crypto_pwhash_str(): Argument #3 ($memlimit) must be greater than or equal to %d in %s:%d +Stack trace: +#0 %s(%d): sodium_crypto_pwhash_str() +#1 %s(%d): wrap() +#2 {main} + thrown in %s on line %d diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index f15e124ba3f5..39e320049c3d 100644 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -10,8 +10,7 @@ PHP_NEW_EXTENSION([spl], m4_normalize([ spl_iterators.c spl_observer.c ]), - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) PHP_INSTALL_HEADERS([ext/spl], m4_normalize([ php_spl.h spl_array.h diff --git a/ext/spl/config.w32 b/ext/spl/config.w32 index 06e87c663357..4044e05ecb46 100644 --- a/ext/spl/config.w32 +++ b/ext/spl/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */); PHP_SPL="yes"; PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h"); diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index e705a1e303a2..e80917a77067 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -42,16 +40,7 @@ ZEND_TLS zend_string *spl_autoload_extensions; static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload) { - zend_class_entry *ce; - - if (!autoload) { - zend_string *lc_name = zend_string_tolower(name); - - ce = zend_hash_find_ptr(EG(class_table), lc_name); - zend_string_release(lc_name); - } else { - ce = zend_lookup_class(name); - } + zend_class_entry *ce = zend_lookup_class_ex(name, NULL, autoload ? 0 : ZEND_FETCH_CLASS_NO_AUTOLOAD); if (ce == NULL) { php_error_docref(NULL, E_WARNING, "Class %s does not exist%s", ZSTR_VAL(name), autoload ? " and could not be loaded" : ""); return NULL; @@ -60,11 +49,48 @@ static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload) return ce; } +static void spl_add_class_name(HashTable *list, zend_string *name) +{ + zval t; + ZVAL_STR_COPY(&t, name); + zend_hash_add(list, name, &t); +} + +static void spl_add_interfaces(HashTable *list, const zend_class_entry *pce) +{ + if (pce->num_interfaces) { + ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED); + for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) { + spl_add_class_name(list, pce->interfaces[num_interfaces]->name); + } + } +} + +static void spl_add_traits(HashTable *list, const zend_class_entry *pce) +{ + for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) { + spl_add_class_name(list, pce->trait_names[num_traits].name); + } +} + +static void spl_add_classes(HashTable *list, const zend_class_entry *pce, bool only_classes, bool only_interfaces) +{ + ZEND_ASSERT(pce); + ZEND_ASSERT(!(only_classes && only_interfaces) && "Cannot have both only classes and only interfaces be enabled"); + if ( + (only_classes && (pce->ce_flags & ZEND_ACC_INTERFACE) == ZEND_ACC_INTERFACE) + || (only_interfaces && (pce->ce_flags & ZEND_ACC_INTERFACE) == 0) + ) { + return; + } + spl_add_class_name(list, pce->name); +} + /* {{{ Return an array containing the names of all parent classes */ PHP_FUNCTION(class_parents) { zval *obj; - zend_class_entry *parent_class, *ce; + zend_class_entry *ce; bool autoload = true; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ @@ -73,7 +99,7 @@ PHP_FUNCTION(class_parents) } if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) { - zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(obj)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_OBJECT_OR_STRING, obj); RETURN_THROWS(); } @@ -86,9 +112,9 @@ PHP_FUNCTION(class_parents) } array_init(return_value); - parent_class = ce->parent; + const zend_class_entry *parent_class = ce->parent; while (parent_class) { - spl_add_class_name(return_value, parent_class, 0, 0); + spl_add_class_name(Z_ARR_P(return_value), parent_class->name); parent_class = parent_class->parent; } } @@ -99,14 +125,14 @@ PHP_FUNCTION(class_implements) { zval *obj; bool autoload = true; - zend_class_entry *ce; + const zend_class_entry *ce; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &obj, &autoload) == FAILURE) { RETURN_THROWS(); } if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) { - zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(obj)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_OBJECT_OR_STRING, obj); RETURN_THROWS(); } @@ -119,7 +145,7 @@ PHP_FUNCTION(class_implements) } array_init(return_value); - spl_add_interfaces(return_value, ce, 1, ZEND_ACC_INTERFACE); + spl_add_interfaces(Z_ARR_P(return_value), ce); } /* }}} */ @@ -128,14 +154,14 @@ PHP_FUNCTION(class_uses) { zval *obj; bool autoload = true; - zend_class_entry *ce; + const zend_class_entry *ce; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &obj, &autoload) == FAILURE) { RETURN_THROWS(); } if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) { - zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(obj)); + zend_wrong_parameter_type_error(1, Z_EXPECTED_OBJECT_OR_STRING, obj); RETURN_THROWS(); } @@ -148,69 +174,69 @@ PHP_FUNCTION(class_uses) } array_init(return_value); - spl_add_traits(return_value, ce, 1, ZEND_ACC_TRAIT); + spl_add_traits(Z_ARR_P(return_value), ce); } /* }}} */ -#define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \ - spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags) - -#define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \ - SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ArrayObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(FilesystemIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(GlobIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(InvalidArgumentException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LengthException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LogicException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(MultipleIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OutOfBoundsException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OutOfRangeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveRegexIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveTreeIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RegexIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplDoublyLinkedList, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFileInfo, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFileObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFixedArray, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplMinHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplMaxHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplObserver, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplPriorityQueue, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplQueue, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplStack, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplSubject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags); \ +#define SPL_ADD_CLASS(class_name, z_list, only_classes, only_interfaces) \ + spl_add_classes(Z_ARR_P(z_list), spl_ce_ ## class_name, only_classes, only_interfaces) + +#define SPL_LIST_CLASSES(z_list, only_classes, only_interfaces) \ + SPL_ADD_CLASS(AppendIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ArrayIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ArrayObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(BadFunctionCallException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(BadMethodCallException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(CachingIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(CallbackFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(DirectoryIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(DomainException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(EmptyIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(FilesystemIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(FilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(GlobIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(InfiniteIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(InvalidArgumentException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(IteratorIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LengthException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LimitIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LogicException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(MultipleIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(NoRewindIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OuterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OutOfBoundsException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OutOfRangeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OverflowException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ParentIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RangeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveArrayIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveCachingIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveRegexIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveTreeIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RegexIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RuntimeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SeekableIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplDoublyLinkedList, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFileInfo, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFileObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFixedArray, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplMinHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplMaxHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplObjectStorage, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplObserver, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplPriorityQueue, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplQueue, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplStack, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplSubject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplTempFileObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(UnderflowException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(UnexpectedValueException, z_list, only_classes, only_interfaces); \ /* {{{ Return an array containing the names of all classes and interfaces defined in SPL */ PHP_FUNCTION(spl_classes) @@ -219,7 +245,7 @@ PHP_FUNCTION(spl_classes) array_init(return_value); - SPL_LIST_CLASSES(return_value, 0, 0, 0) + SPL_LIST_CLASSES(return_value, false, false) } /* }}} */ @@ -299,7 +325,12 @@ PHP_FUNCTION(spl_autoload) pos_len = ZSTR_LEN(file_exts); } - lc_name = zend_string_tolower(class_name); + if (ZSTR_VAL(class_name)[0] == '\\') { + lc_name = zend_string_alloc(ZSTR_LEN(class_name) - 1, 0); + zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(class_name) + 1, ZSTR_LEN(class_name) - 1); + } else { + lc_name = zend_string_tolower(class_name); + } while (pos && *pos && !EG(exception)) { pos1 = strchr(pos, ','); if (pos1) { @@ -486,7 +517,7 @@ PHP_MINFO_FUNCTION(spl) php_info_print_table_row(2, "SPL support", "enabled"); array_init(&list); - SPL_LIST_CLASSES(&list, 0, 1, ZEND_ACC_INTERFACE) + SPL_LIST_CLASSES(&list, false, true) strg = estrdup(""); ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) { spl_build_class_list_string(zv, &strg); @@ -496,7 +527,7 @@ PHP_MINFO_FUNCTION(spl) efree(strg); array_init(&list); - SPL_LIST_CLASSES(&list, 0, -1, ZEND_ACC_INTERFACE) + SPL_LIST_CLASSES(&list, true, false) strg = estrdup(""); ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) { spl_build_class_list_string(zv, &strg); @@ -528,6 +559,7 @@ PHP_MINIT_FUNCTION(spl) PHP_RINIT_FUNCTION(spl) /* {{{ */ { spl_autoload_extensions = NULL; + spl_object_storage_reset_get_hash_depth(); return SUCCESS; } /* }}} */ diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index c2f7ebf9eee1..b1d4f4416a79 100644 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 3d6870a7ee95..1976192e7b06 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -44,8 +42,6 @@ typedef struct _spl_array_object { uint32_t ht_iter; int ar_flags; unsigned char nApplyCount; - bool is_child; - Bucket *bucket; zend_function *fptr_offset_get; zend_function *fptr_offset_set; zend_function *fptr_offset_has; @@ -55,10 +51,7 @@ typedef struct _spl_array_object { zend_object std; } spl_array_object; -static inline spl_array_object *spl_array_from_obj(zend_object *obj) /* {{{ */ { - return (spl_array_object*)((char*)(obj) - XtOffsetOf(spl_array_object, std)); -} -/* }}} */ +#define spl_array_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_array_object, std) #define Z_SPLARRAY_P(zv) spl_array_from_obj(Z_OBJ_P((zv))) @@ -157,7 +150,7 @@ static void spl_array_object_free_storage(zend_object *object) static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) { spl_array_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_array_object), parent); @@ -166,8 +159,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_o object_properties_init(&intern->std, class_type); intern->ar_flags = 0; - intern->is_child = false; - intern->bucket = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = spl_array_from_obj(orig); @@ -465,22 +456,6 @@ static zval *spl_array_read_dimension(zend_object *object, zval *offset, int typ return spl_array_read_dimension_ex(1, object, offset, type, rv); } /* }}} */ -/* - * The assertion(HT_ASSERT_RC1(ht)) failed because the refcount was increased manually when intern->is_child is true. - * We have to set the refcount to 1 to make assertion success and restore the refcount to the original value after - * modifying the array when intern->is_child is true. - */ -static uint32_t spl_array_set_refcount(bool is_child, HashTable *ht, uint32_t refcount) /* {{{ */ -{ - uint32_t old_refcount = 0; - if (is_child) { - old_refcount = GC_REFCOUNT(ht); - GC_SET_REFCOUNT(ht, refcount); - } - - return old_refcount; -} /* }}} */ - static void spl_array_write_dimension_ex(int check_inherited, zend_object *object, zval *offset, zval *value) /* {{{ */ { spl_array_object *intern = spl_array_from_obj(object); @@ -504,19 +479,12 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec } Z_TRY_ADDREF_P(value); - - uint32_t refcount = 0; if (!offset || Z_TYPE_P(offset) == IS_NULL) { ht = spl_array_get_hash_table(intern); if (UNEXPECTED(ht == intern->sentinel_array)) { return; } - refcount = spl_array_set_refcount(intern->is_child, ht, 1); zend_hash_next_index_insert(ht, value); - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } return; } @@ -531,17 +499,13 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec spl_hash_key_release(&key); return; } - refcount = spl_array_set_refcount(intern->is_child, ht, 1); + if (key.key) { zend_hash_update_ind(ht, key.key, value); spl_hash_key_release(&key); } else { zend_hash_index_update(ht, key.h, value); } - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } } /* }}} */ static void spl_array_write_dimension(zend_object *object, zval *offset, zval *value) /* {{{ */ @@ -571,8 +535,6 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec } ht = spl_array_get_hash_table(intern); - uint32_t refcount = spl_array_set_refcount(intern->is_child, ht, 1); - if (key.key) { zval *data = zend_hash_find(ht, key.key); if (data) { @@ -597,10 +559,6 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec } else { zend_hash_index_del(ht, key.h); } - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } } /* }}} */ static void spl_array_unset_dimension(zend_object *object, zval *offset) /* {{{ */ @@ -963,6 +921,10 @@ static zend_result spl_array_skip_protected(spl_array_object *intern, HashTable static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, bool just_array) { /* Handled by ZPP prior to this, or for __unserialize() before passing to here */ ZEND_ASSERT(Z_TYPE_P(array) == IS_ARRAY || Z_TYPE_P(array) == IS_OBJECT); + if (intern->nApplyCount > 0) { + zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited"); + return; + } zval garbage; ZVAL_UNDEF(&garbage); if (Z_TYPE_P(array) == IS_ARRAY) { @@ -972,15 +934,6 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar } else { //??? TODO: try to avoid array duplication ZVAL_ARR(&intern->array, zend_array_dup(Z_ARR_P(array))); - - if (intern->is_child) { - Z_TRY_DELREF(intern->bucket->val); - /* - * replace bucket->val with copied array, so the changes between - * parent and child object can affect each other. - */ - ZVAL_COPY(&intern->bucket->val, &intern->array); - } } } else { php_error_docref(NULL, E_DEPRECATED, @@ -1200,18 +1153,12 @@ PHP_METHOD(ArrayObject, count) RETURN_LONG(spl_array_object_count_elements_helper(intern)); } /* }}} */ -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) /* {{{ */ +static void spl_array_method(zval *return_value, spl_array_object *intern, const char *fname, size_t fname_len, const zval *extra_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 params[2], *arg = NULL; + zval params[2]; + uint32_t param_num = 1; zend_function *fn = zend_hash_str_find_ptr(EG(function_table), fname, fname_len); if (UNEXPECTED(fn == NULL)) { @@ -1223,68 +1170,85 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, const char *fname, si ZVAL_ARR(Z_REFVAL(params[0]), aht); GC_ADDREF(aht); - if (use_arg == SPL_NAT_SORT) { - if (zend_parse_parameters_none() == FAILURE) { - goto exit; - } - - intern->nApplyCount++; - zend_call_known_function(fn, NULL, NULL, return_value, 1, params, NULL); - intern->nApplyCount--; - } 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++; - 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++; - zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); - intern->nApplyCount--; + if (extra_arg) { + param_num = 2; + ZVAL_COPY_VALUE(¶ms[1], extra_arg); } + intern->nApplyCount++; + zend_call_known_function(fn, NULL, NULL, return_value, param_num, params, NULL); + intern->nApplyCount--; -exit: - { - zval *ht_zv = Z_REFVAL(params[0]); - zend_array_release(*ht_ptr); - SEPARATE_ARRAY(ht_zv); - *ht_ptr = Z_ARRVAL_P(ht_zv); - ZVAL_NULL(ht_zv); - zval_ptr_dtor(¶ms[0]); - } + zval *ht_zv = Z_REFVAL(params[0]); + zend_array_release(*ht_ptr); + SEPARATE_ARRAY(ht_zv); + *ht_ptr = Z_ARRVAL_P(ht_zv); + ZVAL_NULL(ht_zv); + zval_ptr_dtor(¶ms[0]); } /* }}} */ -#define SPL_ARRAY_METHOD(cname, fname, use_arg) \ -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_OPTIONAL_FLAG_SORT) +PHP_METHOD(ArrayObject, asort) +{ + zend_long sort_flags = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { + RETURN_THROWS(); + } + zval sort_flag_param; + ZVAL_LONG(&sort_flag_param, sort_flags); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("asort"), &sort_flag_param); +} /* Sort the entries by key. */ -SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_OPTIONAL_FLAG_SORT) +PHP_METHOD(ArrayObject, ksort) +{ + zend_long sort_flags = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { + RETURN_THROWS(); + } + zval sort_flag_param; + ZVAL_LONG(&sort_flag_param, sort_flags); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("ksort"), &sort_flag_param); +} /* Sort the entries by values user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_CALLBACK_SORT) +PHP_METHOD(ArrayObject, uasort) +{ + zval *callback = NULL; + /* TODO: Should check variable is callable */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { + RETURN_THROWS(); + } + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("uasort"), callback); +} /* Sort the entries by key using user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_CALLBACK_SORT) +PHP_METHOD(ArrayObject, uksort) +{ + zval *callback = NULL; + /* TODO: Should check variable is callable */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { + RETURN_THROWS(); + } + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("uksort"), callback); +} /* Sort the entries by values using "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_NAT_SORT) +PHP_METHOD(ArrayObject, natsort) +{ + ZEND_PARSE_PARAMETERS_NONE(); -/* {{{ Sort the entries by key using case-insensitive "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_NAT_SORT) + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("natsort"), NULL); +} + +/* Sort the entries by key using case-insensitive "natural order" algorithm. */ +PHP_METHOD(ArrayObject, natcasesort) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("natcasesort"), NULL); +} /* {{{ Serialize the object */ PHP_METHOD(ArrayObject, serialize) @@ -1530,9 +1494,9 @@ PHP_METHOD(ArrayObject, __unserialize) RETURN_THROWS(); } - if (!instanceof_function(ce, zend_ce_iterator)) { + if (!instanceof_function(ce, spl_ce_ArrayIterator)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot deserialize ArrayObject with iterator class '%s'; this class does not implement the Iterator interface", + "Cannot deserialize ArrayObject with iterator class '%s'; this class is not derived from ArrayIterator", ZSTR_VAL(Z_STR_P(iterator_class_zv))); RETURN_THROWS(); } @@ -1850,15 +1814,6 @@ PHP_METHOD(RecursiveArrayIterator, hasChildren) static void spl_instantiate_child_arg(zend_class_entry *pce, zval *retval, zval *arg1, zval *arg2) /* {{{ */ { object_init_ex(retval, pce); - spl_array_object *new_intern = Z_SPLARRAY_P(retval); - /* - * set new_intern->is_child is true to indicate that the object was created by - * RecursiveArrayIterator::getChildren() method. - */ - new_intern->is_child = true; - - /* find the bucket of parent object. */ - new_intern->bucket = (Bucket *)((char *)(arg1) - XtOffsetOf(Bucket, val));; zend_call_known_instance_method_with_2_params(pce->constructor, Z_OBJ_P(retval), NULL, arg1, arg2); } /* }}} */ @@ -1904,7 +1859,7 @@ PHP_MINIT_FUNCTION(spl_array) memcpy(&spl_handler_ArrayObject, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_ArrayObject.offset = XtOffsetOf(spl_array_object, std); + spl_handler_ArrayObject.offset = offsetof(spl_array_object, std); spl_handler_ArrayObject.clone_obj = spl_array_object_clone; spl_handler_ArrayObject.read_dimension = spl_array_read_dimension; diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index 86de7a955c5b..f99bb3f6fe88 100644 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 86e4b11334c8..ccab32aec783 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -50,11 +48,7 @@ PHPAPI zend_class_entry *spl_ce_GlobIterator; PHPAPI zend_class_entry *spl_ce_SplFileObject; PHPAPI zend_class_entry *spl_ce_SplTempFileObject; -/* Object helper */ -static inline spl_filesystem_object *spl_filesystem_from_obj(zend_object *obj) /* {{{ */ { - return (spl_filesystem_object*)((char*)(obj) - XtOffsetOf(spl_filesystem_object, std)); -} -/* }}} */ +#define spl_filesystem_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_filesystem_object, std) /* define an overloaded iterator structure */ typedef struct { @@ -190,8 +184,8 @@ static zend_object *spl_filesystem_object_new(zend_class_entry *class_type) intern = emalloc(sizeof(spl_filesystem_object) + zend_object_properties_size(class_type)); /* Avoid initializing the entirety of spl_filesystem_object.u.dir.entry. */ memset(intern, 0, - MAX(XtOffsetOf(spl_filesystem_object, u.dir.entry), - XtOffsetOf(spl_filesystem_object, u.file.escape) + sizeof(int))); + MAX(offsetof(spl_filesystem_object, u.dir.entry), + offsetof(spl_filesystem_object, u.file.escape) + sizeof(int))); /* intern->type = SPL_FS_INFO; done by set 0 */ intern->file_class = spl_ce_SplFileObject; intern->info_class = spl_ce_SplFileInfo; @@ -1470,11 +1464,11 @@ PHP_METHOD(RecursiveDirectoryIterator, getChildren) if (subdir) { size_t name_len = strlen(intern->u.dir.entry.d_name); if (intern->u.dir.sub_path && ZSTR_LEN(intern->u.dir.sub_path)) { - zend_string *sub_path = zend_string_alloc(ZSTR_LEN(intern->u.dir.sub_path) + 1 + name_len, 0); - memcpy(ZSTR_VAL(sub_path), ZSTR_VAL(intern->u.dir.sub_path), ZSTR_LEN(intern->u.dir.sub_path)); - ZSTR_VAL(sub_path)[ZSTR_LEN(intern->u.dir.sub_path)] = slash; - memcpy(ZSTR_VAL(sub_path) + ZSTR_LEN(intern->u.dir.sub_path) + 1, intern->u.dir.entry.d_name, name_len); - ZSTR_VAL(sub_path)[ZSTR_LEN(intern->u.dir.sub_path) + 1 + name_len] = 0; + zend_string *sub_path = zend_string_concat3( + ZSTR_VAL(intern->u.dir.sub_path), ZSTR_LEN(intern->u.dir.sub_path), + &slash, 1, + intern->u.dir.entry.d_name, name_len + ); subdir->u.dir.sub_path = sub_path; } else { subdir->u.dir.sub_path = zend_string_init(intern->u.dir.entry.d_name, name_len, 0); @@ -1813,21 +1807,24 @@ static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bo } if (!buf) { - intern->u.file.current_line = ZSTR_EMPTY_ALLOC(); - } else { - if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { - if (line_len > 0 && buf[line_len - 1] == '\n') { + if (!silent) { + spl_filesystem_file_cannot_read(intern); + } + return FAILURE; + } + + if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { + if (line_len > 0 && buf[line_len - 1] == '\n') { + line_len--; + if (line_len > 0 && buf[line_len - 1] == '\r') { line_len--; - if (line_len > 0 && buf[line_len - 1] == '\r') { - line_len--; - } - buf[line_len] = '\0'; } + buf[line_len] = '\0'; } - - intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); - efree(buf); } + + intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); + efree(buf); intern->u.file.current_line_num += line_add; return SUCCESS; @@ -2093,10 +2090,21 @@ PHP_METHOD(SplFileObject, fgets) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) { - RETURN_THROWS(); + if (intern->u.file.current_line) { + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); + intern->u.file.current_line_num++; + } else { + if (spl_filesystem_file_read_ex(intern, /* silent */ true, /* line_add */ 1, /* csv */ false) == FAILURE) { + if (php_stream_eof(intern->u.file.stream)) { + RETURN_EMPTY_STRING(); + } + spl_filesystem_file_cannot_read(intern); + RETURN_THROWS(); + } + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); } - RETURN_STR_COPY(intern->u.file.current_line); } /* }}} */ /* {{{ Return current line from file */ @@ -2142,6 +2150,14 @@ PHP_METHOD(SplFileObject, next) ZEND_PARSE_PARAMETERS_NONE(); + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); + + if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + return; + } + } + spl_filesystem_file_free_line(intern); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { spl_filesystem_file_read_line(ZEND_THIS, intern, true); @@ -2286,6 +2302,8 @@ PHP_METHOD(SplFileObject, fputcsv) RETURN_THROWS(); } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); + if (delim) { if (d_len != 1) { zend_argument_value_error(2, "must be a single character"); @@ -2629,7 +2647,7 @@ PHP_METHOD(SplFileObject, seek) for (i = 0; i < line_pos; i++) { if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { - return; + break; } } if (line_pos > 0 && !SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { @@ -2648,9 +2666,8 @@ PHP_METHOD(SplFileObject, __toString) if (!intern->u.file.current_line) { ZEND_ASSERT(Z_ISUNDEF(intern->u.file.current_zval)); - zend_result result = spl_filesystem_file_read_line(ZEND_THIS, intern, false); - if (UNEXPECTED(result != SUCCESS)) { - RETURN_THROWS(); + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + RETURN_EMPTY_STRING(); } } @@ -2665,7 +2682,7 @@ PHP_MINIT_FUNCTION(spl_directory) spl_ce_SplFileInfo->default_object_handlers = &spl_filesystem_object_handlers; memcpy(&spl_filesystem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - spl_filesystem_object_handlers.offset = XtOffsetOf(spl_filesystem_object, std); + spl_filesystem_object_handlers.offset = offsetof(spl_filesystem_object, std); spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; spl_filesystem_object_handlers.dtor_obj = spl_filesystem_object_destroy_object; spl_filesystem_object_handlers.free_obj = spl_filesystem_object_free_storage; diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index a2d1d8d85475..6d940e8aa8ef 100644 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 5eceff88dfab..77e8b0d4e7da 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ @@ -87,10 +85,7 @@ struct _spl_dllist_it { int flags; }; -static inline spl_dllist_object *spl_dllist_from_obj(zend_object *obj) /* {{{ */ { - return (spl_dllist_object*)((char*)(obj) - XtOffsetOf(spl_dllist_object, std)); -} -/* }}} */ +#define spl_dllist_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_dllist_object, std) #define Z_SPLDLLIST_P(zv) spl_dllist_from_obj(Z_OBJ_P((zv))) @@ -304,7 +299,7 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) /* {{{ */ { spl_dllist_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_dllist_object), parent); @@ -316,7 +311,7 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_ intern->traverse_position = 0; if (orig) { - spl_dllist_object *other = spl_dllist_from_obj(orig); + const spl_dllist_object *other = spl_dllist_from_obj(orig); if (clone_orig) { intern->llist = spl_ptr_llist_init(); @@ -800,6 +795,7 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p if (flags & SPL_DLLIST_IT_LIFO) { *traverse_pointer_ptr = old->prev; + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); (*traverse_position_ptr)--; if (flags & SPL_DLLIST_IT_DELETE) { @@ -810,6 +806,7 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p } } else { *traverse_pointer_ptr = old->next; + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); if (flags & SPL_DLLIST_IT_DELETE) { zval prev; @@ -822,7 +819,6 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p } SPL_LLIST_DELREF(old); - SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); } } /* }}} */ @@ -1209,7 +1205,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */ memcpy(&spl_handler_SplDoublyLinkedList, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplDoublyLinkedList.offset = XtOffsetOf(spl_dllist_object, std); + spl_handler_SplDoublyLinkedList.offset = offsetof(spl_dllist_object, std); spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone; spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements; spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc; diff --git a/ext/spl/spl_dllist.h b/ext/spl/spl_dllist.h index 1ade7c44a3f0..fb2204b2aca9 100644 --- a/ext/spl/spl_dllist.h +++ b/ext/spl/spl_dllist.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_exceptions.c b/ext/spl/spl_exceptions.c index 79449f35d840..8ceba1f7a6a5 100644 --- a/ext/spl/spl_exceptions.c +++ b/ext/spl/spl_exceptions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_exceptions.h b/ext/spl/spl_exceptions.h index 8c390f7646ec..be1de4f51d1b 100644 --- a/ext/spl/spl_exceptions.h +++ b/ext/spl/spl_exceptions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 6f976923341b..d2eae52e3c0c 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Antony Dovgal | | Etienne Kneuss | @@ -55,10 +53,7 @@ typedef struct _spl_fixedarray_it { zend_long current; } spl_fixedarray_it; -static spl_fixedarray_object *spl_fixed_array_from_obj(zend_object *obj) -{ - return (spl_fixedarray_object*)((char*)(obj) - XtOffsetOf(spl_fixedarray_object, std)); -} +#define spl_fixed_array_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_fixedarray_object, std) #define Z_SPLFIXEDARRAY_P(zv) spl_fixed_array_from_obj(Z_OBJ_P((zv))) @@ -172,18 +167,18 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) return; } - /* first initialization */ - if (array->size == 0) { - spl_fixedarray_init(array, size); - return; - } - if (UNEXPECTED(array->cached_resize >= 0)) { /* We're already resizing, so just remember the desired size. * The resize will happen later. */ array->cached_resize = size; return; } + /* first initialization */ + if (array->size == 0) { + spl_fixedarray_init(array, size); + return; + } + array->cached_resize = size; /* clearing the array */ @@ -954,7 +949,7 @@ PHP_MINIT_FUNCTION(spl_fixedarray) memcpy(&spl_handler_SplFixedArray, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplFixedArray.offset = XtOffsetOf(spl_fixedarray_object, std); + spl_handler_SplFixedArray.offset = offsetof(spl_fixedarray_object, std); spl_handler_SplFixedArray.clone_obj = spl_fixedarray_object_clone; spl_handler_SplFixedArray.read_dimension = spl_fixedarray_object_read_dimension; spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension; diff --git a/ext/spl/spl_fixedarray.h b/ext/spl/spl_fixedarray.h index a6cb838b9fc9..e0661a95d872 100644 --- a/ext/spl/spl_fixedarray.h +++ b/ext/spl/spl_fixedarray.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Antony Dovgal | | Etienne Kneuss | diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index e7ecbc33f92e..2e04baa26dee 100644 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -20,63 +18,6 @@ #include "php.h" -/* {{{ spl_add_class_name */ -void spl_add_class_name(zval *list, zend_class_entry *pce, int allow, int ce_flags) -{ - if (!allow || (allow > 0 && (pce->ce_flags & ce_flags)) || (allow < 0 && !(pce->ce_flags & ce_flags))) { - zval *tmp; - - if ((tmp = zend_hash_find(Z_ARRVAL_P(list), pce->name)) == NULL) { - zval t; - ZVAL_STR_COPY(&t, pce->name); - zend_hash_add(Z_ARRVAL_P(list), pce->name, &t); - } - } -} -/* }}} */ - -/* {{{ spl_add_interfaces */ -void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_flags) -{ - if (pce->num_interfaces) { - ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED); - for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) { - spl_add_class_name(list, pce->interfaces[num_interfaces], allow, ce_flags); - } - } -} -/* }}} */ - -/* {{{ spl_add_traits */ -void spl_add_traits(zval *list, zend_class_entry * pce, int allow, int ce_flags) -{ - zend_class_entry *trait; - - for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) { - trait = zend_fetch_class_by_name(pce->trait_names[num_traits].name, - pce->trait_names[num_traits].lc_name, ZEND_FETCH_CLASS_TRAIT); - ZEND_ASSERT(trait); - spl_add_class_name(list, trait, allow, ce_flags); - } -} -/* }}} */ - - -/* {{{ spl_add_classes */ -void spl_add_classes(zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags) -{ - ZEND_ASSERT(pce); - spl_add_class_name(list, pce, allow, ce_flags); - if (sub) { - spl_add_interfaces(list, pce, allow, ce_flags); - while (pce->parent) { - pce = pce->parent; - spl_add_classes(pce, list, sub, allow, ce_flags); - } - } -} -/* }}} */ - void spl_set_private_debug_info_property( const zend_class_entry *ce, const char *property, diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index eb81a8b8f818..1d5010030564 100644 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -19,16 +17,6 @@ #include "php.h" -/* sub: whether to allow subclasses/interfaces - allow = 0: allow all classes and interfaces - allow > 0: allow all that match and mask ce_flags - allow < 0: disallow all that match and mask ce_flags - */ -void spl_add_class_name(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_interfaces(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_traits(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_classes(zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags); - void spl_set_private_debug_info_property(const zend_class_entry *ce, const char *property, size_t property_len, HashTable *debug_info, zval *value); #endif /* PHP_FUNCTIONS_H */ diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 85fc5f8bb698..1073836aa53b 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ @@ -72,10 +70,7 @@ typedef struct _spl_pqueue_elem { zval priority; } spl_pqueue_elem; -static inline spl_heap_object *spl_heap_from_obj(zend_object *obj) /* {{{ */ { - return (spl_heap_object*)((char*)(obj) - XtOffsetOf(spl_heap_object, std)); -} -/* }}} */ +#define spl_heap_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_heap_object, std) #define Z_SPLHEAP_P(zv) spl_heap_from_obj(Z_OBJ_P((zv))) @@ -412,7 +407,7 @@ static void spl_heap_object_free_storage(zend_object *object) /* {{{ */ static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) /* {{{ */ { spl_heap_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_heap_object), parent); @@ -938,7 +933,7 @@ static void spl_heap_it_move_forward(zend_object_iterator *iter) /* {{{ */ { spl_heap_object *object = Z_SPLHEAP_P(&iter->data); - if (UNEXPECTED(spl_heap_consistency_validations(object, false) != SUCCESS)) { + if (UNEXPECTED(spl_heap_consistency_validations(object, true) != SUCCESS)) { return; } @@ -965,6 +960,10 @@ PHP_METHOD(SplHeap, next) ZEND_PARSE_PARAMETERS_NONE(); + if (UNEXPECTED(spl_heap_consistency_validations(intern, true) != SUCCESS)) { + RETURN_THROWS(); + } + spl_ptr_heap_delete_top(intern->heap, NULL, ZEND_THIS); } /* }}} */ @@ -1330,7 +1329,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */ memcpy(&spl_handler_SplHeap, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplHeap.offset = XtOffsetOf(spl_heap_object, std); + spl_handler_SplHeap.offset = offsetof(spl_heap_object, std); spl_handler_SplHeap.clone_obj = spl_heap_object_clone; spl_handler_SplHeap.count_elements = spl_heap_object_count_elements; spl_handler_SplHeap.get_gc = spl_heap_object_get_gc; @@ -1351,7 +1350,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */ memcpy(&spl_handler_SplPriorityQueue, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplPriorityQueue.offset = XtOffsetOf(spl_heap_object, std); + spl_handler_SplPriorityQueue.offset = offsetof(spl_heap_object, std); spl_handler_SplPriorityQueue.clone_obj = spl_heap_object_clone; spl_handler_SplPriorityQueue.count_elements = spl_heap_object_count_elements; spl_handler_SplPriorityQueue.get_gc = spl_pqueue_object_get_gc; diff --git a/ext/spl/spl_heap.h b/ext/spl/spl_heap.h index ccc0dd706bfe..153af1171544 100644 --- a/ext/spl/spl_heap.h +++ b/ext/spl/spl_heap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index a73e69519db5..95fe2d7c0b56 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -138,16 +136,11 @@ typedef struct _spl_dual_it_object { static zend_object_handlers spl_handlers_rec_it_it; static zend_object_handlers spl_handlers_dual_it; -static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *obj) /* {{{ */ { - return (spl_recursive_it_object*)((char*)(obj) - XtOffsetOf(spl_recursive_it_object, std)); -} -/* }}} */ +#define spl_recursive_it_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_recursive_it_object, std) #define Z_SPLRECURSIVE_IT_P(zv) spl_recursive_it_from_obj(Z_OBJ_P((zv))) -static inline spl_dual_it_object *spl_dual_it_from_obj(zend_object *obj) /* {{{ */ { - return (spl_dual_it_object*)((char*)(obj) - XtOffsetOf(spl_dual_it_object, std)); -} /* }}} */ +#define spl_dual_it_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_dual_it_object, std) #define Z_SPLDUAL_IT_P(zv) spl_dual_it_from_obj(Z_OBJ_P((zv))) @@ -257,6 +250,10 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv zend_class_entry *ce; zval retval, child; zend_object_iterator *sub_iter; + zend_object *sub_object; + uint32_t prev_level; + zend_result valid_result; + bool reentered; SPL_FETCH_SUB_ITERATOR(iterator, object); @@ -273,9 +270,20 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv zend_clear_exception(); } } + iterator = object->iterators[object->level].iterator; ZEND_FALLTHROUGH; case RS_START: - if (iterator->funcs->valid(iterator) == FAILURE) { + sub_object = Z_OBJ(object->iterators[object->level].zobject); + prev_level = object->level; + GC_ADDREF(sub_object); + valid_result = iterator->funcs->valid(iterator); + reentered = object->level != prev_level + || object->iterators[object->level].iterator != iterator; + OBJ_RELEASE(sub_object); + if (reentered) { + return; + } + if (valid_result == FAILURE) { break; } object->iterators[object->level].state = RS_TEST; @@ -423,7 +431,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv } } } - if (object->level > 0) { + if (object->level > 0 && object->iterators[object->level].iterator == iterator) { zval garbage; ZVAL_COPY_VALUE(&garbage, &object->iterators[object->level].zobject); ZVAL_UNDEF(&object->iterators[object->level].zobject); @@ -1341,15 +1349,6 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z } break; } - case DIT_AppendIterator: - if (zend_parse_parameters_none() == FAILURE) { - return NULL; - } - intern->dit_type = DIT_AppendIterator; - object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator); - zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL); - intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0); - return intern; case DIT_RegexIterator: case DIT_RecursiveRegexIterator: { zend_string *regex; @@ -2814,7 +2813,21 @@ static void spl_append_it_next(spl_dual_it_object *intern) /* {{{ */ /* {{{ Create an AppendIterator */ PHP_METHOD(AppendIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_AppendIterator, zend_ce_iterator, DIT_AppendIterator); + ZEND_PARSE_PARAMETERS_NONE(); + + spl_dual_it_object *intern = Z_SPLDUAL_IT_P(ZEND_THIS); + + /* TODO: This should be converted to a normal Error as this is triggered when calling the constructor twice */ + if (intern->dit_type != DIT_Unknown) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s::getIterator() must be called exactly once per instance", ZSTR_VAL(spl_ce_AppendIterator->name)); + RETURN_THROWS(); + } + + intern->dit_type = DIT_AppendIterator; + object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator); + zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL); + intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0); + } /* }}} */ /* {{{ Append an iterator */ @@ -3131,14 +3144,14 @@ PHP_MINIT_FUNCTION(spl_iterators) spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator; memcpy(&spl_handlers_rec_it_it, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handlers_rec_it_it.offset = XtOffsetOf(spl_recursive_it_object, std); + spl_handlers_rec_it_it.offset = offsetof(spl_recursive_it_object, std); spl_handlers_rec_it_it.get_method = spl_recursive_it_get_method; spl_handlers_rec_it_it.clone_obj = NULL; spl_handlers_rec_it_it.free_obj = spl_RecursiveIteratorIterator_free_storage; spl_handlers_rec_it_it.get_gc = spl_RecursiveIteratorIterator_get_gc; memcpy(&spl_handlers_dual_it, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handlers_dual_it.offset = XtOffsetOf(spl_dual_it_object, std); + spl_handlers_dual_it.offset = offsetof(spl_dual_it_object, std); spl_handlers_dual_it.get_method = spl_dual_it_get_method; spl_handlers_dual_it.clone_obj = NULL; spl_handlers_dual_it.free_obj = spl_dual_it_free_storage; diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index e77e34fb20c8..5b60705e9b23 100644 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 801c091fbb42..613bf5384dcb 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | | Etienne Kneuss | @@ -47,6 +45,13 @@ static zend_object_handlers spl_handler_MultipleIterator; #define SOS_OVERRIDDEN_WRITE_DIMENSION 2 #define SOS_OVERRIDDEN_UNSET_DIMENSION 4 +ZEND_TLS uint32_t spl_object_storage_get_hash_depth; + +void spl_object_storage_reset_get_hash_depth(void) +{ + spl_object_storage_get_hash_depth = 0; +} + typedef struct _spl_SplObjectStorage { /* {{{ */ HashTable storage; zend_long index; @@ -64,13 +69,20 @@ typedef struct _spl_SplObjectStorageElement { zval inf; } spl_SplObjectStorageElement; /* }}} */ -static inline spl_SplObjectStorage *spl_object_storage_from_obj(zend_object *obj) /* {{{ */ { - return (spl_SplObjectStorage*)((char*)(obj) - XtOffsetOf(spl_SplObjectStorage, std)); -} -/* }}} */ +#define spl_object_storage_from_obj(obj) ZEND_CONTAINER_OF(obj, spl_SplObjectStorage, std) #define Z_SPLOBJSTORAGE_P(zv) spl_object_storage_from_obj(Z_OBJ_P((zv))) +static zend_always_inline bool spl_object_storage_is_mutating_within_get_hash_call(void) +{ + if (UNEXPECTED(spl_object_storage_get_hash_depth)) { + zend_throw_error(NULL, "Modification of SplObjectStorage during getHash() is prohibited"); + return true; + } + + return false; +} + static void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */ { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); @@ -85,7 +97,10 @@ static zend_result spl_object_storage_get_hash(zend_hash_key *key, spl_SplObject zval param; zval rv; ZVAL_OBJ(¶m, obj); + ZVAL_UNDEF(&rv); + spl_object_storage_get_hash_depth++; zend_call_method_with_1_params(&intern->std, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, ¶m); + spl_object_storage_get_hash_depth--; if (UNEXPECTED(Z_ISUNDEF(rv))) { /* An exception has occurred */ return FAILURE; @@ -178,6 +193,10 @@ static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObje static spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *intern, zend_object *obj, zval *inf) /* {{{ */ { + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return NULL; + } + if (EXPECTED(!(intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { return spl_object_storage_attach_handle(intern, obj, inf); } @@ -223,6 +242,10 @@ static spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStora static zend_result spl_object_storage_detach(spl_SplObjectStorage *intern, zend_object *obj) /* {{{ */ { + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return FAILURE; + } + if (EXPECTED(!(intern->flags & SOS_OVERRIDDEN_UNSET_DIMENSION))) { return zend_hash_index_del(&intern->storage, obj->handle); } @@ -241,14 +264,32 @@ static zend_result spl_object_storage_detach(spl_SplObjectStorage *intern, zend_ return ret; } /* }}}*/ -static void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorage *other) { /* {{{ */ +/* TODO: make this an official Zend API? */ +#define SPL_SAFE_HASH_FOREACH_PTR(_ht, _ptr) do { \ + const HashTable *__ht = (_ht); \ + zval *_z = __ht->arPacked; \ + for (uint32_t _idx = 0; _idx < __ht->nNumUsed; _idx++, _z = ZEND_HASH_ELEMENT(__ht, _idx)) { \ + if (UNEXPECTED(Z_ISUNDEF_P(_z))) continue; \ + _ptr = Z_PTR_P(_z); + +static zend_result spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorage *other) { /* {{{ */ spl_SplObjectStorageElement *element; - ZEND_HASH_FOREACH_PTR(&other->storage, element) { - spl_object_storage_attach(intern, element->obj, &element->inf); + SPL_SAFE_HASH_FOREACH_PTR(&other->storage, element) { + zval zv; + zend_object *obj = element->obj; + GC_ADDREF(obj); + ZVAL_COPY(&zv, &element->inf); + spl_SplObjectStorageElement *attached = spl_object_storage_attach(intern, obj, &zv); + zval_ptr_dtor(&zv); + OBJ_RELEASE(obj); + if (UNEXPECTED(!attached)) { + return FAILURE; + } } ZEND_HASH_FOREACH_END(); intern->index = 0; + return SUCCESS; } /* }}} */ #define SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE(class_type, zstr_method) \ @@ -257,7 +298,7 @@ static void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjec static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend_object *orig) /* {{{ */ { spl_SplObjectStorage *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; intern = zend_object_alloc(sizeof(spl_SplObjectStorage), parent); intern->pos = 0; @@ -434,6 +475,9 @@ PHP_METHOD(SplObjectStorage, attach) Z_PARAM_ZVAL(inf) ZEND_PARSE_PARAMETERS_END(); spl_object_storage_attach(intern, obj, inf); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } /* }}} */ // todo: make spl_object_storage_has_dimension return bool as well @@ -482,6 +526,10 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset static void spl_object_storage_write_dimension(zend_object *object, zval *offset, zval *inf) { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + if (UNEXPECTED(offset == NULL || Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { zend_std_write_dimension(object, offset, inf); return; @@ -492,6 +540,10 @@ static void spl_object_storage_write_dimension(zend_object *object, zval *offset static void spl_multiple_iterator_write_dimension(zend_object *object, zval *offset, zval *inf) { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + if (UNEXPECTED(offset == NULL || Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { zend_std_write_dimension(object, offset, inf); return; @@ -506,6 +558,10 @@ static void spl_multiple_iterator_write_dimension(zend_object *object, zval *off static void spl_object_storage_unset_dimension(zend_object *object, zval *offset) { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + if (UNEXPECTED(Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_UNSET_DIMENSION))) { zend_std_unset_dimension(object, offset); return; @@ -523,6 +579,9 @@ PHP_METHOD(SplObjectStorage, detach) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); spl_object_storage_detach(intern, obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; @@ -554,6 +613,7 @@ PHP_METHOD(SplObjectStorage, offsetGet) ZEND_PARSE_PARAMETERS_END(); if (spl_object_storage_get_hash(&key, intern, obj) == FAILURE) { + /* This may be the old NULL fallback, or an exception thrown by getHash(). */ RETURN_NULL(); } @@ -580,7 +640,9 @@ PHP_METHOD(SplObjectStorage, addAll) other = Z_SPLOBJSTORAGE_P(obj); - spl_object_storage_addall(intern, other); + if (UNEXPECTED(spl_object_storage_addall(intern, other) == FAILURE)) { + RETURN_THROWS(); + } RETURN_LONG(zend_hash_num_elements(&intern->storage)); } /* }}} */ @@ -602,6 +664,9 @@ PHP_METHOD(SplObjectStorage, removeAll) zend_hash_internal_pointer_reset(&other->storage); while ((element = zend_hash_get_current_data_ptr(&other->storage)) != NULL) { if (spl_object_storage_detach(intern, element->obj) == FAILURE) { + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_move_forward(&other->storage); } } @@ -626,10 +691,24 @@ PHP_METHOD(SplObjectStorage, removeAllExcept) other = Z_SPLOBJSTORAGE_P(obj); - ZEND_HASH_FOREACH_PTR(&intern->storage, element) { - if (!spl_object_storage_contains(other, element->obj)) { - spl_object_storage_detach(intern, element->obj); + SPL_SAFE_HASH_FOREACH_PTR(&intern->storage, element) { + zend_object *elem_obj = element->obj; + GC_ADDREF(elem_obj); + bool contains = spl_object_storage_contains(other, elem_obj); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(elem_obj); + RETURN_THROWS(); + } + if (!contains) { + if (spl_object_storage_detach(intern, elem_obj) == FAILURE) { + OBJ_RELEASE(elem_obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + continue; + } } + OBJ_RELEASE(elem_obj); } ZEND_HASH_FOREACH_END(); zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); @@ -648,7 +727,13 @@ PHP_METHOD(SplObjectStorage, contains) ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); - RETURN_BOOL(spl_object_storage_contains(intern, obj)); + + bool contains = spl_object_storage_contains(intern, obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + + RETURN_BOOL(contains); } /* }}} */ /* {{{ Determine number of objects in storage */ @@ -738,6 +823,9 @@ PHP_METHOD(SplObjectStorage, setInfo) if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &inf) == FAILURE) { RETURN_THROWS(); } + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + RETURN_THROWS(); + } if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) { RETURN_NULL(); @@ -932,6 +1020,10 @@ PHP_METHOD(SplObjectStorage, unserialize) if (spl_object_storage_get_hash(&key, intern, Z_OBJ_P(entry)) == FAILURE) { zval_ptr_dtor(&inf); + if (EG(exception)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + RETURN_THROWS(); + } goto outexcept; } pelement = spl_object_storage_get(intern, &key); @@ -945,6 +1037,14 @@ PHP_METHOD(SplObjectStorage, unserialize) var_push_dtor(&var_hash, &obj); } element = spl_object_storage_attach(intern, Z_OBJ_P(entry), Z_ISUNDEF(inf)?NULL:&inf); + if (UNEXPECTED(!element)) { + zval_ptr_dtor(&inf); + if (EG(exception)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + RETURN_THROWS(); + } + goto outexcept; + } var_replace(&var_hash, &inf, &element->inf); zval_ptr_dtor(&inf); } @@ -1040,7 +1140,9 @@ PHP_METHOD(SplObjectStorage, __unserialize) } ZVAL_DEREF(val); - spl_object_storage_attach(intern, Z_OBJ_P(key), val); + if (UNEXPECTED(!spl_object_storage_attach(intern, Z_OBJ_P(key), val))) { + RETURN_THROWS(); + } key = NULL; } else { key = val; @@ -1136,8 +1238,14 @@ PHP_METHOD(MultipleIterator, attachIterator) } spl_object_storage_attach(intern, iterator, &zinfo); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } else { spl_object_storage_attach(intern, iterator, NULL); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } } /* }}} */ @@ -1152,6 +1260,9 @@ PHP_METHOD(MultipleIterator, detachIterator) RETURN_THROWS(); } spl_object_storage_detach(intern, Z_OBJ_P(iterator)); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; @@ -1191,7 +1302,9 @@ PHP_METHOD(MultipleIterator, rewind) zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_rewind, it, NULL); + OBJ_RELEASE(it); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1210,7 +1323,9 @@ PHP_METHOD(MultipleIterator, next) zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_next, it, NULL); + OBJ_RELEASE(it); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1237,7 +1352,9 @@ PHP_METHOD(MultipleIterator, valid) zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval); + OBJ_RELEASE(it); if (!Z_ISUNDEF(retval)) { valid = (Z_TYPE(retval) == IS_TRUE); @@ -1275,6 +1392,9 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + zval inf; + GC_ADDREF(it); + ZVAL_COPY(&inf, &element->inf); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval); if (!Z_ISUNDEF(retval)) { @@ -1291,10 +1411,14 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_key, it, &retval); } if (Z_ISUNDEF(retval)) { + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0); return; } } else if (intern->flags & MIT_NEED_ALL) { + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) { zend_throw_exception(spl_ce_RuntimeException, "Called current() with non valid sub iterator", 0); } else { @@ -1306,15 +1430,17 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ } if (intern->flags & MIT_KEYS_ASSOC) { - switch (Z_TYPE(element->inf)) { + switch (Z_TYPE(inf)) { case IS_LONG: - add_index_zval(return_value, Z_LVAL(element->inf), &retval); + add_index_zval(return_value, Z_LVAL(inf), &retval); break; case IS_STRING: - zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR(element->inf), &retval); + zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR(inf), &retval); break; default: zval_ptr_dtor(&retval); + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_throw_exception(spl_ce_InvalidArgumentException, "Sub-Iterator is associated with NULL", 0); return; } @@ -1322,6 +1448,8 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ add_next_index_zval(return_value, &retval); } + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1363,7 +1491,7 @@ PHP_MINIT_FUNCTION(spl_observer) memcpy(&spl_handler_SplObjectStorage, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplObjectStorage.offset = XtOffsetOf(spl_SplObjectStorage, std); + spl_handler_SplObjectStorage.offset = offsetof(spl_SplObjectStorage, std); spl_handler_SplObjectStorage.compare = spl_object_storage_compare_objects; spl_handler_SplObjectStorage.clone_obj = spl_object_storage_clone; spl_handler_SplObjectStorage.get_gc = spl_object_storage_get_gc; diff --git a/ext/spl/spl_observer.h b/ext/spl/spl_observer.h index b7c22b2dfca0..bbb3ed656ccb 100644 --- a/ext/spl/spl_observer.h +++ b/ext/spl/spl_observer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -33,4 +31,6 @@ extern PHPAPI zend_class_entry *spl_ce_MultipleIterator; PHP_MINIT_FUNCTION(spl_observer); +void spl_object_storage_reset_get_hash_depth(void); + #endif /* SPL_OBSERVER_H */ diff --git a/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt index d4c853245127..32defd35e6fc 100644 --- a/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt @@ -1,26 +1,16 @@ --TEST-- -Test ArrayObject::uasort() function : wrong arg count +ArrayObject::uasort() function: non callable error --FILE-- uasort(); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; + $ao->uasort('not_a_valid_function'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } -try { - $ao->uasort(1,2); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; -} ?> --EXPECT-- -ArrayObject::uasort() expects exactly 1 argument, 0 given -ArrayObject::uasort() expects exactly 1 argument, 2 given +TypeError: uasort(): Argument #2 ($callback) must be a valid callback, function "not_a_valid_function" not found or invalid function name diff --git a/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt index 71164383e41b..11b40aae8c8f 100644 --- a/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt @@ -1,26 +1,16 @@ --TEST-- -Test ArrayObject::uksort() function : wrong arg count +ArrayObject::uksort() function: non callable error --FILE-- uksort(); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; + $ao->uksort('not_a_valid_function'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } -try { - $ao->uksort(1,2); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; -} ?> --EXPECT-- -ArrayObject::uksort() expects exactly 1 argument, 0 given -ArrayObject::uksort() expects exactly 1 argument, 2 given +TypeError: uksort(): Argument #2 ($callback) must be a valid callback, function "not_a_valid_function" not found or invalid function name diff --git a/ext/spl/tests/ArrayObject/gh10519.phpt b/ext/spl/tests/ArrayObject/gh10519.phpt index 5ef7fb3144f9..fbb66c166802 100644 --- a/ext/spl/tests/ArrayObject/gh10519.phpt +++ b/ext/spl/tests/ArrayObject/gh10519.phpt @@ -1,5 +1,7 @@ --TEST-- Bug GH-10519 (Array Data Address Reference Issue) +--XFAIL-- +The fix for this was bad --FILE-- uasort(function($a, $b) use ($ao, $other, &$i) { + if ($i++ == 0) { + try { + $ao->__construct($other); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + } + return $a <=> $b; +}); +var_dump($ao); + +?> +--EXPECT-- +Modification of ArrayObject during sorting is prohibited +object(ArrayObject)#1 (1) { + ["storage":"ArrayObject":private]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/ext/spl/tests/GH-22047.phpt b/ext/spl/tests/GH-22047.phpt new file mode 100644 index 000000000000..b01fbfd633c0 --- /dev/null +++ b/ext/spl/tests/GH-22047.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-22047: ArrayObject invalid iterator class in serialized payload +--CREDITS-- +Igor Sak-Sakovskiy (Positive Technologies) +--FILE-- + $v) { + echo "should not reach here\n"; + } +} catch (UnexpectedValueException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +Cannot deserialize ArrayObject with iterator class 'GlobIterator'; this class is not derived from ArrayIterator diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt index 0c21d0b905e9..7d0e3ae8d969 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(14) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt index 8fc9b7fef0a5..0834dbc0524f 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(13) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/bug81477.phpt b/ext/spl/tests/SplFileObject/bug81477.phpt index f7730a791aa0..421c74dc4d68 100644 --- a/ext/spl/tests/SplFileObject/bug81477.phpt +++ b/ext/spl/tests/SplFileObject/bug81477.phpt @@ -21,7 +21,6 @@ string(8) "baz,bat " string(10) "more,data " -string(0) "" --CLEAN-- rewind(); var_dump($file->fgetcsv()); ?> --EXPECT-- -array(1) { - [0]=> - NULL -} +bool(false) bool(false) diff --git a/ext/spl/tests/SplFileObject/gh21742.phpt b/ext/spl/tests/SplFileObject/gh21742.phpt new file mode 100644 index 000000000000..7ea60b53915a --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh21742.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-21742 (SplFileObject::fgets() throws at EOF in while (!$spl->eof()) loop) +--FILE-- +eof()) { + echo $spl->fgets(); +} +echo "clean exit\n"; + +$empty = tempnam(sys_get_temp_dir(), 'spl'); +file_put_contents($empty, ''); +$spl2 = new SplFileObject($empty, 'r'); +$iter = 0; +while (!$spl2->eof()) { + $iter++; + $spl2->fgets(); + if ($iter > 3) break; +} +echo "empty-file iters=$iter\n"; + +unlink($file); +unlink($empty); +?> +--EXPECT-- +Line 0 +Line 1 +Line 2 +Line 3 +Line 4 +clean exit +empty-file iters=1 diff --git a/ext/spl/tests/SplFileObject/gh8561.phpt b/ext/spl/tests/SplFileObject/gh8561.phpt new file mode 100644 index 000000000000..adf36afb8b29 --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8561.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-8561 (SplFileObject: key() and current() unsynchronized after fgets()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +// Case 1: rewind + fgets, then key/current +$file->rewind(); +$file->fgets(); +echo "After rewind+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 2: multiple fgets +$file->rewind(); +$file->fgets(); +$file->fgets(); +echo "After rewind+fgets+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 3: current then fgets +$file->rewind(); +$file->current(); +$file->fgets(); +echo "After current+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+fgets: key=1 current=line 1 +After rewind+fgets+fgets: key=2 current=line 2 +After current+fgets: key=1 current=line 1 diff --git a/ext/spl/tests/SplFileObject/gh8563.phpt b/ext/spl/tests/SplFileObject/gh8563.phpt new file mode 100644 index 000000000000..03891750f8bf --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8563.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-8563 (Different results for seek() on SplFileObject and SplTempFileObject) +--FILE-- +fwrite("line {$i}" . PHP_EOL); + $file_02->fwrite("line {$i}" . PHP_EOL); +} + +$file_01->rewind(); +$file_02->rewind(); + +$file_01->seek(10); +$file_02->seek(10); + +echo 'SplFileObject: ' . $file_01->key() . "\n"; +echo 'SplTempFileObject: ' . $file_02->key() . "\n"; +?> +--CLEAN-- + +--EXPECT-- +SplFileObject: 5 +SplTempFileObject: 5 diff --git a/ext/spl/tests/SplFileObject/gh8564.phpt b/ext/spl/tests/SplFileObject/gh8564.phpt new file mode 100644 index 000000000000..ff16893c4c6b --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8564.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-8564 (SplFileObject: next() moves to nonexistent indexes) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +for ($i = 0; $i < 10; $file->next(), $i++); +echo "next() 10x: key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; + +$file->rewind(); +$file->seek(10); +echo "seek(10): key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; +?> +--EXPECT-- +next() 10x: key=5 valid=false +seek(10): key=5 valid=false diff --git a/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt b/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt new file mode 100644 index 000000000000..f0982364afa8 --- /dev/null +++ b/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt @@ -0,0 +1,28 @@ +--TEST-- +SplFixedArray::setSize: grow re-entrantly during clear (setSize(0)) +--FILE-- +arr !== null) { + $this->arr->setSize(5); + } + } +} + +$arr = new SplFixedArray(2); +$r = new Reentrant(); +$r->arr = $arr; +$arr[0] = $r; +unset($r); +$arr[1] = "tail"; + +$arr->setSize(0); +echo "size: ", $arr->getSize(), "\n"; +$arr[0] = "ok"; +var_dump($arr[0]); +?> +--EXPECT-- +size: 5 +string(2) "ok" diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt new file mode 100644 index 000000000000..9da6270b6d7d --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt @@ -0,0 +1,62 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited +--CREDITS-- +cnitlrt +--FILE-- +mutate) { + $victim[new stdClass()] = null; + } + return spl_object_hash($obj); + } +} + +function populate(SplObjectStorage $victim, SplObjectStorage $other): void { + for ($i = 0; $i < 1024; $i++) { + $o = new stdClass(); + $victim[$o] = null; + $other[$o] = null; + } +} + +$victim = new SplObjectStorage(); +$other = new EvilStorage(); + +populate($victim, $other); +$other->mutate = true; + +try { + $victim->removeAllExcept($other); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($victim), count($other)); + +unset($victim, $other); +$victim = new SplObjectStorage(); +$other = new EvilStorage(); + +populate($victim, $other); +$other->mutate = true; + +try { + $other->addAll($victim); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($victim), count($other)); +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(1024) +int(1024) +Modification of SplObjectStorage during getHash() is prohibited +int(1024) +int(1024) diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt new file mode 100644 index 000000000000..aadbe2acba27 --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt @@ -0,0 +1,32 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited during addAll +--CREDITS-- +cnitlrt +--FILE-- +addAll($storage); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($evil), count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(0) +int(1) diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt new file mode 100644 index 000000000000..2602bc9e1f03 --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt @@ -0,0 +1,32 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited during removeAllExcept +--CREDITS-- +cnitlrt +--FILE-- +removeAllExcept($evil); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($evil), count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(0) +int(1) diff --git a/ext/spl/tests/SplObjectStorage/gh21831.phpt b/ext/spl/tests/SplObjectStorage/gh21831.phpt new file mode 100644 index 000000000000..581012d86a4f --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/gh21831.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21831: SplObjectStorage::getHash() cannot mutate storage during removeAllExcept() +--FILE-- +other) { + $this->other->offsetUnset($obj); + $this->other = null; + } + + return 'x'; + } +} + +$storage = new SplObjectStorage(); +$storage[new stdClass()] = null; + +$filter = new FilterStorage(); +$filter->other = $storage; + +try { + $storage->removeAllExcept($filter); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(1) diff --git a/ext/spl/tests/autoloading/gh22118.phpt b/ext/spl/tests/autoloading/gh22118.phpt new file mode 100644 index 000000000000..635d876c2740 --- /dev/null +++ b/ext/spl/tests/autoloading/gh22118.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-22118: spl_autoload_unregister() unregisters equivalent first-class method callables +--FILE-- +load(...)); + var_dump(spl_autoload_unregister($this->load(...))); + spl_autoload_call('MissingDirect'); + + spl_autoload_register($this->missing(...)); + var_dump(spl_autoload_unregister($this->missing(...))); + spl_autoload_call('MissingTrampoline'); + + spl_autoload_register($this->load(...)); + var_dump(spl_autoload_unregister([$this, 'load'])); + spl_autoload_call('MissingArray'); + + spl_autoload_register($this(...)); + var_dump(spl_autoload_unregister($this)); + spl_autoload_call('MissingInvokable'); + } +} + +spl_autoload_register(autoload_string(...)); +var_dump(spl_autoload_unregister('autoload_string')); +spl_autoload_call('MissingString'); + +(new AutoloadTest())->run(); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/spl/tests/bug42654.phpt b/ext/spl/tests/bug42654.phpt index eb72863e0875..20aad74b7342 100644 --- a/ext/spl/tests/bug42654.phpt +++ b/ext/spl/tests/bug42654.phpt @@ -110,11 +110,11 @@ object(RecursiveArrayIterator)#%d (1) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> @@ -129,11 +129,11 @@ object(RecursiveArrayIterator)#%d (1) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> @@ -146,11 +146,11 @@ array(3) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> diff --git a/ext/spl/tests/bug42654_2.phpt b/ext/spl/tests/bug42654_2.phpt deleted file mode 100644 index bd290247dbdc..000000000000 --- a/ext/spl/tests/bug42654_2.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Bug #42654 (RecursiveIteratorIterator modifies only part of leaves) ---FILE-- - 'val1', array('key2' => 'val2'), 'key3' => 'val3'); - -$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data)); -foreach($iterator as $foo) { - $key = $iterator->key(); - switch($key) { - case 'key1': // first level - case 'key2': // recursive level - echo "update $key".PHP_EOL; - $iterator->offsetSet($key, 'alter'); - } -} -$copy = $iterator->getArrayCopy(); -var_dump($copy); -?> ---EXPECT-- -update key1 -update key2 -array(3) { - ["key1"]=> - string(5) "alter" - [0]=> - array(1) { - ["key2"]=> - string(5) "alter" - } - ["key3"]=> - string(4) "val3" -} diff --git a/ext/spl/tests/class_parents_leading_backslash.phpt b/ext/spl/tests/class_parents_leading_backslash.phpt new file mode 100644 index 000000000000..be538b79db9d --- /dev/null +++ b/ext/spl/tests/class_parents_leading_backslash.phpt @@ -0,0 +1,72 @@ +--TEST-- +class_parents()/class_implements()/class_uses() accept a leading backslash regardless of $autoload +--FILE-- + +--EXPECT-- +array(1) { + ["ParentC"]=> + string(7) "ParentC" +} +array(1) { + ["ParentC"]=> + string(7) "ParentC" +} +array(1) { + ["Iface"]=> + string(5) "Iface" +} +array(1) { + ["Tr"]=> + string(2) "Tr" +} +array(1) { + ["MyNS\NSParentC"]=> + string(14) "MyNS\NSParentC" +} +array(1) { + ["MyNS\NSParentC"]=> + string(14) "MyNS\NSParentC" +} +array(1) { + ["MyNS\NSIface"]=> + string(12) "MyNS\NSIface" +} +array(1) { + ["MyNS\NSTr"]=> + string(9) "MyNS\NSTr" +} diff --git a/ext/spl/tests/gh13685.phpt b/ext/spl/tests/gh13685.phpt index 0f679d0e93fc..2bdddec4584e 100644 --- a/ext/spl/tests/gh13685.phpt +++ b/ext/spl/tests/gh13685.phpt @@ -44,9 +44,9 @@ try { string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" --- Use csv control --- string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" diff --git a/ext/spl/tests/gh15672.phpt b/ext/spl/tests/gh15672.phpt new file mode 100644 index 000000000000..ff3feda46f7e --- /dev/null +++ b/ext/spl/tests/gh15672.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-15672 (MultipleIterator attached to itself overflows the C stack) +--SKIPIF-- + +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=2G +zend.max_allowed_stack_size=512K +--FILE-- +attachIterator(new ArrayIterator([1, 2, 3]), "1"); +$m->attachIterator($m, 3); +foreach ($m as $key => $value) { +} +?> +--EXPECTREGEX-- +.*Maximum call stack size of \d+ bytes.*Infinite recursion\?.*thrown in .* on line \d+ diff --git a/ext/spl/tests/gh15911.phpt b/ext/spl/tests/gh15911.phpt new file mode 100644 index 000000000000..502b2baf616b --- /dev/null +++ b/ext/spl/tests/gh15911.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-15911 (AppendIterator appended to itself overflows the C stack) +--SKIPIF-- + +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=2G +zend.max_allowed_stack_size=512K +--FILE-- +append($it); +foreach ($it as $v) { +} +?> +--EXPECTREGEX-- +.*Maximum call stack size of \d+ bytes.*Infinite recursion\?.*thrown in .* on line \d+ diff --git a/ext/spl/tests/gh16217.phpt b/ext/spl/tests/gh16217.phpt new file mode 100644 index 000000000000..71760389c8e4 --- /dev/null +++ b/ext/spl/tests/gh16217.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-16217 (SplFileObject methods on an uninitialized object segfault) +--FILE-- +newInstanceWithoutConstructor(); +} + +try { + (new ReflectionMethod(SplFileObject::class, "fputcsv"))->invoke(uninitialized(), []); +} catch (Error $e) { + echo "fputcsv: ", $e->getMessage(), "\n"; +} + +try { + (new ReflectionMethod(SplFileObject::class, "next"))->invoke(uninitialized()); +} catch (Error $e) { + echo "next: ", $e->getMessage(), "\n"; +} + +$obj = uninitialized(); +(new ReflectionMethod(SplFileObject::class, "setFlags"))->invoke($obj, SplFileObject::READ_AHEAD); +try { + (new ReflectionMethod(SplFileObject::class, "next"))->invoke($obj); +} catch (Error $e) { + echo "next (READ_AHEAD): ", $e->getMessage(), "\n"; +} + +echo "Done\n"; +?> +--EXPECT-- +fputcsv: Object not initialized +next: Object not initialized +next (READ_AHEAD): Object not initialized +Done diff --git a/ext/spl/tests/gh21499.phpt b/ext/spl/tests/gh21499.phpt new file mode 100644 index 000000000000..719da0094a6d --- /dev/null +++ b/ext/spl/tests/gh21499.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-21499 (RecursiveArrayIterator getChildren UAF after parent free) +--FILE-- +getChildren(); +unset($it); +$child->__construct([2, 3]); +var_dump($child->getArrayCopy()); +?> +--EXPECT-- +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} diff --git a/ext/spl/tests/gh21927.phpt b/ext/spl/tests/gh21927.phpt new file mode 100644 index 000000000000..a60ea5ca1025 --- /dev/null +++ b/ext/spl/tests/gh21927.phpt @@ -0,0 +1,151 @@ +--TEST-- +GH-21927: Use-after-free of self-freeing MultipleIterator children +--FILE-- +parent->detachIterator($this); + echo "rewind: still alive\n"; + } + public function next(): void {} + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { return false; } +} + +class DetachOnNext implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void { + $this->parent->detachIterator($this); + echo "next: still alive\n"; + } + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { return true; } +} + +class DetachOnValid implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { + $this->parent->detachIterator($this); + echo "valid: still alive\n"; + return true; + } +} + +class DetachOnCurrent implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { + $this->parent->detachIterator($this); + echo "current: still alive\n"; + return 'C'; + } + public function key(): mixed { return 'k'; } + public function valid(): bool { return true; } +} + +class DetachOnKey implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { return 'C'; } + public function key(): mixed { + $this->parent->detachIterator($this); + echo "key: still alive\n"; + return 'K'; + } + public function valid(): bool { return true; } +} + +echo "-- detach inside rewind --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnRewind($mi)); +$mi->rewind(); +var_dump($mi->countIterators()); + +echo "-- detach inside next --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnNext($mi)); +$mi->rewind(); +$mi->next(); +var_dump($mi->countIterators()); + +echo "-- detach inside valid --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnValid($mi)); +var_dump($mi->valid()); +var_dump($mi->countIterators()); + +echo "-- detach inside current (numeric keys) --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnCurrent($mi)); +var_dump($mi->current()); +var_dump($mi->countIterators()); + +echo "-- detach inside key (numeric keys) --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnKey($mi)); +var_dump($mi->key()); +var_dump($mi->countIterators()); + +echo "-- detach inside current (assoc keys, refcounted inf) --\n"; +$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC); +$mi->attachIterator(new DetachOnCurrent($mi), 'cur_info_string'); +var_dump($mi->current()); +var_dump($mi->countIterators()); + +echo "-- detach inside key (assoc keys, refcounted inf) --\n"; +$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC); +$mi->attachIterator(new DetachOnKey($mi), 'key_info_string'); +var_dump($mi->key()); +var_dump($mi->countIterators()); + +?> +--EXPECT-- +-- detach inside rewind -- +rewind: still alive +int(0) +-- detach inside next -- +next: still alive +int(0) +-- detach inside valid -- +valid: still alive +bool(true) +int(0) +-- detach inside current (numeric keys) -- +current: still alive +array(1) { + [0]=> + string(1) "C" +} +int(0) +-- detach inside key (numeric keys) -- +key: still alive +array(1) { + [0]=> + string(1) "K" +} +int(0) +-- detach inside current (assoc keys, refcounted inf) -- +current: still alive +array(1) { + ["cur_info_string"]=> + string(1) "C" +} +int(0) +-- detach inside key (assoc keys, refcounted inf) -- +key: still alive +array(1) { + ["key_info_string"]=> + string(1) "K" +} +int(0) diff --git a/ext/spl/tests/gh22062.phpt b/ext/spl/tests/gh22062.phpt new file mode 100644 index 000000000000..ea67a9983a3d --- /dev/null +++ b/ext/spl/tests/gh22062.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-22062 (SplDoublyLinkedList iterator UAF via destructor releasing next node) +--FILE-- +setIteratorMode( + SplDoublyLinkedList::IT_MODE_FIFO | + SplDoublyLinkedList::IT_MODE_DELETE +); + +$list->push(new class($list) { + public function __construct(private SplDoublyLinkedList $list) {} + public function __destruct() { + if ($this->list->count() > 0) { + $this->list->offsetUnset(0); + } + } +}); + +$list->push(new stdClass()); + +foreach ($list as $item) { + unset($item); +} + +var_dump($list->count()); +?> +--EXPECT-- +int(0) diff --git a/ext/spl/tests/gh8562.phpt b/ext/spl/tests/gh8562.phpt new file mode 100644 index 000000000000..40b2554f5794 --- /dev/null +++ b/ext/spl/tests/gh8562.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-8562 (SplFileObject::current() returns wrong result after call to next()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +$file->next(); +echo "After rewind+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->next(); +$file->next(); +echo "After rewind+next+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->current(); +$file->next(); +echo "After current+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+next: key=1 current=line 1 +After rewind+next+next: key=2 current=line 2 +After current+next: key=1 current=line 1 diff --git a/ext/spl/tests/heap_next_write_lock.phpt b/ext/spl/tests/heap_next_write_lock.phpt new file mode 100644 index 000000000000..fcad94f3ccd3 --- /dev/null +++ b/ext/spl/tests/heap_next_write_lock.phpt @@ -0,0 +1,34 @@ +--TEST-- +SplHeap::next() write lock +--CREDITS-- +cnitlrt +--FILE-- +did) { + $this->did = true; + // Re-entrant write during internal heap insertion comparison. + if (!$this->isEmpty()) { + $this->next(); // no write-lock validation + } + } + return parent::compare($p1, $p2); + } +} + +$q = new EvilPQ(); +try { + for ($i = 0; $i < 200; $i++) { + $q->insert("d$i", 100 - $i); + } +} catch (RuntimeException $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +RuntimeException: Heap cannot be changed when it is already being modified. diff --git a/ext/spl/tests/iterator_031.phpt b/ext/spl/tests/iterator_031.phpt index 610e056f5380..c2b5885dd23e 100644 --- a/ext/spl/tests/iterator_031.phpt +++ b/ext/spl/tests/iterator_031.phpt @@ -3,6 +3,13 @@ SPL: AppendIterator::append() rewinds when necessary --FILE-- __construct(); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + class MyArrayIterator extends ArrayIterator { function rewind(): void @@ -14,8 +21,7 @@ class MyArrayIterator extends ArrayIterator $it = new MyArrayIterator(array(1,2)); -foreach($it as $k=>$v) -{ +foreach($it as $k=>$v) { echo "$k=>$v\n"; } @@ -44,31 +50,24 @@ class MyAppendIterator extends AppendIterator parent::append($what); } - function parent__construct() - { + function parent__construct() { parent::__construct(); } } $ap = new MyAppendIterator; -try -{ +try { $ap->append($it); -} -catch(\Error $e) -{ +} catch(\Error $e) { echo $e->getMessage() . "\n"; } $ap->parent__construct(); -try -{ +try { $ap->parent__construct($it); -} -catch(BadMethodCallException $e) -{ +} catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } @@ -76,13 +75,13 @@ $ap->append($it); $ap->append($it); $ap->append($it); -foreach($ap as $k=>$v) -{ +foreach($ap as $k=>$v) { echo "$k=>$v\n"; } ?> --EXPECT-- +BadMethodCallException: AppendIterator::getIterator() must be called exactly once per instance MyArrayIterator::rewind 0=>1 1=>2 diff --git a/ext/spl/tests/phpinfo_out.phpt b/ext/spl/tests/phpinfo_out.phpt new file mode 100644 index 000000000000..8be1a2dead41 --- /dev/null +++ b/ext/spl/tests/phpinfo_out.phpt @@ -0,0 +1,16 @@ +--TEST-- +phpinfo() SPL extension information +--FILE-- + +--EXPECT-- +SPL + +SPL support => enabled +Interfaces => OuterIterator, RecursiveIterator, SeekableIterator, SplObserver, SplSubject +Classes => AppendIterator, ArrayIterator, ArrayObject, BadFunctionCallException, BadMethodCallException, CachingIterator, CallbackFilterIterator, DirectoryIterator, DomainException, EmptyIterator, FilesystemIterator, FilterIterator, GlobIterator, InfiniteIterator, InvalidArgumentException, IteratorIterator, LengthException, LimitIterator, LogicException, MultipleIterator, NoRewindIterator, OutOfBoundsException, OutOfRangeException, OverflowException, ParentIterator, RangeException, RecursiveArrayIterator, RecursiveCachingIterator, RecursiveCallbackFilterIterator, RecursiveDirectoryIterator, RecursiveFilterIterator, RecursiveIteratorIterator, RecursiveRegexIterator, RecursiveTreeIterator, RegexIterator, RuntimeException, SplDoublyLinkedList, SplFileInfo, SplFileObject, SplFixedArray, SplHeap, SplMinHeap, SplMaxHeap, SplObjectStorage, SplPriorityQueue, SplQueue, SplStack, SplTempFileObject, UnderflowException, UnexpectedValueException diff --git a/ext/spl/tests/recursiveiteratoriterator_next_during_endchildren.phpt b/ext/spl/tests/recursiveiteratoriterator_next_during_endchildren.phpt new file mode 100644 index 000000000000..b3c80b2232a8 --- /dev/null +++ b/ext/spl/tests/recursiveiteratoriterator_next_during_endchildren.phpt @@ -0,0 +1,42 @@ +--TEST-- +RecursiveIteratorIterator: next() re-entered from endChildren() must not use-after-free +--FILE-- +data = $d; } + function current(): mixed { return $this->data[$this->pos] ?? null; } + function key(): mixed { return $this->pos; } + function next(): void { $this->pos++; } + function rewind(): void { $this->pos = 0; } + function valid(): bool { return $this->pos < count($this->data); } + function hasChildren(): bool { return is_array($this->current()); } + function getChildren(): RecursiveIterator { return new RIt($this->current()); } +} + +class ReenterRII extends RecursiveIteratorIterator { + public static int $fired = 0; + function endChildren(): void { + if (self::$fired++ === 0) { + $this->next(); + } + } +} + +$tree = [[[1, 2], 3], 4]; +$it = new ReenterRII(new RIt($tree), RecursiveIteratorIterator::SELF_FIRST); +$seen = []; +foreach ($it as $v) { + $seen[] = is_array($v) ? 'array' : $v; + if (count($seen) > 20) { + $seen[] = '...'; + break; + } +} +echo implode(' ', $seen), "\n"; +echo "done\n"; +?> +--EXPECT-- +array array 1 2 4 +done diff --git a/ext/spl/tests/recursiveiteratoriterator_next_during_valid.phpt b/ext/spl/tests/recursiveiteratoriterator_next_during_valid.phpt new file mode 100644 index 000000000000..a2dcf4695e36 --- /dev/null +++ b/ext/spl/tests/recursiveiteratoriterator_next_during_valid.phpt @@ -0,0 +1,47 @@ +--TEST-- +RecursiveIteratorIterator: next() re-entered from a sub-iterator valid() must not use-after-free +--FILE-- +data = $d; $this->depth = $depth; } + function current(): mixed { return $this->data[$this->pos] ?? null; } + function key(): mixed { return $this->pos; } + function next(): void { $this->pos++; } + function rewind(): void { $this->pos = 0; } + function valid(): bool { + if ($this->rii && $this->depth === 2 && $this->pos === count($this->data) && !self::$fired) { + self::$fired = true; + $this->rii->next(); + } + return $this->pos < count($this->data); + } + function hasChildren(): bool { return is_array($this->current()); } + function getChildren(): RecursiveIterator { + $c = new RIt($this->current(), $this->depth + 1); + $c->rii = $this->rii; + return $c; + } +} + +$root = new RIt([[[1, 2], 3], 4]); +$rii = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::SELF_FIRST); +$root->rii = $rii; +$seen = []; +foreach ($rii as $v) { + $seen[] = is_array($v) ? 'array' : $v; + if (count($seen) > 20) { + $seen[] = '...'; + break; + } +} +echo implode(' ', $seen), "\n"; +echo "done\n"; +?> +--EXPECT-- +array array 1 2 3 4 +done diff --git a/ext/spl/tests/recursiveiteratoriterator_rewind_during_next.phpt b/ext/spl/tests/recursiveiteratoriterator_rewind_during_next.phpt new file mode 100644 index 000000000000..3c9863e81a30 --- /dev/null +++ b/ext/spl/tests/recursiveiteratoriterator_rewind_during_next.phpt @@ -0,0 +1,41 @@ +--TEST-- +RecursiveIteratorIterator: rewind() re-entered from an inner next() must not use-after-free +--FILE-- +data = $d; $this->depth = $depth; } + function current(): mixed { return $this->data[$this->pos] ?? null; } + function key(): mixed { return $this->pos; } + function next(): void { + $this->pos++; + if ($this->rii && $this->depth === 1 && $this->pos === 1 && !self::$fired) { + self::$fired = true; + $this->rii->rewind(); + } + } + function rewind(): void { $this->pos = 0; } + function valid(): bool { return $this->pos < count($this->data); } + function hasChildren(): bool { return is_array($this->current()); } + function getChildren(): RecursiveIterator { + $c = new Reenter($this->current(), $this->depth + 1); + $c->rii = $this->rii; + return $c; + } +} +$root = new Reenter([[10, 11], [20, 21]]); +$rii = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::SELF_FIRST); +$root->rii = $rii; +$seen = []; +foreach ($rii as $v) { + if (is_array($v)) { $v = '[' . implode(',', $v) . ']'; } + $seen[] = $v; + if (count($seen) > 20) { $seen[] = '...'; break; } +} +echo implode(' ', $seen), "\n"; +echo "done\n"; +?> +--EXPECT-- +[10,11] 10 [10,11] 10 11 [20,21] 20 21 +done diff --git a/ext/spl/tests/spl_autoload_leading_backslash.phpt b/ext/spl/tests/spl_autoload_leading_backslash.phpt new file mode 100644 index 000000000000..ff8ae3234eee --- /dev/null +++ b/ext/spl/tests/spl_autoload_leading_backslash.phpt @@ -0,0 +1,18 @@ +--TEST-- +spl_autoload(): a leading "\" in the class name is ignored +--FILE-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/spl/tests/spl_object_storage_gethash_bailout.phpt b/ext/spl/tests/spl_object_storage_gethash_bailout.phpt new file mode 100644 index 000000000000..a6327bd62095 --- /dev/null +++ b/ext/spl/tests/spl_object_storage_gethash_bailout.phpt @@ -0,0 +1,44 @@ +--TEST-- +SplObjectStorage getHash() depth counter is reset after a bailout in a user getHash() +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- +offsetSet(new stdClass()); + echo "poison"; +} else { + $s = new SplObjectStorage(); + $s->offsetSet(new stdClass()); + echo "check-ok count=", count($s); +} +PHP; + +php_cli_server_start($code, 'router.php'); + +$base = 'http://' . PHP_CLI_SERVER_ADDRESS; +// Request 1 bails out (OOM) inside the overridden getHash() mid-offsetSet. +@file_get_contents($base . '/poison'); +// A later request on the same worker must not be poisoned by a stuck counter. +echo @file_get_contents($base . '/check'), "\n"; +echo @file_get_contents($base . '/check'), "\n"; +?> +--EXPECT-- +check-ok count=1 +check-ok count=1 diff --git a/ext/spl/tests/unserialize_errors.phpt b/ext/spl/tests/unserialize_errors.phpt index 1138b5c8cd54..64356923ae29 100644 --- a/ext/spl/tests/unserialize_errors.phpt +++ b/ext/spl/tests/unserialize_errors.phpt @@ -144,7 +144,7 @@ Incomplete or ill-typed serialization data Passed variable is not an array or object Incomplete or ill-typed serialization data Cannot deserialize ArrayObject with iterator class 'NonExistent'; no such class exists -Cannot deserialize ArrayObject with iterator class 'Existent'; this class does not implement the Iterator interface +Cannot deserialize ArrayObject with iterator class 'Existent'; this class is not derived from ArrayIterator ArrayIterator: Incomplete or ill-typed serialization data Incomplete or ill-typed serialization data diff --git a/ext/sqlite3/php_sqlite3.h b/ext/sqlite3/php_sqlite3.h index 79f8cf436030..8a9cf3af1598 100644 --- a/ext/sqlite3/php_sqlite3.h +++ b/ext/sqlite3/php_sqlite3.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ diff --git a/ext/sqlite3/php_sqlite3_structs.h b/ext/sqlite3/php_sqlite3_structs.h index 5d9f69cc5770..e8488028240e 100644 --- a/ext/sqlite3/php_sqlite3_structs.h +++ b/ext/sqlite3/php_sqlite3_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -74,9 +72,7 @@ typedef struct _php_sqlite3_db_object { zend_object zo; } php_sqlite3_db_object; -static inline php_sqlite3_db_object *php_sqlite3_db_from_obj(zend_object *obj) { - return (php_sqlite3_db_object*)((char*)(obj) - XtOffsetOf(php_sqlite3_db_object, zo)); -} +#define php_sqlite3_db_from_obj(obj) ZEND_CONTAINER_OF(obj, php_sqlite3_db_object, zo) #define Z_SQLITE3_DB_P(zv) php_sqlite3_db_from_obj(Z_OBJ_P((zv))) @@ -103,9 +99,7 @@ struct _php_sqlite3_result_object { zend_object zo; }; -static inline php_sqlite3_result *php_sqlite3_result_from_obj(zend_object *obj) { - return (php_sqlite3_result*)((char*)(obj) - XtOffsetOf(php_sqlite3_result, zo)); -} +#define php_sqlite3_result_from_obj(obj) ZEND_CONTAINER_OF(obj, php_sqlite3_result, zo) #define Z_SQLITE3_RESULT_P(zv) php_sqlite3_result_from_obj(Z_OBJ_P((zv))) @@ -121,9 +115,7 @@ struct _php_sqlite3_stmt_object { zend_object zo; }; -static inline php_sqlite3_stmt *php_sqlite3_stmt_from_obj(zend_object *obj) { - return (php_sqlite3_stmt*)((char*)(obj) - XtOffsetOf(php_sqlite3_stmt, zo)); -} +#define php_sqlite3_stmt_from_obj(obj) ZEND_CONTAINER_OF(obj, php_sqlite3_stmt, zo) #define Z_SQLITE3_STMT_P(zv) php_sqlite3_stmt_from_obj(Z_OBJ_P((zv))) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 659de2291d86..b81a0677a6c2 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -38,7 +36,7 @@ ZEND_DECLARE_MODULE_GLOBALS(sqlite3) static PHP_GINIT_FUNCTION(sqlite3); static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4); static void sqlite3_param_dtor(zval *data); -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement); +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement); static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_result *result_obj, zend_long mode, zval *result); #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \ @@ -471,7 +469,7 @@ PHP_METHOD(SQLite3, escapeString) zend_string *sql; char *ret; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) { + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "P", &sql)) { RETURN_THROWS(); } @@ -480,6 +478,9 @@ PHP_METHOD(SQLite3, escapeString) if (ret) { RETVAL_STRING(ret); sqlite3_free(ret); + } else { + zend_throw_exception_ex(php_sqlite3_exception_ce, 0, "Unable to escape string"); + RETURN_THROWS(); } } else { RETURN_EMPTY_STRING(); @@ -603,7 +604,7 @@ PHP_METHOD(SQLite3, query) } /* }}} */ -static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* {{{ */ +static void sqlite_value_to_zval(php_sqlite3_db_object *db_obj, sqlite3_stmt *stmt, int column, zval *data) /* {{{ */ { sqlite3_int64 val; @@ -612,7 +613,13 @@ static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* val = sqlite3_column_int64(stmt, column); #if LONG_MAX <= 2147483647 if (val > ZEND_LONG_MAX || val < ZEND_LONG_MIN) { - ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column)); + const char *text = (const char *) sqlite3_column_text(stmt, column); + if (UNEXPECTED(text == NULL)) { + php_sqlite3_error(db_obj, SQLITE_NOMEM, "Failed to retrieve column value due to out of memory"); + ZVAL_NULL(data); + } else { + ZVAL_STRINGL(data, text, sqlite3_column_bytes(stmt, column)); + } } else { #endif ZVAL_LONG(data, (zend_long) val); @@ -629,13 +636,33 @@ static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* ZVAL_NULL(data); break; - case SQLITE3_TEXT: - ZVAL_STRINGL(data, (const char *) sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column)); + case SQLITE3_TEXT: { + const char *text = (const char *) sqlite3_column_text(stmt, column); + if (UNEXPECTED(text == NULL)) { + php_sqlite3_error(db_obj, SQLITE_NOMEM, "Failed to retrieve column value due to out of memory"); + ZVAL_NULL(data); + } else { + ZVAL_STRINGL(data, text, sqlite3_column_bytes(stmt, column)); + } break; + } case SQLITE_BLOB: - default: - ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column)); + default: { + const char *blob = (const char *) sqlite3_column_blob(stmt, column); + if (UNEXPECTED(blob == NULL)) { + if (sqlite3_errcode(sqlite3_db_handle(stmt)) == SQLITE_NOMEM) { + php_sqlite3_error(db_obj, SQLITE_NOMEM, "Failed to retrieve column value due to out of memory"); + ZVAL_NULL(data); + } else { + /* Zero-length BLOB */ + ZVAL_EMPTY_STRING(data); + } + } else { + ZVAL_STRINGL(data, blob, sqlite3_column_bytes(stmt, column)); + } + break; + } } } /* }}} */ @@ -685,14 +712,14 @@ PHP_METHOD(SQLite3, querySingle) case SQLITE_ROW: /* Valid Row */ { if (!entire_row) { - sqlite_value_to_zval(stmt, 0, return_value); + sqlite_value_to_zval(db_obj, stmt, 0, return_value); } else { int i = 0, count = sqlite3_data_count(stmt); array_init_size(return_value, count); for (i = 0; i < count; i++) { zval data; - sqlite_value_to_zval(stmt, i, &data); + sqlite_value_to_zval(db_obj, stmt, i, &data); add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), &data); } } @@ -1131,7 +1158,7 @@ static int php_sqlite3_stream_seek(php_stream *stream, zend_off_t offset, int wh switch(whence) { case SEEK_CUR: if (offset < 0) { - if (sqlite3_stream->position < (size_t)(-offset)) { + if (sqlite3_stream->position < -(size_t)offset) { sqlite3_stream->position = 0; *newoffs = -1; return -1; @@ -1172,7 +1199,7 @@ static int php_sqlite3_stream_seek(php_stream *stream, zend_off_t offset, int wh sqlite3_stream->position = sqlite3_stream->size; *newoffs = -1; return -1; - } else if (sqlite3_stream->size < (size_t)(-offset)) { + } else if (sqlite3_stream->size < -(size_t)offset) { sqlite3_stream->position = 0; *newoffs = -1; return -1; @@ -2016,7 +2043,6 @@ PHP_METHOD(SQLite3Result, fetchArray) case SQLITE_DONE: RETURN_FALSE; - break; default: php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); @@ -2121,7 +2147,7 @@ PHP_METHOD(SQLite3Result, finalize) /* We need to finalize an internal statement */ if (!result_obj->is_prepared_statement) { - zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj, + zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } else { sqlite3_reset(result_obj->stmt_obj->stmt); @@ -2236,9 +2262,9 @@ static void php_sqlite3_free_list_dtor(void **item) } /* }}} */ -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement ) /* {{{ */ +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement ) /* {{{ */ { - return ((*stmt_obj_ptr)->initialised && statement == (*stmt_obj_ptr)->stmt); + return ((*stmt_obj_ptr)->initialised && statement == *stmt_obj_ptr); } /* }}} */ @@ -2352,7 +2378,7 @@ static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */ } if (intern->initialised) { - zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt, + zend_llist_del_element(&(intern->db_obj->free_list), intern, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } @@ -2447,7 +2473,7 @@ static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_res { for (int i = 0; i < n_cols; i ++) { zval data; - sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data); + sqlite_value_to_zval(result_obj->db_obj, result_obj->stmt_obj->stmt, i, &data); if (mode & PHP_SQLITE3_NUM) { add_index_zval(result, i, &data); @@ -2483,7 +2509,7 @@ PHP_MINIT_FUNCTION(sqlite3) memcpy(&sqlite3_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); /* Register SQLite 3 Class */ - sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo); + sqlite3_object_handlers.offset = offsetof(php_sqlite3_db_object, zo); sqlite3_object_handlers.clone_obj = NULL; sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage; sqlite3_object_handlers.get_gc = php_sqlite3_get_gc; @@ -2492,7 +2518,7 @@ PHP_MINIT_FUNCTION(sqlite3) php_sqlite3_sc_entry->default_object_handlers = &sqlite3_object_handlers; /* Register SQLite 3 Prepared Statement Class */ - sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo); + sqlite3_stmt_object_handlers.offset = offsetof(php_sqlite3_stmt, zo); sqlite3_stmt_object_handlers.clone_obj = NULL; sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage; php_sqlite3_stmt_entry = register_class_SQLite3Stmt(); @@ -2500,7 +2526,7 @@ PHP_MINIT_FUNCTION(sqlite3) php_sqlite3_stmt_entry->default_object_handlers = &sqlite3_stmt_object_handlers; /* Register SQLite 3 Result Class */ - sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo); + sqlite3_result_object_handlers.offset = offsetof(php_sqlite3_result, zo); sqlite3_result_object_handlers.clone_obj = NULL; sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage; php_sqlite3_result_entry = register_class_SQLite3Result(); diff --git a/ext/sqlite3/tests/bug72668.phpt b/ext/sqlite3/tests/bug72668.phpt index 40ede8883cc2..7f33338eb5e6 100644 --- a/ext/sqlite3/tests/bug72668.phpt +++ b/ext/sqlite3/tests/bug72668.phpt @@ -12,20 +12,20 @@ $db = new SQLite3(':memory:'); $db->createFunction('my_udf_md5', 'my_udf_md5'); try { - $result = $db->query('SELECT my_udf_md5("test")'); + $result = $db->query("SELECT my_udf_md5('test')"); var_dump($result); } catch(\Exception $e) { echo "Exception: ".$e->getMessage(); } try { - $result = $db->querySingle('SELECT my_udf_md5("test")'); + $result = $db->querySingle("SELECT my_udf_md5('test')"); var_dump($result); } catch(\Exception $e) { echo "Exception: ".$e->getMessage(); } -$statement = $db->prepare('SELECT my_udf_md5("test")'); +$statement = $db->prepare("SELECT my_udf_md5('test')"); try { $result = $statement->execute(); var_dump($result); diff --git a/ext/sqlite3/tests/gh20964.phpt b/ext/sqlite3/tests/gh20964.phpt new file mode 100644 index 000000000000..852940ba983e --- /dev/null +++ b/ext/sqlite3/tests/gh20964.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-20964 (fseek() on SQLite3 blob stream with PHP_INT_MIN causes undefined behavior) +--EXTENSIONS-- +sqlite3 +--FILE-- +exec('CREATE TABLE test (id INTEGER PRIMARY KEY, data BLOB)'); +$db->exec("INSERT INTO test (id, data) VALUES (1, 'hello')"); + +$stream = $db->openBlob('test', 'data', 1); + +var_dump(fseek($stream, PHP_INT_MIN, SEEK_END)); + +rewind($stream); +var_dump(fseek($stream, PHP_INT_MIN, SEEK_CUR)); + +fclose($stream); +$db->close(); +?> +--EXPECT-- +int(-1) +int(-1) diff --git a/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt new file mode 100644 index 000000000000..49d66a1accf5 --- /dev/null +++ b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt @@ -0,0 +1,35 @@ +--TEST-- +SQLite3::escapeString() rejects strings with embedded NUL bytes +--EXTENSIONS-- +sqlite3 +--FILE-- +getMessage(), "\n"; + } +} + +echo "ok: ", SQLite3::escapeString("ok"), "\n"; +echo "quote: ", SQLite3::escapeString("test''%"), "\n"; +echo "empty: ", var_export(SQLite3::escapeString(""), true), "\n"; +?> +--EXPECT-- +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ok: ok +quote: test''''% +empty: '' diff --git a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt index ef28b3b62def..1a511ee13996 100644 --- a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt +++ b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt @@ -9,14 +9,14 @@ require_once(__DIR__ . '/new_db.inc'); $func = 'strtoupper'; var_dump($db->createfunction($func, $func)); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); $func2 = 'strtolower'; var_dump($db->createfunction($func2, $func2)); -var_dump($db->querySingle('SELECT strtolower("TEST")')); +var_dump($db->querySingle("SELECT strtolower('TEST')")); var_dump($db->createfunction($func, $func2)); -var_dump($db->querySingle('SELECT strtoupper("tEst")')); +var_dump($db->querySingle("SELECT strtoupper('tEst')")); ?> diff --git a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt index 49f029d5854f..e07d5b73e999 100644 --- a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt +++ b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt @@ -2,13 +2,6 @@ SQLite3_stmt::readOnly check --EXTENSIONS-- sqlite3 ---SKIPIF-- - --FILE-- = 3.8.3'); ?> --FILE-- createfunction($func, $func, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); $func2 = 'strtolower'; var_dump($db->createfunction($func2, $func2, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtolower("TEST")')); +var_dump($db->querySingle("SELECT strtolower('TEST')")); var_dump($db->createfunction($func, $func2, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtoupper("tEst")')); +var_dump($db->querySingle("SELECT strtoupper('tEst')")); ?> diff --git a/ext/sqlite3/tests/sqlite3_dqs.phpt b/ext/sqlite3/tests/sqlite3_dqs.phpt new file mode 100644 index 000000000000..1efa8ad475fe --- /dev/null +++ b/ext/sqlite3/tests/sqlite3_dqs.phpt @@ -0,0 +1,28 @@ +--TEST-- +SQLite3 DQS +--EXTENSIONS-- +sqlite3 +--SKIPIF-- +enableExceptions(true); + $db->exec('SELECT "test"'); +} catch (\SQLite3Exception) { + die('skip SQLite is lacking DQS'); +} +?> +--FILE-- +exec('CREATE TABLE test (s1 VARCHAR(255), s2 VARCHAR(255))'); +$db->exec('INSERT INTO test VALUES (\'test\', "test")'); +var_dump($db->prepare('SELECT * FROM test')->execute()->fetchArray(SQLITE3_ASSOC)); +?> +--EXPECT-- +array(2) { + ["s1"]=> + string(4) "test" + ["s2"]=> + string(4) "test" +} diff --git a/ext/sqlite3/tests/sqlite3_explain.phpt b/ext/sqlite3/tests/sqlite3_explain.phpt index 40648588733c..1f9d4fc940e4 100644 --- a/ext/sqlite3/tests/sqlite3_explain.phpt +++ b/ext/sqlite3/tests/sqlite3_explain.phpt @@ -14,7 +14,7 @@ if ($version <= 3043000) die("skip for sqlite3 < 3.43.0"); require_once(__DIR__ . '/new_db.inc'); $db->exec('CREATE TABLE test_explain (a string);'); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setExplain(Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN); var_dump($stmt->explain() == Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN); $r = $stmt->execute(); @@ -28,7 +28,7 @@ $result = []; while (($arr = $r->fetchArray(SQLITE3_ASSOC)) !== false) $result[] = $arr; var_dump($result); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setExplain(Sqlite3Stmt::EXPLAIN_MODE_PREPARED); $stmt->execute(); $stmts = $db->prepare('SELECT * FROM test_explain'); @@ -81,7 +81,7 @@ array(%d) { ["opcode"]=> string(%d) "%s" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -102,7 +102,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -119,7 +119,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -140,7 +140,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -157,7 +157,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -176,7 +176,7 @@ array(%d) { ["opcode"]=> string(12) "EndCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -214,7 +214,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -235,7 +235,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(1) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -252,11 +252,11 @@ array(%d) { ["opcode"]=> string(10) "MakeRecord" ["p1"]=> - int(2) + int(%d) ["p2"]=> int(1) ["p3"]=> - int(4) + int(%d) ["p4"]=> string(1) "C" ["p5"]=> @@ -273,9 +273,9 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(4) + int(%d) ["p3"]=> - int(1) + int(%d) ["p4"]=> string(12) "test_explain" ["p5"]=> diff --git a/ext/sqlite3/tests/sqlite3_rename_column.phpt b/ext/sqlite3/tests/sqlite3_rename_column.phpt index 6b4e23bc7186..a3a4caef3ce6 100644 --- a/ext/sqlite3/tests/sqlite3_rename_column.phpt +++ b/ext/sqlite3/tests/sqlite3_rename_column.phpt @@ -14,7 +14,7 @@ if (SQLite3::version()['versionNumber'] < 3025000) { $db = new SQLite3(':memory:'); $db->exec('CREATE TABLE tbl (orig text)'); -$db->exec('insert into tbl values ("one"), ("two")'); +$db->exec("insert into tbl values ('one'), ('two')"); $res1 = $db->prepare('select * from tbl')->execute(); $res2 = $db->prepare('select * from tbl')->execute(); diff --git a/ext/sqlite3/tests/sqlite3_stmt_busy.phpt b/ext/sqlite3/tests/sqlite3_stmt_busy.phpt index 8110d374afe6..eb278561b575 100644 --- a/ext/sqlite3/tests/sqlite3_stmt_busy.phpt +++ b/ext/sqlite3/tests/sqlite3_stmt_busy.phpt @@ -2,17 +2,12 @@ SQLite3_stmt::busy --EXTENSIONS-- sqlite3 ---SKIPIF-- - --FILE-- exec('CREATE TABLE test_busy (a string);'); -$db->exec('INSERT INTO test_busy VALUES ("interleaved"), ("statements")'); +$db->exec("INSERT INTO test_busy VALUES ('interleaved'), ('statements')"); $st = $db->prepare('SELECT a FROM test_busy'); var_dump($st->busy()); $r = $st->execute(); diff --git a/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt b/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt index 81245f5b4bef..52d5b726415e 100644 --- a/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt +++ b/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt @@ -16,8 +16,8 @@ class TrampolineTest { $o = new TrampolineTest(); $callback = [$o, 'strtoupper']; var_dump($db->createfunction('strtoupper', $callback)); -var_dump($db->querySingle('SELECT strtoupper("test")')); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); +var_dump($db->querySingle("SELECT strtoupper('test')")); ?> --EXPECT-- diff --git a/ext/standard/array.c b/ext/standard/array.c index de889154edd4..2d1dd584906a 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -60,6 +58,7 @@ /* }}} */ ZEND_DECLARE_MODULE_GLOBALS(array) +PHPAPI zend_class_entry *sort_direction_ce; /* {{{ php_array_init_globals */ static void php_array_init_globals(zend_array_globals *array_globals) @@ -620,7 +619,6 @@ PHP_FUNCTION(count) cnt = php_count_recursive(Z_ARRVAL_P(array)); } RETURN_LONG(cnt); - break; case IS_OBJECT: { zval retval; /* first, we check if the handler is defined */ @@ -1091,9 +1089,23 @@ PHP_FUNCTION(key) } /* }}} */ -static int php_data_compare(const void *f, const void *s) /* {{{ */ +static zval *php_array_data_minmax(HashTable *array, bool max) /* {{{ */ { - return zend_compare((zval*)f, (zval*)s); + zval *entry, *result = NULL; + + ZEND_HASH_FOREACH_VAL(array, entry) { + if (!result) { + result = entry; + continue; + } + + int cmp = zend_compare(result, entry); + if (max ? cmp < 0 : cmp > 0) { + result = entry; + } + } ZEND_HASH_FOREACH_END(); + + return result; } /* }}} */ @@ -1113,10 +1125,10 @@ PHP_FUNCTION(min) /* mixed min ( array $values ) */ if (argc == 1) { if (Z_TYPE(args[0]) != IS_ARRAY) { - zend_argument_type_error(1, "must be of type array, %s given", zend_zval_value_name(&args[0])); + zend_wrong_parameter_type_error(1, Z_EXPECTED_ARRAY, &args[0]); RETURN_THROWS(); } else { - zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 0); + zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), false); if (result) { RETURN_COPY_DEREF(result); } else { @@ -1241,10 +1253,10 @@ PHP_FUNCTION(max) /* mixed max ( array $values ) */ if (argc == 1) { if (Z_TYPE(args[0]) != IS_ARRAY) { - zend_argument_type_error(1, "must be of type array, %s given", zend_zval_value_name(&args[0])); + zend_wrong_parameter_type_error(1, Z_EXPECTED_ARRAY, &args[0]); RETURN_THROWS(); } else { - zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 1); + zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), true); if (result) { RETURN_COPY_DEREF(result); } else { @@ -2818,7 +2830,7 @@ static uint8_t php_range_process_input(const zval *input, uint32_t arg_num, zend *dval = 0.0; return IS_STRING; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -4115,7 +4127,7 @@ static zend_always_inline void php_array_replace_wrapper(INTERNAL_FUNCTION_PARAM zval *arg = args + i; if (Z_TYPE_P(arg) != IS_ARRAY) { - zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_value_name(arg)); + zend_wrong_parameter_type_error(i + 1, Z_EXPECTED_ARRAY, arg); RETURN_THROWS(); } } @@ -4494,7 +4506,7 @@ PHP_FUNCTION(array_count_values) if ((tmp = zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_P(entry))) == NULL) { zval data; ZVAL_LONG(&data, 1); - zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); + zend_hash_index_add_new(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); } else { Z_LVAL_P(tmp)++; } @@ -4502,7 +4514,7 @@ PHP_FUNCTION(array_count_values) if ((tmp = zend_symtable_find(Z_ARRVAL_P(return_value), Z_STR_P(entry))) == NULL) { zval data; ZVAL_LONG(&data, 1); - zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); + zend_symtable_add_new(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } else { Z_LVAL_P(tmp)++; } @@ -4799,7 +4811,7 @@ PHP_FUNCTION(array_change_key_case) zend_string *string_key; zend_string *new_key; zend_ulong num_key; - zend_long change_to_upper=0; + zend_long change_to_upper = PHP_CASE_LOWER; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ARRAY(array) @@ -4807,13 +4819,18 @@ PHP_FUNCTION(array_change_key_case) Z_PARAM_LONG(change_to_upper) ZEND_PARSE_PARAMETERS_END(); + if (change_to_upper != PHP_CASE_LOWER && change_to_upper != PHP_CASE_UPPER) { + zend_argument_value_error(2, "must be either CASE_LOWER or CASE_UPPER"); + RETURN_THROWS(); + } + array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { if (!string_key) { entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } else { - if (change_to_upper) { + if (change_to_upper == PHP_CASE_UPPER) { new_key = zend_string_toupper(string_key); } else { new_key = zend_string_tolower(string_key); @@ -5741,7 +5758,7 @@ PHP_FUNCTION(array_diff) { zval *args; uint32_t argc, i; - uint32_t num; + uint64_t num; HashTable exclude; zval *value; zend_string *str, *tmp_str, *key; @@ -5831,6 +5848,11 @@ PHP_FUNCTION(array_diff) return; } + if (UNEXPECTED(num >= HT_MAX_SIZE)) { + zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE); + RETURN_THROWS(); + } + ZVAL_NULL(&dummy); /* create exclude map */ zend_hash_init(&exclude, num, NULL, NULL, 0); @@ -5941,6 +5963,7 @@ PHP_FUNCTION(array_multisort) { zval* args; zval** arrays; + HashTable** hashes; Bucket** indirect; uint32_t idx; HashTable* hash; @@ -6062,11 +6085,17 @@ PHP_FUNCTION(array_multisort) for (i = 0; i < array_size; i++) { indirect[i] = indirects + (i * (num_arrays + 1)); } + hashes = safe_emalloc(num_arrays, sizeof(HashTable *), 0); + for (i = 0; i < num_arrays; i++) { + hashes[i] = Z_ARRVAL_P(arrays[i]); + GC_ADDREF(hashes[i]); + HT_ALLOW_COW_VIOLATION(hashes[i]); + } for (i = 0; i < num_arrays; i++) { k = 0; - if (HT_IS_PACKED(Z_ARRVAL_P(arrays[i]))) { - zval *zv = Z_ARRVAL_P(arrays[i])->arPacked; - for (idx = 0; idx < Z_ARRVAL_P(arrays[i])->nNumUsed; idx++, zv++) { + if (HT_IS_PACKED(hashes[i])) { + zval *zv = hashes[i]->arPacked; + for (idx = 0; idx < hashes[i]->nNumUsed; idx++, zv++) { if (Z_TYPE_P(zv) == IS_UNDEF) continue; ZVAL_COPY_VALUE(&indirect[k][i].val, zv); indirect[k][i].h = idx; @@ -6074,8 +6103,8 @@ PHP_FUNCTION(array_multisort) k++; } } else { - Bucket *p = Z_ARRVAL_P(arrays[i])->arData; - for (idx = 0; idx < Z_ARRVAL_P(arrays[i])->nNumUsed; idx++, p++) { + Bucket *p = hashes[i]->arData; + for (idx = 0; idx < hashes[i]->nNumUsed; idx++, p++) { if (Z_TYPE(p->val) == IS_UNDEF) continue; indirect[k][i] = *p; k++; @@ -6095,7 +6124,7 @@ PHP_FUNCTION(array_multisort) /* Restructure the arrays based on sorted indirect - this is mostly taken from zend_hash_sort() function. */ for (i = 0; i < num_arrays; i++) { - hash = Z_ARRVAL_P(arrays[i]); + hash = hashes[i]; hash->nNumUsed = array_size; hash->nNextFreeElement = array_size; hash->nInternalPointer = 0; @@ -6124,6 +6153,14 @@ PHP_FUNCTION(array_multisort) RETVAL_TRUE; clean_up: + for (i = 0; i < num_arrays; i++) { + if (UNEXPECTED(GC_DELREF(hashes[i]) == 0)) { + zend_array_destroy(hashes[i]); + } else { + gc_check_possible_root((zend_refcounted *)hashes[i]); + } + } + efree(hashes); efree(indirects); efree(indirect); efree(func); @@ -6306,11 +6343,50 @@ PHP_FUNCTION(array_rand) } /* }}} */ +/* Apply a single array_sum/array_product step to return_value. */ +static zend_always_inline void php_array_binop_apply( + zval *return_value, zval *entry, const char *op_name, binary_op_type op) +{ + /* For objects we try to cast them to a numeric type */ + if (Z_TYPE_P(entry) == IS_OBJECT) { + zval dst; + zend_result status = Z_OBJ_HT_P(entry)->cast_object(Z_OBJ_P(entry), &dst, _IS_NUMBER); + + /* Do not type error for BC */ + if (status == FAILURE || (Z_TYPE(dst) != IS_LONG && Z_TYPE(dst) != IS_DOUBLE)) { + php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", + op_name, zend_zval_type_name(entry)); + return; + } + op(return_value, return_value, &dst); + return; + } + + zend_result status = op(return_value, return_value, entry); + if (status == FAILURE) { + ZEND_ASSERT(EG(exception)); + zend_clear_exception(); + /* BC resources: previously resources were cast to int */ + if (Z_TYPE_P(entry) == IS_RESOURCE) { + zval tmp; + ZVAL_LONG(&tmp, Z_RES_HANDLE_P(entry)); + op(return_value, return_value, &tmp); + } + /* BC non numeric strings: previously were cast to 0 */ + else if (Z_TYPE_P(entry) == IS_STRING) { + zval tmp; + ZVAL_LONG(&tmp, 0); + op(return_value, return_value, &tmp); + } + php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", + op_name, zend_zval_type_name(entry)); + } +} + /* Wrapper for array_sum and array_product */ -static void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, binary_op_type op, zend_long initial) +static zend_always_inline void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, binary_op_type op, zend_long initial) { HashTable *input; - zval *entry; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ARRAY_HT(input) @@ -6321,42 +6397,39 @@ static void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, b } ZVAL_LONG(return_value, initial); - ZEND_HASH_FOREACH_VAL(input, entry) { - /* For objects we try to cast them to a numeric type */ - if (Z_TYPE_P(entry) == IS_OBJECT) { - zval dst; - zend_result status = Z_OBJ_HT_P(entry)->cast_object(Z_OBJ_P(entry), &dst, _IS_NUMBER); - - /* Do not type error for BC */ - if (status == FAILURE || (Z_TYPE(dst) != IS_LONG && Z_TYPE(dst) != IS_DOUBLE)) { - php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", - op_name, zend_zval_type_name(entry)); - continue; - } - op(return_value, return_value, &dst); - continue; - } - zend_result status = op(return_value, return_value, entry); - if (status == FAILURE) { - ZEND_ASSERT(EG(exception)); - zend_clear_exception(); - /* BC resources: previously resources were cast to int */ - if (Z_TYPE_P(entry) == IS_RESOURCE) { - zval tmp; - ZVAL_LONG(&tmp, Z_RES_HANDLE_P(entry)); - op(return_value, return_value, &tmp); + if (op == add_function) { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + if (EXPECTED(Z_TYPE_P(entry) == IS_LONG) && EXPECTED(Z_TYPE_P(return_value) == IS_LONG)) { + fast_long_add_function(return_value, return_value, entry); + continue; } - /* BC non numeric strings: previously were cast to 0 */ - else if (Z_TYPE_P(entry) == IS_STRING) { - zval tmp; - ZVAL_LONG(&tmp, 0); - op(return_value, return_value, &tmp); + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } else if (op == mul_function) { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + if (EXPECTED(Z_TYPE_P(entry) == IS_LONG) && EXPECTED(Z_TYPE_P(return_value) == IS_LONG)) { + zend_long lval; + double dval; + int overflow; + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(return_value), Z_LVAL_P(entry), lval, dval, overflow); + if (UNEXPECTED(overflow)) { + ZVAL_DOUBLE(return_value, dval); + } else { + Z_LVAL_P(return_value) = lval; + } + continue; } - php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", - op_name, zend_zval_type_name(entry)); - } - } ZEND_HASH_FOREACH_END(); + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } else { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } } /* {{{ Returns the sum of the array entries */ @@ -6409,6 +6482,7 @@ PHP_FUNCTION(array_reduce) fci.retval = return_value; fci.param_count = 2; fci.params = args; + fci.consumed_args = zend_fci_consumed_arg(0); ZEND_HASH_FOREACH_VAL(htbl, operand) { ZVAL_COPY_VALUE(&args[0], return_value); @@ -6477,8 +6551,7 @@ PHP_FUNCTION(array_filter) } if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) { - RETVAL_EMPTY_ARRAY(); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); @@ -6677,7 +6750,7 @@ PHP_FUNCTION(array_map) if (n_arrays == 1) { if (Z_TYPE(arrays[0]) != IS_ARRAY) { - zend_argument_type_error(2, "must be of type array, %s given", zend_zval_value_name(&arrays[0])); + zend_wrong_parameter_type_error(2, Z_EXPECTED_ARRAY, &arrays[0]); RETURN_THROWS(); } const HashTable *input = Z_ARRVAL(arrays[0]); diff --git a/ext/standard/assert.c b/ext/standard/assert.c index a29d022b4ac4..618f69a2cf74 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -247,7 +245,9 @@ PHP_FUNCTION(assert) * exception so we can avoid bailout and use unwind_exit. */ zend_exception_error(EG(exception), E_WARNING); } - zend_throw_unwind_exit(); + if (!EG(exception)) { + zend_throw_unwind_exit(); + } RETURN_THROWS(); } else { RETURN_FALSE; @@ -285,7 +285,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_BAIL: oldint = ASSERTG(bail); @@ -301,7 +300,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_WARNING: oldint = ASSERTG(warning); @@ -317,7 +315,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_CALLBACK: if (Z_TYPE(ASSERTG(callback)) != IS_UNDEF) { @@ -352,7 +349,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(key, 0); } RETURN_LONG(oldint); - break; default: zend_argument_value_error(1, "must be an ASSERT_* constant"); diff --git a/ext/standard/base64.c b/ext/standard/base64.c index 8d4feee84975..5c3f876ef2b9 100644 --- a/ext/standard/base64.c +++ b/ext/standard/base64.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | | Xinchen Hui | @@ -536,7 +534,7 @@ zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t leng /* Step 2: splitting 24-bit words into 32-bit lanes */ str = _mm512_permutexvar_epi8(shuffle_splitting, str); - /* Step 3: moving 6-bit word to sperate bytes */ + /* Step 3: moving 6-bit word to separate bytes */ str = _mm512_multishift_epi64_epi8(multi_shifts, str); /* Step 4: conversion to ASCII */ @@ -643,7 +641,7 @@ zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length, z /* [D1 D2 D0 D1|C1 C2 C0 C1|B1 B2 B0 B1|A1 A2 A0 A1] x 4 */ str = _mm512_shuffle_epi8(str, _mm512_set4_epi32(0x0a0b090a, 0x07080607, 0x04050304, 0x01020001)); - /* Step 3: moving 6-bit word to sperate bytes */ + /* Step 3: moving 6-bit word to separate bytes */ /* in: [bbbbcccc|ccdddddd|aaaaaabb|bbbbcccc] */ /* t0: [0000cccc|cc000000|aaaaaa00|00000000] */ const __m512i t0 = _mm512_and_si512(str, _mm512_set1_epi32(0x0fc0fc00)); diff --git a/ext/standard/base64.h b/ext/standard/base64.h index 19ff0b60d252..a866541b727b 100644 --- a/ext/standard/base64.h +++ b/ext/standard/base64.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | | Xinchen Hui | diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index fbbeeb0b433f..e81050323754 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -297,12 +295,14 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ assertion_error_ce = register_class_AssertionError(zend_ce_error); rounding_mode_ce = register_class_RoundingMode(); + sort_direction_ce = register_class_SortDirection(); BASIC_MINIT_SUBMODULE(var) BASIC_MINIT_SUBMODULE(file) BASIC_MINIT_SUBMODULE(browscap) BASIC_MINIT_SUBMODULE(standard_filters) BASIC_MINIT_SUBMODULE(user_filters) + BASIC_MINIT_SUBMODULE(poll) BASIC_MINIT_SUBMODULE(password) BASIC_MINIT_SUBMODULE(image) @@ -336,6 +336,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ #endif BASIC_MINIT_SUBMODULE(exec) + BASIC_MINIT_SUBMODULE(stream_errors) BASIC_MINIT_SUBMODULE(user_streams) php_register_url_stream_wrapper("php", &php_stream_php_wrapper); @@ -599,6 +600,20 @@ PHP_FUNCTION(ip2long) if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) { RETURN_FALSE; } +#ifdef _AIX + /* + AIX accepts IP strings with extraneous 0 (192.168.042.42 will be treated as + 192.168.42.42), while Linux doesn't. + For consistency, we convert back the IP to a string and check if it is equal to + the original string. If not, the IP should be considered invalid. + */ + char str[INET_ADDRSTRLEN]; + const char* result = inet_ntop(AF_INET, &ip, str, sizeof(str)); + ZEND_ASSERT(result != NULL); + if (strcmp(addr, result) != 0) { + RETURN_FALSE; + } +#endif RETURN_LONG(ntohl(ip.s_addr)); } /* }}} */ @@ -697,7 +712,7 @@ PHP_FUNCTION(getenv) ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(str, str_len) + Z_PARAM_PATH_OR_NULL(str, str_len) Z_PARAM_BOOL(local_only) ZEND_PARSE_PARAMETERS_END(); @@ -740,7 +755,7 @@ PHP_FUNCTION(putenv) #endif ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(setting, setting_len) + Z_PARAM_PATH(setting, setting_len) ZEND_PARSE_PARAMETERS_END(); if (setting_len == 0 || setting[0] == '=') { @@ -1108,13 +1123,18 @@ PHP_FUNCTION(flush) PHP_FUNCTION(sleep) { zend_long num; +#ifdef PHP_WIN32 + const unsigned int max = UINT_MAX / 1000; +#else + const unsigned int max = UINT_MAX; +#endif ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(num) ZEND_PARSE_PARAMETERS_END(); - if (num < 0) { - zend_argument_value_error(1, "must be greater than or equal to 0"); + if (num < 0 || (zend_ulong) num > max) { + zend_argument_value_error(1, "must be between 0 and %u", max); RETURN_THROWS(); } @@ -1131,8 +1151,8 @@ PHP_FUNCTION(usleep) Z_PARAM_LONG(num) ZEND_PARSE_PARAMETERS_END(); - if (num < 0) { - zend_argument_value_error(1, "must be greater than or equal to 0"); + if (num < 0 || (zend_ulong) num > UINT_MAX) { + zend_argument_value_error(1, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } @@ -1282,9 +1302,9 @@ static void add_config_entries(HashTable *hash, zval *return_value) /* {{{ */ zend_string *key; zval *zv; - ZEND_HASH_FOREACH_KEY_VAL(hash, h, key, zv) + ZEND_HASH_FOREACH_KEY_VAL(hash, h, key, zv) { add_config_entry(h, key, zv, return_value); - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1717,11 +1737,11 @@ PHPAPI bool append_user_shutdown_function(php_shutdown_function_entry *shutdown_ ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini) /* {{{ */ { - syntax_highlighter_ini->highlight_comment = INI_STR("highlight.comment"); - syntax_highlighter_ini->highlight_default = INI_STR("highlight.default"); - syntax_highlighter_ini->highlight_html = INI_STR("highlight.html"); - syntax_highlighter_ini->highlight_keyword = INI_STR("highlight.keyword"); - syntax_highlighter_ini->highlight_string = INI_STR("highlight.string"); + syntax_highlighter_ini->highlight_comment = zend_ini_string_literal("highlight.comment"); + syntax_highlighter_ini->highlight_default = zend_ini_string_literal("highlight.default"); + syntax_highlighter_ini->highlight_html = zend_ini_string_literal("highlight.html"); + syntax_highlighter_ini->highlight_keyword = zend_ini_string_literal("highlight.keyword"); + syntax_highlighter_ini->highlight_string = zend_ini_string_literal("highlight.string"); } /* }}} */ @@ -1942,6 +1962,12 @@ PHP_FUNCTION(ini_get_all) add_assoc_null(&option, "local_value"); } + if (ini_entry->def->value) { + add_assoc_stringl(&option, "builtin_default_value", ini_entry->def->value, ini_entry->def->value_length); + } else { + add_assoc_null(&option, "builtin_default_value"); + } + add_assoc_long(&option, "access", ini_entry->modifiable); zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &option); @@ -2029,17 +2055,16 @@ PHP_FUNCTION(ini_restore) PHP_FUNCTION(set_include_path) { zend_string *new_value; - char *old_value; zend_string *key; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_PATH_STR(new_value) ZEND_PARSE_PARAMETERS_END(); - old_value = zend_ini_string("include_path", sizeof("include_path") - 1, 0); + zend_string *old_value = zend_ini_str_literal("include_path"); /* copy to return here, because alter might free it! */ if (old_value) { - RETVAL_STRING(old_value); + RETVAL_STR_COPY(old_value); } else { RETVAL_FALSE; } @@ -2059,7 +2084,7 @@ PHP_FUNCTION(get_include_path) { ZEND_PARSE_PARAMETERS_NONE(); - zend_string *str = zend_ini_str("include_path", sizeof("include_path") - 1, 0); + zend_string *str = zend_ini_str_literal("include_path"); if (str == NULL) { RETURN_FALSE; diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index 004279b9d1ae..4d5a4c02aec0 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -44,6 +42,7 @@ PHP_MINFO_FUNCTION(basic); ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini); +PHP_MINIT_FUNCTION(poll); PHP_MINIT_FUNCTION(user_filters); PHP_RSHUTDOWN_FUNCTION(user_filters); PHP_RSHUTDOWN_FUNCTION(browscap); diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 6d0c565fc2d4..7fc31e7d80ca 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -90,6 +90,11 @@ */ const SORT_FLAG_CASE = UNKNOWN; +enum SortDirection { + case Ascending; + case Descending; +} + /** * @var int * @cvalue PHP_CASE_LOWER @@ -1636,7 +1641,10 @@ function in_array(mixed $needle, array $haystack, bool $strict = false): bool {} */ function array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false {} -/** @prefer-ref $array */ +/** + * @prefer-ref $array + * @forbid-dynamic-calls + */ function extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""): int {} /** @@ -1644,6 +1652,7 @@ function extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = "" * @param array|string $var_names * @return array * @refcount 1 + * @forbid-dynamic-calls */ function compact($var_name, ...$var_names): array {} @@ -1874,7 +1883,7 @@ function array_product(array $array): int|float {} function array_reduce(array $array, callable $callback, mixed $initial = null): mixed {} -function array_filter(array $array, ?callable $callback = null, int $mode = ARRAY_FILTER_USE_KEY): array {} +function array_filter(array $array, ?callable $callback = null, int $mode = ARRAY_FILTER_USE_VALUE): array {} function array_find(array $array, callable $callback): mixed {} @@ -3376,7 +3385,10 @@ function soundex(string $string): string {} /* streamsfuncs.c */ -function stream_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds = null): int|false {} +/** + * @param resource|null $context + */ +function stream_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds = null, $context = null): int|false {} /** * @return resource @@ -3472,6 +3484,11 @@ function stream_socket_sendto($socket, string $data, int $flags = 0, string $add */ function stream_socket_enable_crypto($stream, bool $enable, ?int $crypto_method = null, $session_stream = null): int|bool {} +/** + * @param resource $stream + */ +function stream_socket_get_crypto_status($stream): int {} + #ifdef HAVE_SHUTDOWN /** @param resource $stream */ function stream_socket_shutdown($stream, int $mode): bool {} @@ -3479,17 +3496,19 @@ function stream_socket_shutdown($stream, int $mode): bool {} #ifdef HAVE_SOCKETPAIR /** + * @param resource|null $context * @return array|false * @refcount 1 */ -function stream_socket_pair(int $domain, int $type, int $protocol): array|false {} +function stream_socket_pair(int $domain, int $type, int $protocol, $context = null): array|false {} #endif /** * @param resource $from * @param resource $to + * @param resource|null $context */ -function stream_copy_to_stream($from, $to, ?int $length = null, int $offset = 0): int|false {} +function stream_copy_to_stream($from, $to, ?int $length = null, int $offset = 0, $context = null): int|false {} /** * @param resource $stream @@ -3549,14 +3568,24 @@ function stream_resolve_include_path(string $filename): string|false {} */ function stream_get_wrappers(): array {} +/** + * @return array + */ +function stream_last_errors(): array {} + +function stream_clear_errors(): void {} + /** * @return array * @refcount 1 */ function stream_get_transports(): array {} -/** @param resource|string $stream */ -function stream_is_local($stream): bool {} +/** + * @param resource|string $stream + * @param resource|null $context + */ +function stream_is_local($stream, $context = null): bool {} /** @param resource $stream */ function stream_isatty($stream): bool {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index d0109fa27c96..c5266c5a877c 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 basic_functions.stub.php instead. - * Stub hash: f5583557f058e4862750d1262296d7f59cb0eed0 + * Stub hash: 3b1649a3abb3cfb5cb39d93f30a97765fe862d67 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -346,7 +346,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "ARRAY_FILTER_USE_KEY") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "ARRAY_FILTER_USE_VALUE") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_find, 0, 2, IS_MIXED, 0) @@ -1823,6 +1823,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_select, 0, 4, MAY_BE_LONG ZEND_ARG_TYPE_INFO(1, except, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, microseconds, IS_LONG, 1, "null") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_context_create, 0, 0, 0) @@ -1925,6 +1926,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_socket_enable_crypto, 0, ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, session_stream, "null") ZEND_END_ARG_INFO() +#define arginfo_stream_socket_get_crypto_status arginfo_fpassthru + #if defined(HAVE_SHUTDOWN) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stream_socket_shutdown, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, stream) @@ -1937,6 +1940,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_socket_pair, 0, 3, MAY_BE ZEND_ARG_TYPE_INFO(0, domain, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, protocol, IS_LONG, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() #endif @@ -1945,6 +1949,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_copy_to_stream, 0, 2, MAY ZEND_ARG_INFO(0, to) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "0") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_get_contents, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) @@ -1987,9 +1992,16 @@ ZEND_END_ARG_INFO() #define arginfo_stream_get_wrappers arginfo_ob_list_handlers +#define arginfo_stream_last_errors arginfo_ob_list_handlers + +#define arginfo_stream_clear_errors arginfo_flush + #define arginfo_stream_get_transports arginfo_ob_list_handlers -#define arginfo_stream_is_local arginfo_rewind +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stream_is_local, 0, 1, _IS_BOOL, 0) + ZEND_ARG_INFO(0, stream) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") +ZEND_END_ARG_INFO() #define arginfo_stream_isatty arginfo_rewind @@ -2813,6 +2825,7 @@ ZEND_FUNCTION(stream_socket_get_name); ZEND_FUNCTION(stream_socket_recvfrom); ZEND_FUNCTION(stream_socket_sendto); ZEND_FUNCTION(stream_socket_enable_crypto); +ZEND_FUNCTION(stream_socket_get_crypto_status); #if defined(HAVE_SHUTDOWN) ZEND_FUNCTION(stream_socket_shutdown); #endif @@ -2829,6 +2842,8 @@ ZEND_FUNCTION(stream_get_meta_data); ZEND_FUNCTION(stream_get_line); ZEND_FUNCTION(stream_resolve_include_path); ZEND_FUNCTION(stream_get_wrappers); +ZEND_FUNCTION(stream_last_errors); +ZEND_FUNCTION(stream_clear_errors); ZEND_FUNCTION(stream_get_transports); ZEND_FUNCTION(stream_is_local); ZEND_FUNCTION(stream_isatty); @@ -2944,8 +2959,16 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(array_walk_recursive, arginfo_array_walk_recursive) ZEND_RAW_FENTRY("in_array", zif_in_array, arginfo_in_array, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_in_array, NULL) ZEND_RAW_FENTRY("array_search", zif_array_search, arginfo_array_search, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) - ZEND_FE(extract, arginfo_extract) - ZEND_FE(compact, arginfo_compact) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("extract", zif_extract, arginfo_extract, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("extract", zif_extract, arginfo_extract, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("compact", zif_compact, arginfo_compact, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("compact", zif_compact, arginfo_compact, 0, NULL, NULL) +#endif ZEND_FE(array_fill, arginfo_array_fill) ZEND_FE(array_fill_keys, arginfo_array_fill_keys) ZEND_FE(range, arginfo_range) @@ -3418,6 +3441,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(stream_socket_recvfrom, arginfo_stream_socket_recvfrom) ZEND_FE(stream_socket_sendto, arginfo_stream_socket_sendto) ZEND_FE(stream_socket_enable_crypto, arginfo_stream_socket_enable_crypto) + ZEND_FE(stream_socket_get_crypto_status, arginfo_stream_socket_get_crypto_status) #if defined(HAVE_SHUTDOWN) ZEND_FE(stream_socket_shutdown, arginfo_stream_socket_shutdown) #endif @@ -3437,6 +3461,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(stream_get_line, arginfo_stream_get_line) ZEND_FE(stream_resolve_include_path, arginfo_stream_resolve_include_path) ZEND_FE(stream_get_wrappers, arginfo_stream_get_wrappers) + ZEND_FE(stream_last_errors, arginfo_stream_last_errors) + ZEND_FE(stream_clear_errors, arginfo_stream_clear_errors) ZEND_FE(stream_get_transports, arginfo_stream_get_transports) ZEND_FE(stream_is_local, arginfo_stream_is_local) ZEND_FE(stream_isatty, arginfo_stream_isatty) @@ -3980,6 +4006,17 @@ static void register_basic_functions_symbols(int module_number) attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } +static zend_class_entry *register_class_SortDirection(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("SortDirection", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Ascending", NULL); + + zend_enum_add_case_cstr(class_entry, "Descending", NULL); + + return class_entry; +} + static zend_class_entry *register_class___PHP_Incomplete_Class(void) { zend_class_entry ce, *class_entry; diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index 139b47f2444d..630a4b7e656b 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,13 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: f5583557f058e4862750d1262296d7f59cb0eed0 */ + * Stub hash: 3b1649a3abb3cfb5cb39d93f30a97765fe862d67 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H -#define ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_3b1649a3abb3cfb5cb39d93f30a97765fe862d67_H +#define ZEND_BASIC_FUNCTIONS_DECL_3b1649a3abb3cfb5cb39d93f30a97765fe862d67_H + +typedef enum zend_enum_SortDirection { + ZEND_ENUM_SortDirection_Ascending = 1, + ZEND_ENUM_SortDirection_Descending = 2, +} zend_enum_SortDirection; typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_HalfAwayFromZero = 1, @@ -15,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_3b1649a3abb3cfb5cb39d93f30a97765fe862d67_H */ diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 5009c7793688..7534615a946b 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ @@ -337,7 +335,7 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callb ) { zend_error(E_CORE_ERROR, "Invalid browscap ini file: " "'Parent' value cannot be same as the section name: %s " - "(in file %s)", ZSTR_VAL(ctx->current_section_name), INI_STR("browscap")); + "(in file %s)", ZSTR_VAL(ctx->current_section_name), zend_ini_string_literal("browscap")); return; } @@ -399,7 +397,7 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callb } /* }}} */ -static zend_result browscap_read_file(char *filename, browser_data *browdata, bool persistent) /* {{{ */ +static zend_result browscap_read_file(const char *filename, browser_data *browdata, bool persistent) /* {{{ */ { zend_file_handle fh; browscap_parser_ctx ctx = {0}; @@ -499,7 +497,7 @@ PHP_INI_MH(OnChangeBrowscap) PHP_MINIT_FUNCTION(browscap) /* {{{ */ { - char *browscap = INI_STR("browscap"); + const char *browscap = zend_ini_string_literal("browscap"); #ifdef ZTS ts_allocate_id(&browscap_globals_id, sizeof(browser_data), (ts_allocate_ctor) browscap_globals_ctor, NULL); diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index ef6b3c5a0101..7edfcf1da1f5 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -328,7 +328,7 @@ dnl PHP_CHECK_FUNC(res_search, resolv, socket) -AC_CHECK_FUNCS([posix_spawn_file_actions_addchdir_np elf_aux_info]) +AC_CHECK_FUNCS([posix_spawn_file_actions_addchdir posix_spawn_file_actions_addchdir_np elf_aux_info]) dnl dnl Obsolete check for strptime() declaration. The strptime, where available, @@ -418,6 +418,7 @@ PHP_NEW_EXTENSION([standard], m4_normalize([ image.c incomplete_class.c info.c + io_poll.c iptc.c levenshtein.c libavifinfo/avifinfo.c @@ -452,8 +453,7 @@ PHP_NEW_EXTENSION([standard], m4_normalize([ versioning.c $php_ext_standard_sources ]), - [no],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [no]) PHP_ADD_BUILD_DIR([$ext_builddir/libavifinfo]) diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index 589929027f65..56096097620d 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -28,15 +28,15 @@ EXTENSION("standard", "array.c base64.c basic_functions.c browscap.c \ crypt_sha512.c php_crypt_r.c " + (TARGET_ARCH != 'arm64'? " crc32_x86.c" : "") + " \ datetime.c dir.c dl.c dns.c dns_win32.c exec.c \ file.c filestat.c formatted_print.c fsock.c head.c html.c image.c \ - info.c iptc.c link.c mail.c math.c md5.c metaphone.c microtime.c \ + info.c io_poll.c iptc.c link.c mail.c math.c md5.c metaphone.c microtime.c \ net.c pack.c pageinfo.c quot_print.c soundex.c \ string.c scanf.c syslog.c type.c uniqid.c url.c var.c \ versioning.c assert.c strnatcmp.c levenshtein.c incomplete_class.c \ url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ user_filters.c uuencode.c filters.c proc_open.c password.c \ - streamsfuncs.c http.c flock_compat.c hrtime.c", false /* never shared */, - '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); + streamsfuncs.c http.c flock_compat.c hrtime.c", + false /* never shared */); ADD_SOURCES("ext/standard/libavifinfo", "avifinfo.c", "standard"); PHP_STANDARD = "yes"; ADD_MAKEFILE_FRAGMENT(); diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index e99c3ca9f5a0..fdf9df37c337 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32.h b/ext/standard/crc32.h index 261acdeb1fec..97f2bc01a282 100644 --- a/ext/standard/crc32.h +++ b/ext/standard/crc32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32_x86.c b/ext/standard/crc32_x86.c index 0b655fd6a483..5a6debc6f410 100644 --- a/ext/standard/crc32_x86.c +++ b/ext/standard/crc32_x86.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Frank Du | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32_x86.h b/ext/standard/crc32_x86.h index 91b5ba80e691..c46775f1af22 100644 --- a/ext/standard/crc32_x86.h +++ b/ext/standard/crc32_x86.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Frank Du | +----------------------------------------------------------------------+ diff --git a/ext/standard/credits.c b/ext/standard/credits.c index 4e8722db4d66..1fc74d72db35 100644 --- a/ext/standard/credits.c +++ b/ext/standard/credits.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -101,7 +99,7 @@ PHPAPI ZEND_COLD void php_print_credits(int flag) /* {{{ */ if (flag & PHP_CREDITS_QA) { php_info_print_table_start(); - php_info_print_table_header(1, "PHP Quality Assurance Team"); + php_info_print_table_colspan_header(1, "PHP Quality Assurance Team"); php_info_print_table_row(1, "Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena, David Soria Parra, Stanislav Malyshev, Julien Pauli, Stephen Zarkos, Anatol Belski, Remi Collet, Ferenc Kovacs"); php_info_print_table_end(); } diff --git a/ext/standard/credits.h b/ext/standard/credits.h index a0c5d1e7d90c..2a346dd06ddd 100644 --- a/ext/standard/credits.h +++ b/ext/standard/credits.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/ext/standard/credits_ext.h b/ext/standard/credits_ext.h index 509135a27e3e..b22a3f090c43 100644 --- a/ext/standard/credits_ext.h +++ b/ext/standard/credits_ext.h @@ -19,7 +19,7 @@ CREDIT_LINE("cURL", "Sterling Hughes"); CREDIT_LINE("Date/Time Support", "Derick Rethans"); CREDIT_LINE("DB-LIB (MS SQL, Sybase)", "Wez Furlong, Frank M. Kromann, Adam Baratz"); CREDIT_LINE("DBA", "Sascha Schumann, Marcus Boerger"); -CREDIT_LINE("DOM", "Christian Stocker, Rob Richards, Marcus Boerger, Niels Dossche"); +CREDIT_LINE("DOM", "Christian Stocker, Rob Richards, Marcus Boerger, Nora Dossche"); CREDIT_LINE("enchant", "Pierre-Alain Joye, Ilia Alshanetsky"); CREDIT_LINE("EXIF", "Rasmus Lerdorf, Marcus Boerger"); CREDIT_LINE("FFI", "Dmitry Stogov"); @@ -69,7 +69,7 @@ CREDIT_LINE("System V Semaphores", "Tom May"); CREDIT_LINE("System V Shared Memory", "Christian Cartus"); CREDIT_LINE("tidy", "John Coggeshall, Ilia Alshanetsky"); CREDIT_LINE("tokenizer", "Andrei Zmievski, Johannes Schlueter"); -CREDIT_LINE("uri", "Máté Kocsis, Tim Düsterhus, Ignace Nyamagana Butera, Arnaud Le Blanc, Dennis Snell, Niels Dossche, Nicolas Grekas"); +CREDIT_LINE("uri", "Máté Kocsis, Tim Düsterhus, Ignace Nyamagana Butera, Arnaud Le Blanc, Dennis Snell, Nora Dossche, Nicolas Grekas"); CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen, Sterling Hughes"); CREDIT_LINE("XMLReader", "Rob Richards"); CREDIT_LINE("XMLWriter", "Rob Richards, Pierre-Alain Joye"); diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 54687f6cdf30..d8a9905cfc13 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Bakken | | Zeev Suraski | diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index 2673dcf2b08e..3f3d9cdeb03c 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -23,7 +23,6 @@ #ifdef PHP_WIN32 # include #else -# include # include # include #endif diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index e8cedaa55c20..4a308e2f9af2 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -22,7 +22,6 @@ #ifdef PHP_WIN32 # include #else -# include # include # include #endif diff --git a/ext/standard/css.c b/ext/standard/css.c index 41efc028ff72..87387c9a3826 100644 --- a/ext/standard/css.c +++ b/ext/standard/css.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Colin Viebrock | +----------------------------------------------------------------------+ diff --git a/ext/standard/css.h b/ext/standard/css.h index 6771541f5fc5..59dbef62204c 100644 --- a/ext/standard/css.h +++ b/ext/standard/css.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Colin Viebrock | +----------------------------------------------------------------------+ diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c index 93f47f0f858b..b60182ee7f33 100644 --- a/ext/standard/datetime.c +++ b/ext/standard/datetime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 730ef6154907..f313d5f539d1 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -588,9 +586,13 @@ PHP_FUNCTION(scandir) n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort); } else if (flags == PHP_SCANDIR_SORT_NONE) { n = php_stream_scandir(dirn, &namelist, context, NULL); - } else { + } else if (flags == PHP_SCANDIR_SORT_DESCENDING) { n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr); - } + } else { + zend_argument_value_error(2, "must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants"); + RETURN_THROWS(); + } + if (n < 0) { php_error_docref(NULL, E_WARNING, "(errno %d): %s", errno, strerror(errno)); RETURN_FALSE; diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 31adbceac8c2..ca8ba57a16e9 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brian Schaffner | | Shane Caraveo | @@ -45,7 +43,7 @@ PHPAPI PHP_FUNCTION(dl) size_t filename_len; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(filename, filename_len) + Z_PARAM_PATH(filename, filename_len) ZEND_PARSE_PARAMETERS_END(); if (!PG(enable_dl)) { @@ -93,7 +91,7 @@ PHPAPI void *php_load_shlib(const char *path, char **errp) size_t i = strlen(err); (*errp)=estrdup(err); php_win32_error_msg_free(err); - while (i > 0 && isspace((*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } + while (i > 0 && isspace((unsigned char)(*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } } else { (*errp) = estrdup(""); } @@ -114,11 +112,11 @@ PHPAPI int php_load_extension(const char *filename, int type, int start_now) zend_module_entry *module_entry; zend_module_entry *(*get_module)(void); int error_type, slash_suffix = 0; - char *extension_dir; + const char *extension_dir; char *err1, *err2; if (type == MODULE_PERSISTENT) { - extension_dir = INI_STR("extension_dir"); + extension_dir = zend_ini_string_literal("extension_dir"); } else { extension_dir = PG(extension_dir); } diff --git a/ext/standard/dl.h b/ext/standard/dl.h index 58de973bf4b5..9354caa2ca8d 100644 --- a/ext/standard/dl.h +++ b/ext/standard/dl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brian Schaffner | | Shane Caraveo | diff --git a/ext/standard/dns.c b/ext/standard/dns.c index a574d8dd9aeb..b3fcc1d236af 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: The typical suspects | | Pollita | diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 8caf5813395c..c9ff67e47b1e 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre A. Joye | +----------------------------------------------------------------------+ diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 7bacc976eac5..5c9e5c6076a8 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | | Ilia Alshanetsky | @@ -81,7 +79,7 @@ PHP_MINIT_FUNCTION(exec) static size_t strip_trailing_whitespace(char *buf, size_t bufl) { size_t l = bufl; - while (l-- > 0 && isspace(((unsigned char *)buf)[l])); + while (l-- > 0 && isspace((unsigned char)buf[l])); if (l != (bufl - 1)) { bufl = l + 1; buf[bufl] = '\0'; diff --git a/ext/standard/exec.h b/ext/standard/exec.h index 1ad755363e3d..879334285020 100644 --- a/ext/standard/exec.h +++ b/ext/standard/exec.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/file.c b/ext/standard/file.c index a7b73f1fe56e..fd6f578e4ef0 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -63,11 +61,7 @@ #include "file.h" #ifdef HAVE_PWD_H -# ifdef PHP_WIN32 -# include "win32/pwd.h" -# else -# include -# endif +# include #endif #include "fsock.h" @@ -149,8 +143,8 @@ static PHP_INI_MH(OnUpdateAutoDetectLineEndings) } PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals) - STD_PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, OnUpdateString, from_address, php_file_globals, file_globals) + STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateStr, user_agent, php_file_globals, file_globals) + STD_PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, OnUpdateStr, from_address, php_file_globals, file_globals) STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals) STD_PHP_INI_BOOLEAN("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateAutoDetectLineEndings, auto_detect_line_endings, php_file_globals, file_globals) PHP_INI_END() @@ -223,7 +217,9 @@ PHP_FUNCTION(flock) Z_PARAM_ZVAL(wouldblock) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); php_flock_common(stream, operation, 2, wouldblock, return_value); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -259,6 +255,8 @@ PHP_FUNCTION(get_meta_tags) RETURN_FALSE; } + php_stream_error_operation_begin(); + array_init(return_value); tok_last = TOK_EOF; @@ -370,6 +368,8 @@ PHP_FUNCTION(get_meta_tags) if (value) efree(value); if (name) efree(name); php_stream_close(md.stream); + + php_stream_error_operation_end_for_stream(md.stream); } /* }}} */ @@ -404,12 +404,13 @@ PHP_FUNCTION(file_get_contents) RETURN_THROWS(); } + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, 0); - stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context); if (!stream) { + php_stream_error_operation_end(context); RETURN_FALSE; } @@ -420,8 +421,9 @@ PHP_FUNCTION(file_get_contents) } if (offset != 0 && php_stream_seek(stream, offset, ((offset > 0) ? SEEK_SET : SEEK_END)) < 0) { - php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", offset); php_stream_close(stream); + php_stream_error_operation_end(context); + php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", offset); RETURN_FALSE; } @@ -432,6 +434,7 @@ PHP_FUNCTION(file_get_contents) } php_stream_close(stream); + php_stream_error_operation_end(context); } /* }}} */ @@ -461,6 +464,7 @@ PHP_FUNCTION(file_put_contents) php_stream_from_zval(srcstream, data); } + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); if (flags & PHP_FILE_APPEND) { @@ -479,11 +483,13 @@ PHP_FUNCTION(file_put_contents) stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | REPORT_ERRORS, NULL, context); if (stream == NULL) { + php_stream_error_operation_end(context); RETURN_FALSE; } if ((flags & LOCK_EX) && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) { php_stream_close(stream); + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Exclusive locks are not supported for this stream"); RETURN_FALSE; } @@ -566,6 +572,7 @@ PHP_FUNCTION(file_put_contents) break; } php_stream_close(stream); + php_stream_error_operation_end(context); if (numbytes < 0) { RETURN_FALSE; @@ -611,10 +618,12 @@ PHP_FUNCTION(file) include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES); skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES; + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context); if (!stream) { + php_stream_error_operation_end(context); RETURN_FALSE; } @@ -668,6 +677,7 @@ PHP_FUNCTION(file) } php_stream_close(stream); + php_stream_error_operation_end(context); } /* }}} */ @@ -707,7 +717,9 @@ PHP_FUNCTION(tmpfile) ZEND_PARSE_PARAMETERS_NONE(); + php_stream_error_operation_begin(); stream = php_stream_fopen_tmpfile(); + php_stream_error_operation_end_for_stream(stream); if (stream) { php_stream_to_zval(stream, return_value); @@ -735,9 +747,11 @@ PHP_FUNCTION(fopen) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, 0); stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context); + php_stream_error_operation_end(context); if (stream == NULL) { RETURN_FALSE; @@ -761,9 +775,11 @@ PHPAPI PHP_FUNCTION(fclose) RETURN_FALSE; } + php_stream_error_operation_begin(); php_stream_free(stream, PHP_STREAM_FREE_KEEP_RSRC | (stream->is_persistent ? PHP_STREAM_FREE_CLOSE_PERSISTENT : PHP_STREAM_FREE_CLOSE)); + php_stream_error_operation_end_for_stream(stream); RETURN_TRUE; } @@ -806,19 +822,21 @@ PHP_FUNCTION(popen) fp = VCWD_POPEN(command, posix_mode); if (!fp) { - php_error_docref2(NULL, command, posix_mode, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); efree(posix_mode); RETURN_FALSE; } + php_stream_error_operation_begin(); stream = php_stream_fopen_from_pipe(fp, mode); if (stream == NULL) { - php_error_docref2(NULL, command, mode, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); RETVAL_FALSE; } else { php_stream_to_zval(stream, return_value); } + php_stream_error_operation_end_for_stream(stream); efree(posix_mode); } @@ -833,9 +851,11 @@ PHP_FUNCTION(pclose) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); FG(pclose_wait) = 1; zend_list_close(stream->res); FG(pclose_wait) = 0; + php_stream_error_operation_end_for_stream(stream); RETURN_LONG(FG(pclose_ret)); } /* }}} */ @@ -849,11 +869,13 @@ PHPAPI PHP_FUNCTION(feof) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); if (php_stream_eof(stream)) { - RETURN_TRUE; + RETVAL_TRUE; } else { - RETURN_FALSE; + RETVAL_FALSE; } + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -873,9 +895,11 @@ PHPAPI PHP_FUNCTION(fgets) Z_PARAM_LONG_OR_NULL(len, len_is_null) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); if (len_is_null) { /* ask streams to give us a buffer of an appropriate size */ buf = php_stream_get_line(stream, NULL, 0, &line_len); + php_stream_error_operation_end_for_stream(stream); if (buf == NULL) { RETURN_FALSE; } @@ -889,7 +913,9 @@ PHPAPI PHP_FUNCTION(fgets) } str = zend_string_alloc(len, 0); - if (php_stream_get_line(stream, ZSTR_VAL(str), len, &line_len) == NULL) { + buf = php_stream_get_line(stream, ZSTR_VAL(str), len, &line_len); + php_stream_error_operation_end_for_stream(stream); + if (buf == NULL) { zend_string_efree(str); RETURN_FALSE; } @@ -914,7 +940,9 @@ PHPAPI PHP_FUNCTION(fgetc) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); int result = php_stream_getc(stream); + php_stream_error_operation_end_for_stream(stream); if (result == EOF) { RETVAL_FALSE; @@ -933,7 +961,6 @@ PHP_FUNCTION(fscanf) zval *file_handle; char *buf, *format; size_t len; - void *what; ZEND_PARSE_PARAMETERS_START(2, -1) Z_PARAM_RESOURCE(file_handle) @@ -941,16 +968,18 @@ PHP_FUNCTION(fscanf) Z_PARAM_VARIADIC('*', args, argc) ZEND_PARSE_PARAMETERS_END(); - what = zend_fetch_resource2(Z_RES_P(file_handle), "File-Handle", php_file_le_stream(), php_file_le_pstream()); + php_stream *stream = zend_fetch_resource2(Z_RES_P(file_handle), "File-Handle", php_file_le_stream(), php_file_le_pstream()); - /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up + /* we can't do a ZEND_VERIFY_RESOURCE(stream), otherwise we end up * with a leak if we have an invalid filehandle. This needs changing * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */ - if (!what) { + if (!stream) { RETURN_THROWS(); } - buf = php_stream_get_line((php_stream *) what, NULL, 0, &len); + php_stream_error_operation_begin(); + buf = php_stream_get_line(stream, NULL, 0, &len); + php_stream_error_operation_end_for_stream(stream); if (buf == NULL) { RETURN_FALSE; } @@ -996,7 +1025,9 @@ PHPAPI PHP_FUNCTION(fwrite) RETURN_LONG(0); } + php_stream_error_operation_begin(); ret = php_stream_write(stream, input, num_bytes); + php_stream_error_operation_end_for_stream(stream); if (ret < 0) { RETURN_FALSE; } @@ -1015,8 +1046,9 @@ PHPAPI PHP_FUNCTION(fflush) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); ret = php_stream_flush(stream); - + php_stream_error_operation_end_for_stream(stream); RETURN_BOOL(!ret); } /* }}} */ @@ -1024,13 +1056,17 @@ PHPAPI PHP_FUNCTION(fflush) /* {{{ Rewind the position of a file pointer */ PHPAPI PHP_FUNCTION(rewind) { + int ret; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - RETURN_BOOL(-1 != php_stream_rewind(stream)); + php_stream_error_operation_begin(); + ret = php_stream_rewind(stream); + php_stream_error_operation_end_for_stream(stream); + RETURN_BOOL(-1 != ret); } /* }}} */ @@ -1044,7 +1080,9 @@ PHPAPI PHP_FUNCTION(ftell) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); ret = php_stream_tell(stream); + php_stream_error_operation_end_for_stream(stream); if (ret == -1) { RETURN_FALSE; } @@ -1065,7 +1103,9 @@ PHPAPI PHP_FUNCTION(fseek) Z_PARAM_LONG(whence) ZEND_PARSE_PARAMETERS_END(); - RETURN_LONG(php_stream_seek(stream, offset, (int) whence)); + php_stream_error_operation_begin(); + RETVAL_LONG(php_stream_seek(stream, offset, (int) whence)); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -1089,7 +1129,9 @@ PHP_FUNCTION(mkdir) context = php_stream_context_from_zval(zcontext, 0); - RETURN_BOOL(php_stream_mkdir(dir, (int)mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context)); + php_stream_error_operation_begin(); + RETVAL_BOOL(php_stream_mkdir(dir, (int)mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context)); + php_stream_error_operation_end(context); } /* }}} */ @@ -1109,7 +1151,9 @@ PHP_FUNCTION(rmdir) context = php_stream_context_from_zval(zcontext, 0); - RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context)); + php_stream_error_operation_begin(); + RETVAL_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context)); + php_stream_error_operation_end(context); } /* }}} */ @@ -1133,14 +1177,17 @@ PHP_FUNCTION(readfile) context = php_stream_context_from_zval(zcontext, 0); + php_stream_error_operation_begin(); stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context); if (stream) { size = php_stream_passthru(stream); php_stream_close(stream); - RETURN_LONG(size); + RETVAL_LONG(size); + } else { + RETVAL_FALSE; } + php_stream_error_operation_end(context); - RETURN_FALSE; } /* }}} */ @@ -1182,7 +1229,9 @@ PHPAPI PHP_FUNCTION(fpassthru) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); size = php_stream_passthru(stream); + php_stream_error_operation_end_for_stream(stream); RETURN_LONG(size); } /* }}} */ @@ -1203,26 +1252,31 @@ PHP_FUNCTION(rename) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); + wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0); if (!wrapper || !wrapper->wops) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Unable to locate stream wrapper"); RETURN_FALSE; } if (!wrapper->wops->rename) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source"); RETURN_FALSE; } if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0)) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Cannot rename a file across wrapper types"); RETURN_FALSE; } - context = php_stream_context_from_zval(zcontext, 0); - - RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context)); + RETVAL_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, REPORT_ERRORS, context)); + php_stream_error_operation_end(context); } /* }}} */ @@ -1241,20 +1295,24 @@ PHP_FUNCTION(unlink) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, 0); wrapper = php_stream_locate_url_wrapper(filename, NULL, 0); if (!wrapper || !wrapper->wops) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Unable to locate stream wrapper"); RETURN_FALSE; } if (!wrapper->wops->unlink) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper"); RETURN_FALSE; } - RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, REPORT_ERRORS, context)); + RETVAL_BOOL(wrapper->wops->unlink(wrapper, filename, REPORT_ERRORS, context)); + php_stream_error_operation_end(context); } /* }}} */ @@ -1266,12 +1324,15 @@ PHP_FUNCTION(fsync) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); if (!php_stream_sync_supported(stream)) { + php_stream_error_operation_end_for_stream(stream); php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); RETURN_FALSE; } - RETURN_BOOL(php_stream_sync(stream, /* data_only */ 0) == 0); + RETVAL_BOOL(php_stream_sync(stream, /* data_only */ 0) == 0); + php_stream_error_operation_end_for_stream(stream); } PHP_FUNCTION(fdatasync) @@ -1282,12 +1343,15 @@ PHP_FUNCTION(fdatasync) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); if (!php_stream_sync_supported(stream)) { + php_stream_error_operation_end_for_stream(stream); php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); RETURN_FALSE; } - RETURN_BOOL(php_stream_sync(stream, /* data_only */ 1) == 0); + RETVAL_BOOL(php_stream_sync(stream, /* data_only */ 1) == 0); + php_stream_error_operation_end_for_stream(stream); } /* {{{ Truncate file to 'size' length */ @@ -1306,12 +1370,16 @@ PHP_FUNCTION(ftruncate) RETURN_THROWS(); } + php_stream_error_operation_begin(); + if (!php_stream_truncate_supported(stream)) { + php_stream_error_operation_end_for_stream(stream); php_error_docref(NULL, E_WARNING, "Can't truncate this stream!"); RETURN_FALSE; } - RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size)); + RETVAL_BOOL(0 == php_stream_truncate_set_size(stream, size)); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ PHPAPI void php_fstat(php_stream *stream, zval *return_value) @@ -1395,7 +1463,9 @@ PHP_FUNCTION(fstat) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); php_fstat(stream, return_value); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -1414,13 +1484,16 @@ PHP_FUNCTION(copy) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); + if (php_stream_locate_url_wrapper(source, NULL, 0) == &php_plain_files_wrapper && php_check_open_basedir(source)) { + php_stream_error_operation_end(context); RETURN_FALSE; } - context = php_stream_context_from_zval(zcontext, 0); - - RETURN_BOOL(php_copy_file_ctx(source, target, 0, context) == SUCCESS); + RETVAL_BOOL(php_copy_file_ctx(source, target, 0, context) == SUCCESS); + php_stream_error_operation_end(context); } /* }}} */ @@ -1450,7 +1523,6 @@ PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_ case -1: /* non-statable stream */ goto safe_to_copy; - break; case 0: break; default: /* failed to stat file, does not exist? */ @@ -1465,7 +1537,6 @@ PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_ case -1: /* non-statable stream */ goto safe_to_copy; - break; case 0: break; default: /* failed to stat file, does not exist? */ @@ -1547,7 +1618,9 @@ PHPAPI PHP_FUNCTION(fread) RETURN_THROWS(); } + php_stream_error_operation_begin(); str = php_stream_read_to_str(stream, len); + php_stream_error_operation_end_for_stream(stream); if (!str) { RETURN_FALSE; } @@ -1666,7 +1739,9 @@ PHP_FUNCTION(fputcsv) RETURN_THROWS(); } + php_stream_error_operation_begin(); ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char, eol_str); + php_stream_error_operation_end_for_stream(stream); if (ret < 0) { RETURN_FALSE; } @@ -1799,19 +1874,23 @@ PHP_FUNCTION(fgetcsv) RETURN_THROWS(); } + php_stream_error_operation_begin(); if (len < 0) { if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) { + php_stream_error_operation_end_for_stream(stream); RETURN_FALSE; } } else { buf = emalloc(len + 1); if (php_stream_get_line(stream, buf, len + 1, &buf_len) == NULL) { efree(buf); + php_stream_error_operation_end_for_stream(stream); RETURN_FALSE; } } HashTable *values = php_fgetcsv(stream, delimiter, enclosure, escape_char, buf_len, buf); + php_stream_error_operation_end_for_stream(stream); if (values == NULL) { values = php_bc_fgetcsv_empty_line(); } @@ -1864,7 +1943,7 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); if (inc_len == 1) { char *tmp = bptr; - while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) { + while ((*tmp != delimiter) && isspace((unsigned char)*tmp)) { tmp++; } if (*tmp == enclosure && tmp < limit) { @@ -2148,18 +2227,14 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) switch (ch) { case '<': return TOK_OPENTAG; - break; case '>': return TOK_CLOSETAG; - break; case '=': return TOK_EQUAL; - break; case '/': return TOK_SLASH; - break; case '\'': case '"': @@ -2186,7 +2261,6 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) } return TOK_STRING; - break; case '\n': case '\r': @@ -2195,7 +2269,6 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) case ' ': return TOK_SPACE; - break; default: if (isalnum(ch)) { diff --git a/ext/standard/file.h b/ext/standard/file.h index f8faebd02829..9ba5f5b8b93d 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -34,6 +32,7 @@ PHPAPI PHP_FUNCTION(ftell); PHPAPI PHP_FUNCTION(fseek); PHPAPI PHP_FUNCTION(fpassthru); +PHP_MINIT_FUNCTION(stream_errors); PHP_MINIT_FUNCTION(user_streams); PHPAPI zend_result php_copy_file(const char *src, const char *dest); @@ -94,13 +93,14 @@ typedef struct { size_t def_chunk_size; bool auto_detect_line_endings; zend_long default_socket_timeout; - char *user_agent; /* for the http wrapper */ - char *from_address; /* for the ftp and http wrappers */ + zend_string *user_agent; /* for the http wrapper */ + zend_string *from_address; /* for the ftp and http wrappers */ const char *user_stream_current_filename; /* for simple recursion protection */ php_stream_context *default_context; HashTable *stream_wrappers; /* per-request copy of url_stream_wrappers_hash */ HashTable *stream_filters; /* per-request copy of stream_filters_hash */ - HashTable *wrapper_errors; /* key: wrapper address; value: linked list of char* */ + HashTable *wrapper_logged_errors; /* key: wrapper address; value: linked list of error entries */ + php_stream_error_state stream_error_state; int pclose_wait; #ifdef HAVE_GETHOSTBYNAME_R struct hostent tmp_host_info; diff --git a/ext/standard/file.stub.php b/ext/standard/file.stub.php index 5e12c43f397c..d7b1fef17cdc 100644 --- a/ext/standard/file.stub.php +++ b/ext/standard/file.stub.php @@ -256,6 +256,23 @@ */ const STREAM_CRYPTO_PROTO_TLSv1_3 = UNKNOWN; +/** + * @var int + * @cvalue STREAM_CRYPTO_STATUS_NONE + */ +const STREAM_CRYPTO_STATUS_NONE = UNKNOWN; +/** + * @var int + * @cvalue STREAM_CRYPTO_STATUS_WANT_READ + */ +const STREAM_CRYPTO_STATUS_WANT_READ = UNKNOWN; +/** + * @var int + * @cvalue STREAM_CRYPTO_STATUS_WANT_WRITE + */ +const STREAM_CRYPTO_STATUS_WANT_WRITE = UNKNOWN; + + /** * @var int * @cvalue STREAM_SHUT_RD diff --git a/ext/standard/file_arginfo.h b/ext/standard/file_arginfo.h index b3888925ee9a..24e3722cd86e 100644 --- a/ext/standard/file_arginfo.h +++ b/ext/standard/file_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit file.stub.php instead. - * Stub hash: c394e14cd32587ce9ad0503e21c6c4cf5b301697 */ + * Stub hash: 0c62c6fb217a87010a9e2e63d4b104cde0138655 */ static void register_file_symbols(int module_number) { @@ -52,6 +52,9 @@ static void register_file_symbols(int module_number) REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_1", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_2", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_3", STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_STATUS_NONE", STREAM_CRYPTO_STATUS_NONE, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_STATUS_WANT_READ", STREAM_CRYPTO_STATUS_WANT_READ, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_STATUS_WANT_WRITE", STREAM_CRYPTO_STATUS_WANT_WRITE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR", STREAM_SHUT_RDWR, CONST_PERSISTENT); diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 85c2517ed91a..f7bda3c66bab 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -56,11 +54,7 @@ #endif #ifdef HAVE_PWD_H -# ifdef PHP_WIN32 -# include "win32/pwd.h" -# else -# include -# endif +# include #endif #ifdef HAVE_GRP_H @@ -774,22 +768,18 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) #ifdef F_OK case FS_EXISTS: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, F_OK) == 0); - break; #endif #ifdef W_OK case FS_IS_W: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, W_OK) == 0); - break; #endif #ifdef R_OK case FS_IS_R: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, R_OK) == 0); - break; #endif #ifdef X_OK case FS_IS_X: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, X_OK) == 0); - break; #endif } } diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 0faa0eda6863..1874ed183ceb 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: | | Wez Furlong (wez@thebrainroom.com) | @@ -59,12 +57,14 @@ static php_stream_filter_status_t strfilter_rot13_filter( static const php_stream_filter_ops strfilter_rot13_ops = { strfilter_rot13_filter, NULL, + NULL, "string.rot13" }; -static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory strfilter_rot13_factory = { @@ -135,23 +135,27 @@ static php_stream_filter_status_t strfilter_tolower_filter( static const php_stream_filter_ops strfilter_toupper_ops = { strfilter_toupper_filter, NULL, + NULL, "string.toupper" }; static const php_stream_filter_ops strfilter_tolower_ops = { strfilter_tolower_filter, NULL, + NULL, "string.tolower" }; -static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } -static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory strfilter_toupper_factory = { @@ -181,14 +185,17 @@ typedef struct _php_conv php_conv; typedef php_conv_err_t (*php_conv_convert_func)(php_conv *, const char **, size_t *, char **, size_t *); typedef void (*php_conv_dtor_func)(php_conv *); +typedef php_conv_err_t (*php_conv_reset_func)(php_conv *); struct _php_conv { php_conv_convert_func convert_op; php_conv_dtor_func dtor; + php_conv_reset_func reset_op; }; #define php_conv_convert(a, b, c, d, e) ((php_conv *)(a))->convert_op((php_conv *)(a), (b), (c), (d), (e)) #define php_conv_dtor(a) ((php_conv *)a)->dtor((a)) +#define php_conv_reset(a) (((php_conv *)(a))->reset_op ? ((php_conv *)(a))->reset_op((php_conv *)(a)) : PHP_CONV_ERR_SUCCESS) /* {{{ php_conv_base64_encode */ typedef struct _php_conv_base64_encode { @@ -206,6 +213,7 @@ typedef struct _php_conv_base64_encode { static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left); static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst); +static php_conv_err_t php_conv_base64_encode_reset(php_conv_base64_encode *inst); static const unsigned char b64_tbl_enc[256] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', @@ -226,10 +234,19 @@ static const unsigned char b64_tbl_enc[256] = { 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; +static php_conv_err_t php_conv_base64_encode_reset(php_conv_base64_encode *inst) +{ + /* Reset only mutable state, preserve configuration (lbchars, line_len, etc.) */ + inst->erem_len = 0; + inst->line_ccnt = inst->line_len; + return PHP_CONV_ERR_SUCCESS; +} + static php_conv_err_t php_conv_base64_encode_ctor(php_conv_base64_encode *inst, unsigned int line_len, const char *lbchars, size_t lbchars_len, int lbchars_dup, bool persistent) { inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_encode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_encode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_base64_encode_reset; inst->erem_len = 0; inst->line_ccnt = line_len; inst->line_len = line_len; @@ -449,6 +466,7 @@ typedef struct _php_conv_base64_decode { static php_conv_err_t php_conv_base64_decode_convert(php_conv_base64_decode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left); static void php_conv_base64_decode_dtor(php_conv_base64_decode *inst); +static php_conv_err_t php_conv_base64_decode_reset(php_conv_base64_decode *inst); static unsigned int b64_tbl_dec[256] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -469,10 +487,21 @@ static unsigned int b64_tbl_dec[256] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; +static php_conv_err_t php_conv_base64_decode_reset(php_conv_base64_decode *inst) +{ + /* Reset only mutable state */ + inst->urem = 0; + inst->urem_nbits = 0; + inst->ustat = 0; + inst->eos = 0; + return PHP_CONV_ERR_SUCCESS; +} + static void php_conv_base64_decode_ctor(php_conv_base64_decode *inst) { inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_decode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_decode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_base64_decode_reset; inst->urem = 0; inst->urem_nbits = 0; @@ -618,6 +647,7 @@ typedef struct _php_conv_qprint_encode { static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst); static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p); +static php_conv_err_t php_conv_qprint_encode_reset(php_conv_qprint_encode *inst); static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst) { @@ -627,6 +657,15 @@ static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst) } } +static php_conv_err_t php_conv_qprint_encode_reset(php_conv_qprint_encode *inst) +{ + /* Reset only mutable state, preserve configuration */ + inst->line_ccnt = inst->line_len; + inst->lb_ptr = 0; + inst->lb_cnt = 0; + return PHP_CONV_ERR_SUCCESS; +} + #define NEXT_CHAR(ps, icnt, lb_ptr, lb_cnt, lbchars) \ ((lb_ptr) < (lb_cnt) ? (lbchars)[(lb_ptr)] : *(ps)) @@ -832,6 +871,7 @@ static php_conv_err_t php_conv_qprint_encode_ctor(php_conv_qprint_encode *inst, } inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_encode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_encode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_qprint_encode_reset; inst->line_ccnt = line_len; inst->line_len = line_len; if (lbchars != NULL) { @@ -862,6 +902,10 @@ typedef struct _php_conv_qprint_decode { unsigned int lb_cnt; } php_conv_qprint_decode; +static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst); +static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p); +static php_conv_err_t php_conv_qprint_decode_reset(php_conv_qprint_decode *inst); + static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst) { assert(inst != NULL); @@ -870,6 +914,16 @@ static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst) } } +static php_conv_err_t php_conv_qprint_decode_reset(php_conv_qprint_decode *inst) +{ + /* Reset only mutable state, preserve configuration */ + inst->scan_stat = 0; + inst->next_char = 0; + inst->lb_ptr = 0; + inst->lb_cnt = 0; + return PHP_CONV_ERR_SUCCESS; +} + static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p) { php_conv_err_t err = PHP_CONV_ERR_SUCCESS; @@ -949,7 +1003,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins goto out; } - if (!isxdigit((int) *ps)) { + if (!isxdigit(*ps)) { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } @@ -1040,10 +1094,12 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins return err; } + static php_conv_err_t php_conv_qprint_decode_ctor(php_conv_qprint_decode *inst, const char *lbchars, size_t lbchars_len, int lbchars_dup, bool persistent) { inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_decode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_decode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_qprint_decode_reset; inst->scan_stat = 0; inst->next_char = 0; inst->lb_ptr = inst->lb_cnt = 0; @@ -1519,7 +1575,7 @@ static php_stream_filter_status_t strfilter_convert_filter( php_stream_bucket_delref(bucket); } - if (flags != PSFS_FLAG_NORMAL) { + if (flags & PSFS_FLAG_FLUSH_CLOSE) { if (strfilter_convert_append_bucket(inst, stream, thisfilter, buckets_out, NULL, 0, &consumed, php_stream_is_persistent(stream)) != SUCCESS) { @@ -1540,6 +1596,29 @@ static php_stream_filter_status_t strfilter_convert_filter( return PSFS_ERR_FATAL; } +static zend_result strfilter_convert_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_convert_filter *inst = (php_convert_filter *)Z_PTR(thisfilter->abstract); + + /* Reset stub buffer */ + inst->stub_len = 0; + + /* Reset the converter state - preserves all configuration/options */ + if (inst->cd != NULL) { + php_conv_err_t err = php_conv_reset(inst->cd); + if (err != PHP_CONV_ERR_SUCCESS) { + return FAILURE; + } + } + + return SUCCESS; +} + static void strfilter_convert_dtor(php_stream_filter *thisfilter) { assert(Z_PTR(thisfilter->abstract) != NULL); @@ -1550,14 +1629,15 @@ static void strfilter_convert_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops strfilter_convert_ops = { strfilter_convert_filter, + strfilter_convert_seek, strfilter_convert_dtor, "convert.*" }; -static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, bool persistent) { php_convert_filter *inst; - + php_stream_filter_seekable_t write_seekable; const char *dot; int conv_mode = 0; @@ -1571,6 +1651,10 @@ static php_stream_filter *strfilter_convert_create(const char *filtername, zval } ++dot; + if (php_stream_filter_parse_write_seek_mode(filterparams, &write_seekable) == FAILURE) { + return NULL; + } + inst = pemalloc(sizeof(php_convert_filter), persistent); if (strcasecmp(dot, "base64-encode") == 0) { @@ -1590,7 +1674,7 @@ static php_stream_filter *strfilter_convert_create(const char *filtername, zval return NULL; } - return php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent); + return php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent, PSFS_SEEKABLE_START, write_seekable); } static const php_stream_filter_factory strfilter_convert_factory = { @@ -1637,6 +1721,22 @@ static php_stream_filter_status_t consumed_filter_filter( return PSFS_PASS_ON; } +static zend_result consumed_filter_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_consumed_filter_data *data = (php_consumed_filter_data *)Z_PTR(thisfilter->abstract); + + /* Reset consumed state */ + data->consumed = 0; + data->offset = ~0; + + return SUCCESS; +} + static void consumed_filter_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -1647,11 +1747,12 @@ static void consumed_filter_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops consumed_filter_ops = { consumed_filter_filter, + consumed_filter_seek, consumed_filter_dtor, "consumed" }; -static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, bool persistent) { const php_stream_filter_ops *fops = NULL; php_consumed_filter_data *data; @@ -1667,7 +1768,7 @@ static php_stream_filter *consumed_filter_create(const char *filtername, zval *f data->offset = ~0; fops = &consumed_filter_ops; - return php_stream_filter_alloc(fops, data, persistent); + return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory consumed_filter_factory = { @@ -1709,12 +1810,14 @@ static size_t php_dechunk(char *buf, size_t len, php_chunked_filter_data *data) data->chunk_size = 0; case CHUNK_SIZE: while (p < end) { + size_t digit; + if (*p >= '0' && *p <= '9') { - data->chunk_size = (data->chunk_size * 16) + (*p - '0'); + digit = *p - '0'; } else if (*p >= 'A' && *p <= 'F') { - data->chunk_size = (data->chunk_size * 16) + (*p - 'A' + 10); + digit = *p - 'A' + 10; } else if (*p >= 'a' && *p <= 'f') { - data->chunk_size = (data->chunk_size * 16) + (*p - 'a' + 10); + digit = *p - 'a' + 10; } else if (data->state == CHUNK_SIZE_START) { data->state = CHUNK_ERROR; break; @@ -1722,6 +1825,11 @@ static size_t php_dechunk(char *buf, size_t len, php_chunked_filter_data *data) data->state = CHUNK_SIZE_EXT; break; } + if (data->chunk_size > (SIZE_MAX / 16)) { + data->state = CHUNK_ERROR; + break; + } + data->chunk_size = (data->chunk_size * 16) + digit; data->state = CHUNK_SIZE; p++; } @@ -1851,6 +1959,22 @@ static php_stream_filter_status_t php_chunked_filter( return PSFS_PASS_ON; } +static zend_result php_chunked_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_chunked_filter_data *data = (php_chunked_filter_data *)Z_PTR(thisfilter->abstract); + + /* Reset chunked decoder state */ + data->state = CHUNK_SIZE_START; + data->chunk_size = 0; + + return SUCCESS; +} + static void php_chunked_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -1861,11 +1985,12 @@ static void php_chunked_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops chunked_filter_ops = { php_chunked_filter, + php_chunked_seek, php_chunked_dtor, "dechunk" }; -static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, bool persistent) { const php_stream_filter_ops *fops = NULL; php_chunked_filter_data *data; @@ -1881,7 +2006,7 @@ static php_stream_filter *chunked_filter_create(const char *filtername, zval *fi data->persistent = persistent; fops = &chunked_filter_ops; - return php_stream_filter_alloc(fops, data, persistent); + return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory chunked_filter_factory = { diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index b7e1df7cbc98..6967c4358901 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index af0739bf1528..cfb6d82ba085 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index b0fbfcc89099..f35d196fb971 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Author: Stig S�ther Bakken | + | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ */ @@ -376,7 +374,7 @@ php_sprintf_getnumber(char **buffer, size_t *len) int php_sprintf_get_argnum(char **format, size_t *format_len) { char *temppos = *format; - while (isdigit((int) *temppos)) temppos++; + while (isdigit((unsigned char)*temppos)) temppos++; if (*temppos != '$') { return ARG_NUM_NEXT; } @@ -468,7 +466,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%zu\n", *format, format - format_orig)); - if (isalpha((int)*format)) { + if (isalpha((unsigned char)*format)) { width = precision = 0; argnum = ARG_NUM_NEXT; } else { @@ -537,7 +535,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n } width = Z_LVAL_P(tmp); adjusting |= ADJ_WIDTH; - } else if (isdigit((int)*format)) { + } else if (isdigit((unsigned char)*format)) { PRINTF_DEBUG(("sprintf: getting width\n")); if ((width = php_sprintf_getnumber(&format, &format_len)) < 0) { zend_value_error("Width must be between 0 and %d", INT_MAX); @@ -582,7 +580,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n precision = Z_LVAL_P(tmp); adjusting |= ADJ_PRECISION; expprec = 1; - } else if (isdigit((int)*format)) { + } else if (isdigit((unsigned char)*format)) { if ((precision = php_sprintf_getnumber(&format, &format_len)) < 0) { zend_value_error("Precision must be between 0 and %d", INT_MAX); goto fail; diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 2b9e00a57554..e1a8c1868b93 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Paul Panotzki - Bunyip Information Systems | | Jim Winstead | @@ -22,6 +20,7 @@ #include #include "php_network.h" #include "file.h" +#include "streams/php_streams_int.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) @@ -84,8 +83,9 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) } if (persistent) { - php_fsockopen_format_host_port(&hashkey, "pfsockopen__", strlen("pfsockopen__"), host, - host_len, port); + zend_string *escaped = php_stream_escape_persistent_key(host, host_len); + spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, ZSTR_VAL(escaped), port); + zend_string_release_ex(escaped, false); } if (port > 0) { diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h index 3789a01b7ea0..849d5052238c 100644 --- a/ext/standard/fsock.h +++ b/ext/standard/fsock.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Paul Panotzki - Bunyip Information Systems | | Jim Winstead | diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 98715b2ee8a0..7f8702adbf84 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrew Sitnikov | +----------------------------------------------------------------------+ diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 92200e64f238..2597269bad41 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -32,10 +30,6 @@ #ifdef PHP_WIN32 #include -#define O_RDONLY _O_RDONLY -#include "win32/param.h" -#else -#include #endif #include "php_standard.h" @@ -79,8 +73,8 @@ static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer { buffer[0] = '\0'; /* in case read fails to read anything */ while (php_stream_gets(stream, buffer, buffer_size-1) && - !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) && - isdigit((int) buffer[2]) && buffer[3] == ' ')); + !(isdigit((unsigned char)buffer[0]) && isdigit((unsigned char)buffer[1]) && + isdigit((unsigned char)buffer[2]) && buffer[3] == ' ')); return strtol(buffer, NULL, 10); } /* }}} */ @@ -108,7 +102,9 @@ static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream * /* For write modes close data stream first to signal EOF to server */ result = GET_FTP_RESULT(controlstream); if (result != 226 && result != 250) { - php_error_docref(NULL, E_WARNING, "FTP server error %d:%s", result, tmp_line); + php_stream_wrapper_warn(wrapper, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + ProtocolError, + "FTP server error %d:%s", result, tmp_line); ret = EOF; } } @@ -186,7 +182,8 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char /* get the response */ result = GET_FTP_RESULT(stream); if (result != 334) { - php_stream_wrapper_log_error(wrapper, options, "Server doesn't support FTPS."); + php_stream_wrapper_log_warn(wrapper, context, options, SslNotSupported, + "Server doesn't support FTPS."); goto connect_errexit; } else { /* we must reuse the old SSL session id */ @@ -205,7 +202,8 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL) < 0 || php_stream_xport_crypto_enable(stream, 1) < 0) { - php_stream_wrapper_log_error(wrapper, options, "Unable to activate SSL mode"); + php_stream_wrapper_log_warn(wrapper, context, options, SslNotSupported, + "Unable to activate SSL mode"); php_stream_close(stream); stream = NULL; goto connect_errexit; @@ -235,8 +233,8 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char #define PHP_FTP_CNTRL_CHK(val, val_len, err_msg) { \ unsigned char *s = (unsigned char *) val, *e = (unsigned char *) s + val_len; \ while (s < e) { \ - if (iscntrl(*s)) { \ - php_stream_wrapper_log_error(wrapper, options, err_msg, val); \ + if (iscntrl((unsigned char)*s)) { \ + php_stream_wrapper_log_warn(wrapper, context, options, AuthFailed, err_msg, val); \ goto connect_errexit; \ } \ s++; \ @@ -271,7 +269,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char /* if the user has configured who they are, send that as the password */ if (FG(from_address)) { - php_stream_printf(stream, "PASS %s\r\n", FG(from_address)); + php_stream_printf(stream, "PASS %s\r\n", ZSTR_VAL(FG(from_address))); } else { php_stream_write_string(stream, "PASS anonymous\r\n"); } @@ -344,14 +342,14 @@ static unsigned short php_fopen_do_pasv(php_stream *stream, char *ip, size_t ip_ /* parse pasv command (129, 80, 95, 25, 13, 221) */ tpath = tmp_line; /* skip over the "227 Some message " part */ - for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); + for (tpath += 4; *tpath && !isdigit((unsigned char)*tpath); tpath++); if (!*tpath) { return 0; } /* skip over the host ip, to get the port */ hoststart = tpath; for (i = 0; i < 4; i++) { - for (; isdigit((int) *tpath); tpath++); + for (; isdigit((unsigned char)*tpath); tpath++); if (*tpath != ',') { return 0; } @@ -433,7 +431,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa } if (strpbrk(mode, "wa+")) { if (read_write) { - php_stream_wrapper_log_error(wrapper, options, "FTP does not support simultaneous read/write connections"); + php_stream_wrapper_log_warn(wrapper, context, options, ModeNotSupported, + "FTP does not support simultaneous read/write connections"); return NULL; } if (strchr(mode, 'a')) { @@ -444,7 +443,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa } if (!read_write) { /* No mode specified? */ - php_stream_wrapper_log_error(wrapper, options, "Unknown file open mode"); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidMode, + "Unknown file open mode"); return NULL; } @@ -455,7 +455,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa return php_stream_url_wrap_http(wrapper, path, mode, options, opened_path, context STREAMS_CC); } else { /* ftp proxy is read-only */ - php_stream_wrapper_log_error(wrapper, options, "FTP proxy may only be used in read mode"); + php_stream_wrapper_log_warn(wrapper, context, options, ModeNotSupported, + "FTP proxy may only be used in read mode"); return NULL; } } @@ -507,7 +508,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa goto errexit; } } else { - php_stream_wrapper_log_error(wrapper, options, "Remote file already exists and overwrite context option not specified"); + php_stream_wrapper_log_warn(wrapper, context, options, AlreadyExists, + "Remote file already exists and overwrite context option not specified"); errno = EEXIST; goto errexit; } @@ -531,7 +533,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa php_stream_printf(stream, "REST " ZEND_LONG_FMT "\r\n", Z_LVAL_P(tmpzval)); result = GET_FTP_RESULT(stream); if (result < 300 || result > 399) { - php_stream_wrapper_log_error(wrapper, options, "Unable to resume from offset " ZEND_LONG_FMT, Z_LVAL_P(tmpzval)); + php_stream_wrapper_log_warn(wrapper, context, options, ResumptionFailed, + "Unable to resume from offset " ZEND_LONG_FMT, Z_LVAL_P(tmpzval)); goto errexit; } } @@ -576,7 +579,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL) < 0 || php_stream_xport_crypto_enable(datastream, 1) < 0)) { - php_stream_wrapper_log_error(wrapper, options, "Unable to activate SSL mode"); + php_stream_wrapper_log_warn(wrapper, context, options, SslNotSupported, + "Unable to activate SSL mode"); php_stream_close(datastream); datastream = NULL; tmp_line[0]='\0'; @@ -598,10 +602,12 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa php_stream_close(stream); } if (tmp_line[0] != '\0') - php_stream_wrapper_log_error(wrapper, options, "FTP server reports %s", tmp_line); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "FTP server reports %s", tmp_line); if (error_message) { - php_stream_wrapper_log_error(wrapper, options, "Failed to set up data channel: %s", ZSTR_VAL(error_message)); + php_stream_wrapper_log_warn(wrapper, context, options, NetworkSendFailed, + "Failed to set up data channel: %s", ZSTR_VAL(error_message)); zend_string_release(error_message); } return NULL; @@ -632,9 +638,9 @@ static ssize_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t coun basename = php_basename(ent->d_name, tmp_len, NULL, 0); - tmp_len = MIN(sizeof(ent->d_name), ZSTR_LEN(basename) - 1); + tmp_len = MIN(sizeof(ent->d_name) - 1, ZSTR_LEN(basename)); memcpy(ent->d_name, ZSTR_VAL(basename), tmp_len); - ent->d_name[tmp_len - 1] = '\0'; + ent->d_name[tmp_len] = '\0'; zend_string_release_ex(basename, 0); ent->d_type = DT_UNKNOWN; @@ -746,7 +752,8 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL) < 0 || php_stream_xport_crypto_enable(datastream, 1) < 0)) { - php_stream_wrapper_log_error(wrapper, options, "Unable to activate SSL mode"); + php_stream_wrapper_log_warn(wrapper, context, options, SslNotSupported, + "Unable to activate SSL mode"); php_stream_close(datastream); datastream = NULL; goto opendir_errexit; @@ -770,7 +777,8 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch php_stream_close(stream); } if (tmp_line[0] != '\0') { - php_stream_wrapper_log_error(wrapper, options, "FTP server reports %s", tmp_line); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "FTP server reports %s", tmp_line); } return NULL; } @@ -832,7 +840,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, struct tm tm, tmbuf, *gmt; time_t stamp; - while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit(*p)) { + while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit((unsigned char)*p)) { p++; } @@ -909,14 +917,16 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i stream = php_ftp_fopen_connect(wrapper, url, "r", 0, NULL, context, NULL, &resource, NULL, NULL); if (!stream) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Unable to connect to %s", url); + php_stream_wrapper_warn(wrapper, context, options, AuthFailed, + "Unable to connect to %s", url); } goto unlink_errexit; } if (resource->path == NULL) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Invalid path provided in %s", url); + php_stream_wrapper_warn(wrapper, context, options, InvalidPath, + "Invalid path provided in %s", url); } goto unlink_errexit; } @@ -927,7 +937,8 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Error Deleting file: %s", tmp_line); + php_stream_wrapper_warn(wrapper, context, options, UnlinkFailed, + "Error Deleting file: %s", tmp_line); } goto unlink_errexit; } @@ -991,7 +1002,8 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr stream = php_ftp_fopen_connect(wrapper, url_from, "r", 0, NULL, context, NULL, NULL, NULL, NULL); if (!stream) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Unable to connect to %s", ZSTR_VAL(resource_from->host)); + php_stream_wrapper_warn(wrapper, context, options, AuthFailed, + "Unable to connect to %s", ZSTR_VAL(resource_from->host)); } goto rename_errexit; } @@ -1002,7 +1014,8 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr result = GET_FTP_RESULT(stream); if (result < 300 || result > 399) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Error Renaming file: %s", tmp_line); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "Error Renaming file: %s", tmp_line); } goto rename_errexit; } @@ -1013,7 +1026,8 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Error Renaming file: %s", tmp_line); + php_stream_wrapper_warn(wrapper, context, options, RenameFailed, + "Error Renaming file: %s", tmp_line); } goto rename_errexit; } @@ -1046,14 +1060,16 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in stream = php_ftp_fopen_connect(wrapper, url, "r", 0, NULL, context, NULL, &resource, NULL, NULL); if (!stream) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Unable to connect to %s", url); + php_stream_wrapper_warn(wrapper, context, options, AuthFailed, + "Unable to connect to %s", url); } goto mkdir_errexit; } if (resource->path == NULL) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Invalid path provided in %s", url); + php_stream_wrapper_warn(wrapper, context, options, InvalidPath, + "Invalid path provided in %s", url); } goto mkdir_errexit; } @@ -1094,7 +1110,8 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", tmp_line); + php_stream_wrapper_warn(wrapper, context, options, MkdirFailed, + "%s", tmp_line); } break; } @@ -1138,14 +1155,16 @@ static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, const char *url, in stream = php_ftp_fopen_connect(wrapper, url, "r", 0, NULL, context, NULL, &resource, NULL, NULL); if (!stream) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Unable to connect to %s", url); + php_stream_wrapper_warn(wrapper, context, options, AuthFailed, + "Unable to connect to %s", url); } goto rmdir_errexit; } if (resource->path == NULL) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Invalid path provided in %s", url); + php_stream_wrapper_warn(wrapper, context, options, InvalidPath, + "Invalid path provided in %s", url); } goto rmdir_errexit; } @@ -1155,7 +1174,8 @@ static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, const char *url, in if (result < 200 || result > 299) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", tmp_line); + php_stream_wrapper_warn(wrapper, context, options, RmdirFailed, + "%s", tmp_line); } goto rmdir_errexit; } diff --git a/ext/standard/head.c b/ext/standard/head.c index 797d8d66c56a..34a22327b5e7 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -76,6 +74,13 @@ PHPAPI bool php_header(void) } } +PHPAPI bool php_is_valid_samesite_value(zend_string *value) +{ + return zend_string_equals_literal_ci(value, "Strict") + || zend_string_equals_literal_ci(value, "Lax") + || zend_string_equals_literal_ci(value, "None"); +} + #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", or \"\\014\"" PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, bool secure, bool httponly, @@ -123,7 +128,11 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e return FAILURE; } - /* Should check value of SameSite? */ + if (samesite && ZSTR_LEN(samesite) > 0 && !php_is_valid_samesite_value(samesite)) { + zend_value_error("%s(): \"samesite\" option must be \"Strict\", \"Lax\", \"None\", or \"\"", + get_active_function_name()); + return FAILURE; + } if (value == NULL || ZSTR_LEN(value) == 0) { /* @@ -209,14 +218,23 @@ static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_ if (zend_string_equals_literal_ci(key, "expires")) { *expires = zval_get_long(value); } else if (zend_string_equals_literal_ci(key, "path")) { + if (*path) { + zend_string_release(*path); + } *path = zval_get_string(value); } else if (zend_string_equals_literal_ci(key, "domain")) { + if (*domain) { + zend_string_release(*domain); + } *domain = zval_get_string(value); } else if (zend_string_equals_literal_ci(key, "secure")) { *secure = zend_is_true(value); } else if (zend_string_equals_literal_ci(key, "httponly")) { *httponly = zend_is_true(value); } else if (zend_string_equals_literal_ci(key, "samesite")) { + if (*samesite) { + zend_string_release(*samesite); + } *samesite = zval_get_string(value); } else if (zend_string_equals_literal_ci(key, "partitioned")) { *partitioned = zend_is_true(value); @@ -296,14 +314,15 @@ PHP_FUNCTION(setrawcookie) /* {{{ Returns true if headers have already been sent, false otherwise */ PHP_FUNCTION(headers_sent) { - zval *arg1 = NULL, *arg2 = NULL; - const char *file=""; - int line=0; + zval *by_ref_filename = NULL; + zval *by_ref_line = NULL; + const char *file = ""; + int line = 0; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(arg1) - Z_PARAM_ZVAL(arg2) + Z_PARAM_ZVAL(by_ref_filename) + Z_PARAM_ZVAL(by_ref_line) ZEND_PARSE_PARAMETERS_END(); if (SG(headers_sent)) { @@ -311,17 +330,15 @@ PHP_FUNCTION(headers_sent) file = php_output_get_start_filename(); } - switch(ZEND_NUM_ARGS()) { - case 2: - ZEND_TRY_ASSIGN_REF_LONG(arg2, line); - ZEND_FALLTHROUGH; - case 1: + if (by_ref_filename) { if (file) { - ZEND_TRY_ASSIGN_REF_STRING(arg1, file); + ZEND_TRY_ASSIGN_REF_STRING(by_ref_filename, file); } else { - ZEND_TRY_ASSIGN_REF_EMPTY_STRING(arg1); + ZEND_TRY_ASSIGN_REF_EMPTY_STRING(by_ref_filename); } - break; + } + if (by_ref_line) { + ZEND_TRY_ASSIGN_REF_LONG(by_ref_line, line); } RETURN_BOOL(SG(headers_sent)); diff --git a/ext/standard/head.h b/ext/standard/head.h index 0272fec2dc21..8b91371a46e2 100644 --- a/ext/standard/head.h +++ b/ext/standard/head.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -26,6 +24,8 @@ #define COOKIE_SAMESITE "; SameSite=" #define COOKIE_PARTITIONED "; Partitioned" +PHPAPI bool php_is_valid_samesite_value(zend_string *value); + extern PHP_RINIT_FUNCTION(head); PHPAPI bool php_header(void); diff --git a/ext/standard/hrtime.c b/ext/standard/hrtime.c index 652531bd3ed4..216810b7df1b 100644 --- a/ext/standard/hrtime.c +++ b/ext/standard/hrtime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Niklas Keller | | Author: Anatol Belski | diff --git a/ext/standard/html.c b/ext/standard/html.c index eaba9ddffc1d..1e761c971eda 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jaakko Hyvätti | @@ -678,8 +676,8 @@ static inline zend_result process_numeric_entity(const char **buf, unsigned *cod /* strtol allows whitespace and other stuff in the beginning * we're not interested */ - if ((hexadecimal && !isxdigit(**buf)) || - (!hexadecimal && !isdigit(**buf))) { + if ((hexadecimal && !isxdigit((unsigned char)**buf)) || + (!hexadecimal && !isdigit((unsigned char)**buf))) { return FAILURE; } diff --git a/ext/standard/html.h b/ext/standard/html.h index 40c595ba5d89..8576a5c8b9ce 100644 --- a/ext/standard/html.h +++ b/ext/standard/html.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/html_tables.h b/ext/standard/html_tables.h index 2d17d3fa44be..16f30283fdd4 100644 --- a/ext/standard/html_tables.h +++ b/ext/standard/html_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/html_tables/html_table_gen.php b/ext/standard/html_tables/html_table_gen.php index bc76f6f7e945..a3b2d8807d70 100755 --- a/ext/standard/html_tables/html_table_gen.php +++ b/ext/standard/html_tables/html_table_gen.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -22,15 +20,13 @@ $t = <<. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/http.c b/ext/standard/http.c index 9ce8d5e559a7..d65e7a8acaae 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ @@ -79,7 +77,7 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str, scalar = zend_enum_fetch_case_value(Z_OBJ_P(scalar)); goto try_again; /* All possible types are either handled here or previously */ - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -319,7 +317,7 @@ static zend_result cache_request_parse_body_options(HashTable *options) return FAILURE; } ZEND_HASH_FOREACH_END(); -#undef CACHE_OPTION +#undef CHECK_OPTION return SUCCESS; } diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index b5c06b84a6aa..4b2aa7116a24 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -35,13 +33,6 @@ #include #include -#ifdef PHP_WIN32 -#define O_RDONLY _O_RDONLY -#include "win32/param.h" -#else -#include -#endif - #include "php_standard.h" #ifdef HAVE_SYS_SOCKET_H @@ -245,7 +236,7 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w while (last_header_name < last_header_value) { if (*last_header_name == ' ' || *last_header_name == '\t') { header_info->error = true; - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, InvalidResponse, "HTTP invalid response format (space in header name)!"); zend_string_efree(last_header_line_str); return NULL; @@ -263,7 +254,7 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w } else { /* There is no colon which means invalid response so error. */ header_info->error = true; - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, InvalidResponse, "HTTP invalid response format (no colon in header line)!"); zend_string_efree(last_header_line_str); return NULL; @@ -287,7 +278,7 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w size_t last_header_value_len = strlen(last_header_value); if (last_header_value_len > HTTP_HEADER_MAX_LOCATION_SIZE) { header_info->error = true; - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, InvalidResponse, "HTTP Location header size is over the limit of %d bytes", HTTP_HEADER_MAX_LOCATION_SIZE); zend_string_efree(last_header_line_str); @@ -353,6 +344,23 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w return NULL; } +static inline void smart_str_append_header_value(smart_str *dest, const zend_string *value, const char *header_name) +{ + const char *src = ZSTR_VAL(value); + size_t len = ZSTR_LEN(value); + size_t i = 0; + while (i < len && src[i] != '\r' && src[i] != '\n') { + i++; + } + if (i < len) { + smart_str_appendl(dest, src, i); + php_error_docref(NULL, E_WARNING, + "Header %s value contains newline characters and has been truncated", header_name); + } else { + smart_str_append(dest, value); + } +} + static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context, int redirect_max, int flags, @@ -363,7 +371,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, int use_ssl; int use_proxy = 0; zend_string *tmp = NULL; - char *ua_str = NULL; + zend_string *ua_str = NULL; zval *ua_zval = NULL, *tmpzval = NULL, ssl_proxy_peer_name; int reqok = 0; char *http_header_line = NULL; @@ -388,7 +396,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, tmp_line[0] = '\0'; if (redirect_max < 1) { - php_stream_wrapper_log_error(wrapper, options, "Redirection limit reached, aborting"); + php_stream_wrapper_log_warn(wrapper, context, options, RedirectLimit, + "Redirection limit reached, aborting"); return NULL; } @@ -421,7 +430,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* Normal http request (possibly with proxy) */ if (strpbrk(mode, "awx+")) { - php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper does not support writeable connections"); + php_stream_wrapper_log_warn(wrapper, context, options, ModeNotSupported, + "HTTP wrapper does not support writeable connections"); php_uri_struct_free(resource); return NULL; } @@ -450,7 +460,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } if (request_fulluri && (strchr(path, '\n') != NULL || strchr(path, '\r') != NULL)) { - php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper full URI path does not allow CR or LF characters"); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "HTTP wrapper full URI path does not allow CR or LF characters"); php_uri_struct_free(resource); zend_string_release(transport_string); return NULL; @@ -465,7 +476,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, #endif if (d > timeoutmax) { - php_stream_wrapper_log_error(wrapper, options, "timeout must be lower than " ZEND_ULONG_FMT, (zend_ulong)timeoutmax); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidParam, + "timeout must be lower than " ZEND_ULONG_FMT, (zend_ulong)timeoutmax); zend_string_release(transport_string); php_uri_struct_free(resource); return NULL; @@ -495,7 +507,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } if (errstr) { - php_stream_wrapper_log_error(wrapper, options, "%s", ZSTR_VAL(errstr)); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "%s", ZSTR_VAL(errstr)); zend_string_release_ex(errstr, 0); errstr = NULL; } @@ -515,7 +528,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1); - smart_str_appends(&header, ZSTR_VAL(resource->host)); + smart_str_append(&header, resource->host); smart_str_appendc(&header, ':'); smart_str_append_unsigned(&header, resource->port); smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1); @@ -546,7 +559,11 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); if (php_stream_write(stream, ZSTR_VAL(header.s), ZSTR_LEN(header.s)) != ZSTR_LEN(header.s)) { - php_stream_wrapper_log_error(wrapper, options, "Cannot connect to HTTPS server through proxy"); + if (reset_ssl_peer_name) { + php_stream_context_unset_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name"); + } + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } @@ -567,16 +584,19 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* enable SSL transport layer */ if (stream) { + php_stream_context *old_context = PHP_STREAM_CONTEXT(stream); + if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL) < 0 || php_stream_xport_crypto_enable(stream, 1) < 0) { - php_stream_wrapper_log_error(wrapper, options, "Cannot connect to HTTPS server through proxy"); + php_stream_wrapper_log_warn(wrapper, context, options, SslNotSupported, + "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } - } - if (reset_ssl_peer_name) { - php_stream_context_unset_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name"); + if (reset_ssl_peer_name) { + php_stream_context_unset_option(old_context, "ssl", "peer_name"); + } } } @@ -630,7 +650,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* file */ if (resource->path && ZSTR_LEN(resource->path)) { - smart_str_appends(&req_buf, ZSTR_VAL(resource->path)); + smart_str_append(&req_buf, resource->path); } else { smart_str_appendc(&req_buf, '/'); } @@ -638,7 +658,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* query string */ if (resource->query) { smart_str_appendc(&req_buf, '?'); - smart_str_appends(&req_buf, ZSTR_VAL(resource->query)); + smart_str_append(&req_buf, resource->query); } } @@ -751,14 +771,14 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, smart_str scratch = {0}; /* decode the strings first */ - php_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user)); + ZSTR_LEN(resource->user) = php_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user)); smart_str_append(&scratch, resource->user); smart_str_appendc(&scratch, ':'); /* Note: password is optional! */ if (resource->password) { - php_url_decode(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password)); + ZSTR_LEN(resource->password) = php_url_decode(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password)); smart_str_append(&scratch, resource->password); } @@ -778,14 +798,14 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* if the user has configured who they are, send a From: line */ if (!(have_header & HTTP_HEADER_FROM) && FG(from_address)) { smart_str_appends(&req_buf, "From: "); - smart_str_appends(&req_buf, FG(from_address)); + smart_str_append_header_value(&req_buf, FG(from_address), "From"); smart_str_appends(&req_buf, "\r\n"); } /* Send Host: header so name-based virtual hosts work */ if ((have_header & HTTP_HEADER_HOST) == 0) { smart_str_appends(&req_buf, "Host: "); - smart_str_appends(&req_buf, ZSTR_VAL(resource->host)); + smart_str_append(&req_buf, resource->host); if ((use_ssl && resource->port != 443 && resource->port != 0) || (!use_ssl && resource->port != 80 && resource->port != 0)) { smart_str_appendc(&req_buf, ':'); @@ -807,29 +827,15 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (context && (ua_zval = php_stream_context_get_option(context, "http", "user_agent")) != NULL && Z_TYPE_P(ua_zval) == IS_STRING) { - ua_str = Z_STRVAL_P(ua_zval); + ua_str = Z_STR_P(ua_zval); } else if (FG(user_agent)) { ua_str = FG(user_agent); } - if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str) { -#define _UA_HEADER "User-Agent: %s\r\n" - char *ua; - size_t ua_len; - - ua_len = sizeof(_UA_HEADER) + strlen(ua_str); - - /* ensure the header is only sent if user_agent is not blank */ - if (ua_len > sizeof(_UA_HEADER)) { - ua = emalloc(ua_len + 1); - if ((ua_len = slprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) { - ua[ua_len] = 0; - smart_str_appendl(&req_buf, ua, ua_len); - } else { - php_error_docref(NULL, E_WARNING, "Cannot construct User-agent header"); - } - efree(ua); - } + if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str && ZSTR_LEN(ua_str)) { + smart_str_appends(&req_buf, "User-Agent: "); + smart_str_append_header_value(&req_buf, ua_str, "User-Agent"); + smart_str_appends(&req_buf, "\r\n"); } if (user_headers) { @@ -865,10 +871,11 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } if (!(have_header & HTTP_HEADER_TYPE)) { smart_str_appends(&req_buf, "Content-Type: application/x-www-form-urlencoded\r\n"); - php_error_docref(NULL, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded"); + php_stream_wrapper_notice(wrapper, context, options, InvalidHeader, + "Content-type not specified assuming application/x-www-form-urlencoded"); } smart_str_appends(&req_buf, "\r\n"); - smart_str_appendl(&req_buf, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval)); + smart_str_append(&req_buf, Z_STR_P(tmpzval)); } else { smart_str_appends(&req_buf, "\r\n"); } @@ -952,7 +959,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } else { php_stream_close(stream); stream = NULL; - php_stream_wrapper_log_error(wrapper, options, "HTTP request failed!"); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "HTTP request failed!"); goto out; } } @@ -970,7 +978,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (http_header_line[1] != '\n') { php_stream_close(stream); stream = NULL; - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, InvalidResponse, "HTTP invalid header name (cannot start with CR character)!"); goto out; } @@ -1001,7 +1009,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (*http_header_line == ' ' || *http_header_line == '\t') { php_stream_close(stream); stream = NULL; - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, InvalidResponse, "HTTP invalid response format (folding header at the start)!"); goto out; } @@ -1097,7 +1105,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, php_uri_struct_free(resource); /* check for invalid redirection URLs */ if ((resource = php_uri_parse_to_struct(uri_parser, new_path, strlen(new_path), PHP_URI_COMPONENT_READ_MODE_RAW, true)) == NULL) { - php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, + "Invalid redirect URL! %s", new_path); efree(new_path); goto out; } @@ -1109,7 +1118,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, s = (unsigned char*)ZSTR_VAL(val); e = s + ZSTR_LEN(val); \ while (s < e) { \ if (iscntrl(*s)) { \ - php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); \ + php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl, \ + "Invalid redirect URL! %s", new_path); \ efree(new_path); \ goto out; \ } \ @@ -1135,7 +1145,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, --redirect_max, new_flags, response_header STREAMS_CC); efree(new_path); } else { - php_stream_wrapper_log_error(wrapper, options, "HTTP request failed! %s", tmp_line); + php_stream_wrapper_log_warn(wrapper, context, options, ProtocolError, + "HTTP request failed! %s", tmp_line); } } out: diff --git a/ext/standard/image.c b/ext/standard/image.c index 08cf8983d029..7ce6767126bf 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | @@ -878,6 +876,9 @@ static struct php_gfxinfo *php_handle_iff(php_stream * stream) return NULL; } if ((size & 1) == 1) { + if (size == INT_MAX) { + return NULL; + } size++; } if (chunkId == 0x424d4844) { /* BMHD chunk */ diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index 228e03fbe863..d794612f429d 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/info.c b/ext/standard/info.c index 952f0f92fe6e..dcb01bc08220 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -1021,35 +1019,78 @@ PHPAPI ZEND_COLD void php_print_info(int flag) if (flag & PHP_INFO_LICENSE) { if (!sapi_module.phpinfo_as_text) { - SECTION("PHP License"); + SECTION("License"); php_info_print_box_start(0); php_info_print("

\n"); - php_info_print("This program is free software; you can redistribute it and/or modify "); - php_info_print("it under the terms of the PHP License as published by the PHP Group "); - php_info_print("and included in the distribution in the file: LICENSE\n"); + php_info_print("PHP is free software. You may redistribute it and/or modify it under the "); + php_info_print("terms of the Modified BSD License (SPDX-License-Identifier: BSD-3-Clause).\n"); php_info_print("

\n"); - php_info_print("

"); - php_info_print("This program is distributed in the hope that it will be useful, "); - php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of "); - php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + php_info_print("

\n"); + php_info_print("Copyright © The PHP Group and Contributors.
\n"); + php_info_print("Copyright © Zend Technologies Ltd., a subsidiary company of Perforce Software, Inc.\n"); php_info_print("

\n"); - php_info_print("

"); - php_info_print("If you did not receive a copy of the PHP license, or have any questions about "); - php_info_print("PHP licensing, please contact license@php.net.\n"); + php_info_print("

\n"); + php_info_print("Redistribution and use in source and binary forms, with or without "); + php_info_print("modification, are permitted provided that the following conditions are met:\n"); + php_info_print("

\n"); + php_info_print("
    \n"); + php_info_print("
  1. Redistributions of source code must retain the above copyright notice, this "); + php_info_print("list of conditions and the following disclaimer.
  2. \n"); + php_info_print("
  3. Redistributions in binary form must reproduce the above copyright notice, "); + php_info_print("this list of conditions and the following disclaimer in the documentation "); + php_info_print("and/or other materials provided with the distribution.
  4. \n"); + php_info_print("
  5. Neither the name of the copyright holder nor the names of its "); + php_info_print("contributors may be used to endorse or promote products derived from "); + php_info_print("this software without specific prior written permission.
  6. \n"); + php_info_print("
\n"); + php_info_print("

\n"); + php_info_print("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" "); + php_info_print("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE "); + php_info_print("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE "); + php_info_print("DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE "); + php_info_print("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL "); + php_info_print("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR "); + php_info_print("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER "); + php_info_print("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, "); + php_info_print("OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "); + php_info_print("OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"); php_info_print("

\n"); php_info_print_box_end(); } else { - php_info_print("\nPHP License\n"); - php_info_print("This program is free software; you can redistribute it and/or modify\n"); - php_info_print("it under the terms of the PHP License as published by the PHP Group\n"); - php_info_print("and included in the distribution in the file: LICENSE\n"); php_info_print("\n"); - php_info_print("This program is distributed in the hope that it will be useful,\n"); - php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); - php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + php_info_print("License\n"); + php_info_print("\n"); + php_info_print("PHP is free software. You may redistribute it and/or modify it under the\n"); + php_info_print("terms of the Modified BSD License (SPDX-License-Identifier: BSD-3-Clause).\n"); + php_info_print("\n"); + php_info_print("Copyright © The PHP Group and Contributors.\n"); + php_info_print("Copyright © Zend Technologies Ltd., a subsidiary company of\n"); + php_info_print(" Perforce Software, Inc.\n"); + php_info_print("\n"); + php_info_print("Redistribution and use in source and binary forms, with or without\n"); + php_info_print("modification, are permitted provided that the following conditions are met:\n"); + php_info_print("\n"); + php_info_print("1. Redistributions of source code must retain the above copyright notice, this\n"); + php_info_print(" list of conditions and the following disclaimer.\n"); + php_info_print("\n"); + php_info_print("2. Redistributions in binary form must reproduce the above copyright notice,\n"); + php_info_print(" this list of conditions and the following disclaimer in the documentation\n"); + php_info_print(" and/or other materials provided with the distribution.\n"); + php_info_print("\n"); + php_info_print("3. Neither the name of the copyright holder nor the names of its\n"); + php_info_print(" contributors may be used to endorse or promote products derived from\n"); + php_info_print(" this software without specific prior written permission.\n"); php_info_print("\n"); - php_info_print("If you did not receive a copy of the PHP license, or have any\n"); - php_info_print("questions about PHP licensing, please contact license@php.net.\n"); + php_info_print("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n"); + php_info_print("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"); + php_info_print("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"); + php_info_print("DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n"); + php_info_print("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"); + php_info_print("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n"); + php_info_print("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n"); + php_info_print("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n"); + php_info_print("OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"); + php_info_print("OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"); } } diff --git a/ext/standard/info.h b/ext/standard/info.h index 380d2b6e042a..6d1603dd8346 100644 --- a/ext/standard/info.h +++ b/ext/standard/info.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/ext/standard/io_poll.c b/ext/standard/io_poll.c new file mode 100644 index 000000000000..ca363c7b37d9 --- /dev/null +++ b/ext/standard/io_poll.c @@ -0,0 +1,949 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "zend_enum.h" +#include "zend_exceptions.h" +#include "php_network.h" +#include "php_poll.h" +#include "io_poll_arginfo.h" +#include "io_poll_decl.h" + +/* Class entries */ +static zend_class_entry *php_io_poll_backend_class_entry; +static zend_class_entry *php_io_poll_event_class_entry; +static zend_class_entry *php_io_poll_context_class_entry; +static zend_class_entry *php_io_poll_watcher_class_entry; +static zend_class_entry *php_io_poll_handle_class_entry; +static zend_class_entry *php_io_exception_class_entry; +static zend_class_entry *php_io_poll_exception_class_entry; +static zend_class_entry *php_io_poll_failed_backend_unavailable_class_entry; +static zend_class_entry *php_io_poll_failed_operation_class_entry; +static zend_class_entry *php_io_poll_failed_context_init_class_entry; +static zend_class_entry *php_io_poll_failed_handle_add_class_entry; +static zend_class_entry *php_io_poll_failed_watcher_mod_class_entry; +static zend_class_entry *php_io_poll_failed_wait_class_entry; +static zend_class_entry *php_io_poll_inactive_watcher_class_entry; +static zend_class_entry *php_io_poll_handle_already_watched_class_entry; +static zend_class_entry *php_io_poll_invalid_handle_class_entry; +static zend_class_entry *php_stream_poll_handle_class_entry; + +/* Object handlers */ +static zend_object_handlers php_io_poll_context_object_handlers; +static zend_object_handlers php_io_poll_watcher_object_handlers; +static zend_object_handlers php_io_poll_handle_object_handlers; + +typedef struct php_io_poll_context_object php_io_poll_context_object; + +/* Watcher object structure */ +typedef struct php_io_poll_watcher_object { + php_poll_handle_object *handle; + uint32_t watched_events; + uint32_t triggered_events; + zval data; + bool active; + php_io_poll_context_object *context; /* Back reference to Context object */ + zend_object std; +} php_io_poll_watcher_object; + +/* Context object structure */ +struct php_io_poll_context_object { + php_poll_ctx *ctx; + HashTable *watchers; /* Maps handle pointer -> watcher object */ + zend_object std; +}; + +/* Stream poll handle specific data */ +typedef struct php_stream_poll_handle_data { + php_stream *stream; + zend_resource *res; +} php_stream_poll_handle_data; + +/* Accessor macros */ +#define PHP_POLL_CONTEXT_OBJ_FROM_ZOBJ(_obj) ZEND_CONTAINER_OF(_obj, php_io_poll_context_object, std) + +#define PHP_POLL_WATCHER_OBJ_FROM_ZOBJ(_obj) ZEND_CONTAINER_OF(_obj, php_io_poll_watcher_object, std) + +#define PHP_POLL_WATCHER_OBJ_FROM_ZV(_zv) PHP_POLL_WATCHER_OBJ_FROM_ZOBJ(Z_OBJ_P(_zv)) +#define PHP_POLL_CONTEXT_OBJ_FROM_ZV(_zv) PHP_POLL_CONTEXT_OBJ_FROM_ZOBJ(Z_OBJ_P(_zv)) + +/* Helper to throw failed operation exceptions with error code */ +static inline void php_io_poll_throw_failed_operation( + zend_class_entry *ce, const char *message, php_poll_error error) +{ + zend_throw_exception(ce, message, (zend_long) error); +} + +/* Event enum to bit mask mapping */ +static uint32_t php_io_poll_event_enum_to_bit(zend_object *event_enum) +{ + return 1 << (zend_enum_fetch_case_id(event_enum) - 1); +} + +static uint32_t php_io_poll_event_enums_to_events(zval *event_enums) +{ + HashTable *ht; + uint32_t events = 0; + + if (Z_TYPE_P(event_enums) != IS_ARRAY) { + return 0; + } + + ht = Z_ARRVAL_P(event_enums); + + ZEND_HASH_FOREACH_VAL(ht, zval *entry) { + if (Z_TYPE_P(entry) != IS_OBJECT + || !instanceof_function(Z_OBJCE_P(entry), php_io_poll_event_class_entry)) { + return 0; + } + events |= php_io_poll_event_enum_to_bit(Z_OBJ_P(entry)); + } + ZEND_HASH_FOREACH_END(); + + return events; +} + +static zend_result php_io_poll_events_to_event_enums(uint32_t events, zval *event_enums) +{ + zval enum_case; + + array_init(event_enums); + + if (events & PHP_POLL_READ) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_Read)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_WRITE) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_Write)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_ERROR) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_Error)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_HUP) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_HangUp)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_RDHUP) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_ReadHangUp)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_ONESHOT) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_OneShot)); + add_next_index_zval(event_enums, &enum_case); + } + if (events & PHP_POLL_ET) { + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_by_id(php_io_poll_event_class_entry, ZEND_ENUM_Io_Poll_Event_EdgeTriggered)); + add_next_index_zval(event_enums, &enum_case); + } + + return SUCCESS; +} + +/* Backend enum name to backend type mapping */ +static php_poll_backend_type php_io_poll_backend_enum_to_type(zend_object *backend_enum) +{ + return zend_enum_fetch_case_id(backend_enum) - 2; +} + +static const char *php_io_poll_backend_type_to_name(php_poll_backend_type type) +{ + switch (type) { + case PHP_POLL_BACKEND_POLL: + return "Poll"; + case PHP_POLL_BACKEND_EPOLL: + return "Epoll"; + case PHP_POLL_BACKEND_KQUEUE: + return "Kqueue"; + case PHP_POLL_BACKEND_EVENTPORT: + return "EventPorts"; + case PHP_POLL_BACKEND_WSAPOLL: + return "WSAPoll"; + case PHP_POLL_BACKEND_AUTO: + default: + return "Auto"; + } +} + +/* Stream Poll Handle Implementation */ + +static php_socket_t php_stream_poll_handle_get_fd(php_poll_handle_object *handle) +{ + php_stream_poll_handle_data *data = handle->handle_data; + php_socket_t fd; + + if (!data || !data->stream) { + return SOCK_ERR; + } + + if (php_stream_cast(data->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, + (void *) &fd, 1) + != SUCCESS + || fd == -1) { + return SOCK_ERR; + } + + return fd; +} + +static int php_stream_poll_handle_is_valid(php_poll_handle_object *handle) +{ + php_stream_poll_handle_data *data = handle->handle_data; + return data && data->stream && !php_stream_eof(data->stream); +} + +static void php_stream_poll_handle_cleanup(php_poll_handle_object *handle) +{ + php_stream_poll_handle_data *data = handle->handle_data; + if (data) { + if (data->res) { + zend_list_delete(data->res); + } + efree(data); + handle->handle_data = NULL; + } +} + +static php_poll_handle_ops php_stream_poll_handle_ops = { + .get_fd = php_stream_poll_handle_get_fd, + .is_valid = php_stream_poll_handle_is_valid, + .cleanup = php_stream_poll_handle_cleanup +}; + +/* Handle interface internal only */ +static int php_stream_poll_handle_implement_interface(zend_class_entry *interface, zend_class_entry *implementor) +{ + if (implementor->type == ZEND_USER_CLASS) { + zend_error_noreturn(E_ERROR, "Io\\Poll\\Handle cannot be implemented by user classes"); + return FAILURE; + } + + return SUCCESS; +} + +/* Object Creation Functions */ + +static zend_object *php_stream_poll_handle_create_object(zend_class_entry *ce) +{ + php_poll_handle_object *intern = php_poll_handle_object_create( + sizeof(php_poll_handle_object), ce, &php_stream_poll_handle_ops); + return &intern->std; +} + +static zend_object *php_io_poll_watcher_create_object(zend_class_entry *ce) +{ + php_io_poll_watcher_object *intern = zend_object_alloc(sizeof(php_io_poll_watcher_object), ce); + + zend_object_std_init(&intern->std, ce); + object_properties_init(&intern->std, ce); + + intern->handle = NULL; + intern->watched_events = 0; + intern->triggered_events = 0; + intern->active = false; + intern->context = NULL; + ZVAL_NULL(&intern->data); + + return &intern->std; +} + +static zend_object *php_io_poll_context_create_object(zend_class_entry *ce) +{ + php_io_poll_context_object *intern = zend_object_alloc(sizeof(php_io_poll_context_object), ce); + + zend_object_std_init(&intern->std, ce); + object_properties_init(&intern->std, ce); + + intern->ctx = NULL; + intern->watchers = NULL; + + return &intern->std; +} + +/* Object Destruction Functions */ + +static void php_io_poll_watcher_free_object(zend_object *obj) +{ + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZOBJ(obj); + + zval_ptr_dtor(&intern->data); + + if (intern->handle) { + OBJ_RELEASE(&intern->handle->std); + } + + zend_object_std_dtor(&intern->std); +} + +static void php_io_poll_context_free_object(zend_object *obj) +{ + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZOBJ(obj); + + if (intern->watchers) { + ZEND_HASH_FOREACH_VAL(intern->watchers, zval *zv) { + php_io_poll_watcher_object *watcher = PHP_POLL_WATCHER_OBJ_FROM_ZOBJ(Z_OBJ_P(zv)); + watcher->active = false; + watcher->context = NULL; + } ZEND_HASH_FOREACH_END(); + } + + if (intern->ctx) { + php_poll_destroy(intern->ctx); + } + + if (intern->watchers) { + zend_hash_destroy(intern->watchers); + efree(intern->watchers); + } + + zend_object_std_dtor(&intern->std); +} + +static HashTable *php_io_poll_watcher_get_gc(zend_object *obj, zval **table, int *n) +{ + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZOBJ(obj); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + + zend_get_gc_buffer_add_zval(gc_buffer, &intern->data); + if (intern->handle) { + zend_get_gc_buffer_add_obj(gc_buffer, &intern->handle->std); + } + + zend_get_gc_buffer_use(gc_buffer, table, n); + return NULL; +} + +static HashTable *php_io_poll_context_get_gc(zend_object *obj, zval **table, int *n) +{ + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZOBJ(obj); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + + if (intern->watchers) { + ZEND_HASH_FOREACH_VAL(intern->watchers, zval *zv) { + zend_get_gc_buffer_add_zval(gc_buffer, zv); + } ZEND_HASH_FOREACH_END(); + } + + zend_get_gc_buffer_use(gc_buffer, table, n); + return NULL; +} + +/* Utility functions */ + +static zend_always_inline zend_ulong php_io_poll_compute_ptr_key(void *ptr) +{ + zend_ulong key = (zend_ulong) (uintptr_t) ptr; + return (key >> 3) | (key << ((sizeof(key) * 8) - 3)); +} + +static zend_result php_io_poll_watcher_modify_events( + php_io_poll_watcher_object *watcher, uint32_t events) +{ + if (!watcher->active || !watcher->context) { + zend_throw_exception( + php_io_poll_inactive_watcher_class_entry, "Cannot modify inactive watcher", 0); + return FAILURE; + } + + php_socket_t fd = php_poll_handle_get_fd(watcher->handle); + if (fd == SOCK_ERR) { + zend_throw_exception( + php_io_poll_invalid_handle_class_entry, "Invalid handle for polling", 0); + return FAILURE; + } + + /* Modify in poll context */ + php_poll_ctx *poll_ctx = watcher->context->ctx; + if (php_poll_modify(poll_ctx, (int) fd, events, watcher) != SUCCESS) { + php_poll_error err = php_poll_get_error(poll_ctx); + php_io_poll_throw_failed_operation(php_io_poll_failed_watcher_mod_class_entry, + "Failed to modify watcher in polling system", err); + return FAILURE; + } + + /* Update watcher state */ + watcher->watched_events = events; + + return SUCCESS; +} + +static zend_result php_io_poll_watcher_modify_data(php_io_poll_watcher_object *watcher, zval *data) +{ + if (!watcher->active) { + zend_throw_exception( + php_io_poll_inactive_watcher_class_entry, "Cannot modify inactive watcher", 0); + return FAILURE; + } + + /* Update user data */ + zval_ptr_dtor(&watcher->data); + ZVAL_COPY(&watcher->data, data); + + return SUCCESS; +} + +/* PHP Method Implementations */ + +PHP_METHOD(Io_Poll_Backend, getAvailableBackends) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + array_init(return_value); + + /* Check each backend type for availability */ + php_poll_backend_type backends[] = {PHP_POLL_BACKEND_POLL, PHP_POLL_BACKEND_EPOLL, + PHP_POLL_BACKEND_KQUEUE, PHP_POLL_BACKEND_EVENTPORT, PHP_POLL_BACKEND_WSAPOLL}; + + for (size_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) { + if (php_poll_is_backend_available(backends[i])) { + const char *name = php_io_poll_backend_type_to_name(backends[i]); + zval enum_case; + ZVAL_OBJ_COPY(&enum_case, zend_enum_get_case_cstr(php_io_poll_backend_class_entry, name)); + add_next_index_zval(return_value, &enum_case); + } + } +} + +PHP_METHOD(Io_Poll_Backend, isAvailable) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *enum_obj = Z_OBJ_P(ZEND_THIS); + php_poll_backend_type type = php_io_poll_backend_enum_to_type(enum_obj); + + RETURN_BOOL(php_poll_is_backend_available(type)); +} + +PHP_METHOD(Io_Poll_Backend, supportsEdgeTriggering) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *enum_obj = Z_OBJ_P(ZEND_THIS); + php_poll_backend_type type = php_io_poll_backend_enum_to_type(enum_obj); + + RETURN_BOOL(php_poll_backend_supports_edge_triggering(type)); +} + +PHP_METHOD(StreamPollHandle, __construct) +{ + php_stream *stream; + + ZEND_PARSE_PARAMETERS_START(1, 1) + PHP_Z_PARAM_STREAM(stream) + ZEND_PARSE_PARAMETERS_END(); + + php_poll_handle_object *intern = PHP_POLL_HANDLE_OBJ_FROM_ZV(getThis()); + + if (intern->handle_data) { + zend_throw_error(NULL, "StreamPollHandle object is already constructed"); + RETURN_THROWS(); + } + + /* Set up stream-specific data */ + php_stream_poll_handle_data *data = emalloc(sizeof(php_stream_poll_handle_data)); + data->stream = stream; + data->res = stream->res; + intern->handle_data = data; + + /* Add reference to stream */ + GC_ADDREF(data->res); +} + +PHP_METHOD(StreamPollHandle, getStream) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_poll_handle_object *intern = PHP_POLL_HANDLE_OBJ_FROM_ZV(getThis()); + php_stream_poll_handle_data *data = intern->handle_data; + + if (!data || !data->stream) { + RETURN_NULL(); + } + + GC_ADDREF(data->stream->res); + php_stream_to_zval(data->stream, return_value); +} + +PHP_METHOD(StreamPollHandle, isValid) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_poll_handle_object *intern = PHP_POLL_HANDLE_OBJ_FROM_ZV(getThis()); + RETURN_BOOL(intern->ops->is_valid(intern)); +} + +PHP_METHOD(StreamPollHandle, getFileDescriptor) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_poll_handle_object *intern = PHP_POLL_HANDLE_OBJ_FROM_ZV(getThis()); + php_socket_t fd = php_poll_handle_get_fd(intern); + + if (fd == SOCK_ERR) { + RETURN_LONG(0); + } + + RETURN_LONG((zend_long) fd); +} + +PHP_METHOD(Io_Poll_Watcher, __construct) +{ + zend_throw_error(NULL, "Cannot directly construct Watcher, use Context::add"); +} + +PHP_METHOD(Io_Poll_Watcher, getHandle) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + if (!intern->handle) { + RETURN_NULL(); + } + + RETURN_OBJ_COPY(&intern->handle->std); +} + +PHP_METHOD(Io_Poll_Watcher, getWatchedEvents) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + php_io_poll_events_to_event_enums(intern->watched_events, return_value); +} + +PHP_METHOD(Io_Poll_Watcher, getTriggeredEvents) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + php_io_poll_events_to_event_enums(intern->triggered_events, return_value); +} + +PHP_METHOD(Io_Poll_Watcher, getData) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + ZVAL_COPY(return_value, &intern->data); +} + +PHP_METHOD(Io_Poll_Watcher, hasTriggered) +{ + zval *event_enum; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(event_enum, php_io_poll_event_class_entry) + ZEND_PARSE_PARAMETERS_END(); + + uint32_t event_bit = php_io_poll_event_enum_to_bit(Z_OBJ_P(event_enum)); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + RETURN_BOOL((intern->triggered_events & event_bit) != 0); +} + +PHP_METHOD(Io_Poll_Watcher, isActive) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + RETURN_BOOL(intern->active); +} + +PHP_METHOD(Io_Poll_Watcher, modify) +{ + zval *event_enums; + zval *data = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ARRAY(event_enums) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(data) + ZEND_PARSE_PARAMETERS_END(); + + uint32_t events = php_io_poll_event_enums_to_events(event_enums); + if (!events) { + zend_argument_type_error(1, "must be array of Event enums"); + RETURN_THROWS(); + } + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + + /* Modify events first */ + if (php_io_poll_watcher_modify_events(intern, events) != SUCCESS) { + RETURN_THROWS(); + } + + /* Then modify data if provided */ + if (data) { + if (php_io_poll_watcher_modify_data(intern, data) != SUCCESS) { + RETURN_THROWS(); + } + } +} + +PHP_METHOD(Io_Poll_Watcher, modifyEvents) +{ + zval *event_enums; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(event_enums) + ZEND_PARSE_PARAMETERS_END(); + + uint32_t events = php_io_poll_event_enums_to_events(event_enums); + if (!events) { + zend_argument_type_error(1, "must be array of Event enums"); + RETURN_THROWS(); + } + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + + if (php_io_poll_watcher_modify_events(intern, events) != SUCCESS) { + RETURN_THROWS(); + } +} + +PHP_METHOD(Io_Poll_Watcher, modifyData) +{ + zval *data; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(data) + ZEND_PARSE_PARAMETERS_END(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + + if (php_io_poll_watcher_modify_data(intern, data) != SUCCESS) { + RETURN_THROWS(); + } +} + +PHP_METHOD(Io_Poll_Watcher, remove) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_watcher_object *intern = PHP_POLL_WATCHER_OBJ_FROM_ZV(getThis()); + + if (!intern->active || !intern->context) { + zend_throw_exception( + php_io_poll_inactive_watcher_class_entry, "Cannot remove inactive watcher", 0); + RETURN_THROWS(); + } + + php_io_poll_context_object *context = intern->context; + php_poll_ctx *poll_ctx = context->ctx; + HashTable *watchers = context->watchers; + zend_ulong hash_key = php_io_poll_compute_ptr_key(intern->handle); + php_socket_t fd = php_poll_handle_get_fd(intern->handle); + if (fd != SOCK_ERR) { + php_poll_remove(poll_ctx, (int) fd); + } + + intern->active = false; + intern->context = NULL; + + if (watchers) { + zend_hash_index_del(watchers, hash_key); + } +} + +PHP_METHOD(Io_Poll_Context, __construct) +{ + zval *backend_obj = NULL; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_OBJECT_OF_CLASS(backend_obj, php_io_poll_backend_class_entry) + ZEND_PARSE_PARAMETERS_END(); + + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis()); + + if (intern->ctx) { + zend_throw_error(NULL, "Io\\Poll\\Context object is already constructed"); + RETURN_THROWS(); + } + + php_poll_backend_type backend_type = PHP_POLL_BACKEND_AUTO; + if (backend_obj != NULL) { + backend_type = php_io_poll_backend_enum_to_type(Z_OBJ_P(backend_obj)); + } + + intern->ctx = php_poll_create(backend_type, 0); + + if (!intern->ctx) { + zend_throw_exception_ex( + php_io_poll_failed_backend_unavailable_class_entry, 0, "Backend %s not available", + php_io_poll_backend_type_to_name(backend_type)); + RETURN_THROWS(); + } + + if (php_poll_init(intern->ctx) != SUCCESS) { + php_poll_error err = php_poll_get_error(intern->ctx); + php_poll_destroy(intern->ctx); + intern->ctx = NULL; + php_io_poll_throw_failed_operation(php_io_poll_failed_context_init_class_entry, + "Failed to initialize polling context", err); + RETURN_THROWS(); + } + + intern->watchers = emalloc(sizeof(HashTable)); + zend_hash_init(intern->watchers, 8, NULL, ZVAL_PTR_DTOR, 0); +} + +PHP_METHOD(Io_Poll_Context, add) +{ + zval *handle_obj, *event_enums; + uint32_t events; + zval *data = NULL; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJECT_OF_CLASS(handle_obj, php_io_poll_handle_class_entry) + Z_PARAM_ARRAY(event_enums) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(data) + ZEND_PARSE_PARAMETERS_END(); + + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis()); + php_poll_handle_object *handle = PHP_POLL_HANDLE_OBJ_FROM_ZV(handle_obj); + + /* Get file descriptor */ + php_socket_t fd = php_poll_handle_get_fd(handle); + if (fd == SOCK_ERR) { + zend_throw_exception( + php_io_poll_invalid_handle_class_entry, "Invalid handle for polling", 0); + RETURN_THROWS(); + } + + /* Create watcher object */ + object_init_ex(return_value, php_io_poll_watcher_class_entry); + php_io_poll_watcher_object *watcher = PHP_POLL_WATCHER_OBJ_FROM_ZV(return_value); + + events = php_io_poll_event_enums_to_events(event_enums); + if (!events) { + zend_argument_type_error(2, "must be array of Event enums"); + RETURN_THROWS(); + } + + watcher->handle = handle; + watcher->watched_events = events; + watcher->triggered_events = 0; + + GC_ADDREF(&handle->std); + + if (data) { + ZVAL_COPY(&watcher->data, data); + } else { + ZVAL_NULL(&watcher->data); + } + + /* Add to poll context */ + if (php_poll_add(intern->ctx, (int) fd, events, watcher) != SUCCESS) { + php_poll_error err = php_poll_get_error(intern->ctx); + if (err == PHP_POLL_ERR_EXISTS) { + zend_throw_exception( + php_io_poll_handle_already_watched_class_entry, "Handle already added", 0); + } else { + php_io_poll_throw_failed_operation( + php_io_poll_failed_handle_add_class_entry, "Failed to add handle", err); + } + RETURN_THROWS(); + } + + /* Store in our watchers map using shifted pointer as key */ + zval watcher_zv; + ZVAL_OBJ(&watcher_zv, &watcher->std); + GC_ADDREF(&watcher->std); + + zend_ulong hash_key = php_io_poll_compute_ptr_key(handle); + zend_hash_index_add_new(intern->watchers, hash_key, &watcher_zv); + + watcher->active = true; + watcher->context = intern; +} + +PHP_METHOD(Io_Poll_Context, wait) +{ + zend_long timeout_seconds = -1; + bool timeout_seconds_is_null = true; + zend_long timeout_microseconds = 0; + zend_long max_events = 0; + bool max_events_is_null = true; + + ZEND_PARSE_PARAMETERS_START(0, 3) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(timeout_seconds, timeout_seconds_is_null) + Z_PARAM_LONG(timeout_microseconds) + Z_PARAM_LONG_OR_NULL(max_events, max_events_is_null) + ZEND_PARSE_PARAMETERS_END(); + + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis()); + + /* Build timespec from seconds + microseconds, or NULL for indefinite */ + struct timespec ts; + const struct timespec *timeout = NULL; + if (timeout_seconds >= 0) { + if (timeout_microseconds < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + /* Allow microseconds >= 1000000, carry overflow into seconds + * (same behavior as stream_select) */ + ts.tv_sec = (time_t) (timeout_seconds + (timeout_microseconds / 1000000)); + ts.tv_nsec = (long) ((timeout_microseconds % 1000000) * 1000); + timeout = &ts; + } else if (!timeout_seconds_is_null) { + zend_argument_value_error(1, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + if (max_events_is_null) { + max_events = php_poll_get_suitable_max_events(intern->ctx); + if (max_events <= 0) { + max_events = 64; + } + } else if (max_events <= 0) { + zend_argument_value_error(3, "must be greater than 0"); + RETURN_THROWS(); + } + + php_poll_event *events = safe_emalloc(max_events, sizeof(*events), 0); + int num_events = php_poll_wait(intern->ctx, events, (int) max_events, timeout); + + if (num_events < 0) { + php_poll_error err = php_poll_get_error(intern->ctx); + efree(events); + php_io_poll_throw_failed_operation( + php_io_poll_failed_wait_class_entry, "Poll wait failed", err); + RETURN_THROWS(); + } + + array_init(return_value); + + for (int i = 0; i < num_events; i++) { + php_io_poll_watcher_object *watcher = (php_io_poll_watcher_object *) events[i].data; + if (watcher) { + watcher->triggered_events = events[i].revents; + + zval watcher_zv; + ZVAL_OBJ(&watcher_zv, &watcher->std); + GC_ADDREF(&watcher->std); + + add_next_index_zval(return_value, &watcher_zv); + } + } + + efree(events); +} + +PHP_METHOD(Io_Poll_Context, getBackend) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis()); + php_poll_backend_type backend_type = php_poll_get_backend_type(intern->ctx); + const char *backend_name = php_io_poll_backend_type_to_name(backend_type); + + RETURN_OBJ_COPY(zend_enum_get_case_cstr(php_io_poll_backend_class_entry, backend_name)); +} + +/* Initialize the stream poll classes - add to PHP_MINIT_FUNCTION */ +PHP_MINIT_FUNCTION(poll) +{ + /* Register backend enum */ + php_io_poll_backend_class_entry = register_class_Io_Poll_Backend(); + + /* Register event enum */ + php_io_poll_event_class_entry = register_class_Io_Poll_Event(); + + /* Register Handle interface */ + php_io_poll_handle_class_entry = register_class_Io_Poll_Handle(); + php_io_poll_handle_class_entry->interface_gets_implemented = php_stream_poll_handle_implement_interface; + + /* Register StreamPollHandle class */ + php_stream_poll_handle_class_entry + = register_class_StreamPollHandle(php_io_poll_handle_class_entry); + php_stream_poll_handle_class_entry->create_object = php_stream_poll_handle_create_object; + + memcpy(&php_io_poll_handle_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_io_poll_handle_object_handlers.offset = offsetof(php_poll_handle_object, std); + php_io_poll_handle_object_handlers.free_obj = php_poll_handle_object_free; + php_io_poll_handle_object_handlers.clone_obj = NULL; + php_stream_poll_handle_class_entry->default_object_handlers = &php_io_poll_handle_object_handlers; + + /* Register Watcher class */ + php_io_poll_watcher_class_entry = register_class_Io_Poll_Watcher(); + php_io_poll_watcher_class_entry->create_object = php_io_poll_watcher_create_object; + + memcpy(&php_io_poll_watcher_object_handlers, &std_object_handlers, + sizeof(zend_object_handlers)); + php_io_poll_watcher_object_handlers.offset = offsetof(php_io_poll_watcher_object, std); + php_io_poll_watcher_object_handlers.free_obj = php_io_poll_watcher_free_object; + php_io_poll_watcher_object_handlers.get_gc = php_io_poll_watcher_get_gc; + php_io_poll_watcher_object_handlers.clone_obj = NULL; + php_io_poll_watcher_class_entry->default_object_handlers = &php_io_poll_watcher_object_handlers; + + /* Register Context class */ + php_io_poll_context_class_entry = register_class_Io_Poll_Context(); + php_io_poll_context_class_entry->create_object = php_io_poll_context_create_object; + + memcpy(&php_io_poll_context_object_handlers, &std_object_handlers, + sizeof(zend_object_handlers)); + php_io_poll_context_object_handlers.offset = offsetof(php_io_poll_context_object, std); + php_io_poll_context_object_handlers.free_obj = php_io_poll_context_free_object; + php_io_poll_context_object_handlers.get_gc = php_io_poll_context_get_gc; + php_io_poll_context_object_handlers.clone_obj = NULL; + php_io_poll_context_class_entry->default_object_handlers = &php_io_poll_context_object_handlers; + + /* Register exception hierarchy */ + php_io_exception_class_entry = register_class_Io_IoException(zend_ce_exception); + + php_io_poll_exception_class_entry + = register_class_Io_Poll_PollException(php_io_exception_class_entry); + + php_io_poll_failed_operation_class_entry = register_class_Io_Poll_FailedPollOperationException( + php_io_poll_exception_class_entry); + + php_io_poll_failed_context_init_class_entry + = register_class_Io_Poll_FailedContextInitializationException( + php_io_poll_failed_operation_class_entry); + + php_io_poll_failed_handle_add_class_entry = register_class_Io_Poll_FailedHandleAddException( + php_io_poll_failed_operation_class_entry); + + php_io_poll_failed_watcher_mod_class_entry + = register_class_Io_Poll_FailedWatcherModificationException( + php_io_poll_failed_operation_class_entry); + + php_io_poll_failed_wait_class_entry = register_class_Io_Poll_FailedPollWaitException( + php_io_poll_failed_operation_class_entry); + + php_io_poll_failed_backend_unavailable_class_entry = register_class_Io_Poll_BackendUnavailableException( + php_io_poll_exception_class_entry); + + php_io_poll_inactive_watcher_class_entry = register_class_Io_Poll_InactiveWatcherException( + php_io_poll_exception_class_entry); + + php_io_poll_handle_already_watched_class_entry + = register_class_Io_Poll_HandleAlreadyWatchedException( + php_io_poll_exception_class_entry); + + php_io_poll_invalid_handle_class_entry + = register_class_Io_Poll_InvalidHandleException(php_io_poll_exception_class_entry); + + /* Initialize polling backends */ + php_poll_register_backends(); + + return SUCCESS; +} diff --git a/ext/standard/io_poll.stub.php b/ext/standard/io_poll.stub.php new file mode 100644 index 000000000000..83c1ba5cbe2e --- /dev/null +++ b/ext/standard/io_poll.stub.php @@ -0,0 +1,167 @@ + */ + static public function getAvailableBackends(): array {} + + public function isAvailable(): bool {} + + public function supportsEdgeTriggering(): bool {} + } + + // Keep in sync with main/php_poll.h! + enum Event { + case Read; + case Write; + case Error; + case HangUp; + case ReadHangUp; + case OneShot; + case EdgeTriggered; + } + + interface Handle + { + } + + /** + * @strict-properties + * @not-serializable + */ + final class Watcher + { + private final function __construct() {} + + public function getHandle(): Handle {} + + /** @return list */ + public function getWatchedEvents(): array {} + + /** @return list */ + public function getTriggeredEvents(): array {} + + public function getData(): mixed {} + + public function hasTriggered(Event $event): bool {} + + public function isActive(): bool {} + + public function modify(array $events, mixed $data = null): void {} + + public function modifyEvents(array $events): void {} + + public function modifyData(mixed $data): void {} + + public function remove(): void {} + } + + /** + * @strict-properties + * @not-serializable + */ + final class Context + { + public function __construct(Backend $backend = Backend::Auto) {} + + public function add(Handle $handle, array $events, mixed $data = null): Watcher {} + + /** @return list */ + public function wait(?int $timeoutSeconds = null, int $timeoutMicroseconds = 0, ?int $maxEvents = null): array {} + + public function getBackend(): Backend {} + } + + class PollException extends \Io\IoException {} + + abstract class FailedPollOperationException extends PollException + { + /** @cvalue PHP_POLL_ERROR_CODE_NONE */ + public const int ERROR_NONE = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_SYSTEM */ + public const int ERROR_SYSTEM = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_NOMEM */ + public const int ERROR_NOMEM = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_INVALID */ + public const int ERROR_INVALID = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_EXISTS */ + public const int ERROR_EXISTS = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_NOTFOUND */ + public const int ERROR_NOTFOUND = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_TIMEOUT */ + public const int ERROR_TIMEOUT = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_INTERRUPTED */ + public const int ERROR_INTERRUPTED = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_PERMISSION */ + public const int ERROR_PERMISSION = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_TOOBIG */ + public const int ERROR_TOOBIG = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_AGAIN */ + public const int ERROR_AGAIN = UNKNOWN; + + /** @cvalue PHP_POLL_ERROR_CODE_NOSUPPORT */ + public const int ERROR_NOSUPPORT = UNKNOWN; + } + + class FailedContextInitializationException extends FailedPollOperationException {} + + class FailedHandleAddException extends FailedPollOperationException {} + + class FailedWatcherModificationException extends FailedPollOperationException {} + + class FailedPollWaitException extends FailedPollOperationException {} + + class BackendUnavailableException extends PollException {} + + class InactiveWatcherException extends PollException {} + + class HandleAlreadyWatchedException extends PollException {} + + class InvalidHandleException extends PollException {} +} + +namespace { + /** + * @strict-properties + * @not-serializable + */ + final class StreamPollHandle implements Io\Poll\Handle + { + /** @param resource $stream */ + public function __construct($stream) {} + + /** @return resource */ + public function getStream() {} + + public function isValid(): bool {} + } +} diff --git a/ext/standard/io_poll_arginfo.h b/ext/standard/io_poll_arginfo.h new file mode 100644 index 000000000000..5fc62f629564 --- /dev/null +++ b/ext/standard/io_poll_arginfo.h @@ -0,0 +1,395 @@ +/* This is a generated file, edit io_poll.stub.php instead. + * Stub hash: a7450146c5b3b3f3486611c83a55cf0cc932b27a + * Has decl header: yes */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Backend_getAvailableBackends, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Backend_isAvailable, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Io_Poll_Backend_supportsEdgeTriggering arginfo_class_Io_Poll_Backend_isAvailable + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Io_Poll_Watcher___construct, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Io_Poll_Watcher_getHandle, 0, 0, Io\\Poll\\Handle, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Io_Poll_Watcher_getWatchedEvents arginfo_class_Io_Poll_Backend_getAvailableBackends + +#define arginfo_class_Io_Poll_Watcher_getTriggeredEvents arginfo_class_Io_Poll_Backend_getAvailableBackends + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_getData, 0, 0, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_hasTriggered, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, event, Io\\Poll\\Event, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Io_Poll_Watcher_isActive arginfo_class_Io_Poll_Backend_isAvailable + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_modify, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, events, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_MIXED, 0, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_modifyEvents, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, events, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_modifyData, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Watcher_remove, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Io_Poll_Context___construct, 0, 0, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, backend, Io\\Poll\\Backend, 0, "Io\\Poll\\Backend::Auto") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Io_Poll_Context_add, 0, 2, Io\\Poll\\Watcher, 0) + ZEND_ARG_OBJ_INFO(0, handle, Io\\Poll\\Handle, 0) + ZEND_ARG_TYPE_INFO(0, events, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_MIXED, 0, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Context_wait, 0, 0, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeoutSeconds, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeoutMicroseconds, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, maxEvents, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Io_Poll_Context_getBackend, 0, 0, Io\\Poll\\Backend, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_StreamPollHandle___construct, 0, 0, 1) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +#define arginfo_class_StreamPollHandle_getStream arginfo_class_Io_Poll_Watcher___construct + +#define arginfo_class_StreamPollHandle_isValid arginfo_class_Io_Poll_Backend_isAvailable + +ZEND_METHOD(Io_Poll_Backend, getAvailableBackends); +ZEND_METHOD(Io_Poll_Backend, isAvailable); +ZEND_METHOD(Io_Poll_Backend, supportsEdgeTriggering); +ZEND_METHOD(Io_Poll_Watcher, __construct); +ZEND_METHOD(Io_Poll_Watcher, getHandle); +ZEND_METHOD(Io_Poll_Watcher, getWatchedEvents); +ZEND_METHOD(Io_Poll_Watcher, getTriggeredEvents); +ZEND_METHOD(Io_Poll_Watcher, getData); +ZEND_METHOD(Io_Poll_Watcher, hasTriggered); +ZEND_METHOD(Io_Poll_Watcher, isActive); +ZEND_METHOD(Io_Poll_Watcher, modify); +ZEND_METHOD(Io_Poll_Watcher, modifyEvents); +ZEND_METHOD(Io_Poll_Watcher, modifyData); +ZEND_METHOD(Io_Poll_Watcher, remove); +ZEND_METHOD(Io_Poll_Context, __construct); +ZEND_METHOD(Io_Poll_Context, add); +ZEND_METHOD(Io_Poll_Context, wait); +ZEND_METHOD(Io_Poll_Context, getBackend); +ZEND_METHOD(StreamPollHandle, __construct); +ZEND_METHOD(StreamPollHandle, getStream); +ZEND_METHOD(StreamPollHandle, isValid); + +static const zend_function_entry class_Io_Poll_Backend_methods[] = { + ZEND_ME(Io_Poll_Backend, getAvailableBackends, arginfo_class_Io_Poll_Backend_getAvailableBackends, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Io_Poll_Backend, isAvailable, arginfo_class_Io_Poll_Backend_isAvailable, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Backend, supportsEdgeTriggering, arginfo_class_Io_Poll_Backend_supportsEdgeTriggering, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_Io_Poll_Watcher_methods[] = { + ZEND_ME(Io_Poll_Watcher, __construct, arginfo_class_Io_Poll_Watcher___construct, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) + ZEND_ME(Io_Poll_Watcher, getHandle, arginfo_class_Io_Poll_Watcher_getHandle, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, getWatchedEvents, arginfo_class_Io_Poll_Watcher_getWatchedEvents, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, getTriggeredEvents, arginfo_class_Io_Poll_Watcher_getTriggeredEvents, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, getData, arginfo_class_Io_Poll_Watcher_getData, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, hasTriggered, arginfo_class_Io_Poll_Watcher_hasTriggered, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, isActive, arginfo_class_Io_Poll_Watcher_isActive, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, modify, arginfo_class_Io_Poll_Watcher_modify, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, modifyEvents, arginfo_class_Io_Poll_Watcher_modifyEvents, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, modifyData, arginfo_class_Io_Poll_Watcher_modifyData, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Watcher, remove, arginfo_class_Io_Poll_Watcher_remove, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_Io_Poll_Context_methods[] = { + ZEND_ME(Io_Poll_Context, __construct, arginfo_class_Io_Poll_Context___construct, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Context, add, arginfo_class_Io_Poll_Context_add, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Context, wait, arginfo_class_Io_Poll_Context_wait, ZEND_ACC_PUBLIC) + ZEND_ME(Io_Poll_Context, getBackend, arginfo_class_Io_Poll_Context_getBackend, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_StreamPollHandle_methods[] = { + ZEND_ME(StreamPollHandle, __construct, arginfo_class_StreamPollHandle___construct, ZEND_ACC_PUBLIC) + ZEND_ME(StreamPollHandle, getStream, arginfo_class_StreamPollHandle_getStream, ZEND_ACC_PUBLIC) + ZEND_ME(StreamPollHandle, isValid, arginfo_class_StreamPollHandle_isValid, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static zend_class_entry *register_class_Io_IoException(zend_class_entry *class_entry_Exception) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io", "IoException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_Backend(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Io\\Poll\\Backend", IS_UNDEF, class_Io_Poll_Backend_methods); + + zend_enum_add_case_cstr(class_entry, "Auto", NULL); + + zend_enum_add_case_cstr(class_entry, "Poll", NULL); + + zend_enum_add_case_cstr(class_entry, "Epoll", NULL); + + zend_enum_add_case_cstr(class_entry, "Kqueue", NULL); + + zend_enum_add_case_cstr(class_entry, "EventPorts", NULL); + + zend_enum_add_case_cstr(class_entry, "WSAPoll", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_Event(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Io\\Poll\\Event", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Read", NULL); + + zend_enum_add_case_cstr(class_entry, "Write", NULL); + + zend_enum_add_case_cstr(class_entry, "Error", NULL); + + zend_enum_add_case_cstr(class_entry, "HangUp", NULL); + + zend_enum_add_case_cstr(class_entry, "ReadHangUp", NULL); + + zend_enum_add_case_cstr(class_entry, "OneShot", NULL); + + zend_enum_add_case_cstr(class_entry, "EdgeTriggered", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_Handle(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "Handle", NULL); + class_entry = zend_register_internal_interface(&ce); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_Watcher(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "Watcher", class_Io_Poll_Watcher_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_Context(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "Context", class_Io_Poll_Context_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_PollException(zend_class_entry *class_entry_Io_IoException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "PollException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_IoException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_FailedPollOperationException(zend_class_entry *class_entry_Io_Poll_PollException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "FailedPollOperationException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_PollException, ZEND_ACC_ABSTRACT); + + zval const_ERROR_NONE_value; + ZVAL_LONG(&const_ERROR_NONE_value, PHP_POLL_ERROR_CODE_NONE); + zend_string *const_ERROR_NONE_name = zend_string_init_interned("ERROR_NONE", sizeof("ERROR_NONE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_NONE_name, &const_ERROR_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_NONE_name, true); + + zval const_ERROR_SYSTEM_value; + ZVAL_LONG(&const_ERROR_SYSTEM_value, PHP_POLL_ERROR_CODE_SYSTEM); + zend_string *const_ERROR_SYSTEM_name = zend_string_init_interned("ERROR_SYSTEM", sizeof("ERROR_SYSTEM") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_SYSTEM_name, &const_ERROR_SYSTEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_SYSTEM_name, true); + + zval const_ERROR_NOMEM_value; + ZVAL_LONG(&const_ERROR_NOMEM_value, PHP_POLL_ERROR_CODE_NOMEM); + zend_string *const_ERROR_NOMEM_name = zend_string_init_interned("ERROR_NOMEM", sizeof("ERROR_NOMEM") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_NOMEM_name, &const_ERROR_NOMEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_NOMEM_name, true); + + zval const_ERROR_INVALID_value; + ZVAL_LONG(&const_ERROR_INVALID_value, PHP_POLL_ERROR_CODE_INVALID); + zend_string *const_ERROR_INVALID_name = zend_string_init_interned("ERROR_INVALID", sizeof("ERROR_INVALID") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_INVALID_name, &const_ERROR_INVALID_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_INVALID_name, true); + + zval const_ERROR_EXISTS_value; + ZVAL_LONG(&const_ERROR_EXISTS_value, PHP_POLL_ERROR_CODE_EXISTS); + zend_string *const_ERROR_EXISTS_name = zend_string_init_interned("ERROR_EXISTS", sizeof("ERROR_EXISTS") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_EXISTS_name, &const_ERROR_EXISTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_EXISTS_name, true); + + zval const_ERROR_NOTFOUND_value; + ZVAL_LONG(&const_ERROR_NOTFOUND_value, PHP_POLL_ERROR_CODE_NOTFOUND); + zend_string *const_ERROR_NOTFOUND_name = zend_string_init_interned("ERROR_NOTFOUND", sizeof("ERROR_NOTFOUND") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_NOTFOUND_name, &const_ERROR_NOTFOUND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_NOTFOUND_name, true); + + zval const_ERROR_TIMEOUT_value; + ZVAL_LONG(&const_ERROR_TIMEOUT_value, PHP_POLL_ERROR_CODE_TIMEOUT); + zend_string *const_ERROR_TIMEOUT_name = zend_string_init_interned("ERROR_TIMEOUT", sizeof("ERROR_TIMEOUT") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_TIMEOUT_name, &const_ERROR_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_TIMEOUT_name, true); + + zval const_ERROR_INTERRUPTED_value; + ZVAL_LONG(&const_ERROR_INTERRUPTED_value, PHP_POLL_ERROR_CODE_INTERRUPTED); + zend_string *const_ERROR_INTERRUPTED_name = zend_string_init_interned("ERROR_INTERRUPTED", sizeof("ERROR_INTERRUPTED") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_INTERRUPTED_name, &const_ERROR_INTERRUPTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_INTERRUPTED_name, true); + + zval const_ERROR_PERMISSION_value; + ZVAL_LONG(&const_ERROR_PERMISSION_value, PHP_POLL_ERROR_CODE_PERMISSION); + zend_string *const_ERROR_PERMISSION_name = zend_string_init_interned("ERROR_PERMISSION", sizeof("ERROR_PERMISSION") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_PERMISSION_name, &const_ERROR_PERMISSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_PERMISSION_name, true); + + zval const_ERROR_TOOBIG_value; + ZVAL_LONG(&const_ERROR_TOOBIG_value, PHP_POLL_ERROR_CODE_TOOBIG); + zend_string *const_ERROR_TOOBIG_name = zend_string_init_interned("ERROR_TOOBIG", sizeof("ERROR_TOOBIG") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_TOOBIG_name, &const_ERROR_TOOBIG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_TOOBIG_name, true); + + zval const_ERROR_AGAIN_value; + ZVAL_LONG(&const_ERROR_AGAIN_value, PHP_POLL_ERROR_CODE_AGAIN); + zend_string *const_ERROR_AGAIN_name = zend_string_init_interned("ERROR_AGAIN", sizeof("ERROR_AGAIN") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_AGAIN_name, &const_ERROR_AGAIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_AGAIN_name, true); + + zval const_ERROR_NOSUPPORT_value; + ZVAL_LONG(&const_ERROR_NOSUPPORT_value, PHP_POLL_ERROR_CODE_NOSUPPORT); + zend_string *const_ERROR_NOSUPPORT_name = zend_string_init_interned("ERROR_NOSUPPORT", sizeof("ERROR_NOSUPPORT") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ERROR_NOSUPPORT_name, &const_ERROR_NOSUPPORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ERROR_NOSUPPORT_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_FailedContextInitializationException(zend_class_entry *class_entry_Io_Poll_FailedPollOperationException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "FailedContextInitializationException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_FailedPollOperationException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_FailedHandleAddException(zend_class_entry *class_entry_Io_Poll_FailedPollOperationException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "FailedHandleAddException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_FailedPollOperationException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_FailedWatcherModificationException(zend_class_entry *class_entry_Io_Poll_FailedPollOperationException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "FailedWatcherModificationException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_FailedPollOperationException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_FailedPollWaitException(zend_class_entry *class_entry_Io_Poll_FailedPollOperationException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "FailedPollWaitException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_FailedPollOperationException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_BackendUnavailableException(zend_class_entry *class_entry_Io_Poll_PollException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "BackendUnavailableException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_PollException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_InactiveWatcherException(zend_class_entry *class_entry_Io_Poll_PollException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "InactiveWatcherException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_PollException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_HandleAlreadyWatchedException(zend_class_entry *class_entry_Io_Poll_PollException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "HandleAlreadyWatchedException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_PollException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Io_Poll_InvalidHandleException(zend_class_entry *class_entry_Io_Poll_PollException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Io\\Poll", "InvalidHandleException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Io_Poll_PollException, 0); + + return class_entry; +} + +static zend_class_entry *register_class_StreamPollHandle(zend_class_entry *class_entry_Io_Poll_Handle) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "StreamPollHandle", class_StreamPollHandle_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + zend_class_implements(class_entry, 1, class_entry_Io_Poll_Handle); + + return class_entry; +} diff --git a/ext/standard/io_poll_decl.h b/ext/standard/io_poll_decl.h new file mode 100644 index 000000000000..2b09e3665f58 --- /dev/null +++ b/ext/standard/io_poll_decl.h @@ -0,0 +1,26 @@ +/* This is a generated file, edit io_poll.stub.php instead. + * Stub hash: a7450146c5b3b3f3486611c83a55cf0cc932b27a */ + +#ifndef ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H +#define ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H + +typedef enum zend_enum_Io_Poll_Backend { + ZEND_ENUM_Io_Poll_Backend_Auto = 1, + ZEND_ENUM_Io_Poll_Backend_Poll = 2, + ZEND_ENUM_Io_Poll_Backend_Epoll = 3, + ZEND_ENUM_Io_Poll_Backend_Kqueue = 4, + ZEND_ENUM_Io_Poll_Backend_EventPorts = 5, + ZEND_ENUM_Io_Poll_Backend_WSAPoll = 6, +} zend_enum_Io_Poll_Backend; + +typedef enum zend_enum_Io_Poll_Event { + ZEND_ENUM_Io_Poll_Event_Read = 1, + ZEND_ENUM_Io_Poll_Event_Write = 2, + ZEND_ENUM_Io_Poll_Event_Error = 3, + ZEND_ENUM_Io_Poll_Event_HangUp = 4, + ZEND_ENUM_Io_Poll_Event_ReadHangUp = 5, + ZEND_ENUM_Io_Poll_Event_OneShot = 6, + ZEND_ENUM_Io_Poll_Event_EdgeTriggered = 7, +} zend_enum_Io_Poll_Event; + +#endif /* ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H */ diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index 5482a3c6ff15..59db612a7337 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/standard/levenshtein.c b/ext/standard/levenshtein.c index d4688dcb9c13..efc71d2a2828 100644 --- a/ext/standard/levenshtein.c +++ b/ext/standard/levenshtein.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Hartmut Holzgraefe | +----------------------------------------------------------------------+ diff --git a/ext/standard/link.c b/ext/standard/link.c index 24e3b515dc80..dfd92a0a8709 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -88,7 +84,11 @@ PHP_FUNCTION(linkinfo) Z_PARAM_PATH(link, link_len) ZEND_PARSE_PARAMETERS_END(); - // TODO Check for empty string + if (UNEXPECTED(link_len == 0)) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + dirname = estrndup(link, link_len); zend_dirname(dirname, link_len); diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 395c7bb81d4f..6aac0d364cf0 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -336,8 +334,8 @@ PHP_FUNCTION(mail) subject_r = subject; } - zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL); - if (force_extra_parameters) { + zend_string *force_extra_parameters = zend_ini_str_literal("mail.force_extra_parameters"); + if (force_extra_parameters && ZSTR_LEN(force_extra_parameters) > 0) { extra_cmd = php_escape_shell_cmd(force_extra_parameters); } else if (extra_cmd) { extra_cmd = php_escape_shell_cmd(extra_cmd); @@ -437,9 +435,9 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const zend_string *extra_cmd) { FILE *sendmail; - char *sendmail_path = INI_STR("sendmail_path"); + const char *sendmail_path = zend_ini_string_literal("sendmail_path"); char *sendmail_cmd = NULL; - const zend_string *mail_log = zend_ini_str(ZEND_STRL("mail.log"), false); + const zend_string *mail_log = zend_ini_str_literal("mail.log"); const char *hdr = headers; char *ahdr = NULL; #if PHP_SIGCHILD @@ -536,7 +534,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c char *tsm_errmsg = NULL; /* handle old style win smtp sending */ - if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message) == FAILURE) { + if (TSendMail(zend_ini_string_literal("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message) == FAILURE) { if (tsm_errmsg) { php_error_docref(NULL, E_WARNING, "%s", tsm_errmsg); efree(tsm_errmsg); @@ -553,7 +551,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c if (extra_cmd != NULL) { spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, ZSTR_VAL(extra_cmd)); } else { - sendmail_cmd = sendmail_path; + sendmail_cmd = (char*)sendmail_path; } #if PHP_SIGCHILD @@ -576,7 +574,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c sendmail = popen(sendmail_cmd, "w"); #endif if (extra_cmd != NULL) { - efree (sendmail_cmd); + efree(sendmail_cmd); } if (sendmail) { @@ -701,7 +699,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mail) { - char *sendmail_path = INI_STR("sendmail_path"); + const char *sendmail_path = zend_ini_string_literal("sendmail_path"); #ifdef PHP_WIN32 if (!sendmail_path) { diff --git a/ext/standard/math.c b/ext/standard/math.c index 6418a020f4fa..1498a1efc0b2 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | @@ -24,6 +22,7 @@ #include "zend_exceptions.h" #include "zend_multiply.h" #include "zend_portability.h" +#include "zend_strtod.h" #include #include @@ -152,7 +151,7 @@ static inline double php_round_helper(double integral, double value, double expo return integral; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } // FIXME: GCC bug, branch is considered reachable. ZEND_UNREACHABLE(); @@ -261,7 +260,7 @@ PHP_FUNCTION(abs) } case IS_DOUBLE: RETURN_DOUBLE(fabs(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -280,7 +279,7 @@ PHP_FUNCTION(ceil) RETURN_DOUBLE(zval_get_double(value)); case IS_DOUBLE: RETURN_DOUBLE(ceil(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -299,7 +298,7 @@ PHP_FUNCTION(floor) RETURN_DOUBLE(zval_get_double(value)); case IS_DOUBLE: RETURN_DOUBLE(floor(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -382,7 +381,7 @@ PHP_FUNCTION(round) case IS_DOUBLE: RETURN_DOUBLE(_php_math_round(zval_get_double(value), (int)places, (int)mode)); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -861,9 +860,9 @@ PHPAPI void _php_math_basetozval(zend_string *str, int base, zval *ret) e = s + ZSTR_LEN(str); /* Skip leading whitespace */ - while (s < e && isspace(*s)) s++; + while (s < e && isspace((unsigned char)*s)) s++; /* Skip trailing whitespace */ - while (s < e && isspace(*(e-1))) e--; + while (s < e && isspace((unsigned char)e[-1])) e--; if (e - s >= 2) { if (base == 16 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s += 2; @@ -1003,7 +1002,7 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base) if (Z_TYPE_P(arg) == IS_DOUBLE) { double fvalue = floor(Z_DVAL_P(arg)); /* floor it just in case */ char *ptr, *end; - char buf[(sizeof(double) << 3) + 1]; + char buf[ZEND_DOUBLE_MAX_LENGTH]; /* Don't try to convert +/- infinity */ if (fvalue == ZEND_INFINITY || fvalue == -ZEND_INFINITY) { @@ -1176,7 +1175,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, const char *de tmpbuf = strpprintf(0, "%.*F", dec, d); if (tmpbuf == NULL) { return NULL; - } else if (!isdigit((int)ZSTR_VAL(tmpbuf)[0])) { + } else if (!isdigit((unsigned char)ZSTR_VAL(tmpbuf)[0])) { return tmpbuf; } @@ -1416,10 +1415,14 @@ PHP_FUNCTION(number_format) thousand_sep_len = 1; } + if (UNEXPECTED(dec > INT_MAX || dec < INT_MIN)) { + zend_argument_value_error(2, "must be between %d and %d", INT_MIN, INT_MAX); + RETURN_THROWS(); + } + switch (Z_TYPE_P(num)) { case IS_LONG: RETURN_STR(_php_math_number_format_long(Z_LVAL_P(num), dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; case IS_DOUBLE: // double values of >= 2^52 can not have fractional digits anymore @@ -1429,18 +1432,12 @@ PHP_FUNCTION(number_format) && ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(num)) )) { RETURN_STR(_php_math_number_format_long((zend_long)Z_DVAL_P(num), dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; } - if (dec >= 0) { - dec_int = ZEND_LONG_INT_OVFL(dec) ? INT_MAX : (int)dec; - } else { - dec_int = ZEND_LONG_INT_UDFL(dec) ? INT_MIN : (int)dec; - } + dec_int = (int) dec; RETURN_STR(_php_math_number_format_ex(Z_DVAL_P(num), dec_int, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ diff --git a/ext/standard/md5.c b/ext/standard/md5.c index 9d0f5f886a6b..204514053cf0 100644 --- a/ext/standard/md5.c +++ b/ext/standard/md5.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alexander Peslyak (Solar Designer) | | Lachlan Roche | diff --git a/ext/standard/md5.h b/ext/standard/md5.h index 5444abf46aec..30faa0ac258a 100644 --- a/ext/standard/md5.h +++ b/ext/standard/md5.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alexander Peslyak (Solar Designer) | | Rasmus Lerdorf | diff --git a/ext/standard/metaphone.c b/ext/standard/metaphone.c index 149f95c127c6..8f33057de5ac 100644 --- a/ext/standard/metaphone.c +++ b/ext/standard/metaphone.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -80,7 +78,7 @@ static const char _codes[26] = /* Note: these functions require an uppercase letter input! */ static zend_always_inline char encode(char c) { - if (isalpha(c)) { + if (isalpha((unsigned char)c)) { ZEND_ASSERT(c >= 'A' && c <= 'Z'); return _codes[(c - 'A')]; } else { @@ -107,9 +105,9 @@ static zend_always_inline char encode(char c) { /*----------------------------- */ /* I suppose I could have been using a character pointer instead of - * accesssing the array directly... */ + * accessing the array directly... */ -#define Convert_Raw(c) toupper(c) +#define Convert_Raw(c) toupper((unsigned char)c) /* Look at the next letter in the word */ #define Read_Raw_Next_Letter (word[w_idx+1]) #define Read_Next_Letter (Convert_Raw(Read_Raw_Next_Letter)) @@ -123,14 +121,14 @@ static zend_always_inline char encode(char c) { /* Look two letters down. It makes sure you don't walk off the string. */ #define Read_After_Next_Letter (Read_Raw_Next_Letter != '\0' ? Convert_Raw(word[w_idx+2]) \ : '\0') -#define Look_Ahead_Letter(n) (toupper(Lookahead((char *) word+w_idx, n))) +#define Look_Ahead_Letter(n) (toupper((unsigned char)Lookahead((char *) word+w_idx, n))) /* Allows us to safely look ahead an arbitrary # of letters */ /* I probably could have just used strlen... */ -static char Lookahead(char *word, int how_far) +static char Lookahead(char *word, size_t how_far) { - int idx; + size_t idx; for (idx = 0; word[idx] != '\0' && idx < how_far; idx++); /* Edge forward in the string... */ @@ -165,12 +163,12 @@ static char Lookahead(char *word, int how_far) #define Phone_Len (p_idx) /* Note is a letter is a 'break' in the word */ -#define Isbreak(c) (!isalpha(c)) +#define Isbreak(c) (!isalpha((unsigned char)(c))) /* {{{ metaphone */ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonemes, zend_string **phoned_word, int traditional) { - int w_idx = 0; /* point in the phonization we're at. */ + size_t w_idx = 0; /* point in the phonization we're at. */ size_t p_idx = 0; /* end of the phoned phrase */ size_t max_buffer_len = 0; /* maximum length of the destination buffer */ char curr_letter; @@ -189,7 +187,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem /*-- The first phoneme has to be processed specially. --*/ /* Find our first letter */ - for (; !isalpha(curr_letter = Read_Raw_Curr_Letter); w_idx++) { + for (; !isalpha((unsigned char)(curr_letter = Read_Raw_Curr_Letter)); w_idx++) { /* On the off chance we were given nothing but crap... */ if (curr_letter == '\0') { End_Phoned_Word(); @@ -264,7 +262,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem for (; (curr_letter = Read_Raw_Curr_Letter) != '\0' && (max_phonemes == 0 || Phone_Len < (size_t)max_phonemes); w_idx++) { - /* How many letters to skip because an eariler encoding handled + /* How many letters to skip because an earlier encoding handled * multiple letters */ unsigned short int skip_letter = 0; @@ -277,7 +275,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem */ /* Ignore non-alphas */ - if (!isalpha(curr_letter)) + if (!isalpha((unsigned char)curr_letter)) continue; curr_letter = Convert_Raw(curr_letter); diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index ca8643eb5196..46e770dec3ee 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Paul Panotzki - Bunyip Information Systems | +----------------------------------------------------------------------+ diff --git a/ext/standard/net.c b/ext/standard/net.c index 942d804d42a4..199db6e80943 100644 --- a/ext/standard/net.c +++ b/ext/standard/net.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 55da64897a2e..1ab5d4858cbe 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Chris Schneider | +----------------------------------------------------------------------+ diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c index c1cbc59bfaa1..66ba0da5f158 100644 --- a/ext/standard/pageinfo.c +++ b/ext/standard/pageinfo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -21,11 +19,7 @@ #include #include #ifdef HAVE_PWD_H -#ifdef PHP_WIN32 -#include "win32/pwd.h" -#else -#include -#endif +# include #endif #ifdef HAVE_GRP_H # include diff --git a/ext/standard/pageinfo.h b/ext/standard/pageinfo.h index 029ce8b97981..5ce81685f9ec 100644 --- a/ext/standard/pageinfo.h +++ b/ext/standard/pageinfo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/password.c b/ext/standard/password.c index a8aab315657c..a28ceb7e0ced 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara | | Charles R. Portwood II | diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index 2205082e91df..ab6c8494dd4e 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -63,6 +61,8 @@ PHPAPI bool php_array_pick_keys(php_random_algo_with_state engine, zval *input, #define ARRAY_FILTER_USE_BOTH 1 #define ARRAY_FILTER_USE_KEY 2 +extern PHPAPI zend_class_entry *sort_direction_ce; + ZEND_BEGIN_MODULE_GLOBALS(array) bucket_compare_func_t *multisort_func; bool compare_deprecation_thrown; diff --git a/ext/standard/php_assert.h b/ext/standard/php_assert.h index 103a770e7601..c26e1f11681c 100644 --- a/ext/standard/php_assert.h +++ b/ext/standard/php_assert.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_browscap.h b/ext/standard/php_browscap.h index 4fc4f66a9233..85225bca0244 100644 --- a/ext/standard/php_browscap.h +++ b/ext/standard/php_browscap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h index b7111dfd21b1..19c20c4a6c16 100644 --- a/ext/standard/php_crypt.h +++ b/ext/standard/php_crypt.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Bakken | | Zeev Suraski | diff --git a/ext/standard/php_crypt_r.c b/ext/standard/php_crypt_r.c index bd30ce9ce8cb..15a1508be1cb 100644 --- a/ext/standard/php_crypt_r.c +++ b/ext/standard/php_crypt_r.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre Alain Joye . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre Alain Joye . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_dir_int.h b/ext/standard/php_dir_int.h index 06faf4e678f4..17fcbab7e1cb 100644 --- a/ext/standard/php_dir_int.h +++ b/ext/standard/php_dir_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/php_dns.h b/ext/standard/php_dns.h index 4e04799cdb8a..5b0a29f32bd1 100644 --- a/ext/standard/php_dns.h +++ b/ext/standard/php_dns.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: The typical suspects | | Marcus Boerger | diff --git a/ext/standard/php_ext_syslog.h b/ext/standard/php_ext_syslog.h index fd7958fad292..44c5ad1c02f4 100644 --- a/ext/standard/php_ext_syslog.h +++ b/ext/standard/php_ext_syslog.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h index ef3c1cd60c72..c2ea6eed66e2 100644 --- a/ext/standard/php_filestat.h +++ b/ext/standard/php_filestat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index ea33ba490434..3f062bf2ea1e 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -158,14 +156,18 @@ static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, i if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) { php_stream_filter_append(&stream->readfilters, temp_filter); } else { - php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p); + php_stream_wrapper_warn_nt(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + CreateFailed, + "Unable to create filter (%s)", p); } } if (write_chain) { if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) { php_stream_filter_append(&stream->writefilters, temp_filter); } else { - php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p); + php_stream_wrapper_warn_nt(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + CreateFailed, + "Unable to create filter (%s)", p); } } p = php_strtok_r(NULL, "|", &token); @@ -219,7 +221,9 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration"); + php_stream_wrapper_warn(wrapper, context, options, + Disabled, + "URL file-access is disabled in the server configuration"); } return NULL; } @@ -238,7 +242,9 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c if (!strcasecmp(path, "stdin")) { if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration"); + php_stream_wrapper_warn(wrapper, context, options, + Disabled, + "URL file-access is disabled in the server configuration"); } return NULL; } @@ -297,14 +303,18 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c if (strcmp(sapi_module.name, "cli")) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP"); + php_stream_wrapper_warn(wrapper, context, options, + Disabled, + "Direct access to file descriptors is only available from command-line PHP"); } return NULL; } if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration"); + php_stream_wrapper_warn(wrapper, context, options, + Disabled, + "URL file-access is disabled in the server configuration"); } return NULL; } @@ -312,7 +322,8 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c start = &path[3]; fildes_ori = ZEND_STRTOL(start, &end, 10); if (end == start || *end != '\0') { - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidUrl, "php://fd/ stream must be specified in the form php://fd/"); return NULL; } @@ -324,14 +335,16 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c #endif if (fildes_ori < 0 || fildes_ori >= dtablesize) { - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidParam, "The file descriptors must be non-negative numbers smaller than %d", dtablesize); return NULL; } fd = dup((int)fildes_ori); if (fd == -1) { - php_stream_wrapper_log_error(wrapper, options, + php_stream_wrapper_log_warn(wrapper, context, options, + DupFailed, "Error duping file descriptor " ZEND_LONG_FMT "; possibly it doesn't exist: " "[%d]: %s", fildes_ori, errno, strerror(errno)); return NULL; @@ -380,7 +393,8 @@ static php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const c return stream; } else { /* invalid php://thingy */ - php_error_docref(NULL, E_WARNING, "Invalid php:// URL specified"); + php_stream_wrapper_warn(wrapper, context, options, + InvalidUrl, "Invalid php:// URL specified"); return NULL; } diff --git a/ext/standard/php_fopen_wrappers.h b/ext/standard/php_fopen_wrappers.h index 885e31ffa730..a7e027dcf89f 100644 --- a/ext/standard/php_fopen_wrappers.h +++ b/ext/standard/php_fopen_wrappers.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | diff --git a/ext/standard/php_http.h b/ext/standard/php_http.h index 9350be597ea1..6192d0e63cee 100644 --- a/ext/standard/php_http.h +++ b/ext/standard/php_http.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index 6a4e0987d13d..ea57214bda0b 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | diff --git a/ext/standard/php_incomplete_class.h b/ext/standard/php_incomplete_class.h index 07eabf60d5dc..fb49eaf1b693 100644 --- a/ext/standard/php_incomplete_class.h +++ b/ext/standard/php_incomplete_class.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index bebb526699d0..f7320f1d0700 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 9ebd600537fd..cb0b9db21599 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | diff --git a/ext/standard/php_math_round_mode.h b/ext/standard/php_math_round_mode.h index 9ab02de2c361..abc3c7e284a5 100644 --- a/ext/standard/php_math_round_mode.h +++ b/ext/standard/php_math_round_mode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | diff --git a/ext/standard/php_net.h b/ext/standard/php_net.h index 58739131232d..beabb12caac9 100644 --- a/ext/standard/php_net.h +++ b/ext/standard/php_net.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_password.h b/ext/standard/php_password.h index 5a6f3b2af5c9..6442b782c256 100644 --- a/ext/standard/php_password.h +++ b/ext/standard/php_password.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara | | Charles R. Portwood II | diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h index 5bc792362bbd..34715e966683 100644 --- a/ext/standard/php_standard.h +++ b/ext/standard/php_standard.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index ef62329ba8ed..86c331f8a7c5 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Sæther Bakken | diff --git a/ext/standard/php_uuencode.h b/ext/standard/php_uuencode.h index da3d601851d9..e3d810f1c95f 100644 --- a/ext/standard/php_uuencode.h +++ b/ext/standard/php_uuencode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index d70bbfed814a..8839a2f3df73 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jani Lehtimäki | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_versioning.h b/ext/standard/php_versioning.h index 307ac1234a8c..da3748079aa3 100644 --- a/ext/standard/php_versioning.h +++ b/ext/standard/php_versioning.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 55f4dd484958..beeb157e53a5 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -35,7 +33,7 @@ #include #endif -#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP +#if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) || defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) /* Only defined on glibc >= 2.29, FreeBSD CURRENT, musl >= 1.1.24, * MacOS Catalina or later.. * It should be possible to modify this so it is also @@ -44,7 +42,24 @@ * to be really buggy. */ #include +#ifdef __APPLE__ +#include +#endif #define USE_POSIX_SPAWN + +/* The non-_np variant is in macOS 26 (and _np deprecated). On Apple, it has to be selected by the + * deployment target rather than the configure check: the link check passes whenever the SDK + * exports the symbol even if the running system is older, in which case the weakly linked + * reference resolves to NULL at runtime. */ +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 260000 +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir +#elif defined(__APPLE__) +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir_np +#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir +#else +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir_np +#endif #endif /* This symbol is defined in ext/standard/config.m4. @@ -261,7 +276,7 @@ static void proc_open_rsrc_dtor(zend_resource *rsrc) php_process_handle *proc = (php_process_handle*)rsrc->ptr; #ifdef PHP_WIN32 DWORD wstatus; -#elif HAVE_SYS_WAIT_H +#elif defined(HAVE_SYS_WAIT_H) int wstatus; int waitpid_options = 0; pid_t wait_pid; @@ -292,7 +307,7 @@ static void proc_open_rsrc_dtor(zend_resource *rsrc) } CloseHandle(proc->childHandle); -#elif HAVE_SYS_WAIT_H +#elif defined(HAVE_SYS_WAIT_H) if (!FG(pclose_wait)) { waitpid_options = WNOHANG; } @@ -384,7 +399,7 @@ PHP_FUNCTION(proc_get_status) php_process_handle *proc; #ifdef PHP_WIN32 DWORD wstatus; -#elif HAVE_SYS_WAIT_H +#elif defined(HAVE_SYS_WAIT_H) int wstatus; pid_t wait_pid; #endif @@ -413,7 +428,7 @@ PHP_FUNCTION(proc_get_status) * even if the child has already exited. This is because the result stays available * until the child handle is closed. Hence no caching is used on Windows. */ add_assoc_bool(return_value, "cached", false); -#elif HAVE_SYS_WAIT_H +#elif defined(HAVE_SYS_WAIT_H) wait_pid = waitpid_cached(proc, &wstatus, WNOHANG|WUNTRACED); if (wait_pid == proc->child) { @@ -1017,7 +1032,7 @@ static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int targe case 0: redirect_to = GetStdHandle(STD_INPUT_HANDLE); break; case 1: redirect_to = GetStdHandle(STD_OUTPUT_HANDLE); break; case 2: redirect_to = GetStdHandle(STD_ERROR_HANDLE); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } #endif } @@ -1235,7 +1250,7 @@ PHP_FUNCTION(proc_open) Z_PARAM_ARRAY_HT(descriptorspec) Z_PARAM_ZVAL(pipes) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(cwd, cwd_len) + Z_PARAM_PATH_OR_NULL(cwd, cwd_len) Z_PARAM_ARRAY_HT_OR_NULL(environment) Z_PARAM_ARRAY_OR_NULL(other_options) ZEND_PARSE_PARAMETERS_END(); @@ -1372,7 +1387,6 @@ PHP_FUNCTION(proc_open) if (newprocok == FALSE) { DWORD dw = GetLastError(); - close_all_descriptors(descriptors, ndesc); char *msg = php_win32_error_to_msg(dw); php_error_docref(NULL, E_WARNING, "CreateProcess failed: %s", msg); php_win32_error_msg_free(msg); @@ -1389,14 +1403,13 @@ PHP_FUNCTION(proc_open) if (close_parentends_of_pipes(&factions, descriptors, ndesc) == FAILURE) { posix_spawn_file_actions_destroy(&factions); - close_all_descriptors(descriptors, ndesc); goto exit_fail; } if (cwd) { - r = posix_spawn_file_actions_addchdir_np(&factions, cwd); + r = POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR(&factions, cwd); if (r != 0) { - php_error_docref(NULL, E_WARNING, "posix_spawn_file_actions_addchdir_np() failed: %s", strerror(r)); + php_error_docref(NULL, E_WARNING, ZEND_TOSTR(POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) "() failed: %s", strerror(r)); } } @@ -1409,7 +1422,6 @@ PHP_FUNCTION(proc_open) } posix_spawn_file_actions_destroy(&factions); if (r != 0) { - close_all_descriptors(descriptors, ndesc); php_error_docref(NULL, E_WARNING, "posix_spawn() failed: %s", strerror(r)); goto exit_fail; } @@ -1451,7 +1463,6 @@ PHP_FUNCTION(proc_open) _exit(127); } else if (child < 0) { /* Failed to fork() */ - close_all_descriptors(descriptors, ndesc); php_error_docref(NULL, E_WARNING, "Fork failed: %s", strerror(errno)); goto exit_fail; } @@ -1541,6 +1552,9 @@ PHP_FUNCTION(proc_open) } else { exit_fail: _php_free_envp(env); + if (descriptors) { + close_all_descriptors(descriptors, ndesc); + } RETVAL_FALSE; } diff --git a/ext/standard/proc_open.h b/ext/standard/proc_open.h index 2dba712f995f..6a9e0533bfd2 100644 --- a/ext/standard/proc_open.h +++ b/ext/standard/proc_open.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c index a7132df2f7fd..e9d8fafb9987 100644 --- a/ext/standard/quot_print.c +++ b/ext/standard/quot_print.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kirill Maximov | +----------------------------------------------------------------------+ @@ -212,11 +210,11 @@ PHP_FUNCTION(quoted_printable_decode) switch (str_in[i]) { case '=': if (str_in[i + 1] && str_in[i + 2] && - isxdigit((int) str_in[i + 1]) && - isxdigit((int) str_in[i + 2])) + isxdigit((unsigned char)str_in[i + 1]) && + isxdigit((unsigned char)str_in[i + 2])) { - ZSTR_VAL(str_out)[j++] = (php_hex2int((int) str_in[i + 1]) << 4) - + php_hex2int((int) str_in[i + 2]); + ZSTR_VAL(str_out)[j++] = (php_hex2int((unsigned char)str_in[i + 1]) << 4) + + php_hex2int((unsigned char)str_in[i + 2]); i += 3; } else /* check for soft line break according to RFC 2045*/ { k = 1; diff --git a/ext/standard/quot_print.h b/ext/standard/quot_print.h index 11b829d974b8..faf515210695 100644 --- a/ext/standard/quot_print.h +++ b/ext/standard/quot_print.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kirill Maximov (kir@rus.net) | +----------------------------------------------------------------------+ diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 408e5ede8881..5aeb585fea23 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Clayton Collie | +----------------------------------------------------------------------+ @@ -345,7 +343,7 @@ PHPAPI int ValidateFormat(char *format, int numVars, int *totalSubs) goto xpgCheckDone; } - if ( isdigit( (int)*ch ) ) { + if ( isdigit( (unsigned char)*ch ) ) { /* * Check for an XPG3-style %n$ specification. Note: there * must not be a mixture of XPG3 specs and non-XPG3 specs @@ -656,9 +654,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, /* * If we see whitespace in the format, skip whitespace in the string. */ - if ( isspace( (int)*ch ) ) { + if ( isspace( (unsigned char)*ch ) ) { sch = *string; - while ( isspace( (int)sch ) ) { + while ( isspace( (unsigned char)sch ) ) { if (*string == '\0') { goto done; } @@ -809,7 +807,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { sch = *string; - if (! isspace((int)sch) ) { + if (! isspace((unsigned char)sch) ) { break; } string++; @@ -835,7 +833,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, end = string; while (*end != '\0') { sch = *end; - if ( isspace( (int)sch ) ) { + if ( isspace( (unsigned char)sch ) ) { break; } end++; diff --git a/ext/standard/scanf.h b/ext/standard/scanf.h index d2ef2fc0f2e8..c60a2b664ad4 100644 --- a/ext/standard/scanf.h +++ b/ext/standard/scanf.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Clayton Collie | +----------------------------------------------------------------------+ diff --git a/ext/standard/sha1.c b/ext/standard/sha1.c index 95f2b54d0fd0..4832756f577a 100644 --- a/ext/standard/sha1.c +++ b/ext/standard/sha1.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ diff --git a/ext/standard/sha1.h b/ext/standard/sha1.h index 046d6db2cc47..a1f4801736b1 100644 --- a/ext/standard/sha1.h +++ b/ext/standard/sha1.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c index 5c45f4d3ef67..f06c3ac98572 100644 --- a/ext/standard/soundex.c +++ b/ext/standard/soundex.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Bjørn Borud - Guardian Networks AS | +----------------------------------------------------------------------+ @@ -65,7 +63,7 @@ PHP_FUNCTION(soundex) /* BUG: should also map here accented letters used in non */ /* English words or names (also found in English text!): */ /* esstsett, thorn, n-tilde, c-cedilla, s-caron, ... */ - code = toupper((int)(unsigned char)str[i]); + code = toupper((unsigned char)str[i]); if (code >= 'A' && code <= 'Z') { if (_small == 0) { /* remember first valid char */ diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 506ce0dafed8..d544e8bf5f0f 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Sara Golemon | @@ -23,6 +21,7 @@ #include "streamsfuncs.h" #include "php_network.h" #include "php_string.h" +#include "streams/php_streams_int.h" #ifdef HAVE_UNISTD_H #include #endif @@ -50,11 +49,15 @@ PHP_FUNCTION(stream_socket_pair) zend_long domain, type, protocol; php_stream *s1, *s2; php_socket_t pair[2]; + zval *zcontext = NULL; + php_stream_context *context = NULL; - ZEND_PARSE_PARAMETERS_START(3, 3) + ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_LONG(domain) Z_PARAM_LONG(type) Z_PARAM_LONG(protocol) + Z_PARAM_OPTIONAL + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); if (0 != socketpair((int)domain, (int)type, (int)protocol, pair)) { @@ -64,10 +67,14 @@ PHP_FUNCTION(stream_socket_pair) RETURN_FALSE; } + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); + s1 = php_stream_sock_open_from_socket(pair[0], 0); if (s1 == NULL) { close(pair[0]); close(pair[1]); + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Failed to open stream from socketpair"); RETURN_FALSE; } @@ -75,6 +82,7 @@ PHP_FUNCTION(stream_socket_pair) if (s2 == NULL) { php_stream_free(s1, PHP_STREAM_FREE_CLOSE); close(pair[1]); + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Failed to open stream from socketpair"); RETURN_FALSE; } @@ -88,6 +96,8 @@ PHP_FUNCTION(stream_socket_pair) add_next_index_resource(return_value, s1->res); add_next_index_resource(return_value, s2->res); + + php_stream_error_operation_end(context); } /* }}} */ #endif @@ -126,10 +136,13 @@ PHP_FUNCTION(stream_socket_client) RETURN_THROWS(); } + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); if (flags & PHP_STREAM_CLIENT_PERSISTENT) { - spprintf(&hashkey, 0, "stream_socket_client__%s", ZSTR_VAL(host)); + zend_string *escaped = php_stream_escape_persistent_key(ZSTR_VAL(host), ZSTR_LEN(host)); + spprintf(&hashkey, 0, "stream_socket_client__%s", ZSTR_VAL(escaped)); + zend_string_release_ex(escaped, false); } /* prepare the timeout value for use */ @@ -160,6 +173,7 @@ PHP_FUNCTION(stream_socket_client) (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? STREAM_XPORT_CONNECT_ASYNC : 0), hashkey, tv_pointer, context, &errstr, &err); + php_stream_error_operation_end(context); if (stream == NULL) { /* host might contain binary characters */ @@ -217,6 +231,7 @@ PHP_FUNCTION(stream_socket_server) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); if (zerrno) { @@ -230,6 +245,8 @@ PHP_FUNCTION(stream_socket_server) STREAM_XPORT_SERVER | (int)flags, NULL, NULL, context, &errstr, &err); + php_stream_error_operation_end(context); + if (stream == NULL) { php_error_docref(NULL, E_WARNING, "Unable to connect to %s (%s)", host, errstr == NULL ? "Unknown error" : ZSTR_VAL(errstr)); } @@ -295,6 +312,8 @@ PHP_FUNCTION(stream_socket_accept) tv_pointer = &tv; } + php_stream_error_operation_begin(); + if (0 == php_stream_xport_accept(stream, &clistream, zpeername ? &peername : NULL, NULL, NULL, @@ -309,10 +328,12 @@ PHP_FUNCTION(stream_socket_accept) if (peername) { zend_string_release(peername); } - php_error_docref(NULL, E_WARNING, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error"); + php_stream_warn(stream, AcceptFailed, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error"); RETVAL_FALSE; } + php_stream_error_operation_end_for_stream(stream); + if (errstr) { zend_string_release_ex(errstr, 0); } @@ -331,10 +352,11 @@ PHP_FUNCTION(stream_socket_get_name) Z_PARAM_BOOL(want_peer) ZEND_PARSE_PARAMETERS_END(); - if (0 != php_stream_xport_get_name(stream, want_peer, - &name, - NULL, NULL - ) || !name) { + php_stream_error_operation_begin(); + int ret = php_stream_xport_get_name(stream, want_peer, &name, NULL, NULL); + php_stream_error_operation_end_for_stream(stream); + + if (0 != ret || !name) { RETURN_FALSE; } @@ -365,15 +387,18 @@ PHP_FUNCTION(stream_socket_sendto) Z_PARAM_STRING(target_addr, target_addr_len) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); if (target_addr_len) { /* parse the address */ if (FAILURE == php_network_parse_network_address_with_port(target_addr, target_addr_len, (struct sockaddr*)&sa, &sl)) { + php_stream_error_operation_end_for_stream(stream); php_error_docref(NULL, E_WARNING, "Failed to parse `%s' into a valid network address", target_addr); RETURN_FALSE; } } - RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr_len ? &sa : NULL, sl)); + RETVAL_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr_len ? &sa : NULL, sl)); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -407,9 +432,10 @@ PHP_FUNCTION(stream_socket_recvfrom) read_buf = zend_string_alloc(to_read, 0); + php_stream_error_operation_begin(); recvd = php_stream_xport_recvfrom(stream, ZSTR_VAL(read_buf), to_read, (int)flags, NULL, NULL, - zremote ? &remote_addr : NULL - ); + zremote ? &remote_addr : NULL); + php_stream_error_operation_end_for_stream(stream); if (recvd >= 0) { if (zremote && remote_addr) { @@ -447,6 +473,8 @@ PHP_FUNCTION(stream_get_contents) RETURN_THROWS(); } + php_stream_error_operation_begin(); + if (desiredpos >= 0) { int seek_res = 0; zend_off_t position; @@ -461,6 +489,7 @@ PHP_FUNCTION(stream_get_contents) } if (seek_res != 0) { + php_stream_error_operation_end_for_stream(stream); php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", desiredpos); RETURN_FALSE; @@ -468,10 +497,11 @@ PHP_FUNCTION(stream_get_contents) } if ((contents = php_stream_copy_to_mem(stream, maxlen, 0))) { - RETURN_STR(contents); + RETVAL_STR(contents); } else { - RETURN_EMPTY_STRING(); + RETVAL_EMPTY_STRING(); } + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -482,28 +512,37 @@ PHP_FUNCTION(stream_copy_to_stream) zend_long maxlen, pos = 0; bool maxlen_is_null = 1; size_t len; + zval *zcontext = NULL; + php_stream_context *context = NULL; - ZEND_PARSE_PARAMETERS_START(2, 4) + ZEND_PARSE_PARAMETERS_START(2, 5) PHP_Z_PARAM_STREAM(src) PHP_Z_PARAM_STREAM(dest) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG(pos) + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); if (maxlen_is_null) { maxlen = PHP_STREAM_COPY_ALL; } + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); + if (pos > 0 && php_stream_seek(src, pos, SEEK_SET) < 0) { + php_stream_error_operation_end(context); php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", pos); RETURN_FALSE; } if (php_stream_copy_to_stream_ex(src, dest, maxlen, &len) != SUCCESS) { - RETURN_FALSE; + RETVAL_FALSE; + } else { + RETVAL_LONG(len); } - RETURN_LONG(len); + php_stream_error_operation_end(context); } /* }}} */ @@ -518,11 +557,13 @@ PHP_FUNCTION(stream_get_meta_data) array_init(return_value); + php_stream_error_operation_begin(); if (!php_stream_populate_meta_data(stream, return_value)) { add_assoc_bool(return_value, "timed_out", 0); add_assoc_bool(return_value, "blocked", 1); add_assoc_bool(return_value, "eof", php_stream_eof(stream)); } + php_stream_error_operation_end_for_stream(stream); if (!Z_ISUNDEF(stream->wrapperdata)) { Z_ADDREF_P(&stream->wrapperdata); @@ -594,6 +635,18 @@ PHP_FUNCTION(stream_get_wrappers) } /* }}} */ +PHP_FUNCTION(stream_last_errors) +{ + ZEND_PARSE_PARAMETERS_NONE(); + php_stream_error_get_last(return_value); +} + +PHP_FUNCTION(stream_clear_errors) +{ + ZEND_PARSE_PARAMETERS_NONE(); + php_stream_error_clear_stored(); +} + /* {{{ stream_select related functions */ static int stream_array_to_fd_set(const HashTable *stream_array, fd_set *fds, php_socket_t *max_fd) { @@ -726,7 +779,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array) /* {{{ Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */ PHP_FUNCTION(stream_select) { - zval *r_array, *w_array, *e_array; + zval *r_array, *w_array, *e_array, *zcontext = NULL; struct timeval tv, *tv_p = NULL; fd_set rfds, wfds, efds; php_socket_t max_fd = 0; @@ -735,20 +788,25 @@ PHP_FUNCTION(stream_select) bool secnull; bool usecnull = 1; int set_count, max_set_count = 0; + php_stream_context *context = NULL; - ZEND_PARSE_PARAMETERS_START(4, 5) + ZEND_PARSE_PARAMETERS_START(4, 6) Z_PARAM_ARRAY_EX2(r_array, 1, 1, 0) Z_PARAM_ARRAY_EX2(w_array, 1, 1, 0) Z_PARAM_ARRAY_EX2(e_array, 1, 1, 0) Z_PARAM_LONG_OR_NULL(sec, secnull) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(usec, usecnull) + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); + if (r_array != NULL) { set_count = stream_array_to_fd_set(Z_ARR_P(r_array), &rfds, &max_fd); if (set_count > max_set_count) @@ -771,6 +829,7 @@ PHP_FUNCTION(stream_select) } if (!sets) { + php_stream_error_operation_end(context); zend_value_error("No stream arrays were passed"); RETURN_THROWS(); } @@ -781,6 +840,7 @@ PHP_FUNCTION(stream_select) if (secnull && !usecnull) { if (usec != 0) { + php_stream_error_operation_end(context); zend_argument_value_error(5, "must be null when argument #4 ($seconds) is null"); RETURN_THROWS(); } @@ -789,9 +849,11 @@ PHP_FUNCTION(stream_select) /* If seconds is not set to null, build the timeval, else we wait indefinitely */ if (!secnull) { if (sec < 0) { + php_stream_error_operation_end(context); zend_argument_value_error(4, "must be greater than or equal to 0"); RETURN_THROWS(); } else if (usec < 0) { + php_stream_error_operation_end(context); zend_argument_value_error(5, "must be greater than or equal to 0"); RETURN_THROWS(); } @@ -808,6 +870,7 @@ PHP_FUNCTION(stream_select) if (r_array != NULL) { retval = stream_array_emulate_read_fd_set(r_array); if (retval > 0) { + php_stream_error_operation_end(context); if (w_array != NULL) { zval_ptr_dtor(w_array); ZVAL_EMPTY_ARRAY(w_array); @@ -821,6 +884,7 @@ PHP_FUNCTION(stream_select) } retval = php_select(max_fd+1, &rfds, &wfds, &efds, tv_p); + php_stream_error_operation_end(context); if (retval == -1) { php_error_docref(NULL, E_WARNING, "Unable to select [%d]: %s (max_fd=" PHP_SOCKET_FMT ")", @@ -1147,6 +1211,24 @@ PHP_FUNCTION(stream_context_get_default) } /* }}} */ +/* Check if options contain stream error handling settings */ +static bool php_stream_context_options_has_error_settings(const HashTable *options) +{ + zval *stream_options = zend_hash_str_find(options, ZEND_STRL("stream")); + if (!stream_options) { + return false; + } + + ZVAL_DEREF(stream_options); + if (Z_TYPE_P(stream_options) != IS_ARRAY) { + return false; + } + + return zend_hash_str_exists(Z_ARRVAL_P(stream_options), ZEND_STRL("error_mode")) + || zend_hash_str_exists(Z_ARRVAL_P(stream_options), ZEND_STRL("error_store")) + || zend_hash_str_exists(Z_ARRVAL_P(stream_options), ZEND_STRL("error_handler")); +} + /* {{{ Set default file/stream context, returns the context as a resource */ PHP_FUNCTION(stream_context_set_default) { @@ -1162,6 +1244,11 @@ PHP_FUNCTION(stream_context_set_default) } context = FG(default_context); + if (php_stream_context_options_has_error_settings(options)) { + zend_value_error("Stream error handling options cannot be set on the default context"); + RETURN_THROWS(); + } + if (parse_context_options(context, options) == FAILURE) { RETURN_THROWS(); } @@ -1341,11 +1428,13 @@ PHP_FUNCTION(stream_get_line) max_length = PHP_SOCK_CHUNK_SIZE; } + php_stream_error_operation_begin(); if ((buf = php_stream_get_record(stream, max_length, str, str_len))) { - RETURN_STR(buf); + RETVAL_STR(buf); } else { - RETURN_FALSE; + RETVAL_FALSE; } + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -1361,7 +1450,9 @@ PHP_FUNCTION(stream_set_blocking) Z_PARAM_BOOL(block) ZEND_PARSE_PARAMETERS_END(); - RETURN_BOOL(-1 != php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL)); + php_stream_error_operation_begin(); + RETVAL_BOOL(-1 != php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL)); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ @@ -1402,7 +1493,9 @@ PHP_FUNCTION(stream_set_timeout) } #endif - RETURN_BOOL(PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)); + php_stream_error_operation_begin(); + RETVAL_BOOL(PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)); + php_stream_error_operation_end_for_stream(stream); } #endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */ /* }}} */ @@ -1422,12 +1515,14 @@ PHP_FUNCTION(stream_set_write_buffer) buff = arg2; + php_stream_error_operation_begin(); /* if buff is 0 then set to non-buffered */ if (buff == 0) { ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } else { ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); } + php_stream_error_operation_end_for_stream(stream); RETURN_LONG(ret == 0 ? 0 : EOF); } @@ -1458,7 +1553,9 @@ PHP_FUNCTION(stream_set_chunk_size) RETURN_THROWS(); } + php_stream_error_operation_begin(); ret = php_stream_set_option(stream, PHP_STREAM_OPTION_SET_CHUNK_SIZE, (int)csize, NULL); + php_stream_error_operation_end_for_stream(stream); RETURN_LONG(ret > 0 ? (zend_long)ret : (zend_long)EOF); } @@ -1479,12 +1576,14 @@ PHP_FUNCTION(stream_set_read_buffer) buff = arg2; + php_stream_error_operation_begin(); /* if buff is 0 then set to non-buffered */ if (buff == 0) { ret = php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } else { ret = php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); } + php_stream_error_operation_end_for_stream(stream); RETURN_LONG(ret == 0 ? 0 : EOF); } @@ -1506,11 +1605,14 @@ PHP_FUNCTION(stream_socket_enable_crypto) PHP_Z_PARAM_STREAM_OR_NULL(sessstream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); + if (enable) { if (cryptokindnull) { zval *val; if (!GET_CTX_OPT(stream, "ssl", "crypto_method", val)) { + php_stream_error_operation_end_for_stream(stream); zend_argument_value_error(3, "must be specified when enabling encryption"); RETURN_THROWS(); } @@ -1519,11 +1621,13 @@ PHP_FUNCTION(stream_socket_enable_crypto) } if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream) < 0) { + php_stream_error_operation_end_for_stream(stream); RETURN_FALSE; } } ret = php_stream_xport_crypto_enable(stream, enable); + php_stream_error_operation_end_for_stream(stream); switch (ret) { case -1: RETURN_FALSE; @@ -1537,6 +1641,18 @@ PHP_FUNCTION(stream_socket_enable_crypto) } /* }}} */ +/* Get crypto status */ +PHP_FUNCTION(stream_socket_get_crypto_status) +{ + php_stream *stream; + + ZEND_PARSE_PARAMETERS_START(1, 1) + PHP_Z_PARAM_STREAM(stream) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(php_stream_xport_crypto_get_status(stream)); +} + /* {{{ Determine what file will be opened by calls to fopen() with a relative path */ PHP_FUNCTION(stream_resolve_include_path) { @@ -1559,12 +1675,15 @@ PHP_FUNCTION(stream_resolve_include_path) /* {{{ */ PHP_FUNCTION(stream_is_local) { - zval *zstream; + zval *zstream, *zcontext = NULL; php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; + php_stream_context *context = NULL; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ZVAL(zstream) + Z_PARAM_OPTIONAL + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); if (Z_TYPE_P(zstream) == IS_RESOURCE) { @@ -1575,7 +1694,10 @@ PHP_FUNCTION(stream_is_local) RETURN_THROWS(); } + php_stream_error_operation_begin(); + context = php_stream_context_from_zval(zcontext, 0); wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, 0); + php_stream_error_operation_end(context); } RETURN_BOOL(wrapper && wrapper->is_url == 0); @@ -1591,7 +1713,9 @@ PHP_FUNCTION(stream_supports_lock) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - RETURN_BOOL(php_stream_supports_lock(stream)); + php_stream_error_operation_begin(); + RETVAL_BOOL(php_stream_supports_lock(stream)); + php_stream_error_operation_end_for_stream(stream); } /* {{{ Check if a stream is a TTY. */ @@ -1604,6 +1728,8 @@ PHP_FUNCTION(stream_isatty) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); + /* get the fd. * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting. * It is only used here so that the buffered data warning is not displayed. @@ -1613,8 +1739,10 @@ PHP_FUNCTION(stream_isatty) } else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL) == SUCCESS) { php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)&fileno, 0); } else { + php_stream_error_operation_end_for_stream(stream); RETURN_FALSE; } + php_stream_error_operation_end_for_stream(stream); #ifdef PHP_WIN32 /* Check if the Windows standard handle is redirected to file */ @@ -1644,6 +1772,8 @@ PHP_FUNCTION(sapi_windows_vt100_support) Z_PARAM_BOOL_OR_NULL(enable, enable_is_null) ZEND_PARSE_PARAMETERS_END(); + php_stream_error_operation_begin(); + /* get the fd. * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting. * It is only used here so that the buffered data warning is not displayed. @@ -1653,6 +1783,7 @@ PHP_FUNCTION(sapi_windows_vt100_support) } else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL) == SUCCESS) { php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)&fileno, 0); } else { + php_stream_error_operation_end_for_stream(stream); if (!enable_is_null) { php_error_docref( NULL, @@ -1662,6 +1793,7 @@ PHP_FUNCTION(sapi_windows_vt100_support) } RETURN_FALSE; } + php_stream_error_operation_end_for_stream(stream); /* Check if the file descriptor is a console */ if (!php_win32_console_fileno_is_console(fileno)) { @@ -1701,7 +1833,9 @@ PHP_FUNCTION(stream_socket_shutdown) RETURN_THROWS(); } - RETURN_BOOL(php_stream_xport_shutdown(stream, (stream_shutdown_t)how) == 0); + php_stream_error_operation_begin(); + RETVAL_BOOL(php_stream_xport_shutdown(stream, (stream_shutdown_t)how) == 0); + php_stream_error_operation_end_for_stream(stream); } /* }}} */ #endif diff --git a/ext/standard/streamsfuncs.h b/ext/standard/streamsfuncs.h index 41058472473d..7d6f523bfcd0 100644 --- a/ext/standard/streamsfuncs.h +++ b/ext/standard/streamsfuncs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/standard/string.c b/ext/standard/string.c index 7d609a032dd1..823c32a8cf1e 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Sæther Bakken | @@ -25,10 +23,6 @@ # include #endif -#ifdef HAVE_LIBINTL -# include /* For LC_MESSAGES */ -#endif - #include "scanf.h" #include "zend_API.h" #include "zend_execute.h" @@ -51,32 +45,11 @@ #include "zend_simd.h" -/* this is read-only, so it's ok */ -ZEND_SET_ALIGNED(16, static const char hexconvtab[]) = "0123456789abcdef"; - /* localeconv mutex */ #ifdef ZTS static MUTEX_T locale_mutex = NULL; #endif -/* {{{ php_bin2hex */ -static zend_string *php_bin2hex(const unsigned char *old, const size_t oldlen) -{ - zend_string *result; - size_t i, j; - - result = zend_string_safe_alloc(oldlen, 2 * sizeof(char), 0, 0); - - for (i = j = 0; i < oldlen; i++) { - ZSTR_VAL(result)[j++] = hexconvtab[old[i] >> 4]; - ZSTR_VAL(result)[j++] = hexconvtab[old[i] & 15]; - } - ZSTR_VAL(result)[j] = '\0'; - - return result; -} -/* }}} */ - /* {{{ php_hex2bin */ static zend_string *php_hex2bin(const unsigned char *old, const size_t oldlen) { @@ -164,7 +137,7 @@ PHP_FUNCTION(bin2hex) Z_PARAM_STR(data) ZEND_PARSE_PARAMETERS_END(); - result = php_bin2hex((unsigned char *)ZSTR_VAL(data), ZSTR_LEN(data)); + result = zend_bin2hex_str((unsigned char *) ZSTR_VAL(data), ZSTR_LEN(data)); RETURN_STR(result); } @@ -916,7 +889,7 @@ PHP_FUNCTION(explode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(delim) == 0) { - zend_argument_must_not_be_empty_error(1); + zend_argument_value_error(1, "must not be empty, use str_split() to split a string into characters"); RETURN_THROWS(); } @@ -1591,6 +1564,16 @@ PHP_FUNCTION(pathinfo) Z_PARAM_LONG(opt) ZEND_PARSE_PARAMETERS_END(); + if (opt < PHP_PATHINFO_DIRNAME || opt > PHP_PATHINFO_ALL) { + zend_argument_value_error(2, "must be one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + + if (opt < PHP_PATHINFO_ALL && (opt & (opt - 1))) { + zend_argument_value_error(2, "must be only one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + have_basename = (opt & PHP_PATHINFO_BASENAME); array_init(&tmp); @@ -1878,13 +1861,7 @@ PHP_FUNCTION(str_ends_with) Z_PARAM_STR(needle) ZEND_PARSE_PARAMETERS_END(); - if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) { - RETURN_FALSE; - } - - RETURN_BOOL(memcmp( - ZSTR_VAL(haystack) + ZSTR_LEN(haystack) - ZSTR_LEN(needle), - ZSTR_VAL(needle), ZSTR_LEN(needle)) == 0); + RETURN_BOOL(zend_string_ends_with(haystack, needle)); } /* }}} */ @@ -2203,10 +2180,10 @@ PHP_FUNCTION(chunk_split) if ((size_t)chunklen > ZSTR_LEN(str)) { /* to maintain BC, we must return original string + ending */ - result = zend_string_safe_alloc(ZSTR_LEN(str), 1, endlen, 0); - memcpy(ZSTR_VAL(result), ZSTR_VAL(str), ZSTR_LEN(str)); - memcpy(ZSTR_VAL(result) + ZSTR_LEN(str), end, endlen); - ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; + result = zend_string_concat2( + ZSTR_VAL(str), ZSTR_LEN(str), + end, endlen + ); RETURN_NEW_STR(result); } @@ -3752,9 +3729,9 @@ PHPAPI void php_stripcslashes(zend_string *str) case 'f': *target++='\f'; nlen--; break; case '\\': *target++='\\'; nlen--; break; case 'x': - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[0] = *++source; - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[1] = *++source; numtmp[2] = '\0'; nlen-=3; @@ -4609,7 +4586,7 @@ PHP_FUNCTION(hebrev) do { if (block_type == _HEB_BLOCK_TYPE_HEB) { - while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end block_start) { + while ((_isblank((int)*tmp) || ispunct((unsigned char)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) { tmp--; block_end--; } @@ -5004,7 +4981,7 @@ PHP_FUNCTION(parse_str) size_t arglen; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STRING(arg, arglen) + Z_PARAM_PATH(arg, arglen) Z_PARAM_ZVAL(arrayArg) ZEND_PARSE_PARAMETERS_END(); @@ -5059,7 +5036,7 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { done = true; break; default: - if (!isspace((int)c)) { + if (!isspace((unsigned char)c)) { if (state == 0) { state=1; } @@ -5149,7 +5126,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_ if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { *(rp++) = c; break; } @@ -5196,7 +5173,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_ if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { goto reg_char_1; } depth++; @@ -5755,7 +5732,7 @@ PHP_FUNCTION(substr_count) static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *pad_str, size_t pad_str_len) { char *p = ZSTR_VAL(result) + ZSTR_LEN(result); - + if (pad_str_len == 1) { memset(p, pad_str[0], pad_chars); ZSTR_LEN(result) += pad_chars; @@ -5770,7 +5747,7 @@ static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char * if (p < end) { memcpy(p, pad_str, end - p); } - + ZSTR_LEN(result) += pad_chars; } diff --git a/ext/standard/strnatcmp.c b/ext/standard/strnatcmp.c index 3c3f5a99232f..583cbb5dc47a 100644 --- a/ext/standard/strnatcmp.c +++ b/ext/standard/strnatcmp.c @@ -40,12 +40,12 @@ compare_right(char const **a, char const *aend, char const **b, char const *bend both numbers to know that they have the same magnitude, so we remember it in BIAS. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return bias; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) { if (!bias) @@ -67,12 +67,12 @@ compare_left(char const **a, char const *aend, char const **b, char const *bend) /* Compare two left-aligned numbers: the first to have a different value wins. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return 0; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) return -1; @@ -103,27 +103,27 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len ca = *ap; cb = *bp; /* skip over leading zeros */ - while (ca == '0' && (ap+1 < aend) && isdigit((int)(unsigned char)*(ap+1))) { + while (ca == '0' && (ap+1 < aend) && isdigit((unsigned char)ap[1])) { ca = *++ap; } - while (cb == '0' && (bp+1 < bend) && isdigit((int)(unsigned char)*(bp+1))) { + while (cb == '0' && (bp+1 < bend) && isdigit((unsigned char)bp[1])) { cb = *++bp; } while (1) { /* Skip consecutive whitespace */ - while (isspace((int)(unsigned char)ca)) { + while (isspace(ca)) { ca = *++ap; } - while (isspace((int)(unsigned char)cb)) { + while (isspace(cb)) { cb = *++bp; } /* process run of digits */ - if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) { + if (isdigit(ca) && isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) @@ -147,8 +147,8 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len } if (is_case_insensitive) { - ca = toupper((int)(unsigned char)ca); - cb = toupper((int)(unsigned char)cb); + ca = toupper(ca); + cb = toupper(cb); } if (ca < cb) diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index c5d73eb008ec..78dfb2297fdc 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ @@ -63,7 +61,7 @@ PHP_FUNCTION(openlog) size_t ident_len; ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_STRING(ident, ident_len) + Z_PARAM_PATH(ident, ident_len) Z_PARAM_LONG(option) Z_PARAM_LONG(facility) ZEND_PARSE_PARAMETERS_END(); diff --git a/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt new file mode 100644 index 000000000000..f8a01f48a115 --- /dev/null +++ b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt @@ -0,0 +1,22 @@ +--TEST-- +GHSA-96wq-48vp-hh57: signed integer overflow of char array offset +--CREDITS-- +Aleksey Solovev (Positive Technologies) +--INI-- +memory_limit=3G +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/standard/tests/array/array_change_key_case_flag_error.phpt b/ext/standard/tests/array/array_change_key_case_flag_error.phpt new file mode 100644 index 000000000000..e83a21815c99 --- /dev/null +++ b/ext/standard/tests/array/array_change_key_case_flag_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +array_change_key_case(): invalid $case argument +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: array_change_key_case(): Argument #2 ($case) must be either CASE_LOWER or CASE_UPPER diff --git a/ext/standard/tests/array/array_change_key_case_variation.phpt b/ext/standard/tests/array/array_change_key_case_variation.phpt deleted file mode 100644 index c221a3f34101..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---TEST-- -Test array_change_key_case() function - 2 ---FILE-- - 1, "two" => 2, "THREE" => 3, "FOUR" => "four"); - -/* use 'case' argument other than CASE_LOWER & CASE_UPPER */ -try { - var_dump(array_change_key_case($item, "CASE_UPPER")); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(array_change_key_case($item, 5)); - -/* when keys are different in terms of only case */ -/* should return one value key pair with key being in lowercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 3, "One" => 4) ) ); - -/* should return one value key pair with key being in uppercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 2, "One" => 3), CASE_UPPER ) ); -var_dump( array_change_key_case( array("ONE" => 1, "one" => 1, "One" => 2), 5 ) ); - -echo "end\n"; -?> ---EXPECT-- -array_change_key_case(): Argument #2 ($case) must be of type int, string given -array(4) { - ["ONE"]=> - int(1) - ["TWO"]=> - int(2) - ["THREE"]=> - int(3) - ["FOUR"]=> - string(4) "four" -} -array(1) { - ["one"]=> - int(4) -} -array(1) { - ["ONE"]=> - int(3) -} -array(1) { - ["ONE"]=> - int(2) -} -end diff --git a/ext/standard/tests/array/array_change_key_case_variation4.phpt b/ext/standard/tests/array/array_change_key_case_variation4.phpt deleted file mode 100644 index 82d211451638..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation4.phpt +++ /dev/null @@ -1,132 +0,0 @@ ---TEST-- -Test array_change_key_case() function : usage variations - different int values for $case ---FILE-- - 'un', 'TWO' => 'deux', 'three' => 'trois'); -for ($i = -5; $i <=5; $i += 1){ - echo "\n-- \$sort argument is $i --\n"; - $temp = $input; - var_dump(array_change_key_case($temp, $i)); -} - -echo "Done"; -?> ---EXPECT-- -*** Testing array_change_key_case() : usage variations *** - --- $sort argument is -5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 0 -- -array(3) { - ["one"]=> - string(2) "un" - ["two"]=> - string(4) "deux" - ["three"]=> - string(5) "trois" -} - --- $sort argument is 1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} -Done diff --git a/ext/standard/tests/array/array_diff_max_elements.phpt b/ext/standard/tests/array/array_diff_max_elements.phpt new file mode 100644 index 000000000000..4c65cd049b33 --- /dev/null +++ b/ext/standard/tests/array/array_diff_max_elements.phpt @@ -0,0 +1,16 @@ +--TEST-- +array_diff(): Max elements +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +The total number of elements must be lower than %d diff --git a/ext/standard/tests/array/array_map_foreach_optimization_006.phpt b/ext/standard/tests/array/array_map_foreach_optimization_006.phpt new file mode 100644 index 000000000000..4d37697a616c --- /dev/null +++ b/ext/standard/tests/array/array_map_foreach_optimization_006.phpt @@ -0,0 +1,84 @@ +--TEST-- +array_map(): foreach optimization - PFA +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T2 = DO_ICALL +0004 ASSIGN CV0($array) T2 +0005 TYPE_ASSERT 131079 string("array_map") CV0($array) +0006 T2 = INIT_ARRAY 0 (packed) NEXT +0007 V3 = FE_RESET_R CV0($array) 0015 +0008 T5 = FE_FETCH_R V3 T4 0015 +0009 INIT_FCALL 2 %d string("plusn") +0010 SEND_VAL T4 1 +0011 SEND_VAL int(2) 2 +0012 T4 = DO_UCALL +0013 T2 = ADD_ARRAY_ELEMENT T4 T5 +0014 JMP 0008 +0015 FE_FREE V3 +0016 ASSIGN CV1($foo) T2 +0017 INIT_FCALL 1 %d string("var_dump") +0018 SEND_VAR CV1($foo) 1 +0019 DO_ICALL +0020 RETURN int(1) +LIVE RANGES: + 2: 0007 - 0016 (tmp/var) + 3: 0008 - 0015 (loop) + 4: 0009 - 0010 (tmp/var) + 5: 0009 - 0013 (tmp/var) + +plusn: + ; (lines=4, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 CV1($n) = RECV 2 +0002 T2 = ADD CV0($x) CV1($n) +0003 RETURN T2 +array(10) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) + [3]=> + int(6) + [4]=> + int(7) + [5]=> + int(8) + [6]=> + int(9) + [7]=> + int(10) + [8]=> + int(11) + [9]=> + int(12) +} diff --git a/ext/standard/tests/array/array_map_foreach_optimization_007.phpt b/ext/standard/tests/array/array_map_foreach_optimization_007.phpt new file mode 100644 index 000000000000..8a406ef11ca6 --- /dev/null +++ b/ext/standard/tests/array/array_map_foreach_optimization_007.phpt @@ -0,0 +1,109 @@ +--TEST-- +array_map(): foreach optimization - unoptimizable PFA +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T2 = DO_ICALL +0004 ASSIGN CV0($array) T2 +0005 INIT_FCALL 2 %d string("array_map") +0006 INIT_FCALL 0 %d string("plusn") +0007 SEND_VAL int(2) string("n") +0008 T2 = CALLABLE_CONVERT_PARTIAL 2 +0009 SEND_VAL T2 1 +0010 SEND_VAR CV0($array) 2 +0011 T2 = DO_ICALL +0012 ASSIGN CV1($foo) T2 +0013 INIT_FCALL 1 %d string("var_dump") +0014 SEND_VAR CV1($foo) 1 +0015 DO_ICALL +0016 RETURN int(1) + +plusn: + ; (lines=4, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 CV1($n) = RECV 2 +0002 T2 = ADD CV0($x) CV1($n) +0003 RETURN T2 + +$_main: + ; (lines=4, args=0, vars=1, tmps=%d) + ; (after optimizer) + ; %s:1-9 +0000 T1 = DECLARE_LAMBDA_FUNCTION 0 +0001 BIND_LEXICAL T1 CV0($n) +0002 FREE T1 +0003 RETURN int(1) +LIVE RANGES: + 1: 0001 - 0002 (tmp/var) + +{closure:pfa:%s:9}: + ; (lines=18, args=1, vars=2, tmps=%d) + ; (after optimizer) + ; %s:9-9 +0000 CV0($x) = RECV 1 +0001 BIND_STATIC CV1($n) +0002 T3 = FUNC_NUM_ARGS +0003 T2 = IS_SMALLER_OR_EQUAL T3 int(1) +0004 JMPZ T2 0010 +0005 INIT_FCALL 2 %d string("plusn") +0006 SEND_VAR CV0($x) 1 +0007 SEND_VAR CV1($n) 2 +0008 T2 = DO_UCALL +0009 RETURN T2 +0010 INIT_FCALL 2 %d string("plusn") +0011 SEND_VAR CV0($x) 1 +0012 SEND_VAR CV1($n) 2 +0013 T2 = FUNC_GET_ARGS int(1) +0014 SEND_UNPACK T2 +0015 CHECK_UNDEF_ARGS +0016 T2 = DO_UCALL +0017 RETURN T2 +array(10) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) + [3]=> + int(6) + [4]=> + int(7) + [5]=> + int(8) + [6]=> + int(9) + [7]=> + int(10) + [8]=> + int(11) + [9]=> + int(12) +} diff --git a/ext/standard/tests/array/array_product_packed_long_overflow.phpt b/ext/standard/tests/array/array_product_packed_long_overflow.phpt new file mode 100644 index 000000000000..7c1d8a0adebd --- /dev/null +++ b/ext/standard/tests/array/array_product_packed_long_overflow.phpt @@ -0,0 +1,22 @@ +--TEST-- +array_product() packed long overflow continues in double mode +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt b/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt new file mode 100644 index 000000000000..f2a0639b3456 --- /dev/null +++ b/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt @@ -0,0 +1,35 @@ +--TEST-- +array_reduce(): accumulator refcount stays low during callback +--FILE-- + +--EXPECT-- +array(0) interned { +} +array(1) packed refcount(2){ + [0]=> + int(1) +} +array(2) packed refcount(2){ + [0]=> + int(1) + [1]=> + int(2) +} +array(3) packed refcount(2){ + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/ext/standard/tests/array/array_sum_packed_long_overflow.phpt b/ext/standard/tests/array/array_sum_packed_long_overflow.phpt new file mode 100644 index 000000000000..22e4f3be52aa --- /dev/null +++ b/ext/standard/tests/array/array_sum_packed_long_overflow.phpt @@ -0,0 +1,22 @@ +--TEST-- +array_sum() packed long overflow continues in double mode +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/array/array_sum_product_integration.phpt b/ext/standard/tests/array/array_sum_product_integration.phpt new file mode 100644 index 000000000000..4b83042a3b45 --- /dev/null +++ b/ext/standard/tests/array/array_sum_product_integration.phpt @@ -0,0 +1,32 @@ +--TEST-- +array_sum()/array_product(): PHP 8.3 nested-array warning and array_column() integration +--FILE-- + 'Pen', 'price' => 3], + ['name' => 'Paper', 'price' => 5], +]; +$prices = array_column($products, 'price'); +var_dump($prices === [3, 5]); +var_dump(array_sum($prices) === 8); +var_dump(array_product($prices) === 15); + +echo "-- PHP 8.3: nested array emits warning and is skipped --\n"; +var_dump(array_sum([1, [2], 3])); +var_dump(array_product([2, [3], 4])); + +?> +--EXPECTF-- +-- array_column() + array_sum()/array_product() integration -- +bool(true) +bool(true) +bool(true) +-- PHP 8.3: nested array emits warning and is skipped -- + +Warning: array_sum(): Addition is not supported on type array in %s on line %d +int(4) + +Warning: array_product(): Multiplication is not supported on type array in %s on line %d +int(8) diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt index 4a82d5893157..dcfa8f2e759c 100644 --- a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt @@ -25,5 +25,6 @@ try { echo "Exception caught: " . $e->getMessage() . "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a destructor is deprecated in %s on line %d Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh22678.phpt b/ext/standard/tests/array/gh22678.phpt new file mode 100644 index 000000000000..c1b71b592520 --- /dev/null +++ b/ext/standard/tests/array/gh22678.phpt @@ -0,0 +1,48 @@ +--TEST-- +GH-22678 (Use-after-free in array_multisort() when the comparator mutates the array) +--FILE-- + 'c', 3 => 'a', 1 => 'b']; +array_multisort($b, SORT_STRING); +echo "repacked: ", implode(',', $b), "\n"; + +class Boom { + public function __toString(): string { + throw new Exception("boom"); + } +} + +$c = [new Boom(), new Boom()]; +try { + array_multisort($c, SORT_STRING); +} catch (Exception $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +freed mid-sort: bool(true) +repacked: a,b,c +Exception: boom diff --git a/ext/standard/tests/assert/gh22290.phpt b/ext/standard/tests/assert/gh22290.phpt new file mode 100644 index 000000000000..e519a60f5572 --- /dev/null +++ b/ext/standard/tests/assert/gh22290.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-22290: AST pretty printing does not correctly handle strings containing NUL +--INI-- +zend.assertions=1 +assert.exception=1 +--FILE-- +getMessage(), PHP_EOL; +} + +try { + assert(["a\x00b" => 1] === []); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert("tab\there" === ""); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(str_contains("plain", "zzz")); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +assert(!str_contains($string, "\000")) +assert(["a\000b" => 1] === []) +assert("tab\there" === '') +assert(str_contains('plain', 'zzz')) diff --git a/ext/standard/tests/assert/gh22291.phpt b/ext/standard/tests/assert/gh22291.phpt new file mode 100644 index 000000000000..a50bd5861f05 --- /dev/null +++ b/ext/standard/tests/assert/gh22291.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-22291: AST pretty printing does not correctly handle braces in string interpolation +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +string(5) "{abc}" +string(3) "abc" +assert(!"{{$foo}}") diff --git a/ext/standard/tests/assert/gh22292.phpt b/ext/standard/tests/assert/gh22292.phpt new file mode 100644 index 000000000000..e3aa72bf231a --- /dev/null +++ b/ext/standard/tests/assert/gh22292.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-22292: AST pretty printing does not correctly handle invalid variable names +--FILE-- +getMessage(), PHP_EOL; +} + +try { + $f = new Foo(); + var_dump($f->{'---'}); + assert(!$f->{'---'}); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +string(3) "abc" +assert(!${'---'}) +string(3) "---" +assert(!$f->{'---'}) diff --git a/ext/standard/tests/assert/gh22373.phpt b/ext/standard/tests/assert/gh22373.phpt new file mode 100644 index 000000000000..8c26f77f490b --- /dev/null +++ b/ext/standard/tests/assert/gh22373.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-22373: AST pretty-printing drops meaningful parentheses surrounding property access +--FILE-- +f)('abc') !== 'cba'); + } catch (Error $e) { + echo $e->getMessage(), PHP_EOL; + } + try { + assert(($this?->f)('abc') !== 'cba'); + } catch (Error $e) { + echo $e->getMessage(), PHP_EOL; + } + try { + assert((self::$sf)('abc') !== 'cba'); + } catch (Error $e) { + echo $e->getMessage(), PHP_EOL; + } + } +} + +new Foo(); + +?> +--EXPECT-- +assert(($this->f)('abc') !== 'cba') +assert(($this?->f)('abc') !== 'cba') +assert((self::$sf)('abc') !== 'cba') diff --git a/ext/standard/tests/assert/gh22387.phpt b/ext/standard/tests/assert/gh22387.phpt new file mode 100644 index 000000000000..38c93921608a --- /dev/null +++ b/ext/standard/tests/assert/gh22387.phpt @@ -0,0 +1,62 @@ +--TEST-- +GH-22387: AST pretty-printing drops meaningful parentheses around RHS of instanceof +--FILE-- +getMessage(), PHP_EOL; +} + +try { + assert(!new (bar)()); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(!(bar)::m()); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(!(bar)::$p); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(!(bar)::C); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert((baz)::class !== 'stdClass'); +} catch (AssertionError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +assert(!$foo instanceof (bar)) +assert(!new (bar)()) +assert(!(bar)::m()) +assert(!(bar)::$p) +assert(!(bar)::C) +assert((baz)::class !== 'stdClass') diff --git a/ext/standard/tests/assert/gh22671.phpt b/ext/standard/tests/assert/gh22671.phpt new file mode 100644 index 000000000000..3487b0687ccd --- /dev/null +++ b/ext/standard/tests/assert/gh22671.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-22671 (assert.bail must not call zend_throw_unwind_exit with a pending exception) +--INI-- +zend.assertions=1 +assert.bail=1 +assert.exception=0 +assert.callback=cb +error_reporting=0 +--FILE-- + +--EXPECT-- +shutdown reached diff --git a/ext/standard/tests/dir/bug80960.phpt b/ext/standard/tests/dir/bug80960.phpt index 43d01465599b..e52a4a719995 100644 --- a/ext/standard/tests/dir/bug80960.phpt +++ b/ext/standard/tests/dir/bug80960.phpt @@ -11,14 +11,8 @@ opendir("notexist?"); opendir(str_pad("longname", PHP_MAXPATHLEN - strlen(getcwd()), "_")); ?> --EXPECTF-- -Warning: opendir(notexist*): %s (code: 123) in %s on line %d +Warning: opendir(): Failed to open directory: No such file or directory in %s on line %d -Warning: opendir(notexist*): Failed to open directory: No such file or directory in %s on line %d +Warning: opendir(): Failed to open directory: No such file or directory in %s on line %d -Warning: opendir(notexist?): %s (code: 123) in %s on line %d - -Warning: opendir(notexist?): Failed to open directory: No such file or directory in %s on line %d - -Warning: opendir(longname%r_+%r): %s (code: 111) in %s on line %d - -Warning: opendir(longname%r_+%r): Failed to open directory: Filename too long in %s on line %d +Warning: opendir(): Failed to open directory: Filename too long in %s on line %d diff --git a/ext/standard/tests/dir/dir_variation5.phpt b/ext/standard/tests/dir/dir_variation5.phpt index 41a29760eb05..841257a79c42 100644 --- a/ext/standard/tests/dir/dir_variation5.phpt +++ b/ext/standard/tests/dir/dir_variation5.phpt @@ -24,6 +24,6 @@ echo "Done"; --EXPECTF-- *** Testing dir() : open a file instead of a directory *** -Warning: dir(%s): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/dir/dir_variation6.phpt b/ext/standard/tests/dir/dir_variation6.phpt index 0f9c14b91d47..aa0a9aa3a4c4 100644 --- a/ext/standard/tests/dir/dir_variation6.phpt +++ b/ext/standard/tests/dir/dir_variation6.phpt @@ -42,10 +42,10 @@ echo "Done"; *** Testing dir() : open a non-existent directory *** -- opening previously removed directory -- -Warning: dir(%s): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -- opening non-existent directory -- -Warning: dir(%s): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/dir/dir_variation7.phpt b/ext/standard/tests/dir/dir_variation7.phpt index 2b245fd612a8..b09f6ed82659 100644 --- a/ext/standard/tests/dir/dir_variation7.phpt +++ b/ext/standard/tests/dir/dir_variation7.phpt @@ -71,10 +71,10 @@ rmdir($parent_dir_path); *** Testing dir() : remove execute permission from the parent dir *** -- After restricting 1st level parent directory -- -Warning: dir(%s/dir_variation7/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -- After restricting parent directory -- -Warning: dir(%s/dir_variation7/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/dir/dir_variation8.phpt b/ext/standard/tests/dir/dir_variation8.phpt index 38d60a039052..f2855b08c695 100644 --- a/ext/standard/tests/dir/dir_variation8.phpt +++ b/ext/standard/tests/dir/dir_variation8.phpt @@ -39,16 +39,16 @@ echo "Done"; *** Testing dir() : checking with wildcard characters *** -- wildcard = '*' -- -Warning: dir(%s/dir_var*): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: dir(%s/*): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -- wildcard = '?' -- -Warning: dir(%s/dir_variation81/sub_dir?): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: dir(%s/dir_variation81/sub?dir1): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/dir/dir_variation9.phpt b/ext/standard/tests/dir/dir_variation9.phpt index 88ea69cb3df3..aafcba6dd7a7 100644 --- a/ext/standard/tests/dir/dir_variation9.phpt +++ b/ext/standard/tests/dir/dir_variation9.phpt @@ -97,15 +97,15 @@ object(Directory)#%d (2) { -- With invalid paths -- -Warning: dir(%s/dir_variation91/sub_dir12/sub_dir111/..): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: dir(%s/dir_variation92/sub_dir21/../dir_variation91): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: dir(%s/dir_variation92/sub_dir21/../../dir_variation91/sub_dir12/..): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: dir(%s/dir_variation91/sub_dir11/sub_dir111/../../dir_variation92/sub_dir21/..): Failed to open directory: %s in %s on line %d +Warning: dir(): Failed to open directory: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/dir/opendir_error2.phpt b/ext/standard/tests/dir/opendir_error2.phpt index 32371f917829..5c077bc431f0 100644 --- a/ext/standard/tests/dir/opendir_error2.phpt +++ b/ext/standard/tests/dir/opendir_error2.phpt @@ -27,10 +27,10 @@ var_dump(opendir('idonotexist')); -- Pass a non-existent absolute path: -- -Warning: opendir(%s/idonotexist): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) -- Pass a non-existent relative path: -- -Warning: opendir(idonotexist): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/opendir_variation5.phpt b/ext/standard/tests/dir/opendir_variation5.phpt index f6b2934474b8..856c6998ac46 100644 --- a/ext/standard/tests/dir/opendir_variation5.phpt +++ b/ext/standard/tests/dir/opendir_variation5.phpt @@ -78,10 +78,10 @@ rmdir($parent_dir_path); -- After restricting 1st level parent directory -- -Warning: opendir(%s/opendir_variation5/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) -- After restricting parent directory -- -Warning: opendir(%s/opendir_variation5/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/opendir_variation6-win32.phpt b/ext/standard/tests/dir/opendir_variation6-win32.phpt index 40a0e9197828..92d1d22ca3f6 100644 --- a/ext/standard/tests/dir/opendir_variation6-win32.phpt +++ b/ext/standard/tests/dir/opendir_variation6-win32.phpt @@ -45,24 +45,16 @@ rmdir($dir_path); -- Wildcard = '*' -- -Warning: opendir(%s/opendir_var*): %s in %s on line %d - -Warning: opendir(%s/opendir_var*): Failed to open directory: %s in %s on line %d +Warning: opendir(): %s in %s on line %d bool(false) -Warning: opendir(%s/*): %s in %s on line %d - -Warning: opendir(%s/*): Failed to open directory: %s in %s on line %d +Warning: opendir(): %s in %s on line %d bool(false) -- Wildcard = '?' -- -Warning: opendir(%s/opendir_variation6/sub_dir?): %s in %s on line %d - -Warning: opendir(%s/opendir_variation6/sub_dir?): Failed to open directory: %s in %s on line %d +Warning: opendir(): %s in %s on line %d bool(false) -Warning: opendir(%s/opendir_variation6/sub?dir1): %s in %s on line %d - -Warning: opendir(%s/opendir_variation6/sub?dir1): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/opendir_variation6.phpt b/ext/standard/tests/dir/opendir_variation6.phpt index 7e3046f9af8e..69c9395b0bb3 100644 --- a/ext/standard/tests/dir/opendir_variation6.phpt +++ b/ext/standard/tests/dir/opendir_variation6.phpt @@ -45,16 +45,16 @@ rmdir($dir_path); -- Wildcard = '*' -- -Warning: opendir(%s/opendir_var*): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: opendir(%s/*): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) -- Wildcard = '?' -- -Warning: opendir(%s/opendir_variation6/sub_dir?): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) -Warning: opendir(%s/opendir_variation6/sub?dir1): Failed to open directory: %s in %s on line %d +Warning: opendir(): Failed to open directory: %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/scandir_error2.phpt b/ext/standard/tests/dir/scandir_error2.phpt index d17feb1136be..a2668490b549 100644 --- a/ext/standard/tests/dir/scandir_error2.phpt +++ b/ext/standard/tests/dir/scandir_error2.phpt @@ -27,14 +27,14 @@ var_dump(scandir('/idonotexist')); -- Pass scandir() an absolute path that does not exist -- -Warning: scandir(%s/idonotexist): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) -- Pass scandir() a relative path that does not exist -- -Warning: scandir(/idonotexist): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/scandir_invalid_flag.phpt b/ext/standard/tests/dir/scandir_invalid_flag.phpt new file mode 100644 index 000000000000..76838dc869b8 --- /dev/null +++ b/ext/standard/tests/dir/scandir_invalid_flag.phpt @@ -0,0 +1,12 @@ +--TEST-- +Provide wrong flags to scandir() +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +scandir(): Argument #2 ($sorting_order) must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants diff --git a/ext/standard/tests/dir/scandir_variation5.phpt b/ext/standard/tests/dir/scandir_variation5.phpt index 7bee9f087a7f..7b4f57b949c0 100644 --- a/ext/standard/tests/dir/scandir_variation5.phpt +++ b/ext/standard/tests/dir/scandir_variation5.phpt @@ -70,14 +70,14 @@ rmdir($parent_dir_path); -- After restricting 1st level parent directory -- -Warning: scandir(%s/scandir_variation5/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) -- After restricting parent directory -- -Warning: scandir(%s/scandir_variation5/sub_dir/child_dir): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/scandir_variation6.phpt b/ext/standard/tests/dir/scandir_variation6.phpt index 60f64b5b60d7..82fcaf6fedef 100644 --- a/ext/standard/tests/dir/scandir_variation6.phpt +++ b/ext/standard/tests/dir/scandir_variation6.phpt @@ -46,24 +46,24 @@ rmdir($dir_path); -- Wildcard = '*' -- -Warning: scandir(%s/scandir_var*): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) -Warning: scandir(%s/*): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) -- Wildcard = '?' -- -Warning: scandir(%s/scandir_variation6/sub_dir?): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) -Warning: scandir(%s/scandir_variation6/sub?dir1): Failed to open directory: %s in %s on line %d +Warning: scandir(): Failed to open directory: %s in %s on line %d Warning: scandir(): (errno %d): %s in %s on line %d bool(false) diff --git a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt b/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt deleted file mode 100644 index 44d8b6daa5f9..000000000000 --- a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt +++ /dev/null @@ -1,71 +0,0 @@ ---TEST-- -Test scandir() function : usage variations - different ints as $sorting_order arg ---SKIPIF-- - ---FILE-- - ---CLEAN-- - ---EXPECT-- -*** Testing scandir() : usage variations *** -array(4) { - [0]=> - string(45) "私はガラスを食べられますfile2.tmp" - [1]=> - string(45) "私はガラスを食べられますfile1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(45) "私はガラスを食べられますfile2.tmp" - [1]=> - string(45) "私はガラスを食べられますfile1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(1) "." - [1]=> - string(2) ".." - [2]=> - string(45) "私はガラスを食べられますfile1.tmp" - [3]=> - string(45) "私はガラスを食べられますfile2.tmp" -} diff --git a/ext/standard/tests/dir/scandir_variation9.phpt b/ext/standard/tests/dir/scandir_variation9.phpt deleted file mode 100644 index 56e5575e5590..000000000000 --- a/ext/standard/tests/dir/scandir_variation9.phpt +++ /dev/null @@ -1,65 +0,0 @@ ---TEST-- -Test scandir() function : usage variations - different ints as $sorting_order arg ---FILE-- - ---CLEAN-- - ---EXPECT-- -*** Testing scandir() : usage variations *** -array(4) { - [0]=> - string(9) "file2.tmp" - [1]=> - string(9) "file1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(9) "file2.tmp" - [1]=> - string(9) "file1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(1) "." - [1]=> - string(2) ".." - [2]=> - string(9) "file1.tmp" - [3]=> - string(9) "file2.tmp" -} diff --git a/ext/standard/tests/file/007_variation15.phpt b/ext/standard/tests/file/007_variation15.phpt index 54e89d95f373..cbda911849de 100644 --- a/ext/standard/tests/file/007_variation15.phpt +++ b/ext/standard/tests/file/007_variation15.phpt @@ -55,5 +55,5 @@ int(0) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/007_variation16.phpt b/ext/standard/tests/file/007_variation16.phpt index 7ce4f04a8619..a91374dd6dee 100644 --- a/ext/standard/tests/file/007_variation16.phpt +++ b/ext/standard/tests/file/007_variation16.phpt @@ -46,5 +46,5 @@ int(37) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/007_variation23.phpt b/ext/standard/tests/file/007_variation23.phpt index f080596a2cd0..c475d08a37dc 100644 --- a/ext/standard/tests/file/007_variation23.phpt +++ b/ext/standard/tests/file/007_variation23.phpt @@ -46,5 +46,5 @@ int(0) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/007_variation24.phpt b/ext/standard/tests/file/007_variation24.phpt index 3d4d4c4152ab..bfd2181b346e 100644 --- a/ext/standard/tests/file/007_variation24.phpt +++ b/ext/standard/tests/file/007_variation24.phpt @@ -46,5 +46,5 @@ int(37) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/007_variation7.phpt b/ext/standard/tests/file/007_variation7.phpt index e25c1dd90830..59b703f8c1bd 100644 --- a/ext/standard/tests/file/007_variation7.phpt +++ b/ext/standard/tests/file/007_variation7.phpt @@ -46,5 +46,5 @@ int(0) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/007_variation8.phpt b/ext/standard/tests/file/007_variation8.phpt index ec7cbae903d6..ab5dafb931a2 100644 --- a/ext/standard/tests/file/007_variation8.phpt +++ b/ext/standard/tests/file/007_variation8.phpt @@ -46,5 +46,5 @@ int(37) bool(true) string(7) "Unknown" -Warning: fopen(%s): Failed to open stream: File exists in %s on line %d +Warning: fopen(): Failed to open stream: File exists in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/bug35740.phpt b/ext/standard/tests/file/bug35740.phpt index 29ab0248d8dc..1bba283abc33 100644 --- a/ext/standard/tests/file/bug35740.phpt +++ b/ext/standard/tests/file/bug35740.phpt @@ -8,7 +8,7 @@ include (__DIR__); echo "Done\n"; ?> --EXPECTF-- -Warning: include(%s): Failed to open stream: %s in %s on line %d +Warning: include(): Failed to open stream: %s in %s on line %d Warning: include(): Failed opening '%s' for inclusion (include_path='%s') in %s on line %d Done diff --git a/ext/standard/tests/file/bug43353.phpt b/ext/standard/tests/file/bug43353.phpt index 6089fabadd91..3a9ea39cc91e 100644 --- a/ext/standard/tests/file/bug43353.phpt +++ b/ext/standard/tests/file/bug43353.phpt @@ -2,6 +2,8 @@ Bug #43353 wrong detection of 'data' wrapper --INI-- allow_url_fopen=1 +zend.exception_string_param_max_len=1000000 +error_include_args=On --FILE-- --EXPECTF-- -Warning: fopen(%s): Failed to open stream: `Q' is not a valid mode for fopen in %s on line %d +Warning: fopen(): Failed to open stream: `Q' is not a valid mode for fopen in %s on line %d diff --git a/ext/standard/tests/file/copy_error.phpt b/ext/standard/tests/file/copy_error.phpt index 3814c3d5f262..fb989a358389 100644 --- a/ext/standard/tests/file/copy_error.phpt +++ b/ext/standard/tests/file/copy_error.phpt @@ -11,6 +11,6 @@ echo "*** Done ***\n"; --EXPECTF-- *** Testing copy() function: error conditions -- -Warning: copy(/no/file): Failed to open stream: No such file or directory in %s on line %d +Warning: copy(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/copy_variation14.phpt b/ext/standard/tests/file/copy_variation14.phpt index a79bbf69c5b5..c4ff093ea773 100644 --- a/ext/standard/tests/file/copy_variation14.phpt +++ b/ext/standard/tests/file/copy_variation14.phpt @@ -29,12 +29,12 @@ unlink(__DIR__."/copy_variation14.tmp"); ?> --EXPECTF-- *** Test copy() function: Trying to create a copy of non-existing source in existing destination *** -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) *** Test copy() function: Trying to create copy of an existing source in non-existing destination *** -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) int(1500) diff --git a/ext/standard/tests/file/copy_variation15.phpt b/ext/standard/tests/file/copy_variation15.phpt index abe425a4e323..0068d46a0d41 100644 --- a/ext/standard/tests/file/copy_variation15.phpt +++ b/ext/standard/tests/file/copy_variation15.phpt @@ -42,7 +42,7 @@ rmdir(__DIR__."/copy_variation15"); ?> --EXPECTF-- *** Test copy() function: Trying to create a copy of file in a dir which doesn't have write permissions *** -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) int(300) diff --git a/ext/standard/tests/file/copy_variation16-win32.phpt b/ext/standard/tests/file/copy_variation16-win32.phpt index d2730ce33256..05607042506f 100644 --- a/ext/standard/tests/file/copy_variation16-win32.phpt +++ b/ext/standard/tests/file/copy_variation16-win32.phpt @@ -125,7 +125,7 @@ Size of destination file => int(3500) -- Iteration 7 -- Size of source file => int(3500) Copy operation => -Warning: copy(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: copy(): Failed to open stream: No such file or directory in %s on line %d bool(false) Existence of destination file => bool(false) diff --git a/ext/standard/tests/file/copy_variation17.phpt b/ext/standard/tests/file/copy_variation17.phpt index 446d72d35db7..9c46eeb2601d 100644 --- a/ext/standard/tests/file/copy_variation17.phpt +++ b/ext/standard/tests/file/copy_variation17.phpt @@ -51,19 +51,19 @@ bool(true) bool(true) int(1500) -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) -Warning: copy(%s): %s +Warning: copy(): %s bool(false) bool(false) *** Done *** diff --git a/ext/standard/tests/file/copy_variation2-win32-mb.phpt b/ext/standard/tests/file/copy_variation2-win32-mb.phpt index 67d84ee3e32c..3d1da3377954 100644 --- a/ext/standard/tests/file/copy_variation2-win32-mb.phpt +++ b/ext/standard/tests/file/copy_variation2-win32-mb.phpt @@ -117,13 +117,13 @@ Size of destination file => int(1500) -- Iteration 5 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) -- Iteration 6 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) @@ -150,7 +150,7 @@ Size of destination file => int(1500) -- Iteration 10 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) @@ -191,7 +191,7 @@ Size of destination file => int(1500) -- Iteration 16 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) diff --git a/ext/standard/tests/file/copy_variation2-win32.phpt b/ext/standard/tests/file/copy_variation2-win32.phpt index c8f695efea7d..eb8c7042fe21 100644 --- a/ext/standard/tests/file/copy_variation2-win32.phpt +++ b/ext/standard/tests/file/copy_variation2-win32.phpt @@ -117,13 +117,13 @@ Size of destination file => int(1500) -- Iteration 5 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) -- Iteration 6 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) @@ -150,7 +150,7 @@ Size of destination file => int(1500) -- Iteration 10 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) @@ -191,7 +191,7 @@ Size of destination file => int(1500) -- Iteration 16 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) diff --git a/ext/standard/tests/file/copy_variation3-win32.phpt b/ext/standard/tests/file/copy_variation3-win32.phpt index ed4cbfb89bdc..ee5678a8ab4a 100644 --- a/ext/standard/tests/file/copy_variation3-win32.phpt +++ b/ext/standard/tests/file/copy_variation3-win32.phpt @@ -92,13 +92,13 @@ Size of destination file => int(1500) -- Iteration 3 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) -- Iteration 4 -- Copy operation => -Warning: copy(%s): %s +Warning: copy(): %s bool(false) Existence of destination file => bool(false) *** Done *** diff --git a/ext/standard/tests/file/copy_variation4.phpt b/ext/standard/tests/file/copy_variation4.phpt index d467cb4ce9ab..4dc318789488 100644 --- a/ext/standard/tests/file/copy_variation4.phpt +++ b/ext/standard/tests/file/copy_variation4.phpt @@ -91,7 +91,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 2 -- Existence of destination file before copy => bool(true) @@ -103,7 +103,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 3 -- Existence of destination file before copy => bool(true) @@ -115,7 +115,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 4 -- Existence of destination file before copy => bool(true) @@ -127,7 +127,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 5 -- Existence of destination file before copy => bool(false) diff --git a/ext/standard/tests/file/copy_variation5-win32.phpt b/ext/standard/tests/file/copy_variation5-win32.phpt index af352dbe0732..e4c42e2f9322 100644 --- a/ext/standard/tests/file/copy_variation5-win32.phpt +++ b/ext/standard/tests/file/copy_variation5-win32.phpt @@ -98,7 +98,7 @@ Destination file name => %s/CopY5.TMP Size of source file => int(1500) Size of destination file => int(1500) -Warning: unlink(%s/COPY5.TMP): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -Warning: unlink(%s/CopY5.TMP): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/copy_variation6-win32.phpt b/ext/standard/tests/file/copy_variation6-win32.phpt index c0b3ec972024..32c21a450c1a 100644 --- a/ext/standard/tests/file/copy_variation6-win32.phpt +++ b/ext/standard/tests/file/copy_variation6-win32.phpt @@ -124,7 +124,7 @@ Size of destination file => int(0) -- Iteration 7 -- Copy operation => -Warning: copy(%s/copy_variation6/copy_variation6_sub///../*): Failed to open stream: No such file or directory in %s on line %d +Warning: copy(): Failed to open stream: No such file or directory in %s on line %d bool(false) Existence of destination file => bool(false) diff --git a/ext/standard/tests/file/file_error.phpt b/ext/standard/tests/file/file_error.phpt index 69bb93c0b7ae..fffad3c59b64 100644 --- a/ext/standard/tests/file/file_error.phpt +++ b/ext/standard/tests/file/file_error.phpt @@ -32,7 +32,7 @@ unlink($file_path."/file.tmp"); ValueError: file(): Argument #2 ($flags) must be a valid flag value ValueError: file(): Argument #2 ($flags) must be a valid flag value -Warning: file(temp.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) --- Done --- diff --git a/ext/standard/tests/file/file_get_contents_error.phpt b/ext/standard/tests/file/file_get_contents_error.phpt index 5ac352123b30..add7831ef390 100644 --- a/ext/standard/tests/file/file_get_contents_error.phpt +++ b/ext/standard/tests/file/file_get_contents_error.phpt @@ -11,7 +11,7 @@ $file_path = __DIR__; include($file_path."/file.inc"); echo "\n-- Testing with Non-existing file --\n"; -print( file_get_contents("/no/such/file/or/dir") ); +var_dump( file_get_contents("/no/such/file/or/dir") ); create_files($file_path, 1, "text", 0755, 100, "w", "file_get_contents_error", 1, "byte"); $file_handle = fopen($file_path."/file_put_contents_error.tmp", "w"); @@ -44,7 +44,8 @@ if(file_exists($file_path."/file_put_contents1.tmp")) { -- Testing with Non-existing file -- -Warning: file_get_contents(/no/such/file/or/dir): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d +bool(false) -- Testing for invalid negative maxlen values -- file_get_contents(): Argument #5 ($length) must be greater than or equal to 0 diff --git a/ext/standard/tests/file/file_get_contents_error_folder-win.phpt b/ext/standard/tests/file/file_get_contents_error_folder-win.phpt index ea3902fdbe06..9d3615353f7e 100644 --- a/ext/standard/tests/file/file_get_contents_error_folder-win.phpt +++ b/ext/standard/tests/file/file_get_contents_error_folder-win.phpt @@ -9,4 +9,4 @@ if (substr(PHP_OS, 0, 3) != "WIN") { print "skip - Windows only"; } file_get_contents(__DIR__); ?> --EXPECTF-- -Warning: file_get_contents(%s): Failed to open stream: Permission denied in %s on line %d +Warning: file_get_contents(): Failed to open stream: Permission denied in %s on line %d diff --git a/ext/standard/tests/file/file_get_contents_file_put_contents_error.phpt b/ext/standard/tests/file/file_get_contents_file_put_contents_error.phpt index 91a37cd2e1ac..7133ae766d68 100644 --- a/ext/standard/tests/file/file_get_contents_file_put_contents_error.phpt +++ b/ext/standard/tests/file/file_get_contents_file_put_contents_error.phpt @@ -31,7 +31,7 @@ unlink($file_path."/file_put_contents_error1.tmp"); -- Testing with Non-existing file -- -Warning: file_get_contents(/no/such/file/or/dir): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d -- Testing for invalid negative maxlen values -- file_get_contents(): Argument #5 ($length) must be greater than or equal to 0 diff --git a/ext/standard/tests/file/file_get_contents_variation7-win32-mb.phpt b/ext/standard/tests/file/file_get_contents_variation7-win32-mb.phpt index 5dfa6227bccf..9bb97c623b44 100644 --- a/ext/standard/tests/file/file_get_contents_variation7-win32-mb.phpt +++ b/ext/standard/tests/file/file_get_contents_variation7-win32-mb.phpt @@ -87,12 +87,12 @@ string(%d) "contents read" -- Iteration 5 -- -Warning: file_get_contents(%sfileGetContentsVar7私はガラスを食べられます.dir\fileGetContentsVar7Sub私はガラスを食べられます\..\\\fileGetContentsVar7Sub私はガラスを食べられます\\..\\..\fileGetContentsVar7Sub私はガラスを食べられます\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: file_get_contents(%sfileGetContentsVar7私はガラスを食べられます.dir\fileGetContentsVar7Sub私はガラスを食べられます\BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -109,7 +109,7 @@ string(%d) "contents read" -- Iteration 11 -- -Warning: file_get_contents(BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 12 -- diff --git a/ext/standard/tests/file/file_get_contents_variation7-win32.phpt b/ext/standard/tests/file/file_get_contents_variation7-win32.phpt index a353630c9532..0cf7cc7d5aac 100644 --- a/ext/standard/tests/file/file_get_contents_variation7-win32.phpt +++ b/ext/standard/tests/file/file_get_contents_variation7-win32.phpt @@ -87,12 +87,12 @@ string(%d) "contents read" -- Iteration 5 -- -Warning: file_get_contents(%sfileGetContentsVar7.dir\fileGetContentsVar7Sub\..\\\fileGetContentsVar7Sub\\..\\..\fileGetContentsVar7Sub\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: file_get_contents(%sfileGetContentsVar7.dir\fileGetContentsVar7Sub\BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -109,7 +109,7 @@ string(%d) "contents read" -- Iteration 11 -- -Warning: file_get_contents(BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 12 -- diff --git a/ext/standard/tests/file/file_get_contents_variation7.phpt b/ext/standard/tests/file/file_get_contents_variation7.phpt index 2d574c6410b0..25a31c6dea9c 100644 --- a/ext/standard/tests/file/file_get_contents_variation7.phpt +++ b/ext/standard/tests/file/file_get_contents_variation7.phpt @@ -79,12 +79,12 @@ string(%d) "contents read" -- Iteration 5 -- -Warning: file_get_contents(%sfileGetContentsVar7.dir/fileGetContentsVar7Sub/..///fileGetContentsVar7Sub//..//../fileGetContentsVar7Sub/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: file_get_contents(%sfileGetContentsVar7.dir/fileGetContentsVar7Sub/BADDIR/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -101,7 +101,7 @@ string(%d) "contents read" -- Iteration 11 -- -Warning: file_get_contents(BADDIR/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt index ee408b2c9758..204a5c777257 100644 --- a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt @@ -46,12 +46,12 @@ foreach($names_arr as $key =>$value) { -- Filename: -1 -- -Warning: file_get_contents(-1): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Filename: TRUE -- -Warning: file_get_contents(1): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Filename: FALSE -- @@ -62,7 +62,7 @@ ValueError: Path must not be empty -- Filename: " " -- -Warning: file_get_contents( ): Failed to open stream: Permission denied in %s on line %d +Warning: file_get_contents(): Failed to open stream: Permission denied in %s on line %d bool(false) -- Filename: \0 -- @@ -73,10 +73,10 @@ TypeError: file_get_contents(): Argument #1 ($filename) must be of type string, -- Filename: /no/such/file/dir -- -Warning: file_get_contents(/no/such/file/dir): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Filename: php/php -- -Warning: file_get_contents(php/php): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/standard/tests/file/file_get_contents_variation8.phpt b/ext/standard/tests/file/file_get_contents_variation8.phpt index d6edef55db61..94d3a31c775e 100644 --- a/ext/standard/tests/file/file_get_contents_variation8.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8.phpt @@ -45,11 +45,11 @@ echo "\n*** Done ***\n"; *** Testing file_get_contents() : variation *** -- Iteration 0 -- -Warning: file_get_contents(-1): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 1 -- -Warning: file_get_contents(1): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 2 -- ValueError: Path must not be empty @@ -57,7 +57,7 @@ ValueError: Path must not be empty ValueError: Path must not be empty -- Iteration 4 -- -Warning: file_get_contents( ): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 5 -- ValueError: file_get_contents(): Argument #1 ($filename) must not contain any null bytes @@ -65,11 +65,11 @@ ValueError: file_get_contents(): Argument #1 ($filename) must not contain any nu TypeError: file_get_contents(): Argument #1 ($filename) must be of type string, array given -- Iteration 7 -- -Warning: file_get_contents(/no/such/file/dir): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 8 -- -Warning: file_get_contents(php/php): Failed to open stream: No such file or directory in %s on line %d +Warning: file_get_contents(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/file_get_contents_with_custom_uri_parser.phpt b/ext/standard/tests/file/file_get_contents_with_custom_uri_parser.phpt index b5070b740238..01ee940d9531 100644 --- a/ext/standard/tests/file/file_get_contents_with_custom_uri_parser.phpt +++ b/ext/standard/tests/file/file_get_contents_with_custom_uri_parser.phpt @@ -39,11 +39,11 @@ var_dump(file_get_contents("http://exa%23mple.org", context: $context)); // inva --EXPECTF-- file_get_contents(): Provided stream context has invalid value for the "uri_parser_class" option -Warning: file_get_contents(http:///example.com): Failed to open stream: operation failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: operation failed in %s on line %d bool(false) -Warning: file_get_contents(http://éxamplé.com): Failed to open stream: operation failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: operation failed in %s on line %d bool(false) -Warning: file_get_contents(http://exa%23mple.org): Failed to open stream: operation failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: operation failed in %s on line %d bool(false) diff --git a/ext/standard/tests/file/file_put_contents_variation7-win32.phpt b/ext/standard/tests/file/file_put_contents_variation7-win32.phpt index fe9796979d13..b41af4b1128b 100644 --- a/ext/standard/tests/file/file_put_contents_variation7-win32.phpt +++ b/ext/standard/tests/file/file_put_contents_variation7-win32.phpt @@ -103,12 +103,12 @@ Data written correctly -- Iteration 5 -- -Warning: file_put_contents(%sfilePutContentsVar7.dir\filePutContentsVar7Sub\..\\\filePutContentsVar7Sub\\..\\..\filePutContentsVar7Sub\FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written -- Iteration 6 -- -Warning: file_put_contents(%sfilePutContentsVar7.dir\filePutContentsVar7Sub\BADDIR\FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written -- Iteration 7 -- @@ -125,7 +125,7 @@ Data written correctly -- Iteration 11 -- -Warning: file_put_contents(BADDIR\FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written -- Iteration 12 -- diff --git a/ext/standard/tests/file/file_put_contents_variation7.phpt b/ext/standard/tests/file/file_put_contents_variation7.phpt index fe9cfe57894a..260ee1cf5bfa 100644 --- a/ext/standard/tests/file/file_put_contents_variation7.phpt +++ b/ext/standard/tests/file/file_put_contents_variation7.phpt @@ -100,12 +100,12 @@ Data written correctly -- Iteration 5 -- -Warning: file_put_contents(%sfilePutContentsVar7.dir/filePutContentsVar7Sub/..///filePutContentsVar7Sub//..//../filePutContentsVar7Sub/FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written -- Iteration 6 -- -Warning: file_put_contents(%sfilePutContentsVar7.dir/filePutContentsVar7Sub/BADDIR/FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written -- Iteration 7 -- @@ -122,7 +122,7 @@ Data written correctly -- Iteration 11 -- -Warning: file_put_contents(BADDIR/FileGetContentsVar7.tmp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d No data written *** Done *** diff --git a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt index b1625f030b06..221bffc54db0 100644 --- a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt @@ -62,7 +62,7 @@ ValueError: Path must not be empty -- Filename: " " -- -Warning: file_put_contents( ): Failed to open stream: Permission denied in %s on line %d +Warning: file_put_contents(): Failed to open stream: Permission denied in %s on line %d Failed to write data to: " " -- Filename: \0 -- @@ -73,10 +73,10 @@ TypeError: file_put_contents(): Argument #1 ($filename) must be of type string, -- Filename: /no/such/file/dir -- -Warning: file_put_contents(/no/such/file/dir): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d Failed to write data to: /no/such/file/dir -- Filename: php/php -- -Warning: file_put_contents(php/php): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d Failed to write data to: php/php diff --git a/ext/standard/tests/file/file_put_contents_variation8.phpt b/ext/standard/tests/file/file_put_contents_variation8.phpt index 81bbd2516880..12ae8379f699 100644 --- a/ext/standard/tests/file/file_put_contents_variation8.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8.phpt @@ -75,11 +75,11 @@ ValueError: file_put_contents(): Argument #1 ($filename) must not contain any nu TypeError: file_put_contents(): Argument #1 ($filename) must be of type string, array given -- Iteration 7 -- -Warning: file_put_contents(%sdir): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d Failed to write data to: '%sir' -- Iteration 8 -- -Warning: file_put_contents(%sphp): Failed to open stream: %s in %s on line %d +Warning: file_put_contents(): Failed to open stream: %s in %s on line %d Failed to write data to: '%sphp' *** Done *** diff --git a/ext/standard/tests/file/file_variation8-win32.phpt b/ext/standard/tests/file/file_variation8-win32.phpt index 2aeaf451ae96..644bebe8a2d5 100644 --- a/ext/standard/tests/file/file_variation8-win32.phpt +++ b/ext/standard/tests/file/file_variation8-win32.phpt @@ -99,12 +99,12 @@ array(1) { -- Iteration 5 -- -Warning: file(%sfileVar8_win32.dir\fileVar8Sub\..\\\fileVar8Sub\\..\\..\fileVar8Sub\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: file(%sfileVar8_win32.dir\fileVar8Sub\BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -133,7 +133,7 @@ array(1) { -- Iteration 11 -- -Warning: file(BADDIR\FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 12 -- diff --git a/ext/standard/tests/file/file_variation8.phpt b/ext/standard/tests/file/file_variation8.phpt index 8c79a3bb4f48..cefb26a54440 100644 --- a/ext/standard/tests/file/file_variation8.phpt +++ b/ext/standard/tests/file/file_variation8.phpt @@ -91,12 +91,12 @@ array(1) { -- Iteration 5 -- -Warning: file(%sfileVar8.dir/fileVar8Sub/..///fileVar8Sub//..//../fileVar8Sub/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: file(%sfileVar8.dir/fileVar8Sub/BADDIR/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -125,7 +125,7 @@ array(1) { -- Iteration 11 -- -Warning: file(BADDIR/FileGetContentsVar7.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: file(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/fopen_variation10-win32.phpt b/ext/standard/tests/file/fopen_variation10-win32.phpt index 45ec3052cdcb..b87f5b181164 100644 --- a/ext/standard/tests/file/fopen_variation10-win32.phpt +++ b/ext/standard/tests/file/fopen_variation10-win32.phpt @@ -88,17 +88,17 @@ file in root --c-- -Warning: fopen(c\fopen_variation10.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --\-- -Warning: fopen(\\fopen_variation10.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --/-- -Warning: fopen(/\fopen_variation10.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --c:fopen10.tmpdirTwo-- @@ -106,7 +106,7 @@ file in fopen10.tmpdirTwo --c:adir-- -Warning: fopen(c:adir\fopen_variation10.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --c:\/-- @@ -126,5 +126,5 @@ file in fopen10.tmpDir --/sortout-- -Warning: fopen(/sortout\fopen_variation10.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read diff --git a/ext/standard/tests/file/fopen_variation11-win32.phpt b/ext/standard/tests/file/fopen_variation11-win32.phpt index 22368812637b..60eeb562a962 100644 --- a/ext/standard/tests/file/fopen_variation11-win32.phpt +++ b/ext/standard/tests/file/fopen_variation11-win32.phpt @@ -86,17 +86,17 @@ file in root --c-- -Warning: fopen(c\fopen_variation11.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --\-- -Warning: fopen(\\FOPEN_VARIATION11.TMP): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --/-- -Warning: fopen(\\FOPEN_VARIATION11.TMP): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --c:fopen11.tmpdirTwo-- @@ -104,7 +104,7 @@ file in fopen11.tmpdirTwo --c:adir-- -Warning: fopen(c:adir\fopen_variation11.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read --c:\/-- @@ -124,5 +124,5 @@ file in fopen11.tmpDir --/sortout-- -Warning: fopen(/sortout\fopen_variation11.tmp): Failed to open stream: No such file or directory in %s on line %d +Warning: fopen(): Failed to open stream: No such file or directory in %s on line %d file not opened for read diff --git a/ext/standard/tests/file/fopen_variation14-win32.phpt b/ext/standard/tests/file/fopen_variation14-win32.phpt index 71a0ecd0c70d..ae0049cdbe17 100644 --- a/ext/standard/tests/file/fopen_variation14-win32.phpt +++ b/ext/standard/tests/file/fopen_variation14-win32.phpt @@ -98,42 +98,42 @@ function runtest($fileURIs) { Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen14.tmpDir\fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://./fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://./fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://./fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://./fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://.\fopen14.tmpDir\fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://.\fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://.\fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://.\fopen14.tmpDir\fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://.\fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://.\fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://%s/fopen14.tmpDir/fopen_variation14.tmp --- test passed --- WRITE: file://%s/fopen14.tmpDir/fopen_variation14.tmp --- @@ -150,22 +150,22 @@ test passed Warning: fopen(): Remote host file access not supported, file://../fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://../fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://../fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://../fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://../fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://..\fopen14.tmpDir\fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://..\fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://..\fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://..\fopen14.tmpDir\fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://..\fopen14.tmpDir\fopen_variation14.tmp in %s on line %d -Warning: fopen(file://..\fopen14.tmpDir\fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://%s/fopen14.tmpDir/fopen_variation14.tmp --- test passed --- WRITE: file://%s/fopen14.tmpDir/fopen_variation14.tmp --- diff --git a/ext/standard/tests/file/fopen_variation14.phpt b/ext/standard/tests/file/fopen_variation14.phpt index 554527d08771..5fc8d92b7a0a 100644 --- a/ext/standard/tests/file/fopen_variation14.phpt +++ b/ext/standard/tests/file/fopen_variation14.phpt @@ -90,22 +90,22 @@ function runtest($fileURIs) { Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://./fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://./fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://./fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://./fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file:///%s/fopen14.tmpDir/fopen_variation14.tmp --- test passed --- WRITE: file:///%s/fopen14.tmpDir/fopen_variation14.tmp --- @@ -114,12 +114,12 @@ test passed Warning: fopen(): Remote host file access not supported, file://../fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://../fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://../fopen14.tmpDir/fopen_variation14.tmp --- Warning: fopen(): Remote host file access not supported, file://../fopen14.tmpDir/fopen_variation14.tmp in %s on line %d -Warning: fopen(file://../fopen14.tmpDir/fopen_variation14.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file:///%s/fopen14.tmpDir/fopen_variation14.tmp --- test passed --- WRITE: file:///%s/fopen14.tmpDir/fopen_variation14.tmp --- diff --git a/ext/standard/tests/file/fopen_variation15-win32.phpt b/ext/standard/tests/file/fopen_variation15-win32.phpt index edabaa5c5caf..266ea0d13ce9 100644 --- a/ext/standard/tests/file/fopen_variation15-win32.phpt +++ b/ext/standard/tests/file/fopen_variation15-win32.phpt @@ -102,42 +102,42 @@ function runtest($fileURIs) { Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen15.tmpDir\fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://./fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://./fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://./fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://./fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://.\fopen15.tmpDir\fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://.\fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://.\fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://.\fopen15.tmpDir\fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://.\fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://.\fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://%s/fopen15.tmpDir/fopen_variation15.tmp --- test passed --- WRITE: file://%s/fopen15.tmpDir/fopen_variation15.tmp --- @@ -154,22 +154,22 @@ test passed Warning: fopen(): Remote host file access not supported, file://../fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://../fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://../fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://../fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://../fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://..\fopen15.tmpDir\fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://..\fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://..\fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://..\fopen15.tmpDir\fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://..\fopen15.tmpDir\fopen_variation15.tmp in %s on line %d -Warning: fopen(file://..\fopen15.tmpDir\fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://%s/fopen15.tmpDir/fopen_variation15.tmp --- test passed --- WRITE: file://%s/fopen15.tmpDir/fopen_variation15.tmp --- diff --git a/ext/standard/tests/file/fopen_variation15.phpt b/ext/standard/tests/file/fopen_variation15.phpt index a182865bcbbc..b6cc92548dfc 100644 --- a/ext/standard/tests/file/fopen_variation15.phpt +++ b/ext/standard/tests/file/fopen_variation15.phpt @@ -94,22 +94,22 @@ function runtest($fileURIs) { Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file://./fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://./fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://./fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://./fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://./fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file:///%s/fopen15.tmpDir/fopen_variation15.tmp --- test passed --- WRITE: file:///%s/fopen15.tmpDir/fopen_variation15.tmp --- @@ -118,12 +118,12 @@ test passed Warning: fopen(): Remote host file access not supported, file://../fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://../fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- WRITE: file://../fopen15.tmpDir/fopen_variation15.tmp --- Warning: fopen(): Remote host file access not supported, file://../fopen15.tmpDir/fopen_variation15.tmp in %s on line %d -Warning: fopen(file://../fopen15.tmpDir/fopen_variation15.tmp): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d --- READ: file:///%s/fopen15.tmpDir/fopen_variation15.tmp --- test passed --- WRITE: file:///%s/fopen15.tmpDir/fopen_variation15.tmp --- diff --git a/ext/standard/tests/file/include_userstream_002.phpt b/ext/standard/tests/file/include_userstream_002.phpt index 263576076273..bf0a10963935 100644 --- a/ext/standard/tests/file/include_userstream_002.phpt +++ b/ext/standard/tests/file/include_userstream_002.phpt @@ -101,8 +101,8 @@ include "test2://hello"; Warning: fopen(): test1:// wrapper is disabled in the server configuration by allow_url_include=0 in %sinclude_userstream_002.php on line 11 -Warning: fopen(test1://hello): Failed to open stream: no suitable wrapper could be found in %sinclude_userstream_002.php on line 11 +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %sinclude_userstream_002.php on line 11 -Warning: include(test2://hello): Failed to open stream: "test::stream_open" call failed in %sinclude_userstream_002.php on line 90 +Warning: include(): Failed to open stream: "test::stream_open" call failed in %sinclude_userstream_002.php on line 90 Warning: include(): Failed opening 'test2://hello' for inclusion (include_path='%s') in %sinclude_userstream_002.php on line 90 diff --git a/ext/standard/tests/file/include_userstream_003.phpt b/ext/standard/tests/file/include_userstream_003.phpt index 1f2c44821f86..1a9c96833c90 100644 --- a/ext/standard/tests/file/include_userstream_003.phpt +++ b/ext/standard/tests/file/include_userstream_003.phpt @@ -100,26 +100,26 @@ Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0 Warning: file_get_contents(): test1:// wrapper is disabled in the server configuration by allow_url_fopen=0 in %s on line %d -Warning: file_get_contents(test1://hello): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: file_get_contents(): Failed to open stream: no suitable wrapper could be found in %s on line %d Warning: include(): test1:// wrapper is disabled in the server configuration by allow_url_fopen=0 in %s on line %d -Warning: include(test1://hello): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: include(): Failed to open stream: no suitable wrapper could be found in %s on line %d Warning: include(): Failed opening 'test1://hello' for inclusion (include_path='%s') in %s on line %d Warning: fopen(): test1:// wrapper is disabled in the server configuration by allow_url_fopen=0 in %s on line %d -Warning: fopen(test1://hello): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d -Warning: file_get_contents(test2://hello): Failed to open stream: "test::stream_open" call failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: "test::stream_open" call failed in %s on line %d Warning: fopen(): test1:// wrapper is disabled in the server configuration by allow_url_fopen=0 in %s on line %d -Warning: fopen(test1://hello): Failed to open stream: no suitable wrapper could be found in %s on line %d +Warning: fopen(): Failed to open stream: no suitable wrapper could be found in %s on line %d -Warning: include(test2://hello): Failed to open stream: "test::stream_open" call failed in %s on line %d +Warning: include(): Failed to open stream: "test::stream_open" call failed in %s on line %d Warning: include(): Failed opening 'test2://hello' for inclusion (include_path='%s') in %s on line %d diff --git a/ext/standard/tests/file/mkdir_rmdir_error.phpt b/ext/standard/tests/file/mkdir_rmdir_error.phpt index 4500de027668..44dc68f6da47 100644 --- a/ext/standard/tests/file/mkdir_rmdir_error.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_error.phpt @@ -11,6 +11,6 @@ echo "Done\n"; --EXPECTF-- *** Testing rmdir() on non-existent directory *** -Warning: rmdir(temp): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt b/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt index b6c186ed0b09..4e642cf7ae03 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt @@ -1596,7 +1596,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir私はガラスを食べられます/): Directory not empty in %s on line %d +Warning: rmdir(): Directory not empty in %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt b/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt index f4f412e802ff..377de5e6b9fe 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt @@ -1596,7 +1596,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir/): Directory not empty in %s on line %d +Warning: rmdir(): Directory not empty in %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt index 4da0b374ba94..831cb0c95662 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt @@ -56,7 +56,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir_variation2/): %s on line %d +Warning: rmdir(): %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/open_basedir_cwd_resolve.phpt b/ext/standard/tests/file/open_basedir_cwd_resolve.phpt index 9c95e4904fa0..074a015e1c14 100644 --- a/ext/standard/tests/file/open_basedir_cwd_resolve.phpt +++ b/ext/standard/tests/file/open_basedir_cwd_resolve.phpt @@ -11,5 +11,5 @@ var_dump(file_get_contents('/some/path/outside/open/basedir')); --EXPECTF-- Warning: file_get_contents(): open_basedir restriction in effect. File(/some/path/outside/open/basedir) is not within the allowed path(s): (%s) in %s on line %d -Warning: file_get_contents(/some/path/outside/open/basedir): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d +Warning: file_get_contents(): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d bool(false) diff --git a/ext/standard/tests/file/parse_ini_file_error.phpt b/ext/standard/tests/file/parse_ini_file_error.phpt index ce4952f1083f..583be4380061 100644 --- a/ext/standard/tests/file/parse_ini_file_error.phpt +++ b/ext/standard/tests/file/parse_ini_file_error.phpt @@ -22,11 +22,11 @@ echo "Done"; -- Testing parse_ini_file() function with more than expected no. of arguments -- -Warning: parse_ini_file(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Testing parse_ini_file() function with a non-existent file -- -Warning: parse_ini_file(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/parse_ini_file_variation6-win32-mb.phpt b/ext/standard/tests/file/parse_ini_file_variation6-win32-mb.phpt index c5c5934062cc..6834964a043c 100644 --- a/ext/standard/tests/file/parse_ini_file_variation6-win32-mb.phpt +++ b/ext/standard/tests/file/parse_ini_file_variation6-win32-mb.phpt @@ -91,12 +91,12 @@ array(1) { -- Iteration 5 -- -Warning: parse_ini_file(%sparseIniFileVar私はガラスを食べられます.dir\parseIniFileVar私はガラスを食べられますSub\..\\\parseIniFileVar私はガラスを食べられますSub\\..\\..\parseIniFileVar私はガラスを食べられますSub\parseIniFileVar私はガラスを食べられます.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: parse_ini_file(%sparseIniFileVar私はガラスを食べられます.dir\parseIniFileVar私はガラスを食べられますSub\BADDIR\parseIniFileVar私はガラスを食べられます.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -125,7 +125,7 @@ array(1) { -- Iteration 11 -- -Warning: parse_ini_file(BADDIR\parseIniFileVar私はガラスを食べられます.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 12 -- diff --git a/ext/standard/tests/file/parse_ini_file_variation6-win32.phpt b/ext/standard/tests/file/parse_ini_file_variation6-win32.phpt index a7b005c6e9aa..b187c1ed2173 100644 --- a/ext/standard/tests/file/parse_ini_file_variation6-win32.phpt +++ b/ext/standard/tests/file/parse_ini_file_variation6-win32.phpt @@ -91,12 +91,12 @@ array(1) { -- Iteration 5 -- -Warning: parse_ini_file(%sparseIniFileVar6.dir\parseIniFileVar6Sub\..\\\parseIniFileVar6Sub\\..\\..\parseIniFileVar6Sub\ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: parse_ini_file(%sparseIniFileVar6.dir\parseIniFileVar6Sub\BADDIR\ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -125,7 +125,7 @@ array(1) { -- Iteration 11 -- -Warning: parse_ini_file(BADDIR\ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 12 -- diff --git a/ext/standard/tests/file/parse_ini_file_variation6.phpt b/ext/standard/tests/file/parse_ini_file_variation6.phpt index 4c84672821d8..03fde0dc3032 100644 --- a/ext/standard/tests/file/parse_ini_file_variation6.phpt +++ b/ext/standard/tests/file/parse_ini_file_variation6.phpt @@ -87,12 +87,12 @@ array(1) { -- Iteration 5 -- -Warning: parse_ini_file(%sparseIniFileVar6.dir/parseIniFileVar6Sub/..///parseIniFileVar6Sub//..//../parseIniFileVar6Sub/ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 6 -- -Warning: parse_ini_file(%sparseIniFileVar6.dir/parseIniFileVar6Sub/BADDIR/ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 7 -- @@ -121,7 +121,7 @@ array(1) { -- Iteration 11 -- -Warning: parse_ini_file(BADDIR/ParseIniFileVar6.ini): Failed to open stream: No such file or directory in %s on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/pathinfo_variation3.phpt b/ext/standard/tests/file/pathinfo_variation3.phpt index aa1494b57997..86f88677d813 100644 --- a/ext/standard/tests/file/pathinfo_variation3.phpt +++ b/ext/standard/tests/file/pathinfo_variation3.phpt @@ -15,15 +15,37 @@ var_dump(pathinfo($testfile, PATHINFO_BASENAME)); var_dump(pathinfo($testfile, PATHINFO_FILENAME)); var_dump(pathinfo($testfile, PATHINFO_EXTENSION)); var_dump(pathinfo($testfile, PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME)); +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} ?> --EXPECTF-- @@ -62,11 +84,9 @@ string(6) "inet.h" string(4) "inet" string(1) "h" string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(1) "h" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants diff --git a/ext/standard/tests/file/php_fd_wrapper_03.phpt b/ext/standard/tests/file/php_fd_wrapper_03.phpt index 991c497f5e19..f8ce8ffef61f 100644 --- a/ext/standard/tests/file/php_fd_wrapper_03.phpt +++ b/ext/standard/tests/file/php_fd_wrapper_03.phpt @@ -10,14 +10,13 @@ fopen("php://fd/1/", "w"); echo "\nDone.\n"; ?> --EXPECTF-- -Warning: fopen(): Invalid php:// URL specified in %s on line %d -Warning: fopen(php://fd): Failed to open stream: operation failed in %s on line 2 +Warning: fopen(): Failed to open stream: operation failed in %s on line 2 -Warning: fopen(php://fd/): Failed to open stream: php://fd/ stream must be specified in the form php://fd/ in %s on line %d +Warning: fopen(): Failed to open stream: php://fd/ stream must be specified in the form php://fd/ in %s on line %d -Warning: fopen(php://fd/-2): Failed to open stream: The file descriptors must be non-negative numbers smaller than %d in %s on line %d +Warning: fopen(): Failed to open stream: The file descriptors must be non-negative numbers smaller than %d in %s on line %d -Warning: fopen(php://fd/1/): Failed to open stream: php://fd/ stream must be specified in the form php://fd/ in %s on line %d +Warning: fopen(): Failed to open stream: php://fd/ stream must be specified in the form php://fd/ in %s on line %d Done. diff --git a/ext/standard/tests/file/php_fd_wrapper_04.phpt b/ext/standard/tests/file/php_fd_wrapper_04.phpt index e1f9927ee9d2..068866f9adb2 100644 --- a/ext/standard/tests/file/php_fd_wrapper_04.phpt +++ b/ext/standard/tests/file/php_fd_wrapper_04.phpt @@ -12,6 +12,6 @@ fopen("php://fd/1023", "w"); echo "\nDone.\n"; ?> --EXPECTF-- -Warning: fopen(php://fd/1023): Failed to open stream: Error duping file descriptor 1023; possibly it doesn't exist: [9]: %s in %s on line %d +Warning: fopen(): Failed to open stream: Error duping file descriptor 1023; possibly it doesn't exist: [9]: %s in %s on line %d Done. diff --git a/ext/standard/tests/file/readfile_error.phpt b/ext/standard/tests/file/readfile_error.phpt index ec2cf53946a6..d21554296a15 100644 --- a/ext/standard/tests/file/readfile_error.phpt +++ b/ext/standard/tests/file/readfile_error.phpt @@ -34,6 +34,6 @@ Path must not be empty -- Testing readfile() with non-existent file -- -Warning: readfile(%s/non_existent_file.tmp): Failed to open stream: %s in %s on line %d +Warning: readfile(): Failed to open stream: %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/readfile_variation10-win32.phpt b/ext/standard/tests/file/readfile_variation10-win32.phpt index 2ec770b4101c..1dbb896fbc8c 100644 --- a/ext/standard/tests/file/readfile_variation10-win32.phpt +++ b/ext/standard/tests/file/readfile_variation10-win32.phpt @@ -44,11 +44,11 @@ foreach($names_arr as $key => $value) { -- Filename: -1 -- -Warning: readfile(-1): Failed to open stream: No such file or directory in %s on line %d +Warning: readfile(): Failed to open stream: No such file or directory in %s on line %d -- Filename: TRUE -- -Warning: readfile(1): Failed to open stream: No such file or directory in %s on line %d +Warning: readfile(): Failed to open stream: No such file or directory in %s on line %d -- Filename: FALSE -- ValueError: Path must not be empty @@ -58,7 +58,7 @@ ValueError: Path must not be empty -- Filename: " " -- -Warning: readfile( ): Failed to open stream: Permission denied in %s on line %d +Warning: readfile(): Failed to open stream: Permission denied in %s on line %d -- Filename: \0 -- ValueError: readfile(): Argument #1 ($filename) must not contain any null bytes @@ -68,8 +68,8 @@ TypeError: readfile(): Argument #1 ($filename) must be of type string, array giv -- Filename: /no/such/file/dir -- -Warning: readfile(/no/such/file/dir): Failed to open stream: No such file or directory in %s on line %d +Warning: readfile(): Failed to open stream: No such file or directory in %s on line %d -- Filename: php/php -- -Warning: readfile(php/php): Failed to open stream: No such file or directory in %s on line %d +Warning: readfile(): Failed to open stream: No such file or directory in %s on line %d diff --git a/ext/standard/tests/file/readfile_variation10.phpt b/ext/standard/tests/file/readfile_variation10.phpt index d2875215e5f7..3782f7384515 100644 --- a/ext/standard/tests/file/readfile_variation10.phpt +++ b/ext/standard/tests/file/readfile_variation10.phpt @@ -44,22 +44,22 @@ for( $i=0; $i +--INI-- +zend.exception_string_param_max_len=1000000 +error_include_args=On --SKIPIF-- +--INI-- +zend.exception_string_param_max_len=1000000 +error_include_args=On --SKIPIF-- bool(true) @@ -70,11 +70,11 @@ array(7) { } NULL -Warning: fopen(data://;base64): Failed to open stream: rfc2397: no comma in URL in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: no comma in URL in %sstream_rfc2397_002.php on line %d -Warning: fopen(data://foo,): Failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d -Warning: fopen(data://foo=bar,): Failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d array(8) { ["mediatype"]=> string(10) "text/plain" @@ -95,7 +95,7 @@ array(8) { } NULL -Warning: fopen(data://text/plain;foo,): Failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d array(9) { ["mediatype"]=> string(10) "text/plain" @@ -118,7 +118,7 @@ array(9) { } string(3) "bar" -Warning: fopen(data://text/plain;foo=bar;bla,): Failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d array(9) { ["mediatype"]=> string(10) "text/plain" @@ -141,7 +141,7 @@ array(9) { } string(3) "bar" -Warning: fopen(data://text/plain;foo=bar;bar=baz): Failed to open stream: rfc2397: no comma in URL in %sstream_rfc2397_002.php on line %d +Warning: fopen(): Failed to open stream: rfc2397: no comma in URL in %sstream_rfc2397_002.php on line %d array(10) { ["mediatype"]=> string(10) "text/plain" diff --git a/ext/standard/tests/file/stream_rfc2397_006.phpt b/ext/standard/tests/file/stream_rfc2397_006.phpt index 649c94d6da65..bde1d4e0cebe 100644 --- a/ext/standard/tests/file/stream_rfc2397_006.phpt +++ b/ext/standard/tests/file/stream_rfc2397_006.phpt @@ -26,8 +26,8 @@ foreach($streams as $stream) file_get_contents(): Argument #1 ($filename) must not contain any null bytes file_get_contents(): Argument #1 ($filename) must not contain any null bytes -Warning: file_get_contents(data:;base64,#Zm9vYmFyIGZvb2Jhcg==): Failed to open stream: rfc2397: unable to decode in %sstream_rfc2397_006.php on line %d +Warning: file_get_contents(): Failed to open stream: rfc2397: unable to decode in %sstream_rfc2397_006.php on line %d bool(false) -Warning: file_get_contents(data:;base64,#Zm9vYmFyIGZvb2Jhc=): Failed to open stream: rfc2397: unable to decode in %sstream_rfc2397_006.php on line %d +Warning: file_get_contents(): Failed to open stream: rfc2397: unable to decode in %sstream_rfc2397_006.php on line %d bool(false) diff --git a/ext/standard/tests/file/symlink_link_linkinfo_is_link_error1.phpt b/ext/standard/tests/file/symlink_link_linkinfo_is_link_error1.phpt index f4035f8f40a2..c8420ea86fb2 100644 --- a/ext/standard/tests/file/symlink_link_linkinfo_is_link_error1.phpt +++ b/ext/standard/tests/file/symlink_link_linkinfo_is_link_error1.phpt @@ -27,8 +27,11 @@ var_dump( symlink($filename, false) ); // false as linkname echo "\n*** Testing linkinfo() for error conditions ***\n"; //invalid arguments -var_dump( linkinfo('') ); // empty string as linkname -var_dump( linkinfo(false) ); // boolean false as linkname +try { + var_dump(linkinfo('')); // empty string as linkname +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} echo "Done\n"; ?> @@ -53,10 +56,5 @@ Warning: symlink(): %s in %s on line %d bool(false) *** Testing linkinfo() for error conditions *** - -Warning: linkinfo(): %s in %s on line %d -int(-1) - -Warning: linkinfo(): %s in %s on line %d -int(-1) +linkinfo(): Argument #1 ($path) must not be empty Done diff --git a/ext/standard/tests/file/unlink_error-win32-mb.phpt b/ext/standard/tests/file/unlink_error-win32-mb.phpt index df98e2e36735..a62114fe7dab 100644 --- a/ext/standard/tests/file/unlink_error-win32-mb.phpt +++ b/ext/standard/tests/file/unlink_error-win32-mb.phpt @@ -65,11 +65,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): Is a directory in %s on line %d +Warning: unlink(): Is a directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_error-win32.phpt b/ext/standard/tests/file/unlink_error-win32.phpt index 6bce3d4b8060..1e4500d2b7e8 100644 --- a/ext/standard/tests/file/unlink_error-win32.phpt +++ b/ext/standard/tests/file/unlink_error-win32.phpt @@ -62,11 +62,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): Is a directory in %s on line %d +Warning: unlink(): Is a directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_error.phpt b/ext/standard/tests/file/unlink_error.phpt index 1dd8ef1a25c9..8174f1b01268 100644 --- a/ext/standard/tests/file/unlink_error.phpt +++ b/ext/standard/tests/file/unlink_error.phpt @@ -61,11 +61,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_variation1-win32-mb.phpt b/ext/standard/tests/file/unlink_variation1-win32-mb.phpt index 8d2a80726a67..37132d13d63a 100644 --- a/ext/standard/tests/file/unlink_variation1-win32-mb.phpt +++ b/ext/standard/tests/file/unlink_variation1-win32-mb.phpt @@ -77,7 +77,7 @@ bool(true) -- Unlinking file without write permission, its dir having default permission -- bool(true) -Warning: unlink(%s/unlink_variation1/unlink_variation1-win32.tmp): Permission denied in %s on line %d +Warning: unlink(): Permission denied in %s on line %d bool(false) bool(true) bool(false) diff --git a/ext/standard/tests/file/unlink_variation1-win32.phpt b/ext/standard/tests/file/unlink_variation1-win32.phpt index 813e4a2e77fc..c6a0f8804a38 100644 --- a/ext/standard/tests/file/unlink_variation1-win32.phpt +++ b/ext/standard/tests/file/unlink_variation1-win32.phpt @@ -75,7 +75,7 @@ bool(true) -- Unlinking file without write permission, its dir having default permission -- bool(true) -Warning: unlink(%s/unlink_variation1/unlink_variation1-win32.tmp): Permission denied in %s on line %d +Warning: unlink(): Permission denied in %s on line %d bool(false) bool(true) bool(false) diff --git a/ext/standard/tests/file/unlink_variation1.phpt b/ext/standard/tests/file/unlink_variation1.phpt index eafdf92f1f06..5f6320b60651 100644 --- a/ext/standard/tests/file/unlink_variation1.phpt +++ b/ext/standard/tests/file/unlink_variation1.phpt @@ -64,7 +64,7 @@ echo "Done\n"; -- Unlink file having default permission and its dir having read only permission -- bool(true) -Warning: unlink(%s): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) bool(false) bool(true) diff --git a/ext/standard/tests/file/unlink_variation10.phpt b/ext/standard/tests/file/unlink_variation10.phpt index 127b070d23a2..4a3c8de596fc 100644 --- a/ext/standard/tests/file/unlink_variation10.phpt +++ b/ext/standard/tests/file/unlink_variation10.phpt @@ -95,4 +95,4 @@ directory unlinked --- try to unlink a directory --- -Warning: unlink(unlinkVar10.tmp/linkme.tmp): %s in %s on line %d +Warning: unlink(): %s in %s on line %d diff --git a/ext/standard/tests/file/unlink_variation4.phpt b/ext/standard/tests/file/unlink_variation4.phpt index 99dd0c632dbb..193d50821abd 100644 --- a/ext/standard/tests/file/unlink_variation4.phpt +++ b/ext/standard/tests/file/unlink_variation4.phpt @@ -29,6 +29,6 @@ echo "Done\n"; bool(true) bool(false) -Warning: unlink(%s/unlink_variation4.tmp): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_variation8-win32.phpt b/ext/standard/tests/file/unlink_variation8-win32.phpt index 016beddce1c1..1a9afcae7ff2 100644 --- a/ext/standard/tests/file/unlink_variation8-win32.phpt +++ b/ext/standard/tests/file/unlink_variation8-win32.phpt @@ -80,10 +80,10 @@ file removed file removed -- removing unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing %s/unlinkVar8.tmp/file.tmp -- file removed -- removing %s/./unlinkVar8.tmp/file.tmp -- @@ -92,13 +92,13 @@ file removed file removed -- removing %s/BADDIR/file.tmp -- -Warning: unlink(%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing %s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(%s/unlinkVar8.tmp/file.tmp/): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing unlinkVar8.tmp//file.tmp -- file removed -- removing %s//unlinkVar8.tmp//file.tmp -- diff --git a/ext/standard/tests/file/unlink_variation8.phpt b/ext/standard/tests/file/unlink_variation8.phpt index 71eca9199acd..d79d9e805787 100644 --- a/ext/standard/tests/file/unlink_variation8.phpt +++ b/ext/standard/tests/file/unlink_variation8.phpt @@ -123,22 +123,22 @@ file unlinked file unlinked -- removing unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing /%s/unlinkVar8.tmp/file.tmp -- file removed -- unlinking soft link /%s/unlinkVar8.tmp/file.tmp -- @@ -159,31 +159,31 @@ file unlinked file unlinked -- removing /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- unlinking soft link unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): %s directory in %s on line %d +Warning: unlink(): %s directory in %s on line %d -- unlinking hard link unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- removing /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- unlinking soft link /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): %s directory in %s on line %d +Warning: unlink(): %s directory in %s on line %d -- unlinking hard link /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- removing unlinkVar8.tmp//file.tmp -- file removed -- unlinking soft link unlinkVar8.tmp//file.tmp -- diff --git a/ext/standard/tests/file/unlink_variation9-win32.phpt b/ext/standard/tests/file/unlink_variation9-win32.phpt index 68e11be92763..d5406f99d85f 100644 --- a/ext/standard/tests/file/unlink_variation9-win32.phpt +++ b/ext/standard/tests/file/unlink_variation9-win32.phpt @@ -82,10 +82,10 @@ file removed file removed -- removing unlinkVar9.tmp\..\BADDIR\file.tmp -- -Warning: unlink(unlinkVar9.tmp\..\BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR\file.tmp -- -Warning: unlink(BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing %s\unlinkVar9.tmp\file.tmp -- file removed -- removing %s\.\unlinkVar9.tmp\file.tmp -- @@ -94,13 +94,13 @@ file removed file removed -- removing %s\BADDIR\file.tmp -- -Warning: unlink(%s\BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar9.tmp\file.tmp\ -- -Warning: unlink(unlinkVar9.tmp\file.tmp\): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing %s\unlinkVar9.tmp\file.tmp\ -- -Warning: unlink(%s\unlinkVar9.tmp\file.tmp\): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing unlinkVar9.tmp\\file.tmp -- file removed -- removing %s\\unlinkVar9.tmp\\file.tmp -- diff --git a/ext/standard/tests/filters/chunked_002.phpt b/ext/standard/tests/filters/chunked_002.phpt new file mode 100644 index 000000000000..7114e278e3bd --- /dev/null +++ b/ext/standard/tests/filters/chunked_002.phpt @@ -0,0 +1,58 @@ +--TEST-- +Dechunk write filter state must survive stream seek +--FILE-- + +--EXPECT-- +string(5) "Hello" +string(12) "Hello, World" +string(12) "Hello, World" +string(5) "Hello" +int(5) diff --git a/ext/standard/tests/filters/convert_filter_seek.phpt b/ext/standard/tests/filters/convert_filter_seek.phpt new file mode 100644 index 000000000000..6cbcd7b843f3 --- /dev/null +++ b/ext/standard/tests/filters/convert_filter_seek.phpt @@ -0,0 +1,75 @@ +--TEST-- +convert filters (base64, quoted-printable) with seek to start only +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Testing convert.base64-encode/decode +First read (20 bytes): Hello World! This is +Seek to start: SUCCESS +Content matches: YES + +Warning: fseek(): Stream filter convert.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE + +Testing convert.quoted-printable-encode/decode +First read (10 bytes): 4c696e65310d0a4c696e +Seek to start: SUCCESS +Content matches: YES + +Warning: fseek(): Stream filter convert.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE diff --git a/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt b/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt new file mode 100644 index 000000000000..0a2d4114bf3c --- /dev/null +++ b/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt @@ -0,0 +1,61 @@ +--TEST-- +convert.* write filter: write_seek_mode parameter +--FILE-- + 'preserve']); + fwrite($fp, 'Hello'); + var_dump(fseek($fp, 0, SEEK_SET) === 0); + var_dump(fseek($fp, 100, SEEK_SET) === 0); + fclose($fp); + + /* reset: seeks succeed, callback dispatched */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 'reset']); + fwrite($fp, 'Hello'); + var_dump(fseek($fp, 0, SEEK_SET) === 0); + fclose($fp); + + /* strict: seek fails */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 'strict']); + fwrite($fp, 'Hello'); + var_dump(@fseek($fp, 0, SEEK_SET) === -1); + fclose($fp); + + /* invalid: ValueError */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 42]); + if ($fp) { + fclose($fp); + } +} +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s + +Warning: stream_filter_append(): Unable to create or locate filter "convert.base64-encode" in %s +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s + +Warning: stream_filter_append(): Unable to create or locate filter "convert.quoted-printable-encode" in %s diff --git a/ext/standard/tests/filters/dechunk_size_overflow.phpt b/ext/standard/tests/filters/dechunk_size_overflow.phpt new file mode 100644 index 000000000000..ac42733e16e0 --- /dev/null +++ b/ext/standard/tests/filters/dechunk_size_overflow.phpt @@ -0,0 +1,38 @@ +--TEST-- +dechunk filter must reject a chunk size that overflows size_t +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + +--EXPECTF-- +string(%d) "%s +BODYDATA +0 +" +string(%d) "%s +BODYDATA +0 +" +string(5) "hello" diff --git a/ext/standard/tests/filters/gh22360.phpt b/ext/standard/tests/filters/gh22360.phpt new file mode 100644 index 000000000000..b23483b22b92 --- /dev/null +++ b/ext/standard/tests/filters/gh22360.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-22360 (convert.base64-encode emits padding on incremental flush) +--FILE-- + +--CLEAN-- + +--EXPECT-- +string(4) "YWJj" +YWJj diff --git a/ext/standard/tests/filters/php_user_filter_04.phpt b/ext/standard/tests/filters/php_user_filter_04.phpt new file mode 100644 index 000000000000..6dc62779aa90 --- /dev/null +++ b/ext/standard/tests/filters/php_user_filter_04.phpt @@ -0,0 +1,28 @@ +--TEST-- +php_user_filter with invalid seek signature +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of InvalidSeekFilter::seek($offset): bool must be compatible with php_user_filter::seek(int $offset, int $whence, int $chain): bool in %s on line %d diff --git a/ext/standard/tests/filters/string_filters_seek.phpt b/ext/standard/tests/filters/string_filters_seek.phpt new file mode 100644 index 000000000000..60eab2ccb84a --- /dev/null +++ b/ext/standard/tests/filters/string_filters_seek.phpt @@ -0,0 +1,68 @@ +--TEST-- +string filters (rot13, toupper, tolower) with seek - fully seekable +--FILE-- + 'Uryyb Jbeyq! Guvf vf n grfg sbe fgevat svygre frrxvat.', + 'string.toupper' => 'HELLO WORLD! THIS IS A TEST FOR STRING FILTER SEEKING.', + 'string.tolower' => 'hello world! this is a test for string filter seeking.' +]; + +foreach ($filters as $filter) { + echo "Testing filter: $filter\n"; + + file_put_contents($file, $text); + + $fp = fopen($file, 'r'); + stream_filter_append($fp, $filter, STREAM_FILTER_READ); + + $partial = fread($fp, 20); + echo "First read (20 bytes): $partial\n"; + + $result = fseek($fp, 0, SEEK_SET); + echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + + $full = fread($fp, strlen($text)); + echo "Content matches: " . ($full === $expected[$filter] ? "YES" : "NO") . "\n"; + + $result = fseek($fp, 13, SEEK_SET); + echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + + $from_middle = fread($fp, 10); + $expected_middle = substr($expected[$filter], 13, 10); + echo "Read from middle matches: " . ($from_middle === $expected_middle ? "YES" : "NO") . "\n"; + + fclose($fp); + echo "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +Testing filter: string.rot13 +First read (20 bytes): Uryyb Jbeyq! Guvf vf +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES + +Testing filter: string.toupper +First read (20 bytes): HELLO WORLD! THIS IS +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES + +Testing filter: string.tolower +First read (20 bytes): hello world! this is +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES diff --git a/ext/standard/tests/filters/user_filter_seek_01.phpt b/ext/standard/tests/filters/user_filter_seek_01.phpt new file mode 100644 index 000000000000..6023ced1d0ee --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_01.phpt @@ -0,0 +1,83 @@ +--TEST-- +php_user_filter with seek method - always seekable (stateless filter) +--EXTENSIONS-- +ctype +--FILE-- +data); $i++) { + $char = $bucket->data[$i]; + if (ctype_alpha($char)) { + $base = ctype_upper($char) ? ord('A') : ord('a'); + $rotated .= chr($base + (ord($char) - $base + $this->rotation) % 26); + } else { + $rotated .= $char; + } + } + $bucket->data = $rotated; + $consumed += $bucket->datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + if (isset($this->params['rotation'])) { + $this->rotation = (int)$this->params['rotation']; + } + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + // Stateless filter - always seekable to any position + return true; + } +} + +stream_filter_register('test.rotate', 'RotateFilter'); + +$file = __DIR__ . '/user_filter_seek_001.txt'; +$text = 'Hello World'; + +file_put_contents($file, $text); + +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.rotate', STREAM_FILTER_READ, ['rotation' => 13]); + +$partial = fread($fp, 5); +echo "First read: $partial\n"; + +$result = fseek($fp, 0, SEEK_SET); +echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$full = fread($fp, strlen($text)); +echo "Full content: $full\n"; + +$result = fseek($fp, 6, SEEK_SET); +echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$from_middle = fread($fp, 5); +echo "Read from middle: $from_middle\n"; + +fclose($fp); +unlink($file); + +?> +--EXPECT-- +First read: Uryyb +Seek to start: SUCCESS +Full content: Uryyb Jbeyq +Seek to middle: SUCCESS +Read from middle: Jbeyq diff --git a/ext/standard/tests/filters/user_filter_seek_02.phpt b/ext/standard/tests/filters/user_filter_seek_02.phpt new file mode 100644 index 000000000000..f728e75cdca9 --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_02.phpt @@ -0,0 +1,75 @@ +--TEST-- +php_user_filter with seek method - stateful filter +--FILE-- +data); $i++) { + $modified .= $bucket->data[$i] . $this->count++; + } + $bucket->data = $modified; + $consumed += $bucket->datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + if ($offset === 0 && $whence === SEEK_SET) { + $this->count = 0; + return true; + } + return false; + } +} + +stream_filter_register('test.counting', 'CountingFilter'); + +$file = __DIR__ . '/user_filter_seek_002.txt'; +$text = 'ABC'; + +file_put_contents($file, $text); + +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.counting', STREAM_FILTER_READ); + +$first = fread($fp, 10); +echo "First read: $first\n"; + +$result = fseek($fp, 0, SEEK_SET); +echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$second = fread($fp, 10); +echo "Second read after seek: $second\n"; +echo "Counts reset: " . ($first === $second ? "YES" : "NO") . "\n"; + +$result = fseek($fp, 1, SEEK_SET); +echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +fclose($fp); +unlink($file); + +?> +--EXPECTF-- +First read: A0B1C2 +Seek to start: SUCCESS +Second read after seek: A0B1C2 +Counts reset: YES + +Warning: fseek(): Stream filter seeking for user-filter failed in %s on line %d +Seek to middle: FAILURE diff --git a/ext/standard/tests/filters/user_filter_seek_03.phpt b/ext/standard/tests/filters/user_filter_seek_03.phpt new file mode 100644 index 000000000000..bc814e8ed160 --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_03.phpt @@ -0,0 +1,67 @@ +--TEST-- +php_user_filter::seek receives chain identifier (read vs write) +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + $name = match ($chain) { + STREAM_FILTER_READ => 'read', + STREAM_FILTER_WRITE => 'write', + default => 'other', + }; + self::$log[] = "$name:$offset:$whence"; + return true; + } +} + +stream_filter_register('test.tracking', 'TrackingFilter'); + +$file = __DIR__ . '/user_filter_seek_03.txt'; +file_put_contents($file, "abcdefghij"); + +/* Read chain: seek-to-start should dispatch with STREAM_FILTER_READ */ +TrackingFilter::$log = []; +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.tracking', STREAM_FILTER_READ); +fread($fp, 4); +fseek($fp, 0, SEEK_SET); +fclose($fp); +echo "Read chain log: " . implode(',', TrackingFilter::$log) . "\n"; + +/* Write chain: any seek should dispatch with STREAM_FILTER_WRITE */ +TrackingFilter::$log = []; +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'test.tracking', STREAM_FILTER_WRITE); +fwrite($fp, "xyz"); +fseek($fp, 0, SEEK_SET); +fseek($fp, 5, SEEK_SET); +fclose($fp); +echo "Write chain log: " . implode(',', TrackingFilter::$log) . "\n"; + +unlink($file); + +?> +--EXPECT-- +Read chain log: read:0:0 +Write chain log: write:0:0,write:5:0 diff --git a/ext/standard/tests/general_functions/bug44295-win.phpt b/ext/standard/tests/general_functions/bug44295-win.phpt index e5eb4c26a941..223e0c24a10c 100644 --- a/ext/standard/tests/general_functions/bug44295-win.phpt +++ b/ext/standard/tests/general_functions/bug44295-win.phpt @@ -23,7 +23,7 @@ try { ?> ==DONE== ---EXPECTF-- +--EXPECT-- before -in catch: DirectoryIterator::__construct(c:\not\exists\here): %s (code: 3) +in catch: DirectoryIterator::__construct(): Failed to open directory: No such file or directory ==DONE== diff --git a/ext/standard/tests/general_functions/bug44295.phpt b/ext/standard/tests/general_functions/bug44295.phpt index 12cfb819a42b..131f6496b7b4 100644 --- a/ext/standard/tests/general_functions/bug44295.phpt +++ b/ext/standard/tests/general_functions/bug44295.phpt @@ -25,5 +25,5 @@ try { --EXPECT-- before -in catch: DirectoryIterator::__construct(/this/path/does/not/exist): Failed to open directory: No such file or directory +in catch: DirectoryIterator::__construct(): Failed to open directory: No such file or directory ==DONE== diff --git a/ext/standard/tests/general_functions/dl_null_bytes.phpt b/ext/standard/tests/general_functions/dl_null_bytes.phpt new file mode 100644 index 000000000000..7f251393ba3b --- /dev/null +++ b/ext/standard/tests/general_functions/dl_null_bytes.phpt @@ -0,0 +1,14 @@ +--TEST-- +dl() rejects null bytes in extension filename +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +dl(): Argument #1 ($extension_filename) must not contain any null bytes diff --git a/ext/standard/tests/general_functions/gh22118.phpt b/ext/standard/tests/general_functions/gh22118.phpt new file mode 100644 index 000000000000..32c1a0fa1dec --- /dev/null +++ b/ext/standard/tests/general_functions/gh22118.phpt @@ -0,0 +1,75 @@ +--TEST-- +GH-22118: unregister_tick_function() unregisters equivalent first-class method callables +--FILE-- +direct++; + } + + public function arrayCallable(): void + { + $this->array++; + } + + public function __invoke(): void + { + $this->invoke++; + } + + public function __call(string $name, array $arguments): void + { + $this->trampoline++; + } + + public function run(): void + { + register_tick_function($this->kick(...)); + unregister_tick_function($this->kick(...)); + echo "direct: {$this->direct}\n"; + + register_tick_function($this->missing(...)); + unregister_tick_function($this->missing(...)); + echo "trampoline: {$this->trampoline}\n"; + + register_tick_function($this->arrayCallable(...)); + unregister_tick_function([$this, 'arrayCallable']); + echo "array: {$this->array}\n"; + + register_tick_function($this(...)); + unregister_tick_function($this); + echo "invoke: {$this->invoke}\n"; + } +} + +register_tick_function(tick_string(...)); +unregister_tick_function('tick_string'); +echo "string: {$string}\n"; + +(new TickTest())->run(); +echo "done\n"; +?> +--EXPECT-- +string: 1 +direct: 1 +trampoline: 1 +array: 1 +invoke: 1 +done diff --git a/ext/standard/tests/general_functions/headers_sent_by_ref_args.phpt b/ext/standard/tests/general_functions/headers_sent_by_ref_args.phpt new file mode 100644 index 000000000000..bd222ca91437 --- /dev/null +++ b/ext/standard/tests/general_functions/headers_sent_by_ref_args.phpt @@ -0,0 +1,119 @@ +--TEST-- +headers_sent() by-ref argument with named arguments +--FILE-- + +--EXPECTF-- +headers_sent(line: $line) prior to sending headers +headers_sent(): +bool(false) +headers_list(): +array(0) { +} +$file: +NULL +$line: +int(0) +headers_sent(filename: $file) prior to sending headers +headers_sent(): +bool(false) +headers_list(): +array(0) { +} +$file: +string(0) "" +$line: +NULL +header(): +NULL +headers_sent(line: $line) after sending headers +headers_sent(): +bool(true) +headers_list(): +array(0) { +} +$file: +NULL +$line: +int(39) +headers_sent(filename: $file) after sending headers +headers_sent(): +bool(true) +headers_list(): +array(0) { +} +$file: +string(%d) "%s" +$line: +NULL +Done diff --git a/ext/standard/tests/general_functions/ini_get_all.phpt b/ext/standard/tests/general_functions/ini_get_all.phpt index 2b71b474a013..c54b39ac3325 100644 --- a/ext/standard/tests/general_functions/ini_get_all.phpt +++ b/ext/standard/tests/general_functions/ini_get_all.phpt @@ -33,29 +33,35 @@ array(0) { } array(3) { ["pcre.backtrack_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(7) "1000000" ["local_value"]=> string(7) "1000000" + ["builtin_default_value"]=> + string(7) "1000000" ["access"]=> int(7) } ["pcre.jit"]=> - array(3) { + array(4) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" + ["builtin_default_value"]=> + string(1) "1" ["access"]=> int(7) } ["pcre.recursion_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(6) "100000" ["local_value"]=> string(6) "100000" + ["builtin_default_value"]=> + string(6) "100000" ["access"]=> int(7) } diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt new file mode 100644 index 000000000000..82de8781caa7 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() exposes the built-in default value independent of configuration and runtime changes +--INI-- +precision=8 +--FILE-- + +--EXPECT-- +string(1) "8" +string(1) "8" +string(2) "14" +string(1) "8" +string(1) "3" +string(2) "14" +Done diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt new file mode 100644 index 000000000000..efd86eb947e4 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() reports a null built-in default value for a directive that has no compiled-in default +--INI-- +error_append_string=FOO +--FILE-- + +--EXPECT-- +string(3) "FOO" +string(3) "FOO" +NULL +string(3) "FOO" +string(3) "BAR" +NULL +Done diff --git a/ext/standard/tests/general_functions/parse_ini_file.phpt b/ext/standard/tests/general_functions/parse_ini_file.phpt index ff0f9f2e6f10..b5bc4daac882 100644 --- a/ext/standard/tests/general_functions/parse_ini_file.phpt +++ b/ext/standard/tests/general_functions/parse_ini_file.phpt @@ -117,10 +117,10 @@ var_dump(parse_ini_file($filename, true)); echo "Done\n"; ?> --EXPECTF-- -Warning: parse_ini_file(%sparse_ini_file.dat): Failed to open stream: No such file or directory in %sparse_ini_file.php on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %sparse_ini_file.php on line %d bool(false) -Warning: parse_ini_file(%sparse_ini_file.dat): Failed to open stream: No such file or directory in %sparse_ini_file.php on line %d +Warning: parse_ini_file(): Failed to open stream: No such file or directory in %sparse_ini_file.php on line %d bool(false) array(1) { ["test"]=> diff --git a/ext/standard/tests/general_functions/phpcredits.phpt b/ext/standard/tests/general_functions/phpcredits.phpt index dfcddc61f39d..347f3018d49a 100644 --- a/ext/standard/tests/general_functions/phpcredits.phpt +++ b/ext/standard/tests/general_functions/phpcredits.phpt @@ -33,7 +33,7 @@ Language Design & Concept %wPHP Documentation%w %a -PHP Quality Assurance Team +%wPHP Quality Assurance Team%w %a %wWebsites and Infrastructure team%w diff --git a/ext/standard/tests/general_functions/phpinfo.phpt b/ext/standard/tests/general_functions/phpinfo.phpt index ac7cabd340d8..a7503ec0bc41 100644 --- a/ext/standard/tests/general_functions/phpinfo.phpt +++ b/ext/standard/tests/general_functions/phpinfo.phpt @@ -57,7 +57,7 @@ Environment %r(.*?)%r PHP Variables %r(.*?)%r -PHP License +License %r(.*?)%r bool(true) -- @@ -66,6 +66,6 @@ bool(true) -- phpinfo() -PHP License +License %r(.+?)%r bool(true) diff --git a/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt b/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt new file mode 100644 index 000000000000..faa86c824177 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_open_cwd_null_bytes.phpt @@ -0,0 +1,18 @@ +--TEST-- +proc_open() rejects null bytes in cwd +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +proc_open(): Argument #4 ($cwd) must not contain any null bytes diff --git a/ext/standard/tests/general_functions/proc_open_fd_leak_on_setup_failure.phpt b/ext/standard/tests/general_functions/proc_open_fd_leak_on_setup_failure.phpt new file mode 100644 index 000000000000..e072f75a82d2 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_open_fd_leak_on_setup_failure.phpt @@ -0,0 +1,20 @@ +--TEST-- +proc_open() does not leak file descriptors when descriptor setup fails mid-spec +--SKIPIF-- + +--FILE-- + ["pipe", "r"], 1 => ["bogus_type"]], $pipes); +} +$after = count(scandir("/proc/self/fd")); +var_dump($after <= $before + 2); +?> +--EXPECT-- +bool(true) diff --git a/ext/standard/tests/general_functions/proc_open_pipes3.phpt b/ext/standard/tests/general_functions/proc_open_pipes3.phpt index 1ee42904a058..8f065401eb14 100644 --- a/ext/standard/tests/general_functions/proc_open_pipes3.phpt +++ b/ext/standard/tests/general_functions/proc_open_pipes3.phpt @@ -45,7 +45,7 @@ array(4) { resource(%d) of type (Unknown) } -Warning: proc_open(test): Failed to open stream: %s in %s on line %d +Warning: proc_open(): Failed to open stream: %s in %s on line %d array(4) { [3]=> resource(%d) of type (Unknown) diff --git a/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt b/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt new file mode 100644 index 000000000000..28a346237338 --- /dev/null +++ b/ext/standard/tests/general_functions/putenv_and_getenv_reject_null_bytes.phpt @@ -0,0 +1,35 @@ +--TEST-- +getenv() and putenv() reject null bytes +--FILE-- +getMessage() . "\n"; + } +} + +$var_name = 'PHP_PUTENV_NUL_TEST'; + +foreach ([ + $var_name . "\0SUFFIX=value", + $var_name . "=va\0lue", +] as $assignment) { + try { + putenv($assignment); + } catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; + } +} + +var_dump(getenv($var_name)); + +?> +--EXPECT-- +getenv(): Argument #1 ($name) must not contain any null bytes +getenv(): Argument #1 ($name) must not contain any null bytes +putenv(): Argument #1 ($assignment) must not contain any null bytes +putenv(): Argument #1 ($assignment) must not contain any null bytes +bool(false) diff --git a/ext/standard/tests/general_functions/sleep_error.phpt b/ext/standard/tests/general_functions/sleep_error.phpt index bfe66480fa03..47685fc3a5ae 100644 --- a/ext/standard/tests/general_functions/sleep_error.phpt +++ b/ext/standard/tests/general_functions/sleep_error.phpt @@ -7,7 +7,7 @@ sleep(-10); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: sleep(): Argument #1 ($seconds) must be greater than or equal to 0 in %s:%d +Fatal error: Uncaught ValueError: sleep(): Argument #1 ($seconds) must be between 0 and %d in %s:%d Stack trace: #0 %s(%d): sleep(-10) #1 {main} diff --git a/ext/standard/tests/general_functions/sleep_usleep_uint_overflow.phpt b/ext/standard/tests/general_functions/sleep_usleep_uint_overflow.phpt new file mode 100644 index 000000000000..6f0a7b3fa9e8 --- /dev/null +++ b/ext/standard/tests/general_functions/sleep_usleep_uint_overflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +sleep() and usleep() reject values above their unsigned int limits +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; + } +} +?> +--EXPECTF-- +int(0) +usleep(0) ok +sleep(): Argument #1 ($seconds) must be between 0 and %d +usleep(): Argument #1 ($microseconds) must be between 0 and 4294967295 diff --git a/ext/standard/tests/general_functions/usleep_error.phpt b/ext/standard/tests/general_functions/usleep_error.phpt index 46bd4420580b..9c3825f18b56 100644 --- a/ext/standard/tests/general_functions/usleep_error.phpt +++ b/ext/standard/tests/general_functions/usleep_error.phpt @@ -7,7 +7,7 @@ usleep(-10); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: usleep(): Argument #1 ($microseconds) must be greater than or equal to 0 in %s:%d +Fatal error: Uncaught ValueError: usleep(): Argument #1 ($microseconds) must be between 0 and 4294967295 in %s:%d Stack trace: #0 %s(%d): usleep(-10) #1 {main} diff --git a/ext/standard/tests/gh22449.phpt b/ext/standard/tests/gh22449.phpt new file mode 100644 index 000000000000..94709803aea0 --- /dev/null +++ b/ext/standard/tests/gh22449.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug GH-22449: user_filter_factory_create NULL dereference during shutdown +--FILE-- + +--EXPECTF-- +done + +Warning: stream_filter_append(): Unable to create or locate filter "rotator_notWorking" in %s on line %d diff --git a/ext/standard/tests/http/bug38802.phpt b/ext/standard/tests/http/bug38802.phpt index e3eea5ee652a..8461560b59da 100644 --- a/ext/standard/tests/http/bug38802.phpt +++ b/ext/standard/tests/http/bug38802.phpt @@ -109,7 +109,7 @@ Connection: close " -- Test: fail after 2 redirections -- -Warning: fopen(http://%s:%d/foo/bar): Failed to open stream: Redirection limit reached, aborting in %s +Warning: fopen(): Failed to open stream: Redirection limit reached, aborting in %s bool(false) string(%d) "GET /foo/bar HTTP/1.1 Host: %s:%d @@ -122,7 +122,7 @@ Connection: close " -- Test: fail at first redirection -- -Warning: fopen(http://%s:%d/foo/bar): Failed to open stream: Redirection limit reached, aborting in %s +Warning: fopen(): Failed to open stream: Redirection limit reached, aborting in %s bool(false) string(%d) "GET /foo/bar HTTP/1.1 Host: %s:%d @@ -131,7 +131,7 @@ Connection: close " -- Test: fail at first redirection (2) -- -Warning: fopen(http://%s:%d/foo/bar): Failed to open stream: Redirection limit reached, aborting in %s +Warning: fopen(): Failed to open stream: Redirection limit reached, aborting in %s bool(false) string(%d) "GET /foo/bar HTTP/1.1 Host: %s:%d diff --git a/ext/standard/tests/http/bug47021.phpt b/ext/standard/tests/http/bug47021.phpt index 168721f4ec1b..d3237f5862ed 100644 --- a/ext/standard/tests/http/bug47021.phpt +++ b/ext/standard/tests/http/bug47021.phpt @@ -75,22 +75,22 @@ echo "\n"; Type='text/plain' Hello -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s Type='text/plain' Hello -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s Type='text/plain' Hello -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s Type='text/plain' Hello -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s diff --git a/ext/standard/tests/http/bug60570.phpt b/ext/standard/tests/http/bug60570.phpt index 7b62bdaf0b3c..d6d1bcf7a7d9 100644 --- a/ext/standard/tests/http/bug60570.phpt +++ b/ext/standard/tests/http/bug60570.phpt @@ -39,13 +39,13 @@ function do_test() { do_test(); ?> --EXPECTF-- -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in %s on line %d -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in %s on line %d -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in %s on line %d leak? penultimate iteration: %d, last one: %d bool(true) diff --git a/ext/standard/tests/http/bug69337.phpt b/ext/standard/tests/http/bug69337.phpt index 051108a09488..533a21b5bdbc 100644 --- a/ext/standard/tests/http/bug69337.phpt +++ b/ext/standard/tests/http/bug69337.phpt @@ -33,5 +33,5 @@ http_server_kill($pid); var_dump($f); ?> --EXPECTF-- -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%ain %s on line %d +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%ain %s on line %d bool(false) diff --git a/ext/standard/tests/http/bug76342.phpt b/ext/standard/tests/http/bug76342.phpt index f1464417f98a..d8f733113ba6 100644 --- a/ext/standard/tests/http/bug76342.phpt +++ b/ext/standard/tests/http/bug76342.phpt @@ -31,5 +31,5 @@ http_server_kill($pid); ?> DONE --EXPECTF-- -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! in %s on line %d +Warning: file_get_contents(): Failed to open stream: HTTP request failed! in %s on line %d DONE diff --git a/ext/standard/tests/http/gh16810.phpt b/ext/standard/tests/http/gh16810.phpt index 6feab1fb01f8..e17440c95efc 100644 --- a/ext/standard/tests/http/gh16810.phpt +++ b/ext/standard/tests/http/gh16810.phpt @@ -29,5 +29,5 @@ var_dump(fopen($uri, "r", false, $ctx)); --EXPECTF-- resource(%d) of type (stream) -Warning: fopen(http://%s): Failed to open stream: timeout must be lower than %d in %s on line %d +Warning: fopen(): Failed to open stream: timeout must be lower than %d in %s on line %d bool(false) diff --git a/ext/standard/tests/http/gh17976.phpt b/ext/standard/tests/http/gh17976.phpt new file mode 100644 index 000000000000..bba9a7a0fcf3 --- /dev/null +++ b/ext/standard/tests/http/gh17976.phpt @@ -0,0 +1,65 @@ +--TEST-- +GH-17976 (CRLF injection via from and user_agent INI settings in HTTP wrapper) +--INI-- +allow_url_fopen=1 +--FILE-- + ["tcp_nodelay" => true] + ]); + + $server = stream_socket_server( + "tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctxt); + phpt_notify_server_start($server); + + for ($i = 0; $i < 4; $i++) { + $conn = stream_socket_accept($server); + $result = fread($conn, 4096); + fwrite($conn, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n" . base64_encode($result)); + fclose($conn); + } +CODE; + +$clientCode = <<<'CODE' + // Test 1: from INI with CRLF + ini_set("from", "test\r\nInjected-From: evil"); + ini_set("user_agent", "clean_ua"); + $raw = base64_decode(file_get_contents("http://{{ ADDR }}/")); + echo (str_contains($raw, "Injected-From:") ? "FAIL" : "OK") . ": from INI\n"; + + // Test 2: user_agent INI with CRLF + ini_restore("from"); + ini_set("user_agent", "test\r\nInjected-UA: evil"); + $raw = base64_decode(file_get_contents("http://{{ ADDR }}/")); + echo (str_contains($raw, "Injected-UA:") ? "FAIL" : "OK") . ": user_agent INI\n"; + + // Test 3: user_agent context option with CRLF + ini_restore("user_agent"); + $ctx = stream_context_create(["http" => [ + "user_agent" => "test\nInjected-Ctx: evil" + ]]); + $raw = base64_decode(file_get_contents("http://{{ ADDR }}/", false, $ctx)); + echo (str_contains($raw, "Injected-Ctx:") ? "FAIL" : "OK") . ": user_agent context\n"; + + // Test 4: user_agent INI with a NUL byte before the CRLF + ini_set("user_agent", "ua\0valid\r\nInjected-Nul: evil"); + $raw = base64_decode(file_get_contents("http://{{ ADDR }}/")); + echo (str_contains($raw, "Injected-Nul:") ? "FAIL" : "OK") . ": user_agent NUL+CRLF\n"; +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +Warning: file_get_contents(): Header From value contains newline characters and has been truncated in %s on line %d +OK: from INI + +Warning: file_get_contents(): Header User-Agent value contains newline characters and has been truncated in %s on line %d +OK: user_agent INI + +Warning: file_get_contents(): Header User-Agent value contains newline characters and has been truncated in %s on line %d +OK: user_agent context + +Warning: file_get_contents(): Header User-Agent value contains newline characters and has been truncated in %s on line %d +OK: user_agent NUL+CRLF diff --git a/ext/standard/tests/http/gh22171.phpt b/ext/standard/tests/http/gh22171.phpt new file mode 100644 index 000000000000..0c1aa150f60f --- /dev/null +++ b/ext/standard/tests/http/gh22171.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-22171 (http(s) stream wrapper sends a corrupted Authorization header for percent-encoded userinfo) +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + + $url = preg_replace('(^http://)', 'http://' . $userinfo . '@', $uri); + file_get_contents($url); + + fseek($output, 0, SEEK_SET); + $output = stream_get_contents($output); + + http_server_kill($pid); + + if (preg_match('(^Authorization:\s*Basic\s+(\S+))mi', $output, $m)) { + $decoded = base64_decode($m[1]); + } else { + $decoded = ''; + } + + echo "=== {$label} ===", PHP_EOL; + echo " decoded : ", addcslashes($decoded, "\0..\37"), PHP_EOL; + echo " result : ", ($decoded === $expected ? "OK" : "CORRUPT"), PHP_EOL; +} + +probe('user only', '%76%6f%72%74%66%75', 'vortfu:'); +probe('user + password', '%76%6f%72%74%66%75:%70%61%73%73%77%6f%72%64', 'vortfu:password'); +?> +--EXPECT-- +=== user only === + decoded : vortfu: + result : OK +=== user + password === + decoded : vortfu:password + result : OK diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt index 73e1408c370b..a8786d15a6de 100644 --- a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt @@ -46,7 +46,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); Found the mime-type: text/html; Redirected: string(8000) "%s" -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: %s +Warning: file_get_contents(): Failed to open stream: %s string(0) "" array(3) { [0]=> diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt index cde5aff0afe1..b6df1099a097 100644 --- a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt @@ -45,7 +45,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); --EXPECTF-- Found the mime-type: text/html; -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP Location header size is over the limit of 8182 bytes in %s +Warning: file_get_contents(): Failed to open stream: HTTP Location header size is over the limit of 8182 bytes in %s string(0) "" array(2) { [0]=> diff --git a/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt index e7dd194dbbe6..9542511d68a4 100644 --- a/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt +++ b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt @@ -19,10 +19,4 @@ $context = stream_context_create(['http' => ['proxy' => 'tcp://' . $host, 'reque echo file_get_contents("http://$host/$userinput", false, $context); ?> --EXPECTF-- -Warning: file_get_contents(http://localhost:%d/index.php HTTP/1.1 -Host: localhost:%d - -GET /index2.php HTTP/1.1 -Host: localhost:%d - -GET /index.php): Failed to open stream: HTTP wrapper full URI path does not allow CR or LF characters in %s on line %d +Warning: file_get_contents(): Failed to open stream: HTTP wrapper full URI path does not allow CR or LF characters in %s on line %d diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt index 471f44745ed3..83363fbbcc2f 100644 --- a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt @@ -41,7 +41,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); --EXPECTF-- Found the mime-type: text/html -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (no colon in header line)! in %s bool(false) array(2) { [0]=> diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt index 67ce5517ce3c..db89ebb1d9ec 100644 --- a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt @@ -41,7 +41,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); --EXPECTF-- Found the mime-type: text/html -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (space in header name)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (space in header name)! in %s bool(false) array(2) { [0]=> diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt index e6382420954f..358a85ce0f71 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt @@ -40,7 +40,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECTF-- -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid response format (folding header at the start)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid response format (folding header at the start)! in %s bool(false) array(1) { [0]=> diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt index c0ee01671460..457681ab2947 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt @@ -40,7 +40,7 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECTF-- -Warning: file_get_contents(http://127.0.0.1:%d): Failed to open stream: HTTP invalid header name (cannot start with CR character)! in %s +Warning: file_get_contents(): Failed to open stream: HTTP invalid header name (cannot start with CR character)! in %s bool(false) array(1) { [0]=> diff --git a/ext/standard/tests/http/http_response_header_03.phpt b/ext/standard/tests/http/http_response_header_03.phpt index 5bddc304c724..bdd5c69aba56 100644 --- a/ext/standard/tests/http/http_response_header_03.phpt +++ b/ext/standard/tests/http/http_response_header_03.phpt @@ -30,7 +30,7 @@ http_server_kill($pid); Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 16 NULL -Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%a +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%a bool(false) array(5) { [0]=> diff --git a/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt b/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt new file mode 100644 index 000000000000..e6b90355a4c3 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt @@ -0,0 +1,16 @@ +--TEST-- +$http_response_header dynamic fetch should warn +--FILE-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line %d +string(2) "OK" diff --git a/ext/standard/tests/http/ignore_errors.phpt b/ext/standard/tests/http/ignore_errors.phpt index 9cd8cdc4509f..86a68e406897 100644 --- a/ext/standard/tests/http/ignore_errors.phpt +++ b/ext/standard/tests/http/ignore_errors.phpt @@ -68,7 +68,7 @@ Connection: close " -Warning: fopen(http://%s:%d/foo/bar): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not found +Warning: fopen(): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not found in %s on line %d bool(false) string(%d) "GET /foo/bar HTTP/1.1 diff --git a/ext/standard/tests/image/getimagesize_variation3.phpt b/ext/standard/tests/image/getimagesize_variation3.phpt index f6317db74058..7e848603e5da 100644 --- a/ext/standard/tests/image/getimagesize_variation3.phpt +++ b/ext/standard/tests/image/getimagesize_variation3.phpt @@ -43,10 +43,10 @@ array(0) { -- Non-existent file (nofile.ext) -- -Warning: getimagesize(%snofile.ext): Failed to open stream: No such file or directory in %s on line %d +Warning: getimagesize(): Failed to open stream: No such file or directory in %s on line %d bool(false) -Warning: getimagesize(%snofile.ext): Failed to open stream: No such file or directory in %s on line %d +Warning: getimagesize(): Failed to open stream: No such file or directory in %s on line %d bool(false) array(0) { } diff --git a/ext/standard/tests/image/getimagesizefromstring_iff_overflow.phpt b/ext/standard/tests/image/getimagesizefromstring_iff_overflow.phpt new file mode 100644 index 000000000000..f6fdea9d8e6b --- /dev/null +++ b/ext/standard/tests/image/getimagesizefromstring_iff_overflow.phpt @@ -0,0 +1,24 @@ +--TEST-- +getimagesizefromstring() IFF chunk size integer overflow (GH-getimagesize_oflow) +--CREDITS-- +Alexandre Daubois +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/standard/tests/mail/gh7875.phpt b/ext/standard/tests/mail/gh7875.phpt index 0a1a15ac1160..1f8346a0715d 100644 --- a/ext/standard/tests/mail/gh7875.phpt +++ b/ext/standard/tests/mail/gh7875.phpt @@ -46,5 +46,5 @@ try { @unlink(__DIR__ . "/gh7875.mail.out"); ?> --EXPECTF-- -mail(%s): Failed to open stream: Permission denied +mail(): Failed to open stream: Permission denied bool(false) diff --git a/ext/standard/tests/mail/mail_basic2.phpt b/ext/standard/tests/mail/mail_basic2.phpt index 44d8d86310b0..96a5a4a10a11 100644 --- a/ext/standard/tests/mail/mail_basic2.phpt +++ b/ext/standard/tests/mail/mail_basic2.phpt @@ -20,14 +20,17 @@ $message = 'A Message'; $additional_headers = 'KHeaders'; $additional_parameters = "-n"; $outFile = "/tmp/php_test_mailBasic2.out"; -@unlink($outFile); echo "-- extra parameters --\n"; // Calling mail() with all possible arguments var_dump( mail($to, $subject, $message, $additional_headers, $additional_parameters) ); echo file_get_contents($outFile); -unlink($outFile); + +?> +--CLEAN-- + --EXPECTF-- *** Testing mail() : basic functionality *** diff --git a/ext/standard/tests/math/gh17384.phpt b/ext/standard/tests/math/gh17384.phpt new file mode 100644 index 000000000000..eff207a906a6 --- /dev/null +++ b/ext/standard/tests/math/gh17384.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-17384: number_format() must reject decimals outside the int range +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; + } + } +} + +?> +--EXPECT-- +number_format(): Argument #2 ($decimals) must be between -2147483648 and 2147483647 +number_format(): Argument #2 ($decimals) must be between -2147483648 and 2147483647 +number_format(): Argument #2 ($decimals) must be between -2147483648 and 2147483647 +number_format(): Argument #2 ($decimals) must be between -2147483648 and 2147483647 diff --git a/ext/standard/tests/math/gh22395.phpt b/ext/standard/tests/math/gh22395.phpt new file mode 100644 index 000000000000..73c2c66da199 --- /dev/null +++ b/ext/standard/tests/math/gh22395.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-22395 (base_convert outputs at most 64 characters) +--FILE-- + +--EXPECT-- +int(78) +string(13) "4b61b5e0639ff" diff --git a/ext/standard/tests/math/number_format_basiclong_64bit.phpt b/ext/standard/tests/math/number_format_basiclong_64bit.phpt index fd709fc648f9..7a986efc1fae 100644 --- a/ext/standard/tests/math/number_format_basiclong_64bit.phpt +++ b/ext/standard/tests/math/number_format_basiclong_64bit.phpt @@ -30,7 +30,6 @@ $precisions = array( -17, -19, -20, - PHP_INT_MIN, ); foreach ($numbers as $number) { @@ -54,7 +53,6 @@ foreach ($numbers as $number) { ... with precision -17: string(25) "9,200,000,000,000,000,000" ... with precision -19: string(26) "10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(-9223372036854775808) ... with precision 5: string(32) "-9,223,372,036,854,775,808.00000" ... with precision 0: string(26) "-9,223,372,036,854,775,808" @@ -65,7 +63,6 @@ foreach ($numbers as $number) { ... with precision -17: string(26) "-9,200,000,000,000,000,000" ... with precision -19: string(27) "-10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(2147483647) ... with precision 5: string(19) "2,147,483,647.00000" ... with precision 0: string(13) "2,147,483,647" @@ -76,7 +73,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(-2147483648) ... with precision 5: string(20) "-2,147,483,648.00000" ... with precision 0: string(14) "-2,147,483,648" @@ -87,7 +83,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(9223372034707292160) ... with precision 5: string(31) "9,223,372,034,707,292,160.00000" ... with precision 0: string(25) "9,223,372,034,707,292,160" @@ -98,7 +93,6 @@ foreach ($numbers as $number) { ... with precision -17: string(25) "9,200,000,000,000,000,000" ... with precision -19: string(26) "10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(-9223372034707292160) ... with precision 5: string(32) "-9,223,372,034,707,292,160.00000" ... with precision 0: string(26) "-9,223,372,034,707,292,160" @@ -109,7 +103,6 @@ foreach ($numbers as $number) { ... with precision -17: string(26) "-9,200,000,000,000,000,000" ... with precision -19: string(27) "-10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(2147483648) ... with precision 5: string(19) "2,147,483,648.00000" ... with precision 0: string(13) "2,147,483,648" @@ -120,7 +113,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(-2147483649) ... with precision 5: string(20) "-2,147,483,649.00000" ... with precision 0: string(14) "-2,147,483,649" @@ -131,7 +123,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(4294967294) ... with precision 5: string(19) "4,294,967,294.00000" ... with precision 0: string(13) "4,294,967,294" @@ -142,7 +133,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(4294967295) ... with precision 5: string(19) "4,294,967,295.00000" ... with precision 0: string(13) "4,294,967,295" @@ -153,7 +143,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(4294967293) ... with precision 5: string(19) "4,294,967,293.00000" ... with precision 0: string(13) "4,294,967,293" @@ -164,7 +153,6 @@ foreach ($numbers as $number) { ... with precision -17: string(1) "0" ... with precision -19: string(1) "0" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(9223372036854775806) ... with precision 5: string(31) "9,223,372,036,854,775,806.00000" ... with precision 0: string(25) "9,223,372,036,854,775,806" @@ -175,7 +163,6 @@ foreach ($numbers as $number) { ... with precision -17: string(25) "9,200,000,000,000,000,000" ... with precision -19: string(26) "10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: float(9.223372036854776E+18) ... with precision 5: string(31) "9,223,372,036,854,775,808.00000" ... with precision 0: string(25) "9,223,372,036,854,775,808" @@ -186,7 +173,6 @@ foreach ($numbers as $number) { ... with precision -17: string(25) "9,200,000,000,000,000,000" ... with precision -19: string(26) "10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: int(-9223372036854775807) ... with precision 5: string(32) "-9,223,372,036,854,775,807.00000" ... with precision 0: string(26) "-9,223,372,036,854,775,807" @@ -197,7 +183,6 @@ foreach ($numbers as $number) { ... with precision -17: string(26) "-9,200,000,000,000,000,000" ... with precision -19: string(27) "-10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: float(-9.223372036854776E+18) ... with precision 5: string(32) "-9,223,372,036,854,775,808.00000" ... with precision 0: string(26) "-9,223,372,036,854,775,808" @@ -208,7 +193,6 @@ foreach ($numbers as $number) { ... with precision -17: string(26) "-9,200,000,000,000,000,000" ... with precision -19: string(27) "-10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: float(9.223372036854775E+18) ... with precision 5: string(31) "9,223,372,036,854,774,784.00000" ... with precision 0: string(25) "9,223,372,036,854,774,784" @@ -219,7 +203,6 @@ foreach ($numbers as $number) { ... with precision -17: string(25) "9,200,000,000,000,000,000" ... with precision -19: string(26) "10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" --- testing: float(-9.223372036854775E+18) ... with precision 5: string(32) "-9,223,372,036,854,774,784.00000" ... with precision 0: string(26) "-9,223,372,036,854,774,784" @@ -230,4 +213,3 @@ foreach ($numbers as $number) { ... with precision -17: string(26) "-9,200,000,000,000,000,000" ... with precision -19: string(27) "-10,000,000,000,000,000,000" ... with precision -20: string(1) "0" -... with precision -9223372036854775808: string(1) "0" diff --git a/ext/standard/tests/math/number_format_decimals.phpt b/ext/standard/tests/math/number_format_decimals.phpt index 5fa45fddce2c..b589f0aefeba 100644 --- a/ext/standard/tests/math/number_format_decimals.phpt +++ b/ext/standard/tests/math/number_format_decimals.phpt @@ -29,7 +29,7 @@ $values = array( MIN_INT32, ); -$decimals = array(0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, PHP_INT_MIN); +$decimals = array(0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5); foreach ($values as $value) { echo 'testing '; @@ -55,7 +55,6 @@ testing float(1.5151) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(15.151) ... with decimal places of 0: string(2) "15" ... with decimal places of 1: string(4) "15.2" @@ -68,7 +67,6 @@ testing float(15.151) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(151.51) ... with decimal places of 0: string(3) "152" ... with decimal places of 1: string(5) "151.5" @@ -81,7 +79,6 @@ testing float(151.51) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(1515.1) ... with decimal places of 0: string(5) "1,515" ... with decimal places of 1: string(7) "1,515.1" @@ -94,7 +91,6 @@ testing float(1515.1) ... with decimal places of -3: string(5) "2,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing int(15151) ... with decimal places of 0: string(6) "15,151" ... with decimal places of 1: string(8) "15,151.0" @@ -107,7 +103,6 @@ testing int(15151) ... with decimal places of -3: string(6) "15,000" ... with decimal places of -4: string(6) "20,000" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(-1.5151) ... with decimal places of 0: string(2) "-2" ... with decimal places of 1: string(4) "-1.5" @@ -120,7 +115,6 @@ testing float(-1.5151) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(-15.151) ... with decimal places of 0: string(3) "-15" ... with decimal places of 1: string(5) "-15.2" @@ -133,7 +127,6 @@ testing float(-15.151) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(-151.51) ... with decimal places of 0: string(4) "-152" ... with decimal places of 1: string(6) "-151.5" @@ -146,7 +139,6 @@ testing float(-151.51) ... with decimal places of -3: string(1) "0" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(-1515.1) ... with decimal places of 0: string(6) "-1,515" ... with decimal places of 1: string(8) "-1,515.1" @@ -159,7 +151,6 @@ testing float(-1515.1) ... with decimal places of -3: string(6) "-2,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing int(-15151) ... with decimal places of 0: string(7) "-15,151" ... with decimal places of 1: string(9) "-15,151.0" @@ -172,7 +163,6 @@ testing int(-15151) ... with decimal places of -3: string(7) "-15,000" ... with decimal places of -4: string(7) "-20,000" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing int(999) ... with decimal places of 0: string(3) "999" ... with decimal places of 1: string(5) "999.0" @@ -185,7 +175,6 @@ testing int(999) ... with decimal places of -3: string(5) "1,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing int(-999) ... with decimal places of 0: string(4) "-999" ... with decimal places of 1: string(6) "-999.0" @@ -198,7 +187,6 @@ testing int(-999) ... with decimal places of -3: string(6) "-1,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(999) ... with decimal places of 0: string(3) "999" ... with decimal places of 1: string(5) "999.0" @@ -211,7 +199,6 @@ testing float(999) ... with decimal places of -3: string(5) "1,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing float(-999) ... with decimal places of 0: string(4) "-999" ... with decimal places of 1: string(6) "-999.0" @@ -224,7 +211,6 @@ testing float(-999) ... with decimal places of -3: string(6) "-1,000" ... with decimal places of -4: string(1) "0" ... with decimal places of -5: string(1) "0" -... with decimal places of %i: string(1) "0" testing int(999999) ... with decimal places of 0: string(7) "999,999" ... with decimal places of 1: string(9) "999,999.0" @@ -237,7 +223,6 @@ testing int(999999) ... with decimal places of -3: string(9) "1,000,000" ... with decimal places of -4: string(9) "1,000,000" ... with decimal places of -5: string(9) "1,000,000" -... with decimal places of %i: string(1) "0" testing int(-999999) ... with decimal places of 0: string(8) "-999,999" ... with decimal places of 1: string(10) "-999,999.0" @@ -250,7 +235,6 @@ testing int(-999999) ... with decimal places of -3: string(10) "-1,000,000" ... with decimal places of -4: string(10) "-1,000,000" ... with decimal places of -5: string(10) "-1,000,000" -... with decimal places of %i: string(1) "0" testing float(999999) ... with decimal places of 0: string(7) "999,999" ... with decimal places of 1: string(9) "999,999.0" @@ -263,7 +247,6 @@ testing float(999999) ... with decimal places of -3: string(9) "1,000,000" ... with decimal places of -4: string(9) "1,000,000" ... with decimal places of -5: string(9) "1,000,000" -... with decimal places of %i: string(1) "0" testing float(-999999) ... with decimal places of 0: string(8) "-999,999" ... with decimal places of 1: string(10) "-999,999.0" @@ -276,7 +259,6 @@ testing float(-999999) ... with decimal places of -3: string(10) "-1,000,000" ... with decimal places of -4: string(10) "-1,000,000" ... with decimal places of -5: string(10) "-1,000,000" -... with decimal places of %i: string(1) "0" testing int(2147483647) ... with decimal places of 0: string(13) "2,147,483,647" ... with decimal places of 1: string(15) "2,147,483,647.0" @@ -289,7 +271,6 @@ testing int(2147483647) ... with decimal places of -3: string(13) "2,147,484,000" ... with decimal places of -4: string(13) "2,147,480,000" ... with decimal places of -5: string(13) "2,147,500,000" -... with decimal places of %i: string(1) "0" testing int(-2147483648) ... with decimal places of 0: string(14) "-2,147,483,648" ... with decimal places of 1: string(16) "-2,147,483,648.0" @@ -302,4 +283,3 @@ testing int(-2147483648) ... with decimal places of -3: string(14) "-2,147,484,000" ... with decimal places of -4: string(14) "-2,147,480,000" ... with decimal places of -5: string(14) "-2,147,500,000" -... with decimal places of %i: string(1) "0" diff --git a/ext/standard/tests/math/pi_basic.phpt b/ext/standard/tests/math/pi_basic.phpt index 10814ae8e819..acb95ceb62e7 100644 --- a/ext/standard/tests/math/pi_basic.phpt +++ b/ext/standard/tests/math/pi_basic.phpt @@ -7,7 +7,7 @@ precision=14 echo pi(), "\n"; echo M_PI, "\n"; // N.B pi() ignores all specified arguments no error -// messages are produced if arguments are spcified. +// messages are produced if arguments are specified. ?> --EXPECT-- 3.1415926535898 diff --git a/ext/standard/tests/network/openlog_null_bytes.phpt b/ext/standard/tests/network/openlog_null_bytes.phpt new file mode 100644 index 000000000000..6d3274227815 --- /dev/null +++ b/ext/standard/tests/network/openlog_null_bytes.phpt @@ -0,0 +1,16 @@ +--TEST-- +openlog() rejects null bytes in prefix +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +openlog(): Argument #1 ($prefix) must not contain any null bytes diff --git a/ext/standard/tests/network/setcookie_option_case_variant_leak.phpt b/ext/standard/tests/network/setcookie_option_case_variant_leak.phpt new file mode 100644 index 000000000000..4797d2f259c9 --- /dev/null +++ b/ext/standard/tests/network/setcookie_option_case_variant_leak.phpt @@ -0,0 +1,15 @@ +--TEST-- +setcookie() does not leak when an option array has case-variant duplicate keys +--FILE-- + '/aaaaaaaaaaaaaaaa' . $i, 'Path' => '/bbbbbbbbbbbbbbbb' . $i]); + header_remove(); +} +// Each duplicate-key call leaked the first path string before the fix, +// growing usage by tens of bytes per iteration (hundreds of KB here). +var_dump(memory_get_usage() - $base < 50000); +?> +--EXPECT-- +bool(true) diff --git a/ext/standard/tests/network/stream_socket_server_bind_error.phpt b/ext/standard/tests/network/stream_socket_server_bind_error.phpt new file mode 100644 index 000000000000..2f5becb66a91 --- /dev/null +++ b/ext/standard/tests/network/stream_socket_server_bind_error.phpt @@ -0,0 +1,19 @@ +--TEST-- +stream_socket_server() bind error +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: stream_socket_server(): Unable to connect to tcp://0.0.0.0:%d (Address %r(already )?%rin use) in %s on line %d diff --git a/ext/standard/tests/poll/gh22759.phpt b/ext/standard/tests/poll/gh22759.phpt new file mode 100644 index 000000000000..3df68c4f1314 --- /dev/null +++ b/ext/standard/tests/poll/gh22759.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-22759 (Io\Poll: re-adding a removed handle keeps the new watcher tracked) +--FILE-- +add($handle, [Io\Poll\Event::Read]); +$first->remove(); + +$ref = WeakReference::create($first); +unset($first); +gc_collect_cycles(); +var_dump($ref->get()); + +$second = $context->add($handle, [Io\Poll\Event::Read]); + +unset($context); +gc_collect_cycles(); + +var_dump($second->isActive()); + +try { + $second->remove(); +} catch (Io\Poll\InactiveWatcherException $e) { + echo $e->getMessage(), "\n"; +} + +echo "done\n"; +?> +--EXPECT-- +NULL +bool(false) +Cannot remove inactive watcher +done diff --git a/ext/standard/tests/poll/poll.inc b/ext/standard/tests/poll/poll.inc new file mode 100644 index 000000000000..ce001220bbac --- /dev/null +++ b/ext/standard/tests/poll/poll.inc @@ -0,0 +1,422 @@ + Io\Poll\Backend::Auto, + 'poll' => Io\Poll\Backend::Poll, + 'epoll' => Io\Poll\Backend::Epoll, + 'kqueue' => Io\Poll\Backend::Kqueue, + 'eventports' => Io\Poll\Backend::EventPorts, + 'wsapoll' => Io\Poll\Backend::WSAPoll, + default => throw new ValueError("Unknown backend: $backend"), + }; + + return new Io\Poll\Context($backend_enum); +} + +function pt_stream_poll_add($poll_ctx, $stream, $events, $data = null): Io\Poll\Watcher { + return $poll_ctx->add(new StreamPollHandle($stream), $events, $data); +} + +function pt_skip_for_backend($backend, $msg): void { + $backends_to_skip = is_array($backend) ? $backend : array($backend); + $current_backend = pt_new_stream_poll()->getBackend(); + if (in_array($current_backend->name, $backends_to_skip)) { + die("skip backend {$current_backend->name} $msg\n"); + } +} + +function pt_new_socket_pair(): array { + $domain = (strtoupper(substr(PHP_OS, 0, 3) == 'WIN') ? STREAM_PF_INET : STREAM_PF_UNIX); + $sockets = stream_socket_pair($domain, STREAM_SOCK_STREAM, 0); + if ($sockets === false) { + die("Cannot create socket pair\n"); + } + return $sockets; +} + +function pt_new_tcp_socket_pair(): array { + $server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr); + if (!$server) { + die("Cannot create TCP server: $errstr\n"); + } + $address = stream_socket_get_name($server, false); + + $client = stream_socket_client("tcp://$address", $errno, $errstr); + if (!$client) { + fclose($server); + die("Cannot connect to TCP server: $errstr\n"); + } + + $server_conn = stream_socket_accept($server); + if (!$server_conn) { + fclose($server); + fclose($client); + die("Cannot accept connection\n"); + } + + // Close the listening socket (no longer needed) + fclose($server); + + return [$client, $server_conn]; +} + +function pt_new_tcp_socket_connections(int $num_conns): array { + $server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr); + if (!$server) { + die("Cannot create TCP server: $errstr\n"); + } + $address = stream_socket_get_name($server, false); + + $clients = []; + $server_conns = []; + for ($i = 0; $i < $num_conns; ++$i) { + $clients[$i] = stream_socket_client("tcp://$address", $errno, $errstr); + if (!$clients[$i]) { + fclose($server); + die("Cannot connect to TCP server: $errstr\n"); + } + + $server_conns[$i] = stream_socket_accept($server); + if (!$server_conns[$i]) { + fclose($server); + die("Cannot accept connection\n"); + } + } + + // Close the listening socket (no longer needed) + fclose($server); + + return [$clients, $server_conns]; +} + +function pt_write_sleep($stream, $data, $delay = 10000): int|false { + $result = fwrite($stream, $data); + usleep($delay); + return $result; +} + +function pt_event_array_to_string(array $events): string { + $names = []; + foreach ($events as $event) { + if (is_array($event)) { + // Optional slot, rendered in brackets. + $names[] = '[' . pt_event_array_to_string($event) . ']'; + } else { + $names[] = $event->name; + } + } + return empty($names) ? 'NONE' : implode('|', $names); +} + +function pt_print_events($watchers, $read_data = false): void { + if (!is_array($watchers)) { + die("Events must be an array\n"); + } + echo "Events count: " . count($watchers) . "\n"; + foreach ($watchers as $i => $watcher) { + if (!$watcher instanceof Io\Poll\Watcher) { + die('Invalid event type'); + } + echo "Event[$i]: " . pt_event_array_to_string($watcher->getTriggeredEvents()) . ", user data: " . $watcher->getData(); + if ($read_data && $watcher->hasTriggered(Io\Poll\Event::Read)) { + $data = fread($watcher->getHandle()->getStream(), 1024); + echo ", read data: '$data'"; + } + echo "\n"; + } +} + +function pt_expect_events($watchers, $expected, ?Io\Poll\Context $poll_ctx = null): void { + if (!is_array($watchers)) { + die("Events must be an array\n"); + } + + if (!is_array($expected)) { + die("Expected events must be an array\n"); + } + + $event_count = count($watchers); + $expected_count = count($expected); + + // Get the current backend for backend-specific expectations + $backend = $poll_ctx ? $poll_ctx->getBackend()->name : 'unknown'; + + if ($event_count !== $expected_count) { + echo "Event count mismatch: got $event_count, expected $expected_count\n"; + pt_print_mismatched_events($watchers, $expected, [], $backend); + return; + } + + // Convert events to comparable format for matching + $actual_events = []; + foreach ($watchers as $watcher) { + if (!$watcher instanceof Io\Poll\Watcher) { + die('Invalid event type'); + } + + $event_data = [ + 'events' => $watcher->getTriggeredEvents(), + 'data' => $watcher->getData(), + ]; + + $actual_events[] = $event_data; + } + + // Resolve backend-specific expectations + $resolved_expected = []; + foreach ($expected as $exp_event) { + $resolved_event = $exp_event; + + // Check if events field is a backend-specific map (associative array with string keys) + if (isset($exp_event['events']) && is_array($exp_event['events'])) { + // Check if it's a backend map (has string keys like 'default', 'Kqueue', etc.) + $keys = array_keys($exp_event['events']); + $is_backend_map = false; + foreach ($keys as $key) { + if (is_string($key)) { + $is_backend_map = true; + break; + } + } + + if ($is_backend_map) { + // It's a backend-specific map, resolve it + $resolved_event['events'] = pt_resolve_backend_specific_value($exp_event['events'], $backend); + } + // Otherwise it's already an array of Event enums, leave it as-is + } + + $resolved_expected[] = $resolved_event; + } + + // Try to match each expected event with an actual event + $matched = []; + $unmatched_expected = []; + + foreach ($resolved_expected as $exp_idx => $exp_event) { + $found_match = false; + + foreach ($actual_events as $act_idx => $act_event) { + if (isset($matched[$act_idx])) { + continue; // Already matched + } + + // Check if events and data match + if (pt_events_equal($act_event['events'], $exp_event['events']) && + $act_event['data'] === $exp_event['data']) { + + // If read data is expected, check it + if (isset($exp_event['read'])) { + $read_data = fread($watchers[$act_idx]->getHandle()->getStream(), 1024); + if ($read_data !== $exp_event['read']) { + continue; // Read data doesn't match + } + } + + $matched[$act_idx] = $exp_idx; + $found_match = true; + break; + } + } + + if (!$found_match) { + $unmatched_expected[] = $exp_event; + } + } + + // Check if all events matched + if (count($matched) === $event_count && empty($unmatched_expected)) { + echo "Events matched - count: $event_count\n"; + } else { + echo "Events did not match:\n"; + pt_print_mismatched_events($watchers, $expected, $matched, $backend); + } +} + +function pt_events_equal($actual, $expected): bool { + // Both should be arrays of Event enums + if (!is_array($actual) || !is_array($expected)) { + return false; + } + + // An expected item that is itself an array marks an optional slot: it may be + // absent, or filled by exactly one of the events it lists. Plain enums are + // required. This lets a backend accept e.g. Write with an optional HangUp + // that may not have propagated yet, without weakening the required events. + $required = []; + $optional_groups = []; + foreach ($expected as $item) { + if (is_array($item)) { + $optional_groups[] = array_map(fn($e) => $e->name, $item); + } else { + $required[] = $item->name; + } + } + + $actual_names = array_map(fn($e) => $e->name, $actual); + + // Every required event must be present. + foreach ($required as $name) { + $idx = array_search($name, $actual_names, true); + if ($idx === false) { + return false; + } + unset($actual_names[$idx]); + } + + // Each leftover actual event must be accounted for by a distinct optional + // slot that lists it. + foreach ($actual_names as $name) { + $matched = false; + foreach ($optional_groups as $gi => $group) { + if (in_array($name, $group, true)) { + unset($optional_groups[$gi]); + $matched = true; + break; + } + } + if (!$matched) { + return false; + } + } + + return true; +} + +function pt_resolve_backend_specific_value($backend_map, $current_backend) { + // Direct backend match + if (isset($backend_map[$current_backend])) { + return $backend_map[$current_backend]; + } + + // Check for multi-backend keys (e.g., "Kqueue|EventPorts") + foreach ($backend_map as $key => $value) { + if (strpos($key, '|') !== false) { + $backends = array_map('trim', explode('|', $key)); + if (in_array($current_backend, $backends)) { + return $value; + } + } + } + + // Fall back to default + if (isset($backend_map['default'])) { + return $backend_map['default']; + } + + // If no match found, this is an error + die("No backend-specific value found for '$current_backend' and no default specified\n"); +} + +function pt_print_mismatched_events($actual_watchers, $expected_watchers, $matched = [], $backend_name = null): void { + echo "Actual events:\n"; + foreach ($actual_watchers as $i => $watcher) { + $match_status = isset($matched[$i]) ? " [MATCHED]" : " [UNMATCHED]"; + $watcher_names = pt_event_array_to_string($watcher->getTriggeredEvents()); + echo " Event[$i]: $watcher_names, user data: " . $watcher->getData() . $match_status . "\n"; + } + + echo "Expected events:\n"; + foreach ($expected_watchers as $i => $exp_event) { + $was_matched = in_array($i, $matched); + $match_status = $was_matched ? " [MATCHED]" : " [UNMATCHED]"; + + $events_value = $exp_event['events']; + + // Check if it's a backend-specific map + if (is_array($events_value) && $backend_name !== null) { + $keys = array_keys($events_value); + $is_backend_map = false; + foreach ($keys as $key) { + if (is_string($key)) { + $is_backend_map = true; + break; + } + } + + if ($is_backend_map) { + $events_value = pt_resolve_backend_specific_value($events_value, $backend_name); + } + } + + $watcher_names = is_array($events_value) ? pt_event_array_to_string($events_value) : 'INVALID'; + echo " Event[$i]: $watcher_names, user data: " . $exp_event['data']; + if (isset($exp_event['read'])) { + echo ", read data: '" . $exp_event['read'] . "'"; + } + echo $match_status . "\n"; + } +} + +/* + * Self-test for the pt_* event-matching helpers. + * + * This is deliberately NOT a .phpt: the CI only runs .phpt files, never .inc, + * so this never executes there. It only runs when poll.inc is executed as the + * main script, which lets the (fiddly) optional-slot matching logic be verified + * by hand: + * + * sapi/cli/php ext/standard/tests/poll/poll.inc + */ +function pt_run_self_test(): void { + if (!enum_exists('Io\\Poll\\Event')) { + echo "Io\\Poll\\Event not available; build with poll support to run the self-test\n"; + return; + } + + $R = Io\Poll\Event::Read; + $W = Io\Poll\Event::Write; + $E = Io\Poll\Event::Error; + $H = Io\Poll\Event::HangUp; + + $failures = 0; + $check = function (string $label, bool $cond) use (&$failures) { + if ($cond) { + echo "ok - $label\n"; + } else { + echo "FAIL - $label\n"; + ++$failures; + } + }; + + // Plain required sets are order independent and exact. + $check('exact set matches', pt_events_equal([$W, $H], [$H, $W])); + $check('missing required fails', !pt_events_equal([$W], [$W, $H])); + $check('extra unexpected fails', !pt_events_equal([$W, $H], [$W])); + + // Optional slot: [$W, [$H]] means Write required, HangUp allowed but not + // required. + $check('optional present matches', pt_events_equal([$W, $H], [$W, [$H]])); + $check('optional absent matches', pt_events_equal([$W], [$W, [$H]])); + $check('optional cannot satisfy a required event', !pt_events_equal([$H], [$W, [$H]])); + $check('unlisted extra with optional fails', !pt_events_equal([$W, $E], [$W, [$H]])); + + // A single optional slot accepts at most one of its listed events; separate + // slots can each accept one. + $check('optional picks one of group', pt_events_equal([$W, $H], [$W, [$H, $E]])); + $check('optional group may stay empty', pt_events_equal([$W], [$W, [$H, $E]])); + $check('single slot rejects two', !pt_events_equal([$W, $H, $E], [$W, [$H, $E]])); + $check('two slots accept two', pt_events_equal([$W, $H, $E], [$W, [$H], [$E]])); + + // Rendering. + $check('renders plain set', pt_event_array_to_string([$W, $H]) === 'Write|HangUp'); + $check('renders optional slot', pt_event_array_to_string([$W, [$H]]) === 'Write|[HangUp]'); + $check('renders empty as NONE', pt_event_array_to_string([]) === 'NONE'); + + echo $failures === 0 + ? "\nAll self-tests passed\n" + : "\n$failures self-test(s) FAILED\n"; +} + +if (isset($_SERVER['SCRIPT_FILENAME']) + && realpath($_SERVER['SCRIPT_FILENAME']) === __FILE__) { + pt_run_self_test(); +} diff --git a/ext/standard/tests/poll/poll_backend_getAvailableBackends.phpt b/ext/standard/tests/poll/poll_backend_getAvailableBackends.phpt new file mode 100644 index 000000000000..9ea78d87d1d0 --- /dev/null +++ b/ext/standard/tests/poll/poll_backend_getAvailableBackends.phpt @@ -0,0 +1,12 @@ +--TEST-- +\Io\Poll\Backend::getAvailableBackends() - loop +--FILE-- + +--EXPECT-- +Okay diff --git a/ext/standard/tests/poll/poll_clone_not_allowed.phpt b/ext/standard/tests/poll/poll_clone_not_allowed.phpt new file mode 100644 index 000000000000..f31c4c2ecd7f --- /dev/null +++ b/ext/standard/tests/poll/poll_clone_not_allowed.phpt @@ -0,0 +1,26 @@ +--TEST-- +Io\Poll: Context, Watcher and StreamPollHandle are not cloneable +--FILE-- +add($handle, [Io\Poll\Event::Read]); + +foreach ([$ctx, $handle, $watcher] as $obj) { + try { + clone $obj; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +} + +echo "done\n"; +?> +--EXPECT-- +Trying to clone an uncloneable object of class Io\Poll\Context +Trying to clone an uncloneable object of class StreamPollHandle +Trying to clone an uncloneable object of class Io\Poll\Watcher +done diff --git a/ext/standard/tests/poll/poll_ctx_backend_unix.phpt b/ext/standard/tests/poll/poll_ctx_backend_unix.phpt new file mode 100644 index 000000000000..89f4f3eea10a --- /dev/null +++ b/ext/standard/tests/poll/poll_ctx_backend_unix.phpt @@ -0,0 +1,28 @@ +--TEST-- +Poll context - backend on Unix +--SKIPIF-- + +--FILE-- +getBackend()); +// test with poll that is always available on Unix systems +$poll_ctx = new Io\Poll\Context(Io\Poll\Backend::Poll); +$backend = $poll_ctx->getBackend(); +var_dump($backend->name); +try { + new Io\Poll\Context(Io\Poll\Backend::WSAPoll); +} catch (\Io\Poll\BackendUnavailableException $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +enum(Io\Poll\Backend::%s) +string(4) "Poll" +string(29) "Backend WSAPoll not available" diff --git a/ext/standard/tests/poll/poll_ctx_backend_windows.phpt b/ext/standard/tests/poll/poll_ctx_backend_windows.phpt new file mode 100644 index 000000000000..a8f8498800cc --- /dev/null +++ b/ext/standard/tests/poll/poll_ctx_backend_windows.phpt @@ -0,0 +1,28 @@ +--TEST-- +Poll context - backend on Windows +--SKIPIF-- + +--FILE-- +getBackend()); +// test with WSAPoll +$poll_ctx = new Io\Poll\Context(Io\Poll\Backend::WSAPoll); +$backend = $poll_ctx->getBackend(); +var_dump($backend->name); +try { + new Io\Poll\Context(Io\Poll\Backend::Epoll); +} catch (\Io\Poll\BackendUnavailableException $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +enum(Io\Poll\Backend::%s) +string(7) "WSAPoll" +string(27) "Backend Epoll not available" diff --git a/ext/standard/tests/poll/poll_double_construct.phpt b/ext/standard/tests/poll/poll_double_construct.phpt new file mode 100644 index 000000000000..1fa5b65db38d --- /dev/null +++ b/ext/standard/tests/poll/poll_double_construct.phpt @@ -0,0 +1,28 @@ +--TEST-- +Io\Poll: calling __construct() twice throws instead of leaking +--FILE-- +__construct($r); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$ctx = pt_new_stream_poll(); +try { + $ctx->__construct(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +echo "done\n"; +?> +--EXPECT-- +StreamPollHandle object is already constructed +Io\Poll\Context object is already constructed +done diff --git a/ext/standard/tests/poll/poll_stream_add_error_duplicate.phpt b/ext/standard/tests/poll/poll_stream_add_error_duplicate.phpt new file mode 100644 index 000000000000..8753cad7eb8e --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_add_error_duplicate.phpt @@ -0,0 +1,19 @@ +--TEST-- +Poll stream - add duplicite error +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +ERROR: Handle already added diff --git a/ext/standard/tests/poll/poll_stream_handle_close_then_free.phpt b/ext/standard/tests/poll/poll_stream_handle_close_then_free.phpt new file mode 100644 index 000000000000..9a97fad8dd1c --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_handle_close_then_free.phpt @@ -0,0 +1,20 @@ +--TEST-- +Io\Poll: StreamPollHandle cleanup is safe when the stream is closed first +--FILE-- +add(new StreamPollHandle($r), [Io\Poll\Event::Read]); + +// Close the underlying streams before the watcher and handle are freed. +fclose($r); +fclose($w); + +unset($watcher, $ctx); +gc_collect_cycles(); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/ext/standard/tests/poll/poll_stream_handle_fd_release.phpt b/ext/standard/tests/poll/poll_stream_handle_fd_release.phpt new file mode 100644 index 000000000000..66d042c17138 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_handle_fd_release.phpt @@ -0,0 +1,28 @@ +--TEST-- +Io\Poll: StreamPollHandle releases its stream resource (no fd leak) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/standard/tests/poll/poll_stream_sock_add_only.phpt b/ext/standard/tests/poll/poll_stream_sock_add_only.phpt new file mode 100644 index 000000000000..b282ae846324 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_add_only.phpt @@ -0,0 +1,17 @@ +--TEST-- +Poll stream - only add +--FILE-- + +--EXPECT-- +object(Io\Poll\Context)#1 (0) { +} diff --git a/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt new file mode 100644 index 000000000000..4f32ec28c88d --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt @@ -0,0 +1,18 @@ +--TEST-- +Poll stream - socket modify write +--FILE-- +modify([Io\Poll\Event::Write], "modified_data"); + +pt_expect_events($poll_ctx->wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'modified_data'] +]); +?> +--EXPECT-- +Events matched - count: 1 diff --git a/ext/standard/tests/poll/poll_stream_sock_read.phpt b/ext/standard/tests/poll/poll_stream_sock_read.phpt new file mode 100644 index 000000000000..70aebc9cd926 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_read.phpt @@ -0,0 +1,19 @@ +--TEST-- +Poll stream - socket read +--FILE-- +wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data'] +]); + +?> +--EXPECT-- +Events matched - count: 1 diff --git a/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt new file mode 100644 index 000000000000..c5fec5391652 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt @@ -0,0 +1,38 @@ +--TEST-- +Poll stream - socket remove write +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_1'], + ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2'] +]); + +$watcher1w->remove(); + +pt_expect_events($poll_ctx->wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2'] +]); + +// check that both streams are still usable +var_dump(fwrite($socket1w, "test 1")); +var_dump(fwrite($socket2w, "test 2")); +var_dump(fread($socket1r, 100)); +var_dump(fread($socket2r, 100)); + +?> +--EXPECT-- +Events matched - count: 2 +Events matched - count: 1 +int(6) +int(6) +string(6) "test 1" +string(6) "test 2" diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt new file mode 100644 index 000000000000..3909dea58637 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt @@ -0,0 +1,36 @@ +--TEST-- +Poll stream - socket write / read close +--FILE-- +wait(0, 100000), [ + [ + 'events' => [ + 'default' => [Io\Poll\Event::Write, Io\Poll\Event::Error, Io\Poll\Event::HangUp], + 'Kqueue' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp], + // On Solaris event ports the peer close may not be folded into a + // POLLHUP in the same snapshot as the POLLOUT readiness, so HangUp + // is optional here. + 'EventPorts' => [Io\Poll\Event::Write, [Io\Poll\Event::HangUp]], + ], + 'data' => 'socket2_data' + ] +], $poll_ctx); + +fclose($socket1w); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 1 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt new file mode 100644 index 000000000000..d78d3f4fde35 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt @@ -0,0 +1,38 @@ +--TEST-- +Poll stream - socket read/write events with maxEvents equal to the FD count +--FILE-- + [Io\Poll\Event::Read, Io\Poll\Event::Write], + 'data' => "sock$i", + 'read' => "test $i data", + ]; +} + +pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected); + +// All read data was drained above, so only write events remain +$expected = []; +for ($i = 0; $i < 4; $i++) { + $expected[] = ['events' => [Io\Poll\Event::Write], 'data' => "sock$i"]; +} +pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected); + +?> +--EXPECT-- +Events matched - count: 4 +Events matched - count: 4 diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt new file mode 100644 index 000000000000..f25cb973ddce --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt @@ -0,0 +1,62 @@ +--TEST-- +Poll stream - socket write / read multiple times with edge triggering +--SKIPIF-- + +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'] +]); + +pt_expect_events($poll_ctx->wait(0), []); + +fwrite($socket1w, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data'] +]); + +fwrite($socket1w, "more data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data'] +]); + +pt_expect_events($poll_ctx->wait(0, 100000), []); + +fwrite($socket1w, " and even more data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data'] +]); + +fclose($socket1r); +pt_expect_events($poll_ctx->wait(0, 100000), [ + [ + 'events' => ['default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp]], + 'data' => 'socket2_data' + ] +], $poll_ctx); + +fclose($socket1w); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 1 +Events matched - count: 0 +Events matched - count: 1 +Events matched - count: 2 +Events matched - count: 0 +Events matched - count: 1 +Events matched - count: 1 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt new file mode 100644 index 000000000000..8bc8ea7fcc3d --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt @@ -0,0 +1,70 @@ +--TEST-- +Poll stream - socket write / read multiple times with level triggering +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'] +]); + +pt_expect_events($poll_ctx->wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'] +]); + +fwrite($socket1w, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data'] +]); + +fwrite($socket1w, "more data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data'] +]); + +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data'] +]); + +fwrite($socket1w, " and even more data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data'] +]); + +fclose($socket1r); +pt_expect_events($poll_ctx->wait(0, 100000), [ + [ + 'events' => [ + 'default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp], + // On Solaris event ports the peer close may not be folded into a + // POLLHUP in the same snapshot as the POLLOUT readiness, so HangUp + // is optional here. + 'EventPorts' => [Io\Poll\Event::Write, [Io\Poll\Event::HangUp]], + ], + 'data' => 'socket2_data' + ] +], $poll_ctx); + +fclose($socket1w); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 1 +Events matched - count: 1 +Events matched - count: 2 +Events matched - count: 2 +Events matched - count: 2 +Events matched - count: 2 +Events matched - count: 1 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt new file mode 100644 index 000000000000..4a7b67b8243f --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt @@ -0,0 +1,29 @@ +--TEST-- +Poll stream - socket write / read few time only +--SKIPIF-- + +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'] +]); +fwrite($socket1w, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data'] +]); + +?> +--EXPECT-- +Events matched - count: 1 +Events matched - count: 1 diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt new file mode 100644 index 000000000000..a807e573c5fe --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt @@ -0,0 +1,25 @@ +--TEST-- +Poll stream - socket write / read few time only +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'] +]); +fwrite($socket1w, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data'] +]); + +?> +--EXPECT-- +Events matched - count: 1 +Events matched - count: 2 diff --git a/ext/standard/tests/poll/poll_stream_sock_write.phpt b/ext/standard/tests/poll/poll_stream_sock_write.phpt new file mode 100644 index 000000000000..2d937d7e9a3b --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_write.phpt @@ -0,0 +1,18 @@ +--TEST-- +Poll stream - socket write +--FILE-- +wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'socket_data'] +]); + +?> +--EXPECT-- +Events matched - count: 1 diff --git a/ext/standard/tests/poll/poll_stream_sock_write_close.phpt b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt new file mode 100644 index 000000000000..8927e017b05d --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt @@ -0,0 +1,20 @@ +--TEST-- +Poll stream - socket write close +--FILE-- +wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_read.phpt b/ext/standard/tests/poll/poll_stream_tcp_read.phpt new file mode 100644 index 000000000000..71c7af0ca734 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_read.phpt @@ -0,0 +1,19 @@ +--TEST-- +Poll stream - socket read +--FILE-- +wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data'] +]); + +?> +--EXPECT-- +Events matched - count: 1 diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt new file mode 100644 index 000000000000..f927e73ed4d3 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt @@ -0,0 +1,45 @@ +--TEST-- +Poll stream - TCP read with maxEvents smaller than the number of ready FDs +--FILE-- +wait(0, 100000, 4); + echo "Round $round count: " . count($watchers) . "\n"; + foreach ($watchers as $watcher) { + $data = $watcher->getData(); + if (isset($seen[$data])) { + echo "Duplicate event for $data\n"; + } + $seen[$data] = true; + // Drain so level triggering does not re-report the FD + fread($watcher->getHandle()->getStream(), 1024); + } +} + +ksort($seen); +echo "Seen: " . implode(',', array_keys($seen)) . "\n"; + +pt_expect_events($poll_ctx->wait(0), []); + +?> +--EXPECT-- +Round 1 count: 4 +Round 2 count: 4 +Seen: server0,server1,server2,server3,server4,server5,server6,server7 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt new file mode 100644 index 000000000000..db2ff71fb7c8 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt @@ -0,0 +1,41 @@ +--TEST-- +Poll stream - TCP read write level +--FILE-- +wait(0), []); + +for ($i = 0; $i < count($clients); $i++) { + pt_write_sleep($clients[$i], "test $i data"); +} + +// Build expected events for all 20 connections +$expected_events = []; +for ($i = 0; $i < 20; $i++) { + $expected_events[] = ['events' => [Io\Poll\Event::Read], 'data' => "server{$i}_data", 'read' => "test $i data"]; +} +pt_expect_events($poll_ctx->wait(0, 100000), $expected_events); + +pt_write_sleep($clients[1], "more data"); +pt_write_sleep($clients[2], "more data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'more data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'more data'] +]); + +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 0 +Events matched - count: 20 +Events matched - count: 2 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt new file mode 100644 index 000000000000..02db6355ca1a --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt @@ -0,0 +1,33 @@ +--TEST-- +Poll stream - TCP read write oneshot +--FILE-- +wait(0), []); + +pt_write_sleep($client1, "test data"); +pt_write_sleep($client2, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'test data'], + ['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'test data'] +]); + +pt_write_sleep($client1, "more data"); +pt_write_sleep($client2, "more data"); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 0 +Events matched - count: 2 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt new file mode 100644 index 000000000000..d7a2e48be6f4 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt @@ -0,0 +1,46 @@ +--TEST-- +Poll stream - TCP read oneshot with maxEvents smaller than the number of ready FDs +--FILE-- +wait(0, 100000, 4); + echo "Round $round count: " . count($watchers) . "\n"; + foreach ($watchers as $watcher) { + $data = $watcher->getData(); + if (isset($seen[$data])) { + echo "Duplicate event for $data\n"; + } + $seen[$data] = true; + } +} + +ksort($seen); +echo "Seen: " . implode(',', array_keys($seen)) . "\n"; + +// Every oneshot watcher fired once, so new data must not be reported +pt_write_sleep($clients[0], "more data"); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Round 1 count: 4 +Round 2 count: 4 +Seen: server0,server1,server2,server3,server4,server5,server6,server7 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt new file mode 100644 index 000000000000..6132975e1b50 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt @@ -0,0 +1,28 @@ +--TEST-- +Poll stream - TCP read write oneshot combined +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'], + ['events' => [Io\Poll\Event::Write], 'data' => 'server_data'] +]); + +pt_write_sleep($client, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +pt_write_sleep($client, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 2 +Events matched - count: 0 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt new file mode 100644 index 000000000000..c480caf1b73d --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt @@ -0,0 +1,25 @@ +--TEST-- +Poll stream - TCP read write oneshot combined and mixed +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'], + ['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data'] +]); + +pt_write_sleep($client, "test data"); +pt_expect_events($poll_ctx->wait(0, 100000), []); + +?> +--EXPECT-- +Events matched - count: 2 +Events matched - count: 0 diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt new file mode 100644 index 000000000000..f29a74f19edd --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt @@ -0,0 +1,28 @@ +--TEST-- +Poll stream - TCP read write level combined +--FILE-- +wait(0), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'], + ['events' => [Io\Poll\Event::Write], 'data' => 'server_data'] +]); + +fwrite($client, "test data"); +usleep(10000); +pt_expect_events($poll_ctx->wait(0, 100000), [ + ['events' => [Io\Poll\Event::Write], 'data' => 'client_data'], + ['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data', 'read' => 'test data'] +]); + +?> +--EXPECT-- +Events matched - count: 2 +Events matched - count: 2 diff --git a/ext/standard/tests/poll/poll_stream_wait_no_add.phpt b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt new file mode 100644 index 000000000000..a297fa5e1162 --- /dev/null +++ b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt @@ -0,0 +1,12 @@ +--TEST-- +Poll stream - only wait +--FILE-- +wait(0, 100000); +pt_print_events($events); + +?> +--EXPECT-- +Events count: 0 diff --git a/ext/standard/tests/poll/poll_watcher_gc_cycle.phpt b/ext/standard/tests/poll/poll_watcher_gc_cycle.phpt new file mode 100644 index 000000000000..590649acef8f --- /dev/null +++ b/ext/standard/tests/poll/poll_watcher_gc_cycle.phpt @@ -0,0 +1,31 @@ +--TEST-- +Io\Poll: cycle collector reclaims a Watcher referenced through its own data +--FILE-- +add(new StreamPollHandle($r), [Io\Poll\Event::Read]); + +$c = new Canary(); +$c->ref = $watcher; // Canary -> Watcher +$watcher->modifyData($c); // Watcher->data -> Canary (cycle) + +unset($ctx, $watcher, $c, $r, $w); + +echo "before gc\n"; +gc_collect_cycles(); +echo "after gc\n"; +?> +--EXPECT-- +before gc +Canary freed +after gc diff --git a/ext/standard/tests/poll/poll_watcher_outlives_context.phpt b/ext/standard/tests/poll/poll_watcher_outlives_context.phpt new file mode 100644 index 000000000000..2c058d5b8966 --- /dev/null +++ b/ext/standard/tests/poll/poll_watcher_outlives_context.phpt @@ -0,0 +1,35 @@ +--TEST-- +Io\Poll: Watcher operations are safe after its Context is destroyed +--FILE-- +add(new StreamPollHandle($r), [Io\Poll\Event::Read], "data"); + +// Drop the Context while still holding the Watcher it returned. +unset($ctx); +gc_collect_cycles(); + +var_dump($watcher->isActive()); + +try { + $watcher->remove(); +} catch (Io\Poll\InactiveWatcherException $e) { + echo $e->getMessage(), "\n"; +} + +try { + $watcher->modifyEvents([Io\Poll\Event::Write]); +} catch (Io\Poll\InactiveWatcherException $e) { + echo $e->getMessage(), "\n"; +} + +echo "done\n"; +?> +--EXPECT-- +bool(false) +Cannot remove inactive watcher +Cannot modify inactive watcher +done diff --git a/ext/standard/tests/serialize/serialization_objects_009.phpt b/ext/standard/tests/serialize/serialization_objects_009.phpt index 9485f3ef8068..95b85ccd80f7 100644 --- a/ext/standard/tests/serialize/serialization_objects_009.phpt +++ b/ext/standard/tests/serialize/serialization_objects_009.phpt @@ -8,17 +8,16 @@ eval('class C {}'); $b = unserialize($ser); var_dump($a, $b); - echo "Done"; ?> --EXPECTF-- -Warning: Class __PHP_Incomplete_Class has no unserializer in %sserialization_objects_009.php on line %d +Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d + +Warning: Class C has no unserializer in %s on line %d -Warning: Class C has no unserializer in %sserialization_objects_009.php on line %d -object(__PHP_Incomplete_Class)#%d (1) { - ["__PHP_Incomplete_Class_Name"]=> - string(1) "C" -} -object(C)#%d (0) { -} +Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d +bool(false) +bool(false) Done diff --git a/ext/standard/tests/serialize/serialize_array_ref_reentrancy.phpt b/ext/standard/tests/serialize/serialize_array_ref_reentrancy.phpt new file mode 100644 index 000000000000..490fa4f6c3b0 --- /dev/null +++ b/ext/standard/tests/serialize/serialize_array_ref_reentrancy.phpt @@ -0,0 +1,21 @@ +--TEST-- +serialize(): a by-reference __serialize() that grows the array being walked must not free it +--FILE-- +ref[] = 'x' . $i; + } + return ['d' => 1]; + } +} +$g = new G(); +$inner = [$g, 'tail']; +$g->ref = &$inner; +$top = [&$inner]; +var_dump(serialize($top)); +?> +--EXPECT-- +string(59) "a:1:{i:0;a:2:{i:0;O:1:"G":1:{s:1:"d";i:1;}i:1;s:4:"tail";}}" diff --git a/ext/standard/tests/setcookie_samesite_validation.phpt b/ext/standard/tests/setcookie_samesite_validation.phpt new file mode 100644 index 000000000000..3827f04fe8d4 --- /dev/null +++ b/ext/standard/tests/setcookie_samesite_validation.phpt @@ -0,0 +1,52 @@ +--TEST-- +setcookie() and setrawcookie() validate samesite option +--FILE-- + 'Strict'])); +var_dump(setcookie('test', 'value', ['samesite' => 'Lax'])); +var_dump(setcookie('test', 'value', ['samesite' => 'None'])); +var_dump(setcookie('test', 'value', ['samesite' => ''])); + +// Case-insensitive +var_dump(setcookie('test', 'value', ['samesite' => 'strict'])); +var_dump(setcookie('test', 'value', ['samesite' => 'LAX'])); +var_dump(setcookie('test', 'value', ['samesite' => 'NONE'])); + +// setrawcookie uses the same validation +var_dump(setrawcookie('test', 'value', ['samesite' => 'Lax'])); + +// Invalid values +try { + setcookie('test', 'value', ['samesite' => 'Invalid']); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + setcookie('test', 'value', ['samesite' => "Strict\r\nX-Injected: evil"]); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + setrawcookie('test', 'value', ['samesite' => 'Invalid']); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +setcookie(): "samesite" option must be "Strict", "Lax", "None", or "" +setcookie(): "samesite" option must be "Strict", "Lax", "None", or "" +setrawcookie(): "samesite" option must be "Strict", "Lax", "None", or "" diff --git a/ext/standard/tests/streams/bug72771.phpt b/ext/standard/tests/streams/bug72771.phpt index 59eff72ad049..a8c5daf4b121 100644 --- a/ext/standard/tests/streams/bug72771.phpt +++ b/ext/standard/tests/streams/bug72771.phpt @@ -18,5 +18,5 @@ $ds=opendir($path, $context); var_dump($ds); ?> --EXPECTF-- -Warning: opendir(ftps://127.0.0.1:%d/): Failed to open directory: Server doesn't support FTPS. in %s on line %d +Warning: opendir(): Failed to open directory: Server doesn't support FTPS. in %s on line %d bool(false) diff --git a/ext/standard/tests/streams/bug73457.phpt b/ext/standard/tests/streams/bug73457.phpt index 64b8bf6ac8ed..f46a774484db 100644 --- a/ext/standard/tests/streams/bug73457.phpt +++ b/ext/standard/tests/streams/bug73457.phpt @@ -19,5 +19,5 @@ $ds=file_get_contents($path); var_dump($ds); ?> --EXPECTF-- -Warning: file_get_contents(ftp://127.0.0.1:%d/bug73457): Failed to open stream: Failed to set up data channel: %s in %s on line %d +Warning: file_get_contents(): Failed to open stream: Failed to set up data channel: %s in %s on line %d bool(false) diff --git a/ext/standard/tests/streams/bug74951.phpt b/ext/standard/tests/streams/bug74951.phpt index 43d4f46bfbf6..2668f541fb3c 100644 --- a/ext/standard/tests/streams/bug74951.phpt +++ b/ext/standard/tests/streams/bug74951.phpt @@ -6,8 +6,12 @@ trait Stream00ploiter{ public function s() {} public function n($_) {} } -stream_wrapper_register('e0ploit','Stream00ploiter'); -$s=fopen('e0ploit://',0); + +try { + stream_wrapper_register('e0ploit','Stream00ploiter'); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} ?> ---EXPECTF-- -Warning: fopen(e0ploit://): Failed to open stream: operation failed in %s%ebug74951.php on line 7 +--EXPECT-- +ValueError: stream_wrapper_register(): Argument #2 ($class) must be a concrete class diff --git a/ext/standard/tests/streams/ftp_dirstream_oob.phpt b/ext/standard/tests/streams/ftp_dirstream_oob.phpt new file mode 100644 index 000000000000..9e184f3c8ac6 --- /dev/null +++ b/ext/standard/tests/streams/ftp_dirstream_oob.phpt @@ -0,0 +1,33 @@ +--TEST-- +opendir() with 'ftp://' stream must not go out of bounds on an empty or slash-only listing line +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +resource(%d) of type (stream) +string(5) "file1" +string(0) "" +string(4) "b0rk" +string(0) "" diff --git a/ext/standard/tests/streams/gh14506.phpt b/ext/standard/tests/streams/gh14506.phpt index f83eba4f1ff3..3d82350221d5 100644 --- a/ext/standard/tests/streams/gh14506.phpt +++ b/ext/standard/tests/streams/gh14506.phpt @@ -86,10 +86,10 @@ Warning: fclose(): cannot close the provided stream, as it must not be manually Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d -Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d - Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d +Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d + Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d No stream arrays were passed fclose(): Argument #1 ($stream) must be an open stream resource diff --git a/ext/standard/tests/streams/gh22200.phpt b/ext/standard/tests/streams/gh22200.phpt new file mode 100644 index 000000000000..01a58bbf8cf2 --- /dev/null +++ b/ext/standard/tests/streams/gh22200.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-22200 (Memory leaks in the stream errors code on reentrant error handler) +--FILE-- + +--EXPECT-- +done diff --git a/ext/standard/tests/streams/gh22617.phpt b/ext/standard/tests/streams/gh22617.phpt new file mode 100644 index 000000000000..83dbd832e652 --- /dev/null +++ b/ext/standard/tests/streams/gh22617.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-22617: Persistent abstract unix domain sockets resolved to wrong resource +--CREDITS-- +Roysten +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +string(17) "persistent stream" +bool(true) +string(17) "persistent stream" +bool(true) diff --git a/ext/standard/tests/streams/glob-wrapper.phpt b/ext/standard/tests/streams/glob-wrapper.phpt index 9be0fce6b710..6f5519c60be7 100644 --- a/ext/standard/tests/streams/glob-wrapper.phpt +++ b/ext/standard/tests/streams/glob-wrapper.phpt @@ -27,7 +27,7 @@ foreach ( [ __DIR__, "glob://".__DIR__ ] as $spec) { Warning: opendir(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (/does_not_exist) in %s%eglob-wrapper.php on line 5 -Warning: opendir(%s): Failed to open directory: %r(Operation not permitted|Insufficient privileges)%r in %s%eglob-wrapper.php on line 5 +Warning: opendir(): Failed to open directory: %r(Operation not permitted|Insufficient privileges)%r in %s%eglob-wrapper.php on line 5 Failed to open %s ** Opening glob://%s No files in glob://%s diff --git a/ext/standard/tests/streams/opendir-001.phpt b/ext/standard/tests/streams/opendir-001.phpt index 7fa9bbfd7b13..c5459f0ab477 100644 --- a/ext/standard/tests/streams/opendir-001.phpt +++ b/ext/standard/tests/streams/opendir-001.phpt @@ -15,6 +15,6 @@ $path="ftp://localhost:" . $port."/bogusdir"; var_dump(opendir($path)); ?> --EXPECTF-- -Warning: opendir(ftp://localhost:%d/bogusdir): Failed to open directory: FTP server reports 250 /bogusdir: No such file or directory +Warning: opendir(): Failed to open directory: FTP server reports 250 /bogusdir: No such file or directory in %s on line %d bool(false) diff --git a/ext/standard/tests/streams/opendir-002.phpt b/ext/standard/tests/streams/opendir-002.phpt index 4978c8affa3d..0a5712564e2e 100644 --- a/ext/standard/tests/streams/opendir-002.phpt +++ b/ext/standard/tests/streams/opendir-002.phpt @@ -25,5 +25,5 @@ closedir($ds); resource(%d) of type (stream) string(5) "file1" string(5) "file1" -string(3) "fil" +string(4) "file" string(4) "b0rk" diff --git a/ext/standard/tests/streams/opendir-003.phpt b/ext/standard/tests/streams/opendir-003.phpt index d79d43b1f12e..51676b8dcfee 100644 --- a/ext/standard/tests/streams/opendir-003.phpt +++ b/ext/standard/tests/streams/opendir-003.phpt @@ -20,6 +20,6 @@ $context = stream_context_create(array('ssl' => array('cafile' => __DIR__ . '/. var_dump(opendir($path, $context)); ?> --EXPECTF-- -Warning: opendir(ftps://127.0.0.1:%d/bogusdir): Failed to open directory: FTP server reports 250 /bogusdir: No such file or directory +Warning: opendir(): Failed to open directory: FTP server reports 250 /bogusdir: No such file or directory in %s on line %d bool(false) diff --git a/ext/standard/tests/streams/opendir-004.phpt b/ext/standard/tests/streams/opendir-004.phpt index 9ccb86b4f4b4..3f076e0d8386 100644 --- a/ext/standard/tests/streams/opendir-004.phpt +++ b/ext/standard/tests/streams/opendir-004.phpt @@ -27,5 +27,5 @@ while ($fn=readdir($ds)) { resource(%d) of type (stream) string(5) "file1" string(5) "file1" -string(3) "fil" +string(4) "file" string(4) "b0rk" diff --git a/ext/standard/tests/streams/stream_context_set_option_no_default_leak.phpt b/ext/standard/tests/streams/stream_context_set_option_no_default_leak.phpt new file mode 100644 index 000000000000..788b6d8a4676 --- /dev/null +++ b/ext/standard/tests/streams/stream_context_set_option_no_default_leak.phpt @@ -0,0 +1,29 @@ +--TEST-- +stream_context_set_option() on a context-less stream must not leak into the default context +--FILE-- + +--EXPECT-- +array(0) { +} +array(0) { +} +array(1) { + ["http"]=> + array(1) { + ["filename"]=> + string(8) "test.txt" + } +} diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_append.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_append.phpt new file mode 100644 index 000000000000..efcec5dafbb4 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_append.phpt @@ -0,0 +1,34 @@ +--TEST-- +stream_copy_to_stream() file to file with an append-mode destination +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(3000) +int(3007) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_dest_read_ahead.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_dest_read_ahead.phpt new file mode 100644 index 000000000000..e772b5892483 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_dest_read_ahead.phpt @@ -0,0 +1,38 @@ +--TEST-- +stream_copy_to_stream() file to file with a partially read destination +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(50) +int(60) +int(3000) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_over_2gb.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_over_2gb.phpt new file mode 100644 index 000000000000..b8563c3c57bd --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_file_over_2gb.phpt @@ -0,0 +1,44 @@ +--TEST-- +stream_copy_to_stream() copies files larger than 2GB in full +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +--CLEAN-- + diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_maxlen.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_maxlen.phpt new file mode 100644 index 000000000000..dc9e52a721d7 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_maxlen.phpt @@ -0,0 +1,57 @@ +--TEST-- +stream_copy_to_stream() file to socket with a maxlength shorter than the file (bounded sendfile + source offset) +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +int(8192) +int(8192) +bool(true) +int(8192) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_medium.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_medium.phpt new file mode 100644 index 000000000000..c7bd9afeedac --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_medium.phpt @@ -0,0 +1,48 @@ +--TEST-- +stream_copy_to_stream() 16k with file as $source and socket as $dest +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +int(16384) +int(16384) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_over_eof.phpt b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_over_eof.phpt new file mode 100644 index 000000000000..7834e9420a71 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_file_to_socket_over_eof.phpt @@ -0,0 +1,53 @@ +--TEST-- +stream_copy_to_stream() file to socket with a maxlength larger than the file (sendfile stops at EOF) +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +int(4096) +int(0) +int(4096) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_file.phpt b/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_file.phpt new file mode 100644 index 000000000000..1ef85a7b21a9 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_file.phpt @@ -0,0 +1,37 @@ +--TEST-- +stream_copy_to_stream() with a pipe as $source and file as $dest +--SKIPIF-- + +--FILE-- + ['pipe', 'w']]; +$proc = proc_open( + [PHP_BINARY, '-n', '-r', 'echo str_repeat("p", 5000);'], + $descriptors, + $pipes +); +var_dump(is_resource($proc)); + +$source = $pipes[1]; +$tmp = tmpfile(); + +$copied = stream_copy_to_stream($source, $tmp); +var_dump($copied); + +fseek($tmp, 0, SEEK_SET); +$content = stream_get_contents($tmp); +var_dump(strlen($content)); +var_dump($content === str_repeat("p", 5000)); + +fclose($tmp); +fclose($source); +proc_close($proc); +?> +--EXPECT-- +bool(true) +int(5000) +int(5000) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_socket.phpt b/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_socket.phpt new file mode 100644 index 000000000000..c7a9b9293e4b --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_pipe_to_socket.phpt @@ -0,0 +1,54 @@ +--TEST-- +stream_copy_to_stream() with a pipe as $source and a socket as $dest (splice from pipe) +--SKIPIF-- + +--FILE-- + ['pipe', 'w']]; + $proc = proc_open( + [PHP_BINARY, '-n', '-r', 'echo str_repeat("p", 5000);'], + $descriptors, + $pipes + ); + + $source = $pipes[1]; + $dest = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 10); + + $copied = stream_copy_to_stream($source, $dest); + var_dump($copied); + + fclose($dest); + fclose($source); + proc_close($proc); + + var_dump((int) trim(phpt_wait())); + var_dump(trim(phpt_wait()) === "match"); +CODE; + +include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +int(5000) +int(5000) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket.phpt deleted file mode 100644 index dafe90e40c40..000000000000 --- a/ext/standard/tests/streams/stream_copy_to_stream_socket.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -stream_copy_to_stream() with socket as $source ---SKIPIF-- - ---FILE-- - ---EXPECT-- -string(1) "a" -string(1) "a" diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_empty.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_empty.phpt new file mode 100644 index 000000000000..a0cf3e61bcaf --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_empty.phpt @@ -0,0 +1,23 @@ +--TEST-- +stream_copy_to_stream() from a socket already at EOF returns 0, not false +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_large.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_large.phpt new file mode 100644 index 000000000000..6d66bf4f81ba --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_large.phpt @@ -0,0 +1,42 @@ +--TEST-- +stream_copy_to_stream() 200k bytes with socket as $source and file as $dest +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +int(200000) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_maxlen.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_maxlen.phpt new file mode 100644 index 000000000000..13fcc475059b --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_maxlen.phpt @@ -0,0 +1,48 @@ +--TEST-- +stream_copy_to_stream() socket to file with a maxlength shorter than the data +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +int(4096) +int(4096) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_single.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_single.phpt new file mode 100644 index 000000000000..a5b694ce5650 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_single.phpt @@ -0,0 +1,49 @@ +--TEST-- +stream_copy_to_stream() single byte with socket as $source and file as $dest +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +string(1) "a" +string(1) "a" diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_small.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_small.phpt new file mode 100644 index 000000000000..9b4f8befce93 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_file_small.phpt @@ -0,0 +1,42 @@ +--TEST-- +stream_copy_to_stream() 2048 bytes with socket as $source and file as $dest +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECTF-- +string(2048) "aaaaa%saaa" diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_socket.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_socket.phpt new file mode 100644 index 000000000000..d462d5117091 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_socket.phpt @@ -0,0 +1,69 @@ +--TEST-- +stream_copy_to_stream() socket to socket (splice both directions) +--SKIPIF-- + +--FILE-- +run($clientCode, [ + 'source' => $sourceCode, + 'dest' => $destCode, +]); +?> +--EXPECT-- +int(10000) +int(10000) +bool(true) diff --git a/ext/standard/tests/streams/stream_copy_to_stream_socket_to_stdout.phpt b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_stdout.phpt new file mode 100644 index 000000000000..f378207f4ef3 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_socket_to_stdout.phpt @@ -0,0 +1,32 @@ +--TEST-- +stream_copy_to_stream() with socket as $source and STDOUT as $dest +--SKIPIF-- + +--FILE-- +run($clientCode, $serverCode); +?> +--EXPECT-- +data to stdout diff --git a/ext/standard/tests/streams/stream_copy_to_stream_temp_source_partially_read.phpt b/ext/standard/tests/streams/stream_copy_to_stream_temp_source_partially_read.phpt new file mode 100644 index 000000000000..7c4f74f9f873 --- /dev/null +++ b/ext/standard/tests/streams/stream_copy_to_stream_temp_source_partially_read.phpt @@ -0,0 +1,27 @@ +--TEST-- +stream_copy_to_stream() with a partially read file-backed php://temp source +--FILE-- + +--EXPECT-- +int(2000) +int(2000) +bool(true) diff --git a/ext/standard/tests/streams/stream_errors_error_has_code.phpt b/ext/standard/tests/streams/stream_errors_error_has_code.phpt new file mode 100644 index 000000000000..b8bbe012c8ee --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_error_has_code.phpt @@ -0,0 +1,30 @@ +--TEST-- +Stream errors - multiple operations stored +--FILE-- + [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::All, + ] +]); + +// First operation +$stream1 = fopen('php://nonexistent1', 'r', false, $context); +$error1 = stream_last_errors()[0]; + +// Second operation +$stream2 = fopen('php://nonexistent2', 'r', false, $context); +$error2 = stream_last_errors()[0]; + +// Should get the most recent error (second operation) +if ($error2) { + echo "Got most recent error\n"; + echo "Param contains 'nonexistent2': " . (strpos($error2->param ?? '', 'nonexistent2') !== false ? 'yes' : 'no') . "\n"; +} + +?> +--EXPECT-- +Got most recent error +Param contains 'nonexistent2': no diff --git a/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt b/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt new file mode 100644 index 000000000000..6f470c61d1a1 --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt @@ -0,0 +1,31 @@ +--TEST-- +Stream errors - exception mode for terminal errors +--FILE-- + [ + 'error_mode' => StreamErrorMode::Exception, + ] +]); + +try { + $stream = fopen('php://nonexistent', 'r', false, $context); +} catch (StreamException $e) { + echo "Caught: " . $e->getMessage() . "\n"; + echo "Code: " . $e->getCode() . "\n"; + + $errors = $e->getErrors(); + if (!empty($errors)) { + $error = $errors[0]; + echo "Wrapper: " . $error->wrapperName . "\n"; + echo "Error code name: " . $error->code->name . "\n"; + } +} + +?> +--EXPECTF-- +Caught: Failed to open stream: operation failed +Code: 21 +Wrapper: PHP +Error code name: OpenFailed diff --git a/ext/standard/tests/streams/stream_errors_invalid_types.phpt b/ext/standard/tests/streams/stream_errors_invalid_types.phpt new file mode 100644 index 000000000000..09a1d8f90e30 --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_invalid_types.phpt @@ -0,0 +1,37 @@ +--TEST-- +Stream errors - invalid enum type throws TypeError +--FILE-- + [ + 'error_mode' => 'invalid', + ] + ]); + + fopen('php://nonexistent', 'r', false, $context); +} catch (TypeError $e) { + echo "Caught TypeError for error_mode\n"; +} + +try { + $context = stream_context_create([ + 'stream' => [ + 'error_store' => 123, + ] + ]); + + fopen('php://nonexistent', 'r', false, $context); +} catch (TypeError $e) { + echo "Caught TypeError for error_store\n"; +} + +?> +--EXPECTF-- + +Warning: fopen(): Failed to open stream: operation failed in %s on line %d +Caught TypeError for error_mode + +Warning: fopen(): Failed to open stream: operation failed in %s on line %d +Caught TypeError for error_store diff --git a/ext/standard/tests/streams/stream_errors_mix_modes_storage.phpt b/ext/standard/tests/streams/stream_errors_mix_modes_storage.phpt new file mode 100644 index 000000000000..49c18616dad3 --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_mix_modes_storage.phpt @@ -0,0 +1,149 @@ +--TEST-- +Stream errors - silent mode with mixed error stores +--FILE-- +position += $count; + return str_repeat('x', $count + 10); + } + + public function stream_eof() { + return $this->position >= 100; + } + + public function stream_stat() { + return []; + } +} + +stream_wrapper_register('test', 'TestStream'); + +function stream_test_errors($title, $contextOptions) { + stream_clear_errors(); + $context = stream_context_create($contextOptions); + $stream = fopen('test://foo', 'r', false, $context); + try { + echo $title . "\n"; + $readin = fopen('php://stdin', 'r', false, $context); + $data = fread($stream, 10); + + $read = [$readin, $stream]; + $write = NULL; + $except = NULL; + stream_select($read, $write, $except, 0, 0, $context); + } catch (StreamException $e) { + echo 'EXCEPTION: ' . $e->getMessage() . "\n"; + } + + $errors = stream_last_errors(); + if ($errors) { + $first = $errors[0]; + echo "Error details:\n"; + echo "- Message: $first->message\n"; + echo "- Code: " . $first->code->name . "\n"; + echo "- Wrapper: $first->wrapperName\n"; + echo "- Terminating: " . ($first->terminating ? 'yes' : 'no') . "\n"; + echo "- Count: " . count($errors) . "\n"; + + foreach ($errors as $idx => $error) { + echo " [$idx] " . $error->code->name . ": " . $error->message . "\n"; + } + } else { + echo "No errors stored\n"; + } + echo "\n"; +} + +stream_test_errors('ALL', [ + 'stream' => [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::All, + ] +]); + +stream_test_errors('NON TERMINATING', [ + 'stream' => [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::NonTerminating, + ] +]); + +stream_test_errors('TERMINATING', [ + 'stream' => [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::Terminating, + ] +]); + +stream_test_errors('AUTO EXCEPTION', [ + 'stream' => [ + 'error_mode' => StreamErrorMode::Exception, + 'error_store' => StreamErrorStore::Auto, + ] +]); + +stream_test_errors('AUTO ERROR', [ + 'stream' => [ + 'error_mode' => StreamErrorMode::Error, + 'error_store' => StreamErrorStore::Auto, + ] +]); + +?> +--EXPECTF-- +ALL +Error details: +- Message: TestStream::stream_cast is not implemented! +- Code: NotImplemented +- Wrapper: user-space +- Terminating: yes +- Count: 2 + [0] NotImplemented: TestStream::stream_cast is not implemented! + [1] CastNotSupported: Cannot represent a stream of type user-space as a select()able descriptor + +NON TERMINATING +Error details: +- Message: TestStream::stream_read - read 10 bytes more data than requested (8202 read, 8192 max) - excess data will be lost +- Code: UserspaceInvalidReturn +- Wrapper: user-space +- Terminating: no +- Count: 1 + [0] UserspaceInvalidReturn: TestStream::stream_read - read 10 bytes more data than requested (8202 read, 8192 max) - excess data will be lost + +TERMINATING +Error details: +- Message: TestStream::stream_cast is not implemented! +- Code: NotImplemented +- Wrapper: user-space +- Terminating: yes +- Count: 2 + [0] NotImplemented: TestStream::stream_cast is not implemented! + [1] CastNotSupported: Cannot represent a stream of type user-space as a select()able descriptor + +AUTO EXCEPTION +EXCEPTION: TestStream::stream_cast is not implemented! +Error details: +- Message: TestStream::stream_read - read 10 bytes more data than requested (8202 read, 8192 max) - excess data will be lost +- Code: UserspaceInvalidReturn +- Wrapper: user-space +- Terminating: no +- Count: 1 + [0] UserspaceInvalidReturn: TestStream::stream_read - read 10 bytes more data than requested (8202 read, 8192 max) - excess data will be lost + +AUTO ERROR + +Warning: fread(): TestStream::stream_read - read 10 bytes more data than requested (8202 read, 8192 max) - excess data will be lost in %s on line %d + +Warning: stream_select(): TestStream::stream_cast is not implemented! in %s on line %d + +Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d +No errors stored diff --git a/ext/standard/tests/streams/stream_errors_modes_with_auto_store.phpt b/ext/standard/tests/streams/stream_errors_modes_with_auto_store.phpt new file mode 100644 index 000000000000..2575a8a795f9 --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_modes_with_auto_store.phpt @@ -0,0 +1,49 @@ +--TEST-- +Stream errors - error_store AUTO mode behavior +--FILE-- + [ + 'error_mode' => StreamErrorMode::Error, + 'error_store' => StreamErrorStore::Auto, + ] +]); + +@fopen('php://nonexistent', 'r', false, $context1); +$errors1 = stream_last_errors(); +echo "ERROR mode AUTO: " . (!empty($errors1) ? "has error" : "no error") . "\n"; + +// AUTO with EXCEPTION mode should store NON_TERM +$context2 = stream_context_create([ + 'stream' => [ + 'error_mode' => StreamErrorMode::Exception, + 'error_store' => StreamErrorStore::Auto, + ] +]); + +try { + fopen('php://nonexistent2', 'r', false, $context2); +} catch (StreamException $e) {} + +$errors2 = stream_last_errors(); +echo "EXCEPTION mode AUTO: " . (!empty($errors2) ? "has error" : "no error") . "\n"; + +// AUTO with SILENT mode should store ALL +$context3 = stream_context_create([ + 'stream' => [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::Auto, + ] +]); + +fopen('php://nonexistent3', 'r', false, $context3); +$errors3 = stream_last_errors(); +echo "SILENT mode AUTO: " . (!empty($errors3) ? "has error" : "no error") . "\n"; + +?> +--EXPECTF-- +ERROR mode AUTO: no error +EXCEPTION mode AUTO: %s +SILENT mode AUTO: has error diff --git a/ext/standard/tests/streams/stream_errors_set_default_context_error.phpt b/ext/standard/tests/streams/stream_errors_set_default_context_error.phpt new file mode 100644 index 000000000000..46fc0f7fd34b --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_set_default_context_error.phpt @@ -0,0 +1,18 @@ +--TEST-- +Stream errors - prohibit setting error mode in default context +--FILE-- + [ + 'error_mode' => StreamErrorMode::Exception, + ] + ]); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +Stream error handling options cannot be set on the default context diff --git a/ext/standard/tests/streams/stream_errors_silent_with_handler.phpt b/ext/standard/tests/streams/stream_errors_silent_with_handler.phpt new file mode 100644 index 000000000000..387939a1063a --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_silent_with_handler.phpt @@ -0,0 +1,37 @@ +--TEST-- +Stream errors - custom error handler +--FILE-- + [ + 'error_mode' => StreamErrorMode::Silent, + 'error_handler' => function(array $errors) use (&$handler_called) { + $handler_called = true; + echo "Handler called\n"; + foreach ($errors as $error) { + echo "Wrapper: " . $error->wrapperName . "\n"; + echo "Code: " . $error->code->name . "\n"; + echo "Message: " . $error->message . "\n"; + echo "Param: " . ($error->param ?? 'null') . "\n"; + echo "Terminating: " . ($error->terminating ? 'yes' : 'no') . "\n"; + } + } + ] +]); + +$stream = fopen('php://nonexistent', 'r', false, $context); + +var_dump($handler_called); + +?> +--EXPECT-- +Handler called +Wrapper: PHP +Code: OpenFailed +Message: Failed to open stream: operation failed +Param: null +Terminating: yes +bool(true) diff --git a/ext/standard/tests/streams/stream_errors_silent_with_storage.phpt b/ext/standard/tests/streams/stream_errors_silent_with_storage.phpt new file mode 100644 index 000000000000..9e356216b0dd --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_silent_with_storage.phpt @@ -0,0 +1,29 @@ +--TEST-- +Stream errors - silent mode with error storage +--FILE-- + [ + 'error_mode' => StreamErrorMode::Silent, + ] +]); + +$stream = fopen('php://nonexistent', 'r', false, $context); +var_dump($stream); + +$errors = stream_last_errors(); +foreach ($errors as $error) { + echo "Has error: yes\n"; + echo "Error code: " . $error->code->name . "\n"; + echo "Error wrapper: " . $error->wrapperName . "\n"; + echo "Error message: " . $error->message . "\n"; +} + +?> +--EXPECT-- +bool(false) +Has error: yes +Error code: OpenFailed +Error wrapper: PHP +Error message: Failed to open stream: operation failed diff --git a/ext/standard/tests/streams/stream_errors_silent_without_storage.phpt b/ext/standard/tests/streams/stream_errors_silent_without_storage.phpt new file mode 100644 index 000000000000..8155ce60bfee --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_silent_without_storage.phpt @@ -0,0 +1,20 @@ +--TEST-- +Stream errors - error_store NONE option +--FILE-- + [ + 'error_mode' => StreamErrorMode::Silent, + 'error_store' => StreamErrorStore::None, + ] +]); + +$stream = fopen('php://nonexistent', 'r', false, $context); + +$errors = stream_last_errors(); +echo "Has error: " . (!empty($error) ? "yes" : "no") . "\n"; + +?> +--EXPECT-- +Has error: no diff --git a/ext/standard/tests/streams/stream_errors_standard_error.phpt b/ext/standard/tests/streams/stream_errors_standard_error.phpt new file mode 100644 index 000000000000..93b66b329d99 --- /dev/null +++ b/ext/standard/tests/streams/stream_errors_standard_error.phpt @@ -0,0 +1,20 @@ +--TEST-- +Stream errors - error mode with standard error reporting +--FILE-- + [ + 'error_mode' => StreamErrorMode::Error, + ] +]); + +// This will trigger a warning +$stream = fopen('php://nonexistent', 'r', false, $context); + +var_dump($stream); + +?> +--EXPECTF-- +Warning: fopen(): Failed to open stream: %s in %s on line %d +bool(false) diff --git a/ext/standard/tests/strings/006.phpt b/ext/standard/tests/strings/006.phpt index dabed24c5780..207afd7c5250 100644 --- a/ext/standard/tests/strings/006.phpt +++ b/ext/standard/tests/strings/006.phpt @@ -10,7 +10,7 @@ var_dump(ob_get_contents()); ?> --EXPECTF-- -Warning: highlight_file(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA): Failed to open stream: %s006.php on line %d +Warning: highlight_file(): Failed to open stream: %s006.php on line %d Warning: highlight_file(): Failed opening 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' for highlighting in %s006.php on line %d bool(false) diff --git a/ext/standard/tests/strings/007-win32.phpt b/ext/standard/tests/strings/007-win32.phpt index 9fe9e4821394..ce6a0bd7e4df 100644 --- a/ext/standard/tests/strings/007-win32.phpt +++ b/ext/standard/tests/strings/007-win32.phpt @@ -11,6 +11,6 @@ var_dump(ob_get_contents()); ?> --EXPECTF-- -Warning: php_strip_whitespace(%s): Failed to open stream: No such file or directory in %s on line %d +Warning: php_strip_whitespace(): Failed to open stream: No such file or directory in %s on line %d string(0) "" bool(false) diff --git a/ext/standard/tests/strings/007.phpt b/ext/standard/tests/strings/007.phpt index 69140715b450..5d3c4b045050 100644 --- a/ext/standard/tests/strings/007.phpt +++ b/ext/standard/tests/strings/007.phpt @@ -11,6 +11,6 @@ var_dump(ob_get_contents()); ?> --EXPECTF-- -Warning: php_strip_whitespace(%s): Failed to open stream: File%Sname too long in %s007.php on line %d +Warning: php_strip_whitespace(): Failed to open stream: File%Sname too long in %s007.php on line %d string(0) "" bool(false) diff --git a/ext/standard/tests/strings/bug68996.phpt b/ext/standard/tests/strings/bug68996.phpt index 95d7f9700101..4abb35801575 100644 --- a/ext/standard/tests/strings/bug68996.phpt +++ b/ext/standard/tests/strings/bug68996.phpt @@ -8,4 +8,4 @@ fopen("\xfc\x63", "r"); ?> --EXPECTF--
-Warning: fopen(�c): Failed to open stream: No such file or directory in %sbug68996.php on line 2
+Warning: fopen(): Failed to open stream: No such file or directory in %sbug68996.php on line 2
diff --git a/ext/standard/tests/strings/bug72434.phpt b/ext/standard/tests/strings/bug72434.phpt deleted file mode 100644 index 6d64baa26fa7..000000000000 --- a/ext/standard/tests/strings/bug72434.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize ---FILE-- - rc is 0 -$a = $unserialized_payload[1]; -// Increment the reference counter by 1 again -> rc is 1 -$b = $a; -// Trigger free of $free_me (referenced by $m[1]). -unset($b); -$fill_freed_space_1 = "filler_zval_1"; -$fill_freed_space_2 = "filler_zval_2"; -$fill_freed_space_3 = "filler_zval_3"; -$fill_freed_space_4 = "filler_zval_4"; -debug_zval_dump($unserialized_payload[1]); -?> ---EXPECTF-- -array(1) refcount(3){ - [0]=> - object(stdClass)#%d (0) refcount(1){ - } -} diff --git a/ext/standard/tests/strings/explode.phpt b/ext/standard/tests/strings/explode.phpt index ea467a2d5504..248fade7605c 100644 --- a/ext/standard/tests/strings/explode.phpt +++ b/ext/standard/tests/strings/explode.phpt @@ -62,9 +62,9 @@ array ( 4 => 'd', ) d6bee42a771449205344c0938ad4f035 -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters array(1) { [0]=> string(0) "" @@ -79,7 +79,7 @@ array(1) { [0]=> string(0) "" } -explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters array(1) { [0]=> string(3) "acb" diff --git a/ext/standard/tests/strings/explode1.phpt b/ext/standard/tests/strings/explode1.phpt index 876b159821cd..022654a57643 100644 --- a/ext/standard/tests/strings/explode1.phpt +++ b/ext/standard/tests/strings/explode1.phpt @@ -91,15 +91,15 @@ var_dump( explode("b", $obj) ); --EXPECT-- *** Testing explode() for basic operations *** -- Iteration 1 -- -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters -- Iteration 2 -- -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters -- Iteration 3 -- array(1) { [0]=> @@ -201,10 +201,10 @@ array(2) { string(56) "234NULL23abcd00000TRUEFALSE-11.234444true-11.24%PHP%ZEND" } -- Iteration 7 -- -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty -explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters +explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters -- Iteration 8 -- array(2) { [0]=> diff --git a/ext/standard/tests/strings/highlight_file.phpt b/ext/standard/tests/strings/highlight_file.phpt index 048399216c90..07983b79b61c 100644 --- a/ext/standard/tests/strings/highlight_file.phpt +++ b/ext/standard/tests/strings/highlight_file.phpt @@ -38,7 +38,7 @@ echo "Done\n"; --EXPECTF-- Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0 -Warning: highlight_file(%shighlight_file.dat): Failed to open stream: No such file or directory in %s on line %d +Warning: highlight_file(): Failed to open stream: No such file or directory in %s on line %d Warning: highlight_file(): Failed opening '%shighlight_file.dat' for highlighting in %s on line %d bool(false) diff --git a/ext/standard/tests/strings/md5_file.phpt b/ext/standard/tests/strings/md5_file.phpt index 1eb9b2654ada..a6fba9ea0384 100644 --- a/ext/standard/tests/strings/md5_file.phpt +++ b/ext/standard/tests/strings/md5_file.phpt @@ -66,10 +66,10 @@ echo "\nDone"; *** Testing for error conditions *** Path must not be empty -Warning: md5_file(aZrq16u): Failed to open stream: No such file or directory in %s on line %d +Warning: md5_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -Warning: md5_file(12): Failed to open stream: No such file or directory in %s on line %d +Warning: md5_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) *** Hexadecimal Output for Empty file as Argument *** diff --git a/ext/standard/tests/strings/parse_str_null_bytes.phpt b/ext/standard/tests/strings/parse_str_null_bytes.phpt new file mode 100644 index 000000000000..fd0d94bb0fc8 --- /dev/null +++ b/ext/standard/tests/strings/parse_str_null_bytes.phpt @@ -0,0 +1,14 @@ +--TEST-- +parse_str() rejects null bytes +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +parse_str(): Argument #1 ($string) must not contain any null bytes diff --git a/ext/standard/tests/strings/pathinfo.phpt b/ext/standard/tests/strings/pathinfo.phpt index 2bbea73588cb..1ff42a66121c 100644 --- a/ext/standard/tests/strings/pathinfo.phpt +++ b/ext/standard/tests/strings/pathinfo.phpt @@ -14,14 +14,48 @@ var_dump(pathinfo(__FILE__, PATHINFO_BASENAME)); var_dump(pathinfo(__FILE__, PATHINFO_FILENAME)); var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION)); var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME)); + +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + pathinfo(__FILE__, PATHINFO_DIRNAME-1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_ALL+1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} echo "Done\n"; ?> @@ -94,12 +128,12 @@ string(12) "pathinfo.php" string(8) "pathinfo" string(3) "php" string(%d) "%s%estrings" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(3) "php" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(%d) "%s%estrings" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants Done diff --git a/ext/standard/tests/strings/php_strip_whitespace.phpt b/ext/standard/tests/strings/php_strip_whitespace.phpt index 9f22daa9eb43..a3a811fe4889 100644 --- a/ext/standard/tests/strings/php_strip_whitespace.phpt +++ b/ext/standard/tests/strings/php_strip_whitespace.phpt @@ -39,7 +39,7 @@ var_dump(php_strip_whitespace($filename)); echo "Done\n"; ?> --EXPECTF-- -Warning: php_strip_whitespace(%sphp_strip_whitespace.dat): Failed to open stream: No such file or directory in %s on line %d +Warning: php_strip_whitespace(): Failed to open stream: No such file or directory in %s on line %d string(0) "" string(18) "/* test comment */" string(9) "" diff --git a/ext/standard/tests/strings/sha1.phpt b/ext/standard/tests/strings/sha1.phpt index 1fea3566b5f8..e88edb5acd97 100644 --- a/ext/standard/tests/strings/sha1.phpt +++ b/ext/standard/tests/strings/sha1.phpt @@ -47,5 +47,5 @@ bool(true) string(20) "%a" string(20) "%a" -Warning: sha1_file(%ssha1.dat): Failed to open stream: No such file or directory in %s on line %d +Warning: sha1_file(): Failed to open stream: No such file or directory in %s on line %d Done diff --git a/ext/standard/tests/strings/sha1_file.phpt b/ext/standard/tests/strings/sha1_file.phpt index 60d6ad808f8c..2014eabb98f5 100644 --- a/ext/standard/tests/strings/sha1_file.phpt +++ b/ext/standard/tests/strings/sha1_file.phpt @@ -78,12 +78,12 @@ Path must not be empty -- invalid filename -- -Warning: sha1_file(rewncwYcn89q): Failed to open stream: No such file or directory in %s on line %d +Warning: sha1_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Scalar value as filename -- -Warning: sha1_file(12): Failed to open stream: No such file or directory in %s on line %d +Warning: sha1_file(): Failed to open stream: No such file or directory in %s on line %d bool(false) -- NULL as filename -- diff --git a/ext/standard/tests/versioning/version_compare.phpt b/ext/standard/tests/versioning/version_compare.phpt index 07550dd410f4..e22ddabfa56b 100644 --- a/ext/standard/tests/versioning/version_compare.phpt +++ b/ext/standard/tests/versioning/version_compare.phpt @@ -22,6 +22,9 @@ foreach ($special_forms as $f1) { test("1.0$f1", "1.0$f2"); } } +test("1.2.", "1.2."); +test("1.2..", "1.2.."); + print "TESTING OPERATORS\n"; foreach ($special_forms as $f1) { foreach ($special_forms as $f2) { @@ -106,6 +109,8 @@ TESTING COMPARE 1.0pl1 > 1.0rc1 1.0pl1 > 1.0 1.0pl1 = 1.0pl1 +1.2. = 1.2. +1.2.. = 1.2.. TESTING OPERATORS 1.0-dev lt 1.0-dev : false 1.0-dev < 1.0-dev : false diff --git a/ext/standard/type.c b/ext/standard/type.c index 5bb7b3b803ee..fc681a3c50a7 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -105,7 +103,7 @@ PHP_FUNCTION(settype) convert_to_long(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_FLOAT))) { convert_to_double(ptr); - } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { /* deprecated */ + } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { convert_to_double(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_STRING))) { convert_to_string(ptr); @@ -151,8 +149,7 @@ PHP_FUNCTION(intval) ZEND_PARSE_PARAMETERS_END(); if (Z_TYPE_P(num) != IS_STRING || base == 10) { - RETVAL_LONG(zval_get_long(num)); - return; + RETURN_LONG(zval_get_long(num)); } @@ -160,7 +157,7 @@ PHP_FUNCTION(intval) char *strval = Z_STRVAL_P(num); size_t strlen = Z_STRLEN_P(num); - while (isspace(*strval) && strlen) { + while (isspace((unsigned char)*strval) && strlen) { strval++; strlen--; } @@ -350,7 +347,6 @@ static zend_always_inline void _zend_is_numeric(zval *return_value, zval *arg) case IS_LONG: case IS_DOUBLE: RETURN_TRUE; - break; case IS_STRING: if (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) { @@ -362,7 +358,6 @@ static zend_always_inline void _zend_is_numeric(zval *return_value, zval *arg) default: RETURN_FALSE; - break; } } @@ -404,11 +399,9 @@ PHP_FUNCTION(is_scalar) case IS_LONG: case IS_STRING: RETURN_TRUE; - break; default: RETURN_FALSE; - break; } } /* }}} */ diff --git a/ext/standard/uniqid.c b/ext/standard/uniqid.c index c0b9555ccefd..267851cd73ac 100644 --- a/ext/standard/uniqid.c +++ b/ext/standard/uniqid.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/url.c b/ext/standard/url.c index 4ddf7f80c64f..ac303027a722 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -103,7 +101,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port p = s; while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ - if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { + if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) { goto parse_port; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ @@ -132,7 +130,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port * correctly parse things like a.com:80 */ p = e + 1; - while (p < ue && isdigit(*p)) { + while (p < ue && isdigit((unsigned char)*p)) { p++; } @@ -172,7 +170,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port p = e + 1; pp = p; - while (pp < ue && pp - p < 6 && isdigit(*pp)) { + while (pp < ue && pp - p < 6 && isdigit((unsigned char)*pp)) { pp++; } @@ -591,8 +589,8 @@ PHPAPI size_t php_url_decode_ex(char *dest, const char *src, size_t src_len) if (*data == '+') { *dest = ' '; } - else if (*data == '%' && src_len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + else if (*data == '%' && src_len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { *dest = (char) php_htoi(data + 1); data += 2; src_len -= 2; @@ -664,8 +662,8 @@ PHPAPI size_t php_raw_url_decode_ex(char *dest, const char *src, size_t src_len) const char *data = src; while (src_len--) { - if (*data == '%' && src_len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + if (*data == '%' && src_len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { *dest = (char) php_htoi(data + 1); data += 2; src_len -= 2; @@ -732,7 +730,7 @@ PHP_FUNCTION(get_headers) c = *p; *p = '\0'; s = p + 1; - while (isspace((int)*(unsigned char *)s)) { + while (isspace((unsigned char)*s)) { s++; } diff --git a/ext/standard/url.h b/ext/standard/url.h index 3885ecece578..f807ed67cf9b 100644 --- a/ext/standard/url.h +++ b/ext/standard/url.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/url_scanner_ex.h b/ext/standard/url_scanner_ex.h index e6b296324298..c39b71eebf8c 100644 --- a/ext/standard/url_scanner_ex.h +++ b/ext/standard/url_scanner_ex.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 46254bf38085..506f2d08378e 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | | Yasuo Ohgaki | @@ -85,7 +83,7 @@ static zend_result php_ini_on_update_tags(zend_ini_entry *entry, zend_string *ne *val++ = '\0'; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; str = zend_string_init(key, keylen, 1); @@ -137,7 +135,7 @@ static zend_result php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *n char *q; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; if (keylen > 0) { @@ -245,32 +243,32 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->scheme) { - smart_str_appends(dest, ZSTR_VAL(url_parts->scheme)); + smart_str_append(dest, url_parts->scheme); smart_str_appends(dest, "://"); } else if (*(ZSTR_VAL(url->s)) == '/' && *(ZSTR_VAL(url->s)+1) == '/') { smart_str_appends(dest, "//"); } if (url_parts->user) { - smart_str_appends(dest, ZSTR_VAL(url_parts->user)); + smart_str_append(dest, url_parts->user); if (url_parts->pass) { - smart_str_appends(dest, ZSTR_VAL(url_parts->pass)); + smart_str_append(dest, url_parts->pass); smart_str_appendc(dest, ':'); } smart_str_appendc(dest, '@'); } if (url_parts->host) { - smart_str_appends(dest, ZSTR_VAL(url_parts->host)); + smart_str_append(dest, url_parts->host); } if (url_parts->port) { smart_str_appendc(dest, ':'); smart_str_append_unsigned(dest, (long)url_parts->port); } if (url_parts->path) { - smart_str_appends(dest, ZSTR_VAL(url_parts->path)); + smart_str_append(dest, url_parts->path); } smart_str_appendc(dest, '?'); if (url_parts->query) { - smart_str_appends(dest, ZSTR_VAL(url_parts->query)); + smart_str_append(dest, url_parts->query); smart_str_append(dest, separator); smart_str_append_smart_str(dest, url_app); } else { @@ -278,7 +276,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->fragment) { smart_str_appendc(dest, '#'); - smart_str_appends(dest, ZSTR_VAL(url_parts->fragment)); + smart_str_append(dest, url_parts->fragment); } php_url_free(url_parts); } @@ -463,7 +461,7 @@ static inline void handle_tag(STD_PARA) } smart_str_appendl(&ctx->tag, start, YYCURSOR - start); for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++) - ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]); + ZSTR_VAL(ctx->tag.s)[i] = tolower((unsigned char)ZSTR_VAL(ctx->tag.s)[i]); /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */ if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL) { ok = 1; @@ -601,7 +599,7 @@ PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, co if (encode) { encoded = php_raw_url_encode(name, strlen(name)); - smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&url_app, encoded); zend_string_free(encoded); } else { smart_str_appends(&url_app, name); @@ -609,7 +607,7 @@ PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, co smart_str_appendc(&url_app, '='); if (encode) { encoded = php_raw_url_encode(value, strlen(value)); - smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&url_app, encoded); zend_string_free(encoded); } else { smart_str_appends(&url_app, value); @@ -663,7 +661,7 @@ static void php_url_scanner_ex_activate(bool is_session) ctx = &BG(url_adapt_output_ex); } - memset(ctx, 0, XtOffsetOf(url_adapt_state_ex_t, tags)); + memset(ctx, 0, offsetof(url_adapt_state_ex_t, tags)); } static void php_url_scanner_ex_deactivate(bool is_session) @@ -760,13 +758,13 @@ static inline void php_url_scanner_add_var_impl(const char *name, size_t name_le if (encode) { encoded = php_raw_url_encode(name, name_len); - smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&sname, encoded); zend_string_free(encoded); encoded = php_raw_url_encode(value, value_len); - smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&svalue, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) name, name_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, NULL, /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&hname, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) value, value_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, NULL, /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hvalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&hvalue, encoded); zend_string_free(encoded); } else { smart_str_appendl(&sname, name, name_len); smart_str_appendl(&svalue, value, value_len); @@ -867,14 +865,14 @@ static inline zend_result php_url_scanner_reset_var_impl(zend_string *name, int if (encode) { encoded = php_raw_url_encode(ZSTR_VAL(name), ZSTR_LEN(name)); - smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&sname, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) ZSTR_VAL(name), ZSTR_LEN(name), 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&hname, encoded); zend_string_free(encoded); } else { - smart_str_appendl(&sname, ZSTR_VAL(name), ZSTR_LEN(name)); - smart_str_appendl(&hname, ZSTR_VAL(name), ZSTR_LEN(name)); + smart_str_append(&sname, name); + smart_str_append(&hname, name); } smart_str_0(&sname); smart_str_0(&hname); diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 610784e547e4..986bbbd5f4d3 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: | | Wez Furlong (wez@thebrainroom.com) | @@ -48,6 +46,17 @@ PHP_METHOD(php_user_filter, filter) RETURN_LONG(PSFS_ERR_FATAL); } +PHP_METHOD(php_user_filter, seek) +{ + zend_long offset, whence, chain; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &offset, &whence, &chain) == FAILURE) { + RETURN_THROWS(); + } + + RETURN_TRUE; +} + PHP_METHOD(php_user_filter, onCreate) { ZEND_PARSE_PARAMETERS_NONE(); @@ -123,6 +132,36 @@ static void userfilter_dtor(php_stream_filter *thisfilter) zval_ptr_dtor(obj); } +static zend_result userfilter_assign_stream(php_stream *stream, zval *obj, + zend_string **stream_name_p, uint32_t orig_no_fclose) +{ + /* Give the userfilter class a hook back to the stream */ + const zend_class_entry *old_scope = EG(fake_scope); + EG(fake_scope) = Z_OBJCE_P(obj); + + zend_string *stream_name = ZSTR_INIT_LITERAL("stream", false); + bool stream_property_exists = Z_OBJ_HT_P(obj)->has_property(Z_OBJ_P(obj), stream_name, ZEND_PROPERTY_EXISTS, NULL); + if (stream_property_exists) { + zval stream_zval; + php_stream_to_zval(stream, &stream_zval); + zend_update_property_ex(Z_OBJCE_P(obj), Z_OBJ_P(obj), stream_name, &stream_zval); + /* If property update threw an exception, skip filter execution */ + if (EG(exception)) { + EG(fake_scope) = old_scope; + zend_string_release(stream_name); + stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= orig_no_fclose; + return FAILURE; + } + *stream_name_p = stream_name; + } else { + zend_string_release(stream_name); + } + EG(fake_scope) = old_scope; + + return SUCCESS; +} + static php_stream_filter_status_t userfilter_filter( php_stream *stream, php_stream_filter *thisfilter, @@ -148,31 +187,14 @@ static php_stream_filter_status_t userfilter_filter( uint32_t orig_no_fclose = stream->flags & PHP_STREAM_FLAG_NO_FCLOSE; stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; - /* Give the userfilter class a hook back to the stream */ - const zend_class_entry *old_scope = EG(fake_scope); - EG(fake_scope) = Z_OBJCE_P(obj); - - zend_string *stream_name = ZSTR_INIT_LITERAL("stream", 0); - bool stream_property_exists = Z_OBJ_HT_P(obj)->has_property(Z_OBJ_P(obj), stream_name, ZEND_PROPERTY_EXISTS, NULL); - if (stream_property_exists) { - zval stream_zval; - php_stream_to_zval(stream, &stream_zval); - zend_update_property_ex(Z_OBJCE_P(obj), Z_OBJ_P(obj), stream_name, &stream_zval); - /* If property update threw an exception, skip filter execution */ - if (EG(exception)) { - EG(fake_scope) = old_scope; - if (buckets_in->head) { - php_error_docref(NULL, E_WARNING, "Unprocessed filter buckets remaining on input brigade"); - } - zend_string_release(stream_name); - stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; - stream->flags |= orig_no_fclose; - return PSFS_ERR_FATAL; + zend_string *stream_name = NULL; + if (userfilter_assign_stream(stream, obj, &stream_name, orig_no_fclose) == FAILURE) { + if (buckets_in->head) { + php_error_docref(NULL, E_WARNING, "Unprocessed filter buckets remaining on input brigade"); } + return PSFS_ERR_FATAL; } - EG(fake_scope) = old_scope; - ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1); /* Setup calling arguments */ @@ -217,12 +239,11 @@ static php_stream_filter_status_t userfilter_filter( * Since the property accepted a resource assignment above, it must have * no type hint or be typed as mixed, so we can safely assign null. */ - if (stream_property_exists) { + if (stream_name != NULL) { zend_update_property_null(Z_OBJCE_P(obj), Z_OBJ_P(obj), ZSTR_VAL(stream_name), ZSTR_LEN(stream_name)); + zend_string_release(stream_name); } - zend_string_release(stream_name); - zval_ptr_dtor(&args[3]); zval_ptr_dtor(&args[2]); zval_ptr_dtor(&args[1]); @@ -234,14 +255,74 @@ static php_stream_filter_status_t userfilter_filter( return ret; } +static zend_result userfilter_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + zval *obj = &thisfilter->abstract; + zval retval; + zval args[3]; + + /* the userfilter object probably doesn't exist anymore */ + if (CG(unclean_shutdown)) { + return FAILURE; + } + + /* Check if the seek method exists */ + zend_function *seek_method = zend_hash_str_find_ptr(&Z_OBJCE_P(obj)->function_table, ZEND_STRL("seek")); + if (seek_method == NULL) { + /* Method doesn't exist - consider this a successful seek for BC */ + return SUCCESS; + } + + /* Make sure the stream is not closed while the filter callback executes. */ + uint32_t orig_no_fclose = stream->flags & PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; + + zend_string *stream_name = NULL; + if (userfilter_assign_stream(stream, obj, &stream_name, orig_no_fclose) == FAILURE) { + return FAILURE; + } + + /* Setup calling arguments */ + ZVAL_LONG(&args[0], offset); + ZVAL_LONG(&args[1], whence); + ZVAL_LONG(&args[2], php_stream_filter_get_chain_type(stream, thisfilter)); + + zend_call_known_function(seek_method, Z_OBJ_P(obj), Z_OBJCE_P(obj), &retval, 3, args, NULL); + + zend_result ret = FAILURE; + if (Z_TYPE(retval) != IS_UNDEF) { + ret = zend_is_true(&retval) ? SUCCESS : FAILURE; + zval_ptr_dtor(&retval); + } + + /* filter resources are cleaned up by the stream destructor, + * keeping a reference to the stream resource here would prevent it + * from being destroyed properly */ + if (stream_name != NULL) { + zend_update_property_null(Z_OBJCE_P(obj), Z_OBJ_P(obj), ZSTR_VAL(stream_name), ZSTR_LEN(stream_name)); + zend_string_release(stream_name); + } + + stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= orig_no_fclose; + + return ret; +} + static const php_stream_filter_ops userfilter_ops = { userfilter_filter, + userfilter_seek, userfilter_dtor, "user-filter" }; static php_stream_filter *user_filter_factory_create(const char *filtername, - zval *filterparams, uint8_t persistent) + zval *filterparams, bool persistent) { struct php_user_filter_data *fdat = NULL; php_stream_filter *filter; @@ -256,6 +337,10 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, return NULL; } + if (UNEXPECTED(BG(user_filter_map) == NULL)) { + return NULL; + } + len = strlen(filtername); /* determine the classname/class entry */ @@ -304,7 +389,8 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, return NULL; } - filter = php_stream_filter_alloc(&userfilter_ops, NULL, 0); + filter = php_stream_filter_alloc(&userfilter_ops, NULL, false, + PSFS_SEEKABLE_CHECK, PSFS_SEEKABLE_CHECK); /* filtername */ add_property_string(&obj, "filtername", filtername); diff --git a/ext/standard/user_filters.stub.php b/ext/standard/user_filters.stub.php index acaa42bb33c8..8696845b78c8 100644 --- a/ext/standard/user_filters.stub.php +++ b/ext/standard/user_filters.stub.php @@ -49,6 +49,9 @@ class php_user_filter */ public function filter($in, $out, &$consumed, bool $closing): int {} + /** @tentative-return-type */ + public function seek(int $offset, int $whence, int $chain): bool {} + /** @tentative-return-type */ public function onCreate(): bool {} diff --git a/ext/standard/user_filters_arginfo.h b/ext/standard/user_filters_arginfo.h index 1d3c7bb53586..f5b8a7dfa472 100644 --- a/ext/standard/user_filters_arginfo.h +++ b/ext/standard/user_filters_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit user_filters.stub.php instead. - * Stub hash: 33264435fe01a2cc9aa21a4a087dbbf3c4007206 */ + * Stub hash: 01be6d52377ecd1940c14e3d508df28a70456c58 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_filter, 0, 4, IS_LONG, 0) ZEND_ARG_INFO(0, in) @@ -8,6 +8,12 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_ ZEND_ARG_TYPE_INFO(0, closing, _IS_BOOL, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_seek, 0, 3, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, whence, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, chain, IS_LONG, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_onCreate, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -15,11 +21,13 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_ ZEND_END_ARG_INFO() ZEND_METHOD(php_user_filter, filter); +ZEND_METHOD(php_user_filter, seek); ZEND_METHOD(php_user_filter, onCreate); ZEND_METHOD(php_user_filter, onClose); static const zend_function_entry class_php_user_filter_methods[] = { ZEND_ME(php_user_filter, filter, arginfo_class_php_user_filter_filter, ZEND_ACC_PUBLIC) + ZEND_ME(php_user_filter, seek, arginfo_class_php_user_filter_seek, ZEND_ACC_PUBLIC) ZEND_ME(php_user_filter, onCreate, arginfo_class_php_user_filter_onCreate, ZEND_ACC_PUBLIC) ZEND_ME(php_user_filter, onClose, arginfo_class_php_user_filter_onClose, ZEND_ACC_PUBLIC) ZEND_FE_END diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c index 0389fdd9f979..af70e3a2aa2c 100644 --- a/ext/standard/uuencode.c +++ b/ext/standard/uuencode.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/standard/var.c b/ext/standard/var.c index 8d4c59263725..d79b8941634d 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jani Lehtimäki | | Thies C. Arntzen | @@ -168,7 +166,7 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ break; case IS_OBJECT: { zend_class_entry *ce = Z_OBJCE_P(struc); - if (ce->ce_flags & ZEND_ACC_ENUM) { + if ((ce->ce_flags & ZEND_ACC_ENUM) && ce->__debugInfo == NULL) { zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); php_printf("%senum(%s::%s)\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval)); return; @@ -182,11 +180,16 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ ZEND_GUARD_OR_GC_PROTECT_RECURSION(guard, DEBUG, zobj); myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); - class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); + if (ce->ce_flags & ZEND_ACC_ENUM) { + zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); + php_printf("%senum(%s::%s) (%d) {\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval), myht ? zend_array_count(myht) : 0); + } else { + class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); - php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); - zend_string_release_ex(class_name, 0); + php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); + zend_string_release_ex(class_name, 0); + } if (myht) { zend_ulong num; @@ -228,7 +231,6 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ } struc = Z_REFVAL_P(struc); goto again; - break; default: php_printf("%sUNKNOWN:0\n", COMMON); break; @@ -674,7 +676,6 @@ PHPAPI zend_result php_var_export_ex(zval *struc, int level, smart_str *buf) /* case IS_REFERENCE: struc = Z_REFVAL_P(struc); goto again; - break; default: smart_str_appendl(buf, "NULL", 4); break; @@ -1244,7 +1245,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ && Z_OBJ_HT_P(struc)->get_properties_for == NULL && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties && !zend_object_is_lazy(Z_OBJ_P(struc))) { - /* Optimized version without rebulding properties HashTable */ + /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(struc); zend_class_entry *ce = obj->ce; zend_property_info *prop_info; @@ -1302,13 +1303,17 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ zend_release_properties(myht); return; } - case IS_ARRAY: + case IS_ARRAY: { smart_str_appendl(buf, "a:", 2); myht = Z_ARRVAL_P(struc); + bool rcn = !is_root && (in_rcn_array || GC_REFCOUNT(myht) > 1); + GC_TRY_ADDREF(myht); php_var_serialize_nested_data( buf, struc, myht, zend_array_count(myht), /* incomplete_class */ false, var_hash, - !is_root && (in_rcn_array || GC_REFCOUNT(myht) > 1)); + rcn); + GC_TRY_DTOR_NO_REF(myht); return; + } case IS_REFERENCE: struc = Z_REFVAL_P(struc); goto again; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 353c7086d430..a9f1f96f366f 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -154,6 +152,17 @@ static zend_never_inline void var_push_dtor_value(php_unserialize_data_t *var_ha } } +static zend_always_inline void var_restore_prop_default(php_unserialize_data_t *var_hash, zend_object *obj, zend_property_info *info, zval *data) +{ + /* A partially/incorrectly unserialized value may violate the property's + * declared type, so restore the default and keep the slot consistent. */ + zval *tmp = &obj->ce->default_properties_table[OBJ_PROP_TO_NUM(info->offset)]; + if (Z_REFCOUNTED_P(data)) { + var_push_dtor_value(var_hash, data); + } + ZVAL_COPY_OR_DUP_PROP(data, tmp); +} + static zend_always_inline zval *tmp_var(php_unserialize_data_t *var_hashx, zend_long num) { var_dtor_entries *var_hash; @@ -679,18 +688,15 @@ second_try: } if (!php_var_unserialize_internal(data, p, max, var_hash)) { - if (info && Z_ISREF_P(data)) { - /* Add type source even if we failed to unserialize. - * The data is still stored in the property. */ - ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(data), info); + if (info) { + var_restore_prop_default(var_hash, obj, info, data); } goto failure; } if (UNEXPECTED(info)) { if (!zend_verify_prop_assignable_by_ref(info, data, /* strict */ 1)) { - zval_ptr_dtor(data); - ZVAL_UNDEF(data); + var_restore_prop_default(var_hash, obj, info, data); goto failure; } @@ -772,7 +778,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) if (ce->unserialize == NULL) { zend_error(E_WARNING, "Class %s has no unserializer", ZSTR_VAL(ce->name)); - object_init_ex(rval, ce); + return 0; } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash) != SUCCESS) { return 0; } diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index 6995569fbf87..dc7ca71af469 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ @@ -45,8 +43,8 @@ php_canonicalize_version(const char *version) * s/([^\d\.])([^\D\.])/$1.$2/g; * s/([^\D\.])([^\d\.])/$1.$2/g; */ -#define isdig(x) (isdigit(x)&&(x)!='.') -#define isndig(x) (!isdigit(x)&&(x)!='.') +#define isdig(x) (isdigit((unsigned char)(x))&&(x)!='.') +#define isndig(x) (!isdigit((unsigned char)(x))&&(x)!='.') #define isspecialver(x) ((x)=='-'||(x)=='_'||(x)=='+') lq = *(q - 1); @@ -59,7 +57,7 @@ php_canonicalize_version(const char *version) *q++ = '.'; } *q++ = *p; - } else if (!isalnum(*p)) { + } else if (!isalnum((unsigned char)*p)) { if (lq != '.') { *q++ = '.'; } @@ -68,7 +66,15 @@ php_canonicalize_version(const char *version) } lp = *p++; } - *q++ = '\0'; + + /* Check if the last component is empty (i.e. the last character is a dot) + * and remove it if it is. */ + if (*(q - 1) == '.') { + *(q - 1) = '\0'; + } else { + *q = '\0'; + } + return buf; } @@ -152,17 +158,17 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) if ((n2 = strchr(p2, '.')) != NULL) { *n2 = '\0'; } - if (isdigit(*p1) && isdigit(*p2)) { + if (isdigit((unsigned char)*p1) && isdigit((unsigned char)*p2)) { /* compare element numerically */ l1 = strtol(p1, NULL, 10); l2 = strtol(p2, NULL, 10); compare = ZEND_NORMALIZE_BOOL(l1 - l2); - } else if (!isdigit(*p1) && !isdigit(*p2)) { + } else if (!isdigit((unsigned char)*p1) && !isdigit((unsigned char)*p2)) { /* compare element names */ compare = compare_special_version_forms(p1, p2); } else { /* mix of names and numbers */ - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = compare_special_version_forms("#N#", p2); } else { compare = compare_special_version_forms(p1, "#N#"); @@ -180,13 +186,13 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) } if (compare == 0) { if (n1 != NULL) { - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = 1; } else { compare = php_version_compare(p1, "#N#"); } } else if (n2 != NULL) { - if (isdigit(*p2)) { + if (isdigit((unsigned char)*p2)) { compare = -1; } else { compare = php_version_compare("#N#", p2); diff --git a/ext/sysvmsg/php_sysvmsg.h b/ext/sysvmsg/php_sysvmsg.h index e3be3ed32e31..c82cb09934da 100644 --- a/ext/sysvmsg/php_sysvmsg.h +++ b/ext/sysvmsg/php_sysvmsg.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/sysvmsg/sysvmsg.c b/ext/sysvmsg/sysvmsg.c index 65d29d12c0f9..0c2b3dcf183b 100644 --- a/ext/sysvmsg/sysvmsg.c +++ b/ext/sysvmsg/sysvmsg.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -67,9 +65,7 @@ ZEND_GET_MODULE(sysvmsg) zend_class_entry *sysvmsg_queue_ce; static zend_object_handlers sysvmsg_queue_object_handlers; -static inline sysvmsg_queue_t *sysvmsg_queue_from_obj(zend_object *obj) { - return (sysvmsg_queue_t *)((char *)(obj) - XtOffsetOf(sysvmsg_queue_t, std)); -} +#define sysvmsg_queue_from_obj(obj) ZEND_CONTAINER_OF(obj, sysvmsg_queue_t, std) #define Z_SYSVMSG_QUEUE_P(zv) sysvmsg_queue_from_obj(Z_OBJ_P(zv)) @@ -103,7 +99,7 @@ PHP_MINIT_FUNCTION(sysvmsg) sysvmsg_queue_ce->default_object_handlers = &sysvmsg_queue_object_handlers; memcpy(&sysvmsg_queue_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvmsg_queue_object_handlers.offset = XtOffsetOf(sysvmsg_queue_t, std); + sysvmsg_queue_object_handlers.offset = offsetof(sysvmsg_queue_t, std); sysvmsg_queue_object_handlers.free_obj = sysvmsg_queue_free_obj; sysvmsg_queue_object_handlers.get_constructor = sysvmsg_queue_get_constructor; sysvmsg_queue_object_handlers.clone_obj = NULL; diff --git a/ext/sysvsem/php_sysvsem.h b/ext/sysvsem/php_sysvsem.h index 05d420bf42a4..c40d6dde5f1c 100644 --- a/ext/sysvsem/php_sysvsem.h +++ b/ext/sysvsem/php_sysvsem.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tom May | +----------------------------------------------------------------------+ diff --git a/ext/sysvsem/sysvsem.c b/ext/sysvsem/sysvsem.c index ce624ab4b237..e506bd5bb37c 100644 --- a/ext/sysvsem/sysvsem.c +++ b/ext/sysvsem/sysvsem.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tom May | | Gavin Sherry | @@ -84,9 +82,7 @@ ZEND_GET_MODULE(sysvsem) zend_class_entry *sysvsem_ce; static zend_object_handlers sysvsem_object_handlers; -static inline sysvsem_sem *sysvsem_from_obj(zend_object *obj) { - return (sysvsem_sem *)((char *)(obj) - XtOffsetOf(sysvsem_sem, std)); -} +#define sysvsem_from_obj(obj) ZEND_CONTAINER_OF(obj, sysvsem_sem, std) #define Z_SYSVSEM_P(zv) sysvsem_from_obj(Z_OBJ_P(zv)) @@ -149,7 +145,7 @@ PHP_MINIT_FUNCTION(sysvsem) sysvsem_ce->default_object_handlers = &sysvsem_object_handlers; memcpy(&sysvsem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvsem_object_handlers.offset = XtOffsetOf(sysvsem_sem, std); + sysvsem_object_handlers.offset = offsetof(sysvsem_sem, std); sysvsem_object_handlers.free_obj = sysvsem_free_obj; sysvsem_object_handlers.get_constructor = sysvsem_get_constructor; sysvsem_object_handlers.clone_obj = NULL; diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index 9576349e06d8..b47a70c4e5e1 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Christian Cartus | +----------------------------------------------------------------------+ diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 7f064c50a294..6ca06be935d9 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Christian Cartus | +----------------------------------------------------------------------+ @@ -35,9 +33,7 @@ zend_class_entry *sysvshm_ce; static zend_object_handlers sysvshm_object_handlers; -static inline sysvshm_shm *sysvshm_from_obj(zend_object *obj) { - return (sysvshm_shm *)((char *)(obj) - XtOffsetOf(sysvshm_shm, std)); -} +#define sysvshm_from_obj(obj) ZEND_CONTAINER_OF(obj, sysvshm_shm, std) #define Z_SYSVSHM_P(zv) sysvshm_from_obj(Z_OBJ_P(zv)) @@ -102,7 +98,7 @@ PHP_MINIT_FUNCTION(sysvshm) sysvshm_ce->default_object_handlers = &sysvshm_object_handlers; memcpy(&sysvshm_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvshm_object_handlers.offset = XtOffsetOf(sysvshm_shm, std); + sysvshm_object_handlers.offset = offsetof(sysvshm_shm, std); sysvshm_object_handlers.free_obj = sysvshm_free_obj; sysvshm_object_handlers.get_constructor = sysvshm_get_constructor; sysvshm_object_handlers.clone_obj = NULL; @@ -130,10 +126,17 @@ PHP_FUNCTION(shm_attach) sysvshm_shm *shm_list_ptr; char *shm_ptr; sysvshm_chunk_head *chunk_ptr; - zend_long shm_key, shm_id, shm_size, shm_flag = 0666; + zend_long shm_key_arg, shm_id, shm_size, shm_flag = 0666; + key_t shm_key; bool shm_size_is_null = true; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|l!l", &shm_key, &shm_size, &shm_size_is_null, &shm_flag)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|l!l", &shm_key_arg, &shm_size, &shm_size_is_null, &shm_flag)) { + RETURN_THROWS(); + } + + shm_key = (key_t) shm_key_arg; + if ((zend_long) shm_key != shm_key_arg) { + zend_argument_value_error(1, "is out of range"); RETURN_THROWS(); } @@ -149,17 +152,17 @@ PHP_FUNCTION(shm_attach) /* get the id from a specified key or create new shared memory */ if ((shm_id = shmget(shm_key, 0, 0)) < 0) { if (shm_size < (zend_long)sizeof(sysvshm_chunk_head)) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key_arg); RETURN_FALSE; } if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key_arg, strerror(errno)); RETURN_FALSE; } } if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key_arg, strerror(errno)); RETURN_FALSE; } diff --git a/ext/sysvshm/tests/gh9945.phpt b/ext/sysvshm/tests/gh9945.phpt new file mode 100644 index 000000000000..8185d39b0981 --- /dev/null +++ b/ext/sysvshm/tests/gh9945.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-9945: shm_attach() must reject keys outside the key_t range +--EXTENSIONS-- +sysvshm +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +shm_attach(): Argument #1 ($key) is out of range diff --git a/ext/tidy/php_tidy.h b/ext/tidy/php_tidy.h index 2c31a92a8370..9449580a7ace 100644 --- a/ext/tidy/php_tidy.h +++ b/ext/tidy/php_tidy.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: John Coggeshall | +----------------------------------------------------------------------+ diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 9dcfb733a591..98e1c05a720f 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: John Coggeshall | +----------------------------------------------------------------------+ @@ -106,9 +104,7 @@ struct _PHPTidyObj { zend_object std; }; -static inline PHPTidyObj *php_tidy_fetch_object(zend_object *obj) { - return (PHPTidyObj *)((char*)(obj) - XtOffsetOf(PHPTidyObj, std)); -} +#define php_tidy_fetch_object(obj) ZEND_CONTAINER_OF(obj, PHPTidyObj, std) #define Z_TIDY_P(zv) php_tidy_fetch_object(Z_OBJ_P((zv))) /* }}} */ @@ -705,7 +701,7 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp node = tidyGetBody(obj->ptdoc->doc); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (!node) { @@ -850,7 +846,7 @@ static PHP_MINIT_FUNCTION(tidy) tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler; tidy_object_handlers_node.cast_object = tidy_node_cast_handler; - tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = XtOffsetOf(PHPTidyObj, std); + tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = offsetof(PHPTidyObj, std); tidy_object_handlers_node.free_obj = tidy_object_handlers_doc.free_obj = tidy_object_free_storage; register_tidy_symbols(module_number); @@ -873,7 +869,7 @@ static PHP_RINIT_FUNCTION(tidy) static PHP_RSHUTDOWN_FUNCTION(tidy) { - TG(clean_output) = INI_ORIG_BOOL("tidy.clean_output"); + TG(clean_output) = zend_ini_parse_bool(zend_ini_str(ZEND_STRL("tidy.clean_output"), /* orig */ true)); return SUCCESS; } diff --git a/ext/tokenizer/php_tokenizer.h b/ext/tokenizer/php_tokenizer.h index edc715de8d71..3acdebc4ac66 100644 --- a/ext/tokenizer/php_tokenizer.h +++ b/ext/tokenizer/php_tokenizer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index e594bc62ab38..fdbdd5ddfb61 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index 0900c51d3d95..87b15b8bb345 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Johannes Schlueter | +----------------------------------------------------------------------+ diff --git a/ext/tokenizer/tokenizer_data_gen.php b/ext/tokenizer/tokenizer_data_gen.php index 79753b6e81a5..0119b0cc0237 100755 --- a/ext/tokenizer/tokenizer_data_gen.php +++ b/ext/tokenizer/tokenizer_data_gen.php @@ -39,15 +39,13 @@ $result = <<. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Johannes Schlueter | +----------------------------------------------------------------------+ diff --git a/ext/uri/CREDITS b/ext/uri/CREDITS index fc6ce83fec88..0bbea2af21d2 100644 --- a/ext/uri/CREDITS +++ b/ext/uri/CREDITS @@ -1,2 +1,2 @@ uri -Máté Kocsis, Tim Düsterhus, Ignace Nyamagana Butera, Arnaud Le Blanc, Dennis Snell, Niels Dossche, Nicolas Grekas +Máté Kocsis, Tim Düsterhus, Ignace Nyamagana Butera, Arnaud Le Blanc, Dennis Snell, Nora Dossche, Nicolas Grekas diff --git a/ext/uri/config.m4 b/ext/uri/config.m4 index 31d6c0e10c84..dddf0c6e00b8 100644 --- a/ext/uri/config.m4 +++ b/ext/uri/config.m4 @@ -34,12 +34,12 @@ if test "$PHP_EXTERNAL_URIPARSER" = "no"; then $URIPARSER_DIR/src/UriSetScheme.c $URIPARSER_DIR/src/UriSetUserInfo.c $URIPARSER_DIR/src/UriShorten.c $URIPARSER_DIR/src/UriVersion.c" URI_CFLAGS="-DURI_STATIC_BUILD" else - PKG_CHECK_MODULES([LIBURIPARSER], [liburiparser >= 1.0.0]) + PKG_CHECK_MODULES([LIBURIPARSER], [liburiparser >= 1.0.3]) PHP_EVAL_LIBLINE([$LIBURIPARSER_LIBS]) PHP_EVAL_INCLINE([$LIBURIPARSER_CFLAGS]) fi -PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[$URI_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) +PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[$URI_CFLAGS]) PHP_ADD_EXTENSION_DEP(uri, lexbor) if test "$PHP_EXTERNAL_URIPARSER" = "no"; then diff --git a/ext/uri/config.w32 b/ext/uri/config.w32 index b7c4bfbd2246..597ffb9fa03a 100644 --- a/ext/uri/config.w32 +++ b/ext/uri/config.w32 @@ -1,8 +1,8 @@ -EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include"); 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_FLAG("CFLAGS_URI", "/D URI_STATIC_BUILD /D LEXBOR_STATIC"); ADD_EXTENSION_DEP('uri', 'lexbor'); ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriCopy.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c \ diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 2adece125530..74a559fd591c 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -32,12 +30,16 @@ #include "php_uri_arginfo.h" #include "uriparser/Uri.h" +zend_class_entry *php_uri_ce_rfc3986_uri_builder; zend_class_entry *php_uri_ce_rfc3986_uri; +zend_class_entry *php_uri_ce_rfc3986_uri_type; +zend_class_entry *php_uri_ce_rfc3986_uri_host_type; zend_class_entry *php_uri_ce_whatwg_url; zend_class_entry *php_uri_ce_comparison_mode; zend_class_entry *php_uri_ce_exception; zend_class_entry *php_uri_ce_error; zend_class_entry *php_uri_ce_invalid_uri_exception; +zend_class_entry *php_uri_ce_whatwg_url_host_type; zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; zend_class_entry *php_uri_ce_whatwg_url_validation_error; @@ -45,6 +47,9 @@ zend_class_entry *php_uri_ce_whatwg_url_validation_error; static zend_object_handlers object_handlers_rfc3986_uri; static zend_object_handlers object_handlers_whatwg_uri; +typedef zend_result (*php_uri_component_validator_string)(const zend_string *component); +typedef zend_result (*php_uri_component_validator_long)(zend_long component); + static const zend_module_dep uri_deps[] = { ZEND_MOD_REQUIRED("lexbor") ZEND_MOD_END @@ -52,6 +57,23 @@ static const zend_module_dep uri_deps[] = { static zend_array uri_parsers; +static zend_always_inline zval *php_uri_deref(zval *zv) +{ + if (UNEXPECTED(Z_TYPE_P(zv) == IS_REFERENCE)) { + return Z_REFVAL_P(zv); + } + + return zv; +} + +#define Z_RFC3986_URI_PROP_SCHEME_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0)) +#define Z_RFC3986_URI_PROP_USERINFO_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1)) +#define Z_RFC3986_URI_PROP_HOST_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2)) +#define Z_RFC3986_URI_PROP_PORT_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3)) +#define Z_RFC3986_URI_PROP_PATH_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4)) +#define Z_RFC3986_URI_PROP_QUERY_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5)) +#define Z_RFC3986_URI_PROP_FRAGMENT_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6)) + static HashTable *uri_get_debug_properties(php_uri_object *object) { const HashTable *std_properties = zend_std_get_properties(&object->std); @@ -510,6 +532,16 @@ PHP_METHOD(Uri_WhatWg_Url, __construct) create_whatwg_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } +PHP_METHOD(Uri_Rfc3986_Uri, getUriType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_rfc3986_uri_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_Rfc3986_Uri, getScheme) { php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); @@ -613,6 +645,16 @@ PHP_METHOD(Uri_Rfc3986_Uri, getRawHost) php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_RAW); } +PHP_METHOD(Uri_Rfc3986_Uri, getHostType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_rfc3986_host_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_Rfc3986_Uri, withHost) { php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST); @@ -885,6 +927,16 @@ PHP_METHOD(Uri_WhatWg_Url, withScheme) php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); } +PHP_METHOD(Uri_WhatWg_Url, isSpecialScheme) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + RETVAL_BOOL(php_uri_parser_whatwg_is_special(uri_object->uri)); +} + PHP_METHOD(Uri_WhatWg_Url, withUsername) { php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME); @@ -905,6 +957,16 @@ PHP_METHOD(Uri_WhatWg_Url, getUnicodeHost) php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } +PHP_METHOD(Uri_WhatWg_Url, getHostType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_whatwg_host_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_WhatWg_Url, getFragment) { php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); @@ -1003,6 +1065,186 @@ PHP_METHOD(Uri_WhatWg_Url, __debugInfo) RETURN_ARR(uri_get_debug_properties(uri_object)); } +PHP_METHOD(Uri_Rfc3986_UriBuilder, reset) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + convert_to_null(Z_RFC3986_URI_PROP_SCHEME_P(ZEND_THIS)); + convert_to_null(Z_RFC3986_URI_PROP_USERINFO_P(ZEND_THIS)); + convert_to_null(Z_RFC3986_URI_PROP_HOST_P(ZEND_THIS)); + convert_to_null(Z_RFC3986_URI_PROP_PORT_P(ZEND_THIS)); + zval_ptr_dtor(Z_RFC3986_URI_PROP_PATH_P(ZEND_THIS)); + ZVAL_EMPTY_STRING(Z_RFC3986_URI_PROP_PATH_P(ZEND_THIS)); + convert_to_null(Z_RFC3986_URI_PROP_QUERY_P(ZEND_THIS)); + convert_to_null(Z_RFC3986_URI_PROP_FRAGMENT_P(ZEND_THIS)); + + RETVAL_COPY(ZEND_THIS); +} + +ZEND_ATTRIBUTE_NONNULL static void php_uri_builder_set_component_string( + INTERNAL_FUNCTION_PARAMETERS, const char *name, const size_t name_length, + const php_uri_component_validator_string validator +) { + zend_string *component; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(component) + ZEND_PARSE_PARAMETERS_END(); + + if (validator(component) == FAILURE) { + RETURN_THROWS(); + } + + zend_update_property_str(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), name, name_length, component); + + RETVAL_COPY(ZEND_THIS); +} + +ZEND_ATTRIBUTE_NONNULL static void php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAMETERS, const char *name, const size_t name_length, + const php_uri_component_validator_string validator +) { + zend_string *component; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR_OR_NULL(component) + ZEND_PARSE_PARAMETERS_END(); + + if (component == NULL) { + zend_update_property_null(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), name, name_length); + } else { + if (validator(component) == FAILURE) { + RETURN_THROWS(); + } + + zend_update_property_str(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), name, name_length, component); + } + + RETVAL_COPY(ZEND_THIS); +} + +ZEND_ATTRIBUTE_NONNULL_ARGS(1) static void php_uri_builder_set_component_long_or_null( + INTERNAL_FUNCTION_PARAMETERS, const char *name, const size_t name_length, + const php_uri_component_validator_long validator +) { + zend_long component; + bool component_is_null; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG_OR_NULL(component, component_is_null) + ZEND_PARSE_PARAMETERS_END(); + + if (component_is_null) { + zend_update_property_null(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), name, name_length); + } else { + if (validator(component) == FAILURE) { + RETURN_THROWS(); + } + + zend_update_property_long(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), name, name_length, component); + } + + RETVAL_COPY(ZEND_THIS); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setScheme) +{ + php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("scheme"), + php_uri_parser_rfc3986_validate_scheme + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setUserInfo) +{ + php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("userinfo"), + php_uri_parser_rfc3986_validate_userinfo + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setHost) +{ + php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("host"), + php_uri_parser_rfc3986_validate_host + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setPort) +{ + php_uri_builder_set_component_long_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("port"), + php_uri_parser_rfc3986_validate_port + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setPath) +{ + php_uri_builder_set_component_string( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("path"), + php_uri_parser_rfc3986_validate_path + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setQuery) +{ + php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("query"), + php_uri_parser_rfc3986_validate_query + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, setFragment) +{ + php_uri_builder_set_component_string_or_null( + INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_STRL("fragment"), + php_uri_parser_rfc3986_validate_fragment + ); +} + +PHP_METHOD(Uri_Rfc3986_UriBuilder, build) +{ + zval *base_url = NULL; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(base_url, php_uri_ce_rfc3986_uri) + ZEND_PARSE_PARAMETERS_END(); + + const zval *scheme = Z_RFC3986_URI_PROP_SCHEME_P(ZEND_THIS); + const zval *userinfo = Z_RFC3986_URI_PROP_USERINFO_P(ZEND_THIS); + const zval *host = Z_RFC3986_URI_PROP_HOST_P(ZEND_THIS); + const zval *port = Z_RFC3986_URI_PROP_PORT_P(ZEND_THIS); + const zval *path = Z_RFC3986_URI_PROP_PATH_P(ZEND_THIS); + const zval *query = Z_RFC3986_URI_PROP_QUERY_P(ZEND_THIS); + const zval *fragment = Z_RFC3986_URI_PROP_FRAGMENT_P(ZEND_THIS); + + php_uri_parser_rfc3986_uris *base_uris = NULL; + if (base_url != NULL) { + base_uris = Z_URI_OBJECT_P(base_url)->uri; + } + + php_uri_parser_rfc3986_uris *uriparser_uris = php_uri_parser_rfc3986_build_from_zval( + base_uris, scheme, userinfo, host, port, path, query, fragment + ); + if (uriparser_uris == NULL) { + RETURN_THROWS(); + } + + object_init_ex(return_value, php_uri_ce_rfc3986_uri); + php_uri_object *uri_object = Z_URI_OBJECT_P(return_value); + uri_object->parser = &php_uri_parser_rfc3986; + uri_object->uri = uriparser_uris; +} + PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser) { php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type); @@ -1036,7 +1278,7 @@ PHPAPI void php_uri_object_handler_free(zend_object *object) PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object) { - php_uri_object *uri_object = php_uri_object_from_obj(object); + const php_uri_object *uri_object = php_uri_object_from_obj(object); ZEND_ASSERT(uri_object->uri != NULL); @@ -1072,19 +1314,24 @@ PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser) static PHP_MINIT_FUNCTION(uri) { + php_uri_ce_rfc3986_uri_builder = register_class_Uri_Rfc3986_UriBuilder(); + php_uri_ce_rfc3986_uri = register_class_Uri_Rfc3986_Uri(); php_uri_ce_rfc3986_uri->create_object = php_uri_object_create_rfc3986; php_uri_ce_rfc3986_uri->default_object_handlers = &object_handlers_rfc3986_uri; memcpy(&object_handlers_rfc3986_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - object_handlers_rfc3986_uri.offset = XtOffsetOf(php_uri_object, std); + object_handlers_rfc3986_uri.offset = offsetof(php_uri_object, std); object_handlers_rfc3986_uri.free_obj = php_uri_object_handler_free; object_handlers_rfc3986_uri.clone_obj = php_uri_object_handler_clone; + php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType(); + php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType(); + php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url(); php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg; php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri; memcpy(&object_handlers_whatwg_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - object_handlers_whatwg_uri.offset = XtOffsetOf(php_uri_object, std); + object_handlers_whatwg_uri.offset = offsetof(php_uri_object, std); object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free; object_handlers_whatwg_uri.clone_obj = php_uri_object_handler_clone; @@ -1093,6 +1340,7 @@ static PHP_MINIT_FUNCTION(uri) php_uri_ce_error = register_class_Uri_UriError(zend_ce_error); php_uri_ce_invalid_uri_exception = register_class_Uri_InvalidUriException(php_uri_ce_exception); php_uri_ce_whatwg_invalid_url_exception = register_class_Uri_WhatWg_InvalidUrlException(php_uri_ce_invalid_uri_exception); + php_uri_ce_whatwg_url_host_type = register_class_Uri_WhatWg_UrlHostType(); php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError(); php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType(); diff --git a/ext/uri/php_uri.h b/ext/uri/php_uri.h index 1ec3617b096c..2c8516585c0f 100644 --- a/ext/uri/php_uri.h +++ b/ext/uri/php_uri.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index 6d4b2c3517a5..81a766c0e16d 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -29,6 +29,52 @@ enum UriComparisonMode } namespace Uri\Rfc3986 { + enum UriType + { + case AbsolutePathReference; + case RelativePathReference; + case NetworkPathReference; + case Uri; + } + + enum UriHostType + { + case IPv4; + case IPv6; + case IPvFuture; + case RegisteredName; + } + + /** @strict-properties */ + final class UriBuilder + { + private ?string $scheme = null; + private ?string $userinfo = null; + private ?string $host = null; + private ?int $port = null; + private string $path = ""; + private ?string $query = null; + private ?string $fragment = null; + + public function reset(): static {} + + public function setScheme(?string $scheme): static {} + + public function setUserInfo(#[\SensitiveParameter] ?string $userInfo): static {} + + public function setHost(?string $host): static {} + + public function setPort(?int $port): static {} + + public function setPath(string $path): static {} + + public function setQuery(?string $query): static {} + + public function setFragment(?string $fragment): static {} + + public function build(?\Uri\Rfc3986\Uri $baseUrl = null): \Uri\Rfc3986\Uri {} + } + /** @strict-properties */ final readonly class Uri { @@ -36,6 +82,8 @@ public static function parse(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null): ?s public function __construct(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null) {} + public function getUriType(): ?\Uri\Rfc3986\UriType {} + public function getScheme(): ?string {} public function getRawScheme(): ?string {} @@ -60,6 +108,8 @@ public function getHost(): ?string {} public function getRawHost(): ?string {} + public function getHostType(): ?\Uri\Rfc3986\UriHostType {} + public function withHost(?string $host): static {} public function getPort(): ?int {} @@ -152,6 +202,15 @@ enum UrlValidationErrorType public function __construct(string $context, \Uri\WhatWg\UrlValidationErrorType $type, bool $failure) {} } + enum UrlHostType + { + case IPv4; + case IPv6; + case Domain; + case Opaque; + case Empty; + } + /** @strict-properties */ final readonly class Url { @@ -165,6 +224,8 @@ public function getScheme(): string {} public function withScheme(string $scheme): static {} + public function isSpecialScheme(): bool {} + /** @implementation-alias Uri\Rfc3986\Uri::getUsername */ public function getUsername(): ?string {} @@ -179,6 +240,8 @@ public function getAsciiHost(): ?string {} public function getUnicodeHost(): ?string {} + public function getHostType(): ?\Uri\WhatWg\UrlHostType {} + /** @implementation-alias Uri\Rfc3986\Uri::withHost */ public function withHost(?string $host): static {} diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 18d7f4adf783..1231408fbeb6 100644 --- a/ext/uri/php_uri_arginfo.h +++ b/ext/uri/php_uri_arginfo.h @@ -1,7 +1,42 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: 3c228f4227e7543be5c12c99074789d92c27ab99 + * Stub hash: bfd9247fa79baf877d600134c9ef615ec5ca9cea * Has decl header: yes */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_reset, 0, 0, IS_STATIC, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setScheme, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, scheme, IS_STRING, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setUserInfo, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, userInfo, IS_STRING, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setHost, 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_Rfc3986_UriBuilder_setPort, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setPath, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setQuery, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_setFragment, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, fragment, IS_STRING, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_build, 0, 0, Uri\\Rfc3986\\\125ri, 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_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") @@ -12,14 +47,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Uri_Rfc3986_Uri___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, baseUrl, Uri\\Rfc3986\\\125ri, 1, "null") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getUriType, 0, 0, Uri\\Rfc3986\\\125riType, 1) +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 -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_withScheme, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, scheme, IS_STRING, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withScheme arginfo_class_Uri_Rfc3986_UriBuilder_setScheme #define arginfo_class_Uri_Rfc3986_Uri_getUserInfo arginfo_class_Uri_Rfc3986_Uri_getScheme @@ -41,41 +77,34 @@ ZEND_END_ARG_INFO() #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_withHost, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getHostType, 0, 0, Uri\\Rfc3986\\\125riHostType, 1) ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withHost arginfo_class_Uri_Rfc3986_UriBuilder_setHost + 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_withPort, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withPort arginfo_class_Uri_Rfc3986_UriBuilder_setPort 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 -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_withPath, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withPath arginfo_class_Uri_Rfc3986_UriBuilder_setPath #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 -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_withQuery, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withQuery arginfo_class_Uri_Rfc3986_UriBuilder_setQuery #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_withFragment, 0, 1, IS_STATIC, 0) - ZEND_ARG_TYPE_INFO(0, fragment, IS_STRING, 1) -ZEND_END_ARG_INFO() +#define arginfo_class_Uri_Rfc3986_Uri_withFragment arginfo_class_Uri_Rfc3986_UriBuilder_setFragment 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) @@ -130,6 +159,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withScheme, 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_isSpecialScheme, 0, 0, _IS_BOOL, 0) +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) @@ -146,23 +178,26 @@ ZEND_END_ARG_INFO() #define arginfo_class_Uri_WhatWg_Url_getUnicodeHost arginfo_class_Uri_Rfc3986_Uri_getScheme -#define arginfo_class_Uri_WhatWg_Url_withHost arginfo_class_Uri_Rfc3986_Uri_withHost +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_WhatWg_Url_getHostType, 0, 0, Uri\\WhatWg\\\125rlHostType, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Uri_WhatWg_Url_withHost arginfo_class_Uri_Rfc3986_UriBuilder_setHost #define arginfo_class_Uri_WhatWg_Url_getPort arginfo_class_Uri_Rfc3986_Uri_getPort -#define arginfo_class_Uri_WhatWg_Url_withPort arginfo_class_Uri_Rfc3986_Uri_withPort +#define arginfo_class_Uri_WhatWg_Url_withPort arginfo_class_Uri_Rfc3986_UriBuilder_setPort #define arginfo_class_Uri_WhatWg_Url_getPath arginfo_class_Uri_Rfc3986_Uri_getPath -#define arginfo_class_Uri_WhatWg_Url_withPath arginfo_class_Uri_Rfc3986_Uri_withPath +#define arginfo_class_Uri_WhatWg_Url_withPath arginfo_class_Uri_Rfc3986_UriBuilder_setPath #define arginfo_class_Uri_WhatWg_Url_getQuery arginfo_class_Uri_Rfc3986_Uri_getScheme -#define arginfo_class_Uri_WhatWg_Url_withQuery arginfo_class_Uri_Rfc3986_Uri_withQuery +#define arginfo_class_Uri_WhatWg_Url_withQuery arginfo_class_Uri_Rfc3986_UriBuilder_setQuery #define arginfo_class_Uri_WhatWg_Url_getFragment arginfo_class_Uri_Rfc3986_Uri_getScheme -#define arginfo_class_Uri_WhatWg_Url_withFragment arginfo_class_Uri_Rfc3986_Uri_withFragment +#define arginfo_class_Uri_WhatWg_Url_withFragment arginfo_class_Uri_Rfc3986_UriBuilder_setFragment ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_equals, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, url, Uri\\WhatWg\\\125rl, 0) @@ -184,8 +219,18 @@ ZEND_END_ARG_INFO() #define arginfo_class_Uri_WhatWg_Url___debugInfo arginfo_class_Uri_Rfc3986_Uri___serialize +ZEND_METHOD(Uri_Rfc3986_UriBuilder, reset); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setScheme); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setUserInfo); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setHost); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setPort); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setPath); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setQuery); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, setFragment); +ZEND_METHOD(Uri_Rfc3986_UriBuilder, build); ZEND_METHOD(Uri_Rfc3986_Uri, parse); ZEND_METHOD(Uri_Rfc3986_Uri, __construct); +ZEND_METHOD(Uri_Rfc3986_Uri, getUriType); ZEND_METHOD(Uri_Rfc3986_Uri, getScheme); ZEND_METHOD(Uri_Rfc3986_Uri, getRawScheme); ZEND_METHOD(Uri_Rfc3986_Uri, withScheme); @@ -198,6 +243,7 @@ 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, getHostType); ZEND_METHOD(Uri_Rfc3986_Uri, withHost); ZEND_METHOD(Uri_Rfc3986_Uri, getPort); ZEND_METHOD(Uri_Rfc3986_Uri, withPort); @@ -223,10 +269,12 @@ 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, isSpecialScheme); ZEND_METHOD(Uri_WhatWg_Url, withUsername); ZEND_METHOD(Uri_WhatWg_Url, withPassword); ZEND_METHOD(Uri_WhatWg_Url, getAsciiHost); ZEND_METHOD(Uri_WhatWg_Url, getUnicodeHost); +ZEND_METHOD(Uri_WhatWg_Url, getHostType); ZEND_METHOD(Uri_WhatWg_Url, equals); ZEND_METHOD(Uri_WhatWg_Url, toAsciiString); ZEND_METHOD(Uri_WhatWg_Url, toUnicodeString); @@ -235,9 +283,23 @@ 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_UriBuilder_methods[] = { + ZEND_ME(Uri_Rfc3986_UriBuilder, reset, arginfo_class_Uri_Rfc3986_UriBuilder_reset, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setScheme, arginfo_class_Uri_Rfc3986_UriBuilder_setScheme, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setUserInfo, arginfo_class_Uri_Rfc3986_UriBuilder_setUserInfo, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setHost, arginfo_class_Uri_Rfc3986_UriBuilder_setHost, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setPort, arginfo_class_Uri_Rfc3986_UriBuilder_setPort, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setPath, arginfo_class_Uri_Rfc3986_UriBuilder_setPath, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setQuery, arginfo_class_Uri_Rfc3986_UriBuilder_setQuery, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, setFragment, arginfo_class_Uri_Rfc3986_UriBuilder_setFragment, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_UriBuilder, build, arginfo_class_Uri_Rfc3986_UriBuilder_build, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + 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, getUriType, arginfo_class_Uri_Rfc3986_Uri_getUriType, 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, withScheme, arginfo_class_Uri_Rfc3986_Uri_withScheme, ZEND_ACC_PUBLIC) @@ -250,6 +312,7 @@ static const zend_function_entry class_Uri_Rfc3986_Uri_methods[] = { 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, getHostType, arginfo_class_Uri_Rfc3986_Uri_getHostType, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, withHost, arginfo_class_Uri_Rfc3986_Uri_withHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getPort, arginfo_class_Uri_Rfc3986_Uri_getPort, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, withPort, arginfo_class_Uri_Rfc3986_Uri_withPort, ZEND_ACC_PUBLIC) @@ -287,12 +350,14 @@ 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, isSpecialScheme, arginfo_class_Uri_WhatWg_Url_isSpecialScheme, 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_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, getHostType, arginfo_class_Uri_WhatWg_Url_getHostType, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("withHost", zim_Uri_Rfc3986_Uri_withHost, arginfo_class_Uri_WhatWg_Url_withHost, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getPort", zim_Uri_Rfc3986_Uri_getPort, arginfo_class_Uri_WhatWg_Url_getPort, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("withPort", zim_Uri_Rfc3986_Uri_withPort, arginfo_class_Uri_WhatWg_Url_withPort, ZEND_ACC_PUBLIC, NULL, NULL) @@ -353,6 +418,79 @@ static zend_class_entry *register_class_Uri_UriComparisonMode(void) return class_entry; } +static zend_class_entry *register_class_Uri_Rfc3986_UriType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\Rfc3986\\UriType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "AbsolutePathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "RelativePathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "NetworkPathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "Uri", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_Uri_Rfc3986_UriHostType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\Rfc3986\\UriHostType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "IPv4", NULL); + + zend_enum_add_case_cstr(class_entry, "IPv6", NULL); + + zend_enum_add_case_cstr(class_entry, "IPvFuture", NULL); + + zend_enum_add_case_cstr(class_entry, "RegisteredName", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_Uri_Rfc3986_UriBuilder(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Uri\\Rfc3986", "UriBuilder", class_Uri_Rfc3986_UriBuilder_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zval property_scheme_default_value; + ZVAL_NULL(&property_scheme_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_SCHEME), &property_scheme_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + + zval property_userinfo_default_value; + ZVAL_NULL(&property_userinfo_default_value); + zend_string *property_userinfo_name = zend_string_init("userinfo", sizeof("userinfo") - 1, true); + zend_declare_typed_property(class_entry, property_userinfo_name, &property_userinfo_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release_ex(property_userinfo_name, true); + + zval property_host_default_value; + ZVAL_NULL(&property_host_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_HOST), &property_host_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + + zval property_port_default_value; + ZVAL_NULL(&property_port_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PORT), &property_port_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); + + zval property_path_default_value; + ZVAL_EMPTY_STRING(&property_path_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PATH), &property_path_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zval property_query_default_value; + ZVAL_NULL(&property_query_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_QUERY), &property_query_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + + zval property_fragment_default_value; + ZVAL_NULL(&property_fragment_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_FRAGMENT), &property_fragment_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setuserinfo", sizeof("setuserinfo") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + return class_entry; +} + static zend_class_entry *register_class_Uri_Rfc3986_Uri(void) { zend_class_entry ce, *class_entry; @@ -474,6 +612,23 @@ static zend_class_entry *register_class_Uri_WhatWg_UrlValidationError(void) return class_entry; } +static zend_class_entry *register_class_Uri_WhatWg_UrlHostType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\WhatWg\\UrlHostType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "IPv4", NULL); + + zend_enum_add_case_cstr(class_entry, "IPv6", NULL); + + zend_enum_add_case_cstr(class_entry, "Domain", NULL); + + zend_enum_add_case_cstr(class_entry, "Opaque", NULL); + + zend_enum_add_case_cstr(class_entry, "Empty", NULL); + + return class_entry; +} + static zend_class_entry *register_class_Uri_WhatWg_Url(void) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index da73bc59bf9c..0644afda3105 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -38,7 +36,7 @@ static zend_string *get_known_string_by_property_name(php_uri_property_name prop return ZSTR_KNOWN(ZEND_STR_QUERY); case PHP_URI_PROPERTY_NAME_FRAGMENT: return ZSTR_KNOWN(ZEND_STR_FRAGMENT); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -57,7 +55,7 @@ void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property } } -static void php_uri_property_write_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv) +static void php_uri_property_write_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, const zval *property_zv) { php_uri_object *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(old_uri_object->uri != NULL); diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 2ae76cb2ee4d..9106f6acd15f 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -19,7 +17,10 @@ #include "php_uri_decl.h" +extern zend_class_entry *php_uri_ce_rfc3986_uri_builder; extern zend_class_entry *php_uri_ce_rfc3986_uri; +extern zend_class_entry *php_uri_ce_rfc3986_uri_type; +extern zend_class_entry *php_uri_ce_rfc3986_uri_host_type; extern zend_class_entry *php_uri_ce_whatwg_url; extern zend_class_entry *php_uri_ce_comparison_mode; extern zend_class_entry *php_uri_ce_exception; @@ -28,6 +29,7 @@ extern zend_class_entry *php_uri_ce_invalid_uri_exception; extern zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; extern zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; extern zend_class_entry *php_uri_ce_whatwg_url_validation_error; +extern zend_class_entry *php_uri_ce_whatwg_url_host_type; typedef enum php_uri_recomposition_mode { PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, @@ -44,7 +46,7 @@ typedef enum php_uri_component_read_mode { typedef zend_result (*php_uri_property_handler_read)(void *uri, php_uri_component_read_mode read_mode, zval *retval); -typedef zend_result (*php_uri_property_handler_write)(void *uri, zval *value, zval *errors); +typedef zend_result (*php_uri_property_handler_write)(void *uri, const zval *value, zval *errors); typedef enum php_uri_property_name { PHP_URI_PROPERTY_NAME_SCHEME, @@ -148,9 +150,7 @@ typedef struct php_uri_object { zend_object std; } php_uri_object; -static inline php_uri_object *php_uri_object_from_obj(zend_object *object) { - return (php_uri_object*)((char*)(object) - XtOffsetOf(php_uri_object, std)); -} +#define php_uri_object_from_obj(object) ZEND_CONTAINER_OF(object, php_uri_object, std) #define Z_URI_OBJECT_P(zv) php_uri_object_from_obj(Z_OBJ_P((zv))) @@ -182,7 +182,7 @@ static inline const php_uri_property_handler *php_uri_parser_property_handler_by return &parser->property_handler.query; case PHP_URI_PROPERTY_NAME_FRAGMENT: return &parser->property_handler.fragment; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h index 3c069f3abe6d..9c817659cf76 100644 --- a/ext/uri/php_uri_decl.h +++ b/ext/uri/php_uri_decl.h @@ -1,14 +1,28 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: 3c228f4227e7543be5c12c99074789d92c27ab99 */ + * Stub hash: bfd9247fa79baf877d600134c9ef615ec5ca9cea */ -#ifndef ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H -#define ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H +#ifndef ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H +#define ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H typedef enum zend_enum_Uri_UriComparisonMode { ZEND_ENUM_Uri_UriComparisonMode_IncludeFragment = 1, ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment = 2, } zend_enum_Uri_UriComparisonMode; +typedef enum zend_enum_Uri_Rfc3986_UriType { + ZEND_ENUM_Uri_Rfc3986_UriType_AbsolutePathReference = 1, + ZEND_ENUM_Uri_Rfc3986_UriType_RelativePathReference = 2, + ZEND_ENUM_Uri_Rfc3986_UriType_NetworkPathReference = 3, + ZEND_ENUM_Uri_Rfc3986_UriType_Uri = 4, +} zend_enum_Uri_Rfc3986_UriType; + +typedef enum zend_enum_Uri_Rfc3986_UriHostType { + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv4 = 1, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv6 = 2, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPvFuture = 3, + ZEND_ENUM_Uri_Rfc3986_UriHostType_RegisteredName = 4, +} zend_enum_Uri_Rfc3986_UriHostType; + typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToAscii = 1, ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToUnicode = 2, @@ -41,4 +55,12 @@ typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_FileInvalidWindowsDriveLetterHost = 29, } zend_enum_Uri_WhatWg_UrlValidationErrorType; -#endif /* ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H */ +typedef enum zend_enum_Uri_WhatWg_UrlHostType { + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv4 = 1, + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv6 = 2, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Domain = 3, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Opaque = 4, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Empty = 5, +} zend_enum_Uri_WhatWg_UrlHostType; + +#endif /* ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H */ diff --git a/ext/uri/tests/003.phpt b/ext/uri/tests/003.phpt index a1918f7a838b..38d62b0ec8e6 100644 --- a/ext/uri/tests/003.phpt +++ b/ext/uri/tests/003.phpt @@ -1,7 +1,5 @@ --TEST-- Parse special URIs ---EXTENSIONS-- -uri --FILE-- getFragment()); } -$uri = Uri\Rfc3986\Uri::parse("https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); +$uri = Uri\Rfc3986\Uri::parse("https://username:password@www.example.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"); +$url = Uri\WhatWg\Url::parse("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); callWhatWgGetters($url); ?> @@ -57,8 +55,8 @@ string(8) "password" string(8) "password" string(17) "username:password" string(17) "username:password" -string(14) "www.google.com" -string(14) "www.google.com" +string(15) "www.example.com" +string(15) "www.example.com" int(8080) string(30) "/pathname1/pathname2/pathname3" string(30) "/pathname1/pathname2/pathname3" @@ -70,8 +68,8 @@ string(11) "hash-exists" string(5) "https" string(8) "username" string(8) "password" -string(14) "www.google.com" -string(14) "www.google.com" +string(15) "www.example.com" +string(15) "www.example.com" int(8080) string(30) "/pathname1/pathname2/pathname3" string(10) "query=true" diff --git a/ext/uri/tests/009.phpt b/ext/uri/tests/009.phpt index 05f2820bb3fc..9c896d0153b2 100644 --- a/ext/uri/tests/009.phpt +++ b/ext/uri/tests/009.phpt @@ -1,7 +1,5 @@ --TEST-- Test parsing with IANA schemes ---EXTENSIONS-- -uri --FILE-- getMessage() . "\n"; } -$url1 = new Uri\WhatWg\Url("https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); +$url1 = new Uri\WhatWg\Url("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); $serializedUrl1 = serialize($url1); $url2 = unserialize($serializedUrl1); @@ -123,7 +121,7 @@ try { ?> --EXPECTF-- -string(163) "O:15:"Uri\Rfc3986\Uri":2:{i:0;a:1:{s:3:"uri";s:98:"https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists";}i:1;a:0:{}}" +string(164) "O:15:"Uri\Rfc3986\Uri":2:{i:0;a:1:{s:3:"uri";s:99:"https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists";}i:1;a:0:{}}" object(Uri\Rfc3986\Uri)#%d (%d) { ["scheme"]=> string(5) "https" @@ -132,7 +130,7 @@ object(Uri\Rfc3986\Uri)#%d (%d) { ["password"]=> string(8) "password" ["host"]=> - string(14) "www.google.com" + string(15) "www.example.com" ["port"]=> int(8080) ["path"]=> @@ -150,7 +148,7 @@ Invalid serialization data for Uri\Rfc3986\Uri object Invalid serialization data for Uri\Rfc3986\Uri object Invalid serialization data for Uri\Rfc3986\Uri object Invalid serialization data for Uri\Rfc3986\Uri object -string(162) "O:14:"Uri\WhatWg\Url":2:{i:0;a:1:{s:3:"uri";s:98:"https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists";}i:1;a:0:{}}" +string(163) "O:14:"Uri\WhatWg\Url":2:{i:0;a:1:{s:3:"uri";s:99:"https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists";}i:1;a:0:{}}" object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(5) "https" @@ -159,7 +157,7 @@ object(Uri\WhatWg\Url)#%d (%d) { ["password"]=> string(8) "password" ["host"]=> - string(14) "www.google.com" + string(15) "www.example.com" ["port"]=> int(8080) ["path"]=> diff --git a/ext/uri/tests/032.phpt b/ext/uri/tests/032.phpt index b3e670223883..b17765240c7b 100644 --- a/ext/uri/tests/032.phpt +++ b/ext/uri/tests/032.phpt @@ -1,14 +1,12 @@ --TEST-- Test JSON encoding ---EXTENSIONS-- -uri --FILE-- diff --git a/ext/uri/tests/033.phpt b/ext/uri/tests/033.phpt index 65e8ab26a2dd..e88baadeba0d 100644 --- a/ext/uri/tests/033.phpt +++ b/ext/uri/tests/033.phpt @@ -1,15 +1,13 @@ --TEST-- Test var_export ---EXTENSIONS-- -uri --FILE-- diff --git a/ext/uri/tests/038.phpt b/ext/uri/tests/038.phpt index 64a6289fada2..175a6762894b 100644 --- a/ext/uri/tests/038.phpt +++ b/ext/uri/tests/038.phpt @@ -1,7 +1,5 @@ --TEST-- Test toString() ---EXTENSIONS-- -uri --FILE-- +--EXPECTF-- +Warning: Class Uri\WhatWg\Url has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 25 of 26 bytes in %s on line %d + +Warning: Class Uri\Rfc3986\Uri has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 26 of 27 bytes in %s on line %d diff --git a/ext/uri/tests/rfc3986/builder/all_success_with_reset.phpt b/ext/uri/tests/rfc3986/builder/all_success_with_reset.phpt new file mode 100644 index 000000000000..9c11fb2e6682 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/all_success_with_reset.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder all components - success - calling reset() afterwards +--FILE-- +setScheme("https") + ->setUserInfo("user:info") + ->setHost("example.com") + ->setPort(443) + ->setPath("/foo/bar/baz") + ->setQuery("foo=1&bar=baz") + ->setFragment("fragment"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +$uri = $builder->reset()->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(68) "https://user:info@example.com:443/foo/bar/baz?foo=1&bar=baz#fragment" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + string(4) "user" + ["password"]=> + string(4) "info" + ["host"]=> + string(11) "example.com" + ["port"]=> + int(443) + ["path"]=> + string(12) "/foo/bar/baz" + ["query"]=> + string(13) "foo=1&bar=baz" + ["fragment"]=> + string(8) "fragment" +} +bool(true) +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/basic_error_with_base.phpt b/ext/uri/tests/rfc3986/builder/basic_error_with_base.phpt new file mode 100644 index 000000000000..284de4e6a522 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/basic_error_with_base.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder basic - error - with base URL +--FILE-- +setPath("/foo/bar/baz"); + +try { + $builder->build(new Uri\Rfc3986\Uri("/foo/bar")); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified base URI must be absolute diff --git a/ext/uri/tests/rfc3986/builder/basic_success_with_base.phpt b/ext/uri/tests/rfc3986/builder/basic_success_with_base.phpt new file mode 100644 index 000000000000..b7a84dc00cf1 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/basic_success_with_base.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder basic - success - with base URL +--FILE-- +setPath("/foo/bar/baz"); +$uri = $builder->build(new Uri\Rfc3986\Uri("https://example.com")); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(31) "https://example.com/foo/bar/baz" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(12) "/foo/bar/baz" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/fragment_error_special_char.phpt b/ext/uri/tests/rfc3986/builder/fragment_error_special_char.phpt new file mode 100644 index 000000000000..8ed2a8938e9a --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/fragment_error_special_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setFragment() - error - contains invalid special character +--FILE-- +setFragment("#foo"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified fragment is malformed diff --git a/ext/uri/tests/rfc3986/builder/fragment_error_unicode_char.phpt b/ext/uri/tests/rfc3986/builder/fragment_error_unicode_char.phpt new file mode 100644 index 000000000000..2a15d5e85a82 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/fragment_error_unicode_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setFragment() - error - contains Unicode character +--FILE-- +setFragment("főő"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified fragment is malformed diff --git a/ext/uri/tests/rfc3986/builder/fragment_success_basic.phpt b/ext/uri/tests/rfc3986/builder/fragment_success_basic.phpt new file mode 100644 index 000000000000..a59d9322e1b5 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/fragment_success_basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setFragment() - success - basic +--FILE-- +setFragment("foo"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(4) "#foo" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + string(3) "foo" +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/fragment_success_null.phpt b/ext/uri/tests/rfc3986/builder/fragment_success_null.phpt new file mode 100644 index 000000000000..69fc4d6bca49 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/fragment_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setFragment() - success - null +--FILE-- +setFragment("foo"); +$builder->setFragment(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_error_ipv6_closing_brace.phpt b/ext/uri/tests/rfc3986/builder/host_error_ipv6_closing_brace.phpt new file mode 100644 index 000000000000..45eef13faf71 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_error_ipv6_closing_brace.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - error - missing IPv6 closing brace +--FILE-- +setHost("[2001:%30db8:85a3:0000:0000:8a2e:0370:7334"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified host is malformed diff --git a/ext/uri/tests/rfc3986/builder/host_error_percent_encoding1.phpt b/ext/uri/tests/rfc3986/builder/host_error_percent_encoding1.phpt new file mode 100644 index 000000000000..ae06238a1f8f --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_error_percent_encoding1.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - error - invalid percent encoding octet in registered name +--FILE-- +setHost("ex%3mple.co"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified host is malformed diff --git a/ext/uri/tests/rfc3986/builder/host_error_percent_encoding2.phpt b/ext/uri/tests/rfc3986/builder/host_error_percent_encoding2.phpt new file mode 100644 index 000000000000..cc514ec69191 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_error_percent_encoding2.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - error - invalid percent encoded octet in IPv6 +--FILE-- +setHost("[2001:%308:85a3:0000:0000:8a2e:0370:7334]"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified host is malformed diff --git a/ext/uri/tests/rfc3986/builder/host_success_ip4_to_regname.phpt b/ext/uri/tests/rfc3986/builder/host_success_ip4_to_regname.phpt new file mode 100644 index 000000000000..561a66c40375 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_ip4_to_regname.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - invalid IPv4 address falls back to a registered name +--FILE-- +setHost("192.168.%30.1"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri->getHostType()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(15) "//192.168.%30.1" +enum(Uri\Rfc3986\UriHostType::RegisteredName) +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(13) "192.168.%30.1" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_success_ipv4.phpt b/ext/uri/tests/rfc3986/builder/host_success_ipv4.phpt new file mode 100644 index 000000000000..7ae3b9010851 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_ipv4.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - IPv4 address +--FILE-- +setHost("192.168.0.1"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(13) "//192.168.0.1" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "192.168.0.1" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_success_ipv6.phpt b/ext/uri/tests/rfc3986/builder/host_success_ipv6.phpt new file mode 100644 index 000000000000..f0216f7e7e09 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_ipv6.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - IPv6 address +--FILE-- +setHost("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(43) "//[2001:0db8:85a3:0000:0000:8a2e:0370:7334]" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(41) "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_success_ipvfuture.phpt b/ext/uri/tests/rfc3986/builder/host_success_ipvfuture.phpt new file mode 100644 index 000000000000..470ef1da97dc --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_ipvfuture.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - IPvFuture address +--FILE-- +setHost("[v1.2001:db8::1]"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(18) "//[v1.2001:db8::1]" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(16) "[v1.2001:db8::1]" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_success_null.phpt b/ext/uri/tests/rfc3986/builder/host_success_null.phpt new file mode 100644 index 000000000000..f1689749866b --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - null +--FILE-- +setHost("example.com"); +$builder->setHost(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/host_success_regname.phpt b/ext/uri/tests/rfc3986/builder/host_success_regname.phpt new file mode 100644 index 000000000000..81e93ccfc10a --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/host_success_regname.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setHost() - success - Registered name +--FILE-- +setHost("www.example.com"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(17) "//www.example.com" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(15) "www.example.com" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/path_error_first_segment_colon.phpt b/ext/uri/tests/rfc3986/builder/path_error_first_segment_colon.phpt new file mode 100644 index 000000000000..8cce8d471aa1 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_error_first_segment_colon.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - error - contains a colon in the first path segment when the URI doesn't contain a scheme +--FILE-- +setPath("fo:o/bar/baz"); + +try { + $builder->build(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The path must not begin with ":" when the URI does not contain a scheme diff --git a/ext/uri/tests/rfc3986/builder/path_error_leading_double_slash.phpt b/ext/uri/tests/rfc3986/builder/path_error_leading_double_slash.phpt new file mode 100644 index 000000000000..b1f0a2518f1c --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_error_leading_double_slash.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - error - contains leading double slash when the host is not present +--FILE-- +setPath("//foo/bar/baz"); + +try { + $builder->build(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The path must not begin with "//" when the URI does not contain a host diff --git a/ext/uri/tests/rfc3986/builder/path_error_missing_leading_slash.phpt b/ext/uri/tests/rfc3986/builder/path_error_missing_leading_slash.phpt new file mode 100644 index 000000000000..97b6c3e8b854 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_error_missing_leading_slash.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - error - missing a leading slash when the URI contains a host +--FILE-- +setPath("foo/bar/baz"); +$builder->setHost("example.com"); + +try { + $builder->build(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified path is malformed diff --git a/ext/uri/tests/rfc3986/builder/path_error_special_char.phpt b/ext/uri/tests/rfc3986/builder/path_error_special_char.phpt new file mode 100644 index 000000000000..039b22770246 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_error_special_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - error - contains invalid special character +--FILE-- +setPath("#foo"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified path is malformed diff --git a/ext/uri/tests/rfc3986/builder/path_success_empty_string.phpt b/ext/uri/tests/rfc3986/builder/path_success_empty_string.phpt new file mode 100644 index 000000000000..78ea6cf12cd3 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_success_empty_string.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - success - empty string +--FILE-- +setPath("/foo/bar"); +$builder->setPath(""); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/path_success_first_segment_colon.phpt b/ext/uri/tests/rfc3986/builder/path_success_first_segment_colon.phpt new file mode 100644 index 000000000000..e1fc689ba2f9 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_success_first_segment_colon.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - success - contains a colon in the first segment when the scheme is present +--FILE-- +setScheme("https"); +$builder->setPath(":foo/bar/baz"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(%d) "https::foo/bar/baz" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(12) ":foo/bar/baz" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/path_success_leading_double_slash.phpt b/ext/uri/tests/rfc3986/builder/path_success_leading_double_slash.phpt new file mode 100644 index 000000000000..d00fc87b4400 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/path_success_leading_double_slash.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPath() - success - begins with double slashes when the URI contains a host +--FILE-- +setHost("example.com"); +$builder->setPath("//foo/bar/baz"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(26) "//example.com//foo/bar/baz" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(13) "//foo/bar/baz" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/port_error_missing_host.phpt b/ext/uri/tests/rfc3986/builder/port_error_missing_host.phpt new file mode 100644 index 000000000000..4b40e84c78f3 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/port_error_missing_host.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPort() - error - missing host +--FILE-- +setPort(443); + +try { + $builder->build(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: Cannot set a port without having a host diff --git a/ext/uri/tests/rfc3986/builder/port_error_negative.phpt b/ext/uri/tests/rfc3986/builder/port_error_negative.phpt new file mode 100644 index 000000000000..4cbc0e1c69d7 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/port_error_negative.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPort() - error - negative number +--FILE-- +setPort(-1); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified port is malformed diff --git a/ext/uri/tests/rfc3986/builder/port_success_large.phpt b/ext/uri/tests/rfc3986/builder/port_success_large.phpt new file mode 100644 index 000000000000..14d252a7d9c5 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/port_success_large.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPort() - success - large number +--FILE-- +setPort(PHP_INT_MAX); +$builder->setHost("example.com"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(%d) "//example.com:%d" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + int(%d) + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/port_success_null.phpt b/ext/uri/tests/rfc3986/builder/port_success_null.phpt new file mode 100644 index 000000000000..6c2ffaf7109a --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/port_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setPort() - success - null +--FILE-- +setPort(433); +$builder->setPort(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/query_error_special_char.phpt b/ext/uri/tests/rfc3986/builder/query_error_special_char.phpt new file mode 100644 index 000000000000..ecfced24a44c --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/query_error_special_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setQuery() - error - contains invalid special character +--FILE-- +setQuery("#foo"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified query is malformed diff --git a/ext/uri/tests/rfc3986/builder/query_error_unicode_char.phpt b/ext/uri/tests/rfc3986/builder/query_error_unicode_char.phpt new file mode 100644 index 000000000000..4c212cddd631 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/query_error_unicode_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setQuery() - error - contains Unicode character +--FILE-- +setQuery("főő"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified query is malformed diff --git a/ext/uri/tests/rfc3986/builder/query_success_basic.phpt b/ext/uri/tests/rfc3986/builder/query_success_basic.phpt new file mode 100644 index 000000000000..423b03b0b01d --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/query_success_basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setQuery() - success - basic +--FILE-- +setQuery("foo=1&bar=baz"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(14) "?foo=1&bar=baz" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + string(13) "foo=1&bar=baz" + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/query_success_null.phpt b/ext/uri/tests/rfc3986/builder/query_success_null.phpt new file mode 100644 index 000000000000..8e233c02c84b --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/query_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setQuery() - success - null +--FILE-- +setQuery("foo"); +$builder->setQuery(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/scheme_error_empty.phpt b/ext/uri/tests/rfc3986/builder/scheme_error_empty.phpt new file mode 100644 index 000000000000..13594c163363 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_error_empty.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - error - empty +--FILE-- +setScheme(""); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified scheme is malformed diff --git a/ext/uri/tests/rfc3986/builder/scheme_error_first_char.phpt b/ext/uri/tests/rfc3986/builder/scheme_error_first_char.phpt new file mode 100644 index 000000000000..c178a0fa1f1e --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_error_first_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - error - first character is not alpha +--FILE-- +setScheme("1"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified scheme is malformed diff --git a/ext/uri/tests/rfc3986/builder/scheme_error_special_char.phpt b/ext/uri/tests/rfc3986/builder/scheme_error_special_char.phpt new file mode 100644 index 000000000000..4941db44aa7d --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_error_special_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - error - contains invalid special character +--FILE-- +setScheme(":"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified scheme is malformed diff --git a/ext/uri/tests/rfc3986/builder/scheme_success_basic.phpt b/ext/uri/tests/rfc3986/builder/scheme_success_basic.phpt new file mode 100644 index 000000000000..279ecb273623 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_success_basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - success - basic +--FILE-- +setScheme("scheme"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(7) "scheme:" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(6) "scheme" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/scheme_success_null.phpt b/ext/uri/tests/rfc3986/builder/scheme_success_null.phpt new file mode 100644 index 000000000000..1a9510156b08 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - success - null +--FILE-- +setScheme("https"); +$builder->setScheme(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/scheme_success_special.phpt b/ext/uri/tests/rfc3986/builder/scheme_success_special.phpt new file mode 100644 index 000000000000..f387bc09f2e1 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/scheme_success_special.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setScheme() - success - contains digit & special characters +--FILE-- +setScheme("my-12+34.scheme"); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(16) "my-12+34.scheme:" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(15) "my-12+34.scheme" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/builder/userinfo_error_missing_host.phpt b/ext/uri/tests/rfc3986/builder/userinfo_error_missing_host.phpt new file mode 100644 index 000000000000..a6919e8ffd0a --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/userinfo_error_missing_host.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setUserInfo() - error - missing host +--FILE-- +setUserInfo("user:pass"); + +try { + $builder->build(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: Cannot set a userinfo without having a host diff --git a/ext/uri/tests/rfc3986/builder/userinfo_error_percent_encoding.phpt b/ext/uri/tests/rfc3986/builder/userinfo_error_percent_encoding.phpt new file mode 100644 index 000000000000..0830a57864d7 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/userinfo_error_percent_encoding.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setUserInfo() - error - invalid percent encoding +--FILE-- +setUserInfo("%3"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified userinfo is malformed diff --git a/ext/uri/tests/rfc3986/builder/userinfo_error_special_char.phpt b/ext/uri/tests/rfc3986/builder/userinfo_error_special_char.phpt new file mode 100644 index 000000000000..9d3fb2544daf --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/userinfo_error_special_char.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setUserInfo() - error - contains invalid special character +--FILE-- +setUserInfo("<>"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Uri\InvalidUriException: The specified userinfo is malformed diff --git a/ext/uri/tests/rfc3986/builder/userinfo_success_null.phpt b/ext/uri/tests/rfc3986/builder/userinfo_success_null.phpt new file mode 100644 index 000000000000..3decca97e791 --- /dev/null +++ b/ext/uri/tests/rfc3986/builder/userinfo_success_null.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test Uri\Rfc3986\UriBuilder::setUserInfo() - success - null +--FILE-- +setUserInfo("user:pass"); +$builder->setUserInfo(null); +$uri = $builder->build(); + +var_dump($uri->toRawString()); +var_dump($uri); +var_dump($uri->equals(new Uri\Rfc3986\Uri($uri->toRawString()))); + +?> +--EXPECTF-- +string(0) "" +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +bool(true) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt new file mode 100644 index 000000000000..0ac7ea3f7efd --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IP future +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPvFuture) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt new file mode 100644 index 000000000000..1c0c4448b953 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IPv4 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPv4) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt new file mode 100644 index 000000000000..5f3d826b412a --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IPv6 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPv6) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt new file mode 100644 index 000000000000..3a0e0205befe --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - none +--FILE-- +getHostType()); + +?> +--EXPECT-- +NULL diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt new file mode 100644 index 000000000000..31d4aca36c82 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - registered name +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::RegisteredName) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt new file mode 100644 index 000000000000..1cddc15fa33c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Absolute path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::AbsolutePathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt new file mode 100644 index 000000000000..d7debc5ba66c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Network path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::NetworkPathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt new file mode 100644 index 000000000000..6cb51405f925 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Relative path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::RelativePathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt new file mode 100644 index 000000000000..262300103f9c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt new file mode 100644 index 000000000000..ad8f2f27a8c6 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI with empty authority +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt new file mode 100644 index 000000000000..e266502ce90e --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI without authority +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/rfc3986/modification/fragment_error_reserved.phpt b/ext/uri/tests/rfc3986/modification/fragment_error_reserved.phpt index 1afde4151ac6..2296a797e662 100644 --- a/ext/uri/tests/rfc3986/modification/fragment_error_reserved.phpt +++ b/ext/uri/tests/rfc3986/modification/fragment_error_reserved.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\Rfc3986\Uri component modification - fragment - reserved characters ---EXTENSIONS-- -uri --FILE-- getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Domain) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt b/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt new file mode 100644 index 000000000000..41351350fb61 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - empty +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Empty) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt b/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt new file mode 100644 index 000000000000..f2f63caabb5e --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - IPv4 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::IPv4) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt b/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt new file mode 100644 index 000000000000..ce5bb00b93d5 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - IPv6 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::IPv6) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_none.phpt b/ext/uri/tests/whatwg/getters/host_type_success_none.phpt new file mode 100644 index 000000000000..07d54412a23c --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_none.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - none +--FILE-- +getHostType()); + +?> +--EXPECT-- +NULL diff --git a/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt b/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt new file mode 100644 index 000000000000..844cba82d512 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - opaque +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Opaque) diff --git a/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt b/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt new file mode 100644 index 000000000000..9bbb85755843 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url::isSpecialScheme() - success - not special +--FILE-- +isSpecialScheme()); + +?> +--EXPECT-- +bool(false) diff --git a/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt b/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt new file mode 100644 index 000000000000..1e19641b5600 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test Uri\WhatWg\Url::isSpecialScheme() - success - special +--FILE-- +isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("https://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("ws://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("wss://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("ftp://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("file://example.com"); +var_dump($url->isSpecialScheme()); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/uri/tests/whatwg/modification/fragment_success_auto_encode.phpt b/ext/uri/tests/whatwg/modification/fragment_success_auto_encode.phpt index ac74b8668cd2..7d178691fc01 100644 --- a/ext/uri/tests/whatwg/modification/fragment_success_auto_encode.phpt +++ b/ext/uri/tests/whatwg/modification/fragment_success_auto_encode.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - fragment - characters from the percent encode set ---EXTENSIONS-- -uri --FILE-- withScheme("\tscheme") + ->withHost("\tex.com") + ->withQuery("\refoo=bar") + ->withFragment("\nfoo"); + +try { + $url->withScheme("0"); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; + var_dump($e->errors); +} + +?> +--EXPECT-- +Uri\WhatWg\InvalidUrlException: The specified scheme is malformed +array(0) { +} diff --git a/ext/uri/tests/whatwg/modification/password_success_auto_encoded.phpt b/ext/uri/tests/whatwg/modification/password_success_auto_encoded.phpt index 5db68cb90a62..242c17430101 100644 --- a/ext/uri/tests/whatwg/modification/password_success_auto_encoded.phpt +++ b/ext/uri/tests/whatwg/modification/password_success_auto_encoded.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - password - characters from the percent encode set ---EXTENSIONS-- -uri --FILE-- withPassword("password"); + +var_dump($url1->getPassword()); +var_dump($url2->getPassword()); +var_dump($url2->toAsciiString()); + +?> +--EXPECT-- +NULL +NULL +string(9) "scheme://" diff --git a/ext/uri/tests/whatwg/modification/password_success_encoded.phpt b/ext/uri/tests/whatwg/modification/password_success_encoded.phpt index 82b172d914af..b7f2f5485241 100644 --- a/ext/uri/tests/whatwg/modification/password_success_encoded.phpt +++ b/ext/uri/tests/whatwg/modification/password_success_encoded.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - password - URL encoded characters ---EXTENSIONS-- -uri --FILE-- toAsciiString()); ?> --EXPECT-- string(1) "/" -string(8) "/p^th%23" -string(27) "https://example.com/p^th%23" +string(10) "/p%5Eth%23" +string(29) "https://example.com/p%5Eth%23" diff --git a/ext/uri/tests/whatwg/modification/path_success_empty.phpt b/ext/uri/tests/whatwg/modification/path_success_empty.phpt index 9e8d3495445a..e17856f26dbc 100644 --- a/ext/uri/tests/whatwg/modification/path_success_empty.phpt +++ b/ext/uri/tests/whatwg/modification/path_success_empty.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - path - empty string ---EXTENSIONS-- -uri --FILE-- withPort(433); + +var_dump($url1->getPort()); +var_dump($url2->getPort()); +var_dump($url2->toAsciiString()); + +?> +--EXPECT-- +NULL +NULL +string(9) "scheme://" diff --git a/ext/uri/tests/whatwg/modification/port_success_existing.phpt b/ext/uri/tests/whatwg/modification/port_success_existing.phpt index e5ea806bd1a4..f84e0a9c2de2 100644 --- a/ext/uri/tests/whatwg/modification/port_success_existing.phpt +++ b/ext/uri/tests/whatwg/modification/port_success_existing.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - port - changing an existing one ---EXTENSIONS-- -uri --FILE-- withUsername("user"); + +var_dump($url1->getUsername()); +var_dump($url2->getUsername()); +var_dump($url2->toAsciiString()); + +?> +--EXPECT-- +NULL +NULL +string(9) "scheme://" diff --git a/ext/uri/tests/whatwg/modification/username_success_existing.phpt b/ext/uri/tests/whatwg/modification/username_success_existing.phpt index 2506acf85d71..a0a1e5ffad95 100644 --- a/ext/uri/tests/whatwg/modification/username_success_existing.phpt +++ b/ext/uri/tests/whatwg/modification/username_success_existing.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url component modification - username - changing existing ---EXTENSIONS-- -uri --FILE-- --EXPECT-- -Uri\WhatWg\InvalidUrlException: The specified URI is malformed +Uri\WhatWg\InvalidUrlException: The specified URI is malformed (HostMissing) diff --git a/ext/uri/tests/whatwg/parsing/path_success_percent_encode_set2.phpt b/ext/uri/tests/whatwg/parsing/path_success_percent_encode_set2.phpt index 9419c817fbbd..dd82beeff101 100644 --- a/ext/uri/tests/whatwg/parsing/path_success_percent_encode_set2.phpt +++ b/ext/uri/tests/whatwg/parsing/path_success_percent_encode_set2.phpt @@ -22,10 +22,10 @@ object(Uri\WhatWg\Url)#%d (%d) { ["port"]=> NULL ["path"]=> - string(28) "/foo%22/%3Cbar%3E/^%7Bbaz%7D" + string(30) "/foo%22/%3Cbar%3E/%5E%7Bbaz%7D" ["query"]=> NULL ["fragment"]=> NULL } -string(47) "https://example.com/foo%22/%3Cbar%3E/^%7Bbaz%7D" +string(49) "https://example.com/foo%22/%3Cbar%3E/%5E%7Bbaz%7D" diff --git a/ext/uri/tests/whatwg/reference_resolution/resolve_error_host_null_byte.phpt b/ext/uri/tests/whatwg/reference_resolution/resolve_error_host_null_byte.phpt index ed31e0e5daea..15b2a141f2fd 100644 --- a/ext/uri/tests/whatwg/reference_resolution/resolve_error_host_null_byte.phpt +++ b/ext/uri/tests/whatwg/reference_resolution/resolve_error_host_null_byte.phpt @@ -1,7 +1,5 @@ --TEST-- Test Uri\WhatWg\Url reference resolution - resolve() - null byte ---EXTENSIONS-- -uri --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | | Tim Düsterhus | @@ -34,7 +32,7 @@ static zend_string *decode_component(zend_string *in, php_uri_component_read_mod return out; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } diff --git a/ext/uri/uri_parser_php_parse_url.h b/ext/uri/uri_parser_php_parse_url.h index 6cf532db8352..2dd2660fe153 100644 --- a/ext/uri/uri_parser_php_parse_url.h +++ b/ext/uri/uri_parser_php_parse_url.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | | Tim Düsterhus | diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index a047c63a708d..f4f5f2bf5bd9 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -17,6 +15,7 @@ #include "php.h" #include "uri_parser_rfc3986.h" #include "php_uri_common.h" +#include "Zend/zend_enum.h" #include "Zend/zend_smart_str.h" #include "Zend/zend_exceptions.h" @@ -25,6 +24,7 @@ struct php_uri_parser_rfc3986_uris { UriUriA uri; UriUriA normalized_uri; + unsigned int normalization_mask; bool normalized_uri_initialized; }; @@ -85,16 +85,25 @@ ZEND_ATTRIBUTE_NONNULL static void copy_uri(UriUriA *new_uriparser_uri, const Ur ZEND_ATTRIBUTE_NONNULL static UriUriA *get_normalized_uri(php_uri_parser_rfc3986_uris *uriparser_uris) { if (!uriparser_uris->normalized_uri_initialized) { - copy_uri(&uriparser_uris->normalized_uri, &uriparser_uris->uri); - int result = uriNormalizeSyntaxExMmA(&uriparser_uris->normalized_uri, (unsigned int)-1, mm); - ZEND_ASSERT(result == URI_SUCCESS); + int mask_result = uriNormalizeSyntaxMaskRequiredExA(&uriparser_uris->uri, &uriparser_uris->normalization_mask); + ZEND_ASSERT(mask_result == URI_SUCCESS); + + if (uriparser_uris->normalization_mask != URI_NORMALIZED) { + copy_uri(&uriparser_uris->normalized_uri, &uriparser_uris->uri); + int result = uriNormalizeSyntaxExMmA(&uriparser_uris->normalized_uri, uriparser_uris->normalization_mask, mm); + ZEND_ASSERT(result == URI_SUCCESS); + } uriparser_uris->normalized_uri_initialized = true; } + if (uriparser_uris->normalization_mask == URI_NORMALIZED) { + return &uriparser_uris->uri; + } + return &uriparser_uris->normalized_uri; } -ZEND_ATTRIBUTE_NONNULL static UriUriA *get_uri_for_reading(php_uri_parser_rfc3986_uris *uriparser_uris, php_uri_component_read_mode read_mode) +ZEND_ATTRIBUTE_NONNULL static UriUriA *get_uri_for_reading(php_uri_parser_rfc3986_uris *uriparser_uris, const php_uri_component_read_mode read_mode) { switch (read_mode) { case PHP_URI_COMPONENT_READ_MODE_RAW: @@ -103,7 +112,7 @@ ZEND_ATTRIBUTE_NONNULL static UriUriA *get_uri_for_reading(php_uri_parser_rfc398 ZEND_FALLTHROUGH; case PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: return get_normalized_uri(uriparser_uris); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -112,7 +121,26 @@ ZEND_ATTRIBUTE_NONNULL static UriUriA *get_uri_for_writing(php_uri_parser_rfc398 return &uriparser_uris->uri; } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_scheme_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_uri_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval) +{ + const UriUriA *uriparser_uri = get_uri_for_reading(uri, PHP_URI_COMPONENT_READ_MODE_RAW); + + zend_object *value; + + if (has_text_range(&uriparser_uri->scheme)) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_type, ZEND_ENUM_Uri_Rfc3986_UriType_Uri); + } else if (has_text_range(&uriparser_uri->hostText)) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_type, ZEND_ENUM_Uri_Rfc3986_UriType_NetworkPathReference); + } else if (uriparser_uri->absolutePath) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_type, ZEND_ENUM_Uri_Rfc3986_UriType_AbsolutePathReference); + } else { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_type, ZEND_ENUM_Uri_Rfc3986_UriType_RelativePathReference); + } + + ZVAL_OBJ_COPY(retval, value); +} + +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_scheme_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -125,7 +153,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_scheme_read(voi return SUCCESS; } -static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -149,7 +177,7 @@ static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, zval *value, z } } -ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_parser_rfc3986_uris *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_parser_rfc3986_uris *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -162,7 +190,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_ return SUCCESS; } -zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, zval *value, zval *errors) +zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -189,7 +217,7 @@ zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *u } } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_username_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_username_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -211,7 +239,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_username_read(v return SUCCESS; } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_password_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_password_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -230,20 +258,19 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_password_read(v return SUCCESS; } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); if (has_text_range(&uriparser_uri->hostText)) { 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)); + zend_string *host_str = zend_string_concat3( + "[", 1, + uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText), + "]", 1 + ); + ZVAL_NEW_STR(retval, host_str); } else { ZVAL_STRINGL(retval, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); } @@ -254,7 +281,31 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void return SUCCESS; } -static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zval *errors) +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_host_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval) +{ + const UriUriA *uriparser_uri = get_uri_for_reading(uri, PHP_URI_COMPONENT_READ_MODE_RAW); + + if (!has_text_range(&uriparser_uri->hostText)) { + ZVAL_NULL(retval); + return; + } + + zend_object *value; + + if (uriparser_uri->hostData.ip4 != NULL) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_host_type, ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv4); + } else if (uriparser_uri->hostData.ip6 != NULL) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_host_type, ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv6); + } else if (has_text_range(&uriparser_uri->hostData.ipFuture)) { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_host_type, ZEND_ENUM_Uri_Rfc3986_UriHostType_IPvFuture); + } else { + value = zend_enum_get_case_by_id(php_uri_ce_rfc3986_uri_host_type, ZEND_ENUM_Uri_Rfc3986_UriHostType_RegisteredName); + } + + ZVAL_OBJ_COPY(retval, value); +} + +static zend_result php_uri_parser_rfc3986_host_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -284,7 +335,7 @@ static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zva } } -ZEND_ATTRIBUTE_NONNULL static zend_long port_str_to_zend_long_checked(const char *str, size_t len) +ZEND_ATTRIBUTE_NONNULL static zend_long port_str_to_zend_long_checked(const char *str, const size_t len) { if (len > MAX_LENGTH_OF_LONG) { return -1; @@ -302,7 +353,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_long port_str_to_zend_long_checked(const char return (zend_long)result; } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_port_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_port_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -315,7 +366,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_port_read(void return SUCCESS; } -static zend_result php_uri_parser_rfc3986_port_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_rfc3986_port_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -344,25 +395,41 @@ static zend_result php_uri_parser_rfc3986_port_write(void *uri, zval *value, zva } } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); if (uriparser_uri->pathHead != NULL) { - smart_str str = {0}; + size_t total_len = 0; + const bool need_leading_slash = uriparser_uri->absolutePath || uriHasHostA(uriparser_uri); + + if (need_leading_slash) { + total_len++; + } + + for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { + total_len += get_text_range_length(&p->text); + if (p->next) { + total_len++; + } + } + + zend_string *str = zend_string_alloc(total_len, false); + char *out = ZSTR_VAL(str); - if (uriparser_uri->absolutePath || uriHasHostA(uriparser_uri)) { - smart_str_appendc(&str, '/'); + if (need_leading_slash) { + *(out++) = '/'; } for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { - smart_str_appendl(&str, p->text.first, get_text_range_length(&p->text)); + out = zend_mempcpy(out, p->text.first, get_text_range_length(&p->text)); if (p->next) { - smart_str_appendc(&str, '/'); + *(out++) = '/'; } } - ZVAL_NEW_STR(retval, smart_str_extract(&str)); + *out = '\0'; + ZVAL_NEW_STR(retval, str); } else if (uriparser_uri->absolutePath) { ZVAL_CHAR(retval, '/'); } else { @@ -372,7 +439,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void return SUCCESS; } -static zend_result php_uri_parser_rfc3986_path_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_rfc3986_path_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -396,7 +463,7 @@ static zend_result php_uri_parser_rfc3986_path_write(void *uri, zval *value, zva } } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_query_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_query_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -409,7 +476,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_query_read(void return SUCCESS; } -static zend_result php_uri_parser_rfc3986_query_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_rfc3986_query_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -433,7 +500,7 @@ static zend_result php_uri_parser_rfc3986_query_write(void *uri, zval *value, zv } } -ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_fragment_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_fragment_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); @@ -446,7 +513,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_fragment_read(v return SUCCESS; } -static zend_result php_uri_parser_rfc3986_fragment_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_rfc3986_fragment_write(void *uri, const zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); int result; @@ -478,12 +545,35 @@ static php_uri_parser_rfc3986_uris *uriparser_create_uris(void) return uriparser_uris; } -php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str, size_t uri_str_len, const php_uri_parser_rfc3986_uris *uriparser_base_urls, bool silent) +static zend_result php_uri_parser_rfc3986_add_base_url( + UriUriA *tmp, const UriUriA *uri, const php_uri_parser_rfc3986_uris *uriparser_base_urls, const bool silent +) { + const int result = uriAddBaseUriExMmA(tmp, uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm); + if (result != URI_SUCCESS) { + if (!silent) { + switch (result) { + case URI_ERROR_ADDBASE_REL_BASE: + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified base URI must be absolute", 0); + break; + default: + /* This should be unreachable in practice. */ + zend_throw_exception(php_uri_ce_error, "Failed to resolve the specified URI against the base URI", 0); + break; + } + } + + return FAILURE; + } + + return SUCCESS; +} + +php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str, const size_t uri_str_len, const php_uri_parser_rfc3986_uris *uriparser_base_urls, const bool silent) { UriUriA uri = {0}; /* Parse the URI. */ - int result = uriParseSingleUriExMmA(&uri, uri_str, uri_str + uri_str_len, NULL, mm); + const int result = uriParseSingleUriExMmA(&uri, uri_str, uri_str + uri_str_len, NULL, mm); if (result != URI_SUCCESS) { if (!silent) { switch (result) { @@ -505,20 +595,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str /* Combine the parsed URI with the base URI and store the result in 'tmp', * since the target and source URLs must be distinct. */ - int result = uriAddBaseUriExMmA(&tmp, &uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm); - if (result != URI_SUCCESS) { - if (!silent) { - switch (result) { - case URI_ERROR_ADDBASE_REL_BASE: - zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified base URI must be absolute", 0); - break; - default: - /* This should be unreachable in practice. */ - zend_throw_exception(php_uri_ce_error, "Failed to resolve the specified URI against the base URI", 0); - break; - } - } - + if (php_uri_parser_rfc3986_add_base_url(&tmp, &uri, uriparser_base_urls, silent) == FAILURE) { goto fail; } @@ -552,7 +629,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str return NULL; } -void *php_uri_parser_rfc3986_parse(const char *uri_str, size_t uri_str_len, const void *base_url, zval *errors, bool silent) +static void *php_uri_parser_rfc3986_parse(const char *uri_str, const size_t uri_str_len, const void *base_url, zval *errors, bool silent) { return php_uri_parser_rfc3986_parse_ex(uri_str, uri_str_len, base_url, silent); } @@ -570,7 +647,7 @@ ZEND_ATTRIBUTE_NONNULL static void *php_uri_parser_rfc3986_clone(void *uri) return new_uriparser_uris; } -ZEND_ATTRIBUTE_NONNULL static zend_string *php_uri_parser_rfc3986_to_string(void *uri, php_uri_recomposition_mode recomposition_mode, bool exclude_fragment) +ZEND_ATTRIBUTE_NONNULL static zend_string *php_uri_parser_rfc3986_to_string(void *uri, const php_uri_recomposition_mode recomposition_mode, const bool exclude_fragment) { php_uri_parser_rfc3986_uris *uriparser_uris = uri; const UriUriA *uriparser_uri; @@ -616,6 +693,189 @@ static void php_uri_parser_rfc3986_destroy(void *uri) efree(uriparser_uris); } +static zend_always_inline zend_result php_uri_parser_rfc3986_validate_component_result(const bool well_formed, const char *component_name) +{ + if (well_formed) { + return SUCCESS; + } + + zend_throw_exception_ex(php_uri_ce_invalid_uri_exception, 0, "The specified %s is malformed", component_name); + return FAILURE; +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_scheme(const zend_string *scheme) +{ + const char *p = ZSTR_VAL(scheme); + const size_t len = ZSTR_LEN(scheme); + const bool well_formed = uriIsWellFormedSchemeA(p, p + len) == URI_TRUE; + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "scheme"); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_userinfo(const zend_string *userinfo) +{ + const char *p = ZSTR_VAL(userinfo); + const size_t len = ZSTR_LEN(userinfo); + const bool well_formed = uriIsWellFormedUserInfoA(p, p + len) == URI_TRUE; + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "userinfo"); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_host(const zend_string *host) +{ + const char *p = ZSTR_VAL(host); + const size_t len = ZSTR_LEN(host); + + if (len == 0) { + return SUCCESS; + } + + if (p[0] == '[') { + if (p[len - 1] != ']') { + return php_uri_parser_rfc3986_validate_component_result(false, "host"); + } + + if (len >= 2 && (p[1] == 'v' || p[1] == 'V')) { + return php_uri_parser_rfc3986_validate_component_result( + uriIsWellFormedHostIpFutureMmA(p + 1, p + len - 1, mm) == URI_SUCCESS, + "host" + ); + } + + return php_uri_parser_rfc3986_validate_component_result( + uriIsWellFormedHostIp6MmA(p + 1, p + len - 1, mm) == URI_SUCCESS, + "host" + ); + } + + if (uriIsWellFormedHostIp4A(p, p + len) == URI_TRUE) { + return SUCCESS; + } + + return php_uri_parser_rfc3986_validate_component_result( + uriIsWellFormedHostRegNameA(p, p + len) == URI_TRUE, + "host" + ); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_port(const zend_long port) +{ + char buf[MAX_LENGTH_OF_LONG + 1]; + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, port); + + const bool well_formed = uriIsWellFormedPortA(res, res + strlen(res)); + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "port"); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_path(const zend_string *path) +{ + const char *p = ZSTR_VAL(path); + const size_t len = ZSTR_LEN(path); + /* The build() method checks whether the path begins with a "/" when there's a host. + * In order to skip doing the same check, a false hasHost argument is passed to uriIsWellFormedPathA(). */ + const bool well_formed = uriIsWellFormedPathA(p, p + len, /* hasHost */ false); + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "path"); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_query(const zend_string *query) +{ + const char *p = ZSTR_VAL(query); + const size_t len = ZSTR_LEN(query); + const bool well_formed = uriIsWellFormedQueryA(p, p + len); + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "query"); +} + +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_fragment(const zend_string *fragment) +{ + const char *p = ZSTR_VAL(fragment); + const size_t len = ZSTR_LEN(fragment); + const bool well_formed = uriIsWellFormedFragmentA(p, p + len); + + return php_uri_parser_rfc3986_validate_component_result(well_formed, "fragment"); +} + +ZEND_ATTRIBUTE_NONNULL_ARGS(2,3,4,5,6,7,8) php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_build_from_zval( + const php_uri_parser_rfc3986_uris *uriparser_base_uris, + const zval *scheme, const zval *userinfo, const zval *host, const zval *port, + const zval *path, const zval *query, const zval *fragment +) { + php_uri_parser_rfc3986_uris *uriparser_uris = uriparser_create_uris(); + + if (Z_STRLEN_P(path) > 0) { + /* The first segment of the path must not contain ":" if the URI does not contain a scheme */ + if (Z_TYPE_P(scheme) == IS_NULL) { + const char *p = Z_STRVAL_P(path); + while (*p != '\0' && *p != '/') { + if (*p == ':') { + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The path must not begin with \":\" when the URI does not contain a scheme", 0); + goto failure; + } + + p++; + } + } + + /* The path must not begin with "//" if the URI does not contain a host */ + if (Z_TYPE_P(host) == IS_NULL && zend_string_starts_with_literal(Z_STR_P(path), "//")) { + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The path must not begin with \"//\" when the URI does not contain a host", 0); + goto failure; + } + } + + zend_result result = php_uri_parser_rfc3986_scheme_write(uriparser_uris, scheme, NULL); + if (result == FAILURE) { + goto failure; + } + result = php_uri_parser_rfc3986_host_write(uriparser_uris, host, NULL); + if (result == FAILURE) { + goto failure; + } + /* Intentionally writing userinfo after host to avoid error when the userinfo is set but the host is missing */ + result = php_uri_parser_rfc3986_userinfo_write(uriparser_uris, userinfo, NULL); + if (result == FAILURE) { + goto failure; + } + /* Intentionally writing userinfo after host to avoid error when the port is set but the host is missing */ + result = php_uri_parser_rfc3986_port_write(uriparser_uris, port, NULL); + if (result == FAILURE) { + goto failure; + } + result = php_uri_parser_rfc3986_path_write(uriparser_uris, path, NULL); + if (result == FAILURE) { + goto failure; + } + result = php_uri_parser_rfc3986_query_write(uriparser_uris, query, NULL); + if (result == FAILURE) { + goto failure; + } + result = php_uri_parser_rfc3986_fragment_write(uriparser_uris, fragment, NULL); + if (result == FAILURE) { + goto failure; + } + + if (uriparser_base_uris != NULL) { + UriUriA tmp = {0}; + + if (php_uri_parser_rfc3986_add_base_url(&tmp, &uriparser_uris->uri, uriparser_base_uris, false) == FAILURE) { + goto failure; + } + + uriMakeOwnerMmA(&tmp, mm); + uriFreeUriMembersMmA(&uriparser_uris->uri, mm); + uriparser_uris->uri = tmp; + } + + return uriparser_uris; + +failure: + uriFreeUriMembersMmA(&uriparser_uris->uri, mm); + efree(uriparser_uris); + return NULL; +} + PHPAPI const php_uri_parser php_uri_parser_rfc3986 = { .name = PHP_URI_PARSER_RFC3986, .parse = php_uri_parser_rfc3986_parse, diff --git a/ext/uri/uri_parser_rfc3986.h b/ext/uri/uri_parser_rfc3986.h index 4d88478b6063..9a9f0b38a0c4 100644 --- a/ext/uri/uri_parser_rfc3986.h +++ b/ext/uri/uri_parser_rfc3986.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -23,9 +21,26 @@ PHPAPI extern const php_uri_parser php_uri_parser_rfc3986; typedef struct php_uri_parser_rfc3986_uris php_uri_parser_rfc3986_uris; +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_uri_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval); +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_host_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval); + zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_parser_rfc3986_uris *uri, php_uri_component_read_mode read_mode, zval *retval); -zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, zval *value, zval *errors); +zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, const zval *value, zval *errors); php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str, size_t uri_str_len, const php_uri_parser_rfc3986_uris *uriparser_base_url, bool silent); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_scheme(const zend_string *scheme); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_userinfo(const zend_string *userinfo); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_host(const zend_string *host); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_port(zend_long port); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_path(const zend_string *path); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_query(const zend_string *query); +ZEND_ATTRIBUTE_NONNULL zend_result php_uri_parser_rfc3986_validate_fragment(const zend_string *fragment); + +ZEND_ATTRIBUTE_NONNULL_ARGS(2,3,4,5,6,7,8) php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_build_from_zval( + const php_uri_parser_rfc3986_uris *uriparser_base_uris, + const zval *scheme, const zval *userinfo, const zval *host, const zval *port, + const zval *path, const zval *query, const zval *fragment +); + #endif diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c index 055f130af7c6..6d46feb51aae 100644 --- a/ext/uri/uri_parser_whatwg.c +++ b/ext/uri/uri_parser_whatwg.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -30,7 +28,7 @@ ZEND_TLS lxb_unicode_idna_t lexbor_idna = {0}; static const size_t lexbor_mraw_byte_size = 8192; -static zend_always_inline void zval_string_or_null_to_lexbor_str(zval *value, lexbor_str_t *lexbor_str) +static zend_always_inline void zval_string_or_null_to_lexbor_str(const zval *value, lexbor_str_t *lexbor_str) { if (Z_TYPE_P(value) == IS_STRING && Z_STRLEN_P(value) > 0) { lexbor_str->data = (lxb_char_t *) Z_STRVAL_P(value); @@ -42,12 +40,12 @@ static zend_always_inline void zval_string_or_null_to_lexbor_str(zval *value, le } } -static zend_always_inline void zval_long_or_null_to_lexbor_str(zval *value, lexbor_str_t *lexbor_str) +static zend_always_inline void zval_long_or_null_to_lexbor_str(const zval *value, lexbor_str_t *lexbor_str) { if (Z_TYPE_P(value) == IS_LONG) { - ZVAL_STR(value, zend_long_to_str(Z_LVAL_P(value))); - lexbor_str_init_append(lexbor_str, lexbor_parser.mraw, (const lxb_char_t *) Z_STRVAL_P(value), Z_STRLEN_P(value)); - zval_ptr_dtor_str(value); + char buf[MAX_LENGTH_OF_LONG + 1]; + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, Z_LVAL_P(value)); + lexbor_str_init_append(lexbor_str, lexbor_parser.mraw, (const lxb_char_t *) res, strlen(res)); } else { ZEND_ASSERT(Z_ISNULL_P(value)); lexbor_str->data = (lxb_char_t *) ""; @@ -62,12 +60,13 @@ static zend_always_inline void zval_long_or_null_to_lexbor_str(zval *value, lexb */ static const char *fill_errors(zval *errors) { - if (lexbor_parser.log == NULL || lexbor_plog_length(lexbor_parser.log) == 0) { + size_t log_len; + if (lexbor_parser.log == NULL || (log_len = lexbor_plog_length(lexbor_parser.log)) == 0) { ZVAL_EMPTY_ARRAY(errors); return NULL; } - array_init(errors); + array_init_size(errors, log_len); const char *result = NULL; lexbor_plog_entry_t *lxb_error; @@ -195,7 +194,7 @@ static const char *fill_errors(zval *errors) error_str = "FileInvalidWindowsDriveLetterHost"; ZVAL_FALSE(&failure); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } zval error_type; @@ -236,7 +235,7 @@ static void throw_invalid_url_exception_during_write(zval *errors, const char *c } } -static lxb_status_t serialize_to_smart_str_callback(const lxb_char_t *data, size_t length, void *ctx) +static lxb_status_t serialize_to_smart_str_callback(const lxb_char_t *data, const size_t length, void *ctx) { smart_str *uri_str = ctx; @@ -247,7 +246,7 @@ static lxb_status_t serialize_to_smart_str_callback(const lxb_char_t *data, size return LXB_STATUS_OK; } -static zend_result php_uri_parser_whatwg_scheme_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_scheme_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -258,13 +257,15 @@ static zend_result php_uri_parser_whatwg_scheme_read(void *uri, php_uri_componen return SUCCESS; } -static zend_result php_uri_parser_whatwg_scheme_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_scheme_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_protocol_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "scheme"); @@ -274,6 +275,11 @@ static zend_result php_uri_parser_whatwg_scheme_write(void *uri, zval *value, zv return SUCCESS; } +ZEND_ATTRIBUTE_NONNULL bool php_uri_parser_whatwg_is_special(const lxb_url_t *lexbor_uri) +{ + return lxb_url_is_special(lexbor_uri); +} + /* 4.2. URL miscellaneous: A URL includes credentials if its username or password is not the empty string. */ static bool includes_credentials(const lxb_url_t *lexbor_uri) { @@ -293,13 +299,15 @@ static zend_result php_uri_parser_whatwg_username_read(void *uri, php_uri_compon return SUCCESS; } -static zend_result php_uri_parser_whatwg_username_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_username_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_username_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "username"); @@ -322,13 +330,15 @@ static zend_result php_uri_parser_whatwg_password_read(void *uri, php_uri_compon return SUCCESS; } -static zend_result php_uri_parser_whatwg_password_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_password_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_password_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "password"); @@ -338,7 +348,7 @@ static zend_result php_uri_parser_whatwg_password_write(void *uri, zval *value, return SUCCESS; } -static zend_result php_uri_parser_whatwg_host_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_host_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -373,7 +383,7 @@ static zend_result php_uri_parser_whatwg_host_read(void *uri, php_uri_component_ case PHP_URI_COMPONENT_READ_MODE_RAW: ZVAL_STRINGL(retval, (const char *) lexbor_uri->host.u.domain.data, lexbor_uri->host.u.domain.length); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } else { ZVAL_NULL(retval); @@ -382,13 +392,40 @@ static zend_result php_uri_parser_whatwg_host_read(void *uri, php_uri_component_ return SUCCESS; } -static zend_result php_uri_parser_whatwg_host_write(void *uri, zval *value, zval *errors) +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_whatwg_host_type_read(const lxb_url_t *lexbor_uri, zval *retval) +{ + switch (lexbor_uri->host.type) { + case LXB_URL_HOST_TYPE_IPV4: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "IPv4")); + return; + case LXB_URL_HOST_TYPE_IPV6: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "IPv6")); + return; + case LXB_URL_HOST_TYPE_DOMAIN: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Domain")); + return; + case LXB_URL_HOST_TYPE_EMPTY: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Empty")); + return; + case LXB_URL_HOST_TYPE_OPAQUE: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Opaque")); + return; + case LXB_URL_HOST_TYPE__UNDEF: + ZVAL_NULL(retval); + return; + default: ZEND_UNREACHABLE(); + } +} + +static zend_result php_uri_parser_whatwg_host_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_hostname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "host"); @@ -398,7 +435,7 @@ static zend_result php_uri_parser_whatwg_host_write(void *uri, zval *value, zval return SUCCESS; } -static zend_result php_uri_parser_whatwg_port_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_port_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -411,13 +448,15 @@ static zend_result php_uri_parser_whatwg_port_read(void *uri, php_uri_component_ return SUCCESS; } -static zend_result php_uri_parser_whatwg_port_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_port_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_long_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_port_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "port"); @@ -427,7 +466,7 @@ static zend_result php_uri_parser_whatwg_port_write(void *uri, zval *value, zval return SUCCESS; } -static zend_result php_uri_parser_whatwg_path_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_path_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -440,13 +479,15 @@ static zend_result php_uri_parser_whatwg_path_read(void *uri, php_uri_component_ return SUCCESS; } -static zend_result php_uri_parser_whatwg_path_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_path_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_pathname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "path"); @@ -456,7 +497,7 @@ static zend_result php_uri_parser_whatwg_path_write(void *uri, zval *value, zval return SUCCESS; } -static zend_result php_uri_parser_whatwg_query_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_query_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -469,13 +510,15 @@ static zend_result php_uri_parser_whatwg_query_read(void *uri, php_uri_component return SUCCESS; } -static zend_result php_uri_parser_whatwg_query_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_query_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_search_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "query string"); @@ -485,7 +528,7 @@ static zend_result php_uri_parser_whatwg_query_write(void *uri, zval *value, zva return SUCCESS; } -static zend_result php_uri_parser_whatwg_fragment_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) +static zend_result php_uri_parser_whatwg_fragment_read(void *uri, const php_uri_component_read_mode read_mode, zval *retval) { const lxb_url_t *lexbor_uri = uri; @@ -498,13 +541,15 @@ static zend_result php_uri_parser_whatwg_fragment_read(void *uri, php_uri_compon return SUCCESS; } -static zend_result php_uri_parser_whatwg_fragment_write(void *uri, zval *value, zval *errors) +static zend_result php_uri_parser_whatwg_fragment_write(void *uri, const zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; lexbor_str_t str = {0}; zval_string_or_null_to_lexbor_str(value, &str); + lxb_url_parser_clean(&lexbor_parser); + if (lxb_url_api_hash_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { throw_invalid_url_exception_during_write(errors, "fragment"); @@ -561,7 +606,7 @@ ZEND_MODULE_POST_ZEND_DEACTIVATE_D(uri_parser_whatwg) return SUCCESS; } -lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, bool silent) +lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, const size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, const bool silent) { lxb_url_parser_clean(&lexbor_parser); @@ -585,7 +630,7 @@ lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_le return url; } -static void *php_uri_parser_whatwg_parse(const char *uri_str, size_t uri_str_len, const void *base_url, zval *errors, bool silent) +static void *php_uri_parser_whatwg_parse(const char *uri_str, const size_t uri_str_len, const void *base_url, zval *errors, const bool silent) { return php_uri_parser_whatwg_parse_ex(uri_str, uri_str_len, base_url, errors, silent); } @@ -597,7 +642,7 @@ static void *php_uri_parser_whatwg_clone(void *uri) return lxb_url_clone(lexbor_parser.mraw, lexbor_uri); } -static zend_string *php_uri_parser_whatwg_to_string(void *uri, php_uri_recomposition_mode recomposition_mode, bool exclude_fragment) +static zend_string *php_uri_parser_whatwg_to_string(void *uri, const php_uri_recomposition_mode recomposition_mode, const bool exclude_fragment) { const lxb_url_t *lexbor_uri = uri; smart_str uri_str = {0}; @@ -614,7 +659,7 @@ static zend_string *php_uri_parser_whatwg_to_string(void *uri, php_uri_recomposi case PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII: lxb_url_serialize(lexbor_uri, serialize_to_smart_str_callback, &uri_str, exclude_fragment); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return smart_str_extract(&uri_str); diff --git a/ext/uri/uri_parser_whatwg.h b/ext/uri/uri_parser_whatwg.h index e8bbb585fd66..f714ee483680 100644 --- a/ext/uri/uri_parser_whatwg.h +++ b/ext/uri/uri_parser_whatwg.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -22,6 +20,9 @@ PHPAPI extern const php_uri_parser php_uri_parser_whatwg; +ZEND_ATTRIBUTE_NONNULL bool php_uri_parser_whatwg_is_special(const lxb_url_t *lexbor_uri); +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_whatwg_host_type_read(const lxb_url_t *lexbor_uri, zval *retval); + lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, bool silent); PHP_RINIT_FUNCTION(uri_parser_whatwg); diff --git a/ext/uri/uriparser/include/uriparser/Uri.h b/ext/uri/uriparser/include/uriparser/Uri.h index 88976a484627..ddbbd26f9e44 100644 --- a/ext/uri/uriparser/include/uriparser/Uri.h +++ b/ext/uri/uriparser/include/uriparser/Uri.h @@ -1,4 +1,4 @@ -/* 5abed1007be99942f49ffe603a894d277066b79b9cb824547af0f3b9481cb9ca (1.0.0+) +/* c9d94656d067288e474df19a062d487c736b0fa8517d2ef7bbeb8dcd5a70c05b (1.0.2+) * * uriparser - RFC 3986 URI parsing library * diff --git a/ext/uri/uriparser/include/uriparser/UriBase.h b/ext/uri/uriparser/include/uriparser/UriBase.h index 3a9a868e3bb1..1cc91ceab772 100644 --- a/ext/uri/uriparser/include/uriparser/UriBase.h +++ b/ext/uri/uriparser/include/uriparser/UriBase.h @@ -52,7 +52,7 @@ /* Version */ # define URI_VER_MAJOR 1 # define URI_VER_MINOR 0 -# define URI_VER_RELEASE 0 +# define URI_VER_RELEASE 2 # define URI_VER_SUFFIX_ANSI "" # define URI_VER_SUFFIX_UNICODE URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI) diff --git a/ext/uri/uriparser/src/UriCommon.c b/ext/uri/uriparser/src/UriCommon.c index 3644e8828f35..e9a6992b01c2 100644 --- a/ext/uri/uriparser/src/UriCommon.c +++ b/ext/uri/uriparser/src/UriCommon.c @@ -66,6 +66,8 @@ # endif # include +# include +# include // SIZE_MAX /*extern*/ const URI_CHAR * const URI_FUNC(SafeToPointTo) = _UT("X"); /*extern*/ const URI_CHAR * const URI_FUNC(ConstPwd) = _UT("."); @@ -104,42 +106,35 @@ int URI_FUNC(FreeUriPath)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { } /* Compares two text ranges for equal text content */ -int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b) { - int diff; - +bool URI_FUNC(RangeEquals)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b) { /* NOTE: Both NULL means equal! */ if ((a == NULL) || (b == NULL)) { - return ((a == NULL) ? 0 : 1) - ((b == NULL) ? 0 : 1); + return a == b; } /* NOTE: Both NULL means equal! */ if ((a->first == NULL) || (b->first == NULL)) { - return ((a->first == NULL) ? 0 : 1) - ((b->first == NULL) ? 0 : 1); - } - - diff = ((int)(a->afterLast - a->first) - (int)(b->afterLast - b->first)); - if (diff > 0) { - return 1; - } else if (diff < 0) { - return -1; + return a->first == b->first; } - diff = URI_STRNCMP(a->first, b->first, (a->afterLast - a->first)); + const size_t lenA = a->afterLast - a->first; + const size_t lenB = b->afterLast - b->first; - if (diff > 0) { - return 1; - } else if (diff < 0) { - return -1; + if (lenA != lenB) { + return false; } - return diff; + return URI_STRNCMP(a->first, b->first, lenA) == 0; } UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) { - const int lenInChars = (int)(sourceRange->afterLast - sourceRange->first); - const int lenInBytes = lenInChars * sizeof(URI_CHAR); + const size_t lenInChars = sourceRange->afterLast - sourceRange->first; + if (lenInChars > SIZE_MAX / sizeof(URI_CHAR)) { // detect integer overflow + return URI_FALSE; + } + const size_t lenInBytes = lenInChars * sizeof(URI_CHAR); URI_CHAR * dup = memory->malloc(memory, lenInBytes); if (dup == NULL) { return URI_FALSE; @@ -178,7 +173,7 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, UriBool relative, walker->reserved = NULL; /* Prev pointer */ do { UriBool removeSegment = URI_FALSE; - int len = (int)(walker->text.afterLast - walker->text.first); + const size_t len = walker->text.afterLast - walker->text.first; switch (len) { case 1: if ((walker->text.first)[0] == _UT('.')) { @@ -727,7 +722,7 @@ UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory } /* When dropping a host from a URI without a scheme, an absolute path - * and and empty first path segment, a consecutive reparse would rightfully + * and empty first path segment, a consecutive reparse would rightfully * mis-classify the first path segment as a host marker due to the "//". * To protect against this case, we prepend an artificial "." segment * to the path in here; the function is called after the host has diff --git a/ext/uri/uriparser/src/UriCommon.h b/ext/uri/uriparser/src/UriCommon.h index d141935f19e5..12c691a73386 100644 --- a/ext/uri/uriparser/src/UriCommon.h +++ b/ext/uri/uriparser/src/UriCommon.h @@ -67,6 +67,8 @@ # include # endif +# include + /* Used to point to from empty path segments. * X.first and X.afterLast must be the same non-NULL value then. */ extern const URI_CHAR * const URI_FUNC(SafeToPointTo); @@ -77,7 +79,7 @@ void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri); int URI_FUNC(FreeUriPath)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); -int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b); +bool URI_FUNC(RangeEquals)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b); UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange, const URI_TYPE(TextRange) * sourceRange, diff --git a/ext/uri/uriparser/src/UriCompare.c b/ext/uri/uriparser/src/UriCompare.c index 781100e7e6f4..f9def86f6669 100644 --- a/ext/uri/uriparser/src/UriCompare.c +++ b/ext/uri/uriparser/src/UriCompare.c @@ -72,17 +72,17 @@ UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) { } /* scheme */ - if (URI_FUNC(CompareRange)(&(a->scheme), &(b->scheme))) { + if (!URI_FUNC(RangeEquals)(&(a->scheme), &(b->scheme))) { return URI_FALSE; } - /* absolutePath */ - if ((a->scheme.first == NULL) && (a->absolutePath != b->absolutePath)) { + /* absolutePath -- not meaningful for URIs with a host set! */ + if (!URI_FUNC(HasHost)(a) && (a->absolutePath != b->absolutePath)) { return URI_FALSE; } /* userInfo */ - if (URI_FUNC(CompareRange)(&(a->userInfo), &(b->userInfo))) { + if (!URI_FUNC(RangeEquals)(&(a->userInfo), &(b->userInfo))) { return URI_FALSE; } @@ -107,20 +107,20 @@ UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) { } if (a->hostData.ipFuture.first != NULL) { - if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) { + if (!URI_FUNC(RangeEquals)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) { return URI_FALSE; } } if ((a->hostData.ip4 == NULL) && (a->hostData.ip6 == NULL) && (a->hostData.ipFuture.first == NULL)) { - if (URI_FUNC(CompareRange)(&(a->hostText), &(b->hostText))) { + if (!URI_FUNC(RangeEquals)(&(a->hostText), &(b->hostText))) { return URI_FALSE; } } /* portText */ - if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) { + if (!URI_FUNC(RangeEquals)(&(a->portText), &(b->portText))) { return URI_FALSE; } @@ -133,7 +133,7 @@ UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) { URI_TYPE(PathSegment) * walkA = a->pathHead; URI_TYPE(PathSegment) * walkB = b->pathHead; do { - if (URI_FUNC(CompareRange)(&(walkA->text), &(walkB->text))) { + if (!URI_FUNC(RangeEquals)(&(walkA->text), &(walkB->text))) { return URI_FALSE; } if ((walkA->next == NULL) != (walkB->next == NULL)) { @@ -145,12 +145,12 @@ UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) { } /* query */ - if (URI_FUNC(CompareRange)(&(a->query), &(b->query))) { + if (!URI_FUNC(RangeEquals)(&(a->query), &(b->query))) { return URI_FALSE; } /* fragment */ - if (URI_FUNC(CompareRange)(&(a->fragment), &(b->fragment))) { + if (!URI_FUNC(RangeEquals)(&(a->fragment), &(b->fragment))) { return URI_FALSE; } diff --git a/ext/uri/uriparser/src/UriCopy.c b/ext/uri/uriparser/src/UriCopy.c index 3bc6b0dbe3f4..fbe6340faa42 100644 --- a/ext/uri/uriparser/src/UriCopy.c +++ b/ext/uri/uriparser/src/UriCopy.c @@ -199,6 +199,12 @@ int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri if (URI_FUNC(CopyRangeAsNeeded)(&destWalker->text, &sourceWalker->text, memory) == URI_FALSE) { + // Unless wired to `destUri` above, `destWalker` may be hanging + // in the air now + if (destUri->pathHead != destWalker) { + memory->free(memory, destWalker); + } + URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory); return URI_ERROR_MALLOC; } diff --git a/ext/uri/uriparser/src/UriFile.c b/ext/uri/uriparser/src/UriFile.c index 7510e701c9f5..0af88480b0ad 100644 --- a/ext/uri/uriparser/src/UriFile.c +++ b/ext/uri/uriparser/src/UriFile.c @@ -63,7 +63,8 @@ # include # endif -# include /* for size_t, avoiding stddef.h for older MSVCs */ +# include // size_t +# include // SIZE_MAX static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString, @@ -90,6 +91,11 @@ static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename, : _UT("file:///"); const size_t prefixLen = URI_STRLEN(prefix); + // Detect and avoid integer overflow + if (prefixLen > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_OUTPUT_TOO_LARGE; + } + /* Copy prefix */ memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR)); output += prefixLen; @@ -103,7 +109,13 @@ static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename, if (lastSep + 1 < input) { if (!fromUnix && absolute && (firstSegment == URI_TRUE)) { /* Quick hack to not convert "C:" to "C%3A" */ - const int charsToCopy = (int)(input - (lastSep + 1)); + const size_t charsToCopy = input - (lastSep + 1); + + // Detect and avoid integer overflow + if (charsToCopy > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_OUTPUT_TOO_LARGE; + } + memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR)); output += charsToCopy; } else { diff --git a/ext/uri/uriparser/src/UriMemory.c b/ext/uri/uriparser/src/UriMemory.c index 3caf8199dc45..669f48dd6827 100644 --- a/ext/uri/uriparser/src/UriMemory.c +++ b/ext/uri/uriparser/src/UriMemory.c @@ -45,12 +45,25 @@ #include "UriConfig.h" /* for HAVE_REALLOCARRAY */ #ifdef HAVE_REALLOCARRAY -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 +// For glibc >=2.29 of 2019-02-01 +# if !defined(_DEFAULT_SOURCE) +# define _DEFAULT_SOURCE 1 # endif -# ifdef __NetBSD__ + +// For NetBSD (stdlib.h revision 1.122 of 2020-05-26) +# if defined(__NetBSD__) && !defined(_OPENBSD_SOURCE) # define _OPENBSD_SOURCE 1 # endif + +// POSIX 2024 (XPG8) for e.g. Illumos/SmartOS +# if !defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE - 0 < 800) +# undef _XOPEN_SOURCE +# define _XOPEN_SOURCE 800 +# endif +# if !defined(_POSIX_C_SOURCE) || (_POSIX_C_SOURCE - 0 < 202405L) +# undef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 202405L +# endif #endif #include diff --git a/ext/uri/uriparser/src/UriNormalize.c b/ext/uri/uriparser/src/UriNormalize.c index 8c812d37a0a7..c73e22b28879 100644 --- a/ext/uri/uriparser/src/UriNormalize.c +++ b/ext/uri/uriparser/src/UriNormalize.c @@ -73,6 +73,7 @@ # endif # include +# include // SIZE_MAX static int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask, @@ -254,20 +255,22 @@ URI_FUNC(LowercaseInplaceExceptPercentEncoding)(const URI_CHAR * first, static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory) { - int lenInChars; const int lowerUpperDiff = (_UT('a') - _UT('A')); URI_CHAR * buffer; - int i = 0; + size_t i = 0; if ((first == NULL) || (afterLast == NULL) || (*first == NULL) || (*afterLast == NULL)) { return URI_FALSE; } - lenInChars = (int)(*afterLast - *first); + const size_t lenInChars = *afterLast - *first; if (lenInChars == 0) { return URI_TRUE; - } else if (lenInChars < 0) { + } + + // Detect and avoid integer overflow + if (lenInChars > SIZE_MAX / sizeof(URI_CHAR)) { return URI_FALSE; } @@ -295,8 +298,8 @@ URI_FUNC(FixPercentEncodingEngine)(const URI_CHAR * inFirst, const URI_CHAR * in const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast) { URI_CHAR * write = (URI_CHAR *)outFirst; - const int lenInChars = (int)(inAfterLast - inFirst); - int i = 0; + const size_t lenInChars = inAfterLast - inFirst; + size_t i = 0; /* All but last two */ for (; i + 2 < lenInChars; i++) { @@ -350,7 +353,6 @@ static URI_INLINE void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * firs static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first, const URI_CHAR ** afterLast, UriMemoryManager * memory) { - int lenInChars; URI_CHAR * buffer; /* Death checks */ @@ -360,10 +362,13 @@ static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** f } /* Old text length */ - lenInChars = (int)(*afterLast - *first); + const size_t lenInChars = *afterLast - *first; if (lenInChars == 0) { return URI_TRUE; - } else if (lenInChars < 0) { + } + + // Detect and avoid integer overflow + if (lenInChars > SIZE_MAX / sizeof(URI_CHAR)) { return URI_FALSE; } diff --git a/ext/uri/uriparser/src/UriQuery.c b/ext/uri/uriparser/src/UriQuery.c index 801a237a3a1b..de3a040de042 100644 --- a/ext/uri/uriparser/src/UriQuery.c +++ b/ext/uri/uriparser/src/UriQuery.c @@ -67,6 +67,7 @@ # include # include /* size_t */ +# include // SIZE_MAX static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, @@ -254,7 +255,14 @@ int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * qu if (dest != NULL) { write[0] = _UT('\0'); if (charsWritten != NULL) { - *charsWritten = (int)(write - dest) + 1; /* .. for terminator */ + const size_t lenInChars = write - dest; + + // Detect and avoid integer overflow + if (lenInChars > INT_MAX - 1) { + return URI_ERROR_OUTPUT_TOO_LARGE; + } + + *charsWritten = (int)(lenInChars + 1); /* .. for terminator */ } } @@ -267,8 +275,8 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) * *prevNext, int * itemCou const URI_CHAR * valueAfter, UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory) { - const int keyLen = (int)(keyAfter - keyFirst); - const int valueLen = (int)(valueAfter - valueFirst); + const size_t keyLen = keyAfter - keyFirst; + const size_t valueLen = valueAfter - valueFirst; URI_CHAR * key; URI_CHAR * value; @@ -285,6 +293,13 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) * *prevNext, int * itemCou } (*prevNext)->next = NULL; + // Detect integer overflow + if ((keyLen > SIZE_MAX - 1) || (keyLen + 1 > SIZE_MAX / sizeof(URI_CHAR))) { + memory->free(memory, *prevNext); + *prevNext = NULL; + return URI_FALSE; // Raises malloc error + } + /* Fill key */ key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR)); if (key == NULL) { @@ -305,6 +320,14 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) * *prevNext, int * itemCou /* Fill value */ if (valueFirst != NULL) { + // Detect integer overflow + if ((valueLen > SIZE_MAX - 1) || (valueLen + 1 > SIZE_MAX / sizeof(URI_CHAR))) { + memory->free(memory, key); + memory->free(memory, *prevNext); + *prevNext = NULL; + return URI_FALSE; // Raises malloc error + } + value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR)); if (value == NULL) { memory->free(memory, key); diff --git a/ext/uri/uriparser/src/UriRecompose.c b/ext/uri/uriparser/src/UriRecompose.c index 61ffee77248f..055e0483d3f2 100644 --- a/ext/uri/uriparser/src/UriRecompose.c +++ b/ext/uri/uriparser/src/UriRecompose.c @@ -64,6 +64,9 @@ # include "UriCommon.h" # endif +# include // INT_MAX +# include // SIZE_MAX + static int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars, int * charsWritten, int * charsRequired); @@ -116,10 +119,19 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U /* clang-format off */ /* [03/19] append scheme to result; */ /* clang-format on */ - const int charsToWrite = - (int)(uri->scheme.afterLast - uri->scheme.first); + const size_t charsToWrite = uri->scheme.afterLast - uri->scheme.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->scheme.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -131,6 +143,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - *charsRequired) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite; } /* clang-format off */ @@ -180,10 +197,20 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U /* clang-format on */ /* UserInfo */ if (uri->userInfo.first != NULL) { - const int charsToWrite = - (int)(uri->userInfo.afterLast - uri->userInfo.first); + const size_t charsToWrite = + uri->userInfo.afterLast - uri->userInfo.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->userInfo.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -206,6 +233,13 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if ((charsToWrite > (size_t)INT_MAX - 1) + || (charsToWrite + 1 + > (size_t)INT_MAX - *charsRequired)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite + 1; } } @@ -334,8 +368,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U } } else if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ - const int charsToWrite = (int)(uri->hostData.ipFuture.afterLast - - uri->hostData.ipFuture.first); + const size_t charsToWrite = uri->hostData.ipFuture.afterLast + - uri->hostData.ipFuture.first; if (dest != NULL) { if (written + 1 <= maxChars) { memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR)); @@ -348,7 +382,17 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->hostData.ipFuture.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -371,14 +415,31 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if ((charsToWrite > (size_t)INT_MAX - 1 - 1) + || (1 + charsToWrite + 1 + > (size_t)INT_MAX - *charsRequired)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += 1 + charsToWrite + 1; } } else if (uri->hostText.first != NULL) { /* Regname */ - const int charsToWrite = - (int)(uri->hostText.afterLast - uri->hostText.first); + const size_t charsToWrite = + uri->hostText.afterLast - uri->hostText.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->hostText.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -390,14 +451,19 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - *charsRequired) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite; } } /* Port */ if (uri->portText.first != NULL) { - const int charsToWrite = - (int)(uri->portText.afterLast - uri->portText.first); + const size_t charsToWrite = + uri->portText.afterLast - uri->portText.first; if (dest != NULL) { /* Leading ':' */ if (written + 1 <= maxChars) { @@ -411,8 +477,18 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + /* Port number */ - if (written + charsToWrite <= maxChars) { + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->portText.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -424,6 +500,13 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if ((charsToWrite > (size_t)INT_MAX - 1) + || (1 + charsToWrite + > (size_t)INT_MAX - *charsRequired)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += 1 + charsToWrite; } } @@ -456,10 +539,20 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U if (uri->pathHead != NULL) { URI_TYPE(PathSegment) * walker = uri->pathHead; do { - const int charsToWrite = - (int)(walker->text.afterLast - walker->text.first); + const size_t charsToWrite = + walker->text.afterLast - walker->text.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, walker->text.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -471,6 +564,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - *charsRequired) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite; } @@ -520,10 +618,19 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U /* clang-format off */ /* [13/19] append query to result; */ /* clang-format on */ - const int charsToWrite = - (int)(uri->query.afterLast - uri->query.first); + const size_t charsToWrite = uri->query.afterLast - uri->query.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->query.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -535,6 +642,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - *charsRequired) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite; } /* clang-format off */ @@ -565,10 +677,20 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U /* clang-format off */ /* [17/19] append fragment to result; */ /* clang-format on */ - const int charsToWrite = - (int)(uri->fragment.afterLast - uri->fragment.first); + const size_t charsToWrite = + uri->fragment.afterLast - uri->fragment.first; if (dest != NULL) { - if (written + charsToWrite <= maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - written) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + + if (written + charsToWrite <= (size_t)maxChars) { + // Detect and avoid integer overflow + if (charsToWrite > SIZE_MAX / sizeof(URI_CHAR)) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + memcpy(dest + written, uri->fragment.first, charsToWrite * sizeof(URI_CHAR)); written += charsToWrite; @@ -580,6 +702,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U return URI_ERROR_TOSTRING_TOO_LONG; } } else { + // Detect and avoid integer overflow + if (charsToWrite > (size_t)INT_MAX - *charsRequired) { + return URI_ERROR_TOSTRING_TOO_LONG; + } + (*charsRequired) += charsToWrite; } /* clang-format off */ diff --git a/ext/uri/uriparser/src/UriResolve.c b/ext/uri/uriparser/src/UriResolve.c index 302665d21cd6..90c8bfd778dc 100644 --- a/ext/uri/uriparser/src/UriResolve.c +++ b/ext/uri/uriparser/src/UriResolve.c @@ -183,9 +183,8 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, if ((options & URI_RESOLVE_IDENTICAL_SCHEME_COMPAT) && (absBase->scheme.first != NULL) && (relSource->scheme.first != NULL) - && (0 - == URI_FUNC(CompareRange)(&(absBase->scheme), - &(relSource->scheme)))) { + && (URI_FUNC(RangeEquals)(&(absBase->scheme), + &(relSource->scheme)))) { /* clang-format off */ /* [00/32] undefine(R.scheme); */ /* clang-format on */ diff --git a/ext/uri/uriparser/src/UriShorten.c b/ext/uri/uriparser/src/UriShorten.c index 548b0b4157dd..001bd7db9990 100644 --- a/ext/uri/uriparser/src/UriShorten.c +++ b/ext/uri/uriparser/src/UriShorten.c @@ -111,14 +111,14 @@ static URI_INLINE UriBool URI_FUNC(EqualsAuthority)(const URI_TYPE(Uri) * first, /* IPvFuture */ if (first->hostData.ipFuture.first != NULL) { return ((second->hostData.ipFuture.first != NULL) - && !URI_FUNC(CompareRange)(&first->hostData.ipFuture, - &second->hostData.ipFuture)) + && URI_FUNC(RangeEquals)(&first->hostData.ipFuture, + &second->hostData.ipFuture)) ? URI_TRUE : URI_FALSE; } - return !URI_FUNC(CompareRange)(&first->hostText, &second->hostText) ? URI_TRUE - : URI_FALSE; + return URI_FUNC(RangeEquals)(&first->hostText, &second->hostText) ? URI_TRUE + : URI_FALSE; } static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, @@ -152,7 +152,7 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, /* clang-format off */ /* [01/50] if (A.scheme != Base.scheme) then */ /* clang-format on */ - if (URI_FUNC(CompareRange)(&absSource->scheme, &absBase->scheme)) { + if (!URI_FUNC(RangeEquals)(&absSource->scheme, &absBase->scheme)) { /* clang-format off */ /* [02/50] T.scheme = A.scheme; */ /* clang-format on */ @@ -255,8 +255,7 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, /* clang-format on */ while ( (sourceSeg != NULL) && (baseSeg != NULL) - && !URI_FUNC(CompareRange)(&sourceSeg->text, - &baseSeg->text) + && URI_FUNC(RangeEquals)(&sourceSeg->text, &baseSeg->text) && !((sourceSeg->text.first == sourceSeg->text.afterLast) && ((sourceSeg->next == NULL) != (baseSeg->next == NULL)))) { diff --git a/ext/xml/compat.c b/ext/xml/compat.c index 7e37bf1e412c..10bfa19af7af 100644 --- a/ext/xml/compat.c +++ b/ext/xml/compat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | +----------------------------------------------------------------------+ diff --git a/ext/xml/expat_compat.h b/ext/xml/expat_compat.h index a7faffbac504..721bad71080b 100644 --- a/ext/xml/expat_compat.h +++ b/ext/xml/expat_compat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | +----------------------------------------------------------------------+ diff --git a/ext/xml/php_xml.h b/ext/xml/php_xml.h index 8be95fa7aa8f..982f39933d17 100644 --- a/ext/xml/php_xml.h +++ b/ext/xml/php_xml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Thies C. Arntzen | diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 7a9329bcc804..d1bb4bbda23f 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Thies C. Arntzen | @@ -224,7 +222,7 @@ PHP_MINIT_FUNCTION(xml) xml_parser_ce->default_object_handlers = &xml_parser_object_handlers; memcpy(&xml_parser_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - xml_parser_object_handlers.offset = XtOffsetOf(xml_parser, std); + xml_parser_object_handlers.offset = offsetof(xml_parser, std); xml_parser_object_handlers.free_obj = xml_parser_free_obj; xml_parser_object_handlers.get_gc = xml_parser_get_gc; xml_parser_object_handlers.get_constructor = xml_parser_get_constructor; @@ -297,9 +295,7 @@ static void xml_xmlchar_zval(const XML_Char *s, int len, const XML_Char *encodin } /* }}} */ -static inline xml_parser *xml_parser_from_obj(zend_object *obj) { - return (xml_parser *)((char *)(obj) - XtOffsetOf(xml_parser, std)); -} +#define xml_parser_from_obj(obj) ZEND_CONTAINER_OF(obj, xml_parser, std) #define Z_XMLPARSER_P(zv) xml_parser_from_obj(Z_OBJ_P(zv)) @@ -554,10 +550,10 @@ static void xml_add_to_info(xml_parser *parser, zend_string *name) SEPARATE_ARRAY(Z_REFVAL(parser->info)); zend_array *arr = Z_ARRVAL_P(Z_REFVAL(parser->info)); - if ((element = zend_hash_find(arr, name)) == NULL) { - zval values; - array_init(&values); - element = zend_hash_update(arr, name, &values); + element = zend_hash_lookup(arr, name); + + if (Z_TYPE_P(element) == IS_NULL) { + array_init(element); } add_next_index_long(element, parser->curtag); @@ -831,16 +827,15 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) zval *myval; /* check if the current tag already has a value - if yes append to that! */ if ((myval = zend_hash_find(Z_ARRVAL_P(ctag), ZSTR_KNOWN(ZEND_STR_VALUE))) && Z_TYPE_P(myval) == IS_STRING) { - size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); - Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + Z_STR_P(myval) = zend_string_safe_realloc(Z_STR_P(myval), 1, Z_STRLEN_P(myval), ZSTR_LEN(decoded_value), false); strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } else { if (doprint || (! parser->skipwhite)) { add_assoc_str(ctag, "value", decoded_value); } else { - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } } } else { @@ -858,11 +853,10 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) if (EXPECTED(Z_TYPE_P(mytype) == IS_STRING) && zend_string_equals_literal(Z_STR_P(mytype), "cdata")) { SEPARATE_ARRAY(curtag); if ((myval = zend_hash_find(Z_ARRVAL_P(curtag), ZSTR_KNOWN(ZEND_STR_VALUE)))) { - size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); - Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + Z_STR_P(myval) = zend_string_safe_realloc(Z_STR_P(myval), 1, Z_STRLEN_P(myval), ZSTR_LEN(decoded_value), false); strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); return; } } @@ -881,7 +875,7 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) } else if (parser->level == (XML_MAXLEVEL + 1)) { php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated"); } else { - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } } } @@ -1620,7 +1614,6 @@ PHP_FUNCTION(xml_parser_set_option) default: zend_argument_value_error(2, "must be a XML_OPTION_* constant"); RETURN_THROWS(); - break; } RETURN_TRUE; @@ -1642,19 +1635,14 @@ PHP_FUNCTION(xml_parser_get_option) switch (opt) { case PHP_XML_OPTION_CASE_FOLDING: RETURN_BOOL(parser->case_folding); - break; case PHP_XML_OPTION_SKIP_TAGSTART: RETURN_LONG(parser->toffset); - break; case PHP_XML_OPTION_SKIP_WHITE: RETURN_BOOL(parser->skipwhite); - break; case PHP_XML_OPTION_PARSE_HUGE: RETURN_BOOL(parser->parsehuge); - break; case PHP_XML_OPTION_TARGET_ENCODING: RETURN_STRING((char *)parser->target_encoding); - break; default: zend_argument_value_error(2, "must be a XML_OPTION_* constant"); RETURN_THROWS(); diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index d379b6dfad99..6a7fb65e2af0 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rob Richards | +----------------------------------------------------------------------+ @@ -102,7 +100,7 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl case IS_LONG: ZVAL_LONG(rv, retint); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return SUCCESS; @@ -471,9 +469,7 @@ static void php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_in int retval; xmlreader_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); id = ZEND_THIS; @@ -495,9 +491,7 @@ static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_ char *retchar = NULL; xmlreader_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); id = ZEND_THIS; @@ -575,9 +569,7 @@ PHP_METHOD(XMLReader, close) zval *id; xmlreader_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); id = ZEND_THIS; intern = Z_XMLREADER_P(id); @@ -761,7 +753,7 @@ PHP_METHOD(XMLReader, moveToAttributeNo) } /* }}} */ -/* {{{ Positions reader at attribute spcified by name and namespaceURI. +/* {{{ Positions reader at attribute specified by name and namespaceURI. Returns TRUE on success and FALSE on failure */ PHP_METHOD(XMLReader, moveToAttributeNs) { @@ -827,9 +819,7 @@ PHP_METHOD(XMLReader, read) int retval; xmlreader_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); id = ZEND_THIS; intern = Z_XMLREADER_P(id); @@ -1353,7 +1343,7 @@ PHP_MINIT_FUNCTION(xmlreader) { memcpy(&xmlreader_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std); + xmlreader_object_handlers.offset = offsetof(xmlreader_object, std); xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage; xmlreader_object_handlers.has_property = xmlreader_has_property; xmlreader_object_handlers.read_property = xmlreader_read_property; diff --git a/ext/xmlreader/php_xmlreader.h b/ext/xmlreader/php_xmlreader.h index b14b033a0eea..d33938f40506 100644 --- a/ext/xmlreader/php_xmlreader.h +++ b/ext/xmlreader/php_xmlreader.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rob Richards | +----------------------------------------------------------------------+ @@ -46,9 +44,7 @@ typedef struct _xmlreader_object { zend_object std; } xmlreader_object; -static inline xmlreader_object *php_xmlreader_fetch_object(zend_object *obj) { - return (xmlreader_object *)((char*)(obj) - XtOffsetOf(xmlreader_object, std)); -} +#define php_xmlreader_fetch_object(obj) ZEND_CONTAINER_OF(obj, xmlreader_object, std) #define Z_XMLREADER_P(zv) php_xmlreader_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/xmlreader/tests/012.phpt b/ext/xmlreader/tests/012.phpt index b10421d2624a..e00f37b82667 100644 --- a/ext/xmlreader/tests/012.phpt +++ b/ext/xmlreader/tests/012.phpt @@ -2,6 +2,10 @@ XMLReader: accessing empty and non existing attributes --EXTENSIONS-- xmlreader +--SKIPIF-- + --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rob Richards | | Pierre-A. Joye | @@ -432,7 +430,7 @@ PHP_FUNCTION(xmlwriter_write_element) } /* }}} */ -/* {{{ Write full namesapced element tag - returns FALSE on error */ +/* {{{ Write full namespaced element tag - returns FALSE on error */ PHP_FUNCTION(xmlwriter_write_element_ns) { xmlTextWriterPtr ptr; @@ -1050,7 +1048,7 @@ PHP_FUNCTION(xmlwriter_flush) static PHP_MINIT_FUNCTION(xmlwriter) { memcpy(&xmlwriter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - xmlwriter_object_handlers.offset = XtOffsetOf(ze_xmlwriter_object, std); + xmlwriter_object_handlers.offset = offsetof(ze_xmlwriter_object, std); xmlwriter_object_handlers.dtor_obj = xmlwriter_object_dtor; xmlwriter_object_handlers.clone_obj = NULL; xmlwriter_class_entry_ce = register_class_XMLWriter(); diff --git a/ext/xmlwriter/php_xmlwriter.h b/ext/xmlwriter/php_xmlwriter.h index e9a4dcb2aa49..542c6e838c5e 100644 --- a/ext/xmlwriter/php_xmlwriter.h +++ b/ext/xmlwriter/php_xmlwriter.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rob Richards | | Pierre-A. Joye | @@ -39,9 +37,7 @@ typedef struct _ze_xmlwriter_object { zend_object std; } ze_xmlwriter_object; -static inline ze_xmlwriter_object *php_xmlwriter_fetch_object(zend_object *obj) { - return (ze_xmlwriter_object *)((char*)(obj) - XtOffsetOf(ze_xmlwriter_object, std)); -} +#define php_xmlwriter_fetch_object(obj) ZEND_CONTAINER_OF(obj, ze_xmlwriter_object, std) #define Z_XMLWRITER_P(zv) php_xmlwriter_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/xmlwriter/tests/bug39504.phpt b/ext/xmlwriter/tests/bug39504.phpt index 0cb509d37dd5..eafcd375da93 100644 --- a/ext/xmlwriter/tests/bug39504.phpt +++ b/ext/xmlwriter/tests/bug39504.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not enity) +Bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not entity) --EXTENSIONS-- xmlwriter --FILE-- diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index dec7eb501eb2..b87f9578b215 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Christian Stocker | +----------------------------------------------------------------------+ @@ -144,6 +142,8 @@ zend_object *xsl_objects_new(zend_class_entry *class_type) } #endif +XSL_DEFINE_PROP_ACCESSOR(do_xinclude, "doXInclude", 0) +XSL_DEFINE_PROP_ACCESSOR(clone_document, "cloneDocument", 1) XSL_DEFINE_PROP_ACCESSOR(max_template_depth, "maxTemplateDepth", 2) XSL_DEFINE_PROP_ACCESSOR(max_template_vars, "maxTemplateVars", 3) @@ -266,7 +266,7 @@ static void xsl_libxslt_error_handler(void *ctx, const char *msg, ...) PHP_MINIT_FUNCTION(xsl) { memcpy(&xsl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - xsl_object_handlers.offset = XtOffsetOf(xsl_object, std); + xsl_object_handlers.offset = offsetof(xsl_object, std); xsl_object_handlers.clone_obj = NULL; xsl_object_handlers.free_obj = xsl_objects_free_storage; xsl_object_handlers.get_gc = xsl_objects_get_gc; @@ -323,7 +323,6 @@ PHP_MSHUTDOWN_FUNCTION(xsl) xsltUnregisterExtModuleFunction ((const xmlChar *) "function", (const xmlChar *) "http://php.net/xsl"); xsltSetGenericErrorFunc(NULL, NULL); - xsltCleanupGlobals(); return SUCCESS; } diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h index 36bd9cc72844..9f75fbb86fee 100644 --- a/ext/xsl/php_xsl.h +++ b/ext/xsl/php_xsl.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -64,9 +60,7 @@ typedef struct xsl_object { zend_object std; } xsl_object; -static inline xsl_object *php_xsl_fetch_object(zend_object *obj) { - return (xsl_object *)((char*)(obj) - XtOffsetOf(xsl_object, std)); -} +#define php_xsl_fetch_object(obj) ZEND_CONTAINER_OF(obj, xsl_object, std) #define Z_XSL_P(zv) php_xsl_fetch_object(Z_OBJ_P((zv))) @@ -79,6 +73,8 @@ void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs); zval *xsl_prop_max_template_depth(zend_object *object); zval *xsl_prop_max_template_vars(zend_object *object); +zval *xsl_prop_do_xinclude(zend_object *object); +zval *xsl_prop_clone_document(zend_object *object); PHP_MINIT_FUNCTION(xsl); PHP_MSHUTDOWN_FUNCTION(xsl); diff --git a/ext/xsl/tests/gh21496.phpt b/ext/xsl/tests/gh21496.phpt new file mode 100644 index 000000000000..12ff202aed17 --- /dev/null +++ b/ext/xsl/tests/gh21496.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-21496 (UAF in dom_objects_free_storage when importing non-document node as stylesheet) +--EXTENSIONS-- +dom +xsl +simplexml +--CREDITS-- +YuanchengJiang +--FILE-- +loadXML(<< +XML); +$doc->documentElement->appendChild($comment); +unset($doc); +$proc = new XSLTProcessor(); +var_dump($proc->importStylesheet($comment)); +$sxe = simplexml_load_string(''); +$proc = new XSLTProcessor(); +$proc->importStylesheet($sxe); +?> +--EXPECTF-- +Warning: XSLTProcessor::importStylesheet(): compilation error: file %s line 1 element container in %s on line %d + +Warning: XSLTProcessor::importStylesheet(): xsltParseStylesheetProcess : document is not a stylesheet in %s on line %d +bool(false) + +Warning: XSLTProcessor::importStylesheet(): compilation error: element container in %s on line %d + +Warning: XSLTProcessor::importStylesheet(): xsltParseStylesheetProcess : document is not a stylesheet in %s on line %d + diff --git a/ext/xsl/tests/gh22621.phpt b/ext/xsl/tests/gh22621.phpt new file mode 100644 index 000000000000..b31671eff630 --- /dev/null +++ b/ext/xsl/tests/gh22621.phpt @@ -0,0 +1,63 @@ +--TEST-- +GH-22621 (UAF via XSLTProcessor::registerPHPFunctions() retaining namespace nodes from an external document) +--EXTENSIONS-- +dom +xsl +--CREDITS-- +ExPatch-LLC +--FILE-- +secret'); +$uri = 'file:///' . ltrim(str_replace('\\', '/', $cDIR), '/') . '/gh22621_external.xml'; + +$stored_ns = null; + +function capture_ns($nodes) { + global $stored_ns; + foreach ($nodes as $node) { + if ($node instanceof DOMNameSpaceNode) { + $stored_ns = $node; + } + } + return "captured"; +} + +$xsl = new DOMDocument(); +$xsl->loadXML(<< + + + + + + + +XSL); + +$doc = new DOMDocument(); +$doc->loadXML(''); + +$proc = new XSLTProcessor(); +$proc->registerPHPFunctions(); +$proc->importStylesheet($xsl); +echo $proc->transformToXml($doc); + +var_dump($stored_ns->localName); +var_dump($stored_ns->namespaceURI); +var_dump($stored_ns->parentNode->localName); +var_dump($stored_ns->ownerDocument instanceof DOMDocument); +?> +--CLEAN-- + +--EXPECTF-- + +captured +string(6) "custom" +string(10) "urn:custom" +string(4) "root" +bool(true) diff --git a/ext/xsl/tests/special_operations_with_properties.phpt b/ext/xsl/tests/special_operations_with_properties.phpt index b7904fad8d86..efd6765c34f7 100644 --- a/ext/xsl/tests/special_operations_with_properties.phpt +++ b/ext/xsl/tests/special_operations_with_properties.phpt @@ -29,11 +29,8 @@ echo "--- Unset cloneDocument ---\n"; $xslt = new XSLTProcessor; $xslt->registerPHPFunctions(); unset($xslt->cloneDocument); -try { - $xslt->importStylesheet($xsl); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +$xslt->importStylesheet($xsl); +echo $xslt->transformToXml($xml); echo "--- Unset doXInclude ---\n"; @@ -41,11 +38,7 @@ $xslt = new XSLTProcessor; $xslt->registerPHPFunctions(); unset($xslt->doXInclude); $xslt->importStylesheet($xsl); -try { - echo $xslt->transformToXml($xml); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +echo $xslt->transformToXml($xml); echo "--- Make properties references ---\n"; @@ -59,9 +52,13 @@ echo $xslt->transformToXml($xml); ?> --EXPECT-- --- Unset cloneDocument --- -Typed property XSLTProcessor::$cloneDocument must not be accessed before initialization +Called test + +hello --- Unset doXInclude --- -Typed property XSLTProcessor::$doXInclude must not be accessed before initialization +Called test + +hello --- Make properties references --- Called test diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 1d073822b462..230c7bd39cc2 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -167,18 +165,47 @@ PHP_METHOD(XSLTProcessor, importStylesheet) xsltStylesheetPtr sheetp; bool clone_docu = false; xmlNode *nodep = NULL; - zval *cloneDocu, rv, clone_zv; - zend_string *member; + zval *cloneDocu, clone_zv, owner_zv; id = ZEND_THIS; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &docp) == FAILURE) { RETURN_THROWS(); } + nodep = php_libxml_import_node(docp); + if (nodep == NULL) { + zend_argument_type_error(1, "must be a valid XML node"); + RETURN_THROWS(); + } + + if (Z_OBJ_HANDLER_P(docp, clone_obj) == NULL) { + zend_argument_type_error(1, "must be a cloneable node"); + RETURN_THROWS(); + } + + ZVAL_UNDEF(&owner_zv); + + /* For non-document nodes, resolve the ownerDocument and clone that + * instead as xsltParseStylesheetProcess may free nodes in the document. */ + if (nodep->type != XML_DOCUMENT_NODE && nodep->type != XML_HTML_DOCUMENT_NODE) { + if (nodep->doc == NULL) { + zend_argument_value_error(1, "must be part of a document"); + RETURN_THROWS(); + } + + /* See dom_import_simplexml_common */ + + dom_object *nodeobj = (dom_object *) ((char *) Z_OBJ_P(docp) - Z_OBJ_HT_P(docp)->offset); + + php_dom_create_object((xmlNodePtr) nodep->doc, &owner_zv, nodeobj); + docp = &owner_zv; + } + /* libxslt uses _private, so we must copy the imported * stylesheet document otherwise the node proxies will be a mess. * We will clone the object and detach the libxml internals later. */ zend_object *clone = Z_OBJ_HANDLER_P(docp, clone_obj)(Z_OBJ_P(docp)); + zval_ptr_dtor(&owner_zv); if (!clone) { RETURN_THROWS(); } @@ -186,15 +213,7 @@ PHP_METHOD(XSLTProcessor, importStylesheet) ZVAL_OBJ(&clone_zv, clone); nodep = php_libxml_import_node(&clone_zv); - if (nodep) { - newdoc = nodep->doc; - } - if (newdoc == NULL) { - OBJ_RELEASE(clone); - zend_argument_type_error(1, "must be a valid XML node"); - RETURN_THROWS(); - } - + newdoc = nodep->doc; php_libxml_node_object *clone_lxml_obj = Z_LIBXML_NODE_P(&clone_zv); PHP_LIBXML_SANITIZE_GLOBALS(parse); @@ -229,10 +248,8 @@ PHP_METHOD(XSLTProcessor, importStylesheet) intern->sheet_ref_obj->refcount++; OBJ_RELEASE(clone); - member = ZSTR_INIT_LITERAL("cloneDocument", 0); - cloneDocu = zend_std_read_property(Z_OBJ_P(id), member, BP_VAR_R, NULL, &rv); + cloneDocu = xsl_prop_clone_document(Z_OBJ_P(id)); clone_docu = zend_is_true(cloneDocu); - zend_string_release_ex(member, 0); if (!clone_docu) { /* Check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation. * xsl:key elements may only occur at the top level. Furthermore, all elements at the top level must be in a @@ -272,8 +289,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl xmlNodePtr node = NULL; xsltTransformContextPtr ctxt; php_libxml_node_object *object; - zval *doXInclude, rv; - zend_string *member; + zval *doXInclude; FILE *f; int secPrefsError = 0; xsltSecurityPrefsPtr secPrefs = NULL; @@ -329,10 +345,8 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl } } - member = ZSTR_INIT_LITERAL("doXInclude", 0); - doXInclude = zend_std_read_property(Z_OBJ_P(id), member, BP_VAR_R, NULL, &rv); + doXInclude = xsl_prop_do_xinclude(Z_OBJ_P(id)); ctxt->xinclude = zend_is_true(doXInclude); - zend_string_release_ex(member, 0); zval *max_template_depth = xsl_prop_max_template_depth(Z_OBJ_P(id)); ZEND_ASSERT(Z_TYPE_P(max_template_depth) == IS_LONG); @@ -430,20 +444,18 @@ PHP_METHOD(XSLTProcessor, transformToDoc) if (newdocp) { if (ret_class) { - zend_string *curclass_name; - zend_class_entry *curce; php_libxml_node_object *interndoc; - curce = Z_OBJCE_P(docp); - curclass_name = curce->name; - while (curce->parent != NULL) { - curce = curce->parent; + const zend_class_entry *current_ce = Z_OBJCE_P(docp); + const zend_string *current_class_name = current_ce->name; + while (current_ce->parent != NULL) { + current_ce = current_ce->parent; } - if (!instanceof_function(ret_class, curce)) { + if (!instanceof_function(ret_class, current_ce)) { xmlFreeDoc(newdocp); zend_argument_type_error(2, "must be a class name compatible with %s, %s given", - ZSTR_VAL(curclass_name), ZSTR_VAL(ret_class->name) + ZSTR_VAL(current_class_name), ZSTR_VAL(ret_class->name) ); RETURN_THROWS(); } diff --git a/ext/zend_test/fiber.c b/ext/zend_test/fiber.c index 199d1b28b8cd..da6f4c962d85 100644 --- a/ext/zend_test/fiber.c +++ b/ext/zend_test/fiber.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | +----------------------------------------------------------------------+ diff --git a/ext/zend_test/fiber.h b/ext/zend_test/fiber.h index ad5a4c7b3342..801d0a78af16 100644 --- a/ext/zend_test/fiber.h +++ b/ext/zend_test/fiber.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | +----------------------------------------------------------------------+ diff --git a/ext/zend_test/iterators.c b/ext/zend_test/iterators.c index 47ea017d892a..0171a91708e9 100644 --- a/ext/zend_test/iterators.c +++ b/ext/zend_test/iterators.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/zend_test/iterators.h b/ext/zend_test/iterators.h index cef09109e239..070259094da8 100644 --- a/ext/zend_test/iterators.h +++ b/ext/zend_test/iterators.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/zend_test/object_handlers.c b/ext/zend_test/object_handlers.c index 15e362605f8e..6b8bf4ab9912 100644 --- a/ext/zend_test/object_handlers.c +++ b/ext/zend_test/object_handlers.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: George Peter Banyard | +----------------------------------------------------------------------+ @@ -232,6 +230,44 @@ ZEND_METHOD(NumericCastableNoOperations, __construct) ZVAL_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), n); } +static zend_class_entry *vm_interrupt_comparable_ce; +static zend_object_handlers vm_interrupt_comparable_object_handlers; + +static zend_object* vm_interrupt_comparable_object_create_ex(zend_class_entry* ce, zend_long l) { + zend_object *obj = zend_objects_new(ce); + object_properties_init(obj, ce); + obj->handlers = &vm_interrupt_comparable_object_handlers; + ZVAL_LONG(OBJ_PROP_NUM(obj, 0), l); + return obj; +} + +static zend_object *vm_interrupt_comparable_object_create(zend_class_entry *ce) +{ + return vm_interrupt_comparable_object_create_ex(ce, 0); +} + +static int vm_interrupt_comparable_compare(zval *op1, zval *op2) +{ + ZEND_COMPARE_OBJECTS_FALLBACK(op1, op2); + + zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + + return ZEND_THREEWAY_COMPARE( + Z_LVAL_P(OBJ_PROP_NUM(Z_OBJ_P(op1), 0)), + Z_LVAL_P(OBJ_PROP_NUM(Z_OBJ_P(op2), 0))); +} + +ZEND_METHOD(VmInterruptComparable, __construct) +{ + zend_long l; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(l) + ZEND_PARSE_PARAMETERS_END(); + + ZVAL_LONG(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), l); +} + static zend_class_entry *dimension_handlers_no_ArrayAccess_ce; static zend_object_handlers dimension_handlers_no_ArrayAccess_object_handlers; @@ -302,6 +338,11 @@ void zend_test_object_handlers_init(void) memcpy(&numeric_castable_no_operation_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); numeric_castable_no_operation_object_handlers.cast_object = numeric_castable_no_operation_cast_object; + vm_interrupt_comparable_ce = register_class_VmInterruptComparable(); + vm_interrupt_comparable_ce->create_object = vm_interrupt_comparable_object_create; + memcpy(&vm_interrupt_comparable_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + vm_interrupt_comparable_object_handlers.compare = vm_interrupt_comparable_compare; + dimension_handlers_no_ArrayAccess_ce = register_class_DimensionHandlersNoArrayAccess(); dimension_handlers_no_ArrayAccess_ce->create_object = dimension_handlers_no_ArrayAccess_object_create; memcpy(&dimension_handlers_no_ArrayAccess_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); diff --git a/ext/zend_test/object_handlers.h b/ext/zend_test/object_handlers.h index 528e047360f9..fa188d923667 100644 --- a/ext/zend_test/object_handlers.h +++ b/ext/zend_test/object_handlers.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: George Peter Banyard | +----------------------------------------------------------------------+ diff --git a/ext/zend_test/object_handlers.stub.php b/ext/zend_test/object_handlers.stub.php index a474908b1095..8c8e7f9bfe9b 100644 --- a/ext/zend_test/object_handlers.stub.php +++ b/ext/zend_test/object_handlers.stub.php @@ -23,6 +23,11 @@ final class NumericCastableNoOperations { public function __construct(int|float $val) {} } +final class VmInterruptComparable { + private int $val; + public function __construct(int $val) {} +} + class DimensionHandlersNoArrayAccess { public bool $read = false; public bool $write = false; diff --git a/ext/zend_test/object_handlers_arginfo.h b/ext/zend_test/object_handlers_arginfo.h index 34008c33bc0c..995bd62dc478 100644 --- a/ext/zend_test/object_handlers_arginfo.h +++ b/ext/zend_test/object_handlers_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit object_handlers.stub.php instead. - * Stub hash: 81be60f2c465ffe5c036739d072ab80d9c388907 */ + * Stub hash: 1a70ed60c5af38539b1222a979f97fddf7d1826e */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DoOperationNoCast___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, val, IS_LONG, 0) @@ -15,10 +15,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumericCastableNoOperations___construct, 0, ZEND_ARG_TYPE_MASK(0, val, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() +#define arginfo_class_VmInterruptComparable___construct arginfo_class_DoOperationNoCast___construct + static ZEND_METHOD(DoOperationNoCast, __construct); static ZEND_METHOD(LongCastableNoOperations, __construct); static ZEND_METHOD(FloatCastableNoOperations, __construct); static ZEND_METHOD(NumericCastableNoOperations, __construct); +static ZEND_METHOD(VmInterruptComparable, __construct); static const zend_function_entry class_DoOperationNoCast_methods[] = { ZEND_ME(DoOperationNoCast, __construct, arginfo_class_DoOperationNoCast___construct, ZEND_ACC_PUBLIC) @@ -40,6 +43,11 @@ static const zend_function_entry class_NumericCastableNoOperations_methods[] = { ZEND_FE_END }; +static const zend_function_entry class_VmInterruptComparable_methods[] = { + ZEND_ME(VmInterruptComparable, __construct, arginfo_class_VmInterruptComparable___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static zend_class_entry *register_class_DoOperationNoCast(void) { zend_class_entry ce, *class_entry; @@ -104,6 +112,22 @@ static zend_class_entry *register_class_NumericCastableNoOperations(void) return class_entry; } +static zend_class_entry *register_class_VmInterruptComparable(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "VmInterruptComparable", class_VmInterruptComparable_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); + + zval property_val_default_value; + ZVAL_UNDEF(&property_val_default_value); + zend_string *property_val_name = zend_string_init("val", sizeof("val") - 1, true); + zend_declare_typed_property(class_entry, property_val_name, &property_val_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(property_val_name, true); + + return class_entry; +} + static zend_class_entry *register_class_DimensionHandlersNoArrayAccess(void) { zend_class_entry ce, *class_entry; diff --git a/ext/zend_test/observer.c b/ext/zend_test/observer.c index 85c7d82da0e8..2fd4073b4af0 100644 --- a/ext/zend_test/observer.c +++ b/ext/zend_test/observer.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -18,6 +14,7 @@ #include "php_test.h" #include "observer.h" #include "zend_observer.h" +#include "zend_extensions.h" #include "zend_smart_str.h" #include "ext/standard/php_var.h" #include "zend_generators.h" @@ -78,6 +75,10 @@ static void observer_begin(zend_execute_data *execute_data) { assert_observer_opline(execute_data); + if (ZT_G(observer_set_vm_interrupt_on_begin)) { + zend_atomic_bool_store_ex(&EG(vm_interrupt), true); + } + if (!ZT_G(observer_show_output)) { return; } @@ -146,6 +147,14 @@ static void observer_end(zend_execute_data *execute_data, zval *retval) } } +static void (*zend_test_prev_interrupt_function)(zend_execute_data *execute_data); +static void zend_test_interrupt_function(zend_execute_data *execute_data) +{ + if (zend_test_prev_interrupt_function) { + zend_test_prev_interrupt_function(execute_data); + } +} + static void observer_show_init(zend_function *fbc) { if (fbc->common.function_name) { @@ -334,7 +343,8 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList) } if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) { ZEND_HASH_FOREACH_STR_KEY(*p, funcname) { - if ((func = zend_hash_find_ptr(EG(function_table), funcname))) { + if ((func = zend_hash_find_ptr(EG(function_table), funcname)) + && RUN_TIME_CACHE(&func->common)) { void *old_handler; zend_observer_remove_begin_handler(func, observer_begin, (zend_observer_fcall_begin_handler *)&old_handler); zend_observer_remove_end_handler(func, observer_end, (zend_observer_fcall_end_handler *)&old_handler); @@ -357,7 +367,11 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList) zend_string_release(str); if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) { ZEND_HASH_FOREACH_STR_KEY(*p, funcname) { - if ((func = zend_hash_find_ptr(EG(function_table), funcname))) { + if ((func = zend_hash_find_ptr(EG(function_table), funcname)) + && RUN_TIME_CACHE(&func->common) && *ZEND_OBSERVER_DATA(func)) { + void *old_handler; + zend_observer_remove_begin_handler(func, observer_begin, (zend_observer_fcall_begin_handler *)&old_handler); + zend_observer_remove_end_handler(func, observer_end, (zend_observer_fcall_end_handler *)&old_handler); zend_observer_add_begin_handler(func, observer_begin); zend_observer_add_end_handler(func, observer_end); } @@ -380,10 +394,12 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("zend_test.observer.show_init_backtrace", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_init_backtrace, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.show_opcode", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_opcode, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_ENTRY("zend_test.observer.show_opcode_in_user_handler", "", PHP_INI_SYSTEM, OnUpdateString, observer_show_opcode_in_user_handler, zend_zend_test_globals, zend_test_globals) + STD_PHP_INI_BOOLEAN("zend_test.observer.set_vm_interrupt_on_begin", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_set_vm_interrupt_on_begin, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_init", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_init, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_destroy", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_destroy, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.observer.execute_internal", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_execute_internal, zend_zend_test_globals, zend_test_globals) + STD_PHP_INI_BOOLEAN("zend_test.observer.reserve_op_array_handle", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_reserve_op_array_handle, zend_zend_test_globals, zend_test_globals) PHP_INI_END() void zend_test_observer_init(INIT_FUNC_ARGS) @@ -392,6 +408,9 @@ void zend_test_observer_init(INIT_FUNC_ARGS) if (type != MODULE_TEMPORARY) { REGISTER_INI_ENTRIES(); if (ZT_G(observer_enabled)) { + if (ZT_G(observer_reserve_op_array_handle)) { + zend_get_op_array_extension_handle("zend_test"); + } zend_observer_fcall_register(observer_fcall_init); } } else { @@ -417,10 +436,20 @@ void zend_test_observer_init(INIT_FUNC_ARGS) zend_test_prev_execute_internal = zend_execute_internal; zend_execute_internal = zend_test_execute_internal; } + + if (ZT_G(observer_set_vm_interrupt_on_begin)) { + zend_test_prev_interrupt_function = zend_interrupt_function; + zend_interrupt_function = zend_test_interrupt_function; + } } void zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS) { + if (zend_interrupt_function == zend_test_interrupt_function) { + zend_interrupt_function = zend_test_prev_interrupt_function; + zend_test_prev_interrupt_function = NULL; + } + if (type != MODULE_TEMPORARY) { UNREGISTER_INI_ENTRIES(); } diff --git a/ext/zend_test/observer.h b/ext/zend_test/observer.h index dd19fae2c527..28809a095cbe 100644 --- a/ext/zend_test/observer.h +++ b/ext/zend_test/observer.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index 7ec6f5431234..eb6ef6181c48 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -45,11 +41,13 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test) int observer_show_init_backtrace; int observer_show_opcode; char *observer_show_opcode_in_user_handler; + int observer_set_vm_interrupt_on_begin; int observer_nesting_depth; int observer_fiber_init; int observer_fiber_switch; int observer_fiber_destroy; int observer_execute_internal; + int observer_reserve_op_array_handle; HashTable *global_weakmap; int replace_zend_execute_ex; int register_passes; diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 0faf65f36437..a880c09fc1ff 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -43,6 +39,7 @@ #include "zend_mm_custom_handlers.h" #include "ext/uri/php_uri.h" #include "zend_observer.h" +#include "test_decl.h" #if defined(HAVE_LIBXML) && !defined(PHP_WIN32) # include @@ -57,6 +54,9 @@ static zend_class_entry *zend_test_child_class; static zend_class_entry *zend_test_gen_stub_flag_compatibility_test; static zend_class_entry *zend_attribute_test_class; static zend_class_entry *zend_test_trait; +static zend_class_entry *zend_test_trait_for_internal_class; +static zend_class_entry *zend_test_trait_for_internal_class2; +static zend_class_entry *zend_test_class_with_traits; static zend_class_entry *zend_test_attribute; static zend_class_entry *zend_test_repeatable_attribute; static zend_class_entry *zend_test_parameter_attribute; @@ -69,6 +69,7 @@ static zend_class_entry *zend_test_forbid_dynamic_call; static zend_class_entry *zend_test_ns_foo_class; static zend_class_entry *zend_test_ns_unlikely_compile_error_class; static zend_class_entry *zend_test_ns_not_unlikely_compile_error_class; +static zend_class_entry *zend_test_ns_bar_class; static zend_class_entry *zend_test_ns2_foo_class; static zend_class_entry *zend_test_ns2_ns_foo_class; static zend_class_entry *zend_test_unit_enum; @@ -347,7 +348,7 @@ static ZEND_FUNCTION(zend_number_or_string) RETURN_DOUBLE(Z_DVAL_P(input)); case IS_STRING: RETURN_STR_COPY(Z_STR_P(input)); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -371,7 +372,7 @@ static ZEND_FUNCTION(zend_number_or_string_or_null) RETURN_DOUBLE(Z_DVAL_P(input)); case IS_STRING: RETURN_STR_COPY(Z_STR_P(input)); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -546,13 +547,86 @@ static ZEND_FUNCTION(zend_call_method_if_exists) } RETURN_NULL(); } + if (Z_TYPE_P(return_value) == IS_REFERENCE) { + zend_unwrap_reference(return_value); + } +} + +static ZEND_FUNCTION(zend_test_call_with_consumed_args) +{ + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + zval *args; + zend_long consumed_args; + zval retval; + uint32_t actual_consumed_args = 0; + uint32_t i; + zend_result call_result; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_ARRAY(args) + Z_PARAM_LONG(consumed_args) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(consumed_args < 0 || consumed_args > UINT32_MAX)) { + zend_argument_value_error(3, "must be between 0 and 4294967295"); + RETURN_THROWS(); + } + + zend_fcall_info_args(&fci, args); + + ZVAL_UNDEF(&retval); + fci.retval = &retval; + fci.consumed_args = (uint32_t) consumed_args; + + call_result = zend_call_function(&fci, &fcc); + + for (i = 0; i < fci.param_count && i < 32; i++) { + if (Z_ISUNDEF(fci.params[i])) { + actual_consumed_args |= (1u << i); + } + } + + zend_fcall_info_args_clear(&fci, true); + + if (call_result == FAILURE || EG(exception)) { + if (!Z_ISUNDEF(retval)) { + zval_ptr_dtor(&retval); + } + RETURN_THROWS(); + } + + array_init(return_value); + add_assoc_long(return_value, "consumed_args", actual_consumed_args); + + if (Z_ISUNDEF(retval)) { + add_assoc_null(return_value, "retval"); + } else { + add_assoc_zval(return_value, "retval", &retval); + } +} + +static ZEND_FUNCTION(zend_test_refcount) +{ + zval *value; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(value) + ZEND_PARSE_PARAMETERS_END(); + + if (!Z_REFCOUNTED_P(value)) { + RETURN_LONG(-1); + } + + RETURN_LONG(Z_REFCOUNT_P(value)); } static ZEND_FUNCTION(zend_get_unit_enum) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_OBJ_COPY(zend_enum_get_case_cstr(zend_test_unit_enum, "Foo")); + RETURN_OBJ_COPY(zend_enum_get_case_by_id(zend_test_unit_enum, ZEND_ENUM_ZendTestUnitEnum_Foo)); } static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity) @@ -1047,7 +1121,7 @@ static zend_object *zend_test_class_new(zend_class_entry *class_type) static void zend_test_class_free_obj(zend_object *object) { - zend_test_object *intern = (zend_test_object*)((char*)object - XtOffsetOf(zend_test_object, std)); + zend_test_object *intern = ZEND_CONTAINER_OF(object, zend_test_object, std); if (intern->tmp_method) { zend_internal_function *func = intern->tmp_method; @@ -1062,7 +1136,7 @@ static void zend_test_class_free_obj(zend_object *object) static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) { - zend_test_object *intern = (zend_test_object*)((char*)(*object) - XtOffsetOf(zend_test_object, std)); + zend_test_object *intern = ZEND_CONTAINER_OF(*object, zend_test_object, std); if (zend_string_equals_literal_ci(name, "test")) { zend_internal_function *fptr; @@ -1234,6 +1308,18 @@ static ZEND_METHOD(_ZendTestTrait, testMethod) RETURN_TRUE; } +static ZEND_METHOD(_ZendTestTraitForInternalClass, traitMethod) +{ + ZEND_PARSE_PARAMETERS_NONE(); + RETURN_LONG(789); +} + +static ZEND_METHOD(_ZendTestTraitForInternalClass2, traitMethod2) +{ + ZEND_PARSE_PARAMETERS_NONE(); + RETURN_LONG(101); +} + static ZEND_METHOD(ZendTestNS_Foo, method) { ZEND_PARSE_PARAMETERS_NONE(); @@ -1529,13 +1615,16 @@ PHP_MINIT_FUNCTION(zend_test) zend_test_class_handlers.get_method = zend_test_class_method_get; zend_test_class_handlers.clone_obj = NULL; zend_test_class_handlers.free_obj = zend_test_class_free_obj; - zend_test_class_handlers.offset = XtOffsetOf(zend_test_object, std); + zend_test_class_handlers.offset = offsetof(zend_test_object, std); zend_test_gen_stub_flag_compatibility_test = register_class_ZendTestGenStubFlagCompatibilityTest(); zend_attribute_test_class = register_class_ZendAttributeTest(); zend_test_trait = register_class__ZendTestTrait(); + zend_test_trait_for_internal_class = register_class__ZendTestTraitForInternalClass(); + zend_test_trait_for_internal_class2 = register_class__ZendTestTraitForInternalClass2(); + zend_test_class_with_traits = register_class__ZendTestClassWithTraits(zend_test_trait_for_internal_class, zend_test_trait_for_internal_class2); register_test_symbols(module_number); @@ -1571,6 +1660,7 @@ PHP_MINIT_FUNCTION(zend_test) zend_test_ns_foo_class = register_class_ZendTestNS_Foo(); zend_test_ns_unlikely_compile_error_class = register_class_ZendTestNS_UnlikelyCompileError(); zend_test_ns_not_unlikely_compile_error_class = register_class_ZendTestNS_NotUnlikelyCompileError(); + zend_test_ns_bar_class = register_class_ZendTestNS_Bar(); zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo(); zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo(); @@ -1820,7 +1910,7 @@ typedef off_t off64_t; PHP_ZEND_TEST_API ssize_t copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, size_t len, unsigned int flags) { ssize_t (*original_copy_file_range)(int, off64_t *, int, off64_t *, size_t, unsigned int) = dlsym(RTLD_NEXT, "copy_file_range"); - if (ZT_G(limit_copy_file_range) >= Z_L(0)) { + if (ZT_G(limit_copy_file_range) >= Z_L(0) && ZT_G(limit_copy_file_range) < len) { len = ZT_G(limit_copy_file_range); } return original_copy_file_range(fd_in, off_in, fd_out, off_out, len, flags); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 63f9650f7ef6..7c96ea176a88 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -3,7 +3,7 @@ /** * @generate-class-entries static * @generate-c-enums - * @generate-legacy-arginfo 80000 + * @generate-legacy-arginfo 70000 * @undocumentable */ namespace { @@ -35,6 +35,32 @@ interface _ZendTestInterface public const DUMMY = 0; } + trait _ZendTestTraitForInternalClass + { + /** @var int */ + public const ZEND_TRAIT_CONST = 123; + + public int $traitProp = 456; + + public function traitMethod(): int {} + } + + trait _ZendTestTraitForInternalClass2 + { + /** @var int */ + public const ZEND_TRAIT_CONST2 = 321; + + public static int $staticTraitProp = 999; + + public function traitMethod2(): int {} + } + + class _ZendTestClassWithTraits + { + use _ZendTestTraitForInternalClass; + use _ZendTestTraitForInternalClass2; + } + /** @alias _ZendTestClassAlias */ class _ZendTestClass implements _ZendTestInterface { public const mixed TYPED_CLASS_CONST1 = []; @@ -57,6 +83,12 @@ class _ZendTestClass implements _ZendTestInterface { public static $_StaticProp; public static int $staticIntProp = 123; + /* If there's a problem with escapes in quotes in generated headers, + * the generated header won't compile. (tests/gh22169.phpt) */ + public static string $doubleQuoteEscaped = "BEGIN \n\r\t\v\e\f\\\$\"\101\x41\u{41} END"; + public static string $singleQuoteEscaped = 'BEGIN \n\r\t\v\e\f\\\$\"\101\x41\u{41} END'; + public static string $escapeInterpolated = "begin \$ \\$ end"; + public int $intProp = 123; public ?stdClass $classProp = null; public stdClass|Iterator|null $classUnionProp = null; @@ -187,7 +219,9 @@ class ZendTestClassWithPropertyAttribute { } final class ZendTestForbidDynamicCall { + /** @forbid-dynamic-calls */ public function call(): void {} + /** @forbid-dynamic-calls */ public static function callStatic(): void {} } @@ -303,6 +337,10 @@ function zend_object_init_with_constructor(string $class, mixed ...$args): mixed function zend_call_method_if_exists(object $obj, string $method, mixed ...$args): mixed {} + function zend_test_call_with_consumed_args(callable $cb, array $args, int $consumed_args): array {} + + function zend_test_refcount(mixed $value): int {} + function zend_test_zend_ini_parse_quantity(string $str): int {} function zend_test_zend_ini_parse_uquantity(string $str): int {} @@ -363,6 +401,8 @@ class Foo { public function method(): int {} } + interface Bar {} + class UnlikelyCompileError { /* This method signature would create a compile error due to the string * "ZendTestNS\UnlikelyCompileError" in the generated macro call */ @@ -378,11 +418,20 @@ public function method(): ?NotUnlikelyCompileError {} namespace ZendTestNS2 { + use ZendTestNS\Foo as FooAlias; + use ZendTestNS\UnlikelyCompileError; + use ZendTestNS\{NotUnlikelyCompileError}; + /** @var string */ const ZEND_CONSTANT_A = "namespaced"; class Foo { public ZendSubNS\Foo $foo; + public ZendSubNS\Foo&\ZendTestNS\Bar $intersectionProp; + public ZendSubNS\Foo|\ZendTestNS\Bar $unionProp; + public FooAlias $fooAlias; + public UnlikelyCompileError $unlProp; + public NotUnlikelyCompileError $notUnlProp; public function method(): void {} } diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 6b5dfe9c2567..b2e342382db7 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit test.stub.php instead. - * Stub hash: 0dc403dd439157aa09ae0692b295092bdc59c1d0 + * Stub hash: a221a3df3815679d61fd546ba120fd3a374fe71f * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, IS_NEVER, 0) @@ -123,6 +123,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_call_method_if_exists, 0, 2 ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_call_with_consumed_args, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, cb, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, args, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, consumed_args, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_refcount, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_ini_parse_quantity, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -216,6 +226,10 @@ ZEND_END_ARG_INFO() #define arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_aliased_func arginfo_zend_test_void_return +#define arginfo_class__ZendTestTraitForInternalClass_traitMethod arginfo_zend_test_nodiscard + +#define arginfo_class__ZendTestTraitForInternalClass2_traitMethod2 arginfo_zend_test_nodiscard + #define arginfo_class__ZendTestClass_is_object arginfo_zend_test_nodiscard #define arginfo_class__ZendTestClass___toString arginfo_zend_get_current_func_name @@ -316,6 +330,8 @@ static ZEND_FUNCTION(zend_get_current_func_name); static ZEND_FUNCTION(zend_call_method); static ZEND_FUNCTION(zend_object_init_with_constructor); static ZEND_FUNCTION(zend_call_method_if_exists); +static ZEND_FUNCTION(zend_test_call_with_consumed_args); +static ZEND_FUNCTION(zend_test_refcount); static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity); static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity); static ZEND_FUNCTION(zend_test_zend_ini_str); @@ -349,6 +365,8 @@ static ZEND_FUNCTION(ZendTestNS2_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func); static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func); +static ZEND_METHOD(_ZendTestTraitForInternalClass, traitMethod); +static ZEND_METHOD(_ZendTestTraitForInternalClass2, traitMethod2); static ZEND_METHOD(_ZendTestClass, is_object); static ZEND_METHOD(_ZendTestClass, __toString); static ZEND_METHOD(_ZendTestClass, returnsStatic); @@ -448,6 +466,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_call_method, arginfo_zend_call_method) ZEND_FE(zend_object_init_with_constructor, arginfo_zend_object_init_with_constructor) ZEND_FE(zend_call_method_if_exists, arginfo_zend_call_method_if_exists) + ZEND_FE(zend_test_call_with_consumed_args, arginfo_zend_test_call_with_consumed_args) + ZEND_FE(zend_test_refcount, arginfo_zend_test_refcount) ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity) ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity) ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str) @@ -528,6 +548,16 @@ static const zend_function_entry ext_functions[] = { ZEND_FE_END }; +static const zend_function_entry class__ZendTestTraitForInternalClass_methods[] = { + ZEND_ME(_ZendTestTraitForInternalClass, traitMethod, arginfo_class__ZendTestTraitForInternalClass_traitMethod, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestTraitForInternalClass2_methods[] = { + ZEND_ME(_ZendTestTraitForInternalClass2, traitMethod2, arginfo_class__ZendTestTraitForInternalClass2_traitMethod2, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static const zend_function_entry class__ZendTestClass_methods[] = { ZEND_ME(_ZendTestClass, is_object, arginfo_class__ZendTestClass_is_object, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(_ZendTestClass, __toString, arginfo_class__ZendTestClass___toString, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) @@ -590,8 +620,16 @@ static const zend_function_entry class_ZendTestChildClassWithMethodWithParameter }; static const zend_function_entry class_ZendTestForbidDynamicCall_methods[] = { +#if (PHP_VERSION_ID >= 80600) + ZEND_ME(ZendTestForbidDynamicCall, call, arginfo_class_ZendTestForbidDynamicCall_call, ZEND_FENTRY_FLAGS(ZEND_ACC_PUBLIC, ZEND_ACC2_FORBID_DYN_CALLS)) +#elif (PHP_VERSION_ID >= 80000) ZEND_ME(ZendTestForbidDynamicCall, call, arginfo_class_ZendTestForbidDynamicCall_call, ZEND_ACC_PUBLIC) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_ME(ZendTestForbidDynamicCall, callStatic, arginfo_class_ZendTestForbidDynamicCall_callStatic, ZEND_FENTRY_FLAGS(ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, ZEND_ACC2_FORBID_DYN_CALLS)) +#elif (PHP_VERSION_ID >= 80000) ZEND_ME(ZendTestForbidDynamicCall, callStatic, arginfo_class_ZendTestForbidDynamicCall_callStatic, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) +#endif ZEND_FE_END }; @@ -698,6 +736,75 @@ static zend_class_entry *register_class__ZendTestInterface(void) return class_entry; } +static zend_class_entry *register_class__ZendTestTraitForInternalClass(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestTraitForInternalClass", class__ZendTestTraitForInternalClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif + + zval const_ZEND_TRAIT_CONST_value; + ZVAL_LONG(&const_ZEND_TRAIT_CONST_value, 123); + zend_string *const_ZEND_TRAIT_CONST_name = zend_string_init_interned("ZEND_TRAIT_CONST", sizeof("ZEND_TRAIT_CONST") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TRAIT_CONST_name, &const_ZEND_TRAIT_CONST_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TRAIT_CONST_name, true); + + zval property_traitProp_default_value; + ZVAL_LONG(&property_traitProp_default_value, 456); + zend_string *property_traitProp_name = zend_string_init("traitProp", sizeof("traitProp") - 1, true); + zend_declare_typed_property(class_entry, property_traitProp_name, &property_traitProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(property_traitProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestTraitForInternalClass2(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestTraitForInternalClass2", class__ZendTestTraitForInternalClass2_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif + + zval const_ZEND_TRAIT_CONST2_value; + ZVAL_LONG(&const_ZEND_TRAIT_CONST2_value, 321); + zend_string *const_ZEND_TRAIT_CONST2_name = zend_string_init_interned("ZEND_TRAIT_CONST2", sizeof("ZEND_TRAIT_CONST2") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TRAIT_CONST2_name, &const_ZEND_TRAIT_CONST2_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TRAIT_CONST2_name, true); + + zval property_staticTraitProp_default_value; + ZVAL_LONG(&property_staticTraitProp_default_value, 999); + zend_string *property_staticTraitProp_name = zend_string_init("staticTraitProp", sizeof("staticTraitProp") - 1, true); + zend_declare_typed_property(class_entry, property_staticTraitProp_name, &property_staticTraitProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(property_staticTraitProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestClassWithTraits(zend_class_entry *class_entry__ZendTestTraitForInternalClass, zend_class_entry *class_entry__ZendTestTraitForInternalClass2) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestClassWithTraits", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + zend_class_use_internal_traits(class_entry, 2, class_entry__ZendTestTraitForInternalClass, class_entry__ZendTestTraitForInternalClass2); + + return class_entry; +} + static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_entry__ZendTestInterface) { zend_class_entry ce, *class_entry; @@ -773,6 +880,27 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zend_declare_typed_property(class_entry, property_staticIntProp_name, &property_staticIntProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release_ex(property_staticIntProp_name, true); + zval property_doubleQuoteEscaped_default_value; + zend_string *property_doubleQuoteEscaped_default_value_str = zend_string_init("BEGIN \n\r\t\v\x1b\f\\$\"AAA END", strlen("BEGIN \n\r\t\v\x1b\f\\$\"AAA END"), 1); + ZVAL_STR(&property_doubleQuoteEscaped_default_value, property_doubleQuoteEscaped_default_value_str); + zend_string *property_doubleQuoteEscaped_name = zend_string_init("doubleQuoteEscaped", sizeof("doubleQuoteEscaped") - 1, true); + zend_declare_typed_property(class_entry, property_doubleQuoteEscaped_name, &property_doubleQuoteEscaped_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_doubleQuoteEscaped_name, true); + + zval property_singleQuoteEscaped_default_value; + zend_string *property_singleQuoteEscaped_default_value_str = zend_string_init("BEGIN \\n\\r\\t\\v\\e\\f\\\\\\\\$\\\"\\101\\x41\\u{41} END", strlen("BEGIN \\n\\r\\t\\v\\e\\f\\\\\\\\$\\\"\\101\\x41\\u{41} END"), 1); + ZVAL_STR(&property_singleQuoteEscaped_default_value, property_singleQuoteEscaped_default_value_str); + zend_string *property_singleQuoteEscaped_name = zend_string_init("singleQuoteEscaped", sizeof("singleQuoteEscaped") - 1, true); + zend_declare_typed_property(class_entry, property_singleQuoteEscaped_name, &property_singleQuoteEscaped_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_singleQuoteEscaped_name, true); + + zval property_escapeInterpolated_default_value; + zend_string *property_escapeInterpolated_default_value_str = zend_string_init("begin $ \\$ end", strlen("begin $ \\$ end"), 1); + ZVAL_STR(&property_escapeInterpolated_default_value, property_escapeInterpolated_default_value_str); + zend_string *property_escapeInterpolated_name = zend_string_init("escapeInterpolated", sizeof("escapeInterpolated") - 1, true); + zend_declare_typed_property(class_entry, property_escapeInterpolated_name, &property_escapeInterpolated_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_escapeInterpolated_name, true); + zval property_intProp_default_value; ZVAL_LONG(&property_intProp_default_value, 123); zend_string *property_intProp_name = zend_string_init("intProp", sizeof("intProp") - 1, true); @@ -1294,6 +1422,16 @@ static zend_class_entry *register_class_ZendTestNS_Foo(void) return class_entry; } +static zend_class_entry *register_class_ZendTestNS_Bar(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "Bar", NULL); + class_entry = zend_register_internal_interface(&ce); + + return class_entry; +} + static zend_class_entry *register_class_ZendTestNS_UnlikelyCompileError(void) { zend_class_entry ce, *class_entry; @@ -1340,6 +1478,53 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void) zend_declare_typed_property(class_entry, property_foo_name, &property_foo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_foo_class_ZendTestNS2_ZendSubNS_Foo, 0, 0)); zend_string_release_ex(property_foo_name, true); + zval property_intersectionProp_default_value; + ZVAL_UNDEF(&property_intersectionProp_default_value); + zend_string *property_intersectionProp_name = zend_string_init("intersectionProp", sizeof("intersectionProp") - 1, true); + zend_string *property_intersectionProp_class_ZendTestNS2_ZendSubNS_Foo = zend_string_init("ZendTestNS2\\ZendSubNS\\Foo", sizeof("ZendTestNS2\\ZendSubNS\\Foo") - 1, 1); + zend_string *property_intersectionProp_class_ZendTestNS_Bar = zend_string_init("ZendTestNS\\Bar", sizeof("ZendTestNS\\Bar") - 1, 1); + zend_type_list *property_intersectionProp_type_list = malloc(ZEND_TYPE_LIST_SIZE(2)); + property_intersectionProp_type_list->num_types = 2; + property_intersectionProp_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(property_intersectionProp_class_ZendTestNS2_ZendSubNS_Foo, 0, 0); + property_intersectionProp_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(property_intersectionProp_class_ZendTestNS_Bar, 0, 0); + zend_type property_intersectionProp_type = ZEND_TYPE_INIT_INTERSECTION(property_intersectionProp_type_list, 0); + zend_declare_typed_property(class_entry, property_intersectionProp_name, &property_intersectionProp_default_value, ZEND_ACC_PUBLIC, NULL, property_intersectionProp_type); + zend_string_release_ex(property_intersectionProp_name, true); + + zval property_unionProp_default_value; + ZVAL_UNDEF(&property_unionProp_default_value); + zend_string *property_unionProp_name = zend_string_init("unionProp", sizeof("unionProp") - 1, true); + zend_string *property_unionProp_class_ZendTestNS2_ZendSubNS_Foo = zend_string_init("ZendTestNS2\\ZendSubNS\\Foo", sizeof("ZendTestNS2\\ZendSubNS\\Foo") - 1, 1); + zend_string *property_unionProp_class_ZendTestNS_Bar = zend_string_init("ZendTestNS\\Bar", sizeof("ZendTestNS\\Bar") - 1, 1); + zend_type_list *property_unionProp_type_list = malloc(ZEND_TYPE_LIST_SIZE(2)); + property_unionProp_type_list->num_types = 2; + property_unionProp_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(property_unionProp_class_ZendTestNS2_ZendSubNS_Foo, 0, 0); + property_unionProp_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(property_unionProp_class_ZendTestNS_Bar, 0, 0); + zend_type property_unionProp_type = ZEND_TYPE_INIT_UNION(property_unionProp_type_list, 0); + zend_declare_typed_property(class_entry, property_unionProp_name, &property_unionProp_default_value, ZEND_ACC_PUBLIC, NULL, property_unionProp_type); + zend_string_release_ex(property_unionProp_name, true); + + zval property_fooAlias_default_value; + ZVAL_UNDEF(&property_fooAlias_default_value); + zend_string *property_fooAlias_name = zend_string_init("fooAlias", sizeof("fooAlias") - 1, true); + zend_string *property_fooAlias_class_ZendTestNS_Foo = zend_string_init("ZendTestNS\\Foo", sizeof("ZendTestNS\\Foo")-1, 1); + zend_declare_typed_property(class_entry, property_fooAlias_name, &property_fooAlias_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_fooAlias_class_ZendTestNS_Foo, 0, 0)); + zend_string_release_ex(property_fooAlias_name, true); + + zval property_unlProp_default_value; + ZVAL_UNDEF(&property_unlProp_default_value); + zend_string *property_unlProp_name = zend_string_init("unlProp", sizeof("unlProp") - 1, true); + zend_string *property_unlProp_class_ZendTestNS_UnlikelyCompileError = zend_string_init("ZendTestNS\\\125nlikelyCompileError", sizeof("ZendTestNS\\\125nlikelyCompileError")-1, 1); + zend_declare_typed_property(class_entry, property_unlProp_name, &property_unlProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_unlProp_class_ZendTestNS_UnlikelyCompileError, 0, 0)); + zend_string_release_ex(property_unlProp_name, true); + + zval property_notUnlProp_default_value; + ZVAL_UNDEF(&property_notUnlProp_default_value); + zend_string *property_notUnlProp_name = zend_string_init("notUnlProp", sizeof("notUnlProp") - 1, true); + zend_string *property_notUnlProp_class_ZendTestNS_NotUnlikelyCompileError = zend_string_init("ZendTestNS\\\116otUnlikelyCompileError", sizeof("ZendTestNS\\\116otUnlikelyCompileError")-1, 1); + zend_declare_typed_property(class_entry, property_notUnlProp_name, &property_notUnlProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notUnlProp_class_ZendTestNS_NotUnlikelyCompileError, 0, 0)); + zend_string_release_ex(property_notUnlProp_name, true); + return class_entry; } diff --git a/ext/zend_test/test_decl.h b/ext/zend_test/test_decl.h index a6254865a87a..ea6a2c94fbdf 100644 --- a/ext/zend_test/test_decl.h +++ b/ext/zend_test/test_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit test.stub.php instead. - * Stub hash: 0dc403dd439157aa09ae0692b295092bdc59c1d0 */ + * Stub hash: a221a3df3815679d61fd546ba120fd3a374fe71f */ -#ifndef ZEND_TEST_DECL_0dc403dd439157aa09ae0692b295092bdc59c1d0_H -#define ZEND_TEST_DECL_0dc403dd439157aa09ae0692b295092bdc59c1d0_H +#ifndef ZEND_TEST_DECL_a221a3df3815679d61fd546ba120fd3a374fe71f_H +#define ZEND_TEST_DECL_a221a3df3815679d61fd546ba120fd3a374fe71f_H typedef enum zend_enum_ZendTestUnitEnum { ZEND_ENUM_ZendTestUnitEnum_Foo = 1, @@ -27,4 +27,4 @@ typedef enum zend_enum_ZendTestEnumWithInterface { ZEND_ENUM_ZendTestEnumWithInterface_Bar = 2, } zend_enum_ZendTestEnumWithInterface; -#endif /* ZEND_TEST_DECL_0dc403dd439157aa09ae0692b295092bdc59c1d0_H */ +#endif /* ZEND_TEST_DECL_a221a3df3815679d61fd546ba120fd3a374fe71f_H */ diff --git a/ext/zend_test/test_legacy_arginfo.h b/ext/zend_test/test_legacy_arginfo.h new file mode 100644 index 000000000000..05014c80fd5d --- /dev/null +++ b/ext/zend_test/test_legacy_arginfo.h @@ -0,0 +1,1260 @@ +/* This is a generated file, edit test.stub.php instead. + * Stub hash: a221a3df3815679d61fd546ba120fd3a374fe71f + * Has decl header: yes */ + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, 0) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_array_return arginfo_zend_trigger_bailout + +#define arginfo_zend_test_nullable_array_return arginfo_zend_trigger_bailout + +#define arginfo_zend_test_void_return arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_compile_string, 0, 0, 3) + ZEND_ARG_INFO(0, source_string) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, position) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_deprecated, 0, 0, 0) + ZEND_ARG_INFO(0, arg) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_deprecated_attr arginfo_zend_trigger_bailout + +#define arginfo_zend_test_nodiscard arginfo_zend_trigger_bailout + +#define arginfo_zend_test_deprecated_nodiscard arginfo_zend_trigger_bailout + +#define arginfo_zend_test_aliased arginfo_zend_trigger_bailout + +#define arginfo_zend_test_deprecated_aliased arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_create_unterminated_string, 0, 0, 1) + ZEND_ARG_INFO(0, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_terminate_string, 0, 0, 1) + ZEND_ARG_INFO(1, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_leak_variable, 0, 0, 1) + ZEND_ARG_INFO(0, variable) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_leak_bytes, 0, 0, 0) + ZEND_ARG_INFO(0, bytes) +ZEND_END_ARG_INFO() + +#define arginfo_zend_delref arginfo_zend_leak_variable + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_string_or_object, 0, 0, 1) + ZEND_ARG_INFO(0, param) +ZEND_END_ARG_INFO() + +#define arginfo_zend_string_or_object_or_null arginfo_zend_string_or_object + +#define arginfo_zend_string_or_stdclass arginfo_zend_string_or_object + +#define arginfo_zend_string_or_stdclass_or_null arginfo_zend_string_or_object + +#define arginfo_zend_number_or_string arginfo_zend_string_or_object + +#define arginfo_zend_number_or_string_or_null arginfo_zend_string_or_object + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_iterable, 0, 0, 1) + ZEND_ARG_INFO(0, arg1) + ZEND_ARG_INFO(0, arg2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_weakmap_attach, 0, 0, 2) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_weakmap_remove, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +#define arginfo_zend_weakmap_dump arginfo_zend_trigger_bailout + +#define arginfo_zend_get_unit_enum arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_parameter_with_attribute, 0, 0, 1) + ZEND_ARG_INFO(0, parameter) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_attribute_with_named_argument arginfo_zend_trigger_bailout + +#define arginfo_zend_get_current_func_name arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_call_method, 0, 0, 2) + ZEND_ARG_INFO(0, obj_or_class) + ZEND_ARG_INFO(0, method) + ZEND_ARG_INFO(0, arg1) + ZEND_ARG_INFO(0, arg2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_object_init_with_constructor, 0, 0, 1) + ZEND_ARG_INFO(0, class) + ZEND_ARG_VARIADIC_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_call_method_if_exists, 0, 0, 2) + ZEND_ARG_INFO(0, obj) + ZEND_ARG_INFO(0, method) + ZEND_ARG_VARIADIC_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_call_with_consumed_args, 0, 0, 3) + ZEND_ARG_INFO(0, cb) + ZEND_ARG_INFO(0, args) + ZEND_ARG_INFO(0, consumed_args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_refcount, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_zend_ini_parse_quantity arginfo_zend_create_unterminated_string + +#define arginfo_zend_test_zend_ini_parse_uquantity arginfo_zend_create_unterminated_string + +#define arginfo_zend_test_zend_ini_str arginfo_zend_trigger_bailout + +#define arginfo_zend_test_zstr_init_literal arginfo_zend_trigger_bailout + +#if defined(ZEND_CHECK_STACK_LIMIT) +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_zend_call_stack_get, 0, 0, 0) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_zend_call_stack_use_all arginfo_zend_test_zend_call_stack_get +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_is_string_marked_as_valid_utf8, 0, 0, 1) + ZEND_ARG_INFO(0, string) +ZEND_END_ARG_INFO() + +#define arginfo_zend_get_map_ptr_last arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_crash, 0, 0, 0) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_fill_packed_array, 0, 0, 1) + ZEND_ARG_INFO(1, array) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_create_throwing_resource arginfo_zend_trigger_bailout + +#define arginfo_get_open_basedir arginfo_zend_trigger_bailout + +#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_override_libxml_global_state, 0, 0, 0) +ZEND_END_ARG_INFO() +#endif + +#define arginfo_zend_test_is_pcre_bundled arginfo_zend_trigger_bailout + +#if defined(PHP_WIN32) +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_set_fmode, 0, 0, 1) + ZEND_ARG_INFO(0, binary) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_cast_fread, 0, 0, 1) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_is_zend_ptr, 0, 0, 1) + ZEND_ARG_INFO(0, addr) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_log_err_debug arginfo_zend_create_unterminated_string + +#define arginfo_zend_test_compile_to_ast arginfo_zend_create_unterminated_string + +#define arginfo_zend_test_gh18756 arginfo_zend_trigger_bailout + +#define arginfo_zend_test_opcache_preloading arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_test_uri_parser, 0, 0, 2) + ZEND_ARG_INFO(0, uri) + ZEND_ARG_INFO(0, parser) +ZEND_END_ARG_INFO() + +#define arginfo_zend_test_gh19792 arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_namespaced_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_namespaced_deprecated_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_namespaced_aliased_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_namespaced_deprecated_aliased_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_ZendSubNS_namespaced_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_ZendSubNS_namespaced_aliased_func arginfo_zend_trigger_bailout + +#define arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_aliased_func arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestTraitForInternalClass_traitMethod arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestTraitForInternalClass2_traitMethod2 arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestClass_is_object arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestClass___toString arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestClass_returnsStatic arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestClass_returnsThrowable arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class__ZendTestClass_variadicTest, 0, 0, 0) + ZEND_ARG_VARIADIC_INFO(0, elements) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class__ZendTestClass_takesUnionType, 0, 0, 1) + ZEND_ARG_INFO(0, arg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class__ZendTestMagicCall___call, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +#define arginfo_class__ZendTestMagicCallForward___call arginfo_class__ZendTestMagicCall___call + +#define arginfo_class__ZendTestChildClass_returnsThrowable arginfo_zend_trigger_bailout + +#define arginfo_class_ZendAttributeTest_testMethod arginfo_zend_trigger_bailout + +#define arginfo_class__ZendTestTrait_testMethod arginfo_zend_trigger_bailout + +#define arginfo_class_ZendTestAttributeWithArguments___construct arginfo_class__ZendTestClass_takesUnionType + +#define arginfo_class_ZendTestParameterAttribute___construct arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestPropertyAttribute___construct arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestForbidDynamicCall_call arginfo_zend_trigger_bailout + +#define arginfo_class_ZendTestForbidDynamicCall_callStatic arginfo_zend_trigger_bailout + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestNS_Foo_method, 0, 0, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ZendTestNS_UnlikelyCompileError_method arginfo_zend_trigger_bailout + +#define arginfo_class_ZendTestNS_NotUnlikelyCompileError_method arginfo_zend_trigger_bailout + +#define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_trigger_bailout + +#define arginfo_class_ZendTestNS2_ZendSubNS_Foo_method arginfo_zend_trigger_bailout + +static ZEND_FUNCTION(zend_trigger_bailout); +static ZEND_FUNCTION(zend_test_array_return); +static ZEND_FUNCTION(zend_test_nullable_array_return); +static ZEND_FUNCTION(zend_test_void_return); +static ZEND_FUNCTION(zend_test_compile_string); +static ZEND_FUNCTION(zend_test_deprecated); +static ZEND_FUNCTION(zend_test_deprecated_attr); +static ZEND_FUNCTION(zend_test_nodiscard); +static ZEND_FUNCTION(zend_test_deprecated_nodiscard); +static ZEND_FUNCTION(zend_create_unterminated_string); +static ZEND_FUNCTION(zend_terminate_string); +static ZEND_FUNCTION(zend_leak_variable); +static ZEND_FUNCTION(zend_leak_bytes); +static ZEND_FUNCTION(zend_delref); +static ZEND_FUNCTION(zend_string_or_object); +static ZEND_FUNCTION(zend_string_or_object_or_null); +static ZEND_FUNCTION(zend_string_or_stdclass); +static ZEND_FUNCTION(zend_string_or_stdclass_or_null); +static ZEND_FUNCTION(zend_number_or_string); +static ZEND_FUNCTION(zend_number_or_string_or_null); +static ZEND_FUNCTION(zend_iterable); +static ZEND_FUNCTION(zend_weakmap_attach); +static ZEND_FUNCTION(zend_weakmap_remove); +static ZEND_FUNCTION(zend_weakmap_dump); +static ZEND_FUNCTION(zend_get_unit_enum); +static ZEND_FUNCTION(zend_test_parameter_with_attribute); +static ZEND_FUNCTION(zend_test_attribute_with_named_argument); +static ZEND_FUNCTION(zend_get_current_func_name); +static ZEND_FUNCTION(zend_call_method); +static ZEND_FUNCTION(zend_object_init_with_constructor); +static ZEND_FUNCTION(zend_call_method_if_exists); +static ZEND_FUNCTION(zend_test_call_with_consumed_args); +static ZEND_FUNCTION(zend_test_refcount); +static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity); +static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity); +static ZEND_FUNCTION(zend_test_zend_ini_str); +static ZEND_FUNCTION(zend_test_zstr_init_literal); +#if defined(ZEND_CHECK_STACK_LIMIT) +static ZEND_FUNCTION(zend_test_zend_call_stack_get); +static ZEND_FUNCTION(zend_test_zend_call_stack_use_all); +#endif +static ZEND_FUNCTION(zend_test_is_string_marked_as_valid_utf8); +static ZEND_FUNCTION(zend_get_map_ptr_last); +static ZEND_FUNCTION(zend_test_crash); +static ZEND_FUNCTION(zend_test_fill_packed_array); +static ZEND_FUNCTION(zend_test_create_throwing_resource); +static ZEND_FUNCTION(get_open_basedir); +#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) +static ZEND_FUNCTION(zend_test_override_libxml_global_state); +#endif +static ZEND_FUNCTION(zend_test_is_pcre_bundled); +#if defined(PHP_WIN32) +static ZEND_FUNCTION(zend_test_set_fmode); +#endif +static ZEND_FUNCTION(zend_test_cast_fread); +static ZEND_FUNCTION(zend_test_is_zend_ptr); +static ZEND_FUNCTION(zend_test_log_err_debug); +static ZEND_FUNCTION(zend_test_compile_to_ast); +static ZEND_FUNCTION(zend_test_gh18756); +static ZEND_FUNCTION(zend_test_opcache_preloading); +static ZEND_FUNCTION(zend_test_uri_parser); +static ZEND_FUNCTION(zend_test_gh19792); +static ZEND_FUNCTION(ZendTestNS2_namespaced_func); +static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func); +static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func); +static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func); +static ZEND_METHOD(_ZendTestTraitForInternalClass, traitMethod); +static ZEND_METHOD(_ZendTestTraitForInternalClass2, traitMethod2); +static ZEND_METHOD(_ZendTestClass, is_object); +static ZEND_METHOD(_ZendTestClass, __toString); +static ZEND_METHOD(_ZendTestClass, returnsStatic); +static ZEND_METHOD(_ZendTestClass, returnsThrowable); +static ZEND_METHOD(_ZendTestClass, variadicTest); +static ZEND_METHOD(_ZendTestClass, takesUnionType); +static ZEND_METHOD(_ZendTestMagicCall, __call); +static ZEND_METHOD(_ZendTestMagicCallForward, __call); +static ZEND_METHOD(_ZendTestChildClass, returnsThrowable); +static ZEND_METHOD(ZendAttributeTest, testMethod); +static ZEND_METHOD(_ZendTestTrait, testMethod); +static ZEND_METHOD(ZendTestAttributeWithArguments, __construct); +static ZEND_METHOD(ZendTestParameterAttribute, __construct); +static ZEND_METHOD(ZendTestPropertyAttribute, __construct); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override); +static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override); +static ZEND_METHOD(ZendTestForbidDynamicCall, call); +static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic); +static ZEND_METHOD(ZendTestNS_Foo, method); +static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method); +static ZEND_METHOD(ZendTestNS_NotUnlikelyCompileError, method); +static ZEND_METHOD(ZendTestNS2_Foo, method); +static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method); + +static const zend_function_entry ext_functions[] = { + ZEND_FE(zend_trigger_bailout, arginfo_zend_trigger_bailout) + ZEND_FE(zend_test_array_return, arginfo_zend_test_array_return) + ZEND_FE(zend_test_nullable_array_return, arginfo_zend_test_nullable_array_return) + ZEND_FE(zend_test_void_return, arginfo_zend_test_void_return) + ZEND_FE(zend_test_compile_string, arginfo_zend_test_compile_string) +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("zend_test_deprecated", zif_zend_test_deprecated, arginfo_zend_test_deprecated, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY("zend_test_deprecated", zif_zend_test_deprecated, arginfo_zend_test_deprecated, ZEND_ACC_DEPRECATED) +#endif + ZEND_FE(zend_test_deprecated_attr, arginfo_zend_test_deprecated_attr) + ZEND_FE(zend_test_nodiscard, arginfo_zend_test_nodiscard) + ZEND_FE(zend_test_deprecated_nodiscard, arginfo_zend_test_deprecated_nodiscard) +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("zend_test_aliased", zif_zend_test_void_return, arginfo_zend_test_aliased, 0, NULL, NULL) +#else + ZEND_RAW_FENTRY("zend_test_aliased", zif_zend_test_void_return, arginfo_zend_test_aliased, 0) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("zend_test_deprecated_aliased", zif_zend_test_void_return, arginfo_zend_test_deprecated_aliased, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY("zend_test_deprecated_aliased", zif_zend_test_void_return, arginfo_zend_test_deprecated_aliased, ZEND_ACC_DEPRECATED) +#endif + ZEND_FE(zend_create_unterminated_string, arginfo_zend_create_unterminated_string) + ZEND_FE(zend_terminate_string, arginfo_zend_terminate_string) + ZEND_FE(zend_leak_variable, arginfo_zend_leak_variable) + ZEND_FE(zend_leak_bytes, arginfo_zend_leak_bytes) + ZEND_FE(zend_delref, arginfo_zend_delref) + ZEND_FE(zend_string_or_object, arginfo_zend_string_or_object) + ZEND_FE(zend_string_or_object_or_null, arginfo_zend_string_or_object_or_null) + ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass) + ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null) + ZEND_FE(zend_number_or_string, arginfo_zend_number_or_string) + ZEND_FE(zend_number_or_string_or_null, arginfo_zend_number_or_string_or_null) + ZEND_FE(zend_iterable, arginfo_zend_iterable) + ZEND_FE(zend_weakmap_attach, arginfo_zend_weakmap_attach) + ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove) + ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump) + ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum) + ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute) + ZEND_FE(zend_test_attribute_with_named_argument, arginfo_zend_test_attribute_with_named_argument) + ZEND_FE(zend_get_current_func_name, arginfo_zend_get_current_func_name) + ZEND_FE(zend_call_method, arginfo_zend_call_method) + ZEND_FE(zend_object_init_with_constructor, arginfo_zend_object_init_with_constructor) + ZEND_FE(zend_call_method_if_exists, arginfo_zend_call_method_if_exists) + ZEND_FE(zend_test_call_with_consumed_args, arginfo_zend_test_call_with_consumed_args) + ZEND_FE(zend_test_refcount, arginfo_zend_test_refcount) + ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity) + ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity) + ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str) + ZEND_FE(zend_test_zstr_init_literal, arginfo_zend_test_zstr_init_literal) +#if defined(ZEND_CHECK_STACK_LIMIT) + ZEND_FE(zend_test_zend_call_stack_get, arginfo_zend_test_zend_call_stack_get) + ZEND_FE(zend_test_zend_call_stack_use_all, arginfo_zend_test_zend_call_stack_use_all) +#endif + ZEND_FE(zend_test_is_string_marked_as_valid_utf8, arginfo_zend_test_is_string_marked_as_valid_utf8) + ZEND_FE(zend_get_map_ptr_last, arginfo_zend_get_map_ptr_last) + ZEND_FE(zend_test_crash, arginfo_zend_test_crash) + ZEND_FE(zend_test_fill_packed_array, arginfo_zend_test_fill_packed_array) + ZEND_FE(zend_test_create_throwing_resource, arginfo_zend_test_create_throwing_resource) + ZEND_FE(get_open_basedir, arginfo_get_open_basedir) +#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) + ZEND_FE(zend_test_override_libxml_global_state, arginfo_zend_test_override_libxml_global_state) +#endif + ZEND_FE(zend_test_is_pcre_bundled, arginfo_zend_test_is_pcre_bundled) +#if defined(PHP_WIN32) + ZEND_FE(zend_test_set_fmode, arginfo_zend_test_set_fmode) +#endif + ZEND_FE(zend_test_cast_fread, arginfo_zend_test_cast_fread) + ZEND_FE(zend_test_is_zend_ptr, arginfo_zend_test_is_zend_ptr) + ZEND_FE(zend_test_log_err_debug, arginfo_zend_test_log_err_debug) + ZEND_FE(zend_test_compile_to_ast, arginfo_zend_test_compile_to_ast) + ZEND_FE(zend_test_gh18756, arginfo_zend_test_gh18756) + ZEND_FE(zend_test_opcache_preloading, arginfo_zend_test_opcache_preloading) + ZEND_FE(zend_test_uri_parser, arginfo_zend_test_uri_parser) + ZEND_FE(zend_test_gh19792, arginfo_zend_test_gh19792) +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_deprecated_func"), zif_ZendTestNS2_namespaced_deprecated_func, arginfo_ZendTestNS2_namespaced_deprecated_func, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_deprecated_func"), zif_ZendTestNS2_namespaced_deprecated_func, arginfo_ZendTestNS2_namespaced_deprecated_func, ZEND_ACC_DEPRECATED) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_namespaced_aliased_func, 0, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_namespaced_aliased_func, 0) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_deprecated_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_namespaced_deprecated_aliased_func, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_deprecated_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_namespaced_deprecated_aliased_func, ZEND_ACC_DEPRECATED) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_func"), zif_ZendTestNS2_ZendSubNS_namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_func"), zif_ZendTestNS2_ZendSubNS_namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_deprecated_func"), zif_ZendTestNS2_ZendSubNS_namespaced_deprecated_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_func, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_deprecated_func"), zif_ZendTestNS2_ZendSubNS_namespaced_deprecated_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_func, ZEND_ACC_DEPRECATED) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_ZendSubNS_namespaced_aliased_func, 0, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_ZendSubNS_namespaced_aliased_func, 0) +#endif +#if (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_deprecated_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_aliased_func, ZEND_ACC_DEPRECATED, NULL, NULL) +#else + ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2\\ZendSubNS", "namespaced_deprecated_aliased_func"), zif_zend_test_void_return, arginfo_ZendTestNS2_ZendSubNS_namespaced_deprecated_aliased_func, ZEND_ACC_DEPRECATED) +#endif + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestTraitForInternalClass_methods[] = { + ZEND_ME(_ZendTestTraitForInternalClass, traitMethod, arginfo_class__ZendTestTraitForInternalClass_traitMethod, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestTraitForInternalClass2_methods[] = { + ZEND_ME(_ZendTestTraitForInternalClass2, traitMethod2, arginfo_class__ZendTestTraitForInternalClass2_traitMethod2, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestClass_methods[] = { + ZEND_ME(_ZendTestClass, is_object, arginfo_class__ZendTestClass_is_object, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(_ZendTestClass, __toString, arginfo_class__ZendTestClass___toString, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(_ZendTestClass, returnsStatic, arginfo_class__ZendTestClass_returnsStatic, ZEND_ACC_PUBLIC) + ZEND_ME(_ZendTestClass, returnsThrowable, arginfo_class__ZendTestClass_returnsThrowable, ZEND_ACC_PUBLIC) + ZEND_ME(_ZendTestClass, variadicTest, arginfo_class__ZendTestClass_variadicTest, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(_ZendTestClass, takesUnionType, arginfo_class__ZendTestClass_takesUnionType, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestMagicCall_methods[] = { + ZEND_ME(_ZendTestMagicCall, __call, arginfo_class__ZendTestMagicCall___call, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestMagicCallForward_methods[] = { + ZEND_ME(_ZendTestMagicCallForward, __call, arginfo_class__ZendTestMagicCallForward___call, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestChildClass_methods[] = { + ZEND_ME(_ZendTestChildClass, returnsThrowable, arginfo_class__ZendTestChildClass_returnsThrowable, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendAttributeTest_methods[] = { + ZEND_ME(ZendAttributeTest, testMethod, arginfo_class_ZendAttributeTest_testMethod, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class__ZendTestTrait_methods[] = { + ZEND_ME(_ZendTestTrait, testMethod, arginfo_class__ZendTestTrait_testMethod, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestAttributeWithArguments_methods[] = { + ZEND_ME(ZendTestAttributeWithArguments, __construct, arginfo_class_ZendTestAttributeWithArguments___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestParameterAttribute_methods[] = { + ZEND_ME(ZendTestParameterAttribute, __construct, arginfo_class_ZendTestParameterAttribute___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestPropertyAttribute_methods[] = { + ZEND_ME(ZendTestPropertyAttribute, __construct, arginfo_class_ZendTestPropertyAttribute___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, no_override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestChildClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestChildClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestForbidDynamicCall_methods[] = { +#if (PHP_VERSION_ID >= 80600) + ZEND_ME(ZendTestForbidDynamicCall, call, arginfo_class_ZendTestForbidDynamicCall_call, ZEND_FENTRY_FLAGS(ZEND_ACC_PUBLIC, ZEND_ACC2_FORBID_DYN_CALLS)) +#elif (PHP_VERSION_ID >= 70000) + ZEND_ME(ZendTestForbidDynamicCall, call, arginfo_class_ZendTestForbidDynamicCall_call, ZEND_ACC_PUBLIC) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_ME(ZendTestForbidDynamicCall, callStatic, arginfo_class_ZendTestForbidDynamicCall_callStatic, ZEND_FENTRY_FLAGS(ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, ZEND_ACC2_FORBID_DYN_CALLS)) +#elif (PHP_VERSION_ID >= 70000) + ZEND_ME(ZendTestForbidDynamicCall, callStatic, arginfo_class_ZendTestForbidDynamicCall_callStatic, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) +#endif + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestNS_Foo_methods[] = { + ZEND_ME(ZendTestNS_Foo, method, arginfo_class_ZendTestNS_Foo_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestNS_UnlikelyCompileError_methods[] = { + ZEND_ME(ZendTestNS_UnlikelyCompileError, method, arginfo_class_ZendTestNS_UnlikelyCompileError_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestNS_NotUnlikelyCompileError_methods[] = { + ZEND_ME(ZendTestNS_NotUnlikelyCompileError, method, arginfo_class_ZendTestNS_NotUnlikelyCompileError_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestNS2_Foo_methods[] = { + ZEND_ME(ZendTestNS2_Foo, method, arginfo_class_ZendTestNS2_Foo_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ZendTestNS2_ZendSubNS_Foo_methods[] = { + ZEND_ME(ZendTestNS2_ZendSubNS_Foo, method, arginfo_class_ZendTestNS2_ZendSubNS_Foo_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void register_test_symbols(int module_number) +{ + REGISTER_LONG_CONSTANT("ZEND_TEST_DEPRECATED", 42, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("ZEND_CONSTANT_A", "global", CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("ZEND_TEST_ATTRIBUTED_CONSTANT", 42, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("ZendTestNS2\\ZEND_CONSTANT_A", "namespaced", CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("ZendTestNS2\\ZendSubNS\\ZEND_CONSTANT_A", "namespaced", CONST_PERSISTENT | CONST_CS); +} + +static zend_class_entry *register_class__ZendTestInterface(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestInterface", NULL); + class_entry = zend_register_internal_interface(&ce); + + zval const_DUMMY_value; + ZVAL_LONG(&const_DUMMY_value, 0); + zend_string *const_DUMMY_name = zend_string_init_interned("DUMMY", sizeof("DUMMY") - 1, true); + zend_string *const_DUMMY_comment = zend_string_init_interned("/**\n * \"Lorem ipsum\"\n * @see https://www.php.net\n * @since 8.2\n */", 98, 1); + zend_declare_class_constant_ex(class_entry, const_DUMMY_name, &const_DUMMY_value, ZEND_ACC_PUBLIC, const_DUMMY_comment); + zend_string_release_ex(const_DUMMY_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestTraitForInternalClass(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestTraitForInternalClass", class__ZendTestTraitForInternalClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif + + zval const_ZEND_TRAIT_CONST_value; + ZVAL_LONG(&const_ZEND_TRAIT_CONST_value, 123); + zend_string *const_ZEND_TRAIT_CONST_name = zend_string_init_interned("ZEND_TRAIT_CONST", sizeof("ZEND_TRAIT_CONST") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TRAIT_CONST_name, &const_ZEND_TRAIT_CONST_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TRAIT_CONST_name, true); + + zval property_traitProp_default_value; + ZVAL_LONG(&property_traitProp_default_value, 456); + zend_string *property_traitProp_name = zend_string_init("traitProp", sizeof("traitProp") - 1, true); + zend_declare_property_ex(class_entry, property_traitProp_name, &property_traitProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_traitProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestTraitForInternalClass2(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestTraitForInternalClass2", class__ZendTestTraitForInternalClass2_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif + + zval const_ZEND_TRAIT_CONST2_value; + ZVAL_LONG(&const_ZEND_TRAIT_CONST2_value, 321); + zend_string *const_ZEND_TRAIT_CONST2_name = zend_string_init_interned("ZEND_TRAIT_CONST2", sizeof("ZEND_TRAIT_CONST2") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TRAIT_CONST2_name, &const_ZEND_TRAIT_CONST2_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TRAIT_CONST2_name, true); + + zval property_staticTraitProp_default_value; + ZVAL_LONG(&property_staticTraitProp_default_value, 999); + zend_string *property_staticTraitProp_name = zend_string_init("staticTraitProp", sizeof("staticTraitProp") - 1, true); + zend_declare_property_ex(class_entry, property_staticTraitProp_name, &property_staticTraitProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property_staticTraitProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestClassWithTraits(zend_class_entry *class_entry__ZendTestTraitForInternalClass, zend_class_entry *class_entry__ZendTestTraitForInternalClass2) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestClassWithTraits", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + zend_class_use_internal_traits(class_entry, 2, class_entry__ZendTestTraitForInternalClass, class_entry__ZendTestTraitForInternalClass2); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_entry__ZendTestInterface) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestClass", class__ZendTestClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + zend_class_implements(class_entry, 1, class_entry__ZendTestInterface); + zend_register_class_alias("_ZendTestClassAlias", class_entry); + + zval const_TYPED_CLASS_CONST1_value; + ZVAL_EMPTY_ARRAY(&const_TYPED_CLASS_CONST1_value); + zend_string *const_TYPED_CLASS_CONST1_name = zend_string_init_interned("TYPED_CLASS_CONST1", sizeof("TYPED_CLASS_CONST1") - 1, true); + zend_declare_class_constant_ex(class_entry, const_TYPED_CLASS_CONST1_name, &const_TYPED_CLASS_CONST1_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_TYPED_CLASS_CONST1_name, true); + + zval const_TYPED_CLASS_CONST2_value; + ZVAL_LONG(&const_TYPED_CLASS_CONST2_value, 42); + zend_string *const_TYPED_CLASS_CONST2_name = zend_string_init_interned("TYPED_CLASS_CONST2", sizeof("TYPED_CLASS_CONST2") - 1, true); + zend_declare_class_constant_ex(class_entry, const_TYPED_CLASS_CONST2_name, &const_TYPED_CLASS_CONST2_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_TYPED_CLASS_CONST2_name, true); + + zval const_TYPED_CLASS_CONST3_value; + ZVAL_LONG(&const_TYPED_CLASS_CONST3_value, 1); + zend_string *const_TYPED_CLASS_CONST3_name = zend_string_init_interned("TYPED_CLASS_CONST3", sizeof("TYPED_CLASS_CONST3") - 1, true); + zend_declare_class_constant_ex(class_entry, const_TYPED_CLASS_CONST3_name, &const_TYPED_CLASS_CONST3_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_TYPED_CLASS_CONST3_name, true); + + zval const_ZEND_TEST_DEPRECATED_value; + ZVAL_LONG(&const_ZEND_TEST_DEPRECATED_value, 42); + zend_string *const_ZEND_TEST_DEPRECATED_name = zend_string_init_interned("ZEND_TEST_DEPRECATED", sizeof("ZEND_TEST_DEPRECATED") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TEST_DEPRECATED_name, &const_ZEND_TEST_DEPRECATED_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TEST_DEPRECATED_name, true); + + zval const_ZEND_TEST_DEPRECATED_ATTR_value; + ZVAL_LONG(&const_ZEND_TEST_DEPRECATED_ATTR_value, 42); + zend_string *const_ZEND_TEST_DEPRECATED_ATTR_name = zend_string_init_interned("ZEND_TEST_DEPRECATED_ATTR", sizeof("ZEND_TEST_DEPRECATED_ATTR") - 1, true); + zend_declare_class_constant_ex(class_entry, const_ZEND_TEST_DEPRECATED_ATTR_name, &const_ZEND_TEST_DEPRECATED_ATTR_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_ZEND_TEST_DEPRECATED_ATTR_name, true); + + zval property__StaticProp_default_value; + ZVAL_NULL(&property__StaticProp_default_value); + zend_string *property__StaticProp_name = zend_string_init("_StaticProp", sizeof("_StaticProp") - 1, true); + zend_declare_property_ex(class_entry, property__StaticProp_name, &property__StaticProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property__StaticProp_name, true); + + zval property_staticIntProp_default_value; + ZVAL_LONG(&property_staticIntProp_default_value, 123); + zend_string *property_staticIntProp_name = zend_string_init("staticIntProp", sizeof("staticIntProp") - 1, true); + zend_declare_property_ex(class_entry, property_staticIntProp_name, &property_staticIntProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property_staticIntProp_name, true); + + zval property_doubleQuoteEscaped_default_value; + zend_string *property_doubleQuoteEscaped_default_value_str = zend_string_init("BEGIN \n\r\t\v\x1b\f\\$\"AAA END", strlen("BEGIN \n\r\t\v\x1b\f\\$\"AAA END"), 1); + ZVAL_STR(&property_doubleQuoteEscaped_default_value, property_doubleQuoteEscaped_default_value_str); + zend_string *property_doubleQuoteEscaped_name = zend_string_init("doubleQuoteEscaped", sizeof("doubleQuoteEscaped") - 1, true); + zend_declare_property_ex(class_entry, property_doubleQuoteEscaped_name, &property_doubleQuoteEscaped_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property_doubleQuoteEscaped_name, true); + + zval property_singleQuoteEscaped_default_value; + zend_string *property_singleQuoteEscaped_default_value_str = zend_string_init("BEGIN \\n\\r\\t\\v\\e\\f\\\\\\\\$\\\"\\101\\x41\\u{41} END", strlen("BEGIN \\n\\r\\t\\v\\e\\f\\\\\\\\$\\\"\\101\\x41\\u{41} END"), 1); + ZVAL_STR(&property_singleQuoteEscaped_default_value, property_singleQuoteEscaped_default_value_str); + zend_string *property_singleQuoteEscaped_name = zend_string_init("singleQuoteEscaped", sizeof("singleQuoteEscaped") - 1, true); + zend_declare_property_ex(class_entry, property_singleQuoteEscaped_name, &property_singleQuoteEscaped_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property_singleQuoteEscaped_name, true); + + zval property_escapeInterpolated_default_value; + zend_string *property_escapeInterpolated_default_value_str = zend_string_init("begin $ \\$ end", strlen("begin $ \\$ end"), 1); + ZVAL_STR(&property_escapeInterpolated_default_value, property_escapeInterpolated_default_value_str); + zend_string *property_escapeInterpolated_name = zend_string_init("escapeInterpolated", sizeof("escapeInterpolated") - 1, true); + zend_declare_property_ex(class_entry, property_escapeInterpolated_name, &property_escapeInterpolated_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL); + zend_string_release_ex(property_escapeInterpolated_name, true); + + zval property_intProp_default_value; + ZVAL_LONG(&property_intProp_default_value, 123); + zend_string *property_intProp_name = zend_string_init("intProp", sizeof("intProp") - 1, true); + zend_declare_property_ex(class_entry, property_intProp_name, &property_intProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_intProp_name, true); + + zval property_classProp_default_value; + ZVAL_NULL(&property_classProp_default_value); + zend_string *property_classProp_name = zend_string_init("classProp", sizeof("classProp") - 1, true); + zend_declare_property_ex(class_entry, property_classProp_name, &property_classProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_classProp_name, true); + + zval property_classUnionProp_default_value; + ZVAL_NULL(&property_classUnionProp_default_value); + zend_string *property_classUnionProp_name = zend_string_init("classUnionProp", sizeof("classUnionProp") - 1, true); + zend_declare_property_ex(class_entry, property_classUnionProp_name, &property_classUnionProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_classUnionProp_name, true); + + zval property_classIntersectionProp_default_value; + ZVAL_NULL(&property_classIntersectionProp_default_value); + zend_string *property_classIntersectionProp_name = zend_string_init("classIntersectionProp", sizeof("classIntersectionProp") - 1, true); + zend_declare_property_ex(class_entry, property_classIntersectionProp_name, &property_classIntersectionProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_classIntersectionProp_name, true); + + zval property_readonlyProp_default_value; + ZVAL_NULL(&property_readonlyProp_default_value); + zend_string *property_readonlyProp_name = zend_string_init("readonlyProp", sizeof("readonlyProp") - 1, true); + zend_declare_property_ex(class_entry, property_readonlyProp_name, &property_readonlyProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_readonlyProp_name, true); + + zval property_finalProp_default_value; + ZVAL_NULL(&property_finalProp_default_value); + zend_string *property_finalProp_name = zend_string_init("finalProp", sizeof("finalProp") - 1, true); +#if (PHP_VERSION_ID >= 80400) + zend_declare_property_ex(class_entry, property_finalProp_name, &property_finalProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL, NULL); +#elif (PHP_VERSION_ID >= 70000) + zend_declare_property_ex(class_entry, property_finalProp_name, &property_finalProp_default_value, ZEND_ACC_PUBLIC, NULL); +#endif + zend_string_release_ex(property_finalProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestMagicCall(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestMagicCall", class__ZendTestMagicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestMagicCallForward(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestMagicCallForward", class__ZendTestMagicCallForward_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestChildClass(zend_class_entry *class_entry__ZendTestClass) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestChildClass", class__ZendTestChildClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry__ZendTestClass, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, class_entry__ZendTestClass); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestGenStubFlagCompatibilityTest(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestGenStubFlagCompatibilityTest", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendAttributeTest(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendAttributeTest", class_ZendAttributeTest_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + zval const_TEST_CONST_value; + ZVAL_LONG(&const_TEST_CONST_value, 1); + zend_string *const_TEST_CONST_name = zend_string_init_interned("TEST_CONST", sizeof("TEST_CONST") - 1, true); + zend_declare_class_constant_ex(class_entry, const_TEST_CONST_name, &const_TEST_CONST_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(const_TEST_CONST_name, true); + + zval property_testProp_default_value; + ZVAL_NULL(&property_testProp_default_value); + zend_string *property_testProp_name = zend_string_init("testProp", sizeof("testProp") - 1, true); + zend_declare_property_ex(class_entry, property_testProp_name, &property_testProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_testProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class__ZendTestTrait(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "_ZendTestTrait", class__ZendTestTrait_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif + + zval property_testProp_default_value; + ZVAL_NULL(&property_testProp_default_value); + zend_string *property_testProp_name = zend_string_init("testProp", sizeof("testProp") - 1, true); + zend_declare_property_ex(class_entry, property_testProp_name, &property_testProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_testProp_name, true); + + zval property_classUnionProp_default_value; + ZVAL_NULL(&property_classUnionProp_default_value); + zend_string *property_classUnionProp_name = zend_string_init("classUnionProp", sizeof("classUnionProp") - 1, true); + zend_declare_property_ex(class_entry, property_classUnionProp_name, &property_classUnionProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_classUnionProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestAttribute", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestAttributeWithArguments(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestAttributeWithArguments", class_ZendTestAttributeWithArguments_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + zval property_arg_default_value; + ZVAL_NULL(&property_arg_default_value); + zend_string *property_arg_name = zend_string_init("arg", sizeof("arg") - 1, true); + zend_declare_property_ex(class_entry, property_arg_name, &property_arg_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_arg_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestRepeatableAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestRepeatableAttribute", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + zval property_parameter_default_value; + ZVAL_NULL(&property_parameter_default_value); + zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, true); + zend_declare_property_ex(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_parameter_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestPropertyAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestPropertyAttribute", class_ZendTestPropertyAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + zval property_parameter_default_value; + ZVAL_NULL(&property_parameter_default_value); + zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, true); + zend_string *property_parameter_comment = zend_string_init_interned("/**\n * \"Lorem ipsum\"\n * @see https://www.php.net\n * @since 8.4\n */", 98, 1); + zend_declare_property_ex(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, property_parameter_comment); + zend_string_release_ex(property_parameter_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_class_entry *class_entry_ZendTestClassWithMethodWithParameterAttribute) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestClassWithPropertyAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestClassWithPropertyAttribute", NULL); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + zval property_attributed_default_value; + ZVAL_NULL(&property_attributed_default_value); + zend_string *property_attributed_name = zend_string_init("attributed", sizeof("attributed") - 1, true); + zend_declare_property_ex(class_entry, property_attributed_name, &property_attributed_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_attributed_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestForbidDynamicCall(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestForbidDynamicCall", class_ZendTestForbidDynamicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif + + return class_entry; +} + +#if (PHP_VERSION_ID >= 80100) +static zend_class_entry *register_class_ZendTestUnitEnum(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("ZendTestUnitEnum", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Foo", NULL); + + zend_enum_add_case_cstr(class_entry, "Bar", NULL); + + return class_entry; +} +#endif + +#if (PHP_VERSION_ID >= 80100) +static zend_class_entry *register_class_ZendTestStringEnum(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("ZendTestStringEnum", IS_STRING, NULL); + + zval enum_case_Foo_value; + zend_string *enum_case_Foo_value_str = zend_string_init("Test1", strlen("Test1"), 1); + ZVAL_STR(&enum_case_Foo_value, enum_case_Foo_value_str); + zend_enum_add_case_cstr(class_entry, "Foo", &enum_case_Foo_value); + + zval enum_case_Bar_value; + zend_string *enum_case_Bar_value_str = zend_string_init("Test2", strlen("Test2"), 1); + ZVAL_STR(&enum_case_Bar_value, enum_case_Bar_value_str); + zend_enum_add_case_cstr(class_entry, "Bar", &enum_case_Bar_value); + + zval enum_case_Baz_value; + zend_string *enum_case_Baz_value_str = zend_string_init("Test2\\a", strlen("Test2\\a"), 1); + ZVAL_STR(&enum_case_Baz_value, enum_case_Baz_value_str); + zend_enum_add_case_cstr(class_entry, "Baz", &enum_case_Baz_value); + + zval enum_case_FortyTwo_value; + zend_string *enum_case_FortyTwo_value_str = zend_string_init("42", strlen("42"), 1); + ZVAL_STR(&enum_case_FortyTwo_value, enum_case_FortyTwo_value_str); + zend_enum_add_case_cstr(class_entry, "FortyTwo", &enum_case_FortyTwo_value); + + return class_entry; +} +#endif + +#if (PHP_VERSION_ID >= 80100) +static zend_class_entry *register_class_ZendTestIntEnum(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("ZendTestIntEnum", IS_LONG, NULL); + + zval enum_case_Foo_value; + ZVAL_LONG(&enum_case_Foo_value, 1); + zend_enum_add_case_cstr(class_entry, "Foo", &enum_case_Foo_value); + + zval enum_case_Bar_value; + ZVAL_LONG(&enum_case_Bar_value, 3); + zend_enum_add_case_cstr(class_entry, "Bar", &enum_case_Bar_value); + + zval enum_case_Baz_value; + ZVAL_LONG(&enum_case_Baz_value, -1); + zend_enum_add_case_cstr(class_entry, "Baz", &enum_case_Baz_value); + + return class_entry; +} +#endif + +#if (PHP_VERSION_ID >= 80100) +static zend_class_entry *register_class_ZendTestEnumWithInterface(zend_class_entry *class_entry__ZendTestInterface) +{ + zend_class_entry *class_entry = zend_register_internal_enum("ZendTestEnumWithInterface", IS_UNDEF, NULL); + zend_class_implements(class_entry, 1, class_entry__ZendTestInterface); + + zend_enum_add_case_cstr(class_entry, "Foo", NULL); + + zend_enum_add_case_cstr(class_entry, "Bar", NULL); + + return class_entry; +} +#endif + +static zend_class_entry *register_class_ZendTestNS_Foo(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "Foo", class_ZendTestNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestNS_Bar(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "Bar", NULL); + class_entry = zend_register_internal_interface(&ce); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestNS_UnlikelyCompileError(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "UnlikelyCompileError", class_ZendTestNS_UnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestNS_NotUnlikelyCompileError(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "NotUnlikelyCompileError", class_ZendTestNS_NotUnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestNS2_Foo(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2", "Foo", class_ZendTestNS2_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + zval property_foo_default_value; + ZVAL_NULL(&property_foo_default_value); + zend_string *property_foo_name = zend_string_init("foo", sizeof("foo") - 1, true); + zend_declare_property_ex(class_entry, property_foo_name, &property_foo_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_foo_name, true); + + zval property_intersectionProp_default_value; + ZVAL_NULL(&property_intersectionProp_default_value); + zend_string *property_intersectionProp_name = zend_string_init("intersectionProp", sizeof("intersectionProp") - 1, true); + zend_declare_property_ex(class_entry, property_intersectionProp_name, &property_intersectionProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_intersectionProp_name, true); + + zval property_unionProp_default_value; + ZVAL_NULL(&property_unionProp_default_value); + zend_string *property_unionProp_name = zend_string_init("unionProp", sizeof("unionProp") - 1, true); + zend_declare_property_ex(class_entry, property_unionProp_name, &property_unionProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_unionProp_name, true); + + zval property_fooAlias_default_value; + ZVAL_NULL(&property_fooAlias_default_value); + zend_string *property_fooAlias_name = zend_string_init("fooAlias", sizeof("fooAlias") - 1, true); + zend_declare_property_ex(class_entry, property_fooAlias_name, &property_fooAlias_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_fooAlias_name, true); + + zval property_unlProp_default_value; + ZVAL_NULL(&property_unlProp_default_value); + zend_string *property_unlProp_name = zend_string_init("unlProp", sizeof("unlProp") - 1, true); + zend_declare_property_ex(class_entry, property_unlProp_name, &property_unlProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_unlProp_name, true); + + zval property_notUnlProp_default_value; + ZVAL_NULL(&property_notUnlProp_default_value); + zend_string *property_notUnlProp_name = zend_string_init("notUnlProp", sizeof("notUnlProp") - 1, true); + zend_declare_property_ex(class_entry, property_notUnlProp_name, &property_notUnlProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_notUnlProp_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestNS2_ZendSubNS_Foo(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2\\ZendSubNS", "Foo", class_ZendTestNS2_ZendSubNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else + class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif + + return class_entry; +} diff --git a/ext/zend_test/tests/consumed_args_basic.phpt b/ext/zend_test/tests/consumed_args_basic.phpt new file mode 100644 index 000000000000..711ac8124579 --- /dev/null +++ b/ext/zend_test/tests/consumed_args_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +zend_test_call_with_consumed_args(): consume a non-reference arg +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +array(3) %srefcount(3){ + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +int(1) +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + string(1) "x" +} diff --git a/ext/zend_test/tests/consumed_args_ob_start_refcount.phpt b/ext/zend_test/tests/consumed_args_ob_start_refcount.phpt new file mode 100644 index 000000000000..3d5088d284d9 --- /dev/null +++ b/ext/zend_test/tests/consumed_args_ob_start_refcount.phpt @@ -0,0 +1,23 @@ +--TEST-- +ob_start(): consumed callback arg has low refcount +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(2) +} diff --git a/ext/zend_test/tests/consumed_args_ref_arg.phpt b/ext/zend_test/tests/consumed_args_ref_arg.phpt new file mode 100644 index 000000000000..a528860006b0 --- /dev/null +++ b/ext/zend_test/tests/consumed_args_ref_arg.phpt @@ -0,0 +1,35 @@ +--TEST-- +zend_test_call_with_consumed_args(): do not consume reference args +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +int(0) +array(2) { + [0]=> + int(10) + [1]=> + int(20) +} +array(1) { + [0]=> + int(10) +} diff --git a/ext/zend_test/tests/consumed_args_ref_param_and_ref_arg.phpt b/ext/zend_test/tests/consumed_args_ref_param_and_ref_arg.phpt new file mode 100644 index 000000000000..01d4025842a4 --- /dev/null +++ b/ext/zend_test/tests/consumed_args_ref_param_and_ref_arg.phpt @@ -0,0 +1,37 @@ +--TEST-- +zend_test_call_with_consumed_args(): ref-required params with reference args are not consumed +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +int(0) +array(2) { + [0]=> + int(10) + [1]=> + int(20) +} +array(2) { + [0]=> + int(10) + [1]=> + int(20) +} diff --git a/ext/zend_test/tests/consumed_args_ref_required.phpt b/ext/zend_test/tests/consumed_args_ref_required.phpt new file mode 100644 index 000000000000..f261131a686a --- /dev/null +++ b/ext/zend_test/tests/consumed_args_ref_required.phpt @@ -0,0 +1,24 @@ +--TEST-- +zend_test_call_with_consumed_args(): ref-required params are not consumed +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Warning: {closure:%s:%d}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d +int(0) +int(42) diff --git a/ext/zend_test/tests/gen_stub_test_01.phpt b/ext/zend_test/tests/gen_stub_test_01.phpt index 0f5d525322d6..0cda0651bee3 100644 --- a/ext/zend_test/tests/gen_stub_test_01.phpt +++ b/ext/zend_test/tests/gen_stub_test_01.phpt @@ -18,11 +18,31 @@ var_dump($foo); object(ZendTestNS2\Foo)#%d (%d) { ["foo"]=> uninitialized(ZendTestNS2\ZendSubNS\Foo) + ["intersectionProp"]=> + uninitialized(ZendTestNS2\ZendSubNS\Foo&ZendTestNS\Bar) + ["unionProp"]=> + uninitialized(ZendTestNS2\ZendSubNS\Foo|ZendTestNS\Bar) + ["fooAlias"]=> + uninitialized(ZendTestNS\Foo) + ["unlProp"]=> + uninitialized(ZendTestNS\UnlikelyCompileError) + ["notUnlProp"]=> + uninitialized(ZendTestNS\NotUnlikelyCompileError) } object(ZendTestNS2\Foo)#%d (%d) { ["foo"]=> object(ZendTestNS2\ZendSubNS\Foo)#%d (%d) { } + ["intersectionProp"]=> + uninitialized(ZendTestNS2\ZendSubNS\Foo&ZendTestNS\Bar) + ["unionProp"]=> + uninitialized(ZendTestNS2\ZendSubNS\Foo|ZendTestNS\Bar) + ["fooAlias"]=> + uninitialized(ZendTestNS\Foo) + ["unlProp"]=> + uninitialized(ZendTestNS\UnlikelyCompileError) + ["notUnlProp"]=> + uninitialized(ZendTestNS\NotUnlikelyCompileError) } object(ZendTestNS\UnlikelyCompileError)#%d (%d) { } diff --git a/ext/zend_test/tests/gh16811.phpt b/ext/zend_test/tests/gh16811.phpt new file mode 100644 index 000000000000..1b2b8ece9aa1 --- /dev/null +++ b/ext/zend_test/tests/gh16811.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-16811 (Segmentation fault in zend observer) +--EXTENSIONS-- +zend_test +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.show_output=1 +zend_test.observer.observe_function_names=a,d +--FILE-- + +--EXPECTF-- + + + +string(3) "a,d" diff --git a/ext/zend_test/tests/gh16811_observe_all.phpt b/ext/zend_test/tests/gh16811_observe_all.phpt new file mode 100644 index 000000000000..466aa0c6d4a4 --- /dev/null +++ b/ext/zend_test/tests/gh16811_observe_all.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-16811 (Assertion failure adding duplicate observer handler) +--EXTENSIONS-- +zend_test +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +zend_test.observer.show_output=0 +--FILE-- + +--EXPECT-- +Done diff --git a/ext/zend_test/tests/gh17797.phpt b/ext/zend_test/tests/gh17797.phpt index 271841b4389d..23bc217aef29 100644 --- a/ext/zend_test/tests/gh17797.phpt +++ b/ext/zend_test/tests/gh17797.phpt @@ -17,7 +17,7 @@ Warning: Undefined variable $c in %s on line %d Deprecated: zend_test_compile_string(): Passing null to parameter #3 ($position) of type int is deprecated in %s on line %d -Warning: require(sumfile.php): Failed to open stream: No such file or directory in on line %d diff --git a/ext/zend_test/tests/gh17899.phpt b/ext/zend_test/tests/gh17899.phpt index 184fe0b2aa39..58f445a3b7bf 100644 --- a/ext/zend_test/tests/gh17899.phpt +++ b/ext/zend_test/tests/gh17899.phpt @@ -19,7 +19,7 @@ Warning: Undefined variable $c in %s on line %d Deprecated: zend_test_compile_string(): Passing null to parameter #3 ($position) of type int is deprecated in %s on line %d -Warning: require(sumfile.php): Failed to open stream: No such file or directory in on line %d diff --git a/ext/zend_test/tests/gh22169.phpt b/ext/zend_test/tests/gh22169.phpt new file mode 100644 index 000000000000..5ed2ab22fa21 --- /dev/null +++ b/ext/zend_test/tests/gh22169.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-22169: Ensure escaped strings in stubs are valid +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +string(44) "424547494e200a0d090b1b0c5c242241414120454e44" +string(43) "BEGIN \n\r\t\v\e\f\\\\$\"\101\x41\u{41} END" +string(14) "begin $ \$ end" + diff --git a/ext/zend_test/tests/gh22175.phpt b/ext/zend_test/tests/gh22175.phpt new file mode 100644 index 000000000000..c2db3c9c4e0c --- /dev/null +++ b/ext/zend_test/tests/gh22175.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-22175: zend_call_method_if_exists() must unref return value +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Notice: Only variable references should be returned by reference in %s on line %d diff --git a/ext/zend_test/tests/internal_class_traits.phpt b/ext/zend_test/tests/internal_class_traits.phpt new file mode 100644 index 000000000000..c1a378ee99d4 --- /dev/null +++ b/ext/zend_test/tests/internal_class_traits.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test traits in internal classes +--EXTENSIONS-- +zend_test +--FILE-- +traitProp); + +// Methods from both traits +var_dump($obj->traitMethod()); +var_dump($obj->traitMethod2()); + +// Static property from trait 2 +var_dump(_ZendTestClassWithTraits::$staticTraitProp); + +// Reflection should show both traits +$rc = new ReflectionClass(_ZendTestClassWithTraits::class); +$traits = $rc->getTraitNames(); +sort($traits); +var_dump(count($traits)); +var_dump($traits); + +echo "Done\n"; +?> +--EXPECT-- +int(123) +int(321) +int(456) +int(789) +int(101) +int(999) +int(2) +array(2) { + [0]=> + string(30) "_ZendTestTraitForInternalClass" + [1]=> + string(31) "_ZendTestTraitForInternalClass2" +} +Done diff --git a/ext/zend_test/tests/observer_jit_vm_interrupt.inc b/ext/zend_test/tests/observer_jit_vm_interrupt.inc new file mode 100644 index 000000000000..426d9fdc2cb2 --- /dev/null +++ b/ext/zend_test/tests/observer_jit_vm_interrupt.inc @@ -0,0 +1,8 @@ + +--FILE-- + +--EXPECT-- +total=2438400 diff --git a/ext/zend_test/tests/observer_vm_interrupt_tailcall_helper.phpt b/ext/zend_test/tests/observer_vm_interrupt_tailcall_helper.phpt new file mode 100644 index 000000000000..d0178bdbf614 --- /dev/null +++ b/ext/zend_test/tests/observer_vm_interrupt_tailcall_helper.phpt @@ -0,0 +1,26 @@ +--TEST-- +Observer: VM interrupt during tailcall helper dispatch +--DESCRIPTION-- +This exercises a VM interrupt raised while an opcode handler dispatches to an +extra-argument helper. On the tailcall VM, the helper may return an opline +tagged with ZEND_VM_ENTER_BIT; treating that tagged value as a zend_op * before +tailcalling the next handler can crash. +--EXTENSIONS-- +zend_test +--INI-- +opcache.jit=0 +zend_test.observer.set_vm_interrupt_on_begin=1 +--FILE-- + +--EXPECT-- +stdClass diff --git a/ext/zend_test/tests/observer_vm_interrupt_tailcall_return.phpt b/ext/zend_test/tests/observer_vm_interrupt_tailcall_return.phpt new file mode 100644 index 000000000000..95af2681c253 --- /dev/null +++ b/ext/zend_test/tests/observer_vm_interrupt_tailcall_return.phpt @@ -0,0 +1,29 @@ +--TEST-- +Observer: VM interrupt during tailcall return to caller +--DESCRIPTION-- +This exercises a VM interrupt raised immediately before a user function returns +to a caller that invoked it through DO_FCALL. On the tailcall VM, the caller's +saved opline must point to the opcode after DO_FCALL before a pending interrupt +is handled. +--EXTENSIONS-- +zend_test +--INI-- +opcache.jit=0 +zend_test.observer.set_vm_interrupt_on_begin=1 +--FILE-- + +--EXPECT-- +ok diff --git a/ext/zend_test/tests/zend_object_init_with_constructor.phpt b/ext/zend_test/tests/zend_object_init_with_constructor.phpt index 65b111447f0b..aa3ad7ee845a 100644 --- a/ext/zend_test/tests/zend_object_init_with_constructor.phpt +++ b/ext/zend_test/tests/zend_object_init_with_constructor.phpt @@ -139,7 +139,14 @@ $o = zend_object_init_with_constructor("TestUserWithConstructorNoParams"); var_dump($o); unset($o); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d Testing impossible initializations Error: Cannot instantiate interface _ZendTestInterface Error: Cannot instantiate trait _ZendTestTrait @@ -152,14 +159,14 @@ Testing param passing ArgumentCountError: Too few arguments to function TestUserWithConstructorArgs::__construct(), 0 passed and exactly 2 expected TypeError: TestUserWithConstructorArgs::__construct(): Argument #1 ($int_param) must be of type int, string given Error: Unknown named parameter $unused_param -object(TestUserWithConstructorArgs)#1 (0) { +object(TestUserWithConstructorArgs)#%d (0) { } Destructor for TestUserWithConstructorArgs Passing too many args to constructor -object(TestUserWithConstructorArgs)#1 (0) { +object(TestUserWithConstructorArgs)#%d (0) { } Destructor for TestUserWithConstructorArgs Testing class with defined constructor and no params -object(TestUserWithConstructorNoParams)#1 (0) { +object(TestUserWithConstructorNoParams)#%d (0) { } Destructor for TestUserWithConstructorNoParams diff --git a/ext/zend_test/zend_mm_custom_handlers.c b/ext/zend_test/zend_mm_custom_handlers.c index 2130065109ef..76628f8881b5 100644 --- a/ext/zend_test/zend_mm_custom_handlers.c +++ b/ext/zend_test/zend_mm_custom_handlers.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Florian Engelhardt | +----------------------------------------------------------------------+ diff --git a/ext/zend_test/zend_mm_custom_handlers.h b/ext/zend_test/zend_mm_custom_handlers.h index 7e0c8021e7e2..1db32562320b 100644 --- a/ext/zend_test/zend_mm_custom_handlers.h +++ b/ext/zend_test/zend_mm_custom_handlers.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Florian Engelhardt | +----------------------------------------------------------------------+ diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 29ae030d37b6..590be44f6501 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -49,7 +49,7 @@ if test "$PHP_ZIP" != "no"; then AC_DEFINE([HAVE_ZIP], [1], [Define to 1 if the PHP extension 'zip' is available.]) - PHP_NEW_EXTENSION([zip], [php_zip.c zip_stream.c], [$ext_shared]) + PHP_NEW_EXTENSION([zip], [php_zip.c zip_source.c zip_stream.c], [$ext_shared]) PHP_ADD_EXTENSION_DEP(zip, pcre) PHP_SUBST([ZIP_SHARED_LIBADD]) diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 3f05d8454c1e..8dd22c7761cf 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -8,7 +8,7 @@ if (PHP_ZIP != "no") { (PHP_ZIP_SHARED && CHECK_LIB("libzip.lib", "zip", PHP_ZIP) || CHECK_LIB("libzip_a.lib", "zip", PHP_ZIP) && CHECK_LIB("libbz2_a.lib", "zip", PHP_ZIP) && CHECK_LIB("zlib_a.lib", "zip", PHP_ZIP) && CHECK_LIB("liblzma_a.lib", "zip", PHP_ZIP)) ) { - EXTENSION('zip', 'php_zip.c zip_stream.c'); + EXTENSION('zip', 'php_zip.c zip_source.c zip_stream.c'); ADD_EXTENSION_DEP('zip', 'pcre'); if (get_define("LIBS_ZIP").match("libzip_a(?:_debug)?\.lib")) { diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index c6f516e3a262..a41007b7aa89 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Piere-Alain Joye | +----------------------------------------------------------------------+ @@ -27,6 +25,7 @@ #include "ext/standard/php_filestat.h" #include "zend_attributes.h" #include "zend_interfaces.h" +#include "zend_exceptions.h" #include "php_zip.h" #include "php_zip_arginfo.h" @@ -58,22 +57,32 @@ static int le_zip_entry; } /* }}} */ -/* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */ -#define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \ - if (comment_len == 0) { \ - /* Passing NULL remove the existing comment */ \ - if (zip_file_set_comment(za, index, NULL, 0, 0) < 0) { \ - RETURN_FALSE; \ - } \ - } else if (zip_file_set_comment(za, index, comment, comment_len, 0) < 0) { \ - RETURN_FALSE; \ - } \ - RETURN_TRUE; +/* {{{ php_zip_set_file_comment */ +static bool php_zip_set_file_comment(struct zip *za, zip_uint64_t index, const char *comment, size_t comment_len) +{ + zip_uint32_t current_comment_len; + const char *current_comment = zip_file_get_comment(za, index, ¤t_comment_len, ZIP_FL_ENC_RAW); + + /* Avoid a libzip use-after-free when resetting an unchanged inherited comment. */ + if (current_comment && current_comment_len == comment_len + && memcmp(current_comment, comment, comment_len) == 0) { + return true; + } + + if (comment_len == 0) { + /* Passing NULL removes the existing comment. */ + return zip_file_set_comment(za, index, NULL, 0, 0) == 0; + } + + ZEND_ASSERT(comment_len <= 0xffff); + return zip_file_set_comment(za, index, comment, (zip_uint16_t) comment_len, 0) == 0; +} /* }}} */ # define add_ascii_assoc_string add_assoc_string # define add_ascii_assoc_long add_assoc_long +#ifdef HAVE_ENCRYPTION static bool php_zip_file_set_encryption(struct zip *intern, zend_long index, zend_long method, char *password) { // FIXME: is a workaround to reset/free the password in case of consecutive calls. // when libzip 1.11.5 is available, we can save this call in this case. @@ -84,6 +93,7 @@ static bool php_zip_file_set_encryption(struct zip *intern, zend_long index, zen return (zip_file_set_encryption(intern, (zip_uint64_t)index, (zip_uint16_t)method, password) == 0); } +#endif /* Flatten a path by making a relative path (to .)*/ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */ @@ -151,7 +161,7 @@ static bool php_zip_extract_file(struct zip * za, char *dest, const char *file, new_state.cwd[0] = '\0'; new_state.cwd_length = 0; - /* Clean/normlize the path and then transform any path (absolute or relative) + /* Clean/normalize the path and then transform any path (absolute or relative) to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt) */ virtual_file_ex(&new_state, file, NULL, CWD_EXPAND); @@ -311,11 +321,15 @@ static zend_result php_zip_add_file(ze_zip_object *obj, const char *filename, si } flags ^= ZIP_FL_OPEN_FILE_NOW; zs = zip_source_filep(obj->za, fd, offset_start, offset_len); + if (!zs) { + fclose(fd); + return FAILURE; + } } else { zs = zip_source_file(obj->za, resolved_path, offset_start, offset_len); - } - if (!zs) { - return FAILURE; + if (!zs) { + return FAILURE; + } } /* Replace */ if (replace >= 0) { @@ -357,6 +371,8 @@ static zend_result php_zip_parse_options(HashTable *options, zip_options *opts) /* {{{ */ { zval *option; + zend_long tmp; + bool failed = false; /* default values */ opts->flags = ZIP_FL_OVERWRITE; @@ -367,43 +383,45 @@ static zend_result php_zip_parse_options(HashTable *options, zip_options *opts) if ((option = zend_hash_str_find(options, "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_FALSE && Z_TYPE_P(option) != IS_TRUE) { - php_error_docref(NULL, E_WARNING, "Option \"remove_all_path\" must be of type bool, %s given", - zend_zval_value_name(option)); + zend_type_error("Option \"remove_all_path\" must be of type bool, %s given", zend_zval_value_name(option)); + return FAILURE; } - opts->remove_all_path = zval_get_long(option); + opts->remove_all_path = Z_TYPE_P(option) == IS_TRUE; } if ((option = zend_hash_str_find(options, "comp_method", sizeof("comp_method") - 1)) != NULL) { - if (Z_TYPE_P(option) != IS_LONG) { - php_error_docref(NULL, E_WARNING, "Option \"comp_method\" must be of type int, %s given", - zend_zval_value_name(option)); + tmp = zval_try_get_long(option, &failed); + if (failed) { + zend_type_error("Option \"comp_method\" must be of type int, %s given", zend_zval_value_name(option)); + return FAILURE; } - zend_long comp_method = zval_get_long(option); + zend_long comp_method = tmp; if (comp_method < 0 || comp_method > INT_MAX) { php_error_docref(NULL, E_WARNING, "Option \"comp_method\" must be between 0 and %d", INT_MAX); } opts->comp_method = (zip_int32_t)comp_method; if ((option = zend_hash_str_find(options, "comp_flags", sizeof("comp_flags") - 1)) != NULL) { - if (Z_TYPE_P(option) != IS_LONG) { - php_error_docref(NULL, E_WARNING, "Option \"comp_flags\" must be of type int, %s given", - zend_zval_value_name(option)); + tmp = zval_try_get_long(option, &failed); + if (failed) { + zend_type_error("Option \"comp_flags\" must be of type int, %s given", zend_zval_value_name(option)); + return FAILURE; } - zend_long comp_flags = zval_get_long(option); - if (comp_flags < 0 || comp_flags > USHRT_MAX) { + if (tmp < 0 || tmp > USHRT_MAX) { php_error_docref(NULL, E_WARNING, "Option \"comp_flags\" must be between 0 and %u", USHRT_MAX); } - opts->comp_flags = (zip_uint32_t)comp_flags; + opts->comp_flags = (zip_uint32_t)tmp; } } #ifdef HAVE_ENCRYPTION if ((option = zend_hash_str_find(options, "enc_method", sizeof("enc_method") - 1)) != NULL) { - if (Z_TYPE_P(option) != IS_LONG) { - php_error_docref(NULL, E_WARNING, "Option \"enc_method\" must be of type int, %s given", - zend_zval_value_name(option)); + tmp = zval_try_get_long(option, &failed); + if (failed) { + zend_type_error("Option \"enc_method\" must be of type int, %s given", zend_zval_value_name(option)); + return FAILURE; } - opts->enc_method = zval_get_long(option); + opts->enc_method = tmp; if ((option = zend_hash_str_find(options, "enc_password", sizeof("enc_password") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_STRING) { @@ -457,12 +475,13 @@ static zend_result php_zip_parse_options(HashTable *options, zip_options *opts) } if ((option = zend_hash_str_find(options, "flags", sizeof("flags") - 1)) != NULL) { - if (Z_TYPE_P(option) != IS_LONG) { + tmp = zval_try_get_long(option, &failed); + if (failed) { zend_type_error("Option \"flags\" must be of type int, %s given", zend_zval_value_name(option)); return FAILURE; } - opts->flags = Z_LVAL_P(option); + opts->flags = tmp; } return SUCCESS; @@ -512,13 +531,13 @@ static zend_result php_zip_parse_options(HashTable *options, zip_options *opts) static zend_long php_zip_status(ze_zip_object *obj) /* {{{ */ { - int zep = obj->err_zip; /* saved err if closed */ + zend_long zep = (zend_long)obj->err_zip; /* saved err if closed */ if (obj->za) { zip_error_t *err; err = zip_get_error(obj->za); - zep = zip_error_code_zip(err); + zep = (zend_long)zip_error_code_zip(err); zip_error_fini(err); } return zep; @@ -533,13 +552,13 @@ static zend_long php_zip_last_id(ze_zip_object *obj) /* {{{ */ static zend_long php_zip_status_sys(ze_zip_object *obj) /* {{{ */ { - int syp = obj->err_sys; /* saved err if closed */ + zend_long syp = (zend_long)obj->err_sys; /* saved err if closed */ if (obj->za) { zip_error_t *err; err = zip_get_error(obj->za); - syp = zip_error_code_system(err); + syp = (zend_long)zip_error_code_system(err); zip_error_fini(err); } return syp; @@ -575,30 +594,12 @@ static char * php_zipobj_get_zip_comment(ze_zip_object *obj, int *len) /* {{{ */ } /* }}} */ -/* Add a string to the list of buffers to be released when the object is destroyed.*/ -static void php_zipobj_add_buffer(ze_zip_object *obj, zend_string *str) /* {{{ */ -{ - size_t pos = obj->buffers_cnt++; - obj->buffers = safe_erealloc(obj->buffers, sizeof(*obj->buffers), obj->buffers_cnt, 0); - obj->buffers[pos] = zend_string_copy(str); -} -/* }}} */ - -static void php_zipobj_release_buffers(ze_zip_object *obj) /* {{{ */ -{ - if (obj->buffers_cnt > 0) { - for (size_t i = 0; i < obj->buffers_cnt; i++) { - zend_string_release(obj->buffers[i]); - } - efree(obj->buffers); - obj->buffers = NULL; - } - obj->buffers_cnt = 0; -} -/* }}} */ - -/* Close and free the zip_t */ -static bool php_zipobj_close(ze_zip_object *obj) /* {{{ */ +/* Close and free the zip_t. If the archive was opened as a string, the + * final contents of the archive will be assigned to *out_str and that + * string will afterwards be owned by the caller. + * + * If out_str is NULL, the final string contents, if any, will be discarded. */ +static bool php_zipobj_close(ze_zip_object *obj, zend_string **out_str) /* {{{ */ { struct zip *intern = obj->za; bool success = false; @@ -630,9 +631,25 @@ static bool php_zipobj_close(ze_zip_object *obj) /* {{{ */ obj->filename_len = 0; } - php_zipobj_release_buffers(obj); + if (obj->out_str) { + if (out_str) { + *out_str = obj->out_str; + } else { + zend_string_release(obj->out_str); + } + obj->out_str = NULL; + } else { + ZEND_ASSERT(!out_str); + } obj->za = NULL; + obj->from_string = false; + + if (obj->bailout_callback) { + obj->bailout_callback = false; + zend_bailout(); + } + return success; } /* }}} */ @@ -700,16 +717,18 @@ int php_zip_glob(zend_string *spattern, zend_long flags, zval *return_value) /* /* now catch the FreeBSD style of "no matches" */ if (!globbuf.gl_pathc || !globbuf.gl_pathv) { + php_globfree(&globbuf); return 0; } /* we assume that any glob pattern will match files from one directory only so checking the dirname of the first match should be sufficient */ if (ZIP_OPENBASEDIR_CHECKPATH(globbuf.gl_pathv[0])) { + php_globfree(&globbuf); return -1; } - array_init(return_value); + array_init_size(return_value, (uint32_t)globbuf.gl_pathc); for (size_t n = 0; n < globbuf.gl_pathc; n++) { /* we need to do this every time since PHP_GLOB_ONLYDIR does not guarantee that * all directories will be filtered. GNU libc documentation states the @@ -788,7 +807,7 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val return -1; } - array_init(return_value); + array_init_size(return_value, (uint32_t)files_cnt); /* only the files, directories are ignored */ for (i = 0; i < files_cnt; i++) { @@ -805,7 +824,10 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val if ((path_len + namelist_len + 1) >= MAXPATHLEN) { php_error_docref(NULL, E_WARNING, "add_path string too long (max: %u, %zu given)", MAXPATHLEN - 1, (path_len + namelist_len + 1)); - zend_string_release_ex(namelist[i], false); + /* The loop isn't continued, so all remaining file names must get freed. */ + for (; i < files_cnt; i++) { + zend_string_release_ex(namelist[i], false); + } break; } @@ -1073,10 +1095,16 @@ static void php_zip_object_dtor(zend_object *object) if (intern->za) { if (zip_close(intern->za) != 0) { - php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(intern->za)); + if (!intern->bailout_callback) { + php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(intern->za)); + } zip_discard(intern->za); } intern->za = NULL; + if (intern->bailout_callback) { + intern->bailout_callback = false; + zend_bailout(); + } } } @@ -1084,7 +1112,7 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */ { ze_zip_object * intern = php_zip_fetch_object(object); - php_zipobj_close(intern); + php_zipobj_close(intern, NULL); #ifdef HAVE_PROGRESS_CALLBACK /* if not properly called by libzip */ @@ -1416,12 +1444,10 @@ static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ RETURN_STRING("imploded"); case 7: RETURN_STRING("tokenized"); - break; case 8: RETURN_STRING("deflated"); case 9: RETURN_STRING("deflatedX"); - break; case 10: RETURN_STRING("implodedX"); default: @@ -1493,7 +1519,7 @@ PHP_METHOD(ZipArchive, open) } /* If we already have an opened zip, free it */ - php_zipobj_close(ze_obj); + php_zipobj_close(ze_obj, NULL); /* open for write without option to empty the archive */ if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) { @@ -1517,26 +1543,34 @@ PHP_METHOD(ZipArchive, open) ze_obj->filename = resolved_path; ze_obj->filename_len = strlen(resolved_path); ze_obj->za = intern; + ze_obj->from_string = false; RETURN_TRUE; } /* }}} */ -/* {{{ Create new read-only zip using given string */ +/* {{{ Create new zip from a string, or a create an empty zip to be saved to a string */ PHP_METHOD(ZipArchive, openString) { - zend_string *buffer; + zend_string *buffer = NULL; + zend_long flags = 0; zval *self = ZEND_THIS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &buffer) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|Sl", &buffer, &flags) == FAILURE) { RETURN_THROWS(); } + if (!buffer) { + buffer = ZSTR_EMPTY_ALLOC(); + } + ze_zip_object *ze_obj = Z_ZIP_P(self); + php_zipobj_close(ze_obj, NULL); + zip_error_t err; zip_error_init(&err); - zip_source_t * zip_source = zip_source_buffer_create(ZSTR_VAL(buffer), ZSTR_LEN(buffer), 0, &err); + zip_source_t * zip_source = php_zip_create_string_source(buffer, &ze_obj->out_str, &err); if (!zip_source) { ze_obj->err_zip = zip_error_code_zip(&err); @@ -1545,9 +1579,7 @@ PHP_METHOD(ZipArchive, openString) RETURN_LONG(ze_obj->err_zip); } - php_zipobj_close(ze_obj); - - struct zip *intern = zip_open_from_source(zip_source, ZIP_RDONLY, &err); + struct zip *intern = zip_open_from_source(zip_source, flags, &err); if (!intern) { ze_obj->err_zip = zip_error_code_zip(&err); ze_obj->err_sys = zip_error_code_system(&err); @@ -1556,7 +1588,7 @@ PHP_METHOD(ZipArchive, openString) RETURN_LONG(ze_obj->err_zip); } - php_zipobj_add_buffer(ze_obj, buffer); + ze_obj->from_string = true; ze_obj->za = intern; zip_error_fini(&err); RETURN_TRUE; @@ -1591,27 +1623,50 @@ PHP_METHOD(ZipArchive, close) struct zip *intern; zval *self = ZEND_THIS; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); ZIP_FROM_OBJECT(intern, self); - RETURN_BOOL(php_zipobj_close(Z_ZIP_P(self))); + RETURN_BOOL(php_zipobj_close(Z_ZIP_P(self), NULL)); } /* }}} */ -/* {{{ close the zip archive */ -PHP_METHOD(ZipArchive, count) +/* {{{ close the zip archive and get the result as a string */ +PHP_METHOD(ZipArchive, closeString) { struct zip *intern; zval *self = ZEND_THIS; - zip_int64_t num; - if (zend_parse_parameters_none() == FAILURE) { + ZEND_PARSE_PARAMETERS_NONE(); + + ZIP_FROM_OBJECT(intern, self); + + if (!Z_ZIP_P(self)->from_string) { + zend_throw_error(NULL, "ZipArchive::closeString can only be called on " + "an archive opened with ZipArchive::openString"); RETURN_THROWS(); } + zend_string *ret = NULL; + bool success = php_zipobj_close(Z_ZIP_P(self), &ret); + ZEND_ASSERT(ret); + if (success) { + RETURN_STR(ret); + } + zend_string_release(ret); + RETURN_FALSE; +} +/* }}} */ + +/* {{{ get the number of entries */ +PHP_METHOD(ZipArchive, count) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zip_int64_t num; + + ZEND_PARSE_PARAMETERS_NONE(); + ZIP_FROM_OBJECT(intern, self); num = zip_get_num_entries(intern, 0); @@ -1619,15 +1674,37 @@ PHP_METHOD(ZipArchive, count) } /* }}} */ +PHP_METHOD(ZipArchive, __serialize) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_throw_exception_ex(NULL, 0, + "Serialization of '%s' is not allowed, override __serialize() and __unserialize() to implement it", + ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); +} + +PHP_METHOD(ZipArchive, __unserialize) +{ + zval *data; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(data) + ZEND_PARSE_PARAMETERS_END(); + + (void) data; + + zend_throw_exception_ex(NULL, 0, + "Unserialization of '%s' is not allowed, override __serialize() and __unserialize() to implement it", + ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); +} + /* {{{ clear the internal status */ PHP_METHOD(ZipArchive, clearError) { zval *self = ZEND_THIS; ze_zip_object *ze_obj; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */ if (ze_obj->za) { @@ -1645,9 +1722,7 @@ PHP_METHOD(ZipArchive, getStatusString) zval *self = ZEND_THIS; ze_zip_object *ze_obj; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */ @@ -1921,9 +1996,7 @@ PHP_METHOD(ZipArchive, addFromString) ZIP_FROM_OBJECT(intern, self); ze_obj = Z_ZIP_P(self); - php_zipobj_add_buffer(ze_obj, buffer); - - zs = zip_source_buffer(intern, ZSTR_VAL(buffer), ZSTR_LEN(buffer), 0); + zs = php_zip_create_string_source(buffer, NULL, NULL); if (zs == NULL) { RETURN_FALSE; @@ -2121,7 +2194,7 @@ PHP_METHOD(ZipArchive, setCommentName) zval *self = ZEND_THIS; size_t comment_len, name_len; char * comment, *name; - int idx; + zip_int64_t idx; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &comment, &comment_len) == FAILURE) { @@ -2144,7 +2217,7 @@ PHP_METHOD(ZipArchive, setCommentName) if (idx < 0) { RETURN_FALSE; } - PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len); + RETURN_BOOL(php_zip_set_file_comment(intern, (zip_uint64_t) idx, comment, comment_len)); } /* }}} */ @@ -2157,6 +2230,7 @@ PHP_METHOD(ZipArchive, setCommentIndex) size_t comment_len; char * comment; struct zip_stat sb; + zip_uint64_t idx; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &index, &comment, &comment_len) == FAILURE) { @@ -2171,7 +2245,9 @@ PHP_METHOD(ZipArchive, setCommentIndex) } PHP_ZIP_STAT_INDEX(intern, index, 0, sb); - PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len); + idx = (zip_uint64_t) index; + + RETURN_BOOL(php_zip_set_file_comment(intern, idx, comment, comment_len)); } /* }}} */ @@ -2691,9 +2767,7 @@ PHP_METHOD(ZipArchive, unchangeAll) struct zip *intern; zval *self = ZEND_THIS; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); ZIP_FROM_OBJECT(intern, self); @@ -2707,9 +2781,7 @@ PHP_METHOD(ZipArchive, unchangeArchive) struct zip *intern; zval *self = ZEND_THIS; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); ZIP_FROM_OBJECT(intern, self); @@ -2829,7 +2901,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ ZIP_FROM_OBJECT(intern, self); - PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + PHP_ZIP_STAT_INDEX(intern, index, flags, sb); } if (sb.size < 1) { @@ -2852,6 +2924,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ buffer = zend_string_safe_alloc(1, len, 0, false); zip_int64_t n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); if (n < 1) { + zip_fclose(zf); zend_string_efree(buffer); RETURN_EMPTY_STRING(); } @@ -2943,15 +3016,21 @@ PHP_METHOD(ZipArchive, getStream) #ifdef HAVE_PROGRESS_CALLBACK static void php_zip_progress_callback(zip_t *arch, double state, void *ptr) { - if (!EG(active)) { + ze_zip_object *obj = ptr; + + if (UNEXPECTED(!EG(active) || obj->bailout_callback)) { return; } zval cb_args[1]; - ze_zip_object *obj = ptr; ZVAL_DOUBLE(&cb_args[0], state); - zend_call_known_fcc(&obj->progress_callback, NULL, 1, cb_args, NULL); + + zend_try { + zend_call_known_fcc(&obj->progress_callback, NULL, 1, cb_args, NULL); + } zend_catch { + obj->bailout_callback = true; + } zend_end_try(); } /* {{{ register a progression callback: void callback(double state); */ @@ -2994,11 +3073,18 @@ static int php_zip_cancel_callback(zip_t *arch, void *ptr) zval cb_retval; ze_zip_object *obj = ptr; - if (!EG(active)) { + if (UNEXPECTED(!EG(active) || obj->bailout_callback)) { return 0; } - zend_call_known_fcc(&obj->cancel_callback, &cb_retval, 0, NULL, NULL); + zend_try { + zend_call_known_fcc(&obj->cancel_callback, &cb_retval, 0, NULL, NULL); + } zend_catch { + obj->bailout_callback = true; + /* Cancel if a bailout occurs to allow cleanup to happen */ + return -1; + } zend_end_try(); + if (Z_ISUNDEF(cb_retval)) { /* Cancel if an exception has been thrown */ return -1; @@ -3092,7 +3178,7 @@ static void php_zip_free_prop_handler(zval *el) /* {{{ */ { static PHP_MINIT_FUNCTION(zip) { memcpy(&zip_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - zip_object_handlers.offset = XtOffsetOf(ze_zip_object, zo); + zip_object_handlers.offset = offsetof(ze_zip_object, zo); zip_object_handlers.free_obj = php_zip_object_free_storage; zip_object_handlers.dtor_obj = php_zip_object_dtor; zip_object_handlers.clone_obj = NULL; @@ -3142,7 +3228,6 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_start(); php_info_print_table_row(2, "Zip", "enabled"); - php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION); #ifdef HAVE_LIBZIP_VERSION if (strcmp(LIBZIP_VERSION, zip_libzip_version())) { php_info_print_table_row(2, "Libzip headers version", LIBZIP_VERSION); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 0b96d6ec3eaa..e734c4628f02 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre-Alain Joye | +----------------------------------------------------------------------+ @@ -36,10 +34,11 @@ extern zend_module_entry zip_module_entry; #define ZIP_LENGTH_TO_END 0 #endif -/* Additionnal flags not from libzip */ +/* Additional flags not from libzip */ #define ZIP_FL_OPEN_FILE_NOW (1u<<30) -#define PHP_ZIP_VERSION "1.22.8" +#include "php_version.h" +#define PHP_ZIP_VERSION PHP_VERSION #ifdef HAVE_LIBZIP_VERSION #define LIBZIP_VERSION_STR zip_libzip_version() @@ -68,14 +67,15 @@ typedef struct _ze_zip_read_rsrc { /* Extends zend object */ typedef struct _ze_zip_object { struct zip *za; - zend_string **buffers; HashTable *prop_handler; char *filename; size_t filename_len; - size_t buffers_cnt; + zend_string *out_str; + bool from_string; zip_int64_t last_id; int err_zip; int err_sys; + bool bailout_callback; #ifdef HAVE_PROGRESS_CALLBACK zend_fcall_info_cache progress_callback; #endif @@ -85,9 +85,7 @@ typedef struct _ze_zip_object { zend_object zo; } ze_zip_object; -static inline ze_zip_object *php_zip_fetch_object(zend_object *obj) { - return (ze_zip_object *)((char*)(obj) - XtOffsetOf(ze_zip_object, zo)); -} +#define php_zip_fetch_object(obj) ZEND_CONTAINER_OF(obj, ze_zip_object, zo) #define Z_ZIP_P(zv) php_zip_fetch_object(Z_OBJ_P((zv))) @@ -96,6 +94,8 @@ php_stream *php_stream_zip_open(struct zip *arch, struct zip_stat *sb, const cha extern const php_stream_wrapper php_stream_zip_wrapper; +zip_source_t * php_zip_create_string_source(zend_string *str, zend_string **dest, zip_error_t *err); + #define LIBZIP_ATLEAST(m,n,p) (((m<<16) + (n<<8) + p) <= ((LIBZIP_VERSION_MAJOR<<16) + (LIBZIP_VERSION_MINOR<<8) + LIBZIP_VERSION_MICRO)) #endif /* PHP_ZIP_H */ diff --git a/ext/zip/php_zip.stub.php b/ext/zip/php_zip.stub.php index 42dfb006fc61..2cece2791d1b 100644 --- a/ext/zip/php_zip.stub.php +++ b/ext/zip/php_zip.stub.php @@ -152,7 +152,7 @@ class ZipArchive implements Countable public const int FL_ENC_CP437 = UNKNOWN; /** - * Additionnal flags not from libzip + * Additional flags not from libzip * @cvalue ZIP_FL_OPEN_FILE_NOW */ public const int FL_OPEN_FILE_NOW = UNKNOWN; @@ -646,7 +646,7 @@ class ZipArchive implements Countable /** @tentative-return-type */ public function open(string $filename, int $flags = 0): bool|int {} - public function openString(string $data): bool|int {} + public function openString(string $data = '', int $flags = 0): bool|int {} /** * @tentative-return-type @@ -656,9 +656,15 @@ public function setPassword(#[\SensitiveParameter] string $password): bool {} /** @tentative-return-type */ public function close(): bool {} + public function closeString(): string|false {} + /** @tentative-return-type */ public function count(): int {} + public function __serialize(): array {} + + public function __unserialize(array $data): void {} + /** @tentative-return-type */ public function getStatusString(): string {} diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 89dd33b6f1a0..4f8366dc1512 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_zip.stub.php instead. - * Stub hash: e04b3e90c42074ac364ea25a0e794815bd4271e5 */ + * Stub hash: 206d9be6640ee7e94d68d7e075ab61bf3188cab3 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -45,8 +45,9 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_ZipArchive_open, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ZipArchive_openString, 0, 1, MAY_BE_BOOL|MAY_BE_LONG) - ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ZipArchive_openString, 0, 0, MAY_BE_BOOL|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_STRING, 0, "\'\'") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_setPassword, 0, 1, _IS_BOOL, 0) @@ -56,9 +57,19 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_close, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ZipArchive_closeString, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_count, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive___serialize, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_getStatusString, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -320,7 +331,10 @@ ZEND_METHOD(ZipArchive, open); ZEND_METHOD(ZipArchive, openString); ZEND_METHOD(ZipArchive, setPassword); ZEND_METHOD(ZipArchive, close); +ZEND_METHOD(ZipArchive, closeString); ZEND_METHOD(ZipArchive, count); +ZEND_METHOD(ZipArchive, __serialize); +ZEND_METHOD(ZipArchive, __unserialize); ZEND_METHOD(ZipArchive, getStatusString); ZEND_METHOD(ZipArchive, clearError); ZEND_METHOD(ZipArchive, addEmptyDir); @@ -399,7 +413,10 @@ static const zend_function_entry class_ZipArchive_methods[] = { ZEND_ME(ZipArchive, openString, arginfo_class_ZipArchive_openString, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, setPassword, arginfo_class_ZipArchive_setPassword, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, close, arginfo_class_ZipArchive_close, ZEND_ACC_PUBLIC) + ZEND_ME(ZipArchive, closeString, arginfo_class_ZipArchive_closeString, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, count, arginfo_class_ZipArchive_count, ZEND_ACC_PUBLIC) + ZEND_ME(ZipArchive, __serialize, arginfo_class_ZipArchive___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(ZipArchive, __unserialize, arginfo_class_ZipArchive___unserialize, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, getStatusString, arginfo_class_ZipArchive_getStatusString, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, clearError, arginfo_class_ZipArchive_clearError, ZEND_ACC_PUBLIC) ZEND_ME(ZipArchive, addEmptyDir, arginfo_class_ZipArchive_addEmptyDir, ZEND_ACC_PUBLIC) diff --git a/ext/zip/tests/ZipArchive_closeString_basic.phpt b/ext/zip/tests/ZipArchive_closeString_basic.phpt new file mode 100644 index 000000000000..852a7ebf53f3 --- /dev/null +++ b/ext/zip/tests/ZipArchive_closeString_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +ZipArchive::closeString() basic +--EXTENSIONS-- +zip +--FILE-- +openString(); +$zip->addFromString('test1', '1'); +$zip->addFromString('test2', '2'); +$contents = $zip->closeString(); +echo $contents ? "OK\n" : "FAILED\n"; + +$zip = new ZipArchive(); +$zip->openString($contents); +var_dump($zip->getFromName('test1')); +var_dump($zip->getFromName('test2')); +var_dump($zip->getFromName('nonexistent')); + +?> +--EXPECT-- +OK +string(1) "1" +string(1) "2" +bool(false) diff --git a/ext/zip/tests/ZipArchive_closeString_error.phpt b/ext/zip/tests/ZipArchive_closeString_error.phpt new file mode 100644 index 000000000000..d5dca14a97fc --- /dev/null +++ b/ext/zip/tests/ZipArchive_closeString_error.phpt @@ -0,0 +1,47 @@ +--TEST-- +ZipArchive::closeString() error cases +--EXTENSIONS-- +zip +--FILE-- +openString(); +var_dump($zip->open(__DIR__ . '/test.zip')); +try { + $zip->closeString(); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +echo "2.\n"; +$zip = new ZipArchive(); +$zip->openString('...'); +echo $zip->getStatusString() . "\n"; +try { + $zip->closeString(); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +echo "3.\n"; +$zip = new ZipArchive(); +$zip->openString(file_get_contents(__DIR__ . '/test.zip')); +echo gettype($zip->closeString()) . "\n"; +try { + $zip->closeString(); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +1. +bool(true) +ZipArchive::closeString can only be called on an archive opened with ZipArchive::openString +2. +Not a zip archive +Invalid or uninitialized Zip object +3. +string +Invalid or uninitialized Zip object diff --git a/ext/zip/tests/ZipArchive_closeString_false.phpt b/ext/zip/tests/ZipArchive_closeString_false.phpt new file mode 100644 index 000000000000..af5241f5c3b6 --- /dev/null +++ b/ext/zip/tests/ZipArchive_closeString_false.phpt @@ -0,0 +1,22 @@ +--TEST-- +ZipArchive::closeString() false return +--EXTENSIONS-- +zip +--FILE-- +openString($input)); +$zip->setCompressionIndex(0, ZipArchive::CM_DEFLATE); +var_dump($zip->closeString()); +echo $zip->getStatusString() . "\n"; +?> +--EXPECTREGEX-- +bool\(true\) + +Warning: ZipArchive::closeString\(\): (Zip archive inconsistent|Unexpected length of data).* +bool\(false\) +(Zip archive inconsistent|Unexpected length of data).* diff --git a/ext/zip/tests/ZipArchive_closeString_variation.phpt b/ext/zip/tests/ZipArchive_closeString_variation.phpt new file mode 100644 index 000000000000..a1922ebd8f1f --- /dev/null +++ b/ext/zip/tests/ZipArchive_closeString_variation.phpt @@ -0,0 +1,39 @@ +--TEST-- +ZipArchive::closeString() variations +--EXTENSIONS-- +zip +--FILE-- +openString(); +var_dump($zip->closeString()); +echo $zip->getStatusString() . "\n"; + +echo "2. Update existing archive\n"; +$input = file_get_contents(__DIR__ . '/test.zip'); +$zip = new ZipArchive(); +$zip->openString($input); +$zip->addFromString('entry1.txt', ''); +$result = $zip->closeString(); +echo gettype($result) . "\n"; +var_dump($input !== $result); + +echo "3. Unchanged existing archive\n"; +$zip = new ZipArchive(); +$zip->openString($input); +$result = $zip->closeString(); +echo gettype($result) . "\n"; +var_dump($input === $result); + +?> +--EXPECT-- +1. Empty archive creation +string(0) "" +No error +2. Update existing archive +string +bool(true) +3. Unchanged existing archive +string +bool(true) diff --git a/ext/zip/tests/ZipArchive_openString.phpt b/ext/zip/tests/ZipArchive_openString.phpt index f787b4a84933..2a11505fcf69 100644 --- a/ext/zip/tests/ZipArchive_openString.phpt +++ b/ext/zip/tests/ZipArchive_openString.phpt @@ -4,8 +4,10 @@ ZipArchive::openString() method zip --FILE-- openString(file_get_contents(__DIR__."/test_procedural.zip")); +$zip->openString($input, ZipArchive::RDONLY); for ($i = 0; $i < $zip->numFiles; $i++) { $stat = $zip->statIndex($i); @@ -17,8 +19,22 @@ var_dump($zip->addFromString("foobar/baz", "baz")); var_dump($zip->addEmptyDir("blub")); var_dump($zip->close()); + +echo "2. CREATE and EXCL flags\n"; +$zip = new ZipArchive(); +var_dump($zip->openString($input, ZipArchive::CREATE)); +var_dump($zip->openString($input, ZipArchive::EXCL)); +echo $zip->getStatusString() . "\n"; + +echo "3. CHECKCONS flag\n"; +$inconsistent = file_get_contents(__DIR__ . '/checkcons.zip'); +$zip = new ZipArchive(); +var_dump($zip->openString($inconsistent)); +var_dump($zip->openString($inconsistent, ZipArchive::CHECKCONS)); + ?> --EXPECTF-- +1. Open read-only and read directory foo bar foobar/ @@ -26,3 +42,10 @@ foobar/baz bool(false) bool(false) bool(true) +2. CREATE and EXCL flags +bool(true) +int(10) +File already exists +3. CHECKCONS flag +bool(true) +int(%d) diff --git a/ext/zip/tests/bug53603.phpt b/ext/zip/tests/bug53603.phpt index 914b0b8440c6..ddffff393546 100644 --- a/ext/zip/tests/bug53603.phpt +++ b/ext/zip/tests/bug53603.phpt @@ -28,5 +28,5 @@ $a = $zip->extractTo('teststream://test'); var_dump($a); ?> --EXPECTF-- -Warning: ZipArchive::extractTo(teststream://test/foo): Failed to open stream: "TestStream::stream_open" is not implemented in %s on line %d +Warning: ZipArchive::extractTo(): Failed to open stream: "TestStream::stream_open" is not implemented in %s on line %d bool(false) diff --git a/ext/zip/tests/bug72434.phpt b/ext/zip/tests/bug72434.phpt new file mode 100644 index 000000000000..e2ccebad3754 --- /dev/null +++ b/ext/zip/tests/bug72434.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize +--EXTENSIONS-- +zip +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Unserialization of 'ZipArchive' is not allowed, override __serialize() and __unserialize() to implement it diff --git a/ext/zip/tests/bug_gh21705.phpt b/ext/zip/tests/bug_gh21705.phpt new file mode 100644 index 000000000000..41dabb224510 --- /dev/null +++ b/ext/zip/tests/bug_gh21705.phpt @@ -0,0 +1,33 @@ +--TEST-- +ZipArchive::getFromIndex() honors FL_UNCHANGED for deleted entries +--EXTENSIONS-- +zip +--FILE-- +open($name, ZipArchive::CREATE); +$zip->addFromString('foo.txt', 'foo'); +$zip->addFromString('bar.txt', 'bar'); +$zip->close(); + +$zip = new ZipArchive; +$zip->open($name); + +$index = $zip->locateName('bar.txt'); +$zip->deleteName('bar.txt'); + +var_dump($zip->getFromName('bar.txt', 0, ZipArchive::FL_UNCHANGED)); +var_dump($zip->getFromIndex($index, 0, ZipArchive::FL_UNCHANGED)); + +$zip->close(); +?> +--CLEAN-- + +--EXPECT-- +string(3) "bar" +string(3) "bar" diff --git a/ext/zip/tests/checkcons.zip b/ext/zip/tests/checkcons.zip new file mode 100644 index 000000000000..50bcea128a46 Binary files /dev/null and b/ext/zip/tests/checkcons.zip differ diff --git a/ext/zip/tests/gh21682.phpt b/ext/zip/tests/gh21682.phpt new file mode 100644 index 000000000000..ee09c73e5c4d --- /dev/null +++ b/ext/zip/tests/gh21682.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-21682 (ZipArchive serialization is rejected) +--EXTENSIONS-- +zip +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Serialization of 'ZipArchive' is not allowed, override __serialize() and __unserialize() to implement it diff --git a/ext/zip/tests/gh21682_subclass.phpt b/ext/zip/tests/gh21682_subclass.phpt new file mode 100644 index 000000000000..8c50dd4f3a24 --- /dev/null +++ b/ext/zip/tests/gh21682_subclass.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21682 (ZipArchive subclass implements serialization via __serialize()/__unserialize()) +--EXTENSIONS-- +zip +--FILE-- + $this->closeString()]; + } + + public function __unserialize(array $data): void + { + $this->openString($data['data']); + } +} + +$zip = new MyArchive(); +$zip->openString(); +$zip->addFromString('test1', 'abc123'); + +$roundtrip = unserialize(serialize($zip)); +var_dump($roundtrip instanceof MyArchive); +var_dump($roundtrip->numFiles); +var_dump($roundtrip->getFromName('test1')); +?> +--EXPECT-- +bool(true) +int(1) +string(6) "abc123" diff --git a/ext/zip/tests/gh21682_subclass_no_overrides.phpt b/ext/zip/tests/gh21682_subclass_no_overrides.phpt new file mode 100644 index 000000000000..04fb49d9848e --- /dev/null +++ b/ext/zip/tests/gh21682_subclass_no_overrides.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-21682 (ZipArchive subclass without overrides inherits the serialization throw) +--EXTENSIONS-- +zip +--FILE-- +getMessage() . "\n"; +} + +try { + unserialize('O:5:"MyZip":0:{}'); + echo "ERROR: should have thrown\n"; +} catch (\Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Serialization of 'MyZip' is not allowed, override __serialize() and __unserialize() to implement it +Unserialization of 'MyZip' is not allowed, override __serialize() and __unserialize() to implement it diff --git a/ext/zip/tests/gh21698.phpt b/ext/zip/tests/gh21698.phpt new file mode 100644 index 000000000000..d77b2152e72f --- /dev/null +++ b/ext/zip/tests/gh21698.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21698 (ZipArchive::addGlob memory leak when open_basedir rejects the match) +--EXTENSIONS-- +zip +--FILE-- +open($zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); + +ini_set('open_basedir', '/nonexistent_dir_for_gh21698'); +var_dump($zip->addGlob(__FILE__, 0, [])); +$zip->close(); +?> +--CLEAN-- + +--EXPECTF-- +Warning: ZipArchive::addGlob(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d +bool(false) diff --git a/ext/zip/tests/gh22176.phpt b/ext/zip/tests/gh22176.phpt new file mode 100644 index 000000000000..90b6327072c9 --- /dev/null +++ b/ext/zip/tests/gh22176.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-22176 (Memory leak when a ZipArchive cancel callback bails out in the shutdown destructor) +--EXTENSIONS-- +zip +--SKIPIF-- + +--FILE-- +open(__DIR__ . '/gh22176_cancel.zip', ZipArchive::CREATE); +$zip->registerCancelCallback(function () { + throw new \Exception('cancel boom'); +}); +$zip->addFromString('test', 'test'); +echo "done\n"; +// The archive is flushed and the object destroyed during request shutdown; +// the thrown exception bails out through libzip's zip_close() without leaking +// its internal state, and the bailout resumes once libzip has unwound. +?> +--CLEAN-- + +--EXPECTF-- +done + +Fatal error: Uncaught Exception: cancel boom in %s:%d +Stack trace: +#0 [internal function]: {closure:%s:%d}() +#1 {main} + thrown in %s on line %d diff --git a/ext/zip/tests/gh22176_progress.phpt b/ext/zip/tests/gh22176_progress.phpt new file mode 100644 index 000000000000..5507fe24ab98 --- /dev/null +++ b/ext/zip/tests/gh22176_progress.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-22176 (Memory leak when a ZipArchive progress callback bails out in the shutdown destructor) +--EXTENSIONS-- +zip +--SKIPIF-- + +--FILE-- +open(__DIR__ . '/gh22176_progress.zip', ZipArchive::CREATE); +$zip->registerProgressCallback(0.5, function ($r) { + throw new \Exception('progress boom'); +}); +$zip->addFromString('test', 'test'); +echo "done\n"; +// The archive is flushed and the object destroyed during request shutdown; +// the thrown exception bails out through libzip's zip_close() without leaking +// its internal state, and the bailout resumes once libzip has unwound. +?> +--CLEAN-- + +--EXPECTF-- +done + +Fatal error: Uncaught Exception: progress boom in %s:%d +Stack trace: +#0 [internal function]: {closure:%s:%d}(0.0) +#1 {main} + thrown in %s on line %d diff --git a/ext/zip/tests/gh22649.phpt b/ext/zip/tests/gh22649.phpt new file mode 100644 index 000000000000..d6d0a0928184 --- /dev/null +++ b/ext/zip/tests/gh22649.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-22649 (setCommentName/Index after addFromString should not segfault) +--EXTENSIONS-- +zip +--FILE-- +open($file, ZipArchive::CREATE)) { + exit('failed'); +} + +$zip->addFromString('dir/entry2d.txt', 'entry #2'); +var_dump($zip->setCommentName('dir/entry2d.txt', 'dir/entry2d.txt')); + +$zip->addFromString('dir/entry3d.txt', 'entry #3'); +var_dump($zip->setCommentIndex($zip->lastId, 'dir/entry3d.txt')); + +$zip->close(); + +if (!$zip->open($file, ZipArchive::CREATE)) { + exit('failed'); +} + +$zip->addFromString('dir/entry2d.txt', 'updated entry #2'); +var_dump($zip->setCommentName('dir/entry2d.txt', 'dir/entry2d.txt')); + +$zip->addFromString('dir/entry3d.txt', 'updated entry #3'); +var_dump($zip->setCommentIndex($zip->lastId, 'dir/entry3d.txt')); + +$zip->close(); + +if (!$zip->open($file)) { + exit('failed'); +} + +var_dump($zip->getCommentName('dir/entry2d.txt')); +var_dump($zip->getCommentName('dir/entry3d.txt')); + +$zip->close(); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +string(15) "dir/entry2d.txt" +string(15) "dir/entry3d.txt" +--CLEAN-- + diff --git a/ext/zip/tests/oo_encryption.phpt b/ext/zip/tests/oo_encryption.phpt index f5207e307599..448979b5e532 100644 --- a/ext/zip/tests/oo_encryption.phpt +++ b/ext/zip/tests/oo_encryption.phpt @@ -60,7 +60,7 @@ string(3) "bar" == Stream string(3) "foo" -Warning: file_get_contents(%s): Failed to open stream: operation failed in %s on line %d +Warning: file_get_contents(): Failed to open stream: operation failed in %s on line %d bool(false) string(3) "bar" == Done diff --git a/ext/zip/tests/wrong-file-size.zip b/ext/zip/tests/wrong-file-size.zip new file mode 100644 index 000000000000..fc9fa1a434c7 Binary files /dev/null and b/ext/zip/tests/wrong-file-size.zip differ diff --git a/ext/zip/zip_source.c b/ext/zip/zip_source.c new file mode 100644 index 000000000000..03fa50867d56 --- /dev/null +++ b/ext/zip/zip_source.c @@ -0,0 +1,210 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Tim Starling | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "php.h" +#include "php_zip.h" + +typedef struct _php_zip_string_source { + /* The current string being read from */ + zend_string *in_str; + /* The offset into in_str of the current read position */ + size_t in_offset; + /* The modification time returned in stat calls */ + time_t mtime; + /* The current string being written to */ + zend_string *out_str; + /* The offset into out_str of the current write position */ + size_t out_offset; + /* A place to copy the result to when the archive is closed, or NULL */ + zend_string **dest; + /* The error to be returned when libzip asks for the last error code */ + zip_error_t error; +} php_zip_string_source; + +/* The source callback function, see https://libzip.org/documentation/zip_source_function.html + * This is similar to read_data() in libzip's zip_source_buffer.c */ +static zip_int64_t php_zip_string_cb(void *userdata, void *data, zip_uint64_t len, zip_source_cmd_t cmd) +{ + php_zip_string_source *ctx = userdata; + switch (cmd) { + case ZIP_SOURCE_SUPPORTS: + return zip_source_make_command_bitmap( + ZIP_SOURCE_FREE, +#if LIBZIP_VERSION_MAJOR > 1 || LIBZIP_VERSION_MINOR >= 10 + ZIP_SOURCE_SUPPORTS_REOPEN, +#endif + ZIP_SOURCE_OPEN, + ZIP_SOURCE_READ, + ZIP_SOURCE_CLOSE, + ZIP_SOURCE_STAT, + ZIP_SOURCE_ERROR, + ZIP_SOURCE_SEEK, + ZIP_SOURCE_TELL, + ZIP_SOURCE_BEGIN_WRITE, + ZIP_SOURCE_WRITE, + ZIP_SOURCE_COMMIT_WRITE, + ZIP_SOURCE_ROLLBACK_WRITE, + ZIP_SOURCE_SEEK_WRITE, + ZIP_SOURCE_TELL_WRITE, + ZIP_SOURCE_REMOVE, + -1 + ); + + case ZIP_SOURCE_FREE: + zend_string_release(ctx->out_str); + zend_string_release(ctx->in_str); + efree(ctx); + return 0; + + /* Read ops */ + + case ZIP_SOURCE_OPEN: + ctx->in_offset = 0; + return 0; + + case ZIP_SOURCE_READ: { + size_t remaining = ZSTR_LEN(ctx->in_str) - ctx->in_offset; + len = MIN(len, remaining); + if (len) { + memcpy(data, ZSTR_VAL(ctx->in_str) + ctx->in_offset, len); + ctx->in_offset += len; + } + return len; + } + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + if (len < sizeof(*st)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + st = (zip_stat_t *)data; + zip_stat_init(st); + st->mtime = ctx->mtime; + st->size = ZSTR_LEN(ctx->in_str); + st->comp_size = st->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid = ZIP_STAT_MTIME | ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; + + return sizeof(*st); + } + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + /* Seekable read ops */ + + case ZIP_SOURCE_SEEK: { + zip_int64_t new_offset = zip_source_seek_compute_offset( + ctx->in_offset, ZSTR_LEN(ctx->in_str), data, len, &ctx->error); + if (new_offset < 0) { + return -1; + } + ctx->in_offset = (size_t)new_offset; + return 0; + } + + case ZIP_SOURCE_TELL: + if (ctx->in_offset > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); + return -1; + } + return (zip_int64_t)ctx->in_offset; + + /* Write ops */ + + case ZIP_SOURCE_BEGIN_WRITE: + zend_string_release(ctx->out_str); + ctx->out_str = ZSTR_EMPTY_ALLOC(); + return 0; + + case ZIP_SOURCE_WRITE: + if (ctx->out_offset > SIZE_MAX - len) { + zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); + return -1; + } + if (ctx->out_offset + len > ZSTR_LEN(ctx->out_str)) { + ctx->out_str = zend_string_realloc(ctx->out_str, ctx->out_offset + len, false); + } + memcpy(ZSTR_VAL(ctx->out_str) + ctx->out_offset, data, len); + ctx->out_offset += len; + return len; + + case ZIP_SOURCE_COMMIT_WRITE: + ZSTR_VAL(ctx->out_str)[ZSTR_LEN(ctx->out_str)] = '\0'; + zend_string_release(ctx->in_str); + ctx->in_str = ctx->out_str; + ctx->out_str = ZSTR_EMPTY_ALLOC(); + if (ctx->dest) { + zend_string_release(*(ctx->dest)); + *(ctx->dest) = zend_string_copy(ctx->in_str); + } + return 0; + + case ZIP_SOURCE_ROLLBACK_WRITE: + zend_string_release(ctx->out_str); + ctx->out_str = ZSTR_EMPTY_ALLOC(); + return 0; + + case ZIP_SOURCE_SEEK_WRITE: { + zip_int64_t new_offset = zip_source_seek_compute_offset( + ctx->out_offset, ZSTR_LEN(ctx->out_str), data, len, &ctx->error); + if (new_offset < 0) { + return -1; + } + ctx->out_offset = new_offset; + return 0; + } + + case ZIP_SOURCE_TELL_WRITE: + if (ctx->out_offset > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); + return -1; + } + return (zip_int64_t)ctx->out_offset; + + case ZIP_SOURCE_REMOVE: + zend_string_release(ctx->in_str); + ctx->in_str = ZSTR_EMPTY_ALLOC(); + ctx->in_offset = 0; + return 0; + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } +} + +zip_source_t * php_zip_create_string_source(zend_string *str, zend_string **dest, zip_error_t *err) +{ + php_zip_string_source *ctx = ecalloc(1, sizeof(php_zip_string_source)); + ctx->in_str = zend_string_copy(str); + ctx->out_str = ZSTR_EMPTY_ALLOC(); + ctx->dest = dest; + ctx->mtime = time(NULL); + + if (dest) { + *dest = zend_string_copy(str); + } + + return zip_source_function_create(php_zip_string_cb, (void*)ctx, err); +} diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index 9d6fb733575b..d4c24bd24e13 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Piere-Alain Joye | +----------------------------------------------------------------------+ diff --git a/ext/zlib/php_zlib.h b/ext/zlib/php_zlib.h index b7a9484cd28f..c7286d5c858a 100644 --- a/ext/zlib/php_zlib.h +++ b/ext/zlib/php_zlib.h @@ -1,17 +1,15 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stefan R�hrich | + | Stefan Röhrich | | Michael Wallner | +----------------------------------------------------------------------+ */ diff --git a/ext/zlib/tests/bug55544-win.phpt b/ext/zlib/tests/bug55544-win.phpt index 11116da28b6d..02a1ac837000 100644 Binary files a/ext/zlib/tests/bug55544-win.phpt and b/ext/zlib/tests/bug55544-win.phpt differ diff --git a/ext/zlib/tests/data/func.inc b/ext/zlib/tests/data/func.inc deleted file mode 100644 index 73cfc4e06ffc..000000000000 --- a/ext/zlib/tests/data/func.inc +++ /dev/null @@ -1,18 +0,0 @@ - (\d+\.\d+\.\d+),s', $info, $match)) { - // $version = $match[1]; - if (preg_match(',zlib(?!.*libXML).*Compiled Version (=> | 'foo']); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + deflate_init(ZLIB_ENCODING_DEFLATE, ['memory' => []]); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + deflate_init(ZLIB_ENCODING_DEFLATE, ['window' => new A()]); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + deflate_init(ZLIB_ENCODING_DEFLATE, ['strategy' => $fp]); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +fclose($fp); + +?> +--EXPECT-- +deflate_init(): Argument #2 ($options) the value for option "level" must be of type int, string given +deflate_init(): Argument #2 ($options) the value for option "memory" must be of type int, array given +deflate_init(): Argument #2 ($options) the value for option "window" must be of type int, A given +deflate_init(): Argument #2 ($options) the value for option "strategy" must be of type int, resource given diff --git a/ext/zlib/tests/gh19922.phpt b/ext/zlib/tests/gh19922.phpt index 71644512e665..a9d76a331310 100644 --- a/ext/zlib/tests/gh19922.phpt +++ b/ext/zlib/tests/gh19922.phpt @@ -7,6 +7,5 @@ zlib var_dump(gzopen("php://output", 14)); ?> --EXPECTF-- - -Warning: gzopen(php://output): could not make seekable - php://output in %s on line %d +Warning: gzopen(): could not make seekable - php://output in %s on line %d bool(false) diff --git a/ext/zlib/tests/gh22142.phpt b/ext/zlib/tests/gh22142.phpt new file mode 100644 index 000000000000..84397a4e85a9 --- /dev/null +++ b/ext/zlib/tests/gh22142.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF) +--EXTENSIONS-- +zlib +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +deflate_init(): Argument #2 ($options) the value for option "level" must be of type int, null given diff --git a/ext/zlib/tests/gzencode_variation2-win32.phpt b/ext/zlib/tests/gzencode_variation2-win32.phpt index 2cc1f982089d..183d67f359b8 100644 --- a/ext/zlib/tests/gzencode_variation2-win32.phpt +++ b/ext/zlib/tests/gzencode_variation2-win32.phpt @@ -7,9 +7,8 @@ zlib if( substr(PHP_OS, 0, 3) != "WIN" ) { die("skip.. only for Windows"); } -include 'data/func.inc'; -if (version_compare(get_zlib_version(), "1.2.11") < 0) { - die("skip - at least zlib 1.2.11 required, got " . get_zlib_version()); +if (version_compare(ZLIB_VERSION, "1.2.11") < 0) { + die("skip - at least zlib 1.2.11 required, got " . ZLIB_VERSION); } ?> --FILE-- diff --git a/ext/zlib/tests/gzfile_variation7.phpt b/ext/zlib/tests/gzfile_variation7.phpt index ca221c12cff3..e95443ce267c 100644 --- a/ext/zlib/tests/gzfile_variation7.phpt +++ b/ext/zlib/tests/gzfile_variation7.phpt @@ -11,8 +11,8 @@ var_dump(gzfile($filename, false)); var_dump(gzfile($filename, true)); ?> --EXPECTF-- -Warning: gzfile(nonexistent_file_gzfile.txt.gz): Failed to open stream: No such file or directory in %s on line %d +Warning: gzfile(): Failed to open stream: No such file or directory in %s on line %d bool(false) -Warning: gzfile(nonexistent_file_gzfile.txt.gz): Failed to open stream: No such file or directory in %s on line %d +Warning: gzfile(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/zlib/tests/gzgetc_basic.phpt b/ext/zlib/tests/gzgetc_basic.phpt index ce366e4b6b31..3540332a740e 100644 --- a/ext/zlib/tests/gzgetc_basic.phpt +++ b/ext/zlib/tests/gzgetc_basic.phpt @@ -4,8 +4,7 @@ Test function gzgetc() by calling it with its expected arguments zlib 1.2.5 zlib --SKIPIF-- 0) { +if (version_compare(ZLIB_VERSION, '1.2.5') > 0) { die('skip - only for zlib <= 1.2.5'); } ?> diff --git a/ext/zlib/tests/gzgetc_basic_1.phpt b/ext/zlib/tests/gzgetc_basic_1.phpt index cf6da96e5612..82d7c1941327 100644 --- a/ext/zlib/tests/gzgetc_basic_1.phpt +++ b/ext/zlib/tests/gzgetc_basic_1.phpt @@ -4,9 +4,7 @@ Test function gzgetc() by calling it with its expected arguments zlib 1.2.7 zlib --SKIPIF-- = 1.2.7'); } ?> diff --git a/ext/zlib/tests/gzopen_variation9.phpt b/ext/zlib/tests/gzopen_variation9.phpt index f9ac099dc253..0118dd3ea130 100644 --- a/ext/zlib/tests/gzopen_variation9.phpt +++ b/ext/zlib/tests/gzopen_variation9.phpt @@ -38,6 +38,6 @@ gzopen=bool(false) mode=e -Warning: gzopen(%s/test.txt.gz): Failed to open stream: %s in %s on line %d +Warning: gzopen(): Failed to open stream: %s in %s on line %d gzopen=bool(false) diff --git a/ext/zlib/tests/inflate_add_no_dict.phpt b/ext/zlib/tests/inflate_add_no_dict.phpt new file mode 100644 index 000000000000..da805e567022 --- /dev/null +++ b/ext/zlib/tests/inflate_add_no_dict.phpt @@ -0,0 +1,22 @@ +--TEST-- +inflate_add(): Z_NEED_DICT returned when no dictionary provided to inflate_init() +--EXTENSIONS-- +zlib +--FILE-- + $dict]); +$compressed = deflate_add($dc, $data, ZLIB_FINISH); + +// Inflate without supplying the dictionary +$ic = inflate_init(ZLIB_ENCODING_DEFLATE); +$result = inflate_add($ic, $compressed, ZLIB_SYNC_FLUSH); +var_dump($result); + +?> +--EXPECTF-- +Warning: inflate_add(): Inflating this data requires a preset dictionary, please specify it in the options array of inflate_init() in %s on line %d +bool(false) diff --git a/ext/zlib/tests/inflate_init_window_type_error.phpt b/ext/zlib/tests/inflate_init_window_type_error.phpt new file mode 100644 index 000000000000..fbca3129681e --- /dev/null +++ b/ext/zlib/tests/inflate_init_window_type_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +inflate_init(): window option type validation +--EXTENSIONS-- +zlib +--FILE-- + []]); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +inflate_init(): Argument #2 ($options) the value for option "window" must be of type int, array given diff --git a/ext/zlib/tests/readgzfile_variation7.phpt b/ext/zlib/tests/readgzfile_variation7.phpt index 6f201abe2361..a90feb9b2009 100644 --- a/ext/zlib/tests/readgzfile_variation7.phpt +++ b/ext/zlib/tests/readgzfile_variation7.phpt @@ -10,8 +10,8 @@ var_dump(readgzfile($file, false)); var_dump(readgzfile($file, true)); ?> --EXPECTF-- -Warning: readgzfile(unknown_file.txt.gz): Failed to open stream: No such file or directory in %s on line %d +Warning: readgzfile(): Failed to open stream: No such file or directory in %s on line %d bool(false) -Warning: readgzfile(unknown_file.txt.gz): Failed to open stream: No such file or directory in %s on line %d +Warning: readgzfile(): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/zlib/tests/zlib_filter_seek_deflate.phpt b/ext/zlib/tests/zlib_filter_seek_deflate.phpt new file mode 100644 index 000000000000..743f1be566fd --- /dev/null +++ b/ext/zlib/tests/zlib_filter_seek_deflate.phpt @@ -0,0 +1,52 @@ +--TEST-- +zlib.deflate write filter is not reset on seek +--EXTENSIONS-- +zlib +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Size after write: %d +Seek to start: SUCCESS +Seek to middle: SUCCESS +Decompressed content matches: YES diff --git a/ext/zlib/tests/zlib_filter_seek_inflate.phpt b/ext/zlib/tests/zlib_filter_seek_inflate.phpt new file mode 100644 index 000000000000..2ca7508941cc --- /dev/null +++ b/ext/zlib/tests/zlib_filter_seek_inflate.phpt @@ -0,0 +1,45 @@ +--TEST-- +zlib.inflate filter with seek to start +--EXTENSIONS-- +zlib +--FILE-- + +--CLEAN-- + +--EXPECTF-- +First read (20 bytes): I am the very model +Seek to start: SUCCESS +Position after seek: 0 +Content after seek matches: YES + +Warning: fseek(): Stream filter zlib.inflate is seekable only to start position in %s on line %d +Seek to middle: FAILURE diff --git a/ext/zlib/tests/zlib_filter_write_seek_modes.phpt b/ext/zlib/tests/zlib_filter_write_seek_modes.phpt new file mode 100644 index 000000000000..39824a7283cf --- /dev/null +++ b/ext/zlib/tests/zlib_filter_write_seek_modes.phpt @@ -0,0 +1,78 @@ +--TEST-- +zlib.deflate write filter: write_seek_mode parameter +--EXTENSIONS-- +zlib +--FILE-- + 'reset']); +fwrite($fp, $text1); +ftruncate($fp, 0); +var_dump(fseek($fp, 0, SEEK_SET) === 0); +fwrite($fp, $text2); +fclose($fp); + +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ); +$decoded = stream_get_contents($fp); +fclose($fp); +var_dump($decoded === $text2); + +/* "reset": only seekable to start */ +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, + ['write_seek_mode' => 'reset']); +fwrite($fp, $text1); +var_dump(fseek($fp, 5, SEEK_SET) === 0); +fclose($fp); + +/* "preserve": same as default; seeks accepted, state preserved */ +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, + ['write_seek_mode' => 'preserve']); +fwrite($fp, $text1); +var_dump(fseek($fp, 0, SEEK_SET) === 0); +var_dump(fseek($fp, 50, SEEK_SET) === 0); +fclose($fp); + +/* "strict": every write-chain seek fails */ +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, + ['write_seek_mode' => 'strict']); +fwrite($fp, $text1); +var_dump(@fseek($fp, 0, SEEK_SET) === -1); +var_dump(@fseek($fp, 50, SEEK_SET) === -1); +fclose($fp); + +/* Invalid mode: ValueError */ +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, + ['write_seek_mode' => 'rewind']); +fclose($fp); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) +bool(true) + +Warning: fseek(): Stream filter zlib.deflate is seekable only to start position in %s +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s + +Warning: stream_filter_append(): Unable to create or locate filter "zlib.deflate" in %s diff --git a/ext/zlib/tests/zlib_scheme_dir_basic.phpt b/ext/zlib/tests/zlib_scheme_dir_basic.phpt index 683e87b8eff4..c551e0684f9e 100644 --- a/ext/zlib/tests/zlib_scheme_dir_basic.phpt +++ b/ext/zlib/tests/zlib_scheme_dir_basic.phpt @@ -15,6 +15,6 @@ var_dump(rmdir($srcFile)); bool(false) bool(false) -Warning: opendir(compress.zlib://%s/dir.gz): Failed to open directory: not implemented in %s on line %d +Warning: opendir(): Failed to open directory: not implemented in %s on line %d bool(false) bool(false) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index d5a89768ff62..5b630d74c889 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stefan Röhrich | @@ -49,9 +47,7 @@ ZEND_DECLARE_MODULE_GLOBALS(zlib) zend_class_entry *inflate_context_ce; static zend_object_handlers inflate_context_object_handlers; -static inline php_zlib_context *inflate_context_from_obj(zend_object *obj) { - return (php_zlib_context *)((char *)(obj) - XtOffsetOf(php_zlib_context, std)); -} +#define inflate_context_from_obj(obj) ZEND_CONTAINER_OF(obj, php_zlib_context, std) #define Z_INFLATE_CONTEXT_P(zv) inflate_context_from_obj(Z_OBJ_P(zv)) @@ -87,9 +83,7 @@ static void inflate_context_free_obj(zend_object *object) zend_class_entry *deflate_context_ce; static zend_object_handlers deflate_context_object_handlers; -static inline php_zlib_context *deflate_context_from_obj(zend_object *obj) { - return (php_zlib_context *)((char *)(obj) - XtOffsetOf(php_zlib_context, std)); -} +#define deflate_context_from_obj(obj) ZEND_CONTAINER_OF(obj, php_zlib_context, std) #define Z_DEFLATE_CONTEXT_P(zv) deflate_context_from_obj(Z_OBJ_P(zv)) @@ -856,6 +850,30 @@ static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_ return true; } +ZEND_ATTRIBUTE_NONNULL static bool zlib_get_long_option(HashTable *options, const char *option_name, size_t option_name_len, zend_long *value) +{ + bool failed = false; + zval *option_buffer = zend_hash_str_find(options, option_name, option_name_len); + + if (!option_buffer) { + return true; + } + + /* The |H ZPP specifier may leave HashTable entries wrapped in IS_INDIRECT. */ + ZVAL_DEINDIRECT(option_buffer); + *value = zval_try_get_long(option_buffer, &failed); + if (UNEXPECTED(failed)) { + zend_argument_type_error( + 2, + "the value for option \"%.*s\" must be of type int, %s given", + (int) option_name_len, option_name, zend_zval_value_name(option_buffer) + ); + return false; + } + + return true; +} + /* {{{ Initialize an incremental inflate context with the specified encoding */ PHP_FUNCTION(inflate_init) { @@ -863,16 +881,14 @@ PHP_FUNCTION(inflate_init) zend_long encoding, window = 15; char *dict = NULL; size_t dictlen = 0; - HashTable *options = NULL; - zval *option_buffer; + HashTable *options = (HashTable *) &zend_empty_array; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) { RETURN_THROWS(); } - if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) { - ZVAL_DEINDIRECT(option_buffer); - window = zval_get_long(option_buffer); + if (!zlib_get_long_option(options, ZEND_STRL("window"), &window)) { + RETURN_THROWS(); } if (window < 8 || window > 15) { zend_value_error("zlib window size (logarithm) (" ZEND_LONG_FMT ") must be within 8..15", window); @@ -909,6 +925,7 @@ PHP_FUNCTION(inflate_init) } if (inflateInit2(&ctx->Z, encoding) != Z_OK) { + /* dict is stored in the ctx in the object and will thus be freed by zval_ptr_dtor(). */ zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Failed allocating zlib.inflate context"); RETURN_FALSE; @@ -925,7 +942,7 @@ PHP_FUNCTION(inflate_init) efree(ctx->inflateDict); ctx->inflateDict = NULL; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } } @@ -1022,10 +1039,11 @@ PHP_FUNCTION(inflate_add) zend_string_release_ex(out, 0); php_error_docref(NULL, E_WARNING, "Dictionary does not match expected dictionary (incorrect adler32 hash)"); RETURN_FALSE; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } break; } else { + zend_string_release_ex(out, false); php_error_docref(NULL, E_WARNING, "Inflating this data requires a preset dictionary, please specify it in the options array of inflate_init()"); RETURN_FALSE; } @@ -1082,43 +1100,38 @@ PHP_FUNCTION(deflate_init) zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY; char *dict = NULL; size_t dictlen = 0; - HashTable *options = NULL; - zval *option_buffer; + HashTable *options = (HashTable*)&zend_empty_array; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) { RETURN_THROWS(); } - if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("level"))) != NULL) { - ZVAL_DEINDIRECT(option_buffer); - level = zval_get_long(option_buffer); + if (!zlib_get_long_option(options, ZEND_STRL("level"), &level)) { + RETURN_THROWS(); } if (level < -1 || level > 9) { zend_value_error("deflate_init(): \"level\" option must be between -1 and 9"); RETURN_THROWS(); } - if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("memory"))) != NULL) { - ZVAL_DEINDIRECT(option_buffer); - memory = zval_get_long(option_buffer); + if (!zlib_get_long_option(options, ZEND_STRL("memory"), &memory)) { + RETURN_THROWS(); } if (memory < 1 || memory > 9) { zend_value_error("deflate_init(): \"memory\" option must be between 1 and 9"); RETURN_THROWS(); } - if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) { - ZVAL_DEINDIRECT(option_buffer); - window = zval_get_long(option_buffer); + if (!zlib_get_long_option(options, ZEND_STRL("window"), &window)) { + RETURN_THROWS(); } if (window < 8 || window > 15) { zend_value_error("deflate_init(): \"window\" option must be between 8 and 15"); RETURN_THROWS(); } - if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("strategy"))) != NULL) { - ZVAL_DEINDIRECT(option_buffer); - strategy = zval_get_long(option_buffer); + if (!zlib_get_long_option(options, ZEND_STRL("strategy"), &strategy)) { + RETURN_THROWS(); } switch (strategy) { case Z_FILTERED: @@ -1159,6 +1172,7 @@ PHP_FUNCTION(deflate_init) } if (deflateInit2(&ctx->Z, level, Z_DEFLATED, encoding, memory, strategy) != Z_OK) { + efree(dict); zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Failed allocating zlib.deflate context"); RETURN_FALSE; @@ -1239,13 +1253,11 @@ PHP_FUNCTION(deflate_add) ZSTR_LEN(out) = (char *) ctx->Z.next_out - ZSTR_VAL(out); ZSTR_VAL(out)[ZSTR_LEN(out)] = 0; RETURN_STR(out); - break; case Z_STREAM_END: ZSTR_LEN(out) = (char *) ctx->Z.next_out - ZSTR_VAL(out); ZSTR_VAL(out)[ZSTR_LEN(out)] = 0; deflateReset(&ctx->Z); RETURN_STR(out); - break; default: zend_string_release_ex(out, 0); php_error_docref(NULL, E_WARNING, "zlib error (%s)", zError(status)); @@ -1265,7 +1277,6 @@ ZEND_GET_MODULE(php_zlib) static PHP_INI_MH(OnUpdate_zlib_output_compression) { int int_value; - char *ini_value; if (new_value == NULL) { return FAILURE; } @@ -1277,9 +1288,9 @@ static PHP_INI_MH(OnUpdate_zlib_output_compression) } else { int_value = (int) zend_ini_parse_quantity_warn(new_value, entry->name); } - ini_value = zend_ini_string("output_handler", sizeof("output_handler") - 1, 0); + const zend_string *ini_value = zend_ini_str_literal("output_handler"); - if (ini_value && *ini_value && int_value) { + if (ini_value && ZSTR_LEN(ini_value) > 0 && int_value) { php_error_docref("ref.outcontrol", E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!"); return FAILURE; } @@ -1341,7 +1352,7 @@ static PHP_MINIT_FUNCTION(zlib) inflate_context_ce->default_object_handlers = &inflate_context_object_handlers; memcpy(&inflate_context_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - inflate_context_object_handlers.offset = XtOffsetOf(php_zlib_context, std); + inflate_context_object_handlers.offset = offsetof(php_zlib_context, std); inflate_context_object_handlers.free_obj = inflate_context_free_obj; inflate_context_object_handlers.get_constructor = inflate_context_get_constructor; inflate_context_object_handlers.clone_obj = NULL; @@ -1352,7 +1363,7 @@ static PHP_MINIT_FUNCTION(zlib) deflate_context_ce->default_object_handlers = &deflate_context_object_handlers; memcpy(&deflate_context_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - deflate_context_object_handlers.offset = XtOffsetOf(php_zlib_context, std); + deflate_context_object_handlers.offset = offsetof(php_zlib_context, std); deflate_context_object_handlers.free_obj = deflate_context_free_obj; deflate_context_object_handlers.get_constructor = deflate_context_get_constructor; deflate_context_object_handlers.clone_obj = NULL; diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index e42132fd0008..2d0e4fbb7fa4 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon (pollita@php.net) | +----------------------------------------------------------------------+ @@ -28,6 +26,7 @@ typedef struct _php_zlib_filter_data { size_t outbuf_len; int persistent; bool finished; /* for zlib.deflate: signals that no flush is pending */ + int windowBits; } php_zlib_filter_data; /* }}} */ @@ -143,6 +142,47 @@ static php_stream_filter_status_t php_zlib_inflate_filter( return exit_status; } +static zend_result php_zlib_inflate_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + int status; + + if (!thisfilter || !Z_PTR(thisfilter->abstract)) { + return FAILURE; + } + + php_zlib_filter_data *data = Z_PTR(thisfilter->abstract); + + if (data->finished) { + /* Stream was ended, need to reinitialize */ + status = inflateInit2(&(data->strm), data->windowBits); + if (status != Z_OK) { + php_error_docref(NULL, E_WARNING, "zlib.inflate: failed to reinitialize inflation state"); + return FAILURE; + } + } else { + /* Stream is active, just reset it */ + status = inflateReset(&(data->strm)); + if (status != Z_OK) { + php_error_docref(NULL, E_WARNING, "zlib.inflate: failed to reset inflation state"); + return FAILURE; + } + } + + /* Reset our own state */ + data->strm.next_in = data->inbuf; + data->strm.avail_in = 0; + data->strm.next_out = data->outbuf; + data->strm.avail_out = data->outbuf_len; + data->finished = false; + + return SUCCESS; +} + static void php_zlib_inflate_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -158,6 +198,7 @@ static void php_zlib_inflate_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops php_zlib_inflate_ops = { php_zlib_inflate_filter, + php_zlib_inflate_seek, php_zlib_inflate_dtor, "zlib.inflate" }; @@ -259,6 +300,38 @@ static php_stream_filter_status_t php_zlib_deflate_filter( return exit_status; } +static zend_result php_zlib_deflate_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + int status; + + if (!thisfilter || !Z_PTR(thisfilter->abstract)) { + return FAILURE; + } + + php_zlib_filter_data *data = Z_PTR(thisfilter->abstract); + + /* Reset zlib deflation state */ + status = deflateReset(&(data->strm)); + if (status != Z_OK) { + php_error_docref(NULL, E_WARNING, "zlib.deflate: failed to reset deflation state"); + return FAILURE; + } + + /* Reset our own state */ + data->strm.next_in = data->inbuf; + data->strm.avail_in = 0; + data->strm.next_out = data->outbuf; + data->strm.avail_out = data->outbuf_len; + data->finished = true; + + return SUCCESS; +} + static void php_zlib_deflate_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -272,6 +345,7 @@ static void php_zlib_deflate_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops php_zlib_deflate_ops = { php_zlib_deflate_filter, + php_zlib_deflate_seek, php_zlib_deflate_dtor, "zlib.deflate" }; @@ -280,12 +354,17 @@ static const php_stream_filter_ops php_zlib_deflate_ops = { /* {{{ zlib.* common factory */ -static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *filterparams, bool persistent) { const php_stream_filter_ops *fops = NULL; + php_stream_filter_seekable_t write_seekable; php_zlib_filter_data *data; int status; + if (php_stream_filter_parse_write_seek_mode(filterparams, &write_seekable) == FAILURE) { + return NULL; + } + /* Create this filter */ data = pecalloc(1, sizeof(php_zlib_filter_data), persistent); if (!data) { @@ -315,6 +394,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f } data->strm.data_type = Z_ASCII; + data->persistent = persistent; if (strcasecmp(filtername, "zlib.inflate") == 0) { int windowBits = -MAX_WBITS; @@ -334,6 +414,9 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f } } + /* Save configuration for reset */ + data->windowBits = windowBits; + /* RFC 1951 Inflate */ data->finished = false; status = inflateInit2(&(data->strm), windowBits); @@ -401,6 +484,10 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f php_error_docref(NULL, E_WARNING, "Invalid filter parameter, ignored"); } } + + /* Save configuration for reset */ + data->windowBits = windowBits; + status = deflateInit2(&(data->strm), level, Z_DEFLATED, windowBits, memLevel, 0); data->finished = true; fops = &php_zlib_deflate_ops; @@ -416,7 +503,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f return NULL; } - return php_stream_filter_alloc(fops, data, persistent); + return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START, write_seekable); } const php_stream_filter_factory php_zlib_filter_factory = { diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c index 7420c0cc6ff2..aebf368a16ed 100644 --- a/ext/zlib/zlib_fopen_wrapper.c +++ b/ext/zlib/zlib_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong , based on work by: | | Hartmut Holzgraefe | diff --git a/gcovr.cfg b/gcovr.cfg new file mode 100644 index 000000000000..7ee4cff356e8 --- /dev/null +++ b/gcovr.cfg @@ -0,0 +1,23 @@ +print-summary = yes + +exclude-throw-branches = yes +exclude-unreachable-branches = yes + +exclude = ext/bcmath/libbcmath/.* +exclude = ext/date/lib/.* +exclude = ext/fileinfo/libmagic/.* +exclude = ext/gd/libgd/.* +exclude = ext/hash/sha3/.* +exclude = ext/lexbor/lexbor/.* +exclude = ext/mbstring/libmbfl/.* +exclude = ext/opcache/jit/ir/.* +exclude = ext/pcre/pcre2lib/.* +exclude = ext/uri/uriparser/.* +exclude = Zend/Optimizer/ssa_integrity\.c +exclude = Zend/Optimizer/zend_dump\.c + +# These patterns have implicit ^/$ anchors. +exclude-lines-by-pattern = .*\b(ZEND_PARSE_PARAMETERS_(START|END|NONE)|Z_PARAM_).* +exclude-lines-by-pattern = \s*(default:\s*)?ZEND_UNREACHABLE\(\);\s* +exclude-lines-by-pattern = \s*if \(ctx->debug_level & ZEND_DUMP_\w+\) \{\s* +exclude-lines-by-pattern = \s*zend_dump_op_array\(.*\);\s* diff --git a/main/SAPI.c b/main/SAPI.c index 2fd7e18adcea..62e1c89e4bb9 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Original design: Shane Caraveo | | Authors: Andi Gutmans | @@ -191,7 +189,7 @@ SAPI_API void sapi_read_post_data(void) *p = 0; break; default: - *p = tolower(*p); + *p = tolower((unsigned char)*p); break; } } @@ -733,10 +731,10 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) } /* cut off trailing spaces, linefeeds and carriage-returns */ - if (header_line_len && isspace(header_line[header_line_len-1])) { + if (header_line_len && isspace((unsigned char)header_line[header_line_len - 1])) { do { header_line_len--; - } while(header_line_len && isspace(header_line[header_line_len-1])); + } while(header_line_len && isspace((unsigned char)header_line[header_line_len - 1])); header_line[header_line_len]='\0'; } diff --git a/main/SAPI.h b/main/SAPI.h index 9196982f5495..e62f686603c4 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ diff --git a/main/build-defs.h.in b/main/build-defs.h.in index 72cd9c30fb74..2c62998fc586 100644 --- a/main/build-defs.h.in +++ b/main/build-defs.h.in @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/main/explicit_bzero.c b/main/explicit_bzero.c index c49bdede6624..541c9f408e9a 100644 --- a/main/explicit_bzero.c +++ b/main/explicit_bzero.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/fastcgi.c b/main/fastcgi.c index 3488d6e21eae..02ef614f4639 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -737,7 +735,7 @@ int fcgi_listen(const char *path, int backlog) memset(&sa.sa_unix, 0, sizeof(sa.sa_unix)); sa.sa_unix.sun_family = AF_UNIX; memcpy(sa.sa_unix.sun_path, path, path_len + 1); - sock_len = XtOffsetOf(struct sockaddr_un, sun_path) + path_len; + sock_len = offsetof(struct sockaddr_un, sun_path) + path_len; #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN sa.sa_unix.sun_len = sock_len; #endif diff --git a/main/fastcgi.h b/main/fastcgi.h index 8a1c0516a9c7..c1e7deb181f6 100644 --- a/main/fastcgi.h +++ b/main/fastcgi.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index b6f32ce309dc..c0f88ad3b5ba 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -510,7 +508,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt } /* Don't resolve paths which contain protocol (except of file://) */ - for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = filename; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) { wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (wrapper == &php_plain_files_wrapper) { @@ -542,7 +540,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt /* Check for stream wrapper */ int is_stream_wrapper = 0; - for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = ptr; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) { /* .:// or ..:// is not a stream wrapper */ if (p[-1] != '.' || p[-2] != '.' || p - 2 != ptr) { @@ -617,7 +615,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt actual_path = trypath; /* Check for stream wrapper */ - for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = trypath; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) { wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (!wrapper) { diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index 1a1289836ba3..62bebca9b715 100644 --- a/main/fopen_wrappers.h +++ b/main/fopen_wrappers.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -30,9 +28,6 @@ PHPAPI int php_check_open_basedir(const char *path); PHPAPI int php_check_open_basedir_ex(const char *path, int warn); PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path); -/* OPENBASEDIR_CHECKPATH(filename) to ease merge between 6.x and 5.x */ -#define OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) - PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_len, const char *path); PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path); diff --git a/main/getopt.c b/main/getopt.c index 65ce94ae9bb0..210c32152415 100644 --- a/main/getopt.c +++ b/main/getopt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -20,15 +18,14 @@ #include #include "php_getopt.h" -#define OPTERRCOLON (1) -#define OPTERRNF (2) -#define OPTERRARG (3) +#define OPTERRCOLON 1 +#define OPTERRNF 2 +#define OPTERRARG 3 // Print error message to stderr and return -2 to distinguish it from '?' command line option. static int php_opt_error(int argc, char * const *argv, int optint, int optchr, int err, int show_err) /* {{{ */ { - if (show_err) - { + if (show_err) { fprintf(stderr, "Error in argument %d, char %d: ", optint, optchr+1); switch(err) { @@ -59,8 +56,11 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char static char **prev_optarg = NULL; php_optidx = -1; + if (optarg) { + *optarg = NULL; + } - if(prev_optarg && prev_optarg != optarg) { + if (prev_optarg && prev_optarg != optarg) { /* reset the state */ optchr = 0; dash = 0; @@ -68,20 +68,18 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char prev_optarg = optarg; if (*optind >= argc) { - return(EOF); + return EOF; } if (!dash) { - if ((argv[*optind][0] != '-')) { - return(EOF); - } else { - if (!argv[*optind][1]) - { - /* - * use to specify stdin. Need to let pgm process this and - * the following args - */ - return(EOF); - } + if (argv[*optind][0] != '-') { + return EOF; + } + if (!argv[*optind][1]) { + /* + * use to specify stdin. Need to let pgm process this and + * the following args + */ + return EOF; } } if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) { @@ -91,7 +89,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char /* '--' indicates end of args if not followed by a known long option name */ if (argv[*optind][2] == '\0') { (*optind)++; - return(EOF); + return EOF; } arg_start = 2; @@ -108,7 +106,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char php_optidx++; if (opts[php_optidx].opt_char == '-') { (*optind)++; - return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err); } else if (opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end) && arg_end == strlen(opts[php_optidx].opt_name)) { break; } @@ -126,7 +124,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char if (argv[*optind][optchr] == ':') { dash = 0; (*optind)++; - return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err); } arg_start = 1 + optchr; } @@ -144,7 +142,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char optchr++; arg_start++; } - return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err)); + return php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err); } else if (argv[*optind][optchr] == opts[php_optidx].opt_char) { break; } @@ -159,7 +157,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char if (*optind == argc) { /* Was the value required or is it optional? */ if (opts[php_optidx].need_param == 1) { - return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err); } /* Optional value is not supported with - style */ } else if (opts[php_optidx].need_param == 1) { @@ -177,8 +175,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char } else { /* multiple options specified as one (exclude long opts) */ if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) { - if (!argv[*optind][optchr+1]) - { + if (!argv[*optind][optchr+1]) { dash = 0; (*optind)++; } else { @@ -190,6 +187,6 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char return opts[php_optidx].opt_char; } assert(0); - return(0); /* never reached */ + return 0; /* never reached */ } /* }}} */ diff --git a/main/http_status_codes.h b/main/http_status_codes.h index f29921122d57..e39ba21daf15 100644 --- a/main/http_status_codes.h +++ b/main/http_status_codes.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrea Faulds | +----------------------------------------------------------------------+ diff --git a/main/internal_functions.c.in b/main/internal_functions.c.in index cef0a438c682..de22e2237dbe 100644 --- a/main/internal_functions.c.in +++ b/main/internal_functions.c.in @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/main/io/php_io.c b/main/io/php_io.c new file mode 100644 index 000000000000..bd45ec888790 --- /dev/null +++ b/main/io/php_io.c @@ -0,0 +1,185 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "php_io.h" +#include "php_io_internal.h" + +#include + +#ifdef PHP_WIN32 +#include +#include +#else +#include +#include +#endif + +static php_io php_io_instance = { + .copy = PHP_IO_PLATFORM_COPY, + .platform_name = PHP_IO_PLATFORM_NAME, +}; + +PHPAPI php_io *php_io_get(void) +{ + return &php_io_instance; +} + +PHPAPI zend_result php_io_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + return php_io_get()->copy(src, dest, maxlen, copied); +} + +zend_result php_io_generic_copy_fallback(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ + char buf[PHP_IO_COPY_BUFSIZE]; + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + zend_result result = SUCCESS; + + while (remaining > 0) { + size_t to_read = (remaining < sizeof(buf)) ? remaining : sizeof(buf); + ssize_t bytes_read; + do { + bytes_read = read(src_fd, buf, to_read); + } while (bytes_read < 0 && errno == EINTR); + + if (bytes_read < 0) { + result = FAILURE; + break; + } else if (bytes_read == 0) { + break; + } + + char *writeptr = buf; + size_t to_write = (size_t) bytes_read; + + while (to_write > 0) { + ssize_t bytes_written; + do { + bytes_written = write(dest_fd, writeptr, to_write); + } while (bytes_written < 0 && errno == EINTR); + if (bytes_written <= 0) { + result = FAILURE; + break; + } + total_copied += bytes_written; + writeptr += bytes_written; + to_write -= bytes_written; + } + if (result == FAILURE) { + break; + } + + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= bytes_read; + } + } + + *copied = total_copied; + return result; +} + +/* For a blocking socket source, wait until data is available (or the configured + * timeout elapses) before reading. Mirrors the per-platform wait_for_data + * helpers so the generic copy path honours stream timeouts on systems without a + * kernel offload (e.g. Haiku). Returns >0 ready, 0 timeout, <0 error. */ +#ifndef PHP_WIN32 +static int php_io_generic_wait_for_data(php_io_fd *fd) +{ + if (fd->fd_type != PHP_IO_FD_SOCKET || !fd->is_blocked) { + return 1; + } + + int timeout_ms = (fd->timeout.tv_sec == -1) + ? -1 + : (int) (fd->timeout.tv_sec * 1000 + fd->timeout.tv_usec / 1000); + + struct pollfd pfd; + pfd.fd = fd->fd; + pfd.events = POLLIN; + + int ret; + do { + ret = poll(&pfd, 1, timeout_ms); + } while (ret == -1 && errno == EINTR); + + return ret; +} +#else +static int php_io_generic_wait_for_data(php_io_fd *fd) +{ + (void) fd; + return 1; +} +#endif + +zend_result php_io_generic_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + char buf[PHP_IO_COPY_BUFSIZE]; + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + zend_result result = SUCCESS; + + while (remaining > 0) { + int ready = php_io_generic_wait_for_data(src); + if (ready == 0) { + /* timeout */ + break; + } else if (ready < 0) { + result = FAILURE; + break; + } + + size_t to_read = (remaining < sizeof(buf)) ? remaining : sizeof(buf); + ssize_t bytes_read; + do { + bytes_read = read(src->fd, buf, to_read); + } while (bytes_read < 0 && errno == EINTR); + + if (bytes_read < 0) { + result = FAILURE; + break; + } else if (bytes_read == 0) { + break; + } + + char *writeptr = buf; + size_t to_write = (size_t) bytes_read; + + while (to_write > 0) { + ssize_t bytes_written; + do { + bytes_written = write(dest->fd, writeptr, to_write); + } while (bytes_written < 0 && errno == EINTR); + if (bytes_written <= 0) { + result = FAILURE; + break; + } + total_copied += bytes_written; + writeptr += bytes_written; + to_write -= bytes_written; + } + if (result == FAILURE) { + break; + } + + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= bytes_read; + } + } + + *copied = total_copied; + return result; +} diff --git a/main/io/php_io_copy_freebsd.c b/main/io/php_io_copy_freebsd.c new file mode 100644 index 000000000000..41f5bc3e0681 --- /dev/null +++ b/main/io/php_io_copy_freebsd.c @@ -0,0 +1,98 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ +*/ + +#if defined(__FreeBSD__) || defined(__DragonFly__) + +#include "php_io_internal.h" +#include +#include +#include +#include +#include + +/* Hint the kernel to read ahead a few pages from the source file so the disk + * I/O overlaps with the network send. SF_FLAGS() is FreeBSD-specific and may be + * absent on DragonFly, in which case we pass plain 0 (no readahead hint). */ +#ifdef SF_FLAGS +# define PHP_IO_FREEBSD_SF_FLAGS SF_FLAGS(16, 0) +#else +# define PHP_IO_FREEBSD_SF_FLAGS 0 +#endif + +static zend_result php_io_freebsd_sendfile(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ + off_t start_offset = lseek(src_fd, 0, SEEK_CUR); + if (start_offset == (off_t) -1) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + + off_t total_sent = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? 0 : maxlen; + zend_result result = SUCCESS; + + while (maxlen == PHP_IO_COPY_ALL || remaining > 0) { + off_t sent_in_this_call = 0; + int sendfile_result = sendfile(src_fd, dest_fd, start_offset + total_sent, remaining, NULL, + &sent_in_this_call, PHP_IO_FREEBSD_SF_FLAGS); + + if (sent_in_this_call > 0) { + total_sent += sent_in_this_call; + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= (size_t) sent_in_this_call; + } + } + + if (sendfile_result == 0) { + if (sent_in_this_call == 0 || remaining == 0) { + break; + } + } else { + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN) { + if (sent_in_this_call > 0) { + continue; + } + break; + } + if (total_sent == 0) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + result = FAILURE; + break; + } + } + + if (total_sent > 0) { + /* best effort: keep reporting the delivered bytes even if this fails */ + lseek(src_fd, start_offset + total_sent, SEEK_SET); + } + + *copied = (size_t) total_sent; + return result; +} + +zend_result php_io_freebsd_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + /* unlike linux, sendfile on freebsd works only under those conditions */ + if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_SOCKET) { + return php_io_freebsd_sendfile(src->fd, dest->fd, maxlen, copied); + } + + /* php_io_generic_copy honours the stream timeout for socket sources */ + return php_io_generic_copy(src, dest, maxlen, copied); +} + +#endif diff --git a/main/io/php_io_copy_linux.c b/main/io/php_io_copy_linux.c new file mode 100644 index 000000000000..9a1810349d3d --- /dev/null +++ b/main/io/php_io_copy_linux.c @@ -0,0 +1,354 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifdef __linux__ + +#include "php_io_internal.h" +#include +#include +#include + +#if !defined(HAVE_COPY_FILE_RANGE) && defined(__NR_copy_file_range) +#define HAVE_COPY_FILE_RANGE 1 +static inline ssize_t copy_file_range( + int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned int flags) +{ + return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); +} +#endif + +#ifdef HAVE_SENDFILE +#include +#endif + +#ifdef HAVE_SPLICE +#include +#include +#include +#include +#endif + +static inline int php_io_linux_wait_for_data(php_io_fd *fd) +{ + if (fd->fd_type != PHP_IO_FD_SOCKET || !fd->is_blocked) { + return 1; + } + + struct timeval *ptimeout = (fd->timeout.tv_sec == -1) ? NULL : &fd->timeout; + int timeout_ms; + + if (ptimeout == NULL) { + timeout_ms = -1; + } else { + timeout_ms = ptimeout->tv_sec * 1000 + ptimeout->tv_usec / 1000; + } + + struct pollfd pfd; + pfd.fd = fd->fd; + pfd.events = POLLIN; + + int ret; + do { + ret = poll(&pfd, 1, timeout_ms); + } while (ret == -1 && errno == EINTR); + + return ret; +} + +static zend_result php_io_linux_copy_file_to_file(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ +#ifdef HAVE_COPY_FILE_RANGE + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + + while (remaining > 0) { + size_t to_copy = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX; + ssize_t result = copy_file_range(src_fd, NULL, dest_fd, NULL, to_copy, 0); + + if (result > 0) { + total_copied += result; + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= result; + } + } else if (result == 0) { + break; + } else { + switch (errno) { + case EINVAL: + case EXDEV: + case ENOSYS: + case EIO: + if (total_copied == 0) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + break; + default: + *copied = total_copied; + return FAILURE; + } + break; + } + } + + if (total_copied > 0) { + *copied = total_copied; + return SUCCESS; + } +#endif + + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); +} + +static zend_result php_io_linux_sendfile(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ +#ifdef HAVE_SENDFILE + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + + while (remaining > 0) { + size_t to_send = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX; + ssize_t result = sendfile(dest_fd, src_fd, NULL, to_send); + + if (result > 0) { + total_copied += result; + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= result; + } + } else if (result == 0) { + break; + } else { + switch (errno) { + case EINTR: + continue; + case EINVAL: + case ENOSYS: + if (total_copied == 0) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + break; + case EAGAIN: + break; + default: + *copied = total_copied; + return FAILURE; + } + break; + } + } + + if (total_copied > 0) { + *copied = total_copied; + return SUCCESS; + } +#endif + + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); +} + +#ifdef HAVE_SPLICE +/* Enlarge the intermediate pipe so socket transfers move more data per splice + * round-trip. Capped by /proc/sys/fs/pipe-max-size (1 MiB by default); a failed + * fcntl() simply leaves the kernel default (64 KiB) in place. */ +#define PHP_IO_PIPE_SIZE (1 << 20) + +/* Kernel MAX_RW_COUNT; a larger len fails the pos + len overflow check with + * EINVAL once a file destination sits at a non-zero offset. */ +#define PHP_IO_SPLICE_MAX ((size_t) 0x7ffff000) + +/* SPLICE_F_MORE corks the socket the same way MSG_MORE does, letting the kernel + * coalesce splices into full segments. The final partial segment is not flushed + * by the kernel until the cork timer (<= 200 ms) expires or the socket is next + * written/closed, so the copy loops below clear the cork once they are done. */ +static inline unsigned int php_io_linux_out_flags(const php_io_fd *dest) +{ + return (dest->fd_type == PHP_IO_FD_SOCKET) ? SPLICE_F_MORE : 0; +} + +/* Clearing TCP_CORK pushes out any segment still held by SPLICE_F_MORE; + * on non-TCP sockets the setsockopt() harmlessly fails. */ +static inline void php_io_linux_socket_uncork(const php_io_fd *dest, size_t total_copied) +{ + if (dest->fd_type == PHP_IO_FD_SOCKET && total_copied > 0) { + int off = 0; + setsockopt(dest->fd, IPPROTO_TCP, TCP_CORK, &off, sizeof(off)); + } +} + +static zend_result php_io_linux_splice_from_pipe(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + int dest_fd = dest->fd; + unsigned int out_flags = php_io_linux_out_flags(dest); + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + zend_result result = SUCCESS; + + while (remaining > 0) { + int ready = php_io_linux_wait_for_data(src); + if (ready == 0) { + break; + } else if (ready < 0) { + result = FAILURE; + break; + } + + size_t to_copy = (remaining < PHP_IO_SPLICE_MAX) ? remaining : PHP_IO_SPLICE_MAX; + ssize_t spliced = splice(src->fd, NULL, dest_fd, NULL, to_copy, out_flags); + + if (spliced > 0) { + total_copied += spliced; + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= spliced; + } + } else if (spliced == 0) { + break; + } else { + if (total_copied == 0) { + return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen, copied); + } + result = FAILURE; + break; + } + } + + php_io_linux_socket_uncork(dest, total_copied); + *copied = total_copied; + return result; +} + +static zend_result php_io_linux_splice_via_pipe(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + int dest_fd = dest->fd; + unsigned int out_flags = php_io_linux_out_flags(dest); + int pipefd[2]; + if (pipe(pipefd) == -1) { + return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen, copied); + } + +#ifdef F_SETPIPE_SZ + fcntl(pipefd[1], F_SETPIPE_SZ, PHP_IO_PIPE_SIZE); +#endif + + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + zend_result result = SUCCESS; + + while (remaining > 0) { + int ready = php_io_linux_wait_for_data(src); + if (ready == 0) { + /* timeout */ + break; + } else if (ready < 0) { + result = FAILURE; + break; + } + + size_t to_copy = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX; + + ssize_t in_pipe = splice(src->fd, NULL, pipefd[1], NULL, to_copy, 0); + if (in_pipe < 0) { + if (total_copied == 0) { + close(pipefd[0]); + close(pipefd[1]); + return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen, copied); + } + result = FAILURE; + break; + } + if (in_pipe == 0) { + break; + } + + size_t pipe_remaining = in_pipe; + while (pipe_remaining > 0) { + ssize_t out = splice(pipefd[0], NULL, dest_fd, NULL, pipe_remaining, out_flags); + if (out <= 0) { + /* the dest refused the splice; salvage what already sits in + * the pipe with a plain read/write loop before failing */ + char drain_buf[1024]; + while (pipe_remaining > 0) { + size_t to_drain = (pipe_remaining < sizeof(drain_buf)) + ? pipe_remaining : sizeof(drain_buf); + ssize_t drained; + do { + drained = read(pipefd[0], drain_buf, to_drain); + } while (drained < 0 && errno == EINTR); + if (drained <= 0) { + break; + } + ssize_t drain_written = 0; + while (drain_written < drained) { + ssize_t written; + do { + written = write(dest_fd, drain_buf + drain_written, drained - drain_written); + } while (written < 0 && errno == EINTR); + if (written <= 0) { + total_copied += drain_written; + result = FAILURE; + goto out; + } + drain_written += written; + } + pipe_remaining -= drain_written; + total_copied += drain_written; + } + result = FAILURE; + goto out; + } + pipe_remaining -= out; + total_copied += out; + } + + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= in_pipe; + } + } + +out: + close(pipefd[0]); + close(pipefd[1]); + php_io_linux_socket_uncork(dest, total_copied); + *copied = total_copied; + return result; +} +#endif /* HAVE_SPLICE */ + +zend_result php_io_linux_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_FILE) { + return php_io_linux_copy_file_to_file(src->fd, dest->fd, maxlen, copied); + } + + if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_SOCKET) { + return php_io_linux_sendfile(src->fd, dest->fd, maxlen, copied); + } + + if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_PIPE) { + return php_io_linux_sendfile(src->fd, dest->fd, maxlen, copied); + } + +#ifdef HAVE_SPLICE + if (src->fd_type == PHP_IO_FD_PIPE) { + return php_io_linux_splice_from_pipe(src, dest, maxlen, copied); + } + + if (src->fd_type == PHP_IO_FD_SOCKET) { + return php_io_linux_splice_via_pipe(src, dest, maxlen, copied); + } +#endif + + /* php_io_generic_copy honours the stream timeout for socket sources */ + return php_io_generic_copy(src, dest, maxlen, copied); +} + +#endif /* __linux__ */ diff --git a/main/io/php_io_copy_macos.c b/main/io/php_io_copy_macos.c new file mode 100644 index 000000000000..0ad73c87a39a --- /dev/null +++ b/main/io/php_io_copy_macos.c @@ -0,0 +1,100 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ +*/ + +#if defined(__APPLE__) + +#include "php_io_internal.h" +#include +#include +#include +#include +#include + +static zend_result php_io_macos_sendfile(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ +#ifdef HAVE_SENDFILE + /* macOS sendfile() takes an explicit offset and does not advance the + * source descriptor, so remember the starting position and restore it + * afterwards to keep the streams-layer contract. */ + off_t start_offset = lseek(src_fd, 0, SEEK_CUR); + if (start_offset == (off_t) -1) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + + off_t total_sent = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? 0 : maxlen; + zend_result result = SUCCESS; + + while (maxlen == PHP_IO_COPY_ALL || remaining > 0) { + /* len is in/out: on input the number of bytes to send (0 means + * until end of file), on output the number of bytes actually sent + * (populated even when sendfile() reports EINTR/EAGAIN). */ + off_t len = (maxlen == PHP_IO_COPY_ALL) ? 0 : (off_t) remaining; + int sendfile_result = sendfile(src_fd, dest_fd, start_offset + total_sent, &len, NULL, 0); + + if (len > 0) { + total_sent += len; + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= (size_t) len; + } + } + + if (sendfile_result == 0) { + /* Reached EOF or sent the whole requested range. */ + if (len == 0 || maxlen == PHP_IO_COPY_ALL || remaining == 0) { + break; + } + } else { + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN) { + if (len > 0) { + continue; + } + break; + } + if (total_sent == 0) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + result = FAILURE; + break; + } + } + + if (total_sent > 0) { + /* best effort: keep reporting the delivered bytes even if this fails */ + lseek(src_fd, start_offset + total_sent, SEEK_SET); + } + + *copied = (size_t) total_sent; + return result; +#else + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); +#endif +} + +zend_result php_io_macos_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + /* Like FreeBSD, macOS sendfile() works only with a regular file source + * and a socket destination. */ + if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_SOCKET) { + return php_io_macos_sendfile(src->fd, dest->fd, maxlen, copied); + } + + /* php_io_generic_copy honours the stream timeout for socket sources */ + return php_io_generic_copy(src, dest, maxlen, copied); +} + +#endif diff --git a/main/io/php_io_copy_solaris.c b/main/io/php_io_copy_solaris.c new file mode 100644 index 000000000000..6812bbe3081d --- /dev/null +++ b/main/io/php_io_copy_solaris.c @@ -0,0 +1,104 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ + */ + +#if defined(__sun) && defined(__SVR4) + +#include "php_io_internal.h" +#include +#include +#include +#include +#include + +static zend_result php_io_solaris_sendfile(int src_fd, int dest_fd, size_t maxlen, size_t *copied) +{ +#ifdef HAVE_SENDFILE + /* Solaris/illumos sendfile() takes an explicit offset and does not + * advance the source descriptor, so remember the starting position and + * restore it afterwards to keep the streams-layer contract. */ + off_t start_offset = lseek(src_fd, 0, SEEK_CUR); + if (start_offset == (off_t) -1) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + + /* Unlike Linux, Solaris sendfile() returns -1/EINVAL (rather than 0) when + * called with an offset at or past EOF, so a trailing call issued after the + * source has been fully consumed would spuriously fail an otherwise complete + * copy. Bound the loop to the bytes actually available in the source file so + * we stop exactly at EOF and never call sendfile() past it. */ + struct stat st; + if (fstat(src_fd, &st) != 0 || !S_ISREG(st.st_mode)) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + + size_t available = (st.st_size > start_offset) ? (size_t) (st.st_size - start_offset) : 0; + size_t target = (maxlen == PHP_IO_COPY_ALL || maxlen > available) ? available : maxlen; + + off_t offset = start_offset; + size_t total_copied = 0; + zend_result result = SUCCESS; + + while (total_copied < target) { + size_t remaining = target - total_copied; + size_t to_send = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX; + /* offset is updated in place by sendfile() */ + ssize_t sent = sendfile(dest_fd, src_fd, &offset, to_send); + + if (sent > 0) { + total_copied += (size_t) sent; + } else if (sent == 0) { + /* Source shrank under us; stop with what we have. */ + break; + } else { + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN) { + break; + } + if (total_copied == 0) { + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); + } + result = FAILURE; + break; + } + } + + if (total_copied > 0) { + /* best effort: keep reporting the delivered bytes even if this fails */ + lseek(src_fd, start_offset + (off_t) total_copied, SEEK_SET); + } + + *copied = total_copied; + return result; +#else + return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen, copied); +#endif +} + +zend_result php_io_solaris_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + /* Unlike FreeBSD, Solaris/illumos sendfile() accepts both a socket and a + * regular file as the output descriptor, so file->socket and file->file + * can both be offloaded. */ + if (src->fd_type == PHP_IO_FD_FILE && + (dest->fd_type == PHP_IO_FD_SOCKET || dest->fd_type == PHP_IO_FD_FILE)) { + return php_io_solaris_sendfile(src->fd, dest->fd, maxlen, copied); + } + + /* php_io_generic_copy honours the stream timeout for socket sources */ + return php_io_generic_copy(src, dest, maxlen, copied); +} + +#endif diff --git a/main/io/php_io_copy_windows.c b/main/io/php_io_copy_windows.c new file mode 100644 index 000000000000..de75d2529987 --- /dev/null +++ b/main/io/php_io_copy_windows.c @@ -0,0 +1,189 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_io_internal.h" + +#ifdef PHP_WIN32 + +#include +#include +#include + +static inline ssize_t php_io_win_read(php_io_fd *fd, char *buf, int len) +{ + if (fd->fd_type == PHP_IO_FD_SOCKET) { + int result = recv(fd->socket, buf, len, 0); + return (result == SOCKET_ERROR) ? -1 : (ssize_t) result; + } + return (ssize_t) _read(fd->fd, buf, len); +} + +static inline ssize_t php_io_win_write(php_io_fd *fd, const char *buf, int len) +{ + if (fd->fd_type == PHP_IO_FD_SOCKET) { + int result = send(fd->socket, buf, len, 0); + return (result == SOCKET_ERROR) ? -1 : (ssize_t) result; + } + return (ssize_t) _write(fd->fd, buf, len); +} + +static inline int php_io_win_wait_for_data(php_io_fd *fd) +{ + if (fd->fd_type != PHP_IO_FD_SOCKET || !fd->is_blocked) { + return 1; + } + + int timeout_ms; + if (fd->timeout.tv_sec == -1) { + timeout_ms = -1; + } else { + timeout_ms = fd->timeout.tv_sec * 1000 + fd->timeout.tv_usec / 1000; + } + + WSAPOLLFD pfd; + pfd.fd = fd->socket; + pfd.events = POLLIN; + + int ret; + do { + ret = WSAPoll(&pfd, 1, timeout_ms); + } while (ret == SOCKET_ERROR && WSAGetLastError() == WSAEINTR); + + return (ret == SOCKET_ERROR) ? -1 : ret; +} + +static zend_result php_io_win_copy_loop(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + char buf[PHP_IO_COPY_BUFSIZE]; + size_t total_copied = 0; + size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen; + zend_result result = SUCCESS; + + while (remaining > 0) { + int ready = php_io_win_wait_for_data(src); + if (ready == 0) { + break; + } else if (ready < 0) { + result = FAILURE; + break; + } + + int to_read = (remaining < sizeof(buf)) ? (int) remaining : (int) sizeof(buf); + ssize_t bytes_read = php_io_win_read(src, buf, to_read); + + if (bytes_read < 0) { + result = FAILURE; + break; + } else if (bytes_read == 0) { + break; + } + + const char *writeptr = buf; + size_t to_write = (size_t) bytes_read; + + while (to_write > 0) { + ssize_t bytes_written = php_io_win_write(dest, writeptr, (int) to_write); + if (bytes_written <= 0) { + result = FAILURE; + break; + } + total_copied += bytes_written; + writeptr += bytes_written; + to_write -= bytes_written; + } + if (result == FAILURE) { + break; + } + + if (maxlen != PHP_IO_COPY_ALL) { + remaining -= bytes_read; + } + } + + *copied = total_copied; + return result; +} + +/* Documented TransmitFile per-call max; larger requests get WSAEINVAL, so they + * fall back to the read/write loop. */ +#define PHP_IO_WIN_TRANSMIT_MAX ((size_t) 2147483646) + +/* Negative results from php_io_win_transmit_file(). */ +#define PHP_IO_WIN_TRANSMIT_FALLBACK ((ssize_t) -1) /* nothing sent; retry via loop */ +#define PHP_IO_WIN_TRANSMIT_ERROR ((ssize_t) -2) /* may have sent data; do not retry */ + +static ssize_t php_io_win_transmit_file(int src_fd, SOCKET dest_sock, size_t maxlen) +{ + HANDLE file_handle = (HANDLE) _get_osfhandle(src_fd); + + if (file_handle == INVALID_HANDLE_VALUE || + dest_sock == INVALID_SOCKET || + GetFileType(file_handle) != FILE_TYPE_DISK) { + return PHP_IO_WIN_TRANSMIT_FALLBACK; + } + + LARGE_INTEGER file_pos, file_size; + file_pos.QuadPart = 0; + if (!SetFilePointerEx(file_handle, file_pos, &file_pos, FILE_CURRENT)) { + return PHP_IO_WIN_TRANSMIT_FALLBACK; + } + + if (!GetFileSizeEx(file_handle, &file_size)) { + return PHP_IO_WIN_TRANSMIT_FALLBACK; + } + + LONGLONG available = file_size.QuadPart - file_pos.QuadPart; + if (available <= 0) { + return 0; + } + + /* 64-bit compare avoids truncating maxlen into the DWORD arg below */ + ULONGLONG to_send = (maxlen == PHP_IO_COPY_ALL || (ULONGLONG) maxlen > (ULONGLONG) available) + ? (ULONGLONG) available : (ULONGLONG) maxlen; + + if (to_send > PHP_IO_WIN_TRANSMIT_MAX) { + return PHP_IO_WIN_TRANSMIT_FALLBACK; + } + + if (!TransmitFile(dest_sock, file_handle, (DWORD) to_send, 0, NULL, NULL, 0)) { + /* may have sent data, so don't resend via the loop */ + return PHP_IO_WIN_TRANSMIT_ERROR; + } + + LARGE_INTEGER advance; + advance.QuadPart = (LONGLONG) to_send; + SetFilePointerEx(file_handle, advance, NULL, FILE_CURRENT); + + return (ssize_t) to_send; +} + +zend_result php_io_windows_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied) +{ + if (src->fd_type != PHP_IO_FD_SOCKET && dest->fd_type == PHP_IO_FD_SOCKET) { + ssize_t result = php_io_win_transmit_file(src->fd, dest->socket, maxlen); + if (result >= 0) { + *copied = (size_t) result; + return SUCCESS; + } + if (result == PHP_IO_WIN_TRANSMIT_ERROR) { + *copied = 0; + return FAILURE; + } + /* PHP_IO_WIN_TRANSMIT_FALLBACK: nothing was sent, copy via the loop. */ + } + + return php_io_win_copy_loop(src, dest, maxlen, copied); +} + +#endif /* PHP_WIN32 */ diff --git a/main/io/php_io_freebsd.h b/main/io/php_io_freebsd.h new file mode 100644 index 000000000000..b45bdc81831b --- /dev/null +++ b/main/io/php_io_freebsd.h @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_FREEBSD_H +#define PHP_IO_FREEBSD_H + +#define PHP_IO_PLATFORM_COPY php_io_freebsd_copy +#if defined(__DragonFly__) +# define PHP_IO_PLATFORM_NAME "dragonfly" +#else +# define PHP_IO_PLATFORM_NAME "freebsd" +#endif + +zend_result php_io_freebsd_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#endif /* PHP_IO_FREEBSD_H */ diff --git a/main/io/php_io_generic.h b/main/io/php_io_generic.h new file mode 100644 index 000000000000..35a908555dda --- /dev/null +++ b/main/io/php_io_generic.h @@ -0,0 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_GENERIC_H +#define PHP_IO_GENERIC_H + +#define PHP_IO_PLATFORM_COPY php_io_generic_copy +#define PHP_IO_PLATFORM_NAME "generic" + +#endif /* PHP_IO_GENERIC_H */ diff --git a/main/io/php_io_internal.h b/main/io/php_io_internal.h new file mode 100644 index 000000000000..f6bc8bf3152a --- /dev/null +++ b/main/io/php_io_internal.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_INTERNAL_H +#define PHP_IO_INTERNAL_H + +#include "php_io.h" + +/* Buffer size for the userspace read/write copy loops. Larger than the stream + * layer CHUNK_SIZE (8 KiB) to cut the number of syscalls on bulk transfers. */ +#define PHP_IO_COPY_BUFSIZE (64 * 1024) + +zend_result php_io_generic_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); +zend_result php_io_generic_copy_fallback(int src_fd, int dest_fd, size_t maxlen, size_t *copied); + +#ifdef __linux__ +#include "php_io_linux.h" +#elif defined(PHP_WIN32) +#include "php_io_windows.h" +#elif defined(__FreeBSD__) || defined(__DragonFly__) +#include "php_io_freebsd.h" +#elif defined(__sun) && defined(__SVR4) +#include "php_io_solaris.h" +#elif defined(__APPLE__) +#include "php_io_macos.h" +#else +#include "php_io_generic.h" +#endif + +#endif /* PHP_IO_INTERNAL_H */ diff --git a/main/io/php_io_linux.h b/main/io/php_io_linux.h new file mode 100644 index 000000000000..801b31c236a5 --- /dev/null +++ b/main/io/php_io_linux.h @@ -0,0 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_LINUX_H +#define PHP_IO_LINUX_H + +zend_result php_io_linux_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#define PHP_IO_PLATFORM_COPY php_io_linux_copy +#define PHP_IO_PLATFORM_NAME "linux" + +#endif /* PHP_IO_LINUX_H */ diff --git a/main/io/php_io_macos.h b/main/io/php_io_macos.h new file mode 100644 index 000000000000..b04f270e6d58 --- /dev/null +++ b/main/io/php_io_macos.h @@ -0,0 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_MACOS_H +#define PHP_IO_MACOS_H + +#define PHP_IO_PLATFORM_COPY php_io_macos_copy +#define PHP_IO_PLATFORM_NAME "macos" + +zend_result php_io_macos_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#endif /* PHP_IO_MACOS_H */ diff --git a/main/io/php_io_solaris.h b/main/io/php_io_solaris.h new file mode 100644 index 000000000000..ccba6e6ddd82 --- /dev/null +++ b/main/io/php_io_solaris.h @@ -0,0 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: David Carlier | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_SOLARIS_H +#define PHP_IO_SOLARIS_H + +#define PHP_IO_PLATFORM_COPY php_io_solaris_copy +#define PHP_IO_PLATFORM_NAME "solaris" + +zend_result php_io_solaris_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#endif /* PHP_IO_SOLARIS_H */ diff --git a/main/io/php_io_windows.h b/main/io/php_io_windows.h new file mode 100644 index 000000000000..f6bd64f11ce6 --- /dev/null +++ b/main/io/php_io_windows.h @@ -0,0 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_WINDOWS_H +#define PHP_IO_WINDOWS_H + +zend_result php_io_windows_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#define PHP_IO_PLATFORM_COPY php_io_windows_copy +#define PHP_IO_PLATFORM_NAME "windows" + +#endif /* PHP_IO_WINDOWS_H */ diff --git a/main/main.c b/main/main.c index bbd2d18ba187..b00556f95217 100644 --- a/main/main.c +++ b/main/main.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Rasmus Lerdorf | @@ -64,6 +62,7 @@ #include "win32/php_registry.h" #include "ext/standard/flock_compat.h" #endif +#include "Zend/zend_builtin_functions.h" #include "Zend/zend_exceptions.h" #if PHP_SIGCHILD @@ -147,7 +146,7 @@ PHPAPI char *php_get_version(sapi_module_struct *sapi_module) " GCOV" #endif ); - smart_string_appends(&version_info, "Copyright (c) The PHP Group\n"); + smart_string_appends(&version_info, "Copyright © The PHP Group and Contributors\n"); const char *build_provider = php_build_provider(); if (build_provider) { @@ -803,6 +802,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY_EX("display_errors", "1", PHP_INI_ALL, OnUpdateDisplayErrors, display_errors, php_core_globals, core_globals, display_errors_mode) STD_PHP_INI_BOOLEAN("display_startup_errors", "1", PHP_INI_ALL, OnUpdateBool, display_startup_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_dl", "1", PHP_INI_SYSTEM, OnUpdateBool, enable_dl, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("error_include_args", "0", PHP_INI_ALL, OnUpdateBool, error_include_args, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("expose_php", "1", PHP_INI_SYSTEM, OnUpdateBool, expose_php, php_core_globals, core_globals) STD_PHP_INI_ENTRY("docref_root", "", PHP_INI_ALL, OnUpdateString, docref_root, php_core_globals, core_globals) STD_PHP_INI_ENTRY("docref_ext", "", PHP_INI_ALL, OnUpdateString, docref_ext, php_core_globals, core_globals) @@ -839,7 +839,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("error_log", NULL, PHP_INI_ALL, OnUpdateErrorLog, error_log, php_core_globals, core_globals) STD_PHP_INI_ENTRY("error_log_mode", "0644", PHP_INI_ALL, OnUpdateLong, error_log_mode, php_core_globals, core_globals) STD_PHP_INI_ENTRY("extension_dir", PHP_EXTENSION_DIR, PHP_INI_SYSTEM, OnUpdateStringUnempty, extension_dir, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("sys_temp_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, sys_temp_dir, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("sys_temp_dir", NULL, PHP_INI_SYSTEM, OnUpdateStrNotEmpty, sys_temp_dir, php_core_globals, core_globals) STD_PHP_INI_ENTRY("include_path", PHP_INCLUDE_PATH, PHP_INI_ALL, OnUpdateStringUnempty, include_path, php_core_globals, core_globals) PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout) STD_PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_ALL, OnUpdateBaseDir, open_basedir, php_core_globals, core_globals) @@ -1058,7 +1058,7 @@ static zend_string *escape_html(const char *buffer, size_t buffer_len) { * html error messages if corresponding ini setting (html_errors) is activated. * See: CODING_STANDARDS.md for details. */ -PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args) +PHPAPI ZEND_COLD void php_verror(const char *docref, int type, const char *format, va_list args) { zend_string *replace_origin = NULL; char *docref_buf = NULL, *target = NULL; @@ -1134,7 +1134,14 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ /* if we still have memory then format the origin */ if (is_function) { - origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); + zend_string *dynamic_params = NULL; + if (PG(error_include_args)) { + dynamic_params = zend_trace_current_function_args_string(); + } + origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, dynamic_params ? ZSTR_VAL(dynamic_params) : ""); + if (dynamic_params) { + zend_string_release(dynamic_params); + } } else { origin_len = strlen(function); origin = estrndup(function, origin_len); @@ -1236,7 +1243,7 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ #define php_error_docref_impl(docref, type, format) do {\ va_list args; \ va_start(args, format); \ - php_verror(docref, "", type, format, args); \ + php_verror(docref, type, format, args); \ va_end(args); \ } while (0) @@ -1251,56 +1258,6 @@ PHPAPI ZEND_COLD void php_error_docref_unchecked(const char *docref, int type, c } /* }}} */ -/* {{{ php_error_docref1 */ -/* See: CODING_STANDARDS.md for details. */ -PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...) -{ - va_list args; - - va_start(args, format); - php_verror(docref, param1, type, format, args); - va_end(args); -} -/* }}} */ - -/* {{{ php_error_docref2 */ -/* See: CODING_STANDARDS.md for details. */ -PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...) -{ - char *params; - va_list args; - - spprintf(¶ms, 0, "%s,%s", param1, param2); - va_start(args, format); - php_verror(docref, params ? params : "...", type, format, args); - va_end(args); - if (params) { - efree(params); - } -} -/* }}} */ - -#ifdef PHP_WIN32 -PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1) { - char *buf = php_win32_error_to_msg(error); - size_t buf_len; - - buf_len = strlen(buf); - if (buf_len >= 2) { - buf[buf_len - 1] = '\0'; - buf[buf_len - 2] = '\0'; - } - php_error_docref1(NULL, param1, E_WARNING, "%s (code: %lu)", buf, error); - php_win32_error_msg_free(buf); -} - -PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) { - char *buf = php_win32_error_to_msg(error); - php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", buf, error); - php_win32_error_msg_free(buf); -} -#endif - /* {{{ php_html_puts */ PHPAPI void php_html_puts(const char *str, size_t size) { @@ -1471,8 +1428,8 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c if (PG(xmlrpc_errors)) { php_printf("faultCode" ZEND_LONG_FMT "faultString%s:%s in %s on line %" PRIu32 "%s%s", PG(xmlrpc_error_number), error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno, ZSTR_LEN(backtrace) ? "\nStack trace:\n" : "", ZSTR_VAL(backtrace)); } else { - char *prepend_string = INI_STR("error_prepend_string"); - char *append_string = INI_STR("error_append_string"); + const char *prepend_string = zend_ini_string_literal("error_prepend_string"); + const char *append_string = zend_ini_string_literal("error_append_string"); if (PG(html_errors)) { if (type == E_ERROR || type == E_PARSE) { @@ -2257,7 +2214,7 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi zend_reset_lc_ctype_locale(); zend_update_current_locale(); -#if HAVE_TZSET +#ifdef HAVE_TZSET tzset(); #endif @@ -2325,10 +2282,7 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi /* initialize stream wrappers registry * (this uses configuration parameters from php.ini) */ - if (php_init_stream_wrappers(module_number) == FAILURE) { - fprintf(stderr, "PHP: Unable to initialize stream url wrappers.\n"); - return FAILURE; - } + php_init_stream_wrappers(module_number); zuv.html_errors = 1; php_startup_auto_globals(); @@ -2374,7 +2328,7 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi } /* disable certain functions as requested by php.ini */ - zend_disable_functions(INI_STR("disable_functions")); + zend_disable_functions(zend_ini_string_literal("disable_functions")); /* make core report what it should */ if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) { @@ -2638,7 +2592,7 @@ PHPAPI bool php_execute_script_ex(zend_file_handle *primary_file, zval *retval) #ifdef PHP_WIN32 zend_unset_timeout(); #endif - zend_set_timeout(INI_INT("max_execution_time"), 0); + zend_set_timeout(zend_ini_long_literal("max_execution_time"), false); } if (prepend_file_p && result) { @@ -2812,13 +2766,11 @@ PHPAPI void php_reserve_tsrm_memory(void) tsrm_reserve( TSRM_ALIGNED_SIZE(sizeof(zend_compiler_globals)) + TSRM_ALIGNED_SIZE(sizeof(zend_executor_globals)) + - TSRM_ALIGNED_SIZE(sizeof(zend_php_scanner_globals)) + TSRM_ALIGNED_SIZE(sizeof(zend_ini_scanner_globals)) + TSRM_ALIGNED_SIZE(sizeof(virtual_cwd_globals)) + #ifdef ZEND_SIGNALS TSRM_ALIGNED_SIZE(sizeof(zend_signal_globals_t)) + #endif - TSRM_ALIGNED_SIZE(zend_mm_globals_size()) + TSRM_ALIGNED_SIZE(zend_gc_globals_size()) + TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) + TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct)) + @@ -2835,6 +2787,10 @@ PHPAPI bool php_tsrm_startup_ex(int expected_threads) { bool ret = tsrm_startup(expected_threads, 1, 0, NULL); php_reserve_tsrm_memory(); + /* Must cover the total size of every ZEND_*_OFFSET global, or the furthest underflows the block. */ + tsrm_reserve_fast_front( + TSRM_ALIGNED_SIZE(sizeof(zend_compiler_globals)) + + TSRM_ALIGNED_SIZE(sizeof(zend_executor_globals))); (void)ts_resource(0); return ret; } diff --git a/main/network.c b/main/network.c index 54dbf2b8e580..b4d3ded15196 100644 --- a/main/network.c +++ b/main/network.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Venaas | | Streams work by Wez Furlong | @@ -26,10 +24,6 @@ #ifdef PHP_WIN32 # include # include "win32/winutil.h" -# define O_RDONLY _O_RDONLY -# include "win32/param.h" -#else -#include #endif #include @@ -46,7 +40,7 @@ #endif #ifdef HAVE_POLL_H #include -#elif HAVE_SYS_POLL_H +#elif defined(HAVE_SYS_POLL_H) #include #endif @@ -1461,7 +1455,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf if (*hstbuflen == 0) { *hstbuflen = 1024; - *tmphstbuf = (char *)malloc (*hstbuflen); + *tmphstbuf = (char *)pemalloc(*hstbuflen, true); } while (( res = @@ -1469,7 +1463,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf && (errno == ERANGE)) { /* Enlarge the buffer. */ *hstbuflen *= 2; - *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); + *tmphstbuf = (char *)perealloc(*tmphstbuf, *hstbuflen, true); } if (res != 0) { @@ -1487,7 +1481,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf if (*hstbuflen == 0) { *hstbuflen = 1024; - *tmphstbuf = (char *)malloc (*hstbuflen); + *tmphstbuf = (char *)pemalloc(*hstbuflen, true); } while ((NULL == ( hp = @@ -1495,7 +1489,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf && (errno == ERANGE)) { /* Enlarge the buffer. */ *hstbuflen *= 2; - *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); + *tmphstbuf = (char *)perealloc(*tmphstbuf, *hstbuflen, true); } return hp; } @@ -1505,11 +1499,11 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf { if (*hstbuflen == 0) { *hstbuflen = sizeof(struct hostent_data); - *tmphstbuf = (char *)malloc (*hstbuflen); + *tmphstbuf = (char *)pemalloc(*hstbuflen, true); } else { if (*hstbuflen < sizeof(struct hostent_data)) { *hstbuflen = sizeof(struct hostent_data); - *tmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + *tmphstbuf = (char *)perealloc(*tmphstbuf, *hstbuflen, true); } } memset((void *)(*tmphstbuf),0,*hstbuflen); diff --git a/main/output.c b/main/output.c index ff65a0f9a4d8..664adf7f1688 100644 --- a/main/output.c +++ b/main/output.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Zeev Suraski | | Thies C. Arntzen | @@ -972,6 +970,7 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl handler->func.user->fci.param_count = 2; handler->func.user->fci.params = ob_args; handler->func.user->fci.retval = &retval; + handler->func.user->fci.consumed_args = zend_fci_consumed_arg(0); if (SUCCESS == zend_call_function(&handler->func.user->fci, &handler->func.user->fcc) && Z_TYPE(retval) != IS_UNDEF) { if (handler->flags & PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT) { @@ -1393,9 +1392,7 @@ PHP_FUNCTION(ob_start) /* {{{ Flush (send) contents of the output buffer. The last buffer content is sent to next buffer */ PHP_FUNCTION(ob_flush) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!OG(active)) { php_error_docref("ref.outcontrol", E_NOTICE, "Failed to flush buffer. No buffer to flush"); @@ -1413,9 +1410,7 @@ PHP_FUNCTION(ob_flush) /* {{{ Clean (delete) the current output buffer */ PHP_FUNCTION(ob_clean) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!OG(active)) { php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer. No buffer to delete"); @@ -1433,9 +1428,7 @@ PHP_FUNCTION(ob_clean) /* {{{ Flush (send) the output buffer, and delete current output buffer */ PHP_FUNCTION(ob_end_flush) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!OG(active)) { php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete and flush buffer. No buffer to delete or flush"); @@ -1449,9 +1442,7 @@ PHP_FUNCTION(ob_end_flush) /* {{{ Clean the output buffer, and delete current output buffer */ PHP_FUNCTION(ob_end_clean) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!OG(active)) { php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer. No buffer to delete"); @@ -1465,9 +1456,7 @@ PHP_FUNCTION(ob_end_clean) /* {{{ Get current buffer contents, flush (send) the output buffer, and delete current output buffer */ PHP_FUNCTION(ob_get_flush) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (php_output_get_contents(return_value) == FAILURE) { php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete and flush buffer. No buffer to delete or flush"); @@ -1483,9 +1472,7 @@ PHP_FUNCTION(ob_get_flush) /* {{{ Get current buffer contents and delete current output buffer */ PHP_FUNCTION(ob_get_clean) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if(!OG(active)) { RETURN_FALSE; @@ -1505,9 +1492,7 @@ PHP_FUNCTION(ob_get_clean) /* {{{ Return the contents of the output buffer */ PHP_FUNCTION(ob_get_contents) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (php_output_get_contents(return_value) == FAILURE) { RETURN_FALSE; @@ -1518,9 +1503,7 @@ PHP_FUNCTION(ob_get_contents) /* {{{ Return the nesting level of the output buffer */ PHP_FUNCTION(ob_get_level) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(php_output_get_level()); } @@ -1529,9 +1512,7 @@ PHP_FUNCTION(ob_get_level) /* {{{ Return the length of the output buffer */ PHP_FUNCTION(ob_get_length) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (php_output_get_length(return_value) == FAILURE) { RETURN_FALSE; @@ -1542,9 +1523,7 @@ PHP_FUNCTION(ob_get_length) /* {{{ List all output_buffers in an array */ PHP_FUNCTION(ob_list_handlers) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1595,9 +1574,7 @@ PHP_FUNCTION(ob_implicit_flush) /* {{{ Reset(clear) URL rewriter values */ PHP_FUNCTION(output_reset_rewrite_vars) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (php_url_scanner_reset_vars() == SUCCESS) { RETURN_TRUE; diff --git a/main/php.h b/main/php.h index 32222cfca94e..fb81a4b47455 100644 --- a/main/php.h +++ b/main/php.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -44,6 +42,8 @@ # define PHP_OS_FAMILY "Darwin" #elif defined(__sun__) # define PHP_OS_FAMILY "Solaris" +#elif defined(_AIX) +# define PHP_OS_FAMILY "AIX" #elif defined(__linux__) # define PHP_OS_FAMILY "Linux" #else @@ -207,12 +207,8 @@ typedef unsigned int socklen_t; #include #ifdef HAVE_PWD_H -# ifdef PHP_WIN32 -#include "win32/param.h" -# else -#include -#include -# endif +# include +# include #endif #include @@ -303,20 +299,12 @@ static inline ZEND_ATTRIBUTE_DEPRECATED void php_set_error_handling(error_handli } static inline ZEND_ATTRIBUTE_DEPRECATED void php_std_error_handling(void) {} -PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args) PHP_ATTRIBUTE_FORMAT(printf, 4, 0); +PHPAPI ZEND_COLD void php_verror(const char *docref, int type, const char *format, va_list args) PHP_ATTRIBUTE_FORMAT(printf, 3, 0); /* PHPAPI void php_error(int type, const char *format, ...); */ PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); PHPAPI ZEND_COLD void php_error_docref_unchecked(const char *docref, int type, const char *format, ...); -PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...) - PHP_ATTRIBUTE_FORMAT(printf, 4, 5); -PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...) - PHP_ATTRIBUTE_FORMAT(printf, 5, 6); -#ifdef PHP_WIN32 -PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1); -PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2); -#endif END_EXTERN_C() #define zenderror phperror diff --git a/main/php_compat.h b/main/php_compat.h index 2f9f4c1c89e6..852b4fbb1ff8 100644 --- a/main/php_compat.h +++ b/main/php_compat.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -270,6 +266,8 @@ #define gdImageCreateFromWBMPCtx php_gd_gdImageCreateFromWBMPCtx #define gdImageCreateFromWBMPPtr php_gd_gdImageCreateFromWBMPPtr #define gdImageCreateFromXbm php_gd_gdImageCreateFromXbm +#define gdImageWebp php_gd_gdImageWebp +#define gdImageHeif php_gd_gdImageHeif #define gdImageCreatePaletteFromTrueColor php_gd_gdImageCreatePaletteFromTrueColor #define gdImageCreateTrueColor php_gd_gdImageCreateTrueColor #define gdImageDashedLine php_gd_gdImageDashedLine @@ -311,6 +309,7 @@ #define gdImagePngPtr php_gd_gdImagePngPtr #define gdImagePngPtrEx php_gd_gdImagePngPtrEx #define gdImagePngToSink php_gd_gdImagePngToSink +#define gdPngGetVersionString php_gd_gdPngGetVersionString #define gdImagePolygon php_gd_gdImagePolygon #define gdImageRectangle php_gd_gdImageRectangle #define gdImageRotate php_gd_gdImageRotate @@ -379,7 +378,10 @@ #define gdCacheGet php_gd_gdCacheGet #define gdFontCacheSetup php_gd_gdFontCacheSetup #define gdFontCacheShutdown php_gd_gdFontCacheShutdown +#define gdFontCacheMutexSetup php_gd_gdFontCacheMutexSetup +#define gdFontCacheMutexShutdown php_gd_gdFontCacheMutexShutdown #define gdFreeFontCache php_gd_gdFreeFontCache +#define gdFTUseFontConfig php_gd_gdFTUseFontConfig #endif /* HAVE_GD_BUNDLED */ /* Define to specify how much context to retain around the current parse diff --git a/main/php_content_types.c b/main/php_content_types.c index f01841986728..c727d0ed3314 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/php_content_types.h b/main/php_content_types.h index 6aab33e29421..e734bb1963cd 100644 --- a/main/php_content_types.h +++ b/main/php_content_types.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/php_getopt.h b/main/php_getopt.h index 0238881113a7..6f457f3a58da 100644 --- a/main/php_getopt.h +++ b/main/php_getopt.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/main/php_globals.h b/main/php_globals.h index 893bf25d26cb..0bab9fc95c14 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ @@ -61,6 +59,7 @@ struct _php_core_globals { uint8_t display_errors; bool display_startup_errors; + bool error_include_args; bool log_errors; bool ignore_repeated_errors; bool ignore_repeated_source; @@ -84,7 +83,7 @@ struct _php_core_globals { bool open_basedir_modified; char *extension_dir; char *php_binary; - char *sys_temp_dir; + zend_string *sys_temp_dir; char *upload_tmp_dir; zend_long upload_max_filesize; diff --git a/main/php_ini.c b/main/php_ini.c index e464c05d1fcc..a3b33da65bab 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ @@ -39,7 +37,7 @@ char *tmp = path; \ while (*tmp) { \ if (*tmp == '\\') *tmp = '/'; \ - else *tmp = tolower(*tmp); \ + else *tmp = tolower((unsigned char)*tmp); \ tmp++; \ } \ } @@ -334,7 +332,7 @@ static void php_load_zend_extension_cb(void *arg) } else { DL_HANDLE handle; char *libpath; - char *extension_dir = INI_STR("extension_dir"); + const char *extension_dir = zend_ini_string_literal("extension_dir"); int slash_suffix = 0; char *err1, *err2; @@ -696,7 +694,7 @@ void php_init_config(void) if (total_l) { size_t php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0; - php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); + php_ini_scanned_files = (char *) perealloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1, true); if (!php_ini_scanned_files_len) { *php_ini_scanned_files = '\0'; } diff --git a/main/php_ini.h b/main/php_ini.h index 4253ce43fbe1..ffc2c36186c9 100644 --- a/main/php_ini.h +++ b/main/php_ini.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ diff --git a/main/php_ini_builder.c b/main/php_ini_builder.c index d214a340343f..cdc10f0b5e25 100644 --- a/main/php_ini_builder.c +++ b/main/php_ini_builder.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Max Kellermann | +----------------------------------------------------------------------+ @@ -67,7 +65,7 @@ PHPAPI void php_ini_builder_define(struct php_ini_builder *b, const char *arg) if (val != NULL) { val++; - if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') { + if (!isalnum((unsigned char)*val) && *val != '"' && *val != '\'' && *val != '\0') { php_ini_builder_quoted(b, arg, val - arg - 1, val, arg + len - val); } else { php_ini_builder_realloc(b, len + strlen("\n")); diff --git a/main/php_ini_builder.h b/main/php_ini_builder.h index 7f5be81c10ac..9f73cba13cb7 100644 --- a/main/php_ini_builder.h +++ b/main/php_ini_builder.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Max Kellermann | +----------------------------------------------------------------------+ @@ -62,7 +60,7 @@ static inline char *php_ini_builder_finish(struct php_ini_builder *b) static inline void php_ini_builder_realloc(struct php_ini_builder *b, size_t delta) { /* reserve enough space for the null terminator */ - b->value = realloc(b->value, b->length + delta + 1); + b->value = perealloc(b->value, b->length + delta + 1, true); } /** diff --git a/main/php_io.h b/main/php_io.h new file mode 100644 index 000000000000..79bc245ef754 --- /dev/null +++ b/main/php_io.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | 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: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_IO_H +#define PHP_IO_H + +#include "php.h" +#include "php_network.h" + +#define PHP_IO_COPY_ALL SIZE_MAX + +typedef enum php_io_fd_type { + PHP_IO_FD_FILE = 1, + PHP_IO_FD_SOCKET, + PHP_IO_FD_PIPE, +} php_io_fd_type; + +typedef struct php_io_fd { + union { + int fd; + php_socket_t socket; + }; + php_io_fd_type fd_type; + struct timeval timeout; + unsigned is_blocked:1; +} php_io_fd; + +typedef zend_result (*php_io_copy_fn)(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +typedef struct php_io { + php_io_copy_fn copy; + const char *platform_name; +} php_io; + +PHPAPI php_io *php_io_get(void); + +/* Copies up to maxlen bytes from src to dest; *copied is set even on FAILURE */ +PHPAPI zend_result php_io_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen, size_t *copied); + +#endif /* PHP_IO_H */ diff --git a/main/php_main.h b/main/php_main.h index bd28a0dee1d7..de2ace1c25ed 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/main/php_memory_streams.h b/main/php_memory_streams.h index 0b7f51ee6d90..cf83ba8e084e 100644 --- a/main/php_memory_streams.h +++ b/main/php_memory_streams.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/main/php_network.h b/main/php_network.h index 6700ab42dd3f..e6d3009a6c82 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Venaas | +----------------------------------------------------------------------+ diff --git a/main/php_odbc_utils.c b/main/php_odbc_utils.c index 5cba835f81e3..797a4ac04be1 100644 --- a/main/php_odbc_utils.c +++ b/main/php_odbc_utils.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Calvin Buckley | +----------------------------------------------------------------------+ @@ -73,12 +71,20 @@ PHPAPI bool php_odbc_connstr_should_quote(const char *str) } /** - * Estimates the worst-case scenario for a quoted version of a string's size. + * Gets the length of a string after it has been quoted. */ -PHPAPI size_t php_odbc_connstr_estimate_quote_length(const char *in_str) +PHPAPI size_t php_odbc_connstr_get_quoted_length(const char *in_str) { - /* Assume all '}'. Include '{,' '}', and the null terminator too */ - return (strlen(in_str) * 2) + 3; + /* Start with including the quotes ({}) and the null terminator */ + size_t size = 3; + /* Scan the string like strlen, doubling each } character. */ + while (*in_str) { + size++; + if (*in_str++ == '}') { + size++; + } + } + return size; } /** diff --git a/main/php_odbc_utils.h b/main/php_odbc_utils.h index 183957d6dd12..f2bc46ebc5ba 100644 --- a/main/php_odbc_utils.h +++ b/main/php_odbc_utils.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Calvin Buckley | +----------------------------------------------------------------------+ @@ -18,5 +16,5 @@ PHPAPI bool php_odbc_connstr_is_quoted(const char *str); PHPAPI bool php_odbc_connstr_should_quote(const char *str); -PHPAPI size_t php_odbc_connstr_estimate_quote_length(const char *in_str); +PHPAPI size_t php_odbc_connstr_get_quoted_length(const char *in_str); PHPAPI size_t php_odbc_connstr_quote(char *out_str, const char *in_str, size_t out_str_size); diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index 3a410eb7fa2d..7a33fa3ce192 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ @@ -242,14 +240,14 @@ PHPAPI const char* php_get_temporary_directory(void) /* Is there a temporary directory "sys_temp_dir" in .ini defined? */ { - char *sys_temp_dir = PG(sys_temp_dir); + const zend_string *sys_temp_dir = PG(sys_temp_dir); if (sys_temp_dir) { - size_t len = strlen(sys_temp_dir); - if (len >= 2 && sys_temp_dir[len - 1] == DEFAULT_SLASH) { - PG(php_sys_temp_dir) = estrndup(sys_temp_dir, len - 1); + size_t len = ZSTR_LEN(sys_temp_dir); + if (len >= 2 && ZSTR_VAL(sys_temp_dir)[len - 1] == DEFAULT_SLASH) { + PG(php_sys_temp_dir) = estrndup(ZSTR_VAL(sys_temp_dir), len - 1); return PG(php_sys_temp_dir); - } else if (len >= 1 && sys_temp_dir[len - 1] != DEFAULT_SLASH) { - PG(php_sys_temp_dir) = estrndup(sys_temp_dir, len); + } else if (len >= 1 && ZSTR_VAL(sys_temp_dir)[len - 1] != DEFAULT_SLASH) { + PG(php_sys_temp_dir) = estrndup(ZSTR_VAL(sys_temp_dir), len); return PG(php_sys_temp_dir); } } diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h index 1d8764a7487e..d9d8d8069190 100644 --- a/main/php_open_temporary_file.h +++ b/main/php_open_temporary_file.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ diff --git a/main/php_output.h b/main/php_output.h index 896f1e0a8fea..f0a26824936a 100644 --- a/main/php_output.h +++ b/main/php_output.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/main/php_poll.h b/main/php_poll.h new file mode 100644 index 000000000000..9b878d44bd20 --- /dev/null +++ b/main/php_poll.h @@ -0,0 +1,176 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_POLL_H +#define PHP_POLL_H + +#include "php.h" +#include "php_network.h" + +#include + +/* ----- Public generic API ----- */ + +/* clang-format off */ + +/* Event types. Keep in sync with io_poll.stub.php! */ +#define PHP_POLL_READ 0x01 +#define PHP_POLL_WRITE 0x02 +#define PHP_POLL_ERROR 0x04 +#define PHP_POLL_HUP 0x08 +#define PHP_POLL_RDHUP 0x10 +#define PHP_POLL_ONESHOT 0x20 +#define PHP_POLL_ET 0x40 /* Edge-triggered */ + +/* Poll flags */ +#define PHP_POLL_FLAG_PERSISTENT 0x01 +#define PHP_POLL_FLAG_RAW_EVENTS 0x02 + +/* Poll backend types. Keep in sync with io_poll.stub.php! */ +typedef enum php_poll_backend_type { + PHP_POLL_BACKEND_AUTO = -1, + PHP_POLL_BACKEND_POLL = 0, + PHP_POLL_BACKEND_EPOLL, + PHP_POLL_BACKEND_KQUEUE, + PHP_POLL_BACKEND_EVENTPORT, + PHP_POLL_BACKEND_WSAPOLL +} php_poll_backend_type; + +/* Error code constants for exception codes */ +#define PHP_POLL_ERROR_CODE_NONE 0 +#define PHP_POLL_ERROR_CODE_SYSTEM 1 +#define PHP_POLL_ERROR_CODE_NOMEM 2 +#define PHP_POLL_ERROR_CODE_INVALID 3 +#define PHP_POLL_ERROR_CODE_EXISTS 4 +#define PHP_POLL_ERROR_CODE_NOTFOUND 5 +#define PHP_POLL_ERROR_CODE_TIMEOUT 6 +#define PHP_POLL_ERROR_CODE_INTERRUPTED 7 +#define PHP_POLL_ERROR_CODE_PERMISSION 8 +#define PHP_POLL_ERROR_CODE_TOOBIG 9 +#define PHP_POLL_ERROR_CODE_AGAIN 10 +#define PHP_POLL_ERROR_CODE_NOSUPPORT 11 + +/* Error codes */ +typedef enum php_poll_error { + PHP_POLL_ERR_NONE = PHP_POLL_ERROR_CODE_NONE, /* No error */ + PHP_POLL_ERR_SYSTEM = PHP_POLL_ERROR_CODE_SYSTEM, /* Generic system error */ + PHP_POLL_ERR_NOMEM = PHP_POLL_ERROR_CODE_NOMEM, /* Out of memory (ENOMEM) */ + PHP_POLL_ERR_INVALID = PHP_POLL_ERROR_CODE_INVALID, /* Invalid argument (EINVAL, EBADF) */ + PHP_POLL_ERR_EXISTS = PHP_POLL_ERROR_CODE_EXISTS, /* Already exists (EEXIST) */ + PHP_POLL_ERR_NOTFOUND = PHP_POLL_ERROR_CODE_NOTFOUND, /* Not found (ENOENT) */ + PHP_POLL_ERR_TIMEOUT = PHP_POLL_ERROR_CODE_TIMEOUT, /* Operation timed out (ETIME, ETIMEDOUT) */ + PHP_POLL_ERR_INTERRUPTED = PHP_POLL_ERROR_CODE_INTERRUPTED, /* Interrupted by signal (EINTR) */ + PHP_POLL_ERR_PERMISSION = PHP_POLL_ERROR_CODE_PERMISSION, /* Permission denied (EACCES, EPERM) */ + PHP_POLL_ERR_TOOBIG = PHP_POLL_ERROR_CODE_TOOBIG, /* Too many resources (EMFILE, ENFILE) */ + PHP_POLL_ERR_AGAIN = PHP_POLL_ERROR_CODE_AGAIN, /* Try again (EAGAIN, EWOULDBLOCK) */ + PHP_POLL_ERR_NOSUPPORT = PHP_POLL_ERROR_CODE_NOSUPPORT, /* Not supported (ENOSYS, EOPNOTSUPP) */ +} php_poll_error; + +/* clang-format on */ + +/* Poll event structure */ +struct php_poll_event { + int fd; /* File descriptor */ + uint32_t events; /* Requested events */ + uint32_t revents; /* Returned events */ + void *data; /* User data pointer */ +}; + +/* Forward declarations */ +typedef struct php_poll_ctx php_poll_ctx; +typedef struct php_poll_backend_ops php_poll_backend_ops; +typedef struct php_poll_event php_poll_event; + +PHPAPI bool php_poll_is_backend_available(php_poll_backend_type backend); +PHPAPI bool php_poll_backend_supports_edge_triggering(php_poll_backend_type backend); + +PHPAPI php_poll_ctx *php_poll_create(php_poll_backend_type preferred_backend, uint32_t flags); +PHPAPI php_poll_ctx *php_poll_create_by_name(const char *preferred_backend, uint32_t flags); + +PHPAPI zend_result php_poll_set_max_events_hint(php_poll_ctx *ctx, int max_events); +PHPAPI zend_result php_poll_init(php_poll_ctx *ctx); +PHPAPI void php_poll_destroy(php_poll_ctx *ctx); + +PHPAPI zend_result php_poll_add(php_poll_ctx *ctx, int fd, uint32_t events, void *data); +PHPAPI zend_result php_poll_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *data); +PHPAPI zend_result php_poll_remove(php_poll_ctx *ctx, int fd); + +PHPAPI int php_poll_wait(php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout); + +PHPAPI const char *php_poll_backend_name(php_poll_ctx *ctx); +PHPAPI php_poll_backend_type php_poll_get_backend_type(php_poll_ctx *ctx); +PHPAPI bool php_poll_supports_et(php_poll_ctx *ctx); +PHPAPI php_poll_error php_poll_get_error(php_poll_ctx *ctx); + +/* Get suitable max_events for backend */ +PHPAPI int php_poll_get_suitable_max_events(php_poll_ctx *ctx); + +/* Backend registration */ +PHPAPI void php_poll_register_backends(void); + +/* Error string for the error */ +PHPAPI const char *php_poll_error_string(php_poll_error error); + +/* ----- Public extension API ----- */ + +typedef struct php_poll_handle_ops php_poll_handle_ops; +typedef struct php_poll_handle_object php_poll_handle_object; + +/* Handle operations structure - extensions can provide their own */ +struct php_poll_handle_ops { + /** + * Get file descriptor for this handle + * @param handle The handle object + * @return File descriptor or SOCK_ERR if invalid/not applicable + */ + php_socket_t (*get_fd)(php_poll_handle_object *handle); + + /** + * Check if handle is still valid + * @param handle The handle object + * @return true if valid, false if invalid + */ + int (*is_valid)(php_poll_handle_object *handle); + + /** + * Cleanup handle-specific data + * @param handle The handle object + */ + void (*cleanup)(php_poll_handle_object *handle); +}; + +/* Base poll handle object structure */ +struct php_poll_handle_object { + php_poll_handle_ops *ops; + void *handle_data; + zend_object std; +}; + +#define PHP_POLL_HANDLE_OBJ_FROM_ZOBJ(obj) ZEND_CONTAINER_OF(obj, php_poll_handle_object, std) + +#define PHP_POLL_HANDLE_OBJ_FROM_ZV(zv) PHP_POLL_HANDLE_OBJ_FROM_ZOBJ(Z_OBJ_P(zv)) + +/* Default operations */ +extern php_poll_handle_ops php_poll_handle_default_ops; + +/* Utility functions for extensions */ +PHPAPI php_poll_handle_object *php_poll_handle_object_create( + size_t obj_size, zend_class_entry *ce, php_poll_handle_ops *ops); +PHPAPI void php_poll_handle_object_free(zend_object *obj); + +/* Get file descriptor from any poll handle */ +PHPAPI php_socket_t php_poll_handle_get_fd(php_poll_handle_object *handle); + +#endif /* PHP_POLL_H */ diff --git a/main/php_reentrancy.h b/main/php_reentrancy.h index 5a78df078698..f11ef17acb71 100644 --- a/main/php_reentrancy.h +++ b/main/php_reentrancy.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/main/php_scandir.c b/main/php_scandir.c index 7bf91bdf7f33..c180272e5f48 100644 --- a/main/php_scandir.c +++ b/main/php_scandir.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Shane Caraveo | | Ilia Alshanetsky | @@ -29,7 +27,6 @@ #ifndef HAVE_SCANDIR #ifdef PHP_WIN32 -#include "win32/param.h" #include "win32/readdir.h" #endif diff --git a/main/php_scandir.h b/main/php_scandir.h index ec5565914247..76d27feb15ca 100644 --- a/main/php_scandir.h +++ b/main/php_scandir.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Shane Caraveo | | Ilia Alshanetsky | diff --git a/main/php_streams.h b/main/php_streams.h index 1c52539cfcae..0dd27b8ee88a 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ @@ -248,6 +246,8 @@ struct _php_stream { #endif struct _php_stream *enclosing_stream; /* this is a private stream owned by enclosing_stream */ + + zend_llist *error_list; }; /* php_stream */ #define PHP_STREAM_CONTEXT(stream) \ @@ -539,6 +539,7 @@ PHPAPI ssize_t _php_stream_passthru(php_stream * src STREAMS_DC); #define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC) END_EXTERN_C() +#include "streams/php_stream_errors.h" #include "streams/php_stream_transport.h" #include "streams/php_stream_plain_wrapper.h" #include "streams/php_stream_glob_wrapper.h" @@ -554,6 +555,8 @@ END_EXTERN_C() #define PHP_STREAM_AS_SOCKETD 2 /* cast as fd/socket for select purposes */ #define PHP_STREAM_AS_FD_FOR_SELECT 3 +/* cast as fd/socket for copy purposes */ +#define PHP_STREAM_AS_FD_FOR_COPY 4 /* try really, really hard to make sure the cast happens (avoid using this flag if possible) */ #define PHP_STREAM_CAST_TRY_HARD 0x80000000 @@ -626,7 +629,7 @@ END_EXTERN_C() /* this flag is only used by include/require functions */ #define STREAM_OPEN_FOR_ZEND_STREAM 0x00010000 -zend_result php_init_stream_wrappers(int module_number); +void php_init_stream_wrappers(int module_number); void php_shutdown_stream_wrappers(int module_number); void php_shutdown_stream_hashes(void); PHP_RSHUTDOWN_FUNCTION(streams); @@ -642,10 +645,6 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf); #define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC) #define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC) - -/* pushes an error message onto the stack for a wrapper instance */ -PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, int options, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); - typedef enum { PHP_STREAM_UNCHANGED = 0, /* orig stream was seekable anyway */ PHP_STREAM_RELEASED = 1, /* newstream should be used; origstream is no longer valid */ diff --git a/main/php_syslog.c b/main/php_syslog.c index 975a0423df17..a92b2518caab 100644 --- a/main/php_syslog.c +++ b/main/php_syslog.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Philip Prindeville | +----------------------------------------------------------------------+ diff --git a/main/php_syslog.h b/main/php_syslog.h index f2682d74f238..d3ff747311ac 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/php_ticks.c b/main/php_ticks.c index 4c1e5113e965..c71082dfa2d1 100644 --- a/main/php_ticks.c +++ b/main/php_ticks.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Bakken | +----------------------------------------------------------------------+ diff --git a/main/php_ticks.h b/main/php_ticks.h index 998f4364e5e9..43801a74e89d 100644 --- a/main/php_ticks.h +++ b/main/php_ticks.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Bakken | +----------------------------------------------------------------------+ diff --git a/main/php_variables.c b/main/php_variables.c index 971e1c77ea9f..2121bfd8b35b 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -221,7 +219,7 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac ip++; index_s = ip; - if (isspace(*ip)) { + if (isspace((unsigned char)*ip)) { ip++; } if (*ip==']') { @@ -544,7 +542,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) if (arg == PARSE_COOKIE) { /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */ - while (isspace(*var)) { + while (isspace((unsigned char)*var)) { var++; } if (var == val || *var == '\0') { diff --git a/main/php_variables.h b/main/php_variables.h index 5cb43890bd75..27a45e8daa3c 100644 --- a/main/php_variables.h +++ b/main/php_variables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/main/poll/php_poll_internal.h b/main/poll/php_poll_internal.h new file mode 100644 index 000000000000..951521314393 --- /dev/null +++ b/main/poll/php_poll_internal.h @@ -0,0 +1,176 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_POLL_INTERNAL_H +#define PHP_POLL_INTERNAL_H + +#include "php_poll.h" +#include "php_network.h" + +/* Allocation macros */ +#define php_poll_calloc(nmemb, size, persistent) \ + ((persistent) ? calloc((nmemb), (size)) : ecalloc((nmemb), (size))) +#define php_poll_malloc(size, persistent) ((persistent) ? malloc((size)) : emalloc((size))) +#define php_poll_realloc(ptr, size, persistent) \ + ((persistent) ? realloc((ptr), (size)) : erealloc((ptr), (size))) + +/* Backend interface */ +typedef struct php_poll_backend_ops { + php_poll_backend_type type; + const char *name; + + /* Initialize backend */ + zend_result (*init)(php_poll_ctx *ctx); + + /* Cleanup backend */ + void (*cleanup)(php_poll_ctx *ctx); + + /* Add file descriptor */ + zend_result (*add)(php_poll_ctx *ctx, int fd, uint32_t events, void *data); + + /* Modify file descriptor */ + zend_result (*modify)(php_poll_ctx *ctx, int fd, uint32_t events, void *data); + + /* Remove file descriptor */ + zend_result (*remove)(php_poll_ctx *ctx, int fd); + + /* Wait for events */ + int (*wait)(php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout); + + /* Check if backend is available */ + bool (*is_available)(void); + + /* Get suitable max_events for this backend */ + int (*get_suitable_max_events)(php_poll_ctx *ctx); + + /* Backend supports edge triggering natively */ + bool supports_et; +} php_poll_backend_ops; + +/* Main poll context */ +struct php_poll_ctx { + const php_poll_backend_ops *backend_ops; + php_poll_backend_type backend_type; + php_poll_error last_error; + + /* Optional capacity hint for backends */ + int max_events_hint; + + /* Flags */ + uint32_t initialized : 1; + uint32_t persistent : 1; + uint32_t raw_events : 1; + + /* Backend-specific data */ + void *backend_data; +}; + +/* Generic FD entry structure */ +typedef struct php_poll_fd_entry { + int fd; + uint32_t events; + void *data; + bool active; + uint32_t last_revents; +} php_poll_fd_entry; + +/* FD tracking table */ +typedef struct php_poll_fd_table { + HashTable entries_ht; + bool persistent; +} php_poll_fd_table; + +/* Iterator callback function type */ +typedef bool (*php_poll_fd_iterator_func_t)(int fd, php_poll_fd_entry *entry, void *user_data); + +/* Poll FD helpers - clean API with accessor functions */ +php_poll_fd_table *php_poll_fd_table_init(int initial_capacity, bool persistent); +void php_poll_fd_table_cleanup(php_poll_fd_table *table); +php_poll_fd_entry *php_poll_fd_table_find(php_poll_fd_table *table, int fd); +php_poll_fd_entry *php_poll_fd_table_get(php_poll_fd_table *table, int fd); +php_poll_fd_entry *php_poll_fd_table_get_new(php_poll_fd_table *table, int fd); +bool php_poll_fd_table_remove(php_poll_fd_table *table, int fd); + +/* Accessor functions for table properties */ +static inline int php_poll_fd_table_count(php_poll_fd_table *table) +{ + return zend_hash_num_elements(&table->entries_ht); +} + +static inline bool php_poll_fd_table_is_empty(php_poll_fd_table *table) +{ + return zend_hash_num_elements(&table->entries_ht) == 0; +} + +/* New helper functions for improved backend integration */ +void php_poll_fd_table_foreach( + php_poll_fd_table *table, php_poll_fd_iterator_func_t callback, void *user_data); +php_socket_t php_poll_fd_table_get_max_fd(php_poll_fd_table *table); +int php_poll_fd_table_collect_events( + php_poll_fd_table *table, php_poll_event *events, int max_events); + +/* Error helper functions */ +php_poll_error php_poll_errno_to_error(int err); + +static inline void php_poll_set_errno_error(php_poll_ctx *ctx, int err) +{ + ctx->last_error = php_poll_errno_to_error(err); +} + +static inline void php_poll_set_current_errno_error(php_poll_ctx *ctx) +{ + php_poll_set_errno_error(ctx, errno); +} + +static inline bool php_poll_is_not_found_error(void) +{ + return errno == ENOENT; +} + +static inline bool php_poll_is_timeout_error(void) +{ +#if defined(ETIME) && defined(ETIMEDOUT) + return errno == ETIME || errno == ETIMEDOUT; +#elif defined(ETIME) + return errno == ETIME; +#elif defined(ETIMEDOUT) + return errno == ETIMEDOUT; +#else + return false; +#endif +} + + +static inline void php_poll_set_error(php_poll_ctx *ctx, php_poll_error error) +{ + ctx->last_error = error; +} + +static inline int php_poll_timespec_to_ms(const struct timespec *timeout) +{ + if (timeout == NULL) { + return -1; + } + + int ms = (int) (timeout->tv_sec * 1000); + /* Round nanoseconds up to the next millisecond to avoid premature return */ + if (timeout->tv_nsec > 0) { + ms += (int) ((timeout->tv_nsec + 999999) / 1000000); + } + + return ms; +} + +#endif /* PHP_POLL_INTERNAL_H */ diff --git a/main/poll/poll_backend_epoll.c b/main/poll/poll_backend_epoll.c new file mode 100644 index 000000000000..394b0dc52446 --- /dev/null +++ b/main/poll/poll_backend_epoll.c @@ -0,0 +1,249 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +#ifdef HAVE_EPOLL + +#include + +typedef struct epoll_backend_data { + int epoll_fd; + struct epoll_event *events; + int events_capacity; + int fd_count; +} epoll_backend_data_t; + +static uint32_t epoll_events_to_native(uint32_t events) +{ + uint32_t native = 0; + if (events & PHP_POLL_READ) { + native |= EPOLLIN; + } + if (events & PHP_POLL_WRITE) { + native |= EPOLLOUT; + } + if (events & PHP_POLL_ERROR) { + native |= EPOLLERR; + } + if (events & PHP_POLL_HUP) { + native |= EPOLLHUP; + } + if (events & PHP_POLL_RDHUP) { + native |= EPOLLRDHUP; + } + if (events & PHP_POLL_ONESHOT) { + native |= EPOLLONESHOT; + } + if (events & PHP_POLL_ET) { + native |= EPOLLET; + } + return native; +} + +static uint32_t epoll_events_from_native(uint32_t native) +{ + uint32_t events = 0; + if (native & EPOLLIN) { + events |= PHP_POLL_READ; + } + if (native & EPOLLOUT) { + events |= PHP_POLL_WRITE; + } + if (native & EPOLLERR) { + events |= PHP_POLL_ERROR; + } + if (native & EPOLLHUP) { + events |= PHP_POLL_HUP; + } + if (native & EPOLLRDHUP) { + events |= PHP_POLL_RDHUP; + } + return events; +} + +static zend_result epoll_backend_init(php_poll_ctx *ctx) +{ + epoll_backend_data_t *data = php_poll_calloc(1, sizeof(epoll_backend_data_t), ctx->persistent); + if (!data) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + data->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (data->epoll_fd == -1) { + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + + /* Use hint for initial allocation if provided, otherwise start with reasonable default */ + int initial_capacity = ctx->max_events_hint > 0 ? ctx->max_events_hint : 64; + data->events = php_poll_calloc(initial_capacity, sizeof(struct epoll_event), ctx->persistent); + if (!data->events) { + close(data->epoll_fd); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + data->events_capacity = initial_capacity; + + ctx->backend_data = data; + return SUCCESS; +} + +static void epoll_backend_cleanup(php_poll_ctx *ctx) +{ + epoll_backend_data_t *data = (epoll_backend_data_t *) ctx->backend_data; + if (data) { + if (data->epoll_fd >= 0) { + close(data->epoll_fd); + } + pefree(data->events, ctx->persistent); + pefree(data, ctx->persistent); + ctx->backend_data = NULL; + } +} + +static zend_result epoll_backend_add(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + epoll_backend_data_t *backend_data = (epoll_backend_data_t *) ctx->backend_data; + + struct epoll_event ev = { 0 }; + ev.events = epoll_events_to_native(events); + ev.data.ptr = data; + + if (epoll_ctl(backend_data->epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) { + php_poll_set_error(ctx, (errno == EEXIST) ? PHP_POLL_ERR_EXISTS : PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + backend_data->fd_count++; + + return SUCCESS; +} + +static zend_result epoll_backend_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + epoll_backend_data_t *backend_data = (epoll_backend_data_t *) ctx->backend_data; + + struct epoll_event ev = { 0 }; + ev.events = epoll_events_to_native(events); + ev.data.ptr = data; + + if (epoll_ctl(backend_data->epoll_fd, EPOLL_CTL_MOD, fd, &ev) == -1) { + php_poll_set_error(ctx, (errno == ENOENT) ? PHP_POLL_ERR_NOTFOUND : PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + + return SUCCESS; +} + +static zend_result epoll_backend_remove(php_poll_ctx *ctx, int fd) +{ + epoll_backend_data_t *backend_data = (epoll_backend_data_t *) ctx->backend_data; + + if (epoll_ctl(backend_data->epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1) { + php_poll_set_error(ctx, (errno == ENOENT) ? PHP_POLL_ERR_NOTFOUND : PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + backend_data->fd_count--; + + return SUCCESS; +} + +static int epoll_backend_wait( + php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + epoll_backend_data_t *backend_data = (epoll_backend_data_t *) ctx->backend_data; + + /* Ensure we have enough space for the requested events */ + if (max_events > backend_data->events_capacity) { + struct epoll_event *new_events = php_poll_realloc( + backend_data->events, max_events * sizeof(struct epoll_event), ctx->persistent); + if (!new_events) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return -1; + } + backend_data->events = new_events; + backend_data->events_capacity = max_events; + } + + int nfds; +#ifdef HAVE_EPOLL_PWAIT2 + nfds = epoll_pwait2(backend_data->epoll_fd, backend_data->events, max_events, timeout, NULL); +#else + int timeout_ms = php_poll_timespec_to_ms(timeout); + nfds = epoll_wait(backend_data->epoll_fd, backend_data->events, max_events, timeout_ms); +#endif + + if (nfds > 0) { + for (int i = 0; i < nfds; i++) { + events[i].fd = backend_data->events[i].data.fd; + events[i].events = 0; /* Not used in results */ + events[i].revents = epoll_events_from_native(backend_data->events[i].events); + events[i].data = backend_data->events[i].data.ptr; + } + } else if (nfds < 0) { + php_poll_set_current_errno_error(ctx); + } + + return nfds; +} + +static int epoll_backend_get_suitable_max_events(php_poll_ctx *ctx) +{ + epoll_backend_data_t *backend_data = (epoll_backend_data_t *) ctx->backend_data; + + if (!backend_data) { + return -1; + } + + /* For epoll, we now track exactly how many FDs are registered */ + int active_fds = backend_data->fd_count; + + if (active_fds == 0) { + return 1; + } + + /* Epoll can return exactly one event per registered FD, + * so the suitable max_events is exactly the number of registered FDs */ + return active_fds; +} + +static bool epoll_backend_is_available(void) +{ + int fd = epoll_create1(EPOLL_CLOEXEC); + if (fd >= 0) { + close(fd); + return true; + } + return false; +} + +const php_poll_backend_ops php_poll_backend_epoll_ops = { + .type = PHP_POLL_BACKEND_EPOLL, + .name = "epoll", + .init = epoll_backend_init, + .cleanup = epoll_backend_cleanup, + .add = epoll_backend_add, + .modify = epoll_backend_modify, + .remove = epoll_backend_remove, + .wait = epoll_backend_wait, + .is_available = epoll_backend_is_available, + .get_suitable_max_events = epoll_backend_get_suitable_max_events, + .supports_et = true, +}; + +#endif /* HAVE_EPOLL */ diff --git a/main/poll/poll_backend_eventport.c b/main/poll/poll_backend_eventport.c new file mode 100644 index 000000000000..35e7c61326f1 --- /dev/null +++ b/main/poll/poll_backend_eventport.c @@ -0,0 +1,403 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +#ifdef HAVE_EVENT_PORTS + +#include +#include +#include +#include +#include + +typedef struct eventport_backend_data { + int port_fd; + port_event_t *events; + int events_capacity; + php_poll_fd_table *fd_table; +} eventport_backend_data_t; + +/* We use last_revents field to track if fd needs (re)association */ +#define EVENTPORT_NEEDS_ASSOC 1 +#define EVENTPORT_IS_ASSOCIATED 0 + +/* Convert our event flags to event port flags */ +static int eventport_events_to_native(uint32_t events) +{ + int native = 0; + if (events & PHP_POLL_READ) { + native |= POLLIN; + } + if (events & PHP_POLL_WRITE) { + native |= POLLOUT; + } + if (events & PHP_POLL_ERROR) { + native |= POLLERR; + } + if (events & PHP_POLL_HUP) { + native |= POLLHUP; + } + if (events & PHP_POLL_RDHUP) { + native |= POLLHUP; /* Map RDHUP to HUP */ + } + return native; +} + +/* Convert event port flags back to our event flags */ +static uint32_t eventport_events_from_native(int native) +{ + uint32_t events = 0; + if (native & POLLIN) { + events |= PHP_POLL_READ; + } + if (native & POLLOUT) { + events |= PHP_POLL_WRITE; + } + if (native & POLLERR) { + events |= PHP_POLL_ERROR; + } + if (native & POLLHUP) { + events |= PHP_POLL_HUP; + } + if (native & POLLNVAL) { + events |= PHP_POLL_ERROR; + } + return events; +} + +/* Initialize event port backend */ +static zend_result eventport_backend_init(php_poll_ctx *ctx) +{ + eventport_backend_data_t *data + = php_poll_calloc(1, sizeof(eventport_backend_data_t), ctx->persistent); + if (!data) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + /* Create event port */ + data->port_fd = port_create(); + if (data->port_fd == -1) { + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + + /* Use hint for initial allocation if provided, otherwise start with reasonable default */ + int initial_capacity = ctx->max_events_hint > 0 ? ctx->max_events_hint : 64; + data->events = php_poll_calloc(initial_capacity, sizeof(port_event_t), ctx->persistent); + if (!data->events) { + close(data->port_fd); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + data->events_capacity = initial_capacity; + + /* Initialize FD tracking using helper */ + data->fd_table = php_poll_fd_table_init(initial_capacity, ctx->persistent); + if (!data->fd_table) { + close(data->port_fd); + pefree(data->events, ctx->persistent); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + ctx->backend_data = data; + return SUCCESS; +} + +/* Cleanup event port backend */ +static void eventport_backend_cleanup(php_poll_ctx *ctx) +{ + eventport_backend_data_t *data = (eventport_backend_data_t *) ctx->backend_data; + if (data) { + if (data->port_fd >= 0) { + close(data->port_fd); + } + pefree(data->events, ctx->persistent); + php_poll_fd_table_cleanup(data->fd_table); + pefree(data, ctx->persistent); + ctx->backend_data = NULL; + } +} + +/* Add file descriptor to event port - just store in table */ +static zend_result eventport_backend_add( + php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + eventport_backend_data_t *backend_data = (eventport_backend_data_t *) ctx->backend_data; + + if (php_poll_fd_table_find(backend_data->fd_table, fd)) { + php_poll_set_error(ctx, PHP_POLL_ERR_EXISTS); + return FAILURE; + } + + php_poll_fd_entry *entry = php_poll_fd_table_get_new(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + entry->events = events; + entry->data = user_data; + entry->last_revents = EVENTPORT_NEEDS_ASSOC; /* Mark as needing association */ + + return SUCCESS; +} + +/* Modify file descriptor in event port - just update table */ +static zend_result eventport_backend_modify( + php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + eventport_backend_data_t *backend_data = (eventport_backend_data_t *) ctx->backend_data; + + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + /* Update entry */ + entry->events = events; + entry->data = user_data; + + /* If currently associated, dissociate so we can re-associate with new events */ + if (entry->last_revents == EVENTPORT_IS_ASSOCIATED) { + port_dissociate(backend_data->port_fd, PORT_SOURCE_FD, fd); + } + + entry->last_revents = EVENTPORT_NEEDS_ASSOC; /* Mark as needing re-association */ + + return SUCCESS; +} + +/* Remove file descriptor from event port */ +static zend_result eventport_backend_remove(php_poll_ctx *ctx, int fd) +{ + eventport_backend_data_t *backend_data = (eventport_backend_data_t *) ctx->backend_data; + + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + /* Only dissociate if it was actually associated */ + if (entry->last_revents == EVENTPORT_IS_ASSOCIATED) { + if (port_dissociate(backend_data->port_fd, PORT_SOURCE_FD, fd) == -1) { + /* Only fail if it's not ENOENT (might already be auto-dissociated) */ + if (!php_poll_is_not_found_error()) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + } + } + + php_poll_fd_table_remove(backend_data->fd_table, fd); + return SUCCESS; +} + +/* Callback context for associating fds */ +typedef struct eventport_associate_ctx { + eventport_backend_data_t *backend_data; + php_poll_ctx *ctx; + bool has_error; +} eventport_associate_ctx; + +/* Callback to associate fds that need association */ +static bool eventport_associate_callback(int fd, php_poll_fd_entry *entry, void *user_data) +{ + eventport_associate_ctx *assoc_ctx = (eventport_associate_ctx *) user_data; + + /* Only associate if marked as needing association */ + if (entry->last_revents == EVENTPORT_NEEDS_ASSOC) { + int native_events = eventport_events_to_native(entry->events); + + if (port_associate(assoc_ctx->backend_data->port_fd, PORT_SOURCE_FD, fd, native_events, + entry->data) + == -1) { + /* Association failed - could set error here if needed */ + switch (errno) { + case EBADFD: + /* fd got closed - remove it */ + php_poll_fd_table_remove(assoc_ctx->backend_data->fd_table, fd); + return true; + case ENOMEM: + php_poll_set_error(assoc_ctx->ctx, PHP_POLL_ERR_NOMEM); + break; + case EINVAL: + php_poll_set_error(assoc_ctx->ctx, PHP_POLL_ERR_INVALID); + break; + default: + php_poll_set_error(assoc_ctx->ctx, PHP_POLL_ERR_SYSTEM); + break; + } + assoc_ctx->has_error = true; + return false; /* Stop iteration */ + } + + /* Mark as associated */ + entry->last_revents = EVENTPORT_IS_ASSOCIATED; + } + + return true; /* Continue iteration */ +} + +/* Wait for events using event port */ +static int eventport_backend_wait( + php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + eventport_backend_data_t *backend_data = (eventport_backend_data_t *) ctx->backend_data; + + int fd_count = php_poll_fd_table_count(backend_data->fd_table); + if (fd_count == 0) { + /* No fds to monitor, but we still need to respect timeout */ + if (timeout != NULL && (timeout->tv_sec > 0 || timeout->tv_nsec > 0)) { + nanosleep(timeout, NULL); + } + return 0; + } + + /* First: associate all fds that need association */ + eventport_associate_ctx assoc_ctx + = { .backend_data = backend_data, .ctx = ctx, .has_error = false }; + + php_poll_fd_table_foreach(backend_data->fd_table, eventport_associate_callback, &assoc_ctx); + + if (assoc_ctx.has_error) { + return -1; + } + + /* Ensure we have enough space for the requested events */ + if (max_events > backend_data->events_capacity) { + port_event_t *new_events = php_poll_realloc( + backend_data->events, max_events * sizeof(port_event_t), ctx->persistent); + if (!new_events) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return -1; + } + backend_data->events = new_events; + backend_data->events_capacity = max_events; + } + + /* port_getn accepts NULL timeout for indefinite wait, or a timespec pointer - + * this maps directly to our new API. We need a mutable copy since port_getn + * may modify the timeout. */ + struct timespec ts_copy; + struct timespec *tsp = NULL; + if (timeout != NULL) { + ts_copy = *timeout; + tsp = &ts_copy; + } + + /* Retrieve events from port */ + uint_t nget = 1; /* We want to get multiple events if available */ + int result = port_getn(backend_data->port_fd, backend_data->events, max_events, &nget, tsp); + + if (result == -1) { + if (php_poll_is_timeout_error()) { + return 0; + } + php_poll_set_current_errno_error(ctx); + return -1; + } + + int nfds = (int) nget; + + /* Process events */ + for (int i = 0; i < nfds; i++) { + port_event_t *port_event = &backend_data->events[i]; + + /* Only handle PORT_SOURCE_FD events */ + if (port_event->portev_source == PORT_SOURCE_FD) { + int fd = (int) port_event->portev_object; + + events[i].fd = fd; + events[i].events = 0; + events[i].revents = eventport_events_from_native(port_event->portev_events); + events[i].data = port_event->portev_user; + + /* After event fires, the association is automatically removed by event ports */ + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (entry) { + if (entry->events & PHP_POLL_ONESHOT) { + /* Oneshot: remove from tracking completely */ + php_poll_fd_table_remove(backend_data->fd_table, fd); + } else { + /* Mark for re-association on next wait() call */ + entry->last_revents = EVENTPORT_NEEDS_ASSOC; + } + } + } else { + /* Handle other event sources if needed (timers, user events, etc.) */ + events[i].fd = -1; + events[i].events = 0; + events[i].revents = 0; + events[i].data = port_event->portev_user; + } + } + + return nfds; +} + +/* Check if event port backend is available */ +static bool eventport_backend_is_available(void) +{ + int fd = port_create(); + if (fd >= 0) { + close(fd); + return true; + } + return false; +} + +static int eventport_backend_get_suitable_max_events(php_poll_ctx *ctx) +{ + eventport_backend_data_t *backend_data = (eventport_backend_data_t *) ctx->backend_data; + + if (!backend_data || !backend_data->fd_table) { + return -1; + } + + int fd_count = php_poll_fd_table_count(backend_data->fd_table); + + if (fd_count == 0) { + return 1; + } + + /* Event ports can return exactly one event per association, + * so the suitable max_events is exactly the number of tracked fds */ + return fd_count; +} + +/* Event port backend operations structure */ +const php_poll_backend_ops php_poll_backend_eventport_ops = { + .type = PHP_POLL_BACKEND_EVENTPORT, + .name = "eventport", + .init = eventport_backend_init, + .cleanup = eventport_backend_cleanup, + .add = eventport_backend_add, + .modify = eventport_backend_modify, + .remove = eventport_backend_remove, + .wait = eventport_backend_wait, + .is_available = eventport_backend_is_available, + .get_suitable_max_events = eventport_backend_get_suitable_max_events, + .supports_et = false /* Event ports are level-triggered only */ +}; + +#endif /* HAVE_EVENT_PORTS */ diff --git a/main/poll/poll_backend_kqueue.c b/main/poll/poll_backend_kqueue.c new file mode 100644 index 000000000000..19ff0ad6d228 --- /dev/null +++ b/main/poll/poll_backend_kqueue.c @@ -0,0 +1,521 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +#ifdef HAVE_KQUEUE + +#include +#include +#include + +/* Flags for tracking FD state in single hash table */ +#define KQUEUE_FD_PRESENT (1 << 0) /* FD is registered */ +#define KQUEUE_FD_ONESHOT_COMPLETE (1 << 1) /* Has both read+write oneshot */ +#define KQUEUE_FD_GARBAGE_READ (1 << 2) /* Read filter fired, needs write cleanup */ +#define KQUEUE_FD_GARBAGE_WRITE (1 << 3) /* Write filter fired, needs read cleanup */ +#define KQUEUE_FD_HAS_GARBAGE (KQUEUE_FD_GARBAGE_READ | KQUEUE_FD_GARBAGE_WRITE) + +typedef struct kqueue_backend_data { + int kqueue_fd; + struct kevent *events; + int events_capacity; + int fd_count; /* Track number of unique FDs (not individual filters) */ + int filter_count; /* Track total number of filters for raw events */ + HashTable *fd_tracking; /* Single hash table for all FD state tracking */ +} kqueue_backend_data_t; + +static zend_result kqueue_backend_init(php_poll_ctx *ctx) +{ + kqueue_backend_data_t *data + = php_poll_calloc(1, sizeof(kqueue_backend_data_t), ctx->persistent); + if (!data) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + data->kqueue_fd = kqueue(); + if (data->kqueue_fd == -1) { + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_SYSTEM); + return FAILURE; + } + + /* Use hint for initial allocation if provided, otherwise start with reasonable default */ + int initial_capacity = ctx->max_events_hint > 0 ? ctx->max_events_hint : 64; + data->events = php_poll_calloc(initial_capacity, sizeof(struct kevent), ctx->persistent); + if (!data->events) { + close(data->kqueue_fd); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + data->events_capacity = initial_capacity; + data->fd_count = 0; + data->filter_count = 0; + + /* Initialize single tracking hash table (only if not using raw events) */ + if (!ctx->raw_events) { + data->fd_tracking = php_poll_malloc(sizeof(HashTable), ctx->persistent); + zend_hash_init(data->fd_tracking, 8, NULL, NULL, ctx->persistent); + } else { + data->fd_tracking = NULL; + } + + ctx->backend_data = data; + return SUCCESS; +} + +static void kqueue_backend_cleanup(php_poll_ctx *ctx) +{ + kqueue_backend_data_t *data = (kqueue_backend_data_t *) ctx->backend_data; + if (data) { + if (data->kqueue_fd >= 0) { + close(data->kqueue_fd); + } + pefree(data->events, ctx->persistent); + + /* Cleanup tracking hash table if initialized */ + if (data->fd_tracking) { + zend_hash_destroy(data->fd_tracking); + pefree(data->fd_tracking, ctx->persistent); + } + + pefree(data, ctx->persistent); + ctx->backend_data = NULL; + } +} + +static zend_result kqueue_backend_add(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + kqueue_backend_data_t *backend_data = (kqueue_backend_data_t *) ctx->backend_data; + + /* Check for duplicate in non-raw mode */ + if (!ctx->raw_events) { + zval *existing = zend_hash_index_find(backend_data->fd_tracking, fd); + if (existing && (Z_LVAL_P(existing) & KQUEUE_FD_PRESENT)) { + php_poll_set_error(ctx, PHP_POLL_ERR_EXISTS); + return FAILURE; + } + } + + struct kevent changes[2]; /* Max 2 changes: read + write */ + int change_count = 0; + + uint16_t flags = EV_ADD | EV_ENABLE; + if (events & PHP_POLL_ONESHOT) { + flags |= EV_ONESHOT; + } + if (events & PHP_POLL_ET) { + flags |= EV_CLEAR; + } + + if (events & PHP_POLL_READ) { + EV_SET(&changes[change_count], fd, EVFILT_READ, flags, 0, 0, data); + change_count++; + } + + if (events & PHP_POLL_WRITE) { + EV_SET(&changes[change_count], fd, EVFILT_WRITE, flags, 0, 0, data); + change_count++; + } + + if (change_count > 0) { + int result = kevent(backend_data->kqueue_fd, changes, change_count, NULL, 0, NULL); + if (result == -1) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + + /* Increment counters */ + backend_data->fd_count++; + backend_data->filter_count += change_count; + + /* Track FD state in non-raw mode */ + if (!ctx->raw_events) { + zend_long tracking_flags = KQUEUE_FD_PRESENT; + + /* Mark as complete oneshot if both read+write with oneshot */ + if ((events & (PHP_POLL_READ | PHP_POLL_WRITE | PHP_POLL_ONESHOT)) + == (PHP_POLL_READ | PHP_POLL_WRITE | PHP_POLL_ONESHOT)) { + tracking_flags |= KQUEUE_FD_ONESHOT_COMPLETE; + } + + zval tracking_zval; + ZVAL_LONG(&tracking_zval, tracking_flags); + zend_hash_index_update(backend_data->fd_tracking, fd, &tracking_zval); + } + } + + return SUCCESS; +} + +static zend_result kqueue_backend_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + kqueue_backend_data_t *backend_data = (kqueue_backend_data_t *) ctx->backend_data; + + struct kevent deletes[2]; + struct kevent adds[2]; + int delete_count = 0; + int add_count = 0; + int successful_deletes = 0; + + uint16_t add_flags = EV_ADD | EV_ENABLE; + if (events & PHP_POLL_ONESHOT) { + add_flags |= EV_ONESHOT; + } + if (events & PHP_POLL_ET) { + add_flags |= EV_CLEAR; + } + + /* Delete existing filters that are not in the new events */ + if (!(events & PHP_POLL_READ)) { + EV_SET(&deletes[delete_count], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + delete_count++; + } + if (!(events & PHP_POLL_WRITE)) { + EV_SET(&deletes[delete_count], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + delete_count++; + } + + /* Prepare add operations for requested events */ + if (events & PHP_POLL_READ) { + EV_SET(&adds[add_count], fd, EVFILT_READ, add_flags, 0, 0, data); + add_count++; + } + if (events & PHP_POLL_WRITE) { + EV_SET(&adds[add_count], fd, EVFILT_WRITE, add_flags, 0, 0, data); + add_count++; + } + + /* Delete existing filters individually to count successes */ + for (int i = 0; i < delete_count; i++) { + int result = kevent(backend_data->kqueue_fd, &deletes[i], 1, NULL, 0, NULL); + if (result == 0) { + successful_deletes++; + } else if (!php_poll_is_not_found_error()) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + /* ENOENT is ignored - filter didn't exist */ + } + + /* Add new filters */ + if (add_count > 0) { + int result = kevent(backend_data->kqueue_fd, adds, add_count, NULL, 0, NULL); + if (result == -1) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + } + + /* Update counters and tracking */ + if (successful_deletes > 0 && add_count == 0) { + /* Removed all filters - FD is gone */ + backend_data->fd_count--; + backend_data->filter_count -= successful_deletes; + if (!ctx->raw_events) { + zend_hash_index_del(backend_data->fd_tracking, fd); + } + } else if (add_count > 0) { + if (successful_deletes == 0) { + /* Added filters to previously empty FD */ + backend_data->fd_count++; + backend_data->filter_count += add_count; + } else { + /* Mixed operation when successful_deletes > 0 - update filter count */ + backend_data->filter_count = backend_data->filter_count - successful_deletes + add_count; + } + + if (!ctx->raw_events) { + zend_long tracking_flags = KQUEUE_FD_PRESENT; + if ((events & (PHP_POLL_READ | PHP_POLL_WRITE | PHP_POLL_ONESHOT)) + == (PHP_POLL_READ | PHP_POLL_WRITE | PHP_POLL_ONESHOT)) { + tracking_flags |= KQUEUE_FD_ONESHOT_COMPLETE; + } + zval tracking_zval; + ZVAL_LONG(&tracking_zval, tracking_flags); + zend_hash_index_update(backend_data->fd_tracking, fd, &tracking_zval); + } + } + + return SUCCESS; +} + +static zend_result kqueue_backend_remove(php_poll_ctx *ctx, int fd) +{ + kqueue_backend_data_t *backend_data = (kqueue_backend_data_t *) ctx->backend_data; + struct kevent change; + int successful_deletes = 0; + + /* Try to remove read filter */ + EV_SET(&change, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + int result = kevent(backend_data->kqueue_fd, &change, 1, NULL, 0, NULL); + if (result == 0) { + successful_deletes++; + } else if (!php_poll_is_not_found_error()) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + + /* Try to remove write filter */ + EV_SET(&change, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + result = kevent(backend_data->kqueue_fd, &change, 1, NULL, 0, NULL); + if (result == 0) { + successful_deletes++; + } else if (!php_poll_is_not_found_error()) { + php_poll_set_current_errno_error(ctx); + return FAILURE; + } + + /* If no filters were successfully deleted, that's an error */ + if (successful_deletes == 0) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + /* Update counters */ + backend_data->fd_count--; + backend_data->filter_count -= successful_deletes; + + /* Remove from tracking */ + if (!ctx->raw_events) { + zend_hash_index_del(backend_data->fd_tracking, fd); + } + + return SUCCESS; +} + +static int kqueue_backend_wait( + php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + kqueue_backend_data_t *backend_data = (kqueue_backend_data_t *) ctx->backend_data; + + /* Cap every kevent() request at the entries we can still deliver, like epoll's maxevents. + * Unretrieved events stay pending in the kqueue (EV_ONESHOT deletes and EV_CLEAR resets only + * at retrieval), so nothing is lost and the caller's buffer cannot overflow. */ + if (max_events > backend_data->events_capacity) { + struct kevent *new_events = php_poll_realloc( + backend_data->events, max_events * sizeof(struct kevent), ctx->persistent); + if (!new_events) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return -1; + } + backend_data->events = new_events; + backend_data->events_capacity = max_events; + } + + if (ctx->raw_events) { + /* Raw events mode - direct 1:1 mapping, no grouping */ + int nfds = kevent( + backend_data->kqueue_fd, NULL, 0, backend_data->events, max_events, timeout); + + if (nfds < 0) { + php_poll_set_current_errno_error(ctx); + return -1; + } + + for (int i = 0; i < nfds; i++) { + events[i].fd = (int) backend_data->events[i].ident; + events[i].events = 0; + events[i].revents = 0; + events[i].data = backend_data->events[i].udata; + + /* Convert kqueue filter to poll event */ + if (backend_data->events[i].filter == EVFILT_READ) { + events[i].revents |= PHP_POLL_READ; + } else if (backend_data->events[i].filter == EVFILT_WRITE) { + events[i].revents |= PHP_POLL_WRITE; + } + + /* Convert kqueue flags to poll events */ + if (backend_data->events[i].flags & EV_EOF) { + events[i].revents |= PHP_POLL_HUP; + } + if (backend_data->events[i].flags & EV_ERROR) { + events[i].revents |= PHP_POLL_ERROR; + } + } + + return nfds; + } + + /* Grouped events mode with improved oneshot tracking. + * + * kqueue reports one event per (FD, filter) pair, so a READ+WRITE pair merges into a single + * entry and one round can fill fewer than max_events entries while more events are pending. + * Top up with zero-timeout rounds, each requesting only the remaining free entries. Both + * FreeBSD and XNU re-enqueue delivered level-triggered events at the tail of the active queue, + * so top-up rounds see not-yet-delivered events first, matching epoll's round-robin fill. */ + int unique_events = 0, garbage_events = 0; + const struct timespec zero_timeout = {0, 0}; + const struct timespec *round_timeout = timeout; + + while (true) { + int slots = max_events - unique_events; + int nfds = kevent( + backend_data->kqueue_fd, NULL, 0, backend_data->events, slots, round_timeout); + + if (nfds < 0) { + if (unique_events > 0) { + /* Deliver what was already gathered */ + break; + } + php_poll_set_current_errno_error(ctx); + return -1; + } + + int new_unique_events = 0; + + for (int i = 0; i < nfds; i++) { + int fd = (int) backend_data->events[i].ident; + uint32_t revents = 0; + void *data = backend_data->events[i].udata; + bool is_oneshot = (backend_data->events[i].flags & EV_ONESHOT) != 0; + + /* Convert this event */ + if (backend_data->events[i].filter == EVFILT_READ) { + revents |= PHP_POLL_READ; + } else if (backend_data->events[i].filter == EVFILT_WRITE) { + revents |= PHP_POLL_WRITE; + } + + if (backend_data->events[i].flags & EV_EOF) { + revents |= PHP_POLL_HUP; + } + if (backend_data->events[i].flags & EV_ERROR) { + revents |= PHP_POLL_ERROR; + } + + /* Look for existing event for this FD */ + bool found = false; + for (int j = 0; j < unique_events; j++) { + if (events[j].fd == fd) { + /* Combine with existing event */ + events[j].revents |= revents; + found = true; + break; + } + } + + if (!found) { + /* New FD, create new event */ + ZEND_ASSERT(unique_events < max_events); + events[unique_events].fd = fd; + events[unique_events].events = 0; + events[unique_events].revents = revents; + events[unique_events].data = data; + unique_events++; + new_unique_events++; + + /* Handle oneshot tracking */ + if (is_oneshot) { + zval *tracking = zend_hash_index_find(backend_data->fd_tracking, fd); + if (tracking && (Z_LVAL_P(tracking) & KQUEUE_FD_ONESHOT_COMPLETE)) { + /* Mark which filter fired for garbage collection */ + zend_long flags = Z_LVAL_P(tracking); + flags &= ~KQUEUE_FD_ONESHOT_COMPLETE; /* Clear complete flag */ + if (revents & PHP_POLL_READ) { + flags |= KQUEUE_FD_GARBAGE_READ; /* Need to clean write */ + } + if (revents & PHP_POLL_WRITE) { + flags |= KQUEUE_FD_GARBAGE_WRITE; /* Need to clean read */ + } + ZVAL_LONG(tracking, flags); + backend_data->fd_count--; + garbage_events++; + } + } + } else if (is_oneshot) { + /* Second filter for same FD fired - clear garbage flags */ + zval *tracking = zend_hash_index_find(backend_data->fd_tracking, fd); + if (tracking) { + /* Remove FD from tracking as it gets deleted from kqueue as well */ + zend_hash_index_del(backend_data->fd_tracking, fd); + garbage_events--; + } + } + } + + /* Stop on a partial round (drained or timed out), a full buffer, or a full round with no + * new FDs (kernel re-reported level-triggered events already merged above - don't spin) */ + if (nfds < slots || unique_events == max_events || new_unique_events == 0) { + break; + } + round_timeout = &zero_timeout; + } + + if (garbage_events > 0) { + /* Clean up orphaned filters from complete oneshot FDs */ + struct kevent cleanup_change; + ZEND_HASH_FOREACH_NUM_KEY_VAL(backend_data->fd_tracking, zend_ulong fd_key, zval *tracking) + { + zend_long flags = Z_LVAL_P(tracking); + if (flags & KQUEUE_FD_HAS_GARBAGE) { + int filter = (flags & KQUEUE_FD_GARBAGE_READ) ? EVFILT_WRITE : EVFILT_READ; + EV_SET(&cleanup_change, fd_key, filter, EV_DELETE, 0, 0, NULL); + kevent(backend_data->kqueue_fd, &cleanup_change, 1, NULL, 0, NULL); + + /* Remove FD from tracking after cleanup */ + zend_hash_index_del(backend_data->fd_tracking, fd_key); + } + } + ZEND_HASH_FOREACH_END(); + } + + return unique_events; +} + +static bool kqueue_backend_is_available(void) +{ + int fd = kqueue(); + if (fd >= 0) { + close(fd); + return true; + } + return false; +} + +static int kqueue_backend_get_suitable_max_events(php_poll_ctx *ctx) +{ + kqueue_backend_data_t *backend_data = (kqueue_backend_data_t *) ctx->backend_data; + + if (!backend_data) { + return -1; + } + + /* kqueue reports one event per filter even in grouped mode (events are merged into + * per-FD entries afterwards) and the wait request is capped at max_events, so size + * for the total filter count to allow retrieving all pending events in one call. */ + int active_filters = backend_data->filter_count; + return active_filters == 0 ? 1 : active_filters; +} + +const php_poll_backend_ops php_poll_backend_kqueue_ops = { + .type = PHP_POLL_BACKEND_KQUEUE, + .name = "kqueue", + .init = kqueue_backend_init, + .cleanup = kqueue_backend_cleanup, + .add = kqueue_backend_add, + .modify = kqueue_backend_modify, + .remove = kqueue_backend_remove, + .wait = kqueue_backend_wait, + .is_available = kqueue_backend_is_available, + .get_suitable_max_events = kqueue_backend_get_suitable_max_events, + .supports_et = true +}; + + +#endif /* HAVE_KQUEUE */ diff --git a/main/poll/poll_backend_poll.c b/main/poll/poll_backend_poll.c new file mode 100644 index 000000000000..05a51a04d31d --- /dev/null +++ b/main/poll/poll_backend_poll.c @@ -0,0 +1,290 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +#ifndef PHP_WIN32 + +typedef struct poll_backend_data { + php_poll_fd_table *fd_table; + struct pollfd *temp_fds; + int temp_fds_capacity; +} poll_backend_data_t; + +static uint32_t poll_events_to_native(uint32_t events) +{ + uint32_t native = 0; + if (events & PHP_POLL_READ) { + native |= POLLIN; + } + if (events & PHP_POLL_WRITE) { + native |= POLLOUT; + } + if (events & PHP_POLL_ERROR) { + native |= POLLERR; + } + if (events & PHP_POLL_HUP) { + native |= POLLHUP; + } + return native; +} + +static uint32_t poll_events_from_native(uint32_t native) +{ + uint32_t events = 0; + if (native & POLLIN) { + events |= PHP_POLL_READ; + } + if (native & POLLOUT) { + events |= PHP_POLL_WRITE; + } + if (native & POLLERR) { + events |= PHP_POLL_ERROR; + } + if (native & POLLHUP) { + events |= PHP_POLL_HUP; + } + if (native & POLLNVAL) { + events |= PHP_POLL_ERROR; /* Map invalid FD to error */ + } + return events; +} + +static zend_result poll_backend_init(php_poll_ctx *ctx) +{ + poll_backend_data_t *data = php_poll_calloc(1, sizeof(poll_backend_data_t), ctx->persistent); + if (!data) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + int initial_capacity = ctx->max_events_hint > 0 ? ctx->max_events_hint : 64; + + data->fd_table = php_poll_fd_table_init(initial_capacity, ctx->persistent); + if (!data->fd_table) { + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + data->temp_fds = php_poll_calloc(initial_capacity, sizeof(struct pollfd), ctx->persistent); + if (!data->temp_fds) { + php_poll_fd_table_cleanup(data->fd_table); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + data->temp_fds_capacity = initial_capacity; + + ctx->backend_data = data; + return SUCCESS; +} + +static void poll_backend_cleanup(php_poll_ctx *ctx) +{ + poll_backend_data_t *data = (poll_backend_data_t *) ctx->backend_data; + if (data) { + php_poll_fd_table_cleanup(data->fd_table); + pefree(data->temp_fds, ctx->persistent); + pefree(data, ctx->persistent); + ctx->backend_data = NULL; + } +} + +static zend_result poll_backend_add(php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + poll_backend_data_t *backend_data = (poll_backend_data_t *) ctx->backend_data; + + if (events & PHP_POLL_ET) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOSUPPORT); + return FAILURE; + } + + if (php_poll_fd_table_find(backend_data->fd_table, fd)) { + php_poll_set_error(ctx, PHP_POLL_ERR_EXISTS); + return FAILURE; + } + + php_poll_fd_entry *entry = php_poll_fd_table_get_new(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + entry->events = events; + entry->data = user_data; + + return SUCCESS; +} + +static zend_result poll_backend_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + poll_backend_data_t *backend_data = (poll_backend_data_t *) ctx->backend_data; + + if (events & PHP_POLL_ET) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOSUPPORT); + return FAILURE; + } + + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + entry->events = events; + entry->data = user_data; + + return SUCCESS; +} + +static zend_result poll_backend_remove(php_poll_ctx *ctx, int fd) +{ + poll_backend_data_t *backend_data = (poll_backend_data_t *) ctx->backend_data; + + if (!php_poll_fd_table_remove(backend_data->fd_table, fd)) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + return SUCCESS; +} + +/* Context for building struct pollfd array */ +typedef struct poll_build_context { + struct pollfd *fds; + int index; +} poll_build_context; + +/* Callback to build struct pollfd array from fd_table */ +static bool poll_build_fds_callback(int fd, php_poll_fd_entry *entry, void *user_data) +{ + poll_build_context *ctx = (poll_build_context *) user_data; + + ctx->fds[ctx->index].fd = fd; + ctx->fds[ctx->index].events + = poll_events_to_native(entry->events & ~(PHP_POLL_ET | PHP_POLL_ONESHOT)); + ctx->fds[ctx->index].revents = 0; + ctx->index++; + + return true; +} + +static int poll_backend_wait( + php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + poll_backend_data_t *backend_data = (poll_backend_data_t *) ctx->backend_data; + + int fd_count = php_poll_fd_table_count(backend_data->fd_table); + if (fd_count == 0) { + if (timeout != NULL && (timeout->tv_sec > 0 || timeout->tv_nsec > 0)) { + nanosleep(timeout, NULL); + } + return 0; + } + + /* Ensure temp_fds array is large enough */ + if (fd_count > backend_data->temp_fds_capacity) { + struct pollfd *new_fds = php_poll_realloc( + backend_data->temp_fds, fd_count * sizeof(struct pollfd), ctx->persistent); + if (!new_fds) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return -1; + } + backend_data->temp_fds = new_fds; + backend_data->temp_fds_capacity = fd_count; + } + + /* Build struct pollfd array from fd_table */ + poll_build_context build_ctx = { .fds = backend_data->temp_fds, .index = 0 }; + php_poll_fd_table_foreach(backend_data->fd_table, poll_build_fds_callback, &build_ctx); + + /* Convert timespec to milliseconds (poll() only supports ms resolution) */ + int timeout_ms = php_poll_timespec_to_ms(timeout); + int nfds = poll(backend_data->temp_fds, fd_count, timeout_ms); + + if (nfds < 0) { + php_poll_set_current_errno_error(ctx); + return -1; + } else if (nfds == 0) { + return 0; /* timeout */ + } + + /* Process results - iterate through struct pollfd array directly */ + int event_count = 0; + for (int i = 0; i < fd_count && event_count < max_events; i++) { + struct pollfd *pfd = &backend_data->temp_fds[i]; + + if (pfd->revents != 0) { + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, pfd->fd); + if (entry) { + /* Handle POLLNVAL by automatically removing the invalid FD */ + if (pfd->revents & POLLNVAL) { + php_poll_fd_table_remove(backend_data->fd_table, pfd->fd); + continue; /* Don't report this event */ + } + + events[event_count].fd = pfd->fd; + events[event_count].events = entry->events; + events[event_count].revents = poll_events_from_native(pfd->revents); + events[event_count].data = entry->data; + event_count++; + } + } + } + + /* Handle oneshot removals */ + for (int i = 0; i < event_count; i++) { + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, events[i].fd); + if (entry && (entry->events & PHP_POLL_ONESHOT) && events[i].revents != 0) { + php_poll_fd_table_remove(backend_data->fd_table, events[i].fd); + } + } + + return event_count; +} + +static bool poll_backend_is_available(void) +{ + return true; +} + +static int poll_backend_get_suitable_max_events(php_poll_ctx *ctx) +{ + poll_backend_data_t *backend_data = (poll_backend_data_t *) ctx->backend_data; + + if (UNEXPECTED(!backend_data || !backend_data->fd_table)) { + return -1; + } + + int active_fds = php_poll_fd_table_count(backend_data->fd_table); + return active_fds == 0 ? 1 : active_fds; +} + +const php_poll_backend_ops php_poll_backend_poll_ops = { + .type = PHP_POLL_BACKEND_POLL, + .name = "poll", + .init = poll_backend_init, + .cleanup = poll_backend_cleanup, + .add = poll_backend_add, + .modify = poll_backend_modify, + .remove = poll_backend_remove, + .wait = poll_backend_wait, + .is_available = poll_backend_is_available, + .get_suitable_max_events = poll_backend_get_suitable_max_events, + .supports_et = false, +}; + +#endif diff --git a/main/poll/poll_backend_wsapoll.c b/main/poll/poll_backend_wsapoll.c new file mode 100644 index 000000000000..101a7cfe0e4b --- /dev/null +++ b/main/poll/poll_backend_wsapoll.c @@ -0,0 +1,335 @@ +/* ++----------------------------------------------------------------------+ +| Copyright © The PHP Group and Contributors. | ++----------------------------------------------------------------------+ +| This source file is subject to the Modified BSD License that is | +| bundled with this package in the file LICENSE, and is available | +| through the World Wide Web at . | +| | +| SPDX-License-Identifier: BSD-3-Clause | ++----------------------------------------------------------------------+ +| Authors: Jakub Zelenka | ++----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +#ifdef PHP_WIN32 + +#include +#include + +typedef struct wsapoll_backend_data { + php_poll_fd_table *fd_table; + WSAPOLLFD *temp_fds; + int temp_fds_capacity; +} wsapoll_backend_data_t; + +static uint32_t wsapoll_events_to_native(uint32_t events) +{ + uint32_t native = 0; + if (events & PHP_POLL_READ) { + native |= POLLRDNORM; + } + if (events & PHP_POLL_WRITE) { + native |= POLLWRNORM; + } + if (events & PHP_POLL_ERROR) { + native |= POLLERR; + } + if (events & PHP_POLL_HUP) { + native |= POLLHUP; + } + return native; +} + +static uint32_t wsapoll_events_from_native(uint32_t native) +{ + uint32_t events = 0; + if (native & POLLRDNORM) { + events |= PHP_POLL_READ; + } + if (native & POLLWRNORM) { + events |= PHP_POLL_WRITE; + } + if (native & POLLERR) { + events |= PHP_POLL_ERROR; + } + if (native & POLLHUP) { + events |= PHP_POLL_HUP; + } + if (native & POLLNVAL) { + events |= PHP_POLL_ERROR; /* Map invalid socket to error */ + } + return events; +} + +static zend_result wsapoll_backend_init(php_poll_ctx *ctx) +{ + wsapoll_backend_data_t *data + = php_poll_calloc(1, sizeof(wsapoll_backend_data_t), ctx->persistent); + if (!data) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + int initial_capacity = ctx->max_events_hint > 0 ? ctx->max_events_hint : 64; + + data->fd_table = php_poll_fd_table_init(initial_capacity, ctx->persistent); + if (!data->fd_table) { + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + data->temp_fds = php_poll_calloc(initial_capacity, sizeof(WSAPOLLFD), ctx->persistent); + if (!data->temp_fds) { + php_poll_fd_table_cleanup(data->fd_table); + pefree(data, ctx->persistent); + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + data->temp_fds_capacity = initial_capacity; + + ctx->backend_data = data; + return SUCCESS; +} + +static void wsapoll_backend_cleanup(php_poll_ctx *ctx) +{ + wsapoll_backend_data_t *data = (wsapoll_backend_data_t *) ctx->backend_data; + if (data) { + php_poll_fd_table_cleanup(data->fd_table); + pefree(data->temp_fds, ctx->persistent); + pefree(data, ctx->persistent); + ctx->backend_data = NULL; + } +} + +static zend_result wsapoll_backend_add(php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + wsapoll_backend_data_t *backend_data = (wsapoll_backend_data_t *) ctx->backend_data; + + if (events & PHP_POLL_ET) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOSUPPORT); + return FAILURE; + } + + if (php_poll_fd_table_find(backend_data->fd_table, fd)) { + php_poll_set_error(ctx, PHP_POLL_ERR_EXISTS); + return FAILURE; + } + + php_poll_fd_entry *entry = php_poll_fd_table_get_new(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return FAILURE; + } + + entry->events = events; + entry->data = user_data; + + return SUCCESS; +} + +static zend_result wsapoll_backend_modify( + php_poll_ctx *ctx, int fd, uint32_t events, void *user_data) +{ + wsapoll_backend_data_t *backend_data = (wsapoll_backend_data_t *) ctx->backend_data; + + if (events & PHP_POLL_ET) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOSUPPORT); + return FAILURE; + } + + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (!entry) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + entry->events = events; + entry->data = user_data; + + return SUCCESS; +} + +static zend_result wsapoll_backend_remove(php_poll_ctx *ctx, int fd) +{ + wsapoll_backend_data_t *backend_data = (wsapoll_backend_data_t *) ctx->backend_data; + + if (!php_poll_fd_table_remove(backend_data->fd_table, fd)) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOTFOUND); + return FAILURE; + } + + return SUCCESS; +} + +/* Context for building WSAPOLLFD array */ +typedef struct wsapoll_build_context { + WSAPOLLFD *fds; + int index; +} wsapoll_build_context; + +/* Callback to build WSAPOLLFD array from fd_table */ +static bool wsapoll_build_fds_callback(int fd, php_poll_fd_entry *entry, void *user_data) +{ + wsapoll_build_context *ctx = (wsapoll_build_context *) user_data; + + ctx->fds[ctx->index].fd = (SOCKET) fd; + ctx->fds[ctx->index].events + = (SHORT) wsapoll_events_to_native(entry->events & ~(PHP_POLL_ET | PHP_POLL_ONESHOT)); + ctx->fds[ctx->index].revents = 0; + ctx->index++; + + return true; +} + +static int wsapoll_backend_wait( + php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + wsapoll_backend_data_t *backend_data = (wsapoll_backend_data_t *) ctx->backend_data; + + int fd_count = php_poll_fd_table_count(backend_data->fd_table); + if (fd_count == 0) { + if (timeout != NULL && (timeout->tv_sec > 0 || timeout->tv_nsec > 0)) { + /* Convert to milliseconds, rounding up */ + int sleep_ms = php_poll_timespec_to_ms(timeout); + if (sleep_ms > 0) { + Sleep(sleep_ms); + } + } + return 0; + } + + /* Ensure temp_fds array is large enough */ + if (fd_count > backend_data->temp_fds_capacity) { + WSAPOLLFD *new_fds = php_poll_realloc( + backend_data->temp_fds, fd_count * sizeof(WSAPOLLFD), ctx->persistent); + if (!new_fds) { + php_poll_set_error(ctx, PHP_POLL_ERR_NOMEM); + return -1; + } + backend_data->temp_fds = new_fds; + backend_data->temp_fds_capacity = fd_count; + } + + /* Build WSAPOLLFD array from fd_table */ + wsapoll_build_context build_ctx = { .fds = backend_data->temp_fds, .index = 0 }; + php_poll_fd_table_foreach(backend_data->fd_table, wsapoll_build_fds_callback, &build_ctx); + + /* Convert timespec to milliseconds (WSAPoll only supports ms resolution, round up) */ + int timeout_ms = php_poll_timespec_to_ms(timeout); + + /* Call WSAPoll */ + int nfds = WSAPoll(backend_data->temp_fds, fd_count, timeout_ms); + + if (nfds == SOCKET_ERROR) { + /* WSAPoll specific error handling */ + int wsa_error = WSAGetLastError(); + php_poll_error error_code; + + switch (wsa_error) { + case WSAENOTSOCK: + /* Special case: all sockets in array are invalid + * WSAPoll fails entirely, but we should clean up and return 0 + * This differs from Unix poll() which would report POLLNVAL per socket */ + + /* Remove all invalid sockets from fd_table */ + for (int i = 0; i < fd_count; i++) { + int fd = (int) backend_data->temp_fds[i].fd; + php_poll_fd_table_remove(backend_data->fd_table, fd); + } + return 0; + case WSAENOBUFS: + error_code = PHP_POLL_ERR_NOMEM; + break; + case WSAEINVAL: + case WSAEFAULT: + error_code = PHP_POLL_ERR_INVALID; + break; + default: + error_code = PHP_POLL_ERR_SYSTEM; + break; + } + + php_poll_set_error(ctx, error_code); + return -1; + } + + if (nfds == 0) { + return 0; /* Timeout */ + } + + int event_count = 0; + for (int i = 0; i < fd_count && event_count < max_events; i++) { + WSAPOLLFD *pfd = &backend_data->temp_fds[i]; + + if (pfd->revents != 0) { + int fd = (int) pfd->fd; + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, fd); + if (entry) { + /* WSAPoll-specific handling of POLLNVAL */ + if (pfd->revents & POLLNVAL) { + php_poll_fd_table_remove(backend_data->fd_table, fd); + continue; /* Do not report this event */ + } + + /* Convert WSAPoll events to PHP poll events */ + uint32_t converted_events = wsapoll_events_from_native(pfd->revents); + + events[event_count].fd = fd; + events[event_count].events = entry->events; + events[event_count].revents = converted_events; + events[event_count].data = entry->data; + event_count++; + } + } + } + + /* Handle oneshot removals */ + for (int i = 0; i < event_count; i++) { + php_poll_fd_entry *entry = php_poll_fd_table_find(backend_data->fd_table, events[i].fd); + if (entry && (entry->events & PHP_POLL_ONESHOT) && events[i].revents != 0) { + php_poll_fd_table_remove(backend_data->fd_table, events[i].fd); + } + } + + return event_count; +} + +static bool wsapoll_backend_is_available(void) +{ + /* Always available on the currently supported Windows versions. */ + return true; +} + +static int wsapoll_backend_get_suitable_max_events(php_poll_ctx *ctx) +{ + wsapoll_backend_data_t *backend_data = (wsapoll_backend_data_t *) ctx->backend_data; + + if (UNEXPECTED(!backend_data || !backend_data->fd_table)) { + return -1; + } + + int active_fds = php_poll_fd_table_count(backend_data->fd_table); + return active_fds == 0 ? 1 : active_fds; +} + +const php_poll_backend_ops php_poll_backend_wsapoll_ops = { + .type = PHP_POLL_BACKEND_WSAPOLL, + .name = "wsapoll", + .init = wsapoll_backend_init, + .cleanup = wsapoll_backend_cleanup, + .add = wsapoll_backend_add, + .modify = wsapoll_backend_modify, + .remove = wsapoll_backend_remove, + .wait = wsapoll_backend_wait, + .is_available = wsapoll_backend_is_available, + .get_suitable_max_events = wsapoll_backend_get_suitable_max_events, + .supports_et = false, +}; + +#endif /* PHP_WIN32 */ diff --git a/main/poll/poll_core.c b/main/poll/poll_core.c new file mode 100644 index 000000000000..f985dbcdd3eb --- /dev/null +++ b/main/poll/poll_core.c @@ -0,0 +1,443 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +/* Backend registry */ +static const php_poll_backend_ops *registered_backends[8]; +static int num_registered_backends = 0; + +/* Forward declarations for backend ops */ + +#ifdef HAVE_EPOLL +extern const php_poll_backend_ops php_poll_backend_epoll_ops; +#endif +#ifdef HAVE_KQUEUE +extern const php_poll_backend_ops php_poll_backend_kqueue_ops; +#endif +#ifdef HAVE_EVENT_PORTS +extern const php_poll_backend_ops php_poll_backend_eventport_ops; +#endif +#ifdef PHP_WIN32 +extern const php_poll_backend_ops php_poll_backend_wsapoll_ops; +#else +extern const php_poll_backend_ops php_poll_backend_poll_ops; +#endif + +/* Register all available backends */ +PHPAPI void php_poll_register_backends(void) +{ + num_registered_backends = 0; + +#ifdef HAVE_EVENT_PORTS + /* Event Ports are preferred on Solaris */ + if (php_poll_backend_eventport_ops.is_available()) { + registered_backends[num_registered_backends++] = &php_poll_backend_eventport_ops; + } +#endif + +#ifdef HAVE_KQUEUE + if (php_poll_backend_kqueue_ops.is_available()) { + registered_backends[num_registered_backends++] = &php_poll_backend_kqueue_ops; + } +#endif + +#ifdef HAVE_EPOLL + if (php_poll_backend_epoll_ops.is_available()) { + registered_backends[num_registered_backends++] = &php_poll_backend_epoll_ops; + } +#endif + +#ifdef PHP_WIN32 + registered_backends[num_registered_backends++] = &php_poll_backend_wsapoll_ops; +#else + registered_backends[num_registered_backends++] = &php_poll_backend_poll_ops; +#endif +} + +/* Get backend operations */ +static const php_poll_backend_ops *php_poll_get_backend_ops(php_poll_backend_type backend) +{ + if (backend == PHP_POLL_BACKEND_AUTO) { + /* Return the first (best) available backend */ + return num_registered_backends > 0 ? registered_backends[0] : NULL; + } + + for (int i = 0; i < num_registered_backends; i++) { + if (registered_backends[i] && registered_backends[i]->type == backend) { + return registered_backends[i]; + } + } + + return NULL; +} + +/* Get backend operations by backend name */ +static const php_poll_backend_ops *php_poll_get_backend_ops_by_name(const char *backend_name) +{ + if (!backend_name) { + return NULL; + } + + for (int i = 0; i < num_registered_backends; i++) { + if (registered_backends[i] && strcmp(registered_backends[i]->name, backend_name) == 0) { + return registered_backends[i]; + } + } + + return NULL; +} + +PHPAPI bool php_poll_is_backend_available(php_poll_backend_type backend) +{ + if (backend == PHP_POLL_BACKEND_AUTO) { + return true; /* Auto is always available */ + } + + for (int i = 0; i < num_registered_backends; i++) { + if (registered_backends[i] && registered_backends[i]->type == backend) { + return registered_backends[i]->is_available(); + } + } + + return false; +} + +PHPAPI bool php_poll_backend_supports_edge_triggering(php_poll_backend_type backend) +{ + if (backend == PHP_POLL_BACKEND_AUTO) { + /* Check the first (best) available backend */ + if (num_registered_backends > 0 && registered_backends[0]) { + return registered_backends[0]->supports_et; + } + return false; + } + + for (int i = 0; i < num_registered_backends; i++) { + if (registered_backends[i] && registered_backends[i]->type == backend) { + return registered_backends[i]->supports_et; + } + } + + return false; +} + +static php_poll_ctx *php_poll_create_context(uint32_t flags) +{ + bool persistent = flags & PHP_POLL_FLAG_PERSISTENT; + php_poll_ctx *ctx = php_poll_calloc(1, sizeof(php_poll_ctx), persistent); + if (!ctx) { + return NULL; + } + ctx->persistent = persistent; + ctx->raw_events = (flags & PHP_POLL_FLAG_RAW_EVENTS) != 0; + + return ctx; +} + +/* Create new poll context */ +PHPAPI php_poll_ctx *php_poll_create(php_poll_backend_type preferred_backend, uint32_t flags) +{ + php_poll_ctx *ctx = php_poll_create_context(flags); + if (ctx == NULL) { + return NULL; + } + + /* Get backend operations */ + ctx->backend_ops = php_poll_get_backend_ops(preferred_backend); + if (!ctx->backend_ops) { + pefree(ctx, ctx->persistent); + return NULL; + } + ctx->backend_type = preferred_backend; + + return ctx; +} + +/* Create new poll context */ +PHPAPI php_poll_ctx *php_poll_create_by_name(const char *preferred_backend, uint32_t flags) +{ + if (!strcmp(preferred_backend, "auto")) { + return php_poll_create(PHP_POLL_BACKEND_AUTO, flags); + } + + php_poll_ctx *ctx = php_poll_create_context(flags); + if (ctx == NULL) { + return NULL; + } + + /* Get backend operations */ + ctx->backend_ops = php_poll_get_backend_ops_by_name(preferred_backend); + if (!ctx->backend_ops) { + pefree(ctx, ctx->persistent); + return NULL; + } + ctx->backend_type = ctx->backend_ops->type; + + return ctx; +} + +/* Set event capacity hint (optional optimization) */ +PHPAPI zend_result php_poll_set_max_events_hint(php_poll_ctx *ctx, int max_events) +{ + ZEND_ASSERT(ctx); + if (UNEXPECTED(max_events <= 0)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return FAILURE; + } + + if (UNEXPECTED(ctx->initialized)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return FAILURE; /* Cannot change after init */ + } + + ctx->max_events_hint = max_events; + return SUCCESS; +} + +/* Initialize poll context */ +PHPAPI zend_result php_poll_init(php_poll_ctx *ctx) +{ + if (UNEXPECTED(!ctx)) { + return FAILURE; + } + + if (UNEXPECTED(ctx->initialized)) { + return SUCCESS; + } + + /* Initialize backend - can use ctx->max_events_hint if helpful */ + if (EXPECTED(ctx->backend_ops->init(ctx) == SUCCESS)) { + ctx->initialized = true; + return SUCCESS; + } + + php_poll_set_current_errno_error(ctx); + return FAILURE; +} + +/* Destroy poll context */ +PHPAPI void php_poll_destroy(php_poll_ctx *ctx) +{ + if (!ctx) { + return; + } + + if (ctx->backend_ops && ctx->backend_ops->cleanup) { + ctx->backend_ops->cleanup(ctx); + } + + pefree(ctx, ctx->persistent); +} + +/* Add file descriptor */ +PHPAPI zend_result php_poll_add(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + ZEND_ASSERT(ctx); + if (UNEXPECTED(!ctx->initialized || fd < 0)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return FAILURE; + } + + /* Delegate to backend - it handles all validation and tracking */ + if (EXPECTED(ctx->backend_ops->add(ctx, fd, events, data) == SUCCESS)) { + return SUCCESS; + } + + return FAILURE; +} + +/* Modify file descriptor */ +PHPAPI zend_result php_poll_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *data) +{ + ZEND_ASSERT(ctx); + if (UNEXPECTED(!ctx->initialized || fd < 0)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return FAILURE; + } + + /* Delegate to backend - it handles validation */ + if (EXPECTED(ctx->backend_ops->modify(ctx, fd, events, data) == SUCCESS)) { + return SUCCESS; + } + + return FAILURE; +} + +/* Remove file descriptor */ +PHPAPI zend_result php_poll_remove(php_poll_ctx *ctx, int fd) +{ + ZEND_ASSERT(ctx); + if (UNEXPECTED(!ctx->initialized || fd < 0)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return FAILURE; + } + + /* Delegate to backend - it handles validation */ + if (EXPECTED(ctx->backend_ops->remove(ctx, fd) == SUCCESS)) { + return SUCCESS; + } + + return FAILURE; +} + +/* Wait for events */ +PHPAPI int php_poll_wait(php_poll_ctx *ctx, php_poll_event *events, int max_events, + const struct timespec *timeout) +{ + ZEND_ASSERT(ctx); + if (UNEXPECTED(!ctx->initialized || !events || max_events <= 0)) { + php_poll_set_error(ctx, PHP_POLL_ERR_INVALID); + return -1; + } + + /* Delegate to backend - it handles everything including ET simulation if needed */ + int nfds = ctx->backend_ops->wait(ctx, events, max_events, timeout); + + return nfds; +} + +/* Get backend name */ +PHPAPI const char *php_poll_backend_name(php_poll_ctx *ctx) +{ + return ctx && ctx->backend_ops ? ctx->backend_ops->name : "unknown"; +} + +/* Get backend type */ +PHPAPI php_poll_backend_type php_poll_get_backend_type(php_poll_ctx *ctx) +{ + return ctx && ctx->backend_ops ? ctx->backend_ops->type : PHP_POLL_BACKEND_AUTO; +} + +/* Check edge-triggering support */ +PHPAPI bool php_poll_supports_et(php_poll_ctx *ctx) +{ + return ctx && ctx->backend_ops && ctx->backend_ops->supports_et; +} + +/* Get suitable max_events for backend */ +PHPAPI int php_poll_get_suitable_max_events(php_poll_ctx *ctx) +{ + if (UNEXPECTED(!ctx || !ctx->backend_ops)) { + return -1; + } + + return ctx->backend_ops->get_suitable_max_events(ctx); +} + +/* Error retrieval */ +PHPAPI php_poll_error php_poll_get_error(php_poll_ctx *ctx) +{ + return ctx ? ctx->last_error : PHP_POLL_ERR_INVALID; +} + +/* Errno to php_poll_error mapping helper */ +php_poll_error php_poll_errno_to_error(int err) +{ + switch (err) { + case 0: + return PHP_POLL_ERR_NONE; + + case ENOMEM: + return PHP_POLL_ERR_NOMEM; + + case EINVAL: + case EBADF: + return PHP_POLL_ERR_INVALID; + + case EEXIST: + return PHP_POLL_ERR_EXISTS; + + case ENOENT: + return PHP_POLL_ERR_NOTFOUND; + +#ifdef ETIME + case ETIME: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif + return PHP_POLL_ERR_TIMEOUT; + + case EINTR: + return PHP_POLL_ERR_INTERRUPTED; + + case EACCES: +#ifdef EPERM + case EPERM: +#endif + return PHP_POLL_ERR_PERMISSION; + +#ifdef EMFILE + case EMFILE: +#endif +#ifdef ENFILE + case ENFILE: +#endif + return PHP_POLL_ERR_TOOBIG; + + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return PHP_POLL_ERR_AGAIN; + +#ifdef ENOSYS + case ENOSYS: +#endif +#if ENOTSUP + case ENOTSUP: +#endif +#if defined(EOPNOTSUPP) && EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: +#endif + return PHP_POLL_ERR_NOSUPPORT; + + default: + return PHP_POLL_ERR_SYSTEM; + } +} + +/* Get human-readable error description */ +PHPAPI const char *php_poll_error_string(php_poll_error error) +{ + switch (error) { + case PHP_POLL_ERR_NONE: + return "No error"; + case PHP_POLL_ERR_SYSTEM: + return "System error"; + case PHP_POLL_ERR_NOMEM: + return "Out of memory"; + case PHP_POLL_ERR_INVALID: + return "Invalid argument"; + case PHP_POLL_ERR_EXISTS: + return "File descriptor already exists"; + case PHP_POLL_ERR_NOTFOUND: + return "File descriptor not found"; + case PHP_POLL_ERR_TIMEOUT: + return "Operation timed out"; + case PHP_POLL_ERR_INTERRUPTED: + return "Operation interrupted"; + case PHP_POLL_ERR_PERMISSION: + return "Permission denied"; + case PHP_POLL_ERR_TOOBIG: + return "Too many open files"; + case PHP_POLL_ERR_AGAIN: + return "Resource temporarily unavailable"; + case PHP_POLL_ERR_NOSUPPORT: + return "Operation not supported"; + default: + return "Unknown error"; + } +} diff --git a/main/poll/poll_fd_table.c b/main/poll/poll_fd_table.c new file mode 100644 index 000000000000..1c76da79b7eb --- /dev/null +++ b/main/poll/poll_fd_table.c @@ -0,0 +1,114 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll_internal.h" + +php_poll_fd_table *php_poll_fd_table_init(int initial_capacity, bool persistent) +{ + php_poll_fd_table *table = php_poll_calloc(1, sizeof(php_poll_fd_table), persistent); + if (!table) { + return NULL; + } + + if (initial_capacity <= 0) { + initial_capacity = 64; + } + + _zend_hash_init(&table->entries_ht, initial_capacity, NULL, persistent); + table->persistent = persistent; + + return table; +} + +void php_poll_fd_table_cleanup(php_poll_fd_table *table) +{ + if (table) { + ZEND_HASH_FOREACH_VAL(&table->entries_ht, zval *zv) + { + php_poll_fd_entry *entry = Z_PTR_P(zv); + pefree(entry, table->persistent); + } + ZEND_HASH_FOREACH_END(); + + zend_hash_destroy(&table->entries_ht); + pefree(table, table->persistent); + } +} + +php_poll_fd_entry *php_poll_fd_table_find(php_poll_fd_table *table, int fd) +{ + zval *zv = zend_hash_index_find(&table->entries_ht, (zend_ulong) fd); + return zv ? Z_PTR_P(zv) : NULL; +} + +php_poll_fd_entry *php_poll_fd_table_get_new(php_poll_fd_table *table, int fd) +{ + php_poll_fd_entry *entry = php_poll_calloc(1, sizeof(php_poll_fd_entry), table->persistent); + if (!entry) { + return NULL; + } + + entry->fd = fd; + entry->active = true; + entry->events = 0; + entry->data = NULL; + entry->last_revents = 0; + + zval zv; + ZVAL_PTR(&zv, entry); + if (!zend_hash_index_add(&table->entries_ht, (zend_ulong) fd, &zv)) { + pefree(entry, table->persistent); + return NULL; + } + + return entry; +} + +php_poll_fd_entry *php_poll_fd_table_get(php_poll_fd_table *table, int fd) +{ + php_poll_fd_entry *entry = php_poll_fd_table_find(table, fd); + if (entry) { + return entry; + } + + return php_poll_fd_table_get_new(table, fd); +} + +bool php_poll_fd_table_remove(php_poll_fd_table *table, int fd) +{ + zval *zv = zend_hash_index_find(&table->entries_ht, (zend_ulong) fd); + if (zv == NULL) { + return false; + } + php_poll_fd_entry *entry = Z_PTR_P(zv); + pefree(entry, table->persistent); + return zend_hash_index_del(&table->entries_ht, (zend_ulong) fd) == SUCCESS; +} + +/* Helper function for backends that need to iterate over all entries */ +typedef bool (*php_poll_fd_iterator_func_t)(int fd, php_poll_fd_entry *entry, void *user_data); + +/* Iterate over all active FD entries */ +void php_poll_fd_table_foreach( + php_poll_fd_table *table, php_poll_fd_iterator_func_t callback, void *user_data) +{ + ZEND_HASH_FOREACH_NUM_KEY_VAL(&table->entries_ht, zend_ulong fd, zval *zv) + { + php_poll_fd_entry *entry = Z_PTR_P(zv); + if (entry->active && !callback((int) fd, entry, user_data)) { + break; /* Callback returned false, stop iteration */ + } + } + ZEND_HASH_FOREACH_END(); +} diff --git a/main/poll/poll_handle.c b/main/poll/poll_handle.c new file mode 100644 index 000000000000..228d44e1e420 --- /dev/null +++ b/main/poll/poll_handle.c @@ -0,0 +1,93 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ +*/ + +#include "php_poll.h" +#include "zend_exceptions.h" + +/* Default get_fd implementation - calls PHP method */ +static php_socket_t php_poll_handle_default_get_fd(php_poll_handle_object *handle) +{ + zval retval; + + /* Grab getFileDescriptor() method pointer which is stored in lowercase in the function table */ + zend_function *method = zend_hash_str_find_ptr_lc(&handle->std.ce->function_table, ZEND_STRL("getfiledescriptor")); + ZEND_ASSERT(method && "no default method???"); + + /* Call getFileDescriptor() method */ + zend_call_known_function(method, &handle->std, handle->std.ce, &retval, 0, NULL, NULL); + + /* No need to deref the return value as the class is final and thus the method cannot be changed to return by-ref */ + if (EXPECTED(Z_TYPE(retval) == IS_LONG)) { + php_socket_t fd = Z_LVAL(retval) < 0 ? SOCK_ERR : (php_socket_t) Z_LVAL(retval); + /* No need to clean the retval as we know it is an integer, and thus it's just on the stack */ + return fd; + } + + zval_ptr_dtor(&retval); + return SOCK_ERR; /* Invalid socket */ +} + +/* Default is_valid implementation - assume valid if we can get FD */ +static int php_poll_handle_default_is_valid(php_poll_handle_object *handle) +{ + return php_poll_handle_get_fd(handle) != SOCK_ERR; +} + +/* Default cleanup */ +static void php_poll_handle_default_cleanup(php_poll_handle_object *handle) +{ + /* Base implementation has no cleanup */ +} + +/* Default operations that call PHP userspace methods */ +php_poll_handle_ops php_poll_handle_default_ops = { .get_fd = php_poll_handle_default_get_fd, + .is_valid = php_poll_handle_default_is_valid, + .cleanup = php_poll_handle_default_cleanup }; + +/* Allocate a new poll handle object */ +PHPAPI php_poll_handle_object *php_poll_handle_object_create( + size_t obj_size, zend_class_entry *ce, php_poll_handle_ops *ops) +{ + php_poll_handle_object *intern = zend_object_alloc(obj_size, ce); + + zend_object_std_init(&intern->std, ce); + object_properties_init(&intern->std, ce); + + intern->ops = ops ? ops : &php_poll_handle_default_ops; + intern->handle_data = NULL; + + return intern; +} + +/* Free poll handle object */ +PHPAPI void php_poll_handle_object_free(zend_object *obj) +{ + php_poll_handle_object *intern = PHP_POLL_HANDLE_OBJ_FROM_ZOBJ(obj); + + if (intern->ops && intern->ops->cleanup) { + intern->ops->cleanup(intern); + } + + zend_object_std_dtor(&intern->std); +} + +/* Get file descriptor from handle using ops */ +PHPAPI php_socket_t php_poll_handle_get_fd(php_poll_handle_object *handle) +{ + if (!handle || !handle->ops || !handle->ops->get_fd) { + return SOCK_ERR; + } + + return handle->ops->get_fd(handle); +} diff --git a/main/reentrancy.c b/main/reentrancy.c index bd050ff9ac68..a611841a397a 100644 --- a/main/reentrancy.c +++ b/main/reentrancy.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/main/rfc1867.c b/main/rfc1867.c index f6ffb6fabc7f..e40a1a9e3008 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jani Taskinen | @@ -392,7 +390,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) } /* space in the beginning means same header */ - if (!isspace(line[0])) { + if (!isspace((unsigned char)line[0])) { value = strchr(line, ':'); } @@ -408,7 +406,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) } *value = '\0'; - do { value++; } while (isspace(*value)); + do { value++; } while (isspace((unsigned char)*value)); key = estrdup(line); smart_string_appends(&buf_value, value); @@ -505,7 +503,7 @@ static char *substring_conf(char *start, int len, char quote) static char *php_ap_getword_conf(const zend_encoding *encoding, char *str) { - while (*str && isspace(*str)) { + while (*str && isspace((unsigned char)*str)) { ++str; } @@ -521,7 +519,7 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str) } else { char *strend = str; - while (*strend && !isspace(*strend)) { + while (*strend && !isspace((unsigned char)*strend)) { ++strend; } return substring_conf(str, strend - str, 0); @@ -665,8 +663,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) zend_llist header; void *event_extra_data = NULL; unsigned int llen = 0; - zend_long upload_cnt = REQUEST_PARSE_BODY_OPTION_GET(max_file_uploads, INI_INT("max_file_uploads")); - zend_long body_parts_cnt = REQUEST_PARSE_BODY_OPTION_GET(max_multipart_body_parts, INI_INT("max_multipart_body_parts")); + zend_long upload_cnt = REQUEST_PARSE_BODY_OPTION_GET(max_file_uploads, zend_ini_long_literal("max_file_uploads")); + zend_long body_parts_cnt = REQUEST_PARSE_BODY_OPTION_GET(max_multipart_body_parts, zend_ini_long_literal("max_multipart_body_parts")); zend_long post_max_size = REQUEST_PARSE_BODY_OPTION_GET(post_max_size, SG(post_max_size)); zend_long max_input_vars = REQUEST_PARSE_BODY_OPTION_GET(max_input_vars, PG(max_input_vars)); zend_long upload_max_filesize = REQUEST_PARSE_BODY_OPTION_GET(upload_max_filesize, PG(upload_max_filesize)); @@ -797,7 +795,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) goto fileupload_done; } - while (isspace(*cd)) { + while (isspace((unsigned char)*cd)) { ++cd; } @@ -805,7 +803,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) { char *key = NULL, *word = pair; - while (isspace(*cd)) { + while (isspace((unsigned char)*cd)) { ++cd; } diff --git a/main/rfc1867.h b/main/rfc1867.h index bb690f15aa3e..cbe39c7b4f62 100644 --- a/main/rfc1867.h +++ b/main/rfc1867.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/safe_bcmp.c b/main/safe_bcmp.c index f52dbee5bafe..2a7d3b55945b 100644 --- a/main/safe_bcmp.c +++ b/main/safe_bcmp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: David Carlier | +----------------------------------------------------------------------+ diff --git a/main/snprintf.c b/main/snprintf.c index e9938c79659f..73c981a1cee7 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -288,7 +284,7 @@ PHPAPI char * php_conv_fp(char format, double num, /* * Check for Infinity and NaN */ - if (isalpha((int)*p)) { + if (isalpha((unsigned char)*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = false; @@ -435,11 +431,11 @@ typedef struct buf_area buffy; #define NUM( c ) ( c - '0' ) #define STR_TO_DEC( str, num ) \ - num = NUM( *str++ ) ; \ - while ( isdigit((int)*str ) ) \ + num = NUM( *(str)++ ) ; \ + while ( isdigit((unsigned char)*(str) ) ) \ { \ num *= 10 ; \ - num += NUM( *str++ ) ; \ + num += NUM( *(str)++ ) ; \ } /* @@ -533,7 +529,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{ /* * Try to avoid checking for flags, width or precision */ - if (isascii((int)*fmt) && !islower((int)*fmt)) { + if (isascii((unsigned char)*fmt) && !islower((unsigned char)*fmt)) { /* * Recognize flags: -, #, BLANK, + */ @@ -555,7 +551,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{ /* * Check if a width was specified */ - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = true; } else if (*fmt == '*') { @@ -575,7 +571,7 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{ if (*fmt == '.') { adjust_precision = true; fmt++; - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); diff --git a/main/snprintf.h b/main/snprintf.h index d61ee5e39a69..b123810a77c0 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | | Marcus Boerger | diff --git a/main/spprintf.c b/main/spprintf.c index 0dd7f1552e1c..6553853d8104 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -148,12 +146,12 @@ #define NUM(c) (c - '0') #define STR_TO_DEC(str, num) do { \ - num = NUM(*str++); \ - while (isdigit((int)*str)) { \ + num = NUM(*(str)++); \ + while (isdigit((unsigned char)*(str))) {\ num *= 10; \ - num += NUM(*str++); \ + num += NUM(*(str)++); \ if (num >= INT_MAX / 10) { \ - while (isdigit((int)*str++)); \ + while (isdigit((unsigned char)*(str)++)); \ break; \ } \ } \ @@ -233,7 +231,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_ /* * Try to avoid checking for flags, width or precision */ - if (isascii((int)*fmt) && !islower((int)*fmt)) { + if (isascii((unsigned char)*fmt) && !islower((unsigned char)*fmt)) { /* * Recognize flags: -, #, BLANK, + */ @@ -255,7 +253,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_ /* * Check if a width was specified */ - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = true; } else if (*fmt == '*') { @@ -275,7 +273,7 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_ if (*fmt == '.') { adjust_precision = true; fmt++; - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); diff --git a/main/spprintf.h b/main/spprintf.h index 4da224845b3b..c1d2377d25a5 100644 --- a/main/spprintf.h +++ b/main/spprintf.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/main/streams/cast.c b/main/streams/cast.c index 4dc8ddb5f6a3..863afe4ed4b9 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | +----------------------------------------------------------------------+ @@ -189,7 +187,6 @@ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *resul result[res_curs] = '\0'; } /* }}} */ - /* {{{ php_stream_cast */ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) { @@ -197,7 +194,7 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, castas &= ~PHP_STREAM_CAST_MASK; /* synchronize our buffer (if possible) */ - if (ret && castas != PHP_STREAM_AS_FD_FOR_SELECT) { + if (ret && castas != PHP_STREAM_AS_FD_FOR_SELECT && castas != PHP_STREAM_AS_FD_FOR_COPY) { php_stream_flush(stream); if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { zend_off_t dummy; @@ -207,6 +204,16 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, } } + if (castas == PHP_STREAM_AS_FD_FOR_COPY) { + if (php_stream_is_filtered(stream)) { + return FAILURE; + } + if (stream->ops->cast && stream->ops->cast(stream, castas, ret) == SUCCESS) { + return SUCCESS; + } + return FAILURE; + } + /* filtered streams can only be cast as stdio, and only when fopencookie is present */ if (castas == PHP_STREAM_AS_STDIO) { @@ -259,7 +266,7 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, b) no memory -> lets bail */ - php_error_docref(NULL, E_ERROR, "fopencookie failed"); + php_stream_fatal(stream, CastFailed, "fopencookie failed"); return FAILURE; #endif @@ -299,7 +306,8 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, if (php_stream_is_filtered(stream) && castas != PHP_STREAM_AS_FD_FOR_SELECT) { if (show_err) { - php_error_docref(NULL, E_WARNING, "Cannot cast a filtered stream on this system"); + php_stream_warn(stream, CastNotSupported, + "Cannot cast a filtered stream on this system"); } return FAILURE; } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret) == SUCCESS) { @@ -315,7 +323,8 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, "select()able descriptor" }; - php_error_docref(NULL, E_WARNING, "Cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); + php_stream_warn(stream, CastNotSupported, + "Cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); } return FAILURE; @@ -330,7 +339,9 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, * will be accessing the stream. Emit a warning so that the end-user will * know that they should try something else */ - php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " bytes of buffered data lost during stream conversion!", (zend_long)(stream->writepos - stream->readpos)); + php_stream_warn_nt(stream, BufferedDataLost, + ZEND_LONG_FMT " bytes of buffered data lost during stream conversion!", + (zend_long)(stream->writepos - stream->readpos)); } if (castas == PHP_STREAM_AS_STDIO && ret) { diff --git a/main/streams/filter.c b/main/streams/filter.c index d0c1fdc8e788..e53c4fa14ba0 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | +----------------------------------------------------------------------+ @@ -216,7 +214,7 @@ PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket) * match. If that fails, we try "convert.charset.*", then "convert.*" * This means that we don't need to clog up the hashtable with a zillion * charsets (for example) but still be able to provide them all as filters */ -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, bool persistent) { HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash); const php_stream_filter_factory *factory = NULL; @@ -260,7 +258,9 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval return filter; } -PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, void *abstract, uint8_t persistent STREAMS_DC) +PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, + void *abstract, bool persistent, php_stream_filter_seekable_t read_seekable, + php_stream_filter_seekable_t write_seekable STREAMS_DC) { php_stream_filter *filter; @@ -268,12 +268,59 @@ PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops * memset(filter, 0, sizeof(php_stream_filter)); filter->fops = fops; + filter->read_seekable = read_seekable; + filter->write_seekable = write_seekable; Z_PTR(filter->abstract) = abstract; filter->is_persistent = persistent; return filter; } +PHPAPI zend_result php_stream_filter_parse_write_seek_mode( + const zval *filterparams, + php_stream_filter_seekable_t *write_seekable) +{ + *write_seekable = PSFS_SEEKABLE_ALWAYS; + + if (filterparams == NULL) { + return SUCCESS; + } + if (Z_TYPE_P(filterparams) != IS_ARRAY) { + return SUCCESS; + } + + const zval *write_seek_mode = zend_hash_str_find(Z_ARR_P(filterparams), ZEND_STRL("write_seek_mode")); + if (write_seek_mode == NULL) { + return SUCCESS; + } + + zend_string *tmp_str; + const zend_string *str = zval_get_tmp_string(write_seek_mode, &tmp_str); + zend_result result = SUCCESS; + + if (zend_string_equals_literal(str, "preserve")) { + *write_seekable = PSFS_SEEKABLE_ALWAYS; + } else if (zend_string_equals_literal(str, "reset")) { + *write_seekable = PSFS_SEEKABLE_START; + } else if (zend_string_equals_literal(str, "strict")) { + *write_seekable = PSFS_SEEKABLE_NEVER; + } else { + php_error_docref(NULL, E_WARNING, + "\"write_seek_mode\" filter parameter must be one of " + "\"preserve\", \"reset\", or \"strict\""); + result = FAILURE; + } + + zend_tmp_string_release(tmp_str); + return result; +} + +PHPAPI int php_stream_filter_get_chain_type(php_stream *stream, php_stream_filter *filter) +{ + return filter->chain == &stream->readfilters ? + PHP_STREAM_FILTER_READ : PHP_STREAM_FILTER_WRITE; +} + PHPAPI void php_stream_filter_free(php_stream_filter *filter) { if (filter->fops->dtor) @@ -343,7 +390,8 @@ PHPAPI zend_result php_stream_filter_append_ex(php_stream_filter_chain *chain, p php_stream_bucket_unlink(bucket); php_stream_bucket_delref(bucket); } - php_error_docref(NULL, E_WARNING, "Filter failed to process pre-buffered data"); + php_stream_warn(stream, FilterFailed, + "Filter failed to process pre-buffered data"); return FAILURE; case PSFS_FEED_ME: /* We don't actually need data yet, diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index fb056ce889fa..c7f1145de200 100644 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/main/streams/memory.c b/main/streams/memory.c index 9cb94542df6f..e76598ed0f46 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -128,7 +126,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe switch(whence) { case SEEK_CUR: if (offset < 0) { - if (ms->fpos < (size_t)(-offset)) { + if (ms->fpos < -(size_t)offset) { ms->fpos = 0; *newoffs = -1; return -1; @@ -165,7 +163,7 @@ static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whe stream->eof = 0; stream->fatal_error = 0; return 0; - } else if (ZSTR_LEN(ms->data) < (size_t)(-offset)) { + } else if (ZSTR_LEN(ms->data) < -(size_t)offset) { ms->fpos = 0; *newoffs = -1; return -1; @@ -364,7 +362,9 @@ static ssize_t php_stream_temp_write(php_stream *stream, const char *buf, size_t zend_string *membuf = php_stream_memory_get_buffer(ts->innerstream); php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL); if (file == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to create temporary file, Check permissions in temporary files directory."); + php_stream_wrapper_warn(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + PermissionDenied, + "Unable to create temporary file, Check permissions in temporary files directory."); return 0; } php_stream_write(file, ZSTR_VAL(membuf), ZSTR_LEN(membuf)); @@ -471,6 +471,11 @@ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret) if (!ts->innerstream) { return FAILURE; } + if (castas == PHP_STREAM_AS_FD_FOR_COPY) { + /* the fd would come from the inner stream whose buffer state and + * position the copy fast path cannot see, so use the stream fallback */ + return FAILURE; + } if (php_stream_is(ts->innerstream, PHP_STREAM_IS_STDIO)) { return php_stream_cast(ts->innerstream, castas, ret, 0); } @@ -491,7 +496,8 @@ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret) file = php_stream_fopen_tmpfile(); if (file == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to create temporary file."); + php_stream_wrapper_warn(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + PermissionDenied, "Unable to create temporary file."); return FAILURE; } @@ -641,7 +647,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con } if ((comma = (char *) memchr(path, ',', dlen)) == NULL) { - php_stream_wrapper_log_error(wrapper, options, "rfc2397: no comma in URL"); + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidUrl, "rfc2397: no comma in URL"); return NULL; } @@ -653,7 +660,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con sep = memchr(path, '/', mlen); if (!semi && !sep) { - php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal media type"); + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidUrl, "rfc2397: illegal media type"); return NULL; } @@ -668,7 +676,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con path += plen; } else if (semi != path || mlen != sizeof(";base64")-1 || memcmp(path, ";base64", sizeof(";base64")-1)) { /* must be error since parameters are only allowed after mediatype */ zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal media type"); + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidUrl, "rfc2397: illegal media type"); return NULL; } /* get parameters and potentially ';base64' */ @@ -681,7 +690,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con if (mlen != sizeof("base64")-1 || memcmp(path, "base64", sizeof("base64")-1)) { /* must be error since parameters are only allowed after mediatype and we have no '=' sign */ zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal parameter"); + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidParam, "rfc2397: illegal parameter"); return NULL; } base64 = 1; @@ -701,7 +711,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con } if (mlen) { zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal URL"); + php_stream_wrapper_log_warn(wrapper, context, options, + InvalidUrl, "rfc2397: illegal URL"); return NULL; } } else { @@ -717,7 +728,8 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con base64_comma = php_base64_decode_ex((const unsigned char *)comma, dlen, 1); if (!base64_comma) { zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options, "rfc2397: unable to decode"); + php_stream_wrapper_log_warn(wrapper, context, options, + DecodingFailed, "rfc2397: unable to decode"); return NULL; } comma = ZSTR_VAL(base64_comma); diff --git a/main/streams/mmap.c b/main/streams/mmap.c index 6ed9c057969b..e3831636bcd4 100644 --- a/main/streams/mmap.c +++ b/main/streams/mmap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index cc001cced154..9373182f7c2e 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/main/streams/php_stream_errors.h b/main/streams/php_stream_errors.h new file mode 100644 index 000000000000..67112c8932b7 --- /dev/null +++ b/main/streams/php_stream_errors.h @@ -0,0 +1,201 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ + */ + +#ifndef PHP_STREAM_ERRORS_H +#define PHP_STREAM_ERRORS_H + +#include "php.h" +#include "php_streams.h" +#include "stream_errors_decl.h" + +BEGIN_EXTERN_C() + +/* Error mode context options (internal C constants) */ +#define PHP_STREAM_ERROR_MODE_ERROR 0 +#define PHP_STREAM_ERROR_MODE_EXCEPTION 1 +#define PHP_STREAM_ERROR_MODE_SILENT 2 + +/* Error store context options (internal C constants) */ +#define PHP_STREAM_ERROR_STORE_AUTO 0 +#define PHP_STREAM_ERROR_STORE_NONE 1 +#define PHP_STREAM_ERROR_STORE_NON_TERM 2 +#define PHP_STREAM_ERROR_STORE_TERMINAL 3 +#define PHP_STREAM_ERROR_STORE_ALL 4 + +/* Maximum operation nesting depth */ +#define PHP_STREAM_ERROR_MAX_DEPTH 1000 +/* Operations pool size to prevent extra allocations */ +#define PHP_STREAM_ERROR_OPERATION_POOL_SIZE 8 + +/* Shorthand for error code enum values */ +#define PHP_STREAM_EC(name) ZEND_ENUM_StreamErrorCode_##name + +/* Error code range boundaries (case_id based, ranges are [start, end)) */ +#define STREAM_EC_IO_START PHP_STREAM_EC(ReadFailed) +#define STREAM_EC_IO_END PHP_STREAM_EC(Disabled) +#define STREAM_EC_FS_START PHP_STREAM_EC(Disabled) +#define STREAM_EC_FS_END PHP_STREAM_EC(NotImplemented) +#define STREAM_EC_WRAPPER_START PHP_STREAM_EC(NotImplemented) +#define STREAM_EC_WRAPPER_END PHP_STREAM_EC(FilterNotFound) +#define STREAM_EC_FILTER_START PHP_STREAM_EC(FilterNotFound) +#define STREAM_EC_FILTER_END PHP_STREAM_EC(CastFailed) +#define STREAM_EC_CAST_START PHP_STREAM_EC(CastFailed) +#define STREAM_EC_CAST_END PHP_STREAM_EC(NetworkSendFailed) +#define STREAM_EC_NETWORK_START PHP_STREAM_EC(NetworkSendFailed) +#define STREAM_EC_NETWORK_END PHP_STREAM_EC(ArchivingFailed) +#define STREAM_EC_ENCODING_START PHP_STREAM_EC(ArchivingFailed) +#define STREAM_EC_ENCODING_END PHP_STREAM_EC(AllocationFailed) +#define STREAM_EC_RESOURCE_START PHP_STREAM_EC(AllocationFailed) +#define STREAM_EC_RESOURCE_END PHP_STREAM_EC(LockFailed) +#define STREAM_EC_LOCK_START PHP_STREAM_EC(LockFailed) +#define STREAM_EC_LOCK_END PHP_STREAM_EC(UserspaceNotImplemented) +#define STREAM_EC_USERSPACE_START PHP_STREAM_EC(UserspaceNotImplemented) +#define STREAM_EC_USERSPACE_END (PHP_STREAM_EC(UserspaceCallFailed) + 1) + +/* Wrapper name for PHP errors */ +#define PHP_STREAM_ERROR_WRAPPER_DEFAULT_NAME ":na" +#define PHP_STREAM_ERROR_WRAPPER_NAME(_wrapper) \ + (_wrapper ? _wrapper->wops->label : PHP_STREAM_ERROR_WRAPPER_DEFAULT_NAME) + +/* Error entry in chain (internal linked list) */ +typedef struct _php_stream_error_entry { + zend_string *message; + zend_enum_StreamErrorCode code; + char *wrapper_name; + char *docref; + int severity; + bool terminating; + struct _php_stream_error_entry *next; +} php_stream_error_entry; + +/* Active error operation */ +typedef struct _php_stream_error_operation { + php_stream_error_entry *first_error; + php_stream_error_entry *last_error; + uint32_t error_count; +} php_stream_error_operation; + +/* Stored completed operation */ +typedef struct _php_stream_stored_error { + php_stream_error_entry *first_error; + uint32_t error_count; + struct _php_stream_stored_error *next; +} php_stream_stored_error; + +typedef struct { + php_stream_error_operation *current_operation; + uint32_t operation_depth; + php_stream_stored_error *stored_errors; + uint32_t stored_count; + php_stream_error_operation operation_pool[PHP_STREAM_ERROR_OPERATION_POOL_SIZE]; + php_stream_error_operation *overflow_operations; + uint32_t overflow_capacity; +} php_stream_error_state; + +/* Error operation management */ +PHPAPI php_stream_error_operation *php_stream_error_operation_begin(void); +PHPAPI void php_stream_error_operation_end(php_stream_context *context); +PHPAPI void php_stream_error_operation_end_for_stream(php_stream *stream); +PHPAPI void php_stream_error_operation_abort(void); + +/* State cleanup function */ +PHPAPI void php_stream_error_state_cleanup(void); + +/* Retrieve last stored errors as array of StreamError objects */ +PHPAPI void php_stream_error_get_last(zval *return_value); + +/* Clear all stored errors */ +PHPAPI void php_stream_error_clear_stored(void); + +/* Wrapper error reporting functions */ +PHPAPI void php_stream_wrapper_error_with_name(const char *wrapper_name, + php_stream_context *context, const char *docref, int options, int severity, + bool terminating, zend_enum_StreamErrorCode code, const char *fmt, ...) + ZEND_ATTRIBUTE_FORMAT(printf, 8, 9); + +PHPAPI void php_stream_wrapper_error(php_stream_wrapper *wrapper, php_stream_context *context, + const char *docref, int options, int severity, bool terminating, + zend_enum_StreamErrorCode code, const char *fmt, ...) + ZEND_ATTRIBUTE_FORMAT(printf, 8, 9); + +PHPAPI void php_stream_error(php_stream *stream, const char *docref, int severity, + bool terminating, zend_enum_StreamErrorCode code, const char *fmt, ...) + ZEND_ATTRIBUTE_FORMAT(printf, 6, 7); + +/* Legacy wrapper error log functions */ +PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, + php_stream_context *context, int options, int severity, bool terminating, + zend_enum_StreamErrorCode code, const char *fmt, ...) + ZEND_ATTRIBUTE_FORMAT(printf, 7, 8); + +PHPAPI void php_stream_display_wrapper_name_errors(const char *wrapper_name, + php_stream_context *context, zend_enum_StreamErrorCode code, + const char *caption); + +PHPAPI void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, + php_stream_context *context, zend_enum_StreamErrorCode code, + const char *caption); + +PHPAPI void php_stream_tidy_wrapper_name_error_log(const char *wrapper_name); +PHPAPI void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper); + +/* Convenience macros - code argument is the bare case name (e.g. RenameFailed) */ +#define php_stream_wrapper_warn(wrapper, context, options, code, ...) \ + php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, true, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_wrapper_warn_name(wrapper_name, context, options, code, ...) \ + php_stream_wrapper_error_with_name( \ + wrapper_name, context, NULL, options, E_WARNING, true, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_wrapper_warn_nt(wrapper, context, options, code, ...) \ + php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, false, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_wrapper_notice(wrapper, context, options, code, ...) \ + php_stream_wrapper_error(wrapper, context, NULL, options, E_NOTICE, false, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_warn(stream, code, ...) \ + php_stream_error(stream, NULL, E_WARNING, true, PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_warn_nt(stream, code, ...) \ + php_stream_error(stream, NULL, E_WARNING, false, PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_warn_docref(stream, docref, code, ...) \ + php_stream_error(stream, docref, E_WARNING, true, PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_notice(stream, code, ...) \ + php_stream_error(stream, NULL, E_NOTICE, false, PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_fatal(stream, code, ...) \ + php_stream_error(stream, NULL, E_ERROR, true, PHP_STREAM_EC(code), __VA_ARGS__) + +/* Legacy log variants */ +#define php_stream_wrapper_log_warn(wrapper, context, options, code, ...) \ + php_stream_wrapper_log_error(wrapper, context, options, E_WARNING, true, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_wrapper_log_warn_nt(wrapper, context, options, code, ...) \ + php_stream_wrapper_log_error(wrapper, context, options, E_WARNING, false, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +#define php_stream_wrapper_log_notice(wrapper, context, options, code, ...) \ + php_stream_wrapper_log_error(wrapper, context, options, E_NOTICE, false, \ + PHP_STREAM_EC(code), __VA_ARGS__) + +END_EXTERN_C() + +#endif /* PHP_STREAM_ERRORS_H */ diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index e224b85b2d9a..20df33897799 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | With suggestions from: | @@ -61,6 +59,13 @@ typedef enum { PSFS_PASS_ON /* filter generated output buckets; pass them on to next in chain */ } php_stream_filter_status_t; +typedef enum { + PSFS_SEEKABLE_NEVER, /* seeking filter never possible */ + PSFS_SEEKABLE_START, /* seeking possible only to start (position 0) */ + PSFS_SEEKABLE_CHECK, /* seeking possible but it is always checked if callback function set */ + PSFS_SEEKABLE_ALWAYS, /* seeking is always possible */ +} php_stream_filter_seekable_t; + /* Buckets API. */ BEGIN_EXTERN_C() PHPAPI php_stream_bucket *php_stream_bucket_new(const php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent); @@ -88,6 +93,13 @@ typedef struct _php_stream_filter_ops { int flags ); + zend_result (*seek)( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ); + void (*dtor)(php_stream_filter *thisfilter); const char *label; @@ -106,7 +118,9 @@ struct _php_stream_filter { zval abstract; /* for use by filter implementation */ php_stream_filter *next; php_stream_filter *prev; - int is_persistent; + php_stream_filter_seekable_t read_seekable; + php_stream_filter_seekable_t write_seekable; + bool is_persistent; /* link into stream and chain */ php_stream_filter_chain *chain; @@ -127,10 +141,18 @@ PHPAPI zend_result php_stream_filter_append_ex(php_stream_filter_chain *chain, p PHPAPI zend_result _php_stream_filter_flush(php_stream_filter *filter, bool finish); PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, bool call_dtor); PHPAPI void php_stream_filter_free(php_stream_filter *filter); -PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, void *abstract, uint8_t persistent STREAMS_DC); +PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, + void *abstract, bool persistent, php_stream_filter_seekable_t read_seekable, + php_stream_filter_seekable_t write_seekable STREAMS_DC); +PHPAPI zend_result php_stream_filter_parse_write_seek_mode(const zval *filterparams, + php_stream_filter_seekable_t *write_seekable); +PHPAPI int php_stream_filter_get_chain_type(php_stream *stream, php_stream_filter *filter); + END_EXTERN_C() -#define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC) -#define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC) +#define php_stream_filter_alloc(fops, thisptr, persistent, rseek, wseek) \ + _php_stream_filter_alloc((fops), (thisptr), (persistent), (rseek), (wseek) STREAMS_CC) +#define php_stream_filter_alloc_rel(fops, thisptr, persistent, rseek, wseek) \ + _php_stream_filter_alloc((fops), (thisptr), (persistent), (rseek), (wseek) STREAMS_REL_CC) #define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter)) #define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter)) #define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish)) @@ -138,12 +160,12 @@ END_EXTERN_C() #define php_stream_is_filtered(stream) ((stream)->readfilters.head || (stream)->writefilters.head) typedef struct _php_stream_filter_factory { - php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, uint8_t persistent); + php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, bool persistent); } php_stream_filter_factory; BEGIN_EXTERN_C() PHPAPI zend_result php_stream_filter_register_factory(const char *filterpattern, const php_stream_filter_factory *factory); PHPAPI zend_result php_stream_filter_unregister_factory(const char *filterpattern); PHPAPI zend_result php_stream_filter_register_factory_volatile(zend_string *filterpattern, const php_stream_filter_factory *factory); -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent); +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, bool persistent); END_EXTERN_C() diff --git a/main/streams/php_stream_glob_wrapper.h b/main/streams/php_stream_glob_wrapper.h index 04de00a593dd..c9c7fdcf2463 100644 --- a/main/streams/php_stream_glob_wrapper.h +++ b/main/streams/php_stream_glob_wrapper.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/main/streams/php_stream_mmap.h b/main/streams/php_stream_mmap.h index d477aa79481e..0f85e0269f47 100644 --- a/main/streams/php_stream_mmap.h +++ b/main/streams/php_stream_mmap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/main/streams/php_stream_plain_wrapper.h b/main/streams/php_stream_plain_wrapper.h index ce1a6e3876d1..aa74859c11e5 100644 --- a/main/streams/php_stream_plain_wrapper.h +++ b/main/streams/php_stream_plain_wrapper.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -26,9 +24,6 @@ BEGIN_EXTERN_C() PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zend_string **opened_path, int options STREAMS_DC); #define php_stream_fopen(filename, mode, opened) _php_stream_fopen((filename), (mode), (opened), 0 STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path, int options STREAMS_DC); -#define php_stream_fopen_with_path(filename, mode, path, opened) _php_stream_fopen_with_path((filename), (mode), (path), (opened), 0 STREAMS_CC) - PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC); #define php_stream_fopen_from_file(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_CC) diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h index 96675af6daea..1ee6a840cfd1 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -31,8 +29,8 @@ typedef php_stream *(php_stream_transport_factory_func)(const char *proto, size_ typedef php_stream_transport_factory_func *php_stream_transport_factory; BEGIN_EXTERN_C() -PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory); -PHPAPI int php_stream_xport_unregister(const char *protocol); +PHPAPI void php_stream_xport_register(const char *protocol, php_stream_transport_factory factory); +PHPAPI zend_result php_stream_xport_unregister(const char *protocol); #define STREAM_XPORT_CLIENT 0 #define STREAM_XPORT_SERVER 1 @@ -188,11 +186,17 @@ typedef enum { STREAM_CRYPTO_METHOD_ANY_SERVER = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)) } php_stream_xport_crypt_method_t; +/* Flags for crypto status */ +#define STREAM_CRYPTO_STATUS_NONE 0 +#define STREAM_CRYPTO_STATUS_WANT_READ 1 +#define STREAM_CRYPTO_STATUS_WANT_WRITE 2 + /* These functions provide crypto support on the underlying transport */ BEGIN_EXTERN_C() PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream); PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate); +PHPAPI int php_stream_xport_crypto_get_status(php_stream *stream); END_EXTERN_C() typedef struct _php_stream_xport_crypto_param { @@ -206,7 +210,8 @@ typedef struct _php_stream_xport_crypto_param { } outputs; enum { STREAM_XPORT_CRYPTO_OP_SETUP, - STREAM_XPORT_CRYPTO_OP_ENABLE + STREAM_XPORT_CRYPTO_OP_ENABLE, + STREAM_XPORT_CRYPTO_OP_GET_STATUS } op; } php_stream_xport_crypto_param; diff --git a/main/streams/php_stream_userspace.h b/main/streams/php_stream_userspace.h index 18e0f4028f2c..5b82a88d41a6 100644 --- a/main/streams/php_stream_userspace.h +++ b/main/streams/php_stream_userspace.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/main/streams/php_streams_int.h b/main/streams/php_streams_int.h index 7580088fba31..ceb0dc508a39 100644 --- a/main/streams/php_streams_int.h +++ b/main/streams/php_streams_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -62,3 +60,7 @@ * any other function that expects standard modes and you allow non-standard * ones. result should be a char[5]. */ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *result); + +/* Escapes NUL and backslash bytes so a host containing them cannot truncate or + * collide the persistent stream hash key. */ +zend_string *php_stream_escape_persistent_key(const char *host, size_t hostlen); diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 74d8877a7f38..4db810b8b5e2 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | +----------------------------------------------------------------------+ @@ -34,6 +32,7 @@ #endif #include "SAPI.h" +#include "php_io.h" #include "php_streams_int.h" #ifdef PHP_WIN32 # include "win32/winutil.h" @@ -163,6 +162,20 @@ typedef struct { } php_stdio_stream_data; #define PHP_STDIOP_GET_FD(anfd, data) anfd = (data)->file ? fileno((data)->file) : (data)->fd +#ifdef PHP_WIN32 +static ZEND_COLD void php_win32_stream_wrapper_warn_error( + php_stream_wrapper *wrapper, + php_stream_context *context, + int options, + zend_enum_StreamErrorCode code, + DWORD error +) { + char *buf = php_win32_error_to_msg(error); + php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, true, code, "%s (code: %lu)", buf, error); + php_win32_error_msg_free(buf); +} +#endif + static int do_fstat(php_stdio_stream_data *d, int force) { if (!d->cached_fstat || (force && !d->no_forced_fstat)) { @@ -394,7 +407,8 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun } if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { char errstr[256]; - php_error_docref(NULL, E_NOTICE, "Write of %zu bytes failed with errno=%d %s", + php_stream_notice(stream, WriteFailed, + "Write of %zu bytes failed with errno=%d %s", count, errno, php_socket_strerror_s(errno, errstr, sizeof(errstr))); } } @@ -472,7 +486,8 @@ static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count) } else { if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { char errstr[256]; - php_error_docref(NULL, E_NOTICE, "Read of %zu bytes failed with errno=%d %s", + php_stream_notice(stream, ReadFailed, + "Read of %zu bytes failed with errno=%d %s", count, errno, php_socket_strerror_s(errno, errstr, sizeof(errstr))); } @@ -621,7 +636,8 @@ static int php_stdiop_seek(php_stream *stream, zend_off_t offset, int whence, ze assert(data != NULL); if (!data->is_seekable) { - php_error_docref(NULL, E_WARNING, "Cannot seek on this stream"); + php_stream_wrapper_warn(NULL, PHP_STREAM_CONTEXT(stream), REPORT_ERRORS, + SeekNotSupported, "Cannot seek on this stream"); return -1; } @@ -684,7 +700,6 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret) case PHP_STREAM_AS_FD: PHP_STDIOP_GET_FD(fd, data); - if (SOCK_ERR == fd) { return FAILURE; } @@ -695,6 +710,26 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret) *(php_socket_t *)ret = fd; } return SUCCESS; + + case PHP_STREAM_AS_FD_FOR_COPY: + /* stdio may read ahead, so use the buffered fallback for FILE* streams */ + if (data->file) { + return FAILURE; + } + PHP_STDIOP_GET_FD(fd, data); + if (SOCK_ERR == fd) { + return FAILURE; + } + if (ret) { + php_io_fd *copy_fd = (php_io_fd *) ret; + copy_fd->fd = fd; + copy_fd->fd_type = data->is_pipe ? PHP_IO_FD_PIPE : PHP_IO_FD_FILE; + copy_fd->timeout.tv_sec = 0; + copy_fd->timeout.tv_usec = 0; + copy_fd->is_blocked = 0; + } + return SUCCESS; + default: return FAILURE; } @@ -1129,7 +1164,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const #ifdef PHP_WIN32 if (!dir) { - php_win32_docref1_from_error(GetLastError(), path); + php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(OpenFailed), GetLastError()); } if (dir && dir->finished) { @@ -1158,7 +1193,8 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen char *persistent_id = NULL; if (FAILURE == php_stream_parse_fopen_modes(mode, &open_flags)) { - php_stream_wrapper_log_error(&php_plain_files_wrapper, options, "`%s' is not a valid mode for fopen", mode); + php_stream_wrapper_log_warn(&php_plain_files_wrapper, NULL, options, + InvalidMode, "`%s' is not a valid mode for fopen", mode); return NULL; } @@ -1311,7 +1347,8 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, if (ret == -1) { if (options & REPORT_ERRORS) { char errstr[256]; - php_error_docref1(NULL, url, E_WARNING, "%s", + php_stream_wrapper_warn(wrapper, context, options, + UnlinkFailed, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; @@ -1333,11 +1370,11 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url_from, strlen(url_from))) { - php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to); + php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(InvalidPath), ERROR_INVALID_NAME); return 0; } if (!php_win32_check_trailing_space(url_to, strlen(url_to))) { - php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to); + php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(InvalidPath), ERROR_INVALID_NAME); return 0; } #endif @@ -1379,20 +1416,22 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f * access to the file in the meantime. */ if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); if (errno != EPERM) { success = 0; } + php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, + !success, PHP_STREAM_EC(ChownFailed), + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } if (success) { if (VCWD_CHMOD(url_to, sb.st_mode)) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); if (errno != EPERM) { success = 0; } + php_stream_wrapper_error(wrapper, context, NULL, options, E_WARNING, + !success, PHP_STREAM_EC(ChownFailed), + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } } # endif @@ -1400,12 +1439,12 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f VCWD_UNLINK(url_from); } } else { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn_nt(wrapper, context, options, StatFailed, + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } } else { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn_nt(wrapper, context, options, CopyFailed, + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } # if !defined(ZTS) && !defined(TSRM_WIN32) umask(oldmask); @@ -1416,10 +1455,11 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f #endif #ifdef PHP_WIN32 - php_win32_docref2_from_error(GetLastError(), url_from, url_to); + php_win32_stream_wrapper_warn_error(wrapper, context, options, PHP_STREAM_EC(RenameFailed), GetLastError()); #else - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + RenameFailed, + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); #endif return 0; } @@ -1443,7 +1483,8 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i int ret = VCWD_MKDIR(dir, (mode_t)mode); if (ret < 0 && (options & REPORT_ERRORS)) { - php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); + php_stream_wrapper_warn(wrapper, context, options, + MkdirFailed, "%s", strerror(errno)); return 0; } @@ -1452,7 +1493,8 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i char buf[MAXPATHLEN]; if (!expand_filepath_with_mode(dir, buf, NULL, 0, CWD_EXPAND)) { - php_error_docref(NULL, E_WARNING, "Invalid path"); + php_stream_wrapper_warn(wrapper, context, options, + InvalidPath, "Invalid path"); return 0; } @@ -1504,7 +1546,9 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i int ret = VCWD_MKDIR(buf, (mode_t) mode); if (ret < 0 && errno != EEXIST) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + MkdirFailed, + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1524,7 +1568,9 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i /* issue a warning to client when the last directory was created failed */ if (ret < 0) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + MkdirFailed, + "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1546,13 +1592,17 @@ static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, i char errstr[256]; #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + NotFound, "%s", + php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif if (VCWD_RMDIR(url) < 0) { - php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + RmdirFailed, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } @@ -1575,7 +1625,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_error_docref1(NULL, url, E_WARNING, "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + NotFound, "%s", + php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif @@ -1594,7 +1646,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url if (VCWD_ACCESS(url, F_OK) != 0) { FILE *file = VCWD_FOPEN(url, "w"); if (file == NULL) { - php_error_docref1(NULL, url, E_WARNING, "Unable to create file %s because %s", url, + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + PermissionDenied, + "Unable to create file %s because %s", url, php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } @@ -1608,7 +1662,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_OWNER: if(option == PHP_STREAM_META_OWNER_NAME) { if(php_get_uid_by_name((char *)value, &uid) != SUCCESS) { - php_error_docref1(NULL, url, E_WARNING, "Unable to find uid for %s", (char *)value); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, + "Unable to find uid for %s", (char *)value); return 0; } } else { @@ -1620,7 +1676,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_GROUP_NAME: if(option == PHP_STREAM_META_GROUP_NAME) { if(php_get_gid_by_name((char *)value, &gid) != SUCCESS) { - php_error_docref1(NULL, url, E_WARNING, "Unable to find gid for %s", (char *)value); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, + "Unable to find gid for %s", (char *)value); return 0; } } else { @@ -1638,8 +1696,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url return 0; } if (ret == -1) { - php_error_docref1(NULL, url, E_WARNING, "Operation failed: %s", - php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, + "Operation failed: %s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } php_clear_stat_cache(0, NULL, 0); @@ -1667,144 +1726,3 @@ PHPAPI /*const*/ php_stream_wrapper php_plain_files_wrapper = { NULL, 0 }; - -/* {{{ php_stream_fopen_with_path */ -PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path, int options STREAMS_DC) -{ - /* code ripped off from fopen_wrappers.c */ - char *pathbuf, *end; - const char *ptr; - char trypath[MAXPATHLEN]; - php_stream *stream; - size_t filename_length; - zend_string *exec_filename; - - if (opened_path) { - *opened_path = NULL; - } - - if(!filename) { - return NULL; - } - - filename_length = strlen(filename); -#ifndef PHP_WIN32 - (void) filename_length; -#endif - - /* Relative path open */ - if (*filename == '.' && (IS_SLASH(filename[1]) || filename[1] == '.')) { - /* further checks, we could have ....... filenames */ - ptr = filename + 1; - if (*ptr == '.') { - while (*(++ptr) == '.'); - if (!IS_SLASH(*ptr)) { /* not a relative path after all */ - goto not_relative_path; - } - } - - - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename)) { - return NULL; - } - - return php_stream_fopen_rel(filename, mode, opened_path, options); - } - -not_relative_path: - - /* Absolute path open */ - if (IS_ABSOLUTE_PATH(filename, filename_length)) { - - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename)) { - return NULL; - } - - return php_stream_fopen_rel(filename, mode, opened_path, options); - } - -#ifdef PHP_WIN32 - if (IS_SLASH(filename[0])) { - size_t cwd_len; - char *cwd; - cwd = virtual_getcwd_ex(&cwd_len); - /* getcwd() will return always return [DRIVE_LETTER]:/) on windows. */ - *(cwd+3) = '\0'; - - if (snprintf(trypath, MAXPATHLEN, "%s%s", cwd, filename) >= MAXPATHLEN) { - php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); - } - - efree(cwd); - - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath)) { - return NULL; - } - - return php_stream_fopen_rel(trypath, mode, opened_path, options); - } -#endif - - if (!path || !*path) { - return php_stream_fopen_rel(filename, mode, opened_path, options); - } - - /* check in provided path */ - /* append the calling scripts' current working directory - * as a fallback case - */ - if (zend_is_executing() && - (exec_filename = zend_get_executed_filename_ex()) != NULL) { - const char *exec_fname = ZSTR_VAL(exec_filename); - size_t exec_fname_length = ZSTR_LEN(exec_filename); - - while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length])); - if (exec_fname_length<=0) { - /* no path */ - pathbuf = estrdup(path); - } else { - size_t path_length = strlen(path); - - pathbuf = (char *) emalloc(exec_fname_length + path_length +1 +1); - memcpy(pathbuf, path, path_length); - pathbuf[path_length] = DEFAULT_DIR_SEPARATOR; - memcpy(pathbuf+path_length+1, exec_fname, exec_fname_length); - pathbuf[path_length + exec_fname_length +1] = '\0'; - } - } else { - pathbuf = estrdup(path); - } - - ptr = pathbuf; - - while (ptr && *ptr) { - end = (char *) strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - if (*ptr == '\0') { - goto stream_skip; - } - if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) { - php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN); - } - - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir_ex(trypath, 0)) { - goto stream_skip; - } - - stream = php_stream_fopen_rel(trypath, mode, opened_path, options); - if (stream) { - efree(pathbuf); - return stream; - } -stream_skip: - ptr = end; - } /* end provided path */ - - efree(pathbuf); - return NULL; - -} -/* }}} */ diff --git a/main/streams/stream_errors.c b/main/streams/stream_errors.c new file mode 100644 index 000000000000..b2dfdbb217ad --- /dev/null +++ b/main/streams/stream_errors.c @@ -0,0 +1,832 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Jakub Zelenka | + +----------------------------------------------------------------------+ + */ + +#define ZEND_ENUM_StreamErrorCode_USE_NAME_TABLE +#include "php.h" +#include "php_globals.h" +#include "php_streams.h" +#include "php_stream_errors.h" +#include "zend_enum.h" +#include "zend_exceptions.h" +#include "ext/standard/file.h" +#include "stream_errors_arginfo.h" + +/* Class entries */ +static zend_class_entry *php_ce_stream_error_code; +static zend_class_entry *php_ce_stream_error_mode; +static zend_class_entry *php_ce_stream_error_store; +static zend_class_entry *php_ce_stream_error; +static zend_class_entry *php_ce_stream_exception; + +/* Forward declarations */ +static void php_stream_error_entry_free(php_stream_error_entry *entry); + +/* Helper to create a single StreamError object from an entry */ +static void php_stream_error_create_object(zval *zv, php_stream_error_entry *entry) +{ + object_init_ex(zv, php_ce_stream_error); + + const char *case_name = NULL; + if (entry->code > 0 && entry->code <= ZEND_ENUM_StreamErrorCode_CASE_COUNT) { + case_name = zend_enum_StreamErrorCode_case_names[entry->code]; + } + if (!case_name) { + case_name = "Generic"; + } + + /* TODO: migrate to zend_enum_get_case_by_id() */ + zend_object *enum_obj = zend_enum_get_case_cstr(php_ce_stream_error_code, case_name); + ZEND_ASSERT(enum_obj != NULL); + + zval code_enum; + ZVAL_OBJ_COPY(&code_enum, enum_obj); + + zend_update_property(php_ce_stream_error, Z_OBJ_P(zv), ZEND_STRL("code"), &code_enum); + zval_ptr_dtor(&code_enum); + + zend_update_property_str( + php_ce_stream_error, Z_OBJ_P(zv), ZEND_STRL("message"), entry->message); + + zend_update_property_string(php_ce_stream_error, Z_OBJ_P(zv), ZEND_STRL("wrapperName"), + entry->wrapper_name ? entry->wrapper_name : ""); + + zend_update_property_long( + php_ce_stream_error, Z_OBJ_P(zv), ZEND_STRL("severity"), entry->severity); + + zend_update_property_bool( + php_ce_stream_error, Z_OBJ_P(zv), ZEND_STRL("terminating"), entry->terminating); +} + +/* Create array of StreamError objects from error chain */ +PHPAPI void php_stream_error_create_array(zval *zv, php_stream_error_entry *first) +{ + array_init(zv); + + php_stream_error_entry *entry = first; + while (entry) { + zval error_obj; + php_stream_error_create_object(&error_obj, entry); + zend_hash_next_index_insert_new(Z_ARRVAL_P(zv), &error_obj); + entry = entry->next; + } +} + +/* Context option helpers */ + +static int php_stream_auto_decide_error_store_mode(int error_mode) +{ + switch (error_mode) { + case PHP_STREAM_ERROR_MODE_ERROR: + return PHP_STREAM_ERROR_STORE_NONE; + case PHP_STREAM_ERROR_MODE_EXCEPTION: + return PHP_STREAM_ERROR_STORE_NON_TERM; + case PHP_STREAM_ERROR_MODE_SILENT: + return PHP_STREAM_ERROR_STORE_ALL; + default: + return PHP_STREAM_ERROR_STORE_NONE; + } +} + +static int php_stream_get_error_mode(php_stream_context *context) +{ + if (!context) { + return PHP_STREAM_ERROR_MODE_ERROR; + } + + zval *option = php_stream_context_get_option(context, "stream", "error_mode"); + if (!option) { + return PHP_STREAM_ERROR_MODE_ERROR; + } + + if (Z_TYPE_P(option) != IS_OBJECT + || !instanceof_function(Z_OBJCE_P(option), php_ce_stream_error_mode)) { + zend_type_error("stream context option 'error_mode' must be of type StreamErrorMode"); + return PHP_STREAM_ERROR_MODE_ERROR; + } + + switch ((zend_enum_StreamErrorMode) zend_enum_fetch_case_id(Z_OBJ_P(option))) { + case ZEND_ENUM_StreamErrorMode_Error: + return PHP_STREAM_ERROR_MODE_ERROR; + case ZEND_ENUM_StreamErrorMode_Exception: + return PHP_STREAM_ERROR_MODE_EXCEPTION; + case ZEND_ENUM_StreamErrorMode_Silent: + return PHP_STREAM_ERROR_MODE_SILENT; + } + + return PHP_STREAM_ERROR_MODE_ERROR; +} + +static int php_stream_get_error_store_mode(php_stream_context *context, int error_mode) +{ + if (!context) { + return php_stream_auto_decide_error_store_mode(error_mode); + } + + zval *option = php_stream_context_get_option(context, "stream", "error_store"); + if (!option) { + return php_stream_auto_decide_error_store_mode(error_mode); + } + + if (Z_TYPE_P(option) != IS_OBJECT + || !instanceof_function(Z_OBJCE_P(option), php_ce_stream_error_store)) { + zend_type_error("stream context option 'error_store' must be of type StreamErrorStore"); + return php_stream_auto_decide_error_store_mode(error_mode); + } + + switch ((zend_enum_StreamErrorStore) zend_enum_fetch_case_id(Z_OBJ_P(option))) { + case ZEND_ENUM_StreamErrorStore_Auto: + return php_stream_auto_decide_error_store_mode(error_mode); + case ZEND_ENUM_StreamErrorStore_None: + return PHP_STREAM_ERROR_STORE_NONE; + case ZEND_ENUM_StreamErrorStore_NonTerminating: + return PHP_STREAM_ERROR_STORE_NON_TERM; + case ZEND_ENUM_StreamErrorStore_Terminating: + return PHP_STREAM_ERROR_STORE_TERMINAL; + case ZEND_ENUM_StreamErrorStore_All: + return PHP_STREAM_ERROR_STORE_ALL; + } + + return php_stream_auto_decide_error_store_mode(error_mode); +} + +/* Helper functions */ + +static bool php_stream_has_terminating_error(php_stream_error_operation *op) +{ + php_stream_error_entry *entry = op->first_error; + while (entry) { + if (entry->terminating) { + return true; + } + entry = entry->next; + } + return false; +} + +static inline php_stream_error_operation *php_stream_get_operation_at_depth(uint32_t depth) +{ + php_stream_error_state *state = &FG(stream_error_state); + + if (depth < PHP_STREAM_ERROR_OPERATION_POOL_SIZE) { + return &state->operation_pool[depth]; + } else { + uint32_t overflow_index = depth - PHP_STREAM_ERROR_OPERATION_POOL_SIZE; + ZEND_ASSERT(overflow_index < state->overflow_capacity); + return &state->overflow_operations[overflow_index]; + } +} + +static inline php_stream_error_operation *php_stream_get_parent_operation(void) +{ + php_stream_error_state *state = &FG(stream_error_state); + + if (state->operation_depth <= 1) { + return NULL; + } + + return php_stream_get_operation_at_depth(state->operation_depth - 2); +} + +/* Clean up functions */ + +static void php_stream_error_entry_free(php_stream_error_entry *entry) +{ + while (entry) { + php_stream_error_entry *next = entry->next; + zend_string_release(entry->message); + efree(entry->wrapper_name); + efree(entry->docref); + efree(entry); + entry = next; + } +} + +PHPAPI void php_stream_error_state_cleanup(void) +{ + php_stream_error_state *state = &FG(stream_error_state); + + while (state->current_operation) { + php_stream_error_operation *op = state->current_operation; + state->operation_depth--; + state->current_operation = php_stream_get_parent_operation(); + + php_stream_error_entry_free(op->first_error); + + op->first_error = NULL; + op->last_error = NULL; + op->error_count = 0; + } + + php_stream_stored_error *stored = state->stored_errors; + while (stored) { + php_stream_stored_error *next = stored->next; + php_stream_error_entry_free(stored->first_error); + efree(stored); + stored = next; + } + + state->stored_errors = NULL; + state->stored_count = 0; + state->operation_depth = 0; + + if (state->overflow_operations) { + efree(state->overflow_operations); + state->overflow_operations = NULL; + state->overflow_capacity = 0; + } +} + +PHPAPI void php_stream_error_get_last(zval *return_value) +{ + php_stream_error_state *state = &FG(stream_error_state); + + if (!state->stored_errors) { + ZVAL_EMPTY_ARRAY(return_value); + return; + } + + php_stream_error_create_array(return_value, state->stored_errors->first_error); +} + +PHPAPI void php_stream_error_clear_stored(void) +{ + php_stream_error_state *state = &FG(stream_error_state); + + php_stream_stored_error *stored = state->stored_errors; + while (stored) { + php_stream_stored_error *next = stored->next; + php_stream_error_entry_free(stored->first_error); + efree(stored); + stored = next; + } + + state->stored_errors = NULL; + state->stored_count = 0; +} + +/* Error operation stack management */ + +PHPAPI php_stream_error_operation *php_stream_error_operation_begin(void) +{ + php_stream_error_state *state = &FG(stream_error_state); + + if (state->operation_depth >= PHP_STREAM_ERROR_MAX_DEPTH) { + php_error_docref(NULL, E_WARNING, + "Stream error operation depth exceeded (%u), possible infinite recursion", + state->operation_depth); + return NULL; + } + + php_stream_error_operation *op; + + if (state->operation_depth < PHP_STREAM_ERROR_OPERATION_POOL_SIZE) { + op = &state->operation_pool[state->operation_depth]; + } else { + uint32_t overflow_index = state->operation_depth - PHP_STREAM_ERROR_OPERATION_POOL_SIZE; + + if (overflow_index >= state->overflow_capacity) { + uint32_t new_capacity + = state->overflow_capacity == 0 ? 8 : state->overflow_capacity * 2; + php_stream_error_operation *new_overflow = erealloc( + state->overflow_operations, sizeof(php_stream_error_operation) * new_capacity); + state->overflow_operations = new_overflow; + state->overflow_capacity = new_capacity; + } + + op = &state->overflow_operations[overflow_index]; + } + + op->first_error = NULL; + op->last_error = NULL; + op->error_count = 0; + + state->current_operation = op; + state->operation_depth++; + + return op; +} + +static void php_stream_error_add(zend_enum_StreamErrorCode code, const char *wrapper_name, + zend_string *message, const char *docref, int severity, bool terminating) +{ + php_stream_error_operation *op = FG(stream_error_state).current_operation; + ZEND_ASSERT(op != NULL); + + php_stream_error_entry *entry = emalloc(sizeof(php_stream_error_entry)); + entry->message = message; + entry->code = code; + entry->wrapper_name = wrapper_name ? estrdup(wrapper_name) : NULL; + entry->docref = docref ? estrdup(docref) : NULL; + entry->severity = severity; + entry->terminating = terminating; + entry->next = NULL; + + if (op->last_error) { + op->last_error->next = entry; + } else { + op->first_error = entry; + } + op->last_error = entry; + op->error_count++; +} + +/* Error reporting */ + +static void php_stream_call_error_handler(zval *handler, zval *errors_array) +{ + zend_fcall_info_cache fcc; + char *is_callable_error = NULL; + + if (!zend_is_callable_ex(handler, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (is_callable_error) { + zend_type_error("stream error handler must be a valid callback, %s", is_callable_error); + efree(is_callable_error); + } + return; + } + + zend_call_known_fcc(&fcc, NULL, 1, errors_array, NULL); +} + +static void php_stream_throw_exception_with_errors(php_stream_error_operation *op) +{ + if (!op->first_error) { + return; + } + + zval ex; + object_init_ex(&ex, php_ce_stream_exception); + + /* Set message from first error */ + zend_update_property_string(php_ce_stream_exception, Z_OBJ(ex), ZEND_STRL("message"), + ZSTR_VAL(op->first_error->message)); + + /* Set code from first error */ + zend_update_property_long(php_ce_stream_exception, Z_OBJ(ex), ZEND_STRL("code"), + (zend_long) op->first_error->code); + + /* Build errors array and set it */ + zval errors_array; + php_stream_error_create_array(&errors_array, op->first_error); + zend_update_property(php_ce_stream_exception, Z_OBJ(ex), ZEND_STRL("errors"), &errors_array); + zval_ptr_dtor(&errors_array); + + zend_throw_exception_object(&ex); +} + +static void php_stream_report_errors(php_stream_context *context, php_stream_error_operation *op, + int error_mode, bool is_terminating) +{ + switch (error_mode) { + case PHP_STREAM_ERROR_MODE_ERROR: { + const php_stream_error_entry *entry = op->first_error; + while (entry) { + php_error_docref(entry->docref, entry->severity, "%s", ZSTR_VAL(entry->message)); + entry = entry->next; + } + break; + } + + case PHP_STREAM_ERROR_MODE_EXCEPTION: { + if (is_terminating) { + php_stream_throw_exception_with_errors(op); + } + break; + } + + case PHP_STREAM_ERROR_MODE_SILENT: + break; + } + + /* Call user error handler if set */ + zval *handler + = context ? php_stream_context_get_option(context, "stream", "error_handler") : NULL; + + if (handler) { + zval errors_array; + php_stream_error_create_array(&errors_array, op->first_error); + + php_stream_call_error_handler(handler, &errors_array); + + zval_ptr_dtor(&errors_array); + } +} + +/* Error storage */ + +PHPAPI void php_stream_error_operation_end(php_stream_context *context) +{ + php_stream_error_state *state = &FG(stream_error_state); + php_stream_error_operation *op = state->current_operation; + + if (!op) { + return; + } + + if (op->error_count > 0) { + if (context == NULL) { + context = FG(default_context); + } + + int error_mode = php_stream_get_error_mode(context); + int store_mode = php_stream_get_error_store_mode(context, error_mode); + + bool is_terminating = php_stream_has_terminating_error(op); + + php_stream_report_errors(context, op, error_mode, is_terminating); + + if (store_mode == PHP_STREAM_ERROR_STORE_NONE) { + php_stream_error_entry_free(op->first_error); + op->first_error = NULL; + } else { + php_stream_error_entry *entry = op->first_error; + php_stream_error_entry *prev = NULL; + php_stream_error_entry *to_store_first = NULL; + php_stream_error_entry *to_store_last = NULL; + uint32_t to_store_count = 0; + php_stream_error_entry *remaining_first = NULL; + + while (entry) { + php_stream_error_entry *next = entry->next; + bool should_store = false; + + if (store_mode == PHP_STREAM_ERROR_STORE_ALL) { + should_store = true; + } else if (store_mode == PHP_STREAM_ERROR_STORE_NON_TERM && !entry->terminating) { + should_store = true; + } else if (store_mode == PHP_STREAM_ERROR_STORE_TERMINAL && entry->terminating) { + should_store = true; + } + + if (should_store) { + entry->next = NULL; + if (to_store_last) { + to_store_last->next = entry; + } else { + to_store_first = entry; + } + to_store_last = entry; + to_store_count++; + } else { + entry->next = NULL; + if (prev) { + prev->next = entry; + } else { + remaining_first = entry; + } + prev = entry; + } + + entry = next; + } + + if (to_store_first) { + php_stream_stored_error *stored = emalloc(sizeof(php_stream_stored_error)); + stored->first_error = to_store_first; + stored->error_count = to_store_count; + stored->next = state->stored_errors; + + state->stored_errors = stored; + state->stored_count++; + } + + if (remaining_first) { + php_stream_error_entry_free(remaining_first); + } + + op->first_error = NULL; + } + } + + state->operation_depth--; + state->current_operation = php_stream_get_parent_operation(); + + op->first_error = NULL; + op->last_error = NULL; + op->error_count = 0; +} + +PHPAPI void php_stream_error_operation_end_for_stream(php_stream *stream) +{ + php_stream_error_state *state = &FG(stream_error_state); + php_stream_error_operation *op = state->current_operation; + + if (!op) { + return; + } + + if (op->error_count == 0) { + state->operation_depth--; + state->current_operation = php_stream_get_parent_operation(); + + op->first_error = NULL; + op->last_error = NULL; + return; + } + + php_stream_context *context = PHP_STREAM_CONTEXT(stream); + php_stream_error_operation_end(context); +} + +PHPAPI void php_stream_error_operation_abort(void) +{ + php_stream_error_state *state = &FG(stream_error_state); + php_stream_error_operation *op = state->current_operation; + + if (!op) { + return; + } + + state->operation_depth--; + state->current_operation = php_stream_get_parent_operation(); + + php_stream_error_entry_free(op->first_error); + op->first_error = NULL; + op->last_error = NULL; + op->error_count = 0; +} + +/* Wrapper error reporting */ + +static void php_stream_wrapper_error_internal(const char *wrapper_name, php_stream_context *context, + const char *docref, int severity, bool terminating, + zend_enum_StreamErrorCode code, zend_string *message) +{ + bool implicit_operation = (FG(stream_error_state).current_operation == NULL); + if (implicit_operation) { + php_stream_error_operation_begin(); + } + + php_stream_error_add(code, wrapper_name, message, docref, severity, terminating); + + if (implicit_operation) { + php_stream_error_operation_end(context); + } +} + +PHPAPI void php_stream_wrapper_error_with_name(const char *wrapper_name, + php_stream_context *context, const char *docref, int options, int severity, + bool terminating, zend_enum_StreamErrorCode code, const char *fmt, ...) +{ + if (!(options & REPORT_ERRORS)) { + return; + } + + va_list args; + va_start(args, fmt); + zend_string *message = vstrpprintf(0, fmt, args); + va_end(args); + + php_stream_wrapper_error_internal( + wrapper_name, context, docref, severity, terminating, code, message); +} + +PHPAPI void php_stream_wrapper_error(php_stream_wrapper *wrapper, php_stream_context *context, + const char *docref, int options, int severity, bool terminating, + zend_enum_StreamErrorCode code, const char *fmt, ...) +{ + if (!(options & REPORT_ERRORS)) { + return; + } + + va_list args; + va_start(args, fmt); + zend_string *message = vstrpprintf(0, fmt, args); + va_end(args); + + const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); + + php_stream_wrapper_error_internal( + wrapper_name, context, docref, severity, terminating, code, message); +} + +/* Stream error reporting */ + +PHPAPI void php_stream_error(php_stream *stream, const char *docref, int severity, + bool terminating, zend_enum_StreamErrorCode code, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + zend_string *message = vstrpprintf(0, fmt, args); + va_end(args); + + const char *wrapper_name = stream->wrapper ? stream->wrapper->wops->label : "stream"; + + php_stream_context *context = PHP_STREAM_CONTEXT(stream); + + php_stream_wrapper_error_internal(wrapper_name, context, docref, severity, + terminating, code, message); +} + +/* Legacy wrapper error logging */ + +static void php_stream_error_entry_dtor_legacy(void *error) +{ + php_stream_error_entry *entry = *(php_stream_error_entry **) error; + zend_string_release(entry->message); + efree(entry->wrapper_name); + efree(entry->docref); + efree(entry); +} + +static void php_stream_error_list_dtor(zval *item) +{ + zend_llist *list = (zend_llist *) Z_PTR_P(item); + zend_llist_destroy(list); + efree(list); +} + +static void php_stream_wrapper_log_store_error(zend_string *message, zend_enum_StreamErrorCode code, + const char *wrapper_name, int severity, bool terminating) +{ + php_stream_error_entry *entry = ecalloc(1, sizeof(php_stream_error_entry)); + entry->message = message; + entry->code = code; + entry->wrapper_name = wrapper_name ? estrdup(wrapper_name) : NULL; + entry->severity = severity; + entry->terminating = terminating; + + if (!FG(wrapper_logged_errors)) { + ALLOC_HASHTABLE(FG(wrapper_logged_errors)); + zend_hash_init(FG(wrapper_logged_errors), 8, NULL, php_stream_error_list_dtor, 0); + } + + zend_llist *list + = zend_hash_str_find_ptr(FG(wrapper_logged_errors), wrapper_name, strlen(wrapper_name)); + + if (!list) { + zend_llist new_list; + zend_llist_init( + &new_list, sizeof(php_stream_error_entry *), php_stream_error_entry_dtor_legacy, 0); + list = zend_hash_str_update_mem(FG(wrapper_logged_errors), wrapper_name, + strlen(wrapper_name), &new_list, sizeof(new_list)); + } + + zend_llist_add_element(list, &entry); +} + +PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, + php_stream_context *context, int options, int severity, bool terminating, + zend_enum_StreamErrorCode code, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + zend_string *message = vstrpprintf(0, fmt, args); + const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); + + if (options & REPORT_ERRORS) { + php_stream_wrapper_error_internal( + wrapper_name, context, NULL, severity, terminating, code, message); + } else { + php_stream_wrapper_log_store_error( + message, code, wrapper_name, severity, terminating); + } + va_end(args); +} + +static zend_llist *php_stream_get_wrapper_errors_list(const char *wrapper_name) +{ + if (!FG(wrapper_logged_errors)) { + return NULL; + } + return (zend_llist *) zend_hash_str_find_ptr( + FG(wrapper_logged_errors), wrapper_name, strlen(wrapper_name)); +} + +PHPAPI void php_stream_display_wrapper_name_errors(const char *wrapper_name, + php_stream_context *context, zend_enum_StreamErrorCode code, + const char *caption) +{ + char *msg; + char errstr[256]; + int free_msg = 0; + + if (EG(exception)) { + return; + } + + if (strcmp(wrapper_name, PHP_STREAM_ERROR_WRAPPER_DEFAULT_NAME)) { + zend_llist *err_list = php_stream_get_wrapper_errors_list(wrapper_name); + if (err_list) { + size_t l = 0; + int brlen; + int i; + int count = (int) zend_llist_count(err_list); + const char *br; + php_stream_error_entry **err_entry_p; + zend_llist_position pos; + + if (PG(html_errors)) { + brlen = 7; + br = "
\n"; + } else { + brlen = 1; + br = "\n"; + } + + for (err_entry_p = zend_llist_get_first_ex(err_list, &pos), i = 0; err_entry_p; + err_entry_p = zend_llist_get_next_ex(err_list, &pos), i++) { + l += ZSTR_LEN((*err_entry_p)->message); + if (i < count - 1) { + l += brlen; + } + } + msg = emalloc(l + 1); + msg[0] = '\0'; + for (err_entry_p = zend_llist_get_first_ex(err_list, &pos), i = 0; err_entry_p; + err_entry_p = zend_llist_get_next_ex(err_list, &pos), i++) { + strcat(msg, ZSTR_VAL((*err_entry_p)->message)); + if (i < count - 1) { + strcat(msg, br); + } + } + + free_msg = 1; + } else { + if (!strcmp(wrapper_name, php_plain_files_wrapper.wops->label)) { + msg = php_socket_strerror_s(errno, errstr, sizeof(errstr)); + } else { + msg = "operation failed"; + } + } + } else { + msg = "no suitable wrapper could be found"; + } + + zend_string *message = strpprintf(0, "%s: %s", caption, msg); + + php_stream_wrapper_error_internal(wrapper_name, context, NULL, E_WARNING, true, + code, message); + + if (free_msg) { + efree(msg); + } +} + +PHPAPI void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, + php_stream_context *context, zend_enum_StreamErrorCode code, + const char *caption) +{ + if (wrapper) { + const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); + php_stream_display_wrapper_name_errors(wrapper_name, context, code, caption); + } +} + +PHPAPI void php_stream_tidy_wrapper_name_error_log(const char *wrapper_name) +{ + if (FG(wrapper_logged_errors)) { + zend_hash_str_del(FG(wrapper_logged_errors), wrapper_name, strlen(wrapper_name)); + } +} + +PHPAPI void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper) +{ + if (wrapper) { + const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); + php_stream_tidy_wrapper_name_error_log(wrapper_name); + } +} + +/* StreamException methods */ + +PHP_METHOD(StreamException, getErrors) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zval *errors = zend_read_property( + php_ce_stream_exception, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), 1, NULL); + + RETURN_COPY(errors); +} + +/* Module init */ + +PHP_MINIT_FUNCTION(stream_errors) +{ + php_ce_stream_error_code = register_class_StreamErrorCode(); + php_ce_stream_error_mode = register_class_StreamErrorMode(); + php_ce_stream_error_store = register_class_StreamErrorStore(); + + php_ce_stream_error = register_class_StreamError(); + php_ce_stream_exception = register_class_StreamException(zend_ce_exception); + + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(stream_errors) +{ + return SUCCESS; +} diff --git a/main/streams/stream_errors.stub.php b/main/streams/stream_errors.stub.php new file mode 100644 index 000000000000..28fb381df24d --- /dev/null +++ b/main/streams/stream_errors.stub.php @@ -0,0 +1,144 @@ + */ + private array $errors = []; + + /** @return array */ + public function getErrors(): array {} +} diff --git a/main/streams/stream_errors_arginfo.h b/main/streams/stream_errors_arginfo.h new file mode 100644 index 000000000000..4558f64b77f5 --- /dev/null +++ b/main/streams/stream_errors_arginfo.h @@ -0,0 +1,257 @@ +/* This is a generated file, edit stream_errors.stub.php instead. + * Stub hash: d3087b608996f81bf0dd19c25792feec9744e768 + * Has decl header: yes */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_StreamException_getErrors, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +static ZEND_METHOD(StreamException, getErrors); + +static const zend_function_entry class_StreamException_methods[] = { + ZEND_ME(StreamException, getErrors, arginfo_class_StreamException_getErrors, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static zend_class_entry *register_class_StreamErrorCode(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("StreamErrorCode", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "None", NULL); + + zend_enum_add_case_cstr(class_entry, "Generic", NULL); + + zend_enum_add_case_cstr(class_entry, "ReadFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "WriteFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "SeekFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "SeekNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "FlushFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "TruncateFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "ConnectFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "BindFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "ListenFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "AcceptFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "NotWritable", NULL); + + zend_enum_add_case_cstr(class_entry, "NotReadable", NULL); + + zend_enum_add_case_cstr(class_entry, "Disabled", NULL); + + zend_enum_add_case_cstr(class_entry, "NotFound", NULL); + + zend_enum_add_case_cstr(class_entry, "PermissionDenied", NULL); + + zend_enum_add_case_cstr(class_entry, "AlreadyExists", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidPath", NULL); + + zend_enum_add_case_cstr(class_entry, "PathTooLong", NULL); + + zend_enum_add_case_cstr(class_entry, "OpenFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "CreateFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "DupFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "UnlinkFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "RenameFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "MkdirFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "RmdirFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "StatFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "MetaFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "ChmodFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "ChownFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "CopyFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "TouchFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidMode", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidMeta", NULL); + + zend_enum_add_case_cstr(class_entry, "ModeNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "Readonly", NULL); + + zend_enum_add_case_cstr(class_entry, "RecursionDetected", NULL); + + zend_enum_add_case_cstr(class_entry, "NotImplemented", NULL); + + zend_enum_add_case_cstr(class_entry, "NoOpener", NULL); + + zend_enum_add_case_cstr(class_entry, "PersistentNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "WrapperNotFound", NULL); + + zend_enum_add_case_cstr(class_entry, "WrapperDisabled", NULL); + + zend_enum_add_case_cstr(class_entry, "ProtocolUnsupported", NULL); + + zend_enum_add_case_cstr(class_entry, "WrapperRegistrationFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "WrapperUnregistrationFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "WrapperRestorationFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "FilterNotFound", NULL); + + zend_enum_add_case_cstr(class_entry, "FilterFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "CastFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "CastNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "MakeSeekableFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "BufferedDataLost", NULL); + + zend_enum_add_case_cstr(class_entry, "NetworkSendFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "NetworkRecvFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "SslNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "ResumptionFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "SocketPathTooLong", NULL); + + zend_enum_add_case_cstr(class_entry, "OobNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "ProtocolError", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidUrl", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidResponse", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidHeader", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidParam", NULL); + + zend_enum_add_case_cstr(class_entry, "RedirectLimit", NULL); + + zend_enum_add_case_cstr(class_entry, "AuthFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "TimeOut", NULL); + + zend_enum_add_case_cstr(class_entry, "ArchivingFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "EncodingFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "DecodingFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "InvalidFormat", NULL); + + zend_enum_add_case_cstr(class_entry, "AllocationFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "TemporaryFileFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "LockFailed", NULL); + + zend_enum_add_case_cstr(class_entry, "LockNotSupported", NULL); + + zend_enum_add_case_cstr(class_entry, "UserspaceNotImplemented", NULL); + + zend_enum_add_case_cstr(class_entry, "UserspaceInvalidReturn", NULL); + + zend_enum_add_case_cstr(class_entry, "UserspaceCallFailed", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_StreamErrorMode(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("StreamErrorMode", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Error", NULL); + + zend_enum_add_case_cstr(class_entry, "Exception", NULL); + + zend_enum_add_case_cstr(class_entry, "Silent", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_StreamErrorStore(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("StreamErrorStore", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Auto", NULL); + + zend_enum_add_case_cstr(class_entry, "None", NULL); + + zend_enum_add_case_cstr(class_entry, "NonTerminating", NULL); + + zend_enum_add_case_cstr(class_entry, "Terminating", NULL); + + zend_enum_add_case_cstr(class_entry, "All", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_StreamError(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "StreamError", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_READONLY_CLASS); + + zval property_code_default_value; + ZVAL_UNDEF(&property_code_default_value); + zend_string *property_code_class_StreamErrorCode = zend_string_init("StreamErrorCode", sizeof("StreamErrorCode")-1, 1); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_CODE), &property_code_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_code_class_StreamErrorCode, 0, 0)); + + zval property_message_default_value; + ZVAL_UNDEF(&property_message_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_MESSAGE), &property_message_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zval property_wrapperName_default_value; + ZVAL_UNDEF(&property_wrapperName_default_value); + zend_string *property_wrapperName_name = zend_string_init("wrapperName", sizeof("wrapperName") - 1, true); + zend_declare_typed_property(class_entry, property_wrapperName_name, &property_wrapperName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_wrapperName_name, true); + + zval property_severity_default_value; + ZVAL_UNDEF(&property_severity_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_SEVERITY), &property_severity_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + + zval property_terminating_default_value; + ZVAL_UNDEF(&property_terminating_default_value); + zend_string *property_terminating_name = zend_string_init("terminating", sizeof("terminating") - 1, true); + zend_declare_typed_property(class_entry, property_terminating_name, &property_terminating_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_string_release_ex(property_terminating_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_StreamException(zend_class_entry *class_entry_Exception) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "StreamException", class_StreamException_methods); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); + + zval property_errors_default_value; + ZVAL_EMPTY_ARRAY(&property_errors_default_value); + zend_string *property_errors_name = zend_string_init("errors", sizeof("errors") - 1, true); + zend_declare_typed_property(class_entry, property_errors_name, &property_errors_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); + zend_string_release_ex(property_errors_name, true); + + return class_entry; +} diff --git a/main/streams/stream_errors_decl.h b/main/streams/stream_errors_decl.h new file mode 100644 index 000000000000..3a18055b9e74 --- /dev/null +++ b/main/streams/stream_errors_decl.h @@ -0,0 +1,187 @@ +/* This is a generated file, edit stream_errors.stub.php instead. + * Stub hash: d3087b608996f81bf0dd19c25792feec9744e768 */ + +#ifndef ZEND_STREAM_ERRORS_DECL_d3087b608996f81bf0dd19c25792feec9744e768_H +#define ZEND_STREAM_ERRORS_DECL_d3087b608996f81bf0dd19c25792feec9744e768_H + +typedef enum zend_enum_StreamErrorCode { + ZEND_ENUM_StreamErrorCode_None = 1, + ZEND_ENUM_StreamErrorCode_Generic = 2, + ZEND_ENUM_StreamErrorCode_ReadFailed = 3, + ZEND_ENUM_StreamErrorCode_WriteFailed = 4, + ZEND_ENUM_StreamErrorCode_SeekFailed = 5, + ZEND_ENUM_StreamErrorCode_SeekNotSupported = 6, + ZEND_ENUM_StreamErrorCode_FlushFailed = 7, + ZEND_ENUM_StreamErrorCode_TruncateFailed = 8, + ZEND_ENUM_StreamErrorCode_ConnectFailed = 9, + ZEND_ENUM_StreamErrorCode_BindFailed = 10, + ZEND_ENUM_StreamErrorCode_ListenFailed = 11, + ZEND_ENUM_StreamErrorCode_AcceptFailed = 12, + ZEND_ENUM_StreamErrorCode_NotWritable = 13, + ZEND_ENUM_StreamErrorCode_NotReadable = 14, + ZEND_ENUM_StreamErrorCode_Disabled = 15, + ZEND_ENUM_StreamErrorCode_NotFound = 16, + ZEND_ENUM_StreamErrorCode_PermissionDenied = 17, + ZEND_ENUM_StreamErrorCode_AlreadyExists = 18, + ZEND_ENUM_StreamErrorCode_InvalidPath = 19, + ZEND_ENUM_StreamErrorCode_PathTooLong = 20, + ZEND_ENUM_StreamErrorCode_OpenFailed = 21, + ZEND_ENUM_StreamErrorCode_CreateFailed = 22, + ZEND_ENUM_StreamErrorCode_DupFailed = 23, + ZEND_ENUM_StreamErrorCode_UnlinkFailed = 24, + ZEND_ENUM_StreamErrorCode_RenameFailed = 25, + ZEND_ENUM_StreamErrorCode_MkdirFailed = 26, + ZEND_ENUM_StreamErrorCode_RmdirFailed = 27, + ZEND_ENUM_StreamErrorCode_StatFailed = 28, + ZEND_ENUM_StreamErrorCode_MetaFailed = 29, + ZEND_ENUM_StreamErrorCode_ChmodFailed = 30, + ZEND_ENUM_StreamErrorCode_ChownFailed = 31, + ZEND_ENUM_StreamErrorCode_CopyFailed = 32, + ZEND_ENUM_StreamErrorCode_TouchFailed = 33, + ZEND_ENUM_StreamErrorCode_InvalidMode = 34, + ZEND_ENUM_StreamErrorCode_InvalidMeta = 35, + ZEND_ENUM_StreamErrorCode_ModeNotSupported = 36, + ZEND_ENUM_StreamErrorCode_Readonly = 37, + ZEND_ENUM_StreamErrorCode_RecursionDetected = 38, + ZEND_ENUM_StreamErrorCode_NotImplemented = 39, + ZEND_ENUM_StreamErrorCode_NoOpener = 40, + ZEND_ENUM_StreamErrorCode_PersistentNotSupported = 41, + ZEND_ENUM_StreamErrorCode_WrapperNotFound = 42, + ZEND_ENUM_StreamErrorCode_WrapperDisabled = 43, + ZEND_ENUM_StreamErrorCode_ProtocolUnsupported = 44, + ZEND_ENUM_StreamErrorCode_WrapperRegistrationFailed = 45, + ZEND_ENUM_StreamErrorCode_WrapperUnregistrationFailed = 46, + ZEND_ENUM_StreamErrorCode_WrapperRestorationFailed = 47, + ZEND_ENUM_StreamErrorCode_FilterNotFound = 48, + ZEND_ENUM_StreamErrorCode_FilterFailed = 49, + ZEND_ENUM_StreamErrorCode_CastFailed = 50, + ZEND_ENUM_StreamErrorCode_CastNotSupported = 51, + ZEND_ENUM_StreamErrorCode_MakeSeekableFailed = 52, + ZEND_ENUM_StreamErrorCode_BufferedDataLost = 53, + ZEND_ENUM_StreamErrorCode_NetworkSendFailed = 54, + ZEND_ENUM_StreamErrorCode_NetworkRecvFailed = 55, + ZEND_ENUM_StreamErrorCode_SslNotSupported = 56, + ZEND_ENUM_StreamErrorCode_ResumptionFailed = 57, + ZEND_ENUM_StreamErrorCode_SocketPathTooLong = 58, + ZEND_ENUM_StreamErrorCode_OobNotSupported = 59, + ZEND_ENUM_StreamErrorCode_ProtocolError = 60, + ZEND_ENUM_StreamErrorCode_InvalidUrl = 61, + ZEND_ENUM_StreamErrorCode_InvalidResponse = 62, + ZEND_ENUM_StreamErrorCode_InvalidHeader = 63, + ZEND_ENUM_StreamErrorCode_InvalidParam = 64, + ZEND_ENUM_StreamErrorCode_RedirectLimit = 65, + ZEND_ENUM_StreamErrorCode_AuthFailed = 66, + ZEND_ENUM_StreamErrorCode_TimeOut = 67, + ZEND_ENUM_StreamErrorCode_ArchivingFailed = 68, + ZEND_ENUM_StreamErrorCode_EncodingFailed = 69, + ZEND_ENUM_StreamErrorCode_DecodingFailed = 70, + ZEND_ENUM_StreamErrorCode_InvalidFormat = 71, + ZEND_ENUM_StreamErrorCode_AllocationFailed = 72, + ZEND_ENUM_StreamErrorCode_TemporaryFileFailed = 73, + ZEND_ENUM_StreamErrorCode_LockFailed = 74, + ZEND_ENUM_StreamErrorCode_LockNotSupported = 75, + ZEND_ENUM_StreamErrorCode_UserspaceNotImplemented = 76, + ZEND_ENUM_StreamErrorCode_UserspaceInvalidReturn = 77, + ZEND_ENUM_StreamErrorCode_UserspaceCallFailed = 78, +} zend_enum_StreamErrorCode; + +#define ZEND_ENUM_StreamErrorCode_CASE_COUNT 78 + +#ifdef ZEND_ENUM_StreamErrorCode_USE_NAME_TABLE +static const char *zend_enum_StreamErrorCode_case_names[ZEND_ENUM_StreamErrorCode_CASE_COUNT + 1] = { + [ZEND_ENUM_StreamErrorCode_None] = "None", + [ZEND_ENUM_StreamErrorCode_Generic] = "Generic", + [ZEND_ENUM_StreamErrorCode_ReadFailed] = "ReadFailed", + [ZEND_ENUM_StreamErrorCode_WriteFailed] = "WriteFailed", + [ZEND_ENUM_StreamErrorCode_SeekFailed] = "SeekFailed", + [ZEND_ENUM_StreamErrorCode_SeekNotSupported] = "SeekNotSupported", + [ZEND_ENUM_StreamErrorCode_FlushFailed] = "FlushFailed", + [ZEND_ENUM_StreamErrorCode_TruncateFailed] = "TruncateFailed", + [ZEND_ENUM_StreamErrorCode_ConnectFailed] = "ConnectFailed", + [ZEND_ENUM_StreamErrorCode_BindFailed] = "BindFailed", + [ZEND_ENUM_StreamErrorCode_ListenFailed] = "ListenFailed", + [ZEND_ENUM_StreamErrorCode_AcceptFailed] = "AcceptFailed", + [ZEND_ENUM_StreamErrorCode_NotWritable] = "NotWritable", + [ZEND_ENUM_StreamErrorCode_NotReadable] = "NotReadable", + [ZEND_ENUM_StreamErrorCode_Disabled] = "Disabled", + [ZEND_ENUM_StreamErrorCode_NotFound] = "NotFound", + [ZEND_ENUM_StreamErrorCode_PermissionDenied] = "PermissionDenied", + [ZEND_ENUM_StreamErrorCode_AlreadyExists] = "AlreadyExists", + [ZEND_ENUM_StreamErrorCode_InvalidPath] = "InvalidPath", + [ZEND_ENUM_StreamErrorCode_PathTooLong] = "PathTooLong", + [ZEND_ENUM_StreamErrorCode_OpenFailed] = "OpenFailed", + [ZEND_ENUM_StreamErrorCode_CreateFailed] = "CreateFailed", + [ZEND_ENUM_StreamErrorCode_DupFailed] = "DupFailed", + [ZEND_ENUM_StreamErrorCode_UnlinkFailed] = "UnlinkFailed", + [ZEND_ENUM_StreamErrorCode_RenameFailed] = "RenameFailed", + [ZEND_ENUM_StreamErrorCode_MkdirFailed] = "MkdirFailed", + [ZEND_ENUM_StreamErrorCode_RmdirFailed] = "RmdirFailed", + [ZEND_ENUM_StreamErrorCode_StatFailed] = "StatFailed", + [ZEND_ENUM_StreamErrorCode_MetaFailed] = "MetaFailed", + [ZEND_ENUM_StreamErrorCode_ChmodFailed] = "ChmodFailed", + [ZEND_ENUM_StreamErrorCode_ChownFailed] = "ChownFailed", + [ZEND_ENUM_StreamErrorCode_CopyFailed] = "CopyFailed", + [ZEND_ENUM_StreamErrorCode_TouchFailed] = "TouchFailed", + [ZEND_ENUM_StreamErrorCode_InvalidMode] = "InvalidMode", + [ZEND_ENUM_StreamErrorCode_InvalidMeta] = "InvalidMeta", + [ZEND_ENUM_StreamErrorCode_ModeNotSupported] = "ModeNotSupported", + [ZEND_ENUM_StreamErrorCode_Readonly] = "Readonly", + [ZEND_ENUM_StreamErrorCode_RecursionDetected] = "RecursionDetected", + [ZEND_ENUM_StreamErrorCode_NotImplemented] = "NotImplemented", + [ZEND_ENUM_StreamErrorCode_NoOpener] = "NoOpener", + [ZEND_ENUM_StreamErrorCode_PersistentNotSupported] = "PersistentNotSupported", + [ZEND_ENUM_StreamErrorCode_WrapperNotFound] = "WrapperNotFound", + [ZEND_ENUM_StreamErrorCode_WrapperDisabled] = "WrapperDisabled", + [ZEND_ENUM_StreamErrorCode_ProtocolUnsupported] = "ProtocolUnsupported", + [ZEND_ENUM_StreamErrorCode_WrapperRegistrationFailed] = "WrapperRegistrationFailed", + [ZEND_ENUM_StreamErrorCode_WrapperUnregistrationFailed] = "WrapperUnregistrationFailed", + [ZEND_ENUM_StreamErrorCode_WrapperRestorationFailed] = "WrapperRestorationFailed", + [ZEND_ENUM_StreamErrorCode_FilterNotFound] = "FilterNotFound", + [ZEND_ENUM_StreamErrorCode_FilterFailed] = "FilterFailed", + [ZEND_ENUM_StreamErrorCode_CastFailed] = "CastFailed", + [ZEND_ENUM_StreamErrorCode_CastNotSupported] = "CastNotSupported", + [ZEND_ENUM_StreamErrorCode_MakeSeekableFailed] = "MakeSeekableFailed", + [ZEND_ENUM_StreamErrorCode_BufferedDataLost] = "BufferedDataLost", + [ZEND_ENUM_StreamErrorCode_NetworkSendFailed] = "NetworkSendFailed", + [ZEND_ENUM_StreamErrorCode_NetworkRecvFailed] = "NetworkRecvFailed", + [ZEND_ENUM_StreamErrorCode_SslNotSupported] = "SslNotSupported", + [ZEND_ENUM_StreamErrorCode_ResumptionFailed] = "ResumptionFailed", + [ZEND_ENUM_StreamErrorCode_SocketPathTooLong] = "SocketPathTooLong", + [ZEND_ENUM_StreamErrorCode_OobNotSupported] = "OobNotSupported", + [ZEND_ENUM_StreamErrorCode_ProtocolError] = "ProtocolError", + [ZEND_ENUM_StreamErrorCode_InvalidUrl] = "InvalidUrl", + [ZEND_ENUM_StreamErrorCode_InvalidResponse] = "InvalidResponse", + [ZEND_ENUM_StreamErrorCode_InvalidHeader] = "InvalidHeader", + [ZEND_ENUM_StreamErrorCode_InvalidParam] = "InvalidParam", + [ZEND_ENUM_StreamErrorCode_RedirectLimit] = "RedirectLimit", + [ZEND_ENUM_StreamErrorCode_AuthFailed] = "AuthFailed", + [ZEND_ENUM_StreamErrorCode_TimeOut] = "TimeOut", + [ZEND_ENUM_StreamErrorCode_ArchivingFailed] = "ArchivingFailed", + [ZEND_ENUM_StreamErrorCode_EncodingFailed] = "EncodingFailed", + [ZEND_ENUM_StreamErrorCode_DecodingFailed] = "DecodingFailed", + [ZEND_ENUM_StreamErrorCode_InvalidFormat] = "InvalidFormat", + [ZEND_ENUM_StreamErrorCode_AllocationFailed] = "AllocationFailed", + [ZEND_ENUM_StreamErrorCode_TemporaryFileFailed] = "TemporaryFileFailed", + [ZEND_ENUM_StreamErrorCode_LockFailed] = "LockFailed", + [ZEND_ENUM_StreamErrorCode_LockNotSupported] = "LockNotSupported", + [ZEND_ENUM_StreamErrorCode_UserspaceNotImplemented] = "UserspaceNotImplemented", + [ZEND_ENUM_StreamErrorCode_UserspaceInvalidReturn] = "UserspaceInvalidReturn", + [ZEND_ENUM_StreamErrorCode_UserspaceCallFailed] = "UserspaceCallFailed", +}; +#endif + +typedef enum zend_enum_StreamErrorMode { + ZEND_ENUM_StreamErrorMode_Error = 1, + ZEND_ENUM_StreamErrorMode_Exception = 2, + ZEND_ENUM_StreamErrorMode_Silent = 3, +} zend_enum_StreamErrorMode; + +typedef enum zend_enum_StreamErrorStore { + ZEND_ENUM_StreamErrorStore_Auto = 1, + ZEND_ENUM_StreamErrorStore_None = 2, + ZEND_ENUM_StreamErrorStore_NonTerminating = 3, + ZEND_ENUM_StreamErrorStore_Terminating = 4, + ZEND_ENUM_StreamErrorStore_All = 5, +} zend_enum_StreamErrorStore; + +#endif /* ZEND_STREAM_ERRORS_DECL_d3087b608996f81bf0dd19c25792feec9744e768_H */ diff --git a/main/streams/streams.c b/main/streams/streams.c index 32c7ba99f58c..3d8830d7291f 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Borrowed code from: | @@ -24,6 +22,7 @@ #include "php_globals.h" #include "php_memory_streams.h" #include "php_network.h" +#include "php_io.h" #include "php_open_temporary_file.h" #include "ext/standard/file.h" #include "ext/standard/basic_functions.h" /* for BG(CurrentStatFile) */ @@ -142,141 +141,27 @@ PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream * /* }}} */ -static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper) -{ - if (!FG(wrapper_errors)) { - return NULL; - } else { - return (zend_llist*) zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); - } -} - -/* {{{ wrapper error reporting */ -static void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption) -{ - char *tmp; - char *msg; - char errstr[256]; - int free_msg = 0; - - if (EG(exception)) { - /* Don't emit additional warnings if an exception has already been thrown. */ - return; - } - - tmp = estrdup(path); - if (wrapper) { - zend_llist *err_list = php_get_wrapper_errors_list(wrapper); - if (err_list) { - size_t l = 0; - int brlen; - int i; - int count = (int)zend_llist_count(err_list); - const char *br; - const char **err_buf_p; - zend_llist_position pos; - - if (PG(html_errors)) { - brlen = 7; - br = "
\n"; - } else { - brlen = 1; - br = "\n"; - } - - for (err_buf_p = zend_llist_get_first_ex(err_list, &pos), i = 0; - err_buf_p; - err_buf_p = zend_llist_get_next_ex(err_list, &pos), i++) { - l += strlen(*err_buf_p); - if (i < count - 1) { - l += brlen; - } - } - msg = emalloc(l + 1); - msg[0] = '\0'; - for (err_buf_p = zend_llist_get_first_ex(err_list, &pos), i = 0; - err_buf_p; - err_buf_p = zend_llist_get_next_ex(err_list, &pos), i++) { - strcat(msg, *err_buf_p); - if (i < count - 1) { - strcat(msg, br); - } - } - - free_msg = 1; +zend_string *php_stream_escape_persistent_key(const char *host, size_t hostlen) +{ + zend_string *escaped = zend_string_safe_alloc(hostlen, 2, 0, 0); + char *ptr = ZSTR_VAL(escaped); + for (size_t i = 0; i < hostlen; i++) { + if (host[i] == '\0') { + *ptr++ = '\\'; + *ptr++ = '0'; + } else if (host[i] == '\\') { + *ptr++ = '\\'; + *ptr++ = '\\'; } else { - if (wrapper == &php_plain_files_wrapper) { - msg = php_socket_strerror_s(errno, errstr, sizeof(errstr)); - } else { - msg = "operation failed"; - } + *ptr++ = host[i]; } - } else { - msg = "no suitable wrapper could be found"; - } - - php_strip_url_passwd(tmp); - php_error_docref1(NULL, tmp, E_WARNING, "%s: %s", caption, msg); - efree(tmp); - if (free_msg) { - efree(msg); } -} - -static void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper) -{ - if (wrapper && FG(wrapper_errors)) { - zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); - } -} + *ptr = '\0'; + ZSTR_LEN(escaped) = ptr - ZSTR_VAL(escaped); -static void wrapper_error_dtor(void *error) -{ - efree(*(char**)error); -} - -static void wrapper_list_dtor(zval *item) { - zend_llist *list = (zend_llist*)Z_PTR_P(item); - zend_llist_destroy(list); - efree(list); + return escaped; } -PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, int options, const char *fmt, ...) -{ - va_list args; - char *buffer = NULL; - - va_start(args, fmt); - vspprintf(&buffer, 0, fmt, args); - va_end(args); - - if ((options & REPORT_ERRORS) || wrapper == NULL) { - php_error_docref(NULL, E_WARNING, "%s", buffer); - efree(buffer); - } else { - zend_llist *list = NULL; - if (!FG(wrapper_errors)) { - ALLOC_HASHTABLE(FG(wrapper_errors)); - zend_hash_init(FG(wrapper_errors), 8, NULL, wrapper_list_dtor, 0); - } else { - list = zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); - } - - if (!list) { - zend_llist new_list; - zend_llist_init(&new_list, sizeof(buffer), wrapper_error_dtor, 0); - list = zend_hash_str_update_mem(FG(wrapper_errors), (const char*)&wrapper, - sizeof(wrapper), &new_list, sizeof(new_list)); - } - - /* append to linked list */ - zend_llist_add_element(list, &buffer); - } -} - - -/* }}} */ - /* allocate a new stream for a particular ops */ PHPAPI php_stream *_php_stream_alloc(const php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC) /* {{{ */ { @@ -513,6 +398,11 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov ZVAL_UNDEF(&stream->wrapperdata); } + if (stream->error_list) { + zend_llist_destroy(stream->error_list); + pefree(stream->error_list, stream->is_persistent); + } + if (stream->readbuf) { pefree(stream->readbuf, stream->is_persistent); stream->readbuf = NULL; @@ -1320,7 +1210,7 @@ PHPAPI ssize_t _php_stream_write(php_stream *stream, const char *buf, size_t cou ZEND_ASSERT(buf != NULL); if (stream->ops->write == NULL) { - php_error_docref(NULL, E_NOTICE, "Stream is not writable"); + php_stream_notice(stream, NotWritable, "Stream is not writable"); return (ssize_t) -1; } @@ -1362,6 +1252,58 @@ PHPAPI zend_off_t _php_stream_tell(const php_stream *stream) return stream->position; } +static bool php_stream_are_filters_seekable(php_stream_filter *filter, bool is_start_seeking, int chain_type) +{ + while (filter) { + php_stream_filter_seekable_t seekable = (chain_type == PHP_STREAM_FILTER_READ) ? + filter->read_seekable : filter->write_seekable; + if (seekable == PSFS_SEEKABLE_NEVER) { + php_error_docref(NULL, E_WARNING, "Stream filter %s is never seekable", filter->fops->label); + return false; + } + if (!is_start_seeking && seekable == PSFS_SEEKABLE_START) { + php_error_docref(NULL, E_WARNING, "Stream filter %s is seekable only to start position", filter->fops->label); + return false; + } + filter = filter->next; + } + return true; +} + +static zend_result php_stream_filters_seek(php_stream *stream, php_stream_filter *filter, + bool is_start_seeking, zend_off_t offset, int whence, int chain_type) +{ + while (filter) { + php_stream_filter_seekable_t seekable = (chain_type == PHP_STREAM_FILTER_READ) ? + filter->read_seekable : filter->write_seekable; + if (((seekable == PSFS_SEEKABLE_START && is_start_seeking) || + seekable == PSFS_SEEKABLE_CHECK) && + filter->fops->seek(stream, filter, offset, whence) == FAILURE) { + php_error_docref(NULL, E_WARNING, "Stream filter seeking for %s failed", filter->fops->label); + return FAILURE; + } + filter = filter->next; + } + return SUCCESS; +} + +static zend_result php_stream_filters_seek_all(php_stream *stream, bool is_start_seeking, + zend_off_t offset, int whence) +{ + if (php_stream_filters_seek(stream, stream->writefilters.head, is_start_seeking, + offset, whence, PHP_STREAM_FILTER_WRITE) == FAILURE) { + return FAILURE; + } + if (php_stream_filters_seek(stream, stream->readfilters.head, is_start_seeking, + offset, whence, PHP_STREAM_FILTER_READ) == FAILURE) { + return FAILURE; + } + + return SUCCESS; +} + + + PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) { if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { @@ -1374,6 +1316,20 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) } } + bool is_start_seeking = whence == SEEK_SET && offset == 0; + + if (stream->writefilters.head) { + _php_stream_flush(stream, 0); + if (!php_stream_are_filters_seekable(stream->writefilters.head, is_start_seeking, + PHP_STREAM_FILTER_WRITE)) { + return -1; + } + } + if (stream->readfilters.head && !php_stream_are_filters_seekable( + stream->readfilters.head, is_start_seeking, PHP_STREAM_FILTER_READ)) { + return -1; + } + /* handle the case where we are in the buffer */ if ((stream->flags & PHP_STREAM_FLAG_NO_BUFFER) == 0) { switch(whence) { @@ -1383,7 +1339,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) stream->position += offset; stream->eof = 0; stream->fatal_error = 0; - return 0; + return php_stream_filters_seek_all(stream, is_start_seeking, offset, whence) == SUCCESS ? 0 : -1; } break; case SEEK_SET: @@ -1393,7 +1349,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) stream->position = offset; stream->eof = 0; stream->fatal_error = 0; - return 0; + return php_stream_filters_seek_all(stream, is_start_seeking, offset, whence) == SUCCESS ? 0 : -1; } break; } @@ -1402,11 +1358,6 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { int ret; - - if (stream->writefilters.head) { - _php_stream_flush(stream, 0); - } - switch(whence) { case SEEK_CUR: ZEND_ASSERT(stream->position >= 0); @@ -1433,7 +1384,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) /* invalidate the buffer contents */ stream->readpos = stream->writepos = 0; - return ret; + return php_stream_filters_seek_all(stream, is_start_seeking, offset, whence) == SUCCESS ? ret : -1; } /* else the stream has decided that it can't support seeking after all; * fall through to attempt emulation */ @@ -1454,7 +1405,8 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) return 0; } - php_error_docref(NULL, E_WARNING, "Stream does not support seeking"); + php_stream_warn(stream, SeekNotSupported, + "Stream does not support seeking"); return -1; } @@ -1637,164 +1589,17 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, bool return result; } -/* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ -PHPAPI zend_result _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC) +/* Fallback copy using stream read/write API */ +static zend_result php_stream_copy_fallback(php_stream *src, php_stream *dest, size_t maxlen, size_t *len) { char buf[CHUNK_SIZE]; size_t haveread = 0; - size_t towrite; - size_t dummy; - - if (!len) { - len = &dummy; - } - - if (maxlen == 0) { - *len = 0; - return SUCCESS; - } - -#ifdef HAVE_COPY_FILE_RANGE - if (php_stream_is(src, PHP_STREAM_IS_STDIO) && - php_stream_is(dest, PHP_STREAM_IS_STDIO) && - src->writepos == src->readpos) { - /* both php_stream instances are backed by a file descriptor, are not filtered and the - * read buffer is empty: we can use copy_file_range() */ - int src_fd, dest_fd, dest_open_flags = 0; - - /* copy_file_range does not work with O_APPEND */ - if (php_stream_cast(src, PHP_STREAM_AS_FD, (void*)&src_fd, 0) == SUCCESS && - php_stream_cast(dest, PHP_STREAM_AS_FD, (void*)&dest_fd, 0) == SUCCESS && - /* get dest open flags to check if the stream is open in append mode */ - php_stream_parse_fopen_modes(dest->mode, &dest_open_flags) == SUCCESS && - !(dest_open_flags & O_APPEND)) { - - /* clamp to INT_MAX to avoid EOVERFLOW */ - const size_t cfr_max = MIN(maxlen, (size_t)SSIZE_MAX); - - /* copy_file_range() is a Linux-specific system call which allows efficient copying - * between two file descriptors, eliminating the need to transfer data from the kernel - * to userspace and back. For networking file systems like NFS and Ceph, it even - * eliminates copying data to the client, and local filesystems like Btrfs and XFS can - * create shared extents. */ - ssize_t result = copy_file_range(src_fd, NULL, dest_fd, NULL, cfr_max, 0); - if (result > 0) { - size_t nbytes = (size_t)result; - haveread += nbytes; - - src->position += nbytes; - dest->position += nbytes; - - if ((maxlen != PHP_STREAM_COPY_ALL && nbytes == maxlen) || php_stream_eof(src)) { - /* the whole request was satisfied or end-of-file reached - done */ - *len = haveread; - return SUCCESS; - } - - /* there may be more data; continue copying using the fallback code below */ - } else if (result == 0) { - /* end of file */ - *len = haveread; - return SUCCESS; - } else if (result < 0) { - switch (errno) { - case EINVAL: - /* some formal error, e.g. overlapping file ranges */ - break; - - case EXDEV: - /* pre Linux 5.3 error */ - break; - - case ENOSYS: - /* not implemented by this Linux kernel */ - break; - - case EIO: - /* Some filesystems will cause failures if the max length is greater than the file length - * in certain circumstances and configuration. In those cases the errno is EIO and we will - * fall back to other methods. We cannot use stat to determine the file length upfront because - * that is prone to races and outdated caching. */ - break; - - default: - /* unexpected I/O error - give up, no fallback */ - *len = haveread; - return FAILURE; - } - - /* fall back to classic copying */ - } - } - } -#endif // HAVE_COPY_FILE_RANGE if (maxlen == PHP_STREAM_COPY_ALL) { maxlen = 0; } - if (php_stream_mmap_possible(src)) { - char *p; - - do { - /* We must not modify maxlen here, because otherwise the file copy fallback below can fail */ - size_t chunk_size, must_read, mapped; - if (maxlen == 0) { - /* Unlimited read */ - must_read = chunk_size = PHP_STREAM_MMAP_MAX; - } else { - must_read = maxlen - haveread; - if (must_read >= PHP_STREAM_MMAP_MAX) { - chunk_size = PHP_STREAM_MMAP_MAX; - } else { - /* In case the length we still have to read from the file could be smaller than the file size, - * chunk_size must not get bigger the size we're trying to read. */ - chunk_size = must_read; - } - } - - p = php_stream_mmap_range(src, php_stream_tell(src), chunk_size, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped); - - if (p) { - ssize_t didwrite; - - if (php_stream_seek(src, mapped, SEEK_CUR) != 0) { - php_stream_mmap_unmap(src); - break; - } - - didwrite = php_stream_write(dest, p, mapped); - if (didwrite < 0) { - *len = haveread; - php_stream_mmap_unmap(src); - return FAILURE; - } - - php_stream_mmap_unmap(src); - - *len = haveread += didwrite; - - /* we've got at least 1 byte to read - * less than 1 is an error - * AND read bytes match written */ - if (mapped == 0 || mapped != didwrite) { - return FAILURE; - } - if (mapped < chunk_size) { - return SUCCESS; - } - /* If we're not reading as much as possible, so a bounded read */ - if (maxlen != 0) { - must_read -= mapped; - if (must_read == 0) { - return SUCCESS; - } - } - } - } while (p); - } - - while(1) { + while (1) { size_t readchunk = sizeof(buf); ssize_t didread; char *writeptr; @@ -1809,14 +1614,14 @@ PHPAPI zend_result _php_stream_copy_to_stream_ex(php_stream *src, php_stream *de return didread < 0 ? FAILURE : SUCCESS; } - towrite = didread; + size_t towrite = didread; writeptr = buf; haveread += didread; while (towrite) { ssize_t didwrite = php_stream_write(dest, writeptr, towrite); if (didwrite <= 0) { - *len = haveread - (didread - towrite); + *len = haveread - towrite; return FAILURE; } @@ -1833,6 +1638,53 @@ PHPAPI zend_result _php_stream_copy_to_stream_ex(php_stream *src, php_stream *de return SUCCESS; } +PHPAPI zend_result _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC) +{ + size_t dummy; + + if (!len) { + len = &dummy; + } + + if (maxlen == 0) { + *len = 0; + return SUCCESS; + } + + /* Try optimized fd-level copy if both streams support it and their read buffers + * are empty, so the fd offsets match the logical stream positions */ + if (!php_stream_is(src, PHP_STREAM_IS_USERSPACE) && !php_stream_is(dest, PHP_STREAM_IS_USERSPACE) && + src->writepos == src->readpos && dest->writepos == dest->readpos && + !php_stream_is_filtered(src) && !php_stream_is_filtered(dest)) { + php_io_fd src_copy_fd, dest_copy_fd; + + if (php_stream_cast(src, PHP_STREAM_AS_FD_FOR_COPY, (void *) &src_copy_fd, 0) == SUCCESS && + php_stream_cast(dest, PHP_STREAM_AS_FD_FOR_COPY, (void *) &dest_copy_fd, 0) == SUCCESS) { + + /* copy_file_range does not work with O_APPEND */ + if (src_copy_fd.fd_type == PHP_IO_FD_FILE && dest_copy_fd.fd_type == PHP_IO_FD_FILE) { + int dest_flags = 0; + if (php_stream_parse_fopen_modes(dest->mode, &dest_flags) == SUCCESS + && (dest_flags & O_APPEND)) { + goto fallback; + } + } + + size_t io_maxlen = (maxlen == PHP_STREAM_COPY_ALL) ? PHP_IO_COPY_ALL : maxlen; + size_t copied = 0; + zend_result result = php_io_copy(&src_copy_fd, &dest_copy_fd, io_maxlen, &copied); + + src->position += copied; + dest->position += copied; + *len = copied; + return result; + } + } + +fallback: + return php_stream_copy_fallback(src, dest, maxlen, len); +} + /* Returns the number of bytes moved. * Returns 1 when source len is 0. * Deprecated in favor of php_stream_copy_to_stream_ex() */ @@ -1878,14 +1730,16 @@ void php_shutdown_stream_hashes(void) FG(stream_filters) = NULL; } - if (FG(wrapper_errors)) { - zend_hash_destroy(FG(wrapper_errors)); - efree(FG(wrapper_errors)); - FG(wrapper_errors) = NULL; + if (FG(wrapper_logged_errors)) { + zend_hash_destroy(FG(wrapper_logged_errors)); + efree(FG(wrapper_logged_errors)); + FG(wrapper_logged_errors) = NULL; } + + php_stream_error_state_cleanup(); } -zend_result php_init_stream_wrappers(int module_number) +void php_init_stream_wrappers(int module_number) { le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number); @@ -1897,16 +1751,12 @@ zend_result php_init_stream_wrappers(int module_number) zend_hash_init(php_get_stream_filters_hash_global(), 8, NULL, NULL, 1); zend_hash_init(php_stream_xport_get_hash(), 8, NULL, NULL, 1); - return (php_stream_xport_register("tcp", php_stream_generic_socket_factory) == SUCCESS - && - php_stream_xport_register("udp", php_stream_generic_socket_factory) == SUCCESS + php_stream_xport_register("tcp", php_stream_generic_socket_factory); + php_stream_xport_register("udp", php_stream_generic_socket_factory); #if defined(AF_UNIX) && !(defined(PHP_WIN32) || defined(__riscos__)) - && - php_stream_xport_register("unix", php_stream_generic_socket_factory) == SUCCESS - && - php_stream_xport_register("udg", php_stream_generic_socket_factory) == SUCCESS + php_stream_xport_register("unix", php_stream_generic_socket_factory); + php_stream_xport_register("udg", php_stream_generic_socket_factory); #endif - ) ? SUCCESS : FAILURE; } void php_shutdown_stream_wrappers(int module_number) @@ -1922,7 +1772,7 @@ void php_shutdown_stream_wrappers(int module_number) static inline zend_result php_stream_wrapper_scheme_validate(const char *protocol, size_t protocol_len) { for (size_t i = 0; i < protocol_len; i++) { - if (!isalnum((int)protocol[i]) && + if (!isalnum((unsigned char)protocol[i]) && protocol[i] != '+' && protocol[i] != '-' && protocol[i] != '.') { @@ -2002,7 +1852,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const return (php_stream_wrapper*)((options & STREAM_LOCATE_WRAPPERS_ONLY) ? NULL : &php_plain_files_wrapper); } - for (p = path; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + for (p = path; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; } @@ -2049,7 +1899,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (!localhost && path[n+3] != '\0' && path[n+3] != '/') { #endif if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Remote host file access not supported, %s", path); + php_stream_wrapper_warn(plain_files_wrapper, NULL, options, + ProtocolUnsupported, + "Remote host file access not supported, %s", path); } return NULL; } @@ -2088,7 +1940,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const } if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "file:// wrapper is disabled in the server configuration"); + php_stream_wrapper_warn(plain_files_wrapper, NULL, options, + Disabled, + "file:// wrapper is disabled in the server configuration"); } return NULL; } @@ -2186,10 +2040,12 @@ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, stream->flags |= PHP_STREAM_FLAG_NO_BUFFER | PHP_STREAM_FLAG_IS_DIR; } } else if (wrapper) { - php_stream_wrapper_log_error(wrapper, options & ~REPORT_ERRORS, "not implemented"); + php_stream_wrapper_log_warn(wrapper, context, options & ~REPORT_ERRORS, + NoOpener, "not implemented"); } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "Failed to open directory"); + php_stream_display_wrapper_errors(wrapper, context, PHP_STREAM_EC(OpenFailed), + "Failed to open directory"); } php_stream_tidy_wrapper_error_log(wrapper); @@ -2256,16 +2112,25 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options); if ((options & STREAM_USE_URL) && (!wrapper || !wrapper->is_url)) { - php_error_docref(NULL, E_WARNING, "This function may only be used against URLs"); + if (wrapper) { + php_stream_wrapper_warn(wrapper, context, options, + ProtocolUnsupported, + "This function may only be used against URLs"); + } else { + php_error_docref(NULL, E_WARNING, "This function may only be used against URLs"); + } if (resolved_path) { zend_string_release_ex(resolved_path, 0); } return NULL; } + /* wrapper name needs to be stored as wrapper can be removed in opener (user stream) */ + char *wrapper_name = pestrdup(PHP_STREAM_ERROR_WRAPPER_NAME(wrapper), persistent); if (wrapper) { if (!wrapper->wops->stream_opener) { - php_stream_wrapper_log_error(wrapper, options & ~REPORT_ERRORS, + php_stream_wrapper_log_warn(wrapper, context, options & ~REPORT_ERRORS, + NoOpener, "wrapper does not support stream open"); } else { stream = wrapper->wops->stream_opener(wrapper, @@ -2276,7 +2141,8 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod /* if the caller asked for a persistent stream but the wrapper did not * return one, force an error here */ if (stream && persistent && !stream->is_persistent) { - php_stream_wrapper_log_error(wrapper, options & ~REPORT_ERRORS, + php_stream_wrapper_log_warn(wrapper, context, options & ~REPORT_ERRORS, + PersistentNotSupported, "wrapper does not support persistent streams"); php_stream_close(stream); stream = NULL; @@ -2300,6 +2166,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod stream->open_filename = __zend_orig_filename ? __zend_orig_filename : __zend_filename; stream->open_lineno = __zend_orig_lineno ? __zend_orig_lineno : __zend_lineno; #endif + /* Attach an explicitly provided context to the stream, but never the + * default context: sharing it by reference would let a later + * stream_context_set_option() on the stream mutate the global default + * context, leaking options into every other stream. Stream errors fall + * back to the default context on their own when the stream has none. */ + if (stream->ctx == NULL && context != NULL && context != FG(default_context) && !persistent) { + php_stream_context_set(stream, context); + } } if (stream != NULL && (options & STREAM_MUST_SEEK)) { @@ -2312,6 +2186,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod if (resolved_path) { zend_string_release_ex(resolved_path, 0); } + pefree(wrapper_name, persistent); return stream; case PHP_STREAM_RELEASED: if (newstream->orig_path) { @@ -2321,19 +2196,16 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod if (resolved_path) { zend_string_release_ex(resolved_path, 0); } + pefree(wrapper_name, persistent); return newstream; default: php_stream_close(stream); stream = NULL; - if (options & REPORT_ERRORS) { - char *tmp = estrdup(path); - php_strip_url_passwd(tmp); - php_error_docref1(NULL, tmp, E_WARNING, "could not make seekable - %s", - tmp); - efree(tmp); - - options &= ~REPORT_ERRORS; - } + php_stream_wrapper_warn(wrapper, context, options, + SeekNotSupported, + "could not make seekable - %s", path); + /* We do not want multiple errors so we negate it */ + options &= ~REPORT_ERRORS; } } @@ -2347,13 +2219,15 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "Failed to open stream"); + php_stream_display_wrapper_name_errors(wrapper_name, context, PHP_STREAM_EC(OpenFailed), + "Failed to open stream"); if (opened_path && *opened_path) { zend_string_release_ex(*opened_path, 0); *opened_path = NULL; } } - php_stream_tidy_wrapper_error_log(wrapper); + php_stream_tidy_wrapper_name_error_log(wrapper_name); + pefree(wrapper_name, persistent); if (resolved_path) { zend_string_release_ex(resolved_path, 0); } diff --git a/main/streams/transports.c b/main/streams/transports.c index 83297d9a06ce..ca0ab7a3d310 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -16,7 +14,7 @@ #include "php.h" #include "php_streams_int.h" -#include "ext/standard/file.h" +#include "ext/standard/file.h" /* For FG(default_socket_timeout) */ static HashTable xport_hash; @@ -25,27 +23,26 @@ PHPAPI HashTable *php_stream_xport_get_hash(void) return &xport_hash; } -PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory) +PHPAPI void php_stream_xport_register(const char *protocol, php_stream_transport_factory factory) { - zend_string *str = zend_string_init_interned(protocol, strlen(protocol), 1); + zend_string *str = zend_string_init_interned(protocol, strlen(protocol), true); zend_hash_update_ptr(&xport_hash, str, factory); - zend_string_release_ex(str, 1); - return SUCCESS; + zend_string_release_ex(str, true); } -PHPAPI int php_stream_xport_unregister(const char *protocol) +PHPAPI zend_result php_stream_xport_unregister(const char *protocol) { return zend_hash_str_del(&xport_hash, protocol, strlen(protocol)); } -#define ERR_REPORT(out_err, fmt, arg) \ +#define ERR_REPORT(code, out_err, fmt, arg) \ if (out_err) { *out_err = strpprintf(0, fmt, arg); } \ - else { php_error_docref(NULL, E_WARNING, fmt, arg); } + else { php_stream_wrapper_warn(NULL, NULL, REPORT_ERRORS, code, fmt, arg); } -#define ERR_RETURN(out_err, local_err, fmt) \ +#define ERR_RETURN(code, out_err, local_err, fmt) \ if (out_err) { *out_err = local_err; } \ - else { php_error_docref(NULL, E_WARNING, fmt, local_err ? ZSTR_VAL(local_err) : "Unspecified error"); \ + else { php_stream_wrapper_warn(NULL, NULL, REPORT_ERRORS, code, fmt, local_err ? ZSTR_VAL(local_err) : "Unspecified error"); \ if (local_err) { zend_string_release_ex(local_err, 0); local_err = NULL; } \ } @@ -95,7 +92,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in } orig_path = name; - for (p = name; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + for (p = name; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; } @@ -116,7 +113,8 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in n = sizeof(wrapper_name) - 1; PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n); - ERR_REPORT(error_string, "Unable to find the socket transport \"%s\" - did you forget to enable it when you configured PHP?", + ERR_REPORT(WrapperNotFound, error_string, + "Unable to find the socket transport \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); return NULL; @@ -125,7 +123,8 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in if (factory == NULL) { /* should never happen */ - php_error_docref(NULL, E_WARNING, "Could not find a factory !?"); + php_stream_wrapper_warn(NULL, context, REPORT_ERRORS, + WrapperNotFound, "Could not find a factory !?"); return NULL; } @@ -146,7 +145,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in flags & STREAM_XPORT_CONNECT_ASYNC ? 1 : 0, timeout, &error_text, error_code)) { - ERR_RETURN(error_string, error_text, "connect() failed: %s"); + ERR_RETURN(ConnectFailed, error_string, error_text, "connect() failed: %s"); failed = true; } @@ -156,7 +155,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in /* server */ if (flags & STREAM_XPORT_BIND) { if (0 != php_stream_xport_bind(stream, name, namelen, &error_text)) { - ERR_RETURN(error_string, error_text, "bind() failed: %s"); + ERR_RETURN(BindFailed, error_string, error_text, "bind() failed: %s"); failed = true; } else if (flags & STREAM_XPORT_LISTEN) { zval *zbacklog = NULL; @@ -167,7 +166,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in } if (0 != php_stream_xport_listen(stream, backlog, &error_text)) { - ERR_RETURN(error_string, error_text, "listen() failed: %s"); + ERR_RETURN(ListenFailed, error_string, error_text, "listen() failed: %s"); failed = true; } } @@ -370,7 +369,8 @@ PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_cr return param.outputs.returncode; } - php_error_docref("streams.crypto", E_WARNING, "This stream does not support SSL/crypto"); + php_stream_warn_docref(stream, "streams.crypto", SslNotSupported, + "This stream does not support SSL/crypto"); return ret; } @@ -390,11 +390,32 @@ PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate) return param.outputs.returncode; } - php_error_docref("streams.crypto", E_WARNING, "This stream does not support SSL/crypto"); + php_stream_warn_docref(stream, "streams.crypto", SslNotSupported, + "This stream does not support SSL/crypto"); return ret; } +PHPAPI int php_stream_xport_crypto_get_status(php_stream *stream) +{ + php_stream_xport_crypto_param param; + int ret; + + memset(¶m, 0, sizeof(param)); + param.op = STREAM_XPORT_CRYPTO_OP_GET_STATUS; + + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_CRYPTO_API, 0, ¶m); + + if (ret == PHP_STREAM_OPTION_RETURN_OK) { + return param.outputs.returncode; + } + + php_stream_warn_docref(stream, "streams.crypto", SslNotSupported, + "This stream does not support SSL/crypto"); + + return STREAM_CRYPTO_STATUS_NONE; +} + /* Similar to recv() system call; read data from the stream, optionally * peeking, optionally retrieving OOB data */ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen, @@ -412,7 +433,8 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle } if (stream->readfilters.head) { - php_error_docref(NULL, E_WARNING, "Cannot peek or fetch OOB data from a filtered stream"); + php_stream_warn(stream, FilterFailed, + "Cannot peek or fetch OOB data from a filtered stream"); return -1; } @@ -482,7 +504,8 @@ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t b oob = (flags & STREAM_OOB) == STREAM_OOB; if ((oob || addr) && stream->writefilters.head) { - php_error_docref(NULL, E_WARNING, "Cannot write OOB data, or data to a targeted address on a filtered stream"); + php_stream_warn(stream, FilterFailed, + "Cannot write OOB data, or data to a targeted address on a filtered stream"); return -1; } diff --git a/main/streams/userspace.c b/main/streams/userspace.c index f5e25aa96c77..9b6f283c075d 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Sara Golemon | @@ -251,10 +249,7 @@ typedef struct _php_userstream_data php_userstream_data_t; static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context, zval *object) { - if (uwrap->ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { - ZVAL_UNDEF(object); - return; - } + ZEND_ASSERT((uwrap->ce->ce_flags & ZEND_ACC_UNINSTANTIABLE) == 0); /* create an instance of our class */ if (object_init_ex(object, uwrap->ce) == FAILURE) { @@ -293,7 +288,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { - php_stream_wrapper_log_error(wrapper, options, "infinite recursion prevented"); + php_stream_wrapper_log_warn(wrapper, context, options, + RecursionDetected, "infinite recursion prevented"); return NULL; } FG(user_stream_current_filename) = filename; @@ -334,8 +330,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * zval_ptr_dtor(&args[0]); if (UNEXPECTED(call_result == FAILURE)) { - php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" is not implemented", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_wrapper_log_warn(wrapper, context, options,NotImplemented, + "\"%s::" USERSTREAM_OPEN "\" is not implemented", ZSTR_VAL(us->wrapper->ce->name)); zval_ptr_dtor(&args[3]); goto end; } @@ -357,8 +353,9 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * /* set wrapper data to be a reference to our object */ ZVAL_COPY(&stream->wrapperdata, &us->object); } else { - php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_wrapper_log_warn(wrapper, context, options, + UserspaceCallFailed, + "\"%s::" USERSTREAM_OPEN "\" call failed", ZSTR_VAL(us->wrapper->ce->name)); } zval_ptr_dtor(&zretval); @@ -394,7 +391,8 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { - php_stream_wrapper_log_error(wrapper, options, "infinite recursion prevented"); + php_stream_wrapper_log_warn(wrapper, context, options, + RecursionDetected, "infinite recursion prevented"); return NULL; } FG(user_stream_current_filename) = filename; @@ -419,8 +417,9 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char zval_ptr_dtor(&args[0]); if (UNEXPECTED(call_result == FAILURE)) { - php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" is not implemented", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_wrapper_log_warn(wrapper, context, options, NotImplemented, + "\"%s::" USERSTREAM_DIR_OPEN "\" is not implemented", + ZSTR_VAL(us->wrapper->ce->name)); goto end; } /* Exception occurred in call */ @@ -435,8 +434,9 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char /* set wrapper data to be a reference to our object */ ZVAL_COPY(&stream->wrapperdata, &us->object); } else { - php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_wrapper_log_warn(wrapper, context, options, + UserspaceCallFailed, + "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", ZSTR_VAL(us->wrapper->ce->name)); } zval_ptr_dtor(&zretval); @@ -464,6 +464,11 @@ PHP_FUNCTION(stream_wrapper_register) RETURN_THROWS(); } + if (UNEXPECTED(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { + zend_argument_value_error(2, "must be a concrete class"); + RETURN_THROWS(); + } + uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap)); uwrap->ce = ce; uwrap->wrapper.wops = &user_stream_wops; @@ -479,10 +484,15 @@ PHP_FUNCTION(stream_wrapper_register) /* We failed. But why? */ if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) { - php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol)); + php_stream_wrapper_warn(&uwrap->wrapper, NULL, REPORT_ERRORS, + WrapperRegistrationFailed, + "Protocol %s:// is already defined.", ZSTR_VAL(protocol)); } else { /* Hash doesn't exist so it must have been an invalid protocol scheme */ - php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(uwrap->ce->name), ZSTR_VAL(protocol)); + php_stream_wrapper_warn(&uwrap->wrapper, NULL, REPORT_ERRORS, + WrapperRegistrationFailed, + "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", + ZSTR_VAL(uwrap->ce->name), ZSTR_VAL(protocol)); } zend_list_delete(rsrc); @@ -502,7 +512,9 @@ PHP_FUNCTION(stream_wrapper_unregister) php_stream_wrapper *wrapper = zend_hash_find_ptr(php_stream_get_url_stream_wrappers_hash(), protocol); if (php_unregister_url_stream_wrapper_volatile(protocol) == FAILURE) { /* We failed */ - php_error_docref(NULL, E_WARNING, "Unable to unregister protocol %s://", ZSTR_VAL(protocol)); + php_stream_wrapper_warn(wrapper, NULL, REPORT_ERRORS, + WrapperUnregistrationFailed, + "Unable to unregister protocol %s://", ZSTR_VAL(protocol)); RETURN_FALSE; } @@ -530,13 +542,17 @@ PHP_FUNCTION(stream_wrapper_restore) global_wrapper_hash = php_stream_get_url_stream_wrappers_hash_global(); if ((wrapper = zend_hash_find_ptr(global_wrapper_hash, protocol)) == NULL) { - php_error_docref(NULL, E_WARNING, "%s:// never existed, nothing to restore", ZSTR_VAL(protocol)); + php_stream_wrapper_warn_name(user_stream_wops.label, NULL, REPORT_ERRORS, + WrapperNotFound, + "%s:// never existed, nothing to restore", ZSTR_VAL(protocol)); RETURN_FALSE; } wrapper_hash = php_stream_get_url_stream_wrappers_hash(); if (wrapper_hash == global_wrapper_hash || zend_hash_find_ptr(wrapper_hash, protocol) == wrapper) { - php_error_docref(NULL, E_NOTICE, "%s:// was never changed, nothing to restore", ZSTR_VAL(protocol)); + php_stream_wrapper_notice(wrapper, NULL, REPORT_ERRORS, + WrapperRestorationFailed, + "%s:// was never changed, nothing to restore", ZSTR_VAL(protocol)); RETURN_TRUE; } @@ -544,7 +560,9 @@ PHP_FUNCTION(stream_wrapper_restore) php_unregister_url_stream_wrapper_volatile(protocol); if (php_register_url_stream_wrapper_volatile(protocol, wrapper) == FAILURE) { - php_error_docref(NULL, E_WARNING, "Unable to restore original %s:// wrapper", ZSTR_VAL(protocol)); + php_stream_wrapper_warn(wrapper, NULL, REPORT_ERRORS, + WrapperRestorationFailed, + "Unable to restore original %s:// wrapper", ZSTR_VAL(protocol)); RETURN_FALSE; } @@ -572,8 +590,8 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_ zval_ptr_dtor(&args[0]); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_WRITE " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); } stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; @@ -593,7 +611,9 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_ /* don't allow strange buffer overruns due to bogus return */ if (didwrite > 0 && didwrite > count) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " wrote " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " written, " ZEND_LONG_FMT " max)", + php_stream_warn_nt(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_WRITE " wrote " ZEND_LONG_FMT " bytes more data than requested (" + ZEND_LONG_FMT " written, " ZEND_LONG_FMT " max)", ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count); didwrite = count; @@ -624,8 +644,8 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count } if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_READ " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); goto err; } @@ -641,8 +661,12 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count didread = Z_STRLEN(retval); if (didread > 0) { if (didread > count) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " read, " ZEND_LONG_FMT " max) - excess data will be lost", - ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didread - count), (zend_long)didread, (zend_long)count); + php_stream_warn_nt(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT + " bytes more data than requested (" ZEND_LONG_FMT " read, " + ZEND_LONG_FMT " max) - excess data will be lost", + ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didread - count), + (zend_long)didread, (zend_long)count); didread = count; } memcpy(buf, Z_STRVAL(retval), didread); @@ -658,7 +682,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, NotImplemented, "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", ZSTR_VAL(us->wrapper->ce->name)); stream->eof = 1; @@ -774,7 +798,8 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when *newoffs = Z_LVAL(retval); ret = 0; } else if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); ret = -1; } else { ret = -1; @@ -838,8 +863,8 @@ static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb) zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_STAT " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); return -1; } if (UNEXPECTED(Z_ISUNDEF(retval))) { @@ -857,7 +882,7 @@ static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb) return ret; } -static int user_stream_set_check_liveliness(const php_userstream_data_t *us) +static int user_stream_set_check_liveliness(php_stream *stream, const php_userstream_data_t *us) { zval retval; @@ -866,7 +891,7 @@ static int user_stream_set_check_liveliness(const php_userstream_data_t *us) zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, NotImplemented, "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", ZSTR_VAL(us->wrapper->ce->name)); return PHP_STREAM_OPTION_RETURN_ERR; @@ -877,15 +902,15 @@ static int user_stream_set_check_liveliness(const php_userstream_data_t *us) if (EXPECTED(Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { return Z_TYPE(retval) == IS_TRUE ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; } else { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_EOF " value must be of type bool, %s given", + php_stream_warn(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_EOF " value must be of type bool, %s given", ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); zval_ptr_dtor(&retval); return PHP_STREAM_OPTION_RETURN_ERR; } } -static int user_stream_set_locking(const php_userstream_data_t *us, int value) +static int user_stream_set_locking(php_stream *stream, const php_userstream_data_t *us, int value) { zval retval; zval zlock; @@ -920,9 +945,8 @@ static int user_stream_set_locking(const php_userstream_data_t *us, int value) /* lock support test (TODO: more check) */ return PHP_STREAM_OPTION_RETURN_OK; } - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_LOCK " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_LOCK " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); return PHP_STREAM_OPTION_RETURN_ERR; } if (UNEXPECTED(Z_ISUNDEF(retval))) { @@ -934,14 +958,15 @@ static int user_stream_set_locking(const php_userstream_data_t *us, int value) } // TODO: ext/standard/tests/file/userstreams_004.phpt returns null implicitly for function // Should this warn or not? And should this be considered an error? - //php_error_docref(NULL, E_WARNING, - // "%s::" USERSTREAM_LOCK " value must be of type bool, %s given", + //php_stream_warn(stream, UserspaceInvalidReturn, + // "%s::" USERSTREAM_LOCK " value must be of type bool, %s given", // ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); zval_ptr_dtor(&retval); return PHP_STREAM_OPTION_RETURN_NOTIMPL; } -static int user_stream_set_truncation(const php_userstream_data_t *us, int value, void *ptrparam) { +static int user_stream_set_truncation(php_stream *stream, const php_userstream_data_t *us, + int value, void *ptrparam) { zend_string *func_name = ZSTR_INIT_LITERAL(USERSTREAM_TRUNCATE, false); if (value == PHP_STREAM_TRUNCATE_SUPPORTED) { @@ -969,9 +994,8 @@ static int user_stream_set_truncation(const php_userstream_data_t *us, int value zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_TRUNCATE " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_TRUNCATE " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); return PHP_STREAM_OPTION_RETURN_ERR; } if (UNEXPECTED(Z_ISUNDEF(retval))) { @@ -980,15 +1004,16 @@ static int user_stream_set_truncation(const php_userstream_data_t *us, int value if (EXPECTED(Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { return Z_TYPE(retval) == IS_TRUE ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; } else { - php_error_docref(NULL, E_WARNING, - "%s::" USERSTREAM_TRUNCATE " value must be of type bool, %s given", + php_stream_warn(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_TRUNCATE " value must be of type bool, %s given", ZSTR_VAL(us->wrapper->ce->name), zend_zval_value_name(&retval)); zval_ptr_dtor(&retval); return PHP_STREAM_OPTION_RETURN_ERR; } } -static int user_stream_set_option(const php_userstream_data_t *us, int option, int value, void *ptrparam) +static int user_stream_set_option(php_stream *stream, const php_userstream_data_t *us, int option, + int value, void *ptrparam) { zval args[3]; ZVAL_LONG(&args[0], option); @@ -1013,7 +1038,7 @@ static int user_stream_set_option(const php_userstream_data_t *us, int option, i zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, + php_stream_warn(stream, NotImplemented, "%s::" USERSTREAM_SET_OPTION " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); return PHP_STREAM_OPTION_RETURN_ERR; @@ -1038,19 +1063,19 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value switch (option) { case PHP_STREAM_OPTION_CHECK_LIVENESS: - return user_stream_set_check_liveliness(us); + return user_stream_set_check_liveliness(stream, us); case PHP_STREAM_OPTION_LOCKING: - return user_stream_set_locking(us, value); + return user_stream_set_locking(stream, us, value); case PHP_STREAM_OPTION_TRUNCATE_API: - return user_stream_set_truncation(us, value, ptrparam); + return user_stream_set_truncation(stream, us, value, ptrparam); case PHP_STREAM_OPTION_READ_BUFFER: case PHP_STREAM_OPTION_WRITE_BUFFER: case PHP_STREAM_OPTION_READ_TIMEOUT: case PHP_STREAM_OPTION_BLOCKING: - return user_stream_set_option(us, option, value, ptrparam); + return user_stream_set_option(stream, us, option, value, ptrparam); default: return PHP_STREAM_OPTION_RETURN_NOTIMPL; @@ -1083,7 +1108,8 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name)); } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { ret = Z_TYPE(zretval) == IS_TRUE; } @@ -1121,7 +1147,8 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name)); } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { ret = Z_TYPE(zretval) == IS_TRUE; } @@ -1159,7 +1186,8 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { ret = Z_TYPE(zretval) == IS_TRUE; } @@ -1196,7 +1224,8 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name)); } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { ret = Z_TYPE(zretval) == IS_TRUE; } @@ -1235,7 +1264,9 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i ZVAL_STRING(&args[2], value); break; default: - php_error_docref(NULL, E_WARNING, "Unknown option %d for " USERSTREAM_METADATA, option); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + InvalidMeta, + "Unknown option %d for " USERSTREAM_METADATA, option); return ret; } @@ -1258,7 +1289,8 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name)); } else if (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE) { ret = Z_TYPE(zretval) == IS_TRUE; } @@ -1296,8 +1328,8 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i zval_ptr_dtor(&object); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", - ZSTR_VAL(uwrap->ce->name)); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, NotImplemented, + "%s::" USERSTREAM_STATURL " is not implemented!", ZSTR_VAL(uwrap->ce->name)); return -1; } if (UNEXPECTED(Z_ISUNDEF(zretval))) { @@ -1332,8 +1364,9 @@ static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t co zend_string_release_ex(func_name, false); if (UNEXPECTED(call_result == FAILURE)) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", - ZSTR_VAL(us->wrapper->ce->name)); + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_DIR_READ " is not implemented!", + ZSTR_VAL(us->wrapper->ce->name)); return -1; } if (UNEXPECTED(Z_ISUNDEF(retval))) { @@ -1418,7 +1451,8 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) if (UNEXPECTED(call_result == FAILURE)) { if (report_errors) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", + php_stream_warn(stream, NotImplemented, + "%s::" USERSTREAM_CAST " is not implemented!", ZSTR_VAL(us->wrapper->ce->name)); } goto out; @@ -1432,14 +1466,16 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) php_stream_from_zval_no_verify(intstream, &retval); if (!intstream) { if (report_errors) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource", + php_stream_warn(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_CAST " must return a stream resource", ZSTR_VAL(us->wrapper->ce->name)); } break; } if (intstream == stream) { if (report_errors) { - php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself", + php_stream_warn(stream, UserspaceInvalidReturn, + "%s::" USERSTREAM_CAST " must not return itself", ZSTR_VAL(us->wrapper->ce->name)); } intstream = NULL; diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index 9eae9e460e47..3eef731544de 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -17,7 +15,7 @@ #include "php.h" #include "ext/standard/file.h" #include "php_streams.h" -#include "php_network.h" +#include "php_io.h" #if defined(PHP_WIN32) || defined(__riscos__) # undef AF_UNIX @@ -116,9 +114,8 @@ static ssize_t php_sockop_write(php_stream *stream, const char *buf, size_t coun if (!(stream->flags & PHP_STREAM_FLAG_SUPPRESS_ERRORS)) { estr = php_socket_strerror(err, NULL, 0); - php_error_docref(NULL, E_NOTICE, - "Send of %zu bytes failed with errno=%d %s", - count, err, estr); + php_stream_warn(stream, NetworkSendFailed, + "Send of %zu bytes failed with errno=%d %s", count, err, estr); efree(estr); } } @@ -454,8 +451,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void xparam->inputs.addrlen); if (xparam->outputs.returncode == -1) { char *err = php_socket_strerror(php_socket_errno(), NULL, 0); - php_error_docref(NULL, E_WARNING, - "%s\n", err); + php_stream_warn(stream, NetworkSendFailed, "%s", err); efree(err); } return PHP_STREAM_OPTION_RETURN_OK; @@ -527,11 +523,19 @@ static int php_sockop_cast(php_stream *stream, int castas, void **ret) if (ret) *(php_socket_t *)ret = sock->socket; return SUCCESS; + case PHP_STREAM_AS_FD_FOR_COPY: + if (ret) { + php_io_fd *copy_fd = (php_io_fd *) ret; + copy_fd->socket = sock->socket; + copy_fd->fd_type = PHP_IO_FD_SOCKET; + copy_fd->timeout = sock->timeout; + copy_fd->is_blocked = sock->is_blocked; + } + return SUCCESS; default: return FAILURE; } } -/* }}} */ /* These may look identical, but we need them this way so that * we can determine which type of socket we are dealing with @@ -595,7 +599,8 @@ static const php_stream_ops php_stream_unixdg_socket_ops = { /* network socket operations */ #ifdef AF_UNIX -static inline int parse_unix_address(php_stream_xport_param *xparam, struct sockaddr_un *unix_addr) +static inline int parse_unix_address(php_stream *stream, php_stream_xport_param *xparam, + struct sockaddr_un *unix_addr) { memset(unix_addr, 0, sizeof(*unix_addr)); unix_addr->sun_family = AF_UNIX; @@ -614,9 +619,9 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock * BUT, to get into this branch of code, the name is too long, * so we don't care. */ xparam->inputs.namelen = max_length; - php_error_docref(NULL, E_NOTICE, - "socket path exceeded the maximum allowed length of %lu bytes " - "and was truncated", max_length); + php_stream_notice(stream, InvalidPath, + "socket path exceeded the maximum allowed length of %lu bytes and was truncated", + max_length); } memcpy(unix_addr->sun_path, xparam->inputs.name, xparam->inputs.namelen); @@ -697,10 +702,15 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t * return -1; } - parse_unix_address(xparam, &unix_addr); + parse_unix_address(stream, xparam, &unix_addr); - return bind(sock->socket, (const struct sockaddr *)&unix_addr, - (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + xparam->inputs.namelen); + int result = bind(sock->socket, (const struct sockaddr *)&unix_addr, + (socklen_t) offsetof(struct sockaddr_un, sun_path) + xparam->inputs.namelen); + if (result == -1 && xparam->want_errortext) { + char errstr[256]; + xparam->outputs.error_text = strpprintf(0, "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + } + return result; } #endif @@ -828,10 +838,10 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_ return -1; } - parse_unix_address(xparam, &unix_addr); + parse_unix_address(stream, xparam, &unix_addr); ret = php_network_connect_socket(sock->socket, - (const struct sockaddr *)&unix_addr, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + xparam->inputs.namelen, + (const struct sockaddr *)&unix_addr, (socklen_t) offsetof(struct sockaddr_un, sun_path) + xparam->inputs.namelen, xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC, xparam->inputs.timeout, xparam->want_errortext ? &xparam->outputs.error_text : NULL, &err); diff --git a/main/strlcat.c b/main/strlcat.c index b514a7e0d5d5..9590fd19229c 100644 --- a/main/strlcat.c +++ b/main/strlcat.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/main/strlcpy.c b/main/strlcpy.c index 9ca99311aa42..f7e563967377 100644 --- a/main/strlcpy.c +++ b/main/strlcpy.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/php.ini-development b/php.ini-development index 6f93f440112e..8663f1c21de7 100644 --- a/php.ini-development +++ b/php.ini-development @@ -611,6 +611,12 @@ ignore_repeated_source = Off ; Production Value: On ;fatal_error_backtraces = On +; This directive controls whether PHP will print the actual arguments of a +; function upon an error. If this is off (or there was an error fetching the +; arguments), the function providing the error may optionally provide some +; additional information after the problem function's name. +;error_include_args = Off + ;;;;;;;;;;;;;;;;; ; Data Handling ; ;;;;;;;;;;;;;;;;; @@ -1027,7 +1033,7 @@ cli_server.color = On [Pcre] ; PCRE library backtracking limit. ; https://php.net/pcre.backtrack-limit -;pcre.backtrack_limit=100000 +;pcre.backtrack_limit=1000000 ; PCRE library recursion limit. ; Please note that if you set this value to a high number you may consume all @@ -1305,10 +1311,9 @@ session.save_handler = files ; Strict session mode does not accept an uninitialized session ID, and ; regenerates the session ID if the browser sends an uninitialized session ID. ; Strict mode protects applications from session fixation via a session adoption -; vulnerability. It is disabled by default for maximum compatibility, but -; enabling it is encouraged. +; vulnerability. ; https://wiki.php.net/rfc/strict_sessions -session.use_strict_mode = 0 +session.use_strict_mode = 1 ; Whether to use cookies. ; https://php.net/session.use-cookies @@ -1350,13 +1355,13 @@ session.cookie_domain = ; Whether or not to add the httpOnly flag to the cookie, which makes it ; inaccessible to browser scripting languages such as JavaScript. ; https://php.net/session.cookie-httponly -session.cookie_httponly = +session.cookie_httponly = 1 ; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF) ; Current valid values are "Strict", "Lax" or "None". When using "None", ; make sure to include the quotes, as `none` is interpreted like `false` in ini files. ; https://tools.ietf.org/html/draft-west-first-party-cookies-07 -session.cookie_samesite = +session.cookie_samesite = "Lax" ; Handler used to serialize data. php is the standard serializer of PHP. ; https://php.net/session.serialize-handler @@ -1386,13 +1391,6 @@ session.gc_divisor = 1000 ; https://php.net/session.gc-maxlifetime session.gc_maxlifetime = 1440 -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script is the equivalent of setting -; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; find /path/to/sessions -cmin +24 -type f | xargs rm ; Check HTTP Referer to invalidate externally stored URLs containing ids. ; HTTP_REFERER has to contain this substring for the session to be diff --git a/php.ini-production b/php.ini-production index 9aafad21e9c7..497a3774b8ed 100644 --- a/php.ini-production +++ b/php.ini-production @@ -613,6 +613,12 @@ ignore_repeated_source = Off ; Production Value: On ;fatal_error_backtraces = On +; This directive controls whether PHP will print the actual arguments of a +; function upon an error. If this is off (or there was an error fetching the +; arguments), the function providing the error may optionally provide some +; additional information after the problem function's name. +;error_include_args = Off + ;;;;;;;;;;;;;;;;; ; Data Handling ; ;;;;;;;;;;;;;;;;; @@ -1029,7 +1035,7 @@ cli_server.color = On [Pcre] ; PCRE library backtracking limit. ; https://php.net/pcre.backtrack-limit -;pcre.backtrack_limit=100000 +;pcre.backtrack_limit=1000000 ; PCRE library recursion limit. ; Please note that if you set this value to a high number you may consume all @@ -1307,10 +1313,9 @@ session.save_handler = files ; Strict session mode does not accept an uninitialized session ID, and ; regenerates the session ID if the browser sends an uninitialized session ID. ; Strict mode protects applications from session fixation via a session adoption -; vulnerability. It is disabled by default for maximum compatibility, but -; enabling it is encouraged. +; vulnerability. ; https://wiki.php.net/rfc/strict_sessions -session.use_strict_mode = 0 +session.use_strict_mode = 1 ; Whether to use cookies. ; https://php.net/session.use-cookies @@ -1352,13 +1357,13 @@ session.cookie_domain = ; Whether or not to add the httpOnly flag to the cookie, which makes it ; inaccessible to browser scripting languages such as JavaScript. ; https://php.net/session.cookie-httponly -session.cookie_httponly = +session.cookie_httponly = 1 ; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF) ; Current valid values are "Strict", "Lax" or "None". When using "None", ; make sure to include the quotes, as `none` is interpreted like `false` in ini files. ; https://tools.ietf.org/html/draft-west-first-party-cookies-07 -session.cookie_samesite = +session.cookie_samesite = "Lax" ; Handler used to serialize data. php is the standard serializer of PHP. ; https://php.net/session.serialize-handler @@ -1388,13 +1393,6 @@ session.gc_divisor = 1000 ; https://php.net/session.gc-maxlifetime session.gc_maxlifetime = 1440 -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script is the equivalent of setting -; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; find /path/to/sessions -cmin +24 -type f | xargs rm ; Check HTTP Referer to invalidate externally stored URLs containing ids. ; HTTP_REFERER has to contain this substring for the session to be diff --git a/run-extra-tests.php b/run-extra-tests.php index 725f2b58c373..16dfac69d13a 100755 --- a/run-extra-tests.php +++ b/run-extra-tests.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/run-tests.php b/run-tests.php index 68d2cb69256d..1d8be660388d 100755 --- a/run-tests.php +++ b/run-tests.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ilia Alshanetsky | | Preston L. Bannister | @@ -275,6 +273,7 @@ function main(): void 'fatal_error_backtraces=Off', 'display_errors=1', 'display_startup_errors=1', + 'error_include_args=0', 'log_errors=0', 'html_errors=0', 'track_errors=0', @@ -304,6 +303,7 @@ function main(): void 'zend.exception_ignore_args=0', 'zend.exception_string_param_max_len=15', 'short_open_tag=0', + 'date.timezone=UTC', ]; $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0'; @@ -1054,6 +1054,32 @@ function find_files(string $dir, bool $is_ext_dir = false, bool $ignore = false) closedir($o); } +function rmdir_recursive($dir) +{ + if (!file_exists($dir)) { + return; + } + if (!is_dir($dir)) { + unlink($dir); + return; + } + + $dh = opendir($dir); + if (!$dh) { + return; + } + + while (($entry = readdir($dh)) !== false) { + if ($entry === '.' || $entry === '..') { + continue; + } + rmdir_recursive($dir . DIRECTORY_SEPARATOR . $entry); + } + + closedir($dh); + rmdir($dir); +} + /** * @param array|string $name */ @@ -2065,7 +2091,11 @@ function run_test(string $php, $file, array $env): string $orig_ini_settings = settings2params($ini_settings); if ($file_cache !== null) { - $ini_settings['opcache.file_cache'] = '/tmp'; + $ini_settings['opcache.file_cache'] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php-run-tests-file-cache'; + if ($file_cache === 'prime') { + rmdir_recursive($ini_settings['opcache.file_cache']); + mkdir($ini_settings['opcache.file_cache'], recursive: true); + } // Make sure warnings still show up on the second run. $ini_settings['opcache.record_warnings'] = '1'; // File cache is currently incompatible with JIT. diff --git a/sapi/apache2handler/apache_config.c b/sapi/apache2handler/apache_config.c index a31ba68f9281..1f9447e62938 100644 --- a/sapi/apache2handler/apache_config.c +++ b/sapi/apache2handler/apache_config.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index e335721f19e9..3001a4d61d9a 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -6,6 +6,15 @@ PHP_ARG_WITH([apxs2], [no], [no]) +PHP_ARG_ENABLE([apache2-conf], + [whether to activate the PHP module in Apache httpd.conf via apxs], + [AS_HELP_STRING([--disable-apache2-conf], + [Do not activate the PHP module in the Apache httpd.conf during installation + via apxs. Useful when installing into a staging directory or when Apache + configuration is managed separately (e.g., via a2enmod).])], + [yes], + [no]) + if test "$PHP_APXS2" != "no"; then AS_VAR_IF([PHP_APXS2], [yes], [ APXS=apxs @@ -69,7 +78,7 @@ if test "$PHP_APXS2" != "no"; then [AC_MSG_ERROR([Please note that Apache version >= 2.4 is required])]) APXS_LIBEXECDIR='$(INSTALL_ROOT)'$($APXS -q LIBEXECDIR) - if test -z $($APXS -q SYSCONFDIR); then + if test -z $($APXS -q SYSCONFDIR) || test "$PHP_APACHE2_CONF" = "no"; then INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ -i -n php" diff --git a/sapi/apache2handler/mod_php.c b/sapi/apache2handler/mod_php.c index c7308fe2df60..9228b3ec049c 100644 --- a/sapi/apache2handler/mod_php.c +++ b/sapi/apache2handler/mod_php.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sascha Schumann | | Parts based on Apache 1.3 SAPI module by | diff --git a/sapi/apache2handler/php_apache.h b/sapi/apache2handler/php_apache.h index c49dd2970880..18b4e5a75910 100644 --- a/sapi/apache2handler/php_apache.h +++ b/sapi/apache2handler/php_apache.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index c2b15af86a60..1baa1f5225e0 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -179,10 +177,10 @@ PHP_FUNCTION(apache_request_headers) ctx = SG(server_context); arr = apr_table_elts(ctx->r->headers_in); - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) val = ""; add_assoc_string(return_value, key, val); - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); } /* }}} */ @@ -200,10 +198,10 @@ PHP_FUNCTION(apache_response_headers) ctx = SG(server_context); arr = apr_table_elts(ctx->r->headers_out); - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) val = ""; add_assoc_string(return_value, key, val); - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); } /* }}} */ @@ -411,12 +409,12 @@ PHP_MINFO_FUNCTION(apache) SECTION("Apache Environment"); php_info_print_table_start(); php_info_print_table_header(2, "Variable", "Value"); - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) { val = ""; } php_info_print_table_row(2, key, val); - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); php_info_print_table_end(); @@ -426,21 +424,21 @@ PHP_MINFO_FUNCTION(apache) php_info_print_table_row(2, "HTTP Request", ((php_struct *) SG(server_context))->r->the_request); arr = apr_table_elts(((php_struct *) SG(server_context))->r->headers_in); - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) { val = ""; } php_info_print_table_row(2, key, val); - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); php_info_print_table_colspan_header(2, "HTTP Response Headers"); arr = apr_table_elts(((php_struct *) SG(server_context))->r->headers_out); - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) { val = ""; } php_info_print_table_row(2, key, val); - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); php_info_print_table_end(); } diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index 2387d24741a4..83b3f02fb743 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sascha Schumann | | Parts based on Apache 1.3 SAPI module by | @@ -269,14 +267,14 @@ php_apache_sapi_register_variables(zval *track_vars_array) char *key, *val; size_t new_val_len; - APR_ARRAY_FOREACH_OPEN(arr, key, val) + APR_ARRAY_FOREACH_OPEN(arr, key, val) { if (!val) { val = ""; } if (sapi_module.input_filter(PARSE_SERVER, key, &val, strlen(val), &new_val_len)) { php_register_variable_safe(key, val, new_val_len, track_vars_array); } - APR_ARRAY_FOREACH_CLOSE() + } APR_ARRAY_FOREACH_CLOSE(); if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &ctx->r->uri, strlen(ctx->r->uri), &new_val_len)) { php_register_variable_safe("PHP_SELF", ctx->r->uri, new_val_len, track_vars_array); diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 213870db54f1..7efd8f159d59 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -97,6 +95,8 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS; # endif #endif +#include "zend_perf_stat.h" + #ifndef PHP_WIN32 /* XXX this will need to change later when threaded fastcgi is implemented. shane */ static struct sigaction act, old_term, old_quit, old_int; @@ -1735,6 +1735,7 @@ int main(int argc, char *argv[]) int warmup_repeats = 0; int repeats = 1; int benchmark = 0; + bool perf_enabled = false; #ifdef HAVE_GETTIMEOFDAY struct timeval start, end; #else @@ -2443,14 +2444,16 @@ consult the installation file that came with this distribution, or visit \n\ } } /* end !cgi && !fastcgi */ -#ifdef HAVE_VALGRIND if (warmup_repeats == 0) { + zend_perf_stat_enable(); + perf_enabled = true; +#ifdef HAVE_VALGRIND CALLGRIND_START_INSTRUMENTATION; # ifdef HAVE_VALGRIND_CACHEGRIND_H CACHEGRIND_START_INSTRUMENTATION; # endif - } #endif + } /* request startup only after we've done all we can to * get path_translated */ @@ -2570,6 +2573,10 @@ consult the installation file that came with this distribution, or visit \n\ SG(request_info).query_string = NULL; } + if (perf_enabled) { + zend_perf_stat_disable(); + perf_enabled = false; + } #ifdef HAVE_VALGRIND /* We're not interested in measuring shutdown */ CALLGRIND_STOP_INSTRUMENTATION; diff --git a/sapi/cgi/tests/001.phpt b/sapi/cgi/tests/001.phpt index c990a77efaee..00fc656f75bc 100644 --- a/sapi/cgi/tests/001.phpt +++ b/sapi/cgi/tests/001.phpt @@ -16,6 +16,6 @@ echo "Done\n"; ?> --EXPECTF-- string(%d) "PHP %s (cgi%s (built: %s -Copyright (c) The PHP Group -%AZend Engine v%s, Copyright (c) Zend Technologies%A" +Copyright © The PHP Group and Contributors +%AZend Engine v%s, Copyright © Zend by Perforce%A" Done diff --git a/sapi/cli/cli.h b/sapi/cli/cli.h index 85b55af3845d..2f6ef95052ce 100644 --- a/sapi/cli/cli.h +++ b/sapi/cli/cli.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Johannes Schlueter | +----------------------------------------------------------------------+ diff --git a/sapi/cli/generate_mime_type_map.php b/sapi/cli/generate_mime_type_map.php index c48766b0a3e5..d1a841268a97 100755 --- a/sapi/cli/generate_mime_type_map.php +++ b/sapi/cli/generate_mime_type_map.php @@ -57,15 +57,13 @@ echo <<
. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | +----------------------------------------------------------------------+ diff --git a/sapi/cli/mime_type_map.h b/sapi/cli/mime_type_map.h index 505ae862d054..689e522dbaea 100644 --- a/sapi/cli/mime_type_map.h +++ b/sapi/cli/mime_type_map.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | +----------------------------------------------------------------------+ diff --git a/sapi/cli/php.1.in b/sapi/cli/php.1.in index 797ef3242b6a..30626015ce77 100644 --- a/sapi/cli/php.1.in +++ b/sapi/cli/php.1.in @@ -456,17 +456,9 @@ contributors all around the world. .SH VERSION INFORMATION This manpage describes \fBphp\fP, version @PHP_VERSION@. .SH COPYRIGHT -Copyright \(co The PHP Group +Copyright \(co The PHP Group and Contributors .LP -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: -.PD 0 -.P -.B https://www.php.net/license/3_01.txt -.PD 1 -.P -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 -.B license@php.net -so we can mail you a copy immediately. +This source file is subject to the Modified BSD License that is +bundled with this package in the file LICENSE, and is available +through the World Wide Web at +.B https://www.php.net/license/ diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index d1781eab671c..e5e573d1533c 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | | Marcus Boerger | @@ -1056,13 +1054,25 @@ static int do_cli(int argc, char **argv) /* {{{ */ } ZVAL_STRING(&arg, reflection_what); - object_init_ex(&ref, pce); memset(&execute_data, 0, sizeof(zend_execute_data)); execute_data.func = (zend_function *) &zend_pass_function; EG(current_execute_data) = &execute_data; - zend_call_known_instance_method_with_1_params( - pce->constructor, Z_OBJ(ref), NULL, &arg); + // Avoid deprecation warnings from ReflectionMethod::__construct() + // with one argument + if (pce == reflection_method_ptr) { + zend_function *create_from_method = zend_hash_str_find_ptr( + &(pce->function_table), + "createfrommethodname", + strlen( "createFromMethodName" ) + ); + zend_call_known_function( + create_from_method, NULL, pce, &ref, 1, &arg, NULL); + } else { + object_init_ex(&ref, pce); + zend_call_known_instance_method_with_1_params( + pce->constructor, Z_OBJ(ref), NULL, &arg); + } if (EG(exception)) { zval rv; @@ -1083,10 +1093,9 @@ static int do_cli(int argc, char **argv) /* {{{ */ case PHP_CLI_MODE_REFLECTION_EXT_INFO: { size_t len = strlen(reflection_what); - char *lcname = zend_str_tolower_dup(reflection_what, len); zend_module_entry *module; - if ((module = zend_hash_str_find_ptr(&module_registry, lcname, len)) == NULL) { + if ((module = zend_hash_str_find_ptr_lc(&module_registry, reflection_what, len)) == NULL) { if (!strcmp(reflection_what, "main")) { display_ini_entries(NULL); } else { @@ -1097,7 +1106,6 @@ static int do_cli(int argc, char **argv) /* {{{ */ php_info_print_module(module); } - efree(lcname); break; } diff --git a/sapi/cli/php_cli_process_title.c b/sapi/cli/php_cli_process_title.c index fe36c9a2fdbc..5f682cb4cc93 100644 --- a/sapi/cli/php_cli_process_title.c +++ b/sapi/cli/php_cli_process_title.c @@ -1,23 +1,17 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Keyur Govande (kgovande@gmail.com) | +----------------------------------------------------------------------+ */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include "php.h" #include "php_cli_process_title.h" #include "ps_title.h" diff --git a/sapi/cli/php_cli_process_title.h b/sapi/cli/php_cli_process_title.h index 9527b4b4b6d4..3cb8c8b46162 100644 --- a/sapi/cli/php_cli_process_title.h +++ b/sapi/cli/php_cli_process_title.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Keyur Govande (kgovande@gmail.com) | +----------------------------------------------------------------------+ diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 65d6d5a898de..797979b67305 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | | Xinchen Hui | @@ -653,7 +651,7 @@ static int sapi_cli_server_register_entry_cb(zval *entry, int num_args, va_list if (key[i] == '-') { key[i] = '_'; } else { - key[i] = toupper(key[i]); + key[i] = toupper((unsigned char)key[i]); } } spprintf(&real_key, 0, "%s_%s", "HTTP", key); @@ -2648,7 +2646,7 @@ static zend_result php_cli_server_recv_event_read_request(php_cli_server *server case 0: php_cli_server_poller_add(&server->poller, POLLIN, client->sock); return SUCCESS; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } /* Under ASAN the compiler somehow doesn't realise that the switch block always returns */ return FAILURE; diff --git a/sapi/cli/php_cli_server.h b/sapi/cli/php_cli_server.h index 2440a5b59996..6477ab180fb2 100644 --- a/sapi/cli/php_cli_server.h +++ b/sapi/cli/php_cli_server.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | +----------------------------------------------------------------------+ diff --git a/sapi/cli/php_http_parser.c b/sapi/cli/php_http_parser.c index c7c2ad0caaea..ac3c19d5d963 100644 --- a/sapi/cli/php_http_parser.c +++ b/sapi/cli/php_http_parser.c @@ -82,6 +82,7 @@ static const char *method_strings[] = , "POST" , "PUT" , "PATCH" + , "QUERY" , "CONNECT" , "OPTIONS" , "TRACE" @@ -521,6 +522,7 @@ size_t php_http_parser_execute (php_http_parser *parser, case 'N': parser->method = PHP_HTTP_NOTIFY; break; case 'O': parser->method = PHP_HTTP_OPTIONS; break; case 'P': parser->method = PHP_HTTP_POST; /* or PROPFIND or PROPPATCH or PUT */ break; + case 'Q': parser->method = PHP_HTTP_QUERY; break; case 'R': parser->method = PHP_HTTP_REPORT; break; case 'S': parser->method = PHP_HTTP_SUBSCRIBE; /* or SEARCH */ break; case 'T': parser->method = PHP_HTTP_TRACE; break; diff --git a/sapi/cli/php_http_parser.h b/sapi/cli/php_http_parser.h index 345ca405edd0..d7006b6d04d7 100644 --- a/sapi/cli/php_http_parser.h +++ b/sapi/cli/php_http_parser.h @@ -79,6 +79,7 @@ enum php_http_method , PHP_HTTP_POST , PHP_HTTP_PUT , PHP_HTTP_PATCH + , PHP_HTTP_QUERY /* pathological */ , PHP_HTTP_CONNECT , PHP_HTTP_OPTIONS diff --git a/sapi/cli/ps_title.h b/sapi/cli/ps_title.h index 7436c2b25a94..99c9a290ee54 100644 --- a/sapi/cli/ps_title.h +++ b/sapi/cli/ps_title.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Keyur Govande | +----------------------------------------------------------------------+ diff --git a/sapi/cli/tests/001.phpt b/sapi/cli/tests/001.phpt index bb85ad434357..8038c3e78b76 100644 --- a/sapi/cli/tests/001.phpt +++ b/sapi/cli/tests/001.phpt @@ -13,6 +13,6 @@ echo "Done\n"; ?> --EXPECTF-- string(%d) "PHP %s (cli) (built: %s)%s -Copyright (c) The PHP Group -%AZend Engine v%s, Copyright (c) Zend Technologies%A" +Copyright © The PHP Group and Contributors +%AZend Engine v%s, Copyright © Zend by Perforce%A" Done diff --git a/sapi/cli/tests/004.phpt b/sapi/cli/tests/004.phpt index c88b85480bdb..b6e0e74fa6ff 100644 --- a/sapi/cli/tests/004.phpt +++ b/sapi/cli/tests/004.phpt @@ -12,6 +12,9 @@ $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); var_dump(shell_exec("$php -n --rf unknown")); var_dump(shell_exec("$php -n --rf echo")); var_dump(shell_exec("$php -n --rf phpinfo")); +// Regression tests for https://github.com/php/php-src/issues/21754 +var_dump(shell_exec("$php -n --rf ReflectionMethod::__construct")); +var_dump(shell_exec("$php -n --rf ReflectionMethod::missing")); echo "Done\n"; ?> @@ -28,5 +31,16 @@ string(155) "Function [ function phpinfo ] { - Return [ true ] } +" +string(213) "Method [ public method __construct ] { + + - Parameters [2] { + Parameter #0 [ object|string $objectOrMethod ] + Parameter #1 [ ?string $method = null ] + } +} + +" +string(61) "Exception: Method ReflectionMethod::missing() does not exist " Done diff --git a/sapi/cli/tests/019.phpt b/sapi/cli/tests/019.phpt index 481ea2228b34..4045c648ab0a 100644 --- a/sapi/cli/tests/019.phpt +++ b/sapi/cli/tests/019.phpt @@ -21,16 +21,38 @@ echo "\nDone\n"; phpinfo() PHP Version => %s %a -PHP License -This program is free software; you can redistribute it and/or modify -it under the terms of the PHP License as published by the PHP Group -and included in the distribution in the file: LICENSE +License -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +PHP is free software. You may redistribute it and/or modify it under the +terms of the Modified BSD License (SPDX-License-Identifier: BSD-3-Clause). -If you did not receive a copy of the PHP license, or have any -questions about PHP licensing, please contact license@php.net. +Copyright © The PHP Group and Contributors. +Copyright © Zend Technologies Ltd., a subsidiary company of + Perforce Software, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Done diff --git a/sapi/cli/tests/bug69655.phpt b/sapi/cli/tests/bug69655.phpt index 4ab53bcbaae0..d13f67f5f12e 100644 --- a/sapi/cli/tests/bug69655.phpt +++ b/sapi/cli/tests/bug69655.phpt @@ -17,11 +17,11 @@ foreach (['MKCO', 'MKCOLL', 'M'] as $method) { } ?> --EXPECTF-- -Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented in %s on line %d -Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented in %s on line %d -Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented in %s on line %d diff --git a/sapi/cli/tests/bug70264.phpt b/sapi/cli/tests/bug70264.phpt index e1b0ee8fe8b1..4de5b72ffb05 100644 --- a/sapi/cli/tests/bug70264.phpt +++ b/sapi/cli/tests/bug70264.phpt @@ -14,8 +14,8 @@ echo file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS . "/..\\CREDITS"); echo file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS . "/..%5CCREDITS"); ?> --EXPECTF-- -Warning: file_get_contents(http://%s/..\CREDITS): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in %sbug70264.php on line %d -Warning: file_get_contents(http://%s/..%5CCREDITS): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found +Warning: file_get_contents(): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in %sbug70264.php on line %d diff --git a/sapi/cli/tests/bug73630a.phpt b/sapi/cli/tests/bug73630a.phpt index 45880c6cda09..33576a9e2b11 100644 --- a/sapi/cli/tests/bug73630a.phpt +++ b/sapi/cli/tests/bug73630a.phpt @@ -21,5 +21,5 @@ $path = "/" . str_repeat("x", 16400) . "//example.com"; var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS . "$path")); ?> --EXPECTF-- -Warning: file_get_contents(http://%s//example.com): Failed to open stream: HTTP request failed! in %s on line %d +Warning: file_get_contents(): Failed to open stream: HTTP request failed! in %s on line %d bool(false) diff --git a/sapi/cli/tests/bug80092.phpt b/sapi/cli/tests/bug80092.phpt index eac60e7e3778..a05620f1975d 100644 --- a/sapi/cli/tests/bug80092.phpt +++ b/sapi/cli/tests/bug80092.phpt @@ -41,6 +41,6 @@ foreach (explode("\n", $output) as $line) { --EXPECTF-- preloaded PHP %s -Copyright (c) The PHP Group +Copyright © The PHP Group and Contributors %AZend Engine %s %A with Zend OPcache %a diff --git a/sapi/cli/tests/gh21901.phpt b/sapi/cli/tests/gh21901.phpt new file mode 100644 index 000000000000..39c76913d1f8 --- /dev/null +++ b/sapi/cli/tests/gh21901.phpt @@ -0,0 +1,13 @@ +--TEST-- +Stale getopt() optional value in CLI +--FILE-- + +--EXPECTF-- +Configuration File (php.ini) Path: %s +Loaded Configuration File: %s +Scan for additional .ini files in: %s +Additional .ini files parsed: %s diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc index 3022022f894e..3ad6ced5cb44 100644 --- a/sapi/cli/tests/php_cli_server.inc +++ b/sapi/cli/tests/php_cli_server.inc @@ -24,7 +24,8 @@ function php_cli_server_start( file_put_contents($doc_root . '/' . ($router ?: 'index.php'), ''); } - $cmd = [$php_executable, '-t', $doc_root, '-n', ...$cmd_args, '-S', 'localhost:0']; + // XXX: This should ideally use the same INI overrides as run-tests + $cmd = [$php_executable, '-d', 'error_include_args=0', '-t', $doc_root, '-n', ...$cmd_args, '-S', 'localhost:0']; if (!is_null($router)) { $cmd[] = $router; } diff --git a/sapi/cli/tests/php_cli_server_query_method.phpt b/sapi/cli/tests/php_cli_server_query_method.phpt new file mode 100644 index 000000000000..58ce95bfd1e3 --- /dev/null +++ b/sapi/cli/tests/php_cli_server_query_method.phpt @@ -0,0 +1,40 @@ +--TEST-- +Support HTTP QUERY method +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 200 OK +Host: %s +Date: %s +Connection: close +X-Powered-By: %s +Content-type: text/html; charset=UTF-8 + +string(5) "QUERY" diff --git a/sapi/cli/tests/sapi_windows_set_ctrl_trampoline.phpt b/sapi/cli/tests/sapi_windows_set_ctrl_trampoline.phpt new file mode 100644 index 000000000000..4699387b2c39 --- /dev/null +++ b/sapi/cli/tests/sapi_windows_set_ctrl_trampoline.phpt @@ -0,0 +1,31 @@ +--TEST-- +sapi_windows_set_ctrl_handler() trampoline test +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Done diff --git a/sapi/embed/php_embed.c b/sapi/embed/php_embed.c index 06cd1fb0763b..75249f97fc87 100644 --- a/sapi/embed/php_embed.c +++ b/sapi/embed/php_embed.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ diff --git a/sapi/embed/php_embed.h b/sapi/embed/php_embed.h index 3a4844629dea..9cd582a939a5 100644 --- a/sapi/embed/php_embed.h +++ b/sapi/embed/php_embed.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 4d4952eee86e..89c53a0c4d28 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -262,100 +262,16 @@ AS_VAR_IF([php_cv_have_SO_LISTENQLEN], [yes], [Define to 1 if you have 'SO_LISTENQ*'.])]) ]) -AC_DEFUN([PHP_FPM_KQUEUE], -[AC_CACHE_CHECK([for kqueue], - [php_cv_have_kqueue], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl - #include - #include - #include - ], [dnl - int kfd; - struct kevent k; - kfd = kqueue(); - /* 0 -> STDIN_FILENO */ - EV_SET(&k, 0, EVFILT_READ , EV_ADD | EV_CLEAR, 0, 0, NULL); - (void)kfd; - ])], - [php_cv_have_kqueue=yes], - [php_cv_have_kqueue=no])]) -AS_VAR_IF([php_cv_have_kqueue], [yes], - [AC_DEFINE([HAVE_KQUEUE], [1], - [Define to 1 if system has a working 'kqueue' function.])]) -]) - -AC_DEFUN([PHP_FPM_EPOLL], -[AC_CACHE_CHECK([for epoll], - [php_cv_have_epoll], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [dnl - int epollfd; - struct epoll_event e; - - epollfd = epoll_create(1); - if (epollfd < 0) { - return 1; - } - - e.events = EPOLLIN | EPOLLET; - e.data.fd = 0; - - if (epoll_ctl(epollfd, EPOLL_CTL_ADD, 0, &e) == -1) { - return 1; - } - - e.events = 0; - if (epoll_wait(epollfd, &e, 1, 1) < 0) { - return 1; - } - ])], - [php_cv_have_epoll=yes], - [php_cv_have_epoll=no])]) -AS_VAR_IF([php_cv_have_epoll], [yes], - [AC_DEFINE([HAVE_EPOLL], [1], [Define to 1 if system has a working epoll.])]) -]) - -AC_DEFUN([PHP_FPM_SELECT], -[AC_CACHE_CHECK([for select], - [php_cv_have_select], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl - /* According to POSIX.1-2001 */ - #include - - /* According to earlier standards */ - #include - #include - #include - ], [dnl - fd_set fds; - struct timeval t; - t.tv_sec = 0; - t.tv_usec = 42; - FD_ZERO(&fds); - /* 0 -> STDIN_FILENO */ - FD_SET(0, &fds); - select(FD_SETSIZE, &fds, NULL, NULL, &t); - ])], - [php_cv_have_select=yes], - [php_cv_have_select=no])]) -AS_VAR_IF([php_cv_have_select], [yes], - [AC_DEFINE([HAVE_SELECT], [1], - [Define to 1 if system has a working 'select' function.])]) -]) - if test "$PHP_FPM" != "no"; then PHP_FPM_CLOCK PHP_FPM_TRACE PHP_FPM_BUILTIN_ATOMIC PHP_FPM_LQ - PHP_FPM_KQUEUE - PHP_FPM_EPOLL - PHP_FPM_SELECT AC_CHECK_FUNCS([clearenv setproctitle setproctitle_fast]) AC_CHECK_HEADER([priv.h], [AC_CHECK_FUNCS([setpflags])]) AC_CHECK_HEADER([sys/times.h], [AC_CHECK_FUNCS([times])]) - AC_CHECK_HEADER([port.h], [AC_CHECK_FUNCS([port_create])]) PHP_ARG_WITH([fpm-user],, [AS_HELP_STRING([[--with-fpm-user[=USER]]], diff --git a/sapi/fpm/fpm/events/epoll.c b/sapi/fpm/fpm/events/epoll.c index 0a6eadb6aebe..2de3b463ae59 100644 --- a/sapi/fpm/fpm/events/epoll.c +++ b/sapi/fpm/fpm/events/epoll.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/epoll.h b/sapi/fpm/fpm/events/epoll.h index f20480c687c2..8b3d1867c0b1 100644 --- a/sapi/fpm/fpm/events/epoll.h +++ b/sapi/fpm/fpm/events/epoll.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/kqueue.c b/sapi/fpm/fpm/events/kqueue.c index 21939d341418..22b9d1a8d3ab 100644 --- a/sapi/fpm/fpm/events/kqueue.c +++ b/sapi/fpm/fpm/events/kqueue.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/kqueue.h b/sapi/fpm/fpm/events/kqueue.h index 1f68d44369ba..4690b065dfce 100644 --- a/sapi/fpm/fpm/events/kqueue.h +++ b/sapi/fpm/fpm/events/kqueue.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/poll.c b/sapi/fpm/fpm/events/poll.c index 30ebbc785d94..10085e83faa8 100644 --- a/sapi/fpm/fpm/events/poll.c +++ b/sapi/fpm/fpm/events/poll.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/poll.h b/sapi/fpm/fpm/events/poll.h index d9859160985c..24fa512eda9e 100644 --- a/sapi/fpm/fpm/events/poll.h +++ b/sapi/fpm/fpm/events/poll.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/port.c b/sapi/fpm/fpm/events/port.c index 73cf24c82c2c..b7f5715abad4 100644 --- a/sapi/fpm/fpm/events/port.c +++ b/sapi/fpm/fpm/events/port.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ @@ -19,7 +17,7 @@ #include "../fpm.h" #include "../zlog.h" -#ifdef HAVE_PORT_CREATE +#ifdef HAVE_EVENT_PORTS #include #include @@ -45,19 +43,19 @@ port_event_t *events = NULL; int nevents = 0; static int pfd = -1; -#endif /* HAVE_PORT_CREATE */ +#endif /* HAVE_EVENT_PORTS */ struct fpm_event_module_s *fpm_event_port_module(void) /* {{{ */ { -#ifdef HAVE_PORT_CREATE +#ifdef HAVE_EVENT_PORTS return &port_module; #else return NULL; -#endif /* HAVE_PORT_CREATE */ +#endif /* HAVE_EVENT_PORTS */ } /* }}} */ -#ifdef HAVE_PORT_CREATE +#ifdef HAVE_EVENT_PORTS /* * Init the module @@ -196,4 +194,4 @@ static int fpm_event_port_remove(struct fpm_event_s *ev) /* {{{ */ } /* }}} */ -#endif /* HAVE_PORT_CREATE */ +#endif /* HAVE_EVENT_PORTS */ diff --git a/sapi/fpm/fpm/events/port.h b/sapi/fpm/fpm/events/port.h index 65a29e8eac14..5768c891bdac 100644 --- a/sapi/fpm/fpm/events/port.h +++ b/sapi/fpm/fpm/events/port.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/select.c b/sapi/fpm/fpm/events/select.c index 66e8107f07c6..f6132b025747 100644 --- a/sapi/fpm/fpm/events/select.c +++ b/sapi/fpm/fpm/events/select.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/events/select.h b/sapi/fpm/fpm/events/select.h index 12f10220f5fb..e4cafde1ed9b 100644 --- a/sapi/fpm/fpm/events/select.h +++ b/sapi/fpm/fpm/events/select.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jerome Loyet | +----------------------------------------------------------------------+ diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 3979d875a18e..a77f7776bdbe 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -973,7 +973,7 @@ static int fpm_conf_process_all_pools(void) } for (i = 0; i < strlen(status); i++) { - if (!isalnum(status[i]) && status[i] != '/' && status[i] != '-' && status[i] != '_' && status[i] != '.' && status[i] != '~') { + if (!isalnum((unsigned char)status[i]) && status[i] != '/' && status[i] != '-' && status[i] != '_' && status[i] != '.' && status[i] != '~') { zlog(ZLOG_ERROR, "[pool %s] the status path '%s' must contain only the following characters '[alphanum]/_-.~'", wp->config->name, status); return -1; } @@ -996,7 +996,7 @@ static int fpm_conf_process_all_pools(void) } for (i = 0; i < strlen(ping); i++) { - if (!isalnum(ping[i]) && ping[i] != '/' && ping[i] != '-' && ping[i] != '_' && ping[i] != '.' && ping[i] != '~') { + if (!isalnum((unsigned char)ping[i]) && ping[i] != '/' && ping[i] != '-' && ping[i] != '_' && ping[i] != '.' && ping[i] != '~') { zlog(ZLOG_ERROR, "[pool %s] the ping path '%s' must contain only the following characters '[alphanum]/_-.~'", wp->config->name, ping); return -1; } diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 83b00eb4c4d3..3a8435f9e6cc 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | 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. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index 9cb8731363fa..ff6ef68f3949 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -522,8 +522,8 @@ int fpm_status_handle_request(void) /* {{{ */ if (full_syntax) { unsigned int i; int first; - zend_string *tmp_query_string; - char *query_string; + zend_string *tmp_query_string, *tmp_request_uri_string; + char *query_string, *request_uri_string; struct timeval duration, now; float cpu; @@ -548,13 +548,36 @@ int fpm_status_handle_request(void) /* {{{ */ } } + request_uri_string = NULL; + tmp_request_uri_string = NULL; + if (proc->request_uri[0] != '\0') { + if (encode_html) { + tmp_request_uri_string = php_escape_html_entities_ex( + (const unsigned char *) proc->request_uri, + strlen(proc->request_uri), 1, ENT_DISALLOWED | ENT_HTML_DOC_XML1 | ENT_COMPAT, + NULL, /* double_encode */ 1, /* quiet */ 0); + request_uri_string = ZSTR_VAL(tmp_request_uri_string); + } else if (encode_json) { + tmp_request_uri_string = php_json_encode_string(proc->request_uri, + strlen(proc->request_uri), PHP_JSON_INVALID_UTF8_IGNORE); + request_uri_string = ZSTR_VAL(tmp_request_uri_string); + /* remove quotes around the string */ + if (ZSTR_LEN(tmp_request_uri_string) >= 2) { + request_uri_string[ZSTR_LEN(tmp_request_uri_string) - 1] = '\0'; + ++request_uri_string; + } + } else { + request_uri_string = proc->request_uri; + } + } + query_string = NULL; tmp_query_string = NULL; if (proc->query_string[0] != '\0') { if (encode_html) { tmp_query_string = php_escape_html_entities_ex( (const unsigned char *) proc->query_string, - strlen(proc->query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, + strlen(proc->query_string), 1, ENT_DISALLOWED | ENT_HTML_DOC_XML1 | ENT_COMPAT, NULL, /* double_encode */ 1, /* quiet */ 0); } else if (encode_json) { tmp_query_string = php_json_encode_string(proc->query_string, @@ -593,7 +616,7 @@ int fpm_status_handle_request(void) /* {{{ */ proc->requests, (unsigned long) (duration.tv_sec * 1000000UL + duration.tv_usec), proc->request_method[0] != '\0' ? proc->request_method : "-", - proc->request_uri[0] != '\0' ? proc->request_uri : "-", + request_uri_string ? request_uri_string : "-", query_string ? "?" : "", query_string ? query_string : "", proc->content_length, @@ -604,6 +627,9 @@ int fpm_status_handle_request(void) /* {{{ */ PUTS(buffer); efree(buffer); + if (tmp_request_uri_string) { + zend_string_free(tmp_request_uri_string); + } if (tmp_query_string) { zend_string_free(tmp_query_string); } diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index 941b911ed08f..6a46c9419e67 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -203,21 +203,13 @@ contributors all around the world. .SH VERSION INFORMATION This manpage describes \fBphp-fpm\fP, version @PHP_VERSION@. .SH COPYRIGHT -Copyright \(co The PHP Group +Copyright \(co The PHP Group and Contributors .PD 0 .P -Copyright (c) 2007-2009, Andrei Nigmatulin +Copyright \(co 2007-2009, Andrei Nigmatulin .PD 1 .LP -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: -.PD 0 -.P -.B https://www.php.net/license/3_01.txt -.PD 1 -.P -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 -.B license@php.net -so we can mail you a copy immediately. +This source file is subject to the Modified BSD License that is +bundled with this package in the file LICENSE, and is available +through the World Wide Web at +.B https://www.php.net/license/ diff --git a/sapi/fpm/status.html.in b/sapi/fpm/status.html.in index 31824234a3e8..aee7e5530597 100644 --- a/sapi/fpm/status.html.in +++ b/sapi/fpm/status.html.in @@ -2,7 +2,7 @@ diff --git a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt new file mode 100644 index 000000000000..475bc130a42b --- /dev/null +++ b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt @@ -0,0 +1,48 @@ +--TEST-- +FPM: GHSA-7qg2-v9fj-4mwv - status xss +--SKIPIF-- + +--FILE-- +start(); +$tester->expectLogStartNotices(); +$responses = $tester + ->multiRequest([ + ['uri' => '/', 'query' => ''], + ['uri' => '/status', 'query' => 'full&html', 'delay' => 100000], + ]); +var_dump(strpos($responses[1]->getBody(), '